ordinary_checked_bindings.bend
bendvy-ecs-core@0.1.0.0 · 67 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.0/ordinary_checked_condition.bend as Cond
3import bendvy-ecs-core@0.1.0.0/check.bend as K
4import bendvy-ecs-core@0.1.0.0/schedule.bend as Sch
5
6type Description is Data:Description{systemId:U32,condition:Cond.Description}
7type Selection<World:Type,Owner:Type> is Type:
8 Selected{world:World,owner:Owner,result:Result<&2,&2,Cond.Error,Bool>}
9 Unbound{world:World,owner:Owner}
10type BoundOwner<Owner:Type> is Type:BoundOwner{systemId:U32,owner:Owner}
11type Bindings<World:Type,Owner:Type,-select:Owner -> World -> U32 -> Selection<World,Owner>> is Type:
12 Bindings{owner:Owner,descriptions:List<&2,Description>}
13def selected_returned(~World:Type,~Owner:Type,id:U32,value:Cond.Evaluation<World,Owner>) -> Selection<World,BoundOwner<Owner>>:
14 match value:
15 case Cond.Evaluation{world,owner,Fail{Cond.NoBinding{}}}:Unbound{world,BoundOwner{id,owner}}
16 case Cond.Evaluation{world,owner,result}:Selected{world,BoundOwner{id,owner},result}
17def selected(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Cond.Evaluation<World,Owner>,allowed:Bool,id:U32,owner:Owner,world:World) -> Selection<World,BoundOwner<Owner>>:
18 match allowed:
19 case False{}:Unbound{world,BoundOwner{id,owner}}
20 case True{}:selected_returned(~World,~Owner,id,evaluate(owner,world))
21def select(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Cond.Evaluation<World,Owner>,value:BoundOwner<Owner>,world:World,target:U32) -> Selection<World,BoundOwner<Owner>>:
22 match value:
23 case BoundOwner{+id,owner}:selected(~World,~Owner,~evaluate,U32.is_eq(id,target),id,owner,world)
24def bind(~World:Type,~Owner:Type,~evaluate:Owner -> World -> Cond.Evaluation<World,Owner>,+id:U32,value:Cond.Condition<World,Owner,evaluate>) -> Bindings<World,BoundOwner<Owner>,select(~World,~Owner,~evaluate)>:
25 match value:
26 case Cond.Condition{owner,description}:Bindings{BoundOwner{id,owner},[Description{id,description}]}
27def includes(values:List<&2,Description>,+id:U32) -> Bool:
28 match values:
29 case []:False{}
30 case Description{other,_} <> rest:Bool.or(U32.is_eq(id,other),includes(rest,id))
31def with_right(~World:Type,~Left:Type,~Right:Type,right:Right,value:Selection<World,Left>) -> Selection<World,Left & Right>:
32 match value:
33 case Selected{world,left,result}:Selected{world,(left,right),result}
34 case Unbound{world,left}:Unbound{world,(left,right)}
35def with_left(~World:Type,~Left:Type,~Right:Type,left:Left,value:Selection<World,Right>) -> Selection<World,Left & Right>:
36 match value:
37 case Selected{world,right,result}:Selected{world,(left,right),result}
38 case Unbound{world,right}:Unbound{world,(left,right)}
39def pair_left_returned(~World:Type,~Left:Type,~Right:Type,~right_select:Right -> World -> U32 -> Selection<World,Right>,right:Right,id:U32,value:Selection<World,Left>) -> Selection<World,Left & Right>:
40 match value:
41 case Selected{world,left,result}:Selected{world,(left,right),result}
42 case Unbound{world,left}:with_left(~World,~Left,~Right,left,right_select(right,world,id))
43def pair_shared(~World:Type,~Left:Type,~Right:Type,~left_select:Left -> World -> U32 -> Selection<World,Left>,~right_select:Right -> World -> U32 -> Selection<World,Right>,owners:Left & Right,world:World,+id:U32) -> Selection<World,Left & Right>:
44 match owners:
45 case (left,right):pair_left_returned(~World,~Left,~Right,~right_select,right,id,left_select(left,world,id))
46def pair_select(~World:Type,~Left:Type,~Right:Type,~left_select:Left -> World -> U32 -> Selection<World,Left>,~right_select:Right -> World -> U32 -> Selection<World,Right>,owners:Left & Right,world:World,id:U32) -> Selection<World,Left & Right>:
47 pair_shared(~World,~Left,~Right,~left_select,~right_select,owners,world,id)
48def pair(~World:Type,~Left:Type,~Right:Type,~left_select:Left -> World -> U32 -> Selection<World,Left>,~right_select:Right -> World -> U32 -> Selection<World,Right>,left:Bindings<World,Left,left_select>,right:Bindings<World,Right,right_select>) -> Bindings<World,Left & Right,pair_select(~World,~Left,~Right,~left_select,~right_select)>:
49 match left right:
50 case Bindings{left,ld} Bindings{right,rd}:Bindings{(left,right),List.append(&2,Description,ld,rd)}
51def contains(ids:List<&2,U32>,+id:U32) -> Bool:
52 match ids:
53 case []:False{}
54 case head <> rest:Bool.or(U32.is_eq(id,head),contains(rest,id))
55def unique(values:List<&2,Description>,+seen:List<&2,U32>) -> Bool:
56 match values:
57 case []:True{}
58 case Description{+id,_} <> rest:Bool.and(Bool.not(contains(seen,id)),unique(rest,id <> seen))
59def has_system(steps:List<&2,Sch.Step>,+id:U32) -> Bool:
60 match steps:
61 case []:False{}
62 case Sch.System{other,_} <> rest:Bool.or(U32.is_eq(other,id),has_system(rest,id))
63 case _ <> rest:has_system(rest,id)
64def targets(values:List<&2,Description>,+steps:List<&2,Sch.Step>) -> Bool:
65 match values:
66 case []:True{}
67 case Description{id,_} <> rest:Bool.and(has_system(steps,id),targets(rest,steps))