execution_lifetime_scope_store.bend
bendvy-ecs-core@0.1.0.3 · 83 lines · 21 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/lifetime_scope.bend as Scope
3import bendvy-ecs-core@0.1.0.3/world.bend as W
4import bendvy-ecs-core@0.1.0.3/entity_allocator.bend as Allocator
5import bendvy-ecs-core@0.1.0.3/entity_key.bend as Key
6
7
8
9
10type Store<-S:Data> is Type:
11 Store{namespace:U32,members:List<&2,Scope.Member>}
12type View<-S:Data> is Data:
13 View{namespace:U32,members:List<&2,Scope.Member>}
14type Refusal is Data:
15 NamespaceMismatch{}
16 MissingEntity{}
17type Assignment<-S:Data> is Data:
18 Assigned{scope:Scope.Scope<S>,handle:W.Handle<S>}
19 AssignmentRefused{scope:Scope.Scope<S>,handle:W.Handle<S>,reason:Refusal}
20def fresh(~S:Data,namespace:U32) -> Store<S>:
21 Store{namespace,[]}
22def project(~S:Data,store:Store<S>) -> Store<S> & View<S>:
23 match store:
24 case Store{+namespace,+members}:(Store{namespace,members},View{namespace,members})
25def assigned(~S:Data,scope:Scope.Scope<S>,handle:W.Handle<S>,namespace:U32,members:List<&2,Scope.Member>,result:Allocator.Allocator & Bool) -> Allocator.Allocator & (Store<S> & Assignment<S>):
26 match scope handle result:
27 case scope handle, (allocator,False{}):(allocator,(Store{namespace,members},AssignmentRefused{scope,handle,MissingEntity{}}))
28 case Scope.Scope{+scopeNamespace,+name} W.Handle{+handleNamespace,+key}, (allocator,True{}):(allocator,(Store{namespace,List.append(&2,Scope.Member,Scope.without(members,key),[Scope.Member{name,key}])},Assigned{Scope.Scope{scopeNamespace,name},W.Handle{handleNamespace,key}}))
29def assign_checked(~S:Data,allowed:Bool,allocator:Allocator.Allocator,store:Store<S>,scope:Scope.Scope<S>,handle:W.Handle<S>) -> Allocator.Allocator & (Store<S> & Assignment<S>):
30 match allowed store handle:
31 case False{} store handle:(allocator,(store,AssignmentRefused{scope,handle,NamespaceMismatch{}}))
32 case True{} Store{namespace,members} W.Handle{+handleNamespace,+key}:assigned(~S,scope,W.Handle{handleNamespace,key},namespace,members,Allocator.checked(allocator,key,1))
33def assign(~S:Data,+actual:U32,allocator:Allocator.Allocator,store:Store<S>,scope:Scope.Scope<S>,handle:W.Handle<S>) -> Allocator.Allocator & (Store<S> & Assignment<S>):
34 match store scope handle:
35 case Store{+namespace,members} Scope.Scope{+scopeNamespace,+name} W.Handle{+handleNamespace,+key}:assign_checked(~S,Bool.and(U32.is_eq(actual,namespace),Bool.and(U32.is_eq(actual,scopeNamespace),U32.is_eq(actual,handleNamespace))),allocator,Store{namespace,members},Scope.Scope{scopeNamespace,name},W.Handle{handleNamespace,key})
36type Snapshot<-S:Data> is Data:
37 Selected{scope:Scope.Scope<S>,members:List<&2,Key.Key>}
38 SnapshotRefused{scope:Scope.Scope<S>}
39def snapshot_checked(~S:Data,allowed:Bool,store:Store<S>,scope:Scope.Scope<S>) -> Store<S> & Snapshot<S>:
40 match allowed store scope:
41 case False{} store scope:(store,SnapshotRefused{scope})
42 case True{} Store{namespace,+members} Scope.Scope{+scopeNamespace,+name}:(Store{namespace,members},Selected{Scope.Scope{scopeNamespace,name},Scope.select(members,name)})
43def snapshot(~S:Data,+actual:U32,store:Store<S>,scope:Scope.Scope<S>) -> Store<S> & Snapshot<S>:
44 match store scope:
45 case Store{+namespace,members} Scope.Scope{+scopeNamespace,+name}:snapshot_checked(~S,Bool.and(U32.is_eq(actual,namespace),U32.is_eq(actual,scopeNamespace)),Store{namespace,members},Scope.Scope{scopeNamespace,name})
46
47def removed(~S:Data,store:Store<S>,key:Key.Key) -> Store<S>:
48 match store:
49 case Store{namespace,members}:Store{namespace,Scope.without(members,key)}
50
51type Request<-S:Data> is Data:
52 Assign{scope:Scope.Scope<S>,handle:W.Handle<S>}
53 Select{scope:Scope.Scope<S>}
54 Forget{handle:W.Handle<S>}
55 Inspect{}
56type Outcome<-S:Data> is Data:
57 Assignment{result:Assignment<S>}
58 Selection{result:Snapshot<S>}
59 Forgotten{handle:W.Handle<S>}
60 Inspected{namespace:U32}
61 Refused{request:Request<S>}
62def assignment_returned(~S:Data,result:Allocator.Allocator & (Store<S> & Assignment<S>)) -> Allocator.Allocator & (Store<S> & Outcome<S>):
63 match result:
64 case (allocator,(store,result)):(allocator,(store,Assignment{result}))
65def selection_returned(~S:Data,allocator:Allocator.Allocator,result:Store<S> & Snapshot<S>) -> Allocator.Allocator & (Store<S> & Outcome<S>):
66 match result:
67 case (store,result):(allocator,(store,Selection{result}))
68def forgotten(~S:Data,allowed:Bool,allocator:Allocator.Allocator,store:Store<S>,+handle:W.Handle<S>) -> Allocator.Allocator & (Store<S> & Outcome<S>):
69 match allowed:
70 case False{}:(allocator,(store,Refused{Forget{handle}}))
71 case True{}:(allocator,(removed(~S,store,W.handle_key(~S,handle)),Forgotten{handle}))
72def forget_namespace(~S:Data,+actual:U32,allocator:Allocator.Allocator,store:Store<S>,handle:W.Handle<S>,namespace:U32) -> Allocator.Allocator & (Store<S> & Outcome<S>):
73 match store:
74 case Store{+stored,members}:forgotten(~S,Bool.and(U32.is_eq(actual,stored),U32.is_eq(actual,namespace)),allocator,Store{stored,members},handle)
75def inspected(~S:Data,allocator:Allocator.Allocator,store:Store<S>) -> Allocator.Allocator & (Store<S> & Outcome<S>):
76 match store:
77 case Store{+namespace,members}:(allocator,(Store{namespace,members},Inspected{namespace}))
78def apply(~S:Data,+actual:U32,allocator:Allocator.Allocator,store:Store<S>,request:Request<S>) -> Allocator.Allocator & (Store<S> & Outcome<S>):
79 match request:
80 case Inspect{}:inspected(~S,allocator,store)
81 case Assign{scope,handle}:assignment_returned(~S,assign(~S,actual,allocator,store,scope,handle))
82 case Select{scope}:selection_returned(~S,allocator,snapshot(~S,actual,store,scope))
83 case Forget{W.Handle{+namespace,+key}}:forget_namespace(~S,actual,allocator,store,W.Handle{namespace,key},namespace)