Skip to content

Commit

Permalink
Revert "Switch to new object style API for timer"
Browse files Browse the repository at this point in the history
This reverts commit c7bafe1.
  • Loading branch information
creationix committed Mar 15, 2012
1 parent c7bafe1 commit 33fa411
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 108 deletions.
180 changes: 84 additions & 96 deletions src/luv_timer.cc
Expand Up @@ -11,129 +11,117 @@
using namespace candor;
using namespace candorIO;

typedef candor::internal::List<char*, candor::internal::EmptyClass> List;

static Object* HandlePrototype;
static Object* TimerPrototype;
static Function* CloneScript;

static Object* ObjectClone(Object* source) {
Value* argv[1];
argv[0] = source;
Value* result = CloneScript->Call(1, argv);
if (!result->Is<Object>()) {
printf("result is not an object!\n");
}
return result->As<Object>();
}

// Wrapper C functions when functions pointers are needed
static void luv_on_timer(uv_timer_t* handle, int status) {
(reinterpret_cast<uvTimer*>(handle->data))->OnTimer(status);
}
static Value* luv_create_timer(uint32_t argc, Arguments& argv) {
Object* obj = ObjectClone(TimerPrototype);
printf("obj %p\n", obj);
CData* cdata = CData::New(sizeof(uv_timer_t));
obj->Set("cdata", cdata);
printf("cdata %p\n", cdata);
uv_timer_t* timer = (uv_timer_t*)cdata->GetContents();
uv_timer_init(uv_default_loop(), timer);
printf("timer %p\n", timer);
timer->data = obj;
return obj;
assert(argc == 0);
return (new uvTimer())->Wrap();
}
static Value* luv_timer_start(uint32_t argc, Arguments& argv) {
assert(argc && argv[0]->Is<CData>());
return CWrapper::Unwrap<uvTimer>(argv[0])->Start(argc, argv);
}
static Value* luv_timer_stop(uint32_t argc, Arguments& argv) {
assert(argc && argv[0]->Is<CData>());
return CWrapper::Unwrap<uvTimer>(argv[0])->Stop(argc, argv);
}
static Value* luv_timer_again(uint32_t argc, Arguments& argv) {
assert(argc && argv[0]->Is<CData>());
return CWrapper::Unwrap<uvTimer>(argv[0])->Again(argc, argv);
}
static Value* luv_timer_get_repeat(uint32_t argc, Arguments& argv) {
assert(argc && argv[0]->Is<CData>());
return CWrapper::Unwrap<uvTimer>(argv[0])->GetRepeat(argc, argv);
}
static Value* luv_timer_set_repeat(uint32_t argc, Arguments& argv) {
assert(argc && argv[0]->Is<CData>());
return CWrapper::Unwrap<uvTimer>(argv[0])->SetRepeat(argc, argv);
}
static void luv_on_close(uv_handle_t* handle) {
(reinterpret_cast<uvTimer*>(handle->data))->OnClose();
}
static Value* luv_close(uint32_t argc, Arguments& argv) {
assert(argc && argv[0]->Is<CData>());
return CWrapper::Unwrap<uvTimer>(argv[0])->Close(argc, argv);
}

