execution_command_removed.bend

bendvy-ecs-core@0.1.0.3 · 63 lines · 13 definitions

1import Base
2import bendvy-ecs-core@0.1.0.3/execution_resource_policy.bend as Policy
3import bendvy-ecs-core@0.1.0.3/execution_lifecycle_notices.bend as Notice
4import bendvy-ecs-core@0.1.0.3/change_tick.bend as Tick
5import bendvy-ecs-core@0.1.0.3/execution_composer_layout.bend as Layout
6import bendvy-ecs-core@0.1.0.3/chunk_column.bend as Column
7import bendvy-ecs-core@0.1.0.3/owner_product.bend as Product
8
9# Structural receipts retain each actual raw owner, including unlike affine
10# families. Removing a cached row never invokes its refresher.
11def Removed(layout:Layout.Layout) -> Type:
12  match layout:
13    case Layout.EmptyLayout{}:Unit
14    case Layout.LayoutLeaf{P,_,_,_,_}:Maybe<&1,P>
15    case Layout.ClassifiedLayoutLeaf{P,_,_,_,_,_}:Maybe<&1,P>
16    case Layout.LayoutPair{left,right}:Product.Owner<Removed(left),Removed(right)>
17def raw(-P:Type,-V:Data,value:Maybe<&1,Layout.Viewed<P,V>>) -> Maybe<&1,P>:
18  match value:
19    case None{}:None{}
20    case Some{Layout.Viewed{owner,_}}:Some{owner}
21def leaf_done(~S:Data,-P:Type,-V:Data,-key:String,-origin:Layout.Layout,result:Column.Column<S,Layout.Viewed<P,V>> & Maybe<&1,Layout.Viewed<P,V>>) -> Layout.ColumnSlot<S,Layout.Viewed<P,V>,key,origin> & Maybe<&1,P>:
22  match result:
23    case (column,previous):(Layout.ColumnSlot{column},raw(P,V,previous))
24def leaf(~S:Data,-P:Type,-V:Data,-key:String,-origin:Layout.Layout,index:U32,slot:Layout.ColumnSlot<S,Layout.Viewed<P,V>,key,origin>) -> Layout.ColumnSlot<S,Layout.Viewed<P,V>,key,origin> & Maybe<&1,P>:
25  match slot:
26    case Layout.ColumnSlot{column}:leaf_done(~S,P,V,key,origin,Column.take(S,Layout.Viewed<P,V>,column,index))
27def joined(~S:Data,-left:Layout.Layout,-right:Layout.Layout,leftOwner:Layout.columns(~S,left),removed:Removed(left),result:Layout.columns(~S,right) & Removed(right)) -> Product.Owner<Layout.columns(~S,left),Layout.columns(~S,right)> & Product.Owner<Removed(left),Removed(right)>:
28  match result:
29    case (rightOwner,rightRemoved):(Product.Owner{leftOwner,rightOwner},Product.Owner{removed,rightRemoved})
30def took_left(~S:Data,-left:Layout.Layout,-right:Layout.Layout,takeRight:U32 -> Layout.columns(~S,right) -> Layout.columns(~S,right) & Removed(right),index:U32,rightOwner:Layout.columns(~S,right),result:Layout.columns(~S,left) & Removed(left)) -> Product.Owner<Layout.columns(~S,left),Layout.columns(~S,right)> & Product.Owner<Removed(left),Removed(right)>:
31  match result:
32    case (leftOwner,removed):joined(~S,left,right,leftOwner,removed,takeRight(index,rightOwner))
33def pair(~S:Data,-left:Layout.Layout,-right:Layout.Layout,takeLeft:U32 -> Layout.columns(~S,left) -> Layout.columns(~S,left) & Removed(left),takeRight:U32 -> Layout.columns(~S,right) -> Layout.columns(~S,right) & Removed(right),+index:U32,owner:Product.Owner<Layout.columns(~S,left),Layout.columns(~S,right)>) -> Product.Owner<Layout.columns(~S,left),Layout.columns(~S,right)> & Product.Owner<Removed(left),Removed(right)>:
34  match owner:
35    case Product.Owner{leftOwner,rightOwner}:took_left(~S,left,right,takeRight,index,rightOwner,takeLeft(index,leftOwner))
36def take(~S:Data,layout:Layout.Layout) -> U32 -> Layout.columns(~S,layout) -> Layout.columns(~S,layout) & Removed(layout):
37  match layout:
38    case Layout.EmptyLayout{}:index => owner => (owner,Unit{})
39    case Layout.LayoutLeaf{P,V,refresh,key,accessPolicy}:leaf(~S,P,V,key,Layout.LayoutLeaf{P,V,refresh,key,accessPolicy})
40    case Layout.ClassifiedLayoutLeaf{P,V,refresh,key,policy,accessPolicy}:leaf(~S,P,V,key,Layout.ClassifiedLayoutLeaf{P,V,refresh,key,policy,accessPolicy})
41    case Layout.LayoutPair{left,right}:index => owner => pair(~S,left,right,take(~S,left),take(~S,right),index,owner)
42
43# Inspect actual displaced owners once and return those same owners. No cached
44# view or presence metadata can manufacture a removal notice or refresh payloads.
45def noticed_leaf(~S:Data,-P:Type,key:String,entity:Notice.Identity<S>,tick:Tick.Tick,journal:Notice.Journal<S>,removed:Maybe<&1,P>) -> Notice.Journal<S> & Maybe<&1,P>:
46  match removed:
47    case None{}:(journal,None{})
48    case Some{owner}:(Notice.append(~S,Notice.Removed{key},entity,tick,journal),Some{owner})
49def noticed_right(~S:Data,-left:Layout.Layout,-right:Layout.Layout,leftOwner:Removed(left),result:Notice.Journal<S> & Removed(right)) -> Notice.Journal<S> & Removed(Layout.LayoutPair{left,right}):
50  match result:
51    case (journal,rightOwner):(journal,Product.Owner{leftOwner,rightOwner})
52def noticed_left(~S:Data,-left:Layout.Layout,-right:Layout.Layout,noticeRight:Notice.Identity<S> -> Tick.Tick -> Notice.Journal<S> -> Removed(right) -> Notice.Journal<S> & Removed(right),entity:Notice.Identity<S>,tick:Tick.Tick,rightOwner:Removed(right),result:Notice.Journal<S> & Removed(left)) -> Notice.Journal<S> & Removed(Layout.LayoutPair{left,right}):
53  match result:
54    case (journal,leftOwner):noticed_right(~S,left,right,leftOwner,noticeRight(entity,tick,journal,rightOwner))
55def noticed_pair(~S:Data,-left:Layout.Layout,-right:Layout.Layout,noticeLeft:Notice.Identity<S> -> Tick.Tick -> Notice.Journal<S> -> Removed(left) -> Notice.Journal<S> & Removed(left),noticeRight:Notice.Identity<S> -> Tick.Tick -> Notice.Journal<S> -> Removed(right) -> Notice.Journal<S> & Removed(right),+entity:Notice.Identity<S>,+tick:Tick.Tick,journal:Notice.Journal<S>,removed:Removed(Layout.LayoutPair{left,right})) -> Notice.Journal<S> & Removed(Layout.LayoutPair{left,right}):
56  match removed:
57    case Product.Owner{leftOwner,rightOwner}:noticed_left(~S,left,right,noticeRight,entity,tick,rightOwner,noticeLeft(entity,tick,journal,leftOwner))
58def notices(~S:Data,layout:Layout.Layout) -> Notice.Identity<S> -> Tick.Tick -> Notice.Journal<S> -> Removed(layout) -> Notice.Journal<S> & Removed(layout):
59  match layout:
60    case Layout.EmptyLayout{}:entity => tick => journal => removed => (journal,removed)
61    case Layout.LayoutLeaf{P,_,_,key,_}:noticed_leaf(~S,P,key)
62    case Layout.ClassifiedLayoutLeaf{P,_,_,key,_,_}:noticed_leaf(~S,P,key)
63    case Layout.LayoutPair{left,right}:entity => tick => journal => removed => noticed_pair(~S,left,right,notices(~S,left),notices(~S,right),entity,tick,journal,removed)