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 ;
2024-09-09 09:56:33 +08:00
using System.Runtime.InteropServices ;
2024-03-03 03:51:49 +08:00
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-09-09 09:56:33 +08:00
[StructLayout(LayoutKind.Sequential)]
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 ;
2024-09-09 09:56:33 +08:00
[SerializeField]
private byte _offset ; // Fucking Unity drove me crazy with the error "Cannot get managed reference index with out bounds offset". This workaround helps avoid that error.
2024-03-03 03:51:49 +08:00
#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
2024-09-09 09:56:33 +08:00
public sealed override object GetRaw ( ) { return component ; }
public sealed override void SetRaw ( object raw ) { component = ( T ) raw ; }
2024-03-03 03:51:49 +08:00
#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-09-09 09:56:33 +08:00
where T : struct , IEcsTagComponent
2024-03-03 03:51:49 +08:00
{
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