Thank you Bruce for this hint.
I also looked into the jucer sources to find out if there is a kind of factory.
What I found was a handler for each component:
Component* createNewComponent (JucerDocument*)
{
return new TextButton (T("new button"), String::empty);
}
I have to dig a bit deeper to find out if and how the jucer finds a handler by name.
For those, who are interested, what I have so far (WIP), it’s a functor based factory template:
This defines a factory for juce components:
This are the typedefs for creator functors:
typedef CreatorTemplate< TextEditor > TextEditorCreator;
typedef CreatorTemplate< WebBrowserComponent > WebBrowserComponentCreator;
typedef CreatorTemplate< ValueTreeView > ValueTreeViewCreator;
With this call you can register a functor:
component_factory.registerCreator( new TextEditorCreator,T("TextEditor") );
component_factory.registerCreator( new WebBrowserComponentCreator, T("WebBrowserComponent") );
component_factory.registerCreator( new ValueTreeViewCreator, T("ValueTreeView") );
and later use this call to create a component based on info from a ValueTree
(thanks Jules for the ValueTree class)
[code]Component* GuiSystem::createComponent( const ValueTree& node )
{
Component* comp = NULL;
if( node.hasType(“Panel”) ) // a gui node item
{
String type = node.getProperty ( String(T(“Type”) ));
String name = node.getProperty ( String(T(“Name”) ));
comp = component_factory.createObject(type);
initializeComponent( comp, node );
}
return comp;
}
[/code]
Here comes the code for the factory:
[code]class Functor
{
public:
virtual void* create(void) const
{
return 0;
}
virtual void* operator()(void)
{
return 0;
//cout << typeid(T).name() <<endl;
}
};
template
class CreatorTemplate : public Functor
{
public:
virtual T* create(void)const
{
return new T;
}
virtual T* operator()(void) // covariant return type
{
return new T;
//cout << typeid(T).name() <<endl;
}
};
//typedef CreatorTemplate< Functor > FunctorCreator;
typedef std::vector<const Functor*> FunctorArray;
/**
This factory creates objects by calling a create functor
For each class you have to provide an external functor which can create an instance of that class
typename T is the type of object you want to create, eg a juce::Component
*/
template
class CreatorFactory
{
public:
/*
CreatorFactory()
{
void* result = test_functor();
}
*/
size_t registerCreator( Functor* functor, String type)
{
size_t idx = functors.size();
const Functor* existing_functor = getFunctor(type);
if( existing_functor == NULL) // not yet registered
{
typenames.add(type);
functors.push_back(functor);
}
return idx;
}
const Functor* getFunctor( const String& name) const
{
const Functor* functor = NULL;
for( size_t i=0;i<typenames.size();i++)
{
if( typenames[i] == name )
{
functor = functors[i];
break;
}
}
return functor;
}
size_t getTypeID( const String& name) const
{
size_t type_id = (size_t)-1;
for( size_t i=0;i<typenames.size();i++)
{
if( typenames[i] == name )
{
type_id = i;
break;
}
}
return type_id;
}
T* createObject( const String& name)
{
T* object = NULL;
const Functor* functor = getFunctor(name);
if( functor )
{
object = (T*)functor->create();
}
else
{
std::cout << "Factory Couldn't create a " << name.toUTF8() << std::endl;
}
return object;
}
/**
Builds a list with the names of all available functors
*/
size_t getTypeNames( StringArray& names ) const
{
for( size_t i=0;i<typenames.size();i++)
{
const String& name = typenames[i];
names.add(name);
}
return names.size();
}
Functor test_functor;
StringArray typenames;
FunctorArray functors;
};
[/code]