Skip to content

Commit a618e7d

Browse files
authored
UPM package version 3.4.6
1 parent 332a3aa commit a618e7d

File tree

13 files changed

+95
-72
lines changed

13 files changed

+95
-72
lines changed

CHANGELOG.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Svelto.ECS Changelog
22
All notable changes to this project will be documented in this file. Changes are listed in random order of importance.
33

4-
## [3.4.5] - 04-2023
5-
* improved code after internal data refactoring and fixed some bugs
6-
* Added static DynamicEntityDescriptor method to create a new DynamicEntityDescriptor without passing an array of components
7-
* factory method to build entities without entity descriptor is now internal
4+
## [3.4.6] - 05-2023
5+
6+
* SveltoOnDOTS bug fixes/improvements
7+
* Comments and code cleanup
88

99
## [3.4.4] - 04-2023
1010

Core/ComponentTypeID.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ public static ComponentID id
2020
get => _id.Data;
2121
}
2222

23+
/// <summary>
24+
/// c# Static constructors are guaranteed to be thread safe
25+
/// The runtime guarantees that a static constructor is only called once. So even if a type is called by multiple threads at the same time,
26+
/// the static constructor is always executed one time. To get a better understanding how this works, it helps to know what purpose it serves.
27+
/// </summary>
2328
static ComponentTypeID()
2429
{
2530
Init();

Core/ComponentTypeMap.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
using System;
2+
using System.Collections.Concurrent;
23
using System.Runtime.CompilerServices;
34
using Svelto.DataStructures;
45

56
namespace Svelto.ECS
67
{
7-
public static class ComponentTypeMap
8+
static class ComponentTypeMap
89
{
9-
static readonly FasterDictionary<RefWrapper<Type>, ComponentID> _componentTypeMap = new FasterDictionary<RefWrapper<Type>, ComponentID>();
10-
static readonly FasterDictionary<ComponentID, Type> _reverseComponentTypeMap = new FasterDictionary<ComponentID, Type>();
10+
static readonly ConcurrentDictionary<Type, ComponentID> _componentTypeMap = new ConcurrentDictionary<Type, ComponentID>();
11+
static readonly ConcurrentDictionary<ComponentID, Type> _reverseComponentTypeMap = new ConcurrentDictionary<ComponentID, Type>();
1112

1213
public static void Add(Type type, ComponentID idData)
1314
{
14-
_componentTypeMap.Add(type, idData);
15-
_reverseComponentTypeMap.Add(idData, type);
15+
_componentTypeMap.TryAdd(type, idData);
16+
_reverseComponentTypeMap.TryAdd(idData, type);
1617
}
1718

1819
[MethodImpl(MethodImplOptions.AggressiveInlining)]

Core/EnginesRoot.Engines.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ public partial class EnginesRoot
1616
{
1717
static EnginesRoot()
1818
{
19-
EntityDescriptorsWarmup.Init();
20-
GroupHashMap.Init();
19+
EntityDescriptorsWarmup.WarmUp();
20+
GroupHashMap.WarmUp();
2121
//SharedDictonary.Init();
2222
SerializationDescriptorMap.Init();
2323

Core/EntityDescriptor/DynamicEntityDescriptor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static DynamicEntityDescriptor<TType> CreateDynamicEntityDescriptor()
4545

4646
public DynamicEntityDescriptor(IComponentBuilder[] extraEntityBuilders)
4747
{
48-
this = CreateDynamicEntityDescriptor();
48+
this = DynamicEntityDescriptor<TType>.CreateDynamicEntityDescriptor();
4949

5050
var extraEntitiesLength = extraEntityBuilders.Length;
5151

@@ -54,7 +54,7 @@ public DynamicEntityDescriptor(IComponentBuilder[] extraEntityBuilders)
5454

5555
public DynamicEntityDescriptor(FasterList<IComponentBuilder> extraEntityBuilders)
5656
{
57-
this = CreateDynamicEntityDescriptor();
57+
this = DynamicEntityDescriptor<TType>.CreateDynamicEntityDescriptor();
5858

5959
var extraEntities = extraEntityBuilders.ToArrayFast(out _);
6060
var extraEntitiesLength = extraEntityBuilders.count;

Core/EntityReference/EnginesRoot.LocatorMap.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,10 @@ public SharedSveltoDictionaryNative<uint, EntityReference> GetEntityReferenceMap
173173
public bool TryGetEGID(EntityReference reference, out EGID egid)
174174
{
175175
egid = default;
176-
#if DEBUG && !PROFILE_SVELTO
176+
177177
if (reference == EntityReference.Invalid)
178178
return false;
179-
#endif
179+
180180
// Make sure we are querying for the current version of the locator.
181181
// Otherwise the locator is pointing to a removed entity.
182182
ref var entityReferenceMapElement = ref _entityReferenceMap[reference.index];

Core/Groups/EntityDescriptorsWarmup.cs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55

66
namespace Svelto.ECS
77
{
8-
public static class EntityDescriptorsWarmup
8+
static class EntityDescriptorsWarmup
99
{
1010
/// <summary>
1111
/// c# Static constructors are guaranteed to be thread safe
1212
/// Warmup all EntityDescriptors and ComponentTypeID classes to avoid huge overheads when they are first used
1313
/// </summary>
14-
internal static void Init()
14+
internal static void WarmUp()
1515
{
1616
List<Assembly> assemblies = AssemblyUtility.GetCompatibleAssemblies();
1717
foreach (Assembly assembly in assemblies)
@@ -30,10 +30,7 @@ internal static void Init()
3030

3131
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(warmup.TypeHandle);
3232
}
33-
catch (Exception e)
34-
{
35-
continue;
36-
}
33+
catch { }
3734
}
3835
}
3936

@@ -51,10 +48,7 @@ internal static void Init()
5148
//this warms up the component builder. There could be different implementation of components builders for the same component type in theory
5249
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(componentType.TypeHandle);
5350
}
54-
catch (Exception e)
55-
{
56-
continue;
57-
}
51+
catch { }
5852
}
5953
}
6054
}

Core/Groups/GroupCompound.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ public abstract class GroupCompound<G1, G2, G3, G4>: ITouchedByReflection
2727
{
2828
static GroupCompound()
2929
{
30-
//avoid race conditions if compounds are using on multiple thread
30+
//avoid race conditions if compounds are using on multiple thread. This shouldn't be necessary though since c# static constructors are guaranteed to be thread safe!
31+
/// c# Static constructors are guaranteed to be thread safe
32+
/// The runtime guarantees that a static constructor is only called once. So even if a type is called by multiple threads at the same time,
33+
/// the static constructor is always executed one time. To get a better understanding how this works, it helps to know what purpose it serves.
3134
if (Interlocked.CompareExchange(ref isInitializing, 1, 0) == 0 &&
3235
GroupCompoundInitializer.skipStaticCompoundConstructorsWith4Tags.Value == false)
3336
{

Core/Groups/GroupHashMap.cs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ public static class GroupHashMap
1010
{
1111
/// <summary>
1212
/// c# Static constructors are guaranteed to be thread safe
13+
/// The runtime guarantees that a static constructor is only called once. So even if a type is called by multiple threads at the same time,
14+
/// the static constructor is always executed one time. To get a better understanding how this works, it helps to know what purpose it serves.
15+
///
16+
/// Warmup the group hash map. This will call all the static constructors of the group types
1317
/// </summary>
14-
internal static void Init()
18+
internal static void WarmUp()
1519
{
1620
List<Assembly> assemblies = AssemblyUtility.GetCompatibleAssemblies();
1721
foreach (Assembly assembly in assemblies)
@@ -26,8 +30,8 @@ internal static void Init()
2630
{
2731
CheckForGroupCompounds(type);
2832

29-
if (type != null && type.IsClass && type.IsSealed &&
30-
type.IsAbstract) //IsClass and IsSealed and IsAbstract means only static classes
33+
//Search inside static types
34+
if (type != null && type.IsClass && type.IsSealed && type.IsAbstract) //IsClass and IsSealed and IsAbstract means only static classes
3135
{
3236
var subClasses = type.GetNestedTypes();
3337

@@ -40,8 +44,8 @@ internal static void Init()
4044

4145
foreach (var field in fields)
4246
{
43-
if (field.IsStatic
44-
&& (typeOfExclusiveGroup.IsAssignableFrom(field.FieldType)
47+
if (field.IsStatic
48+
&& (typeOfExclusiveGroup.IsAssignableFrom(field.FieldType)
4549
|| typeOfExclusiveGroupStruct.IsAssignableFrom(field.FieldType)
4650
|| typeOfExclusiveBuildGroup.IsAssignableFrom(field.FieldType)))
4751
{
@@ -52,7 +56,8 @@ internal static void Init()
5256
var group = (ExclusiveGroup)field.GetValue(null);
5357
groupIDAndBitMask = ((ExclusiveGroupStruct)@group).ToIDAndBitmask();
5458
}
55-
else if (typeOfExclusiveGroupStruct.IsAssignableFrom(field.FieldType))
59+
else
60+
if (typeOfExclusiveGroupStruct.IsAssignableFrom(field.FieldType))
5661
{
5762
var group = (ExclusiveGroupStruct)field.GetValue(null);
5863
groupIDAndBitMask = @group.ToIDAndBitmask();
@@ -94,7 +99,7 @@ static void CheckForGroupCompounds(Type type)
9499
{
95100
if (typeof(ITouchedByReflection).IsAssignableFrom(type))
96101
{
97-
//this wil call the static constructor, but only once. Static constructors won't be called
102+
//this calls the static constructor, but only once. Static constructors won't be called
98103
//more than once with this
99104
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.BaseType.TypeHandle);
100105
}
@@ -107,7 +112,7 @@ static void CheckForGroupCompounds(Type type)
107112
/// <param name="exclusiveGroupStruct"></param>
108113
/// <param name="name"></param>
109114
/// <exception cref="ECSException"></exception>
110-
public static void RegisterGroup(ExclusiveGroupStruct exclusiveGroupStruct, string name)
115+
internal static void RegisterGroup(ExclusiveGroupStruct exclusiveGroupStruct, string name)
111116
{
112117
//Group already registered by another field referencing the same group, can happen because
113118
//the group poked is a group compound which static constructor is already been called at this point
@@ -125,7 +130,7 @@ public static void RegisterGroup(ExclusiveGroupStruct exclusiveGroupStruct, stri
125130
_hashByGroups.Add(exclusiveGroupStruct, nameHash);
126131
}
127132

128-
internal static uint GetHashFromGroup(ExclusiveGroupStruct groupStruct)
133+
public static uint GetHashFromGroup(ExclusiveGroupStruct groupStruct)
129134
{
130135
#if DEBUG && !PROFILE_SVELTO
131136
if (_hashByGroups.ContainsKey(groupStruct) == false)
@@ -135,7 +140,7 @@ internal static uint GetHashFromGroup(ExclusiveGroupStruct groupStruct)
135140
return _hashByGroups[groupStruct];
136141
}
137142

138-
internal static ExclusiveGroupStruct GetGroupFromHash(uint groupHash)
143+
public static ExclusiveGroupStruct GetGroupFromHash(uint groupHash)
139144
{
140145
#if DEBUG && !PROFILE_SVELTO
141146
if (_groupsByHash.ContainsKey(groupHash) == false)

0 commit comments

Comments
 (0)