My Project
Loading...
Searching...
No Matches
GObjectMemory.h
1/*
2 * Copyright (C) 2013-2017 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Jussi Pakkanen <jussi.pakkanen@canonical.com>
17 * Pete Woods <pete.woods@canonical.com>
18 */
19
20#ifndef UNITY_UTIL_GOBJECTMEMORY_H
21#define UNITY_UTIL_GOBJECTMEMORY_H
22
23#include <memory>
24#include <stdexcept>
25#include <glib-object.h>
26
27#include <unity/util/ResourcePtr.h>
28
29namespace unity
30{
31
32namespace util
33{
34
35namespace
36{
37
38inline static void check_floating_gobject(gpointer t)
39{
40 if (G_IS_OBJECT(t) && g_object_is_floating(G_OBJECT(t)))
41 {
42 throw std::invalid_argument("cannot manage floating GObject reference - call g_object_ref_sink(o) first");
43 }
44}
45
46}
47
61{
62 void operator()(gpointer ptr) noexcept
63 {
64 if (G_IS_OBJECT(ptr))
65 {
66 g_object_unref(ptr);
67 }
68 }
69};
70
71template<typename T> using GObjectSPtr = std::shared_ptr<T>;
72template<typename T> using GObjectUPtr = std::unique_ptr<T, GObjectDeleter>;
73
74namespace internal
75{
76
77template<typename SP>
78class GObjectAssigner
79{
80public:
81 typedef typename SP::element_type ElementType;
82
83 GObjectAssigner(SP& smart_ptr) noexcept:
84 smart_ptr_(smart_ptr)
85 {
86 }
87
88 GObjectAssigner(const GObjectAssigner& other) = delete;
89
90 GObjectAssigner(GObjectAssigner&& other) noexcept:
91 ptr_(other.ptr_), smart_ptr_(other.smart_ptr_)
92 {
93 other.ptr_ = nullptr;
94 }
95
96 ~GObjectAssigner() noexcept
97 {
98 smart_ptr_ = SP(ptr_, GObjectDeleter());
99 }
100
101 GObjectAssigner& operator=(const GObjectAssigner& other) = delete;
102
103 operator ElementType**() noexcept
104 {
105 return &ptr_;
106 }
107
108private:
109 ElementType* ptr_ = nullptr;
110
111 SP& smart_ptr_;
112};
113
114template <typename T>
115struct GObjectSignalUnsubscriber
116{
117 void operator()(gulong handle) noexcept
118 {
119 if (handle != 0 && G_IS_OBJECT(obj_.get()))
120 {
121 g_signal_handler_disconnect(obj_.get(), handle);
122 }
123 }
124
125 GObjectSPtr<T> obj_;
126};
127
128}
129
142template<typename T>
143inline GObjectUPtr<T> unique_gobject(T* ptr)
144{
145 check_floating_gobject(ptr);
146 GObjectDeleter d;
147 return GObjectUPtr<T>(ptr, d);
148}
149
162template<typename T>
163inline GObjectSPtr<T> share_gobject(T* ptr)
164{
165 check_floating_gobject(ptr);
166 GObjectDeleter d;
167 return GObjectSPtr<T>(ptr, d);
168}
169
180template<typename T, typename ... Args>
181inline GObjectUPtr<T> make_gobject(GType object_type, const gchar *first_property_name, Args&&... args) noexcept
182{
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))
185 {
186 g_object_ref_sink(ptr);
187 }
188 return unique_gobject(G_TYPE_CHECK_INSTANCE_CAST(ptr, object_type, T));
189}
190
200template<typename SP>
201inline internal::GObjectAssigner<SP> assign_gobject(SP& smart_ptr) noexcept
202{
203 return internal::GObjectAssigner<SP>(smart_ptr);
204}
205
206template<typename T>
207using GObjectSignalConnection = ResourcePtr<gulong, internal::GObjectSignalUnsubscriber<T>>;
208
218template <typename T>
219inline GObjectSignalConnection<T> gobject_signal_connection(gulong id, const GObjectSPtr<T>& obj)
220{
221 return GObjectSignalConnection<T>(id, internal::GObjectSignalUnsubscriber<T>{obj});
222}
223
224} // namespace until
225
226} // namespace unity
227
228#endif
Top-level namespace for all things Unity-related.
Definition: Version.h:38
Used by the make_gobject, unique_gobject and share_gobject as the deleter.
Definition: GObjectMemory.h:61