com.elestrago.unity.entitas-redux 3.4.2 → 3.5.1
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.
- package/CHANGELOG.md +16 -0
- package/Core/Libs/ListReflectionExtensions.cs +34 -0
- package/Core/Libs/ListReflectionExtensions.cs.meta +3 -0
- package/Core/Matcher/Interfaces/IMatcher.cs +7 -1
- package/Core/Matcher/Matcher.cs +4 -17
- package/Core/Matcher/MatcherStatic.cs +13 -49
- package/Core/Matcher/MatcherToString.cs +20 -39
- package/Core/Matcher/SingleMatcher.cs +27 -0
- package/Core/Matcher/SingleMatcher.cs.meta +3 -0
- package/Core/Systems/Systems.cs +25 -8
- package/Plugins/EntitasRedux.Core.Generator.dll +0 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
## [3.5.1](https://gitlab.com/elestrago-pkg/entitas-redux/-/tags/3.5.1)
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Use `Memory<T>` instead `List<T>` in `Systems` for frequently update systems
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## [3.5.0](https://gitlab.com/elestrago-pkg/entitas-redux/-/tags/3.5.0)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Use `SingleMatcher` for context component matchers
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
5
21
|
## [3.4.2](https://gitlab.com/elestrago-pkg/entitas-redux/-/tags/3.4.2)
|
|
6
22
|
|
|
7
23
|
### Added
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Collections.Generic;
|
|
3
|
+
using System.Reflection;
|
|
4
|
+
|
|
5
|
+
namespace EntitasRedux.Core.Libs
|
|
6
|
+
{
|
|
7
|
+
public static class ListReflectionExtensions
|
|
8
|
+
{
|
|
9
|
+
// We can cache the FieldInfo objects for a slight performance improvement
|
|
10
|
+
// This avoids looking them up every time the method is called.
|
|
11
|
+
private static class ListInternals<T>
|
|
12
|
+
{
|
|
13
|
+
public static readonly FieldInfo ItemsField =
|
|
14
|
+
typeof(List<T>).GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/// <summary>
|
|
18
|
+
/// Gets a Span<T> over the internal storage of a List<T> using reflection.
|
|
19
|
+
/// WARNING: This is highly fragile and depends on the internal implementation of List<T>.
|
|
20
|
+
/// It may break in future .NET versions. Use with extreme caution.
|
|
21
|
+
/// </summary>
|
|
22
|
+
public static Memory<T> AsMemoryReflection<T>(this List<T> list)
|
|
23
|
+
{
|
|
24
|
+
if (list == null)
|
|
25
|
+
return Memory<T>.Empty;
|
|
26
|
+
|
|
27
|
+
// Get the internal array and size using the cached reflection info
|
|
28
|
+
var items = (T[])ListInternals<T>.ItemsField.GetValue(list);
|
|
29
|
+
|
|
30
|
+
// Create a span from the internal array, respecting the list's current size
|
|
31
|
+
return new Memory<T>(items, 0, list.Count);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -28,7 +28,13 @@ namespace JCMG.EntitasRedux
|
|
|
28
28
|
public interface IMatcher<TEntity>
|
|
29
29
|
where TEntity : class, IEntity
|
|
30
30
|
{
|
|
31
|
+
/// <summary>
|
|
32
|
+
/// Initialized in context matcher implementation
|
|
33
|
+
/// </summary>
|
|
34
|
+
public static string[] ComponentNames;
|
|
35
|
+
|
|
31
36
|
int[] Indices { get; }
|
|
37
|
+
|
|
32
38
|
bool Matches(TEntity entity);
|
|
33
39
|
}
|
|
34
|
-
}
|
|
40
|
+
}
|
package/Core/Matcher/Matcher.cs
CHANGED
|
@@ -28,26 +28,13 @@ namespace JCMG.EntitasRedux
|
|
|
28
28
|
public partial class Matcher<TEntity> : IAllOfMatcher<TEntity>
|
|
29
29
|
where TEntity : class, IEntity
|
|
30
30
|
{
|
|
31
|
-
public string[] ComponentNames { get; set; }
|
|
32
|
-
|
|
33
31
|
private int[] _allOfIndices;
|
|
34
32
|
private int[] _anyOfIndices;
|
|
35
33
|
|
|
36
34
|
private int[] _indices;
|
|
37
35
|
private int[] _noneOfIndices;
|
|
38
36
|
|
|
39
|
-
public int[] Indices
|
|
40
|
-
{
|
|
41
|
-
get
|
|
42
|
-
{
|
|
43
|
-
if (_indices == null)
|
|
44
|
-
{
|
|
45
|
-
_indices = MergeIndices(_allOfIndices, _anyOfIndices, _noneOfIndices);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return _indices;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
37
|
+
public int[] Indices => _indices ??= MergeIndices(_allOfIndices, _anyOfIndices, _noneOfIndices);
|
|
51
38
|
|
|
52
39
|
public int[] AllOfIndices => _allOfIndices;
|
|
53
40
|
|
|
@@ -84,8 +71,8 @@ namespace JCMG.EntitasRedux
|
|
|
84
71
|
public bool Matches(TEntity entity)
|
|
85
72
|
{
|
|
86
73
|
return (_allOfIndices == null || entity.HasComponents(_allOfIndices)) &&
|
|
87
|
-
|
|
88
|
-
|
|
74
|
+
(_anyOfIndices == null || entity.HasAnyComponent(_anyOfIndices)) &&
|
|
75
|
+
(_noneOfIndices == null || !entity.HasAnyComponent(_noneOfIndices));
|
|
89
76
|
}
|
|
90
77
|
}
|
|
91
|
-
}
|
|
78
|
+
}
|
|
@@ -33,46 +33,32 @@ namespace JCMG.EntitasRedux
|
|
|
33
33
|
/// <summary>
|
|
34
34
|
/// Lazy-loaded index buffer (ThreadStatic)
|
|
35
35
|
/// </summary>
|
|
36
|
-
private static List<int> IndexBuffer => _indexBufferThreadStatic
|
|
36
|
+
private static List<int> IndexBuffer => _indexBufferThreadStatic ??= new List<int>();
|
|
37
37
|
|
|
38
38
|
/// <summary>
|
|
39
39
|
/// Lazy-loaded index set buffer (ThreadStatic)
|
|
40
40
|
/// </summary>
|
|
41
|
-
private static HashSet<int> IndexSetBuffer => _indexSetBufferThreadStatic
|
|
41
|
+
private static HashSet<int> IndexSetBuffer => _indexSetBufferThreadStatic ??= new HashSet<int>();
|
|
42
42
|
|
|
43
|
-
[ThreadStatic]
|
|
44
|
-
private static List<int> _indexBufferThreadStatic = new();
|
|
43
|
+
[ThreadStatic] private static List<int> _indexBufferThreadStatic = new();
|
|
45
44
|
|
|
46
|
-
[ThreadStatic]
|
|
47
|
-
private static HashSet<int> _indexSetBufferThreadStatic = new();
|
|
45
|
+
[ThreadStatic] private static HashSet<int> _indexSetBufferThreadStatic = new();
|
|
48
46
|
|
|
49
|
-
public static IAllOfMatcher<TEntity> AllOf(params int[] indices)
|
|
47
|
+
public static IAllOfMatcher<TEntity> AllOf(params int[] indices) => new Matcher<TEntity>
|
|
50
48
|
{
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return matcher;
|
|
54
|
-
}
|
|
49
|
+
_allOfIndices = DistinctIndices(indices)
|
|
50
|
+
};
|
|
55
51
|
|
|
56
52
|
public static IAllOfMatcher<TEntity> AllOf(params IMatcher<TEntity>[] matchers)
|
|
57
|
-
|
|
58
|
-
var allOfMatcher = (Matcher<TEntity>)AllOf(MergeIndices(matchers));
|
|
59
|
-
SetComponentNames(ref allOfMatcher, matchers);
|
|
60
|
-
return allOfMatcher;
|
|
61
|
-
}
|
|
53
|
+
=> AllOf(MergeIndices(matchers));
|
|
62
54
|
|
|
63
|
-
public static IAnyOfMatcher<TEntity> AnyOf(params int[] indices)
|
|
55
|
+
public static IAnyOfMatcher<TEntity> AnyOf(params int[] indices) => new Matcher<TEntity>
|
|
64
56
|
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return matcher;
|
|
68
|
-
}
|
|
57
|
+
_anyOfIndices = DistinctIndices(indices)
|
|
58
|
+
};
|
|
69
59
|
|
|
70
60
|
public static IAnyOfMatcher<TEntity> AnyOf(params IMatcher<TEntity>[] matchers)
|
|
71
|
-
|
|
72
|
-
var anyOfMatcher = (Matcher<TEntity>)AnyOf(MergeIndices(matchers));
|
|
73
|
-
SetComponentNames(ref anyOfMatcher, matchers);
|
|
74
|
-
return anyOfMatcher;
|
|
75
|
-
}
|
|
61
|
+
=> AnyOf(MergeIndices(matchers));
|
|
76
62
|
|
|
77
63
|
private static int[] MergeIndices(int[] allOfIndices, int[] anyOfIndices, int[] noneOfIndices)
|
|
78
64
|
{
|
|
@@ -115,28 +101,6 @@ namespace JCMG.EntitasRedux
|
|
|
115
101
|
return indices;
|
|
116
102
|
}
|
|
117
103
|
|
|
118
|
-
private static string[] GetComponentNames(IMatcher<TEntity>[] matchers)
|
|
119
|
-
{
|
|
120
|
-
for (var i = 0; i < matchers.Length; i++)
|
|
121
|
-
{
|
|
122
|
-
if (matchers[i] is Matcher<TEntity> matcher && matcher.ComponentNames != null)
|
|
123
|
-
{
|
|
124
|
-
return matcher.ComponentNames;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
private static void SetComponentNames(ref Matcher<TEntity> matcher, IMatcher<TEntity>[] matchers)
|
|
132
|
-
{
|
|
133
|
-
var componentNames = GetComponentNames(matchers);
|
|
134
|
-
if (componentNames != null)
|
|
135
|
-
{
|
|
136
|
-
matcher.ComponentNames = componentNames;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
104
|
private static int[] DistinctIndices(IList<int> indices)
|
|
141
105
|
{
|
|
142
106
|
foreach (var index in indices)
|
|
@@ -153,4 +117,4 @@ namespace JCMG.EntitasRedux
|
|
|
153
117
|
return uniqueIndices;
|
|
154
118
|
}
|
|
155
119
|
}
|
|
156
|
-
}
|
|
120
|
+
}
|
|
@@ -29,55 +29,36 @@ namespace JCMG.EntitasRedux
|
|
|
29
29
|
{
|
|
30
30
|
public partial class Matcher<TEntity>
|
|
31
31
|
{
|
|
32
|
-
private StringBuilder _toStringBuilder;
|
|
32
|
+
private static StringBuilder _toStringBuilder;
|
|
33
33
|
|
|
34
34
|
private string _toStringCache;
|
|
35
35
|
|
|
36
36
|
public override string ToString()
|
|
37
37
|
{
|
|
38
|
-
if (_toStringCache
|
|
39
|
-
|
|
40
|
-
if (_toStringBuilder == null)
|
|
41
|
-
{
|
|
42
|
-
_toStringBuilder = new StringBuilder();
|
|
43
|
-
}
|
|
38
|
+
if (_toStringCache != null)
|
|
39
|
+
return _toStringCache;
|
|
44
40
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
{
|
|
48
|
-
AppendIndices(
|
|
49
|
-
_toStringBuilder,
|
|
50
|
-
"AllOf",
|
|
51
|
-
_allOfIndices,
|
|
52
|
-
ComponentNames);
|
|
53
|
-
}
|
|
41
|
+
_toStringBuilder ??= new StringBuilder();
|
|
42
|
+
_toStringBuilder.Length = 0;
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
{
|
|
57
|
-
if (_allOfIndices != null)
|
|
58
|
-
{
|
|
59
|
-
_toStringBuilder.Append(".");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
AppendIndices(
|
|
63
|
-
_toStringBuilder,
|
|
64
|
-
"AnyOf",
|
|
65
|
-
_anyOfIndices,
|
|
66
|
-
ComponentNames);
|
|
67
|
-
}
|
|
44
|
+
var componentNames = IMatcher<TEntity>.ComponentNames;
|
|
68
45
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
AppendIndices(
|
|
72
|
-
_toStringBuilder,
|
|
73
|
-
".NoneOf",
|
|
74
|
-
_noneOfIndices,
|
|
75
|
-
ComponentNames);
|
|
76
|
-
}
|
|
46
|
+
if (_allOfIndices != null)
|
|
47
|
+
AppendIndices(_toStringBuilder, "AllOf", _allOfIndices, componentNames);
|
|
77
48
|
|
|
78
|
-
|
|
49
|
+
if (_anyOfIndices != null)
|
|
50
|
+
{
|
|
51
|
+
if (_allOfIndices != null)
|
|
52
|
+
_toStringBuilder.Append(".");
|
|
53
|
+
|
|
54
|
+
AppendIndices(_toStringBuilder, "AnyOf", _anyOfIndices, componentNames);
|
|
79
55
|
}
|
|
80
56
|
|
|
57
|
+
if (_noneOfIndices != null)
|
|
58
|
+
AppendIndices(_toStringBuilder, ".NoneOf", _noneOfIndices, componentNames);
|
|
59
|
+
|
|
60
|
+
_toStringCache = _toStringBuilder.ToString();
|
|
61
|
+
|
|
81
62
|
return _toStringCache;
|
|
82
63
|
}
|
|
83
64
|
|
|
@@ -108,4 +89,4 @@ namespace JCMG.EntitasRedux
|
|
|
108
89
|
sb.Append(")");
|
|
109
90
|
}
|
|
110
91
|
}
|
|
111
|
-
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
namespace JCMG.EntitasRedux
|
|
2
|
+
{
|
|
3
|
+
public class SingleMatcher<TEntity> : IMatcher<TEntity>
|
|
4
|
+
where TEntity : class, IEntity
|
|
5
|
+
{
|
|
6
|
+
private readonly int _index;
|
|
7
|
+
|
|
8
|
+
private string _toStringCache;
|
|
9
|
+
|
|
10
|
+
public SingleMatcher(int index)
|
|
11
|
+
{
|
|
12
|
+
_index = index;
|
|
13
|
+
Indices = new[] { index };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public int[] Indices { get; }
|
|
17
|
+
|
|
18
|
+
public bool Matches(TEntity entity) => entity.HasComponent(_index);
|
|
19
|
+
|
|
20
|
+
public override string ToString()
|
|
21
|
+
{
|
|
22
|
+
return string.IsNullOrEmpty(_toStringCache)
|
|
23
|
+
? _toStringCache = $"AllOf({IMatcher<TEntity>.ComponentNames[_index]})"
|
|
24
|
+
: _toStringCache;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
package/Core/Systems/Systems.cs
CHANGED
|
@@ -23,7 +23,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
23
23
|
THE SOFTWARE.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
+
using System;
|
|
26
27
|
using System.Collections.Generic;
|
|
28
|
+
using EntitasRedux.Core.Libs;
|
|
27
29
|
|
|
28
30
|
namespace JCMG.EntitasRedux
|
|
29
31
|
{
|
|
@@ -51,6 +53,11 @@ namespace JCMG.EntitasRedux
|
|
|
51
53
|
protected readonly List<ICleanupSystem> _cleanupSystems;
|
|
52
54
|
protected readonly List<ITearDownSystem> _tearDownSystems;
|
|
53
55
|
|
|
56
|
+
private Memory<IFixedUpdateSystem> _fixedUpdateSystemsMemory;
|
|
57
|
+
private Memory<IUpdateSystem> _updateSystemsMemory;
|
|
58
|
+
private Memory<ILateUpdateSystem> _lateUpdateSystemsMemory;
|
|
59
|
+
private Memory<ICleanupSystem> _cleanupSystemsMemory;
|
|
60
|
+
|
|
54
61
|
/// <summary>
|
|
55
62
|
/// Creates a new Systems instance.
|
|
56
63
|
/// </summary>
|
|
@@ -157,9 +164,9 @@ namespace JCMG.EntitasRedux
|
|
|
157
164
|
/// </summary>
|
|
158
165
|
public virtual void Update()
|
|
159
166
|
{
|
|
160
|
-
|
|
167
|
+
foreach (var system in _updateSystemsMemory.Span)
|
|
161
168
|
{
|
|
162
|
-
|
|
169
|
+
system.Update();
|
|
163
170
|
}
|
|
164
171
|
}
|
|
165
172
|
|
|
@@ -169,9 +176,9 @@ namespace JCMG.EntitasRedux
|
|
|
169
176
|
/// </summary>
|
|
170
177
|
public virtual void FixedUpdate()
|
|
171
178
|
{
|
|
172
|
-
|
|
179
|
+
foreach (var system in _fixedUpdateSystemsMemory.Span)
|
|
173
180
|
{
|
|
174
|
-
|
|
181
|
+
system.FixedUpdate();
|
|
175
182
|
}
|
|
176
183
|
}
|
|
177
184
|
|
|
@@ -181,9 +188,9 @@ namespace JCMG.EntitasRedux
|
|
|
181
188
|
/// </summary>
|
|
182
189
|
public virtual void LateUpdate()
|
|
183
190
|
{
|
|
184
|
-
|
|
191
|
+
foreach (var system in _lateUpdateSystemsMemory.Span)
|
|
185
192
|
{
|
|
186
|
-
|
|
193
|
+
system.LateUpdate();
|
|
187
194
|
}
|
|
188
195
|
}
|
|
189
196
|
|
|
@@ -193,6 +200,8 @@ namespace JCMG.EntitasRedux
|
|
|
193
200
|
/// </summary>
|
|
194
201
|
public virtual void Initialize()
|
|
195
202
|
{
|
|
203
|
+
PrepareUpdateSystems();
|
|
204
|
+
|
|
196
205
|
for (var i = 0; i < _initializeSystems.Count; i++)
|
|
197
206
|
{
|
|
198
207
|
_initializeSystems[i].Initialize();
|
|
@@ -205,9 +214,9 @@ namespace JCMG.EntitasRedux
|
|
|
205
214
|
/// </summary>
|
|
206
215
|
public virtual void Cleanup()
|
|
207
216
|
{
|
|
208
|
-
|
|
217
|
+
foreach (var system in _cleanupSystemsMemory.Span)
|
|
209
218
|
{
|
|
210
|
-
|
|
219
|
+
system.Cleanup();
|
|
211
220
|
}
|
|
212
221
|
}
|
|
213
222
|
|
|
@@ -222,5 +231,13 @@ namespace JCMG.EntitasRedux
|
|
|
222
231
|
_tearDownSystems[i].TearDown();
|
|
223
232
|
}
|
|
224
233
|
}
|
|
234
|
+
|
|
235
|
+
private void PrepareUpdateSystems()
|
|
236
|
+
{
|
|
237
|
+
_fixedUpdateSystemsMemory = _fixedUpdateSystems.AsMemoryReflection();
|
|
238
|
+
_updateSystemsMemory = _updateSystems.AsMemoryReflection();
|
|
239
|
+
_lateUpdateSystemsMemory = _lateUpdateSystems.AsMemoryReflection();
|
|
240
|
+
_cleanupSystemsMemory = _cleanupSystems.AsMemoryReflection();
|
|
241
|
+
}
|
|
225
242
|
}
|
|
226
243
|
}
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "com.elestrago.unity.entitas-redux",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.1",
|
|
4
4
|
"displayName": "JCMG Entitas Redux",
|
|
5
5
|
"description": "Entitas Redux is an fast, accessible, and feature-rich ECS framework for Unity. It leverages code generation and an extensible plugin framework to make life easier for developers.",
|
|
6
6
|
"category": "Unity",
|