Archived

This topic is now archived and is closed to further replies.

dathui

Sending between objects?

Recommended Posts

I have a desigproblem. I have a couple of objects that should be able to send data between themselves, but without actual pointers to eachother. I''m thinking of some kind of package-system where you stuff your data in a package, push in an adress and then just leave it for the packagehandler to make sure it lands at the right object. this would mean that each object got an unique ID...anybody else got any suggestions?

Share this post


Link to post
Share on other sites
You'd want to use pointers, because sending lots of bytes between classes is very uneffective. I don't know what you are using this for though, but that is the general approach.

Maybe something like this:
struct data_s
{
...
};

{
class1 aClass;
class2 anotherClass;

aClass.getPackage( anotherClass.getPackageAdress() );
}
Where getPackageAdress would point to a data_s which has been filled with appropriate data, and getPackage would use the adress passed as a parameter to read the data needed.

_______________ ____ ___ __ _
www.chromeCode.com

[edited by - Enselic on January 5, 2004 3:51:22 PM]

Share this post


Link to post
Share on other sites
my first idea was to use functionpointers with a streamclass.
A a;
B b;
Stream s;
s.setOutputStream(b.out);
s.setInputStream(a.in);

now a and b would be able to walk thru eachother thru s.out(char*), sent to b.ou, and s.in(char*), send to a.in.
But that crashed when i looked a bit more into function pointers, you have to specify what class the function is inside :/

so i''m looking for a similar solution but possibly without function pointers.

Share this post


Link to post
Share on other sites
You''d have to use function pointers of some sort if you want a generic messaging system like you are describing.

I use Boost.Function for this genericity.

I''m also considering writing an article about how I do messaging.

Share this post


Link to post
Share on other sites
you could also try somthing like the following.

create a concept of an information package in your game. information packages would all be derived from some base class, and they would all be stored in a central place (perhaps a global singelton named something like InformationPackageManager). Each time a unit wants to share information with other units it would create an information package and somehow broadcast a notice to (either all nearby units, or a specific unit, or whatever) the notice contains just the package ID with which the information can be retrieved from the InformationPackageManager. you can add expiration dates on the information so you don't end up with information package overload at the end of the game. if a unit tries to retrieve an invalidated package the function just returns and error and the unit just continues as if that information wasn't present. you can build in intelligence to the information expiration such that if only one unit knows this info, and it dies, then the info gets expired instantly.

For the Info packages themselves, perhaps have a single enumerated type or something similar loaded from a text file where you define each number to mean a specific thing like: "enemy close to my position", "need backup", "man down", whatever. perhaps the info packet would need one other field like an int or a pointer or whatever.

thus, you could do something like:


union AnyType {
int *ival;
float *fval;
double *dval;
char *sval;
};

class InfoPackage {
MessageType msgType;
AnyType data;
};


at any given moment in your AI update loop, units can call something like:


InfoID newInfoID = InformationPackageManager->addInformation(msgType, data);

UnitsList receiveUnits = someFunctionToGetTargetUnits();

for (int i = 0; i < receiveUnits.size(); ++i)
receiveUnits[i]->sendInfo(newInfoID);


so basically you just send out alerts to specific units that there is new data they should look at and you just pass them an info id. if they choose to look at the data, are able to hear you, whatever, they can just look up the data from the infomation warehouse and alter their behavior based on that info. you end up with only one instance of each piece of information and a quick and low data traffic way to pass information around. the only trick is in getting rid of that data when it's no longer needed so you don't get memory bloat.

then again, i have no idea what your specific problem is, so let me know if that helps at all and perhaps i can add some more brainstorming...

-me

[edited by - Palidine on January 5, 2004 5:24:59 PM]

Share this post


Link to post
Share on other sites
What I did was create a SuperClass to all my subclasses with a function called Event(int, DWORD, DWORD, void*). That int is an enum''ed event (enum EVENT_TYPE{EVENT_TOUCHED, EVENT_KILLED,...} the two DWORDs are the ID''s of the sender and receiver, and the void* is a void* to a parameter that can be used (for instance in EVENT_DAMAGED, it contains an int that is the amount of damage to deal). Of course, you have to know what the parameter''s going to be, so in your Event function you can cast it to the proper type. Then I have a global function (you could also encapsulate this) called SendEvent, that takes all of those parameters and then sends off the event to the sender/receiver.

Share this post


Link to post
Share on other sites
quote:
Original post by Palidine
then again, i have no idea what your specific problem is, so let me know if that helps at all and perhaps i can add some more brainstorming...

-me

[edited by - Palidine on January 5, 2004 5:24:59 PM]


a bit more brainstorming would be very appreciated

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I just used a message singleton and each class would have a copy of the same msg handler. The classes/objects would then register with the msg handler in their initialisation giving it a uniqie ID. The Msg handler then created a queue for each registered class to hold its messages.

It was up to the classes to check for mail in by calling the msngr handler, which just returned the message at the front of the queue.

In addition to the queue, each class could register a function/callback to be called by the msgr for really important messages, sort of like an interrupt. So normal priority messages would be placed in the queue to be checked at leasiure, while others such as QUIT etc. were initiated automatically.

Don''t know if it''s a good way to do it or not but it worked quite well for our game.

Share this post


Link to post
Share on other sites
quote:
Original post by antareus
I am in the middle of writing an article for GD on this subject actually. Look for it shortly.


woa...goodies''r''us

will look for it

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
I just used a message singleton and each class would have a copy of the same msg handler. The classes/objects would then register with the msg handler in their initialisation giving it a uniqie ID. The Msg handler then created a queue for each registered class to hold its messages.

It was up to the classes to check for mail in by calling the msngr handler, which just returned the message at the front of the queue.

In addition to the queue, each class could register a function/callback to be called by the msgr for really important messages, sort of like an interrupt. So normal priority messages would be placed in the queue to be checked at leasiure, while others such as QUIT etc. were initiated automatically.

Don''t know if it''s a good way to do it or not but it worked quite well for our game.


i had a similar design in mind...thou i was worried about how fast it would be, but i''ll look into it as it worked well for you. thanks

Share this post


Link to post
Share on other sites