From 894cbe4a0bf3ec571f46a365c5fe3182cd590ded Mon Sep 17 00:00:00 2001 From: Ben Bierens Date: Wed, 8 Feb 2023 14:54:29 +0100 Subject: [PATCH] implements minimal state switching --- codex/utils/asyncstatemachine.nim | 9 +++++++- tests/codex/utils/testasyncstatemachine.nim | 24 +++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/codex/utils/asyncstatemachine.nim b/codex/utils/asyncstatemachine.nim index 004deda4..e861ed7c 100644 --- a/codex/utils/asyncstatemachine.nim +++ b/codex/utils/asyncstatemachine.nim @@ -5,6 +5,13 @@ type AsyncStateMachine* = ref object of RootObj AsyncState* = ref object of RootObj -method start*(stateMachine: AsyncStateMachine, initialState: AsyncState) = +method run*(state: AsyncState): Future[?AsyncState] {.base.} = discard +proc runState(state: AsyncState): Future[void] {.async.} = + if next =? await state.run(): + await runState(next) + +proc start*(stateMachine: AsyncStateMachine, initialState: AsyncState) = + asyncSpawn runState(initialState) + diff --git a/tests/codex/utils/testasyncstatemachine.nim b/tests/codex/utils/testasyncstatemachine.nim index c0d1f884..d5c49f34 100644 --- a/tests/codex/utils/testasyncstatemachine.nim +++ b/tests/codex/utils/testasyncstatemachine.nim @@ -4,16 +4,27 @@ import pkg/chronos import codex/utils/asyncstatemachine import ../helpers/eventually -type TestState = ref object of AsyncState +type + TestState = ref object of AsyncState + State1 = ref object of AsyncState + State2 = ref object of AsyncState var runInvoked = 0 +var state2runInvoked = 0 -method run(state: TestState): Future[?AsyncState] = +method run(state: TestState): Future[?AsyncState] {.async.} = inc runInvoked +method run(state: State1): Future[?AsyncState] {.async.} = + return some AsyncState(State2.new()) + +method run(state: State2): Future[?AsyncState] {.async.} = + inc state2runInvoked + suite "async state machines": setup: runInvoked = 0 + state2runInvoked = 0 test "creates async state machine": let sm = AsyncStateMachine.new() @@ -27,3 +38,12 @@ suite "async state machines": check eventually runInvoked == 1 + test "moves to next state when run completes": + let sm = AsyncStateMachine.new() + let state1 = State1.new() + let state2 = State2.new() + + sm.start(state1) + + check eventually state2runInvoked == 1 +