Component Based Objects?

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

At a certain point in his article he states that if you want cars to have rigid body physics that youd have to move the rigid body class up in the hiearchy (You need to take a look at his sample scheme to know what he means).
What I'm wondering about is, why are there physics integrated in that hiearchy in the first place? If you build up your program with 1 class hiearchy, the way he describes, you will inevitably run into problems.

I also took a look at the C++ example where an object is made up of several shapes, shapes are derived from Component and then added to an Object.
Maybe its a bad or too simple example but why do you need a component system for that? Wouldnt it be simpler and cleaner without it?

Maybe theres something I have overseen but I dont see the benefits of such a system. If someone could provide more complicated examples, I'd like to take a look at them.
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

Well, say you have a CollisionHandler component. You can derive other components to handle collisions in certain ways. (ie, emit a sound, animate, spawn a particle effect, whatever you want) Now you have a CollisionShape component. From this you derive components such as "SphereShape", "CubeShape", "MeshShape", "HeightMapShape", etc.

Using these, you can customize a GameObject (say some grass) and add a CubeShape (or whatever best fits its shape..) and add a CollisionSound component. And you can do this at run time, using an editor. You don't have to create a big class that can toggle between collision shapes, or handle all the different types of collision effects you want. Implement a GameObject::clone function and you can easily duplicate this structure in as many instances as you want.

Another aspect would be setting the mass of an object. Some objects may have mass and some don't. Why make a gigantic structure to support every possible property of an object?

The one problem with my example is that I previously thought you should only have one type of each component, but its definately likely you'd want more than one CollisionHandler for certain objects..

Another example would be behaviors. Say you support multiple battle tactics in your game: Run away from all opponents, Fight weakest opponent, Attack same mob as the group leader, etc. These are all derived Components of a "Behavior" Component. (I think these are refered to as "Component Families"). Also you have the requirement that certain types of monsters have certain behaviors, some of which may be unique to the monster. Now using the traditional approach, you would have to create a class for each type of monster or player that has a different set of allowed Behaviors. Or you could code one class to contain every single behavior in the game and have some map to manage which ones can and can't be used.

OR. . .

You simply create and set the behavior of a given GameObject on the fly. Create a BehaviorManager Component that stores the supported behaviors and have the ability to set the Behavior Component. If there is no behavior, nothing happens. If there is, it does something when you call GO::update().

Also consider Data Persistence. If you have a class that inherits a lot of properties, a lot of which it may or may not use, it will take up quite a bit of space on disk. If you serialize a GameObject and just the components that make up the object, the size of the data is kept at a minimum:

Code: Select all

GameObject Rock
{
  ...
  Render
  {
  }
  Location
  {
    position 0 0 0
    orientation 1 1 1 1
  }
  Mesh
  {
    mesh_file rock0.mesh
  }
}

GameObject MainCharacter
{
  ...
}
It seems like you're resistant to making the code more modular (re-usable), easy to debug, implement, maintain, and support various combinations with ease. If you have a valid heirarchy in your mind, you can present it for discussion. :wink:
Creator of QuickGUI!
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

Well it sounds cool in theory but I'd like to see it implemented. I can see some opportunities when components dont have to work together but once they do I dont see the benefit of it.
Lord_Fausto
Gnoblar
Posts: 6
Joined: Mon Mar 05, 2007 12:12 am

Post by Lord_Fausto »

Code: Select all

GameObject Rock
{
  ...
  Render
  {
  }
  Location
  {
    position 0 0 0
    orientation 1 1 1 1
  }
  Mesh
  {
    mesh_file rock0.mesh
  }
}

GameObject MainCharacter
{
  ...
}
Why you don't use a manager for de meshes and another for the entities?

Looks like

Code: Select all

class Object3D{
     private Mesh;
     private Material;
.....

}

class Object3DManager{
    vector Object3D;
....
}
class ObjectEntity{

     private Object3D;
     private position;
     private OverrideMaterial;
....
}
//And the ObjectEntityManager for manage it
Now you can reuse all the meshes you load and if you would you can override de default material.

You create a mesh containing a rock width brown material, you create 3 objects in diferent positions and override one material to gray.

This only waste one mesh and 2 materials, it is correct????
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

Now say I wanted to turn the Rock into a LightStone:

Code: Select all

GameObject Rock 
{ 
  ... 
  Render 
  { 
  } 
  Location 
  { 
    position 0 0 0 
    orientation 1 1 1 1 
  } 
  Mesh 
  { 
    mesh_file rock0.mesh 
  } 
  Light
  {
    attenuation ...
    diffuse ...
    specular ...
    ...
  }
} 
How easy can you modify your classes to support this? And can you do it at runtime? (Or a rock that emits particles when you get near it. Or a rock that shakes a little every so often (animation) ) :wink:
Creator of QuickGUI!
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

