mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-19 21:28:50 +00:00
st/oxr: Respect action set priority for exact matching inputs
* Only suppress action when synced actionset has relevant subpath
This commit is contained in:
parent
4c8e3eb95f
commit
983665d95c
|
@ -49,13 +49,19 @@ oxr_session_get_action_attachment(
|
||||||
static void
|
static void
|
||||||
oxr_action_cache_update(struct oxr_logger *log,
|
oxr_action_cache_update(struct oxr_logger *log,
|
||||||
struct oxr_session *sess,
|
struct oxr_session *sess,
|
||||||
|
uint32_t countActionSets,
|
||||||
|
const XrActiveActionSet *actionSets,
|
||||||
|
struct oxr_action_attachment *act_attached,
|
||||||
struct oxr_action_cache *cache,
|
struct oxr_action_cache *cache,
|
||||||
int64_t time,
|
int64_t time,
|
||||||
|
struct oxr_sub_paths *sub_path,
|
||||||
bool select);
|
bool select);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
oxr_action_attachment_update(struct oxr_logger *log,
|
oxr_action_attachment_update(struct oxr_logger *log,
|
||||||
struct oxr_session *sess,
|
struct oxr_session *sess,
|
||||||
|
uint32_t countActionSets,
|
||||||
|
const XrActiveActionSet *actionSets,
|
||||||
struct oxr_action_attachment *act_attached,
|
struct oxr_action_attachment *act_attached,
|
||||||
int64_t time,
|
int64_t time,
|
||||||
struct oxr_sub_paths sub_paths);
|
struct oxr_sub_paths sub_paths);
|
||||||
|
@ -69,6 +75,13 @@ oxr_action_bind_inputs(struct oxr_logger *log,
|
||||||
struct oxr_interaction_profile *profile,
|
struct oxr_interaction_profile *profile,
|
||||||
enum oxr_sub_action_path sub_path);
|
enum oxr_sub_action_path sub_path);
|
||||||
|
|
||||||
|
static void
|
||||||
|
oxr_session_get_action_set_attachment(
|
||||||
|
struct oxr_session *sess,
|
||||||
|
XrActionSet actionSet,
|
||||||
|
struct oxr_action_set_attachment **act_set_attached,
|
||||||
|
struct oxr_action_set **act_set);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Action attachment functions
|
* Action attachment functions
|
||||||
|
@ -287,6 +300,8 @@ oxr_action_set_create(struct oxr_logger *log,
|
||||||
createInfo->localizedActionSetName,
|
createInfo->localizedActionSetName,
|
||||||
&act_set->loc_item);
|
&act_set->loc_item);
|
||||||
|
|
||||||
|
act_set_ref->priority = createInfo->priority;
|
||||||
|
|
||||||
*out_act_set = act_set;
|
*out_act_set = act_set;
|
||||||
|
|
||||||
return XR_SUCCESS;
|
return XR_SUCCESS;
|
||||||
|
@ -720,12 +735,113 @@ oxr_action_cache_stop_output(struct oxr_logger *log,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
oxr_input_combine_input(struct oxr_action_input *inputs,
|
oxr_input_is_input_for_cache(struct oxr_action_input *action_input,
|
||||||
size_t num_inputs,
|
struct oxr_action_cache *cache)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < cache->num_inputs; i++) {
|
||||||
|
if (action_input->bound_path == cache->inputs[i].bound_path) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
oxr_input_is_bound_in_act_set(
|
||||||
|
struct oxr_action_input *action_input,
|
||||||
|
struct oxr_action_set_attachment *act_set_attached)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < act_set_attached->num_action_attachments; i++) {
|
||||||
|
struct oxr_action_attachment *act_attached =
|
||||||
|
&act_set_attached->act_attachments[i];
|
||||||
|
|
||||||
|
#define ACCUMULATE_PATHS(X) \
|
||||||
|
if (oxr_input_is_input_for_cache(action_input, &act_attached->X)) { \
|
||||||
|
return true; \
|
||||||
|
}
|
||||||
|
OXR_FOR_EACH_SUBACTION_PATH(ACCUMULATE_PATHS)
|
||||||
|
#undef ACCUMULATE_PATHS
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
oxr_input_supressed(struct oxr_session *sess,
|
||||||
|
uint32_t countActionSets,
|
||||||
|
const XrActiveActionSet *actionSets,
|
||||||
|
struct oxr_sub_paths *sub_path,
|
||||||
|
struct oxr_action_attachment *act_attached,
|
||||||
|
struct oxr_action_input *action_input)
|
||||||
|
{
|
||||||
|
struct oxr_action_set_ref *act_set_ref =
|
||||||
|
act_attached->act_set_attached->act_set_ref;
|
||||||
|
uint32_t priority = act_set_ref->priority;
|
||||||
|
|
||||||
|
// find sources that are bound to an action in a set with higher prio
|
||||||
|
for (uint32_t i = 0; i < countActionSets; i++) {
|
||||||
|
XrActionSet set = actionSets[i].actionSet;
|
||||||
|
|
||||||
|
struct oxr_action_set *other_act_set = NULL;
|
||||||
|
struct oxr_action_set_attachment *other_act_set_attached = NULL;
|
||||||
|
oxr_session_get_action_set_attachment(
|
||||||
|
sess, set, &other_act_set_attached, &other_act_set);
|
||||||
|
|
||||||
|
if (other_act_set_attached == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip the action set that the current action is in */
|
||||||
|
if (other_act_set_attached->act_set_ref == act_set_ref) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* input may be suppressed by action set with higher prio */
|
||||||
|
if (other_act_set_attached->act_set_ref->priority <= priority) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Currently updated input source with subpath X can be
|
||||||
|
* suppressed, if input source also occurs in action set with
|
||||||
|
* higher priority if
|
||||||
|
* - high prio set syncs w/ ANY subpath or
|
||||||
|
* - high prio set syncs w/ subpath matching this input subpath
|
||||||
|
*/
|
||||||
|
bool relevant_subpath =
|
||||||
|
other_act_set_attached->requested_sub_paths.any;
|
||||||
|
|
||||||
|
#define ACCUMULATE_PATHS(X) \
|
||||||
|
relevant_subpath |= \
|
||||||
|
(other_act_set_attached->requested_sub_paths.X && sub_path->X);
|
||||||
|
OXR_FOR_EACH_SUBACTION_PATH(ACCUMULATE_PATHS)
|
||||||
|
#undef ACCUMULATE_PATHS
|
||||||
|
|
||||||
|
if (!relevant_subpath) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oxr_input_is_bound_in_act_set(action_input,
|
||||||
|
other_act_set_attached)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
oxr_input_combine_input(struct oxr_session *sess,
|
||||||
|
uint32_t countActionSets,
|
||||||
|
const XrActiveActionSet *actionSets,
|
||||||
|
struct oxr_action_attachment *act_attached,
|
||||||
|
struct oxr_sub_paths *sub_path,
|
||||||
|
struct oxr_action_cache *cache,
|
||||||
struct oxr_input_value_tagged *out_input,
|
struct oxr_input_value_tagged *out_input,
|
||||||
int64_t *timestamp,
|
int64_t *timestamp,
|
||||||
bool *is_active)
|
bool *is_active)
|
||||||
{
|
{
|
||||||
|
struct oxr_action_input *inputs = cache->inputs;
|
||||||
|
size_t num_inputs = cache->num_inputs;
|
||||||
|
|
||||||
if (num_inputs == 0) {
|
if (num_inputs == 0) {
|
||||||
*is_active = false;
|
*is_active = false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -739,6 +855,13 @@ oxr_input_combine_input(struct oxr_action_input *inputs,
|
||||||
struct oxr_action_input *action_input = &(inputs[i]);
|
struct oxr_action_input *action_input = &(inputs[i]);
|
||||||
struct xrt_input *input = action_input->input;
|
struct xrt_input *input = action_input->input;
|
||||||
|
|
||||||
|
// suppress input if it is also bound to action in set with
|
||||||
|
// higher priority
|
||||||
|
if (oxr_input_supressed(sess, countActionSets, actionSets,
|
||||||
|
sub_path, act_attached, action_input)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (input->active) {
|
if (input->active) {
|
||||||
any_active = true;
|
any_active = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -822,8 +945,12 @@ oxr_input_combine_input(struct oxr_action_input *inputs,
|
||||||
static void
|
static void
|
||||||
oxr_action_cache_update(struct oxr_logger *log,
|
oxr_action_cache_update(struct oxr_logger *log,
|
||||||
struct oxr_session *sess,
|
struct oxr_session *sess,
|
||||||
|
uint32_t countActionSets,
|
||||||
|
const XrActiveActionSet *actionSets,
|
||||||
|
struct oxr_action_attachment *act_attached,
|
||||||
struct oxr_action_cache *cache,
|
struct oxr_action_cache *cache,
|
||||||
int64_t time,
|
int64_t time,
|
||||||
|
struct oxr_sub_paths *sub_path,
|
||||||
bool selected)
|
bool selected)
|
||||||
{
|
{
|
||||||
struct oxr_action_state last = cache->current;
|
struct oxr_action_state last = cache->current;
|
||||||
|
@ -846,8 +973,14 @@ oxr_action_cache_update(struct oxr_logger *log,
|
||||||
if (cache->stop_output_time < time) {
|
if (cache->stop_output_time < time) {
|
||||||
oxr_action_cache_stop_output(log, sess, cache);
|
oxr_action_cache_stop_output(log, sess, cache);
|
||||||
}
|
}
|
||||||
} else if (oxr_input_combine_input(cache->inputs, cache->num_inputs,
|
} else if (cache->num_inputs > 0) {
|
||||||
&combined, ×tamp, &is_active)) {
|
|
||||||
|
if (!oxr_input_combine_input(
|
||||||
|
sess, countActionSets, actionSets, act_attached,
|
||||||
|
sub_path, cache, &combined, ×tamp, &is_active)) {
|
||||||
|
oxr_log(log, "Failed to get/combine input values");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If the input is not active signal that.
|
// If the input is not active signal that.
|
||||||
if (!is_active) {
|
if (!is_active) {
|
||||||
|
@ -952,6 +1085,8 @@ oxr_action_cache_update(struct oxr_logger *log,
|
||||||
static void
|
static void
|
||||||
oxr_action_attachment_update(struct oxr_logger *log,
|
oxr_action_attachment_update(struct oxr_logger *log,
|
||||||
struct oxr_session *sess,
|
struct oxr_session *sess,
|
||||||
|
uint32_t countActionSets,
|
||||||
|
const XrActiveActionSet *actionSets,
|
||||||
struct oxr_action_attachment *act_attached,
|
struct oxr_action_attachment *act_attached,
|
||||||
int64_t time,
|
int64_t time,
|
||||||
struct oxr_sub_paths sub_paths)
|
struct oxr_sub_paths sub_paths)
|
||||||
|
@ -964,8 +1099,12 @@ oxr_action_attachment_update(struct oxr_logger *log,
|
||||||
//! @todo "/user" sub-action path.
|
//! @todo "/user" sub-action path.
|
||||||
|
|
||||||
#define UPDATE_SELECT(X) \
|
#define UPDATE_SELECT(X) \
|
||||||
|
struct oxr_sub_paths sub_paths_##X = {0}; \
|
||||||
|
sub_paths_##X.X = true; \
|
||||||
bool select_##X = sub_paths.X || sub_paths.any; \
|
bool select_##X = sub_paths.X || sub_paths.any; \
|
||||||
oxr_action_cache_update(log, sess, &act_attached->X, time, select_##X);
|
oxr_action_cache_update(log, sess, countActionSets, actionSets, \
|
||||||
|
act_attached, &act_attached->X, time, \
|
||||||
|
&sub_paths_##X, select_##X);
|
||||||
|
|
||||||
OXR_FOR_EACH_VALID_SUBACTION_PATH(UPDATE_SELECT)
|
OXR_FOR_EACH_VALID_SUBACTION_PATH(UPDATE_SELECT)
|
||||||
#undef UPDATE_SELECT
|
#undef UPDATE_SELECT
|
||||||
|
@ -1324,12 +1463,12 @@ oxr_action_sync_data(struct oxr_logger *log,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
oxr_action_attachment_update(log, sess, act_attached,
|
oxr_action_attachment_update(log, sess, countActionSets,
|
||||||
|
actionSets, act_attached,
|
||||||
now, sub_paths);
|
now, sub_paths);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return oxr_session_success_focused_result(sess);
|
return oxr_session_success_focused_result(sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1728,6 +1728,9 @@ struct oxr_action_set_ref
|
||||||
//! Unique key for the session hashmap.
|
//! Unique key for the session hashmap.
|
||||||
uint32_t act_set_key;
|
uint32_t act_set_key;
|
||||||
|
|
||||||
|
//! Application supplied action set priority.
|
||||||
|
uint32_t priority;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
struct u_hashset *name_store;
|
struct u_hashset *name_store;
|
||||||
|
|
Loading…
Reference in a new issue