ordinary_inspector_declaration.bend
bendvy-ecs-core@0.1.0.0 · 53 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.0/ordinary_component_binding.bend as B
3import bendvy-ecs-core@0.1.0.0/ordinary_declaration.bend as Identity
4import bendvy-ecs-core@0.1.0.0/ordinary_query_declaration.bend as D
5import bendvy-ecs-core@0.1.0.0/inspector.bend as I
6import bendvy-ecs-core@0.1.0.0/inspector_query.bend as Q
7import bendvy-ecs-core@0.1.0.0/inspector_query_projection.bend as Projection
8import bendvy-ecs-core@0.1.0.0/column.bend as Col
9import bendvy-ecs-core@0.1.0.0/inspector_query_projection.bend as Rows
10
11# Ordinary read-only Inspector query plus clauses from the same binding.
12# Retains no World or registered reader; raw construction is trusted setup.
13type Declaration<-S:Data,-H:Type,-V:Data> is Type:
14 Declaration{query:Q.ReadQuery<H,S,V>,clauses:List<&2,D.Clause<S>>}
15# Consume this declaration to obtain its typed read-query capability.
16# Does not enumerate rows or advance an observation/system cursor.
17def query(~S:Data,~H:Type,~V:Data,declaration:Declaration<S,H,V>) -> Q.ReadQuery<H,S,V>:
18 match declaration:
19 case Declaration{query,_}:query
20# Return declaration and detached clauses without accessing World or
21# reading components. Prefer this when retaining the declaration owner.
22def observe(~S:Data,~H:Type,~V:Data,declaration:Declaration<S,H,V>) -> Declaration<S,H,V> & List<&2,D.Clause<S>>:
23 match declaration:
24 case Declaration{query,+clauses}:(Declaration{query,clauses},clauses)
25# Build required component inspection from its operational binding.
26# Derives read grant and clauses together; view preserves P while exposing V.
27def read(~S:Data,~Store:Type,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,~R:Type,~E:Data,~binding:B.Binding<S,Store,Rest,P,V,Token,take,put,view>) -> Declaration<S,I.Frame<S,Store,R,E>,V>:
28 Declaration{Q.grant(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,~B.family(~S,~Store,~Rest,~P,~V,~Token,~take,~put,~view,binding),~Projection.Required{}),[D.Clause{Identity.key(~S,~P,B.identity(~S,~Store,~Rest,~P,~V,~Token,~take,~put,~view,binding)),D.Read{}}]}
29# Build optional component inspection, preserving explicit absence for a
30# live entity. Canonical lookup still rejects stale/foreign handles.
31def optional(~S:Data,~Store:Type,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,~R:Type,~E:Data,~binding:B.Binding<S,Store,Rest,P,V,Token,take,put,view>) -> Declaration<S,I.Frame<S,Store,R,E>,V>:
32 Declaration{Q.grant(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,~B.family(~S,~Store,~Rest,~P,~V,~Token,~take,~put,~view,binding),~Projection.Optional{}),[D.Clause{Identity.key(~S,~P,B.identity(~S,~Store,~Rest,~P,~V,~Token,~take,~put,~view,binding)),D.Optional{}}]}
33# Build a presence-plus-added filter using Inspector cursor visibility.
34# Does not consume registered system lifecycle/event cursors during setup.
35def added(~S:Data,~Store:Type,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,~R:Type,~E:Data,~binding:B.Binding<S,Store,Rest,P,V,Token,take,put,view>) -> Declaration<S,I.Frame<S,Store,R,E>,V>:
36 Declaration{Q.grant(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,~B.family(~S,~Store,~Rest,~P,~V,~Token,~take,~put,~view,binding),~Projection.Added{}),[D.Clause{Identity.key(~S,~P,B.identity(~S,~Store,~Rest,~P,~V,~Token,~take,~put,~view,binding)),D.Added{}}]}
37# Build a presence-plus-changed filter relative to the Inspector cursor.
38# Operational binding and descriptive clauses share one source of truth.
39def changed(~S:Data,~Store:Type,~Rest:Type,~P:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,P>,~put:Rest -> Col.Column<S,P> -> Store,~view:P -> P & V,~R:Type,~E:Data,~binding:B.Binding<S,Store,Rest,P,V,Token,take,put,view>) -> Declaration<S,I.Frame<S,Store,R,E>,V>:
40 Declaration{Q.grant(~S,~Store,~R,~E,~Rest,~P,~V,~Token,~take,~put,~view,~B.family(~S,~Store,~Rest,~P,~V,~Token,~take,~put,~view,binding),~Projection.Changed{}),[D.Clause{Identity.key(~S,~P,B.identity(~S,~Store,~Rest,~P,~V,~Token,~take,~put,~view,binding)),D.Changed{}}]}
41# Consume declaration to obtain its detached query description, with no
42# component read, registration execution or cursor change.
43def clauses(~S:Data,~H:Type,~V:Data,declaration:Declaration<S,H,V>) -> List<&2,D.Clause<S>>:
44 match declaration:
45 case Declaration{_,clauses}:clauses
46def each_result(~S:Data,~H:Type,~V:Data,clauses:List<&2,D.Clause<S>>,result:H & List<&2,Rows.Row<S,V>>) -> H & (List<&2,Rows.Row<S,V>> & List<&2,D.Clause<S>>):
47 match result:
48 case (owner,rows):(owner,(rows,clauses))
49# Execute the declared read-only enumeration, returning owner, detached rows
50# and retained clauses. Uses the matching Inspector grant; no mutable payload
51# alias or registered system reader ownership escapes.
52def each(~S:Data,~H:Type,~V:Data,~declaration:Declaration<S,H,V>,owner:H) -> H & (List<&2,Rows.Row<S,V>> & List<&2,D.Clause<S>>):
53 each_result(~S,~H,~V,clauses(~S,~H,~V,declaration),Q.each(~H,~S,~V,~query(~S,~H,~V,declaration),owner))