gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog server/movie_root.cpp server/mo...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/movie_root.cpp server/mo...
Date: Fri, 09 Feb 2007 13:38:50 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/02/09 13:38:50

Modified files:
        .              : ChangeLog 
        server         : movie_root.cpp movie_root.h timers.cpp timers.h 
        server/asobj   : xmlsocket.cpp 
        testsuite/misc-ming.all: Makefile.am 
Added files:
        testsuite/misc-ming.all: intervalTest.as 

Log message:
                * server/movie_root.{cpp,h}: Store Timer objects
                  by value, not by pointer (make memory management easier);
                  I might change this in the future, but for now it works
                  fine. Possible future changes include: reserving a number
                  of slots for timers (possibly setting a limit), reusing
                  slots of expired timers (needs a testcase to see if that's
                  allowed).
                * server/timers.{cpp,h}: Big cleanup; got rid of 
timer_as_object;
                  use integer values for times, reduced function calls (store 
timeouts
                  in microseconds directly); documented.
                * server/asobj/xmlsocket.cpp: fix use of Timer class.
                * testsuite/misc-ming.all/: Makefile.am, intervalTest.as: new
                  test for setInterval() and clearInterval(). Lacks a test 
*runner*
                  but the manually running it clearly shows it works with this 
commit
                  (and not before). Note that self-contained tests are already
                  present, but a MovieTester based runner is required for proper
                  testing.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2287&r2=1.2288
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.39&r2=1.40
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/gnash/server/timers.cpp?cvsroot=gnash&r1=1.21&r2=1.22
http://cvs.savannah.gnu.org/viewcvs/gnash/server/timers.h?cvsroot=gnash&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/xmlsocket.cpp?cvsroot=gnash&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/Makefile.am?cvsroot=gnash&r1=1.62&r2=1.63
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/intervalTest.as?cvsroot=gnash&rev=1.1

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2287
retrieving revision 1.2288
diff -u -b -r1.2287 -r1.2288
--- ChangeLog   9 Feb 2007 13:29:14 -0000       1.2287
+++ ChangeLog   9 Feb 2007 13:38:50 -0000       1.2288
@@ -1,3 +1,23 @@
+2007-02-09 Sandro Santilli <address@hidden>
+
+       * server/movie_root.{cpp,h}: Store Timer objects
+         by value, not by pointer (make memory management easier);
+         I might change this in the future, but for now it works
+         fine. Possible future changes include: reserving a number
+         of slots for timers (possibly setting a limit), reusing
+         slots of expired timers (needs a testcase to see if that's
+         allowed).
+       * server/timers.{cpp,h}: Big cleanup; got rid of timer_as_object;
+         use integer values for times, reduced function calls (store timeouts
+         in microseconds directly); documented.
+       * server/asobj/xmlsocket.cpp: fix use of Timer class.
+       * testsuite/misc-ming.all/: Makefile.am, intervalTest.as: new
+         test for setInterval() and clearInterval(). Lacks a test *runner*
+         but the manually running it clearly shows it works with this commit
+         (and not before). Note that self-contained tests are already
+         present, but a MovieTester based runner is required for proper
+         testing.
+
 2007-02-09 Martin Guy <address@hidden>
 
        * server/asobj/Math.cpp: Methods for constants have uppercase names

Index: server/movie_root.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.cpp,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -b -r1.39 -r1.40
--- server/movie_root.cpp       9 Feb 2007 00:19:07 -0000       1.39
+++ server/movie_root.cpp       9 Feb 2007 13:38:50 -0000       1.40
@@ -401,29 +401,26 @@
 #endif
 
 unsigned int
-movie_root::add_interval_timer(Timer& timer)
+movie_root::add_interval_timer(const Timer& timer)
 {
        assert(testInvariant());
                        
-       int id = _intervalTimers.size();
+       int id = _intervalTimers.size()+1;
 
        // TODO: find first NULL element in vector for reuse ?
-       _intervalTimers.push_back(&timer);
+       _intervalTimers.push_back(timer);
        return id;
 }
        
 bool
 movie_root::clear_interval_timer(unsigned int x)
 {
-       if ( x >= _intervalTimers.size() ) return false;
+       if ( ! x || x > _intervalTimers.size() ) return false;
 
-       Timer* timer = _intervalTimers[x];
+       Timer& timer = _intervalTimers[x-1];
 
-       // Check that _intervalTimers[x] does really exists.
-       if ( ! timer ) return false;
-
-       timer->clearInterval();
-       _intervalTimers[x] = NULL;
+       // will make sure next expire() will always return false!
+       timer.clearInterval();
 
        assert(testInvariant());
 
@@ -441,10 +438,7 @@
                        it != itEnd;
                        ++it)
        {
-               Timer* timerptr = *it;
-               if ( ! timerptr ) continue;
-
-               Timer& timer = *timerptr;
+               Timer& timer = *it;
                if ( timer.expired() )
                {
                        // log_msg("FIXME: Interval Timer Expired!\n");

Index: server/movie_root.h
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- server/movie_root.h 9 Feb 2007 05:52:49 -0000       1.35
+++ server/movie_root.h 9 Feb 2007 13:38:50 -0000       1.36
@@ -14,7 +14,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: movie_root.h,v 1.35 2007/02/09 05:52:49 rsavoye Exp $ */
+/* $Id: movie_root.h,v 1.36 2007/02/09 13:38:50 strk Exp $ */
 
 /// \page events_handling Handling of user events
 ///
@@ -76,11 +76,10 @@
 #include "mouse_button_state.h" // for composition
 #include "drag_state.h" // for composition
 #include "sprite_instance.h" // for inlines
+#include "timers.h" // for composition
 
 // Forward declarations
-namespace gnash {
-       class Timer;
-}
+// none needed
 
 namespace gnash
 {
@@ -204,10 +203,13 @@
 
        /// Add an interval timer
        //
+       /// @param timer
+       ///     A Timer, will be copied.
+       ///
        /// @return an integer indentifying the timer
        ///         for subsequent call to clear_interval_timer
        ///
-       unsigned int add_interval_timer(Timer& timer);
+       unsigned int add_interval_timer(const Timer& timer);
 
        /// Remove timer identified by given integer
        //
@@ -389,7 +391,7 @@
        //        for timers, as we'll be removing them from the
        //        list but still want Timer "identifiers" to be
        //        valid.
-       typedef std::vector<Timer *> TimerList;
+       typedef std::vector<Timer> TimerList;
        TimerList _intervalTimers;
 
        std::vector< as_object* >       m_keypress_listeners;

Index: server/timers.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/timers.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- server/timers.cpp   9 Feb 2007 00:19:07 -0000       1.21
+++ server/timers.cpp   9 Feb 2007 13:38:50 -0000       1.22
@@ -18,7 +18,7 @@
 //
 //
 
-/* $Id: timers.cpp,v 1.21 2007/02/09 00:19:07 strk Exp $ */
+/* $Id: timers.cpp,v 1.22 2007/02/09 13:38:50 strk Exp $ */
 
 #include "timers.h"
 #include "as_function.h" // for class as_function
@@ -33,114 +33,70 @@
 using namespace std;
 
 namespace gnash {
+
   Timer::Timer() :
-      _which(0),
-      _interval(0.0),
-      _start(0.0),
+      _interval(0),
+      _start(0),
       _object(0),
       _env(0)
   {
   }
   
-  Timer::Timer(as_value *obj, int ms)
-  {
-    setInterval(*obj, ms);
-    start();
-  }
-  
   Timer::~Timer()
   {
-    log_msg("%s: \n", __FUNCTION__);
-  }
-  
-  int
-  Timer::setInterval(as_value obj, int ms)
-  {
-    _function = obj;
-    _interval = ms * 0.01;
-    // _interval = ms * 0.000001;
-    start();
-
-    return 0;
-  }
-
-  int
-  Timer::setInterval(as_value obj, int ms, as_environment *en)
-  {
-    _function = obj;
-    _interval = ms * 0.01;
-    _env = en;
-    // _interval = ms * 0.000001;
-    start();
-
-    return 0;
+    //log_msg("%s: \n", __FUNCTION__);
   }
-  int
-  Timer::setInterval(as_value obj, int ms, std::vector<variable *> *locals)
-  {
-    _function = obj;
-    _interval = ms * 0.01;
-    _locals = locals;
-    // _interval = ms * 0.000001;
-    start();
 
-    return 0;
-  }
 
-  int
-  Timer::setInterval(as_value obj, int ms, as_object *this_ptr, as_environment 
*en)
+  void
+  Timer::setInterval(as_function& method, unsigned ms, as_object* this_ptr, 
as_environment *env)
   {
-    _function = obj;
-    _interval = ms * 0.01;
-    _env = en;
+    _function = &method;
+    _interval = ms * 1000; // transform to microseconds 
+    //log_msg("_interval microseconds: %lu", _interval);
+    _env = env;
     _object = this_ptr;
-    // _interval = ms * 0.000001;
     start();
-
-    return 0;
   }
 
   void
   Timer::clearInterval()
   {
-    _interval = 0.0;
-    _start = 0.0;
+    _interval = 0;
+    _start = 0;
   }
   
   void
   Timer::start()
   {
-    uint64 ticks = tu_timer::get_profile_ticks();
-    _start = tu_timer::profile_ticks_to_seconds(ticks);
+       _start = tu_timer::get_profile_ticks();
+       //log_msg("_start at seconds %lu", _start);
   }
   
 
-  bool
-  Timer::expired()
+bool
+Timer::expired()
+{
+       if (_start)
   {
-    if (_start > 0.0) {
-      uint64 ticks = tu_timer::get_profile_ticks();
-      double now = tu_timer::profile_ticks_to_seconds(ticks);
+               uint64 now = tu_timer::get_profile_ticks();
+               //log_msg("now: %lu", now);
+               assert(now > _start);
+
       //printf("FIXME: %s: now is %f, start time is %f, interval is %f\n", 
__FUNCTION__, now, _start, _interval);
-      if (now > _start + _interval) {
+               if (now > _start + _interval)
+               {
         _start = now;               // reset the timer
         //log_msg("Timer expired! \n");
         return true;
       }
-      // FIXME: Sometimes, "now" and "_start" have bad values.
-      // I don't know why, but this works around the problem..
-      else if (now < _start) {
-        log_msg( "Timer::expired - now (%f) is before start (%f)!\n"
-                 "     Expiring right now.\n",
-                 now, _start);
-        _start = now;
-        return true;
       }
+       else
+       {
+               //log_msg("Timer not enabled!");
     }
-      
-    // log_msg("Timer not enabled! \n");
     return false;
-  }
+}
 
 void
 Timer::operator() ()
@@ -148,26 +104,19 @@
     //printf("FIXME: %s:\n", __FUNCTION__);
     //log_msg("INTERVAL ID is %d\n", getIntervalID());
 
-    const as_value& timer_method = getASFunction();
-    as_environment* as_env = getASEnvironment();
-               
-    as_object* obj = getObject();
-    as_value val = call_method(timer_method, as_env, obj, 0, 0);
-
-    //as_object* this_ptr = getASObject();
-    //as_value val = call_method(timer_method, as_env, this_ptr, 0, 0);
+    as_value timer_method(_function.get());
+    as_value val = call_method(timer_method, _env, _object.get(), 0, 0);
 
 }
 
+// TODO: move to Global.cpp
 void
 timer_setinterval(const fn_call& fn)
 {
-       log_msg("%s: args=%d\n", __FUNCTION__, fn.nargs);
-    
-       timer_as_object *ptr = new timer_as_object;
+       //log_msg("%s: args=%d", __FUNCTION__, fn.nargs);
     
        // Get interval function
-       as_function *as_func = fn.arg(0).to_as_function();
+       boost::intrusive_ptr<as_function> as_func = fn.arg(0).to_as_function();
        if ( ! as_func )
        {
                IF_VERBOSE_ASCODING_ERRORS(
@@ -183,44 +132,19 @@
        // Get interval time
        int ms = int(fn.arg(1).to_number());
 
-       fn.env->add_frame_barrier();
-       //method = env->get_variable("loopvar");
-
-#if 0
-    // FIXME: This is pretty gross, but something is broke elsewhere and it 
doesn't
-    // seem to effect anything else. When a function is called from a executing
-    // function, like calling setInterval() from within the callback to
-    // XMLSocket::onConnect(), the local variables of the parent function need 
to
-    // be propogated to the local stack as regular variables (not locals) or
-    // they can't be found in the scope of the executing chld function. There 
is
-    // probably a better way to do this... but at least this works.
-    for (i=0; i< fn.env->get_local_frame_top(); i++) {
-      if (fn.env->m_local_frames[i].m_name.size()) {
-        //method = env->get_variable(env->m_local_frames[i].m_name);
-        //if (method.get_type() != as_value::UNDEFINED)
-        {
-          string local_name  = fn.env->m_local_frames[i].m_name;
-          as_value local_val = fn.env->m_local_frames[i].m_value;
-          fn.env->set_variable(local_name, local_val);
-        }
-      }
-    }
-#endif
-
-       as_value val(as_func);
-
-       //Ptr->obj.setInterval(val, ms);
-       ptr->obj.setInterval(val, ms, ptr, fn.env);
+       Timer timer;
+       timer.setInterval(*as_func, ms, fn.this_ptr, fn.env);
     
        movie_root& root = VM::get().getRoot();
-       int id = root.add_interval_timer(ptr->obj);
+       int id = root.add_interval_timer(timer);
        fn.result->set_int(id);
 }
   
+// TODO: move to Global.cpp
 void
 timer_clearinterval(const fn_call& fn)
 {
-       log_msg("%s: nargs = %d\n", __FUNCTION__, fn.nargs);
+       //log_msg("%s: nargs = %d", __FUNCTION__, fn.nargs);
 
        int id = int(fn.arg(0).to_number());
 
@@ -228,4 +152,5 @@
        bool ret = root.clear_interval_timer(id);
        fn.result->set_bool(ret);
 }
-}
+
+} // namespace gnash

Index: server/timers.h
===================================================================
RCS file: /sources/gnash/gnash/server/timers.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- server/timers.h     9 Feb 2007 00:19:07 -0000       1.13
+++ server/timers.h     9 Feb 2007 13:38:50 -0000       1.14
@@ -27,13 +27,17 @@
 
 #include "as_value.h" // for struct variable composition
 #include "as_object.h" // for inheritance
+#include "as_function.h" // for visibility of destructor by intrusive_ptr
+#include "smart_ptr.h"
 
 #include "tu_timer.h"
 
 #include <string>
 
+// Forward declarations
 namespace gnash {
        class fn_call;
+       class as_function;
 }
 
 namespace gnash {
@@ -43,62 +47,97 @@
     as_value value;
   };
 
-  class Timer
-    {
-    public:
+/// An interval timer.
+//
+/// This is constructed when _global.setInterval() is called.
+/// Instances of this class will be stored in the movie_root singleton.
+///
+/// A timer has a function to call, a context in which to call it, and
+/// interval specifying how often the function must be called.
+//
+/// It is *not* a "smart" timer, which is
+/// it will *not* automatically execute at given intervals. Rather, it
+/// will be movie_root responsibility to execute the timer-associated
+/// function at regular intervals. As a facility, the Timer class provides
+/// an execution operator, proxying the execution to the associated function
+/// with properly set-up context.
+///
+///
+class Timer
+{
+
+public:
+
+      /// Construct a disabled (cleared) timer.
       Timer();
-      Timer(as_value *obj, int ms);
-      Timer(as_value method, int ms);
+
       ~Timer();
-      int setInterval(as_value obj, int ms);
-      int setInterval(as_value obj, int ms, as_object *this_ptr, 
as_environment *env);
-      int setInterval(as_value obj, int ms, as_environment *env);
-      int setInterval(as_value obj, int ms, std::vector<variable *> *locals);
-      void setInterval(int ms) 
-      {
-        _interval = ms * 0.000001;
-      }
 
+      /// Setup the Timer, enabling it.
+      //
+      /// @param method
+      ///      The function to call from execution operator.
+      ///      Will be stored in an intrusive_ptr.
+      ///
+      /// @param ms
+      ///      The number of milliseconds between expires.
+      ///
+      /// @param this_ptr
+      ///      The object to be used as 'this' pointer when calling the
+      ///      associated function. Will be stored in an intrusive_ptr.
+      ///      It is allowed to be NULL as long as fn_call is allowed
+      ///      a NULL as 'this_ptr' (we might want to change this).
+      ///
+      /// @param env
+      ///      The environment in which the associated function will be run.
+      ///      Not sure we should provide this rather then extracting from 
this_ptr...
+      ///
+      void setInterval(as_function& method, unsigned ms, as_object* this_ptr, 
as_environment *env);
+
+      /// Clear the timer, ready for reuse
+      //
+      /// When a Timer is cleared, the expired() function
+      /// will always return false.
+      ///
+      /// Use setInterval() to reset it.
+      ///
       void clearInterval();
-      void start();
-      bool expired();
-      void setObject(as_object *ao) { _object = ao; }
-      as_object *getObject() { return _object; }
       
-      // Accessors
-      const as_value& getASFunction() { return _function;  }
-      as_environment *getASEnvironment() { return _env;  }
-      as_object *getASObject() { return _object;  }
-      std::vector<struct variable *> *getLocals() { return _locals;  }
-      int getIntervalID()  { return _which;  }
-      void add_local(const std::string& name, as_value value) {
-        struct variable *var = new struct variable; // FIXME: who'll delete ?
-        var->name = name;
-        var->value = value;
-        _locals->push_back(var);
-      }
+      /// Return true if interval ticks are passed since last call to start()
+      //
+      /// Always returns false if the timer is cleared.
+      //
+      bool expired();
 
-      /// Execute timer function
+      /// Execute associated function properly setting up context
       void operator() ();
       
       
 
-    private:
-      int             _which;                // Which timer
-      double          _interval;
-      double          _start;
-      as_value        _function;
-      as_object      *_object;
-      as_environment *_env;
-      std::vector<struct variable *> *_locals;
+private:
       
-    };
+      /// Set timer start
+      //
+      /// Called by every function setting the interval.
+      ///
+      void start();
   
-  class timer_as_object : public gnash::as_object
-  {
-  public:
-    Timer obj;
-  };
+      /// Number of microseconds between expirations 
+      uint64 _interval;
+
+      /// Number of microseconds since epoch at Timer start
+      uint64 _start;
+
+      /// The associated function, stored in an intrusive pointer
+      boost::intrusive_ptr<as_function> _function;
+
+      /// Context for the function call. Will be used as 'this' pointer.
+      boost::intrusive_ptr<as_object> _object;
+
+      /// how to keep this alive ?
+      as_environment *_env;
+
+};
   
   void timer_setinterval(const fn_call& fn);
   void timer_clearinterval(const fn_call& fn);

Index: server/asobj/xmlsocket.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/xmlsocket.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- server/asobj/xmlsocket.cpp  9 Feb 2007 00:19:07 -0000       1.4
+++ server/asobj/xmlsocket.cpp  9 Feb 2007 13:38:50 -0000       1.5
@@ -26,6 +26,7 @@
 #include "fn_call.h"
 #include "sprite_instance.h"
 #include "VM.h"
+#include "builtin_function.h" // for setting timer, should likely avoid that..
 
 #include "log.h"
 
@@ -529,10 +530,9 @@
 
 #if 1
   Timer *timer = new Timer;
-  as_c_function_ptr ondata_handler =
-    (as_c_function_ptr)&xmlsocket_event_ondata;
-  timer->setInterval(ondata_handler, 50, ptr, fn.env);
-  timer->setObject(ptr);
+  boost::intrusive_ptr<builtin_function> ondata_handler = new builtin_function(
+                 &xmlsocket_event_ondata, NULL);
+  timer->setInterval(*ondata_handler, 50, ptr, fn.env);
   VM::get().getRoot().add_interval_timer(*timer);
 #endif
 

Index: testsuite/misc-ming.all/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/Makefile.am,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -b -r1.62 -r1.63
--- testsuite/misc-ming.all/Makefile.am 8 Feb 2007 22:23:01 -0000       1.62
+++ testsuite/misc-ming.all/Makefile.am 9 Feb 2007 13:38:50 -0000       1.63
@@ -478,6 +478,9 @@
        sh $< $(top_builddir) VarAndCharClashTest.swf > $@
        chmod 755 $@
 
+intervalTest.swf: $(srcdir)/../media/green.swf ../Dejagnu.swf 
$(srcdir)/intervalTest.as 
+       $(MAKESWF) -o $@ ../Dejagnu.swf $(srcdir)/intervalTest.as
+
 # This will only work with Ming-0.4.0beta2 (support for prebuilt clips 
inclusion)
 # Uses a low frame rate to test immediate redraw on key event
 KeyTest.swf: $(srcdir)/../media/green.swf ../Dejagnu.swf $(srcdir)/KeyTest.as 

Index: testsuite/misc-ming.all/intervalTest.as
===================================================================
RCS file: testsuite/misc-ming.all/intervalTest.as
diff -N testsuite/misc-ming.all/intervalTest.as
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ testsuite/misc-ming.all/intervalTest.as     9 Feb 2007 13:38:50 -0000       
1.1
@@ -0,0 +1,60 @@
+// 
+//   Copyright (C) 2007 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+//
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+// These are already checked in Global.as, and it would be
+// clear if things don't work as expected
+check_equals(typeof(setInterval), 'function');
+check_equals(typeof(clearInterval), 'function');
+
+do_this = function() {
+       ++this_counter;
+       xtrace("Doing this "+this_counter);
+       if ( this_counter > 3 )
+       {
+               clearInterval(this_interval);
+               xtrace("This interval cleared ");
+               if ( this_counter > 4 )
+               {
+                       totals();
+               }
+       }
+};
+
+do_that = function() {
+       ++that_counter;
+       xtrace("Doing that "+that_counter);
+       if ( that_counter > 3 )
+       {
+               clearInterval(that_interval);
+               xtrace("That interval cleared ");
+               this_interval = setInterval(do_this, 1);
+               // interval 1 is NOT reused
+               check_equals(this_interval, 3);
+       }
+};
+
+this_counter = 0;
+this_interval  = setInterval(do_this, 0.0001);
+check_equals(this_interval, 1);
+
+that_counter = 0;
+that_interval  = setInterval(do_that, 1000);
+check_equals(that_interval, 2);
+
+stop();




reply via email to

[Prev in Thread] Current Thread [Next in Thread]