local.bend
bendvy-ecs-core@0.1.0.4 · 136 lines · 27 definitions
1import Base
2import bendvy-ecs-core@0.1.0.4/change_tick.bend as Tick
3import bendvy-ecs-core@0.1.0.4/world.bend as W
4import bendvy-ecs-core@0.1.0.4/registration.bend as Reg
5
6
7
8
9
10type Outcome<World: Type,L: Type,Error: Data,Out: Type> is Type:
11 Succeeded{world: World,local: L,output: Out}
12 Failed{world: World,local: L,error: Error}
13
14
15
16type Instance<S: Data,C: Type,R: Type,E: Data,L: Type,Args: Type,Error: Data,Out: Type,-runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>> is Type:
17 Instance{namespace: U32,id: U32,name: String,access: List<&2,String>,local: L}
18
19
20type Registered<S: Data,C: Type,R: Type,E: Data,L: Type,Args: Type,Error: Data,Out: Type,-runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>> is Type:
21 Registered{world: W.World<S,C,R,E>,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>}
22 RegistrationRejected{world: W.World<S,C,R,E>,local: L}
23
24
25
26type Run<S: Data,C: Type,R: Type,E: Data,L: Type,Args: Type,Error: Data,Out: Type,-runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>> is Type:
27 Completed{world: W.World<S,C,R,E>,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>,result: Result<&2,&1,Error,Out>,tick:Tick.Tick}
28 Refused{world: W.World<S,C,R,E>,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>,args: Args}
29
30
31
32type Disposal<S: Data,C: Type,R: Type,E: Data,L: Type,Args: Type,Error: Data,Out: Type,-runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,Disposed: Type> is Type:
33 Disposed{world: W.World<S,C,R,E>,output: Disposed}
34 DisposalRejected{world: W.World<S,C,R,E>,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>}
35
36
37
38
39type Cell<L: Type> is Type:
40 Cell{local: L}
41
42
43
44type Ops<H: Type,L: Type,V: Data> is Type:
45 Ops{read: H -> H & V,replace: H -> L -> H}
46def projected(~L: Type,~V: Data,result: L & V) -> Cell<L> & V:
47 (local,value) = result
48 (Cell{local},value)
49def read_cell(~L: Type,~V: Data,~project: L -> L & V,cell: Cell<L>) -> Cell<L> & V:
50 match cell:
51 case Cell{local}: projected(~L,~V,project(local))
52
53def replace_cell(~L: Type,cell: Cell<L>,local: L) -> Cell<L>:
54 match cell:
55 case Cell{old}: Cell{local}
56def modify_cell(~L: Type,cell: Cell<L>,modify: L -> L) -> Cell<L>:
57 match cell:
58 case Cell{local}: Cell{modify(local)}
59def unwrapped(~L: Type,~Out: Type,result: Cell<L> & Out) -> L & Out:
60 match result:
61 case (Cell{local},out): (local,out)
62
63
64
65
66def provide(~L: Type,~V: Data,~Out: Type,~project: L -> L & V,~consume: @-H: Type -> Ops<H,L,V> -> H -> H & Out,local: L) -> L & Out:
67 unwrapped(~L,~Out,consume(Cell<L>,Ops{read_cell(~L,~V,~project),replace_cell(~L)},Cell{local}))
68
69
70
71
72def provide_with(~L: Type,~V: Data,~Args: Type,~Out: Type,~project: L -> L & V,~consume: @-H: Type -> Ops<H,L,V> -> H -> Args -> H & Out,local: L,args: Args) -> L & Out:
73 unwrapped(~L,~Out,consume(Cell<L>,Ops{read_cell(~L,~V,~project),replace_cell(~L)},Cell{local},args))
74
75def register_result(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,registered: W.World<S,C,R,E> & W.Registration,+namespace: U32,+name: String,+access: List<&2,String>,local: L) -> Registered<S,C,R,E,L,Args,Error,Out,runner>:
76 match registered:
77 case (world,W.Registered{id}): Registered{world,Instance{namespace,id,name,access,local}}
78 case (world,W.RegistrationRejected{_}): RegistrationRejected{world,local}
79def register_named(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,named: W.World<S,C,R,E> & U32,+name: String,+access: List<&2,String>,local: L) -> Registered<S,C,R,E,L,Args,Error,Out,runner>:
80 (world,+namespace) = named
81 register_result(~S,~C,~R,~E,~L,~Args,~Error,~Out,~runner,W.register(~S,~C,~R,~E,world,name,access),namespace,name,access,local)
82
83
84
85def register(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,world: W.World<S,C,R,E>,name: String,access: List<&2,String>,local: L) -> Registered<S,C,R,E,L,Args,Error,Out,runner>:
86 register_named(~S,~C,~R,~E,~L,~Args,~Error,~Out,~runner,W.namespace(~S,~C,~R,~E,world),name,access,local)
87
88def completed(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,namespace: U32,id: U32,name: String,access: List<&2,String>,tick:Tick.Tick,outcome: Outcome<W.World<S,C,R,E>,L,Error,Out>) -> Run<S,C,R,E,L,Args,Error,Out,runner>:
89 match outcome:
90 case Succeeded{world,local,out}: Completed{W.leave_run(~S,~C,~R,~E,world),Instance{namespace,id,name,access,local},Done{out},tick}
91 case Failed{world,local,error}: Completed{W.leave_run(~S,~C,~R,~E,world),Instance{namespace,id,name,access,local},Fail{error},tick}
92def entered(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,namespace: U32,id: U32,name: String,access: List<&2,String>,local:L,args:Args,observed:W.World<S,C,R,E> & Tick.Tick) -> Run<S,C,R,E,L,Args,Error,Out,runner>:
93 match observed:
94 case (world,tick):completed(~S,~C,~R,~E,~L,~Args,~Error,~Out,~runner,namespace,id,name,access,tick,runner(world,local,args))
95def checked(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,allowed: Bool,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>,world: W.World<S,C,R,E>,args: Args) -> Run<S,C,R,E,L,Args,Error,Out,runner>:
96 match allowed instance:
97 case False{} instance: Refused{world,instance,args}
98 case True{} Instance{namespace,id,name,access,local}: entered(~S,~C,~R,~E,~L,~Args,~Error,~Out,~runner,namespace,id,name,access,local,args,W.enter_run(~S,~C,~R,~E,world))
99
100
101
102
103def run(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>,world: W.World<S,C,R,E>,args: Args) -> Run<S,C,R,E,L,Args,Error,Out,runner>:
104 match instance world:
105 case Instance{+namespace,+id,+name,+access,local} W.World{+actual,allocator,store,resource,events,pending,+registrations,nextSystemId,clock}:
106 checked(~S,~C,~R,~E,~L,~Args,~Error,~Out,~runner,Bool.and(U32.is_eq(namespace,actual),W.registration_list_matches(registrations,id,name,access)),Instance{namespace,id,name,access,local},W.World{actual,allocator,store,resource,events,pending,registrations,nextSystemId,clock},args)
107
108def skip(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>) -> Instance<S,C,R,E,L,Args,Error,Out,runner>:
109 instance
110
111
112
113def identity(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>) -> Instance<S,C,R,E,L,Args,Error,Out,runner> & U32:
114 match instance:
115 case Instance{namespace,+id,name,access,local}: (Instance{namespace,id,name,access,local},id)
116def observed(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,~V: Data,namespace: U32,id: U32,name: String,access: List<&2,String>,value: L & V) -> Instance<S,C,R,E,L,Args,Error,Out,runner> & V:
117 (local,value) = value
118 (Instance{namespace,id,name,access,local},value)
119
120
121
122def observe(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,~V: Data,~project: L -> L & V,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>) -> Instance<S,C,R,E,L,Args,Error,Out,runner> & V:
123 match instance:
124 case Instance{namespace,id,name,access,local}: observed(~S,~C,~R,~E,~L,~Args,~Error,~Out,~runner,~V,namespace,id,name,access,project(local))
125
126def disposal(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,~Disposed: Type,~disposeLocal: L -> Disposed,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>,result: W.World<S,C,R,E> & Bool) -> Disposal<S,C,R,E,L,Args,Error,Out,runner,Disposed>:
127 match instance result:
128 case instance, (world,False{}): DisposalRejected{world,instance}
129 case Instance{_,_,_,_,local}, (world,True{}): Disposed{world,disposeLocal(local)}
130
131
132
133
134def dispose(~S: Data,~C: Type,~R: Type,~E: Data,~L: Type,~Args: Type,~Error: Data,~Out: Type,~runner: W.World<S,C,R,E> -> L -> Args -> Outcome<W.World<S,C,R,E>,L,Error,Out>,~Disposed: Type,~disposeLocal: L -> Disposed,instance: Instance<S,C,R,E,L,Args,Error,Out,runner>,world: W.World<S,C,R,E>) -> Disposal<S,C,R,E,L,Args,Error,Out,runner,Disposed>:
135 match instance:
136 case Instance{+namespace,+id,+name,+access,local}: disposal(~S,~C,~R,~E,~L,~Args,~Error,~Out,~runner,~Disposed,~disposeLocal,Instance{namespace,id,name,access,local},Reg.remove(~S,~C,~R,~E,world,namespace,id,name,access))