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))