dependency_registration.bend
bendvy-ecs-core@0.1.0.3 · 58 lines · 16 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/dependency_plan.bend as Plan
3import bendvy-ecs-core@0.1.0.3/dependency_executor.bend as Exec
4import bendvy-ecs-core@0.1.0.3/execution_owner_continuation.bend as Continuation
5
6type Registry<-World:Type,-Owners:Type,-Error:Data,-Out:Data,-dispatch:Owners -> World -> U32 -> Owners & (World & Exec.Invocation<Error,Out>)> is Type:
7 Registry{owners:Owners,nodes:List<&2,Plan.Node<String>>}
8
9type Product<L:Type,R:Type> is Type:
10 Product{left:L,right:R,leftIds:List<&2,U32>}
11def ids(nodes:List<&2,Plan.Node<String>>) -> List<&2,U32>:
12 match nodes:
13 case []:[]
14 case Plan.Node{id,_} <> rest:id <> ids(rest)
15def contains(ids:List<&2,U32>,+id:U32) -> Bool:
16 match ids:
17 case []:False{}
18 case first <> rest:Bool.or(U32.is_eq(first,id),contains(rest,id))
19
20def left_returned(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation<Error,Out>),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation<Error,Out>),pair:(R & List<&2,U32>) & (L & (World & Exec.Invocation<Error,Out>))) -> Product<L,R> & (World & Exec.Invocation<Error,Out>):
21 match pair:
22 case ((right,leftIds),(left,(world,status))):(Product{left,right,leftIds},(world,status))
23def right_returned(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation<Error,Out>),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation<Error,Out>),pair:(L & List<&2,U32>) & (R & (World & Exec.Invocation<Error,Out>))) -> Product<L,R> & (World & Exec.Invocation<Error,Out>):
24 match pair:
25 case ((left,leftIds),(right,(world,status))):(Product{left,right,leftIds},(world,status))
26def paired_selected(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation<Error,Out>),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation<Error,Out>),selected:Bool,left:L,right:R,leftIds:List<&2,U32>,world:World,id:U32) -> Product<L,R> & (World & Exec.Invocation<Error,Out>):
27 match selected:
28 case True{}:
29 continuation:Continuation.PairedHeader<(L & (World & Exec.Invocation<Error,Out>)),(Product<L,R> & (World & Exec.Invocation<Error,Out>))> = Continuation.PairedHeader{R & List<&2,U32>,(right,leftIds),left_returned(~World,~L,~R,~Error,~Out,~leftDispatch,~rightDispatch)}
30 Continuation.paired_returned(L & (World & Exec.Invocation<Error,Out>),Product<L,R> & (World & Exec.Invocation<Error,Out>),continuation,leftDispatch(left,world,id))
31 case False{}:
32 continuation:Continuation.PairedHeader<(R & (World & Exec.Invocation<Error,Out>)),(Product<L,R> & (World & Exec.Invocation<Error,Out>))> = Continuation.PairedHeader{L & List<&2,U32>,(left,leftIds),right_returned(~World,~L,~R,~Error,~Out,~leftDispatch,~rightDispatch)}
33 Continuation.paired_returned(R & (World & Exec.Invocation<Error,Out>),Product<L,R> & (World & Exec.Invocation<Error,Out>),continuation,rightDispatch(right,world,id))
34def paired_dispatch_actual(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation<Error,Out>),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation<Error,Out>),owners:Product<L,R>,world:World,+id:U32) -> Product<L,R> & (World & Exec.Invocation<Error,Out>):
35 match owners:
36 case Product{left,right,+leftIds}:paired_selected(~World,~L,~R,~Error,~Out,~leftDispatch,~rightDispatch,contains(leftIds,id),left,right,leftIds,world,id)
37def paired_dispatch(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation<Error,Out>),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation<Error,Out>),owners:Product<L,R>,world:World,id:U32) -> Product<L,R> & (World & Exec.Invocation<Error,Out>):
38 paired_dispatch_actual(~World,~L,~R,~Error,~Out,~leftDispatch,~rightDispatch,owners,world,id)
39def paired(~World:Type,~L:Type,~R:Type,~Error:Data,~Out:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation<Error,Out>),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation<Error,Out>),left:Registry<World,L,Error,Out,leftDispatch>,right:Registry<World,R,Error,Out,rightDispatch>) -> Registry<World,Product<L,R>,Error,Out,paired_dispatch(~World,~L,~R,~Error,~Out,~leftDispatch,~rightDispatch)>:
40 match left right:
41 case Registry{left,+ln} Registry{right,rn}:Registry{Product{left,right,ids(ln)},List.append(&2,Plan.Node<String>,ln,rn)}
42
43def empty_dispatch(~World:Type,~Error:Data,~Out:Data,owners:Unit,world:World,_:U32) -> Unit & (World & Exec.Invocation<Error,Out>):
44 (owners,(world,Exec.AdmissionRefused{}))
45def empty(~World:Type,~Error:Data,~Out:Data) -> Registry<World,Unit,Error,Out,empty_dispatch(~World,~Error,~Out)>:
46 Registry{Unit{},[]}
47
48type ConditionRegistry<-World:Type,-Owners:Type,-Error:Data,-dispatch:Owners -> World -> U32 -> Owners & (World & Exec.Invocation<Error,Bool>)> is Type:
49 ConditionRegistry{registry:Registry<World,Owners,Error,Bool,dispatch>,invalid:Maybe<&2,Plan.Invalid<String>>}
50def condition_permission(allowed:Bool,id:U32) -> Maybe<&2,Plan.Invalid<String>>:
51 match allowed:
52 case True{}:None{}
53 case False{}:Some{Plan.InvalidCondition{id}}
54def empty_conditions(~World:Type,~Error:Data) -> ConditionRegistry<World,Unit,Error,empty_dispatch(~World,~Error,~Bool)>:
55 ConditionRegistry{empty(~World,~Error,~Bool),None{}}
56def paired_conditions(~World:Type,~L:Type,~R:Type,~Error:Data,~leftDispatch:L -> World -> U32 -> L & (World & Exec.Invocation<Error,Bool>),~rightDispatch:R -> World -> U32 -> R & (World & Exec.Invocation<Error,Bool>),left:ConditionRegistry<World,L,Error,leftDispatch>,right:ConditionRegistry<World,R,Error,rightDispatch>) -> ConditionRegistry<World,Product<L,R>,Error,paired_dispatch(~World,~L,~R,~Error,~Bool,~leftDispatch,~rightDispatch)>:
57 match left right:
58 case ConditionRegistry{left,li} ConditionRegistry{right,ri}:ConditionRegistry{paired(~World,~L,~R,~Error,~Bool,~leftDispatch,~rightDispatch,left,right),Plan.first_error(~String,li,ri)}