您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
120 行
4.8 KiB
120 行
4.8 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using Unity.Properties;
|
|
|
|
namespace Unity.Entities.Properties
|
|
{
|
|
/// <summary>
|
|
/// Container to iterate on Entity instances.
|
|
/// </summary>
|
|
public unsafe struct EntityContainer : IPropertyContainer
|
|
{
|
|
/// <summary>
|
|
/// WARNING This property does NOT implement the List property fully and instead makes the assumption that we are only serializing...
|
|
/// This may cause problems when we start to write UI code and should be looked at.
|
|
/// This is a quick implementation to get higher performance visits
|
|
/// </summary>
|
|
private sealed class ReadOnlyComponentsProperty : StructListStructProperty<EntityContainer, StructProxy>
|
|
{
|
|
public ReadOnlyComponentsProperty(string name) : base(name, null, null) { }
|
|
|
|
public override void Accept(ref EntityContainer container, IPropertyVisitor visitor)
|
|
{
|
|
var count = container.m_Manager.GetComponentCount(container.m_Entity);
|
|
var listContext = new VisitContext<IList<StructProxy>> { Property = this, Value = null, Index = -1 };
|
|
|
|
// @TODO improve, split the deps
|
|
HashSet<Type> primitiveTypes = new HashSet<Type>();
|
|
|
|
// try to gather the primitive types for that visitor
|
|
var entityVisitor = visitor as IPrimitivePropertyVisitor;
|
|
if (entityVisitor != null)
|
|
{
|
|
primitiveTypes = entityVisitor.SupportedPrimitiveTypes();
|
|
}
|
|
else
|
|
{
|
|
// @TODO remove that dependency
|
|
// Fallback on the optimized visitor for now
|
|
primitiveTypes = OptimizedVisitor.SupportedTypes();
|
|
}
|
|
|
|
if (visitor.BeginCollection(ref container, listContext))
|
|
{
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
var item = Get(ref container, i, primitiveTypes);
|
|
var context = new VisitContext<StructProxy>
|
|
{
|
|
Property = this,
|
|
Value = item,
|
|
Index = i
|
|
};
|
|
|
|
if (visitor.BeginContainer(ref container, context))
|
|
{
|
|
(item.PropertyBag as StructPropertyBag<StructProxy>)?.Visit(ref item, visitor);
|
|
}
|
|
|
|
visitor.EndContainer(ref container, context);
|
|
}
|
|
}
|
|
|
|
visitor.EndCollection(ref container, listContext);
|
|
}
|
|
|
|
private static StructProxy Get(ref EntityContainer container, int index, HashSet<Type> primitiveTypes)
|
|
{
|
|
var typeIndex = container.m_Manager.GetComponentTypeIndex(container.m_Entity, index);
|
|
var propertyType = TypeManager.GetType(typeIndex);
|
|
|
|
if (typeof(ISharedComponentData).IsAssignableFrom(propertyType))
|
|
{
|
|
var o = container.m_Manager.GetSharedComponentData(container.m_Entity, typeIndex);
|
|
|
|
// TODO: skip the StructObjectProxyProperty adapter and have the Accept()
|
|
// TODO: handle Struct & Object proxies
|
|
var p = new StructProxy
|
|
{
|
|
bag = new StructPropertyBag<StructProxy>(
|
|
new StructObjectProxyProperty(propertyType, o, primitiveTypes)
|
|
),
|
|
data = default(byte*),
|
|
type = propertyType
|
|
};
|
|
|
|
return p;
|
|
}
|
|
|
|
{
|
|
var p = new StructProxy
|
|
{
|
|
bag = TypeInformation.GetOrCreate(propertyType, primitiveTypes),
|
|
data = (byte*)container.m_Manager.GetComponentDataRawRW(container.m_Entity, typeIndex),
|
|
type = propertyType
|
|
};
|
|
|
|
return p;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static readonly IListStructProperty<EntityContainer> s_ComponentsProperty = new ReadOnlyComponentsProperty(
|
|
"Components");
|
|
|
|
private static readonly StructPropertyBag<EntityContainer> s_PropertyBag = new StructPropertyBag<EntityContainer>(s_ComponentsProperty);
|
|
|
|
private readonly EntityManager m_Manager;
|
|
private readonly Entity m_Entity;
|
|
|
|
public IVersionStorage VersionStorage => null;
|
|
public IPropertyBag PropertyBag => s_PropertyBag;
|
|
|
|
public EntityContainer(EntityManager manager, Entity entity)
|
|
{
|
|
m_Manager = manager;
|
|
m_Entity = entity;
|
|
}
|
|
}
|
|
}
|