Monado OpenXR Runtime
Loading...
Searching...
No Matches
oxr_handle_base.h
Go to the documentation of this file.
1// Copyright 2019, Collabora, Ltd.
2// Copyright 2026, Beyley Cardellio
3// SPDX-License-Identifier: BSL-1.0
4/*!
5 * @file
6 * @brief Contains handle-related functions and defines only required in a few
7 * locations.
8 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
9 * @author Beyley Cardellio <ep1cm1n10n123@gmail.com>
10 * @ingroup oxr_main
11 */
12
13#pragma once
14
15#include "../oxr_logger.h"
16
17#include "oxr_handle_array.h"
18
19#include <stdlib.h>
20
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26// Forward declare
27struct oxr_handle_base;
29
30/*!
31 * Function pointer type for a handle destruction function.
32 *
33 * @relates oxr_handle_base
34 */
35typedef XrResult (*oxr_handle_destroyer)(struct oxr_logger *log, struct oxr_handle_base *hb);
36
37/*!
38 * State of a handle base, to reduce likelihood of going "boom" on
39 * out-of-order destruction or other unsavory behavior.
40 *
41 * @ingroup oxr_main
42 */
44{
45 /*! State during/before oxr_handle_init, or after failure */
47
48 /*! State after successful oxr_handle_init */
50
51 /*! State after successful oxr_handle_destroy */
53};
54
55/*!
56 * A single OpenXR handle, which is a child of a parent handle holder, if any.
57 *
58 * Each object referenced by an OpenXR handle should have one of these as its
59 * first element, thus "extending" this class.
60 */
62{
63 //! Magic (per-handle-type) value for debugging.
64 uint64_t debug;
65
66 /*!
67 * Pointer to this object's parent handle holder, if any.
68 */
70
71 /*!
72 * Current handle state.
73 */
75
76 /*!
77 * Destroy the object this handle refers to.
78 */
80};
81
82/*!
83 * Used to hold diverse child handles and ensure orderly destruction.
84 *
85 * @extends oxr_handle_base
86 */
88{
89 struct oxr_handle_base base;
90
91 /*!
92 * Array of children, if any.
93 */
95};
96
97
98/*!
99 * Initialize a handle, and if a parent is specified, update its child
100 * list to include this handle.
101 *
102 * @protected @memberof oxr_handle_base
103 */
104XrResult
106 struct oxr_handle_base *hb,
107 uint64_t debug,
108 oxr_handle_destroyer destroy,
109 struct oxr_handle_parent_base *parent);
110
111/*!
112 * Initialize a handle holder, and if a parent is specified, update its child
113 * list to include this handle.
114 *
115 * @protected @memberof oxr_handle_parent_base
116 */
117XrResult
119 struct oxr_handle_parent_base *hpb,
120 uint64_t debug,
121 oxr_handle_destroyer destroy,
122 struct oxr_handle_parent_base *parent);
123
124/*!
125 * Destroys a single handle, removing it from its parent if it has one.
126 *
127 * oxr_handle_destroy wraps this to provide some extra output and start `level`
128 * at 0. `level`, which is reported in debug output, is the current depth of
129 * recursion.
130 *
131 * @protected @memberof oxr_handle_base
132 */
133XrResult
134oxr_handle_destroy_internal(struct oxr_logger *log, struct oxr_handle_base *hb, int level);
135
136/*!
137 * Recursively destroys a handle and all of its children, removing it from its parent if it has one.
138 *
139 * oxr_handle_parent_destroy wraps this to provide some extra output and start `level`
140 * at 0. `level`, which is reported in debug output, is the current depth of
141 * recursion.
142 *
143 * @protected @memberof oxr_handle_parent_base
144 */
145XrResult
146oxr_handle_parent_destroy_internal(struct oxr_logger *log, struct oxr_handle_parent_base *hpb, int level);
147
148/*!
149 * Allocate some memory for use as a handle, and initialize it as a handle.
150 *
151 * Mainly for internal use - use OXR_ALLOCATE_HANDLE instead which wraps this.
152 *
153 * @relates oxr_handle_base
154 */
155XrResult
157 size_t size,
158 uint64_t debug,
159 oxr_handle_destroyer destroy,
160 struct oxr_handle_parent_base *parent,
161 void **out);
162
163/*!
164 * Allocate some memory for use as a handle holder, and initialize it as a handle holder.
165 *
166 * Mainly for internal use - use OXR_ALLOCATE_HANDLE_PARENT instead which wraps this.
167 *
168 * @relates oxr_handle_parent_base
169 */
170XrResult
172 size_t size,
173 uint64_t debug,
174 oxr_handle_destroyer destroy,
175 struct oxr_handle_parent_base *parent,
176 void **out);
177
178/*!
179 * Destroy the handle's object.
180 *
181 * This should be how all handle-associated objects are destroyed.
182 *
183 * @public @memberof oxr_handle_base
184 */
185XrResult
186oxr_handle_destroy(struct oxr_logger *log, struct oxr_handle_base *hb);
187
188/*!
189 * Destroy the handle's object, as well as all child handles recursively.
190 *
191 * This should be how all handle-associated objects are destroyed.
192 *
193 * @public @memberof oxr_handle_parent_base
194 */
195XrResult
196oxr_handle_parent_destroy(struct oxr_logger *log, struct oxr_handle_parent_base *hpb);
197
198/*!
199 * Returns a human-readable label for a handle state.
200 *
201 * @relates oxr_handle_base
202 */
203const char *
204oxr_handle_state_to_string(enum oxr_handle_state state);
205
206/*!
207 * Allocates memory for a handle and evaluates to an XrResult.
208 *
209 * @param LOG pointer to struct oxr_logger
210 * @param OUT the pointer to handle struct type you already created.
211 * @param DEBUG Magic per-type debugging constant
212 * @param DESTROY Handle destructor function
213 * @param PARENT a parent handle, if any
214 *
215 * Use when you want to do something other than immediately returning in case of
216 * failure. If returning immediately is OK, see OXR_ALLOCATE_HANDLE_OR_RETURN().
217 *
218 * @relates oxr_handle_base
219 */
220#define OXR_ALLOCATE_HANDLE(LOG, OUT, DEBUG, DESTROY, PARENT) \
221 oxr_handle_allocate_and_init(LOG, sizeof(*OUT), DEBUG, DESTROY, PARENT, (void **)&OUT)
222
223/*!
224 * Allocates memory for a handle holder and evaluates to an XrResult.
225 *
226 * @param LOG pointer to struct oxr_logger
227 * @param OUT the pointer to handle struct type you already created.
228 * @param DEBUG Magic per-type debugging constant
229 * @param DESTROY Handle destructor function
230 * @param PARENT a parent handle, if any
231 *
232 * Use when you want to do something other than immediately returning in case of
233 * failure. If returning immediately is OK, see OXR_ALLOCATE_HANDLE_PARENT_OR_RETURN().
234 *
235 * @relates oxr_handle_parent_base
236 */
237#define OXR_ALLOCATE_HANDLE_PARENT(LOG, OUT, DEBUG, DESTROY, PARENT) \
238 oxr_handle_parent_allocate_and_init(LOG, sizeof(*OUT), DEBUG, DESTROY, PARENT, (void **)&OUT)
239
240#ifdef XRT_TYPEOF
241#define ASSERT_HANDLE_TYPE(OUT, TYPE, HANDLE_TYPE) \
242 do { \
243 static_assert(offsetof(XRT_TYPEOF(*OUT), handle) == 0, \
244 "OUT must have a field 'handle' of type struct oxr_handle_base"); \
245 static_assert(sizeof(((XRT_TYPEOF(*OUT) *)0)->handle) == sizeof(HANDLE_TYPE), \
246 "OUT must have a field 'handle' of type struct oxr_handle_base"); \
247 } while (0)
248#else
249/* No-op, no static assert available */
250#define ASSERT_HANDLE_TYPE(OUT, TYPE, HANDLE_TYPE) \
251 do { \
252 } while (0)
253#endif
254
255/*!
256 * Allocate memory for a handle, returning in case of failure.
257 *
258 * @param LOG pointer to struct oxr_logger
259 * @param OUT the pointer to handle struct type you already created.
260 * @param DEBUG Magic per-type debugging constant
261 * @param DESTROY Handle destructor function
262 * @param PARENT a parent handle, if any
263 *
264 * Will return an XrResult from the current function if something fails.
265 * If that's not OK, see OXR_ALLOCATE_HANDLE().
266 *
267 * @relates oxr_handle_base
268 */
269#define OXR_ALLOCATE_HANDLE_OR_RETURN(LOG, OUT, DEBUG, DESTROY, PARENT) \
270 do { \
271 /* static assert that out has field 'handle' of type struct oxr_handle_base */ \
272 ASSERT_HANDLE_TYPE(OUT, typeof(*OUT), struct oxr_handle_base); \
273 XrResult allocResult = OXR_ALLOCATE_HANDLE(LOG, OUT, DEBUG, DESTROY, PARENT); \
274 if (allocResult != XR_SUCCESS) { \
275 return allocResult; \
276 } \
277 } while (0)
278
279/*!
280 * Allocate memory for a handle holder, returning in case of failure.
281 *
282 * @param LOG pointer to struct oxr_logger
283 * @param OUT the pointer to handle struct type you already created.
284 * @param DEBUG Magic per-type debugging constant
285 * @param DESTROY Handle destructor function
286 * @param PARENT a parent handle, if any
287 *
288 * Will return an XrResult from the current function if something fails.
289 * If that's not OK, see OXR_ALLOCATE_HANDLE_PARENT().
290 *
291 * @relates oxr_handle_parent_base
292 */
293#define OXR_ALLOCATE_HANDLE_PARENT_OR_RETURN(LOG, OUT, DEBUG, DESTROY, PARENT) \
294 do { \
295 /* static assert that out has field 'handle' of type struct oxr_handle_parent_base */ \
296 ASSERT_HANDLE_TYPE(OUT, typeof(*OUT), struct oxr_handle_parent_base); \
297 XrResult allocResult = OXR_ALLOCATE_HANDLE_PARENT(LOG, OUT, DEBUG, DESTROY, PARENT); \
298 if (allocResult != XR_SUCCESS) { \
299 return allocResult; \
300 } \
301 } while (0)
302
303#ifdef __cplusplus
304}
305#endif
oxr_handle_state
State of a handle base, to reduce likelihood of going "boom" on out-of-order destruction or other uns...
Definition oxr_handle_base.h:44
@ OXR_HANDLE_STATE_DESTROYED
State after successful oxr_handle_destroy.
Definition oxr_handle_base.h:52
@ OXR_HANDLE_STATE_LIVE
State after successful oxr_handle_init.
Definition oxr_handle_base.h:49
@ OXR_HANDLE_STATE_UNINITIALIZED
State during/before oxr_handle_init, or after failure.
Definition oxr_handle_base.h:46
A dynamic array of handles.
Manages an array of handles, does not have a init function but must be zero initialized where it is d...
Definition oxr_handle_array.h:21
A single OpenXR handle, which is a child of a parent handle holder, if any.
Definition oxr_handle_base.h:62
XrResult oxr_handle_allocate_and_init(struct oxr_logger *log, size_t size, uint64_t debug, oxr_handle_destroyer destroy, struct oxr_handle_parent_base *parent, void **out)
Allocate some memory for use as a handle, and initialize it as a handle.
uint64_t debug
Magic (per-handle-type) value for debugging.
Definition oxr_handle_base.h:64
enum oxr_handle_state state
Current handle state.
Definition oxr_handle_base.h:74
struct oxr_handle_parent_base * parent
Pointer to this object's parent handle holder, if any.
Definition oxr_handle_base.h:69
XrResult(* oxr_handle_destroyer)(struct oxr_logger *log, struct oxr_handle_base *hb)
Function pointer type for a handle destruction function.
Definition oxr_handle_base.h:35
oxr_handle_destroyer destroy
Destroy the object this handle refers to.
Definition oxr_handle_base.h:79
XrResult oxr_handle_init(struct oxr_logger *log, struct oxr_handle_base *hb, uint64_t debug, oxr_handle_destroyer destroy, struct oxr_handle_parent_base *parent)
Initialize a handle, and if a parent is specified, update its child list to include this handle.
Used to hold diverse child handles and ensure orderly destruction.
Definition oxr_handle_base.h:88
XrResult oxr_handle_parent_init(struct oxr_logger *log, struct oxr_handle_parent_base *hpb, uint64_t debug, oxr_handle_destroyer destroy, struct oxr_handle_parent_base *parent)
Initialize a handle holder, and if a parent is specified, update its child list to include this handl...
struct oxr_handle_array children
Array of children, if any.
Definition oxr_handle_base.h:94
XrResult oxr_handle_parent_allocate_and_init(struct oxr_logger *log, size_t size, uint64_t debug, oxr_handle_destroyer destroy, struct oxr_handle_parent_base *parent, void **out)
Allocate some memory for use as a handle holder, and initialize it as a handle holder.
Logger struct that lives on the stack, one for each call client call.
Definition oxr_logger.h:44