holopy3/Assets/SteamVR/Input/SteamVR_Input_ActionFile.cs
2020-12-10 15:25:12 +01:00

668 lines
No EOL
22 KiB
C#

//======= Copyright (c) Valve Corporation, All rights reserved. ===============
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Valve.Newtonsoft.Json;
using System.IO;
namespace Valve.VR
{
[System.Serializable]
public class SteamVR_Input_ActionFile
{
public List<SteamVR_Input_ActionFile_Action> actions = new List<SteamVR_Input_ActionFile_Action>();
public List<SteamVR_Input_ActionFile_ActionSet> action_sets = new List<SteamVR_Input_ActionFile_ActionSet>();
public List<SteamVR_Input_ActionFile_DefaultBinding> default_bindings = new List<SteamVR_Input_ActionFile_DefaultBinding>();
public List<Dictionary<string, string>> localization = new List<Dictionary<string, string>>();
[JsonIgnore]
public string filePath;
[JsonIgnore]
public List<SteamVR_Input_ActionFile_LocalizationItem> localizationHelperList = new List<SteamVR_Input_ActionFile_LocalizationItem>();
public void InitializeHelperLists()
{
foreach (var actionset in action_sets)
{
actionset.actionsInList = new List<SteamVR_Input_ActionFile_Action>(actions.Where(action => action.path.StartsWith(actionset.name) && SteamVR_Input_ActionFile_ActionTypes.listIn.Contains(action.type)));
actionset.actionsOutList = new List<SteamVR_Input_ActionFile_Action>(actions.Where(action => action.path.StartsWith(actionset.name) && SteamVR_Input_ActionFile_ActionTypes.listOut.Contains(action.type)));
actionset.actionsList = new List<SteamVR_Input_ActionFile_Action>(actions.Where(action => action.path.StartsWith(actionset.name)));
}
foreach (var item in localization)
{
localizationHelperList.Add(new SteamVR_Input_ActionFile_LocalizationItem(item));
}
}
public void SaveHelperLists()
{
//fix actions list
foreach (var actionset in action_sets)
{
actionset.actionsList.Clear();
actionset.actionsList.AddRange(actionset.actionsInList);
actionset.actionsList.AddRange(actionset.actionsOutList);
}
actions.Clear();
foreach (var actionset in action_sets)
{
actions.AddRange(actionset.actionsInList);
actions.AddRange(actionset.actionsOutList);
}
localization.Clear();
foreach (var item in localizationHelperList)
{
Dictionary<string, string> localizationItem = new Dictionary<string, string>();
localizationItem.Add(SteamVR_Input_ActionFile_LocalizationItem.languageTagKeyName, item.language);
foreach (var itemItem in item.items)
{
localizationItem.Add(itemItem.Key, itemItem.Value);
}
localization.Add(localizationItem);
}
}
public static string GetShortName(string name)
{
string fullName = name;
int lastSlash = fullName.LastIndexOf('/');
if (lastSlash != -1)
{
if (lastSlash == fullName.Length - 1)
{
fullName = fullName.Remove(lastSlash);
lastSlash = fullName.LastIndexOf('/');
if (lastSlash == -1)
{
return GetCodeFriendlyName(fullName);
}
}
return GetCodeFriendlyName(fullName.Substring(lastSlash + 1));
}
return GetCodeFriendlyName(fullName);
}
public static string GetCodeFriendlyName(string name)
{
name = name.Replace('/', '_').Replace(' ', '_');
if (char.IsLetter(name[0]) == false)
name = "_" + name;
for (int charIndex = 0; charIndex < name.Length; charIndex++)
{
if (char.IsLetterOrDigit(name[charIndex]) == false && name[charIndex] != '_')
{
name = name.Remove(charIndex, 1);
name = name.Insert(charIndex, "_");
}
}
return name;
}
public string[] GetFilesToCopy(bool throwErrors = false)
{
List<string> files = new List<string>();
FileInfo actionFileInfo = new FileInfo(this.filePath);
string path = actionFileInfo.Directory.FullName;
files.Add(this.filePath);
foreach (var binding in default_bindings)
{
string bindingPath = Path.Combine(path, binding.binding_url);
if (File.Exists(bindingPath))
files.Add(bindingPath);
else
{
if (throwErrors)
{
Debug.LogError("<b>[SteamVR]</b> Could not bind binding file specified by the actions.json manifest: " + bindingPath);
}
}
}
return files.ToArray();
}
public void CopyFilesToPath(string toPath, bool overwrite)
{
string[] files = SteamVR_Input.actionFile.GetFilesToCopy();
foreach (string file in files)
{
FileInfo bindingInfo = new FileInfo(file);
string newFilePath = Path.Combine(toPath, bindingInfo.Name);
bool exists = false;
if (File.Exists(newFilePath))
exists = true;
if (exists)
{
if (overwrite)
{
FileInfo existingFile = new FileInfo(newFilePath);
existingFile.IsReadOnly = false;
existingFile.Delete();
File.Copy(file, newFilePath);
RemoveAppKey(newFilePath);
Debug.Log("<b>[SteamVR]</b> Copied (overwrote) SteamVR Input file at path: " + newFilePath);
}
else
{
Debug.Log("<b>[SteamVR]</b> Skipped writing existing file at path: " + newFilePath);
}
}
else
{
File.Copy(file, newFilePath);
RemoveAppKey(newFilePath);
Debug.Log("<b>[SteamVR]</b> Copied SteamVR Input file to folder: " + newFilePath);
}
}
}
private const string findString_appKeyStart = "\"app_key\"";
private const string findString_appKeyEnd = "\",";
private static void RemoveAppKey(string newFilePath)
{
if (File.Exists(newFilePath))
{
string jsonText = System.IO.File.ReadAllText(newFilePath);
string findString = "\"app_key\"";
int stringStart = jsonText.IndexOf(findString);
if (stringStart == -1)
return; //no app key
int stringEnd = jsonText.IndexOf("\",", stringStart);
if (stringEnd == -1)
return; //no end?
stringEnd += findString_appKeyEnd.Length;
int stringLength = stringEnd - stringStart;
string newJsonText = jsonText.Remove(stringStart, stringLength);
FileInfo file = new FileInfo(newFilePath);
file.IsReadOnly = false;
File.WriteAllText(newFilePath, newJsonText);
}
}
public static SteamVR_Input_ActionFile Open(string path)
{
if (File.Exists(path))
{
string jsonText = File.ReadAllText(path);
SteamVR_Input_ActionFile actionFile = Valve.Newtonsoft.Json.JsonConvert.DeserializeObject<SteamVR_Input_ActionFile>(jsonText);
actionFile.filePath = path;
actionFile.InitializeHelperLists();
return actionFile;
}
return null;
}
public void Save(string path)
{
FileInfo existingActionsFile = new FileInfo(path);
if (existingActionsFile.Exists)
{
existingActionsFile.IsReadOnly = false;
}
//SanitizeActionFile(); //todo: shouldn't we be doing this?
string json = JsonConvert.SerializeObject(this, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
File.WriteAllText(path, json);
}
}
public enum SteamVR_Input_ActionFile_DefaultBinding_ControllerTypes
{
vive, //hmd
vive_pro, //hmd
vive_controller,
generic,
holographic_controller,
oculus_touch,
gamepad,
knuckles,
index_hmd, //hmd
vive_cosmos_controller,
rift, //hmd
vive_tracker_camera,
vive_tracker,
}
[System.Serializable]
public class SteamVR_Input_ActionFile_DefaultBinding
{
public string controller_type;
public string binding_url;
public SteamVR_Input_ActionFile_DefaultBinding GetCopy()
{
SteamVR_Input_ActionFile_DefaultBinding newDefaultBinding = new SteamVR_Input_ActionFile_DefaultBinding();
newDefaultBinding.controller_type = this.controller_type;
newDefaultBinding.binding_url = this.binding_url;
return newDefaultBinding;
}
}
[System.Serializable]
public class SteamVR_Input_ActionFile_ActionSet
{
[JsonIgnore]
private const string actionSetInstancePrefix = "instance_";
public string name;
public string usage;
[JsonIgnore]
public string codeFriendlyName
{
get
{
return SteamVR_Input_ActionFile.GetCodeFriendlyName(name);
}
}
[JsonIgnore]
public string shortName
{
get
{
int lastIndex = name.LastIndexOf('/');
if (lastIndex == name.Length - 1)
return string.Empty;
return SteamVR_Input_ActionFile.GetShortName(name);
}
}
public void SetNewShortName(string newShortName)
{
name = GetPathFromName(newShortName);
}
public static string CreateNewName()
{
return GetPathFromName("NewSet");
}
private const string nameTemplate = "/actions/{0}";
public static string GetPathFromName(string name)
{
return string.Format(nameTemplate, name);
}
public static SteamVR_Input_ActionFile_ActionSet CreateNew()
{
return new SteamVR_Input_ActionFile_ActionSet() { name = CreateNewName() };
}
public SteamVR_Input_ActionFile_ActionSet GetCopy()
{
SteamVR_Input_ActionFile_ActionSet newSet = new SteamVR_Input_ActionFile_ActionSet();
newSet.name = this.name;
newSet.usage = this.usage;
return newSet;
}
public override bool Equals(object obj)
{
if (obj is SteamVR_Input_ActionFile_ActionSet)
{
SteamVR_Input_ActionFile_ActionSet set = (SteamVR_Input_ActionFile_ActionSet)obj;
if (set == this)
return true;
if (set.name == this.name)
return true;
return false;
}
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
[JsonIgnore]
public List<SteamVR_Input_ActionFile_Action> actionsInList = new List<SteamVR_Input_ActionFile_Action>();
[JsonIgnore]
public List<SteamVR_Input_ActionFile_Action> actionsOutList = new List<SteamVR_Input_ActionFile_Action>();
[JsonIgnore]
public List<SteamVR_Input_ActionFile_Action> actionsList = new List<SteamVR_Input_ActionFile_Action>();
}
public enum SteamVR_Input_ActionFile_Action_Requirements
{
optional,
suggested,
mandatory,
}
[System.Serializable]
public class SteamVR_Input_ActionFile_Action
{
[JsonIgnore]
private static string[] _requirementValues;
[JsonIgnore]
public static string[] requirementValues
{
get
{
if (_requirementValues == null)
_requirementValues = System.Enum.GetNames(typeof(SteamVR_Input_ActionFile_Action_Requirements));
return _requirementValues;
}
}
public string name;
public string type;
public string scope;
public string skeleton;
public string requirement;
public SteamVR_Input_ActionFile_Action GetCopy()
{
SteamVR_Input_ActionFile_Action newAction = new SteamVR_Input_ActionFile_Action();
newAction.name = this.name;
newAction.type = this.type;
newAction.scope = this.scope;
newAction.skeleton = this.skeleton;
newAction.requirement = this.requirement;
return newAction;
}
[JsonIgnore]
public SteamVR_Input_ActionFile_Action_Requirements requirementEnum
{
get
{
for (int index = 0; index < requirementValues.Length; index++)
{
if (string.Equals(requirementValues[index], requirement, System.StringComparison.CurrentCultureIgnoreCase))
{
return (SteamVR_Input_ActionFile_Action_Requirements)index;
}
}
return SteamVR_Input_ActionFile_Action_Requirements.suggested;
}
set
{
requirement = value.ToString();
}
}
[JsonIgnore]
public string codeFriendlyName
{
get
{
return SteamVR_Input_ActionFile.GetCodeFriendlyName(name);
}
}
[JsonIgnore]
public string shortName
{
get
{
return SteamVR_Input_ActionFile.GetShortName(name);
}
}
[JsonIgnore]
public string path
{
get
{
int lastIndex = name.LastIndexOf('/');
if (lastIndex != -1 && lastIndex + 1 < name.Length)
{
return name.Substring(0, lastIndex + 1);
}
return name;
}
}
private const string nameTemplate = "/actions/{0}/{1}/{2}";
public static string CreateNewName(string actionSet, string direction)
{
return string.Format(nameTemplate, actionSet, direction, "NewAction");
}
public static string CreateNewName(string actionSet, SteamVR_ActionDirections direction, string actionName)
{
return string.Format(nameTemplate, actionSet, direction.ToString().ToLower(), actionName);
}
public static SteamVR_Input_ActionFile_Action CreateNew(string actionSet, SteamVR_ActionDirections direction, string actionType)
{
return new SteamVR_Input_ActionFile_Action() { name = CreateNewName(actionSet, direction.ToString().ToLower()), type = actionType };
}
[JsonIgnore]
public SteamVR_ActionDirections direction
{
get
{
if (type.ToLower() == SteamVR_Input_ActionFile_ActionTypes.vibration)
return SteamVR_ActionDirections.Out;
return SteamVR_ActionDirections.In;
}
}
protected const string prefix = "/actions/";
[JsonIgnore]
public string actionSet
{
get
{
int setEnd = name.IndexOf('/', prefix.Length);
if (setEnd == -1)
return string.Empty;
return name.Substring(0, setEnd);
}
}
public void SetNewActionSet(string newSetName)
{
name = string.Format(nameTemplate, newSetName, direction.ToString().ToLower(), shortName);
}
public override string ToString()
{
return shortName;
}
public override bool Equals(object obj)
{
if (obj is SteamVR_Input_ActionFile_Action)
{
SteamVR_Input_ActionFile_Action action = (SteamVR_Input_ActionFile_Action)obj;
if (this == obj)
return true;
if (this.name == action.name && this.type == action.type && this.skeleton == action.skeleton && this.requirement == action.requirement)
return true;
return false;
}
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
public class SteamVR_Input_ActionFile_LocalizationItem
{
public const string languageTagKeyName = "language_tag";
public string language;
public Dictionary<string, string> items = new Dictionary<string, string>();
public SteamVR_Input_ActionFile_LocalizationItem(string newLanguage)
{
language = newLanguage;
}
public SteamVR_Input_ActionFile_LocalizationItem(Dictionary<string, string> dictionary)
{
if (dictionary == null)
return;
if (dictionary.ContainsKey(languageTagKeyName))
language = (string)dictionary[languageTagKeyName];
else
Debug.Log("<b>[SteamVR]</b> Input: Error in actions file, no language_tag in localization array item.");
foreach (KeyValuePair<string, string> item in dictionary)
{
if (item.Key != languageTagKeyName)
items.Add(item.Key, (string)item.Value);
}
}
}
public class SteamVR_Input_ManifestFile
{
public string source;
public List<SteamVR_Input_ManifestFile_Application> applications;
}
public class SteamVR_Input_ManifestFile_Application
{
public string app_key;
public string launch_type;
public string url;
public string binary_path_windows;
public string binary_path_linux;
public string binary_path_osx;
public string action_manifest_path;
//public List<SteamVR_Input_ManifestFile_Application_Binding> bindings = new List<SteamVR_Input_ManifestFile_Application_Binding>();
public string image_path;
public Dictionary<string, SteamVR_Input_ManifestFile_ApplicationString> strings = new Dictionary<string, SteamVR_Input_ManifestFile_ApplicationString>();
}
public class SteamVR_Input_Unity_AssemblyFile_Definition
{
public string name = "SteamVR_Actions";
public string[] references = new string[] { "SteamVR" };
public string[] optionalUnityReferences = new string[0];
public string[] includePlatforms = new string[0];
public string[] excludePlatforms = new string[] { "Android" };
public bool allowUnsafeCode = false;
public bool overrideReferences = false;
public string[] precompiledReferences = new string[0];
public bool autoReferenced = false;
public string[] defineConstraints = new string[0];
}
public class SteamVR_Input_ManifestFile_ApplicationString
{
public string name;
}
public class SteamVR_Input_ManifestFile_Application_Binding
{
public string controller_type;
public string binding_url;
}
public class SteamVR_Input_ManifestFile_Application_Binding_ControllerTypes
{
public static string oculus_touch = "oculus_touch";
public static string vive_controller = "vive_controller";
public static string knuckles = "knuckles";
public static string holographic_controller = "holographic_controller";
public static string vive = "vive";
public static string vive_pro = "vive_pro";
public static string holographic_hmd = "holographic_hmd";
public static string rift = "rift";
public static string vive_tracker_camera = "vive_tracker_camera";
public static string vive_cosmos = "vive_cosmos";
public static string vive_cosmos_controller = "vive_cosmos_controller";
public static string index_hmd = "index_hmd";
}
static public class SteamVR_Input_ActionFile_ActionTypes
{
public static string boolean = "boolean";
public static string vector1 = "vector1";
public static string vector2 = "vector2";
public static string vector3 = "vector3";
public static string vibration = "vibration";
public static string pose = "pose";
public static string skeleton = "skeleton";
public static string skeletonLeftPath = "\\skeleton\\hand\\left";
public static string skeletonRightPath = "\\skeleton\\hand\\right";
public static string[] listAll = new string[] { boolean, vector1, vector2, vector3, vibration, pose, skeleton };
public static string[] listIn = new string[] { boolean, vector1, vector2, vector3, pose, skeleton };
public static string[] listOut = new string[] { vibration };
public static string[] listSkeletons = new string[] { skeletonLeftPath, skeletonRightPath };
}
static public class SteamVR_Input_ActionFile_ActionSet_Usages
{
public static string leftright = "leftright";
public static string single = "single";
public static string hidden = "hidden";
public static string leftrightDescription = "per hand";
public static string singleDescription = "mirrored";
public static string hiddenDescription = "hidden";
public static string[] listValues = new string[] { leftright, single, hidden };
public static string[] listDescriptions = new string[] { leftrightDescription, singleDescription, hiddenDescription };
}
}