Boat Attack使用了Universal RP的许多新图形功能,可以用于探索 Universal RP 的使用方式和技巧。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

270 行
12 KiB

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.Properties;
using Unity.Properties.Reflection;
namespace Unity.Entities
{
public readonly struct EntityContainer
{
static EntityContainer()
{
PropertyBagResolver.Register(new EntityContainerPropertyBag());
PropertyBagResolver.RegisterProvider(new ReflectedPropertyBagProvider());
}
internal readonly EntityManager EntityManager;
internal readonly Entity Entity;
internal readonly bool IsReadOnly;
public int GetComponentCount() => EntityManager.GetComponentCount(Entity);
public EntityContainer(EntityManager entityManager, Entity entity, bool readOnly = true)
{
EntityManager = entityManager;
Entity = entity;
IsReadOnly = readOnly;
}
}
public class EntityContainerPropertyBag : PropertyBag<EntityContainer>
{
private struct EntityProperty : IProperty<EntityContainer, Entity>
{
public string GetName() => "Entity";
public bool IsReadOnly => true;
public bool IsContainer => true;
public IPropertyAttributeCollection Attributes { get; }
public Entity GetValue(ref EntityContainer container) => container.Entity;
public void SetValue(ref EntityContainer container, Entity value)
=> throw new NotSupportedException("Property is ReadOnly");
public EntityProperty(params Attribute[] attributes)
{
Attributes = new PropertyAttributeCollection(attributes);
}
}
/// <summary>
/// Dynamic property to handle returning all components from an entity.
/// </summary>
private struct ComponentsProperty : ICollectionProperty<EntityContainer, IEnumerable<object>>
{
private struct GetComponentDataCallback<TCallback> : IContainerTypeCallback
where TCallback : ICollectionElementGetter<EntityContainer>
{
public TCallback Callback;
public EntityContainer Container;
public int Index;
public int TypeIndex;
public IPropertyAttributeCollection Attributes => null;
public void Invoke<TComponent>()
{
Callback.VisitProperty<ComponentDataProperty<TComponent>, TComponent>(new ComponentDataProperty<TComponent>(Index, TypeIndex, Container.IsReadOnly), ref Container);
}
}
private struct GetSharedComponentDataCallback<TCallback> : IContainerTypeCallback
where TCallback : ICollectionElementGetter<EntityContainer>
{
public TCallback Callback;
public EntityContainer Container;
public int Index;
public int TypeIndex;
public IPropertyAttributeCollection Attributes => null;
public void Invoke<TComponent>()
{
Callback.VisitProperty<SharedComponentDataProperty<TComponent>, TComponent>(new SharedComponentDataProperty<TComponent>(Index, TypeIndex), ref Container);
}
}
private struct GetBufferElementDataCallback<TCallback> : IContainerTypeCallback
where TCallback : ICollectionElementGetter<EntityContainer>
{
public TCallback Callback;
public EntityContainer Container;
public int Index;
public int TypeIndex;
public void Invoke<TBuffer>()
{
Callback.VisitProperty<DynamicBufferProperty<TBuffer>, DynamicBufferContainer<TBuffer>>(new DynamicBufferProperty<TBuffer>(Index, TypeIndex, Container.IsReadOnly), ref Container);
}
}
public struct ComponentDataProperty<TValue> : ICollectionElementProperty<EntityContainer, TValue>
{
private readonly int m_Index;
private readonly int m_TypeIndex;
private readonly bool m_IsReadOnly;
public string GetName() => typeof(TValue).Name;
public bool IsReadOnly => TypeManager.GetTypeInfo(m_TypeIndex).IsZeroSized || m_IsReadOnly;
public bool IsContainer => true;
public IPropertyAttributeCollection Attributes => null;
public int Index => m_Index;
public ComponentDataProperty(int index, int typeIndex, bool isReadOnly)
{
m_Index = index;
m_TypeIndex = typeIndex;
m_IsReadOnly = isReadOnly;
}
public unsafe TValue GetValue(ref EntityContainer container)
{
if (!TypeManager.GetTypeInfo(m_TypeIndex).IsZeroSized)
{
return Unsafe.AsRef<TValue>(container.EntityManager.GetComponentDataRawRO(container.Entity, m_TypeIndex));
}
return default;
}
public unsafe void SetValue(ref EntityContainer container, TValue value)
{
if (TypeManager.GetTypeInfo(m_TypeIndex).IsZeroSized)
{
throw new InvalidOperationException("Property is ReadOnly");
}
Unsafe.Copy(container.EntityManager.GetComponentDataRawRW(container.Entity, m_TypeIndex), ref value);
}
}
public struct SharedComponentDataProperty<TValue> : ICollectionElementProperty<EntityContainer, TValue>
{
private readonly int m_Index;
private readonly int m_TypeIndex;
public string GetName() => typeof(TValue).Name;
public bool IsReadOnly => true;
public bool IsContainer => true;
public IPropertyAttributeCollection Attributes => null;
public int Index => m_Index;
public SharedComponentDataProperty(int index, int typeIndex)
{
m_Index = index;
m_TypeIndex = typeIndex;
}
public TValue GetValue(ref EntityContainer container)
{
var obj = container.EntityManager.GetSharedComponentData(container.Entity, m_TypeIndex);
return (TValue) obj;
}
public void SetValue(ref EntityContainer container, TValue value)
{
throw new InvalidOperationException("Property is ReadOnly");
}
}
public struct DynamicBufferProperty<TValue> : ICollectionElementProperty<EntityContainer, DynamicBufferContainer<TValue>>
{
private readonly int m_Index;
private readonly int m_TypeIndex;
private readonly bool m_IsReadOnly;
public string GetName() => typeof(TValue).Name;
public bool IsReadOnly => m_IsReadOnly;
public bool IsContainer => true;
public IPropertyAttributeCollection Attributes => null;
public int Index => m_Index;
public DynamicBufferProperty(int index, int typeIndex, bool isReadOnly)
{
m_Index = index;
m_TypeIndex = typeIndex;
m_IsReadOnly = isReadOnly;
}
public unsafe DynamicBufferContainer<TValue> GetValue(ref EntityContainer container)
{
var ptr = m_IsReadOnly
? container.EntityManager.GetBufferRawRO(container.Entity, m_TypeIndex)
: container.EntityManager.GetBufferRawRW(container.Entity, m_TypeIndex);
var len = container.EntityManager.GetBufferLength(container.Entity, m_TypeIndex);
return new DynamicBufferContainer<TValue>(ptr, len, Unsafe.SizeOf<TValue>());
}
public void SetValue(ref EntityContainer container, DynamicBufferContainer<TValue> value)
=> throw new NotSupportedException("Property is ReadOnly");
}
public string GetName() => "Components";
public bool IsReadOnly => true;
public bool IsContainer => false;
public IPropertyAttributeCollection Attributes => null;
public IEnumerable<object> GetValue(ref EntityContainer container) => default;
public void SetValue(ref EntityContainer container, IEnumerable<object> value) => throw new InvalidOperationException("Property is ReadOnly");
public void Clear(ref EntityContainer container) => throw new InvalidOperationException("Property is ReadOnly");
public int GetCount(ref EntityContainer container) => container.GetComponentCount();
public void SetCount(ref EntityContainer container, int count)=> throw new InvalidOperationException("Property is ReadOnly");
public void GetPropertyAtIndex<TGetter>(ref EntityContainer container, int index, ref ChangeTracker changeTracker, TGetter getter)
where TGetter : ICollectionElementGetter<EntityContainer>
{
var typeIndex = container.EntityManager.GetComponentTypeIndex(container.Entity, index);
var type = TypeManager.GetType(typeIndex);
if (typeof(IComponentData).IsAssignableFrom(type))
{
PropertyBagResolver.Resolve(type)?.Cast(new GetComponentDataCallback<TGetter>
{
Callback = getter,
Container = container,
Index = index,
TypeIndex = typeIndex
});
}
else if (typeof(ISharedComponentData).IsAssignableFrom(type))
{
PropertyBagResolver.Resolve(type)?.Cast(new GetSharedComponentDataCallback<TGetter>()
{
Callback = getter,
Container = container,
Index = index,
TypeIndex = typeIndex
});
}
else if (typeof(IBufferElementData).IsAssignableFrom(type))
{
PropertyBagResolver.Resolve(type)?.Cast(new GetBufferElementDataCallback<TGetter>
{
Callback = getter,
Container = container,
Index = index,
TypeIndex = typeIndex
});
}
}
}
private readonly EntityProperty m_Entity = new EntityProperty(new NonSerializedAttribute());
private readonly ComponentsProperty m_Components = new ComponentsProperty();
public override void Accept<TVisitor>(ref EntityContainer container, TVisitor visitor, ref ChangeTracker changeTracker)
{
visitor.VisitProperty<EntityProperty, EntityContainer, Entity>(m_Entity, ref container, ref changeTracker);
visitor.VisitCollectionProperty<ComponentsProperty, EntityContainer, IEnumerable<object>>(m_Components, ref container, ref changeTracker);
}
public override bool FindProperty<TAction>(string name, ref EntityContainer container, ref ChangeTracker changeTracker, ref TAction action)
{
if (name.Equals("Components"))
{
action.VisitCollectionProperty<ComponentsProperty, IEnumerable<object>>(m_Components, ref container, ref changeTracker);
return true;
}
return false;
}
}
}