🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Why Aren't Pluggable Factories Rocking My Multiplayer World?

Started by
6 comments, last by a2k 22 years, 8 months ago
i understand how the concept works, but it''s a bitch to get it implemented. well, specifically, i''m having trouble with registering the maker class into the maker map. the static map doesn''t seem to be working for me. right now, i have a protected static makerMap in the net_message_maker class, but my constructMessage member function (implemented in a separate source file) has trouble linking with this static makerMap. I''m stumped. It should see its own class member variables, right? so, anyone who''s read Mason McCuskey''s article, or successfully used Adrian Perez''s code, i''d like some light shed on the subject. Thanks very much. a2k
------------------General Equation, this is Private Function reporting for duty, sir!a2k
Advertisement
Well you don''t have to read anything from them to be able to help you seeing as they didn''t invent the technique (John Vlissides came up with it.)

Anyhow, are you trying to say that you are having a problem linking your code?

Maybe if you posted some source code and the exact error message it would be easier to help you.

Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
///===== this is in my header

class NET_MESSAGE_MAKER; //forward decl

typedef map netMessageMakerMap;


class NET_MESSAGE_MAKER
{
public:
NET_MESSAGE_MAKER(unsigned long int type)
{
//registry.insert(std::make_pair(type, this));
registry.insert(netMessageMakerMap::value_type(type, this));
}
~NET_MESSAGE_MAKER(){}

static NET_MESSAGE *constructMessage( uchar *data, int datasize);

protected:
static netMessageMakerMap registry;
virtual NET_MESSAGE *makeMessage( uchar *data, int datasize) const = 0;

};

//============= this is one of the derivative classes in
//============= the source file, specifically for login
//============= request message maker, where NM_LOGIN_REQUEST
//============= is defined in another header.

class cNM_LoginRequestMaker : public NET_MESSAGE_MAKER
{
private:
NET_MESSAGE *makeMessage( uchar *data, int datasize) const
{
NET_MESSAGE *msg = NULL;
try
{
msg = new NM_LOGIN_REQUEST;
msg->serializeFrom(data, datasize);
}
catch (...)
{
delete msg;
throw;
}
return msg;
}
static const cNM_LoginRequestMaker registerthis;
//automatically forces constructor of NET_MESSAGE_MAKER
//to insert into the map (supposedly)
public:
cNM_LoginRequestMaker() : NET_MESSAGE_MAKER(1) {}

};


//==== this is in the same source file, the implementation
//==== of constructmessage

NET_MESSAGE *NET_MESSAGE_MAKER::constructMessage( uchar *data, int datasize )
{
//first character is the message id;
uchar msgID = *data;


// find the appropriate factory in the map of factories...
//aa: this registry seems to not like being used as protected, though it should work
//NET_MESSAGE_MAKER *maker = (*registry.find(msgID)).second;
NET_MESSAGE_MAKER *maker = (*registry.find(msgID)).second;
if( !maker )
return NULL;


// use that factory to construct the net_message derivative
return maker->makeMessage( data, datasize );

}

//and the error is an unresolved external for the protected static map

however, looking through adrian perez''s code, i see he used:

netMessageMakerMap NET_MESSAGE_MAKER::registry = netMessageMakerMap();

before defining any of the derivative classes, which would i assume instantiates the registry to a new netMessageMakerMap.

now, if i did that, it would compile and link, but when i step through the constructMessage function and it attempts to find a messagemaker in the map of message makers, the pointer becomes null (or 0xcdcdcdcd in debug), which indicates to me that the static registry was not initialized (inserted) properly.

any more specifics, i''ll be glad to add, but this should start people off...

a2k
last one was me, obviously

oh, and also, the typedef map is actually:

typedef map (lessthan) unsigned long int, NET_MESSAGE_MAKER * (greater than) netMessageMakerMap;



Edited by - a2k on October 14, 2001 4:36:04 PM

Edited by - a2k on October 14, 2001 4:36:54 PM
------------------General Equation, this is Private Function reporting for duty, sir!a2k
okay, i''ve found some new stuff out... static members gotta be initialized somewheres, which clears up the whole registry thing, but now, i have the other static member (the one that registers the derived classes) and i''m not sure where to initialize this one. i think it''s just this static instantiation/initialization that is preventing this thing from working. can someone throw me a frickin bone please?

a2k
------------------General Equation, this is Private Function reporting for duty, sir!a2k
woohoo! got it! thanks everyone for helping!!!!! =D
------------------General Equation, this is Private Function reporting for duty, sir!a2k
One thing you need to be careful with is that static initialization does not have a guaranteed order between translation units (source files).

So if you declare a static in file A and one in file B, there is no guarantee that file A''s static will get initialized first.

Glad you figured it out though.

Dire
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
that''s okay, the way i got it is, i have one source file that instantiates the registry, and then calls all the define makers in this source file, and that''s it, so whenever i want to add a new message, i just throw it in here, and it references the right static registry. so, all static member variables are instantiated all in the same source file.

a2k
------------------General Equation, this is Private Function reporting for duty, sir!a2k

This topic is closed to new replies.

Advertisement