Browse Source

Decouple timer from EventEmitter

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
e72b072d53
  1. 14
      src/node.js
  2. 42
      src/node_timer.cc
  3. 7
      src/node_timer.h

14
src/node.js

@ -246,35 +246,33 @@ function addTimerListener (callback) {
// Special case the no param case to avoid the extra object creation. // Special case the no param case to avoid the extra object creation.
if (arguments.length > 2) { if (arguments.length > 2) {
var args = Array.prototype.slice.call(arguments, 2); var args = Array.prototype.slice.call(arguments, 2);
timer.addListener("timeout", function(){ timer.callback = function () { callback.apply(timer, args); };
callback.apply(timer, args);
});
} else { } else {
timer.addListener("timeout", callback); timer.callback = callback;
} }
} }
GLOBAL.setTimeout = function (callback, after) { global.setTimeout = function (callback, after) {
var timer = new process.Timer(); var timer = new process.Timer();
addTimerListener.apply(timer, arguments); addTimerListener.apply(timer, arguments);
timer.start(after, 0); timer.start(after, 0);
return timer; return timer;
}; };
GLOBAL.setInterval = function (callback, repeat) { global.setInterval = function (callback, repeat) {
var timer = new process.Timer(); var timer = new process.Timer();
addTimerListener.apply(timer, arguments); addTimerListener.apply(timer, arguments);
timer.start(repeat, repeat); timer.start(repeat, repeat);
return timer; return timer;
}; };
GLOBAL.clearTimeout = function (timer) { global.clearTimeout = function (timer) {
if (timer instanceof process.Timer) { if (timer instanceof process.Timer) {
timer.stop(); timer.stop();
} }
}; };
GLOBAL.clearInterval = GLOBAL.clearTimeout; global.clearInterval = global.clearTimeout;

42
src/node_timer.cc

@ -9,6 +9,7 @@ Persistent<FunctionTemplate> Timer::constructor_template;
static Persistent<String> timeout_symbol; static Persistent<String> timeout_symbol;
static Persistent<String> repeat_symbol; static Persistent<String> repeat_symbol;
static Persistent<String> callback_symbol;
void void
Timer::Initialize (Handle<Object> target) Timer::Initialize (Handle<Object> target)
@ -17,12 +18,12 @@ Timer::Initialize (Handle<Object> target)
Local<FunctionTemplate> t = FunctionTemplate::New(Timer::New); Local<FunctionTemplate> t = FunctionTemplate::New(Timer::New);
constructor_template = Persistent<FunctionTemplate>::New(t); constructor_template = Persistent<FunctionTemplate>::New(t);
constructor_template->Inherit(EventEmitter::constructor_template);
constructor_template->InstanceTemplate()->SetInternalFieldCount(1); constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
constructor_template->SetClassName(String::NewSymbol("Timer")); constructor_template->SetClassName(String::NewSymbol("Timer"));
timeout_symbol = NODE_PSYMBOL("timeout"); timeout_symbol = NODE_PSYMBOL("timeout");
repeat_symbol = NODE_PSYMBOL("repeat"); repeat_symbol = NODE_PSYMBOL("repeat");
callback_symbol = NODE_PSYMBOL("callback");
NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", Timer::Start); NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", Timer::Start);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", Timer::Stop); NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", Timer::Stop);
@ -66,7 +67,23 @@ Timer::OnTimeout (EV_P_ ev_timer *watcher, int revents)
assert(revents == EV_TIMEOUT); assert(revents == EV_TIMEOUT);
timer->Emit(timeout_symbol, 0, NULL); HandleScope scope;
Local<Value> callback_v = timer->handle_->Get(callback_symbol);
if (!callback_v->IsFunction()) {
timer->Stop();
return;
}
Local<Function> callback = Local<Function>::Cast(callback_v);
TryCatch try_catch;
callback->Call(timer->handle_, 0, NULL);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
if (timer->watcher_.repeat == 0) timer->Unref(); if (timer->watcher_.repeat == 0) timer->Unref();
} }
@ -90,8 +107,8 @@ Timer::New (const Arguments& args)
Handle<Value> Handle<Value>
Timer::Start (const Arguments& args) Timer::Start (const Arguments& args)
{ {
Timer *timer = ObjectWrap::Unwrap<Timer>(args.Holder());
HandleScope scope; HandleScope scope;
Timer *timer = ObjectWrap::Unwrap<Timer>(args.Holder());
if (args.Length() != 2) if (args.Length() != 2)
return ThrowException(String::New("Bad arguments")); return ThrowException(String::New("Bad arguments"));
@ -108,13 +125,18 @@ Timer::Start (const Arguments& args)
return Undefined(); return Undefined();
} }
Handle<Value>
Timer::Stop (const Arguments& args) Handle<Value> Timer::Stop(const Arguments& args) {
{ HandleScope scope;
Timer *timer = ObjectWrap::Unwrap<Timer>(args.Holder()); Timer *timer = ObjectWrap::Unwrap<Timer>(args.Holder());
if (ev_is_active(&timer->watcher_)) { timer->Stop();
ev_timer_stop(EV_DEFAULT_UC_ &timer->watcher_);
timer->Unref();
}
return Undefined(); return Undefined();
} }
void Timer::Stop () {
if (watcher_.active) {
ev_timer_stop(EV_DEFAULT_UC_ &watcher_);
Unref();
}
}

7
src/node_timer.h

@ -2,20 +2,20 @@
#define node_timer_h #define node_timer_h
#include <node.h> #include <node.h>
#include <node_events.h> #include <node_object_wrap.h>
#include <v8.h> #include <v8.h>
#include <ev.h> #include <ev.h>
namespace node { namespace node {
class Timer : EventEmitter { class Timer : ObjectWrap {
public: public:
static void Initialize (v8::Handle<v8::Object> target); static void Initialize (v8::Handle<v8::Object> target);
protected: protected:
static v8::Persistent<v8::FunctionTemplate> constructor_template; static v8::Persistent<v8::FunctionTemplate> constructor_template;
Timer () : EventEmitter () { } Timer () : ObjectWrap () { }
~Timer(); ~Timer();
static v8::Handle<v8::Value> New (const v8::Arguments& args); static v8::Handle<v8::Value> New (const v8::Arguments& args);
@ -26,6 +26,7 @@ class Timer : EventEmitter {
private: private:
static void OnTimeout (EV_P_ ev_timer *watcher, int revents); static void OnTimeout (EV_P_ ev_timer *watcher, int revents);
void Stop ();
ev_timer watcher_; ev_timer watcher_;
}; };

Loading…
Cancel
Save