-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathReactWebBridge.cs
157 lines (128 loc) · 4.25 KB
/
ReactWebBridge.cs
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
using ReactUnity;
using ReactUnity.Styling;
using ReactUnity.UGUI;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ReactWebBridge : MonoBehaviour
{
public const string ReplaceSnippet = "/*INJECT_CODE*/";
public bool AutoRender;
public ReactRendererUGUI ReactCanvas;
private string CssContent;
private string PendingCssContent;
private StyleSheet StyleSheet;
private string ScriptContent;
private bool Rendered;
public ScriptSourceLanguage ScriptLanguage = ScriptSourceLanguage.JavaScript;
[Multiline(10)]
public string TestScript = "";
[Multiline(10)]
public string TestStyle = "";
public TextAsset InjectableScript;
public TextAsset RerenderScript;
private void Awake()
{
ReactCanvas.AdvancedOptions.AutoRender = false;
ReactCanvas.enabled = true;
}
private void OnEnable()
{
if (AutoRender) Test();
}
private void Start()
{
#if UNITY_WEBGL && !UNITY_EDITOR
WebGLInput.captureAllKeyboardInput = false;
#endif
}
[ContextMenu("Test")]
public void Test()
{
if (ScriptLanguage == ScriptSourceLanguage.Html) SetHTML(TestScript);
else SetJSX(TestScript);
SetCSS(TestStyle);
RenderBridge();
}
public void SetJSX(string script)
{
var text = InjectableScript.text;
ScriptContent = script;
// If an html document was rendered previously, rerender will fail
if (ScriptLanguage == ScriptSourceLanguage.Html)
Rendered = false;
ScriptLanguage = ScriptSourceLanguage.JavaScript;
var injectedScript = text.Replace(ReplaceSnippet, script);
ReactCanvas.Source = ScriptSource.Text(injectedScript, ScriptSourceLanguage.JavaScript);
}
public void SetHTML(string script)
{
ScriptContent = script;
ScriptLanguage = ScriptSourceLanguage.Html;
ReactCanvas.Source = ScriptSource.Text(script, ScriptSourceLanguage.Html);
}
public void SetCSS(string script)
{
CssContent = script;
PendingCssContent = script;
}
public void ReplaceCSS(string script)
{
CssContent = script;
PendingCssContent = script;
if (ReactCanvas.Context == null) return;
if (StyleSheet != null) ReactCanvas.Context.RemoveStyle(StyleSheet);
if (!string.IsNullOrWhiteSpace(script))
StyleSheet = ReactCanvas.Context.InsertStyle(script);
PendingCssContent = null;
}
public void RenderBridge()
{
if (string.IsNullOrWhiteSpace(ScriptContent)) return;
if (!Rendered || ReactCanvas.Context == null || ScriptLanguage == ScriptSourceLanguage.Html)
{
StyleSheet = null;
ReactCanvas.Context?.Style.StyleTree.Children.Clear();
ReactCanvas.Render();
if (!string.IsNullOrWhiteSpace(CssContent))
StyleSheet = ReactCanvas.Context?.InsertStyle(CssContent);
PendingCssContent = null;
Rendered = true;
}
else
{
var hasError = false;
try
{
var rerenderScript = RerenderScript.text.Replace(ReplaceSnippet, ScriptContent);
ReactCanvas.Context.Script.ExecuteScript(rerenderScript, "ReactUnityInjectableRender");
if (PendingCssContent != null) ReplaceCSS(PendingCssContent);
}
catch (System.Exception ex)
{
Debug.LogWarning("Failed fast rendering. Falling back to regular render. " + ex.Message);
Rendered = false;
hasError = true;
}
if (hasError) RenderBridge();
}
}
public void ReloadScene()
{
StyleSheet = null;
var scene = SceneManager.GetActiveScene();
SceneManager.LoadScene(scene.name);
}
public void LoadScene(string sceneName)
{
StyleSheet = null;
SceneManager.LoadScene(sceneName);
}
private void OnDisable()
{
Rendered = false;
}
private void OnDestroy()
{
Rendered = false;
}
}