like this?

Code: Select all

class Animation
{
   void update();
};

class GameObject
{
  std::vector<Animation> animations;
};
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

You'd actually need a manager to decide how to blend together, disable, enable animations, etc...

Not only that, but now you've made every single GameObject inherit or implement the functions of an Animation Manager and a list of Animations. So this one specific instance of a GameObject (rock that animates) caused every other GameObject to grow in size, in code, and script size. (more to parse, more to read, more to maintain..)
Creator of QuickGUI!
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

ok, something like this then?

Code: Select all

class Animation 
{ 
   void update();
   std::string name;
}; 

class AnimationManager
{
  std::vector<Animation> animations;
};

class GameObject 
{ 
   std::vector<std::string> animations;
};
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

:lol: . I think that doesn't clear my point. I won't get to tinkering with this design until QGUI has gotten to a more mature state, so probably next year I will begin using this. I really hope you understand the design, and how it is beneficial. If not, you can always re-read the thread. :wink:
Creator of QuickGUI!
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

How so?
I think the modifications resolved your following concerns...
Not only that, but now you've made every single GameObject inherit or implement the functions of an Animation Manager and a list of Animations. So this one specific instance of a GameObject (rock that animates) caused every other GameObject to grow in size, in code, and script size. (more to parse, more to read, more to maintain..)
Feel free to correct me, I wanna learn something too :)
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

The point is, every time you want to add functionality, you increase your class size. That scenario involved animation, a mesh, and a material.

Now outline your class or hierarchy that would allow the following functionality for Game Objects:

- Mesh
- Animation
- Particle Systems
- Lights
- Camera
- Collision Shape
- Collision Handlers
- Move Speed
- Movement
- Turning
- Pathing
- Story Dialog
- Inventory
- Equipment
etc. . .

Are you trying to tell me you will make one class that supports all of the following? And then you have this Rock, that only uses a Mesh, it just sits there, but it also supports having equipment and story dialog. :lol:

Do you have some brilliant hierarchy that will enable me to create a particular Object that can carry 1 to all of the functionality I just listed? (I can't wait to see your hierarchy! :shock: ) :wink:
Creator of QuickGUI!
User avatar
steven
Gnoll
Posts: 657
Joined: Mon Feb 28, 2005 1:53 pm
Location: Australia - Canberra (ex - Switzerland - Geneva)
Contact:

Post by steven »

Chris already mentioned that we have a component/object design but you could take a look again.

You find a overview of the design here.
And here you find a code and xml sample how to use it.
And on this page you find a list of the components we envision.
With this design we can make object with any combination of components. For example, a flying tree or a door that speaks. :)

PS: The oge code is lgpl so if you find bug or make improvements we require feedback :wink:


Here is the uml diagram of our design:

Image
Last edited by steven on Tue Oct 23, 2007 1:01 am, edited 1 time in total.
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

Isnt checking wether a certain object contains a certain component more or less the same as using a dynamic_cast to check wether a certain class implements a certain interface?

for example:

Code: Select all

#include <vector>
#include <stdio.h>

class Renderable
{
public:
	virtual void render() = 0;
};

class GameObject
{
public:
	virtual ~GameObject() { }
};

class Rock : public GameObject
{
public:
	
};
class Flower : public GameObject, public Renderable
{
public:
	virtual void render() { printf("Flower rendering.\n"); }
};
class Player : public GameObject, public Renderable
{
public:
	virtual void render() { printf("Player rendering.\n"); }
};

int main()
{
	std::vector<GameObject *> list;

	list.push_back( new Rock() );
	list.push_back( new Rock() );
	list.push_back( new Flower() );
	list.push_back( new Rock() );
	list.push_back( new Player() );
	list.push_back( new Flower() );
	list.push_back( new Player() );
	list.push_back( new Flower() );


	for ( std::vector<GameObject *>::iterator iter = list.begin(); iter != list.end(); iter++ )
	{
		Renderable *r = dynamic_cast<Renderable *>( *iter );
		if ( r )
			r->render();
	}

	return 0;
}
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

@steven:

