# HG changeset patch # User Thinker K.F. Li # Date 1280554238 -28800 # Node ID 1748dce31cdbae76173dffb19481802d00441f5e # Parent aa52883534fccee25294d55ca6ea814e1f158aa1# Parent 492da72e6537f7aeb8617e13712273b20a981ffa Merge the head from wycc diff -r 492da72e6537 -r 1748dce31cdb nodejs/Makefile.am --- a/nodejs/Makefile.am Thu Jul 29 00:15:19 2010 +0800 +++ b/nodejs/Makefile.am Sat Jul 31 13:30:38 2010 +0800 @@ -17,7 +17,8 @@ LDFLAGS="$(mbfly_node_LDFLAGS)" \ TOP_BUILDDIR="$(abs_top_builddir)" \ WAFLOCK=$(abs_builddir)/objs/.lock-wscript \ - $(NODE_WAF) configure build --blddir=$(abs_builddir)/objs + $(NODE_WAF) configure build --srcdir=$(abs_srcdir) \ + --blddir=$(abs_builddir)/objs clean-mbfly-node: cd $(srcdir); \ diff -r 492da72e6537 -r 1748dce31cdb nodejs/observer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nodejs/observer.cc Sat Jul 31 13:30:38 2010 +0800 @@ -0,0 +1,61 @@ +#include +#include "mbfly_njs.h" + +extern "C" { +#include +#include +} + +#ifndef ASSERT +#define ASSERT(x) +#endif + +using namespace v8; + +struct xnjsmb_observer_data { + Persistent func; +}; + +static void +event_handler(event_t *evt, void *arg); + +static observer_t * +_subject_add_event_observer(subject_t *subject, int type, + Handle func) { + observer_t *observer; + xnjsmb_observer_data *data; + + data = new xnjsmb_observer_data; + if(data == NULL) + return NULL; + data->func = Persistent::New(func); + observer = subject_add_event_observer(subject, type, + event_handler, + data); + + return observer; +} + +static void +_subject_remove_observer(subject_t *subject, observer_t *observer) { + xnjsmb_observer_data *data; + + subject_remove_observer(subject, observer); + data = (xnjsmb_observer_data *)observer->arg; + delete data; +} + +#include "observer-inc.h" + +static void +event_handler(event_t *evt, void *arg) { + xnjsmb_observer_data *data = (xnjsmb_observer_data *)arg; + Handle evt_obj; + Handle func_args[1]; + + evt_obj = xnjsmb_event_new(evt); + ASSERT(!evt_obj.IsEmpty()); + func_args[0] = evt_obj; + data->func->Call(Context::GetCurrent()->Global(), 1, func_args); +} + diff -r 492da72e6537 -r 1748dce31cdb nodejs/observer.m4 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nodejs/observer.m4 Sat Jul 31 13:30:38 2010 +0800 @@ -0,0 +1,17 @@ +STRUCT([mb_obj], [mb_obj_t], [INT([obj_type])], []) + +STRUCT([observer], [observer_t], + [INT([type])], []) + +STRUCT([subject], [subject_t], [], + [METHOD([add_event_observer], [_subject_add_event_observer], + (INT([type]), FUNC([handler])), 2, + [OBJ([observer], [observer_t])]), + METHOD([remove_observer], [_subject_remove_observer], + (OBJ([observer], [observer_t])), 1, []), + METHOD([get_object], [subject_get_object], (), 0, + [OBJ([mb_obj], [mb_obj_t])])]) + +STRUCT([event], [event_t], + [INT([type]), OBJ([tgt], [subject], [subject_t]), + OBJ([cur_tgt], [subject], [subject_t]), INT([flags])], []) diff -r 492da72e6537 -r 1748dce31cdb nodejs/wscript --- a/nodejs/wscript Thu Jul 29 00:15:19 2010 +0800 +++ b/nodejs/wscript Sat Jul 31 13:30:38 2010 +0800 @@ -15,20 +15,29 @@ conf.check_tool('compiler_cc') conf.check_tool('node_addon') conf.env.SRCDIR = Options.options.srcdir - conf.env.TOP_BUILDDIR = os.environ['TOP_BUILDDIR'] + conf.env.TOP_BUILDDIR = os.environ['TOP_BUILDDIR'] pass def build(conf): import Utils + conf(rule='m4 -I ${SRCDIR}/../tools gen_v8_binding.m4 ${SRC} > ${TGT}', + source='observer.m4', target='observer-inc.h', + name='observer-inc', shell=True, always=True, before=['cxx']) + obj = conf.new_task_gen('cxx', 'shlib', 'node_addon') obj.target = 'mbfly' obj.source = 'mbfly_njs.cc coord.cc shapes.cc paints.cc font.cc ' + \ 'image_ldr.cc' - obj.add_objects = 'X_supp_njs.o' + obj.add_objects = 'X_supp_njs.o observer.o' obj.staticlib = 'mbfly' - + obj = conf.new_task_gen('cc', 'shlib', 'node_addon') obj.target = 'X_supp_njs.o' obj.source = 'X_supp_njs.c' + + obj = conf.new_task_gen('cxx', 'shlib', 'node_addon') + obj.target = 'observer.o' + obj.source = 'observer.cc' + obj.includes = '.' pass diff -r 492da72e6537 -r 1748dce31cdb tools/gen_v8_binding.m4 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/gen_v8_binding.m4 Sat Jul 31 13:30:38 2010 +0800 @@ -0,0 +1,340 @@ +dnl +dnl Developers should provide SET, WRAP, UNWRAP, and THROW C macros. +dnl +changequote(`[', `]')dnl +include([foreach.m4])dnl +divert([-1])dnl + +define([UNQUOTE], [$*]) + +define([QUOTE], [[[$*]]]) + +define([COUNT],[ifelse([$*],[],0,[$#])]) + +define([IMPORT],[define([$1],[$2$1(]$[]@[)])]) + +define([PROJ_PREFIX], [xnjsmb_]) + +define([START_ACCESSOR], [dnl +divert([-1])dnl + define([INT], [ +static Handle +]PROJ_PREFIX[]STRUCT_NAME[_get_$][1(Local property, const AccessorInfo &info) { + Handle self = info.This(); + STRUCT_TYPE *data; + + data = (STRUCT_TYPE *)UNWRAP(self); + return Integer::New(data->$][1); +} + +static void +]PROJ_PREFIX[]STRUCT_NAME[_set_$][1(Local property, + Local value, + const AccessorInfo &info) { + Handle self = info.This(); + STRUCT_TYPE *data; + + data = (STRUCT_TYPE *)UNWRAP(self); + data->$][1 = value->Int32Value(); +} +]) + define([OBJ], [ +static Handle +]PROJ_PREFIX[]STRUCT_NAME[_get_$][1(Local property, const AccessorInfo &info) { + Handle self = info.This(); + STRUCT_TYPE *data; + + data = (STRUCT_TYPE *)UNWRAP(self); + return ]PROJ_PREFIX[$][2_new(data->$][1); +} + +static void +]PROJ_PREFIX[]STRUCT_NAME[_set_$][1(Local property, + Local value, + const AccessorInfo &info) { + Handle self = info.This(); + Handle obj; + $][3 *v; + STRUCT_TYPE *data; + + data = (STRUCT_TYPE *)UNWRAP(self); + obj = value->ToObject(); + v = ($][3 *)UNWRAP(obj); + data->$][1 = v; +} +]) + define([STR], [ +static Handle +]PROJ_PREFIX[]STRUCT_NAME[_get_$][1(Local property, const AccessorInfo &info) { + Handle self = info.This(); + STRUCT_TYPE *data; + + data = (STRUCT_TYPE *)UNWRAP(self); + return String::New(data->$][1); +} + +static void +]PROJ_PREFIX[]STRUCT_NAME[_set_$][1(Local property, + Local value, + const AccessorInfo &info) { + Handle self = info.This(); + STRUCT_TYPE *data; + + data = (STRUCT_TYPE *)UNWRAP(self); + String::Utf8Value utf8(value->ToString()); + free(data->$][1); + data->$][1 = strdup(*utf8); +} +]) +divert([])dnl +]) + +define([STOP_ACCESSOR], [dnl +divert([-1])dnl +undefine([INT]) +undefine([OBJ]) +undefine([STR]) +divert([])dnl +]) + +define([SET_ACCESSSOR], [dnl +define([INT], [$][1])dnl +define([OBJ], [$][1])dnl +define([STR], [$][1])dnl + inst_temp->SetAccessor(String::New("$1"), + PROJ_PREFIX[]STRUCT_NAME[]_get_[]$1, + PROJ_PREFIX[]STRUCT_NAME[]_set_[]$1); +undefine([INT])dnl +undefine([OBJ])dnl +undefine([STR])dnl +]) + +define([START_METHOD_ARG_VAR], [dnl +define([INT], [dnl + int arg_$][1; +])dnl +define([OBJ], [dnl + $][2 *arg_$][1; +])dnl +define([STR], [dnl + char *arg_$][1; +])dnl +define([FUNC], [dnl + Handle arg_$][1; +])dnl +]) + +define([START_METHOD_ARG_TYPE_CHK], [dnl +define([INT], [ || + !args[[i++]]->IsInt32()])dnl +define([OBJ], [ || + !args[[i++]]->IsObject()])dnl +define([STR], [ || + !args[[i++]]->IsString()])dnl +define([FUNC], [ || + !args[[i++]]->IsFunction()])dnl +]) + +define([START_METHOD_ARG_ASSIGN], [dnl +define([INT], [dnl + arg_$][1 = args[[i++]]->Int32Value(); +])dnl +define([OBJ], [dnl + arg_$][1 = ($][2 *)UNWRAP(args[[i++]]->ToObject()); +])dnl +define([STR], [dnl + arg_$][1 = strdup(*String::Utf8Value(args[[i++]]->ToString())); +])dnl +define([FUNC], [dnl + arg_$][1 = args[[i++]].As(); +])dnl +]) + +define([START_METHOD_ARG_PASS], [dnl +define([INT], [arg_$][1])dnl +define([OBJ], [arg_$][1])dnl +define([STR], [arg_$][1])dnl +define([FUNC], [arg_$][1])dnl +]) + +define([START_METHOD_RET_VAL], [dnl +define([INT], [dnl + int _ret; +])dnl +define([OBJ], [dnl + $][2 *_ret; +])dnl +define([STR], [dnl + char *_ret; +])dnl +define([FUNC], [dnl + Handle _ret; +])dnl +]) + +define([START_METHOD_RET_ASSIGN], [dnl +define([INT], [_ret = (int)])dnl +define([OBJ], [_ret = ($][2 *)])dnl +define([STR], [_ret = (char *)])dnl +define([FUNC], [_ret = ])dnl +]) + +define([START_METHOD_RET], [dnl +define([INT], [ + return Integer::New(_ret); +])dnl +define([OBJ], [ + return PROJ_PREFIX[]$][1[]_new(_ret); +])dnl +define([STR], [ + return String::New(_ret); +])dnl +define([FUNC], [ + return _ret; +])dnl +]) + +define([STOP_METHOD_ARG], [dnl +undefine([INT])dnl +undefine([OBJ])dnl +undefine([STR])dnl +undefine([FUNC])dnl +]) + +define([START_METHOD], [dnl +define([METHOD], [ +static Handle +PROJ_PREFIX[]STRUCT_NAME[]_$][1(const Arguments &args) { + int i; + int argc = args.Length(); + Handle self = args.This(); + STRUCT_TYPE *_self = (STRUCT_TYPE *)UNWRAP(self); +foreach([ITER], $][3, [START_METHOD_ARG_VAR[]ITER[]STOP_METHOD_ARG])dnl +START_METHOD_RET_VAL[]$][5[]STOP_METHOD_ARG + + if(argc != $][4) + THROW("Invalid number of arguments (!=$][4)"); + i = 0; + if(0]dnl +foreach([ITER], $][3, [START_METHOD_ARG_TYPE_CHK[]ITER[]STOP_METHOD_ARG])[) + THROW("Invalid argument type"); + + i = 0; +foreach([ITER], $][3, [START_METHOD_ARG_ASSIGN[]ITER[]STOP_METHOD_ARG])dnl + + START_METHOD_RET_ASSIGN[]$][5[]STOP_METHOD_ARG[]$][2(_self[]foreach([ITER], $][3, [START_METHOD_ARG_PASS[], ITER[]STOP_METHOD_ARG])); +START_METHOD_RET[]$][5[]STOP_METHOD_ARG[]dnl +ifelse($][5, [], [ + return Null(); +])dnl +} +])dnl +]) + +define([STOP_METHOD], [undefine([METHOD])]) + +define([SET_METHOD], [dnl +define([METHOD], [dnl + SET(proto_temp, "$][1", + FunctionTemplate::New(PROJ_PREFIX[]STRUCT_NAME[]_$][1)); +])dnl +$1[]dnl +undefine([METHOD])dnl +]) + +dnl +dnl STRUCT(struct_name, struct_type, member_vars, methods) +dnl +define([STRUCT], [dnl +define([STRUCT_NAME], [$1])dnl +define([STRUCT_TYPE], [$2])dnl +[ +/* ************************************************** + * STRUCT: $1 + * Generated by gen_v8_binding.m4 + */ +static Handle +]PROJ_PREFIX[$1(const Arguments &args) { +} + +static Persistent ]PROJ_PREFIX[$1][_temp; + +static Handle +]PROJ_PREFIX[$1][_new($2 *data) { + Handle obj; + Handle func; + + func = ]PROJ_PREFIX[$1][_temp->GetFunction(); + obj = func->NewInstance(); + WRAP(obj, data); + + return obj; +} +]dnl +foreach([ITER], ($3), [START_ACCESSOR ITER STOP_ACCESSOR])dnl +foreach([ITER], ($4), [START_METHOD ITER STOP_METHOD])dnl +[ +static void +]PROJ_PREFIX[$1][_init(void) { + Handle func_temp; + Handle inst_temp; + Handle proto_temp; + + func_temp = FunctionTemplate::New(]PROJ_PREFIX[$1); + func_temp->SetClassName(String::New("]STRUCT_NAME[")); + inst_temp = func_temp->InstanceTemplate(); + inst_temp->SetInternalFieldCount(1); + ] +foreach([ITER], ($3), [SET_ACCESSSOR(ITER)])dnl + inst_temp = func_temp->InstanceTemplate(); + +foreach([ITER], ($4), [SET_METHOD(ITER)])dnl + + PROJ_PREFIX[$1][_temp = Persistent::New(func_temp); +}]dnl +]) + +dnl +dnl FUNCTION(func_name, real_func, arguments, arguement_count, return_type) +dnl +define([FUNCTION], [dnl +/* ************************************************** + * [FUNCTION]: $1 + * Generated by gen_v8_binding.m4 + */ +static Handle +PROJ_PREFIX[]$1(const Arguments &args) { + int argc = args.Length(); + int i; +foreach([ITER], ($3), [START_METHOD_ARG_VAR[]ITER[]STOP_METHOD_ARG])dnl +START_METHOD_RET_VAL[]$5[]STOP_METHOD_ARG[]dnl + + if(argc != $4) + THROW("Invalid number of arguments (!=$][4)"); + i = 0; + if(0]dnl +[foreach([ITER], ($3), [START_METHOD_ARG_TYPE_CHK[]ITER[]STOP_METHOD_ARG])) + THROW("Invalid argument type"); + + i = 0; +foreach([ITER], ($3), [START_METHOD_ARG_ASSIGN[]ITER[]STOP_METHOD_ARG])dnl + +define([SEP], [])dnl + START_METHOD_RET_ASSIGN[]$5[]STOP_METHOD_ARG[]$2(foreach([ITER], ($3), [START_METHOD_ARG_PASS[]SEP[]ITER[]STOP_METHOD_ARG[]define([SEP], [, ])]));[]undefine([SEP]) +START_METHOD_RET[]$][5[]STOP_METHOD_ARG[]dnl +ifelse($][5, [], [ + return Null(); +])dnl +} +static Persistent PROJ_PREFIX[]$1[]_temp; + +static void +PROJ_PREFIX[]$1[]_init(void) { + Handle func_temp; + + func_temp = FunctionTemplate::New(PROJ_PREFIX[]$1); + PROJ_PREFIX[]$1[]_temp = Persistent::New(func_temp); +} +]) + +divert([])dnl