1 /* ide-foundry-compat.c
2 *
3 * Copyright 2018-2019 Christian Hergert <chergert@redhat.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21 #define G_LOG_DOMAIN "ide-foundry-compat"
22
23 #include "config.h"
24
25 #include "ide-build-manager.h"
26 #include "ide-build-system.h"
27 #include "ide-device-manager.h"
28 #include "ide-config-manager.h"
29 #include "ide-foundry-compat.h"
30 #include "ide-run-manager.h"
31 #include "ide-runtime-manager.h"
32 #include "ide-test-manager.h"
33 #include "ide-toolchain-manager.h"
34
35 static gpointer
ensure_child_typed_borrowed(IdeContext * context,GType child_type)36 ensure_child_typed_borrowed (IdeContext *context,
37 GType child_type)
38 {
39 gpointer ret;
40
41 if (!IDE_IS_MAIN_THREAD ())
42 {
43 IDE_BACKTRACE;
44
45 g_error ("A plugin has attempted to access child of type %s on a thread without referencing. "
46 "This is not allowed and the application will terminate.",
47 g_type_name (child_type));
48 }
49
50 g_assert (IDE_IS_MAIN_THREAD ());
51 g_assert (IDE_IS_CONTEXT (context));
52
53 if (!(ret = ide_context_peek_child_typed (context, child_type)))
54 {
55 g_autoptr(IdeObject) child = NULL;
56
57 if (!ide_context_has_project (context))
58 {
59 g_critical ("A plugin has attempted to access the %s foundry subsystem before a project has been loaded. "
60 "This is not supported and may cause undesired behavior.",
61 g_type_name (child_type));
62 }
63
64 child = ide_object_ensure_child_typed (IDE_OBJECT (context), child_type);
65 ret = ide_context_peek_child_typed (context, child_type);
66 }
67
68 return ret;
69 }
70
71 static gpointer
get_child_typed_borrowed(IdeContext * context,GType child_type)72 get_child_typed_borrowed (IdeContext *context,
73 GType child_type)
74 {
75 GObject *ret;
76
77 g_assert (IDE_IS_MAIN_THREAD ());
78 g_assert (IDE_IS_CONTEXT (context));
79
80 /* We get a full ref to the child, but we want to return a borrowed
81 * reference to the manager. Since we're on the main thread, we can
82 * guarantee that no destroy will happen (since that has to happen
83 * in the main thread).
84 */
85 if ((ret = ide_object_get_child_typed (IDE_OBJECT (context), child_type)))
86 g_object_unref (ret);
87
88 return ret;
89 }
90
91 /**
92 * ide_build_manager_from_context:
93 * @context: a #IdeContext
94 *
95 * Returns: (transfer none): an #IdeBuildManager
96 *
97 * Since: 3.32
98 */
99 IdeBuildManager *
ide_build_manager_from_context(IdeContext * context)100 ide_build_manager_from_context (IdeContext *context)
101 {
102 g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
103
104 return ensure_child_typed_borrowed (context, IDE_TYPE_BUILD_MANAGER);
105 }
106
107 /**
108 * ide_build_manager_ref_from_context:
109 * @context: a #IdeContext
110 *
111 * Returns: (transfer full): an #IdeBuildManager
112 *
113 * Since: 3.32
114 */
115 IdeBuildManager *
ide_build_manager_ref_from_context(IdeContext * context)116 ide_build_manager_ref_from_context (IdeContext *context)
117 {
118 g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
119
120 return ide_object_ensure_child_typed (IDE_OBJECT (context), IDE_TYPE_BUILD_MANAGER);
121 }
122
123 /**
124 * ide_build_system_from_context:
125 * @context: a #IdeContext
126 *
127 * Gets the build system for the context. If no build system has been
128 * registered, then this returns %NULL.
129 *
130 * Returns: (transfer none) (nullable): an #IdeBuildSystem
131 *
132 * Since: 3.32
133 */
134 IdeBuildSystem *
ide_build_system_from_context(IdeContext * context)135 ide_build_system_from_context (IdeContext *context)
136 {
137 g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
138
139 return get_child_typed_borrowed (context, IDE_TYPE_BUILD_SYSTEM);
140 }
141
142 /**
143 * ide_config_manager_from_context:
144 * @context: a #IdeContext
145 *
146 * Returns: (transfer none): an #IdeConfigManager
147 *
148 * Since: 3.32
149 */
150 IdeConfigManager *
ide_config_manager_from_context(IdeContext * context)151 ide_config_manager_from_context (IdeContext *context)
152 {
153 g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
154
155 return ensure_child_typed_borrowed (context, IDE_TYPE_CONFIG_MANAGER);
156 }
157
158 /**
159 * ide_device_manager_from_context:
160 * @context: a #IdeContext
161 *
162 * Returns: (transfer none): an #IdeDeviceManager
163 *
164 * Since: 3.32
165 */
166 IdeDeviceManager *
ide_device_manager_from_context(IdeContext * context)167 ide_device_manager_from_context (IdeContext *context)
168 {
169 g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
170
171 return ensure_child_typed_borrowed (context, IDE_TYPE_DEVICE_MANAGER);
172 }
173
174 /**
175 * ide_toolchain_manager_from_context:
176 * @context: a #IdeContext
177 *
178 * Returns: (transfer none): an #IdeToolchainManager
179 *
180 * Since: 3.32
181 */
182 IdeToolchainManager *
ide_toolchain_manager_from_context(IdeContext * context)183 ide_toolchain_manager_from_context (IdeContext *context)
184 {
185 g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
186
187 return ensure_child_typed_borrowed (context, IDE_TYPE_TOOLCHAIN_MANAGER);
188 }
189
190 /**
191 * ide_run_manager_from_context:
192 * @context: a #IdeContext
193 *
194 * Returns: (transfer none): an #IdeRunManager
195 *
196 * Since: 3.32
197 */
198 IdeRunManager *
ide_run_manager_from_context(IdeContext * context)199 ide_run_manager_from_context (IdeContext *context)
200 {
201 g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
202
203 return ensure_child_typed_borrowed (context, IDE_TYPE_RUN_MANAGER);
204 }
205
206 /**
207 * ide_runtime_manager_from_context:
208 * @context: a #IdeContext
209 *
210 * Returns: (transfer none): an #IdeRuntimeManager
211 *
212 * Since: 3.32
213 */
214 IdeRuntimeManager *
ide_runtime_manager_from_context(IdeContext * context)215 ide_runtime_manager_from_context (IdeContext *context)
216 {
217 g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
218
219 return ensure_child_typed_borrowed (context, IDE_TYPE_RUNTIME_MANAGER);
220 }
221
222 /**
223 * ide_test_manager_from_context:
224 * @context: a #IdeContext
225 *
226 * Returns: (transfer none): an #IdeTestManager
227 *
228 * Since: 3.32
229 */
230 IdeTestManager *
ide_test_manager_from_context(IdeContext * context)231 ide_test_manager_from_context (IdeContext *context)
232 {
233 g_return_val_if_fail (IDE_IS_CONTEXT (context), NULL);
234
235 return ensure_child_typed_borrowed (context, IDE_TYPE_TEST_MANAGER);
236 }
237