Skip to content

Commit fee22d0

Browse files
committed
feat!: release v3.0.0 core architecture refresh
- replace ServiceRegistry with ServiceContainer and add tagged service API - migrate SceneEntityIndex to LocalConnector-first indexing with runtime-safe tag refresh - remove EntityKeyBehaviour and legacy debug config tooling - add FrameworkConfig + FrameworkLogger and improve SceneConnector spawn/collection flow - add EditMode/PlayMode tests, examples, and Russian docs - isolate benchmark assembly to Editor and move benchmark logs to docs
1 parent 16feef2 commit fee22d0

File tree

85 files changed

+3234
-2142
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+3234
-2142
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ Assets/AbyssMothNodeFramework/Resources/AbyssMothNodeFramework.meta
7878
Assets/AbyssMothNodeFramework/Resources/AbyssMothNodeFramework/
7979

8080
Resources/AbyssMothNodeFramework.meta
81-
Resources/AbyssMothNodeFramework/ConnectorDebugConfig.asset
82-
Resources/AbyssMothNodeFramework/ConnectorDebugConfig.asset.meta
81+
Resources/AbyssMothNodeFramework/FrameworkConfig.asset
82+
Resources/AbyssMothNodeFramework/FrameworkConfig.asset.meta
8383
Resources/AbyssMothNodeFramework/ProjectRootConnector.prefab
8484
Resources/AbyssMothNodeFramework/ProjectRootConnector.prefab.meta
8585
Resources.meta

Benchmark/AMNF.Benchmark.asmdef

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
"GUID:adbda3056052341eba6768c10b1769d6",
66
"GUID:776d03a35f1b52c4a9aed9f56d7b4229"
77
],
8-
"includePlatforms": [],
8+
"includePlatforms": [
9+
"Editor"
10+
],
911
"excludePlatforms": [],
1012
"allowUnsafeCode": false,
1113
"overrideReferences": false,
@@ -14,4 +16,4 @@
1416
"defineConstraints": [],
1517
"versionDefines": [],
1618
"noEngineReferences": false
17-
}
19+
}

Benchmark/BenchmarkResults.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Benchmark Results (Historical)
2+
3+
Источник: исторические логи `ConnectorBenchmarkRunner` из старой версии файла.
4+
5+
## Срез 1
6+
7+
- Baseline double-loop: `59.666 ms` | `10,000,000 calls` | `~5.97 ns/call`
8+
- Interface list Step: `30.292 ms` | `10,000,000 calls` | `~3.03 ns/call`
9+
- LocalConnector Tick (cached): `182.26 ms` | `10,000,000 calls` | `~18.23 ns/call`
10+
11+
## Срез 2
12+
13+
- Baseline double-loop: `54.414 ms` | `10,000,000 calls` | `~5.44 ns/call`
14+
- Interface list Step: `29.201 ms` | `10,000,000 calls` | `~2.92 ns/call`
15+
- LocalConnector Tick (cached): `177.095 ms` | `10,000,000 calls` | `~17.71 ns/call`
16+
17+
## Unity probe
18+
19+
- Unity BehaviourUpdate avg: `0.179 ms/frame` (`frames: 300`)
20+
21+
## Вывод из старого прогона
22+
23+
Оценка накладных расходов диспетчеризации (`LocalConnector.Tick` vs interface-loop):
24+
- порядка `~15 ns` на вызов в том замере.
25+
- при `1000` тикающих нод это около `0.015 ms/frame`.
26+
- при `5000` тикающих нод это около `0.075 ms/frame`.
27+
28+
Важно: эти числа исторические. Для актуальной версии использовать свежие прогоны по протоколу из `Benchmark/README.md`.

Benchmark/BenchmarkResults.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Benchmark/ConnectorBenchmarkRunner.cs

