Browse Source

in the middle putting in event code. broken.

v0.7.4-release
Ryan 16 years ago
parent
commit
2ecd7ffe54
  1. 56
      src/events.cc
  2. 21
      src/events.h
  3. 33
      src/events.js
  4. 77
      src/net.cc
  5. 5
      src/net.h
  6. 3
      src/node.cc
  7. 6
      src/node.js
  8. 8
      wscript

56
src/events.cc

@ -0,0 +1,56 @@
#include "events.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h> /* inet_ntop */
#include <netinet/in.h> /* sockaddr_in, sockaddr_in6 */
using namespace v8;
using namespace node;
Persistent<FunctionTemplate> EventEmitter::constructor_template;
void
EventEmitter::Initialize (v8::Handle<v8::Object> target)
{
HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New();
constructor_template = Persistent<FunctionTemplate>::New(t);
// All 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[])
{
Local<Value> emit_v = handle_->Get(String::NewSymbol("emit"));
assert(emit_v->IsFunction());
Local<Function> emit = Local<Function>::Cast(emit_v);
Local<Array> event_args = Array::New(argc);
for (int i = 0; i < argc; i++) {
event_args->Set(Integer::New(i), argv[i]);
}
Handle<Value> emit_argv[2] = { String::NewSymbol(type), event_args };
TryCatch try_catch;
emit->Call(handle_, 2, emit_argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
return false;
}
return true;
}

21
src/events.h

@ -0,0 +1,21 @@
#ifndef node_events_h
#define node_events_h
#include "node.h"
#include <v8.h>
namespace node {
class EventEmitter : public ObjectWrap {
public:
static void Initialize (v8::Handle<v8::Object> target);
static v8::Persistent<v8::FunctionTemplate> constructor_template;
bool Emit (const char *type, int argc, v8::Handle<v8::Value> argv[]);
EventEmitter (v8::Handle<v8::Object> handle)
: ObjectWrap(handle) { };
};
} // namespace node
#endif

33
src/events.js

@ -0,0 +1,33 @@
(function () {
// node.EventEmitter is defined in src/events.cc
var emitter = node.EventEmitter.prototype;
emitter.addListener = function (type, listener) {
if (!this._events) this._events = {};
if (!this._events.hasOwnProperty(type)) this._events[type] = [];
this._events[type].push(listener);
};
emitter.listeners = function (type, listener) {
if (!this._events) this._events = {};
if (!this._events.hasOwnProperty(type)) this._events[type] = [];
return this._events[type];
};
/* This function is called often from C++.
* See events.cc
*/
emitter.emit = function (type, args) {
if (this["on" + type] instanceof Function) {
this["on" + type].apply(this, args);
}
if (!this._events) return;
if (!this._events.hasOwnProperty(type)) return;
for (var i = 0; i < this._events[type].length; i++) {
var listener = this._events[type][i];
listener.apply(this, args);
}
};
})(); // end annonymous namespace

77
src/net.cc

@ -1,4 +1,5 @@
#include "net.h"
#include "events.h"
#include <assert.h>
#include <stdlib.h>
@ -18,21 +19,12 @@ using namespace node;
#define RAW_SYMBOL String::NewSymbol("raw")
#define ASCII_SYMBOL String::NewSymbol("ascii")
#define ON_RECEIVE_SYMBOL String::NewSymbol("onReceive")
#define ON_DISCONNECT_SYMBOL String::NewSymbol("onDisconnect")
#define ON_CONNECT_SYMBOL String::NewSymbol("onConnect")
#define ON_DRAIN_SYMBOL String::NewSymbol("onDrain")
#define ON_TIMEOUT_SYMBOL String::NewSymbol("onTimeout")
#define ON_ERROR_SYMBOL String::NewSymbol("onError")
#define ON_EOF_SYMBOL String::NewSymbol("onEOF")
#define ENCODING_SYMBOL String::NewSymbol("encoding")
#define TIMEOUT_SYMBOL String::NewSymbol("timeout")
#define SERVER_SYMBOL String::NewSymbol("server")
#define REMOTE_ADDRESS_SYMBOL String::NewSymbol("remoteAddress")
#define PROTOCOL_SYMBOL String::NewSymbol("protocol")
#define CONNECTION_HANDLER_SYMBOL String::NewSymbol("connectionHandler")
#define READY_STATE_SYMBOL String::NewSymbol("readyState")
#define OPEN_SYMBOL String::NewSymbol("open")
@ -65,6 +57,7 @@ Connection::Initialize (v8::Handle<v8::Object> target)
Local<FunctionTemplate> t = FunctionTemplate::New(New);
constructor_template = Persistent<FunctionTemplate>::New(t);
constructor_template->Inherit(EventEmitter::constructor_template);
constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "connect", Connect);
@ -102,7 +95,7 @@ Connection::ReadyStateGetter (Local<String> _, const AccessorInfo& info)
}
Connection::Connection (Handle<Object> handle)
: ObjectWrap(handle)
: EventEmitter(handle)
{
encoding_ = RAW;
@ -439,11 +432,6 @@ Connection::OnReceive (const void *buf, size_t len)
{
HandleScope scope;
Handle<Value> callback_v = handle_->Get(ON_RECEIVE_SYMBOL);
if (!callback_v->IsFunction()) return;
Handle<Function> callback = Handle<Function>::Cast(callback_v);
const int argc = 1;
Handle<Value> argv[argc];
@ -466,47 +454,31 @@ Connection::OnReceive (const void *buf, size_t len)
argv[0] = Local<Value>::New(Null());
}
TryCatch try_catch;
callback->Call(handle_, argc, argv);
if (try_catch.HasCaught())
FatalException(try_catch);
Emit("Receive", argc, argv);
}
void
Connection::OnDisconnect ()
{
HandleScope scope;
Local<Value> callback_v = handle_->Get(ON_DISCONNECT_SYMBOL);
if (!callback_v->IsFunction()) return;
Handle<Function> callback = Handle<Function>::Cast(callback_v);
Handle<Value> argv[1];
argv[0] = socket_.errorno == 0 ? False() : True();
TryCatch try_catch;
callback->Call(handle_, 1, argv);
if (try_catch.HasCaught())
node::FatalException(try_catch);
Emit("Disconnect", 1, argv);
}
#define DEFINE_SIMPLE_CALLBACK(name, symbol) \
#define DEFINE_SIMPLE_CALLBACK(name, type) \
void name () \
{ \
HandleScope scope; \
Local<Value> callback_v = handle_->Get(symbol); \
if (!callback_v->IsFunction()) return; \
Handle<Function> callback = Handle<Function>::Cast(callback_v); \
TryCatch try_catch; \
callback->Call(handle_, 0, NULL); \
if (try_catch.HasCaught()) \
node::FatalException(try_catch); \
Emit (type, 0, NULL); \
}
DEFINE_SIMPLE_CALLBACK(Connection::OnConnect, ON_CONNECT_SYMBOL)
DEFINE_SIMPLE_CALLBACK(Connection::OnDrain, ON_DRAIN_SYMBOL)
DEFINE_SIMPLE_CALLBACK(Connection::OnTimeout, ON_TIMEOUT_SYMBOL)
DEFINE_SIMPLE_CALLBACK(Connection::OnEOF, ON_EOF_SYMBOL)
DEFINE_SIMPLE_CALLBACK(Connection::OnConnect, "Connect")
DEFINE_SIMPLE_CALLBACK(Connection::OnDrain, "Drain")
DEFINE_SIMPLE_CALLBACK(Connection::OnTimeout, "Timeout")
DEFINE_SIMPLE_CALLBACK(Connection::OnEOF, "EOF")
Persistent<FunctionTemplate> Acceptor::constructor_template;
@ -517,7 +489,7 @@ Acceptor::Initialize (Handle<Object> target)
Local<FunctionTemplate> t = FunctionTemplate::New(New);
constructor_template = Persistent<FunctionTemplate>::New(t);
constructor_template->Inherit(EventEmitter::constructor_template);
constructor_template->InstanceTemplate()->SetInternalFieldCount(1);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "listen", Listen);
@ -527,10 +499,11 @@ Acceptor::Initialize (Handle<Object> target)
}
Acceptor::Acceptor (Handle<Object> handle, Handle<Function> connection_handler, Handle<Object> options)
: ObjectWrap(handle)
: EventEmitter(handle)
{
HandleScope scope;
#if 0
handle_->SetHiddenValue(CONNECTION_HANDLER_SYMBOL, connection_handler);
int backlog = 1024; // default value
@ -538,13 +511,9 @@ Acceptor::Acceptor (Handle<Object> handle, Handle<Function> connection_handler,
if (backlog_v->IsInt32()) {
backlog = backlog_v->IntegerValue();
}
#endif
Local<Value> on_error_v = options->Get(ON_ERROR_SYMBOL);
if (on_error_v->IsFunction()) {
handle_->Set(ON_ERROR_SYMBOL, on_error_v);
}
oi_server_init(&server_, backlog);
oi_server_init(&server_, 1024);
server_.on_connection = Acceptor::on_connection;
server_.data = this;
}
@ -588,16 +557,6 @@ Connection*
Acceptor::OnConnection (struct sockaddr *addr, socklen_t len)
{
HandleScope scope;
Local<Value> connection_handler_v =
handle_->GetHiddenValue(CONNECTION_HANDLER_SYMBOL);
if (!connection_handler_v->IsFunction()) {
printf("Connection handler was empty!");
Close();
return NULL;
}
Local<Function> connection_handler =
Local<Function>::Cast(connection_handler_v);
TryCatch try_catch;
@ -617,10 +576,8 @@ Acceptor::OnConnection (struct sockaddr *addr, socklen_t len)
connection->SetAcceptor(handle_);
Handle<Value> argv[1] = { js_connection };
Local<Value> ret = connection_handler->Call(handle_, 1, argv);
if (ret.IsEmpty())
FatalException(try_catch);
Emit("Connection", 1, argv);
return connection;
}

5
src/net.h

@ -2,6 +2,7 @@
#define node_net_h
#include "node.h"
#include "events.h"
#include <v8.h>
#include <oi_socket.h>
@ -9,7 +10,7 @@ namespace node {
class Acceptor;
class Connection : public ObjectWrap {
class Connection : public EventEmitter {
public:
static void Initialize (v8::Handle<v8::Object> target);
@ -107,7 +108,7 @@ private:
friend class Acceptor;
};
class Acceptor : public ObjectWrap {
class Acceptor : public EventEmitter {
public:
static void Initialize (v8::Handle<v8::Object> target);

3
src/node.cc

@ -1,5 +1,6 @@
#include "node.h"
#include "events.h"
#include "net.h"
#include "file.h"
#include "http.h"
@ -312,6 +313,7 @@ Load (int argc, char *argv[])
NODE_SET_METHOD(node_obj, "debug", debug);
NODE_SET_METHOD(node_obj, "reallyExit", node_exit);
EventEmitter::Initialize(node_obj);
Timer::Initialize(node_obj);
Process::Initialize(node_obj);
@ -331,6 +333,7 @@ Load (int argc, char *argv[])
HTTPServer::Initialize(http);
HTTPConnection::Initialize(http);
ExecuteNativeJS("events.js", native_events);
ExecuteNativeJS("http.js", native_http);
ExecuteNativeJS("file.js", native_file);
ExecuteNativeJS("node.js", native_node);

6
src/node.js

@ -1,3 +1,9 @@
node.tcp.Server = function (on_connection, options) {
this.__proto__ = node.tcp.LowLevelServer ();
node.debug("hello world");
if (on_connection) this.addListener("Connection", on_connection);
};
// Timers
function setTimeout (callback, delay) {

8
wscript

@ -141,7 +141,12 @@ def build(bld):
js2c.JS2C(source, targets)
native_cc = bld.new_task_gen(
source="src/http.js src/file.js src/node.js",
source = """
src/events.js
src/http.js
src/file.js
src/node.js
""",
target="src/natives.h",
rule=javascript_in_c,
before="cxx"
@ -155,6 +160,7 @@ def build(bld):
node.target = 'node'
node.source = """
src/node.cc
src/events.cc
src/http.cc
src/net.cc
src/file.cc

Loading…
Cancel
Save