diff options
author | pixel <pixel> | 2006-02-01 18:32:25 +0000 |
---|---|---|
committer | pixel <pixel> | 2006-02-01 18:32:25 +0000 |
commit | aac581d00d4efa8c3b03fd802f22457d4127e23f (patch) | |
tree | e71267006aa6cd3e7a7e314d8e4ee5c4d367288e | |
parent | 97b4a5904a989e216b1fbb4d0a55b7340bd7f88a (diff) |
Adding widgets new/delete scheduling - avoiding multithreading glitches.
-rw-r--r-- | include/widgets.h | 11 | ||||
-rw-r--r-- | lib/widgets.cc | 75 |
2 files changed, 64 insertions, 22 deletions
diff --git a/include/widgets.h b/include/widgets.h index 109f623..e46a226 100644 --- a/include/widgets.h +++ b/include/widgets.h @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: widgets.h,v 1.14 2006-01-31 17:02:39 pixel Exp $ */ +/* $Id: widgets.h,v 1.15 2006-02-01 18:32:25 pixel Exp $ */ #ifndef __WIDGETS_H__ #define __WIDGETS_H__ @@ -49,7 +49,7 @@ namespace mogltk { }; class widget : public Base { public: - virtual ~widget(); + virtual ~widget() throw (GeneralException); virtual void move(int x, int y); virtual void resize(int sx, int sy); int GetX(); @@ -113,12 +113,17 @@ namespace mogltk { Uint32 t; }; static std::vector<timed_event> timed_events; + static std::vector<widget *> add_list; + static std::vector<widget *> del_list; + static bool in_delete_loop; void computeabs(); void idraw(); bool ievent(int x, int y, event_t event); void icomputeabs(); void iresize_notify(); + + void linkme(); }; namespace widgets { @@ -385,7 +390,7 @@ namespace mogltk { virtual void do_action(mogltk::widget *) { if (a) a->do_action(parent); - delete parent; + parent->delete_me(); delete this; } private: diff --git a/lib/widgets.cc b/lib/widgets.cc index 1f98597..02b6d6f 100644 --- a/lib/widgets.cc +++ b/lib/widgets.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: widgets.cc,v 1.17 2006-01-31 17:02:39 pixel Exp $ */ +/* $Id: widgets.cc,v 1.18 2006-02-01 18:32:26 pixel Exp $ */ #include <SDL.h> #include <vector> @@ -39,8 +39,9 @@ mogltk::widget * dragged_widget = 0; std::vector<mogltk::widget *> out_move, out_click; std::vector<mogltk::widget::timed_event> mogltk::widget::timed_events; -std::vector<mogltk::widget *> to_delete; - +std::vector<mogltk::widget *> mogltk::widget::add_list; +std::vector<mogltk::widget *> mogltk::widget::del_list; +bool mogltk::widget::in_delete_loop = false; class widget_mouse_event : public mogltk::engine::mouseevent { public: @@ -211,15 +212,24 @@ mogltk::widget * mogltk::widget::focused = 0; mogltk::widget::widget(widget * _father, int _x, int _y, int _sx, int _sy, int _type, String _name, mogltk::shape * _sh) : x(_x), y(_y), sx(_sx), sy(_sy), father(_father), prev(0), child(0), last(0), panel(0), type(_type), name(_name), sh(_sh), exclusive(0), visible(true), enabled(true) { + LOCK; + add_list.push_back(this); + UNLOCK; if (!father) { - root = this; - father = this; - next = 0; x = 0; y = 0; sx = engine::base_o->GetWidth(); sy = engine::base_o->GetHeight(); + } +} + +void mogltk::widget::linkme() { + LOCK; + if (!father) { + root = this; + father = this; + next = 0; } else { next = father->child; if (next) @@ -234,9 +244,12 @@ mogltk::widget::widget(widget * _father, int _x, int _y, int _sx, int _sy, int _ computeabs(); } -mogltk::widget::~widget() { +mogltk::widget::~widget() throw (GeneralException) { while(child) delete child; + + if (!in_delete_loop) + throw GeneralException("Invalid wild delete."); LOCK; if (prev) @@ -266,14 +279,19 @@ mogltk::widget::~widget() { } } -#if 0 - for (iw = to_delete.begin(); iw != to_delete.end(); iw++) { + for (iw = del_list.begin(); iw != del_list.end(); iw++) { if (*iw == this) { - to_delete.erase(iw); - iw = to_delete.begin(); + del_list.erase(iw); + iw = del_list.begin(); + } + } + + for (iw = add_list.begin(); iw != add_list.end(); iw++) { + if (*iw == this) { + add_list.erase(iw); + iw = add_list.begin(); } } -#endif for (it = timed_events.begin(); it != timed_events.end(); it++) { if (it->w == this) { @@ -414,7 +432,8 @@ void mogltk::widget::fulldraw() { mogltk::ColorP::Min = BLACK; mogltk::ColorP::Min.A = 0; - root->idraw(); + if (root) + root->idraw(); if (!was2D) mogltk::engine::glbase_o->Leave2DMode(); @@ -647,7 +666,9 @@ void mogltk::widget::center(bool cx, bool cy) { } void mogltk::widget::delete_me() { - to_delete.push_back(this); + LOCK; + del_list.push_back(this); + UNLOCK; } @@ -661,7 +682,7 @@ void mogltk::widget::delete_me() { mogltk::widgets::Root::Root(mogltk::shape * sh, mogltk::widgets::drawer * _dr) : widget(0, 0, 0, 0, 0, 0, "Root", sh), dr(_dr) { if (engine::root) - delete engine::root; + engine::root->delete_me(); engine::root = this; } @@ -806,7 +827,7 @@ class SmartBoxCloseAction : public mogltk::widgets::action { public: SmartBoxCloseAction(mogltk::widget * _parent) : parent(_parent) { } virtual void do_action(mogltk::widget *) { - delete parent; + parent->delete_me(); delete this; } private: @@ -890,7 +911,8 @@ void mogltk::widget::mainloop() { int mx, my; while (!end_event_loop && !engine::quitrequested()) { - root->fulldraw(); + if (root) + root->fulldraw(); mx = mogltk::engine::mouseX(); my = mogltk::engine::mouseY(); @@ -904,10 +926,25 @@ void mogltk::widget::mainloop() { engine::base_o->Flip(); widget::check_timed_events(); - for (std::vector<widget *>::iterator i = to_delete.begin(); i != to_delete.end(); i++) { + LOCK; + std::vector<widget *> del_list_copy = del_list; + del_list.clear(); + UNLOCK; + + in_delete_loop = true; + for (std::vector<widget *>::iterator i = del_list_copy.begin(); i != del_list_copy.end(); i++) { delete *i; } - to_delete.clear(); + in_delete_loop = false; + + LOCK; + std::vector<widget *> add_list_copy = add_list; + add_list.clear(); + UNLOCK; + + for (std::vector<widget *>::iterator i = add_list_copy.begin(); i != add_list_copy.end(); i++) { + (*i)->linkme(); + } } delete mouse; |