mirror of https://github.com/lukechilds/node.git
Ryan
16 years ago
5 changed files with 381 additions and 212 deletions
@ -0,0 +1,190 @@ |
|||
#include <ev.h> |
|||
#include <v8.h> |
|||
using namespace v8; |
|||
static struct ev_loop *loop; |
|||
|
|||
class Timer { |
|||
public: |
|||
Timer(Handle<Function> callback, int argc, Handle<Value> argv[], ev_tstamp after, ev_tstamp repeat); |
|||
~Timer(); |
|||
Local<External> CreateTimeoutID (); |
|||
void CallCallback (); |
|||
private: |
|||
ev_timer watcher; |
|||
Persistent<External> timeoutID; |
|||
Persistent<Function> callback; |
|||
int argc; |
|||
Persistent<Value> argv[]; |
|||
}; |
|||
|
|||
static void |
|||
onTimeout (struct ev_loop *loop, ev_timer *watcher, int revents) |
|||
{ |
|||
Timer *timer = static_cast<Timer*>(watcher->data); |
|||
|
|||
timer->CallCallback(); |
|||
|
|||
// use ev_is_active instead?
|
|||
if(watcher->repeat == 0.) |
|||
delete timer; |
|||
} |
|||
|
|||
Timer::Timer (Handle<Function> _callback, int _argc, Handle<Value> _argv[], ev_tstamp after, ev_tstamp repeat) |
|||
{ |
|||
HandleScope scope; |
|||
callback = Persistent<Function>::New(_callback); |
|||
argc = _argc; |
|||
|
|||
ev_timer_init (&watcher, onTimeout, after, repeat); |
|||
watcher.data = this; |
|||
ev_timer_start (loop, &watcher); |
|||
} |
|||
|
|||
Timer::~Timer () |
|||
{ |
|||
ev_timer_stop (loop, &watcher); |
|||
|
|||
callback.Dispose(); |
|||
|
|||
timeoutID.Dispose(); |
|||
timeoutID.Clear(); |
|||
} |
|||
|
|||
void |
|||
Timer::CallCallback () |
|||
{ |
|||
HandleScope scope; |
|||
|
|||
TryCatch try_catch; |
|||
|
|||
Handle<Value> r = callback->Call (Context::GetCurrent()->Global(), argc, argv); |
|||
if (r.IsEmpty()) { |
|||
String::Utf8Value error(try_catch.Exception()); |
|||
printf("timer callback error: %s\n", *error); |
|||
} |
|||
} |
|||
|
|||
Local<External> |
|||
Timer::CreateTimeoutID () |
|||
{ |
|||
HandleScope scope; |
|||
|
|||
Local<External> timeoutID_local = External::New(this); |
|||
|
|||
timeoutID = Persistent<External>::New(timeoutID_local); |
|||
|
|||
return scope.Close(timeoutID_local); |
|||
} |
|||
|
|||
static Timer * |
|||
UnwrapTimeoutID (Handle<External> timeoutID) |
|||
{ |
|||
HandleScope scope; |
|||
|
|||
Timer *timer = static_cast<Timer*>(timeoutID->Value()); |
|||
|
|||
return timer; |
|||
} |
|||
|
|||
// timeoutID = setTimeout(func, delay, [param1, param2, ...]);
|
|||
// timeoutID = setTimeout(code, delay);
|
|||
//
|
|||
// * timeoutID is the ID of the timeout, which can be used with
|
|||
// clearTimeout.
|
|||
//
|
|||
// * func is the function you want to execute after delay milliseconds.
|
|||
//
|
|||
// * code in the alternate syntax, is a string of code you want to execute
|
|||
// after delay milliseconds. (not recommended)
|
|||
//
|
|||
// * delay is the number of milliseconds (thousandths of a second) that the
|
|||
// function call should be delayed by.
|
|||
static Handle<Value> |
|||
setTimeout(const Arguments& args) |
|||
{ |
|||
if (args.Length() < 2) |
|||
return Undefined(); |
|||
|
|||
HandleScope scope; |
|||
|
|||
Local<Function> callback = Local<Function>::Cast(args[0]); |
|||
uint32_t delay = args[1]->Uint32Value(); |
|||
|
|||
ev_tstamp after = (double)delay / 1000.0; |
|||
|
|||
int argc = 0; |
|||
Handle<Value> argv[] = {}; |
|||
/*
|
|||
int argc = args.Length() - 2; |
|||
Handle<Value> argv[] = new Handle<Value>[argc]; |
|||
// the rest of the arguments, if any arg parameters for the callback
|
|||
for(int i = 2; i < args.Length(); i++) |
|||
argv[i - 2] = args[i]; |
|||
*/ |
|||
|
|||
Timer *timer = new Timer(callback, argc, argv, after, 0.0); |
|||
|
|||
Local<External> timeoutID = timer->CreateTimeoutID(); |
|||
|
|||
return scope.Close(timeoutID); |
|||
} |
|||
|
|||
// clearTimeout(timeoutID)
|
|||
static Handle<Value> clearTimeout |
|||
( const Arguments& args |
|||
) |
|||
{ |
|||
if (args.Length() < 1) |
|||
return Undefined(); |
|||
|
|||
Handle<External> timeoutID = Handle<External>::Cast(args[0]); |
|||
Timer *timer = UnwrapTimeoutID(timeoutID); |
|||
|
|||
delete timer; |
|||
|
|||
return Undefined(); |
|||
} |
|||
|
|||
// intervalID = setInterval(func, delay[, param1, param2, ...]);
|
|||
// intervalID = setInterval(code, delay);
|
|||
//
|
|||
// where
|
|||
//
|
|||
// * intervalID is a unique interval ID you can pass to clearInterval().
|
|||
//
|
|||
// * func is the function you want to be called repeatedly.
|
|||
//
|
|||
// * code in the alternate syntax, is a string of code you want to be executed
|
|||
// repeatedly.
|
|||
//
|
|||
// * delay is the number of milliseconds (thousandths of a second) that the
|
|||
// setInterval() function should wait before each call to func.
|
|||
static Handle<Value> setInterval |
|||
( const Arguments& args |
|||
) |
|||
{ |
|||
} |
|||
|
|||
void |
|||
node_timer_initialize (Handle<Object> target, struct ev_loop *_loop) |
|||
{ |
|||
loop = _loop; |
|||
|
|||
HandleScope scope; |
|||
|
|||
target->Set ( String::New("setTimeout") |
|||
, FunctionTemplate::New(setTimeout)->GetFunction() |
|||
); |
|||
|
|||
target->Set ( String::New("clearTimeout") |
|||
, FunctionTemplate::New(clearTimeout)->GetFunction() |
|||
); |
|||
|
|||
target->Set ( String::New("setInterval") |
|||
, FunctionTemplate::New(setInterval)->GetFunction() |
|||
); |
|||
|
|||
target->Set ( String::New("clearInterval") |
|||
, FunctionTemplate::New(clearTimeout)->GetFunction() |
|||
); |
|||
} |
@ -0,0 +1,10 @@ |
|||
#ifndef node_timer_h |
|||
#define node_timer_h |
|||
|
|||
#include <ev.h> |
|||
#include <v8.h> |
|||
using namespace v8; |
|||
|
|||
void node_timer_initialize (Handle<Object> target, struct ev_loop *_loop); |
|||
|
|||
#endif // node_timer_h
|
Loading…
Reference in new issue