1 import Base 2 import ../change_tick.bend as Tick 3 import ../clock_state.bend as Clock 4 import ../world.bend as W 5 import ../entity_allocator.bend as A 6 import ../transaction.bend as T 7 import ../trace_facts.bend as Facts 8 import ../deferred_command.bend as Deferred 9 import ../compose.bend as Q 10 import ../component.bend as C 11 import ../column.bend as Col 12 import ./query_read_session.bend as Session 13 14 # Read operations retain this affine shell without inspecting its fields. 15 type Shell<-S:Data,-Store:Type,-R:Type,-E:Data> is Type: 16 Shell{resource:R,worldEvents:List<&2,E>,pending:List>>,registrations:List<&2,W.RegistrationMeta>,nextSystemId:U32,clock:Clock.State,undo:List<(W.World -> W.World)>,commands:List>>,events:List<&2,E>,trace:Facts.State} 17 type Frame<-S:Data,-Store:Type,-R:Type,-E:Data> is Type: 18 Frame{namespace:U32,allocator:A.Allocator,store:Store,handle:W.Handle,error:Maybe<&2,W.WorldError>,cursor:Maybe<&2,Tick.Tick>,shell:Shell} 19 def extract(~S:Data,~Store:Type,~R:Type,~E:Data,frame:Q.Frame) -> Frame: 20 match frame: 21 case Q.Frame{T.Tx{W.World{namespace,allocator,store,resource,worldEvents,pending,registrations,nextSystemId,clock},undo,commands,events,trace},handle,error,cursor}:Frame{namespace,allocator,store,handle,error,cursor,Shell{resource,worldEvents,pending,registrations,nextSystemId,clock,undo,commands,events,trace}} 22 def restore(~S:Data,~Store:Type,~R:Type,~E:Data,frame:Frame) -> Q.Frame: 23 match frame: 24 case Frame{namespace,allocator,store,handle,error,cursor,Shell{resource,worldEvents,pending,registrations,nextSystemId,clock,undo,commands,events,trace}}:Q.Frame{T.Tx{W.World{namespace,allocator,store,resource,worldEvents,pending,registrations,nextSystemId,clock},undo,commands,events,trace},handle,error,cursor} 25 26 def extract_value(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,observed:Q.Frame & V) -> Frame & V: 27 match observed: 28 case (frame,value):(extract(~S,~Store,~R,~E,frame),value) 29 def bridge_get(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,~get:Q.Frame -> Q.Frame & V,frame:Frame) -> Frame & V: 30 extract_value(~S,~Store,~R,~E,~V,get(restore(~S,~Store,~R,~E,frame))) 31 def bridge_set(~S:Data,~Store:Type,~R:Type,~E:Data,~P:Type,~set:Q.Frame -> P -> Q.Frame,frame:Frame,value:P) -> Frame: 32 extract(~S,~Store,~R,~E,set(restore(~S,~Store,~R,~E,frame),value)) 33 34 def read_returned(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,handle:W.Handle,error:Maybe<&2,W.WorldError>,shell:Shell,observed:Session.Owner & C.Access) -> Frame & C.Access: 35 match observed: 36 case (Session.Owner{namespace,allocator,store,cursor},value):(Frame{namespace,allocator,store,handle,error,cursor,shell},value) 37 def read(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~take:Store -> Rest & Col.Column,~put:Rest -> Col.Column -> Store,~view:P -> P & V,frame:Frame) -> Frame & C.Access: 38 match frame: 39 case Frame{namespace,allocator,store,+handle,error,cursor,shell}:read_returned(~S,~Store,~R,~E,~V,handle,error,shell,Session.read(~S,~Store,~Rest,~P,~V,~take,~put,~view,Session.Owner{namespace,allocator,store,cursor},handle)) 40 def selected(~S:Data,~Store:Type,~R:Type,~E:Data,~V:Data,mode:Q.Selection,observed:Frame & C.Access) -> Frame & Bool: 41 match observed: 42 case (frame,value):(frame,Q.selected_value(~V,mode,value)) 43 def family_match(~S:Data,~Store:Type,~R:Type,~E:Data,~Rest:Type,~P:Type,~V:Data,~take:Store -> Rest & Col.Column,~put:Rest -> Col.Column -> Store,~view:P -> P & V,~mode:Q.Selection,frame:Frame) -> Frame & Bool: 44 selected(~S,~Store,~R,~E,~V,mode,read(~S,~Store,~R,~E,~Rest,~P,~V,~take,~put,~view,frame)) 45 def all(~S:Data,~Store:Type,~R:Type,~E:Data,frame:Frame) -> Frame & Bool: 46 (frame,True{}) 47 def and_selected(~S:Data,~Store:Type,~R:Type,~E:Data,~right:Frame -> Frame & Bool,observed:Frame & Bool) -> Frame & Bool: 48 match observed: 49 case (frame,False{}):(frame,False{}) 50 case (frame,True{}):right(frame) 51 def both(~S:Data,~Store:Type,~R:Type,~E:Data,~left:Frame -> Frame & Bool,~right:Frame -> Frame & Bool,frame:Frame) -> Frame & Bool: 52 and_selected(~S,~Store,~R,~E,~right,left(frame))