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)