static void luv_on_timer(uv_timer_t* handle, int status) {
((Object*)handle->data)->Get("onTimer")->As<Function>()->Call(0, NULL);

// Create the Timer object that wraps the C functions
void luv_timer_init(Object* uv) {
Object* timer = Object::New();
uv->Set("Timer", timer);
timer->Set("create", Function::New(luv_create_timer));
timer->Set("start", Function::New(luv_timer_start));
timer->Set("stop", Function::New(luv_timer_stop));
timer->Set("again", Function::New(luv_timer_again));
timer->Set("getRepeat", Function::New(luv_timer_get_repeat));
timer->Set("setRepeat", Function::New(luv_timer_set_repeat));
timer->Set("close", Function::New(luv_close));
}

static Value* luv_timer_start(uint32_t argc, Arguments& argv) {
printf("*argc %d\n", argc);
assert(argc == 4 && argv[0]->Is<Object>() && argv[1]->Is<Number>() && argv[2]->Is<Number>() && argv[3]->Is<Function>());
Object* obj = argv[0]->As<Object>();
printf("*obj %p\n", obj);
CData* cdata = obj->Get("cdata")->As<CData>();
printf("*cdata %p\n", cdata);
uv_timer_t* timer = (uv_timer_t*)cdata->GetContents();
// Implement class methods.

uvTimer::uvTimer() {
uv_timer_init(uv_default_loop(), &handle);
handle.data = this;
}

void uvTimer::OnTimer(int status) {
onTimer->Call(0, NULL);
}

Value* uvTimer::Start(uint32_t argc, Arguments& argv) {
assert(this == handle.data);
assert(argc == 4 && argv[1]->Is<Number>() && argv[2]->Is<Number>() && argv[3]->Is<Function>());
int64_t timeout = argv[1]->As<Number>()->IntegralValue();
int64_t repeat = argv[2]->As<Number>()->IntegralValue();
obj->Set("onTimer", argv[3]);
uv_timer_start(timer, luv_on_timer, timeout, repeat);
onTimer.Wrap(argv[3]->As<Function>());
uv_timer_start(&handle, luv_on_timer, timeout, repeat);
Ref();
return Nil::New();
}

static Value* luv_timer_get_repeat(uint32_t argc, Arguments& argv) {
assert(argc == 1 && argv[0]->Is<Object>());
Object* obj = argv[0]->As<Object>();
uv_timer_t* timer = (uv_timer_t*)obj->Get("cdata")->As<CData>()->GetContents();
int64_t repeat = uv_timer_get_repeat(timer);
Value* uvTimer::GetRepeat(uint32_t argc, Arguments& argv) {
assert(argc == 1);
int64_t repeat = uv_timer_get_repeat(&handle);
return Number::NewIntegral(repeat);
}

static Value* luv_timer_set_repeat(uint32_t argc, Arguments& argv) {
assert(argc == 2 && argv[0]->Is<CData>() && argv[1]->Is<Number>());
Object* obj = argv[0]->As<Object>();
uv_timer_t* timer = (uv_timer_t*)obj->Get("cdata")->As<CData>()->GetContents();
Value* uvTimer::SetRepeat(uint32_t argc, Arguments& argv) {
assert(argc == 2 && argv[1]->Is<Number>());
int64_t repeat = argv[1]->As<Number>()->IntegralValue();
uv_timer_set_repeat(timer, repeat);
uv_timer_set_repeat(&handle, repeat);
return Nil::New();
}

static Value* luv_timer_stop(uint32_t argc, Arguments& argv) {
assert(argc == 1 && argv[0]->Is<Object>());
Object* obj = argv[0]->As<Object>();
uv_timer_t* timer = (uv_timer_t*)obj->Get("cdata")->As<CData>()->GetContents();
uv_timer_stop(timer);
Value* uvTimer::Stop(uint32_t argc, Arguments& argv) {
assert(argc == 1);
uv_timer_stop(&handle);
onTimer.Unwrap();
Unref();
return Nil::New();
}

static Value* luv_timer_again(uint32_t argc, Arguments& argv) {
assert(argc == 1 && argv[0]->Is<Object>());
Object* obj = argv[0]->As<Object>();
uv_timer_t* timer = (uv_timer_t*)obj->Get("cdata")->As<CData>()->GetContents();
uv_timer_again(timer);
Value* uvTimer::Again(uint32_t argc, Arguments& argv) {
assert(argc == 1);
uv_timer_again(&handle);
return Nil::New();
}

static void luv_on_close(uv_handle_t* handle) {
((Object*)handle->data)->Get("onClose")->As<Function>()->Call(0, NULL);
void uvTimer::OnClose() {
onClose->Call(0, NULL);
onClose.Unwrap();
Unref();
}

static Value* luv_close(uint32_t argc, Arguments& argv) {
assert(argc && argv[0]->Is<Object>());
Object* obj = argv[0]->As<Object>();
uv_handle_t* handle = (uv_handle_t*)obj->Get("cdata")->As<CData>()->GetContents();
Value* uvTimer::Close(uint32_t argc, Arguments& argv) {
if (argc > 1 && argv[1]->Is<Function>()) {
obj->Set("onClose", argv[1]);
onClose.Wrap(argv[1]->As<Function>());
}
uv_close(handle, luv_on_close);
uv_close((uv_handle_t*)&handle, luv_on_close);
Ref();
return Nil::New();
}


// Create the Timer object that wraps the C functions
void luv_timer_init(Object* uv) {

// Compile the cloneScript
const char* cloneScript = "return (source) {\ntarget = {}\nkeys = keysof source\nlength = sizeof keys\ni = 0\nwhile (i < length) {\nkey = keys[i]\nvalue = source[key]\ntarget[key] = value\ni++\n}\nreturn target\n}";
CloneScript = Function::New(cloneScript, strlen(cloneScript));
new Handle<Function>(CloneScript);
CloneScript = CloneScript->Call(0, NULL)->As<Function>();
new Handle<Function>(CloneScript);
if (!CloneScript->Is<Function>()) {
printf("CloneScript is not a function!\n");
}

// Create the Handle prototype
HandlePrototype = Object::New();
new Handle<Object>(HandlePrototype);
HandlePrototype->Set("close", Function::New(luv_close));

// Create the Timer prototype
TimerPrototype = ObjectClone(HandlePrototype);
new Handle<Object>(TimerPrototype);
TimerPrototype->Set("start", Function::New(luv_timer_start));
TimerPrototype->Set("stop", Function::New(luv_timer_stop));
TimerPrototype->Set("again", Function::New(luv_timer_again));
TimerPrototype->Set("getRepeat", Function::New(luv_timer_get_repeat));
TimerPrototype->Set("setRepeat", Function::New(luv_timer_set_repeat));

uv->Set("createTimer", Function::New(luv_create_timer));
}
19 changes: 19 additions & 0 deletions src/luv_timer.h
Expand Up @@ -5,6 +5,25 @@
#include "candor.h"
using namespace candor;

namespace candorIO {

class uvTimer : public CWrapper {
uv_timer_t handle;
Handle<Function> onTimer;
Handle<Function> onClose;
public:
uvTimer();
void OnTimer(int status);
Value* Start(uint32_t argc, Arguments& argv);
Value* GetRepeat(uint32_t argc, Arguments& argv);
Value* SetRepeat(uint32_t argc, Arguments& argv);
Value* Stop(uint32_t argc, Arguments& argv);
Value* Again(uint32_t argc, Arguments& argv);
void OnClose();
Value* Close(uint32_t argc, Arguments& argv);
};
}

void luv_timer_init(Object* uv);

#endif
25 changes: 13 additions & 12 deletions test.can
@@ -1,5 +1,6 @@
print = global.print
uv = global.uv
Timer = global.uv.Timer
Handle = global.uv.Handle

// Simple pretty printer
dump(value) {
Expand Down Expand Up @@ -51,41 +52,41 @@ p(label, value) {
print(label, dump(value))
}

p("uv", uv)
p("Timer", Timer)

timer = uv.createTimer()
timer = Timer.create()
__$gc()
timer2 = uv.createTimer()
timer2 = Timer.create()
__$gc()

timer.start(timer, 2400, 0, () {
Timer.start(timer, 2400, 0, () {
__$gc()
print("onTimeout")
__$gc()
Timer.stop(timer2)
__$gc()
timer2.stop(timer2)
timer.stop(timer)
Timer.stop(timer)
__$gc()
timer.close(timer, () {
Timer.close(timer, () {
__$gc()
print("close1")
})
__$gc()
timer2.close(timer2, () {
Timer.close(timer2, () {
__$gc()
print("close2")
})
__$gc()
})
__$gc()

timer2.start(timer2, 333, 333, () {
Timer.start(timer2, 333, 333, () {
__$gc()
print("onInterval")
period = timer2.getRepeat(timer2)
period = Timer.getRepeat(timer2)
__$gc()
p("period", period)
timer2.setRepeat(timer2, period / 1.2 + 1)
Timer.setRepeat(timer2, period / 1.2 + 1)
__$gc()
})
__$gc()
Expand Down

0 comments on commit 33fa411

Please sign in to comment.