public void AssembleCsProgram(uint heapSize) { // The heap size is determined by the symbol count + the unique extern string count UdonSharp.HeapFactory heapFactory = new UdonSharp.HeapFactory(heapSize); UdonEditorInterface assemblerInterface = new UdonEditorInterface(null, heapFactory, null, null, null, null, null, null, null); assemblerInterface.AddTypeResolver(new UdonBehaviourTypeResolver()); FieldInfo assemblyError = typeof(UdonAssemblyProgramAsset).GetField("assemblyError", BindingFlags.NonPublic | BindingFlags.Instance); try { program = assemblerInterface.Assemble(udonAssembly); assemblyError.SetValue(this, null); hasInteractEvent = false; foreach (string entryPoint in program.EntryPoints.GetExportedSymbols()) { if (entryPoint == "_interact") { hasInteractEvent = true; break; } } } catch (Exception e) { program = null; assemblyError.SetValue(this, e.Message); Debug.LogException(e); } }
private UdonEditorManager() { _udonEditorInterface = new UdonEditorInterface(); _udonEditorInterface.AddTypeResolver(new UdonBehaviourTypeResolver()); EditorSceneManager.sceneOpened += OnSceneOpened; EditorSceneManager.sceneSaving += OnSceneSaving; EditorApplication.playModeStateChanged += OnPlayModeStateChanged; }
/// <summary> /// В typesForResolver надо передавать как минимум {"VRCUdonUdonBehaviour", typeof(UdonBehaviour)} /// </summary> public static DoshikNodeDefinition[] GetAllNodeDefinitions(IDictionary <string, Type> typesForResolver) { var udonEditorInterface = new UdonEditorInterface(); udonEditorInterface.AddTypeResolver(new AnyTypeResolver(typesForResolver)); var rootRegistries = udonEditorInterface.GetNodeRegistries(); return(GetNodeDefinitions(rootRegistries.Values, new INodeRegistry[0]).ToArray()); }
private UdonEditorManager() { _udonEditorInterface = new Lazy <UdonEditorInterface>(() => { var editorInterface = new UdonEditorInterface(); editorInterface.AddTypeResolver(new UdonBehaviourTypeResolver()); return(editorInterface); }); // Async init the editor interface to avoid 1+ second delay added to assembly reload. Task.Run(() => { var _ = _udonEditorInterface.Value; }); EditorSceneManager.sceneOpened += OnSceneOpened; EditorSceneManager.sceneSaving += OnSceneSaving; EditorApplication.playModeStateChanged += OnPlayModeStateChanged; }
internal bool AssembleCsProgram(uint heapSize) { if (editorInterfaceInstance == null || heapFactoryInstance == null) { // The heap size is determined by the symbol count + the unique extern string count heapFactoryInstance = new UdonSharp.HeapFactory(); editorInterfaceInstance = new UdonEditorInterface(null, heapFactoryInstance, null, null, null, null, null, null, null); editorInterfaceInstance.AddTypeResolver(new UdonBehaviourTypeResolver()); // todo: can be removed with SDK's >= VRCSDK-UDON-2020.06.15.14.08_Public } heapFactoryInstance.FactoryHeapSize = heapSize; FieldInfo assemblyError = typeof(UdonAssemblyProgramAsset).GetField("assemblyError", BindingFlags.NonPublic | BindingFlags.Instance); try { program = editorInterfaceInstance.Assemble(udonAssembly); assemblyError.SetValue(this, null); hasInteractEvent = false; foreach (string entryPoint in program.EntryPoints.GetExportedSymbols()) { if (entryPoint == "_interact") { hasInteractEvent = true; break; } } } catch (Exception e) { program = null; assemblyError.SetValue(this, e.Message); Debug.LogException(e); return(false); } return(true); }
public void AssembleCsProgram(uint heapSize) { // The heap size is determined by the symbol count + the unique extern string count UdonSharp.HeapFactory heapFactory = new UdonSharp.HeapFactory(heapSize); UdonEditorInterface assemblerInterface = new UdonEditorInterface(null, heapFactory, null, null, null, null, null, null, null); assemblerInterface.AddTypeResolver(new UdonBehaviourTypeResolver()); FieldInfo assemblyError = typeof(UdonAssemblyProgramAsset).GetField("assemblyError", BindingFlags.NonPublic | BindingFlags.Instance); try { program = assemblerInterface.Assemble(udonAssembly); assemblyError.SetValue(this, null); } catch (Exception e) { program = null; assemblyError.SetValue(this, e.Message); Debug.LogException(e); } }
public static UdonAssemblyProgramAsset UdonSharpProgramToAssemblyProgram(UdonSharpProgramAsset udonSharpProgramAsset, string savePath) { if (EditorApplication.isPlaying) { throw new System.NotSupportedException("USharpEditorUtility.UdonSharpProgramToAssemblyProgram() cannot be called in play mode"); } UdonAssemblyProgramAsset newProgramAsset = ScriptableObject.CreateInstance <UdonAssemblyProgramAsset>(); AssetDatabase.CreateAsset(newProgramAsset, savePath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); newProgramAsset = AssetDatabase.LoadAssetAtPath <UdonAssemblyProgramAsset>(savePath); udonSharpProgramAsset.CompileCsProgram(); string programAssembly = UdonSharpEditorCache.Instance.GetUASMStr(udonSharpProgramAsset); // Strip comments/inline code StringBuilder asmBuilder = new StringBuilder(); using (StringReader reader = new StringReader(programAssembly)) { string line = reader.ReadLine(); while (line != null) { if (!string.IsNullOrWhiteSpace(line) && !line.TrimStart().StartsWith("#", System.StringComparison.Ordinal)) { asmBuilder.AppendFormat("{0}\n", line); } line = reader.ReadLine(); } } programAssembly = asmBuilder.ToString(); FieldInfo assemblyField = typeof(UdonAssemblyProgramAsset).GetField("udonAssembly", BindingFlags.NonPublic | BindingFlags.Instance); assemblyField.SetValue(newProgramAsset, programAssembly); IUdonProgram program = null; try { UdonSharp.HeapFactory heapFactory = new UdonSharp.HeapFactory(); UdonEditorInterface editorInterface = new UdonEditorInterface(null, heapFactory, null, null, null, null, null, null, null); heapFactory.FactoryHeapSize = udonSharpProgramAsset.GetSerializedUdonProgramAsset().RetrieveProgram().Heap.GetHeapCapacity(); program = editorInterface.Assemble(programAssembly); } catch (System.Exception e) { Debug.LogError(e); return(null); } FieldInfo assemblyProgramField = typeof(UdonProgramAsset).GetField("program", BindingFlags.NonPublic | BindingFlags.Instance); assemblyProgramField.SetValue(newProgramAsset, program); IUdonProgram uSharpProgram = udonSharpProgramAsset.GetRealProgram(); IUdonProgram assemblyProgram = (IUdonProgram)assemblyProgramField.GetValue(newProgramAsset); if (uSharpProgram == null || assemblyProgram == null) { return(null); } ImmutableArray <string> symbols = uSharpProgram.SymbolTable.GetSymbols(); foreach (string symbol in symbols) { uint symbolAddress = uSharpProgram.SymbolTable.GetAddressFromSymbol(symbol); System.Type symbolType = uSharpProgram.Heap.GetHeapVariableType(symbolAddress); object symbolValue = uSharpProgram.Heap.GetHeapVariable(symbolAddress); assemblyProgram.Heap.SetHeapVariable(assemblyProgram.SymbolTable.GetAddressFromSymbol(symbol), symbolValue, symbolType); } EditorUtility.SetDirty(newProgramAsset); newProgramAsset.SerializedProgramAsset.StoreProgram(assemblyProgram); EditorUtility.SetDirty(newProgramAsset.SerializedProgramAsset); AssetDatabase.SaveAssets(); // This doesn't work unfortunately due to how Udon tries to locate the serialized asset when importing an assembly //string serializedAssetPath = $"{Path.GetDirectoryName(savePath)}/{Path.GetFileNameWithoutExtension(savePath)}_serialized.asset"; //AssetDatabase.MoveAsset(AssetDatabase.GetAssetPath(newProgramAsset.SerializedProgramAsset), serializedAssetPath); //AssetDatabase.SaveAssets(); return(newProgramAsset); }