Mercurial > MadButterfly
changeset 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 | d2f2ed27b84d |
children | ed59e659a202 |
files | nodejs/coord.cc nodejs/shapes.cc nodejs/shapes.m4 nodejs/testcase.js |
diffstat | 4 files changed, 75 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/nodejs/coord.cc Wed Aug 25 18:22:32 2010 +0800 +++ b/nodejs/coord.cc Wed Aug 25 18:46:47 2010 +0800 @@ -196,6 +196,7 @@ xnjsmb_coord_add_shape(coord_t *coord, Handle<Object> self, shape_t *shape, const char **err) { Handle<Object> js_rt; + Persistent<Object> *shape_hdl; redraw_man_t *rdman; int r; @@ -204,6 +205,11 @@ r = rdman_add_shape(rdman, shape, coord); if(r != 0) *err = "Unknown error"; + + /* see \ref jsgc */ + shape_hdl = (Persistent<Object> *)mb_prop_get(&shape->obj.props, + PROP_JSOBJ); + shape_hdl->ClearWeak(); } static void
--- 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;
--- a/nodejs/shapes.m4 Wed Aug 25 18:22:32 2010 +0800 +++ b/nodejs/shapes.m4 Wed Aug 25 18:46:47 2010 +0800 @@ -5,9 +5,11 @@ [xnjsmb_shape_stroke_width_get], [xnjsmb_shape_stroke_width_set])], [METHOD([show], [sh_show], (), 0, []), - METHOD([hide], [sh_hide], (), 0, [])]) + METHOD([hide], [sh_hide], (), 0, []), + METHOD([remove], [xnjsmb_shape_remove], (SELF), 0, [])]) -STRUCT([path], [shape_t], [], [], (([INHERIT], [shape]))) +STRUCT([path], [shape_t], [], [], + (([INHERIT], [shape]), ([STMOD], [xnjsmb_shape_mod]))) STRUCT([stext], [shape_t], [], [METHOD([set_text], [sh_stext_set_text], (STR([txt])), 1, []),
--- a/nodejs/testcase.js Wed Aug 25 18:22:32 2010 +0800 +++ b/nodejs/testcase.js Wed Aug 25 18:46:47 2010 +0800 @@ -44,15 +44,25 @@ /* test removing a coord */ var rm_coord = mb_rt.coord_new(root); -var rm_rect = mb_rt.rect_new(150, 150, 50, 50, 10, 10); -paint.fill(rm_rect); -rm_coord.add_shape(rm_rect); +var rm_rect1 = mb_rt.rect_new(150, 150, 50, 50, 10, 10); +paint.fill(rm_rect1); +rm_coord.add_shape(rm_rect1); +var rm_rect2 = mb_rt.rect_new(100, 150, 50, 50, 10, 10); +paint.fill(rm_rect2); +rm_coord.add_shape(rm_rect2); setTimeout(function() { rm_coord.remove(); mb_rt.redraw_changed(); mb_rt.flush(); }, 3000); +/* test removing a shape */ +setTimeout(function() { + rm_rect1.remove(); + mb_rt.redraw_changed(); + mb_rt.flush(); + }, 2000); + /* Moving a path */ sys.puts(mb_rt.path_new); var path = mb_rt.path_new("m 100,50 L 120,50 L 200,150 L 180,150 z");