ordinary_machine_transition_reader.bend

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

1import Base
2import bendvy-ecs-core@0.1.0.1/change_tick.bend as Tick
3import bendvy-ecs-core@0.1.0.1/world.bend as W
4import bendvy-ecs-core@0.1.0.1/system.bend as Sys
5import bendvy-ecs-core@0.1.0.1/system_instance.bend as SI
6import bendvy-ecs-core@0.1.0.1/system_cleanup.bend as Cleanup
7import bendvy-ecs-core@0.1.0.1/machine.bend as M
8import bendvy-ecs-core@0.1.0.1/machine_stream.bend as St
9import bendvy-ecs-core@0.1.0.1/event_runtime.bend as Ev
10import bendvy-ecs-core@0.1.0.1/ordinary_machine_initialization.bend as Resource
11import bendvy-ecs-core@0.1.0.1/ordinary_machine_declaration.bend as Machine
12
13# One schema-owned declaration binds the actual stream lens and descriptive name.
14type Declaration<-S:Data,-K:Data,-V:Data,-R:Type,-take:R -> R & St.Stream<V>,-put:R -> St.Stream<V> -> R> is Data:
15  Declaration{name:String}
16type Input<V:Data,A:Type> is Type:
17  Input{reading:Ev.Reading<M.Transition<V>>,args:A}
18type Completion<Error:Data,Out:Type> is Type:
19  CallbackSucceeded{output:Out}
20  CallbackFailed{error:Error}
21type ReadResult<-World:Type,-Reader:Type,-Args:Type,-Error:Data,-Out:Type,-V:Data> is Type:
22  ReadSucceeded{world:World,reader:Reader,output:Out,reading:Ev.Reading<M.Transition<V>>}
23  ReadFailed{world:World,reader:Reader,error:Error,reading:Ev.Reading<M.Transition<V>>}
24  ReadRejected{world:World,reader:Reader,args:Args}
25
26def validate(~S:Data,~K:Data,reader:St.Reader<S,K>,namespace:U32,id:U32) -> St.Reader<S,K> & Bool:
27  match reader:
28    case St.Reader{+actual,+key}:(St.Reader{actual,key},Bool.and(U32.is_eq(actual,namespace),U32.is_eq(key,id)))
29def create(~S:Data,~K:Data,~C:Type,~R:Type,~E:Data,namespace:U32,id:U32,world:W.World<S,C,R,E>) -> W.World<S,C,R,E> & St.Reader<S,K>:
30  (world,St.Reader{namespace,id})
31def stream_set_result(~S:Data,~C:Type,~R:Type,~E:Data,result:W.World<S,C,R,E> & Unit) -> W.World<S,C,R,E>:
32  match result:
33    case (world,_):world
34def stream_set_resource(~V:Data,~R:Type,~put:R -> St.Stream<V> -> R,stream:St.Stream<V>,resource:R) -> R & Unit:
35  (put(resource,stream),Unit{})
36def stream_set(~S:Data,~V:Data,~C:Type,~R:Type,~E:Data,~put:R -> St.Stream<V> -> R,world:W.World<S,C,R,E>,stream:St.Stream<V>) -> W.World<S,C,R,E>:
37  stream_set_result(~S,~C,~R,~E,Resource.with_resource(~S,~C,~R,~E,~Unit,(resource => stream_set_resource(~V,~R,~put,stream,resource)),world))
38def removed(~S:Data,~V:Data,~C:Type,~R:Type,~E:Data,~put:R -> St.Stream<V> -> R,id:U32,result:W.World<S,C,R,E> & St.Stream<V>) -> W.World<S,C,R,E>:
39  match result:
40    case (world,stream):stream_set(~S,~V,~C,~R,~E,~put,world,St.dispose(~V,stream,id))
41def remove(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,world:W.World<S,C,R,E>,reader:St.Reader<S,K>) -> W.World<S,C,R,E>:
42  match reader:
43    case St.Reader{_,id}:removed(~S,~V,~C,~R,~E,~put,id,W.observe_resource(~S,~C,~R,~E,~St.Stream<V>,~take,world))
44
45# Initializer declarations supply the same operational state cell and name.
46def initialized_taken(~S:Data,~K:Data,~V:Data,~R:Type,~put:R -> Resource.State<S,K,V> -> R,result:R & Resource.State<S,K,V>) -> R & St.Stream<V>:
47  match result:
48    case (resource,Resource.State{slot,+stream,revision}):(put(resource,Resource.State{slot,stream,revision}),stream)
49def initialized_take(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & Resource.State<S,K,V>,~put:R -> Resource.State<S,K,V> -> R,resource:R) -> R & St.Stream<V>:
50  initialized_taken(~S,~K,~V,~R,~put,take(resource))
51def initialized_put_taken(~S:Data,~K:Data,~V:Data,~R:Type,~put:R -> Resource.State<S,K,V> -> R,stream:St.Stream<V>,result:R & Resource.State<S,K,V>) -> R:
52  match result:
53    case (resource,Resource.State{slot,_,revision}):put(resource,Resource.State{slot,stream,revision})
54def initialized_put(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & Resource.State<S,K,V>,~put:R -> Resource.State<S,K,V> -> R,resource:R,stream:St.Stream<V>) -> R:
55  initialized_put_taken(~S,~K,~V,~R,~put,stream,take(resource))
56def from_initialization(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & Resource.State<S,K,V>,~put:R -> Resource.State<S,K,V> -> R,~declaration:Machine.Declaration<S,K,V,R,Resource.take_slot(~S,~K,~V,~R,~take,~put)>) -> Declaration<S,K,V,R,initialized_take(~S,~K,~V,~R,~take,~put),initialized_put(~S,~K,~V,~R,~take,~put)>:
57  Declaration{Machine.name(~S,~K,~V,~R,~Resource.take_slot(~S,~K,~V,~R,~take,~put),declaration)}
58
59def instance_type(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>) -> Type:SI.Instance<S,C,R,E,Input<V,A>,Error,Out,callback,St.Reader<S,K>,validate(~S,~K),remove(~S,~K,~V,~C,~R,~E,~take,~put)>
60def registration_type(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>) -> Type:SI.Registration<S,C,R,E,Input<V,A>,Error,Out,callback,St.Reader<S,K>,validate(~S,~K),remove(~S,~K,~V,~C,~R,~E,~take,~put)>
61def disposal_type(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>) -> Type:SI.Disposal<S,C,R,E,Input<V,A>,Error,Out,callback,St.Reader<S,K>,validate(~S,~K),remove(~S,~K,~V,~C,~R,~E,~take,~put)>
62def access(~S:Data,~K:Data,~V:Data,~R:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,value:Declaration<S,K,V,R,take,put>) -> List<&2,String>:
63  match value:
64    case Declaration{name}:["machine." ++ name ++ ".transition.read"]
65def register(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,~declaration:Declaration<S,K,V,R,take,put>,world:W.World<S,C,R,E>,name:String) -> registration_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback):
66  SI.register(~S,~C,~R,~E,~Input<V,A>,~Error,~Out,~callback,~St.Reader<S,K>,~validate(~S,~K),~remove(~S,~K,~V,~C,~R,~E,~take,~put),~create(~S,~K,~C,~R,~E),world,name,access(~S,~K,~V,~R,~take,~put,declaration))
67def dispose(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,reader:instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),world:W.World<S,C,R,E>) -> disposal_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback):
68  SI.dispose(~S,~C,~R,~E,~Input<V,A>,~Error,~Out,~callback,~St.Reader<S,K>,~validate(~S,~K),~remove(~S,~K,~V,~C,~R,~E,~take,~put),reader,world)
69# Unrun reader parameters neither activate nor consume unread transitions.
70def skip(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,reader:instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),world:W.World<S,C,R,E>) -> instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback) & W.World<S,C,R,E>:(reader,world)
71
72def delivered(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,reader:instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),world:W.World<S,C,R,E>,reading:Ev.Reading<M.Transition<V>>,completion:Completion<Error,Out>) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
73  match completion:
74    case CallbackSucceeded{output}:ReadSucceeded{world,reader,output,reading}
75    case CallbackFailed{error}:ReadFailed{world,reader,error,reading}
76def finished(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,registry:Sys.Registry<S,C,R,E,Input<V,A>,Error,Out,callback>,world:W.World<S,C,R,E>,reading:Ev.Reading<M.Transition<V>>,completion:Completion<Error,Out>,result:St.Reader<S,K> & St.Stream<V>) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
77  match result:
78    case (reader,stream):delivered(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,SI.Instance{Cleanup.Instance{registry,reader}},stream_set(~S,~V,~C,~R,~E,~put,world,stream),reading,completion)
79def finishing(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,reader:instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),reading:Ev.Reading<M.Transition<V>>,tick:Nat,success:Bool,completion:Completion<Error,Out>,result:W.World<S,C,R,E> & St.Stream<V>) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
80  match reader result:
81    case SI.Instance{Cleanup.Instance{registry,ports}}, (world,stream):finished(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,registry,world,reading,completion,St.finish(~S,~K,~V,ports,stream,tick,success))
82def finish(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,reader:instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),world:W.World<S,C,R,E>,reading:Ev.Reading<M.Transition<V>>,tick:Nat,success:Bool,completion:Completion<Error,Out>) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
83  finishing(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,reader,reading,tick,success,completion,W.observe_resource(~S,~C,~R,~E,~St.Stream<V>,~take,world))
84def callback_result(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,reading:Ev.Reading<M.Transition<V>>,tick:Nat,result:SI.RunResult<S,C,R,E,Input<V,A>,Error,Out,callback,St.Reader<S,K>,validate(~S,~K),remove(~S,~K,~V,~C,~R,~E,~take,~put)>) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
85  match result:
86    case SI.Completed{reader,Sys.Succeeded{world,output}}:finish(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,reader,world,reading,tick,True{},CallbackSucceeded{output})
87    case SI.Completed{reader,Sys.Failed{world,error}}:finish(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,reader,world,reading,tick,False{},CallbackFailed{error})
88    case SI.RegistrationRejected{reader,world,Input{_,args}}:ReadRejected{world,reader,args}
89def opened(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,registry:Sys.Registry<S,C,R,E,Input<V,A>,Error,Out,callback>,world:W.World<S,C,R,E>,args:A,tick:Nat,result:St.OpenResult<S,K,V>) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
90  match result:
91    case St.ReaderRefused{reader,stream}:ReadRejected{stream_set(~S,~V,~C,~R,~E,~put,world,stream),SI.Instance{Cleanup.Instance{registry,reader}},args}
92    case St.Opened{reader,stream,+reading}:callback_result(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,reading,tick,SI.run(~S,~C,~R,~E,~Input<V,A>,~Error,~Out,~callback,~St.Reader<S,K>,~validate(~S,~K),~remove(~S,~K,~V,~C,~R,~E,~take,~put),SI.Instance{Cleanup.Instance{registry,reader}},stream_set(~S,~V,~C,~R,~E,~put,world,stream),Input{reading,args}))
93def opening(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,reader:instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),args:A,+tick:Nat,result:W.World<S,C,R,E> & St.Stream<V>) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
94  match reader result:
95    case SI.Instance{Cleanup.Instance{registry,St.Reader{+namespace,id}}}, (world,stream):opened(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,registry,world,args,tick,St.open(~S,~K,~V,St.Reader{namespace,id},stream,namespace,tick))
96def clocked(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,reader:instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),args:A,result:W.World<S,C,R,E> & Tick.Tick) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
97  match result:
98    case (world,tick):opening(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,reader,args,Tick.total(tick),W.observe_resource(~S,~C,~R,~E,~St.Stream<V>,~take,world))
99def checked(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,allowed:Bool,reader:instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),args:A,result:W.World<S,C,R,E> & Bool) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
100  match allowed result:
101    case False{}, (world,_):ReadRejected{world,reader,args}
102    case True{}, (world,False{}):ReadRejected{world,reader,args}
103    case True{}, (world,True{}):clocked(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,reader,args,W.clock(~S,~C,~R,~E,world))
104def namespaced(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,reader:instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),args:A,result:W.World<S,C,R,E> & U32) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
105  match reader result:
106    case SI.Instance{Cleanup.Instance{Sys.Registry{+namespace,+id,+name,+access,cursor},St.Reader{+owner,+key}}}, (world,actual):checked(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,Bool.and(U32.is_eq(namespace,actual),Bool.and(U32.is_eq(owner,namespace),U32.is_eq(key,id))),SI.Instance{Cleanup.Instance{Sys.Registry{namespace,id,name,access,cursor},St.Reader{owner,key}}},args,W.registration_matches(~S,~C,~R,~E,world,id,name,access))
107# Namespace/registration checks precede activation, callback and any cursor change.
108def read(~S:Data,~K:Data,~V:Data,~C:Type,~R:Type,~E:Data,~A:Type,~Error:Data,~Out:Type,~take:R -> R & St.Stream<V>,~put:R -> St.Stream<V> -> R,~callback:W.World<S,C,R,E> -> Input<V,A> -> Sys.Outcome<W.World<S,C,R,E>,Error,Out>,reader:instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),world:W.World<S,C,R,E>,args:A) -> ReadResult<W.World<S,C,R,E>,instance_type(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback),A,Error,Out,V>:
109  namespaced(~S,~K,~V,~C,~R,~E,~A,~Error,~Out,~take,~put,~callback,reader,args,W.namespace(~S,~C,~R,~E,world))