20 #ifndef UNITY_UTIL_GOBJECTMEMORY_H
21 #define UNITY_UTIL_GOBJECTMEMORY_H
25 #include <glib-object.h>
27 #include <unity/util/ResourcePtr.h>
38 inline static void check_floating_gobject(gpointer t)
40 if (G_IS_OBJECT(t) && g_object_is_floating(G_OBJECT(t)))
42 throw std::invalid_argument(
"cannot manage floating GObject reference - call g_object_ref_sink(o) first");
62 void operator()(gpointer ptr) noexcept
71 template<
typename T>
using GObjectSPtr = std::shared_ptr<T>;
72 template<
typename T>
using GObjectUPtr = std::unique_ptr<T, GObjectDeleter>;
81 typedef typename SP::element_type ElementType;
83 GObjectAssigner(SP& smart_ptr) noexcept:
88 GObjectAssigner(
const GObjectAssigner& other) =
delete;
90 GObjectAssigner(GObjectAssigner&& other) noexcept:
91 ptr_(other.ptr_), smart_ptr_(other.smart_ptr_)
96 ~GObjectAssigner() noexcept
98 smart_ptr_ = SP(ptr_, GObjectDeleter());
101 GObjectAssigner& operator=(
const GObjectAssigner& other) =
delete;
103 operator ElementType**() noexcept
109 ElementType* ptr_ =
nullptr;
114 template <
typename T>
115 struct GObjectSignalUnsubscriber
117 void operator()(gulong handle) noexcept
119 if (handle != 0 && G_IS_OBJECT(obj_.get()))
121 g_signal_handler_disconnect(obj_.get(), handle);
143 inline GObjectUPtr<T> unique_gobject(T* ptr)
145 check_floating_gobject(ptr);
147 return GObjectUPtr<T>(ptr, d);
163 inline GObjectSPtr<T> share_gobject(T* ptr)
165 check_floating_gobject(ptr);
167 return GObjectSPtr<T>(ptr, d);
180 template<
typename T,
typename ... Args>
181 inline GObjectUPtr<T> make_gobject(GType object_type,
const gchar *first_property_name, Args&&... args) noexcept
183 gpointer ptr = g_object_new(object_type, first_property_name, std::forward<Args>(args)...);
184 if (G_IS_OBJECT(ptr) && g_object_is_floating(ptr))
186 g_object_ref_sink(ptr);
188 return unique_gobject(G_TYPE_CHECK_INSTANCE_CAST(ptr, object_type, T));
200 template<
typename SP>
201 inline internal::GObjectAssigner<SP> assign_gobject(SP& smart_ptr) noexcept
203 return internal::GObjectAssigner<SP>(smart_ptr);
207 using GObjectSignalConnection = ResourcePtr<gulong, internal::GObjectSignalUnsubscriber<T>>;
218 template <
typename T>
219 inline GObjectSignalConnection<T> gobject_signal_connection(gulong
id,
const GObjectSPtr<T>& obj)
221 return GObjectSignalConnection<T>(
id, internal::GObjectSignalUnsubscriber<T>{obj});