1 import Base 2 import ./entity_allocator.bend as A 3 import ./relation_types.bend as T 4 import ./execution_relation_operation.bend as O 5 import ./execution_relation_interpreter.bend as I 6 import ./execution_relation_failure_message.bend as Failure 7 import ./execution_relation_failure_channel.bend as Reader 8 import ./execution_stream_channel.bend as Channel 9 import ./execution_composer_layout.bend as Layout 10 import ./change_tick.bend as Tick 11 12 # Constructors and mutation functions are trusted provisioning/barrier helpers. 13 # Gameplay receives only operations over an abstract H, never this owner. 14 type Store<-S:Data,-descriptor:T.Descriptor> is Type: 15 Store{namespace:U32,graph:T.Graph,failures:Channel.Store>,sequence:Nat,nextReader:U32} 16 type View<-S:Data,-descriptor:T.Descriptor> is Data: 17 View{namespace:U32,graph:T.Graph,failures:Channel.Store>,sequence:Nat,nextReader:U32} 18 type Reason is Data: 19 NamespaceMismatch{} 20 OperationRefused{reason:O.Reason} 21 type Receipt is Data: 22 Applied{operation:O.Operation} 23 Refused{operation:O.Operation,reason:Reason} 24 type Registration<-S:Data,-descriptor:T.Descriptor,-origin:Layout.Layout,-route:Layout.Route> is Type: 25 Registered{store:Store,reader:Reader.Reader} 26 RegistrationRefused{store:Store} 27 def fresh(~S:Data,~descriptor:T.Descriptor,namespace:U32) -> Store: 28 Store{namespace,T.Graph{[],[]},Channel.empty(~Failure.Message),0n,1} 29 def project_generic(-S:Data,-descriptor:T.Descriptor,store:Store) -> Store & View: 30 match store: 31 case Store{+namespace,+graph,+failures,+sequence,+nextReader}:(Store{namespace,graph,failures,sequence,nextReader},View{namespace,graph,failures,sequence,nextReader}) 32 def project(~S:Data,~descriptor:T.Descriptor,store:Store) -> Store & View: 33 project_generic(S,descriptor,store) 34 def published(~S:Data,~descriptor:T.Descriptor,namespace:U32,graph:T.Graph,nextReader:U32,allocator:A.Allocator,operation:O.Operation,reason:O.Reason,result:Nat & Channel.Store>) -> A.Allocator & (Store & Receipt): 35 match result: 36 case (sequence,failures):(allocator,(Store{namespace,graph,failures,sequence,nextReader},Refused{operation,OperationRefused{reason}})) 37 def publish(~S:Data,~descriptor:T.Descriptor,namespace:U32,graph:T.Graph,failures:Channel.Store>,sequence:Nat,nextReader:U32,allocator:A.Allocator,operation:O.Operation,reason:O.Reason,message:Maybe<&2,Failure.Message>) -> A.Allocator & (Store & Receipt): 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,sequence,failures,message)) 41 def interpreted(~S:Data,~descriptor:T.Descriptor,namespace:U32,failures:Channel.Store>,sequence:Nat,nextReader:U32,result:A.Allocator & O.Outcome) -> A.Allocator & (Store & Receipt): 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)) 45 def admitted(~S:Data,~descriptor:T.Descriptor,same:Bool,+namespace:U32,allocator:A.Allocator,store:Store,operation:O.Operation) -> A.Allocator & (Store & Receipt): 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)) 49 def apply(~S:Data,~descriptor:T.Descriptor,+namespace:U32,allocator:A.Allocator,store:Store,operation:O.Operation) -> A.Allocator & (Store & Receipt): 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) 52 def register_checked(~S:Data,~descriptor:T.Descriptor,~origin:Layout.Layout,~route:Layout.Route,available:Bool,store:Store) -> Registration: 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}} 56 def register(~S:Data,~descriptor:T.Descriptor,~origin:Layout.Layout,~route:Layout.Route,store:Store) -> Registration: 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}) 59 def maintained(~S:Data,~descriptor:T.Descriptor,tick:Tick.Tick,store:Store) -> Store: 60 match store: 61 case Store{namespace,graph,failures,+sequence,nextReader}:Store{namespace,graph,Channel.maintain(~Failure.Message,sequence,tick,failures),sequence,nextReader}