Git Product home page Git Product logo

playdux-unity's Introduction

Playdux Logo Playdux

Playdux is a unidirectional state container (a la Redux) intended for use in Unity 3D. It is definitely WIP at the moment, however the basic Redux-like functionality is there.

Dependencies

Playdux depends on UniRx by neuecc (https://github.com/neuecc/UniRx).

Usage

For more extensive usage examples, visit the example projects repo.

The Store class is the center of Playdux. It currently has the following functionality:

Creation

When creating a Store, you must specify the type of the root of your state hierarchy, an initial value for your state hierarchy, and a root reducer:

MyStateRoot RootReducer(MyStateRoot state, IAction action)
{
    // perform some transformation
    return newState;
}

// ...

MyStateRoot initialState = new MyStateRoot( /* state initialization params */ );
Store<MyStateRoot> myStore = new Store<MyStateRoot>(initialState, RootReducer);

Dispatching

After your store has been created, you can dispatch actions to it using Store.Dispatch:

myStore.Dispatch(new MyAction( /* action params */ ));

Dispatch will subsequently pass the action to the root reducer provided at creation, set the new state, and notify observers.

Getting the State

You can use the Store.State property to get the current state at any time. You can also get a particular segment of the state using Select, which allows you to pass a selector function which will get the particular piece of state you are interested in from the root state object:

var justTheName = myStore.Select(state => state.Person.Name);

You can also get an IObservable of which will emit changes to the state. This is done using State.ObservableFor, which also takes a selector function, similar to Store.State:

myStore.ObservableFor(state => state.Person.Name).Subscribe(name => Debug.Log($"Name changed to {name}!"))

This example uses reactive extensions (UniRx) to subscribe to the resulting IObservable with a lambda.

ObservableFor has an additional optional parameter, notifyImmediately. If this parameter is true, the returned IObservable will emit the current state as soon as it is subscribed. If it is false, the observable will emit the next time that segment of state has changed.

Future Feature Additions

  • Add useful example projects. These will likely be in a different repo. (issue #4)
  • Add SideEffectors. SideEffectors are intended to be Playdux's corollary to Redux's Middlewares or ngrx's Effects. They react to actions to accomplish side effects, whereas reducers cannot accomplish side effects. (issue #3)
  • Playdux devtools. I want to add Redux-like devtools in the Unity Editor to allow for time-travel debugging, etc. (issue #5)

playdux-unity's People

Contributors

schultzcole avatar

Stargazers

 avatar

Watchers

 avatar  avatar

playdux-unity's Issues

Interfaceify Store

Store should implement a few interfaces:

  • IActionDispatcher: has the Dispatch method.
  • IStateSource: has the State property and Select and ObservableFor methods.
  • IStore: implements IActionDispatcher and IStateSource

This way, IActionDispatcher can be passed to a component that needs to dispatch actions without that component needing to care about the resulting state, and vice versa. It will also make components that depend on Store much more testable.

Add MonoBehaviour wrapper for Store

There should be a MonoBehaviour version of Store that implements IStore so that the store can be injected via the Unity inspector into components that depend on the store.

Add special Initialize action

Initialize action should take the initial state of the store.
Having an initial action to kick off observers is important, and it also provides a prescribed method of setting the entire state to a particular value (for instance resetting the game).

Add SideEffectors

SideEffectors are objects or systems that react to actions, but are allowed to produce side effects. Unlike reducers, SideEffectors cannot modify state directly, however they can dispatch actions.

SideEffectors should have two method "hooks" into the Store:

  • PreEffect: called immediately when an action is dispatched, before reduction.
  • PostEffect: called after reduction.

Each hook is passed the action that was dispatched, the current state, and an IActionDispatcher.

Architecturally, SideEffectors reduce burden on components by being responsible for side effects, especially asynchrony. For example, a component doesn't need to care about the details of requesting a remote resource, it just needs to care about displaying it.

Here's an example flow for the use case where clicking a button should load a remote image and display it in a component:

  1. Button is clicked and dispatches a ButtonClicked action.
  2. A SideEffector hooks on the ButtonClicked action and initiates a web request for the resource.
  3. Reducer takes the ButtonClicked action and updates state to indicate that the image component is in the 'loading' state.
  4. The image component observes the 'loading' state and displays a loading icon.
  5. The SideEffector receives a response with the requested resource and dispatches another action: ImageLoaded, with the image included.
  6. Reducer takes the ImageLoaded action and updates the image component state to 'loaded' and adds the image to the state.
  7. The image component observes the 'loaded' state, gets the image, and displays it.

Add Playdux devtools

Playdux should have full-featured devtools, similar to redux devtools, integrated in the Unity editor.

Playdux devtools can be implemented as a SideEffector, so this issue depends on #3
Should Playdux devtools be a separate git repo?

Rename to AReSSC

Observer -> Consumer

I think consumer is a better term for clients paying attention to changes in state. While AReSSO (AReSSC?) does use Observables to notify consumers, I think calling them "observers" could end up getting a bit confusing as Observer already has a specific (and subtly different) meaning in RX parlance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.