ordinary_app_population.bend

bendvy-ecs-core@0.1.0.0 · 67 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.0/clock_state.bend as Clock
3import bendvy-ecs-core@0.1.0.0/deferred_command.bend as Deferred
4import entity_allocator.bend as Alloc
5import bendvy-ecs-core@0.1.0.0/world.bend as W
6import bendvy-ecs-core@0.1.0.0/ordinary_schema.bend as Schema
7import bendvy-ecs-core@0.1.0.0/schema_fragments.bend as Fragment
8import bendvy-ecs-core@0.1.0.0/ordinary_app_schema.bend as SchemaApp
9import bendvy-ecs-core@0.1.0.0/ordinary_app_composer.bend as Build
10import bendvy-ecs-core@0.1.0.0/ordinary_app_registration_fields.bend as Records
11import bendvy-ecs-core@0.1.0.0/ordinary_app_observation_data.bend as DTO
12import bendvy-ecs-core@0.1.0.0/ordinary_app_recipe.bend as Tree
13import bendvy-ecs-core@0.1.0.0/ordinary_schema_provision.bend as Provision
14# Existing Schema/App types remain unchanged. There is one retained Schema.
15# Ordinary schema App with a closed matching population-count operation.
16# Retains actual World/system owners; no duplicate schema or payload is stored.
17type Application<S:Data,C:Type,R:Type,E:Data,H:Type,Rows:Data,-observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,-fold:H -> H & List<&2,Records.Fields<S>>,-count:C -> List<&2,W.Handle<S>> -> C & List<&2,Maybe<&2,U32>>> is Type:
18  Application{app:SchemaApp.Application<S,C,R,E,H,Rows,observe,fold>}
19# Detached live-membership count for one component key. Does not include
20# absent components or imply a physical allocation/memory measurement.
21type ComponentCount is Data:
22  ComponentCount{key:String,count:U32}
23# Detached alive-entity count and ordered component-key counts. Resources
24# do not contribute component rows; this is observation, not a World save.
25type Population is Data:
26  Population{alive:U32,components:List<&2,ComponentCount>}
27# Ordinary component/resource/product builders make entries and slots together.
28# Raw manually forged Provision values are trusted setup, not validated adapters.
29def rows(~S:Data,pairs:List<&1,Fragment.Entry<S> & Maybe<&2,U32>>) -> List<&2,ComponentCount>:
30  match pairs:
31    case []:[]
32    case (Fragment.Entry{Fragment.Component{},key,_},Some{count}) <> rest:ComponentCount{key,count} <> rows(~S,rest)
33    case _ <> rest:rows(~S,rest)
34# Attach a matching Provision/schema to retained registered App owners.
35# Does not validate arbitrarily forged provision/count relationships or run
36# system bodies; ordinary constructors keep entries and count slots aligned.
37def attached(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~empty:Unit -> C,~count:C -> List<&2,W.Handle<S>> -> C & List<&2,Maybe<&2,U32>>,provision:Provision.Provision<S,C,R,empty,count>,app:Build.Registered<S,W.World<S,C,R,E>,H,Rows,observe,fold>) -> Application<S,C,R,E,H,Rows,observe,fold,count>:
38  match provision:
39    case Provision.Provision{schema}:Application{SchemaApp.attached(~S,~C,~R,~E,~H,~Rows,~observe,~fold,schema,app)}
40# Toggle debug on the retained population App without counting entities
41# or invoking registered systems.
42def enabled(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~count:C -> List<&2,W.Handle<S>> -> C & List<&2,Maybe<&2,U32>>,app:Application<S,C,R,E,H,Rows,observe,fold,count>,flag:Bool) -> Application<S,C,R,E,H,Rows,observe,fold,count>:
43  match app:
44    case Application{app}:Application{SchemaApp.enabled(~S,~C,~R,~E,~H,~Rows,~observe,~fold,app,flag)}
45def counted(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~count:C -> List<&2,W.Handle<S>> -> C & List<&2,Maybe<&2,U32>>,+schema:Schema.Schema<S,C,R>,owners:H,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,alive:U32,namespace:U32,allocator:Alloc.Allocator,resource:R,events:List<&2,E>,pending:List<Deferred.Command<W.World<S,C,R,E>>>,registrations:List<&2,W.RegistrationMeta>,nextSystemId:U32,clock:Clock.State,result:C & List<&2,Maybe<&2,U32>>) -> Application<S,C,R,E,H,Rows,observe,fold,count> & Maybe<&2,Population>:
46  match result:
47    case (store,slots):(Application{SchemaApp.Application{schema,Build.Registered{W.World{namespace,allocator,store,resource,events,pending,registrations,nextSystemId,clock},owners,recipe,True{}}}},Some{Population{alive,rows(~S,List.zip(&2,Fragment.Entry<S>,&2,Maybe<&2,U32>,Fragment.bare_entries(~S,Schema.entries(~S,~C,~R,schema)),slots))}})
48def scanned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~count:C -> List<&2,W.Handle<S>> -> C & List<&2,Maybe<&2,U32>>,schema:Schema.Schema<S,C,R>,owners:H,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,observe>,result:W.World<S,C,R,E> & List<&2,W.Handle<S>>) -> Application<S,C,R,E,H,Rows,observe,fold,count> & Maybe<&2,Population>:
49  match result:
50    case (W.World{namespace,allocator,store,resource,events,pending,registrations,nextSystemId,clock},+handles):counted(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~count,schema,owners,recipe,U32.from_nat(List.length(&2,W.Handle<S>,handles)),namespace,allocator,resource,events,pending,registrations,nextSystemId,clock,count(store,handles))
51# Return the App with Some detached population only when debug is enabled;
52# disabled returns None without traversal. Enabled scans live handles and
53# preserves storage owners through the count callback. Registered query/event
54# cursors do not advance; raw counting callbacks remain trusted setup.
55def population(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~count:C -> List<&2,W.Handle<S>> -> C & List<&2,Maybe<&2,U32>>,app:Application<S,C,R,E,H,Rows,observe,fold,count>) -> Application<S,C,R,E,H,Rows,observe,fold,count> & Maybe<&2,Population>:
56  match app:
57    case Application{SchemaApp.Application{schema,Build.Registered{world,owners,recipe,False{}}}}:(Application{SchemaApp.Application{schema,Build.Registered{world,owners,recipe,False{}}}},None{})
58    case Application{SchemaApp.Application{schema,Build.Registered{world,owners,recipe,True{}}}}:scanned(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~count,schema,owners,recipe,W.handles(~S,~C,~R,~E,world))
59
60def returned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~count:C -> List<&2,W.Handle<S>> -> C & List<&2,Maybe<&2,U32>>,result:Application<S,C,R,E,H,Rows,observe,fold,count> & Maybe<&2,Population>) -> SchemaApp.Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Population>:
61  match result:
62    case (Application{app},view):(app,view)
63# Advanced observation on an existing schema App using its matching count
64# operation. Returns that same App shape plus optional population, following
65# population's enabled/disabled behavior without another retained schema.
66def schema_population(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:H -> H & List<&2,Records.Fields<S>>,~count:C -> List<&2,W.Handle<S>> -> C & List<&2,Maybe<&2,U32>>,app:SchemaApp.Application<S,C,R,E,H,Rows,observe,fold>) -> SchemaApp.Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Population>:
67  returned(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~count,population(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~count,Application{app}))