1 import Base 2 import ./clock_state.bend as Clock 3 import ./deferred_command.bend as Deferred 4 import entity_allocator.bend as Alloc 5 import ./world.bend as W 6 import ./ordinary_schema.bend as Schema 7 import ./schema_fragments.bend as Fragment 8 import ./ordinary_app_schema.bend as SchemaApp 9 import ./ordinary_app_composer.bend as Build 10 import ./ordinary_app_registration_fields.bend as Records 11 import ./ordinary_app_observation_data.bend as DTO 12 import ./ordinary_app_recipe.bend as Tree 13 import ./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. 17 type Application -> W.World & DTO.Observation,-fold:H -> H & List<&2,Records.Fields>,-count:C -> List<&2,W.Handle> -> C & List<&2,Maybe<&2,U32>>> is Type: 18 Application{app:SchemaApp.Application} 19 # Detached live-membership count for one component key. Does not include 20 # absent components or imply a physical allocation/memory measurement. 21 type 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. 25 type 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. 29 def rows(~S:Data,pairs:List<&1,Fragment.Entry & 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. 37 def attached(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World -> W.World & DTO.Observation,~fold:H -> H & List<&2,Records.Fields>,~empty:Unit -> C,~count:C -> List<&2,W.Handle> -> C & List<&2,Maybe<&2,U32>>,provision:Provision.Provision,app:Build.Registered,H,Rows,observe,fold>) -> Application: 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. 42 def enabled(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World -> W.World & DTO.Observation,~fold:H -> H & List<&2,Records.Fields>,~count:C -> List<&2,W.Handle> -> C & List<&2,Maybe<&2,U32>>,app:Application,flag:Bool) -> Application: 43 match app: 44 case Application{app}:Application{SchemaApp.enabled(~S,~C,~R,~E,~H,~Rows,~observe,~fold,app,flag)} 45 def counted(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World -> W.World & DTO.Observation,~fold:H -> H & List<&2,Records.Fields>,~count:C -> List<&2,W.Handle> -> C & List<&2,Maybe<&2,U32>>,+schema:Schema.Schema,owners:H,recipe:Tree.Recipe,Rows,observe>,alive:U32,namespace:U32,allocator:Alloc.Allocator,resource:R,events:List<&2,E>,pending:List>>,registrations:List<&2,W.RegistrationMeta>,nextSystemId:U32,clock:Clock.State,result:C & List<&2,Maybe<&2,U32>>) -> Application & 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,&2,Maybe<&2,U32>,Fragment.bare_entries(~S,Schema.entries(~S,~C,~R,schema)),slots))}}) 48 def scanned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World -> W.World & DTO.Observation,~fold:H -> H & List<&2,Records.Fields>,~count:C -> List<&2,W.Handle> -> C & List<&2,Maybe<&2,U32>>,schema:Schema.Schema,owners:H,recipe:Tree.Recipe,Rows,observe>,result:W.World & List<&2,W.Handle>) -> Application & 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,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. 55 def population(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World -> W.World & DTO.Observation,~fold:H -> H & List<&2,Records.Fields>,~count:C -> List<&2,W.Handle> -> C & List<&2,Maybe<&2,U32>>,app:Application) -> Application & 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 60 def returned(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World -> W.World & DTO.Observation,~fold:H -> H & List<&2,Records.Fields>,~count:C -> List<&2,W.Handle> -> C & List<&2,Maybe<&2,U32>>,result:Application & Maybe<&2,Population>) -> SchemaApp.Application & 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. 66 def schema_population(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World -> W.World & DTO.Observation,~fold:H -> H & List<&2,Records.Fields>,~count:C -> List<&2,W.Handle> -> C & List<&2,Maybe<&2,U32>>,app:SchemaApp.Application) -> SchemaApp.Application & 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}))