@@ -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