private static void WriteCreateActionSpaceHelpers(StringBuilder sb, ActionSet actionSet, Action action, int indent, INamingConventionConverter conv) { Action <string> appendLineTrim = (string text) => sb.AppendLine(text.TrimEnd()); Action <string> appendLine = (string text) => appendLineTrim($"{new string(' ', indent * 4)}{text}"); Action <bool> addLineIfTrue = (bool condition) => { if (condition) { appendLineTrim(""); } }; Action <TopLevelPath> writeActionSpaceFunction = (TopLevelPath subactionPath) => { appendLine(""); appendLine($"XrResult {conv.Rename("Create", GetNameWithSubaction(action.Name, subactionPath), "ActionSpace")}(XrSession session, XrSpace* space) const"); appendLine("{"); indent++; appendLine($"XrActionSpaceCreateInfo actionSpaceInfo{{XR_TYPE_ACTION_SPACE_CREATE_INFO}};"); appendLine($"actionSpaceInfo.action = {GetActionHandleMemberName(action.Name, conv)};"); appendLine($"actionSpaceInfo.poseInActionSpace.orientation.w = 1.0f;"); if (subactionPath != TopLevelPath.Null) { appendLine($"actionSpaceInfo.subactionPath = {GetSubactionMemberName(subactionPath, conv)};"); } appendLine($"return xrCreateActionSpace(session, &actionSpaceInfo, space);"); indent--; appendLine("}"); }; foreach (var subaction in GetActionSubactionPaths(actionSet, action, includeNull: true)) { writeActionSpaceFunction(subaction); } }
private static string GetActionHandleMemberName(string actionName, INamingConventionConverter conv) => conv.Rename(actionName);
private static string GetActionSetStructName(ActionSet actionSet, INamingConventionConverter conv) => conv.Rename(actionSet.Name, "ActionSet");
private static string GetActionStateMemberName(Action action, TopLevelPath subactionPath, INamingConventionConverter conv) => conv.Rename(GetNameWithSubaction(action.Name, subactionPath), "ActionState");
public static string GetBindingVariableName(string bindingPath, INamingConventionConverter conv) => conv.Rename(bindingPath.Replace('/', '_'));
public static string GetInteractionProfileMemberName(string interactionProfilePath, INamingConventionConverter conv) => conv.Rename(interactionProfilePath.Replace("/interaction_profiles/", "").Replace('/', '_'));
public static string GetSuggestedBindingsMemberName(string interactionProfilePath, INamingConventionConverter conv) => conv.Rename(interactionProfilePath.Replace("/interaction_profiles/", "").Replace('/', '_'), "Bindings");
private static void WriteActionSetStateStruct(StringBuilder sb, ActionSet actionSet, int indent, INamingConventionConverter conv) { Action <string> appendLineTrim = (string text) => sb.AppendLine(text.TrimEnd()); Action <string> appendLine = (string text) => appendLineTrim($"{new string(' ', indent * 4)}{text}"); Action <bool> addLineIfTrue = (bool condition) => { if (condition) { appendLineTrim(""); } }; var inputActions = actionSet.Actions.Where(a => a.Type != ActionType.Haptic); var usedTopLevelPathsWithoutNull = inputActions.SelectMany(a => GetActionSubactionPaths(actionSet, a)).Distinct().OrderBy(s => s); appendLine(""); appendLine($"struct {conv.Rename("", actionSet.Name, "ActionStates")}"); appendLine("{"); indent++; // Write out a struct with all actions that have subactions enabled for per-subaction querying. bool hasSubactionPath = false; foreach (var action in inputActions.Where(a => a.UseSubactionPaths)) { if (!hasSubactionPath) { // Delay writing struct to here so it isn't written at all if there are no subaction paths. appendLine("struct SubactionStates"); appendLine("{"); indent++; hasSubactionPath = true; appendLine("XrPath SubactionPath = XR_NULL_PATH;"); } appendLine($"const {GetActionStateStructName(action.Type)}* {GetActionStateMemberName(action, TopLevelPath.Null, conv)} = nullptr;"); } if (hasSubactionPath) { indent--; appendLine("};"); appendLine(""); } appendLine($"XrResult UpdateActionStates(XrSession session, {GetActionSetStructName(actionSet, conv)} const& actionSet)"); appendLine("{"); indent++; appendLine("XrActionStateGetInfo actionStateGetInfo{XR_TYPE_ACTION_STATE_GET_INFO};"); appendLine("XrResult result = XR_SUCCESS;"); foreach (var action in inputActions) { foreach (var subaction in GetActionSubactionPaths(actionSet, action, includeNull: true)) { appendLine(""); appendLine("if (XR_SUCCEEDED(result))"); appendLine("{"); indent++; appendLine($"actionStateGetInfo.action = actionSet.{GetActionHandleMemberName(action.Name, conv)};"); if (action.UseSubactionPaths) { appendLine($"actionStateGetInfo.subactionPath = actionSet.{GetSubactionMemberName(subaction, conv)};"); } else { appendLine($"actionStateGetInfo.subactionPath = XR_NULL_PATH;"); } appendLine($"result = {GetActionStateUpdateFunction(action.Type)}(session, &actionStateGetInfo, &{GetActionStateMemberName(action, subaction, conv)});"); indent--; appendLine("}"); } } appendLine("return result;"); indent--; appendLine("}"); // Write function to get the action states for a specific subaction path. if (usedTopLevelPathsWithoutNull.Any()) { appendLine(""); appendLine($"SubactionStates GetSubactionStates({GetActionSetStructName(actionSet, conv)} const& actionSet, XrPath subactionPath) const"); appendLine("{"); indent++; bool firstCase = true; foreach (var subactionPath in usedTopLevelPathsWithoutNull) { appendLine($"{(firstCase ? "" : "else ")}if (subactionPath == actionSet.{GetSubactionMemberName(subactionPath, conv)})"); appendLine("{"); indent++; var subactionMemberVariables = inputActions .Where(a => a.UseSubactionPaths) .Select(a => { bool hasThisSubactionBinding = GetActionSubactionPaths(actionSet, a).Any(s => s == subactionPath); return(hasThisSubactionBinding ? ("&" + GetActionStateMemberName(a, subactionPath, conv)) : "nullptr"); }); appendLine($"return {{subactionPath, {string.Join(", ", subactionMemberVariables)}}};"); indent--; appendLine("}"); firstCase = false; } appendLine("else"); appendLine("{"); indent++; appendLine("return {}; // Unknown subaction path."); indent--; appendLine("}"); indent--; appendLine("}"); } appendLine(""); foreach (var action in inputActions) { foreach (var subaction in GetActionSubactionPaths(actionSet, action, includeNull: true)) { appendLine($"{GetActionStateStructName(action.Type)} {GetActionStateMemberName(action, subaction, conv)}{{{GetActionStateStructType(action.Type)}}};"); } } // Write out per-subaction path member struct shortcuts. /*addLineIfTrue(usedTopLevelPathsWithoutNull.Any()); * foreach (var subactionPath in usedTopLevelPathsWithoutNull) * { * appendLine($"SubactionStates {GetSubactionMemberName(subactionPath, conv)};"); * }*/ indent--; appendLine("};"); }
private static void WriteActionSetStruct(StringBuilder sb, ActionSet actionSet, int indent, INamingConventionConverter conv) { Action <string> appendLineTrim = (string text) => sb.AppendLine(text.TrimEnd()); Action <string> appendLine = (string text) => appendLineTrim($"{new string(' ', indent * 4)}{text}"); Action <bool> addLineIfTrue = (bool condition) => { if (condition) { appendLineTrim(""); } }; appendLine(""); appendLine($"struct {GetActionSetStructName(actionSet, conv)}"); appendLine("{"); indent++; appendLine($"~{GetActionSetStructName(actionSet, conv)}()"); appendLine("{"); indent++; appendLine("if (ActionSet != XR_NULL_HANDLE)"); appendLine("{"); indent++; appendLine("(void)xrDestroyActionSet(ActionSet);"); indent--; appendLine("}"); indent--; appendLine("}"); appendLine(""); WriteActionSetInitializeMethod(sb, actionSet, indent, conv); foreach (var action in actionSet.Actions) { if (action.Type != ActionType.Pose) { continue; } WriteCreateActionSpaceHelpers(sb, actionSet, action, indent, conv); } appendLine(""); appendLine($"XrActionSet {conv.Rename("ActionSet")}{{XR_NULL_HANDLE}};"); appendLine(""); foreach (var action in actionSet.Actions) { appendLine($"XrAction {GetActionHandleMemberName(action.Name, conv)}{{XR_NULL_HANDLE}};"); } // Write out the used subaction paths. var usedTopLevelPathsWithoutNull = actionSet.Actions.SelectMany(a => GetActionSubactionPaths(actionSet, a)).ToHashSet(); addLineIfTrue(usedTopLevelPathsWithoutNull.Any()); foreach (var subactionPath in usedTopLevelPathsWithoutNull) { appendLine($"XrPath {GetSubactionMemberName(subactionPath, conv)}{{XR_NULL_PATH}};"); } indent--; appendLine("};"); }