Skip to content
This repository has been archived by the owner on Dec 12, 2021. It is now read-only.

Refactor code by adding Effect, EffectQueue, Feedback #12

Merged
merged 1 commit into from
Jun 12, 2019

Conversation

inamiy
Copy link
Owner

@inamiy inamiy commented Jun 12, 2019

This PR brings quite a lot of improvements for effect handling including a bit of breaking changes.

New Features

1. Effect and EffectQueue (preferred)

enum Queue: EffectQueueProtocol {
    case request

    var flattenStrategy: FlattenStrategy {
        return .latest
    }
}

let mappings: [EffectMapping] = [
    .login    | .loggedOut  => .loggingIn  | Effect(loginOKProducer, queue: .request),
    .loginOK  | .loggingIn  => .loggedIn   | nil,
    .logout   | .loggedIn   => .loggingOut | Effect(logoutOKProducer, queue: .request),
    .logoutOK | .loggingOut => .loggedOut  | nil
]

automaton = Automaton(state: .loggedOut, inputs: signal, mapping: reduce(mappings))
  • Effect wraps a pure SignalProducer as a side-effect, and is also aware of which EffectQueue to be registered on.
  • EffectQueue is an Equatable enum to identify queues, which also associates with FlattenStrategy for flattening effects.
    • EffectQueue provides more flexible flattening strategies compared to previous ver 0.5.0 or Feedback systems.

2. Feedback (alternative approach found in ReactiveFeedback)

let mappings: [Mapping] = [
    .login    | .loggedOut  => .loggingIn,
    .loginOK  | .loggingIn  => .loggedIn,
    .logout   | .loggedIn   => .loggingOut,
    .logoutOK | .loggingOut => .loggedOut
]

automaton = Automaton(
    state: .loggedOut,
    inputs: signal,
    mapping: reduce(mappings),
    feedback: reduce([
        Feedback(
            filter: { $0.input == AuthInput.login },
            produce: { _ in loginOKProducer }
        ),
        Feedback(
            filter: { $0.input == AuthInput.logout },
            produce: { _ in logoutOKProducer }
        )
    ])
)

Compared to ReactiveFeedback, this feature includes:

  1. Feedback is isomorphic to Signal<(Input, FromState, ToState)> -> Signal<Input> which efficiently calculates next input from 3-tuple instead of 1 (ToState only as Moore Machine) or 2-tuple (Input and FromState as Mealy Machine).
    • This can be said as Moore-Mealy-hybrid machine!
  2. Cleanly separates inputs (hot signals) and feedback (cold producers)
  3. Reducible feedback via reduce.

Other breaking Changes

  • Introduced Initial Effect, same as Elm.Platform
  • (Slightly) Renamed some methods
  • When inputs send .completed, all running side-effects will be terminated immediately rather than waiting them to send final replies. This behavior will be same as send(.interrupted).

# for free to subscribe to this conversation on GitHub. Already have an account? #.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant