您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
280 行
9.8 KiB
280 行
9.8 KiB
using System;
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
using Unity.Collections;
|
|
using Unity.Collections.LowLevel.Unsafe;
|
|
|
|
namespace Unity.Entities
|
|
{
|
|
[NativeContainer]
|
|
public unsafe struct ExclusiveEntityTransaction
|
|
{
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
private AtomicSafetyHandle m_Safety;
|
|
#endif
|
|
[NativeDisableUnsafePtrRestriction] private GCHandle m_ArchetypeManager;
|
|
|
|
[NativeDisableUnsafePtrRestriction] private GCHandle m_EntityGroupManager;
|
|
|
|
[NativeDisableUnsafePtrRestriction] private GCHandle m_SharedComponentDataManager;
|
|
|
|
[NativeDisableUnsafePtrRestriction] private EntityDataManager* m_Entities;
|
|
|
|
[NativeDisableUnsafePtrRestriction]
|
|
private readonly ComponentTypeInArchetype* m_CachedComponentTypeInArchetypeArray;
|
|
|
|
internal SharedComponentDataManager SharedComponentDataManager
|
|
{
|
|
get
|
|
{
|
|
return (SharedComponentDataManager) m_SharedComponentDataManager.Target;
|
|
}
|
|
}
|
|
|
|
internal ArchetypeManager ArchetypeManager
|
|
{
|
|
get
|
|
{
|
|
return (ArchetypeManager) m_ArchetypeManager.Target;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
internal ExclusiveEntityTransaction(ArchetypeManager archetypes, EntityGroupManager entityGroupManager,
|
|
SharedComponentDataManager sharedComponentDataManager, EntityDataManager* data)
|
|
{
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
m_Safety = new AtomicSafetyHandle();
|
|
#endif
|
|
m_Entities = data;
|
|
m_ArchetypeManager = GCHandle.Alloc(archetypes, GCHandleType.Weak);
|
|
m_EntityGroupManager = GCHandle.Alloc(entityGroupManager, GCHandleType.Weak);
|
|
m_SharedComponentDataManager = GCHandle.Alloc(sharedComponentDataManager, GCHandleType.Weak);
|
|
|
|
m_CachedComponentTypeInArchetypeArray =
|
|
(ComponentTypeInArchetype*) UnsafeUtility.Malloc(sizeof(ComponentTypeInArchetype) * 32 * 1024, 16,
|
|
Allocator.Persistent);
|
|
}
|
|
|
|
internal void OnDestroyManager()
|
|
{
|
|
UnsafeUtility.Free(m_CachedComponentTypeInArchetypeArray, Allocator.Persistent);
|
|
m_ArchetypeManager.Free();
|
|
m_EntityGroupManager.Free();
|
|
m_SharedComponentDataManager.Free();
|
|
m_Entities = null;
|
|
}
|
|
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
internal void SetAtomicSafetyHandle(AtomicSafetyHandle safety)
|
|
{
|
|
m_Safety = safety;
|
|
}
|
|
#endif
|
|
|
|
private int PopulatedCachedTypeInArchetypeArray(ComponentType* requiredComponents, int count)
|
|
{
|
|
m_CachedComponentTypeInArchetypeArray[0] = new ComponentTypeInArchetype(ComponentType.Create<Entity>());
|
|
for (var i = 0; i < count; ++i)
|
|
SortingUtilities.InsertSorted(m_CachedComponentTypeInArchetypeArray, i + 1, requiredComponents[i]);
|
|
return count + 1;
|
|
}
|
|
|
|
[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
|
|
public void CheckAccess()
|
|
{
|
|
#if ENABLE_UNITY_COLLECTIONS_CHECKS
|
|
AtomicSafetyHandle.CheckWriteAndThrow(m_Safety);
|
|
#endif
|
|
}
|
|
|
|
internal EntityArchetype CreateArchetype(ComponentType* types, int count)
|
|
{
|
|
CheckAccess();
|
|
|
|
var groupManager = (EntityGroupManager) m_EntityGroupManager.Target;
|
|
|
|
EntityArchetype type;
|
|
type.Archetype = ArchetypeManager.GetOrCreateArchetype(m_CachedComponentTypeInArchetypeArray,
|
|
PopulatedCachedTypeInArchetypeArray(types, count), groupManager);
|
|
|
|
return type;
|
|
}
|
|
|
|
public EntityArchetype CreateArchetype(params ComponentType[] types)
|
|
{
|
|
fixed (ComponentType* typesPtr = types)
|
|
{
|
|
return CreateArchetype(typesPtr, types.Length);
|
|
}
|
|
}
|
|
|
|
public Entity CreateEntity(EntityArchetype archetype)
|
|
{
|
|
CheckAccess();
|
|
|
|
Entity entity;
|
|
CreateEntityInternal(archetype, &entity, 1);
|
|
return entity;
|
|
}
|
|
|
|
public void CreateEntity(EntityArchetype archetype, NativeArray<Entity> entities)
|
|
{
|
|
CreateEntityInternal(archetype, (Entity*) entities.GetUnsafePtr(), entities.Length);
|
|
}
|
|
|
|
public Entity CreateEntity(params ComponentType[] types)
|
|
{
|
|
return CreateEntity(CreateArchetype(types));
|
|
}
|
|
|
|
private void CreateEntityInternal(EntityArchetype archetype, Entity* entities, int count)
|
|
{
|
|
CheckAccess();
|
|
m_Entities->CreateEntities(ArchetypeManager, archetype.Archetype, entities, count);
|
|
}
|
|
|
|
public Entity Instantiate(Entity srcEntity)
|
|
{
|
|
Entity entity;
|
|
InstantiateInternal(srcEntity, &entity, 1);
|
|
return entity;
|
|
}
|
|
|
|
public void Instantiate(Entity srcEntity, NativeArray<Entity> outputEntities)
|
|
{
|
|
InstantiateInternal(srcEntity, (Entity*) outputEntities.GetUnsafePtr(), outputEntities.Length);
|
|
}
|
|
|
|
private void InstantiateInternal(Entity srcEntity, Entity* outputEntities, int count)
|
|
{
|
|
CheckAccess();
|
|
|
|
if (!m_Entities->Exists(srcEntity))
|
|
throw new ArgumentException("srcEntity is not a valid entity");
|
|
|
|
var groupManager = (EntityGroupManager) m_EntityGroupManager.Target;
|
|
|
|
m_Entities->InstantiateEntities(ArchetypeManager, SharedComponentDataManager, groupManager, srcEntity, outputEntities,
|
|
count, m_CachedComponentTypeInArchetypeArray);
|
|
}
|
|
|
|
public void DestroyEntity(NativeArray<Entity> entities)
|
|
{
|
|
DestroyEntityInternal((Entity*) entities.GetUnsafeReadOnlyPtr(), entities.Length);
|
|
}
|
|
|
|
public void DestroyEntity(NativeSlice<Entity> entities)
|
|
{
|
|
DestroyEntityInternal((Entity*) entities.GetUnsafeReadOnlyPtr(), entities.Length);
|
|
}
|
|
|
|
public void DestroyEntity(Entity entity)
|
|
{
|
|
DestroyEntityInternal(&entity, 1);
|
|
}
|
|
|
|
private void DestroyEntityInternal(Entity* entities, int count)
|
|
{
|
|
CheckAccess();
|
|
m_Entities->AssertEntitiesExist(entities, count);
|
|
|
|
var groupManager = (EntityGroupManager) m_EntityGroupManager.Target;
|
|
|
|
m_Entities->TryRemoveEntityId(entities, count, ArchetypeManager, SharedComponentDataManager, groupManager,
|
|
m_CachedComponentTypeInArchetypeArray);
|
|
}
|
|
|
|
public void AddComponent(Entity entity, ComponentType type)
|
|
{
|
|
CheckAccess();
|
|
|
|
var groupManager = (EntityGroupManager) m_EntityGroupManager.Target;
|
|
|
|
m_Entities->AssertEntitiesExist(&entity, 1);
|
|
m_Entities->AddComponent(entity, type, ArchetypeManager, SharedComponentDataManager, groupManager,
|
|
m_CachedComponentTypeInArchetypeArray);
|
|
}
|
|
|
|
public void RemoveComponent(Entity entity, ComponentType type)
|
|
{
|
|
CheckAccess();
|
|
|
|
var groupManager = (EntityGroupManager) m_EntityGroupManager.Target;
|
|
|
|
m_Entities->AssertEntityHasComponent(entity, type);
|
|
m_Entities->RemoveComponent(entity, type, ArchetypeManager, SharedComponentDataManager, groupManager,
|
|
m_CachedComponentTypeInArchetypeArray);
|
|
}
|
|
|
|
public bool Exists(Entity entity)
|
|
{
|
|
CheckAccess();
|
|
|
|
return m_Entities->Exists(entity);
|
|
}
|
|
|
|
public T GetComponentData<T>(Entity entity) where T : struct, IComponentData
|
|
{
|
|
CheckAccess();
|
|
|
|
var typeIndex = TypeManager.GetTypeIndex<T>();
|
|
m_Entities->AssertEntityHasComponent(entity, typeIndex);
|
|
|
|
var ptr = m_Entities->GetComponentDataWithTypeRO(entity, typeIndex);
|
|
|
|
T data;
|
|
UnsafeUtility.CopyPtrToStructure(ptr, out data);
|
|
return data;
|
|
}
|
|
|
|
public void SetComponentData<T>(Entity entity, T componentData) where T : struct, IComponentData
|
|
{
|
|
CheckAccess();
|
|
|
|
var typeIndex = TypeManager.GetTypeIndex<T>();
|
|
m_Entities->AssertEntityHasComponent(entity, typeIndex);
|
|
|
|
var ptr = m_Entities->GetComponentDataWithTypeRW(entity, typeIndex, m_Entities->GlobalSystemVersion);
|
|
UnsafeUtility.CopyStructureToPtr(ref componentData, ptr);
|
|
}
|
|
|
|
public T GetSharedComponentData<T>(Entity entity) where T : struct, ISharedComponentData
|
|
{
|
|
var typeIndex = TypeManager.GetTypeIndex<T>();
|
|
m_Entities->AssertEntityHasComponent(entity, typeIndex);
|
|
|
|
var sharedComponentIndex = m_Entities->GetSharedComponentDataIndex(entity, typeIndex);
|
|
return SharedComponentDataManager.GetSharedComponentData<T>(sharedComponentIndex);
|
|
}
|
|
|
|
public void SetSharedComponentData<T>(Entity entity, T componentData) where T : struct, ISharedComponentData
|
|
{
|
|
CheckAccess();
|
|
|
|
var typeIndex = TypeManager.GetTypeIndex<T>();
|
|
m_Entities->AssertEntityHasComponent(entity, typeIndex);
|
|
|
|
var archetypeManager = ArchetypeManager;
|
|
var sharedComponentDataManager = SharedComponentDataManager;
|
|
|
|
var newSharedComponentDataIndex = sharedComponentDataManager.InsertSharedComponent(componentData);
|
|
m_Entities->SetSharedComponentDataIndex(archetypeManager, sharedComponentDataManager, entity, typeIndex,
|
|
newSharedComponentDataIndex);
|
|
sharedComponentDataManager.RemoveReference(newSharedComponentDataIndex);
|
|
}
|
|
|
|
internal void AllocateConsecutiveEntitiesForLoading(int count)
|
|
{
|
|
m_Entities->AllocateConsecutiveEntitiesForLoading(count);
|
|
}
|
|
|
|
|
|
internal void AddExistingChunk(Chunk* chunk)
|
|
{
|
|
ArchetypeManager.AddExistingChunk(chunk);
|
|
m_Entities->AddExistingChunk(chunk);
|
|
}
|
|
}
|
|
}
|