ReactKit / SwiftState

Elegant state machine for Swift.
MIT License
904 stars 93 forks source link

Refactor code for better typing, naming, and RouteMapping support. #36

Closed inamiy closed 8 years ago

inamiy commented 9 years ago

This is a BREAKING CHANGE and release candidate for next version 4.0.0, greatly improved typing and RouteMapping support (handling states/events with associated values).

See Also: https://github.com/ReactKit/SwiftState/issues/34

Simple Class Names

I renamed many verbose class names e.g. StateTransition to simple Transition. (Even if the name collides with other frameworks, we can just simply add framework-prefix e.g. SwiftState.Transition to avoid it.)

Better Typing

As requested in https://github.com/ReactKit/SwiftState/issues/34 by @frogcjn, current version 3.x needs to use StateType/EventType which conforms to NilLiteralConvertible to represent .Any state/event, but it was quite ugly because we needed to add extra case Any in their enums.

To alleviate this, I added extra enum wrappers (State<S> & Event<E>) so that users no longer need to implement .Any anymore.

RouteMapping

RouteMapping and StateRouteMapping are new ways of adding routes which has a closure type

public typealias RouteMapping = (event: E?, fromState: S, userInfo: Any?) -> S?
public typealias StateRouteMapping = (fromState: S, userInfo: Any?) -> [S]?

to navigate StateMachine to preferred toState without using traditional arrow style, e.g. fromState => toState. These closures help resolving states & events with associated values.

Please see FrogcjnTest.swift#L124-L180 RouteMappingTests.swift#L77-L133 for more details.

Simple Machine class (works like Redux)

StateMachine (which can tryState() as well as tryEvent()) is now a subclass of simpler class Machine which is capable of tryEvent() only. By splitting these codes, along with RouteMapping, Machine will now behave like rackt/redux in JavaScript, a safe state container. For more information on Redux, see http://redux.js.org/ .

Easy Disposable of routes & handlers

There were previously RouteID and HandlerID being passed as return value for asking StateMachine to unregister, but now Disposable (derived from ReactiveCocoa) will take care of it.

Others

inamiy commented 9 years ago

Please ping me for any thoughts on this :wink:

frogcjn commented 9 years ago

Cool! FrogcjnTest.swift#L124-L180 this is just what I needs. Thanks!

inamiy commented 9 years ago

@frogcjn Thanks! I need to improve tests too, so it may take a bit more time to finish this up. So please let me get this right ;)

inamiy commented 8 years ago

I applied a 2nd big refactor in f7ce748 to add following features:

There are now 2 machine classes, Machine and its subclass StateMachine. StateMachine behaves just as same as old version 3.x and below. On the other hand, Machine is more simpler version, and works very similar to rackt/redux in JavaScript, a safe state container.

inamiy commented 8 years ago

See also (strict directory structure): https://github.com/apple/swift-package-manager/pull/16

inamiy commented 8 years ago

Ref: swift-package-manager + SwiftState 4.0.0-RC (e9c1bf3) build failure in Ubuntu 14.04 https://gist.github.com/inamiy/b75cba8916716c81dd7d

mxcl commented 8 years ago

Hey, we don't want to force anyone to have a directory structure they don't want. We will add configurability to the Package.swift so you can have the layout you prefer. We didn't have time to do that for the initial release.

inamiy commented 8 years ago

@mxcl Changing directory structure in this pull request is no problem because there are many refactoring including file name changes. As long as Sources and Tests keep their dirnames canonical, I don't even have to add extra exclusion lines in Package.swift, and I just love it :wink:

inamiy commented 8 years ago

Ready to :shipit:

susieyy commented 8 years ago

🎉🎉🎉