Update of /cvsroot/pclasses/pclasses2/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7519/src
Added Files:
Factory.cpp
Log Message:
- Rewrite of Factory<>. The new Factory eliminates the problem that client-
and library code use different Factory instances. We address this problem
by introducing a non-templated base class for the Factory template.
--- NEW FILE: Factory.cpp ---
/***************************************************************************
* Copyright (C) 2005 by Christian Prochnow, SecuLogiX GmbH *
* cp...@se... *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "pclasses/Trace.h"
#include "pclasses/Factory.h"
namespace P {
/*
The FactoryInstanceMap holds the instances of our Factory objects.
*/
class FactoryInstanceMap {
public:
typedef std::pair<std::string, std::string> InstanceKey;
typedef std::map<InstanceKey, FactoryBase*> FactoryMap;
static FactoryInstanceMap& instance()
{
static FactoryInstanceMap inst;
return inst;
}
void addFactory(const std::string& ifaceType,
const std::string& contextType, FactoryBase* fac)
{
P_TRACE(FactoryInstanceMap) << "FactoryBase added for ifaceType="
<< ifaceType << ", contextType=" << contextType;
_factories[std::make_pair(ifaceType,contextType)] = fac;
}
FactoryBase* findFactory(const std::string& ifaceType,
const std::string& contextType)
{
FactoryMap::const_iterator i =
_factories.find(std::make_pair(ifaceType,contextType));
return i != _factories.end() ? i->second : 0;
}
private:
FactoryInstanceMap() {}
~FactoryInstanceMap() {}
FactoryMap _factories;
};
typedef std::list<FactoryBase::LoaderFunc> FactoryLoaderList;
FactoryLoaderList FactoryLoaders;
FactoryBase::FactoryBase()
{
}
FactoryBase::~FactoryBase()
{
}
void FactoryBase::loadType(const std::string& ifaceType,
const std::string& contextType, const std::string& key)
{
P_TRACE_GLOBAL() << "FactoryBase::loadType() running loaders for ifaceType=" << ifaceType
<< ", contextType=" << contextType << ", key=" << key;
FactoryLoaderList::const_iterator i = FactoryLoaders.begin();
while(i != FactoryLoaders.end())
{
(*i)(ifaceType, contextType, key);
++i;
}
}
void FactoryBase::registerLoader(LoaderFunc lf)
{
FactoryLoaders.push_back(lf);
}
FactoryBase& FactoryBase::instance(const std::string& ifaceType,
const std::string& contextType, FactoryCreateFunc createFunc)
{
FactoryInstanceMap& instMap = FactoryInstanceMap::instance();
FactoryBase* ret = instMap.findFactory(ifaceType, contextType);
if(!ret)
{
ret = createFunc();
instMap.addFactory(ifaceType, contextType, ret);
}
return *ret;
}
} // !namespace P
|