What would be the downside to using a generic all-encompassing Component
class versus specific classes (PositionComponent
, InputComponent
, et cetera) for each component in an entity/component system?
By 'generic' I mean:
class Component {
String name; // component name, like "position"
Map attribs; // Attributes like "x" and "y" stored here.
}
Where a 'specific' component might be:
class PositionComponent {
int x, y;
}
I feel like creating a separate class for each component means tons of 3-5 line classes in my code-base.
Answer
There are a few things to watch out for in the "generic" component approach you propose:
- It means that a component is pure data, and cannot have any behavior unless you start doing things like allowing behavior objects (function pointers, or what-have-you) to be stored in the
attribs
member or in a similar member. This is a valid possible approach for an ECS, but not all ECS's choose the "component is pure data" model, and it's certainly not the only approach. - The generic component stores all attributes in a dictionary; this means string (or some kind of key) lookups to recover data, boxing, and non-contiguous storage. The associative container also has storage overhead. All of these have performance impacts. You are also abandoning type-safety.
- Storage of the name as a string (rather than being able to intuit it from the type of the component) also means extra overhead.
Personally, I've never seen a "generic component" like you proposed out in the wild for anything real. It seems like a terribly poor choice, if for no other reason than when you have generalized the component so much you might as well reduce the overhead by making the entity the thing that stores all those properties, and namespace them:
class Entity {
Dictionary components;
}
// ...
var entity = new Entity();
entity.components.Add("Position.X", 1.0f);
entity.components.Add("Position.Y", 2.0f);
entity.components.Add("Position.Z", 3.0f);
entity.components.Add("RigidBody.Mass", 100.0f);
entity.components.Add("Killable.HP", 15.0f);
(But I still don't recommend it.)
No comments:
Post a Comment