38
void SignalBase::Disconnect()
38
bool SignalBase::Disconnect()
40
bool disconnected = false;
40
42
if (connection_id_ && G_IS_OBJECT(object_))
42
44
g_signal_handler_disconnect(object_, connection_id_);
43
45
g_object_remove_weak_pointer(object_, reinterpret_cast<gpointer*>(&object_));
47
50
connection_id_ = 0;
54
bool SignalBase::Block() const
58
if (connection_id_ && G_IS_OBJECT(object_))
60
g_signal_handler_block(object_, connection_id_);
67
bool SignalBase::Unblock() const
69
bool unblocked = false;
71
if (connection_id_ && G_IS_OBJECT(object_))
73
g_signal_handler_unblock(object_, connection_id_);
50
80
GObject* SignalBase::object() const
75
105
// was too messy to try and write a copy constructor/operator that would steal
76
106
// from "other" and make the new one the owner. Not only did it create
77
107
// opportunity for random bugs, it also made the API bad.
78
void SignalManager::Add(SignalBase* signal)
108
SignalBase::Ptr SignalManager::Add(SignalBase* signal)
80
Add(SignalBase::Ptr(signal));
110
return Add(SignalBase::Ptr(signal));
83
void SignalManager::Add(SignalBase::Ptr const& signal)
113
SignalBase::Ptr SignalManager::Add(SignalBase::Ptr const& signal)
85
115
connections_.push_back(signal);
86
116
g_object_weak_ref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this);
89
void SignalManager::OnObjectDestroyed(SignalManager* self, GObject* old_obj)
91
for (auto it = self->connections_.begin(); it != self->connections_.end();)
93
auto const& signal = *it;
95
// When an object has been destroyed, the signal member is nullified,
96
// so at this point we can be sure that removing signal with a null object,
97
// means removing invalid signals.
98
if (!signal->object())
100
it = self->connections_.erase(it);
109
120
// This uses void* to keep in line with the g_signal* functions
110
121
// (it allows you to pass in a GObject without casting up).
111
void SignalManager::Disconnect(void* object, std::string const& signal_name)
122
bool SignalManager::ForeachMatchedSignal(void* object, std::string const& signal_name, std::function<void(SignalBase::Ptr const&)> action, bool erase_after)
113
bool all_signals = signal_name.empty();
124
bool action_performed = false;
125
bool all_objects = (object == reinterpret_cast<void*>(std::numeric_limits<uintptr_t>::max()));
126
bool all_signals = all_objects || signal_name.empty();
115
128
for (auto it = connections_.begin(); it != connections_.end();)
117
130
auto const& signal = *it;
119
if (signal->object() == object && (all_signals || signal->name() == signal_name))
132
if ((all_objects || signal->object() == object) && (all_signals || signal->name() == signal_name))
121
g_object_weak_unref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this);
122
it = connections_.erase(it);
136
action_performed = true;
140
it = erase_after ? connections_.erase(it) : ++it;
148
return action_performed;
151
void SignalManager::OnObjectDestroyed(SignalManager* self, GObject* old_obj)
153
self->ForeachMatchedSignal(nullptr, "", nullptr, /*erase_after*/ true);
156
bool SignalManager::Block(void* object, std::string const& signal_name)
158
return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) {
163
bool SignalManager::Unblock(void* object, std::string const& signal_name)
165
return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) {
170
bool SignalManager::Disconnect(void* object, std::string const& signal_name)
172
return ForeachMatchedSignal(object, signal_name, [this] (SignalBase::Ptr const& signal) {
173
g_object_weak_unref(signal->object(), (GWeakNotify)&OnObjectDestroyed, this);