From: Christian P. <cp...@us...> - 2005-05-06 15:16:14
|
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 |