Thanks for the diagram. I read the list of components, its seems like a good list, or at least a great place to start. (won't know until we try to make a game right?) It has to be really hard to come up with a design flexible enough for any type of game.

@REiNDEeR:

Haha, you're so determined not to approve of this design, its funny. You could take your approach, but you'd end up coding a class definition per object, and every time an artist, friend, co-worker or other comes up with an idea for another object you would have to go and code it in.

My math could be wrong on this, but I quickly listed 14 components, and 14 factorial would mean you can have 87178291200 different combinations of objects given my requirements. Start coding!

Not to mention you didn't address the idea of having multiple kinds of rocks. One rock could be a plain rock, another plays a sound, another animates while playing a sound. . .etc Apply this to any type of object. Different types of flowers, doors, dogs, people, whatever you want.
Creator of QuickGUI!
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

Uhh this was a simple example, too bad you cant see the bigger picture.

But allright then show me how your gonna implement different types of rocks the component way. Id love to see that.
Lacero
Halfling
Posts: 72
Joined: Tue Feb 13, 2007 1:57 am

Post by Lacero »

But even in your example you can see how bad it's going to get. You had to write two entire render functions to support two game objects that can render. Interfaces can't inherit implementations, if you want to be able to render things you need to write it all over again.

Not to mention you've used up the "render" function now, so every single inherited component needs to have uniquely named functions and so the calling code needs to know about them.
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

Alright REiNDEeR, this is my last chance to show you what I mean, maybe you will understand it better in code:

Code: Select all

// forward declaration
class GameObject;

class Component
{
public:
	Component(int Type);
	virtual ~Component();

	void notifyOwner(GameObject* owner);

	GameObject* getOwner();
	int getType();
protected:
	GameObject* mOwner;
	int mType;
};

// Contains a SceneNode that is a part of the Scene Graph.
class CRender : public Component
{
public:
	CRender() : Component(COMPONENT_RENDER) {}
	~CRender();

	SceneNode* getSceneNode();

	// if SceneNode doesn't exist, checks owner for ID and creates a SceneNode at (0,0,0).
	// Queries owner to see if "COMPONENT_MESH" exists, as well as "COMPONENT_LIGHT" and
	// "COMPONENT_CAMERA", etc. and attaches to the scene node, if it is not attached.
	// Queries owner to see if "COMPONENT_LOCATION" exists, and if so, updates SceneNode position/orientation
	void addToScene();
	void removeFromScene();
protected:
	SceneNode* mSceneNode;
};

class CLocation : public Component
{
public:
	CLocation(Vector3 worldPosition, Quaternion orientation) : Component(COMPONENT_LOCATION), ... {...}
	CLocation(Vector3 worldPosition, Degree pitch, Degree yaw, Degree roll) : Component(COMPONENT_LOCATION), ... {...}

	Vector3 getWorldPosition();
	Quaternion getOrientation();
	Degree getPitch();
	Degree getYaw();
	Degree getRoll();
protected:
	Vector3 mWorldPosition;
	Quaternion mOrientation;
	Degree mPitch;
	Degree mYaw;
	Degree mRoll;
};

// Creates an Ogre Entity, attached to its own SceneNode.
class CMesh : public Component
{
public:
	CMesh(Ogre::String meshFile, SceneManager* mSceneManager) : Component(COMPONENT_MESH), ... {}
	~CMesh();

	// Setters and getters for Entity properties that the game deals with..
	// Can be modified/added to easily.

	Ogre::String getMeshFile();
	Entity* getOgreEntity();
	SceneNode* getSceneNode();
protected:
	Entity* mEntity;
	Ogre::String mMeshFile;
	SceneNode* mSceneNode;
};

// Creates a Light, attached to its own SceneNode
class CLight : public Component
{
public:
	CLight(SceneManager* mSceneManager) : Component(COMPONENT_LIGHT) {}
	~CLight();

	// Setters and getters for Light properties that the game deals with..
	// Can be modified/added to easily.

	Light* getLight();
	SceneNode* getSceneNode();
protected:
	Light* mLight;
	SceneNode* mSceneNode;
};

void main()
{
	GameObject* rock1;
	rock1->addComponent(new CRender());
	rock1->addComponent(new CMesh("rock1.mesh",mSceneManager));
	rock1->addComponent(new CLocation(Vector3(100, 0, 25),45,0,0));

	GameObject* rock2;
	rock2->addComponent(new CRender());
	rock2->addComponent(new CMesh("rock2.mesh",mSceneManager));
	rock2->addComponent(new CLight(mSceneManager));
	rock2->addComponent(new CLocation(Vector3(25,0,45),125,0,0));

	...

	// renders objects by adding them to scene graph.
	mGameObjectManager->addObjectsToScene();
}
Hope it makes sense now, you can define an Objects structure by adding and removing components. You can even do this in runtime, inside an editor.
Creator of QuickGUI!
User avatar
Game_Ender
Ogre Magi
Posts: 1269
Joined: Wed May 25, 2005 2:31 am
Location: Rockville, MD, USA

Post by Game_Ender »

REiNDEeR is right in that functionally using multiple inheritance lets you have an object that inherits from each component type you want. This is the same as just placing each type of Component into a container object in the game object. The key difference is when you use inheritance you fix the design at compile time. With the aggregation approach you make the Component things you add at runtime.

Here is a use case I have a hard time picturing:
I have a ship, and I can attach and detach objects to my ship. Lets say this means that any two objects with a "Physics" Component should be able to attach to each other. How do I code this?
The only way I could see would be with some kind of event system. I am just interested in how you deal with getting at the right Component out of the game object in an efficient manner.
REiNDEeR
Greenskin
Posts: 149
Joined: Sat Apr 14, 2007 1:27 pm

Post by REiNDEeR »

Game_Ender wrote:REiNDEeR is right in that functionally using multiple inheritance lets you have an object that inherits from each component type you want. This is the same as just placing each type of Component into a container object in the game object. The key difference is when you use inheritance you fix the design at compile time. With the aggregation approach you make the Component things you add at runtime.
yes thats true, the example was actually to show what I meant with that statement.

@KungFooMasta:
im gonna refrain from making comments like you did but do you expect those components are magically gonna work together or something?

Did you even take a look at the OGE design and how to use it?
User avatar
Falagard
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2060
Joined: Thu Feb 26, 2004 12:11 am
Location: Toronto, Canada
x 3
Contact:

Post by Falagard »

Here is a use case I have a hard time picturing:
I have a ship, and I can attach and detach objects to my ship. Lets say this means that any two objects with a "Physics" Component should be able to attach to each other. How do I code this?
The only way I could see would be with some kind of event system. I am just interested in how you deal with getting at the right Component out of the game object in an efficient manner.
I'll try to explain how I'm doing it.

In my case, I have Components and Behaviors. Components are containers for Behaviors, and don't do much themselves. Behaviors do all the work.

An instance of a Component will have instances of Behaviors attached to provide functionality. A Component instance can also have child Components attached to it.

The Component class has functions for a) querying Behaviors assigned to it, and b) querying its child Components.

