@@ -11,6 +11,8 @@ tags: ['RFC']
11
11
12
12
第三次提交版本,2024年1月31日,更新了有关应用 CSS IN JS 实现样式替换的方案。
13
13
14
+ 第四次提交版本,2024年2月16日,更新了有关 ` applyStyle ` 指令如何运转的描述和热替换的新方案。
15
+
14
16
## 总体方案
15
17
16
18
WebGAL 将使用模板思想进行 UI 自定义。在 WebGAL Terre 编辑器中,额外添加一个模板编辑器。在创建 WebGAL 游戏时和创建 WebGAL 游戏后,可以选择要使用的模板。
@@ -123,48 +125,22 @@ applyStyle:Title_button->Title_button_2, Dialog->Dialog_1;
123
125
124
126
首先,在初始化模板时,WebGAL 维护一个从原始的模板中类名到要应用的类名的映射:
125
127
126
- ```
127
- const styleMap = new Map <string,{targetClass:string, currentApplyClass: string}>();
128
+ ``` ts
129
+ type replacedUIlable = Record <string , string >
128
130
` ` `
129
131
130
- ` targetClass ` 代表在 ` applyStyle ` 时注册的某个组件的标识符,比如 ` Title_button ` ,` currentApplyClass ` 代表目前应用的类名,在初始化时与标识符保持一致,但是可以被 ` applyStyle ` 指令切换 。
132
+ ` 键 ` 代表在 ` applyStyle ` 时注册的某个组件的标识符,比如 ` Title_button ` , ` 值 ` 代表目前应用的类名,由 ` applyStyle ` 指令写入 。
131
133
132
- 在注册时,就订阅类名切换的事件。如果某个插入的 css 段中的类名发生了“切换类名”,那么这个事件就会发出。指令会重新注册 ` currentApplyClass ` ,然后重新在获取到的样式文件中寻找指定的类名,然后使用 CSS IN JS 框架应用。
134
+ 如果 ` applyStyle ` 指令被执行,指令会写 ` replacedUIlable ` ,更新状态,然后被 CSS IN JS 框架应用。
133
135
134
- 比如,原有的 ` styleMap ` 中有一个实体 ` "Title_button"->{targetClass: "Title_button", currentApplyClass:"Title_button"} `
136
+ 比如,原有的 ` replacedUIlable ` 中有一个实体 ` " Title_button" ->" Title_button" `
135
137
136
138
运行了指令 ` applyStyle : Title_button ->Title_button_2 ;`
137
139
138
- 此时更新 Map,注册为 ` Title_button"->{targetClass:"Title_button", currentApplyClass:" Title_button_2"} `
140
+ 此时更新为 ` Title_button " ->" Title_button_2 " `
139
141
140
142
这时候,要替换到标识符被注册为` Title_button ` 的类名就变为 ` Title_button_2 ` ,原有的 ` Title_button ` 不再生效。
141
143
142
- 由此可见,切换类名的脚本要发出事件
143
-
144
- ```
145
- // ... 其他逻辑
146
- eventBus.emit('classname-change',类名)
147
- ```
148
-
149
- ` useApplyStyle ` 要接受事件并判断是否要重新替换 CSS:
150
-
151
- ``` ts
152
- const useApplyStyle = (url : string ) => {
153
- useEffect (()=> {
154
- const applyStyle = ()=> {
155
- // ...... 其他代码
156
- }
157
- eventBus .on (' classname-change' ,className => {
158
- const isHotReplace = Object .keys (classNameMap ).findIndex (e === className ) > - 1 ;
159
- if (isHotReplace ) applyStyle ();
160
- })
161
- return ()=> {
162
- eventBus .off (...... )
163
- }
164
- },[])
165
- }
166
- ```
167
-
168
144
### 引用资源
169
145
170
146
如果一个模板要引用资源,必须引用在模板资源目录下的资源。
@@ -241,20 +217,7 @@ registerStyleEditor('UI/Title/title.scss', "Title_button", t("标题按钮")) //
241
217
242
218
为了在编辑的流程中优化编辑体验,要实现热替换特性。
243
219
244
- 还记得我们定义的 ` useApplyStyle ` 吗?在这个函数中,我们在全局注册一个文件路径到指定的 ` style ` 块的映射,比如
245
-
246
- ``` ts
247
- const useApplyStyle = (url : string ) => {
248
- useEffect (()=> {
249
- const applyStyle = ()=> {
250
- // ...... 其他代码
251
- }
252
- register (url , applyStyle );// 注册回调函数,当编辑器后端通知时,重新跑一遍 applyStyle
253
- },[])
254
- }
255
- ```
256
-
257
- 这样,当我们的编辑器后端向引擎发送一个 WebSocket 消息时,就可以让引擎重新请求对应的 scss 文件,然后删除之前动态添加的 style 标签,重新转换 css ,然后动态添加标签。
220
+ 编辑器只需要向引擎发送一个消息,让引擎去重新请求所有的样式文件就可以了。由于编辑器大多数情况下在本地运行,所以网络请求的延迟可以忽略不计。
258
221
259
222
## 双模编辑
260
223
0 commit comments