ordinary_app_machine.bend

bendvy-ecs-core@0.1.0.1 · 109 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.1/ordinary_machine_initialization.bend as Init
3import bendvy-ecs-core@0.1.0.1/ordinary_app_composer.bend as Build
4import bendvy-ecs-core@0.1.0.1/ordinary_app_recipe.bend as Tree
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/inspector.bend as I
9import bendvy-ecs-core@0.1.0.1/ordinary_machine_declaration.bend as OD
10import bendvy-ecs-core@0.1.0.1/ordinary_machine_operations.bend as Ops
11import bendvy-ecs-core@0.1.0.1/machine.bend as M
12import bendvy-ecs-core@0.1.0.1/capabilities.bend as Cap
13import bendvy-ecs-core@0.1.0.1/transaction.bend as T
14import bendvy-ecs-core@0.1.0.1/commands.bend as Cmd
15
16# A declaration-derived value observer, not a fabricated resource/system record.
17def current_text(~S:Data,~K:Data,~V:Data,~render:V -> String,view:M.CurrentView<S,K,V>) -> String:
18  match view:
19    case M.Unavailable{}:"Unavailable"
20    case M.Current{value}:"Current:" ++ render(value)
21# The ordered vocabulary comes from the same operational declaration. The
22# registered observer is invoked only on the enabled snapshot branch.
23def vocabulary_text(~V:Data,~render:V -> String,values:List<&2,V>) -> List<&2,String>:
24  match values:
25    case []:[]
26    case value <> rest:render(value) <> vocabulary_text(~V,~render,rest)
27def vocabulary_description(~V:Data,~render:V -> String,name:String,value:Maybe<&2,List<&2,V>>) -> List<&2,String>:
28  match value:
29    case None{}:[]
30    case Some{values}:[name ++ ":Vocabulary=" ++ List.show(&2,String,x=>x,vocabulary_text(~V,~render,values))]
31def presented(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,result:I.Frame<S,C,R,E> & M.CurrentView<S,K,V>) -> W.World<S,C,R,E> & DTO.Observation<M.CurrentView<S,K,V>>:
32  match result:
33    case (I.Frame{world,_},+view):(world,DTO.Observation{view,List.append(&2,String,[OD.name(~S,~K,~V,~R,~take,declaration) ++ ":" ++ current_text(~S,~K,~V,~render,view)],vocabulary_description(~V,~render,OD.name(~S,~K,~V,~R,~take,declaration),OD.values(~S,~K,~V,~R,~take,declaration)))})
34# Advanced declaration-derived current-value observer with detached rendering and
35# optional vocabulary. Returns World; the retained slot projector/render function
36# are trusted setup, not a newly validated arbitrary resource adapter.
37def observe(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,world:W.World<S,C,R,E>) -> W.World<S,C,R,E> & DTO.Observation<M.CurrentView<S,K,V>>:
38  presented(~S,~K,~V,~C,~R,~E,~take,~declaration,~render,OD.get(~I.Frame<S,C,R,E>,~S,~K,~V,~OD.inspect(~S,~K,~V,~C,~R,~E,~take,~declaration),I.Frame{world,None{}}))
39# Advanced observer attachment pairing prior rows with declared machine current
40# view. Retains World, registration owners and debug; does not create machine state.
41def attach(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,app:Build.Registered<S,W.World<S,C,R,E>,Owners,Rows,prior,fold>) -> Build.Registered<S,W.World<S,C,R,E>,Owners,DTO.Product<Rows,M.CurrentView<S,K,V>>,Tree.observe_pair(~W.World<S,C,R,E>,~Rows,~M.CurrentView<S,K,V>,~prior,~observe(~S,~K,~V,~C,~R,~E,~take,~declaration,~render)),fold>:
42  match app:
43    case Build.Registered{world,owners,_,debug}:Build.Registered{world,owners,Tree.Recipe{},debug}
44# Operational queue and debug current grant are generated from the SAME declaration.
45# Queue a machine request through declaration-derived write caps in one Tx, then
46# finish with the supplied outcome. Success retains queued state; failure restores
47# recorded changes. This does not commit a transition or execute handler phases;
48# vocabulary metadata is not a value-membership validation gate.
49def queue(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~Error:Data,world:W.World<S,C,R,E>,request:M.QueueInput<V>,outcome:T.Outcome<Error>) -> T.Returned<W.World<S,C,R,E>,Error>:
50  Cmd.tx_finish(~S,~C,~R,~E,~Error,Cap.value_set(~T.Tx<W.World<S,C,R,E>,E>,~M.QueueInput<V>,~M.CurrentView<S,K,V>,~Ops.write(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration),T.begin(~W.World<S,C,R,E>,~E,world),request),outcome)
51
52# Ordinary operational binding: setup derives the observer from the same declaration.
53# Composer App type adding this declaration's detached current-value observation.
54# Machine storage remains in World resources; no fabricated system owner is added.
55def Application(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>) -> Type:
56  Build.Registered<S,W.World<S,C,R,E>,Owners,DTO.Product<Rows,M.CurrentView<S,K,V>>,Tree.observe_pair(~W.World<S,C,R,E>,~Rows,~M.CurrentView<S,K,V>,~prior,~observe(~S,~K,~V,~C,~R,~E,~take,~declaration,~render)),fold>
57# Install the declaration-derived machine observer, preserving actual App owners.
58# Does not initialize state, register handlers or apply a queued transition.
59def install(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,app:Build.Registered<S,W.World<S,C,R,E>,Owners,Rows,prior,fold>) -> Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold):
60  attach(~S,~K,~V,~C,~R,~E,~take,~declaration,~render,~Owners,~Rows,~prior,~fold,app)
61def returned(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,~Error:Data,owners:Owners,recipe:Tree.Recipe<W.World<S,C,R,E>,DTO.Product<Rows,M.CurrentView<S,K,V>>,Tree.observe_pair(~W.World<S,C,R,E>,~Rows,~M.CurrentView<S,K,V>,~prior,~observe(~S,~K,~V,~C,~R,~E,~take,~declaration,~render))>,debug:Bool,result:T.Returned<W.World<S,C,R,E>,Error>) -> Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold) & T.Outcome<Error>:
62  match result:
63    case T.Returned{world,status}:(Build.Registered{world,owners,recipe,debug},status)
64# App-level queue adapter returning actual App and transaction outcome. Retains
65# observer/debug/registration owners; transition application remains explicit.
66def queue_app(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,~Error:Data,app:Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold),request:M.QueueInput<V>,outcome:T.Outcome<Error>) -> Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold) & T.Outcome<Error>:
67  match app:
68    case Build.Registered{world,owners,recipe,debug}:returned(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold,~Error,owners,recipe,debug,queue(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~Error,world,request,outcome))
69def read_finished(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,view:M.CurrentView<S,K,V>,result:Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold) & T.Outcome<Unit>) -> Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold) & M.CurrentView<S,K,V>:
70  match result:
71    case (app,_):(app,view)
72def read_taken(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,owners:Owners,recipe:Tree.Recipe<W.World<S,C,R,E>,DTO.Product<Rows,M.CurrentView<S,K,V>>,Tree.observe_pair(~W.World<S,C,R,E>,~Rows,~M.CurrentView<S,K,V>,~prior,~observe(~S,~K,~V,~C,~R,~E,~take,~declaration,~render))>,debug:Bool,result:T.Tx<W.World<S,C,R,E>,E> & M.CurrentView<S,K,V>) -> Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold) & M.CurrentView<S,K,V>:
73  match result:
74    case (frame,view):read_finished(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold,view,returned(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold,~Unit,owners,recipe,debug,Cmd.tx_finish(~S,~C,~R,~E,~Unit,frame,T.Success{})))
75# Read declared current value while returning App, without depending on debug.
76# Unavailable remains an explicit view. Does not apply queue or run handlers.
77def read_app(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,app:Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold)) -> Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold) & M.CurrentView<S,K,V>:
78  match app:
79    case Build.Registered{world,owners,recipe,debug}:read_taken(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold,owners,recipe,debug,Cap.value_read(~T.Tx<W.World<S,C,R,E>,E>,~M.CurrentView<S,K,V>,~Ops.read(~S,~K,~V,~C,~R,~E,~take,~declaration),T.begin(~W.World<S,C,R,E>,~E,world)))
80# Type spelling and snapshot assembly are generated by the operational library.
81# Advanced detached row type: prior observation paired with current machine view.
82def ObservedRows(~S:Data,~K:Data,~V:Data,~Rows:Data) -> Data:
83  DTO.Product<Rows,M.CurrentView<S,K,V>>
84# Advanced closed observer composition threading World through prior then machine.
85def observation(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>) -> W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<DTO.Product<Rows,M.CurrentView<S,K,V>>>:
86  Tree.observe_pair(~W.World<S,C,R,E>,~Rows,~M.CurrentView<S,K,V>,~prior,~observe(~S,~K,~V,~C,~R,~E,~take,~declaration,~render))
87# Advanced typed observation recipe projection, with no separate machine owner.
88def Recipe(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>) -> Type:
89  Tree.Recipe<W.World<S,C,R,E>,DTO.Product<Rows,M.CurrentView<S,K,V>>,Tree.observe_pair(~W.World<S,C,R,E>,~Rows,~M.CurrentView<S,K,V>,~prior,~observe(~S,~K,~V,~C,~R,~E,~take,~declaration,~render))>
90# Set observation flag then return optional combined snapshot with App. Disabled
91# bypasses current-value projection/rendering; no queue application or barrier.
92def snapshot_app(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & M.Slot<S,K,V>,~put:R -> M.Slot<S,K,V> -> R,~same:V -> V -> Bool,~declaration:OD.Declaration<S,K,V,R,take>,~render:V -> String,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,app:Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold),flag:Bool) -> Application(~S,~K,~V,~C,~R,~E,~take,~put,~same,~declaration,~render,~Owners,~Rows,~prior,~fold) & Maybe<&2,DTO.Product<List<&2,DTO.Binding<S>>,DTO.Observation<DTO.Product<Rows,M.CurrentView<S,K,V>>>>>:
93  Build.snapshot(~S,~W.World<S,C,R,E>,~Owners,~DTO.Product<Rows,M.CurrentView<S,K,V>>,~Tree.observe_pair(~W.World<S,C,R,E>,~Rows,~M.CurrentView<S,K,V>,~prior,~observe(~S,~K,~V,~C,~R,~E,~take,~declaration,~render)),~fold,Build.enabled(~S,~W.World<S,C,R,E>,~Owners,~DTO.Product<Rows,M.CurrentView<S,K,V>>,~Tree.observe_pair(~W.World<S,C,R,E>,~Rows,~M.CurrentView<S,K,V>,~prior,~observe(~S,~K,~V,~C,~R,~E,~take,~declaration,~render)),~fold,app,flag))
94
95# Ordinary initialization preserves the existing app's sole owners and debug recipe.
96def initialized_app(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & Init.State<S,K,V>,~put:R -> Init.State<S,K,V> -> R,~C:Type,~E:Data,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,owners:Owners,recipe:Tree.Recipe<W.World<S,C,R,E>,Rows,prior>,debug:Bool,world:W.World<S,C,R,E>) -> Build.Registered<S,W.World<S,C,R,E>,Owners,Rows,prior,fold>:
97  Build.Registered{world,owners,recipe,debug}
98# Initialize missing state from make; already-present state skips make. Preserve
99# actual App owners/recipe/debug. Uses ordinary initialization and its initial
100# publication/revision semantics, not handler execution or generic undo recovery.
101def init_app(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & Init.State<S,K,V>,~put:R -> Init.State<S,K,V> -> R,~C:Type,~E:Data,~declaration:OD.Declaration<S,K,V,R,Init.take_slot(~S,~K,~V,~R,~take,~put)>,~make:W.World<S,C,R,E> -> W.World<S,C,R,E> & V,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,app:Build.Registered<S,W.World<S,C,R,E>,Owners,Rows,prior,fold>) -> Build.Registered<S,W.World<S,C,R,E>,Owners,Rows,prior,fold>:
102  match app:
103    case Build.Registered{world,owners,recipe,debug}:initialized_app(~S,~K,~V,~R,~take,~put,~C,~E,~Owners,~Rows,~prior,~fold,owners,recipe,debug,Init.init_state(~S,~K,~V,~R,~take,~put,~C,~E,~declaration,~make,world))
104# Explicitly insert/replace state value through ordinary initialization storage.
105# Preserve App owners; occupied insertion resets transition messages under the
106# existing insertion contract. This is distinct from a queued transition request.
107def insert_app(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & Init.State<S,K,V>,~put:R -> Init.State<S,K,V> -> R,~C:Type,~E:Data,~declaration:OD.Declaration<S,K,V,R,Init.take_slot(~S,~K,~V,~R,~take,~put)>,~Owners:Type,~Rows:Data,~prior:W.World<S,C,R,E> -> W.World<S,C,R,E> & DTO.Observation<Rows>,~fold:Owners -> Owners & List<&2,Fields.Fields<S>>,app:Build.Registered<S,W.World<S,C,R,E>,Owners,Rows,prior,fold>,value:V) -> Build.Registered<S,W.World<S,C,R,E>,Owners,Rows,prior,fold>:
108  match app:
109    case Build.Registered{world,owners,recipe,debug}:initialized_app(~S,~K,~V,~R,~take,~put,~C,~E,~Owners,~Rows,~prior,~fold,owners,recipe,debug,Init.insert_state(~S,~K,~V,~R,~take,~put,~C,~E,~declaration,world,value))