execution_relation_store.bend
bendvy-ecs-core@0.1.0.3 · 61 lines · 16 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/entity_allocator.bend as A
3import bendvy-ecs-core@0.1.0.3/relation_types.bend as T
4import bendvy-ecs-core@0.1.0.3/execution_relation_operation.bend as O
5import bendvy-ecs-core@0.1.0.3/execution_relation_interpreter.bend as I
6import bendvy-ecs-core@0.1.0.3/execution_relation_failure_message.bend as Failure
7import bendvy-ecs-core@0.1.0.3/execution_relation_failure_channel.bend as Reader
8import bendvy-ecs-core@0.1.0.3/execution_stream_channel.bend as Channel
9import bendvy-ecs-core@0.1.0.3/execution_composer_layout.bend as Layout
10import bendvy-ecs-core@0.1.0.3/change_tick.bend as Tick
11
12
13
14type Store<-S:Data,-descriptor:T.Descriptor<S>> is Type:
15 Store{namespace:U32,graph:T.Graph<S>,failures:Channel.Store<Failure.Message<S,descriptor>>,sequence:Nat,nextReader:U32}
16type View<-S:Data,-descriptor:T.Descriptor<S>> is Data:
17 View{namespace:U32,graph:T.Graph<S>,failures:Channel.Store<Failure.Message<S,descriptor>>,sequence:Nat,nextReader:U32}
18type Reason is Data:
19 NamespaceMismatch{}
20 OperationRefused{reason:O.Reason}
21type Receipt<S:Data> is Data:
22 Applied{operation:O.Operation<S>}
23 Refused{operation:O.Operation<S>,reason:Reason}
24type Registration<-S:Data,-descriptor:T.Descriptor<S>,-origin:Layout.Layout,-route:Layout.Route> is Type:
25 Registered{store:Store<S,descriptor>,reader:Reader.Reader<S,descriptor,origin,route>}
26 RegistrationRefused{store:Store<S,descriptor>}
27def fresh(~S:Data,~descriptor:T.Descriptor<S>,namespace:U32) -> Store<S,descriptor>:
28 Store{namespace,T.Graph{[],[]},Channel.empty(~Failure.Message<S,descriptor>),0n,1}
29def project_generic(-S:Data,-descriptor:T.Descriptor<S>,store:Store<S,descriptor>) -> Store<S,descriptor> & View<S,descriptor>:
30 match store:
31 case Store{+namespace,+graph,+failures,+sequence,+nextReader}:(Store{namespace,graph,failures,sequence,nextReader},View{namespace,graph,failures,sequence,nextReader})
32def project(~S:Data,~descriptor:T.Descriptor<S>,store:Store<S,descriptor>) -> Store<S,descriptor> & View<S,descriptor>:
33 project_generic(S,descriptor,store)
34def published(~S:Data,~descriptor:T.Descriptor<S>,namespace:U32,graph:T.Graph<S>,nextReader:U32,allocator:A.Allocator,operation:O.Operation<S>,reason:O.Reason,result:Nat & Channel.Store<Failure.Message<S,descriptor>>) -> A.Allocator & (Store<S,descriptor> & Receipt<S>):
35 match result:
36 case (sequence,failures):(allocator,(Store{namespace,graph,failures,sequence,nextReader},Refused{operation,OperationRefused{reason}}))
37def publish(~S:Data,~descriptor:T.Descriptor<S>,namespace:U32,graph:T.Graph<S>,failures:Channel.Store<Failure.Message<S,descriptor>>,sequence:Nat,nextReader:U32,allocator:A.Allocator,operation:O.Operation<S>,reason:O.Reason,message:Maybe<&2,Failure.Message<S,descriptor>>) -> A.Allocator & (Store<S,descriptor> & Receipt<S>):
38 match message:
39 case None{}:(allocator,(Store{namespace,graph,failures,sequence,nextReader},Refused{operation,OperationRefused{reason}}))
40 case Some{message}:published(~S,~descriptor,namespace,graph,nextReader,allocator,operation,reason,Channel.push(~Failure.Message<S,descriptor>,sequence,failures,message))
41def interpreted(~S:Data,~descriptor:T.Descriptor<S>,namespace:U32,failures:Channel.Store<Failure.Message<S,descriptor>>,sequence:Nat,nextReader:U32,result:A.Allocator & O.Outcome<S>) -> A.Allocator & (Store<S,descriptor> & Receipt<S>):
42 match result:
43 case (allocator,O.Applied{graph,operation}):(allocator,(Store{namespace,graph,failures,sequence,nextReader},Applied{operation}))
44 case (allocator,O.Refused{graph,+operation,+reason}):publish(~S,~descriptor,namespace,graph,failures,sequence,nextReader,allocator,operation,reason,Failure.refused(~S,~descriptor,operation,reason))
45def admitted(~S:Data,~descriptor:T.Descriptor<S>,same:Bool,+namespace:U32,allocator:A.Allocator,store:Store<S,descriptor>,operation:O.Operation<S>) -> A.Allocator & (Store<S,descriptor> & Receipt<S>):
46 match same store:
47 case False{} store:(allocator,(store,Refused{operation,NamespaceMismatch{}}))
48 case True{} Store{_,graph,failures,sequence,nextReader}:interpreted(~S,~descriptor,namespace,failures,sequence,nextReader,I.apply(~S,~descriptor,namespace,allocator,graph,operation))
49def apply(~S:Data,~descriptor:T.Descriptor<S>,+namespace:U32,allocator:A.Allocator,store:Store<S,descriptor>,operation:O.Operation<S>) -> A.Allocator & (Store<S,descriptor> & Receipt<S>):
50 match store:
51 case Store{+storedNamespace,graph,failures,sequence,nextReader}:admitted(~S,~descriptor,U32.is_eq(namespace,storedNamespace),namespace,allocator,Store{storedNamespace,graph,failures,sequence,nextReader},operation)
52def register_checked(~S:Data,~descriptor:T.Descriptor<S>,~origin:Layout.Layout,~route:Layout.Route,available:Bool,store:Store<S,descriptor>) -> Registration<S,descriptor,origin,route>:
53 match available store:
54 case False{} store:RegistrationRefused{store}
55 case True{} Store{+namespace,graph,failures,sequence,+nextReader}:Registered{Store{namespace,graph,failures,sequence,(nextReader + 1 : U32)},Reader.Reader{namespace,nextReader,0n}}
56def register(~S:Data,~descriptor:T.Descriptor<S>,~origin:Layout.Layout,~route:Layout.Route,store:Store<S,descriptor>) -> Registration<S,descriptor,origin,route>:
57 match store:
58 case Store{namespace,graph,failures,sequence,+nextReader}:register_checked(~S,~descriptor,~origin,~route,U32.is_lt(nextReader,4294967295),Store{namespace,graph,failures,sequence,nextReader})
59def maintained(~S:Data,~descriptor:T.Descriptor<S>,tick:Tick.Tick,store:Store<S,descriptor>) -> Store<S,descriptor>:
60 match store:
61 case Store{namespace,graph,failures,+sequence,nextReader}:Store{namespace,graph,Channel.maintain(~Failure.Message<S,descriptor>,sequence,tick,failures),sequence,nextReader}