2024-03-09 03:35:01 +08:00
using System.Collections.Generic ;
using System.Linq ;
2023-05-07 00:50:44 +08:00
using System.Runtime.CompilerServices ;
2024-10-12 23:18:58 +08:00
using DCFApixels.DragonECS.Unity ;
2023-05-07 00:50:44 +08:00
using UnityEngine ;
2024-10-12 23:18:58 +08:00
using DCFApixels.DragonECS.Unity.Internal ;
2024-10-11 23:29:48 +08:00
#if UNITY_EDITOR
2024-05-16 19:03:03 +08:00
using UnityEditor ;
2024-10-11 23:29:48 +08:00
#endif
2023-05-07 00:50:44 +08:00
namespace DCFApixels.DragonECS
{
2024-10-19 00:05:07 +08:00
using static EcsConsts ;
2024-03-10 10:20:44 +08:00
public static class EcsConnect
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-10 10:24:58 +08:00
public static void Connect ( this Component cmp , entlong entity , bool applyTemplates )
{
Connect ( entity , cmp , applyTemplates ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Connect ( this entlong entity , Component cmp , bool applyTemplates )
{
if ( cmp . TryGetComponent ( out EcsEntityConnect connect ) = = false )
{
connect = cmp . gameObject . AddComponent < EcsEntityConnect > ( ) ;
}
connect . ConnectWith ( entity , applyTemplates ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Connect ( this GameObject go , entlong entity , bool applyTemplates )
2024-03-10 10:20:44 +08:00
{
Connect ( entity , go , applyTemplates ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-10 10:24:58 +08:00
public static void Connect ( this entlong entity , GameObject go , bool applyTemplates )
2024-03-10 10:20:44 +08:00
{
if ( go . TryGetComponent ( out EcsEntityConnect connect ) = = false )
{
connect = go . AddComponent < EcsEntityConnect > ( ) ;
}
connect . ConnectWith ( entity , applyTemplates ) ;
}
2024-03-10 10:24:58 +08:00
2024-03-10 10:20:44 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-10 10:24:58 +08:00
public static void Connect ( this EcsEntityConnect connect , entlong entity , bool applyTemplates )
2024-03-10 10:20:44 +08:00
{
Connect ( entity , connect , applyTemplates ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-10 10:24:58 +08:00
public static void Connect ( this entlong entity , EcsEntityConnect connect , bool applyTemplates )
2024-03-10 10:20:44 +08:00
{
connect . ConnectWith ( entity , applyTemplates ) ;
}
}
2024-03-10 10:24:58 +08:00
2024-05-25 22:28:38 +08:00
[SelectionBase]
2024-03-09 09:56:45 +08:00
[DisallowMultipleComponent]
2024-10-19 00:05:07 +08:00
[AddComponentMenu(FRAMEWORK_NAME + "/" + nameof(EcsEntityConnect), 30)]
2024-10-12 14:37:21 +08:00
[MetaColor(MetaColor.DragonCyan)]
2024-06-13 18:04:47 +08:00
[MetaGroup(EcsUnityConsts.PACK_GROUP, EcsUnityConsts.ENTITY_BUILDING_GROUP)]
2024-10-19 00:05:07 +08:00
[MetaDescription(AUTHOR, nameof(MonoBehaviour) + ". Responsible for connecting the entity and GameObject using the EcsEntityConnect.ConnectWith method.")]
2024-10-12 21:03:19 +08:00
[MetaID("FF7EB3809201DEC2F1977C00D3B3443B")]
2023-05-07 00:50:44 +08:00
public class EcsEntityConnect : MonoBehaviour
{
private entlong _entity ;
private EcsWorld _world ;
2024-05-25 22:28:38 +08:00
private static SparseArray < EcsEntityConnect > _connectedEntities = new SparseArray < EcsEntityConnect > ( ) ;
2024-03-28 18:43:42 +08:00
[SerializeField]
2024-10-12 20:11:37 +08:00
private bool _deleteEntityWithDestroy = false ;
2023-05-07 00:50:44 +08:00
[SerializeField]
2024-04-26 06:05:29 +08:00
private ScriptableEntityTemplateBase [ ] _scriptableTemplates ;
2023-05-07 00:50:44 +08:00
[SerializeField]
2024-04-26 06:05:29 +08:00
private MonoEntityTemplateBase [ ] _monoTemplates ;
2023-05-07 00:50:44 +08:00
2024-03-28 18:43:42 +08:00
private bool _isConnectInvoked = false ;
2024-03-10 22:27:17 +08:00
2023-05-07 00:50:44 +08:00
#region Properties
public entlong Entity
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-09 03:35:01 +08:00
get { return _entity ; }
2023-05-07 00:50:44 +08:00
}
public EcsWorld World
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-10 09:50:20 +08:00
get { return _world ; }
2023-05-07 00:50:44 +08:00
}
2024-03-10 10:20:44 +08:00
public bool IsConnected
2023-05-07 00:50:44 +08:00
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-10 09:50:20 +08:00
get { return _entity . IsAlive ; }
2023-05-07 00:50:44 +08:00
}
2024-04-26 06:05:29 +08:00
public IEnumerable < ScriptableEntityTemplateBase > ScriptableTemplates
2024-03-09 03:35:01 +08:00
{
get { return _scriptableTemplates ; }
}
2024-04-26 06:05:29 +08:00
public IEnumerable < MonoEntityTemplateBase > MonoTemplates
2024-03-09 03:35:01 +08:00
{
get { return _monoTemplates ; }
}
2024-10-18 17:22:02 +08:00
public IEnumerable < IEntityTemplate > AllTemplates
2024-03-09 03:35:01 +08:00
{
2024-10-18 17:22:02 +08:00
get { return ( ( IEnumerable < IEntityTemplate > ) _scriptableTemplates ) . Concat ( _monoTemplates ) ; }
2024-03-09 03:35:01 +08:00
}
2023-05-07 00:50:44 +08:00
#endregion
2024-03-09 03:35:01 +08:00
#region Connect
2024-03-10 09:50:20 +08:00
public void ConnectWith ( entlong entity , bool applyTemplates )
2023-05-07 00:50:44 +08:00
{
2024-03-10 10:20:44 +08:00
Disconnect ( ) ;
2023-05-07 00:50:44 +08:00
2024-03-10 09:50:20 +08:00
if ( entity . TryUnpack ( out int newEntityID , out EcsWorld world ) )
2023-05-07 00:50:44 +08:00
{
2024-03-28 18:43:42 +08:00
_isConnectInvoked = true ;
2023-05-07 00:50:44 +08:00
_entity = entity ;
2024-03-10 09:50:20 +08:00
_world = world ;
2024-05-25 22:28:38 +08:00
_connectedEntities . Add ( GetInstanceID ( ) , this ) ;
2024-03-10 22:27:17 +08:00
var goConnects = world . GetPool < GameObjectConnect > ( ) ;
if ( goConnects . Has ( newEntityID ) )
2024-03-09 03:35:01 +08:00
{
2024-03-10 22:27:17 +08:00
ref readonly var goConnect = ref goConnects . Read ( newEntityID ) ;
if ( goConnect . IsConnected )
2024-03-10 10:20:44 +08:00
{
2024-03-10 22:27:17 +08:00
goConnect . Connect . Disconnect ( ) ;
2024-03-10 10:20:44 +08:00
}
2024-03-09 03:35:01 +08:00
}
2024-03-10 10:20:44 +08:00
2024-03-10 22:27:17 +08:00
goConnects . TryAddOrGet ( newEntityID ) = new GameObjectConnect ( this ) ;
2023-05-07 00:50:44 +08:00
if ( applyTemplates )
2024-03-09 03:35:01 +08:00
{
2024-11-01 12:44:45 +08:00
ApplyTemplatesFor ( world . ID , newEntityID ) ;
2024-03-09 03:35:01 +08:00
}
2023-05-07 00:50:44 +08:00
}
}
2024-03-10 10:20:44 +08:00
public void Disconnect ( )
{
2024-03-28 18:43:42 +08:00
if ( _isConnectInvoked = = false )
2024-03-10 22:27:17 +08:00
{
return ;
}
2024-03-28 18:43:42 +08:00
_isConnectInvoked = false ;
2024-03-28 23:24:39 +08:00
if ( _world . IsNullOrDetroyed ( ) = = false & & _entity . TryGetID ( out int oldEntityID ) )
2024-03-10 10:20:44 +08:00
{
2024-03-10 22:27:17 +08:00
var unityGameObjects = _world . GetPool < GameObjectConnect > ( ) ;
2024-03-10 10:29:58 +08:00
unityGameObjects . TryDel ( oldEntityID ) ;
2024-03-10 10:20:44 +08:00
}
2024-08-13 22:16:58 +08:00
_connectedEntities . Remove ( GetInstanceID ( ) ) ;
2024-03-10 10:20:44 +08:00
_world = null ;
2024-03-10 10:35:02 +08:00
_entity = entlong . NULL ;
2024-03-10 10:20:44 +08:00
}
2024-03-09 03:35:01 +08:00
#endregion
#region ApplyTemplates
2024-03-10 09:50:20 +08:00
public void ApplyTemplatesFor ( short worldID , int entityID )
2023-05-07 00:50:44 +08:00
{
2024-03-09 03:35:01 +08:00
foreach ( var template in _scriptableTemplates )
2024-03-03 03:51:49 +08:00
{
2024-03-10 09:50:20 +08:00
template . Apply ( worldID , entityID ) ;
2024-03-03 03:51:49 +08:00
}
2024-03-09 03:35:01 +08:00
foreach ( var template in _monoTemplates )
2024-03-03 03:51:49 +08:00
{
2024-03-10 09:50:20 +08:00
template . Apply ( worldID , entityID ) ;
2024-03-03 03:51:49 +08:00
}
2023-05-07 00:50:44 +08:00
}
2024-03-09 03:35:01 +08:00
#endregion
2024-03-10 19:23:05 +08:00
#region UnityEvents
private void OnDestroy ( )
{
2024-03-28 18:43:42 +08:00
entlong ent = _entity ;
2024-03-10 19:23:05 +08:00
Disconnect ( ) ;
2024-05-25 22:28:38 +08:00
2024-10-12 20:11:37 +08:00
if ( _deleteEntityWithDestroy = = false )
2024-03-28 18:43:42 +08:00
{
2024-05-25 22:28:38 +08:00
return ;
2024-03-28 18:43:42 +08:00
}
2024-05-25 22:28:38 +08:00
ent . UnpackUnchecked ( out int e , out short gen , out short worldID ) ;
var world = EcsWorld . GetWorld ( worldID ) ;
if ( world ! = null & & world . IsAlive ( e , gen ) )
{
world . DelEntity ( e ) ;
}
//if (_deleteEntiityWithDestroy && ent.TryUnpack(out int id, out EcsWorld world))
//{
// world.DelEntity(id);
//}
}
#endregion
#region Other
public static EcsEntityConnect GetConnectByInstanceID ( int instanceID )
{
return _connectedEntities [ instanceID ] ;
}
public static bool TryGetConnectByInstanceID ( int instanceID , out EcsEntityConnect conncet )
{
return _connectedEntities . TryGetValue ( instanceID , out conncet ) ;
2024-03-10 19:23:05 +08:00
}
#endregion
2024-03-09 03:35:01 +08:00
#region Editor
2024-03-09 22:36:35 +08:00
#if UNITY_EDITOR
[ContextMenu("Autoset")]
internal void Autoset_Editor ( )
2024-03-09 03:35:01 +08:00
{
2024-03-09 22:36:35 +08:00
Autoset ( this ) ;
2024-03-09 03:35:01 +08:00
}
2024-03-09 22:36:35 +08:00
[ContextMenu("Autoset Cascade")]
internal void AutosetCascade_Editor ( )
{
foreach ( var item in GetComponentsInChildren < EcsEntityConnect > ( ) )
{
Autoset ( item ) ;
}
}
[ContextMenu("Unlink Entity")]
internal void UnlinkEntity_Editor ( )
{
2024-03-10 09:50:20 +08:00
ConnectWith ( entlong . NULL , false ) ;
2024-03-09 22:36:35 +08:00
}
[ContextMenu("Delete Entity")]
internal void DeleteEntity_Editor ( )
{
if ( _entity . TryUnpack ( out int id , out EcsWorld world ) )
{
world . DelEntity ( id ) ;
}
UnlinkEntity_Editor ( ) ;
}
private static void Autoset ( EcsEntityConnect target )
{
2024-04-26 06:05:29 +08:00
IEnumerable < MonoEntityTemplateBase > result ;
2024-03-28 18:43:42 +08:00
if ( target . MonoTemplates ! = null & & target . MonoTemplates . Count ( ) > 0 )
{
result = target . MonoTemplates . Where ( o = > o ! = null ) . Union ( GetTemplatesFor ( target . transform ) ) ;
}
else
{
result = GetTemplatesFor ( target . transform ) ;
}
2024-03-09 22:36:35 +08:00
target . _monoTemplates = result . ToArray ( ) ;
EditorUtility . SetDirty ( target ) ;
}
2024-04-26 06:05:29 +08:00
private static IEnumerable < MonoEntityTemplateBase > GetTemplatesFor ( Transform parent )
2024-03-09 22:36:35 +08:00
{
2024-04-26 06:05:29 +08:00
IEnumerable < MonoEntityTemplateBase > result = parent . GetComponents < MonoEntityTemplateBase > ( ) ;
2024-03-09 22:36:35 +08:00
for ( int i = 0 ; i < parent . childCount ; i + + )
{
var child = parent . GetChild ( i ) ;
if ( child . TryGetComponent < EcsEntityConnect > ( out _ ) )
{
2024-04-26 06:05:29 +08:00
return Enumerable . Empty < MonoEntityTemplateBase > ( ) ;
2024-03-09 22:36:35 +08:00
}
result = result . Concat ( GetTemplatesFor ( child ) ) ;
}
return result ;
}
#endif
2024-03-09 03:35:01 +08:00
#endregion
2023-05-07 00:50:44 +08:00
}
2024-03-06 21:37:21 +08:00
}