0
0
mirror of https://github.com/nodejs/node.git synced 2024-12-01 16:10:02 +01:00

Timers on Events

This commit is contained in:
Ryan 2009-06-25 20:25:44 +02:00
parent 2ecd7ffe54
commit b4af3b9fb5
3 changed files with 63 additions and 49 deletions

View File

@ -1,20 +1,23 @@
node.tcp.Server = function (on_connection, options) {
this.__proto__ = node.tcp.LowLevelServer ();
node.debug("hello world");
if (on_connection) this.addListener("Connection", on_connection);
node.tcp.createServer = function (on_connection, options) {
var server = new node.tcp.Server();
server.addListener("Connection", on_connection);
//server.setOptions(options);
return server;
};
// Timers
function setTimeout (callback, delay) {
var timer = new node.Timer(callback, delay, 0);
timer.start();
function setTimeout (callback, after) {
var timer = new node.Timer();
timer.addListener("Timeout", callback);
timer.start(after, 0);
return timer;
}
function setInterval (callback, delay) {
var timer = new node.Timer(callback, delay, delay);
timer.start();
function setInterval (callback, repeat) {
var timer = new node.Timer();
timer.addListener("Timeout", callback);
timer.start(repeat, repeat);
return timer;
}

View File

@ -5,7 +5,7 @@
using namespace v8;
using namespace node;
#define CALLBACK_SYMBOL String::NewSymbol("callback")
#define REPEAT_SYMBOL String::NewSymbol("repeat")
Persistent<FunctionTemplate> Timer::constructor_template;
@ -16,31 +16,50 @@ Timer::Initialize (Handle<Object> target)
Local<FunctionTemplate> t = FunctionTemplate::New(Timer::New);
constructor_template = Persistent<FunctionTemplate>::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<Value>
Timer::RepeatGetter (Local<String> property, const AccessorInfo& info)
{
HandleScope scope;
Timer *timer = NODE_UNWRAP(Timer, info.This());
assert(timer);
assert (property == REPEAT_SYMBOL);
Local<Integer> v = Integer::New(timer->watcher_.repeat);
return scope.Close(v);
}
void
Timer::RepeatSetter (Local<String> property, Local<Value> value, const AccessorInfo& info)
{
HandleScope scope;
Timer *timer = NODE_UNWRAP(Timer, info.This());
assert(timer);
assert (property == REPEAT_SYMBOL);
timer->watcher_.repeat = (double)(property->IntegerValue()) / 1000;
}
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_->GetHiddenValue(CALLBACK_SYMBOL);
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())
FatalException(try_catch);
timer->Emit("Timeout", 0, NULL);
/* XXX i'm a bit worried if this is the correct test?
* it's rather crutial for memory leaks the conditional here test to see
@ -50,18 +69,6 @@ Timer::OnTimeout (EV_P_ ev_timer *watcher, int revents)
timer->Detach();
}
Timer::Timer (Handle<Object> handle, Handle<Function> callback, ev_tstamp after, ev_tstamp repeat)
: ObjectWrap(handle)
{
HandleScope scope;
handle_->SetHiddenValue(CALLBACK_SYMBOL, callback);
ev_timer_init(&watcher_, Timer::OnTimeout, after, repeat);
watcher_.data = this;
}
Timer::~Timer ()
{
ev_timer_stop (EV_DEFAULT_UC_ &watcher_);
@ -70,17 +77,9 @@ Timer::~Timer ()
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 *t = new Timer(args.Holder(), callback, after, repeat);
Timer *t = new Timer(args.Holder());
ObjectWrap::InformV8ofAllocation(t);
return args.This();
@ -90,8 +89,20 @@ Handle<Value>
Timer::Start (const Arguments& args)
{
Timer *timer = NODE_UNWRAP(Timer, args.Holder());
HandleScope scope;
if (args.Length() != 2)
return ThrowException(String::New("Bad arguments"));
ev_tstamp after = (double)(args[0]->IntegerValue()) / 1000.0;
ev_tstamp repeat = (double)(args[1]->IntegerValue()) / 1000.0;
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();
}

View File

@ -2,12 +2,13 @@
#define node_timer_h
#include "node.h"
#include "events.h"
#include <v8.h>
#include <ev.h>
namespace node {
class Timer : ObjectWrap {
class Timer : EventEmitter {
public:
static void Initialize (v8::Handle<v8::Object> target);
@ -16,15 +17,14 @@ class Timer : ObjectWrap {
protected:
static v8::Persistent<v8::FunctionTemplate> constructor_template;
Timer(v8::Handle<v8::Object> handle,
v8::Handle<v8::Function> callback,
ev_tstamp after,
ev_tstamp repeat);
Timer (v8::Handle<v8::Object> handle) : EventEmitter (handle) { }
~Timer();
static v8::Handle<v8::Value> New (const v8::Arguments& args);
static v8::Handle<v8::Value> Start (const v8::Arguments& args);
static v8::Handle<v8::Value> Stop (const v8::Arguments& args);
static v8::Handle<v8::Value> RepeatGetter (v8::Local<v8::String> property, const v8::AccessorInfo& info);
static void RepeatSetter (v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
private:
static void OnTimeout (EV_P_ ev_timer *watcher, int revents);