// Copyright 2009 Ryan Dahl
#include
#include
namespace node {
using namespace v8;
Persistent EventEmitter::constructor_template;
static Persistent events_symbol;
void EventEmitter::Initialize(Local ctemplate) {
HandleScope scope;
constructor_template = Persistent::New(ctemplate);
constructor_template->SetClassName(String::NewSymbol("EventEmitter"));
events_symbol = NODE_PSYMBOL("_events");
// All other prototype methods are defined in events.js
}
bool EventEmitter::Emit(Handle event, int argc, Handle argv[]) {
HandleScope scope;
// HandleScope not needed here because only called from one of the two
// functions below
Local events_v = handle_->Get(events_symbol);
if (!events_v->IsObject()) return false;
Local events = events_v->ToObject();
Local listeners_v = events->Get(event);
TryCatch try_catch;
if (listeners_v->IsFunction()) {
// Optimized one-listener case
Local listener = Local::Cast(listeners_v);
listener->Call(handle_, argc, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
return false;
}
} else if (listeners_v->IsArray()) {
Local listeners = Local::Cast(listeners_v->ToObject()->Clone());
for (uint32_t i = 0; i < listeners->Length(); i++) {
Local listener_v = listeners->Get(i);
if (!listener_v->IsFunction()) continue;
Local listener = Local::Cast(listener_v);
listener->Call(handle_, argc, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
return false;
}
}
} else {
return false;
}
return true;
}
} // namespace node