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; }
}