ordinary_app_schedule_description.bend
bendvy-ecs-core@0.1.0.1 · 97 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.1/ordinary_condition_composition.bend as Comp
3import bendvy-ecs-core@0.1.0.1/ordinary_app_schedule.bend as Schedule
4import bendvy-ecs-core@0.1.0.1/ordinary_app_schema.bend as SchemaApp
5import bendvy-ecs-core@0.1.0.1/ordinary_app_observation_data.bend as DTO
6import bendvy-ecs-core@0.1.0.1/ordinary_app_registration_fields.bend as Fields
7import bendvy-ecs-core@0.1.0.1/world.bend as W
8import bendvy-ecs-core@0.1.0.1/schedule.bend as Sch
9import bendvy-ecs-core@0.1.0.1/schedule_provision.bend as SP
10# Names derive only from the retained actual Registry namespace/id. A missing
11# binding stays None; this adapter never invents a label or condition name.
12# Detached zero-based plan placement retaining requirements and condition slot.
13# System names are joined by actual namespace/id; missing bindings remain None.
14# Phase/barrier entries remain in position order, not fabricated system metadata.
15type Placement<S:Data> is Data:
16 System{position:Nat,namespace:U32,id:U32,name:Maybe<&2,String>,condition:U32,requirements:List<&2,SP.Requirement<S>>}
17 Phase{position:Nat,name:String,requirements:List<&2,SP.Requirement<S>>}
18 Barrier{position:Nat,requirements:List<&2,SP.Requirement<S>>}
19# Preserve the original single-schedule description with derived ordered
20# placements. No new runtime state or gameplay capability is introduced.
21type Description<S:Data,Rows:Data> is Data:
22 Description{original:Schedule.Description<S,Rows>,placements:List<&2,Placement<S>>}
23def selected(same:Bool,name:String,next:Maybe<&2,String>) -> Maybe<&2,String>:
24 match same:
25 case False{}:next
26 case True{}:Some{name}
27# Advanced metadata lookup by exact namespace/id; no fallback or invented label.
28def binding_name(~S:Data,+namespace:U32,+id:U32,bindings:List<&2,DTO.Binding<S>>) -> Maybe<&2,String>:
29 match bindings:
30 case []:None{}
31 case DTO.Binding{otherNamespace,otherId,name,_,_,_,_} <> rest:selected(Bool.and(U32.is_eq(namespace,otherNamespace),U32.is_eq(id,otherId)),name,binding_name(~S,namespace,id,rest))
32def step(~S:Data,+namespace:U32,bindings:List<&2,DTO.Binding<S>>,position:Nat,planned:Schedule.PlannedStep<S>) -> Placement<S>:
33 match planned:
34 case Schedule.PlannedStep{Sch.System{+id,condition},requirements}:System{position,namespace,id,binding_name(~S,namespace,id,bindings),condition,requirements}
35 case Schedule.PlannedStep{Sch.Phase{name},requirements}:Phase{position,name,requirements}
36 case Schedule.PlannedStep{Sch.Barrier{},requirements}:Barrier{position,requirements}
37# Advanced placement derivation over supplied planned steps, starting at position.
38# Bindings are detached input metadata, not another registration authority.
39def placed(~S:Data,steps:List<&2,Schedule.PlannedStep<S>>,+namespace:U32,+bindings:List<&2,DTO.Binding<S>>,+position:Nat) -> List<&2,Placement<S>>:
40 match steps:
41 case []:[]
42 case first <> rest:step(~S,namespace,bindings,position,first) <> placed(~S,rest,namespace,bindings,1n+position)
43# Derive placements from the original snapshot's retained plan and bindings,
44# preserving that original complete description.
45def described(~S:Data,~Rows:Data,+description:Schedule.Description<S,Rows>) -> Description<S,Rows>:
46 match description:
47 case Schedule.Description{SchemaApp.Description{_,DTO.Product{bindings,_}},namespace,_,steps}:Description{description,placed(~S,steps,namespace,bindings,0n)}
48def 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,Fields.Fields<S>>,result:Schedule.Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Schedule.Description<S,Rows>>) -> Schedule.Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Description<S,Rows>>:
49 match result:
50 case (app,None{}):(app,None{})
51 case (app,Some{view}):(app,Some{described(~S,~Rows,view)})
52# The existing snapshot's disabled branch returns before fold/observe and before
53# this adapter derives any placements. No new observation callback is accepted.
54# Observe the single-schedule App, then derive placements only for an enabled
55# snapshot. Disabled returns App and None before observer/placement work.
56def snapshot(~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,Fields.Fields<S>>,app:Schedule.Application<S,C,R,E,H,Rows,observe,fold>) -> Schedule.Application<S,C,R,E,H,Rows,observe,fold> & Maybe<&2,Description<S,Rows>>:
57 returned(~S,~C,~R,~E,~H,~Rows,~observe,~fold,Schedule.snapshot(~S,~C,~R,~E,~H,~Rows,~observe,~fold,app))
58
59# Detached system position/id/slot plus optional condition description. Missing
60# condition metadata stays None; the slot is not a newly evaluated condition.
61type ConditionPlacement is Data:
62 ConditionPlacement{position:Nat,namespace:U32,id:U32,slot:U32,condition:Maybe<&2,Comp.Description>}
63# Preserve original placements and detached condition bindings with their system
64# placements; no condition callback is invoked by description derivation.
65type ConditionedDescription<S:Data,Rows:Data> is Data:
66 ConditionedDescription{original:Description<S,Rows>,bindings:List<&2,Comp.BindingDescription>,placements:List<&2,ConditionPlacement>}
67def condition_selected(chosen:Bool,facts:Comp.Description,rest:Maybe<&2,Comp.Description>) -> Maybe<&2,Comp.Description>:
68 match chosen:
69 case True{}:Some{facts}
70 case False{}:rest
71def condition_for(bindings:List<&2,Comp.BindingDescription>,+id:U32) -> Maybe<&2,Comp.Description>:
72 match bindings:
73 case []:None{}
74 case Comp.BindingDescription{other,facts} <> rest:condition_selected(U32.is_eq(other,id),facts,condition_for(rest,id))
75def condition_step(~S:Data,namespace:U32,bindings:List<&2,Comp.BindingDescription>,position:Nat,planned:Schedule.PlannedStep<S>) -> List<&2,ConditionPlacement>:
76 match planned:
77 case Schedule.PlannedStep{Sch.System{+id,slot},_}:[ConditionPlacement{position,namespace,id,slot,condition_for(bindings,id)}]
78 case _ :[]
79def condition_placements(~S:Data,steps:List<&2,Schedule.PlannedStep<S>>,+namespace:U32,+bindings:List<&2,Comp.BindingDescription>,+position:Nat) -> List<&2,ConditionPlacement>:
80 match steps:
81 case []:[]
82 case first <> rest:List.append(&2,ConditionPlacement,condition_step(~S,namespace,bindings,position,first),condition_placements(~S,rest,namespace,bindings,1n+position))
83# Advanced metadata adapter joining supplied condition descriptions to system ids
84# and retaining the complete original schedule description.
85def with_conditions(~S:Data,~Rows:Data,+original:Schedule.Description<S,Rows>,+bindings:List<&2,Comp.BindingDescription>) -> ConditionedDescription<S,Rows>:
86 match original:
87 case Schedule.Description{_,namespace,_,steps}:ConditionedDescription{described(~S,~Rows,original),bindings,condition_placements(~S,steps,namespace,bindings,0n)}
88def conditions_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,Fields.Fields<S>>,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Comp.Evaluation<W.World<S,C,R,E>,B>,observed:Schedule.ConditionedApplication<S,C,R,E,H,Rows,observe,fold,B,select> & Maybe<&2,Schedule.ConditionDescription<S,Rows>>) -> Schedule.ConditionedApplication<S,C,R,E,H,Rows,observe,fold,B,select> & Maybe<&2,ConditionedDescription<S,Rows>>:
89 match observed:
90 case (app,None{}):(app,None{})
91 case (app,Some{Schedule.ConditionDescription{original,bindings}}):(app,Some{with_conditions(~S,~Rows,original,bindings)})
92# The standard App snapshot decides debug before any condition placement work.
93# Return the conditioned App and optional placement/condition description using
94# its existing snapshot. Debug is checked before condition placement derivation;
95# this does not execute conditions or change their actual owner state.
96def snapshot_conditions(~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,Fields.Fields<S>>,~B:Type,~select:B -> W.World<S,C,R,E> -> U32 -> Comp.Evaluation<W.World<S,C,R,E>,B>,app:Schedule.ConditionedApplication<S,C,R,E,H,Rows,observe,fold,B,select>) -> Schedule.ConditionedApplication<S,C,R,E,H,Rows,observe,fold,B,select> & Maybe<&2,ConditionedDescription<S,Rows>>:
97 conditions_returned(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~B,~select,Schedule.snapshot_conditions(~S,~C,~R,~E,~H,~Rows,~observe,~fold,~B,~select,app))