summaryrefslogtreecommitdiff
path: root/VRCSDK3Worlds/Assets/Udon/Editor/ProgramSources/UdonAssemblyProgram/UdonAssemblyProgramAsset.cs
blob: 0045931e6a191d4518f5efefe548ad4275dfe5d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using UnityEditor;
using UnityEngine;
using VRC.Udon.Editor;
using VRC.Udon.Editor.ProgramSources;
using VRC.Udon.Editor.ProgramSources.Attributes;

[assembly: UdonProgramSourceNewMenu(typeof(UdonAssemblyProgramAsset), "Udon Assembly Program Asset")]

namespace VRC.Udon.Editor.ProgramSources
{
    [CreateAssetMenu(menuName = "VRChat/Udon/Udon Assembly Program Asset", fileName = "New Udon Assembly Program Asset")]
    public class UdonAssemblyProgramAsset : UdonProgramAsset
    {
        [SerializeField]
        protected string udonAssembly = "";

        [SerializeField]
        protected string assemblyError = null;

        public delegate void AssembleDelegate(bool success, string assembly);
        public event AssembleDelegate OnAssemble;

        protected override void DrawProgramSourceGUI(UdonBehaviour udonBehaviour, ref bool dirty)
        {
            DrawAssemblyTextArea(!Application.isPlaying, ref dirty);
            DrawAssemblyErrorTextArea();

            base.DrawProgramSourceGUI(udonBehaviour, ref dirty);
        }

        protected override void RefreshProgramImpl()
        {
            AssembleProgram();
        }

        [PublicAPI]
        protected virtual void DrawAssemblyTextArea(bool allowEditing, ref bool dirty)
        {
            EditorGUILayout.LabelField("Assembly Code", EditorStyles.boldLabel);
            if(GUILayout.Button("Copy Assembly To Clipboard"))
            {
                EditorGUIUtility.systemCopyBuffer = udonAssembly;
            }

            EditorGUI.BeginChangeCheck();
            using(new EditorGUI.DisabledScope(!allowEditing))
            {
                string newAssembly = EditorGUILayout.TextArea(udonAssembly);
                if(EditorGUI.EndChangeCheck())
                {
                    dirty = true;
                    Undo.RecordObject(this, "Edit Assembly Program Code");
                    udonAssembly = newAssembly;
                    UdonEditorManager.Instance.QueueAndRefreshProgram(this);
                }
            }
        }

        [PublicAPI]
        protected void DrawAssemblyErrorTextArea()
        {
            if(string.IsNullOrEmpty(assemblyError))
            {
                return;
            }

            EditorGUILayout.LabelField("Assembly Error", EditorStyles.boldLabel);
            using(new EditorGUI.DisabledScope(true))
            {
                EditorGUILayout.TextArea(assemblyError);
            }
        }

        [PublicAPI]
        protected void AssembleProgram()
        {
            try
            {
                program = UdonEditorManager.Instance.Assemble(udonAssembly);
                assemblyError = null;
                OnAssemble?.Invoke(true, udonAssembly);
            }
            catch(Exception e)
            {
                program = null;
                assemblyError = e.Message;
                Debug.LogException(e);
                OnAssemble?.Invoke(false, assemblyError);
            }
        }

    }
}