123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using UnityEditor;
- using UnityEngine;
- using System.CodeDom;
- using Microsoft.CSharp;
- using System.IO;
- using System.CodeDom.Compiler;
- using System.Reflection;
- using System.Linq.Expressions;
- using UnityEditor.SceneManagement;
- using UnityEditor.Callbacks;
- using Valve.Newtonsoft.Json;
- namespace Valve.VR
- {
- #pragma warning disable 0219 // variable assigned but not used.
- public static class SteamVR_Input_Generator
- {
- public const string steamVRInputOverwriteBuildKey = "SteamVR_Input_OverwriteBuild";
- public const string steamVRInputDeleteUnusedKey = "SteamVR_Input_DeleteUnused";
- private const string actionSetClassNamePrefix = "SteamVR_Input_ActionSet_";
- public const string generationNeedsReloadKey = "SteamVR_Input_GenerationNeedsReload";
- private const string progressBarTitle = "SteamVR Input Generation";
- public const string steamVRInputActionSetClassesFolder = "ActionSetClasses";
- public const string steamVRInputActionsClass = "SteamVR_Input_Actions";
- public const string steamVRInputActionSetsClass = "SteamVR_Input_ActionSets";
- public const string steamVRInputInitializationClass = "SteamVR_Input_Initialization";
- public const string steamVRActionsAssemblyDefinition = "SteamVR_Actions";
- private static bool generating = false;
- public static void BeginGeneration()
- {
- generating = true;
- fileChanged = false;
- SteamVR_Input_EditorWindow.SetProgressBarText("Beginning generation...", 0);
- GenerationStep_CreateActionSetClasses();
- GenerationStep_CreateHelperClasses();
- GenerationStep_CreateInitClass();
- GenerationStep_CreateAssemblyDefinition();
- DeleteUnusedScripts();
- if (fileChanged)
- EditorPrefs.SetBool(generationNeedsReloadKey, true);
- AssetDatabase.Refresh();
- SteamVR_Input_EditorWindow.ClearProgressBar();
- generating = false;
- }
- [DidReloadScripts]
- private static void OnReload()
- {
- bool didGenerate = EditorPrefs.GetBool(generationNeedsReloadKey);
- if (didGenerate)
- {
- EditorPrefs.SetBool(generationNeedsReloadKey, false);
- if (string.IsNullOrEmpty(EditorSceneManager.GetActiveScene().path) == false)
- EditorApplication.delayCall += ReloadScene;
- }
- }
- public static void ReloadScene()
- {
- EditorPrefs.SetBool(generationNeedsReloadKey, false);
- if (string.IsNullOrEmpty(EditorSceneManager.GetActiveScene().path) == false)
- {
- if (EditorSceneManager.GetActiveScene().isDirty)
- {
- EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo();
- }
- string previousPath = EditorSceneManager.GetActiveScene().path;
- EditorSceneManager.NewScene(NewSceneSetup.EmptyScene);
- EditorSceneManager.OpenScene(previousPath); //reload open scene to avoid any weird serialization
- }
- }
- public static bool IsGenerating()
- {
- return generating;
- }
- public static void CancelGeneration()
- {
- generating = false;
- }
- private static List<CodeTypeDeclaration> setClasses = new List<CodeTypeDeclaration>();
- private static void GenerationStep_CreateInitClass()
- {
- CodeCompileUnit compileUnit = new CodeCompileUnit();
- CodeTypeDeclaration inputClass = CreatePartialInputClass(compileUnit);
- CodeMemberMethod preinitMethod = CreateStaticMethod(inputClass, SteamVR_Input_Generator_Names.preinitializeMethodName, true);
- string steamVRInputClassName = typeof(SteamVR_Input).Name;
- AddStaticInvokeToMethod(preinitMethod, SteamVR_Input_Generator_Names.actionsClassName, startPreInitActionSetsMethodName);
- AddStaticInvokeToMethod(preinitMethod, steamVRInputClassName, initializeActionSetDictionariesMethodName);
- AddStaticInvokeToMethod(preinitMethod, SteamVR_Input_Generator_Names.actionsClassName, preInitActionsMethodName);
- AddStaticInvokeToMethod(preinitMethod, SteamVR_Input_Generator_Names.actionsClassName, initializeActionsArraysMethodName);
- AddStaticInvokeToMethod(preinitMethod, steamVRInputClassName, initializeActionDictionariesMethodName);
- AddStaticInvokeToMethod(preinitMethod, steamVRInputClassName, finishPreInitActionSetsMethodName);
- // Build the output file name.
- string fullSourceFilePath = GetSourceFilePath(steamVRInputInitializationClass);
- CreateFile(fullSourceFilePath, compileUnit);
- }
- private static void GenerationStep_CreateAssemblyDefinition()
- {
- string fullSourceFilePath = GetSourceFilePath(steamVRActionsAssemblyDefinition, ".asmdef");
- if (File.Exists(fullSourceFilePath) == false)
- {
- SteamVR_Input_Unity_AssemblyFile_Definition actionsAssemblyDefinitionData = new SteamVR_Input_Unity_AssemblyFile_Definition();
- actionsAssemblyDefinitionData.autoReferenced = true;
- string jsonText = JsonConvert.SerializeObject(actionsAssemblyDefinitionData, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Include });
- File.WriteAllText(fullSourceFilePath, jsonText);
- }
- }
- private static void GenerationStep_CreateActionSetClasses()
- {
- SteamVR_Input_EditorWindow.SetProgressBarText("Generating action set classes...", 0.25f);
- SteamVR_Input.InitializeFile();
- CreateActionsSubFolder();
- setClasses = GenerateActionSetClasses();
- Debug.LogFormat("<b>[SteamVR Input]</b> Created input script set classes: {0}", setClasses.Count);
- }
- private static void GenerationStep_CreateHelperClasses()
- {
- SteamVR_Input_EditorWindow.SetProgressBarText("Generating actions and actionsets classes...", 0.5f);
- GenerateActionHelpers(steamVRInputActionsClass);
- GenerateActionSetsHelpers(steamVRInputActionSetsClass);
- string actionsFullpath = Path.Combine(GetClassPath(), steamVRInputActionsClass + ".cs");
- string actionSetsFullpath = Path.Combine(GetClassPath(), steamVRInputActionSetsClass + ".cs");
- Debug.LogFormat("<b>[SteamVR Input]</b> Created input script main classes: {0} and {1}", actionsFullpath, actionSetsFullpath);
- }
- private static void DeleteUnusedScripts()
- {
- string folderPath = GetSubFolderPath();
- string[] files = Directory.GetFiles(folderPath);
- List<string> toDelete = new List<string>();
- for (int fileIndex = 0; fileIndex < files.Length; fileIndex++)
- {
- FileInfo file = new FileInfo(files[fileIndex]);
- if (file.Name.EndsWith(".cs") || file.Name.EndsWith(".cs.meta"))
- {
- bool isSet = false;
- if (SteamVR_Input.actionFile.action_sets.Any(set => string.Equals(GetSetClassName(set) + ".cs", file.Name, StringComparison.CurrentCultureIgnoreCase) ||
- string.Equals(GetSetClassName(set) + ".cs.meta", file.Name, StringComparison.CurrentCultureIgnoreCase)))
- {
- isSet = true;
- }
- bool isAction = false;
- if (SteamVR_Input.actionFile.actions.Any(action => string.Equals(action.codeFriendlyName + ".cs", file.Name, StringComparison.CurrentCultureIgnoreCase) ||
- string.Equals(action.codeFriendlyName + ".cs.meta", file.Name, StringComparison.CurrentCultureIgnoreCase)))
- {
- isAction = true;
- }
- if (isSet == false && isAction == false)
- {
- toDelete.Add(files[fileIndex]);
- }
- }
- }
- if (toDelete.Count > 0)
- {
- string filesToDelete = "";
- foreach (string file in toDelete)
- filesToDelete += file + "\n";
- bool confirm = EditorUtility.DisplayDialog("SteamVR Input", "Would you like to delete the following unused input files:\n" + filesToDelete, "Delete", "No");
- if (confirm)
- {
- foreach (string fileName in toDelete)
- {
- FileInfo file = new FileInfo(fileName);
- file.IsReadOnly = false;
- file.Delete();
- }
- }
- }
- }
- private static void CreateActionsSubFolder()
- {
- string folderPath = GetSubFolderPath();
- if (Directory.Exists(folderPath) == false)
- {
- Directory.CreateDirectory(folderPath);
- }
- }
- public static void DeleteActionClassFiles()
- {
- DeleteActionClass(steamVRInputActionsClass);
- DeleteActionClass(steamVRInputActionSetsClass);
- string folderPath = GetSubFolderPath();
- bool confirm = EditorUtility.DisplayDialog("Confirmation", "Are you absolutely sure you want to delete all code files in " + folderPath + "?", "Delete", "Cancel");
- if (confirm)
- {
- DeleteActionObjects("*.cs*");
- }
- }
- public static void DeleteGeneratedFolder()
- {
- string generatedFolderPath = GetClassPath();
- string subFolderPath = GetSubFolderPath();
- bool confirm = EditorUtility.DisplayDialog("Confirmation", "Are you absolutely sure you want to delete all code files in " + generatedFolderPath + "?", "Delete", "Cancel");
- if (confirm)
- {
- DeleteActionObjects("*.cs*", generatedFolderPath);
- DeleteActionObjects("*.cs*", subFolderPath);
- }
- }
- public static void DeleteActionObjects(string filter, string folderPath = null)
- {
- if (folderPath == null)
- folderPath = GetSubFolderPath();
- string[] assets = Directory.GetFiles(folderPath, filter);
- for (int assetIndex = 0; assetIndex < assets.Length; assetIndex++)
- {
- AssetDatabase.DeleteAsset(assets[assetIndex]);
- }
- Debug.LogFormat("<b>[SteamVR Input]</b> Deleted {0} files at path: {1}", assets.Length, folderPath);
- }
- private static void DeleteActionClass(string className)
- {
- string filePath = GetSourceFilePath(className);
- if (File.Exists(filePath) == true)
- {
- AssetDatabase.DeleteAsset(filePath);
- Debug.Log("<b>[SteamVR Input]</b> Deleted: " + filePath);
- }
- else
- {
- Debug.Log("<b>[SteamVR Input]</b> No file found at: " + filePath);
- }
- }
- private static string GetTypeStringForAction(SteamVR_Input_ActionFile_Action action)
- {
- return GetTypeForAction(action).Name;
- }
- private static Type GetTypeForAction(SteamVR_Input_ActionFile_Action action)
- {
- string actionType = action.type.ToLower();
- if (SteamVR_Input_ActionFile_ActionTypes.boolean == actionType)
- {
- return typeof(SteamVR_Action_Boolean);
- }
- if (SteamVR_Input_ActionFile_ActionTypes.vector1 == actionType)
- {
- return typeof(SteamVR_Action_Single);
- }
- if (SteamVR_Input_ActionFile_ActionTypes.vector2 == actionType)
- {
- return typeof(SteamVR_Action_Vector2);
- }
- if (SteamVR_Input_ActionFile_ActionTypes.vector3 == actionType)
- {
- return typeof(SteamVR_Action_Vector3);
- }
- if (SteamVR_Input_ActionFile_ActionTypes.pose == actionType)
- {
- return typeof(SteamVR_Action_Pose);
- }
- if (SteamVR_Input_ActionFile_ActionTypes.skeleton == actionType)
- {
- return typeof(SteamVR_Action_Skeleton);
- }
- if (SteamVR_Input_ActionFile_ActionTypes.vibration == actionType)
- {
- return typeof(SteamVR_Action_Vibration);
- }
- throw new System.Exception("unknown type (" + action.type + ") in actions file for action: " + action.name);
- }
- private static string GetClassPath()
- {
- string path = Path.Combine(SteamVR.GetSteamVRFolderParentPath(), SteamVR_Settings.instance.steamVRInputPath);
- if (Directory.Exists(path) == false)
- Directory.CreateDirectory(path);
- return path;
- }
- private static string GetSubFolderPath()
- {
- return Path.Combine(GetClassPath(), steamVRInputActionSetClassesFolder);
- }
- private static string GetSourceFilePath(string classname, string suffix = ".cs")
- {
- string sourceFileName = string.Format("{0}{1}", classname, suffix);
- return Path.Combine(GetClassPath(), sourceFileName);
- }
- private static bool fileChanged = false;
- private static void CreateFile(string fullPath, CodeCompileUnit compileUnit)
- {
- // Generate the code with the C# code provider.
- CSharpCodeProvider provider = new CSharpCodeProvider();
- // Build the output file name.
- string fullSourceFilePath = fullPath;
- //Debug.Log("[SteamVR] Writing class to: " + fullSourceFilePath);
- string path = GetClassPath();
- string priorMD5 = null;
- FileInfo file = new FileInfo(fullSourceFilePath);
- if (file.Exists)
- {
- file.IsReadOnly = false;
- priorMD5 = SteamVR_Utils.GetBadMD5HashFromFile(fullSourceFilePath);
- }
- // Create a TextWriter to a StreamWriter to the output file.
- using (StreamWriter sw = new StreamWriter(fullSourceFilePath, false))
- {
- IndentedTextWriter tw = new IndentedTextWriter(sw, " ");
- // Generate source code using the code provider.
- provider.GenerateCodeFromCompileUnit(compileUnit, tw,
- new CodeGeneratorOptions() { BracingStyle = "C" });
- // Close the output file.
- tw.Close();
- string newMD5 = SteamVR_Utils.GetBadMD5HashFromFile(fullSourceFilePath);
- if (priorMD5 != newMD5)
- fileChanged = true;
- }
- //Debug.Log("[SteamVR] Complete! Input class at: " + fullSourceFilePath);
- }
- private const string getActionMethodParamName = "path";
- private const string skipStateUpdatesParamName = "skipStateAndEventUpdates";
- private static List<CodeTypeDeclaration> GenerateActionSetClasses()
- {
- List<CodeTypeDeclaration> setClasses = new List<CodeTypeDeclaration>();
- for (int actionSetIndex = 0; actionSetIndex < SteamVR_Input.actionFile.action_sets.Count; actionSetIndex++)
- {
- SteamVR_Input_ActionFile_ActionSet actionSet = SteamVR_Input.actionFile.action_sets[actionSetIndex];
- CodeTypeDeclaration setClass = CreateActionSetClass(actionSet);
- setClasses.Add(setClass);
- }
- return setClasses;
- }
- private const string initializeActionDictionariesMethodName = "PreinitializeActionDictionaries";
- private const string initializeActionSetDictionariesMethodName = "PreinitializeActionSetDictionaries";
- private const string preInitActionsMethodName = "PreInitActions";
- private const string initializeActionsArraysMethodName = "InitializeActionArrays";
- private static void GenerateActionHelpers(string actionsClassFileName)
- {
- CodeCompileUnit compileUnit = new CodeCompileUnit();
- CodeTypeDeclaration inputClass = CreatePartialInputClass(compileUnit);
- CodeArrayCreateExpression actionsArray = new CodeArrayCreateExpression(new CodeTypeReference(typeof(SteamVR_Action)));
- CodeArrayCreateExpression actionsInArray = new CodeArrayCreateExpression(new CodeTypeReference(typeof(ISteamVR_Action_In)));
- CodeArrayCreateExpression actionsOutArray = new CodeArrayCreateExpression(new CodeTypeReference(typeof(ISteamVR_Action_Out)));
- CodeArrayCreateExpression actionsVibrationArray = new CodeArrayCreateExpression(new CodeTypeReference(typeof(SteamVR_Action_Vibration)));
- CodeArrayCreateExpression actionsPoseArray = new CodeArrayCreateExpression(new CodeTypeReference(typeof(SteamVR_Action_Pose)));
- CodeArrayCreateExpression actionsSkeletonArray = new CodeArrayCreateExpression(new CodeTypeReference(typeof(SteamVR_Action_Skeleton)));
- CodeArrayCreateExpression actionsBooleanArray = new CodeArrayCreateExpression(new CodeTypeReference(typeof(SteamVR_Action_Boolean)));
- CodeArrayCreateExpression actionsSingleArray = new CodeArrayCreateExpression(new CodeTypeReference(typeof(SteamVR_Action_Single)));
- CodeArrayCreateExpression actionsVector2Array = new CodeArrayCreateExpression(new CodeTypeReference(typeof(SteamVR_Action_Vector2)));
- CodeArrayCreateExpression actionsVector3Array = new CodeArrayCreateExpression(new CodeTypeReference(typeof(SteamVR_Action_Vector3)));
- CodeArrayCreateExpression actionsNonPoseNonSkeletonArray = new CodeArrayCreateExpression(new CodeTypeReference(typeof(ISteamVR_Action_In)));
- //add the getaction method to
- CodeMemberMethod actionsArraysInitMethod = CreateStaticMethod(inputClass, initializeActionsArraysMethodName, false);
- CodeMemberMethod actionsPreInitMethod = CreateStaticMethod(inputClass, preInitActionsMethodName, false);
- for (int actionSetIndex = 0; actionSetIndex < SteamVR_Input.actionFile.action_sets.Count; actionSetIndex++)
- {
- SteamVR_Input_ActionFile_ActionSet actionSet = SteamVR_Input.actionFile.action_sets[actionSetIndex];
- string actionSetShortName = actionSet.shortName;
- actionSetShortName = actionSetShortName.Substring(0, 1).ToLower() + actionSetShortName.Substring(1);
- for (int actionIndex = 0; actionIndex < actionSet.actionsList.Count; actionIndex++)
- {
- SteamVR_Input_ActionFile_Action action = actionSet.actionsList[actionIndex];
- string actionShortName = action.shortName;
- string typeName = GetTypeStringForAction(action);
- string codeFriendlyInstanceName;
- if (actionSet.actionsList.Count(findAction => findAction.shortName == actionShortName) >= 2)
- codeFriendlyInstanceName = string.Format("{0}_{1}_{2}", actionSetShortName, action.direction.ToString().ToLower(), actionShortName);
- else
- codeFriendlyInstanceName = string.Format("{0}_{1}", actionSetShortName, actionShortName);
- CodeMemberField actionField = CreateFieldAndPropertyWrapper(inputClass, codeFriendlyInstanceName, typeName);
- AddAssignActionStatement(actionsPreInitMethod, inputClass.Name, actionField.Name, action.name, typeName);
- actionsArray.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- if (action.direction == SteamVR_ActionDirections.In)
- {
- actionsInArray.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- if (typeName == typeof(SteamVR_Action_Pose).Name)
- {
- actionsPoseArray.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- }
- else if (typeName == typeof(SteamVR_Action_Skeleton).Name)
- {
- actionsSkeletonArray.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- }
- else if (typeName == typeof(SteamVR_Action_Boolean).Name)
- {
- actionsBooleanArray.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- }
- else if (typeName == typeof(SteamVR_Action_Single).Name)
- {
- actionsSingleArray.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- }
- else if (typeName == typeof(SteamVR_Action_Vector2).Name)
- {
- actionsVector2Array.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- }
- else if (typeName == typeof(SteamVR_Action_Vector3).Name)
- {
- actionsVector3Array.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- }
- if ((typeName == typeof(SteamVR_Action_Skeleton).Name) == false && (typeName == typeof(SteamVR_Action_Pose).Name) == false)
- {
- actionsNonPoseNonSkeletonArray.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- }
- }
- else
- {
- actionsVibrationArray.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- actionsOutArray.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- }
- }
- }
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsFieldName, actionsArray);
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsInFieldName, actionsInArray);
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsOutFieldName, actionsOutArray);
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsVibrationFieldName, actionsVibrationArray);
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsPoseFieldName, actionsPoseArray);
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsBooleanFieldName, actionsBooleanArray);
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsSingleFieldName, actionsSingleArray);
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsVector2FieldName, actionsVector2Array);
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsVector3FieldName, actionsVector3Array);
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsSkeletonFieldName, actionsSkeletonArray);
- AddAssignStatement(actionsArraysInitMethod, SteamVR_Input_Generator_Names.actionsNonPoseNonSkeletonIn, actionsNonPoseNonSkeletonArray);
- // Build the output file name.
- string fullSourceFilePath = GetSourceFilePath(actionsClassFileName);
- CreateFile(fullSourceFilePath, compileUnit);
- }
- private const string startPreInitActionSetsMethodName = "StartPreInitActionSets";
- private const string finishPreInitActionSetsMethodName = "PreinitializeFinishActionSets";
- private static void GenerateActionSetsHelpers(string actionSetsClassFileName)
- {
- CodeCompileUnit compileUnit = new CodeCompileUnit();
- CodeTypeDeclaration inputClass = CreatePartialInputClass(compileUnit);
- CodeMemberMethod startPreInitActionSetsMethod = CreateStaticMethod(inputClass, startPreInitActionSetsMethodName, false);
- CodeArrayCreateExpression actionSetsArray = new CodeArrayCreateExpression(new CodeTypeReference(typeof(SteamVR_ActionSet)));
- for (int actionSetIndex = 0; actionSetIndex < SteamVR_Input.actionFile.action_sets.Count; actionSetIndex++)
- {
- SteamVR_Input_ActionFile_ActionSet actionSet = SteamVR_Input.actionFile.action_sets[actionSetIndex];
- string shortName = GetValidIdentifier(actionSet.shortName);
- string codeFriendlyInstanceName = shortName;
- string setTypeName = GetSetClassName(actionSet);
- CodeMemberField actionSetField = CreateFieldAndPropertyWrapper(inputClass, shortName, setTypeName);
- AddAssignActionSetStatement(startPreInitActionSetsMethod, inputClass.Name, actionSetField.Name, actionSet.name, setTypeName);
- actionSetsArray.Initializers.Add(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), codeFriendlyInstanceName));
- }
- AddAssignStatement(startPreInitActionSetsMethod, SteamVR_Input_Generator_Names.actionSetsFieldName, actionSetsArray);
- // Build the output file name.
- string fullSourceFilePath = GetSourceFilePath(actionSetsClassFileName);
- CreateFile(fullSourceFilePath, compileUnit);
- }
- private static CSharpCodeProvider provider = new CSharpCodeProvider();
- private static string GetValidIdentifier(string name)
- {
- string newName = name.Replace("-", "_");
- newName = provider.CreateValidIdentifier(newName);
- return newName;
- }
- public static MethodInfo GetMethodInfo<T>(Expression<Action<T>> expression)
- {
- var member = expression.Body as MethodCallExpression;
- if (member != null)
- return member.Method;
- throw new ArgumentException("Expression is not a method", "expression");
- }
- private static CodeTypeDeclaration CreatePartialInputClass(CodeCompileUnit compileUnit)
- {
- CodeNamespace codeNamespace = new CodeNamespace(typeof(SteamVR_Input).Namespace);
- codeNamespace.Imports.Add(new CodeNamespaceImport("System"));
- codeNamespace.Imports.Add(new CodeNamespaceImport("UnityEngine"));
- compileUnit.Namespaces.Add(codeNamespace);
- CodeTypeDeclaration inputClass = new CodeTypeDeclaration(SteamVR_Input_Generator_Names.actionsClassName);
- inputClass.IsPartial = true;
- codeNamespace.Types.Add(inputClass);
- return inputClass;
- }
- private static string GetSetClassName(SteamVR_Input_ActionFile_ActionSet set)
- {
- return actionSetClassNamePrefix + set.shortName;
- }
- private const string inActionFieldPrefix = "in_";
- private const string outActionFieldPrefix = "out_";
- private const string setFinishPreInitializeMethodName = "FinishPreInitialize";
- private static CodeTypeDeclaration CreateActionSetClass(SteamVR_Input_ActionFile_ActionSet set)
- {
- CodeCompileUnit compileUnit = new CodeCompileUnit();
- CodeNamespace codeNamespace = new CodeNamespace(typeof(SteamVR_Input).Namespace);
- codeNamespace.Imports.Add(new CodeNamespaceImport("System"));
- codeNamespace.Imports.Add(new CodeNamespaceImport("UnityEngine"));
- compileUnit.Namespaces.Add(codeNamespace);
- CodeTypeDeclaration setClass = new CodeTypeDeclaration(GetSetClassName(set));
- setClass.BaseTypes.Add(typeof(SteamVR_ActionSet));
- setClass.Attributes = MemberAttributes.Public;
- codeNamespace.Types.Add(setClass);
- string actionSetShortName = set.shortName;
- actionSetShortName = actionSetShortName.Substring(0, 1).ToLower() + actionSetShortName.Substring(1);
- foreach (var inAction in set.actionsInList)
- {
- string inActionName = inAction.shortName;
- if (set.actionsOutList.Any(outAction => inAction.shortName == outAction.shortName))
- inActionName = inActionFieldPrefix + inActionName;
- string actionClassPropertyName = string.Format("{0}_{1}", actionSetShortName, inActionName);
- CreateActionPropertyWrapper(setClass, SteamVR_Input_Generator_Names.actionsClassName, inActionName, actionClassPropertyName, inAction);
- }
- foreach (var outAction in set.actionsOutList)
- {
- string outActionName = outAction.shortName;
- if (set.actionsInList.Any(inAction => inAction.shortName == outAction.shortName))
- outActionName = outActionFieldPrefix + outActionName;
- string actionClassPropertyName = string.Format("{0}_{1}", actionSetShortName, outActionName);
- CreateActionPropertyWrapper(setClass, SteamVR_Input_Generator_Names.actionsClassName, outActionName, actionClassPropertyName, outAction);
- }
- // Build the output file name.
- string folderPath = GetSubFolderPath();
- string fullSourceFilePath = Path.Combine(folderPath, setClass.Name + ".cs");
- CreateFile(fullSourceFilePath, compileUnit);
- return setClass;
- }
- private static CodeMemberMethod CreateStaticMethod(CodeTypeDeclaration inputClass, string methodName, bool isPublic)
- {
- CodeMemberMethod method = new CodeMemberMethod();
- method.Name = methodName;
- if (isPublic)
- method.Attributes = MemberAttributes.Public | MemberAttributes.Static;
- else
- method.Attributes = MemberAttributes.Private | MemberAttributes.Static;
- inputClass.Members.Add(method);
- return method;
- }
- private static CodeMemberMethod CreateStaticConstructorMethod(CodeTypeDeclaration inputClass)
- {
- CodeTypeConstructor method = new CodeTypeConstructor();
- method.Attributes = MemberAttributes.Static;
- inputClass.Members.Add(method);
- return method;
- }
- private static CodeMemberField CreateField(CodeTypeDeclaration inputClass, string fieldName, Type fieldType, bool isStatic)
- {
- if (fieldType == null)
- Debug.Log("null fieldType");
- CodeMemberField field = new CodeMemberField();
- field.Name = fieldName;
- field.Type = new CodeTypeReference(fieldType);
- field.Attributes = MemberAttributes.Public;
- if (isStatic)
- field.Attributes |= MemberAttributes.Static;
- inputClass.Members.Add(field);
- return field;
- }
- private static CodeMemberField CreateFieldAndPropertyWrapper(CodeTypeDeclaration inputClass, string name, string type)
- {
- CodeMemberField actionField = CreatePrivateField(inputClass, name, type, true);
- CodeMemberProperty actionProperty = CreateStaticProperty(inputClass, name, type, actionField);
- return actionField;
- }
- private static CodeMemberProperty CreateStaticProperty(CodeTypeDeclaration inputClass, string propertyName, string propertyType, CodeMemberField privateField)
- {
- CodeMemberProperty property = new CodeMemberProperty();
- property.Name = propertyName;
- property.Type = new CodeTypeReference(propertyType);
- property.Attributes = MemberAttributes.Public | MemberAttributes.Static;
- CodeFieldReferenceExpression fieldReference = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(inputClass.Name), privateField.Name);
- CodeMethodInvokeExpression invokeExpression = new CodeMethodInvokeExpression(fieldReference, "GetCopy");
- invokeExpression.Method.TypeArguments.Add(property.Type);
- CodeMethodReturnStatement returnStatement = new CodeMethodReturnStatement(invokeExpression);
- property.GetStatements.Add(returnStatement);
- inputClass.Members.Add(property);
- return property;
- }
- private static CodeMemberProperty CreateActionPropertyWrapper(CodeTypeDeclaration addToClass, string actionClass, string propertyName, string actionClassFieldName, SteamVR_Input_ActionFile_Action action)
- {
- string propertyType = GetTypeStringForAction(action);
- CodeMemberProperty property = new CodeMemberProperty();
- property.Name = propertyName;
- property.Type = new CodeTypeReference(propertyType);
- property.Attributes = MemberAttributes.Public;
- CodeFieldReferenceExpression fieldReference = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(actionClass), actionClassFieldName);
- CodeMethodReturnStatement returnStatement = new CodeMethodReturnStatement(fieldReference);
- property.GetStatements.Add(returnStatement);
- addToClass.Members.Add(property);
- return property;
- }
- private const string privateFieldPrefix = "p_";
- private static CodeMemberField CreatePrivateField(CodeTypeDeclaration inputClass, string fieldName, string fieldType, bool isStatic)
- {
- return CreateField(inputClass, privateFieldPrefix + fieldName, fieldType, isStatic, false);
- }
- private static CodeMemberField CreateField(CodeTypeDeclaration inputClass, string fieldName, string fieldType, bool isStatic, bool isPublic = true)
- {
- CodeMemberField field = new CodeMemberField();
- field.Name = fieldName;
- field.Type = new CodeTypeReference(fieldType);
- if (isPublic)
- field.Attributes = MemberAttributes.Public;
- else
- field.Attributes = MemberAttributes.Private;
- if (isStatic)
- field.Attributes |= MemberAttributes.Static;
- inputClass.Members.Add(field);
- return field;
- }
- private static CodeMethodInvokeExpression AddStaticInvokeToMethod(CodeMemberMethod methodToAddTo, string classToInvoke, string invokeMethodName)
- {
- CodeMethodInvokeExpression invokeMethod = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(
- new CodeTypeReferenceExpression(classToInvoke), invokeMethodName));
- methodToAddTo.Statements.Add(invokeMethod);
- return invokeMethod;
- }
- private static void AddAssignStatement(CodeMemberMethod methodToAddTo, string fieldToAssign, CodeArrayCreateExpression array)
- {
- methodToAddTo.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SteamVR_Input)), fieldToAssign), array));
- }
- private const string createActionMethodName = "Create";
- private const string createActionSetMethodName = "Create";
- private const string getActionFromPathMethodName = "GetActionFromPath";
- //grab = SteamVR_Action.Create<SteamVR_Action_Boolean>("path");
- private static void AddAssignActionStatement(CodeMemberMethod methodToAddTo, string actionClassName, string fieldToAssign, string actionPath, string actionType)
- {
- CodeMethodInvokeExpression invokeMethod = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(SteamVR_Action).Name), createActionMethodName));
- invokeMethod.Method.TypeArguments.Add(actionType);
- invokeMethod.Parameters.Add(new CodePrimitiveExpression(actionPath));
- methodToAddTo.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(actionClassName), fieldToAssign), new CodeCastExpression(new CodeTypeReference(actionType), invokeMethod)));
- }
- private static void AddAssignActionSetStatement(CodeMemberMethod methodToAddTo, string actionClassName, string fieldToAssign, string actionSetName, string actionSetType)
- {
- CodeMethodInvokeExpression invokeMethod = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(SteamVR_ActionSet).Name), createActionSetMethodName));
- invokeMethod.Method.TypeArguments.Add(actionSetType);
- invokeMethod.Parameters.Add(new CodePrimitiveExpression(actionSetName));
- methodToAddTo.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(actionClassName), fieldToAssign), new CodeCastExpression(new CodeTypeReference(actionSetType), invokeMethod)));
- }
- private static void AddAssignLocalActionStatement(CodeMemberMethod methodToAddTo, string fieldToAssign, string actionPath, string actionType, bool create)
- {
- CodeMethodInvokeExpression invokeMethod;
- if (create)
- invokeMethod = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(SteamVR_Action).Name), createActionMethodName));
- else
- invokeMethod = new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(SteamVR_Input).Name), getActionFromPathMethodName));
- invokeMethod.Method.TypeArguments.Add(actionType);
- invokeMethod.Parameters.Add(new CodePrimitiveExpression(actionPath));
- methodToAddTo.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldToAssign), new CodeCastExpression(new CodeTypeReference(actionType), invokeMethod)));
- }
- private static void AddAssignNewInstanceStatement(CodeMemberMethod methodToAddTo, string fieldToAssign, string fieldType)
- {
- CodeObjectCreateExpression createExpression = new CodeObjectCreateExpression(new CodeTypeReference(fieldType));
- methodToAddTo.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldToAssign), createExpression));
- }
- private static CodeConditionStatement CreateStringCompareStatement(CodeMemberMethod methodToAddTo, string action, string paramName, string returnActionName)
- {
- MethodInfo stringEqualsMethodInfo = GetMethodInfo<string>(set => string.Equals(null, null, StringComparison.CurrentCultureIgnoreCase));
- CodeTypeReferenceExpression stringType = new CodeTypeReferenceExpression(typeof(string));
- CodePrimitiveExpression actionName = new CodePrimitiveExpression(action);
- CodeVariableReferenceExpression pathName = new CodeVariableReferenceExpression(paramName);
- CodeVariableReferenceExpression caseInvariantName = new CodeVariableReferenceExpression("StringComparison.CurrentCultureIgnoreCase");
- CodeMethodInvokeExpression stringCompare = new CodeMethodInvokeExpression(stringType, stringEqualsMethodInfo.Name, pathName, actionName, caseInvariantName);
- CodeMethodReturnStatement returnAction = new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SteamVR_Input)), returnActionName));
- CodeConditionStatement condition = new CodeConditionStatement(stringCompare, returnAction);
- methodToAddTo.Statements.Add(condition);
- return condition;
- }
- }
- }
|