com.kylin.di 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/.github/workflows/publish.yml +22 -0
  2. package/CHANGELOG.md +17 -0
  3. package/CLAUDE.md +58 -0
  4. package/LICENSE +21 -0
  5. package/README.md +704 -0
  6. package/Runtime/Attributes/InjectAttribute.cs +11 -0
  7. package/Runtime/Attributes/InjectAttribute.cs.meta +2 -0
  8. package/Runtime/Attributes/ViewModelAttribute.cs +17 -0
  9. package/Runtime/Attributes/ViewModelAttribute.cs.meta +2 -0
  10. package/Runtime/Attributes.meta +8 -0
  11. package/Runtime/Core/DIBehaviour.cs +70 -0
  12. package/Runtime/Core/DIBehaviour.cs.meta +2 -0
  13. package/Runtime/Core/LifetimeScope.cs +264 -0
  14. package/Runtime/Core/LifetimeScope.cs.meta +2 -0
  15. package/Runtime/Core.meta +8 -0
  16. package/Runtime/DI/DependencyBuilder.cs +114 -0
  17. package/Runtime/DI/DependencyBuilder.cs.meta +2 -0
  18. package/Runtime/DI/DependencyInjector.cs +104 -0
  19. package/Runtime/DI/DependencyInjector.cs.meta +2 -0
  20. package/Runtime/DI/InstanceFactory.cs +36 -0
  21. package/Runtime/DI/InstanceFactory.cs.meta +2 -0
  22. package/Runtime/DI/KDI.cs +54 -0
  23. package/Runtime/DI/KDI.cs.meta +2 -0
  24. package/Runtime/DI/Registration.cs +29 -0
  25. package/Runtime/DI/Registration.cs.meta +2 -0
  26. package/Runtime/DI/Scope.cs +183 -0
  27. package/Runtime/DI/Scope.cs.meta +2 -0
  28. package/Runtime/DI/ScopeBuilder.cs +68 -0
  29. package/Runtime/DI/ScopeBuilder.cs.meta +2 -0
  30. package/Runtime/DI/ScopeExtensions.cs +70 -0
  31. package/Runtime/DI/ScopeExtensions.cs.meta +2 -0
  32. package/Runtime/DI.meta +8 -0
  33. package/Runtime/Debug/ClosureAnalyzer.cs +377 -0
  34. package/Runtime/Debug/ClosureAnalyzer.cs.meta +2 -0
  35. package/Runtime/Debug/ClosureProfilerWindow.cs +435 -0
  36. package/Runtime/Debug/ClosureProfilerWindow.cs.meta +2 -0
  37. package/Runtime/Debug/SubscriberInfo.cs +661 -0
  38. package/Runtime/Debug/SubscriberInfo.cs.meta +3 -0
  39. package/Runtime/Debug.meta +3 -0
  40. package/Runtime/Kylin.DI.asmdef +14 -0
  41. package/Runtime/Kylin.DI.asmdef.meta +7 -0
  42. package/Runtime/SubscribableProperty/Reaction.cs +61 -0
  43. package/Runtime/SubscribableProperty/Reaction.cs.meta +2 -0
  44. package/Runtime/SubscribableProperty/SubscribableCollection.cs +325 -0
  45. package/Runtime/SubscribableProperty/SubscribableCollection.cs.meta +3 -0
  46. package/Runtime/SubscribableProperty/SubscribableCollectionExtensions.cs +24 -0
  47. package/Runtime/SubscribableProperty/SubscribableCollectionExtensions.cs.meta +3 -0
  48. package/Runtime/SubscribableProperty/SubscribableCommand.cs +52 -0
  49. package/Runtime/SubscribableProperty/SubscribableCommand.cs.meta +2 -0
  50. package/Runtime/SubscribableProperty/SubscribableDictionary.cs +350 -0
  51. package/Runtime/SubscribableProperty/SubscribableDictionary.cs.meta +3 -0
  52. package/Runtime/SubscribableProperty/SubscribableProperty.cs +119 -0
  53. package/Runtime/SubscribableProperty/SubscribableProperty.cs.meta +2 -0
  54. package/Runtime/SubscribableProperty/SubscribablePropertyExtensions.cs +39 -0
  55. package/Runtime/SubscribableProperty/SubscribablePropertyExtensions.cs.meta +3 -0
  56. package/Runtime/SubscribableProperty/SubscribablePropertyLinq.cs +86 -0
  57. package/Runtime/SubscribableProperty/SubscribablePropertyLinq.cs.meta +2 -0
  58. package/Runtime/SubscribableProperty.meta +8 -0
  59. package/Runtime/Update/IFixedUpdatable.cs +16 -0
  60. package/Runtime/Update/IFixedUpdatable.cs.meta +2 -0
  61. package/Runtime/Update/ILateUpdatable.cs +16 -0
  62. package/Runtime/Update/ILateUpdatable.cs.meta +2 -0
  63. package/Runtime/Update/IUpdatable.cs +16 -0
  64. package/Runtime/Update/IUpdatable.cs.meta +2 -0
  65. package/Runtime/Update/IUpdatePriority.cs +15 -0
  66. package/Runtime/Update/IUpdatePriority.cs.meta +2 -0
  67. package/Runtime/Update/UpdateLoopManager.cs +240 -0
  68. package/Runtime/Update/UpdateLoopManager.cs.meta +2 -0
  69. package/Runtime/Update.meta +8 -0
  70. package/Runtime.meta +8 -0
  71. package/package.json +19 -0
