]> mj.ucw.cz Git - anim.git/blob - AA/Anim.pm
A bit of animation.
[anim.git] / AA / Anim.pm
1 package AA::Anim;
2
3 my @timer_queue;
4 my $debug = 0;
5 my $now = 0;
6
7 our $timer = AA->new('T');
8 $timer->DefSet('T', 0);
9
10 sub now($) {
11         return $timer->Get('T');
12 }
13
14 sub add_timer($$$) {
15         my ($class, $after, $sub) = @_;
16         my $t = $now + $after;
17         push @timer_queue, [ $t, $sub ];
18         print "@@@ Adding timer for $t\n" if $debug;
19         @timer_queue = sort { $a->[0] <=> $b->[0] } @timer_queue;
20 }
21
22 sub add_final($$) {
23         my ($class, $sub) = @_;
24         push @timer_queue, [ 1000000, $sub ];
25 }
26
27 sub start($) {
28         AA::Anim->add_final(sub { });
29         $now = 0;
30 }
31
32 sub step($) {
33         print "@@@ Tick tock: it's $now o'clock\n" if $debug;
34         $timer->Set('T', $now);
35         my $tm;
36         if (!@timer_queue) {
37                 print "@@@ idle\n" if $debug;
38                 return 0;
39         } elsif ($timer_queue[0]->[0] >= 1000000) {
40                 while ($tm = shift @timer_queue) {
41                         print "@@@ finalizer\n" if $debug;
42                         &{$tm->[1]};
43                 }
44         } else {
45                 while (@timer_queue && $timer_queue[0]->[0] <= $now) {
46                         print "@@@ timer for ", $timer_queue[0]->[0], "\n" if $debug;
47                         $tm = shift @timer_queue;
48                         &{$tm->[1]};
49                 }
50         }
51         $now++;
52         return 1;
53 }
54
55 sub ticker($$$$) {
56         my ($class, $x0, $x1, $dt) = @_;
57         my $t0 = $now;
58         return sub {
59                 my $t = AA::Anim->now;
60                 if ($t - $t0 >= $dt) {
61                         return $x1;
62                 } else {
63                         return $x0 + ($x1 - $x0) * ($t - $t0)/$dt;
64                 }
65         };
66 }
67
68 1;