Behaviors can have interdependencies with other Behaviors assigned to a particular Component, but they should be able to function (without crashing, for example) if a dependent Behavior doesn't exist.

For example, there may be a MeshBehavior and a MovementBehavior instance attached to a Component instance. The MeshBehavior knows how to load an Entity and put it in the scene, as well as having functions for playing an animation, but doesn't know anything about the MovementBehavior.

The MovementBehavior knows about movement, perhaps just movement direction and velocity, and also about MeshBehaviors. It can have a property called "MeshToAnimate" which has the name of the MeshBehavior it should animate when the Component moves - it may know how to play a walking forward animation when moving forward, a run animation when moving quickly, turning, strafing, etc.

Let's say MovementBehavior is moved by some external system, such as a CharacterBehavior.

When MovementBehavior has its velocity and direction set, it then decides it needs to send an event to play whatever animation is needed on the MeshBehavior. It can either get a pointer to the MeshBehavior by asking the Component, its container, for the MeshBehavior directly by name, or by sending events. Whether the MovementBehavior calls functions directly on the MeshBehavior or uses events instead doesn't really matter. If it is uses events it'll still need to know what types of events to send, which are going to be specific to the MeshBehavior regardless. In my opinion events are great because they can be queued and processed asynchronously, so I fully intend to use them, but either way the MovementBehavior has a dependency on the MeshBehavior. The nice thing is that MeshBehavior can just be an interface which can be implemented in different ways if needed.

The MovementBehavior needs to still be able to handle the case where a MeshBehavior indicated by the "MeshToAnimate" doesn't exist, but that's fairly simple. As long as it checks for the existence of that Behavior first, and elegantly handles its absence, you'll be to add/swap/replace Behaviors as your development schedule dictates.

This didn't specifically answer your question about Physics components, but did show how Behaviors can have interdependencies.

Attaching something like a Gun to a Ship would mean that there'd be a Component with the name "Ship" (but not a Ship class) with whatever Behaviors a ship needs, and a Component with the name "Gun" with whatever Behaviors a gun needs. My system has the idea of attachment slots, when you attach one Component to another Component it can be attached at a named slot. The Behavior instances assigned to a Component can expose these slots, so when a Component gets attached to a slot on another Component, the Behavior that owns that slot gets notified and can act upon that. For example, the PhysicsBehavior is a collection of bodies, shapes and joints. It might expose a slot called "GunPivot" which is actually a joint, and the gun Component is attached to the "GunPivot" slot on the Ship Component.