Lines changed: 6 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,3 @@
1-
// Dump:
2-
3-
// ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
4-
// ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
5-
//
6-
// Baseline double-loop: 59.666 ms | calls: 10000000 | ~5.97 ns/call | extra: 163732.3
7-
// UnityEngine.Debug:Log (object)
8-
// AbyssMoth.ConnectorBenchmarkRunner:PrintResult (string,double,int,int,object) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:203)
9-
// AbyssMoth.ConnectorBenchmarkRunner:RunBaselineLoop (single) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:139)
10-
// AbyssMoth.ConnectorBenchmarkRunner:RunBenchmark () (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:84)
11-
// System.Reflection.MethodBase:Invoke (object,object[])
12-
// NaughtyAttributes.Editor.NaughtyEditorGUI:Button (UnityEngine.Object,System.Reflection.MethodInfo) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/Utility/NaughtyEditorGUI.cs:167)
13-
// NaughtyAttributes.Editor.NaughtyInspector:DrawButtons (bool) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:188)
14-
// NaughtyAttributes.Editor.NaughtyInspector:OnInspectorGUI () (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:52)
15-
// UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&) (at /Users/bokken/build/output/unity/unity/Modules/IMGUI/GUIUtility.cs:224)
16-
//
17-
//
18-
// Interface list Step: 30.292 ms | calls: 10000000 | ~3.03 ns/call
19-
// UnityEngine.Debug:Log (object)
20-
// AbyssMoth.ConnectorBenchmarkRunner:PrintResult (string,double,int,int,object) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:205)
21-
// AbyssMoth.ConnectorBenchmarkRunner:RunInterfaceLoop (single) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:165)
22-
// AbyssMoth.ConnectorBenchmarkRunner:RunBenchmark () (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:85)
23-
// System.Reflection.MethodBase:Invoke (object,object[])
24-
// NaughtyAttributes.Editor.NaughtyEditorGUI:Button (UnityEngine.Object,System.Reflection.MethodInfo) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/Utility/NaughtyEditorGUI.cs:167)
25-
// NaughtyAttributes.Editor.NaughtyInspector:DrawButtons (bool) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:188)
26-
// NaughtyAttributes.Editor.NaughtyInspector:OnInspectorGUI () (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:52)
27-
// UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&) (at /Users/bokken/build/output/unity/unity/Modules/IMGUI/GUIUtility.cs:224)
28-
//
29-
//
30-
// LocalConnector Tick (cached): 182.26 ms | calls: 10000000 | ~18.23 ns/call
31-
// UnityEngine.Debug:Log (object)
32-
// AbyssMoth.ConnectorBenchmarkRunner:PrintResult (string,double,int,int,object) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:205)
33-
// AbyssMoth.ConnectorBenchmarkRunner:RunLocalConnectorLoop (single) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:188)
34-
// AbyssMoth.ConnectorBenchmarkRunner:RunBenchmark () (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:86)
35-
// System.Reflection.MethodBase:Invoke (object,object[])
36-
// NaughtyAttributes.Editor.NaughtyEditorGUI:Button (UnityEngine.Object,System.Reflection.MethodInfo) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/Utility/NaughtyEditorGUI.cs:167)
37-
// NaughtyAttributes.Editor.NaughtyInspector:DrawButtons (bool) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:188)
38-
// NaughtyAttributes.Editor.NaughtyInspector:OnInspectorGUI () (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:52)
39-
// UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&) (at /Users/bokken/build/output/unity/unity/Modules/IMGUI/GUIUtility.cs:224)
40-
//
41-
// ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
42-
// ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
43-
//
44-
// Baseline double-loop: 54.414 ms | calls: 10000000 | ~5.44 ns/call | extra: 163732.3
45-
// UnityEngine.Debug:Log (object)
46-
// AbyssMoth.ConnectorBenchmarkRunner:PrintResult (string,double,int,int,object) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:203)
47-
// AbyssMoth.ConnectorBenchmarkRunner:RunBaselineLoop (single) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:139)
48-
// AbyssMoth.ConnectorBenchmarkRunner:RunBenchmark () (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:84)
49-
// System.Reflection.MethodBase:Invoke (object,object[])
50-
// NaughtyAttributes.Editor.NaughtyEditorGUI:Button (UnityEngine.Object,System.Reflection.MethodInfo) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/Utility/NaughtyEditorGUI.cs:167)
51-
// NaughtyAttributes.Editor.NaughtyInspector:DrawButtons (bool) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:188)
52-
// NaughtyAttributes.Editor.NaughtyInspector:OnInspectorGUI () (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:52)
53-
// UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&) (at /Users/bokken/build/output/unity/unity/Modules/IMGUI/GUIUtility.cs:224)
54-
//
55-
// Interface list Step: 29.201 ms | calls: 10000000 | ~2.92 ns/call
56-
// UnityEngine.Debug:Log (object)
57-
// AbyssMoth.ConnectorBenchmarkRunner:PrintResult (string,double,int,int,object) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:205)
58-
// AbyssMoth.ConnectorBenchmarkRunner:RunInterfaceLoop (single) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:165)
59-
// AbyssMoth.ConnectorBenchmarkRunner:RunBenchmark () (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:85)
60-
// System.Reflection.MethodBase:Invoke (object,object[])
61-
// NaughtyAttributes.Editor.NaughtyEditorGUI:Button (UnityEngine.Object,System.Reflection.MethodInfo) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/Utility/NaughtyEditorGUI.cs:167)
62-
// NaughtyAttributes.Editor.NaughtyInspector:DrawButtons (bool) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:188)
63-
// NaughtyAttributes.Editor.NaughtyInspector:OnInspectorGUI () (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:52)
64-
// UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&) (at /Users/bokken/build/output/unity/unity/Modules/IMGUI/GUIUtility.cs:224)
65-
//
66-
// LocalConnector Tick (cached): 177.095 ms | calls: 10000000 | ~17.71 ns/call
67-
// UnityEngine.Debug:Log (object)
68-
// AbyssMoth.ConnectorBenchmarkRunner:PrintResult (string,double,int,int,object) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:205)
69-
// AbyssMoth.ConnectorBenchmarkRunner:RunLocalConnectorLoop (single) (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:188)
70-
// AbyssMoth.ConnectorBenchmarkRunner:RunBenchmark () (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:86)
71-
// System.Reflection.MethodBase:Invoke (object,object[])
72-
// NaughtyAttributes.Editor.NaughtyEditorGUI:Button (UnityEngine.Object,System.Reflection.MethodInfo) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/Utility/NaughtyEditorGUI.cs:167)
73-
// NaughtyAttributes.Editor.NaughtyInspector:DrawButtons (bool) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:188)
74-
// NaughtyAttributes.Editor.NaughtyInspector:OnInspectorGUI () (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:52)
75-
// UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&) (at /Users/bokken/build/output/unity/unity/Modules/IMGUI/GUIUtility.cs:224)
76-
//
77-
// Unity Update probe started. Keep scene quiet for better signal.
78-
// UnityEngine.Debug:Log (object)
79-
// AbyssMoth.ConnectorBenchmarkRunner/<UnityUpdateProbeCoroutine>d__19:MoveNext () (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:210)
80-
// UnityEngine.MonoBehaviour:StartCoroutine (System.Collections.IEnumerator)
81-
// AbyssMoth.ConnectorBenchmarkRunner:RunBenchmark () (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:89)
82-
// System.Reflection.MethodBase:Invoke (object,object[])
83-
// NaughtyAttributes.Editor.NaughtyEditorGUI:Button (UnityEngine.Object,System.Reflection.MethodInfo) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/Utility/NaughtyEditorGUI.cs:167)
84-
// NaughtyAttributes.Editor.NaughtyInspector:DrawButtons (bool) (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:188)
85-
// NaughtyAttributes.Editor.NaughtyInspector:OnInspectorGUI () (at Assets/AbyssMothFramework/Plugins/NAP/NaughtyAttributes/Scripts/Editor/NaughtyInspector.cs:52)
86-
// UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&) (at /Users/bokken/build/output/unity/unity/Modules/IMGUI/GUIUtility.cs:224)
87-
//
88-
// Unity BehaviourUpdate avg: 0.179 ms/frame (frames: 300)
89-
// UnityEngine.Debug:Log (object)
90-
// AbyssMoth.ConnectorBenchmarkRunner/<UnityUpdateProbeCoroutine>d__19:MoveNext () (at Assets/AbyssMothNodeFramework/Benchmark/ConnectorBenchmarkRunner.cs:249)
91-
// UnityEngine.SetupCoroutine:InvokeMoveNext (System.Collections.IEnumerator,intptr) (at /Users/bokken/build/output/unity/unity/Runtime/Export/Scripting/Coroutines.cs:17)
92-
//
93-
// ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
94-
// ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
95-
//
96-
97-
// Brain activation :D
98-
//
99-
// Разбор чисел:
100-
// Сделал nodesCount=1000, tickLoops=10000 → 10 000 000 вызовов.
101-
// Interface list Step: ~29–30 ms на 10 млн → ~3 ns/call
102-
// LocalConnector cached: ~177–182 ms на 10 млн → ~18 ns/call
103-
//
104-
// Разница ~ 15 ns на вызов (18-3).
105-
//
106-
// Теперь переведём в реальность игры:
107-
// Если у нас 1000 тикающих нод в кадр
108-
// 15 ns * 1000 = 15000 ns = 0.015 ms разницы на кадр.
109-
// Это вообще ни о чём. Особенно учитывая размер моих игр:3
110-
//
111-
// Даже если 5000 нод:
112-
// 15 ns * 5000 = 0.075 ms на кадр.
113-
// То есть по CPU-оверходу диспатча моя система выглядит нормально.
114-
115-
1161
using System;
1172
using System.Collections;
1183
using System.Collections.Generic;
@@ -124,6 +9,9 @@
1249
using Debug = UnityEngine.Debug;
12510

