using System;
using System.Collections.Generic;
using System.Reflection;
using Svelto.DataStructures;
using Svelto.ECS.Internal;
namespace Svelto.ECS
{
public class EntityDescriptor
{
protected EntityDescriptor()
{}
///
/// if you want to avoid allocation in run-time, you can prebuild
/// EntityDescriptors and use them to build entities at different
/// times
///
protected EntityDescriptor(INodeBuilder[] nodesToBuild)
{
_nodesToBuild = new FasterList(nodesToBuild);
}
protected EntityDescriptor(INodeBuilder[] nodesToBuild,
params object[] componentsImplementor):this(nodesToBuild)
{
ProcessImplementors(componentsImplementor);
}
public void AddImplementors(params object[] componentsImplementor)
{
ProcessImplementors(componentsImplementor);
}
public void AddNodes(params INodeBuilder[] nodesWithID)
{
_nodesToBuild.AddRange(nodesWithID);
}
internal void BuildGroupedNodes
(int entityID, int groupID,
Dictionary> groupNodes,
ref BuildNodeCallbackStruct callBackstruct)
{
for (int index = 0; index < _nodesToBuild.Count; index++)
{
var nodeBuilder = _nodesToBuild[index];
var nodeType = nodeBuilder.GetNodeType();
Dictionary groupedNodesTyped;
if (groupNodes.TryGetValue(nodeType, out groupedNodesTyped) == false)
{
groupedNodesTyped = new Dictionary();
groupNodes.Add(nodeType, groupedNodesTyped);
};
ITypeSafeList nodes;
var mustAdd = groupedNodesTyped.TryGetValue(groupID, out nodes) == false;
var node = nodeBuilder.BuildAndAddToList(ref nodes, entityID);
if (mustAdd)
groupedNodesTyped[groupID] = nodes;
if (node != null && nodeBuilder.reflects != FillNodeMode.None)
{
node = FillNode(node, nodeBuilder.reflects);
SetupImplementors(ref callBackstruct, nodes);
}
/* var groupNode = node as IGroupedNode;
if (groupNode != null)
groupNode.groupID = groupID;*/
}
}
internal void BuildNodes(int entityID,
Dictionary nodesToAdd,
ref BuildNodeCallbackStruct callBackstruct)
{
for (int index = 0; index < _nodesToBuild.Count; index++)
{
var nodeBuilder = _nodesToBuild[index];
var nodeType = nodeBuilder.GetNodeType();
ITypeSafeList nodes;
var mustAdd = nodesToAdd.TryGetValue(nodeType, out nodes) == false;
var node = nodeBuilder.BuildAndAddToList(ref nodes, entityID);
if (mustAdd)
nodesToAdd[nodeType] = nodes;
if (node != null && nodeBuilder.reflects != FillNodeMode.None)
{
FillNode(node, nodeBuilder.reflects);
SetupImplementors(ref callBackstruct, nodes);
}
}
}
void ProcessImplementors(object[] implementors)
{
for (int index = 0; index < implementors.Length; index++)
{
var implementor = implementors[index];
if (implementor != null)
{
if (implementor is IRemoveEntityComponent)
_removingImplementors.Add(new DataStructures.WeakReference(implementor as IRemoveEntityComponent));
if (implementor is IDisableEntityComponent)
_disablingImplementors.Add(new DataStructures.WeakReference(implementor as IDisableEntityComponent));
if (implementor is IEnableEntityComponent)
_enablingImplementors.Add(new DataStructures.WeakReference(implementor as IEnableEntityComponent));
var interfaces = implementor.GetType().GetInterfaces();
var weakReference = new DataStructures.WeakReference