File Coverage

lib/Context/Singleton/Frame/Promise.pm
Criterion Covered Total %
statement 69 72 95.8
branch 10 14 71.4
condition 5 6 83.3
subroutine 23 24 95.8
pod 0 14 0.0
total 107 130 82.3


line stmt bran cond sub pod time code
1              
2 4     4   86593 use v5.10;
  4         15  
3 4     4   18 use strict;
  4         8  
  4         83  
4 4     4   18 use warnings;
  4         6  
  4         218  
5              
6             package Context::Singleton::Frame::Promise;
7              
8             our $VERSION = v1.0.5;
9              
10 4     4   22 use Scalar::Util qw[ weaken ];
  4         6  
  4         195  
11              
12 4     4   1623 use namespace::clean;
  4         28425  
  4         20  
13              
14             sub new {
15 150     150 0 21949 my ($class, %params) = @_;
16              
17             bless {
18             depth => $params{depth},
19 150         693 is_resolvable => 0,
20             dependencies => [],
21             listeners => {},
22             }, $class;
23             }
24              
25             sub depth {
26 4     4 0 15 $_[0]->{depth};
27             }
28              
29             sub value {
30 59     59 0 3669 $_[0]->{value};
31             }
32              
33             sub set_value {
34 80     80 0 33014 my ($self, $value, $in_depth) = @_;
35              
36 80   66     174 $in_depth //= $self->depth;
37              
38 80 100       128 unless ($self->is_deduced) {
39 65         135 $self->{value} = $value;
40 65         115 $self->set_deducible ($in_depth);
41             }
42              
43 80         142 $self;
44             }
45              
46             sub is_deduced {
47 205     205 0 60690 exists $_[0]->{value};
48             }
49              
50             sub is_deducible {
51 670     670 0 19323 $_[0]->{is_deducible};
52             }
53              
54             sub set_deducible {
55 172     172 0 268 my ($self, $in_depth) = @_;
56              
57 172 100 100     287 unless ($self->is_deducible and $self->deduced_in_depth >= $in_depth) {
58 129         175 $self->{is_deducible} = 1;
59 129         286 $self->_set_deduced_in_depth ($in_depth);
60 129         216 $self->_broadcast_deducible;
61             }
62              
63 172         284 $self;
64             }
65              
66             sub deduced_in_depth {
67 297     297 0 10663 $_[0]->{in_depth};
68             }
69              
70             sub _set_deduced_in_depth {
71 129     129   223 $_[0]->{in_depth} = $_[1];
72             }
73              
74             sub _listeners {
75 247     247   345 $_[0]->{listeners};
76             }
77              
78             sub add_listeners {
79 118     118 0 178 my ($self, @new_listeners) = @_;
80              
81             # - Listener life time is a frame it is created for
82             # weaken helps tracking them (children do listen parents here)
83             # - Listener is another promise
84             # - Listeners are stored in linked list
85              
86 118         173 my $head = $self->_listeners;
87 118         163 for my $listener (@new_listeners) {
88             my $entry = $head->{next} = {
89             prev => $head,
90             next => $head->{next},
91 118         304 listener => $listener,
92             };
93              
94             $entry->{next}{prev} = $head->{next}
95 118 100       230 if $entry->{next};
96              
97 118         320 Scalar::Util::weaken $entry->{listener};
98              
99             $self->_notify_listener ($entry->{listener})
100 118 100       180 if $self->is_deducible;
101             }
102              
103 118         188 $self;
104             }
105              
106             sub listen {
107 8     8 0 19 my ($self, @promises) = @_;
108              
109 8         19 for my $promise (grep defined, @promises) {
110 9         16 $promise->add_listeners ($self);
111             }
112              
113 8         13 $self;
114             }
115              
116             sub _dependencies {
117 257     257   614 $_[0]->{dependencies};
118             }
119              
120             sub add_dependencies {
121 118     118 0 207 my ($self, @new_dependencies) = @_;
122              
123 118         235 @new_dependencies = grep defined, @new_dependencies;
124              
125 118         164 for my $dependency (@new_dependencies) {
126 109         117 push @{ $self->_dependencies }, $dependency;
  109         179  
127             #Scalar::Util::weaken ($self->_dependencies->[-1]);
128             }
129              
130 118         233 $_->add_listeners ($self) for @new_dependencies;
131              
132 118         187 $self;
133             }
134              
135             sub dependencies {
136 148     148 0 166 @{ $_[0]->_dependencies };
  148         210  
137             }
138              
139             sub deducible_dependencies {
140 118     118 0 158 my ($self) = @_;
141              
142 118         198 grep { $_->is_deducible } $self->dependencies;
  156         252  
143             }
144              
145             sub _broadcast_deducible {
146 129     129   185 my ($self) = @_;
147              
148 129 50       179 return unless $self->is_deducible;
149              
150 129         218 my $head = $self->_listeners;
151 129         259 while ($head = $head->{next}) {
152 8 50       22 unless ($head->{listener}) {
153             # obsoleted weak listener
154 0         0 $head->{prev}{next} = $head->{next};
155             $head->{next}{prev} = $head->{prev}
156 0 0       0 if $head->{next};
157 0         0 next;
158             }
159              
160 8         28 $self->_notify_listener ($head->{listener});
161             }
162              
163 129         181 $self;
164             }
165              
166       0 0   sub notify_deducible {
167             }
168              
169             sub _notify_listener {
170 89     89   131 my ($self, $listener) = @_;
171              
172 89         149 $listener->notify_deducible ($self->deduced_in_depth);
173             }
174              
175             1;
176              
177             __END__