File Coverage

blib/lib/RxPerl/SyncTimers.pm
Criterion Covered Total %
statement 67 67 100.0
branch 9 12 75.0
condition 3 3 100.0
subroutine 16 16 100.0
pod 0 2 0.0
total 95 100 95.0


line stmt bran cond sub pod time code
1             package RxPerl::SyncTimers;
2              
3 4     4   25 use strict;
  4         15  
  4         146  
4 4     4   51 use warnings;
  4         9  
  4         201  
5              
6 4     4   2103 use parent 'RxPerl::Base';
  4         1393  
  4         25  
7              
8 4     4   2706 use RxPerl ':all';
  4         16  
  4         2725  
9              
10 4     4   2452 use Sub::Util 'set_subname';
  4         1536  
  4         377  
11 4     4   36 use Module::Load 'load';
  4         8  
  4         69  
12              
13 4     4   336 use Exporter 'import';
  4         10  
  4         4083  
14             our @EXPORT_OK = (@RxPerl::EXPORT_OK);
15             our %EXPORT_TAGS = (%RxPerl::EXPORT_TAGS);
16              
17             our $VERSION = "v6.29.8";
18              
19             my $mojo_loaded = eval {
20             load 'Mojo::IOLoop';
21             1;
22             };
23              
24             foreach my $func_name (@EXPORT_OK) {
25             set_subname __PACKAGE__."::$func_name", \&{$func_name};
26             }
27              
28             our $promise_class;
29             our $DEBUG = 0;
30              
31             my $_id_cursor = 0;
32             my %_timed_events;
33             my %_timeline;
34              
35             our $time = 0;
36              
37             sub reset {
38 254     254 0 510 my ($class) = @_;
39              
40 254         428 $_id_cursor = 0;
41 254         565 undef %_timed_events;
42 254         436 undef %_timeline;
43 254         579 $time = 0;
44             }
45              
46             sub start {
47 258     258 0 668 my ($class) = @_;
48              
49 258         532 while (%_timeline) {
50 1008         3431 my @times = sort {$a <=> $b} keys %_timeline;
  3394         5871  
51 1008         1792 $time = $times[0];
52 1008 50       1756 print "** Time jump to: $time **\n" if $DEBUG;
53 1008         1245 while (my $item = shift @{ $_timeline{$time} }) {
  2795         79320  
54 1787         4167 delete $_timed_events{$item->{id}};
55 1787         4194 $item->{sub}->();
56 1787 50       6321 Mojo::IOLoop->start if $mojo_loaded;
57             }
58 1008         3233 delete $_timeline{$time};
59             }
60             }
61              
62 1895     1895   12029 sub _round_number { 0 + sprintf("%.1f", $_[0]) }
63              
64             sub _timer {
65 1895     1895   3613 my ($after, $sub, %opts) = @_;
66              
67             # opts can be: id
68              
69 1895   100     5146 my $id = $opts{id} // $_id_cursor++;
70 1895         3691 my $target_time = _round_number($time + $after);
71 1895         7386 $_timed_events{$id} = {
72             time => $target_time,
73             sub => $sub,
74             };
75 1895         2610 push @{ $_timeline{$target_time} }, {
  1895         7397  
76             id => $id,
77             sub => $sub,
78             };
79              
80 1895         4555 return $id;
81             }
82              
83             sub _cancel_timer {
84 304     304   511 my ($id) = @_;
85              
86 304 100       697 return if !defined $id;
87              
88 202 100       625 my $event = delete $_timed_events{$id} or return;
89              
90 108 50       523 exists $_timeline{$event->{time}} or return;
91              
92 108         162 @{ $_timeline{$event->{time}} } = grep {$_->{id} ne $id} @{ $_timeline{$event->{time}} };
  108         363  
  134         346  
  108         323  
93              
94 108 100       172 if (! @{ $_timeline{$event->{time}} }) {
  108         479  
95 87         729 delete $_timeline{$event->{time}};
96             }
97             }
98              
99             sub _add_recursive_timer {
100 260     260   392 my ($after, $sub, $id) = @_;
101              
102             _timer($after, sub {
103 202     202   394 _add_recursive_timer($after, $sub, $id);
104 202         390 $sub->();
105 260         870 }, id => $id);
106             }
107              
108             sub _interval {
109 58     58   99 my ($after, $sub) = @_;
110              
111 58         77 my $id = $_id_cursor++;
112              
113 58         130 _add_recursive_timer($after, $sub, $id);
114              
115 58         176 return $id;
116             }
117              
118             sub _cancel_interval {
119 160     160   291 my ($id) = @_;
120              
121 160         279 _cancel_timer($id);
122             }
123              
124             1;