clock_state.bend

bendvy-ecs-core@0.1.0.0 · 72 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.0/change_tick.bend as Tick
3
4# Administrative time and captured execution ticks. Payloads never live here.
5# Nested execution restores its enclosing tick without rewinding World time.
6type State is Data:
7  State{now:Tick.Tick,scopes:List<&2,Tick.Tick>}
8
9def empty() -> State:
10  State{Tick.zero(),[]}
11
12def now(state:State) -> Tick.Tick:
13  match state:
14    case State{tick,_}:tick
15
16def entered(+tick:Tick.Tick,scopes:List<&2,Tick.Tick>) -> State & Tick.Tick:
17  (State{tick,tick <> scopes},tick)
18
19# Every admitted system execution captures exactly one new change tick.
20def enter(state:State) -> State & Tick.Tick:
21  match state:
22    case State{tick,scopes}:entered(Tick.next(tick),scopes)
23
24def left(tick:Tick.Tick,scopes:List<&2,Tick.Tick>) -> State:
25  match scopes:
26    case []:State{tick,[]}
27    case _ <> rest:State{tick,rest}
28
29# Complete an execution scope; administrative time is retained on failure too.
30def leave(state:State) -> State:
31  match state:
32    case State{tick,scopes}:left(tick,scopes)
33
34def advanced(+tick:Tick.Tick,scopes:List<&2,Tick.Tick>) -> State & Tick.Tick:
35  (State{tick,scopes},tick)
36
37# Advance an explicit direct/deferred boundary without opening a system scope.
38def advance(state:State) -> State & Tick.Tick:
39  match state:
40    case State{tick,scopes}:advanced(Tick.next(tick),scopes)
41
42def write_scoped(tick:Tick.Tick,scopes:List<&2,Tick.Tick>) -> State & Tick.Tick:
43  match scopes:
44    case []:advanced(Tick.next(tick),[])
45    case +active <> rest:(State{tick,active <> rest},active)
46
47# Writes in a system reuse its captured tick; standalone writes get a new tick.
48def write(state:State) -> State & Tick.Tick:
49  match state:
50    case State{tick,scopes}:write_scoped(tick,scopes)
51
52# Captured tick of the enclosing execution, or administrative time outside a run.
53def current_scoped(tick:Tick.Tick,scopes:List<&2,Tick.Tick>) -> Tick.Tick:
54  match scopes:
55    case []:tick
56    case active <> _:active
57def current(state:State) -> Tick.Tick:
58  match state:
59    case State{tick,scopes}:current_scoped(tick,scopes)
60
61# Lower query execution reuses an admitted scope, opening one only when direct.
62def ensured(+tick:Tick.Tick,scopes:List<&2,Tick.Tick>) -> State & Bool:
63  match scopes:
64    case []:(State{Tick.next(tick),[Tick.next(tick)]},True{})
65    case active <> rest:(State{tick,active <> rest},False{})
66def ensure(state:State) -> State & Bool:
67  match state:
68    case State{tick,scopes}:ensured(tick,scopes)
69def finish(owned:Bool,state:State) -> State:
70  match owned:
71    case False{}:state
72    case True{}:leave(state)