decode_requests.bend
bendvy-ecs-core@0.1.0.1 · 66 lines · 0 definitions
1import Base
2import bendvy-ecs-core@0.1.0.1/resource.bend as Resource
3import bendvy-ecs-core@0.1.0.1/bundle_batch.bend as Batch
4import bendvy-ecs-core@0.1.0.1/bundle_delivery.bend as Delivery
5import bendvy-ecs-core@0.1.0.1/bundle_requests.bend as Commands
6import bendvy-ecs-core@0.1.0.1/world.bend as W
7import bendvy-ecs-core@0.1.0.1/transaction.bend as T
8import bendvy-ecs-core@0.1.0.1/capabilities.bend as Cap
9import bendvy-ecs-core@0.1.0.1/decode_data.bend as D
10import bendvy-ecs-core@0.1.0.1/persistence_declaration.bend as Decl
11import bendvy-ecs-core@0.1.0.1/ordinary_declaration.bend as Identity
12
13# The packet owns original P plus detached canonical input. Typed schema delivery
14# constructs its actual component; no generic Raw -> arbitrary Type inverse.
15type Packet<P:Type> is Type:
16 Packet{owner:Maybe<&1,P>,original:D.Raw,canonical:D.Raw}
17type Input<S:Data,P:Type> is Type:
18 Input{operation:Commands.Operation<S>,owner:P}
19type Error is Data:
20 Validation{error:D.Error}
21 Entity{error:W.WorldError}
22type Output<S:Data,P:Type> is Type:
23 Accepted{target:W.Handle<S>,spawned:Bool,canonical:D.Raw}
24 Refused{owner:Maybe<&1,P>,error:Error}
25type Owner<S:Data,C:Type,R:Type,E:Data,P:Type,-identity:Identity.Declaration<S,P>,-project:P -> P & D.Raw> is Type:
26 Owner{batch:Batch.Batch<S,C,R,E,Packet<P>>,declaration:Decl.Constructed<S,P,identity,project>}
27
28def inserted(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,declaration:Decl.Constructed<S,P,identity,project>,target:W.Handle<S>,canonical:D.Raw,result:Batch.Inserted<S,C,R,E,Packet<P>>) -> Owner<S,C,R,E,P,identity,project> & Output<S,P>:
29 match result:
30 case Batch.Inserted{batch}:(Owner{batch,declaration},Accepted{target,False{},canonical})
31 case Batch.Refused{batch,Packet{owner,_,_},error}:(Owner{batch,declaration},Refused{owner,Entity{error}})
32def spawned(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,declaration:Decl.Constructed<S,P,identity,project>,canonical:D.Raw,result:Batch.Spawned<S,C,R,E,Packet<P>>) -> Owner<S,C,R,E,P,identity,project> & Output<S,P>:
33 match result:
34 case Batch.Spawned{batch,target}:(Owner{batch,declaration},Accepted{target,True{},canonical})
35 case Batch.SpawnRefused{batch,Packet{owner,_,_},error}:(Owner{batch,declaration},Refused{owner,Entity{error}})
36def enqueue_packet(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,declaration:Decl.Constructed<S,P,identity,project>,batch:Batch.Batch<S,C,R,E,Packet<P>>,operation:Commands.Operation<S>,owner:P,original:D.Raw,+canonical:D.Raw) -> Owner<S,C,R,E,P,identity,project> & Output<S,P>:
37 match operation:
38 case Commands.Insert{+target}:inserted(~S,~C,~R,~E,~P,~identity,~project,declaration,target,canonical,Batch.insert(~S,~C,~R,~E,~Packet<P>,batch,target,Packet{Some{owner},original,canonical}))
39 case Commands.Spawn{}:spawned(~S,~C,~R,~E,~P,~identity,~project,declaration,canonical,Batch.spawn(~S,~C,~R,~E,~Packet<P>,batch,Packet{Some{owner},original,canonical}))
40def enqueue(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,declaration:Decl.Constructed<S,P,identity,project>,batch:Batch.Batch<S,C,R,E,Packet<P>>,operation:Commands.Operation<S>,canonical:D.Raw,projected:P & D.Raw) -> Owner<S,C,R,E,P,identity,project> & Output<S,P>:
41 match projected:
42 case (owner,original):enqueue_packet(~S,~C,~R,~E,~P,~identity,~project,declaration,batch,operation,owner,original,canonical)
43def validated(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,declaration:Decl.Constructed<S,P,identity,project>,batch:Batch.Batch<S,C,R,E,Packet<P>>,operation:Commands.Operation<S>,receipt:D.Receipt<P>) -> Owner<S,C,R,E,P,identity,project> & Output<S,P>:
44 match receipt:
45 case D.Receipt{owner,D.Rejected{error}}:(Owner{batch,declaration},Refused{Some{owner},Validation{error}})
46 case D.Receipt{owner,D.Accepted{canonical}}:enqueue(~S,~C,~R,~E,~P,~identity,~project,declaration,batch,operation,canonical,project(owner))
47def request(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,frame:Owner<S,C,R,E,P,identity,project>,input:Input<S,P>) -> Owner<S,C,R,E,P,identity,project> & Output<S,P>:
48 match frame input:
49 case Owner{batch,+declaration} Input{operation,owner}:validated(~S,~C,~R,~E,~P,~identity,~project,declaration,batch,operation,Decl.validate(~S,~P,~identity,~project,declaration,owner))
50def grant(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw) -> Cap.OwnedRequest<Owner<S,C,R,E,P,identity,project>,Input<S,P>,Output<S,P>>:
51 Cap.OwnedRequest{frame => input => request(~S,~C,~R,~E,~P,~identity,~project,frame,input)}
52def invoke(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~A:Type,~U:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~body:@-H:Type -> @-cap:Cap.OwnedRequest<H,Input<S,P>,Output<S,P>> -> A -> H -> H & U,owner:Owner<S,C,R,E,P,identity,project>,args:A) -> Owner<S,C,R,E,P,identity,project> & U:
53 Cap.invoke_owned(~(H => Cap.OwnedRequest<H,Input<S,P>,Output<S,P>>),~A,~U,~body,~Owner<S,C,R,E,P,identity,project>,~grant(~S,~C,~R,~E,~P,~identity,~project),args,owner)
54def finish(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~Error:Data,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,~attempt:W.World<S,C,R,E> -> W.Handle<S> -> Packet<P> -> Delivery.Delivery<W.World<S,C,R,E>,Packet<P>>,~recover:W.World<S,C,R,E> -> Packet<P> -> W.WorldError -> W.World<S,C,R,E>,owner:Owner<S,C,R,E,P,identity,project>,outcome:T.Outcome<Error>) -> Batch.Finished<S,C,R,E,Packet<P>,Error>:
55 match owner:
56 case Owner{batch,_}:Batch.finish(~S,~C,~R,~E,~Packet<P>,~Error,~attempt,~recover,batch,outcome)
57
58# Additive trusted resource provider over the SAME transaction; gameplay can use
59# it only when provisioning explicitly includes this owned grant in its Ops.
60def resource_replaced(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,declaration:Decl.Constructed<S,P,identity,project>,prepared:List<Batch.Prepared<S,Packet<P>>>,tx:T.Tx<W.World<S,C,R,E>,E>) -> Owner<S,C,R,E,P,identity,project> & Unit:
61 (Owner{Batch.Batch{tx,prepared},declaration},Unit{})
62def replace_resource(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw,owner:Owner<S,C,R,E,P,identity,project>,replacement:R) -> Owner<S,C,R,E,P,identity,project> & Unit:
63 match owner:
64 case Owner{Batch.Batch{tx,prepared},declaration}:resource_replaced(~S,~C,~R,~E,~P,~identity,~project,declaration,prepared,Resource.tx_replace(~S,~C,~R,~E,tx,replacement))
65def resource_grant(~S:Data,~C:Type,~R:Type,~E:Data,~P:Type,~identity:Identity.Declaration<S,P>,~project:P -> P & D.Raw) -> Cap.OwnedRequest<Owner<S,C,R,E,P,identity,project>,R,Unit>:
66 Cap.OwnedRequest{owner => replacement => replace_resource(~S,~C,~R,~E,~P,~identity,~project,owner,replacement)}