#include "node.h" #include "timer.h" #include using namespace v8; using namespace node; #define REPEAT_SYMBOL String::NewSymbol("repeat") Persistent Timer::constructor_template; void Timer::Initialize (Handle target) { HandleScope scope; Local t = FunctionTemplate::New(Timer::New); constructor_template = Persistent::New(t); constructor_template->Inherit(EventEmitter::constructor_template); constructor_template->InstanceTemplate()->SetInternalFieldCount(1); NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", Timer::Start); NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", Timer::Stop); constructor_template->PrototypeTemplate()->SetAccessor(REPEAT_SYMBOL, RepeatGetter, RepeatSetter); target->Set(String::NewSymbol("Timer"), constructor_template->GetFunction()); } Handle Timer::RepeatGetter (Local property, const AccessorInfo& info) { HandleScope scope; Timer *timer = ObjectWrap::Unwrap(info.This()); assert(timer); assert (property == REPEAT_SYMBOL); Local v = Integer::New(timer->watcher_.repeat); return scope.Close(v); } void Timer::RepeatSetter (Local property, Local value, const AccessorInfo& info) { HandleScope scope; Timer *timer = ObjectWrap::Unwrap(info.This()); assert(timer); assert(property == REPEAT_SYMBOL); timer->watcher_.repeat = NODE_V8_UNIXTIME(value); } void Timer::OnTimeout (EV_P_ ev_timer *watcher, int revents) { Timer *timer = static_cast(watcher->data); assert(revents == EV_TIMEOUT); timer->Emit("timeout", 0, NULL); if (timer->watcher_.repeat == 0) timer->Detach(); } Timer::~Timer () { ev_timer_stop (EV_DEFAULT_UC_ &watcher_); } Handle Timer::New (const Arguments& args) { HandleScope scope; Timer *t = new Timer(); t->Wrap(args.Holder()); return args.This(); } Handle Timer::Start (const Arguments& args) { Timer *timer = ObjectWrap::Unwrap(args.Holder()); HandleScope scope; if (args.Length() != 2) return ThrowException(String::New("Bad arguments")); ev_tstamp after = NODE_V8_UNIXTIME(args[0]); ev_tstamp repeat = NODE_V8_UNIXTIME(args[1]); ev_timer_init(&timer->watcher_, Timer::OnTimeout, after, repeat); timer->watcher_.data = timer; ev_timer_start(EV_DEFAULT_UC_ &timer->watcher_); timer->Attach(); return Undefined(); } Handle Timer::Stop (const Arguments& args) { Timer *timer = ObjectWrap::Unwrap(args.Holder()); ev_timer_stop(EV_DEFAULT_UC_ &timer->watcher_); timer->Detach(); return Undefined(); }