change_tick.bend
bendvy-ecs-core@0.1.0.3 · 90 lines · 17 definitions
1import Base
2
3
4
5
6type Tick is Data:
7 Tick{epoch:Nat,low:U32}
8
9
10
11def max_change_age() -> U32:3258167296
12
13
14
15def zero() -> Tick:Tick{0n,0}
16
17def incremented(wrapped:Bool,epoch:Nat,low:U32) -> Tick:
18 match wrapped:
19 case False{}:Tick{epoch,U32.add(low,1)}
20 case True{}:Tick{1n+epoch,0}
21
22
23def next(tick:Tick) -> Tick:
24 match tick:
25 case Tick{epoch,+low}:incremented(U32.is_eq(low,4294967295),epoch,low)
26
27
28def low(tick:Tick) -> U32:
29 match tick:
30 case Tick{_,value}:value
31
32
33
34def total(tick:Tick) -> Nat:
35 match tick:
36 case Tick{epoch,value}:Nat.add(Nat.mul(epoch,1n+4294967295n),U32.to_nat(value))
37
38def ordered_epochs(equal:Bool,earlier:Bool,stamp:U32,this:U32) -> Bool:
39 match equal:
40 case True{}:U32.is_le(stamp,this)
41 case False{}:earlier
42
43
44
45def not_future(stamp:Tick,this:Tick) -> Bool:
46 match stamp this:
47 case Tick{+se,sl} Tick{+te,tl}:ordered_epochs(Nat.is_eq(se,te),Nat.is_lt(se,te),sl,tl)
48
49def crossing_age(lowWrapped:Bool,stamp:U32,this:U32) -> U32:
50 match lowWrapped:
51 case False{}:max_change_age()
52 case True{}:U32.min(U32.sub(this,stamp),max_change_age())
53
54def distance(same:Bool,adjacent:Bool,+stamp:U32,+this:U32) -> U32:
55 match same adjacent:
56 case True{} _:U32.min(U32.sub(this,stamp),max_change_age())
57 case False{} True{}:crossing_age(U32.is_lt(this,stamp),stamp,this)
58 case False{} False{}:max_change_age()
59
60def valid_age(valid:Bool,stamp:Tick,this:Tick) -> U32:
61 match valid stamp this:
62 case False{} _ _:max_change_age()
63 case True{} Tick{+se,sl} Tick{+te,tl}:distance(Nat.is_eq(se,te),Nat.is_eq(1n+se,te),sl,tl)
64
65
66
67
68def age(+stamp:Tick,+this:Tick) -> U32:
69 valid_age(not_future(stamp,this),stamp,this)
70
71def valid_newer(valid:Bool,stamp:Tick,last:Tick,+this:Tick) -> Bool:
72 match valid:
73 case False{}:False{}
74 case True{}:U32.is_gt(age(last,this),age(stamp,this))
75
76
77
78
79def newer(+stamp:Tick,+last:Tick,+this:Tick) -> Bool:
80 valid_newer(Bool.and(not_future(stamp,this),not_future(last,this)),stamp,last,this)
81
82
83def show(tick:Tick) -> String:
84 match tick:
85 case Tick{epoch,low}:Nat.show(epoch) ++ ":" ++ U32.show(low)
86
87def cursor_show(cursor:Maybe<&2,Tick>) -> String:
88 match cursor:
89 case None{}:"never"
90 case Some{tick}:show(tick)