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   25 use strict;
  4         8  
  4         106  
4 4     4   30 use warnings;
  4         7  
  4         102  
5              
6 4     4   1725 use parent 'RxPerl::Base';
  4         1195  
  4         21  
7              
8 4     4   2224 use RxPerl ':all';
  4         12  
  4         1861  
9              
10 4     4   1953 use Sub::Util 'set_subname';
  4         1224  
  4         225  
11              
12 4     4   32 use Exporter 'import';
  4         9  
  4         3232  
13             our @EXPORT_OK = (@RxPerl::EXPORT_OK);
14             our %EXPORT_TAGS = (%RxPerl::EXPORT_TAGS);
15              
16             our $VERSION = "v6.27.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 236     236 0 414 my ($class) = @_;
33              
34 236         333 $_id_cursor = 0;
35 236         422 undef %_timed_events;
36 236         350 undef %_timeline;
37 236         498 $time = 0;
38             }
39              
40             sub start {
41 240     240 0 463 my ($class) = @_;
42              
43 240         551 while (%_timeline) {
44 968         3052 my @times = sort {$a <=> $b} keys %_timeline;
  3297         5502  
45 968         1746 $time = $times[0];
46 968 50       1694 print "** Time jump to: $time **\n" if $DEBUG;
47 968         1314 while (my $item = shift @{ $_timeline{$time} }) {
  2666         6477  
48 1698         3607 delete $_timed_events{$item->{id}};
49 1698         3467 $item->{sub}->();
50             }
51 968         2970 delete $_timeline{$time};
52             }
53             }
54              
55 1799     1799   10331 sub _round_number { 0 + sprintf("%.1f", $_[0]) }
56              
57             sub _timer {
58 1799     1799   3512 my ($after, $sub, %opts) = @_;
59              
60             # opts can be: id
61              
62 1799   100     5275 my $id = $opts{id} // $_id_cursor++;
63 1799         3705 my $target_time = _round_number($time + $after);
64 1799         5992 $_timed_events{$id} = {
65             time => $target_time,
66             sub => $sub,
67             };
68 1799         2541 push @{ $_timeline{$target_time} }, {
  1799         6880  
69             id => $id,
70             sub => $sub,
71             };
72              
73 1799         4828 return $id;
74             }
75              
76             sub _cancel_timer {
77 281     281   487 my ($id) = @_;
78              
79 281 100       658 return if !defined $id;
80              
81 185 100       535 my $event = delete $_timed_events{$id} or return;
82              
83 101 50       481 exists $_timeline{$event->{time}} or return;
84              
85 101         152 @{ $_timeline{$event->{time}} } = grep {$_->{id} ne $id} @{ $_timeline{$event->{time}} };
  101         345  
  124         322  
  101         282  
86              
87 101 100       156 if (! @{ $_timeline{$event->{time}} }) {
  101         441  
88 83         626 delete $_timeline{$event->{time}};
89             }
90             }
91              
92             sub _add_recursive_timer {
93 242     242   408 my ($after, $sub, $id) = @_;
94              
95             _timer($after, sub {
96 191     191   467 _add_recursive_timer($after, $sub, $id);
97 191         398 $sub->();
98 242         860 }, id => $id);
99             }
100              
101             sub _interval {
102 51     51   104 my ($after, $sub) = @_;
103              
104 51         79 my $id = $_id_cursor++;
105              
106 51         137 _add_recursive_timer($after, $sub, $id);
107              
108 51         120 return $id;
109             }
110              
111             sub _cancel_interval {
112 147     147   243 my ($id) = @_;
113              
114 147         246 _cancel_timer($id);
115             }
116              
117             1;