internal/query_read_session.bend

bendvy-ecs-core@0.1.0.1 · 52 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.1/change_tick.bend as Tick
3import bendvy-ecs-core@0.1.0.1/clock_state.bend as Clock
4import bendvy-ecs-core@0.1.0.1/world.bend as W
5import bendvy-ecs-core@0.1.0.1/entity_key.bend as K
6import bendvy-ecs-core@0.1.0.1/entity_allocator.bend as A
7import bendvy-ecs-core@0.1.0.1/component.bend as C
8import bendvy-ecs-core@0.1.0.1/column.bend as Col
9import bendvy-ecs-core@0.1.0.1/inspector.bend as I
10import bendvy-ecs-core@0.1.0.1/inspector_query.bend as IQ
11import bendvy-ecs-core@0.1.0.1/inspector_query_world.bend as IW
12import bendvy-ecs-core@0.1.0.1/inspector_query_projection.bend as P
13import bendvy-ecs-core@0.1.0.1/compose.bend as Q
14import bendvy-ecs-core@0.1.0.1/deferred_command.bend as Deferred
15
16# A scan owns one Store; unrelated World owners remain outside its row loop.
17type Owner<-S:Data,-Store:Type> is Type:
18  Owner{namespace:U32,allocator:A.Allocator,store:Store,cursor:Maybe<&2,Tick.Tick>}
19
20def read_join(~S:Data,~Store:Type,~V:Data,namespace:U32,allocator:A.Allocator,cursor:Maybe<&2,Tick.Tick>,observed:Store & C.Access<V>) -> Owner<S,Store> & C.Access<V>:
21  (store,value)=observed
22  (Owner{namespace,allocator,store,cursor},value)
23def read_valid(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~take:Store -> Rest & Col.Column<S,Payload>,~put:Rest -> Col.Column<S,Payload> -> Store,~view:Payload -> Payload & V,namespace:U32,store:Store,cursor:Maybe<&2,Tick.Tick>,key:K.Key,observed:A.Allocator & Bool) -> Owner<S,Store> & C.Access<V>:
24  match key observed:
25    case _, (allocator,False{}):(Owner{namespace,allocator,store,cursor},C.MissingEntity{})
26    case K.EntityKey{id,_}, (allocator,True{}):read_join(~S,~Store,~V,namespace,allocator,cursor,C.get_store(~S,~Store,~Unit,~Nat,~Rest,~Payload,~V,~Unit,~take,~put,~view,id,take(store)))
27def read_namespace(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~take:Store -> Rest & Col.Column<S,Payload>,~put:Rest -> Col.Column<S,Payload> -> Store,~view:Payload -> Payload & V,allowed:Bool,namespace:U32,allocator:A.Allocator,store:Store,cursor:Maybe<&2,Tick.Tick>,+key:K.Key) -> Owner<S,Store> & C.Access<V>:
28  match allowed:
29    case False{}:(Owner{namespace,allocator,store,cursor},C.MissingEntity{})
30    case True{}:read_valid(~S,~Store,~Rest,~Payload,~V,~take,~put,~view,namespace,store,cursor,key,A.checked(allocator,key,1))
31def read(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~take:Store -> Rest & Col.Column<S,Payload>,~put:Rest -> Col.Column<S,Payload> -> Store,~view:Payload -> Payload & V,owner:Owner<S,Store>,target:W.Handle<S>) -> Owner<S,Store> & C.Access<V>:
32  match owner target:
33    case Owner{+namespace,allocator,store,cursor} W.Handle{ns,key}:read_namespace(~S,~Store,~Rest,~Payload,~V,~take,~put,~view,U32.is_eq(namespace,ns),namespace,allocator,store,cursor,key)
34def matched(~S:Data,~Store:Type,mode:Q.Selection,observed:Owner<S,Store> & C.Access<Bool>) -> Owner<S,Store> & Bool:
35  (owner,value)=observed
36  (owner,Q.selected_value(~Bool,mode,value))
37def matches(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~take:Store -> Rest & Col.Column<S,Payload>,~put:Rest -> Col.Column<S,Payload> -> Store,~mode:Q.Selection,owner:Owner<S,Store>,target:W.Handle<S>) -> Owner<S,Store> & Bool:
38  matched(~S,~Store,mode,read(~S,~Store,~Rest,~Payload,~Bool,~take,~put,~Col.present(~Payload),owner,target))
39def slot(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~take:Store -> Rest & Col.Column<S,Payload>,~put:Rest -> Col.Column<S,Payload> -> Store,~view:Payload -> Payload & V,~mode:Q.Selection) -> P.DeclaredSelection<Owner<S,Store>,S,C.Access<V>>:
40  P.DeclaredSelection{owner=>target=>matches(~S,~Store,~Rest,~Payload,~take,~put,~mode,owner,target),owner=>target=>read(~S,~Store,~Rest,~Payload,~V,~take,~put,~view,owner,target)}
41
42def restore(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,resource:R,events:List<&2,E>,pending:List<Deferred.Command<W.World<S,Store,R,E>>>,registrations:List<&2,W.RegistrationMeta>,nextSystemId:U32,clock:Clock.State,observed:Owner<S,Store> & List<&2,IQ.ProjectedRow<S,V>>) -> I.Frame<S,Store,R,E> & List<&2,IQ.ProjectedRow<S,V>>:
43  match observed:
44    case (Owner{namespace,allocator,store,cursor},rows):(I.Frame{W.World{namespace,allocator,store,resource,events,pending,registrations,nextSystemId,clock},cursor},rows)
45def enter_world(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,~selection:P.DeclaredSelection<Owner<S,Store>,S,V>,world:W.World<S,Store,R,E>,cursor:Maybe<&2,Tick.Tick>,targets:List<&2,W.Handle<S>>) -> I.Frame<S,Store,R,E> & List<&2,IQ.ProjectedRow<S,V>>:
46  match world:
47    case W.World{namespace,allocator,store,resource,events,pending,registrations,nextSystemId,clock}:restore(~S,~Store,~R,~E,~V,resource,events,pending,registrations,nextSystemId,clock,IQ.composed_scanned(~Owner<S,Store>,~S,~V,~selection,(Owner{namespace,allocator,store,cursor},targets)))
48def enter(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,~selection:P.DeclaredSelection<Owner<S,Store>,S,V>,observed:I.Frame<S,Store,R,E> & List<&2,W.Handle<S>>) -> I.Frame<S,Store,R,E> & List<&2,IQ.ProjectedRow<S,V>>:
49  match observed:
50    case (I.Frame{world,cursor},targets):enter_world(~S,~Store,~R,~E,~V,~selection,world,cursor,targets)
51def enumerate(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,~selection:P.DeclaredSelection<Owner<S,Store>,S,V>,frame:I.Frame<S,Store,R,E>) -> I.Frame<S,Store,R,E> & List<&2,IQ.ProjectedRow<S,V>>:
52  enter(~S,~Store,~R,~E,~V,~selection,IQ.composed_handles_field(~I.Frame<S,Store,R,E>,~S,IW.inspect_world(~S,~Store,~R,~E))(frame))