#include <arpa/inet.h> /* inet_ntop */
#include <netinet/in.h> /* sockaddr_in, sockaddr_in6 */
+#ifndef RAMP
+# define RAMP(x) ((x) > 0 ? (x) : 0)
+#endif
+
using namespace v8;
using namespace node;
HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New();
+
constructor_template = Persistent<FunctionTemplate>::New(t);
- // All prototype methods are defined in events.js
+ Local<FunctionTemplate> __emit = FunctionTemplate::New(Emit);
+ constructor_template->PrototypeTemplate()->Set(String::NewSymbol("emit"), __emit);
+
+ // All other prototype methods are defined in events.js
target->Set(String::NewSymbol("EventEmitter"),
constructor_template->GetFunction());
}
-bool
-EventEmitter::Emit (const char *type, int argc, Handle<Value> argv[])
+static bool
+ReallyEmit (Handle<Object> self, Handle<String> event, int argc, Handle<Value> argv[])
{
HandleScope scope;
- Local<Value> emit_v = handle_->Get(String::NewSymbol("emit"));
- assert(emit_v->IsFunction());
- Local<Function> emit = Local<Function>::Cast(emit_v);
-
- Local<Value> events_v = handle_->Get(String::NewSymbol("_events"));
+ Local<Value> events_v = self->Get(String::NewSymbol("_events"));
if (!events_v->IsObject()) return false;
Local<Object> events = events_v->ToObject();
- Local<Value> listeners_v = events->Get(String::NewSymbol(type));
+ Local<Value> listeners_v = events->Get(event);
if (!listeners_v->IsArray()) return false;
Local<Array> listeners = Local<Array>::Cast(listeners_v);
- TryCatch try_catch;
+ for (unsigned int i = 0; i < listeners->Length(); i++) {
+ HandleScope scope;
- for (int i = 0; i < listeners->Length(); i++) {
Local<Value> listener_v = listeners->Get(Integer::New(i));
if (!listener_v->IsFunction()) continue;
Local<Function> listener = Local<Function>::Cast(listener_v);
- listener->Call(handle_, argc, argv);
+ TryCatch try_catch;
+
+ listener->Call(self, argc, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
return true;
}
+Handle<Value>
+EventEmitter::Emit (const Arguments& args)
+{
+ HandleScope scope;
+ Local<String> event = args[0]->ToString();
+ int argc = 0;
+ Local<Array> emit_args;
+ if (args[1]->IsArray()) {
+ emit_args = Local<Array>::Cast(args[1]);
+ argc = emit_args->Length();
+ }
+ Local<Value> argv[argc];
+
+ for (int i = 0; i < argc; i++) {
+ argv[i] = emit_args->Get(Integer::New(i));
+ }
+
+ bool r = ReallyEmit(args.Holder(), event, argc, argv);
+
+ return scope.Close(r ? True() : False());
+}
+
+bool
+EventEmitter::Emit (const char *event_s, int argc, Handle<Value> argv[])
+{
+ HandleScope scope;
+ Local<String> event = String::NewSymbol(event_s);
+ return ReallyEmit(handle_, event, argc, argv);
+}
+
Persistent<FunctionTemplate> Promise::constructor_template;
void
(function () {
// node.EventEmitter is defined in src/events.cc
-var emitter = node.EventEmitter.prototype;
-
-emitter.addListener = function (type, listener) {
+// node.EventEmitter.prototype.emit() is also defined there.
+node.EventEmitter.prototype.addListener = function (type, listener) {
if (listener instanceof Function) {
if (!this._events) this._events = {};
if (!this._events.hasOwnProperty(type)) this._events[type] = [];
}
};
-emitter.listeners = function (type) {
+node.EventEmitter.prototype.listeners = function (type) {
if (!this._events) this._events = {};
if (!this._events.hasOwnProperty(type)) this._events[type] = [];
return this._events[type];
};
-// This function is called often from C++.
-// FIXME there is a counterpart for this function in C++
-// both must have the same behavior.
-// See events.cc
-emitter.emit = function (type, args) {
- if (!this._events) return;
- if (!this._events.hasOwnProperty(type)) return;
-
- var listeners = this._events[type];
-
- for (var i = 0; i < listeners.length; i++) {
- listeners[i].apply(this, args);
- }
-};
-
// node.Promise is defined in src/events.cc
var promise = node.Promise.prototype;