using System; using static gaemstone.Flecs.Core; namespace gaemstone.ECS; /// /// When present on an attribute attached to a type that's part of a module /// being registered automatically through , /// an entity is automatically created and /// called on it, meaning it can be looked up using . /// public interface ICreateEntityAttribute { } [AttributeUsage(AttributeTargets.Struct)] public class EntityAttribute : Attribute, ICreateEntityAttribute { } /// /// Use a custom name or path for this entity instead of the type's name. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)] public class PathAttribute : Attribute, ICreateEntityAttribute { public string Value { get; } public PathAttribute(string value) => Value = value; } /// /// Register the entity under a globally unique symbol. /// Uses the type's name by default. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)] public class SymbolAttribute : Attribute, ICreateEntityAttribute { public string? Value { get; } public SymbolAttribute() { } public SymbolAttribute(string value) => Value = value; } /// /// 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, ICreateEntityAttribute { public bool AutoAdd { get; init; } = true; } /// /// 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, /// including types registered in other assemblies. /// public class ProxyAttribute : ProxyAttribute { public ProxyAttribute() : base(typeof(T)) { } } /// /// Marked entity automatically has the specified entity added to it when /// automatically registered. Equivalent to . /// public class AddAttribute : AddEntityAttribute { public AddAttribute() : base(typeof(TEntity)) { } } /// /// Marked entity automatically has the specified relationship pair added to it when /// automatically registered, Equivalent to . /// public class AddAttribute : AddRelationAttribute { public AddAttribute() : base(typeof(TRelation), typeof(TTarget)) { } } /// /// Marked entity represents a relationship type. /// It may be used as the "relation" in a pair. /// /// /// The relationship may have component data associated with /// it when added to an entity under these circumstances: /// /// If marked as a , does not carry data. /// If marked as a , carries the relation's data. /// If marked with neither, will carry the target's data, if it's a component. /// /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)] public class RelationAttribute : Attribute, ICreateEntityAttribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)] public class ComponentAttribute : Attribute, ICreateEntityAttribute { } /// [AttributeUsage(AttributeTargets.Struct)] public class TagAttribute : AddAttribute, ICreateEntityAttribute { } /// public class IsAAttribute : AddAttribute { } /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)] public class ChildOfAttribute : AddAttribute { } /// public class DependsOnAttribute : AddAttribute { } /// public class ExclusiveAttribute : AddAttribute { } /// public class WithAttribute : AddAttribute { } // Base attributes for other attributes. [AttributeUsage(AttributeTargets.Struct)] public class ProxyAttribute : Attribute { public Type Type { get; } internal ProxyAttribute(Type type) => Type = type; } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = true)] public class AddEntityAttribute : Attribute { public Type Entity { get; } internal AddEntityAttribute(Type entity) => Entity = entity; } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = true)] public class AddRelationAttribute : Attribute { public Type Relation { get; } public Type Target { get; } internal AddRelationAttribute(Type relation, Type target) { Relation = relation; Target = target; } }