コード例 #1
0
        /// <summary>
        /// Creates a new UdonAssemblyProgramAsset from an UdonSharpProgramAsset for the sake of portability. Most info used for the inspector gets stripped so this isn't a great solution for remotely complex assets.
        /// </summary>
        /// <param name="udonSharpProgramAsset">The source program asset</param>
        /// <param name="savePath">The save path for the asset file. Save path is only needed here because Udon needs a GUID for saving the serialized program asset and it'd be a pain to break that requirement at the moment</param>
        /// <returns>The exported UdonAssemblyProgramAsset</returns>
        public static UdonAssemblyProgramAsset UdonSharpProgramToAssemblyProgram(UdonSharpProgramAsset udonSharpProgramAsset, string savePath)
        {
            if (EditorApplication.isPlaying)
            {
                throw new System.NotSupportedException("UdonSharpEditorUtility.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);

            FieldInfo assemblyField = typeof(UdonAssemblyProgramAsset).GetField("udonAssembly", BindingFlags.NonPublic | BindingFlags.Instance);

            udonSharpProgramAsset.CompileCsProgram();

            assemblyField.SetValue(newProgramAsset, assemblyField.GetValue(udonSharpProgramAsset));

            MethodInfo assembleMethod = typeof(UdonAssemblyProgramAsset).GetMethod("AssembleProgram", BindingFlags.NonPublic | BindingFlags.Instance);

            assembleMethod.Invoke(newProgramAsset, new object[] { });

            IUdonProgram uSharpProgram         = udonSharpProgramAsset.GetRealProgram();
            FieldInfo    assemblyProgramGetter = typeof(UdonProgramAsset).GetField("program", BindingFlags.NonPublic | BindingFlags.Instance);
            IUdonProgram assemblyProgram       = (IUdonProgram)assemblyProgramGetter.GetValue(newProgramAsset);

            if (uSharpProgram == null || assemblyProgram == null)
            {
                return(null);
            }

            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);
        }
コード例 #2
0
        private static T GetVariable <T>(UdonBehaviour behaviour, string variableKey)
        {
            T output;

            if (behaviour.publicVariables.TryGetVariableValue <T>(variableKey, out output))
            {
                return(output);
            }

            // Try to get the default value if there's no custom value specified
            if (behaviour.programSource != null && behaviour.programSource is UdonSharpProgramAsset udonSharpProgramAsset)
            {
                udonSharpProgramAsset.UpdateProgram();

                IUdonProgram program = udonSharpProgramAsset.GetRealProgram();

                uint varAddress;
                if (program.SymbolTable.TryGetAddressFromSymbol(variableKey, out varAddress))
                {
                    if (program.Heap.TryGetHeapVariable <T>(varAddress, out output))
                    {
                        return(output);
                    }
                }
            }

            return(default);
コード例 #3
0
        private void DrawSerializationDebug()
        {
            EditorGUILayout.LabelField($"DataFormat: {(DataFormat)_serializationDataFormatSerializedProperty.enumValueIndex}");

            if (string.IsNullOrEmpty(_serializedProgramBytesStringSerializedProperty.stringValue))
            {
                return;
            }

            if (_serializationDataFormatSerializedProperty.enumValueIndex == (int)DataFormat.JSON)
            {
                using (new EditorGUI.DisabledScope(true))
                {
                    EditorGUILayout.TextArea(System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(_serializedProgramBytesStringSerializedProperty.stringValue)));
                }
            }
            else
            {
                using (new EditorGUI.DisabledScope(true))
                {
                    SerializedUdonProgramAsset serializedUdonProgramAsset = (SerializedUdonProgramAsset)target;
                    IUdonProgram udonProgram     = serializedUdonProgramAsset.RetrieveProgram();
                    byte[]       serializedBytes = SerializationUtility.SerializeValue(udonProgram, DataFormat.JSON, out List <UnityEngine.Object> _);
                    EditorGUILayout.TextArea(System.Text.Encoding.UTF8.GetString(serializedBytes));
                }
            }
        }
コード例 #4
0
        private static T GetVariable <T>(UdonBehaviour behaviour, string variableKey)
        {
            T output;

            if (behaviour.publicVariables.TryGetVariableValue <T>(variableKey, out output))
            {
                return(output);
            }

            // The type no longer matches exactly, but is trivially convertible
            // This will usually flow into a reassignment of the public variable type in SetVarInternal() when the value gets copied back to Udon
            if (behaviour.publicVariables.TryGetVariableValue(variableKey, out object outputObj) && !outputObj.IsUnityObjectNull() && outputObj is T)
            {
                return((T)outputObj);
            }

            // Try to get the default value if there's no custom value specified
            if (behaviour.programSource != null && behaviour.programSource is UdonSharpProgramAsset udonSharpProgramAsset)
            {
                udonSharpProgramAsset.UpdateProgram();

                IUdonProgram program = udonSharpProgramAsset.GetRealProgram();

                uint varAddress;
                if (program.SymbolTable.TryGetAddressFromSymbol(variableKey, out varAddress))
                {
                    if (program.Heap.TryGetHeapVariable <T>(varAddress, out output))
                    {
                        return(output);
                    }
                }
            }

            return(default);
コード例 #5
0
ファイル: CyanEmuUdonHelper.cs プロジェクト: esnya/CyanEmu
        public static void OnInit(UdonBehaviour behaviour, IUdonProgram program)
        {
            CyanEmuUdonHelper helper = behaviour.gameObject.AddComponent <CyanEmuUdonHelper>();

            helper.SetUdonBehaviour(behaviour);

            NetworkReadyFieldInfo_.SetValue(behaviour, CyanEmuMain.IsNetworkReady());
        }
コード例 #6
0
        public int AssignHeapConstants()
        {
            CompilationModule[] compiledModules = modules.Where(e => e.ErrorCount == 0).ToArray();

            foreach (CompilationModule module in compiledModules)
            {
                IUdonProgram program = module.programAsset.GetRealProgram();

                if (program != null)
                {
                    foreach (SymbolDefinition symbol in module.moduleSymbols.GetAllUniqueChildSymbols())
                    {
                        uint symbolAddress = program.SymbolTable.GetAddressFromSymbol(symbol.symbolUniqueName);

                        if (symbol.symbolDefaultValue != null)
                        {
                            program.Heap.SetHeapVariable(symbolAddress, symbol.symbolDefaultValue, symbol.symbolCsType);
                        }
                        else if (symbol.symbolCsType.IsArray &&
                                 (symbol.declarationType.HasFlag(SymbolDeclTypeFlags.Public))) // Initialize null array fields to a 0-length array like Unity does
                        {
                            program.Heap.SetHeapVariable(symbolAddress, System.Activator.CreateInstance(symbol.symbolCsType, new object[] { 0 }), symbol.symbolCsType);
                        }
                    }
                }
            }

            int fieldInitializerErrorCount = RunFieldInitalizers(compiledModules);

            foreach (CompilationModule module in compiledModules)
            {
                IUdonProgram program = module.programAsset.GetRealProgram();

                if (program != null)
                {
                    // Do not let users assign null to array fields, Unity does not allow this in its normal handling
                    foreach (SymbolDefinition symbol in module.moduleSymbols.GetAllUniqueChildSymbols())
                    {
                        uint symbolAddress = program.SymbolTable.GetAddressFromSymbol(symbol.symbolUniqueName);

                        if (symbol.symbolCsType.IsArray &&
                            (symbol.declarationType.HasFlag(SymbolDeclTypeFlags.Public)))     // Initialize null array fields to a 0-length array like Unity does
                        {
                            object currentArrayValue = program.Heap.GetHeapVariable(symbolAddress);

                            if (currentArrayValue == null)
                            {
                                program.Heap.SetHeapVariable(symbolAddress, System.Activator.CreateInstance(symbol.symbolCsType, new object[] { 0 }), symbol.symbolCsType);
                            }
                        }
                    }
                }
            }

            return(fieldInitializerErrorCount);
        }
コード例 #7
0
        public override void StoreProgram(IUdonProgram udonProgram)
        {
            byte[] serializedProgramBytes = SerializationUtility.SerializeValue(udonProgram, DEFAULT_SERIALIZATION_DATA_FORMAT, out programUnityEngineObjects);
            serializedProgramBytesString = Convert.ToBase64String(serializedProgramBytes);
            serializationDataFormat      = DEFAULT_SERIALIZATION_DATA_FORMAT;

            #if UNITY_EDITOR
            UnityEditor.EditorUtility.SetDirty(this);
            #endif
        }
コード例 #8
0
        public sealed override void RunEditorUpdate(UdonBehaviour udonBehaviour, ref bool dirty)
        {
            if (program == null && serializedUdonProgramAsset != null)
            {
                program = serializedUdonProgramAsset.RetrieveProgram();
            }

            if (program == null)
            {
                RefreshProgram();
            }

            DrawProgramSourceGUI(udonBehaviour, ref dirty);

            if (dirty)
            {
                EditorUtility.SetDirty(this);
            }
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        private int RunFieldInitalizers(CompilationModule[] compiledModules)
        {
            CompilationModule[] modulesToInitialize = compiledModules.Where(e => e.fieldsWithInitializers.Count > 0).ToArray();

            // We don't need to run the costly compilation if the user hasn't defined any fields with initializers
            if (modulesToInitialize.Length == 0)
            {
                return(0);
            }

            int initializerErrorCount = 0;

            SyntaxTree[]    initializerTrees   = new SyntaxTree[modulesToInitialize.Length];
            StringBuilder[] codeStringBuilders = new StringBuilder[modulesToInitialize.Length];

            for (int moduleIdx = 0; moduleIdx < modulesToInitialize.Length; ++moduleIdx)
            {
                CompilationModule module = modulesToInitialize[moduleIdx];

                CodeCompileUnit compileUnit = new CodeCompileUnit();
                CodeNamespace   ns          = new CodeNamespace("FieldInitialzers");
                compileUnit.Namespaces.Add(ns);
                foreach (var resolverUsingNamespace in module.resolver.usingNamespaces)
                {
                    if (!string.IsNullOrEmpty(resolverUsingNamespace))
                    {
                        ns.Imports.Add(new CodeNamespaceImport(resolverUsingNamespace));
                    }
                }

                CodeTypeDeclaration _class = new CodeTypeDeclaration($"Initializer{moduleIdx}");
                ns.Types.Add(_class);
                CodeMemberMethod method = new CodeMemberMethod();
                _class.Members.Add(method);
                method.Attributes = MemberAttributes.Public | MemberAttributes.Static;
                method.ReturnType = new CodeTypeReference(typeof(void));
                method.Name       = "DoInit";
                method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IUdonProgram), "program"));

                foreach (var fieldDeclarationSyntax in module.fieldsWithInitializers)
                {
                    var  type    = fieldDeclarationSyntax.Declaration.Type;
                    int  count   = 0;
                    bool isConst = fieldDeclarationSyntax.Modifiers.Any(t => t.ToString() == "const");
                    foreach (var variable in fieldDeclarationSyntax.Declaration.Variables)
                    {
                        FieldDefinition fieldDef = module.compiledClassDefinition?.fieldDefinitions?.Find(e => (e.fieldSymbol.declarationType == SymbolDeclTypeFlags.Private || e.fieldSymbol.declarationType == SymbolDeclTypeFlags.Public) &&
                                                                                                          e.fieldSymbol.symbolOriginalName == variable.Identifier.ToString());

                        string typeQualifiedName = type.ToString();
                        if (fieldDef != null)
                        {
                            if (fieldDef.fieldSymbol.symbolCsType.Namespace.Length == 0)
                            {
                                typeQualifiedName = fieldDef.fieldSymbol.symbolCsType.Name;
                            }
                            else
                            {
                                typeQualifiedName = fieldDef.fieldSymbol.symbolCsType.Namespace + "." + fieldDef.fieldSymbol.symbolCsType.Name;
                            }
                        }

                        if (variable.Initializer != null)
                        {
                            string name = variable.Identifier.ToString();
                            if (isConst)
                            {
                                _class.Members.Add(new CodeSnippetTypeMember($"const {typeQualifiedName} {name} {variable.Initializer};"));
                            }
                            else
                            {
                                method.Statements.Add(new CodeSnippetStatement($"{typeQualifiedName} {name} {variable.Initializer};"));
                            }

                            method.Statements.Add(new CodeSnippetStatement(
                                                      $"program.Heap.SetHeapVariable(program.SymbolTable.GetAddressFromSymbol(\"{variable.Identifier}\"), {name});"));

                            count++;
                        }
                    }
                }

                StringBuilder sb = new StringBuilder();
                codeStringBuilders[moduleIdx] = sb;

                CSharpCodeProvider provider = new CSharpCodeProvider();
                using (StringWriter streamWriter = new StringWriter(sb))
                {
                    provider.GenerateCodeFromCompileUnit(compileUnit, streamWriter, new CodeGeneratorOptions());
                }

                SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sb.ToString());

                initializerTrees[moduleIdx] = syntaxTree;
            }

            var assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
            var references = new List <MetadataReference>();

            for (int i = 0; i < assemblies.Length; i++)
            {
                if (!assemblies[i].IsDynamic && assemblies[i].Location.Length > 0)
                {
                    references.Add(MetadataReference.CreateFromFile(assemblies[i].Location));
                }
            }

            CSharpCompilation compilation = CSharpCompilation.Create(
                $"init{initAssemblyCounter++}",
                syntaxTrees: initializerTrees,
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var memoryStream = new MemoryStream())
            {
                EmitResult result = compilation.Emit(memoryStream);
                if (!result.Success)
                {
                    // todo: make these errors point to the correct source files
                    bool error = false;
                    foreach (Diagnostic diagnostic in result.Diagnostics)
                    {
                        if (diagnostic.Severity == DiagnosticSeverity.Error)
                        {
                            Debug.LogError(diagnostic);
                            error = true;
                            initializerErrorCount++;
                        }
                    }

                    if (error)
                    {
                        Debug.LogError($"Generated Source code: {string.Join("\n", codeStringBuilders.Select(e => e.ToString()))}");
                    }
                }
                else
                {
                    memoryStream.Seek(0, SeekOrigin.Begin);

                    Assembly assembly = Assembly.Load(memoryStream.ToArray());

                    for (int moduleIdx = 0; moduleIdx < modulesToInitialize.Length; ++moduleIdx)
                    {
                        CompilationModule module  = modulesToInitialize[moduleIdx];
                        IUdonProgram      program = module.programAsset.GetRealProgram();

                        System.Type cls        = assembly.GetType($"FieldInitialzers.Initializer{moduleIdx}");
                        MethodInfo  methodInfo = cls.GetMethod("DoInit", BindingFlags.Public | BindingFlags.Static);
                        methodInfo.Invoke(null, new[] { program });

                        foreach (var fieldDeclarationSyntax in module.fieldsWithInitializers)
                        {
                            foreach (var variable in fieldDeclarationSyntax.Declaration.Variables)
                            {
                                string varName = variable.Identifier.ToString();

                                object heapValue = program.Heap.GetHeapVariable(program.SymbolTable.GetAddressFromSymbol(varName));

                                if (heapValue != null && UdonSharpUtils.IsUserDefinedType(heapValue.GetType()))
                                {
                                    UdonSharpUtils.LogBuildError($"Field: '{varName}' UdonSharp does not yet support field initializers on user-defined types or jagged arrays", AssetDatabase.GetAssetPath(module.programAsset.sourceCsScript), 0, 0);
                                }
                            }
                        }
                    }
                }
            }

            return(initializerErrorCount);
        }
