diff --git a/src/gaemstone/ECS/Attributes.cs b/src/gaemstone/ECS/Attributes.cs index f2fa1f1..c043ece 100644 --- a/src/gaemstone/ECS/Attributes.cs +++ b/src/gaemstone/ECS/Attributes.cs @@ -19,6 +19,18 @@ public interface ICreateEntityAttribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)] public class PrivateAttribute : Attribute { } +/// +/// A singleton is a single instance of a tag or component that can be retrieved +/// without explicitly specifying an entity in a query, where it is equivalent +/// to with itself as the generic type parameter. +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)] +public class SingletonAttribute : Attribute +{ + /// Whether to add the entity to itself on registration. + public bool AutoAdd { get; init; } = false; +} + /// /// Register the proxied type instead of the one marked with this attribute. /// This can be used to make types not registered in a module available, diff --git a/src/gaemstone/ECS/Entity.cs b/src/gaemstone/ECS/Entity.cs index 63b2abc..1eb9de8 100644 --- a/src/gaemstone/ECS/Entity.cs +++ b/src/gaemstone/ECS/Entity.cs @@ -21,18 +21,6 @@ public class EntityAttribute : Attribute, ICreateEntityAttribute } } -/// -/// A singleton is a single instance of a tag or component that can be retrieved -/// without explicitly specifying an entity in a query, where it is equivalent -/// to with itself as the generic type parameter. -/// -[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)] -public class SingletonAttribute : EntityAttribute -{ - public SingletonAttribute() { } - public SingletonAttribute(params string[] path) : base(path) { } -} - public readonly struct Entity : IEquatable { diff --git a/src/gaemstone/ECS/Universe+Modules.cs b/src/gaemstone/ECS/Universe+Modules.cs index b6cd235..e59b86e 100644 --- a/src/gaemstone/ECS/Universe+Modules.cs +++ b/src/gaemstone/ECS/Universe+Modules.cs @@ -198,7 +198,7 @@ internal class ModuleInfo foreach (var attr in type.GetMultiple()) entity.Add(Lookup(attr.Relation), Lookup(attr.Target)); - if (type.Has()) entity.Add(entity); + if (type.Get()?.AutoAdd == true) entity.Add(entity); if (type.Has()) entity.CreateComponent(proxyType); else entity.CreateLookup(proxyType); } diff --git a/src/gaemstone/Utility/IL/IterActionGenerator.cs b/src/gaemstone/Utility/IL/IterActionGenerator.cs index 599a758..7de3703 100644 --- a/src/gaemstone/Utility/IL/IterActionGenerator.cs +++ b/src/gaemstone/Utility/IL/IterActionGenerator.cs @@ -271,8 +271,8 @@ public unsafe class IterActionGenerator // Reference types have a backing type of nint - they're pointers. FieldType = underlyingType.IsValueType ? underlyingType : typeof(nint); - Source = Info.Get()?.Type - ?? (UnderlyingType.Has() ? UnderlyingType : null); + if (UnderlyingType.Has()) Source = UnderlyingType; + if (Info.Get()?.Type is Type type) Source = type; } public static ParamInfo Build(ParameterInfo info)