@@ -0,0 +1,15 @@
1
+ namespace Kylin.DI
2
+ {
3
+ /// <summary>
4
+ /// Update 실행 순서 우선순위 인터페이스 (선택적)
5
+ /// - 낮은 값이 먼저 실행됨
6
+ /// - 기본값: 0
7
+ /// </summary>
8
+ public interface IUpdatePriority
9
+ {
10
+ /// <summary>
11
+ /// 실행 우선순위 (낮을수록 먼저 실행)
12
+ /// </summary>
13
+ int UpdatePriority { get; }
14
+ }
15
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: d48478d25d4ff6a4897d1252dda2f9b4
@@ -0,0 +1,240 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using UnityEngine;
4
+
5
+ namespace Kylin.DI
6
+ {
7
+ public class UpdateLoopManager : MonoBehaviour
8
+ {
9
+ private static UpdateLoopManager _instance;
10
+ private static bool _applicationQuitting;
11
+
12
+ [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
13
+ private static void ResetStatic()
14
+ {
15
+ _instance = null;
16
+ _applicationQuitting = false;
17
+ }
18
+
19
+ public static UpdateLoopManager Instance
20
+ {
21
+ get
22
+ {
23
+ if (_applicationQuitting) return null;
24
+
25
+ if (_instance == null)
26
+ {
27
+ var go = new GameObject("[KDI] UpdateLoopManager");
28
+ _instance = go.AddComponent<UpdateLoopManager>();
29
+ DontDestroyOnLoad(go);
30
+ }
31
+ return _instance;
32
+ }
33
+ }
34
+
35
+ private List<IUpdatable> _updatables = new List<IUpdatable>();
36
+ private List<IFixedUpdatable> _fixedUpdatables = new List<IFixedUpdatable>();
37
+ private List<ILateUpdatable> _lateUpdatables = new List<ILateUpdatable>();
38
+
39
+ private bool _updatablesDirty = false;
40
+ private bool _fixedUpdatablesDirty = false;
41
+ private bool _lateUpdatablesDirty = false;
42
+
43
+ private Queue<Action> _pendingOperations = new Queue<Action>();
44
+ private readonly object _lock = new object();
45
+
46
+ public void Register(object service)
47
+ {
48
+ if (service == null) return;
49
+
50
+ lock (_lock)
51
+ {
52
+ _pendingOperations.Enqueue(() =>
53
+ {
54
+ if (service is IUpdatable updatable)
55
+ {
56
+ if (!_updatables.Contains(updatable))
57
+ {
58
+ _updatables.Add(updatable);
59
+ _updatablesDirty = true;
60
+ }
61
+ }
62
+
63
+ if (service is IFixedUpdatable fixedUpdatable)
64
+ {
65
+ if (!_fixedUpdatables.Contains(fixedUpdatable))
66
+ {
67
+ _fixedUpdatables.Add(fixedUpdatable);
68
+ _fixedUpdatablesDirty = true;
69
+ }
70
+ }
71
+
72
+ if (service is ILateUpdatable lateUpdatable)
73
+ {
74
+ if (!_lateUpdatables.Contains(lateUpdatable))
75
+ {
76
+ _lateUpdatables.Add(lateUpdatable);
77
+ _lateUpdatablesDirty = true;
78
+ }
79
+ }
80
+ });
81
+ }
82
+ }
83
+
84
+ public void Unregister(object service)
85
+ {
86
+ if (service == null) return;
87
+
88
+ lock (_lock)
89
+ {
90
+ _pendingOperations.Enqueue(() =>
91
+ {
92
+ if (service is IUpdatable updatable)
93
+ {
94
+ _updatables.Remove(updatable);
95
+ }
96
+
97
+ if (service is IFixedUpdatable fixedUpdatable)
98
+ {
99
+ _fixedUpdatables.Remove(fixedUpdatable);
100
+ }
101
+
102
+ if (service is ILateUpdatable lateUpdatable)
103
+ {
104
+ _lateUpdatables.Remove(lateUpdatable);
105
+ }
106
+ });
107
+ }
108
+ }
109
+
110
+
111
+ private void Update()
112
+ {
113
+ ProcessPendingOperations();
114
+
115
+ if (_updatablesDirty)
116
+ {
117
+ SortByPriority(_updatables);
118
+ _updatablesDirty = false;
119
+ }
120
+
121
+ float deltaTime = Time.deltaTime;
122
+ for (int i = 0; i < _updatables.Count; i++)
123
+ {
124
+ try
125
+ {
126
+ _updatables[i]?.KDIUpdate(deltaTime);
127
+ }
128
+ catch (Exception ex)
129
+ {
130
+ Debug.LogError($"[UpdateLoopManager] Error in KDIUpdate: {ex}");
131
+ }
132
+ }
133
+ }
134
+
135
+ private void FixedUpdate()
136
+ {
137
+ if (_fixedUpdatablesDirty)
138
+ {
139
+ SortByPriority(_fixedUpdatables);
140
+ _fixedUpdatablesDirty = false;
141
+ }
142
+
143
+ float fixedDeltaTime = Time.fixedDeltaTime;
144
+ for (int i = 0; i < _fixedUpdatables.Count; i++)
145
+ {
146
+ try
147
+ {
148
+ _fixedUpdatables[i]?.KDIFixedUpdate(fixedDeltaTime);
149
+ }
150
+ catch (Exception ex)
151
+ {
152
+ Debug.LogError($"[UpdateLoopManager] Error in KDIFixedUpdate: {ex}");
153
+ }
154
+ }
155
+ }
156
+
157
+ private void LateUpdate()
158
+ {
159
+ if (_lateUpdatablesDirty)
160
+ {
161
+ SortByPriority(_lateUpdatables);
162
+ _lateUpdatablesDirty = false;
163
+ }
164
+
165
+ float deltaTime = Time.deltaTime;
166
+ for (int i = 0; i < _lateUpdatables.Count; i++)
167
+ {
168
+ try
169
+ {
170
+ _lateUpdatables[i]?.KDILateUpdate(deltaTime);
171
+ }
172
+ catch (Exception ex)
173
+ {
174
+ Debug.LogError($"[UpdateLoopManager] Error in KDILateUpdate: {ex}");
175
+ }
176
+ }
177
+ }
178
+
179
+ private void ProcessPendingOperations()
180
+ {
181
+ lock (_lock)
182
+ {
183
+ while (_pendingOperations.Count > 0)
184
+ {
185
+ var operation = _pendingOperations.Dequeue();
186
+ operation?.Invoke();
187
+ }
188
+ }
189
+ }
190
+
191
+ /// <summary>
192
+ /// 우선순위에 따라 정렬
193
+ /// </summary>
194
+ private void SortByPriority<T>(List<T> list)
195
+ {
196
+ list.Sort((a, b) =>
197
+ {
198
+ int priorityA = (a is IUpdatePriority pa) ? pa.UpdatePriority : 0;
199
+ int priorityB = (b is IUpdatePriority pb) ? pb.UpdatePriority : 0;
200
+ return priorityA.CompareTo(priorityB);
201
+ });
202
+ }
203
+
204
+ /// <summary>
205
+ /// 등록된 서비스 수 확인
206
+ /// </summary>
207
+ public (int update, int fixedUpdate, int lateUpdate) GetRegisteredCount()
208
+ {
209
+ return (_updatables.Count, _fixedUpdatables.Count, _lateUpdatables.Count);
210
+ }
211
+
212
+ [ContextMenu("Print Registered Services")]
213
+ private void PrintRegisteredServices()
214
+ {
215
+ Debug.Log($"[UpdateLoopManager] Registered Services:");
216
+ Debug.Log($" - KDIUpdate: {_updatables.Count}");
217
+ Debug.Log($" - KDIFixedUpdate: {_fixedUpdatables.Count}");
218
+ Debug.Log($" - KDILateUpdate: {_lateUpdatables.Count}");
219
+
220
+ foreach (var updatable in _updatables)
221
+ {
222
+ var priority = (updatable is IUpdatePriority p) ? p.UpdatePriority : 0;
223
+ Debug.Log($" • {updatable.GetType().Name} (Priority: {priority})");
224
+ }
225
+ }
226
+
227
+ private void OnApplicationQuit()
228
+ {
229
+ _applicationQuitting = true;
230
+ }
231
+
232
+ private void OnDestroy()
233
+ {
234
+ if (_instance == this)
235
+ {
236
+ _instance = null;
237
+ }
238
+ }
239
+ }
240
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 7fd705fa89c8605479a5685845f84a77
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: aa4c4dd437131504aa95f854806b9dfe
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
package/Runtime.meta ADDED
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: dcf55dbc96d7a0c4fadc827e658ce2fb
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "com.kylin.di",
3
+ "version": "1.0.0",
4
+ "displayName": "KDI (Kylin Dependency Injection)",
5
+ "description": "Scope-based dependency injection framework for Unity 6. Field injection only, hierarchical scopes, built-in reactive properties.",
6
+ "unity": "6000.0",
7
+ "documentationUrl": "",
8
+ "license": "MIT",
9
+ "keywords": [
10
+ "dependency-injection",
11
+ "di",
12
+ "ioc",
13
+ "scope",
14
+ "reactive"
15
+ ],
16
+ "author": {
17
+ "name": "Kylin"
18
+ }
19
+ }