ordinary_query_builder.bend
bendvy-ecs-core@0.1.0.1 · 66 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.1/ordinary_query_observable.bend as O
3import bendvy-ecs-core@0.1.0.1/ordinary_query_declaration.bend as N
4import bendvy-ecs-core@0.1.0.1/ordinary_component_binding.bend as B
5import bendvy-ecs-core@0.1.0.1/inspector_query_projection.bend as P
6import bendvy-ecs-core@0.1.0.1/inspector_query.bend as IQ
7import bendvy-ecs-core@0.1.0.1/inspector.bend as I
8import bendvy-ecs-core@0.1.0.1/compose.bend as Q
9import bendvy-ecs-core@0.1.0.1/component.bend as C
10import bendvy-ecs-core@0.1.0.1/column.bend as Col
11import bendvy-ecs-core@0.1.0.1/capabilities.bend as Cap
12import bendvy-ecs-core@0.1.0.1/internal/query_read_session.bend as Session
13
14# Supported ordinary setup for read/optional/pair queries. Each binding defines
15# both ordinary authority and the compact read recipe; finish returns the existing
16# ordinary Declaration. Other forms and mixed composition use O.pair after finish.
17# The concrete Store remains indexed until composition finishes; gameplay keeps
18# the existing opaque owner and query interfaces.
19# Setup carrier for read/optional/pair declarations and their detached
20# inspection recipe. It owns no runtime world or payload; use finish to obtain
21# the ordinary observable declaration accepted by registration.
22type Builder<-S:Data,-Store:Type,-R:Type,-E:Data,-H:Type,-G:Type,-V:Data> is Type:
23 Builder{ordinary:Unit -> O.Declaration<S,H,G,I.Frame<S,Store,R,E>,V>,session:Unit -> P.DeclaredSelection<Session.Owner<S,Store>,S,V>}
24# Consume the setup builder to obtain its ordinary observable declaration.
25# No query executes; use finish to retain the prepared read enumeration path.
26def ordinary(~S:Data,~Store:Type,~R:Type,~E:Data,~H:Type,~G:Type,~V:Data,builder:Builder<S,Store,R,E,H,G,V>) -> O.Declaration<S,H,G,I.Frame<S,Store,R,E>,V>:
27 match builder:
28 case Builder{ordinary,_}:ordinary(Unit{})
29def session(~S:Data,~Store:Type,~R:Type,~E:Data,~H:Type,~G:Type,~V:Data,builder:Builder<S,Store,R,E,H,G,V>) -> P.DeclaredSelection<Session.Owner<S,Store>,S,V>:
30 match builder:
31 case Builder{_,session}:session(Unit{})
32# Build a required component read and matching detached inspection recipe
33# from one trusted binding. view preserves Payload and exposes Data V only.
34# Operational reads return Found/ComponentAbsent/MissingEntity; declaration
35# creation neither acquires a world nor advances system visibility.
36def read(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,Payload>,~put:Rest -> Col.Column<S,Payload> -> Store,~view:Payload -> Payload & V,~R:Type,~E:Data,~binding:B.Binding<S,Store,Rest,Payload,V,Token,take,put,view>) -> Builder<S,Store,R,E,Q.Frame<S,Store,R,E>,Cap.Read<Q.Frame<S,Store,R,E>,V>,C.Access<V>>:
37 Builder{_=>O.read(~S,~Store,~Rest,~Payload,~V,~Token,~take,~put,~view,~R,~E,~binding),_=>Session.slot(~S,~Store,~Rest,~Payload,~V,~take,~put,~view,~Q.Required{})}
38
39# Build an optional read: a missing component does not exclude a live row.
40# Access results retain ComponentAbsent; stale/foreign handles remain
41# MissingEntity. The projection preserves affine Payload while exposing V.
42def optional(~S:Data,~Store:Type,~Rest:Type,~Payload:Type,~V:Data,~Token:Data,~take:Store -> Rest & Col.Column<S,Payload>,~put:Rest -> Col.Column<S,Payload> -> Store,~view:Payload -> Payload & V,~R:Type,~E:Data,~binding:B.Binding<S,Store,Rest,Payload,V,Token,take,put,view>) -> Builder<S,Store,R,E,Q.Frame<S,Store,R,E>,Cap.Read<Q.Frame<S,Store,R,E>,V>,C.Access<V>>:
43 Builder{_=>O.optional(~S,~Store,~Rest,~Payload,~V,~Token,~take,~put,~view,~R,~E,~binding),_=>Session.slot(~S,~Store,~Rest,~Payload,~V,~take,~put,~view,~Q.Optional{})}
44
45# Combine setup builders with conjunctive row selection and nested grants
46# (L & R); detached results use Product<LV,RV>. Both builders must share schema,
47# storage and owner. Nest pairs for larger shapes; no fixed arity limit is
48# introduced. No row traversal occurs during construction.
49def pair(~S:Data,~Store:Type,~Resource:Type,~E:Data,~H:Type,~L:Type,~R:Type,~LV:Data,~RV:Data,~left:Builder<S,Store,Resource,E,H,L,LV>,~right:Builder<S,Store,Resource,E,H,R,RV>) -> Builder<S,Store,Resource,E,H,L & R,P.Product<LV,RV>>:
50 Builder{_=>O.pair(~S,~H,~L,~R,~I.Frame<S,Store,Resource,E>,~LV,~RV,~ordinary(~S,~Store,~Resource,~E,~H,~L,~LV,left),~ordinary(~S,~Store,~Resource,~E,~H,~R,~RV,right)),_=>P.pair(~Session.Owner<S,Store>,~S,~LV,~RV,~session(~S,~Store,~Resource,~E,~H,~L,~LV,left),~session(~S,~Store,~Resource,~E,~H,~R,~RV,right))}
51# Unsupported declarations remain ordinary O.Declaration values. Composing one
52# with finish(builder) through O.pair retains the complete opaque evaluator.
53# Produce an ordinary observable declaration with prepared read enumeration.
54# Supports this builder's read/optional/pair forms; mix other supported forms
55# afterward using ordinary-query-observable.pair. Preserves typed operational
56# grants and detached inspection; this call does not execute either.
57# Example: test-fixtures/connected-performance/sparse-motion64/consumer/s-perf/
58# canonical-api-v1/sparse-runtime-v1/motion-logical.bend, declaration().
59def finish(~S:Data,~Store:Type,~R:Type,~E:Data,~H:Type,~G:Type,~V:Data,~builder:Builder<S,Store,R,E,H,G,V>) -> O.Declaration<S,H,G,I.Frame<S,Store,R,E>,V>:
60 O.PreparedDeclaration{_=>O.operational(~S,~H,~G,~I.Frame<S,Store,R,E>,~V,ordinary(~S,~Store,~R,~E,~H,~G,~V,builder)),_=>O.inspection(~S,~H,~G,~I.Frame<S,Store,R,E>,~V,ordinary(~S,~Store,~R,~E,~H,~G,~V,builder)),owner=>Session.enumerate(~S,~Store,~R,~E,~V,~session(~S,~Store,~R,~E,~H,~G,~V,builder),owner)}
61# Trusted advanced adapter replacing the builder's operational declaration
62# while retaining its inspection and read-enumeration recipes. Caller must
63# preserve their intended relationship; no semantic equivalence is checked.
64# Does not grant inspection the replacement's write operations.
65def replace_operational(~S:Data,~Store:Type,~R:Type,~E:Data,~H:Type,~Old:Type,~New:Type,~V:Data,~operation:N.Declaration<S,H,New>,~builder:Builder<S,Store,R,E,H,Old,V>) -> Builder<S,Store,R,E,H,New,V>:
66 Builder{_=>O.Declaration{_=>operation,_=>O.inspection(~S,~H,~Old,~I.Frame<S,Store,R,E>,~V,ordinary(~S,~Store,~R,~E,~H,~Old,~V,builder))},_=>session(~S,~Store,~R,~E,~H,~Old,~V,builder)}