コード例 #11
0
        private void RunFieldInitalizers(CompilationModule module)
        {
            IUdonProgram program = module.programAsset.GetRealProgram();

            // We don't need to run the costly compilation if the user hasn't defined any fields with initializers
            if (module.fieldsWithInitializers.Count == 0)
            {
                return;
            }

            CodeCompileUnit compileUnit = new CodeCompileUnit();
            CodeNamespace   ns          = new CodeNamespace("FieldInitialzers");

            compileUnit.Namespaces.Add(ns);
            foreach (var resolverUsingNamespace in module.resolver.usingNamespaces)
            {
                if (!string.IsNullOrEmpty(resolverUsingNamespace))
                {
                    ns.Imports.Add(new CodeNamespaceImport(resolverUsingNamespace));
                }
            }

            CodeTypeDeclaration _class = new CodeTypeDeclaration("Initializer");

            ns.Types.Add(_class);
            CodeMemberMethod method = new CodeMemberMethod();

            _class.Members.Add(method);
            method.Attributes = MemberAttributes.Public | MemberAttributes.Static;
            method.ReturnType = new CodeTypeReference(typeof(void));
            method.Name       = "DoInit";
            method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IUdonProgram), "program"));

            foreach (var fieldDeclarationSyntax in module.fieldsWithInitializers)
            {
                var  type    = fieldDeclarationSyntax.Declaration.Type;
                int  count   = 0;
                bool isConst = fieldDeclarationSyntax.Modifiers.Any(t => t.ToString() == "const");
                foreach (var variable in fieldDeclarationSyntax.Declaration.Variables)
                {
                    if (variable.Initializer != null)
                    {
                        string name = variable.Identifier.ToString();
                        if (isConst)
                        {
                            _class.Members.Add(new CodeSnippetTypeMember($"const {type} {name} {variable.Initializer};"));
                        }
                        else
                        {
                            method.Statements.Add(new CodeSnippetStatement($"{type} {name} {variable.Initializer};"));
                        }

                        method.Statements.Add(new CodeSnippetStatement(
                                                  $"program.Heap.SetHeapVariable(program.SymbolTable.GetAddressFromSymbol(\"{variable.Identifier}\"), {name});"));

                        count++;
                    }
                }
            }

            CSharpCodeProvider provider = new CSharpCodeProvider();
            StringBuilder      sb       = new StringBuilder();

            using (StringWriter streamWriter = new StringWriter(sb))
            {
                provider.GenerateCodeFromCompileUnit(compileUnit, streamWriter, new CodeGeneratorOptions());
            }

            SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sb.ToString());

            var assemblies = System.AppDomain.CurrentDomain.GetAssemblies();
            var references = new List <MetadataReference>();

            for (int i = 0; i < assemblies.Length; i++)
            {
                if (!assemblies[i].IsDynamic && assemblies[i].Location.Length > 0)
                {
                    references.Add(MetadataReference.CreateFromFile(assemblies[i].Location));
                }
            }

            CSharpCompilation compilation = CSharpCompilation.Create(
                $"init{initAssemblyCounter++}",
                syntaxTrees: new[] { syntaxTree },
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var memoryStream = new MemoryStream())
            {
                EmitResult result = compilation.Emit(memoryStream);
                if (!result.Success)
                {
                    bool error = false;
                    foreach (Diagnostic diagnostic in result.Diagnostics)
                    {
                        if (diagnostic.Severity == DiagnosticSeverity.Error)
                        {
                            Debug.LogError(diagnostic);
                            error = true;
                        }
                    }

                    if (error)
                    {
                        Debug.LogError($"Generated Source code: {sb}");
                    }
                }
                else
                {
                    memoryStream.Seek(0, SeekOrigin.Begin);

                    Assembly   assembly   = Assembly.Load(memoryStream.ToArray());
                    var        cls        = assembly.GetType("FieldInitialzers.Initializer");
                    MethodInfo methodInfo = cls.GetMethod("DoInit", BindingFlags.Public | BindingFlags.Static);
                    methodInfo.Invoke(null, new[] { program });
                }
            }
        }
コード例 #12
0
 public abstract void StoreProgram(IUdonProgram udonProgram);
コード例 #13
0
        /// <summary>
        /// プログラムからのディスアセンブル
        /// </summary>
        /// <param name="program">VRC.Udon.Common.Interfaces.IUdonProgram</param>
        /// <returns>string</returns>
        protected static string GetDisassembleCode(IUdonProgram program)
        {
            var disasm = new UAssemblyDisassembler();

            return(String.Join("\n", disasm.DisassembleProgram(program)));
        }