mirror of
https://github.com/codex-storage/nim-codex.git
synced 2025-02-16 14:57:54 +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/upraises
|
||||
|
||||
template makeStateMachine*(MachineType, StateType) =
|
||||
# template makeStateMachine*(Machine, State) =
|
||||
|
||||
type
|
||||
MachineType* = ref object of RootObj
|
||||
state: StateType
|
||||
running: Future[void]
|
||||
scheduled: AsyncQueue[Event]
|
||||
scheduling: Future[void]
|
||||
StateType* = ref object of RootObj
|
||||
Event = proc(state: StateType): ?StateType {.gcsafe, upraises:[].}
|
||||
type
|
||||
Machine* = ref object of RootObj
|
||||
state: State
|
||||
running: Future[void]
|
||||
scheduled: AsyncQueue[Event]
|
||||
scheduling: Future[void]
|
||||
State* = ref object of RootObj
|
||||
Event = proc(state: State): ?State {.gcsafe, upraises:[].}
|
||||
|
||||
proc transition(_: type Event, previous, next: StateType): Event =
|
||||
return proc (state: StateType): ?StateType =
|
||||
if state == previous:
|
||||
return some next
|
||||
proc transition(_: type Event, previous, next: State): Event =
|
||||
return proc (state: State): ?State =
|
||||
if state == previous:
|
||||
return some next
|
||||
|
||||
proc schedule*(machine: MachineType, event: Event) =
|
||||
machine.scheduled.putNoWait(event)
|
||||
proc schedule*(machine: Machine, event: 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
|
||||
|
||||
proc run(machine: MachineType, state: StateType) {.async.} =
|
||||
try:
|
||||
if next =? await state.run():
|
||||
machine.schedule(Event.transition(state, next))
|
||||
except CancelledError:
|
||||
discard
|
||||
proc scheduler(machine: Machine) {.async.} =
|
||||
try:
|
||||
while true:
|
||||
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 scheduler(machine: MachineType) {.async.} =
|
||||
try:
|
||||
while true:
|
||||
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: Machine, initialState: State) =
|
||||
machine.scheduling = machine.scheduler()
|
||||
machine.schedule(Event.transition(machine.state, initialState))
|
||||
|
||||
proc start*(machine: MachineType, initialState: StateType) =
|
||||
machine.scheduling = machine.scheduler()
|
||||
machine.schedule(Event.transition(machine.state, initialState))
|
||||
proc stop*(machine: Machine) =
|
||||
machine.scheduling.cancel()
|
||||
machine.running.cancel()
|
||||
|
||||
proc stop*(machine: MachineType) =
|
||||
machine.scheduling.cancel()
|
||||
machine.running.cancel()
|
||||
|
||||
proc new*(_: type MachineType): MachineType =
|
||||
MachineType(scheduled: newAsyncQueue[Event]())
|
||||
proc new*(_: type Machine): Machine =
|
||||
Machine(scheduled: newAsyncQueue[Event]())
|
||||
|
@ -5,8 +5,6 @@ import pkg/upraises
|
||||
import codex/utils/asyncstatemachine
|
||||
import ../helpers/eventually
|
||||
|
||||
makeStateMachine(Machine, State)
|
||||
|
||||
type
|
||||
State1 = ref object of State
|
||||
State2 = ref object of State
|
||||
|
Loading…
x
Reference in New Issue
Block a user