Skip to content

Commit cbd81a2

Browse files
[Entities] Fixed a bug with removing and adding a component;
[Entities] Add EntityTests and ComponentTests;
1 parent 54d92a6 commit cbd81a2

File tree

11 files changed

+1212
-1004
lines changed

11 files changed

+1212
-1004
lines changed

Engine/Core/Entities/Entity+Components.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,14 @@ public readonly IComponent[] GetComponentsInChildren(Type t, bool includeSelf =
103103

104104
var result = new List<IComponent>();
105105

106-
if(includeSelf && World.Current.TryGetComponent(this, out var c, t))
106+
if(includeSelf && TryGetComponent(t, out var c))
107107
{
108108
result.Add(c);
109109
}
110110

111111
void Recursive(Entity e)
112112
{
113-
if(e.TryGetComponent(out c, t))
113+
if(e.TryGetComponent(t, out c))
114114
{
115115
result.Add(c);
116116
}
@@ -266,7 +266,7 @@ public readonly IComponent GetComponentInParent(Type t)
266266
return default;
267267
}
268268

269-
if(transform.parent.entity.TryGetComponent(out var value, t))
269+
if(transform.parent.entity.TryGetComponent(t, out var value))
270270
{
271271
return value;
272272
}
@@ -304,10 +304,10 @@ public readonly T GetComponentInParent<T>() where T : IComponent
304304
/// <summary>
305305
/// Attempts to get a component from an entity
306306
/// </summary>
307-
/// <param name="component">The component instance</param>
308307
/// <param name="t">The component type</param>
308+
/// <param name="component">The component instance</param>
309309
/// <returns>Whether the component was found</returns>
310-
public readonly bool TryGetComponent(out IComponent component, Type t)
310+
public readonly bool TryGetComponent(Type t, out IComponent component)
311311
{
312312
if (World.Current == null)
313313
{
@@ -316,7 +316,7 @@ public readonly bool TryGetComponent(out IComponent component, Type t)
316316
return false;
317317
}
318318

319-
return World.Current.TryGetComponent(this, out component, t);
319+
return World.Current.TryGetComponent(this, t, out component);
320320
}
321321

322322
/// <summary>

Engine/Core/World/World+Components.cs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public IComponent AddComponent(Entity entity,
8383
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
8484
Type t)
8585
{
86-
if(t.GetCustomAttribute(typeof(AbstractComponentAttribute)) != null ||
86+
if(t.GetCustomAttribute<AbstractComponentAttribute>() != null ||
8787
TryGetEntity(entity, out var entityInfo) == false)
8888
{
8989
return default;
@@ -95,6 +95,8 @@ public IComponent AddComponent(Entity entity,
9595

9696
var hash = t.FullName.GetHashCode();
9797

98+
removedComponents.Remove((entity, hash));
99+
98100
if (entityInfo.components.TryGetValue(hash, out var component))
99101
{
100102
//Already has one, return it
@@ -354,10 +356,10 @@ public T GetComponent<T>(Entity entity) where T : IComponent
354356
/// Attempts to get a component from an entity
355357
/// </summary>
356358
/// <param name="entity">The entity to get from</param>
357-
/// <param name="component">The component instance</param>
358359
/// <param name="t">The component type</param>
360+
/// <param name="component">The component instance</param>
359361
/// <returns>Whether the component was found</returns>
360-
public bool TryGetComponent(Entity entity, out IComponent component, Type t)
362+
public bool TryGetComponent(Entity entity, Type t, out IComponent component)
361363
{
362364
if (typeof(IComponent).IsAssignableFrom(t) == false ||
363365
TryGetEntity(entity, out var entityInfo) == false)
@@ -399,7 +401,7 @@ public bool TryGetComponent(Entity entity, out IComponent component, Type t)
399401
/// <returns>Whether the component was found</returns>
400402
public bool TryGetComponent<T>(Entity entity, out T component) where T: IComponent
401403
{
402-
if(TryGetComponent(entity, out IComponent c, typeof(T)))
404+
if(TryGetComponent(entity, typeof(T), out IComponent c))
403405
{
404406
component = (T)c;
405407

@@ -415,6 +417,7 @@ public bool TryGetComponent<T>(Entity entity, out T component) where T: ICompone
415417
/// Updates an entity's component.
416418
/// This is required if the component type is a struct.
417419
/// </summary>
420+
/// <remarks>If the component doesn't exist, a new instance will be created and replaced with the new one</remarks>
418421
/// <param name="entity">The entity to update</param>
419422
/// <param name="component">The component instance to replace</param>
420423
public void SetComponent(Entity entity, IComponent component)
@@ -425,6 +428,11 @@ public void SetComponent(Entity entity, IComponent component)
425428
return;
426429
}
427430

431+
if(GetComponent(entity, component.GetType()) == null)
432+
{
433+
AddComponent(entity, component.GetType());
434+
}
435+
428436
lock (lockObject)
429437
{
430438
if (componentCompatibilityCache.TryGetValue(component.GetType().FullName.GetHashCode(), out var compatibility) == false)
@@ -436,6 +444,38 @@ public void SetComponent(Entity entity, IComponent component)
436444
{
437445
if(entityInfo.components.ContainsKey(typeName))
438446
{
447+
removedComponents.Remove((entity, typeName.GetHashCode()));
448+
449+
var t = component.GetType();
450+
451+
if (t.GetCustomAttribute<AutoAssignEntityAttribute>() != null)
452+
{
453+
try
454+
{
455+
var field = t.GetField("entity");
456+
457+
field?.SetValue(component, entity);
458+
459+
var property = t.GetProperty("entity");
460+
461+
if (property != null)
462+
{
463+
if (property.CanWrite)
464+
{
465+
property.SetValue(component, entity);
466+
}
467+
else
468+
{
469+
Log.Debug($"[{t.FullName}]: Can't auto assign entity: Property isn't writable");
470+
}
471+
}
472+
}
473+
catch (Exception e)
474+
{
475+
Log.Debug($"[{t.FullName}]: Failed to auto assign entity: {e}");
476+
}
477+
}
478+
439479
entityInfo.components[typeName] = component;
440480

441481
needsEmitWorldChange = true;

0 commit comments

Comments
 (0)