DragonECS-Unity/src/EntityTemplate/Templates/ComponentTemplateBase.cs

160 lines
5.3 KiB
C#
Raw Normal View History

2024-03-07 03:18:00 +08:00
using System;
2024-03-03 03:51:49 +08:00
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using static DCFApixels.DragonECS.IComponentTemplate;
namespace DCFApixels.DragonECS
{
public interface IComponentTemplate : ITemplateNode
{
#region Properties
Type Type { get; }
#endregion
#region Methods
object GetRaw();
void SetRaw(object raw);
void OnGizmos(Transform transform, GizmosMode mode);
void OnValidate(UnityEngine.Object obj);
#endregion
public enum GizmosMode
{
Always,
Selected
}
}
2024-03-06 23:29:54 +08:00
public interface IComponentTemplateWithMetaOverride : IComponentTemplate, ITypeMeta { }
2024-03-03 03:51:49 +08:00
[Serializable]
2024-03-06 23:29:54 +08:00
public abstract class ComponentTemplateBase : IComponentTemplateWithMetaOverride
2024-03-03 03:51:49 +08:00
{
#region Properties
public abstract Type Type { get; }
public virtual string Name { get { return string.Empty; } }
2024-03-06 23:29:54 +08:00
public virtual MetaColor Color { get { return new MetaColor(MetaColor.Black); } }
public virtual MetaGroup Group { get { return MetaGroup.Empty; } }
2024-05-01 15:02:54 +08:00
public virtual MetaDescription Description { get { return MetaDescription.Empty; } }
2024-06-10 18:05:06 +08:00
public virtual IReadOnlyList<string> Tags { get { return Array.Empty<string>(); } }
2024-03-03 03:51:49 +08:00
#endregion
#region Methods
public abstract object GetRaw();
public abstract void SetRaw(object raw);
public virtual void OnGizmos(Transform transform, GizmosMode mode) { }
public virtual void OnValidate(UnityEngine.Object obj) { }
2024-04-22 17:20:10 +08:00
public abstract void Apply(short worldID, int entityID);
2024-03-03 03:51:49 +08:00
#endregion
}
[Serializable]
2024-03-06 23:29:54 +08:00
public abstract class ComponentTemplateBase<T> : ComponentTemplateBase
2024-03-03 03:51:49 +08:00
{
2024-03-06 23:29:54 +08:00
protected static TypeMeta Meta = EcsDebugUtility.GetTypeMeta<T>();
2024-03-03 03:51:49 +08:00
[SerializeField]
protected T component;
#region Properties
2024-05-16 20:31:06 +08:00
public sealed override Type Type { get { return typeof(T); } }
2024-03-06 23:29:54 +08:00
public override string Name { get { return Meta.Name; } }
2024-05-15 00:36:56 +08:00
public override MetaColor Color { get { return Meta.Color; } }
2024-03-06 23:29:54 +08:00
public override MetaGroup Group { get { return Meta.Group; } }
2024-05-01 15:02:54 +08:00
public override MetaDescription Description { get { return Meta.Description; } }
2024-06-10 18:05:06 +08:00
public override IReadOnlyList<string> Tags { get { return Meta.Tags; } }
2024-03-03 03:51:49 +08:00
#endregion
#region Methods
public override object GetRaw()
{
return component;
}
public override void SetRaw(object raw)
{
component = (T)raw;
}
#endregion
}
2024-03-06 23:29:54 +08:00
public abstract class ComponentTemplate<T> : ComponentTemplateBase<T>
2024-03-03 03:51:49 +08:00
where T : struct, IEcsComponent
{
2024-04-22 17:20:10 +08:00
public override void Apply(short worldID, int entityID)
2024-03-03 03:51:49 +08:00
{
2024-03-07 03:24:02 +08:00
EcsWorld.GetPoolInstance<EcsPool<T>>(worldID).TryAddOrGet(entityID) = component;
2024-03-03 03:51:49 +08:00
}
}
2024-03-06 23:29:54 +08:00
public abstract class TagComponentTemplate<T> : ComponentTemplateBase<T>
2024-03-03 03:51:49 +08:00
where T : struct, IEcsTagComponent
{
2024-04-22 17:20:10 +08:00
public override void Apply(short worldID, int entityID)
2024-03-03 03:51:49 +08:00
{
2024-03-07 03:24:02 +08:00
EcsWorld.GetPoolInstance<EcsTagPool<T>>(worldID).Set(entityID, true);
2024-03-03 03:51:49 +08:00
}
}
}
namespace DCFApixels.DragonECS.Unity.Internal
{
internal static class ComponentTemplateExtensions
{
private static MethodInfo memberwiseCloneMethdo = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);
internal static IComponentTemplate Clone(this IComponentTemplate obj)
{
return (IComponentTemplate)memberwiseCloneMethdo.Invoke(obj, null);
}
}
}
#if UNITY_EDITOR
namespace DCFApixels.DragonECS.Unity.Editors
{
internal static class ComponentTemplateTypeCache
{
private static Type[] _types;
private static IComponentTemplate[] _dummies;
2024-03-06 23:29:54 +08:00
internal static ReadOnlySpan<Type> Types
{
get { return _types; }
}
internal static ReadOnlySpan<IComponentTemplate> Dummies
{
get { return _dummies; }
}
2024-03-03 03:51:49 +08:00
static ComponentTemplateTypeCache()
{
List<Type> types = new List<Type>();
Type interfaceType = typeof(IComponentTemplate);
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
2024-05-15 00:36:56 +08:00
var targetTypes = assembly.GetTypes().Where(type => !type.IsGenericType && !(type.IsAbstract || type.IsInterface) /*&& type.GetCustomAttribute<SerializableAttribute>() != null*/);
2024-03-03 03:51:49 +08:00
types.AddRange(targetTypes.Where(type => interfaceType.IsAssignableFrom(type)));
foreach (var t in targetTypes)
{
if (t.IsSubclassOf(typeof(ComponentTemplateBase<>)))
{
types.Add(t);
}
}
}
_types = types.ToArray();
foreach (var type in _types)
{
2024-03-06 21:37:21 +08:00
EcsDebugUtility.GetTypeMeta(type);
2024-03-03 03:51:49 +08:00
}
_dummies = new IComponentTemplate[_types.Length];
for (int i = 0; i < _types.Length; i++)
{
_dummies[i] = (IComponentTemplate)Activator.CreateInstance(_types[i]);
}
}
}
}
#endif