mirror of https://github.com/lukechilds/node.git
Browse Source
Timer now uses ObjectWrap. setTimeout, setInterval are now implemented in javascript.v0.7.4-release
Ryan
16 years ago
7 changed files with 139 additions and 161 deletions
@ -0,0 +1,103 @@ |
|||||
|
#include "node.h" |
||||
|
#include "timer.h" |
||||
|
#include <assert.h> |
||||
|
|
||||
|
using namespace v8; |
||||
|
|
||||
|
class Timer : node::ObjectWrap { |
||||
|
public: |
||||
|
Timer(Handle<Object> handle, Handle<Function> callback, ev_tstamp after, ev_tstamp repeat); |
||||
|
~Timer(); |
||||
|
|
||||
|
static Handle<Value> New (const Arguments& args); |
||||
|
static Handle<Value> Start (const Arguments& args); |
||||
|
static Handle<Value> Stop (const Arguments& args); |
||||
|
|
||||
|
private: |
||||
|
static void OnTimeout (EV_P_ ev_timer *watcher, int revents); |
||||
|
ev_timer watcher_; |
||||
|
}; |
||||
|
|
||||
|
void |
||||
|
Timer::OnTimeout (EV_P_ ev_timer *watcher, int revents) |
||||
|
{ |
||||
|
Timer *timer = static_cast<Timer*>(watcher->data); |
||||
|
|
||||
|
HandleScope scope; |
||||
|
|
||||
|
Local<Value> callback_value = timer->handle_->Get(String::NewSymbol("callback")); |
||||
|
if (!callback_value->IsFunction()) |
||||
|
return; |
||||
|
|
||||
|
Local<Function> callback = Local<Function>::Cast(callback_value); |
||||
|
|
||||
|
TryCatch try_catch; |
||||
|
callback->Call (timer->handle_, 0, NULL); |
||||
|
if (try_catch.HasCaught()) |
||||
|
node::fatal_exception(try_catch); |
||||
|
} |
||||
|
|
||||
|
Timer::Timer (Handle<Object> handle, Handle<Function> callback, ev_tstamp after, ev_tstamp repeat) |
||||
|
: ObjectWrap(handle) |
||||
|
{ |
||||
|
HandleScope scope; |
||||
|
|
||||
|
handle_->Set(String::NewSymbol("callback"), callback); |
||||
|
|
||||
|
ev_timer_init(&watcher_, Timer::OnTimeout, after, repeat); |
||||
|
watcher_.data = this; |
||||
|
|
||||
|
ev_timer_start(EV_DEFAULT_UC_ &watcher_); |
||||
|
} |
||||
|
|
||||
|
Timer::~Timer () |
||||
|
{ |
||||
|
ev_timer_stop (EV_DEFAULT_UC_ &watcher_); |
||||
|
} |
||||
|
|
||||
|
Handle<Value> |
||||
|
Timer::New (const Arguments& args) |
||||
|
{ |
||||
|
if (args.Length() < 2) |
||||
|
return Undefined(); |
||||
|
|
||||
|
HandleScope scope; |
||||
|
|
||||
|
Local<Function> callback = Local<Function>::Cast(args[0]); |
||||
|
|
||||
|
ev_tstamp after = (double)(args[1]->IntegerValue()) / 1000.0; |
||||
|
ev_tstamp repeat = (double)(args[2]->IntegerValue()) / 1000.0; |
||||
|
|
||||
|
Timer *timer = new Timer(args.Holder(), callback, after, repeat); |
||||
|
|
||||
|
return scope.Close(timer->handle_); |
||||
|
} |
||||
|
|
||||
|
Handle<Value> |
||||
|
Timer::Start (const Arguments& args) |
||||
|
{ |
||||
|
Timer *timer = NODE_UNWRAP(Timer, args.Holder()); |
||||
|
ev_timer_start(EV_DEFAULT_UC_ &timer->watcher_); |
||||
|
return Undefined(); |
||||
|
} |
||||
|
|
||||
|
Handle<Value> |
||||
|
Timer::Stop (const Arguments& args) |
||||
|
{ |
||||
|
Timer *timer = NODE_UNWRAP(Timer, args.Holder()); |
||||
|
ev_timer_stop(EV_DEFAULT_UC_ &timer->watcher_); |
||||
|
return Undefined(); |
||||
|
} |
||||
|
|
||||
|
void |
||||
|
node::Init_timer (Handle<Object> target) |
||||
|
{ |
||||
|
HandleScope scope; |
||||
|
|
||||
|
Local<FunctionTemplate> timer_template = FunctionTemplate::New(Timer::New); |
||||
|
timer_template->InstanceTemplate()->SetInternalFieldCount(1); |
||||
|
target->Set(String::NewSymbol("Timer"), timer_template->GetFunction()); |
||||
|
|
||||
|
NODE_SET_METHOD(timer_template->InstanceTemplate(), "start", Timer::Start); |
||||
|
NODE_SET_METHOD(timer_template->InstanceTemplate(), "stop", Timer::Stop); |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
#ifndef node_timer_h |
||||
|
#define node_timer_h |
||||
|
|
||||
|
#include <v8.h> |
||||
|
|
||||
|
namespace node { |
||||
|
|
||||
|
void Init_timer (v8::Handle<v8::Object> target); |
||||
|
|
||||
|
} // namespace node
|
||||
|
#endif // node_timer_h
|
@ -1,146 +0,0 @@ |
|||||
#include "node.h" |
|
||||
#include "timers.h" |
|
||||
#include <assert.h> |
|
||||
|
|
||||
using namespace v8; |
|
||||
|
|
||||
static Persistent<ObjectTemplate> timer_template; |
|
||||
|
|
||||
class Timer { |
|
||||
public: |
|
||||
Timer(Handle<Function> callback, ev_tstamp after, ev_tstamp repeat); |
|
||||
~Timer(); |
|
||||
|
|
||||
static Handle<Value> setTimeout (const Arguments& args); |
|
||||
static Handle<Value> setInterval (const Arguments& args); |
|
||||
static Handle<Value> clearTimeout (const Arguments& args); |
|
||||
|
|
||||
Persistent<Object> handle_; |
|
||||
|
|
||||
private: |
|
||||
static Timer* Unwrap (Handle<Object> handle); |
|
||||
static void OnTimeout (EV_P_ ev_timer *watcher, int revents); |
|
||||
ev_timer watcher_; |
|
||||
}; |
|
||||
|
|
||||
Timer* |
|
||||
Timer::Unwrap (Handle<Object> handle) |
|
||||
{ |
|
||||
HandleScope scope; |
|
||||
Handle<External> field = Handle<External>::Cast(handle->GetInternalField(0)); |
|
||||
Timer* timer = static_cast<Timer*>(field->Value()); |
|
||||
return timer; |
|
||||
} |
|
||||
|
|
||||
void |
|
||||
Timer::OnTimeout (EV_P_ ev_timer *watcher, int revents) |
|
||||
{ |
|
||||
Timer *timer = static_cast<Timer*>(watcher->data); |
|
||||
|
|
||||
HandleScope scope; |
|
||||
|
|
||||
Local<Value> callback_value = timer->handle_->Get(String::NewSymbol("callback")); |
|
||||
if (!callback_value->IsFunction()) |
|
||||
return; |
|
||||
|
|
||||
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; |
|
||||
} |
|
||||
|
|
||||
Timer::Timer (Handle<Function> callback, ev_tstamp after, ev_tstamp repeat) |
|
||||
{ |
|
||||
HandleScope scope; |
|
||||
|
|
||||
handle_ = Persistent<Object>::New(timer_template->NewInstance()); |
|
||||
handle_->Set(String::NewSymbol("callback"), callback); |
|
||||
|
|
||||
Local<External> external = External::New(this); |
|
||||
handle_->SetInternalField(0, external); |
|
||||
|
|
||||
ev_timer_init(&watcher_, Timer::OnTimeout, after, repeat); |
|
||||
watcher_.data = this; |
|
||||
|
|
||||
ev_timer_start(EV_DEFAULT_UC_ &watcher_); |
|
||||
} |
|
||||
|
|
||||
Timer::~Timer () |
|
||||
{ |
|
||||
ev_timer_stop (EV_DEFAULT_UC_ &watcher_); |
|
||||
handle_->SetInternalField(0, Undefined()); |
|
||||
handle_.Dispose(); |
|
||||
} |
|
||||
|
|
||||
Handle<Value> |
|
||||
Timer::setTimeout (const Arguments& args) |
|
||||
{ |
|
||||
if (args.Length() < 2) |
|
||||
return Undefined(); |
|
||||
|
|
||||
HandleScope scope; |
|
||||
|
|
||||
Local<Function> callback = Local<Function>::Cast(args[0]); |
|
||||
int delay = args[1]->IntegerValue(); |
|
||||
|
|
||||
ev_tstamp after = (double)delay / 1000.0; |
|
||||
|
|
||||
if (args.Length() > 2) |
|
||||
assert(0 && "extra params to setTimeout not yet implemented."); |
|
||||
|
|
||||
Timer *timer = new Timer(callback, after, 0.0); |
|
||||
|
|
||||
return scope.Close(timer->handle_); |
|
||||
} |
|
||||
|
|
||||
Handle<Value> |
|
||||
Timer::setInterval (const Arguments& args) |
|
||||
{ |
|
||||
if (args.Length() < 2) |
|
||||
return Undefined(); |
|
||||
|
|
||||
HandleScope scope; |
|
||||
|
|
||||
Local<Function> callback = Local<Function>::Cast(args[0]); |
|
||||
int delay = args[1]->IntegerValue(); |
|
||||
|
|
||||
ev_tstamp after = (double)delay / 1000.0; |
|
||||
|
|
||||
Timer *timer = new Timer(callback, after, after); |
|
||||
|
|
||||
return scope.Close(timer->handle_); |
|
||||
} |
|
||||
|
|
||||
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 Undefined(); |
|
||||
} |
|
||||
|
|
||||
void |
|
||||
node::Init_timers (Handle<Object> target) |
|
||||
{ |
|
||||
HandleScope scope; |
|
||||
|
|
||||
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); |
|
||||
} |
|
@ -1,11 +0,0 @@ |
|||||
#ifndef node_timers_h |
|
||||
#define node_timers_h |
|
||||
|
|
||||
#include <v8.h> |
|
||||
|
|
||||
namespace node { |
|
||||
|
|
||||
void Init_timers (v8::Handle<v8::Object> target); |
|
||||
|
|
||||
} // namespace node
|
|
||||
#endif // node_timers_h
|
|
Loading…
Reference in new issue