mirror of
https://github.com/codex-storage/nim-codex.git
synced 2025-02-19 16:24:32 +00:00
[statemachine] remove template, replace with inheritable Machine/State
- remove `makeStateMachine` template, replace with inheritable Machine/State so that normal imports can be used - rename `MachineType` to `Machine` - rename `StateType` to `State`
This commit is contained in:
parent
21527bb70f
commit
d7b66611b3
@ -2,55 +2,55 @@ import pkg/questionable
|
|||||||
import pkg/chronos
|
import pkg/chronos
|
||||||
import pkg/upraises
|
import pkg/upraises
|
||||||
|
|
||||||
template makeStateMachine*(MachineType, StateType) =
|
# template makeStateMachine*(Machine, State) =
|
||||||
|
|
||||||
type
|
type
|
||||||
MachineType* = ref object of RootObj
|
Machine* = ref object of RootObj
|
||||||
state: StateType
|
state: State
|
||||||
running: Future[void]
|
running: Future[void]
|
||||||
scheduled: AsyncQueue[Event]
|
scheduled: AsyncQueue[Event]
|
||||||
scheduling: Future[void]
|
scheduling: Future[void]
|
||||||
StateType* = ref object of RootObj
|
State* = ref object of RootObj
|
||||||
Event = proc(state: StateType): ?StateType {.gcsafe, upraises:[].}
|
Event = proc(state: State): ?State {.gcsafe, upraises:[].}
|
||||||
|
|
||||||
proc transition(_: type Event, previous, next: StateType): Event =
|
proc transition(_: type Event, previous, next: State): Event =
|
||||||
return proc (state: StateType): ?StateType =
|
return proc (state: State): ?State =
|
||||||
if state == previous:
|
if state == previous:
|
||||||
return some next
|
return some next
|
||||||
|
|
||||||
proc schedule*(machine: MachineType, event: Event) =
|
proc schedule*(machine: Machine, event: Event) =
|
||||||
machine.scheduled.putNoWait(event)
|
machine.scheduled.putNoWait(event)
|
||||||
|
|
||||||
method run*(state: StateType): Future[?StateType] {.base, upraises:[].} =
|
method run*(state: State): Future[?State] {.base, upraises:[].} =
|
||||||
|
discard
|
||||||
|
|
||||||
|
proc run(machine: Machine, state: State) {.async.} =
|
||||||
|
try:
|
||||||
|
if next =? await state.run():
|
||||||
|
machine.schedule(Event.transition(state, next))
|
||||||
|
except CancelledError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc run(machine: MachineType, state: StateType) {.async.} =
|
proc scheduler(machine: Machine) {.async.} =
|
||||||
try:
|
try:
|
||||||
if next =? await state.run():
|
while true:
|
||||||
machine.schedule(Event.transition(state, next))
|
let event = await machine.scheduled.get()
|
||||||
except CancelledError:
|
if next =? event(machine.state):
|
||||||
discard
|
if not machine.running.isNil:
|
||||||
|
await machine.running.cancelAndWait()
|
||||||
|
machine.state = next
|
||||||
|
machine.running = machine.run(machine.state)
|
||||||
|
asyncSpawn machine.running
|
||||||
|
except CancelledError:
|
||||||
|
discard
|
||||||
|
|
||||||
proc scheduler(machine: MachineType) {.async.} =
|
proc start*(machine: Machine, initialState: State) =
|
||||||
try:
|
machine.scheduling = machine.scheduler()
|
||||||
while true:
|
machine.schedule(Event.transition(machine.state, initialState))
|
||||||
let event = await machine.scheduled.get()
|
|
||||||
if next =? event(machine.state):
|
|
||||||
if not machine.running.isNil:
|
|
||||||
await machine.running.cancelAndWait()
|
|
||||||
machine.state = next
|
|
||||||
machine.running = machine.run(machine.state)
|
|
||||||
asyncSpawn machine.running
|
|
||||||
except CancelledError:
|
|
||||||
discard
|
|
||||||
|
|
||||||
proc start*(machine: MachineType, initialState: StateType) =
|
proc stop*(machine: Machine) =
|
||||||
machine.scheduling = machine.scheduler()
|
machine.scheduling.cancel()
|
||||||
machine.schedule(Event.transition(machine.state, initialState))
|
machine.running.cancel()
|
||||||
|
|
||||||
proc stop*(machine: MachineType) =
|
proc new*(_: type Machine): Machine =
|
||||||
machine.scheduling.cancel()
|
Machine(scheduled: newAsyncQueue[Event]())
|
||||||
machine.running.cancel()
|
|
||||||
|
|
||||||
proc new*(_: type MachineType): MachineType =
|
|
||||||
MachineType(scheduled: newAsyncQueue[Event]())
|
|
||||||
|
@ -5,8 +5,6 @@ import pkg/upraises
|
|||||||
import codex/utils/asyncstatemachine
|
import codex/utils/asyncstatemachine
|
||||||
import ../helpers/eventually
|
import ../helpers/eventually
|
||||||
|
|
||||||
makeStateMachine(Machine, State)
|
|
||||||
|
|
||||||
type
|
type
|
||||||
State1 = ref object of State
|
State1 = ref object of State
|
||||||
State2 = ref object of State
|
State2 = ref object of State
|
||||||
|
Loading…
x
Reference in New Issue
Block a user