execution_declaration.bend

bendvy-ecs-core@0.1.0.3 · 95 lines · 24 definitions

1import Base
2import bendvy-ecs-core@0.1.0.3/execution_state_effect.bend as StateEffect
3import bendvy-ecs-core@0.1.0.3/execution_reservation_authority.bend as Effect
4import bendvy-ecs-core@0.1.0.3/execution_state.bend as State
5import bendvy-ecs-core@0.1.0.3/capabilities.bend as Cap
6import bendvy-ecs-core@0.1.0.3/execution_query_recipe.bend as Recipe
7import bendvy-ecs-core@0.1.0.3/execution_resource_recipe.bend as Resources
8
9type Mode is Data:
10  Exclusive{}
11  SharedView{}
12type Permission is Data:
13  ReadOnly{}
14  Writable{}
15type AccessKind is Data:
16  ComponentAccess{}
17  ResourceAccess{}
18  ServiceAccess{}
19  LifecycleAccess{}
20type Access is Data:
21  Access{key:String,kind:AccessKind,mode:Mode,permission:Permission}
22def keys(accesses:List<&2,Access>) -> List<&2,String>:
23  match accesses:
24    case []:[]
25    case Access{key,_,_,_} <> rest:key <> keys(rest)
26
27type Declaration<-S:Data,-C:Type,-R:Type,-Ops:Type -> Type> is Type:
28  Declaration{caps:Ops(State.Scope<S,C,R>),access:List<&2,Access>}
29def access(~S:Data,~C:Type,~R:Type,~Ops:Type -> Type,value:Declaration<S,C,R,Ops>) -> List<&2,String>:
30  match value:
31    case Declaration{_,access}:keys(access)
32def grants(~S:Data,~C:Type,~R:Type,~Ops:Type -> Type,value:Declaration<S,C,R,Ops>) -> Ops(State.Scope<S,C,R>):
33  match value:
34    case Declaration{caps,_}:caps
35def Combined(~L:Type -> Type,~R:Type -> Type,H:Type) -> Type:
36  Cap.Bundle<L(H),R(H)>
37def paired(~S:Data,~C:Type,~R:Type,~L:Type -> Type,~Right:Type -> Type,left:Declaration<S,C,R,L>,right:Declaration<S,C,R,Right>) -> Declaration<S,C,R,Combined(~L,~Right)>:
38  match left right:
39    case Declaration{lc,la} Declaration{rc,ra}:Declaration{Cap.Bundle{lc,rc},List.append(&2,Access,la,ra)}
40
41def requirements(~S:Data,~C:Type,~R:Type,~Ops:Type -> Type,value:Declaration<S,C,R,Ops>) -> List<&2,Access>:
42  match value:
43    case Declaration{_,access}:access
44
45def requirement_key(kind:AccessKind,key:String) -> String:
46  match kind:
47    case ComponentAccess{}:"component/" ++ key
48    case ResourceAccess{}:"resource/" ++ key
49    case ServiceAccess{}:"service/" ++ key
50    case LifecycleAccess{}:"lifecycle/" ++ key
51def qualified(accesses:List<&2,Access>) -> List<&2,String>:
52  match accesses:
53    case []:[]
54    case Access{_,LifecycleAccess{},_,_} <> rest:qualified(rest)
55    case Access{key,kind,_,_} <> rest:requirement_key(kind,key) <> qualified(rest)
56def requirement_keys(~S:Data,~C:Type,~R:Type,~Ops:Type -> Type,value:Declaration<S,C,R,Ops>) -> List<&2,String>:
57  qualified(requirements(~S,~C,~R,~Ops,value))
58def permitted_read(permission:Permission) -> Bool:
59  match permission:
60    case ReadOnly{}:True{}
61    case Writable{}:False{}
62def read_only(accesses:List<&2,Access>) -> Bool:
63  match accesses:
64    case []:True{}
65    case Access{_,_,_,permission} <> rest:Bool.and(permitted_read(permission),read_only(rest))
66
67# Generalized declarations retain symbolic recipes until actual admission.
68# Unsupported construction inventory cannot be converted to Declaration/grants.
69type Recipes<-S:Data,-WC:Type> is Data:
70  Recipes{queries:List<&2,Recipe.Recipe<S,WC>>,resources:List<&2,Resources.Entry>}
71type Compilation<-S:Data,-WC:Type,-C:Type,-R:Type,-Ops:Data -> (Type -> Type) -> Type -> Type> is Type:
72  Supported{declaration:Declaration<S,C,R,Ops(Effect.Granted,StateEffect.Transition(~State.Invocation<S>))>,recipes:Recipes<S,WC>}
73  Unsupported{caps:Ops(Effect.Granted,StateEffect.Transition(~State.Invocation<S>),State.Scope<S,C,R>),access:List<&2,Access>,recipes:Recipes<S,WC>}
74def compilation_supported(~S:Data,~WC:Type,~C:Type,~R:Type,~Ops:Data -> (Type -> Type) -> Type -> Type,value:Compilation<S,WC,C,R,Ops>) -> Bool:
75  match value:
76    case Supported{_,_}:True{}
77    case Unsupported{_,_,_}:False{}
78def compilation_requirements(~S:Data,~WC:Type,~C:Type,~R:Type,~Ops:Data -> (Type -> Type) -> Type -> Type,value:Compilation<S,WC,C,R,Ops>) -> List<&2,Access>:
79  match value:
80    case Supported{Declaration{_,access},_}:access
81    case Unsupported{_,access,_}:access
82def compilation_access(~S:Data,~WC:Type,~C:Type,~R:Type,~Ops:Data -> (Type -> Type) -> Type -> Type,value:Compilation<S,WC,C,R,Ops>) -> List<&2,String>:
83  keys(compilation_requirements(~S,~WC,~C,~R,~Ops,value))
84def compilation_requirement_keys(~S:Data,~WC:Type,~C:Type,~R:Type,~Ops:Data -> (Type -> Type) -> Type -> Type,value:Compilation<S,WC,C,R,Ops>) -> List<&2,String>:
85  qualified(compilation_requirements(~S,~WC,~C,~R,~Ops,value))
86def compilation_read_only(~S:Data,~WC:Type,~C:Type,~R:Type,~Ops:Data -> (Type -> Type) -> Type -> Type,value:Compilation<S,WC,C,R,Ops>) -> Bool:
87  match value:
88    case Supported{Declaration{_,access},_}:read_only(access)
89    case Unsupported{_,_,_}:False{}
90# Trusted static construction projection. Calling this does not admit execution;
91# factories must pattern-match the same Compilation before registration or body.
92def trusted_construction_caps(~S:Data,~WC:Type,~C:Type,~R:Type,~Ops:Data -> (Type -> Type) -> Type -> Type,compilation:Compilation<S,WC,C,R,Ops>) -> Ops(Effect.Granted,StateEffect.Transition(~State.Invocation<S>),State.Scope<S,C,R>):
93  match compilation:
94    case Unsupported{caps,_,_}:caps
95    case Supported{Declaration{caps,_},_}:caps