File Coverage

blib/lib/RxPerl/SyncTimers.pm
Criterion Covered Total %
statement 63 63 100.0
branch 8 10 80.0
condition 3 3 100.0
subroutine 15 15 100.0
pod 0 2 0.0
total 89 93 95.7


line stmt bran cond sub pod time code
1             package RxPerl::SyncTimers;
2              
3 4     4   32 use strict;
  4         23  
  4         113  
4 4     4   19 use warnings;
  4         7  
  4         105  
5              
6 4     4   1864 use parent 'RxPerl::Base';
  4         1243  
  4         20  
7              
8 4     4   2301 use RxPerl ':all';
  4         9  
  4         1866  
9              
10 4     4   2087 use Sub::Util 'set_subname';
  4         1277  
  4         250  
11              
12 4     4   35 use Exporter 'import';
  4         9  
  4         3009  
13             our @EXPORT_OK = (@RxPerl::EXPORT_OK);
14             our %EXPORT_TAGS = (%RxPerl::EXPORT_TAGS);
15              
16             our $VERSION = "v6.28.0";
17              
18             foreach my $func_name (@EXPORT_OK) {
19             set_subname __PACKAGE__."::$func_name", \&{$func_name};
20             }
21              
22             our $promise_class;
23             our $DEBUG = 0;
24              
25             my $_id_cursor = 0;
26             my %_timed_events;
27             my %_timeline;
28              
29             our $time = 0;
30              
31             sub reset {
32 234     234 0 395 my ($class) = @_;
33              
34 234         308 $_id_cursor = 0;
35 234         397 undef %_timed_events;
36 234         420 undef %_timeline;
37 234         448 $time = 0;
38             }
39              
40             sub start {
41 238     238 0 486 my ($class) = @_;
42              
43 238         573 while (%_timeline) {
44 961         3219 my @times = sort {$a <=> $b} keys %_timeline;
  3300         6102  
45 961         1740 $time = $times[0];
46 961 50       1747 print "** Time jump to: $time **\n" if $DEBUG;
47 961         1366 while (my $item = shift @{ $_timeline{$time} }) {
  2650         6587  
48 1689         3637 delete $_timed_events{$item->{id}};
49 1689         3334 $item->{sub}->();
50             }
51 961         2938 delete $_timeline{$time};
52             }
53             }
54              
55 1789     1789   10819 sub _round_number { 0 + sprintf("%.1f", $_[0]) }
56              
57             sub _timer {
58 1789     1789   3313 my ($after, $sub, %opts) = @_;
59              
60             # opts can be: id
61              
62 1789   100     5087 my $id = $opts{id} // $_id_cursor++;
63 1789         3581 my $target_time = _round_number($time + $after);
64 1789         6174 $_timed_events{$id} = {
65             time => $target_time,
66             sub => $sub,
67             };
68 1789         2619 push @{ $_timeline{$target_time} }, {
  1789         7037  
69             id => $id,
70             sub => $sub,
71             };
72              
73 1789         5020 return $id;
74             }
75              
76             sub _cancel_timer {
77 280     280   456 my ($id) = @_;
78              
79 280 100       640 return if !defined $id;
80              
81 184 100       500 my $event = delete $_timed_events{$id} or return;
82              
83 100 50       464 exists $_timeline{$event->{time}} or return;
84              
85 100         186 @{ $_timeline{$event->{time}} } = grep {$_->{id} ne $id} @{ $_timeline{$event->{time}} };
  100         327  
  123         344  
  100         279  
86              
87 100 100       209 if (! @{ $_timeline{$event->{time}} }) {
  100         394  
88 82         645 delete $_timeline{$event->{time}};
89             }
90             }
91              
92             sub _add_recursive_timer {
93 236     236   404 my ($after, $sub, $id) = @_;
94              
95             _timer($after, sub {
96 186     186   392 _add_recursive_timer($after, $sub, $id);
97 186         438 $sub->();
98 236         894 }, id => $id);
99             }
100              
101             sub _interval {
102 50     50   105 my ($after, $sub) = @_;
103              
104 50         83 my $id = $_id_cursor++;
105              
106 50         122 _add_recursive_timer($after, $sub, $id);
107              
108 50         127 return $id;
109             }
110              
111             sub _cancel_interval {
112 146     146   246 my ($id) = @_;
113              
114 146         261 _cancel_timer($id);
115             }
116              
117             1;