The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

st/oxr: Add action (key) only to bindings that have the right child

st/oxr: Preserve which path the app suggested

The OXR_DEBUG_BINDINGS output uses this to print debug info.

Otherwise there should be no difference - the entire problem was that
parents like /trigger are added to each of the oxr_bindings that respresent
a component like /trigger/click, /trigger/value, etc.

So as long as we only add the act_key to the oxr_binding that we want
selected, the preferred_binding_path_index is purely informative of what
the app originally suggested.

st/oxr: Get rid of hardcoded array size

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2431>

authored by

Christoph Haag and committed by
Marge Bot
2dbcf9a7 155488d2

+108 -6
+108 -6
src/xrt/state_trackers/oxr/oxr_binding.c
··· 210 210 } 211 211 } 212 212 213 - static void 214 - add_act_key_to_matching_bindings(struct oxr_binding *bindings, size_t binding_count, XrPath path, uint32_t act_key) 213 + static bool 214 + ends_with(const char *str, const char *suffix) 215 215 { 216 - for (size_t x = 0; x < binding_count; x++) { 217 - struct oxr_binding *b = &bindings[x]; 216 + size_t len = strlen(str); 217 + size_t suffix_len = strlen(suffix); 218 + 219 + return (len >= suffix_len) && (0 == strcmp(str + (len - suffix_len), suffix)); 220 + } 221 + 222 + static bool 223 + add_by_component(struct oxr_logger *log, 224 + struct oxr_instance *inst, 225 + struct oxr_binding *bindings, 226 + size_t binding_count, 227 + XrPath path, 228 + struct oxr_action *act, 229 + const char **components, 230 + size_t component_count) 231 + { 232 + for (uint32_t component_index = 0; component_index < component_count; component_index++) { 233 + // once we found everything for a component like click we don't want to keep going to add to a component 234 + // like /value 235 + // component is the outer loop so that we finish everything for a component in one go. 236 + bool found_all_for_component = false; 237 + 238 + for (size_t i = 0; i < binding_count; i++) { 239 + struct oxr_binding *b = &bindings[i]; 240 + 241 + bool path_found = false; 242 + // search for path and component together and only add to the first found binding that has both 243 + bool component_found = false; 244 + 245 + uint32_t preferred_path_index; 246 + for (uint32_t y = 0; y < b->path_count; y++) { 247 + if (b->paths[y] == path) { 248 + path_found = true; 249 + // we preserve the info which path the app selected instead of pretending it 250 + // selected /click, /value, etc. if it did not 251 + preferred_path_index = y; 252 + } 253 + 254 + const char *str; 255 + size_t len; 256 + oxr_path_get_string(log, inst, b->paths[y], &str, &len); 257 + if (ends_with(str, components[component_index])) { 258 + component_found = true; 259 + } 260 + } 261 + 262 + 263 + if (!(path_found && component_found)) { 264 + continue; 265 + } 266 + 267 + U_ARRAY_REALLOC_OR_FREE(b->act_keys, uint32_t, (b->act_key_count + 1)); 268 + U_ARRAY_REALLOC_OR_FREE(b->preferred_binding_path_index, uint32_t, (b->act_key_count + 1)); 269 + b->preferred_binding_path_index[b->act_key_count] = preferred_path_index; 270 + b->act_keys[b->act_key_count++] = act->act_key; 271 + found_all_for_component = true; 272 + } 273 + 274 + if (found_all_for_component) { 275 + return true; 276 + } 277 + } 278 + return true; 279 + } 280 + 281 + static bool 282 + add_direct(struct oxr_logger *log, 283 + struct oxr_instance *inst, 284 + struct oxr_binding *bindings, 285 + size_t binding_count, 286 + XrPath path, 287 + struct oxr_action *act) 288 + { 289 + for (size_t i = 0; i < binding_count; i++) { 290 + struct oxr_binding *b = &bindings[i]; 218 291 219 292 bool found = false; 220 293 uint32_t preferred_path_index; ··· 233 306 U_ARRAY_REALLOC_OR_FREE(b->act_keys, uint32_t, (b->act_key_count + 1)); 234 307 U_ARRAY_REALLOC_OR_FREE(b->preferred_binding_path_index, uint32_t, (b->act_key_count + 1)); 235 308 b->preferred_binding_path_index[b->act_key_count] = preferred_path_index; 236 - b->act_keys[b->act_key_count++] = act_key; 309 + b->act_keys[b->act_key_count++] = act->act_key; 310 + } 311 + 312 + return true; 313 + } 314 + 315 + static void 316 + add_act_key_to_matching_bindings(struct oxr_logger *log, 317 + struct oxr_instance *inst, 318 + struct oxr_binding *bindings, 319 + size_t binding_count, 320 + XrPath path, 321 + struct oxr_action *act) 322 + { 323 + XrActionType xr_act_type = act->data->action_type; 324 + 325 + const char *str; 326 + size_t len; 327 + oxr_path_get_string(log, inst, path, &str, &len); 328 + 329 + // check if we need to select a child 330 + if (xr_act_type == XR_ACTION_TYPE_BOOLEAN_INPUT && !ends_with(str, "/click") && !ends_with(str, "/touch")) { 331 + const char *components[2] = {"click", "value"}; 332 + add_by_component(log, inst, bindings, binding_count, path, act, components, 2); 333 + } else if (xr_act_type == XR_ACTION_TYPE_FLOAT_INPUT && !ends_with(str, "/value") && 334 + !ends_with(str, "/click")) { 335 + const char *components[2] = {"value", "click"}; 336 + add_by_component(log, inst, bindings, binding_count, path, act, components, 2); 337 + } else { 338 + add_direct(log, inst, bindings, binding_count, path, act); 237 339 } 238 340 } 239 341 ··· 612 714 const XrActionSuggestedBinding *s = &suggestedBindings->suggestedBindings[i]; 613 715 struct oxr_action *act = XRT_CAST_OXR_HANDLE_TO_PTR(struct oxr_action *, s->action); 614 716 615 - add_act_key_to_matching_bindings(bindings, binding_count, s->binding, act->act_key); 717 + add_act_key_to_matching_bindings(log, inst, bindings, binding_count, s->binding, act); 616 718 } 617 719 618 720 out: