Skip to content

Commit d0e665f

Browse files
committed
added support for binding rules that allow multiple components (v3.4.6)
1 parent 504fb21 commit d0e665f

4 files changed

Lines changed: 91 additions & 36 deletions

File tree

Assets/OxGFrame/CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# CHANGELOG
22

3+
## [3.4.6] - 2025-08-18
4+
5+
# English
6+
7+
- CoreFrame
8+
- Added support for binding rules that allow multiple components.
9+
- Example: _Node@MyObj*Txt*Img*BtnPlus → parsed into bindings: _myObjTxt, _myObjImg, _myObjBtnPlus.
10+
11+
# 中文
12+
13+
- CoreFrame
14+
- 新增支持綁定規則允許多組件。
15+
- 例如:_Node@MyObj*Txt*Img*BtnPlus -> 解析綁定為 _myObjTxt, _myObjImg, _myObjBtnPlus。
16+
317
## [3.4.5] - 2025-08-07
418

519
# English

Assets/OxGFrame/CoreFrame/Scripts/Editor/BindCodeAutoGenerateEditor.cs

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ private static void _CollectBindInfo(string name)
194194
string[] bindArgs = Binder.GetAccessModifierSplitNameBySeparator(bindInfo);
195195

196196
// MyObj*Txt$public => ["MyObj*Txt", "public"]
197-
string bindName = bindArgs[0];
197+
string fullBindName = bindArgs[0];
198198
string variableAccessModifier = (bindArgs.Length > 1) ? bindArgs[1] : null;
199199

200200
// 匹配 Attr []
@@ -213,52 +213,70 @@ private static void _CollectBindInfo(string name)
213213
}
214214
else
215215
{
216-
MatchCollection attrMatches = Regex.Matches(bindName, pattern);
216+
MatchCollection attrMatches = Regex.Matches(fullBindName, pattern);
217217
if (attrMatches.Count > 0)
218218
{
219219
// 將匹配的子字符串存入陣列
220220
attrNames = attrMatches.Cast<Match>().Select(m => m.Value).ToArray();
221221
// 將所有方括號替換為空字串
222-
bindName = Regex.Replace(bindName, pattern, "");
222+
fullBindName = Regex.Replace(fullBindName, pattern, "");
223223
}
224224
}
225225
#endregion
226226

227-
// 組件結尾檢測
228-
string[] tails = Binder.GetTailSplitNameBySeparator(bindName);
229-
string variableName, componentName;
227+
// 組件結尾檢測 => fullBindName = MyObj*Txt*Img = [MyObj, Txt, Img]
228+
string[] tails = Binder.GetTailSplitNameBySeparator(fullBindName);
229+
string variableName;
230+
List<string> bindNames = new List<string>();
231+
List<string> componentNames = new List<string>();
230232

231233
if (tails != null &&
232234
tails.Length >= 2)
233235
// Component
234236
{
235-
variableName = tails[0] + tails[1];
236-
componentName = tails[1];
237+
variableName = tails[0];
238+
// Multi Components
239+
for (int i = 1; i < tails.Length; i++)
240+
{
241+
// 合併綁定名稱 = MyObj*Txt
242+
bindNames.Add($"{tails[0]}*{tails[i]}");
243+
componentNames.Add(tails[i]);
244+
}
237245
}
238246
// GameObject
239247
else
240248
{
241-
variableName = bindName;
242-
componentName = _DEF_COMPONENT_NAME;
249+
variableName = tails[0];
250+
bindNames.Add(tails[0]);
251+
componentNames.Add(_DEF_COMPONENT_NAME);
243252
}
244253

245-
// 修正 Case
246-
switch (_settings.variableCaseType)
254+
for (int i = 0; i < bindNames.Count; i++)
247255
{
248-
case BindCodeSetting.CaseType.CamelCase:
249-
variableName = char.ToLower(variableName[0]) + variableName.Substring(1);
250-
break;
251-
case BindCodeSetting.CaseType.PascalCase:
252-
variableName = char.ToUpper(variableName[0]) + variableName.Substring(1);
253-
break;
254-
}
256+
string bindName = bindNames[i];
257+
string componentName = componentNames[i];
258+
string finalBindName = componentName.Equals(_DEF_COMPONENT_NAME) ? variableName : variableName + componentName;
259+
string finalVariableName = string.Empty;
255260

256-
// 搜集綁定資訊
257-
if (_collectBindInfos.ContainsKey(bindName))
258-
{
259-
_collectBindInfos[bindName].count++;
261+
// 修正 Case
262+
switch (_settings.variableCaseType)
263+
{
264+
case BindCodeSetting.CaseType.CamelCase:
265+
finalVariableName = char.ToLower(finalBindName[0]) + finalBindName.Substring(1);
266+
break;
267+
case BindCodeSetting.CaseType.PascalCase:
268+
finalVariableName = char.ToUpper(finalBindName[0]) + finalBindName.Substring(1);
269+
break;
270+
}
271+
272+
// 搜集綁定資訊
273+
if (_collectBindInfos.ContainsKey(bindName))
274+
{
275+
_collectBindInfos[bindName].count++;
276+
}
277+
else
278+
_collectBindInfos.Add(bindName, new BindInfo(attrNames, variableAccessModifier, bindName, finalVariableName, componentName, 1));
260279
}
261-
else _collectBindInfos.Add(bindName, new BindInfo(attrNames, variableAccessModifier, bindName, variableName, componentName, 1));
262280
}
263281
#endregion
264282

Assets/OxGFrame/CoreFrame/Scripts/Runtime/Core/Common/Binder.cs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using OxGFrame.CoreFrame.CPFrame;
22
using OxGKit.LoggingSystem;
3+
using System;
4+
using System.Collections.Generic;
35
using System.Text.RegularExpressions;
46
using UnityEngine;
57

