Blender  V3.3
wm_xr_actionmap.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
11 #include <math.h>
12 #include <string.h>
13 
14 #include "BKE_context.h"
15 #include "BKE_idprop.h"
16 
17 #include "BLI_listbase.h"
18 #include "BLI_string.h"
19 
20 #include "GHOST_Types.h"
21 
22 #include "MEM_guardedalloc.h"
23 
24 #include "WM_api.h"
25 #include "WM_types.h"
26 
27 #include "wm_xr_intern.h"
28 
29 #define WM_XR_ACTIONMAP_STR_DEFAULT "actionmap"
30 #define WM_XR_ACTIONMAP_ITEM_STR_DEFAULT "action"
31 #define WM_XR_ACTIONMAP_BINDING_STR_DEFAULT "binding"
32 
33 /* -------------------------------------------------------------------- */
40  const char *name,
41  bool replace_existing)
42 {
43  XrActionMapBinding *amb_prev = WM_xr_actionmap_binding_find(ami, name);
44  if (amb_prev && replace_existing) {
45  return amb_prev;
46  }
47 
48  XrActionMapBinding *amb = MEM_callocN(sizeof(XrActionMapBinding), __func__);
49  BLI_strncpy(amb->name, name, MAX_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 NULL;
72 }
73 
75 {
76  char name[MAX_NAME];
77  char *suffix;
78  size_t baselen;
79  size_t idx = 0;
80 
81  BLI_strncpy(name, amb->name, MAX_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  BLI_strncpy(amb->name, name, MAX_NAME);
99 }
100 
102 {
103  XrActionMapBinding *amb_dst = MEM_dupallocN(amb_src);
104  amb_dst->prev = amb_dst->next = NULL;
105 
107  LISTBASE_FOREACH (XrComponentPath *, path, &amb_src->component_paths) {
108  XrComponentPath *path_new = 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 
128 {
130 }
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 NULL;
160 }
161 
164 /* -------------------------------------------------------------------- */
171 {
174 }
175 
177 {
178  if (ami->op_properties_ptr) {
181  ami->op_properties_ptr = NULL;
182  ami->op_properties = NULL;
183  }
184  else {
185  BLI_assert(ami->op_properties == NULL);
186  }
187 }
188 
190 {
193  }
194  BLI_freelistN(&ami->bindings);
195  ami->selbinding = 0;
196 
198 
199  BLI_freelistN(&ami->user_paths);
200 }
201 
203 {
204  switch (ami->type) {
205  case XR_BOOLEAN_INPUT:
206  case XR_FLOAT_INPUT:
207  case XR_VECTOR2F_INPUT:
208  break;
209  case XR_POSE_INPUT:
210  case XR_VIBRATION_OUTPUT:
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 == NULL) {
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) {
231  ami->op_properties_ptr->data = 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 = MEM_callocN(sizeof(XrActionMapItem), __func__);
253  BLI_strncpy(ami->name, name, MAX_NAME);
254  if (ami_prev) {
255  WM_xr_actionmap_item_ensure_unique(actionmap, ami);
256  }
257 
258  BLI_addtail(&actionmap->items, ami);
259 
260  /* Set type to float (button) input by default. */
261  ami->type = XR_FLOAT_INPUT;
262 
263  return ami;
264 }
265 
267  const char *name,
268  const XrActionMapItem *amiexcept)
269 {
270  LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
271  if (STREQLEN(name, ami->name, MAX_NAME) && (ami != amiexcept)) {
272  return ami;
273  }
274  }
275  return NULL;
276 }
277 
279 {
280  char name[MAX_NAME];
281  char *suffix;
282  size_t baselen;
283  size_t idx = 0;
284 
285  BLI_strncpy(name, ami->name, MAX_NAME);
286  baselen = BLI_strnlen(name, MAX_NAME);
287  suffix = &name[baselen];
288 
289  while (wm_xr_actionmap_item_find_except(actionmap, name, ami)) {
290  if ((baselen + 1) + (log10(++idx) + 1) > MAX_NAME) {
291  /* Use default base name. */
293  baselen = BLI_strnlen(name, MAX_NAME);
294  suffix = &name[baselen];
295  idx = 0;
296  }
297  else {
298  BLI_snprintf(suffix, MAX_NAME, "%zu", idx);
299  }
300  }
301 
302  BLI_strncpy(ami->name, name, MAX_NAME);
303 }
304 
306 {
307  XrActionMapItem *ami_dst = MEM_dupallocN(ami_src);
308  ami_dst->prev = ami_dst->next = NULL;
309 
310  BLI_listbase_clear(&ami_dst->bindings);
311  LISTBASE_FOREACH (XrActionMapBinding *, amb, &ami_src->bindings) {
313  BLI_addtail(&ami_dst->bindings, amb_new);
314  }
315 
316  if (ami_dst->op_properties) {
317  ami_dst->op_properties_ptr = MEM_callocN(sizeof(PointerRNA), "wmOpItemPtr");
319  ami_dst->op_properties = IDP_CopyProperty(ami_src->op_properties);
320  ami_dst->op_properties_ptr->data = ami_dst->op_properties;
321  }
322  else {
323  ami_dst->op_properties = NULL;
324  ami_dst->op_properties_ptr = NULL;
325  }
326 
327  BLI_listbase_clear(&ami_dst->user_paths);
328  LISTBASE_FOREACH (XrUserPath *, path, &ami_src->user_paths) {
329  XrUserPath *path_new = MEM_dupallocN(path);
330  BLI_addtail(&ami_dst->user_paths, path_new);
331  }
332 
333  return ami_dst;
334 }
335 
337 {
338  XrActionMapItem *ami_dst = wm_xr_actionmap_item_copy(ami_src);
339 
340  WM_xr_actionmap_item_ensure_unique(actionmap, ami_dst);
341 
342  BLI_addtail(&actionmap->items, ami_dst);
343 
344  return ami_dst;
345 }
346 
348 {
349  int idx = BLI_findindex(&actionmap->items, ami);
350 
351  if (idx != -1) {
353  BLI_freelinkN(&actionmap->items, ami);
354 
355  if (idx <= actionmap->selitem) {
356  if (--actionmap->selitem < 0) {
357  actionmap->selitem = 0;
358  }
359  }
360 
361  return true;
362  }
363 
364  return false;
365 }
366 
368 {
369  LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
370  if (STREQLEN(name, ami->name, MAX_NAME)) {
371  return ami;
372  }
373  }
374  return NULL;
375 }
376 
379 /* -------------------------------------------------------------------- */
385 XrActionMap *WM_xr_actionmap_new(wmXrRuntimeData *runtime, const char *name, bool replace_existing)
386 {
387  XrActionMap *am_prev = WM_xr_actionmap_find(runtime, name);
388  if (am_prev && replace_existing) {
389  WM_xr_actionmap_clear(am_prev);
390  return am_prev;
391  }
392 
393  XrActionMap *am = MEM_callocN(sizeof(struct XrActionMap), __func__);
394  BLI_strncpy(am->name, name, MAX_NAME);
395  if (am_prev) {
396  WM_xr_actionmap_ensure_unique(runtime, am);
397  }
398 
399  BLI_addtail(&runtime->actionmaps, am);
400 
401  return am;
402 }
403 
405  const char *name,
406  const XrActionMap *am_except)
407 {
408  LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
409  if (STREQLEN(name, am->name, MAX_NAME) && (am != am_except)) {
410  return am;
411  }
412  }
413 
414  return NULL;
415 }
416 
418 {
419  char name[MAX_NAME];
420  char *suffix;
421  size_t baselen;
422  size_t idx = 0;
423 
424  BLI_strncpy(name, actionmap->name, MAX_NAME);
425  baselen = BLI_strnlen(name, MAX_NAME);
426  suffix = &name[baselen];
427 
428  while (wm_xr_actionmap_find_except(runtime, name, actionmap)) {
429  if ((baselen + 1) + (log10(++idx) + 1) > MAX_NAME) {
430  /* Use default base name. */
432  baselen = BLI_strnlen(name, MAX_NAME);
433  suffix = &name[baselen];
434  idx = 0;
435  }
436  else {
437  BLI_snprintf(suffix, MAX_NAME, "%zu", idx);
438  }
439  }
440 
441  BLI_strncpy(actionmap->name, name, MAX_NAME);
442 }
443 
445 {
446  XrActionMap *am_dst = MEM_dupallocN(am_src);
447  am_dst->prev = am_dst->next = NULL;
448 
449  BLI_listbase_clear(&am_dst->items);
450  LISTBASE_FOREACH (XrActionMapItem *, ami, &am_src->items) {
452  BLI_addtail(&am_dst->items, ami_new);
453  }
454 
455  return am_dst;
456 }
457 
459 {
460  XrActionMap *am_dst = wm_xr_actionmap_copy(am_src);
461 
462  WM_xr_actionmap_ensure_unique(runtime, am_dst);
463 
464  BLI_addtail(&runtime->actionmaps, am_dst);
465 
466  return am_dst;
467 }
468 
470 {
471  int idx = BLI_findindex(&runtime->actionmaps, actionmap);
472 
473  if (idx != -1) {
474  WM_xr_actionmap_clear(actionmap);
475  BLI_freelinkN(&runtime->actionmaps, actionmap);
476 
477  if (idx <= runtime->actactionmap) {
478  if (--runtime->actactionmap < 0) {
479  runtime->actactionmap = 0;
480  }
481  }
482  if (idx <= runtime->selactionmap) {
483  if (--runtime->selactionmap < 0) {
484  runtime->selactionmap = 0;
485  }
486  }
487 
488  return true;
489  }
490 
491  return false;
492 }
493 
495 {
496  LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
497  if (STREQLEN(name, am->name, MAX_NAME)) {
498  return am;
499  }
500  }
501  return NULL;
502 }
503 
505 {
506  LISTBASE_FOREACH (XrActionMapItem *, ami, &actionmap->items) {
508  }
509  BLI_freelistN(&actionmap->items);
510  actionmap->selitem = 0;
511 }
512 
514 {
515  LISTBASE_FOREACH (XrActionMap *, am, &runtime->actionmaps) {
517  }
518  BLI_freelistN(&runtime->actionmaps);
519  runtime->actactionmap = runtime->selactionmap = 0;
520 }
521 
523 {
524  return &runtime->actionmaps;
525 }
526 
528 {
529  return runtime->actactionmap;
530 }
531 
533 {
534  runtime->actactionmap = idx;
535 }
536 
538 {
539  return runtime->selactionmap;
540 }
541 
543 {
544  runtime->selactionmap = idx;
545 }
546 
struct IDProperty * IDP_CopyProperty(const struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:899
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define STREQLEN(a, b, n)
#define MAX_NAME
Definition: DNA_defs.h:48
@ XR_FLOAT_INPUT
Definition: DNA_xr_types.h:66
@ XR_BOOLEAN_INPUT
Definition: DNA_xr_types.h:65
@ XR_VECTOR2F_INPUT
Definition: DNA_xr_types.h:67
@ XR_POSE_INPUT
Definition: DNA_xr_types.h:68
@ XR_VIBRATION_OUTPUT
Definition: DNA_xr_types.h:69
Read Guarded memory(de)allocation.
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
struct StructRNA * type
Definition: RNA_types.h:37
void * data
Definition: RNA_types.h:38
struct XrActionMapBinding * next
Definition: DNA_xr_types.h:131
ListBase component_paths
Definition: DNA_xr_types.h:139
struct XrActionMapBinding * prev
Definition: DNA_xr_types.h:131
ListBase bindings
Definition: DNA_xr_types.h:192
struct XrActionMapItem * prev
Definition: DNA_xr_types.h:159
struct XrActionMapItem * next
Definition: DNA_xr_types.h:159
IDProperty * op_properties
Definition: DNA_xr_types.h:173
ListBase user_paths
Definition: DNA_xr_types.h:168
struct PointerRNA * op_properties_ptr
Definition: DNA_xr_types.h:175
ListBase items
Definition: DNA_xr_types.h:203
char name[64]
Definition: DNA_xr_types.h:201
struct XrActionMap * next
Definition: DNA_xr_types.h:198
struct XrActionMap * prev
Definition: DNA_xr_types.h:198
struct StructRNA * srna
Definition: WM_types.h:969
ListBase actionmaps
Definition: wm_xr_intern.h:78
wmOperatorType * ot
Definition: wm_files.c:3479
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operator_properties_alloc(PointerRNA **ptr, IDProperty **properties, const char *opstring)
Definition: wm_operators.c:680
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
Definition: wm_operators.c:661
void WM_operator_properties_create(PointerRNA *ptr, const char *opstring)
Definition: wm_operators.c:667
void WM_operator_properties_free(PointerRNA *ptr)
Definition: wm_operators.c:783
void WM_operator_properties_sanitize(PointerRNA *ptr, const bool no_context)
Definition: wm_operators.c:701
short WM_xr_actionmap_active_index_get(const wmXrRuntimeData *runtime)
#define WM_XR_ACTIONMAP_BINDING_STR_DEFAULT
#define WM_XR_ACTIONMAP_ITEM_STR_DEFAULT
void WM_xr_actionmap_ensure_unique(wmXrRuntimeData *runtime, XrActionMap *actionmap)
static void wm_xr_actionmap_item_properties_set(XrActionMapItem *ami)
static void wm_xr_actionmap_item_clear(XrActionMapItem *ami)
void WM_xr_actionmap_selected_index_set(wmXrRuntimeData *runtime, short idx)
XrActionMap * WM_xr_actionmap_new(wmXrRuntimeData *runtime, const char *name, bool replace_existing)
static XrActionMap * wm_xr_actionmap_find_except(wmXrRuntimeData *runtime, const char *name, const XrActionMap *am_except)
XrActionMapBinding * WM_xr_actionmap_binding_add_copy(XrActionMapItem *ami, XrActionMapBinding *amb_src)
static XrActionMapItem * wm_xr_actionmap_item_find_except(XrActionMap *actionmap, const char *name, const XrActionMapItem *amiexcept)
XrActionMapBinding * WM_xr_actionmap_binding_new(XrActionMapItem *ami, const char *name, bool replace_existing)
static XrActionMapItem * wm_xr_actionmap_item_copy(XrActionMapItem *ami_src)
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)
XrActionMap * WM_xr_actionmap_find(wmXrRuntimeData *runtime, const char *name)
static void wm_xr_actionmap_binding_clear(XrActionMapBinding *amb)
XrActionMapItem * WM_xr_actionmap_item_find(XrActionMap *actionmap, const char *name)
static XrActionMap * wm_xr_actionmap_copy(XrActionMap *am_src)
XrActionMapBinding * WM_xr_actionmap_binding_find(XrActionMapItem *ami, const char *name)
XrActionMapItem * WM_xr_actionmap_item_new(XrActionMap *actionmap, const char *name, bool replace_existing)
static XrActionMapBinding * wm_xr_actionmap_binding_copy(XrActionMapBinding *amb_src)
XrActionMapItem * WM_xr_actionmap_item_add_copy(XrActionMap *actionmap, XrActionMapItem *ami_src)
XrActionMap * WM_xr_actionmap_add_copy(wmXrRuntimeData *runtime, XrActionMap *am_src)
static void wm_xr_actionmap_item_properties_free(XrActionMapItem *ami)
void WM_xr_actionmap_item_ensure_unique(XrActionMap *actionmap, XrActionMapItem *ami)
bool WM_xr_actionmap_binding_remove(XrActionMapItem *ami, XrActionMapBinding *amb)
void WM_xr_actionmap_binding_ensure_unique(XrActionMapItem *ami, XrActionMapBinding *amb)
static XrActionMapBinding * wm_xr_actionmap_binding_find_except(XrActionMapItem *ami, const char *name, XrActionMapBinding *ambexcept)
void WM_xr_actionmap_item_properties_update_ot(XrActionMapItem *ami)
#define WM_XR_ACTIONMAP_STR_DEFAULT
void WM_xr_actionmap_clear(XrActionMap *actionmap)
bool WM_xr_actionmap_remove(wmXrRuntimeData *runtime, XrActionMap *actionmap)
bool WM_xr_actionmap_item_remove(XrActionMap *actionmap, XrActionMapItem *ami)
ListBase * WM_xr_actionmaps_get(wmXrRuntimeData *runtime)