This is a simple example, I have a class which I used to new
and use it to collect data to do things in OOP style.
public class IntCollection
{
private List<int> ints = new List<int>();
public IntCollection() { }
public void Add(int i)
{
ints.Add(i);
}
public int Sum()
{
int sum = 0;
for(int i = 0; i < ints.Count; i++)
{
sum += ints[i];
}
return sum;
}
}
I want to try out C# jobs and ECS on this class and then I can speed up the Sum()
method by doing it as a job, for example. But to keep the existing user of this class use the same outward interface as before (new the class, .Add and then .Sum it should just works like before) my idea is to do ECS things inside the class like this :
public struct IntCollectionData : IComponentData
{
public int[] ints;
}
public class IntCollectionECS
{
private Entity entityToData;
private static EntityArchetype archetype;
public IntCollectionECS()
{
EntityManager em = World.Active.GetOrCreateManager<EntityManager>();
if(archetype.Valid == false)
{
em.CreateArchetype(typeof(IntCollectionData));
}
entityToData = em.CreateEntity(archetype);
}
public void Add(int toAdd)
{
EntityManager em = World.Active.GetOrCreateManager<EntityManager>();
IntCollectionData icd = em.GetComponentData<IntCollectionData>(entityToData);
int[] largerArray = new int[icd.ints.Length+1];
for(int i = 0; i < icd.ints.Length; i++)
{
largerArray[i] = icd.ints[i];
}
largerArray[largerArray.Length-1] = toAdd;
icd.ints = largerArray;
//Set data back after enlarging it with a new data.
em.SetComponentData<IntCollectionData>(entityToData, icd);
}
public int Sum()
{
EntityManager em = World.Active.GetOrCreateManager<EntityManager>();
IntCollectionData icd = em.GetComponentData<IntCollectionData>(entityToData);
int sum = 0;
for(int i = 0; i < icd.ints.Length; i++)
{
sum += icd.ints[i];
}
return sum;
}
}
So the constructor will create an archetype if it is the first time. And when new
-ing the class it would tell the entity manager to create a new entity. After this, the Add
method would request the data from entity manager to modify and save back. The Sum
method would do roughly the same.
However I got an error
ArgumentException: IntCollectionData is an IComponentData, and thus must be blittable (No managed object is allowed on the struct).
Unity.Entities.TypeManager.BuildComponentType (System.Type type)
Suggesting that array is not allowed on the IComponentData? How can I approach building an entity with an array of data belong to it?
(Of course in my game IntCollectionData
is more complicated, and the equivalent of Add
do much more thing that would benefit if I have all the data separated as a struct, arranged neatly by the ECS system, and allowing quick iteration + burst compiler. The old class has all the data together with its logic)