commands.bend
bendvy-ecs-core@0.1.0.4 · 180 lines · 32 definitions
1import Base
2import bendvy-ecs-core@0.1.0.4/trace_world.bend as TraceWorld
3import bendvy-ecs-core@0.1.0.4/deferred_command.bend as Deferred
4import bendvy-ecs-core@0.1.0.4/trace_facts.bend as TraceFacts
5import bendvy-ecs-core@0.1.0.4/world.bend as W
6import bendvy-ecs-core@0.1.0.4/transaction.bend as T
7
8
9def enqueue_list(~S: Data,~C: Type,~R: Type,~E: Data,commands:List<Deferred.Command<W.World<S,C,R,E>>>,world: W.World<S,C,R,E>) -> W.World<S,C,R,E>:
10 match commands:
11 case []: world
12 case command <> rest: enqueue_list(~S,~C,~R,~E,rest,W.enqueue_command(~S,~C,~R,~E,world,command))
13
14
15
16
17def enqueue(~S: Data,~C: Type,~R: Type,~E: Data,world: W.World<S,C,R,E>,commands:List<Deferred.Command<W.World<S,C,R,E>>>) -> W.World<S,C,R,E>:
18 enqueue_list(~S,~C,~R,~E,commands,world)
19
20
21
22def publish(~S: Data,~C: Type,~R: Type,~E: Data,world: W.World<S,C,R,E>,events: List<&2,E>) -> W.World<S,C,R,E>:
23 W.event_publish(~S,~C,~R,~E,world,events)
24
25
26
27
28
29def tx_finish(~S: Data,~C: Type,~R: Type,~E: Data,~Error: Data,tx: T.Tx<W.World<S,C,R,E>,E>,outcome: T.Outcome<Error>) -> T.Returned<W.World<S,C,R,E>,Error>:
30 T.finish(~W.World<S,C,R,E>,~E,~Error,~enqueue(~S,~C,~R,~E),~publish(~S,~C,~R,~E),tx,outcome)
31
32def spawned(~S: Data,~C: Type,~R: Type,~E: Data,~P: Type,~populate: W.World<S,C,R,E> -> W.Handle<S> -> P -> W.World<S,C,R,E>,activated: W.World<S,C,R,E> & W.Status,handle: W.Handle<S>,payload: P) -> W.World<S,C,R,E>:
33 match activated:
34 case (world,W.Accepted{}): populate(world,handle,payload)
35 case (world,W.Rejected{_}): world
36
37
38
39
40def spawn_apply(~S: Data,~C: Type,~R: Type,~E: Data,~P: Type,~populate: W.World<S,C,R,E> -> W.Handle<S> -> P -> W.World<S,C,R,E>,world: W.World<S,C,R,E>,+handle: W.Handle<S>,payload: P) -> W.World<S,C,R,E>:
41 spawned(~S,~C,~R,~E,~P,~populate,W.activate(~S,~C,~R,~E,world,handle),handle,payload)
42
43def spawn_applied_traced(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~populate:W.World<S,C,R,E> -> W.Handle<S> -> P -> W.World<S,C,R,E>,trace:TraceFacts.State,+handle:W.Handle<S>,payload:P,result:W.World<S,C,R,E> & W.Status) -> W.World<S,C,R,E> & TraceFacts.State:
44 match result:
45 case (world,+status):(spawned(~S,~C,~R,~E,~P,~populate,(world,status),handle,payload),TraceWorld.applied(~S,trace,"spawn",handle,status))
46
47
48def spawn_command(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~populate:W.World<S,C,R,E> -> W.Handle<S> -> P -> W.World<S,C,R,E>,enabled:Bool,+handle:W.Handle<S>,payload:P) -> Deferred.Command<W.World<S,C,R,E>>:
49 match enabled:
50 case False{}:Deferred.Raw{world=>spawn_apply(~S,~C,~R,~E,~P,~populate,world,handle,payload)}
51 case True{}:Deferred.Observed{trace=>world=>spawn_applied_traced(~S,~C,~R,~E,~P,~populate,trace,handle,payload,W.activate(~S,~C,~R,~E,world,handle))}
52
53
54def track_pending(~S:Data,~C:Type,~R:Type,~E:Data,tx:T.Tx<W.World<S,C,R,E>,E>,+handle:W.Handle<S>) -> T.Tx<W.World<S,C,R,E>,E>:
55 match tx:
56 case T.Tx{world,undo,commands,events,trace}:T.Tx{W.mark_pending(~S,~C,~R,~E,world,handle),(w => W.clear_pending(~S,~C,~R,~E,w,handle)) <> undo,commands,events,trace}
57
58def spawn_reserved(~S: Data,~C: Type,~R: Type,~E: Data,~P: Type,~populate: W.World<S,C,R,E> -> W.Handle<S> -> P -> W.World<S,C,R,E>,reservation: W.Reservation<S>,world: W.World<S,C,R,E>,undo: List<(W.World<S,C,R,E> -> W.World<S,C,R,E>)>,commands:List<Deferred.Command<W.World<S,C,R,E>>>,events: List<&2,E>,+trace:TraceFacts.State,payload: P) -> T.Tx<W.World<S,C,R,E>,E> & W.Reservation<S>:
59 match reservation:
60 case W.ReservationRejected{error}: (T.Tx{world,undo,commands,events,trace},W.ReservationRejected{error})
61 case W.Reserved{+handle}: (track_pending(~S,~C,~R,~E,T.Tx{world,undo,spawn_command(~S,~C,~R,~E,~P,~populate,TraceFacts.enabled(trace),handle,payload) <> commands,events,TraceWorld.deferred(~S,trace,"spawn",TraceFacts.StageOperation{},handle,TraceFacts.Attempted{})},handle),W.Reserved{handle})
62
63def spawn_join(~S: Data,~C: Type,~R: Type,~E: Data,~P: Type,~populate: W.World<S,C,R,E> -> W.Handle<S> -> P -> W.World<S,C,R,E>,reserved: W.World<S,C,R,E> & W.Reservation<S>,undo: List<(W.World<S,C,R,E> -> W.World<S,C,R,E>)>,commands:List<Deferred.Command<W.World<S,C,R,E>>>,events: List<&2,E>,trace:TraceFacts.State,payload: P) -> T.Tx<W.World<S,C,R,E>,E> & W.Reservation<S>:
64 (world,reservation) = reserved
65 spawn_reserved(~S,~C,~R,~E,~P,~populate,reservation,world,undo,commands,events,trace,payload)
66
67
68
69
70
71
72
73def tx_spawn(~S: Data,~C: Type,~R: Type,~E: Data,~P: Type,~populate: W.World<S,C,R,E> -> W.Handle<S> -> P -> W.World<S,C,R,E>,tx: T.Tx<W.World<S,C,R,E>,E>,payload: P) -> T.Tx<W.World<S,C,R,E>,E> & W.Reservation<S>:
74 match tx:
75 case T.Tx{world,undo,commands,events,trace}: spawn_join(~S,~C,~R,~E,~P,~populate,W.reserve_id(~S,~C,~R,~E,world),undo,commands,events,trace,payload)
76
77def deactivate_join(~S: Data,~C: Type,~R: Type,~E: Data,deactivated: W.World<S,C,R,E> & W.Status) -> W.World<S,C,R,E>:
78 (world,status) = deactivated
79 world
80
81
82
83def despawn_apply(~S: Data,~C: Type,~R: Type,~E: Data,world: W.World<S,C,R,E>,handle: W.Handle<S>) -> W.World<S,C,R,E>:
84 deactivate_join(~S,~C,~R,~E,W.deactivate(~S,~C,~R,~E,world,handle))
85
86def despawn_applied_traced(~S:Data,~C:Type,~R:Type,~E:Data,trace:TraceFacts.State,handle:W.Handle<S>,result:W.World<S,C,R,E> & W.Status) -> W.World<S,C,R,E> & TraceFacts.State:
87 match result:
88 case (world,status):(world,TraceWorld.applied(~S,trace,"despawn",handle,status))
89
90
91def despawn_command(~S:Data,~C:Type,~R:Type,~E:Data,enabled:Bool,+handle:W.Handle<S>) -> Deferred.Command<W.World<S,C,R,E>>:
92 match enabled:
93 case False{}:Deferred.Raw{world=>despawn_apply(~S,~C,~R,~E,world,handle)}
94 case True{}:Deferred.Observed{trace=>world=>despawn_applied_traced(~S,~C,~R,~E,trace,handle,W.deactivate(~S,~C,~R,~E,world,handle))}
95def despawn_checked(~S: Data,~C: Type,~R: Type,~E: Data,allowed: Bool,world: W.World<S,C,R,E>,undo: List<(W.World<S,C,R,E> -> W.World<S,C,R,E>)>,commands:List<Deferred.Command<W.World<S,C,R,E>>>,events: List<&2,E>,+trace:TraceFacts.State,+handle: W.Handle<S>) -> T.Tx<W.World<S,C,R,E>,E> & W.Status:
96 match allowed:
97 case False{}: (T.Tx{world,undo,commands,events,trace},W.Rejected{W.MissingEntity{}})
98 case True{}: (T.Tx{world,undo,despawn_command(~S,~C,~R,~E,TraceFacts.enabled(trace),handle) <> commands,events,TraceWorld.deferred(~S,trace,"despawn",TraceFacts.StageOperation{},handle,TraceFacts.Attempted{})},W.Accepted{})
99
100def despawn_join(~S: Data,~C: Type,~R: Type,~E: Data,checked: W.World<S,C,R,E> & Bool,undo: List<(W.World<S,C,R,E> -> W.World<S,C,R,E>)>,commands:List<Deferred.Command<W.World<S,C,R,E>>>,events: List<&2,E>,trace:TraceFacts.State,handle: W.Handle<S>) -> T.Tx<W.World<S,C,R,E>,E> & W.Status:
101 (world,allowed) = checked
102 despawn_checked(~S,~C,~R,~E,allowed,world,undo,commands,events,trace,handle)
103
104
105
106
107
108def tx_despawn(~S: Data,~C: Type,~R: Type,~E: Data,tx: T.Tx<W.World<S,C,R,E>,E>,+handle: W.Handle<S>) -> T.Tx<W.World<S,C,R,E>,E> & W.Status:
109 match tx:
110 case T.Tx{world,undo,commands,events,trace}: despawn_join(~S,~C,~R,~E,W.command_valid(~S,~C,~R,~E,world,handle),undo,commands,events,trace,handle)
111
112
113def clear_join(~S: Data,~C: Type,~R: Type,~E: Data,+handle:W.Handle<S>,cleared: W.World<S,C,R,E> & Unit) -> W.World<S,C,R,E>:
114 (world,unit) = cleared
115 W.release_cleared(~S,~C,~R,~E,world,handle)
116
117def clear_accepted(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C,activated: W.World<S,C,R,E> & W.Status,+handle: W.Handle<S>) -> W.World<S,C,R,E>:
118 match activated:
119 case (world,W.Rejected{_}): world
120 case (world,W.Accepted{}): clear_join(~S,~C,~R,~E,handle,W.with_store(~S,~C,~R,~E,~Unit,(store => (clear(store,handle),Unit{})),world))
121
122
123
124
125def despawn_apply_with(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C,world: W.World<S,C,R,E>,+handle: W.Handle<S>) -> W.World<S,C,R,E>:
126 clear_accepted(~S,~C,~R,~E,~clear,W.deactivate(~S,~C,~R,~E,world,handle),handle)
127
128def despawn_checked_with(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C,allowed: Bool,world: W.World<S,C,R,E>,undo: List<(W.World<S,C,R,E> -> W.World<S,C,R,E>)>,commands:List<Deferred.Command<W.World<S,C,R,E>>>,events: List<&2,E>,trace:TraceFacts.State,handle: W.Handle<S>) -> T.Tx<W.World<S,C,R,E>,E> & W.Status:
129 match allowed:
130 case False{}: (T.Tx{world,undo,commands,events,trace},W.Rejected{W.MissingEntity{}})
131 case True{}: (T.Tx{world,undo,Deferred.Raw{(w => despawn_apply_with(~S,~C,~R,~E,~clear,w,handle))} <> commands,events,trace},W.Accepted{})
132
133def despawn_join_with(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C,checked: W.World<S,C,R,E> & Bool,undo: List<(W.World<S,C,R,E> -> W.World<S,C,R,E>)>,commands:List<Deferred.Command<W.World<S,C,R,E>>>,events: List<&2,E>,trace:TraceFacts.State,handle: W.Handle<S>) -> T.Tx<W.World<S,C,R,E>,E> & W.Status:
134 (world,allowed) = checked
135 despawn_checked_with(~S,~C,~R,~E,~clear,allowed,world,undo,commands,events,trace,handle)
136
137
138
139
140def tx_despawn_with(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C,tx: T.Tx<W.World<S,C,R,E>,E>,+handle: W.Handle<S>) -> T.Tx<W.World<S,C,R,E>,E> & W.Status:
141 match tx:
142 case T.Tx{world,undo,commands,events,trace}: despawn_join_with(~S,~C,~R,~E,~clear,W.command_valid(~S,~C,~R,~E,world,handle),undo,commands,events,trace,handle)
143
144
145def clear_observed_join(~S: Data,~C: Type,~R: Type,~E: Data,~record: W.Handle<S> -> E,+handle: W.Handle<S>,cleared: W.World<S,C,R,E> & List<&2,E>) -> W.World<S,C,R,E>:
146 (world,records) = cleared
147 W.release_cleared(~S,~C,~R,~E,W.event_publish(~S,~C,~R,~E,world,List.append(&2,E,records,[record(handle)])),handle)
148
149def clear_observed_accepted(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C & List<&2,E>,~record: W.Handle<S> -> E,activated: W.World<S,C,R,E> & W.Status,+handle: W.Handle<S>) -> W.World<S,C,R,E>:
150 match activated:
151 case (world,W.Rejected{_}): world
152 case (world,W.Accepted{}): clear_observed_join(~S,~C,~R,~E,~record,handle,W.with_store(~S,~C,~R,~E,~List<&2,E>,(store => clear(store,handle)),world))
153
154def despawn_valid_observed(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C & List<&2,E>,~record: W.Handle<S> -> E,checked: W.World<S,C,R,E> & Bool,+handle: W.Handle<S>) -> W.World<S,C,R,E>:
155 match checked:
156 case (world,False{}): world
157 case (world,True{}): clear_observed_accepted(~S,~C,~R,~E,~clear,~record,W.deactivate(~S,~C,~R,~E,world,handle),handle)
158
159
160
161
162def despawn_apply_observed(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C & List<&2,E>,~record: W.Handle<S> -> E,world: W.World<S,C,R,E>,+handle: W.Handle<S>) -> W.World<S,C,R,E>:
163 despawn_valid_observed(~S,~C,~R,~E,~clear,~record,W.valid(~S,~C,~R,~E,world,handle),handle)
164
165def despawn_checked_observed(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C & List<&2,E>,~record: W.Handle<S> -> E,allowed: Bool,world: W.World<S,C,R,E>,undo: List<(W.World<S,C,R,E> -> W.World<S,C,R,E>)>,commands:List<Deferred.Command<W.World<S,C,R,E>>>,events: List<&2,E>,trace:TraceFacts.State,+handle: W.Handle<S>) -> T.Tx<W.World<S,C,R,E>,E> & W.Status:
166 match allowed:
167 case False{}: (T.Tx{world,undo,commands,events,trace},W.Rejected{W.MissingEntity{}})
168 case True{}: (T.Tx{world,undo,Deferred.Raw{(w => despawn_apply_observed(~S,~C,~R,~E,~clear,~record,w,handle))} <> commands,events,trace},W.Accepted{})
169
170def despawn_join_observed(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C & List<&2,E>,~record: W.Handle<S> -> E,checked: W.World<S,C,R,E> & Bool,undo: List<(W.World<S,C,R,E> -> W.World<S,C,R,E>)>,commands:List<Deferred.Command<W.World<S,C,R,E>>>,events: List<&2,E>,trace:TraceFacts.State,+handle: W.Handle<S>) -> T.Tx<W.World<S,C,R,E>,E> & W.Status:
171 (world,allowed) = checked
172 despawn_checked_observed(~S,~C,~R,~E,~clear,~record,allowed,world,undo,commands,events,trace,handle)
173
174
175
176
177
178def tx_despawn_observed(~S: Data,~C: Type,~R: Type,~E: Data,~clear: C -> W.Handle<S> -> C & List<&2,E>,~record: W.Handle<S> -> E,tx: T.Tx<W.World<S,C,R,E>,E>,+handle: W.Handle<S>) -> T.Tx<W.World<S,C,R,E>,E> & W.Status:
179 match tx:
180 case T.Tx{world,undo,commands,events,trace}: despawn_join_observed(~S,~C,~R,~E,~clear,~record,W.command_valid(~S,~C,~R,~E,world,handle),undo,commands,events,trace,handle)