1 import Base 2 import ./ordinary_condition_composition.bend as Comp 3 import ./ordinary_app_schedule.bend as Schedule 4 import ./ordinary_app_schema.bend as SchemaApp 5 import ./ordinary_app_observation_data.bend as DTO 6 import ./ordinary_app_registration_fields.bend as Fields 7 import ./world.bend as W 8 import ./schedule.bend as Sch 9 import ./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. 15 type Placement is Data: 16 System{position:Nat,namespace:U32,id:U32,name:Maybe<&2,String>,condition:U32,requirements:List<&2,SP.Requirement>} 17 Phase{position:Nat,name:String,requirements:List<&2,SP.Requirement>} 18 Barrier{position:Nat,requirements:List<&2,SP.Requirement>} 19 # Preserve the original single-schedule description with derived ordered 20 # placements. No new runtime state or gameplay capability is introduced. 21 type Description is Data: 22 Description{original:Schedule.Description,placements:List<&2,Placement>} 23 def 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. 28 def binding_name(~S:Data,+namespace:U32,+id:U32,bindings:List<&2,DTO.Binding>) -> 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)) 32 def step(~S:Data,+namespace:U32,bindings:List<&2,DTO.Binding>,position:Nat,planned:Schedule.PlannedStep) -> Placement: 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. 39 def placed(~S:Data,steps:List<&2,Schedule.PlannedStep>,+namespace:U32,+bindings:List<&2,DTO.Binding>,+position:Nat) -> List<&2,Placement>: 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. 45 def described(~S:Data,~Rows:Data,+description:Schedule.Description) -> Description: 46 match description: 47 case Schedule.Description{SchemaApp.Description{_,DTO.Product{bindings,_}},namespace,_,steps}:Description{description,placed(~S,steps,namespace,bindings,0n)} 48 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,Fields.Fields>,result:Schedule.Application & Maybe<&2,Schedule.Description>) -> Schedule.Application & Maybe<&2,Description>: 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. 56 def snapshot(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World -> W.World & DTO.Observation,~fold:H -> H & List<&2,Fields.Fields>,app:Schedule.Application) -> Schedule.Application & Maybe<&2,Description>: 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. 61 type 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. 65 type ConditionedDescription is Data: 66 ConditionedDescription{original:Description,bindings:List<&2,Comp.BindingDescription>,placements:List<&2,ConditionPlacement>} 67 def 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 71 def 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)) 75 def condition_step(~S:Data,namespace:U32,bindings:List<&2,Comp.BindingDescription>,position:Nat,planned:Schedule.PlannedStep) -> 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 _ :[] 79 def condition_placements(~S:Data,steps:List<&2,Schedule.PlannedStep>,+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. 85 def with_conditions(~S:Data,~Rows:Data,+original:Schedule.Description,+bindings:List<&2,Comp.BindingDescription>) -> ConditionedDescription: 86 match original: 87 case Schedule.Description{_,namespace,_,steps}:ConditionedDescription{described(~S,~Rows,original),bindings,condition_placements(~S,steps,namespace,bindings,0n)} 88 def conditions_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,Fields.Fields>,~B:Type,~select:B -> W.World -> U32 -> Comp.Evaluation,B>,observed:Schedule.ConditionedApplication & Maybe<&2,Schedule.ConditionDescription>) -> Schedule.ConditionedApplication & Maybe<&2,ConditionedDescription>: 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. 96 def snapshot_conditions(~S:Data,~C:Type,~R:Type,~E:Data,~H:Type,~Rows:Data,~observe:W.World -> W.World & DTO.Observation,~fold:H -> H & List<&2,Fields.Fields>,~B:Type,~select:B -> W.World -> U32 -> Comp.Evaluation,B>,app:Schedule.ConditionedApplication) -> Schedule.ConditionedApplication & Maybe<&2,ConditionedDescription>: 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))