T-45: We should split out the (Navigable)-State-Stack
The state-stack (https://github.com/doridori/StateStack) (comprised of state-frames) should live as its own android independent project.
Really its a type of state-machine, which:
- Allows states to exist in a stack, and have a notion of if they are at the top of the stack or not, and allow moving backwards through the stack.
- Has a notion of the state machine being
activeorpaused(minimal lifecycle) - Accepts listeners
- ~Has no notion of how states are created~
- ~There should be a stack operation builder as talked about in #36, but this should defer the actual building of a stack object in some abstract way, so the implementor can decide if this is with the caller creating the state or the state being created reflectivly (which is better suited for android lifecycle restoration aka the intent system)~
- Regarding new
statecreation, we need to not overthink this one. States can be created by anything (i.e. another State or some external code) in any way. There is some consideration thats needs to take place if the state machine should be easily serialisable / restorable, but this can be as simple as a rule saying States should only take primitiveArgobjects in their constructors, which would allow some external serialiser to grab all the current class names and Args objects, and recreate the state machine from this info. Really this should be something contained in an F.A.Q and sample project as opposed to in the core lib, as if one does not care about this function there is no need to clutter the state creation logic just in case someone wants to save/restore.
- Querying of stack state and contents
- currently Allows multiple type of stack frame types
- Currently this is done with baked in visible frame annotations. This should be removed, and the listeners (defined outside of the project) can contain the logic about how to tell if a frame should be rendered or not. (may involve writing a listener transformer, that takes events and may be able to convert them into visible events depending on the implementation)
- I think this should be removed as the integrator can define this externally
- Logging of stack changes
- Stack operation builder for atomic stack operations (simplfies internal callback logic)
- Easy testing
statesshould auto have the parent state-machine set to it, and have the ability perform transitions on it directly. For testing, a mock state-machine can be attached to the state.
(see MM state map for more)
The android project would then define:
- Listening for stack changes, and working out if a new view should be rendered.
- View rendering animations
- Pushing (or pulling) the state to any interested views
- Pulling may be much simpler than current impl. Pulls when its created and does all its setup on successful pull. If it cant pull the state it wants its safe to assume the view is just about to be destroyed and a new one will take its place (that represents the current actual state). It seems that views are not recreated on config-change unless the view is inside a fragment, so when fragment-less this should never really happen anyway.
- Transforming the state via a Presentation layer #42
- Restoring the stack state if needed (if states have been created via reflection and using
Args) - Translating android lifecycle events into the
activeorpausedevents - Creating stack frames (and the DI approach e.g. using
Providershidden behind a builder as opposed to current field injection)
Once this is done we can split the android project into sub projects. core can provide the interfaces and core activity binding (headless frag?).
Sub projects can fill out those interfaces for view support and fragment support. The latter would not preclude using the new arch components - this will be an orthogonal concern.
Should follow the principles of library design as spoken about by Lisa in the Day 1 keynote http://uk.droidcon.com/#program