khanat-opennel-code/code/nel/src/net/module_manager.cpp

894 lines
27 KiB
C++

// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdnet.h"
#include "nel/misc/app_context.h"
#include "nel/misc/dynloadlib.h"
#include "nel/misc/command.h"
#include "nel/misc/path.h"
#include "nel/misc/twin_map.h"
#include "nel/misc/sstring.h"
#include "nel/misc/smart_ptr_inline.h"
#include "nel/net/module_common.h"
#include "nel/net/module_manager.h"
#include "nel/net/service.h"
#include "nel/net/module_gateway.h"
#include "nel/net/module.h"
#include "nel/net/module_socket.h"
#include "nel/net/net_log.h"
using namespace std;
using namespace NLMISC;
// for init of the module manager (if not already done by the application)
NLMISC_CATEGORISED_COMMAND(net, initModuleManager, "force the initialisation of the module manager", "")
{
nlunreferenced(rawCommandString);
nlunreferenced(args);
nlunreferenced(quiet);
nlunreferenced(human);
// not really hard in fact :)
NLNET::IModuleManager::getInstance();
log.displayNL("Module manager is now initialised.");
return true;
}
namespace NLNET
{
/// Implementation class for module manager
class CModuleManager : public IModuleManager, public ICommandsHandler
{
NLMISC_SAFE_SINGLETON_DECL(CModuleManager);
public:
static void releaseInstance()
{
if (_Instance)
{
NLMISC::INelContext::getInstance().releaseSingletonPointer("CModuleManager", _Instance);
delete _Instance;
_Instance = NULL;
}
}
struct TModuleLibraryInfo : public CRefCount
{
/// The file name of the library with access path
std::string FullPathLibraryName;
/// The short name of the library, i.e not path, no decoration (.dll or .so and NeL compilation mode tag)
std::string ShortLibraryName;
/// The list of module factory name that are in use in the library.
std::vector<std::string> ModuleFactoryList;
/// The library handler
CLibrary LibraryHandler;
/// the NeL Module library interface pointer.
CNelModuleLibrary *ModuleLibrary;
};
/** the user set unique name root, replace the normal unique name
* generation system if not empty
*/
string _UniqueNameRoot;
typedef map<std::string, CSmartPtr<TModuleLibraryInfo> > TModuleLibraryInfos;
/// Module library registry
TModuleLibraryInfos _ModuleLibraryRegistry;
typedef std::map<std::string, IModuleFactory*> TModuleFactoryRegistry;
/// Module factory registry
TModuleFactoryRegistry _ModuleFactoryRegistry;
typedef NLMISC::CTwinMap<std::string, TModulePtr> TModuleInstances;
/// Modules instances tracker
TModuleInstances _ModuleInstances;
typedef NLMISC::CTwinMap<TModuleId, TModulePtr> TModuleIds;
/// Modules IDs tracker
TModuleIds _ModuleIds;
/// Local module ID generator
TModuleId _LastGeneratedId;
typedef NLMISC::CTwinMap<TModuleId, TModuleProxyPtr> TModuleProxyIds;
/// Modules proxy IDs tracker
TModuleProxyIds _ModuleProxyIds;
typedef map<string, IModuleSocket *> TModuleSockets;
/// Module socket registry
TModuleSockets _ModuleSocketsRegistry;
typedef std::map<std::string, IModuleGateway*> TModuleGateways;
/// Module factory registry
TModuleGateways _ModuleGatewaysRegistry;
///////////////////////////////////////////////////////////////////
// Methods
///////////////////////////////////////////////////////////////////
static bool isInitialized()
{
return _Instance != NULL;
}
const std::string &getCommandHandlerName() const
{
static string moduleManagerName("moduleManager");
return moduleManagerName;
}
CModuleManager() :
IModuleManager(),
ICommandsHandler(),
_LastGeneratedId(0)
{
registerCommandsHandler();
// register local module factory
TLocalModuleFactoryRegistry &lmfr = TLocalModuleFactoryRegistry::instance();
addModuleFactoryRegistry(lmfr);
}
~CModuleManager()
{
// unload any loaded module library
while (!_ModuleLibraryRegistry.empty())
{
TModuleLibraryInfo *mli = _ModuleLibraryRegistry.begin()->second;
unloadModuleLibrary(mli->ShortLibraryName);
}
// delete any lasting modules
while (!_ModuleInstances.getAToBMap().empty())
{
deleteModule(_ModuleInstances.getAToBMap().begin()->second);
}
// there should not be proxies or gateway lasting
// nlassert(_ModuleProxyInstances.getAToBMap().empty());
_Instance = NULL;
}
virtual void applicationExit()
{
TModuleInstances::TAToBMap::const_iterator first(_ModuleInstances.getAToBMap().begin()), last(_ModuleInstances.getAToBMap().end());
for (; first != last; ++first)
{
IModule *module = first->second;
module->onApplicationExit();
}
}
virtual void setUniqueNameRoot(const std::string &uniqueNameRoot)
{
_UniqueNameRoot = uniqueNameRoot;
}
virtual const std::string &getUniqueNameRoot()
{
if (_UniqueNameRoot.empty())
{
string hostName;
if (IService::isServiceInitialized())
hostName = IService::getInstance()->getHostName();
else
hostName = ::NLNET::CInetAddress::localHost().hostName();
int pid = ::getpid();
_UniqueNameRoot = hostName+":"+toString(pid);
}
return _UniqueNameRoot;
}
void addModuleFactoryRegistry(TLocalModuleFactoryRegistry &moduleFactoryRegistry)
{
vector<string> moduleList;
moduleFactoryRegistry.fillFactoryList(moduleList);
// fill the module factory registry
vector<string>::iterator first(moduleList.begin()), last(moduleList.end());
for (; first != last; ++first)
{
const std::string &className = *first;
IModuleFactory *factory = moduleFactoryRegistry.getFactory(className);
if (_ModuleFactoryRegistry.find(*first) != _ModuleFactoryRegistry.end())
{
// a module class of that name already exist
nlinfo("CModuleManger : add module factory : module class '%s' is already registered; ignoring new factory @%p",
className.c_str(),
factory);
}
else
{
// store the factory
nlinfo("Adding module '%s' factory", className.c_str());
_ModuleFactoryRegistry.insert(make_pair(className, factory));
}
}
}
virtual bool loadModuleLibrary(const std::string &libraryName)
{
// build the short name
string path = CFile::getPath(libraryName);
string shortName = CLibrary::cleanLibName(libraryName);
if (_ModuleLibraryRegistry.find(shortName) != _ModuleLibraryRegistry.end())
{
// this lib is already loaded !
nlwarning("CModuleManager : trying to load library '%s' in '%s'\n"
"but it is already loaded as '%s', ignoring.",
shortName.c_str(),
libraryName.c_str(),
_ModuleLibraryRegistry[shortName]->FullPathLibraryName.c_str());
return false;
}
// now, load the library
string fullName = NLMISC::CPath::standardizePath(path)+CLibrary::makeLibName(shortName);
std::auto_ptr<TModuleLibraryInfo> mli = auto_ptr<TModuleLibraryInfo>(new TModuleLibraryInfo);
if (!mli->LibraryHandler.loadLibrary(fullName, false, true, true))
{
nlwarning("CModuleManager : failed to load the library '%s' in '%s'",
shortName.c_str(),
fullName.c_str());
return false;
}
// the lib is loaded, check that it is a 'pure' nel library
if (!mli->LibraryHandler.isLibraryPure())
{
nlwarning("CModuleManager : the library '%s' is not a pure Nel library",
shortName.c_str());
return false;
}
// Check that the lib is a pure module library
CNelModuleLibrary *modLib = dynamic_cast<CNelModuleLibrary *>(mli->LibraryHandler.getNelLibraryInterface());
if (modLib == NULL)
{
nlwarning("CModuleManager : the library '%s' is not a pure Nel Module library",
shortName.c_str());
return false;
}
// ok, all is fine ! we can store the loaded library info
mli->FullPathLibraryName = fullName;
TLocalModuleFactoryRegistry &lmfr = modLib->getLocalModuleFactoryRegistry();
lmfr.fillFactoryList(mli->ModuleFactoryList);
mli->ModuleLibrary = modLib;
mli->ShortLibraryName = shortName;
pair<TModuleLibraryInfos::iterator, bool> ret = _ModuleLibraryRegistry.insert(make_pair(shortName, mli.release()));
if (!ret.second)
{
nlwarning("CModuleManager : failed to store module library information !");
return false;
}
// fill the module factory registry
addModuleFactoryRegistry(lmfr);
return true;
}
virtual bool unloadModuleLibrary(const std::string &libraryName)
{
string shorName = CLibrary::cleanLibName(libraryName);
TModuleLibraryInfos::iterator it(_ModuleLibraryRegistry.find(shorName));
if (it == _ModuleLibraryRegistry.end())
{
nlwarning("CModuleManager : failed to unload library '%s' : unknown or not loaded library", shorName.c_str());
return false;
}
// by erasing this entry, we delete the CLibrary object that hold the library
// module, thus destroying any factory the belong into and deleting the
// instantiated module !
// Wow, that's pretty much for a single line ;)
_ModuleLibraryRegistry.erase(it);
return true;
}
/** Register a module factory in the manager
*/
// virtual void registerModuleFactory(class IModuleFactory *moduleFactory)
// {
// nlstop;
// }
/** Unregister a module factory
*/
virtual void unregisterModuleFactory(class IModuleFactory *moduleFactory)
{
// we need to remove the factory from the registry
TModuleFactoryRegistry::iterator it(_ModuleFactoryRegistry.find(moduleFactory->getModuleClassName()));
if (it == _ModuleFactoryRegistry.end())
{
nlwarning("The module factory for class '%s' in not registered.", moduleFactory->getModuleClassName().c_str());
return;
}
else if (it->second != moduleFactory)
{
nlinfo("The module factory @%p for class '%s' is not the registered one, ignoring.",
moduleFactory,
moduleFactory->getModuleClassName().c_str());
return;
}
nlinfo("ModuleManager : unregistering factory for module class '%s'", moduleFactory->getModuleClassName().c_str());
// remove the factory
_ModuleFactoryRegistry.erase(it);
}
/** Fill the vector with the list of available module.
* Note that the vector is not cleared before being filled.
*/
virtual void getAvailableModuleClassList(std::vector<std::string> &moduleClassList)
{
TModuleFactoryRegistry::iterator first(_ModuleFactoryRegistry.begin()), last(_ModuleFactoryRegistry.end());
for (; first != last; ++first)
{
moduleClassList.push_back(first->first);
}
}
/** Create a new module instance.
* The method create a module of the specified class with the
* specified local name.
* The class MUST be available in the factory and the
* name MUST be unique OR empty.
* If the name is empty, the method generate a name using
* the module class and a number.
*/
virtual IModule *createModule(const std::string &className, const std::string &localName, const std::string &paramString)
{
TModuleFactoryRegistry::iterator it(_ModuleFactoryRegistry.find(className));
if (it == _ModuleFactoryRegistry.end())
{
nlwarning("createModule : unknown module class '%s'", className.c_str());
return NULL;
}
string moduleName = localName;
if (moduleName.empty())
{
// we need to generate a name
uint i=0;
do
{
moduleName = className+toString(i++);
} while (_ModuleInstances.getB(moduleName) != NULL);
}
else
{
// check that the module name is unique
if (_ModuleInstances.getB(moduleName) != NULL)
{
nlwarning("createModule : the name '%s' is already used by another module, can't instantiate the module", moduleName.c_str());
return NULL;
}
}
IModuleFactory *mf = it->second;
// sanity check
nlassert(mf->getModuleClassName() == className);
std::auto_ptr<IModule> module = auto_ptr<IModule>(mf->createModule());
if (module.get() == NULL)
{
nlwarning("createModule : factory failed to create a module instance for class '%s'", className.c_str());
return NULL;
}
CModuleBase *modBase = dynamic_cast<CModuleBase*>(module.get());
if (modBase == NULL)
{
nlwarning("Invalid module returned by factory for class '%s'", className.c_str());
return NULL;
}
// init the module basic data
modBase->_ModuleName = moduleName;
modBase->_ModuleId = ++_LastGeneratedId;
// init the module with parameter string
TParsedCommandLine mii;
mii.parseParamList(paramString);
bool initResult = module->initModule(mii);
// store the module in the manager
_ModuleInstances.add(moduleName, module.get());
_ModuleIds.add(modBase->_ModuleId, module.get());
if (initResult)
{
// ok, all is fine, return the module
return module.release();
}
else
{
// error during initialization, delete the module
nlwarning("Create module : the new module '%s' of class '%s' has failed to initilize properly.",\
moduleName.c_str(),
className.c_str());
deleteModule(module.release());
return NULL;
}
}
void deleteModule(IModule *module)
{
nlassert(module != NULL);
// remove module from trackers
nlassert(_ModuleInstances.getA(module) != NULL);
nlassert(_ModuleIds.getA(module) != NULL);
_ModuleInstances.removeWithB(module);
_ModuleIds.removeWithB(module);
// unplug the module if needed
vector<IModuleSocket *> sockets;
module->getPluggedSocketList(sockets);
for (uint i=0; i<sockets.size(); ++i)
{
module->unplugModule(sockets[i]);
}
// ask the factory to delete the module
CModuleBase *modBase = dynamic_cast<CModuleBase *>(module);
nlassert(modBase != NULL);
modBase->getFactory()->deleteModule(module);
}
/** Lookup in the created module for a module having the
* specified local name.
*/
virtual IModule *getLocalModule(const std::string &moduleName)
{
TModuleInstances::TAToBMap::const_iterator it(_ModuleInstances.getAToBMap().find(moduleName));
if (it == _ModuleInstances.getAToBMap().end())
return NULL;
else
return it->second;
}
virtual void updateModules()
{
H_AUTO(CModuleManager_updateModules);
// module are updated in creation order (i.e in module ID order)
TModuleIds::TAToBMap::const_iterator first(_ModuleIds.getAToBMap().begin()), last(_ModuleIds.getAToBMap().end());
for (; first != last; ++first)
{
TModulePtr module = first->second;
CModuleBase *modBase = dynamic_cast<CModuleBase *>(module.getPtr());
if (modBase != NULL)
{
// look for module task to run
while (!modBase->_ModuleTasks.empty())
{
CModuleTask *task = modBase->_ModuleTasks.front();
task->resume();
// check for finished task
if (task->isFinished())
{
LNETL6_DEBUG("NLNETL6: updateModule : task %p is finished, delete and remove from task list", task);
// delete the task and resume the next one if any
delete task;
modBase->_ModuleTasks.erase(modBase->_ModuleTasks.begin());
}
else
{
// no more work for this update
break;
}
}
}
{
H_AUTO(CModuleManager_updateModules_2);
// update the module internal
first->second->onModuleUpdate();
}
}
}
/** Lookup in the created socket for a socket having the
* specified local name.
*/
virtual IModuleSocket *getModuleSocket(const std::string &socketName)
{
TModuleSockets::iterator it(_ModuleSocketsRegistry.find(socketName));
if (it == _ModuleSocketsRegistry.end())
return NULL;
else
return it->second;
}
/** Register a socket in the manager.
*/
virtual void registerModuleSocket(IModuleSocket *moduleSocket)
{
nlassert(moduleSocket != NULL);
TModuleSockets::iterator it(_ModuleSocketsRegistry.find(moduleSocket->getSocketName()));
nlassert(it == _ModuleSocketsRegistry.end());
nldebug("Registering module socket '%s'", moduleSocket->getSocketName().c_str());
_ModuleSocketsRegistry.insert(make_pair(moduleSocket->getSocketName(), moduleSocket));
}
/** Unregister a socket in the manager.
*/
virtual void unregisterModuleSocket(IModuleSocket *moduleSocket)
{
nlassert(moduleSocket != NULL);
TModuleSockets::iterator it(_ModuleSocketsRegistry.find(moduleSocket->getSocketName()));
nlassert(it != _ModuleSocketsRegistry.end());
nldebug("Unregistering module socket '%s'", moduleSocket->getSocketName().c_str());
_ModuleSocketsRegistry.erase(it);
}
/** Lookup in the created gateway for a gateway having the
* specified local name.
*/
virtual IModuleGateway *getModuleGateway(const std::string &gatewayName)
{
TModuleGateways::iterator it(_ModuleGatewaysRegistry.find(gatewayName));
if (it == _ModuleGatewaysRegistry.end())
return NULL;
else
return it->second;
}
/** Register a gateway in the manager.
*/
virtual void registerModuleGateway(IModuleGateway *moduleGateway)
{
nlassert(moduleGateway != NULL);
TModuleGateways::iterator it(_ModuleGatewaysRegistry.find(moduleGateway->getGatewayName()));
nlassert(it == _ModuleGatewaysRegistry.end());
nldebug("Registering module gateway '%s'", moduleGateway->getGatewayName().c_str());
_ModuleGatewaysRegistry.insert(make_pair(moduleGateway->getGatewayName(), moduleGateway));
}
/** Unregister a socket in the manager.
*/
virtual void unregisterModuleGateway(IModuleGateway *moduleGateway)
{
nlassert(moduleGateway != NULL);
TModuleGateways::iterator it(_ModuleGatewaysRegistry.find(moduleGateway->getGatewayName()));
nlassert(it != _ModuleGatewaysRegistry.end());
nldebug("Unregistering module gateway '%s'", moduleGateway->getGatewayName().c_str());
_ModuleGatewaysRegistry.erase(it);
}
/** Get a module proxy with the module ID */
virtual TModuleProxyPtr getModuleProxy(TModuleId moduleProxyId)
{
const TModuleProxyPtr *pproxy = _ModuleProxyIds.getB(moduleProxyId);
if (pproxy == NULL)
return NULL;
else
return *pproxy;
}
/** Called by a module that is begin destroyed.
* This remove module information from the
* the manager
*/
// virtual void onModuleDeleted(IModule *module)
// {
// // not needed ? to remove
// }
virtual IModuleProxy *createModuleProxy(
IModuleGateway *gateway,
CGatewayRoute *route,
uint32 distance,
IModule *localModule,
const std::string &moduleClassName,
const std::string &moduleFullyQualifiedName,
const std::string &moduleManifest,
TModuleId foreignModuleId)
{
std::auto_ptr<CModuleProxy> modProx = auto_ptr<CModuleProxy>(new CModuleProxy(localModule, ++_LastGeneratedId, moduleClassName, moduleFullyQualifiedName, moduleManifest));
modProx->_Gateway = gateway;
modProx->_Route = route;
modProx->_Distance = distance;
modProx->_ForeignModuleId = foreignModuleId;
nldebug("Creating module proxy (ID : %u, foreign ID : %u, name : '%s', class : '%s' at %u hop",
modProx->getModuleProxyId(),
modProx->getForeignModuleId(),
modProx->getModuleName().c_str(),
modProx->getModuleClassName().c_str(),
modProx->_Distance);
// _ModuleProxyInstances.add(moduleFullyQualifiedName, TModuleProxyPtr(modProx.get()));
_ModuleProxyIds.add(modProx->getModuleProxyId(), TModuleProxyPtr(modProx.get()));
return modProx.release();
}
virtual void releaseModuleProxy(TModuleId moduleProxyId)
{
TModuleProxyIds::TAToBMap::const_iterator it(_ModuleProxyIds.getAToBMap().find(moduleProxyId));
nlassert(it != _ModuleProxyIds.getAToBMap().end());
CRefPtr<IModuleProxy> sanityCheck(it->second.getPtr());
nldebug("Releasing module proxy ('%s', ID : %u)",
it->second->getModuleName().c_str(),
moduleProxyId);
// remove the smart ptr, must delete the proxy
// _ModuleProxyInstances.removeWithB(it->second);
_ModuleProxyIds.removeWithB(it->second);
nlassertex(sanityCheck == NULL, ("Someone has kept a smart pointer on the proxy '%s' of class '%s'", sanityCheck->getModuleName().c_str(), sanityCheck->getModuleClassName().c_str()));
}
virtual uint32 getNbModule()
{
return (uint32)_ModuleInstances.getAToBMap().size();
}
virtual uint32 getNbModuleProxy()
{
return (uint32)_ModuleProxyIds.getAToBMap().size();
}
NLMISC_COMMAND_HANDLER_TABLE_BEGIN(CModuleManager)
NLMISC_COMMAND_HANDLER_ADD(CModuleManager, dump, "dump various information about module manager state", "");
NLMISC_COMMAND_HANDLER_ADD(CModuleManager, loadLibrary, "load a pure nel library module (give the path if needed and only the undecorated lib name)", "[path]<undecoratedLibName>");
NLMISC_COMMAND_HANDLER_ADD(CModuleManager, unloadLibrary, "unload a pure nel library module (give the undecorated name, any path will be removed", "<undecoratedLibName>");
NLMISC_COMMAND_HANDLER_ADD(CModuleManager, createModule, "create a new module instance", "<moduleClass> <instanceName> [*<moduleArg>]");
NLMISC_COMMAND_HANDLER_ADD(CModuleManager, deleteModule, "delete a module instance", "<instanceName>");
NLMISC_COMMAND_HANDLER_TABLE_END
NLMISC_CLASS_COMMAND_DECL(deleteModule)
{
nlunreferenced(rawCommandString);
nlunreferenced(quiet);
nlunreferenced(human);
if (args.size() != 1)
return false;
TModulePtr const *module = _ModuleInstances.getB(args[0]);
if (module == NULL)
{
log.displayNL("Unknow module '%s'", args[0].c_str());
return false;
}
nlinfo("Deleting module '%s'", args[0].c_str());
CRefPtr<IModule> sanityCheck(*module);
deleteModule(*module);
if (sanityCheck != NULL)
{
log.displayNL("Failed to delete the module instance !");
return false;
}
return true;
}
NLMISC_CLASS_COMMAND_DECL(unloadLibrary)
{
nlunreferenced(rawCommandString);
nlunreferenced(log);
nlunreferenced(quiet);
nlunreferenced(human);
if (args.size() != 1)
return false;
unloadModuleLibrary(args[0]);
return true;
}
NLMISC_CLASS_COMMAND_DECL(loadLibrary)
{
nlunreferenced(log);
nlunreferenced(quiet);
nlunreferenced(human);
if (args.size() < 1)
return false;
CSString libName = rawCommandString;
// remove the command name
libName.strtok(" \t");
// load the library
return this->loadModuleLibrary(libName);
}
NLMISC_CLASS_COMMAND_DECL(createModule)
{
nlunreferenced(log);
nlunreferenced(quiet);
nlunreferenced(human);
if (args.size() < 2)
return false;
CSString moduleArgs = rawCommandString;
// remove the command name
moduleArgs.strtok(" \t");
// retrieve module class
string moduleClass = moduleArgs.strtok(" \t");
// retrieve module instance name
string moduleName = moduleArgs.strtok(" \t");
nlinfo("Creating module '%s' of class '%s' with params '%s'",
moduleName.c_str(),
moduleClass.c_str(),
moduleArgs.c_str());
// create the module instance
IModule *module = createModule(moduleClass, moduleName, moduleArgs);
return module != NULL;
}
NLMISC_CLASS_COMMAND_DECL(dump)
{
nlunreferenced(rawCommandString);
nlunreferenced(args);
nlunreferenced(quiet);
nlunreferenced(human);
log.displayNL("Dumping CModuleManager internal states :");
{
std::vector<std::string> moduleList;
TLocalModuleFactoryRegistry::instance().fillFactoryList(moduleList);
log.displayNL(" List of %u local modules classes :", moduleList.size());
for (uint i=0; i<moduleList.size(); ++i)
{
if (_ModuleFactoryRegistry.find(moduleList[i]) == _ModuleFactoryRegistry.end())
{
log.displayNL(" %s : UNAVAILABLE !", moduleList[i].c_str());
}
else
{
IModuleFactory *modFact = TLocalModuleFactoryRegistry::instance().getFactory(moduleList[i]);
log.displayNL(" %s : OK\tInit params : '%s'", moduleList[i].c_str(), modFact->getInitStringHelp().c_str());
}
}
}
{
log.displayNL(" List of %u loaded module libraries :", _ModuleLibraryRegistry.size());
TModuleLibraryInfos::iterator first(_ModuleLibraryRegistry.begin()), last(_ModuleLibraryRegistry.end());
for (; first != last; ++first)
{
TModuleLibraryInfo &mli = *(first->second);
log.displayNL(" Library '%s' loaded from '%s', contains %u modules classes:",
first->first.c_str(),
mli.FullPathLibraryName.c_str(),
mli.ModuleFactoryList.size());
{
vector<string>::iterator f2(mli.ModuleFactoryList.begin()), l2(mli.ModuleFactoryList.end());
for (uint i=0; i<mli.ModuleFactoryList.size(); ++i)
{
if (_ModuleFactoryRegistry.find(mli.ModuleFactoryList[i]) == _ModuleFactoryRegistry.end())
{
log.displayNL(" %s : UNAVAILABLE, this class is already registered !", mli.ModuleFactoryList[i].c_str());
}
else
{
log.displayNL(" %s : OK", mli.ModuleFactoryList[i].c_str());
}
}
}
}
}
{
log.displayNL(" List of %u module instances :", _ModuleInstances.getAToBMap().size());
TModuleInstances::TAToBMap::const_iterator first(_ModuleInstances.getAToBMap().begin()), last(_ModuleInstances.getAToBMap().end());
for (; first != last; ++first)
{
IModule *module = first->second;
log.displayNL(" ID:%5u : \tname = '%s' \tclass = '%s'",
module->getModuleId(),
module->getModuleName().c_str(),
module->getModuleClassName().c_str());
}
}
{
log.displayNL(" List of %u module proxies :", _ModuleProxyIds.getAToBMap().size());
TModuleProxyIds::TAToBMap::const_iterator first(_ModuleProxyIds.getAToBMap().begin()), last(_ModuleProxyIds.getAToBMap().end());
for (; first != last; ++first)
{
IModuleProxy *modProx = first->second;
if (modProx->getGatewayRoute() != NULL)
{
log.displayNL(" ID:%5u (Foreign ID : %u) : \tname = '%s' \tclass = '%s'",
modProx->getModuleProxyId(),
modProx->getForeignModuleId(),
modProx->getModuleName().c_str(),
modProx->getModuleClassName().c_str());
}
else
{
log.displayNL(" ID:%5u (Local proxy for module ID : %u) : \tname = '%s' \tclass = '%s'",
modProx->getModuleProxyId(),
modProx->getForeignModuleId(),
modProx->getModuleName().c_str(),
modProx->getModuleClassName().c_str());
}
}
}
return true;
}
};
bool IModuleManager::isInitialized()
{
return CModuleManager::isInitialized();
}
IModuleManager &IModuleManager::getInstance()
{
return CModuleManager::getInstance();
}
void IModuleManager::releaseInstance()
{
CModuleManager::releaseInstance();
}
NLMISC_SAFE_SINGLETON_IMPL(CModuleManager);
extern void forceGatewayLink();
extern void forceLocalGatewayLink();
extern void forceGatewayTransportLink();
extern void forceGatewayL5TransportLink();
void forceLink()
{
forceGatewayLink();
forceLocalGatewayLink();
forceGatewayTransportLink();
forceGatewayL5TransportLink();
}
} // namespace NLNET