relation_failure_runtime.bend
bendvy-ecs-core@0.1.0.1 · 151 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.1/change_tick.bend as Tick
3import internal/relation_failures/domains.bend as D
4import internal/relation_failures/readings.bend as Read
5import internal/relation_failures/routing.bend as Route
6import internal/relation_failures/barrier.bend as B
7import world.bend as W
8import system.bend as Sy
9import event_runtime.bend as Ev
10
11type Runtime<S: Data,C: Type,R: Type,E: Data> is Type:
12 Runtime{world: W.World<S,C,R,E>,domains: List<&2,D.Domain<S,E>>,positions: List<&2,Ev.Position>,tick: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,nextReader: U32}
13type Input<S: Data,E: Data,A: Type> is Type:
14 Input{readings: List<&2,Read.KeyReading<S,E>>,args: A}
15type Reader<S: Data,C: Type,R: Type,E: Data,A: Type,Error: Data,O: Type,-runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>> is Type:
16 Reader{registry: Sy.Registry<S,C,R,E,Input<S,E,A>,Error,O,runner>,keys: List<&2,D.DescriptorKey<S>>,id: U32}
17type Registered<S: Data,C: Type,R: Type,E: Data,A: Type,Error: Data,O: Type,-runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>> is Type:
18 Registered{runtime: Runtime<S,C,R,E>,reader: Reader<S,C,R,E,A,Error,O,runner>}
19 RegistrationFailed{runtime: Runtime<S,C,R,E>}
20type Completion<Error: Data,O: Type,A: Type> is Type:
21 Succeeded{output: O}
22 Failed{error: Error}
23 Rejected{args: A}
24type RunResult<S: Data,C: Type,R: Type,E: Data,A: Type,Error: Data,O: Type,-runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>> is Type:
25 Ran{runtime: Runtime<S,C,R,E>,reader: Reader<S,C,R,E,A,Error,O,runner>,completion: Completion<Error,O,A>}
26
27def started_clocked(~S: Data,~C: Type,~R: Type,~E: Data,clocked: W.World<S,C,R,E> & Tick.Tick) -> Runtime<S,C,R,E>:
28 (world,clock) = clocked
29 Runtime{world,[],[],Tick.total(clock),0n,0n,65536n,1}
30def start(~S: Data,~C: Type,~R: Type,~E: Data,world: W.World<S,C,R,E>) -> Runtime<S,C,R,E>:
31 started_clocked(~S,~C,~R,~E,W.clock(~S,~C,~R,~E,world))
32
33def frame(~S: Data,~C: Type,~R: Type,~E: Data,runtime: Runtime<S,C,R,E>) -> Runtime<S,C,R,E>:
34 match runtime:
35 case Runtime{world,domains,+positions,+tick,+frameStart,_,+capacity,+nextReader}: Runtime{world,D.trim(~S,~E,domains,positions,frameStart,capacity),positions,tick,tick,frameStart,capacity,nextReader}
36
37def registered_result(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,result: Sy.RegistrationResult<S,C,R,E,Input<S,E,A>,Error,O,runner>,+keys: List<&2,D.DescriptorKey<S>>,domains: List<&2,D.Domain<S,E>>,positions: List<&2,Ev.Position>,tick: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32) -> Registered<S,C,R,E,A,Error,O,runner>:
38 match result:
39 case Sy.RegistrationFailed{world}: RegistrationFailed{Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader}}
40 case Sy.Registered{world,registry}: Registered{Runtime{world,domains,positions,tick,frameStart,boundary,capacity,(nextReader+1 : U32)},Reader{registry,keys,nextReader}}
41
42def register_available(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,runtime: Runtime<S,C,R,E>,+keys: List<&2,D.DescriptorKey<S>>,+name: String,+access: List<&2,String>) -> Registered<S,C,R,E,A,Error,O,runner>:
43 match runtime:
44 case Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader}: registered_result(~S,~C,~R,~E,~A,~Error,~O,~runner,Sy.register(~S,~C,~R,~E,~Input<S,E,A>,~Error,~O,~runner,world,name,access),keys,domains,positions,tick,frameStart,boundary,capacity,nextReader)
45
46
47# Shared by standalone readers and composed parameters; no system registration.
48def reserve_reader_checked(~S:Data,~C:Type,~R:Type,~E:Data,available:Bool,runtime:Runtime<S,C,R,E>) -> Runtime<S,C,R,E> & Maybe<&2,U32>:
49 match available runtime:
50 case False{} runtime:(runtime,None{})
51 case True{} Runtime{world,domains,positions,tick,frameStart,boundary,capacity,+nextReader}:
52 (Runtime{world,domains,positions,tick,frameStart,boundary,capacity,(nextReader+1 : U32)},Some{nextReader})
53def reserve_reader(~S:Data,~C:Type,~R:Type,~E:Data,runtime:Runtime<S,C,R,E>) -> Runtime<S,C,R,E> & Maybe<&2,U32>:
54 match runtime:
55 case Runtime{world,domains,positions,tick,frameStart,boundary,capacity,+nextReader}:
56 reserve_reader_checked(~S,~C,~R,~E,U32.is_lt(nextReader,4294967295),Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader})
57def register_checked(~S:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~O:Type,~runner:W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,available:Bool,runtime:Runtime<S,C,R,E>,keys:List<&2,D.DescriptorKey<S>>,name:String,access:List<&2,String>) -> Registered<S,C,R,E,A,Error,O,runner>:
58 match available:
59 case False{}:RegistrationFailed{runtime}
60 case True{}:register_available(~S,~C,~R,~E,~A,~Error,~O,~runner,runtime,keys,name,access)
61def register(~S:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~O:Type,~runner:W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,runtime:Runtime<S,C,R,E>,keys:List<&2,D.DescriptorKey<S>>,name:String,access:List<&2,String>) -> Registered<S,C,R,E,A,Error,O,runner>:
62 match runtime:
63 case Runtime{world,domains,positions,tick,frameStart,boundary,capacity,+nextReader}:
64 register_checked(~S,~C,~R,~E,~A,~Error,~O,~runner,U32.is_lt(nextReader,4294967295),Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader},keys,name,access)
65
66def position_or(position: Maybe<Ev.Position>,id: U32,tick: Nat) -> Ev.Position:
67 match position:
68 case None{}: Ev.Position{id,0n,tick}
69 case Some{found}: found
70
71def succeeded_collected(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,id:U32,joined: W.World<S,C,R,E> & List<&2,D.Domain<S,E>>,registry: Sy.Registry<S,C,R,E,Input<S,E,A>,Error,O,runner>,+keys: List<&2,D.DescriptorKey<S>>,positions: List<&2,Ev.Position>,tick: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32,output: O) -> RunResult<S,C,R,E,A,Error,O,runner>:
72 (world,domains) = joined
73 Ran{Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader},Reader{registry,keys,id},Succeeded{output}}
74
75def failed_clocked(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,~classify: E -> Maybe<D.DescriptorKey<S>>,clocked: W.World<S,C,R,E> & Tick.Tick,registry: Sy.Registry<S,C,R,E,Input<S,E,A>,Error,O,runner>,+keys: List<&2,D.DescriptorKey<S>>,+domains: List<&2,D.Domain<S,E>>,+positions: List<&2,Ev.Position>,+id: U32,+previous: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32,error: Error) -> RunResult<S,C,R,E,A,Error,O,runner>:
76 (world,clock) = clocked
77 Ran{Runtime{world,Read.activate(~S,~E,keys,domains,id),Ev.activate(positions,id,previous),Tick.total(clock),frameStart,boundary,capacity,nextReader},Reader{registry,keys,id},Failed{error}}
78def succeeded_clocked(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,~classify: E -> Maybe<D.DescriptorKey<S>>,clocked: W.World<S,C,R,E> & Tick.Tick,registry: Sy.Registry<S,C,R,E,Input<S,E,A>,Error,O,runner>,+keys: List<&2,D.DescriptorKey<S>>,+domains: List<&2,D.Domain<S,E>>,+positions: List<&2,Ev.Position>,+id: U32,+previous: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32,output: O) -> RunResult<S,C,R,E,A,Error,O,runner>:
79 (world,+clock) = clocked
80 succeeded_collected(~S,~C,~R,~E,~A,~Error,~O,~runner,id,Route.collect(~S,~C,~R,~E,~classify,world,Tick.total(clock),Read.activate(~S,~E,keys,domains,id)),registry,keys,Ev.update(Ev.activate(positions,id,previous),id,Tick.total(clock),False{}),Tick.total(clock),frameStart,boundary,capacity,nextReader,output)
81
82def outcome(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,~classify: E -> Maybe<D.DescriptorKey<S>>,outcome: Sy.Outcome<W.World<S,C,R,E>,Error,O>,registry: Sy.Registry<S,C,R,E,Input<S,E,A>,Error,O,runner>,+keys: List<&2,D.DescriptorKey<S>>,+domains: List<&2,D.Domain<S,E>>,+positions: List<&2,Ev.Position>,+id: U32,+tick: Nat,+frameStart: Nat,+boundary: Nat,+capacity: Nat,+nextReader: U32) -> RunResult<S,C,R,E,A,Error,O,runner>:
83 match outcome:
84 case Sy.Failed{world,error}: failed_clocked(~S,~C,~R,~E,~A,~Error,~O,~runner,~classify,W.clock(~S,~C,~R,~E,world),registry,keys,domains,positions,id,tick,frameStart,boundary,capacity,nextReader,error)
85 case Sy.Succeeded{world,output}: succeeded_clocked(~S,~C,~R,~E,~A,~Error,~O,~runner,~classify,W.clock(~S,~C,~R,~E,world),registry,keys,domains,positions,id,tick,frameStart,boundary,capacity,nextReader,output)
86
87def run_result(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,~classify: E -> Maybe<D.DescriptorKey<S>>,result: Sy.RunResult<S,C,R,E,Input<S,E,A>,Error,O,runner>,+keys: List<&2,D.DescriptorKey<S>>,domains: List<&2,D.Domain<S,E>>,positions: List<&2,Ev.Position>,id: U32,tick: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32) -> RunResult<S,C,R,E,A,Error,O,runner>:
88 match result:
89 case Sy.RegistrationRejected{registry,world,Input{_,args}}: Ran{Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader},Reader{registry,keys,id},Rejected{args}}
90 case Sy.Completed{registry,completed}: outcome(~S,~C,~R,~E,~A,~Error,~O,~runner,~classify,completed,registry,keys,domains,positions,id,tick,frameStart,boundary,capacity,nextReader)
91
92def effect_clocked(~S: Data,~C: Type,~R: Type,~E: Data,~O: Type,effect: W.World<S,C,R,E> -> W.World<S,C,R,E> & O,advanced: W.World<S,C,R,E> & Tick.Tick) -> W.World<S,C,R,E> & O:
93 (world,_) = advanced
94 effect(world)
95
96
97def run_identified(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,~classify: E -> Maybe<D.DescriptorKey<S>>,runtime: Runtime<S,C,R,E>,identified: Sy.Registry<S,C,R,E,Input<S,E,A>,Error,O,runner> & U32,+keys: List<&2,D.DescriptorKey<S>>,args: A) -> RunResult<S,C,R,E,A,Error,O,runner>:
98 match runtime:
99 case Runtime{world,+domains,+positions,+tick,+frameStart,+boundary,+capacity,+nextReader}:
100 (registry,+id) = identified
101 run_result(~S,~C,~R,~E,~A,~Error,~O,~runner,~classify,Sy.run(~S,~C,~R,~E,~Input<S,E,A>,~Error,~O,~runner,registry,world,Input{Read.all(~S,~E,keys,domains,position_or(Ev.lookup(positions,id),id,tick)),args}),keys,domains,positions,id,tick,frameStart,boundary,capacity,nextReader)
102
103def run(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,~classify: E -> Maybe<D.DescriptorKey<S>>,runtime: Runtime<S,C,R,E>,reader: Reader<S,C,R,E,A,Error,O,runner>,args: A) -> RunResult<S,C,R,E,A,Error,O,runner>:
104 match reader:
105 case Reader{registry,keys,id}: run_identified(~S,~C,~R,~E,~A,~Error,~O,~runner,~classify,runtime,(registry,id),keys,args)
106def skipped_checked(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,allowed: Bool,runtime: Runtime<S,C,R,E>,reader: Reader<S,C,R,E,A,Error,O,runner>,+id: U32) -> Runtime<S,C,R,E> & Reader<S,C,R,E,A,Error,O,runner>:
107 match allowed runtime:
108 case False{} runtime: (runtime,reader)
109 case True{} Runtime{world,domains,positions,+tick,frameStart,boundary,capacity,nextReader}: (Runtime{world,domains,Ev.update(positions,id,tick,False{}),tick,frameStart,boundary,capacity,nextReader},reader)
110
111def skip_meta(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,checked: W.World<S,C,R,E> & Bool,registry: Sy.Registry<S,C,R,E,Input<S,E,A>,Error,O,runner>,keys: List<&2,D.DescriptorKey<S>>,domains: List<&2,D.Domain<S,E>>,positions: List<&2,Ev.Position>,tick: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32,+id: U32) -> Runtime<S,C,R,E> & Reader<S,C,R,E,A,Error,O,runner>:
112 (world,allowed) = checked
113 skipped_checked(~S,~C,~R,~E,~A,~Error,~O,~runner,allowed,Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader},Reader{registry,keys,id},id)
114
115def skip_namespace(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,same: Bool,world: W.World<S,C,R,E>,registry: Sy.Registry<S,C,R,E,Input<S,E,A>,Error,O,runner>,keys: List<&2,D.DescriptorKey<S>>,readerId:U32,domains: List<&2,D.Domain<S,E>>,positions: List<&2,Ev.Position>,tick: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32) -> Runtime<S,C,R,E> & Reader<S,C,R,E,A,Error,O,runner>:
116 match same registry:
117 case False{} registry: (Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader},Reader{registry,keys,readerId})
118 case True{} Sy.Registry{+namespace,+id,+name,+access,+cursor}: skip_meta(~S,~C,~R,~E,~A,~Error,~O,~runner,W.registration_matches(~S,~C,~R,~E,world,id,name,access),Sy.Registry{namespace,id,name,access,cursor},keys,domains,positions,tick,frameStart,boundary,capacity,nextReader,readerId)
119
120def skip_named(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,reader: Reader<S,C,R,E,A,Error,O,runner>,named: W.World<S,C,R,E> & U32,domains: List<&2,D.Domain<S,E>>,positions: List<&2,Ev.Position>,tick: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32) -> Runtime<S,C,R,E> & Reader<S,C,R,E,A,Error,O,runner>:
121 match reader:
122 case Reader{Sy.Registry{+namespace,+id,+name,+access,+cursor},keys,readerId}:
123 (world,actual) = named
124 skip_namespace(~S,~C,~R,~E,~A,~Error,~O,~runner,U32.is_eq(namespace,actual),world,Sy.Registry{namespace,id,name,access,cursor},keys,readerId,domains,positions,tick,frameStart,boundary,capacity,nextReader)
125
126def skip(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World<S,C,R,E> -> Input<S,E,A> -> Sy.Outcome<W.World<S,C,R,E>,Error,O>,runtime: Runtime<S,C,R,E>,reader: Reader<S,C,R,E,A,Error,O,runner>) -> Runtime<S,C,R,E> & Reader<S,C,R,E,A,Error,O,runner>:
127 match runtime:
128 case Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader}: skip_named(~S,~C,~R,~E,~A,~Error,~O,~runner,reader,W.namespace(~S,~C,~R,~E,world),domains,positions,tick,frameStart,boundary,capacity,nextReader)
129
130def barrier_join(~S: Data,~C: Type,~R: Type,~E: Data,state: B.BarrierState<S,C,R,E>,positions: List<&2,Ev.Position>,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32) -> Runtime<S,C,R,E>:
131 match state:
132 case B.BarrierState{world,domains,tick}: Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader}
133
134def barrier(~S: Data,~C: Type,~R: Type,~E: Data,~classify: E -> Maybe<D.DescriptorKey<S>>,runtime: Runtime<S,C,R,E>) -> Runtime<S,C,R,E>:
135 match runtime:
136 case Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader}: barrier_join(~S,~C,~R,~E,B.barrier(~S,~C,~R,~E,~classify,world,domains),positions,frameStart,boundary,capacity,nextReader)
137
138def with_world_collected(~S: Data,~C: Type,~R: Type,~E: Data,~O: Type,collected: W.World<S,C,R,E> & List<&2,D.Domain<S,E>>,output: O,positions: List<&2,Ev.Position>,tick: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32) -> Runtime<S,C,R,E> & O:
139 (world,domains) = collected
140 (Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader},output)
141
142def with_world_clocked(~S: Data,~C: Type,~R: Type,~E: Data,~O: Type,~classify: E -> Maybe<D.DescriptorKey<S>>,clocked: W.World<S,C,R,E> & Tick.Tick,output: O,domains: List<&2,D.Domain<S,E>>,positions: List<&2,Ev.Position>,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32) -> Runtime<S,C,R,E> & O:
143 (world,+clock) = clocked
144 with_world_collected(~S,~C,~R,~E,~O,Route.collect(~S,~C,~R,~E,~classify,world,Tick.total(clock),domains),output,positions,Tick.total(clock),frameStart,boundary,capacity,nextReader)
145def with_world_result(~S: Data,~C: Type,~R: Type,~E: Data,~O: Type,~classify: E -> Maybe<D.DescriptorKey<S>>,result: W.World<S,C,R,E> & O,domains: List<&2,D.Domain<S,E>>,positions: List<&2,Ev.Position>,_: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32) -> Runtime<S,C,R,E> & O:
146 (world,output) = result
147 with_world_clocked(~S,~C,~R,~E,~O,~classify,W.clock(~S,~C,~R,~E,world),output,domains,positions,frameStart,boundary,capacity,nextReader)
148
149def with_world(~S: Data,~C: Type,~R: Type,~E: Data,~O: Type,~classify: E -> Maybe<D.DescriptorKey<S>>,effect: W.World<S,C,R,E> -> W.World<S,C,R,E> & O,runtime: Runtime<S,C,R,E>) -> Runtime<S,C,R,E> & O:
150 match runtime:
151 case Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader}: with_world_result(~S,~C,~R,~E,~O,~classify,effect_clocked(~S,~C,~R,~E,~O,effect,W.write_clock(~S,~C,~R,~E,world)),domains,positions,tick,frameStart,boundary,capacity,nextReader)