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