1 import Base 2 import relation_failure_runtime.bend as K 3 import internal/relation_failures/domains.bend as D 4 import world.bend as W 5 import system.bend as Sy 6 import event_runtime.bend as Ev 7 8 # Supplemental owned Bend contract: pinned TS has no public unregister method. 9 # Release stream membership only after actual successful Sy.dispose. 10 type Disposal -> K.Input -> Sy.Outcome,Error,O>> is Type: 11 ReaderDisposed{runtime: K.Runtime} 12 ReaderDisposalRejected{runtime: K.Runtime,reader: K.Reader} 13 14 def keep(found: Bool,id: U32,rest: List<&2,U32>) -> List<&2,U32>: 15 match found: 16 case True{}: rest 17 case False{}: id <> rest 18 19 def remove(ids: List<&2,U32>,+wanted: U32) -> List<&2,U32>: 20 match ids: 21 case []: [] 22 case +id <> rest: keep(U32.is_eq(id,wanted),id,remove(rest,wanted)) 23 24 def release(~S: Data,~E: Data,domains: List<&2,D.Domain>,+id: U32) -> List<&2,D.Domain>: 25 match domains: 26 case []: [] 27 case D.Domain{key,queue,ids} <> rest: D.Domain{key,queue,remove(ids,id)} <> release(~S,~E,rest,id) 28 29 def completed(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World -> K.Input -> Sy.Outcome,Error,O>,result: Sy.Disposal,Error,O,runner>,keys: List<&2,D.DescriptorKey>,domains: List<&2,D.Domain>,positions: List<&2,Ev.Position>,+id: U32,+tick: Nat,frameStart: Nat,boundary: Nat,capacity: Nat,+nextReader: U32) -> Disposal: 30 match result: 31 case Sy.Disposed{world}: ReaderDisposed{K.Runtime{world,release(~S,~E,domains,id),Ev.update(positions,id,tick,True{}),tick,frameStart,boundary,capacity,nextReader}} 32 case Sy.DisposalRejected{world,registry}: ReaderDisposalRejected{K.Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader},K.Reader{registry,keys,id}} 33 34 def identified(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World -> K.Input -> Sy.Outcome,Error,O>,runtime: K.Runtime,identity: Sy.Registry,Error,O,runner> & U32,keys: List<&2,D.DescriptorKey>) -> Disposal: 35 match runtime: 36 case K.Runtime{world,domains,positions,tick,frameStart,boundary,capacity,nextReader}: 37 (registry,+id) = identity 38 completed(~S,~C,~R,~E,~A,~Error,~O,~runner,Sy.dispose(~S,~C,~R,~E,~K.Input,~Error,~O,~runner,registry,world),keys,domains,positions,id,tick,frameStart,boundary,capacity,nextReader) 39 40 def dispose(~S: Data,~C: Type,~R: Type,~E: Data,~A: Type,~Error: Data,~O: Type,~runner: W.World -> K.Input -> Sy.Outcome,Error,O>,runtime: K.Runtime,reader: K.Reader) -> Disposal: 41 match reader: 42 case K.Reader{registry,keys,id}: identified(~S,~C,~R,~E,~A,~Error,~O,~runner,runtime,(registry,id),keys)