Jump to content
  • Advertisement
Sign in to follow this  
Lord Maz

Pluggable factories

This topic is 4865 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Found this pattern here that looks like the perfect solution for one of my problems, but while trying to implement it I ran into some snags... All the problems relate to the static object in net_message_createplayerorgroup_maker. First of all; it doesn't do its job correctly - it never calls anything for me. Well, I tried to remedy it by declaring the object (even though having to do this for each type would render the pattern useless) but that made the system crash; I think it has to do with the fact that I'm working with PalmOS and it doesn't like when bits & pieces of code gets called before (in the static initialization) the other initialization code. So, now for my question: Is there any other way to generate objects of the right type automatically (meaning: without having to do any changes to the factory or other upper systems)? I've also checked out the reflective factory pattern, but I couldn't even get that one to compile and using so much preprocessor magic doesn't seem kosher either.

Share this post


Link to post
Share on other sites
Advertisement
As you've guessed the problem is an order of initialization issue I've been bitten by it myself in the past and the reason quite often is that all the clients register themself and then the constructor for the static registry is run afterwards oh the joy...

That is:
1: clients plug them self in
2: registry get created (whoops... that means that all the clients just saw their registrations go bollocks)

The solution is quite simple, put the static member inside a function to ensure proper creation order.

Share this post


Link to post
Share on other sites
Well.. hrm. Wouldn't I need to call some function then for each new factory I create? The whole idea of the pattern is to get rid of these kinds of needs - I want my new objects to be truely plugin-able, like the article described.

Share this post


Link to post
Share on other sites
Quote:
Original post by Lord Maz
Well.. hrm. Wouldn't I need to call some function then for each new factory I create? The whole idea of the pattern is to get rid of these kinds of needs - I want my new objects to be truely plugin-able, like the article described.


urm, no you just wrap variable access with a function, there's surly a static member buried somewhere localise it, put it (as a static variable) into a static function in the same class with a reasonble name substitute all accesses from the old name to the newly created function, recompile, et voila should work.

Share this post


Link to post
Share on other sites
Something like this:


class CFactory
{
public:

static CFactory& Instance()
{
static CFactory;

return Factory;
}
};


This will create the factory on the first call to register from a client.

Share this post


Link to post
Share on other sites
I'm not sure type of functionality you are looking for but here's a quick description of the factory I implemented some time back....


The factory is implemented as a template and is based around families of classes. The premis is that the factory only creates a specific collection of objects that are all derived from the same root. the basic declaration is as follows:

template<typename _BASE>
class AbstractFactory {

class ExemplarBase {
public:
virtual int GetID() { return 0;/* ... id stuff here ...*/ }

virtual _BASE *Create() = 0;
};

public:

template<typename _CLASS> class Exemplar : public ExemplarBase {
public:
Exemplar(AbstractFactory<_BASE> &parent, int classID) {
parent.Register(this, classID);
}
_BASE *Create() {
return new _CLASS;
}
};

bool Register(ExemplarBase *src, int classID) {
//... add 'src' to the list of exemplars
return true;
}

template<typename _CLASS> _CLASS *Create(int classID) {
// ... find exemplar ...
ExemplarBase *ex = Find(classID);

return dynamic_cast<_CLASS*>(ex->Create());
}
};

class BaseClass { public: virtual ~BaseClass() {} };
class Child1 : public BaseClass {};
class Child2 : public BaseClass {};
class Child3 : public BaseClass {};

AbstractFactory<BaseClass> myFactory;
AbstractFactory<BaseClass>::Exemplar<Child1> child1ex(myFactory, 1);
AbstractFactory<BaseClass>::Exemplar<Child2> child2ex(myFactory, 2);
AbstractFactory<BaseClass>::Exemplar<Child3> child3ex(myFactory, 3);

void test() {

Child3 *c = myFactory.Create<Child3>(3);
// the next call fails on the dynamic_cast
Child3 *c = myFactory.Create<Child3>(1);
};



Some key points:


1. With the implementation using templates you have the option of creating as many factories for as many families of classes as possible.

2. The use of the exemplar eliminates the need for any hard coding within the factory itself. It also eliminates the need for creating static methods in the classes for instantiation (or similar methods).

3. the Create() method automatically handles dynamic casting to the requested type.


This isn't complete but it should give you a good idea of alternative implementations.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!