summaryrefslogtreecommitdiff
path: root/libs/sigc++2/sigc++/trackable.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/sigc++2/sigc++/trackable.cc')
-rw-r--r--libs/sigc++2/sigc++/trackable.cc124
1 files changed, 124 insertions, 0 deletions
diff --git a/libs/sigc++2/sigc++/trackable.cc b/libs/sigc++2/sigc++/trackable.cc
new file mode 100644
index 0000000000..46e2592ffb
--- /dev/null
+++ b/libs/sigc++2/sigc++/trackable.cc
@@ -0,0 +1,124 @@
+// -*- c++ -*-
+/*
+ * Copyright 2002, The libsigc++ Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <sigc++/trackable.h>
+#include <iostream>
+using namespace std;
+
+namespace sigc
+{
+
+trackable::trackable()
+: callback_list_(0)
+{}
+
+/* Don't copy the notification list.
+ The objects watching src don't need to be notified when the new object dies. */
+trackable::trackable(const trackable& /*src*/)
+: callback_list_(0)
+{}
+
+trackable& trackable::operator=(const trackable& src)
+{
+ if(this != &src)
+ notify_callbacks(); //Make sure that we have finished with existing stuff before replacing it.
+
+ return *this;
+}
+
+trackable::~trackable()
+{
+ notify_callbacks();
+}
+
+void trackable::add_destroy_notify_callback(void* data, func_destroy_notify func) const
+{
+ callback_list()->add_callback(data, func);
+}
+
+void trackable::remove_destroy_notify_callback(void* data) const
+{
+ callback_list()->remove_callback(data);
+}
+
+void trackable::notify_callbacks()
+{
+ if (callback_list_)
+ delete callback_list_; //This invokes all of the callbacks.
+
+ callback_list_ = 0;
+}
+
+internal::trackable_callback_list* trackable::callback_list() const
+{
+ if (!callback_list_)
+ callback_list_ = new internal::trackable_callback_list;
+
+ return callback_list_;
+}
+
+
+namespace internal
+{
+
+trackable_callback_list::~trackable_callback_list()
+{
+ clearing_ = true;
+
+ for (callback_list::iterator i = callbacks_.begin(); i != callbacks_.end(); ++i)
+ (*i).func_((*i).data_);
+}
+
+void trackable_callback_list::add_callback(void* data, func_destroy_notify func)
+{
+ if (!clearing_) // TODO: Is it okay to silently ignore attempts to add dependencies when the list is being cleared?
+ // I'd consider this a serious application bug, since the app is likely to segfault.
+ // But then, how should we handle it? Throw an exception? Martin.
+ callbacks_.push_back(trackable_callback(data, func));
+}
+
+void trackable_callback_list::clear()
+{
+ clearing_ = true;
+
+ for (callback_list::iterator i = callbacks_.begin(); i != callbacks_.end(); ++i)
+ (*i).func_((*i).data_);
+
+ callbacks_.clear();
+
+ clearing_ = false;
+}
+
+void trackable_callback_list::remove_callback(void* data)
+{
+ if (clearing_) return; // No circular notices
+
+ for (callback_list::iterator i = callbacks_.begin(); i != callbacks_.end(); ++i)
+ if ((*i).data_ == data)
+ {
+ callbacks_.erase(i);
+ return;
+ }
+}
+
+} /* namespace internal */
+
+
+} /* namespace sigc */