I am at what I believe to be the last big logical leap before completing my component based game engine in C# using XNA. I have my Entity class and abstract components defined. My issue is arising in my EntityFactory.
When I want to create a new entity I pass in an EntityType enum to a static method in the factory, and it goes through a switch/case statement finding which components to put together. The problem is, I am trying to create a way that the components can share fields with other components in the same Entity without them having access to everything. For instance, if two components have Vector2 fields that represents position, they should both point to the same Vector2.
I can do this by initializing all fields in the entity factory and requiring that they be passed into the constructor of the component (and using ref for the primitives), but this would be extremely hard to maintain, since any time I expanded or changed a component, I would have to rewrite code in the factory in every place that component was used. I really want to avoid this solution, but if I can't find a better way, I will put up with it.
My current solution is to create a wrapper class called Attribute. It contains two fields:
private AttributeType type;
private Object data;
Attribute Type is an enum, representing the purpose of the attribute. So there are entries in the enum of Position, Rotation, Texture, etc.
The EntityFactory creates an empty list of attributes, and passes it to each component constructor. The setField method would be called by the component's constructor rather than initializing the fields. Here is the Attribute class and the setField method.
public class Attribute
{
private AttributeType type;
private Object data;
public AttributeType Type
{
get { return this.type; }
}
public Object Data
{
get { return this.data; }
}
public Attribute(AttributeType type, Object data)
{
this.type = type;
this.data = data;
}
public static void setField<T>(List<Attribute> attributeList, AttributeType type, out T field, T defaultValue)
{
bool attributeFound = false;
field = defaultValue;
foreach (Attribute attribute in attributeList)
{
if (attribute.Type == type)
{
field = (T)attribute.Data;
attributeFound = true;
break;
}
}
if (!attributeFound)
{
attributeList.Add(new Attribute(type, field));
}
}
}
My problem is when the attribute contains data that is of a primitive type. I considered writing a method in the Attribute class of
public void getData<T>(out T field) { field = this.data; }
however I can't seem to pass in data to the Attribute constructor using ref. I can't make Attribute generic since it wouldn't go into a list. I am just wondering if there is a way to handle value type as well as reference type data, or am I making a logical mistake somewhere in this whole thing.