changeset 662:689e15edbf72

Merge the head from FourDollars
author Thinker K.F. Li <thinker@branda.to>
date Sun, 01 Aug 2010 20:20:33 +0800
parents 90c7726bc953 (diff) 21f944e79b19 (current diff)
children 974d98233eab
files
diffstat 6 files changed, 230 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/nodejs/coord.cc	Sat Jul 31 17:31:00 2010 +0800
+++ b/nodejs/coord.cc	Sun Aug 01 20:20:33 2010 +0800
@@ -16,126 +16,52 @@
 
 using namespace v8;
 
-static Handle<Value>
-xnjsmb_coord_get_index(uint32_t index, const AccessorInfo &info) {
-    HandleScope scope;
-    Handle<Object> self;
-    coord_t *coord;
-    co_aix v;
+static float
+coord_get_index(coord_t *coord, Handle<Object> self, int idx,
+		const char **err) {
+    if(idx < 0 || idx >= 6) {
+        *err = "Invalid index: out of range";
+        return 0;
+    }
 
-    if(index < 0 || index >= 6)
-	THROW("Invalid index");
-    
-    self = info.This();
-    coord = (coord_t *)UNWRAP(self);
-    v = coord_get_matrix(coord)[index];
-
-    return Number::New(v);
+    return coord_get_matrix(coord)[idx];
 }
 
-static Handle<Value>
-xnjsmb_coord_set_index(uint32_t index, Local<Value> value,
-		       const AccessorInfo &info) {
-    
-    HandleScope scope;
-    Handle<Object> self;
+static float
+coord_set_index(coord_t *coord, Handle<Object> self,
+		int idx, float v, const char **err) {
     Handle<Object> js_rt;
     redraw_man_t *rdman;
-    coord_t *coord;
-    co_aix v;
+    
+    if(idx < 0 || idx >= 6) {
+        *err = "Invalid index: out of range";
+        return 0;
+    }
 
-    if(index < 0 || index >= 6)
-	THROW("Invalid Index");
-    if(!value->IsNumber())
-	THROW("Invalid value");
-
-    self = info.This();
-    coord = (coord_t *)UNWRAP(self);
-    v = value->NumberValue();
-    coord_get_matrix(coord)[index] = v;
-
+    coord_get_matrix(coord)[idx] = v;
+    
     js_rt = GET(self, "mbrt")->ToObject();
     rdman = xnjsmb_rt_rdman(js_rt);
     rdman_coord_changed(rdman, coord);
 
-    return value;
+    return v;
 }
 
-/*! \brief Callback functio to add a shape to a coord in Javascript.
- *
- * coord.add_shape(shape)
- */
-static Handle<Value>
-xnjsmb_coord_add_shape(const Arguments &args) {
-    int argc = args.Length();
-    Handle<Object> self = args.This();
-    Handle<Object> shape_obj;
-    Handle<Object> rt_obj;
-    Handle<Value> rt_val;
+static void
+xnjsmb_coord_add_shape(coord_t *coord, Handle<Object> self,
+			shape_t *shape, const char **err) {
+    Handle<Object> js_rt;
     redraw_man_t *rdman;
-    coord_t *coord;
-    shape_t *sh;
     int r;
-
-    if(argc != 1)
-	THROW("Invalid number of arguments (!= 1)");
     
-    shape_obj = args[0]->ToObject();
-    sh = (shape_t *)UNWRAP(shape_obj);
-    ASSERT(sh != NULL);
-    
-    coord = (coord_t *)UNWRAP(self);
-    ASSERT(coord != NULL);
-
-    rt_val = GET(self, "mbrt");
-    rt_obj = rt_val->ToObject();
-    rdman = xnjsmb_rt_rdman(rt_obj);
-    
-    r = rdman_add_shape(rdman, sh, coord);
+    js_rt = GET(self, "mbrt")->ToObject();
+    rdman = xnjsmb_rt_rdman(js_rt);
+    r = rdman_add_shape(rdman, shape, coord);
     if(r != 0)
-	THROW("Unknown error");
-
-    return Null();
+	*err = "Unknown error";
 }
 
-static Persistent<ObjectTemplate> coord_obj_temp;
-
-static void
-xnjsmb_init_temp(void) {
-    Handle<FunctionTemplate> add_shape_temp;
-    
-    coord_obj_temp = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
-    coord_obj_temp->SetIndexedPropertyHandler(xnjsmb_coord_get_index,
-					      xnjsmb_coord_set_index);
-    coord_obj_temp->SetInternalFieldCount(1);
-
-    add_shape_temp = FunctionTemplate::New(xnjsmb_coord_add_shape);
-    SET(coord_obj_temp, "add_shape", add_shape_temp);
-}
-
-/*! \brief Create and initialize a Javascript object for a coord.
- */
-static Handle<Object>
-xnjsmb_coord_new_jsobj(coord_t *coord, Handle<Object> parent_obj,
-		       Handle<Object> js_rt) {
-    Handle<Object> coord_obj;
-    static int init_temp = 0;
-    
-    if(!init_temp) {
-	xnjsmb_init_temp();
-	init_temp = 1;
-    }
-
-    coord_obj = coord_obj_temp->NewInstance();
-    ASSERT(coord_obj != NULL);
-    WRAP(coord_obj, coord);
-
-    if(!parent_obj.IsEmpty())
-	SET(coord_obj, "parent", parent_obj);
-    SET(coord_obj, "mbrt", js_rt);
-
-    return coord_obj;
-}
+#include "coord-inc.h"
 
 /*! \brief Create a coord object associated with the rdman of the runtime.
  *
@@ -166,7 +92,11 @@
     
     coord = rdman_coord_new(rdman, parent);
     ASSERT(coord != NULL);
-    coord_obj = xnjsmb_coord_new_jsobj(coord, parent_obj, js_rt);
+    
+    coord_obj = xnjsmb_auto_coord_new(coord).As<Object>();
+    if(!parent_obj.IsEmpty())
+	SET(coord_obj, "parent", parent_obj);
+    SET(coord_obj, "mbrt", js_rt);
 
     scope.Close(coord_obj);
     
@@ -185,10 +115,17 @@
     redraw_man_t *rdman;
     coord_t *root;
     Handle<Object> obj;
+    static int init_flag = 0;
+
+    if(!init_flag) {
+	xnjsmb_auto_coord_init();
+	init_flag = 1;
+    }
     
     rdman = xnjsmb_rt_rdman(js_rt);
     root = rdman_get_root(rdman);
-    obj = xnjsmb_coord_new_jsobj(root, Handle<Object>(NULL), js_rt);
+    obj = xnjsmb_auto_coord_new(root).As<Object>();
+    SET(obj, "mbrt", js_rt);
 
     SET(js_rt, "root", obj);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nodejs/coord.m4	Sun Aug 01 20:20:33 2010 +0800
@@ -0,0 +1,6 @@
+define([PROJ_PREFIX], [xnjsmb_auto_])dnl
+STRUCT([coord], [coord_t], [],
+	[METHOD([add_shape], [xnjsmb_coord_add_shape],
+		(SELF, OBJ([shape], [shape_t]), ERR), 1, [])],
+	((GET_INDEX, (coord_get_index, NUMBER)),
+	 (SET_INDEX, (coord_set_index, NUMBER))))
--- a/nodejs/observer.cc	Sat Jul 31 17:31:00 2010 +0800
+++ b/nodejs/observer.cc	Sun Aug 01 20:20:33 2010 +0800
@@ -45,6 +45,7 @@
     delete data;
 }
 
+/* This is the part of the code generated by gen_v8_binding.m4 */
 #include "observer-inc.h"
 
 static void
@@ -53,9 +54,12 @@
     Handle<Value> evt_obj;
     Handle<Value> func_args[1];
 
-    evt_obj = xnjsmb_event_new(evt);
+    evt_obj = xnjsmb_auto_event_new(evt);
     ASSERT(!evt_obj.IsEmpty());
     func_args[0] = evt_obj;
     data->func->Call(Context::GetCurrent()->Global(), 1, func_args);
 }
 
+void
+xnjsmb_observer_init(void) {
+}
--- a/nodejs/observer.m4	Sat Jul 31 17:31:00 2010 +0800
+++ b/nodejs/observer.m4	Sun Aug 01 20:20:33 2010 +0800
@@ -1,4 +1,4 @@
-STRUCT([mb_obj], [mb_obj_t], [INT([obj_type])], [])
+define([PROJ_PREFIX], [xnjsmb_auto_])
 
 STRUCT([observer], [observer_t],
        [INT([type])], [])
@@ -8,9 +8,7 @@
        	       (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])])])
