Blender V4.3
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
13#include <cmath>
14#include <cstring>
15
16#include "BKE_idprop.hh"
17
18#include "BLI_listbase.h"
19#include "BLI_string.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/* -------------------------------------------------------------------- */
39 const char *name,
40 bool replace_existing)
41{
43 if (amb_prev && replace_existing) {
44 return amb_prev;
45 }
46
47 XrActionMapBinding *amb = static_cast<XrActionMapBinding *>(
48 MEM_callocN(sizeof(XrActionMapBinding), __func__));
49 STRNCPY(amb->name, name);
50 if (amb_prev) {
52 }
53
54 BLI_addtail(&ami->bindings, amb);
55
56 /* Set non-zero threshold by default. */
57 amb->float_threshold = 0.3f;
58
59 return amb;
60}
61
63 const char *name,
64 XrActionMapBinding *ambexcept)
65{
67 if (STREQLEN(name, amb->name, MAX_NAME) && (amb != ambexcept)) {
68 return amb;
69 }
70 }
71 return nullptr;
72}
73
75{
76 char name[MAX_NAME];
77 char *suffix;
78 size_t baselen;
79 size_t idx = 0;
80
81 STRNCPY(name, amb->name);
82 baselen = BLI_strnlen(name, MAX_NAME);
83 suffix = &name[baselen];
84
85 while (wm_xr_actionmap_binding_find_except(ami, name, amb)) {
86 if ((baselen + 1) + (log10(++idx) + 1) > MAX_NAME) {
87 /* Use default base name. */
89 baselen = BLI_strnlen(name, MAX_NAME);
90 suffix = &name[baselen];
91 idx = 0;
92 }
93 else {
94 BLI_snprintf(suffix, MAX_NAME, "%zu", idx);
95 }
96 }
97
98 STRNCPY(amb->name, name);
99}
100
102{
103 XrActionMapBinding *amb_dst = static_cast<XrActionMapBinding *>(MEM_dupallocN(amb_src));
104 amb_dst->prev = amb_dst->next = nullptr;
105
108 XrComponentPath *path_new = static_cast<XrComponentPath *>(MEM_dupallocN(path));
109 BLI_addtail(&amb_dst->component_paths, path_new);
110 }
111
112 return amb_dst;
113}
114
116 XrActionMapBinding *amb_src)
117{
119
121
122 BLI_addtail(&ami->bindings, amb_dst);
123
124 return amb_dst;
125}
126
131
133{
134 int idx = BLI_findindex(&ami->bindings, amb);
135
136 if (idx != -1) {
138 BLI_freelinkN(&ami->bindings, amb);
139
140 if (idx <= ami->selbinding) {
141 if (--ami->selbinding < 0) {
142 ami->selbinding = 0;
143 }
144 }
145
146 return true;
147 }
148
149 return false;
150}
151
153{
155 if (STREQLEN(name, amb->name, MAX_NAME)) {
156 return amb;
157 }
158 }
159 return nullptr;
160}
161
164/* -------------------------------------------------------------------- */
175
177{
178 if (ami->op_properties_ptr) {
181 ami->op_properties_ptr = nullptr;
182 ami->op_properties = nullptr;
183 }
184 else {
185 BLI_assert(ami->op_properties == nullptr);
186 }
187}
188
201
203{
204 switch (ami->type) {
205 case XR_BOOLEAN_INPUT:
206 case XR_FLOAT_INPUT:
208 break;
209 case XR_POSE_INPUT:
212 memset(ami->op, 0, sizeof(ami->op));
213 return;
214 }
215
216 if (ami->op[0] == 0) {
218 return;
219 }
220
221 if (ami->op_properties_ptr == nullptr) {
223 }
224 else {
226 if (ot) {
227 if (ot->srna != ami->op_properties_ptr->type) {
228 /* Matches wm_xr_actionmap_item_properties_set() but doesn't alloc new ptr. */
230 if (ami->op_properties) {
232 }
234 }
235 }
236 else {
238 }
239 }
240}
241
243 const char *name,
244 bool replace_existing)
245{
246 XrActionMapItem *ami_prev = WM_xr_actionmap_item_find(actionmap, name);
247 if (ami_prev && replace_existing) {
249 return ami_prev;
250 }
251
252 XrActionMapItem *ami = static_cast<XrActionMapItem *>(
253 MEM_callocN(sizeof(XrActionMapItem), __func__));
254 STRNCPY(ami->name, name);
255 if (ami_prev) {
257 }
258
259 BLI_addtail(&actionmap->items, ami);
260
261 /* Set type to float (button) input by default. */
262 ami->type = XR_FLOAT_INPUT;
263
264 return ami;
265}
266
268 const char *name,
269 const XrActionMapItem *amiexcept)
270{
271 LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
272 if (STREQLEN(name, ami->name, MAX_NAME) && (ami != amiexcept)) {
273 return ami;
274 }
275 }
276 return nullptr;
277}
278
280{
281 char name[MAX_NAME];
282 char *suffix;
283 size_t baselen;
284 size_t idx = 0;
285
286 STRNCPY(name, ami->name);
287 baselen = BLI_strnlen(name, MAX_NAME);
288 suffix = &name[baselen];
289
290 while (wm_xr_actionmap_item_find_except(actionmap, name, ami)) {
291 if ((baselen + 1) + (log10(++idx) + 1) > MAX_NAME) {
292 /* Use default base name. */
294 baselen = BLI_strnlen(name, MAX_NAME);
295 suffix = &name[baselen];
296 idx = 0;
297 }
298 else {
299 BLI_snprintf(suffix, MAX_NAME, "%zu", idx);
300 }
301 }
302
303 STRNCPY(ami->name, name);
304}
305
307{
308 XrActionMapItem *ami_dst = static_cast<XrActionMapItem *>(MEM_dupallocN(ami_src));
309 ami_dst->prev = ami_dst->next = nullptr;
310
311 BLI_listbase_clear(&ami_dst->bindings);
312 LISTBASE_FOREACH (XrActionMapBinding *, amb, &ami_src->bindings) {
314 BLI_addtail(&ami_dst->bindings, amb_new);
315 }
316
317 if (ami_dst->op_properties) {
318 ami_dst->op_properties_ptr = static_cast<PointerRNA *>(
319 MEM_callocN(sizeof(PointerRNA), "wmOpItemPtr"));
321 ami_dst->op_properties = IDP_CopyProperty(ami_src->op_properties);
322 ami_dst->op_properties_ptr->data = ami_dst->op_properties;
323 }
324 else {
325 ami_dst->op_properties = nullptr;
326 ami_dst->op_properties_ptr = nullptr;
327 }
328
330 LISTBASE_FOREACH (XrUserPath *, path, &ami_src->user_paths) {
331 XrUserPath *path_new = static_cast<XrUserPath *>(MEM_dupallocN(path));
332 BLI_addtail(&ami_dst->user_paths, path_new);
333 }
334
335 return ami_dst;
336}
337
339{
340 XrActionMapItem *ami_dst = wm_xr_actionmap_item_copy(ami_src);
341
342 WM_xr_actionmap_item_ensure_unique(actionmap, ami_dst);
343
344 BLI_addtail(&actionmap->items, ami_dst);
345
346 return ami_dst;
347}
348
350{
351 int idx = BLI_findindex(&actionmap->items, ami);
352
353 if (idx != -1) {
355 BLI_freelinkN(&actionmap->items, ami);
356
357 if (idx <= actionmap->selitem) {
358 if (--actionmap->selitem < 0) {
359 actionmap->selitem = 0;
360 }
361 }
362
363 return true;
364 }
365
366 return false;
367}
368
370{
371 LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
372 if (STREQLEN(name, ami->name, MAX_NAME)) {
373 return ami;
374 }
375 }
376 return nullptr;
377}
378
381/* -------------------------------------------------------------------- */
387XrActionMap *WM_xr_actionmap_new(wmXrRuntimeData *runtime, const char *name, bool replace_existing)
388{
389 XrActionMap *am_prev = WM_xr_actionmap_find(runtime, name);
390 if (am_prev && replace_existing) {
391 WM_xr_actionmap_clear(am_prev);
392 return am_prev;
393 }
394
395 XrActionMap *am = static_cast<XrActionMap *>(MEM_callocN(sizeof(XrActionMap), __func__));
396 STRNCPY(am->name, name);
397 if (am_prev) {
399 }
400
401 BLI_addtail(&runtime->actionmaps, am);
402
403 return am;
404}
405
407 const char *name,
408 const XrActionMap *am_except)
409{
410 LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
411 if (STREQLEN(name, am->name, MAX_NAME) && (am != am_except)) {
412 return am;
413 }
414 }
415
416 return nullptr;
417}
418
420{
421 char name[MAX_NAME];
422 char *suffix;
423 size_t baselen;
424 size_t idx = 0;
425
426 STRNCPY(name, actionmap->name);
427 baselen = BLI_strnlen(name, MAX_NAME);
428 suffix = &name[baselen];
429
430 while (wm_xr_actionmap_find_except(runtime, name, actionmap)) {
431 if ((baselen + 1) + (log10(++idx) + 1) > MAX_NAME) {
432 /* Use default base name. */
434 baselen = BLI_strnlen(name, MAX_NAME);
435 suffix = &name[baselen];
436 idx = 0;
437 }
438 else {
439 BLI_snprintf(suffix, MAX_NAME, "%zu", idx);
440 }
441 }
442
443 STRNCPY(actionmap->name, name);
444}
445
447{
448 XrActionMap *am_dst = static_cast<XrActionMap *>(MEM_dupallocN(am_src));
449 am_dst->prev = am_dst->next = nullptr;
450
451 BLI_listbase_clear(&am_dst->items);
452 LISTBASE_FOREACH (XrActionMapItem *, ami, &am_src->items) {
454 BLI_addtail(&am_dst->items, ami_new);
455 }
456
457 return am_dst;
458}
459
461{
462 XrActionMap *am_dst = wm_xr_actionmap_copy(am_src);
463
464 WM_xr_actionmap_ensure_unique(runtime, am_dst);
465
466 BLI_addtail(&runtime->actionmaps, am_dst);
467
468 return am_dst;
469}
470
472{
473 int idx = BLI_findindex(&runtime->actionmaps, actionmap);
474
475 if (idx != -1) {
476 WM_xr_actionmap_clear(actionmap);
477 BLI_freelinkN(&runtime->actionmaps, actionmap);
478
479 if (idx <= runtime->actactionmap) {
480 if (--runtime->actactionmap < 0) {
481 runtime->actactionmap = 0;
482 }
483 }
484 if (idx <= runtime->selactionmap) {
485 if (--runtime->selactionmap < 0) {
486 runtime->selactionmap = 0;
487 }
488 }
489
490 return true;
491 }
492
493 return false;
494}
495
497{
498 LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
499 if (STREQLEN(name, am->name, MAX_NAME)) {
500 return am;
501 }
502 }
503 return nullptr;
504}
505
507{
508 LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
510 }
511 BLI_freelistN(&actionmap->items);
512 actionmap->selitem = 0;
513}
514
516{
517 LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
519 }
520 BLI_freelistN(&runtime->actionmaps);
521 runtime->actactionmap = runtime->selactionmap = 0;
522}
523
525{
526 return &runtime->actionmaps;
527}
528
530{
531 return runtime->actactionmap;
532}
533
535{
536 runtime->actactionmap = idx;
537}
538
540{
541 return runtime->selactionmap;
542}
543
545{
546 runtime->selactionmap = idx;
547}
548
IDProperty * IDP_CopyProperty(const IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:861
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:269
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define STRNCPY(dst, src)
Definition BLI_string.h:593
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition string.c:909
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#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_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
StructRNA * type
Definition RNA_types.hh:41
void * data
Definition RNA_types.hh:42
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
StructRNA * srna
Definition WM_types.hh:1080
ListBase actionmaps
wmOperatorType * ot
Definition wm_files.cc:4125
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)