1 //
2 //   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 //   Free Software   Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 //
19 //
20 //
21 
22 #include "Timers.h"
23 #include "log.h"
24 #include "fn_call.h"
25 #include "VM.h"
26 #include "movie_root.h"
27 #include "Global_as.h"
28 #include "as_function.h"
29 
30 #include <limits> // for numeric_limits
31 #include <functional>
32 #include <algorithm>
33 
34 namespace gnash {
35 
~Timer()36 Timer::~Timer()
37 {
38 }
39 
Timer(as_function & method,unsigned long ms,as_object * this_ptr,fn_call::Args args,bool runOnce)40 Timer::Timer(as_function& method, unsigned long ms,
41         as_object* this_ptr, fn_call::Args args, bool runOnce)
42     :
43     _interval(ms),
44     _start(std::numeric_limits<unsigned long>::max()),
45     _function(&method),
46     _methodName(),
47     _object(this_ptr),
48     _args(std::move(args)),
49     _runOnce(runOnce)
50 {
51     start();
52 }
53 
Timer(as_object * this_ptr,ObjectURI methodName,unsigned long ms,fn_call::Args args,bool runOnce)54 Timer::Timer(as_object* this_ptr, ObjectURI methodName,
55         unsigned long ms, fn_call::Args args, bool runOnce)
56     :
57     _interval(ms),
58     _start(std::numeric_limits<unsigned long>::max()),
59     _function(nullptr),
60     _methodName(std::move(methodName)),
61     _object(this_ptr),
62     _args(std::move(args)),
63     _runOnce(runOnce)
64 {
65     start();
66 }
67 
68 void
clearInterval()69 Timer::clearInterval()
70 {
71     _interval = 0;
72     _start = std::numeric_limits<unsigned long>::max();
73 }
74 
75 void
start()76 Timer::start()
77 {
78     _start = getVM(*_object).getTime();
79 }
80 
81 
82 bool
expired(unsigned long now,unsigned long & elapsed)83 Timer::expired(unsigned long now, unsigned long& elapsed)
84 {
85     if (cleared()) return false;
86     long unsigned expTime = _start + _interval;
87     if (now < expTime) return false;
88     elapsed = expTime-now;
89     return true;
90 }
91 
92 void
executeAndReset()93 Timer::executeAndReset()
94 {
95     if (cleared()) return;
96     execute();
97     if (_runOnce) clearInterval();
98     else _start += _interval; // reset the timer
99 }
100 
101 void
execute()102 Timer::execute()
103 {
104 
105     // If _function is not 0, _methodName should be 0 anyway, but the
106     // ternary operator is there for clarity.
107     as_object* super = _function ? _object->get_super()
108                                  : _object->get_super(_methodName);
109     VM& vm = getVM(*_object);
110 
111     as_value timer_method = _function ? _function :
112                                         getMember(*_object, _methodName);
113 
114     as_environment env(vm);
115 
116     // Copy args
117     fn_call::Args argsCopy(_args);
118 
119     invoke(timer_method, env, _object, argsCopy, super);
120 
121 }
122 
123 void
markReachableResources() const124 Timer::markReachableResources() const
125 {
126     _args.setReachable();
127 
128     if (_function) _function->setReachable();
129     if (_object) _object->setReachable();
130 }
131 
132 } // namespace gnash
133