Archived

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

a2k

Why Aren't Pluggable Factories Rocking My Multiplayer World?

Recommended Posts

a2k    124
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

Share this post


Link to post
Share on other sites
Dire.Wolf    122
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

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
///===== 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

Share this post


Link to post
Share on other sites
a2k    124
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

Share this post


Link to post
Share on other sites
a2k    124
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

Share this post


Link to post
Share on other sites
Dire.Wolf    122
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

Share this post


Link to post
Share on other sites
a2k    124
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

Share this post


Link to post
Share on other sites