Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Component oriented design
08-05-2010, 03:27 PM,
Component oriented design
While working on the texture, model, sound managers(caches), I've noticed that the same pattern would be applicable to other objects(car, cardynamics, ...).

Joe, what do you think about going towards a component oriented implementation?

First rough concept of the track description file given available components(transform, drawable, body, surface):

t0 = transform
t0.position = 0, 1, 0
t0.orientation = 0, 0.15, 0.15

d0 = drawable
d0.transform = t0
d0.mesh = tree.obj
d0.texture = tree.png
d0.color = 1, 1, 1 # default color(no blending)
d0.doublesided = true

To make it collidable/dynamic add a body component (body and drawable are sharing transform and mesh):

s0 = surface
s0.bumplength = 1.0
s0.bumpamlitude = 0.2
s0.treaded = 0.7
s0.nontreaded = 0.4
s0.rollresistance = 1.0

b0 = body
b0.transform = t0
b0.shape = tree.obj
b0.mass = 0 # default mass(static body)
b0.surface = s0
08-05-2010, 11:14 PM,
So first of all, the way the scene is defined in the track description file is independent from how the engine is structured. The engine could be component-based or not at all component based and still use description file layout you proposed. I like the layout you proposed.

About the engine architecture... I think the general idea of the component-based stuff is good, but I don't like the implementation that they commonly use: "Giving each component a common interface means deriving from a base class with virtual functions." My understanding is that component-based architecture means making all components derive from a generic component class, putting all the components into one component manager, and having that update them all in one big generic update. I don't like that at all. In my opinion, making all of your component types derive from a generic component class blurs the lines between the components. Instead, break things out into different components that have their own, unrelated types. Drawables get their own type, and are unrelated to physics bodies which get their own type, etc.

The two arguments for component-based aggregation (as I understand them) are 1) data-driven aggregation and 2) easy updating of all objects.

For 1, I don't think doing the full-on component thing and allowing data-driven aggregation gets you much; I foresee difficulty later on with debugging and understanding code. Instead of defining aggregation in your data, just put it in your code. If it's a car, then make a car type and have it include drawable and body objects.

For 2, I understand that if all bodies need to be updated, you might not want to traverse all of your entity types to see if they have bodies that need to be updated. Instead of going component-based, though, just put all of your physics bodies into a body manager, and have the manager update all bodies. Just keep a reference around inside your entity. I think that's a lot clearer than making all bodies derive from the generic component type and putting all components in a component manager and having that update all components, especially since sometimes the manager needs to do a lot of work that is specific to the type of component it's updating.

Okay, that was a brain dump, I'll stop now.
08-06-2010, 04:20 PM,
I think there is no need to have a base class for the components. We could have a bunch of concrete component "managers".

class ComponentManager
template <class T>
shared_ptr<T> get(const Load<T> & loader);
Manager<Texture> textures;
Manager<Model> models;

The component itself could be a simple struct. The loader class implements loading logics. Hmm... the concrete loaders will still have to implement a common interface.

The motivation for the component based aproach for me has been to get rid of the gigantic interfaces of car, cardynamics. I think the car doesn't have to know that it has got brakes, clutch and a transmission. The driver/input and head-up display could deal(communicate) with this components directly.
08-08-2010, 01:44 AM,
Hmm, I don't think there's anything in the current architecture stopping the input or HUD from dealing with the brakes, clutch, etc directly. The reason I didn't do that and instead routed everything through the CAR object was to provide a layer of abstraction. The abstraction allows the CAR to present a standardized interface to the brakes/transmission/etc for the rest of the game. It's nice because it allows stuff like auto-clutching if you don't have a dedicated clutch input, for example. If you take that sort of code out of CAR, then you have to start putting it somewhere else, either inside the clutch (which I don't like because then the clutch has to know stuff about the game's controls) or in whatever was previously delegating that functionality to CAR (in this case I think it would be GAME, which is even larger and more crowded than CAR).

However, I do agree though that there are a lot of useless functions in CAR that merely call functions in CARDYNAMICS. We could break out the CARDYNAMICS from the CAR, so the CARDYNAMICS handles all non-visual aspects of the car, then turn CAR into some sort of CARINSTANCE or even an abstract OBJECTINSTANCE that handles placing one or more textured models at one or more offsets, and updating those models appropriately when given a CARDYNAMICS object. The driver input code that's currently scattered between GAME and CAR could be put in a new CARCONTROLLER object that calls functions in CARDYNAMICS. The HUD would also communicate with the CARDYNAMICS object. The idea is to be more like a model/view/controller architecture.

Forum Jump:

Users browsing this thread: 1 Guest(s)