+	       (OBJ([observer], [observer_t])), 1, [])])
 
 STRUCT([event], [event_t],
        [INT([type]), OBJ([tgt], [subject], [subject_t]),
--- a/nodejs/wscript	Sat Jul 31 17:31:00 2010 +0800
+++ b/nodejs/wscript	Sun Aug 01 20:20:33 2010 +0800
@@ -24,12 +24,15 @@
     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'])
+    conf(rule='m4 -I ${SRCDIR}/../tools gen_v8_binding.m4 ${SRC} > ${TGT}',
+         source='coord.m4', target='coord-inc.h',
+         name='coord-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 ' + \
+    obj.source = 'mbfly_njs.cc shapes.cc paints.cc font.cc ' + \
 	'image_ldr.cc'
-    obj.add_objects = 'X_supp_njs.o observer.o'
+    obj.add_objects = 'X_supp_njs.o observer.o coord.o'
     obj.staticlib = 'mbfly'
 
     obj = conf.new_task_gen('cc', 'shlib', 'node_addon')
@@ -40,4 +43,9 @@
     obj.target = 'observer.o'
     obj.source = 'observer.cc'
     obj.includes = '.'
+    
+    obj = conf.new_task_gen('cxx', 'shlib', 'node_addon')
+    obj.target = 'coord.o'
+    obj.source = 'coord.cc'
+    obj.includes = '.'
     pass
--- a/tools/gen_v8_binding.m4	Sat Jul 31 17:31:00 2010 +0800
+++ b/tools/gen_v8_binding.m4	Sun Aug 01 20:20:33 2010 +0800
@@ -13,6 +13,8 @@
 
 define([IMPORT],[define([$1],[$2$1(]$[]@[)])])
 
+define([EXPAND], [$1])
+
 define([PROJ_PREFIX], [xnjsmb_])
 
 define([START_ACCESSOR], [dnl
@@ -38,6 +40,27 @@
     data->$][1 = value->Int32Value();
 }
 ])
+  define([NUMBER], [
+static Handle<Value>
+]PROJ_PREFIX[]STRUCT_NAME[_get_$][1(Local<String> property, const AccessorInfo &info) {
+    Handle<Object> self = info.This();
+    STRUCT_TYPE *data;
+
+    data = (STRUCT_TYPE *)UNWRAP(self);
+    return Number::New(data->$][1);
+}
+
+static void
+]PROJ_PREFIX[]STRUCT_NAME[_set_$][1(Local<String> property,
+		      Local<Value> value,
+		      const AccessorInfo &info) {
+    Handle<Object> self = info.This();
+    STRUCT_TYPE *data;
+
+    data = (STRUCT_TYPE *)UNWRAP(self);
+    data->$][1 = value->NumberValue();
+}
+])
   define([OBJ], [
 static Handle<Value>
 ]PROJ_PREFIX[]STRUCT_NAME[_get_$][1(Local<String> property, const AccessorInfo &info) {
@@ -45,7 +68,7 @@
     STRUCT_TYPE *data;
 
     data = (STRUCT_TYPE *)UNWRAP(self);
-    return ]PROJ_PREFIX[$][2_new(data->$][1);
+    return ]PROJ_PREFIX[$][2_new(($][3 *)data->$][1);
 }
 
 static void
@@ -92,6 +115,7 @@
 define([STOP_ACCESSOR], [dnl
 divert([-1])dnl
 undefine([INT])
+undefine([NUMBER])
 undefine([OBJ])
 undefine([STR])
 divert([])dnl
@@ -99,12 +123,14 @@
 
 define([SET_ACCESSSOR], [dnl
 define([INT], [$][1])dnl
+define([NUMBER], [$][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([NUMBER])dnl
 undefine([OBJ])dnl
 undefine([STR])dnl
 ])
@@ -113,6 +139,9 @@
 define([INT], [dnl
     int arg_$][1;
 ])dnl
+define([NUMBER], [dnl
+    double arg_$][1;
+])dnl
 define([OBJ], [dnl
     $][2 *arg_$][1;
 ])dnl
@@ -122,23 +151,40 @@
 define([FUNC], [dnl
     Handle<Function> arg_$][1;
 ])dnl
+define([SELF], [])dnl
+define([ERR], [])dnl
 ])
 
 define([START_METHOD_ARG_TYPE_CHK], [dnl
 define([INT], [ ||
        !args[[i++]]->IsInt32()])dnl
+define([NUMBER], [ ||
+       !args[[i++]]->IsNumber()])dnl
 define([OBJ], [ ||
        !args[[i++]]->IsObject()])dnl
 define([STR], [ ||
        !args[[i++]]->IsString()])dnl
 define([FUNC], [ ||
        !args[[i++]]->IsFunction()])dnl
+define([SELF], [])dnl
+define([ERR], [])dnl
+])
+
+define([START_TYPE_CHK], [dnl
+define([INT], [$1->IsInt32()])dnl
+define([NUMBER], [$1->IsNumber()])dnl
+define([OBJ], [$1->IsObject()])dnl
+define([STR], [$1->IsString()])dnl
+define([FUNC], [$1->IsFunction()])dnl
 ])
 
 define([START_METHOD_ARG_ASSIGN], [dnl
 define([INT], [dnl
     arg_$][1 = args[[i++]]->Int32Value();
 ])dnl
+define([NUMBER], [dnl
+    arg_$][1 = args[[i++]]->NumberValue();
+])dnl
 define([OBJ], [dnl
     arg_$][1 = ($][2 *)UNWRAP(args[[i++]]->ToObject());
 ])dnl
@@ -148,19 +194,45 @@
 define([FUNC], [dnl
     arg_$][1 = args[[i++]].As<Function>();
 ])dnl
+define([SELF], [])dnl
+define([ERR], [])dnl
+])
+
+define([START_VALUE_ASSIGN], [dnl
+define([INT], [dnl
+    $1 = $2->Int32Value();
+])dnl
+define([NUMBER], [dnl
+    $1 = $2->NumberValue();
+])dnl
+define([OBJ], [dnl
+    $1 = ($][2 *)UNWRAP($2->ToObject());
+])dnl
+define([STR], [dnl
+    $1 = strdup(*String::Utf8Value($2->ToString()));
+])dnl
+define([FUNC], [dnl
+    $1 = $2.As<Function>();
+])dnl
 ])
 
 define([START_METHOD_ARG_PASS], [dnl
 define([INT], [arg_$][1])dnl
+define([NUMBER], [arg_$][1])dnl
 define([OBJ], [arg_$][1])dnl
 define([STR], [arg_$][1])dnl
 define([FUNC], [arg_$][1])dnl
+define([SELF], [self])dnl
+define([ERR], [&_err])dnl
 ])
 
 define([START_METHOD_RET_VAL], [dnl
 define([INT], [dnl
     int _ret;
 ])dnl
+define([NUMBER], [dnl
+    double _ret;
+])dnl
 define([OBJ], [dnl
     $][2 *_ret;
 ])dnl
@@ -172,8 +244,27 @@
 ])dnl
 ])
 
+define([START_VAR], [dnl
+define([INT], [dnl
+    int $1;
+])dnl
+define([NUMBER], [dnl
+    double $1;
+])dnl
+define([OBJ], [dnl
+    $][2 *$1;
+])dnl
+define([STR], [dnl
+    char *$1;
+])dnl
+define([FUNC], [dnl
+    Handle<Function> $1;
+])dnl
+])
+
 define([START_METHOD_RET_ASSIGN], [dnl
 define([INT], [_ret = (int)])dnl
+define([NUMBER], [_ret = (double)])dnl
 define([OBJ], [_ret = ($][2 *)])dnl
 define([STR], [_ret = (char *)])dnl
 define([FUNC], [_ret = ])dnl
@@ -183,6 +274,9 @@
 define([INT], [
     return Integer::New(_ret);
 ])dnl
+define([NUMBER], [
+    return Number::New(_ret);
+])dnl
 define([OBJ], [
     return PROJ_PREFIX[]$][1[]_new(_ret);
 ])dnl
@@ -196,9 +290,12 @@
 
 define([STOP_METHOD_ARG], [dnl
 undefine([INT])dnl
+undefine([NUMBER])dnl
 undefine([OBJ])dnl
 undefine([STR])dnl
 undefine([FUNC])dnl
+undefine([SELF])dnl
+undefine([ERR])dnl
 ])
 
 define([START_METHOD], [dnl
@@ -209,20 +306,23 @@
     int argc = args.Length();
     Handle<Object> self = args.This();
     STRUCT_TYPE *_self = (STRUCT_TYPE *)UNWRAP(self);
+    const char *_err = NULL;
 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])[)
+    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]));
+    if(_err)
+        THROW(_err);
 START_METHOD_RET[]$][5[]STOP_METHOD_ARG[]dnl
 ifelse($][5, [], [
     return Null();
@@ -242,12 +342,61 @@
 undefine([METHOD])dnl
 ])
 
+define([DEF_GET_INDEX], [
+static Handle<Value>
+PROJ_PREFIX[]STRUCT_NAME[]_get_index(uint32_t index, const AccessorInfo &info) {
+    Handle<Object> self = info.This();
+    STRUCT_TYPE *obj = (STRUCT_TYPE *)UNWRAP(self);
+    const char *_err = NULL;
+START_METHOD_RET_VAL[]$2[]STOP_METHOD_ARG[]dnl
+
+    _ret = $1(obj, self, index, &_err);
+    if(_err)
+        THROW(_err);
+START_METHOD_RET[]$2[]STOP_METHOD_ARG[]dnl
+}
+])
+
+define([DEF_SET_INDEX], [
+static Handle<Value>
+PROJ_PREFIX[]STRUCT_NAME[]_set_index(uint32_t index, Local<Value> value,
+	const AccessorInfo &info) {
+    Handle<Object> self = info.This();
+    STRUCT_TYPE *obj = (STRUCT_TYPE *)UNWRAP(self);
+    const char *_err = NULL;
+START_VAR([in_value])[]$2[]STOP_METHOD_ARG[]dnl
+START_METHOD_RET_VAL[]$2[]STOP_METHOD_ARG[]dnl
+
+    if(START_TYPE_CHK(value)[]![]$2[]STOP_METHOD_ARG)
+        THROW("Invalid value type");
+
+START_VALUE_ASSIGN(in_value, value)[]$2[]STOP_METHOD_ARG[]dnl
+    _ret = $1(obj, self, index, in_value, &_err);
+    if(_err) THROW(_err);
+START_METHOD_RET[]$2[]STOP_METHOD_ARG[]dnl
+}
+])
+
+define([INSTALL_INDEX_FUNCTIONS],[dnl
+define([FIRST], [$][1])dnl
+ifdef([GET_INDEX], [ifdef([SET_INDEX], [dnl
+    inst_temp->SetIndexedPropertyHandler(PROJ_PREFIX[]STRUCT_NAME[]_get_index,
+					 PROJ_PREFIX[]STRUCT_NAME[]_set_index);
+], [dnl
+    inst_temp->SetIndexedPropertyHandler(PROJ_PREFIX[]STRUCT_NAME[]_get_index);
+])])dnl
+undefine([FIRST])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
+dnl
+ifelse([$5], [], [], [foreach([ITER], $5, [EXPAND([define]ITER)])])dnl
+dnl
 [
 /* **************************************************
  * STRUCT: $1
@@ -273,6 +422,8 @@
 ]dnl
 foreach([ITER], ($3), [START_ACCESSOR ITER STOP_ACCESSOR])dnl
 foreach([ITER], ($4), [START_METHOD ITER STOP_METHOD])dnl
+ifdef([GET_INDEX], [EXPAND([DEF_GET_INDEX]GET_INDEX)])dnl
+ifdef([SET_INDEX], [EXPAND([DEF_SET_INDEX]SET_INDEX)])dnl
 [
 static void
 ]PROJ_PREFIX[$1][_init(void) {
@@ -286,12 +437,20 @@
     inst_temp->SetInternalFieldCount(1);
     ]
 foreach([ITER], ($3), [SET_ACCESSSOR(ITER)])dnl
-    inst_temp = func_temp->InstanceTemplate();
+INSTALL_INDEX_FUNCTIONS[]dnl
 
+    proto_temp = func_temp->PrototypeTemplate();
 foreach([ITER], ($4), [SET_METHOD(ITER)])dnl
 
     PROJ_PREFIX[$1][_temp = Persistent<FunctionTemplate>::New(func_temp);
 }]dnl
+dnl
+ifelse([$5], [], [], [foreach([ITER], $5, [dnl
+define([DUMMY], [undefine]ITER)dnl
+DUMMY[]dnl
+undefine([DUMMY])])dnl
+])dnl
+dnl
 ])
 
 dnl
@@ -306,6 +465,7 @@
 PROJ_PREFIX[]$1(const Arguments &args) {
     int argc = args.Length();
     int i;
+    const char *_err = NULL;
 foreach([ITER], ($3), [START_METHOD_ARG_VAR[]ITER[]STOP_METHOD_ARG])dnl
 START_METHOD_RET_VAL[]$5[]STOP_METHOD_ARG[]dnl
     
@@ -321,6 +481,8 @@
 
 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])
+    if(_err)
+        THROW(_err);
 START_METHOD_RET[]$][5[]STOP_METHOD_ARG[]dnl
 ifelse($][5, [], [
     return Null();