Mercurial > MadButterfly
changeset 741:d8764f10e141
Remove a coord from the tree in JS
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Wed, 25 Aug 2010 10:40:30 +0800 |
parents | 00a8c8a9e157 |
children | 24038e7a365b |
files | nodejs/coord.cc nodejs/coord.m4 |
diffstat | 2 files changed, 64 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/nodejs/coord.cc Wed Aug 25 10:07:33 2010 +0800 +++ b/nodejs/coord.cc Wed Aug 25 10:40:30 2010 +0800 @@ -41,9 +41,15 @@ * object added to the tree of a mbrt (runtime object), and remove the * reference and invalidate it when it being removed. * - * The binding also hold a weak reference to every object, it free the - * object when the callback of the weak reference being called and it - * being valid. If the object is invalid, the callback does nothing. + * For coords, they are always attached to the tree when it is valid. + * So, binding hold a persistent reference to it. The reference is + * purged when a coord being removed from the tree and being + * invalidated. + * + * For any shape, it is not attached to the tree at begining, but is + * attached to a tree laterly, or is collected by GC. The binding + * hold a weak reference for a new shape, and upgrade to a strong + * reference when the shape being added to the tree. */ using namespace v8; @@ -53,6 +59,44 @@ * * @{ */ +/*! \brief Invalidate JS objects for coords and shapes in a subtree. + * + * \param self is the object of the root of subtree. + * + * \sa \ref jsgc + */ +static void +xnjsmb_coord_invalidate_subtree(Handle<Object> self) { + Handle<Object> *child_hdl; + Handle<Object> *mem_hdl; + redraw_man_t *rdman; + coord_t *coord, *child; + shape_t *mem; + Handle<Value> _false = Boolean::New(0); + + if(!GET(self, "valid")->ToBoolean()->Value()) /* Invalidated object */ + return; + + coord = (coord_t *)UNWRAP(self); + + /* Invalidate all coords in the subtree */ + FOR_COORDS_PREORDER(coord, child) { + child_hdl = (Handle<Object> *)mb_prop_get(&child->obj.props, + PROP_JSOBJ); + child = (coord_t *)UNWRAP(*child_hdl); + WRAP(*child_hdl, NULL); + SET(*child_hdl, "valid", _false); + + /* Invalidate members of a coord */ + FOR_COORD_SHAPES(child, mem) { + mem_hdl = (Handle<Object> *)mb_prop_get(&mem->obj.props, + PROP_JSOBJ); + WRAP(*mem_hdl, NULL); + SET(*mem_hdl, "valid", _false); + } + } +} + static void xnjsmb_coord_mod(Handle<Object> self, coord_t *coord) { Persistent<Object> *self_hdl; @@ -68,6 +112,7 @@ subject = coord->mouse_event; subject_o = export_xnjsmb_auto_subject_new(subject); SET(self, "mouse_event", subject_o); + SET(self, "valid", Boolean::New(1)); } static float @@ -115,6 +160,20 @@ *err = "Unknown error"; } +static void +xnjsmb_coord_remove(coord_t *coord, Handle<Object> self, const char **err) { + Handle<Object> js_rt; + redraw_man_t *rdman; + + js_rt = GET(self, "mbrt")->ToObject(); + rdman = xnjsmb_rt_rdman(js_rt); + + xnjsmb_coord_invalidate_subtree(self); + + /* Free all coords and shapes in the subtree */ + rdman_coord_free(rdman, coord); +} + #include "coord-inc.h" /*! \brief This function used by \ref xnjsmb_mb_rt to wrap coord object.
--- a/nodejs/coord.m4 Wed Aug 25 10:07:33 2010 +0800 +++ b/nodejs/coord.m4 Wed Aug 25 10:40:30 2010 +0800 @@ -1,7 +1,8 @@ define([PROJ_PREFIX], [xnjsmb_auto_])dnl STRUCT([coord], [coord_t], [], [METHOD([add_shape], [xnjsmb_coord_add_shape], - (SELF, OBJ([shape], [shape], [shape_t]), ERR), 1, [])], + (SELF, OBJ([shape], [shape], [shape_t]), ERR), 1, []), + METHOD([remove], [xnjsmb_coord_remove], (SELF, ERR), 0, [])], ((GET_INDEX, (coord_get_index, NUMBER)), (SET_INDEX, (coord_set_index, NUMBER)), ([STMOD], [xnjsmb_coord_mod])))