Click Here to go to most recent update.
(Sorry for all the source boxes - only way to read it nicely [headshake])
Ok so I've had quite a few ideas recently that just have not worked out. So I decided to start at the point at which they failed - messaging. Now I would like to make an easy way to be able to have all my objects interact with each other. Don't ask me why, I just want to see if this concept is possible. So before I begin, I know a lot of people who see this code are going to have heart attacks - I am 100% aware of safety issues, I just want you to know that. Here's the idea -
I start out with having a generic messaging structure -
struct IMessage
{
std::vector<void*> ptr;
};
I then have my base class that acts as the "Root" of all other classes:
class Actor
{
private:
typedef void (Actor::*ActorPtr)( const IMessage *data );
ActorPtr mActorPtr;
std::map< std::string, Actor::ActorPtr> Functions;
public:
Actor();
~Actor();
virtual void Create( const IMessage *data = 0 );
virtual void Render( const IMessage *data = 0 );
virtual void Destroy( const IMessage *data = 0 );
virtual void Message( std::string message, const IMessage *data = 0);
};
Now some important things to point out. It contains a std::map of function pointers. This is part of the messaging system, as you will see shortly.
Now as for function implemtations, there are two main functions that are the most important -
void Actor::Message( std::string message, const IMessage *data )
{
if( Functions.find( message ) != Functions.end() )
{
(this->*Functions[ message ])( data );
}
else
{
std::cout << std::endl << "Non processed message: " << message << std::endl;
}
}
This function is what receives a message and then calls the appropriate function with the passed data. Next -
Actor::Actor()
{
Functions["Create"] = &Actor::Create;
Functions["Render"] = &Actor::Render;
Functions["Destroy"] = &Actor::Destroy;
}
The ctor, for the time being, registers what function calls are mapped to what string.
Now as for use, it is very simple. The first way in messaging a class, is without data:
Actor A1;
A1.Message("Create");
A1.Message("Render");
A1.Message("Destroy");
To which Actor::Create, Actor::Render, and Actor::Destroy are called.
The second way in messaging a class, is with data:
IMessage tmp;
tmp.ptr.resize( 1, 0 );
tmp.ptr[0] = (void*)("This is a test");
A1.Message("Print", &tmp );
Now as for handling the data sent in, it is up to the class to properly handle it. Once again I am aware of safety issues, but that is not my concern as of now.
Now that was just the Base Actor class, other classes are derived from there and work in a similar way. The basic idea is that any class can interact with any other class
without knowing about it. This means that you can send unit data to your GUI wihtout having to include in the header files for your units and GUI - thus greatly reducing any dependecies.
Here is a sample Main.CPP file:
#include "Actor.h"
Actor *Actor1;
Box B1;
int main( int argc, char* argv[] )
{
Actor1 = &B1;
Actor1->Message( "Create" );
IMessage tmp;
tmp.ptr.resize( 1, 0 );
tmp.ptr[0] = (void*)("File1.bmp");
Actor1->Message( "SetTexture", &tmp );
Actor1->Message( "12345" );
tmp.ptr.resize( 3, 0 );
tmp.ptr[0] = (void*)("5");
tmp.ptr[1] = (void*)("0");
tmp.ptr[2] = (void*)("-8");
Actor1->Message( "SetPosition", &tmp );
tmp.ptr.resize( 3, 0 );
float x = 0.25f, y = 1.0f, z = -0.75f;
tmp.ptr[0] = (void*)(&x);
tmp.ptr[1] = (void*)(&y);
tmp.ptr[2] = (void*)(&z);
Actor1->Message( "SetRotate", &tmp );
Actor1->Message( "Render" );
Actor1->Message( "Destroy" );
return 0;
}
When ran, the output is:
Call to Box::Create
Call to Box::SetTexture
FileName: File1.bmp
Non processed message: 12345
Call to Box::SetPosition
X: 5
Y: 0
Z: -8
Call to Box::SetRotate
X: 0.25
Y: 1
Z: -0.75
Call to Box::Render
Call to Box::Destroy
Press any key to continue
Now idealy, an Object Factory would be used so there would not be an explicit Box variable, but this is just a quick demo.
What are your reactions to this idea? Sound promising or too much hassal (in terms of use, I'm the one programming it [wink]).
Thanks for your time! Unlike my other posts, I will try not to actively defend anything brought up - I will let a few responses be made then reply to them, just so it doesn't grow to such a large size that no one want's to read it (like my last post [lol]) I am open to
ALL comments and suggestions - I want to hear what you developers think.
- Drew
[Edited by - Drew_Benton on March 31, 2005 6:24:59 PM]