blob: 13c83464242c00c8c51e3fd185e2405ccd386023 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
use Test;
my $minumum-version = Version.new('2019.07.1.357.gd.00674.b.31');
die "Scalar::History requires $minumum-version or later"
if ( $*PERL.compiler.version cmp $minumum-version ) == Less;
class Scalar::History::Proxy is Proxy
{
has @!history;
has $!position;
# This is needed for now since the standard ways
# like assigning in the `has` statement, TWEAK
# and BUILD don't work with `Proxy`
method new( :&FETCH!, :&STORE!, *%_ ) is raw
{
my $self := self.Proxy::new( :&FETCH, :&STORE );
$self.VAR.TWEAK( |%_ );
$self
}
method TWEAK( :$!position = 0 ) {
# yadayada
}
method current-value( \SELF: )
{
@!history[ $!position ]
}
method latest-value( \SELF: )
{
@!history[ *-1 ]
}
method get-history( \SELF: Bool :$all = False )
{
my $to-index = $all ?? @!history.elems - 1 !! $!position;
@!history[ ^$to-index ]
}
method reset-history( \SELF: )
{
@!history = ();
$!position = 0;
}
method forward-history( \SELF: $steps )
{
$!position = $!position + $steps;
$!position = @!history.elems - 1
if $!position >= @!history.elems;
$!position;
}
method rewind-history( \SELF: $steps )
{
$!position = $!position - $steps;
$!position = 0
if $!position < 0;
$!position;
}
method store-value( \SELF: $new-value, $register-duplicates )
{
# Forget stuff after rewind
if @!history.elems > $!position + 1
{
@!history.splice( $!position + 1 );
}
if !($new-value eqv SELF.current-value) || $register-duplicates
{
@!history.push( $new-value );
$!position = @!history.elems - 1;
}
}
}
class Scalar::History
{
method create( $value, ::T $type = Any, Bool :$register-duplicates = False )
{
return-rw Scalar::History::Proxy.new(
FETCH => method ( \SELF: ) {
SELF.current-value() },
STORE => method ( \SELF: T $new-value ) {
SELF.store-value( $new-value, $register-duplicates ); }
) = $value;
}
}
|