class NetPlayer : public NetworkObject
{
void Pack(...);
void UnPack(...);
}
So I do not want to register each class by hand somewhere, but I will need a unique identifier for each class to be able to de-serialize the object. Note: I'm counting on having to cheat a little by making NetworkObject a macro so there by (secretly) adding some code to the derived class. Does anyone have any ideas on how to do this?
Automatically generate unique ID's at compile time
I'm designing my networking system, and I'm looking for a way to do the following:
[size="1"]Daedalus Development | E-Mail me
I am writing a medium size network game and just had the same problem. I just took an unsigned int at 0 and kept incrementing it for every connection received. My server is never likely to receive 4294967295 connections before a restart so I figured that it would work.
I won an award at my office for the worst abuse of a compiler preprocessor command ever. I needed unique IDs for events being sent within the game system. What I ended up doing is wrapping a call to the __LINE__ preprocessor macro and using that. In your case it becomes a problem - I only needed a unique number within one compiled application - with your system you need a unique number across two or more executables which may be running different versions - it's possible ( probable ) the line numbers will change as you change your code, but maybe you can using a table that has a list in them, but you might as well use an enum table then.
^^^^^^^
that was me
that was me
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)
http://www.silvermace.com/ -- My personal website
http://www.silvermace.com/ -- My personal website
grrrr - ok the login thing doesn't happen anymore (growl!) sorry...
#dth-0
#dth-0
"C and C++ programmers seem to think that the shortest distance between two points is the great circle route on a spherical distortion of Euclidean space."Stephen Dewhurst
Thank you all for the answers. I especially liked the one about the __LINE__ directive.
Just to clarify something which I think some people misunderstood.
I'd like to give each class a unique id. This id has to be given a value at compile time, since it has to be the same over different computers (servers as well as clients). So the random number generator and such are unusable.
Just to clarify something which I think some people misunderstood.
I'd like to give each class a unique id. This id has to be given a value at compile time, since it has to be the same over different computers (servers as well as clients). So the random number generator and such are unusable.
[size="1"]Daedalus Development | E-Mail me
Quote:
Original post by Sphet
I won an award at my office for the worst abuse of a compiler preprocessor command ever.
<offtopic>
ROFL! I don't know why I found that so funny, but I just sprayed cola over my monitor...
</offtopic>
EDIT:
If you have a macro, then you can change the constructor of the object to make a call to some function that will create a hash of the classname.
For example:
//------------ Main header file #define DECLARE_SERIALIZABLE(classname) int classname::s_nID = 0;#define CONSTRUCT_SERIALIZABLE(classname) if(s_nID == 0) {s_nID = Hash(#classname)}#define IMPLEMENT_SERIALIZABLE private: static int s_nID;int Hash(const char* szName);//------------ Header file class NetPlayer : public NetworkObject{ IMPLEMENT_SERIALIZABLE;public: NetPlayer(); void Pack(...); void UnPack(...);}//------------ Source file DECLARE_SERIALIZABLE(NetworkObject);NetPlayer::NetPlayer(){ CONSTRUCT_SERIALIZABLE(NetworkObject);}
3 macros is probably overkill, but theres bound to be another way to do it in 1 or 2 macros.
The Hash() function generates a hash of the classname(E.g. using MD5), to get a unique ID for the class. You check if you need to generate an ID, by seeing if the ID is currently 0. That should lower the overhead.
Thank you Evil Steve. This is seems to be more what I'm looking for. I'll take a look at it this evening, and see what I can come up with.
[size="1"]Daedalus Development | E-Mail me
Hashing is what you are looking for. I can come up with two methods. Use uses "clean" C++, but requires RTTI (slow). The other uses a preprocessor directives to basically do the same. Note that both aren't compatible.
For both, you still need a GenerateHash() function. I'm using the following wich has a very good speed/spread rate:
#include <typeinfo.h>class NetPlayer : public NetworkObject<NetPlayer> { //...}template <class T>class NetPlayer {public: int GetID() { static int id = GenerateHash(typeid(T).raw_name()); return id; }}
#define NET_CLASS_START(decl) decl { public: int GetID() { static int id = GenerateHash(#decl); return id; }#define NET_CLASS_END };NET_CLASS_START(class NetPlater: public NetworkObject) //...NET_CLASS_END
For both, you still need a GenerateHash() function. I'm using the following wich has a very good speed/spread rate:
unsigned long GenerateHash(register const char* string) { register unsigned long hash = 0; do hash = hash * 33 + *string; while(*(++string)!='\0'); hash = hash + (hash>>5); return hash;}
Something else I just recognized: I somehow have to register each network class at a central point. And I cannot see how I can do that without adding this class somewhere else in the program in a list or something.
So assuming I have to register each class at a central point, the central point can of course easily hand out ID's. The way I'm thinking of this now is just a function with register all the classes. Of course the order of registering is the same on all machines, so the ID's will be correctly the same.
Is there a way to register classes within the own class file?
So assuming I have to register each class at a central point, the central point can of course easily hand out ID's. The way I'm thinking of this now is just a function with register all the classes. Of course the order of registering is the same on all machines, so the ID's will be correctly the same.
Is there a way to register classes within the own class file?
[size="1"]Daedalus Development | E-Mail me
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement