summaryrefslogtreecommitdiff
path: root/src/timers.cc
diff options
context:
space:
mode:
authorRyan <ry@tinyclouds.org>2009-04-21 16:22:14 +0200
committerRyan <ry@tinyclouds.org>2009-04-21 16:24:56 +0200
commit5d57fa5060ff9d6a5c708ad4159fe582d146f700 (patch)
tree7340376665858ca947960b3dd0322c71247a7e50 /src/timers.cc
parent47fad676b44976b2e8fc23450eaed4a538cc5c7a (diff)
downloadnode-new-5d57fa5060ff9d6a5c708ad4159fe582d146f700.tar.gz
clean up timers a bit
Diffstat (limited to 'src/timers.cc')
-rw-r--r--src/timers.cc188
1 files changed, 70 insertions, 118 deletions
diff --git a/src/timers.cc b/src/timers.cc
index 88154ed81d..967cfb27e1 100644
--- a/src/timers.cc
+++ b/src/timers.cc
@@ -4,102 +4,82 @@
using namespace v8;
+static Persistent<ObjectTemplate> timer_template;
+
class Timer {
public:
- Timer(Handle<Function> callback, int argc, Handle<Value> argv[], ev_tstamp after, ev_tstamp repeat);
+ Timer(Handle<Function> callback, ev_tstamp after, ev_tstamp repeat);
~Timer();
- Local<External> CreateTimeoutID ();
- void CallCallback ();
- private:
- ev_timer watcher;
- Persistent<External> timeoutID;
- Persistent<Function> callback;
- int argc;
- Persistent<Value> argv[];
-};
-static void
-onTimeout (struct ev_loop *loop, ev_timer *watcher, int revents)
-{
- Timer *timer = static_cast<Timer*>(watcher->data);
+ static Handle<Value> setTimeout (const Arguments& args);
+ static Handle<Value> setInterval (const Arguments& args);
+ static Handle<Value> clearTimeout (const Arguments& args);
- timer->CallCallback();
+ Persistent<Object> handle_;
- // use ev_is_active instead?
- if(watcher->repeat == 0.)
- delete timer;
-}
+ private:
+ static Timer* Unwrap (Handle<Object> handle);
+ static void OnTimeout (EV_P_ ev_timer *watcher, int revents);
+ ev_timer watcher_;
+};
-Timer::Timer (Handle<Function> _callback, int _argc, Handle<Value> _argv[], ev_tstamp after, ev_tstamp repeat)
+Timer*
+Timer::Unwrap (Handle<Object> handle)
{
HandleScope scope;
- callback = Persistent<Function>::New(_callback);
- argc = _argc;
-
- ev_timer_init (&watcher, onTimeout, after, repeat);
- watcher.data = this;
- ev_timer_start (node_loop(), &watcher);
-}
-
-Timer::~Timer ()
-{
- ev_timer_stop (node_loop(), &watcher);
-
- callback.Dispose();
-
- timeoutID.Dispose();
- timeoutID.Clear();
+ Handle<External> field = Handle<External>::Cast(handle->GetInternalField(0));
+ Timer* timer = static_cast<Timer*>(field->Value());
+ return timer;
}
void
-Timer::CallCallback ()
+Timer::OnTimeout (EV_P_ ev_timer *watcher, int revents)
{
+ Timer *timer = static_cast<Timer*>(watcher->data);
+
HandleScope scope;
- TryCatch try_catch;
+ Local<Value> callback_value = timer->handle_->Get(String::NewSymbol("callback"));
+ if (!callback_value->IsFunction())
+ return;
- callback->Call (Context::GetCurrent()->Global(), argc, argv);
+ Local<Function> callback = Local<Function>::Cast(callback_value);
+ TryCatch try_catch;
+ callback->Call (Context::GetCurrent()->Global(), 0, NULL);
if(try_catch.HasCaught())
node_fatal_exception(try_catch);
+
+ // use ev_is_active instead?
+ if(watcher->repeat == 0.)
+ delete timer;
}
-Local<External>
-Timer::CreateTimeoutID ()
+Timer::Timer (Handle<Function> callback, ev_tstamp after, ev_tstamp repeat)
{
HandleScope scope;
- Local<External> timeoutID_local = External::New(this);
+ handle_ = Persistent<Object>::New(timer_template->NewInstance());
+ handle_->Set(String::NewSymbol("callback"), callback);
- timeoutID = Persistent<External>::New(timeoutID_local);
+ Local<External> external = External::New(this);
+ handle_->SetInternalField(0, external);
- return scope.Close(timeoutID_local);
+ ev_timer_init(&watcher_, Timer::OnTimeout, after, repeat);
+ watcher_.data = this;
+
+ ev_timer_start(node_loop(), &watcher_);
}
-static Timer *
-UnwrapTimeoutID (Handle<External> timeoutID)
+Timer::~Timer ()
{
- HandleScope scope;
-
- Timer *timer = static_cast<Timer*>(timeoutID->Value());
-
- return timer;
+ ev_timer_stop (node_loop(), &watcher_);
+ handle_->SetInternalField(0, Undefined());
+ handle_.Dispose();
}
-// timeoutID = setTimeout(func, delay, [param1, param2, ...]);
-// timeoutID = setTimeout(code, delay);
-//
-// * timeoutID is the ID of the timeout, which can be used with
-// clearTimeout.
-//
-// * func is the function you want to execute after delay milliseconds.
-//
-// * code in the alternate syntax, is a string of code you want to execute
-// after delay milliseconds. (not recommended)
-//
-// * delay is the number of milliseconds (thousandths of a second) that the
-// function call should be delayed by.
-NODE_METHOD(setTimeout)
+Handle<Value>
+Timer::setTimeout (const Arguments& args)
{
if (args.Length() < 2)
return Undefined();
@@ -113,52 +93,14 @@ NODE_METHOD(setTimeout)
if (args.Length() > 2)
assert(0 && "extra params to setTimeout not yet implemented.");
- int argc = 0;
- Handle<Value> argv[] = {};
- /*
- int argc = args.Length() - 2;
- Handle<Value> argv[] = new Handle<Value>[argc];
- // the rest of the arguments, if any arg parameters for the callback
- for(int i = 2; i < args.Length(); i++)
- argv[i - 2] = args[i];
- */
-
- Timer *timer = new Timer(callback, argc, argv, after, 0.0);
- Local<External> timeoutID = timer->CreateTimeoutID();
+ Timer *timer = new Timer(callback, after, 0.0);
- return scope.Close(timeoutID);
+ return scope.Close(timer->handle_);
}
-// clearTimeout(timeoutID)
-NODE_METHOD(clearTimeout)
-{
- if (args.Length() < 1)
- return Undefined();
-
- Handle<External> timeoutID = Handle<External>::Cast(args[0]);
- Timer *timer = UnwrapTimeoutID(timeoutID);
-
- delete timer;
-
- return Undefined();
-}
-
-// intervalID = setInterval(func, delay[, param1, param2, ...]);
-// intervalID = setInterval(code, delay);
-//
-// where
-//
-// * intervalID is a unique interval ID you can pass to clearInterval().
-//
-// * func is the function you want to be called repeatedly.
-//
-// * code in the alternate syntax, is a string of code you want to be executed
-// repeatedly.
-//
-// * delay is the number of milliseconds (thousandths of a second) that the
-// setInterval() function should wait before each call to func.
-NODE_METHOD(setInterval)
+Handle<Value>
+Timer::setInterval (const Arguments& args)
{
if (args.Length() < 2)
return Undefined();
@@ -170,16 +112,23 @@ NODE_METHOD(setInterval)
ev_tstamp after = (double)delay / 1000.0;
- if (args.Length() > 2)
- assert(0 && "extra params to setInterval not yet implemented.");
- int argc = 0;
- Handle<Value> argv[] = {};
+ Timer *timer = new Timer(callback, after, after);
- Timer *timer = new Timer(callback, argc, argv, after, after);
+ return scope.Close(timer->handle_);
+}
- Local<External> timeoutID = timer->CreateTimeoutID();
+Handle<Value>
+Timer::clearTimeout (const Arguments& args)
+{
+ if (args.Length() < 1)
+ return Undefined();
+
+ HandleScope scope;
+ Local<Object> handle = Local<Object>::Cast(args[0]);
+ Timer *timer = Timer::Unwrap(handle);
+ delete timer;
- return scope.Close(timeoutID);
+ return Undefined();
}
void
@@ -187,8 +136,11 @@ NodeInit_timers (Handle<Object> target)
{
HandleScope scope;
- NODE_SET_METHOD(target, "setTimeout", setTimeout);
- NODE_SET_METHOD(target, "clearTimeout", clearTimeout);
- NODE_SET_METHOD(target, "setInterval", setInterval);
- NODE_SET_METHOD(target, "clearInterval", clearTimeout);
+ timer_template = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
+ timer_template->SetInternalFieldCount(1);
+
+ NODE_SET_METHOD(target, "setTimeout", Timer::setTimeout);
+ NODE_SET_METHOD(target, "setInterval", Timer::setInterval);
+ NODE_SET_METHOD(target, "clearTimeout", Timer::clearTimeout);
+ NODE_SET_METHOD(target, "clearInterval", Timer::clearTimeout);
}