Blender V5.0
wm_xr_actionmap.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13#include <cmath>
14#include <cstring>
15
16#include "BKE_idprop.hh"
17
18#include "BLI_listbase.h"
19#include "BLI_string_utf8.h"
20
21#include "MEM_guardedalloc.h"
22
23#include "WM_api.hh"
24#include "WM_types.hh"
25
26#include "wm_xr_intern.hh"
27
28#define WM_XR_ACTIONMAP_STR_DEFAULT "actionmap"
29#define WM_XR_ACTIONMAP_ITEM_STR_DEFAULT "action"
30#define WM_XR_ACTIONMAP_BINDING_STR_DEFAULT "binding"
31
32/* -------------------------------------------------------------------- */
37
39 const char *name,
40 bool replace_existing)
41{
43 if (amb_prev && replace_existing) {
44 return amb_prev;
45 }
46
48 STRNCPY_UTF8(amb->name, name);
49 if (amb_prev) {
51 }
52
53 BLI_addtail(&ami->bindings, amb);
54
55 /* Set non-zero threshold by default. */
56 amb->float_threshold = 0.3f;
57
58 return amb;
59}
60
62 const char *name,
63 XrActionMapBinding *ambexcept)
64{
66 if (STREQLEN(name, amb->name, MAX_NAME) && (amb != ambexcept)) {
67 return amb;
68 }
69 }
70 return nullptr;
71}
72
74{
75 char name[MAX_NAME];
76 char *suffix;
77 size_t baselen;
78 size_t idx = 0;
79
80 baselen = STRNCPY_UTF8_RLEN(name, amb->name);
81 suffix = &name[baselen];
82
83 while (wm_xr_actionmap_binding_find_except(ami, name, amb)) {
84 if ((baselen + 1) + (log10(++idx) + 1) > MAX_NAME) {
85 /* Use default base name. */
87 suffix = &name[baselen];
88 idx = 0;
89 }
90 else {
91 BLI_snprintf_utf8(suffix, MAX_NAME, "%zu", idx);
92 }
93 }
94
95 STRNCPY_UTF8(amb->name, name);
96}
97
99{
100 XrActionMapBinding *amb_dst = static_cast<XrActionMapBinding *>(MEM_dupallocN(amb_src));
101 amb_dst->prev = amb_dst->next = nullptr;
102
105 XrComponentPath *path_new = static_cast<XrComponentPath *>(MEM_dupallocN(path));
106 BLI_addtail(&amb_dst->component_paths, path_new);
107 }
108
109 return amb_dst;
110}
111
113 XrActionMapBinding *amb_src)
114{
116
118
119 BLI_addtail(&ami->bindings, amb_dst);
120
121 return amb_dst;
122}
123
128
130{
131 int idx = BLI_findindex(&ami->bindings, amb);
132
133 if (idx != -1) {
135 BLI_freelinkN(&ami->bindings, amb);
136
137 if (idx <= ami->selbinding) {
138 if (--ami->selbinding < 0) {
139 ami->selbinding = 0;
140 }
141 }
142
143 return true;
144 }
145
146 return false;
147}
148
150{
152 if (STREQLEN(name, amb->name, MAX_NAME)) {
153 return amb;
154 }
155 }
156 return nullptr;
157}
158
160
161/* -------------------------------------------------------------------- */
166
172
174{
175 if (ami->op_properties_ptr) {
177 MEM_delete(ami->op_properties_ptr);
178 ami->op_properties_ptr = nullptr;
179 ami->op_properties = nullptr;
180 }
181 else {
182 BLI_assert(ami->op_properties == nullptr);
183 }
184}
185
198
200{
201 switch (ami->type) {
202 case XR_BOOLEAN_INPUT:
203 case XR_FLOAT_INPUT:
205 break;
206 case XR_POSE_INPUT:
209 memset(ami->op, 0, sizeof(ami->op));
210 return;
211 }
212
213 if (ami->op[0] == 0) {
215 return;
216 }
217
218 if (ami->op_properties_ptr == nullptr) {
220 }
221 else {
223 if (ot) {
224 if (ot->srna != ami->op_properties_ptr->type) {
225 /* Matches wm_xr_actionmap_item_properties_set() but doesn't alloc new ptr. */
227 if (ami->op_properties) {
229 }
231 }
232 }
233 else {
235 }
236 }
237}
238
240 const char *name,
241 bool replace_existing)
242{
243 XrActionMapItem *ami_prev = WM_xr_actionmap_item_find(actionmap, name);
244 if (ami_prev && replace_existing) {
246 return ami_prev;
247 }
248
250 STRNCPY_UTF8(ami->name, name);
251 if (ami_prev) {
253 }
254
255 BLI_addtail(&actionmap->items, ami);
256
257 /* Set type to float (button) input by default. */
258 ami->type = XR_FLOAT_INPUT;
259
260 return ami;
261}
262
264 const char *name,
265 const XrActionMapItem *amiexcept)
266{
267 LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
268 if (STREQLEN(name, ami->name, MAX_NAME) && (ami != amiexcept)) {
269 return ami;
270 }
271 }
272 return nullptr;
273}
274
276{
277 char name[MAX_NAME];
278 char *suffix;
279 size_t baselen;
280 size_t idx = 0;
281
282 baselen = STRNCPY_UTF8_RLEN(name, ami->name);
283 suffix = &name[baselen];
284
285 while (wm_xr_actionmap_item_find_except(actionmap, name, ami)) {
286 if ((baselen + 1) + (log10(++idx) + 1) > MAX_NAME) {
287 /* Use default base name. */
289 suffix = &name[baselen];
290 idx = 0;
291 }
292 else {
293 BLI_snprintf_utf8(suffix, MAX_NAME, "%zu", idx);
294 }
295 }
296
297 STRNCPY_UTF8(ami->name, name);
298}
299
301{
302 XrActionMapItem *ami_dst = static_cast<XrActionMapItem *>(MEM_dupallocN(ami_src));
303 ami_dst->prev = ami_dst->next = nullptr;
304
305 BLI_listbase_clear(&ami_dst->bindings);
306 LISTBASE_FOREACH (XrActionMapBinding *, amb, &ami_src->bindings) {
308 BLI_addtail(&ami_dst->bindings, amb_new);
309 }
310
311 if (ami_dst->op_properties) {
312 ami_dst->op_properties_ptr = MEM_new<PointerRNA>("wmOpItemPtr");
314 ami_dst->op_properties = IDP_CopyProperty(ami_src->op_properties);
315 ami_dst->op_properties_ptr->data = ami_dst->op_properties;
316 }
317 else {
318 ami_dst->op_properties = nullptr;
319 ami_dst->op_properties_ptr = nullptr;
320 }
321
323 LISTBASE_FOREACH (XrUserPath *, path, &ami_src->user_paths) {
324 XrUserPath *path_new = static_cast<XrUserPath *>(MEM_dupallocN(path));
325 BLI_addtail(&ami_dst->user_paths, path_new);
326 }
327
328 return ami_dst;
329}
330
332{
333 XrActionMapItem *ami_dst = wm_xr_actionmap_item_copy(ami_src);
334
335 WM_xr_actionmap_item_ensure_unique(actionmap, ami_dst);
336
337 BLI_addtail(&actionmap->items, ami_dst);
338
339 return ami_dst;
340}
341
343{
344 int idx = BLI_findindex(&actionmap->items, ami);
345
346 if (idx != -1) {
348 BLI_freelinkN(&actionmap->items, ami);
349
350 if (idx <= actionmap->selitem) {
351 if (--actionmap->selitem < 0) {
352 actionmap->selitem = 0;
353 }
354 }
355
356 return true;
357 }
358
359 return false;
360}
361
363{
364 LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
365 if (STREQLEN(name, ami->name, MAX_NAME)) {
366 return ami;
367 }
368 }
369 return nullptr;
370}
371
373
374/* -------------------------------------------------------------------- */
379
380XrActionMap *WM_xr_actionmap_new(wmXrRuntimeData *runtime, const char *name, bool replace_existing)
381{
382 XrActionMap *am_prev = WM_xr_actionmap_find(runtime, name);
383 if (am_prev && replace_existing) {
384 WM_xr_actionmap_clear(am_prev);
385 return am_prev;
386 }
387
389 STRNCPY_UTF8(am->name, name);
390 if (am_prev) {
392 }
393
394 BLI_addtail(&runtime->actionmaps, am);
395
396 return am;
397}
398
400 const char *name,
401 const XrActionMap *am_except)
402{
403 LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
404 if (STREQLEN(name, am->name, MAX_NAME) && (am != am_except)) {
405 return am;
406 }
407 }
408
409 return nullptr;
410}
411
413{
414 char name[MAX_NAME];
415 char *suffix;
416 size_t baselen;
417 size_t idx = 0;
418
419 baselen = STRNCPY_UTF8_RLEN(name, actionmap->name);
420 suffix = &name[baselen];
421
422 while (wm_xr_actionmap_find_except(runtime, name, actionmap)) {
423 if ((baselen + 1) + (log10(++idx) + 1) > MAX_NAME) {
424 /* Use default base name. */
426 suffix = &name[baselen];
427 idx = 0;
428 }
429 else {
430 BLI_snprintf_utf8(suffix, MAX_NAME, "%zu", idx);
431 }
432 }
433
434 STRNCPY_UTF8(actionmap->name, name);
435}
436
438{
439 XrActionMap *am_dst = static_cast<XrActionMap *>(MEM_dupallocN(am_src));
440 am_dst->prev = am_dst->next = nullptr;
441
442 BLI_listbase_clear(&am_dst->items);
443 LISTBASE_FOREACH (XrActionMapItem *, ami, &am_src->items) {
445 BLI_addtail(&am_dst->items, ami_new);
446 }
447
448 return am_dst;
449}
450
452{
453 XrActionMap *am_dst = wm_xr_actionmap_copy(am_src);
454
455 WM_xr_actionmap_ensure_unique(runtime, am_dst);
456
457 BLI_addtail(&runtime->actionmaps, am_dst);
458
459 return am_dst;
460}
461
463{
464 int idx = BLI_findindex(&runtime->actionmaps, actionmap);
465
466 if (idx != -1) {
467 WM_xr_actionmap_clear(actionmap);
468 BLI_freelinkN(&runtime->actionmaps, actionmap);
469
470 if (idx <= runtime->actactionmap) {
471 if (--runtime->actactionmap < 0) {
472 runtime->actactionmap = 0;
473 }
474 }
475 if (idx <= runtime->selactionmap) {
476 if (--runtime->selactionmap < 0) {
477 runtime->selactionmap = 0;
478 }
479 }
480
481 return true;
482 }
483
484 return false;
485}
486
488{
489 LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
490 if (STREQLEN(name, am->name, MAX_NAME)) {
491 return am;
492 }
493 }
494 return nullptr;
495}
496
498{
499 LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
501 }
502 BLI_freelistN(&actionmap->items);
503 actionmap->selitem = 0;
504}
505
507{
508 LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
510 }
511 BLI_freelistN(&runtime->actionmaps);
512 runtime->actactionmap = runtime->selactionmap = 0;
513}
514
516{
517 return &runtime->actionmaps;
518}
519
521{
522 return runtime->actactionmap;
523}
524
526{
527 runtime->actactionmap = idx;
528}
529
531{
532 return runtime->selactionmap;
533}
534
536{
537 runtime->selactionmap = idx;
538}
539
IDProperty * IDP_CopyProperty(const IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:863
#define BLI_assert(a)
Definition BLI_assert.h:46
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
void BLI_freelinkN(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:270
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
size_t size_t size_t BLI_snprintf_utf8(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define STRNCPY_UTF8_RLEN(dst, src)
#define STRNCPY_UTF8(dst, src)
#define STREQLEN(a, b, n)
#define MAX_NAME
Definition DNA_defs.h:50
@ XR_FLOAT_INPUT
@ XR_BOOLEAN_INPUT
@ XR_VECTOR2F_INPUT
@ XR_POSE_INPUT
@ XR_VIBRATION_OUTPUT
Read Guarded memory(de)allocation.
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
const char * name
StructRNA * type
Definition RNA_types.hh:52
void * data
Definition RNA_types.hh:53
struct XrActionMapBinding * next
struct XrActionMapBinding * prev
struct XrActionMapItem * prev
struct XrActionMapItem * next
IDProperty * op_properties
ListBase user_paths
struct PointerRNA * op_properties_ptr
ListBase items
char name[64]
struct XrActionMap * next
struct XrActionMap * prev
ListBase actionmaps
wmOperatorType * ot
Definition wm_files.cc:4237
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operator_properties_alloc(PointerRNA **ptr, IDProperty **properties, const char *opstring)
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
void WM_operator_properties_create(PointerRNA *ptr, const char *opstring)
void WM_operator_properties_free(PointerRNA *ptr)
void WM_operator_properties_sanitize(PointerRNA *ptr, const bool no_context)
short WM_xr_actionmap_active_index_get(const wmXrRuntimeData *runtime)
XrActionMapItem * WM_xr_actionmap_item_find(XrActionMap *actionmap, const char *name)
static XrActionMap * wm_xr_actionmap_find_except(wmXrRuntimeData *runtime, const char *name, const XrActionMap *am_except)
#define WM_XR_ACTIONMAP_BINDING_STR_DEFAULT
#define WM_XR_ACTIONMAP_ITEM_STR_DEFAULT
static XrActionMap * wm_xr_actionmap_copy(XrActionMap *am_src)
void WM_xr_actionmap_ensure_unique(wmXrRuntimeData *runtime, XrActionMap *actionmap)
XrActionMap * WM_xr_actionmap_find(wmXrRuntimeData *runtime, const char *name)
XrActionMapItem * WM_xr_actionmap_item_add_copy(XrActionMap *actionmap, XrActionMapItem *ami_src)
static void wm_xr_actionmap_item_properties_set(XrActionMapItem *ami)
XrActionMapItem * WM_xr_actionmap_item_new(XrActionMap *actionmap, const char *name, bool replace_existing)
static void wm_xr_actionmap_item_clear(XrActionMapItem *ami)
static XrActionMapBinding * wm_xr_actionmap_binding_find_except(XrActionMapItem *ami, const char *name, XrActionMapBinding *ambexcept)
void WM_xr_actionmap_selected_index_set(wmXrRuntimeData *runtime, short idx)
XrActionMapBinding * WM_xr_actionmap_binding_add_copy(XrActionMapItem *ami, XrActionMapBinding *amb_src)
static XrActionMapItem * wm_xr_actionmap_item_copy(XrActionMapItem *ami_src)
XrActionMapBinding * WM_xr_actionmap_binding_new(XrActionMapItem *ami, const char *name, bool replace_existing)
XrActionMapBinding * WM_xr_actionmap_binding_find(XrActionMapItem *ami, const char *name)
void WM_xr_actionmap_active_index_set(wmXrRuntimeData *runtime, short idx)
void WM_xr_actionmaps_clear(wmXrRuntimeData *runtime)
short WM_xr_actionmap_selected_index_get(const wmXrRuntimeData *runtime)
static void wm_xr_actionmap_binding_clear(XrActionMapBinding *amb)
static XrActionMapBinding * wm_xr_actionmap_binding_copy(XrActionMapBinding *amb_src)
static void wm_xr_actionmap_item_properties_free(XrActionMapItem *ami)
void WM_xr_actionmap_item_ensure_unique(XrActionMap *actionmap, XrActionMapItem *ami)
XrActionMap * WM_xr_actionmap_new(wmXrRuntimeData *runtime, const char *name, bool replace_existing)
bool WM_xr_actionmap_binding_remove(XrActionMapItem *ami, XrActionMapBinding *amb)
ListBase * WM_xr_actionmaps_get(wmXrRuntimeData *runtime)
void WM_xr_actionmap_binding_ensure_unique(XrActionMapItem *ami, XrActionMapBinding *amb)
XrActionMap * WM_xr_actionmap_add_copy(wmXrRuntimeData *runtime, XrActionMap *am_src)
void WM_xr_actionmap_item_properties_update_ot(XrActionMapItem *ami)
#define WM_XR_ACTIONMAP_STR_DEFAULT
void WM_xr_actionmap_clear(XrActionMap *actionmap)
static XrActionMapItem * wm_xr_actionmap_item_find_except(XrActionMap *actionmap, const char *name, const XrActionMapItem *amiexcept)
bool WM_xr_actionmap_remove(wmXrRuntimeData *runtime, XrActionMap *actionmap)
bool WM_xr_actionmap_item_remove(XrActionMap *actionmap, XrActionMapItem *ami)