Whenever a Component is attached to a slot on the PhysicsBehavior, the behavior may query the Component to find out if it has its own PhysicsBehavior, and if so it can get a list of bodies, shapes and joints that the attached Component has and do something, such as assign the body of the gun to the joint.

It's complex, but powerful.
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

@Game_Ender:

Not sure how I'd tackle this, honestly. What it sounds like to me is adding a GameObject to another GameObject. In fact, I don't see anything wrong with this approach, I would try that route. Easier said than done, but this way you don't start modifying components to own GameObjects and such.

As far as getting components, in my mind, components are able to access each other and use them. I need a more concrete example to come up with a decent solution. Say you wanted to attach a Gun to a ship, and wanted it for whatever reason. I'd probably have to make some property field that all GO's have, lets say a "purpose" field. (string)

// return's a list of GO's with purpose == "weapon"
mOwner->getGameObjects("weapon");

This is just an example, it might not be a great design. Maybe if I had a good reason why I wanted the gun I could create a solution that would work.

@REiNDEeR:

This is not my design, it is A design that I have recently read up on. If you want me to post fully working production code of how the system works in a Game environment, tough luck. I'm trying not to say harsh words, but your responses pretty much ignore everything I've been trying to explain to you. What Game Ender labeled as the key difference is the most important feature of this design, and the reason it is superior. I failed to state it directly.. but here it is again for emphasis:

"The key difference is when you use inheritance you fix the design at compile time. With the aggregation approach you make the Component things you add at runtime."

I believe it's also refered to as a "Data driven design".

I read the components and UML diagram, but I'm not about to dive into the code base and make an app with OGE. (nothing against OGE, I just don't have any time)

@Falagard:

It does sound complex. I'm still debating whether to invest in events or calling directly.. one method is easier, but the other would probably be a great/smart investment. Plus I have code for reference. :) Thanks for sharing your implementation.
Creator of QuickGUI!
User avatar
Falagard
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2060
Joined: Thu Feb 26, 2004 12:11 am
Location: Toronto, Canada
x 3
Contact:

Post by Falagard »

Just to clarify the obvious, there are two ways Behaviors (Components in most other people's terminology - I prefer the name Behavior but they're the same thing) need to communicate between each other - one is to ask a behavior to do something, and the other is when a behavior needs to indicate that something has happened.

You can use events to do both, or you can call directly on the behavior for to get it to do something, and use delegates for the when you want to know something has happened.
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

Well those can be the same thing. If something has happened and you know what needs to be done... but depending on complexity, you might not always know what needs to be done, so it's a good idea to support this. Plus I haven't made it this far in development, so I'll take your word for it. :lol:

Now I need to visualize (in my head) how to do events / messaging. Do you create an Event object which stores every type of information (like void *), or is there a better way? In other words, how to interpret the event type, and then once it is determined to be a relevant event, how to obtain the data? (how do you do it? :twisted: )

I think I'll reread mirlix's code this weekend, I'll probably learn more on the second pass.

[edit]
I just thought of an idea. Make an Event structure that has a <Type>, <GameObjectID> and <ComponentID>, and the receiver should be able to request the appropriate data.. On second thought, this doesn't work. We want to be able to send data itself in the form of messages, right? [/edit]
Creator of QuickGUI!
User avatar
Falagard
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2060
Joined: Thu Feb 26, 2004 12:11 am
Location: Toronto, Canada
x 3
Contact:

Post by Falagard »

Message system basic concept:

Message base class, derive specific message types from it - has a function called getName() which returns unique name for that type of message.

MessageManager where you call subscribe(messageName, delegate) to subscribe to messages that are named messageName. Delegate is a function that takes a message pointer as a parameter. The subscriber will get this function called whenever a message with that name is sent. The subscriber can cast it into a known type of message, such as MoveMessage or whatever, and handle it. MessageManager also has a publish(message) function to publish the messages.

In my case I also have a MessageQueue class which is passed to MessageManager::subscribe to indicate which queue the message should get added to for cross thread messaging, and a MessageSubscriptionList class storing the delegates that are associated with a particular message name.
User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
x 16
Contact:

Post by KungFooMasta »

Awesome, that's not so bad. I'm not currently interested in taking in multi threaded development, but the Message Design seems simple enough. Just create a message class and derive classes from that. They all share an ID field, and all have appropriate data.
Creator of QuickGUI!
Post Reply