12611
// ReSharper disable NotAccessedField.Local
12+
// Benchmark usage notes:
13+
// - README: Benchmark/README.md
14+
// - Historical runs: Benchmark/BenchmarkResults.md
12715

12816
namespace AbyssMoth
12917
{
@@ -177,7 +65,7 @@ public sealed class ConnectorBenchmarkRunner : MonoBehaviour
17765

17866
private readonly List<IBenchmarkStep> interfaceAgents = new();
17967
private LocalConnector connector;
180-
private ServiceRegistry registry;
68+
private ServiceContainer registry;
18169
private GameObject root;
18270

18371
[Button("Run Benchmark")]
@@ -214,7 +102,7 @@ private void SetupInterfaceAgents()
214102

215103
private void SetupLocalConnector()
216104
{
217-
registry = new ServiceRegistry();
105+
registry = new ServiceContainer();
218106

219107
root = new GameObject($"BenchmarkRoot {nodesCount}");
220108
root.transform.SetParent(transform, worldPositionStays: false);
@@ -396,4 +284,4 @@ public void Update() =>
396284
value += 1f;
397285
}
398286
}
399-
}
287+
}

Benchmark/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# AMNF Benchmark
2+
3+
Назначение: быстрый sanity-check стоимости диспетчеризации `Tick` в `LocalConnector`.
4+
5+
## Что измеряет
6+
7+
`ConnectorBenchmarkRunner` сравнивает:
8+
- baseline double-loop,
9+
- вызов интерфейса (`IBenchmarkStep.Step`),
10+
- `LocalConnector.Tick` с кэшированными нодами,
11+
- (опционально) `BehaviourUpdate` через `ProfilerRecorder`.
12+
13+
## Как запускать
14+
15+
1. Открой пустую сцену в Editor.
16+
2. Добавь `ConnectorBenchmarkRunner` на объект сцены.
17+
3. Включи Play Mode.
18+
4. Нажми кнопку `Run Benchmark` в инспекторе.
19+
5. Скопируй лог из Console.
20+
21+
## Рекомендации по чистоте замера
22+
23+
- не держать тяжелые системы в сцене,
24+
- отключить лишние editor окна/оверлеи,
25+
- запускать несколько прогонов и смотреть медиану,
26+
- сравнивать относительные изменения между версиями, а не абсолютные ns.
27+
28+
## Параметры по умолчанию
29+
30+
- `nodesCount = 1000`
31+
- `tickLoops = 10000`
32+
- `warmupLoops = 300`
33+
34+
Итого ~10M вызовов на замер.
35+
36+
## Исторические результаты
37+
38+
Старые результаты вынесены в:
39+
- `Benchmark/BenchmarkResults.md`

Benchmark/README.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)