@@ -63,18 +65,38 @@ private static void _BindIntoCollector(string name, GameObject go, FrameBase fBa
6365
string[] bindArgs = GetAccessModifierSplitNameBySeparator(bindInfo);
6466

6567
// MyObj*Txt$public => ["MyObj*Txt", "public"]
66-
string bindName = bindArgs[0];
68+
string fullBindName = bindArgs[0];
6769

6870
// 匹配 Attr []
6971
string pattern = @"\[(.*?)\]";
70-
MatchCollection attrMatches = Regex.Matches(bindName, pattern);
72+
MatchCollection attrMatches = Regex.Matches(fullBindName, pattern);
7173
if (attrMatches.Count > 0)
7274
{
7375
// 將所有方括號替換為空字串
74-
bindName = Regex.Replace(bindName, pattern, "");
76+
fullBindName = Regex.Replace(fullBindName, pattern, "");
7577
}
7678
#endregion
7779

80+
// 組件結尾檢測 => fullBindName = MyObj*Txt*Img = [MyObj, Txt, Img]
81+
string[] tails = GetTailSplitNameBySeparator(fullBindName);
82+
List<string> bindNames = new List<string>();
83+
84+
// Multi Components
85+
if (tails != null &&
86+
tails.Length >= 2)
87+
{
88+
for (int i = 1; i < tails.Length; i++)
89+
{
90+
// 合併綁定名稱 = MyObj*Txt
91+
bindNames.Add($"{tails[0]}*{tails[i]}");
92+
}
93+
}
94+
// GameObject
95+
else
96+
{
97+
bindNames.Add($"{tails[0]}");
98+
}
99+
78100
// 再去判斷取得後的字串陣列是否綁定格式資格
79101
if (heads == null ||
80102
heads.Length < 2 ||
@@ -87,8 +109,9 @@ private static void _BindIntoCollector(string name, GameObject go, FrameBase fBa
87109
// 找到對應的綁定類型後, 進行綁定
88110
if (FrameConfig.BIND_COMPONENTS[bindType] == "GameObject")
89111
{
90-
// 綁定至 FrameBase 中對應的容器, 此時進行完成綁定
91-
fBase.collector.AddNode(bindName, go);
112+
// 綁定至收集器, 此時進行完成綁定
113+
foreach (var bindName in bindNames)
114+
fBase.collector.AddNode(bindName, go);
92115
}
93116
}
94117
#endregion
@@ -139,7 +162,7 @@ public static bool CheckNodeHasPrefix(string name)
139162

140163
/// <summary>
141164
/// 透過【BIND_HEAD_SEPARATOR】執行 Split 字串, 返回取得字串陣列
142-
/// ※備註: (Example) _Node@MyObj*Txt => ["_Node", "MyObj*Txt"]
165+
/// <para> ※備註: (Example) _Node@MyObj*Txt => ["_Node", "MyObj*Txt"] </para>
143166
/// </summary>
144167
/// <param name="name"></param>
145168
/// <returns></returns>
@@ -148,12 +171,12 @@ public static string[] GetHeadSplitNameBySeparator(string name)
148171
if (string.IsNullOrEmpty(name))
149172
return null;
150173

151-
return name.Split(FrameConfig.BIND_HEAD_SEPARATOR);
174+
return name.Split(FrameConfig.BIND_HEAD_SEPARATOR, StringSplitOptions.RemoveEmptyEntries);
152175
}
153176

154177
/// <summary>
155178
/// 透過【BIND_TAIL_SEPARATOR】執行 Split 字串, 返回取得字串陣列
156-
/// ※備註: (Example) MyObj*Txt => ["MyObj", "Txt"]
179+
/// <para> ※備註: (Example) MyObj*Txt => ["MyObj", "Txt"] </para>
157180
/// </summary>
158181
/// <param name="name"></param>
159182
/// <returns></returns>
@@ -162,12 +185,12 @@ public static string[] GetTailSplitNameBySeparator(string name)
162185
if (string.IsNullOrEmpty(name))
163186
return null;
164187

165-
return name.Split(FrameConfig.BIND_TAIL_SEPARATOR);
188+
return name.Split(FrameConfig.BIND_TAIL_SEPARATOR, StringSplitOptions.RemoveEmptyEntries);
166189
}
167190

168191
/// <summary>
169192
/// 透過【BIND_ACCESS_MODIFIER_SEPARATOR】執行 Split 字串, 返回取得字串陣列
170-
/// ※備註: (Example) MyObj*Txt$public => ["MyObj*Txt", "public"]
193+
/// <para> ※備註: (Example) MyObj*Txt$public => ["MyObj*Txt", "public"] </para>
171194
/// </summary>
172195
/// <param name="name"></param>
173196
/// <returns></returns>
@@ -176,7 +199,7 @@ public static string[] GetAccessModifierSplitNameBySeparator(string name)
176199
if (string.IsNullOrEmpty(name))
177200
return null;
178201

179-
return name.Split(FrameConfig.BIND_ACCESS_MODIFIER_SEPARATOR);
202+
return name.Split(FrameConfig.BIND_ACCESS_MODIFIER_SEPARATOR, StringSplitOptions.RemoveEmptyEntries);
180203
}
181204
#endregion
182205
}

Assets/OxGFrame/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "com.michaelo.oxgframe",
33
"displayName": "OxGFrame",
44
"description": "The OxGFrame is a framework based on Unity for accelerating game development. Supports multi-platform Win, OSX, Android, iOS, WebGL.",
5-
"version": "3.4.5",
5+
"version": "3.4.6",
66
"unity": "2021.3",
77
"license": "MIT",
88
"samples": [

0 commit comments

Comments
 (0)