summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2006-02-01 18:32:25 +0000
committerpixel <pixel>2006-02-01 18:32:25 +0000
commitaac581d00d4efa8c3b03fd802f22457d4127e23f (patch)
treee71267006aa6cd3e7a7e314d8e4ee5c4d367288e
parent97b4a5904a989e216b1fbb4d0a55b7340bd7f88a (diff)
Adding widgets new/delete scheduling - avoiding multithreading glitches.
-rw-r--r--include/widgets.h11
-rw-r--r--lib/widgets.cc75
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;