Skip to content

Commit be66947

Browse files
committed
Merge pull request #41 from ReactKit/addAnyHandler
Add `addAnyHandler()`.
2 parents aba5e20 + 1b9ffee commit be66947

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

Sources/StateMachine.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ public final class StateMachine<S: StateType, E: EventType>: Machine<S, E>
269269

270270
// MARK: addHandler (no-event)
271271

272+
/// Add `handler` that is called when `tryState()` succeeds for target `transition`.
273+
/// - Note: `handler` will not be invoked for `tryEvent()`.
272274
public func addHandler(transition: Transition<S>, order: HandlerOrder = _defaultOrder, handler: Handler) -> Disposable
273275
{
274276
if self._handlers[transition] == nil {
@@ -308,6 +310,26 @@ public final class StateMachine<S: StateType, E: EventType>: Machine<S, E>
308310
return false
309311
}
310312

313+
// MARK: addAnyHandler (event-based & state-based)
314+
315+
/// Add `handler` that is called when either `tryEvent()` or `tryState()` succeeds for target `transition`.
316+
public func addAnyHandler(transition: Transition<S>, order: HandlerOrder = _defaultOrder, handler: Handler) -> Disposable
317+
{
318+
let disposable1 = self.addHandler(transition, order: order, handler: handler)
319+
let disposable2 = self.addHandler(event: .Any, order: order) { context in
320+
if (transition.fromState == .Any || transition.fromState == context.fromState) &&
321+
(transition.toState == .Any || transition.toState == context.toState)
322+
{
323+
handler(context)
324+
}
325+
}
326+
327+
return ActionDisposable {
328+
disposable1.dispose()
329+
disposable2.dispose()
330+
}
331+
}
332+
311333
//--------------------------------------------------
312334
// MARK: - RouteChain
313335
//--------------------------------------------------

Tests/StateMachineEventTests.swift

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,4 +374,75 @@ class StateMachineEventTests: _TestCase
374374

375375
XCTAssertEqual(invokeCount, 0, "Handler should NOT be performed")
376376
}
377+
378+
//--------------------------------------------------
379+
// MARK: - addAnyHandler
380+
//--------------------------------------------------
381+
382+
func testAddAnyHandler()
383+
{
384+
var invokeCounts = [0, 0, 0, 0, 0, 0]
385+
386+
let machine = StateMachine<MyState, MyEvent>(state: .State0) { machine in
387+
388+
// add 0 => 1 => 2 (event-based)
389+
machine.addRoutes(event: .Event0, transitions: [
390+
.State0 => .State1,
391+
.State1 => .State2,
392+
])
393+
394+
// add 2 => 3 (state-based)
395+
machine.addRoute(.State2 => .State3)
396+
397+
//
398+
// addAnyHandler (for both event-based & state-based)
399+
//
400+
401+
machine.addAnyHandler(.State0 => .State1) { context in
402+
invokeCounts[0]++
403+
}
404+
405+
machine.addAnyHandler(.State1 => .State2) { context in
406+
invokeCounts[1]++
407+
}
408+
409+
machine.addAnyHandler(.State2 => .State3) { context in
410+
invokeCounts[2]++
411+
}
412+
413+
machine.addAnyHandler(.Any => .State3) { context in
414+
invokeCounts[3]++
415+
}
416+
417+
machine.addAnyHandler(.State0 => .Any) { context in
418+
invokeCounts[4]++
419+
}
420+
421+
machine.addAnyHandler(.Any => .Any) { context in
422+
invokeCounts[5]++
423+
}
424+
425+
}
426+
427+
// initial
428+
XCTAssertEqual(machine.state, MyState.State0)
429+
XCTAssertEqual(invokeCounts, [0, 0, 0, 0, 0, 0])
430+
431+
// tryEvent
432+
machine <-! .Event0
433+
XCTAssertEqual(machine.state, MyState.State1)
434+
XCTAssertEqual(invokeCounts, [1, 0, 0, 0, 1, 1])
435+
436+
// tryEvent
437+
machine <-! .Event0
438+
XCTAssertEqual(machine.state, MyState.State2)
439+
XCTAssertEqual(invokeCounts, [1, 1, 0, 0, 1, 2])
440+
441+
// tryState
442+
machine <- .State3
443+
XCTAssertEqual(machine.state, MyState.State3)
444+
XCTAssertEqual(invokeCounts, [1, 1, 1, 1, 1, 3])
445+
446+
}
447+
377448
}

0 commit comments

Comments
 (0)