st/oxr: Do dup checking on actions and action sets

This commit is contained in:
Jakob Bornecrantz 2020-05-30 23:44:03 +01:00
parent e5c9636f10
commit 6fc410dadd
5 changed files with 163 additions and 1 deletions

View file

@ -0,0 +1,2 @@
OpenXR: Track the name and localized name for both actions and action sets, that
way we can make sure that there are no duplicates. This is required by the spec.

View file

@ -151,7 +151,9 @@ oxr_xrCreateActionSet(XrInstance instance,
{
struct oxr_action_set *act_set = NULL;
struct oxr_instance *inst = NULL;
struct u_hashset_item *d = NULL;
struct oxr_logger log;
int h_ret;
XrResult ret;
OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst,
"xrCreateActionSet");
@ -162,6 +164,34 @@ oxr_xrCreateActionSet(XrInstance instance,
&log, createInfo->actionSetName);
OXR_VERIFY_ARG_LOCALIZED_NAME(&log, createInfo->localizedActionSetName);
/*
* Dup checks.
*/
h_ret = u_hashset_find_c_str(inst->action_sets.name_store,
createInfo->actionSetName, &d);
if (h_ret >= 0) {
return oxr_error(
&log, XR_ERROR_NAME_DUPLICATED,
"(createInfo->actionSetName == '%s') is duplicated",
createInfo->actionSetName);
}
h_ret = u_hashset_find_c_str(inst->action_sets.loc_store,
createInfo->localizedActionSetName, &d);
if (h_ret >= 0) {
return oxr_error(&log, XR_ERROR_LOCALIZED_NAME_DUPLICATED,
"(createInfo->localizedActionSetName == '%s') "
"is duplicated",
createInfo->localizedActionSetName);
}
/*
* All ok.
*/
ret = oxr_action_set_create(&log, inst, createInfo, &act_set);
if (ret != XR_SUCCESS) {
return ret;
@ -196,9 +226,11 @@ oxr_xrCreateAction(XrActionSet actionSet,
XrAction *action)
{
struct oxr_action_set *act_set;
struct u_hashset_item *d = NULL;
struct oxr_action *act = NULL;
struct oxr_logger log;
XrResult ret;
int h_ret;
OXR_VERIFY_ACTIONSET_AND_INIT_LOG(&log, actionSet, act_set,
"xrCreateAction");
@ -218,6 +250,34 @@ oxr_xrCreateAction(XrActionSet actionSet,
return ret;
}
/*
* Dup checks.
*/
h_ret = u_hashset_find_c_str(act_set->actions.name_store,
createInfo->actionName, &d);
if (h_ret >= 0) {
return oxr_error(
&log, XR_ERROR_NAME_DUPLICATED,
"(createInfo->actionName == '%s') is duplicated",
createInfo->actionName);
}
h_ret = u_hashset_find_c_str(act_set->actions.loc_store,
createInfo->localizedActionName, &d);
if (h_ret >= 0) {
return oxr_error(&log, XR_ERROR_LOCALIZED_NAME_DUPLICATED,
"(createInfo->localizedActionName == '%s') "
"is duplicated",
createInfo->localizedActionName);
}
/*
* All ok.
*/
ret = oxr_action_create(&log, act_set, createInfo, &act);
if (ret != XR_SUCCESS) {
return ret;

View file

@ -89,6 +89,22 @@ oxr_action_set_destroy_cb(struct oxr_logger *log, struct oxr_handle_base *hb)
//! @todo Move to oxr_objects.h
struct oxr_action_set *act_set = (struct oxr_action_set *)hb;
if (act_set->name_item != NULL) {
u_hashset_erase_item(act_set->inst->action_sets.name_store,
act_set->name_item);
free(act_set->name_item);
act_set->name_item = NULL;
}
if (act_set->loc_item != NULL) {
u_hashset_erase_item(act_set->inst->action_sets.loc_store,
act_set->loc_item);
free(act_set->loc_item);
act_set->loc_item = NULL;
}
u_hashset_destroy(&act_set->actions.name_store);
u_hashset_destroy(&act_set->actions.loc_store);
free(act_set);
return XR_SUCCESS;
@ -102,18 +118,40 @@ oxr_action_set_create(struct oxr_logger *log,
{
// Mod music for all!
static uint32_t key_gen = 1;
int h_ret;
//! @todo Implement more fully.
struct oxr_action_set *act_set = NULL;
OXR_ALLOCATE_HANDLE_OR_RETURN(log, act_set, OXR_XR_DEBUG_ACTIONSET,
oxr_action_set_destroy_cb, &inst->handle);
h_ret = u_hashset_create(&act_set->actions.name_store);
if (h_ret != 0) {
oxr_handle_destroy(log, &act_set->handle);
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
"Failed to create name_store hashset");
}
h_ret = u_hashset_create(&act_set->actions.loc_store);
if (h_ret != 0) {
oxr_handle_destroy(log, &act_set->handle);
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
"Failed to create loc_store hashset");
}
act_set->key = key_gen++;
act_set->inst = inst;
strncpy(act_set->name, createInfo->actionSetName,
sizeof(act_set->name));
u_hashset_create_and_insert_str_c(inst->action_sets.name_store,
createInfo->actionSetName,
&act_set->name_item);
u_hashset_create_and_insert_str_c(inst->action_sets.loc_store,
createInfo->localizedActionSetName,
&act_set->loc_item);
*out_act_set = act_set;
return XR_SUCCESS;
@ -132,6 +170,19 @@ oxr_action_destroy_cb(struct oxr_logger *log, struct oxr_handle_base *hb)
//! @todo Move to oxr_objects.h
struct oxr_action *act = (struct oxr_action *)hb;
if (act->name_item != NULL) {
u_hashset_erase_item(act->act_set->actions.name_store,
act->name_item);
free(act->name_item);
act->name_item = NULL;
}
if (act->loc_item != NULL) {
u_hashset_erase_item(act->act_set->actions.loc_store,
act->loc_item);
free(act->loc_item);
act->loc_item = NULL;
}
free(act);
return XR_SUCCESS;
@ -163,6 +214,13 @@ oxr_action_create(struct oxr_logger *log,
strncpy(act->name, createInfo->actionName, sizeof(act->name));
u_hashset_create_and_insert_str_c(act_set->actions.name_store,
createInfo->actionName,
&act->name_item);
u_hashset_create_and_insert_str_c(act_set->actions.loc_store,
createInfo->localizedActionName,
&act->loc_item);
*out_act = act;
return XR_SUCCESS;

View file

@ -63,6 +63,9 @@ oxr_instance_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
oxr_path_destroy(log, inst);
u_hashset_destroy(&inst->action_sets.name_store);
u_hashset_destroy(&inst->action_sets.loc_store);
for (size_t i = 0; i < inst->system.num_xdevs; i++) {
oxr_xdev_destroy(&inst->system.xdevs[i]);
}
@ -102,7 +105,7 @@ oxr_instance_create(struct oxr_logger *log,
{
struct oxr_instance *inst = NULL;
struct xrt_device *xdevs[NUM_XDEVS] = {0};
int xinst_ret, m_ret;
int xinst_ret, m_ret, h_ret;
XrResult ret;
OXR_ALLOCATE_HANDLE_OR_RETURN(log, inst, OXR_XR_DEBUG_INSTANCE,
@ -129,6 +132,21 @@ oxr_instance_create(struct oxr_logger *log,
return ret;
}
h_ret = u_hashset_create(&inst->action_sets.name_store);
if (h_ret != 0) {
oxr_instance_destroy(log, &inst->handle);
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
"Failed to create name_store hashset");
}
h_ret = u_hashset_create(&inst->action_sets.loc_store);
if (h_ret != 0) {
oxr_instance_destroy(log, &inst->handle);
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
"Failed to create loc_store hashset");
}
// Cache certain often looked up paths.
// clang-format off
cache_path(log, inst, "/user", &inst->path_cache.user);

View file

@ -971,6 +971,12 @@ struct oxr_instance
struct time_state *timekeeping;
struct
{
struct u_hashset *name_store;
struct u_hashset *loc_store;
} action_sets;
//! Path store, for looking up paths.
struct u_hashset *path_store;
//! Mapping from ID to path.
@ -1392,6 +1398,18 @@ struct oxr_action_set
//! Unique key for the session hashmap.
uint32_t key;
//! The item in the name hashset.
struct u_hashset_item *name_item;
//! The item in the localized hashset.
struct u_hashset_item *loc_item;
struct
{
struct u_hashset *name_store;
struct u_hashset *loc_store;
} actions;
};
/*!
@ -1418,6 +1436,12 @@ struct oxr_action
//! Which sub action paths that this action was created with.
struct oxr_sub_paths sub_paths;
//! The item in the name hashset.
struct u_hashset_item *name_item;
//! The item in the localized hashset.
struct u_hashset_item *loc_item;
};
/*!