2 * Copyright 2002, The libsigc++ Development Team
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <sigc++/trackable.h>
25 trackable::trackable() noexcept
26 : callback_list_(nullptr)
29 /* Don't copy the notification list.
30 The objects watching src don't need to be notified when the new object dies. */
31 trackable::trackable(const trackable& /*src*/) noexcept
32 : callback_list_(nullptr)
35 // Don't move the notification list.
36 // The objects watching src don't need to be notified when the new object dies.
37 // They need to be notified now, because src probably becomes useless.
39 // If trackable's move constructor is modified, check if Glib::Object's
40 // move constructor should be modified similarly.
41 trackable::trackable(trackable&& src)
42 : callback_list_(nullptr)
44 src.notify_callbacks();
47 trackable& trackable::operator=(const trackable& src)
50 notify_callbacks(); //Make sure that we have finished with existing stuff before replacing it.
55 trackable& trackable::operator=(trackable&& src)
59 notify_callbacks(); //Make sure that we have finished with existing stuff before replacing it.
60 src.notify_callbacks(); // src probably becomes useless.
65 trackable::~trackable()
70 void trackable::add_destroy_notify_callback(void* data, func_destroy_notify func) const
72 callback_list()->add_callback(data, func);
75 void trackable::remove_destroy_notify_callback(void* data) const
77 callback_list()->remove_callback(data);
80 void trackable::notify_callbacks()
83 delete callback_list_; //This invokes all of the callbacks.
85 callback_list_ = nullptr;
88 internal::trackable_callback_list* trackable::callback_list() const
91 callback_list_ = new internal::trackable_callback_list;
93 return callback_list_;
100 trackable_callback_list::~trackable_callback_list()
104 for (auto& callback : callbacks_)
106 callback.func_(callback.data_);
109 void trackable_callback_list::add_callback(void* data, func_destroy_notify func)
111 if (!clearing_) // TODO: Is it okay to silently ignore attempts to add dependencies when the list is being cleared?
112 // I'd consider this a serious application bug, since the app is likely to segfault.
113 // But then, how should we handle it? Throw an exception? Martin.
114 callbacks_.push_back(trackable_callback(data, func));
117 void trackable_callback_list::clear()
121 for (auto& callback : callbacks_)
123 callback.func_(callback.data_);
130 void trackable_callback_list::remove_callback(void* data)
132 for (callback_list::iterator i = callbacks_.begin(); i != callbacks_.end(); ++i)
135 if (callback.data_ == data && callback.func_ != nullptr)
137 //Don't remove a list element while the list is being cleared.
138 //It could invalidate the iterator in ~trackable_callback_list() or clear().
139 //But it may be necessary to invalidate the callback. See bug 589202.
141 callback.func_ = nullptr;
149 } /* namespace internal */
151 } /* namespace sigc */