diff nodejs/shapes.cc @ 748:56a5e08cd8af

Make shapes can be removed from the tree
author Thinker K.F. Li <thinker@codemud.net>
date Wed, 25 Aug 2010 18:46:47 +0800
parents dd1f3382d6a4
children ed59e659a202
line wrap: on
line diff
--- a/nodejs/shapes.cc	Wed Aug 25 18:22:32 2010 +0800
+++ b/nodejs/shapes.cc	Wed Aug 25 18:46:47 2010 +0800
@@ -11,6 +11,8 @@
 #define ASSERT(x)
 #endif
 
+#define OK 0
+
 using namespace v8;
 
 /*! \defgroup xnjsmb_shapes JS binding for shapes.
@@ -18,6 +20,29 @@
  *
  * @{
  */
+/*! \brief This function is called when GC collecting a shape.
+ *
+ * It was installed by Persistent<Object>::MakeWeak().
+ */
+static void
+xnjsmb_shape_recycled(Persistent<Value> obj, void *parameter) {
+    Persistent<Object> *self_hdl = (Persistent<Object> *)parameter;
+    Handle<Object> js_rt;
+    redraw_man_t *rdman;
+    shape_t *shape;
+
+    shape = (shape_t *)UNWRAP(*self_hdl);
+    if(shape == NULL)
+	return;
+    
+    WRAP(*self_hdl, NULL);
+
+    js_rt = GET(*self_hdl, "mbrt")->ToObject();
+    rdman = xnjsmb_rt_rdman(js_rt);
+    rdman_shape_changed(rdman, shape);
+    rdman_shape_free(rdman, shape);
+}
+
 static void
 xnjsmb_shape_mod(Handle<Object> self, shape_t *sh) {
     Persistent<Object> *self_hdl;
@@ -28,6 +53,8 @@
     self_hdl = new Persistent<Object>();
     *self_hdl = Persistent<Object>::New(self);
     mb_prop_set(&sh->obj.props, PROP_JSOBJ, self_hdl);
+
+    self_hdl->MakeWeak(self_hdl, xnjsmb_shape_recycled);
 }
 
 static void
@@ -102,6 +129,31 @@
 }
 
 static void
+xnjsmb_shape_remove(shape_t *sh, Handle<Object> self) {
+    Handle<Object> js_rt;
+    redraw_man_t *rdman;
+    Persistent<Object> *self_hdl;
+    int r;
+
+    self_hdl = (Persistent<Object> *)mb_prop_get(&sh->obj.props,
+						 PROP_JSOBJ);
+    
+    SET(*self_hdl, "valid", Boolean::New(0));
+    WRAP(*self_hdl, NULL);
+
+    js_rt = GET(*self_hdl, "mbrt")->ToObject();
+    ASSERT(js_rt != NULL);
+    rdman = xnjsmb_rt_rdman(js_rt);
+    
+    rdman_shape_changed(rdman, sh);
+    r = rdman_shape_free(rdman, sh);
+    if(r != OK)
+	THROW_noret("Can not free a shape for unknown reason");
+
+    delete self_hdl;
+}
+
+static void
 xnjsmb_sh_rect_set(shape_t *sh, Handle<Object> self, float x, float y,
 		   float w, float h, float rx, float ry) {
     Handle<Object> rt;