Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / nel / src / net / module_manager.cpp
blob20c947d034e325f0015c9bb1d5c79dd970de2916
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "stdnet.h"
19 #include "nel/misc/app_context.h"
20 #include "nel/misc/dynloadlib.h"
21 #include "nel/misc/command.h"
22 #include "nel/misc/path.h"
23 #include "nel/misc/twin_map.h"
24 #include "nel/misc/sstring.h"
25 #include "nel/misc/smart_ptr_inline.h"
27 #include "nel/net/module_common.h"
28 #include "nel/net/module_manager.h"
29 #include "nel/net/service.h"
30 #include "nel/net/module_gateway.h"
31 #include "nel/net/module.h"
32 #include "nel/net/module_socket.h"
33 #include "nel/net/net_log.h"
36 using namespace std;
37 using namespace NLMISC;
39 // for init of the module manager (if not already done by the application)
40 NLMISC_CATEGORISED_COMMAND(net, initModuleManager, "force the initialisation of the module manager", "")
42 nlunreferenced(rawCommandString);
43 nlunreferenced(args);
44 nlunreferenced(quiet);
45 nlunreferenced(human);
47 // not really hard in fact :)
48 NLNET::IModuleManager::getInstance();
50 log.displayNL("Module manager is now initialised.");
52 return true;
56 namespace NLNET
58 /// Implementation class for module manager
59 class CModuleManager : public IModuleManager, public ICommandsHandler
61 NLMISC_SAFE_SINGLETON_DECL(CModuleManager);
63 public:
65 static void releaseInstance()
67 if (_Instance)
69 NLMISC::INelContext::getInstance().releaseSingletonPointer("CModuleManager", _Instance);
70 delete _Instance;
71 _Instance = NULL;
75 struct TModuleLibraryInfo : public CRefCount
77 /// The file name of the library with access path
78 std::string FullPathLibraryName;
79 /// The short name of the library, i.e not path, no decoration (.dll or .so and NeL compilation mode tag)
80 std::string ShortLibraryName;
81 /// The list of module factory name that are in use in the library.
82 std::vector<std::string> ModuleFactoryList;
83 /// The library handler
84 CLibrary LibraryHandler;
85 /// the NeL Module library interface pointer.
86 CNelModuleLibrary *ModuleLibrary;
89 /** the user set unique name root, replace the normal unique name
90 * generation system if not empty
92 string _UniqueNameRoot;
94 typedef map<std::string, CSmartPtr<TModuleLibraryInfo> > TModuleLibraryInfos;
95 /// Module library registry
96 TModuleLibraryInfos _ModuleLibraryRegistry;
98 typedef std::map<std::string, IModuleFactory*> TModuleFactoryRegistry;
99 /// Module factory registry
100 TModuleFactoryRegistry _ModuleFactoryRegistry;
102 typedef NLMISC::CTwinMap<std::string, TModulePtr> TModuleInstances;
103 /// Modules instances tracker
104 TModuleInstances _ModuleInstances;
106 typedef NLMISC::CTwinMap<TModuleId, TModulePtr> TModuleIds;
107 /// Modules IDs tracker
108 TModuleIds _ModuleIds;
110 /// Local module ID generator
111 TModuleId _LastGeneratedId;
113 typedef NLMISC::CTwinMap<TModuleId, TModuleProxyPtr> TModuleProxyIds;
114 /// Modules proxy IDs tracker
115 TModuleProxyIds _ModuleProxyIds;
117 typedef map<string, IModuleSocket *> TModuleSockets;
118 /// Module socket registry
119 TModuleSockets _ModuleSocketsRegistry;
121 typedef std::map<std::string, IModuleGateway*> TModuleGateways;
122 /// Module factory registry
123 TModuleGateways _ModuleGatewaysRegistry;
125 ///////////////////////////////////////////////////////////////////
126 // Methods
127 ///////////////////////////////////////////////////////////////////
129 static bool isInitialized()
131 return _Instance != NULL;
134 const std::string &getCommandHandlerName() const
136 static string moduleManagerName("moduleManager");
137 return moduleManagerName;
141 CModuleManager() :
142 IModuleManager(),
143 ICommandsHandler(),
144 _LastGeneratedId(0)
146 registerCommandsHandler();
148 // register local module factory
149 TLocalModuleFactoryRegistry &lmfr = TLocalModuleFactoryRegistry::instance();
150 addModuleFactoryRegistry(lmfr);
153 ~CModuleManager()
155 // unload any loaded module library
156 while (!_ModuleLibraryRegistry.empty())
158 TModuleLibraryInfo *mli = _ModuleLibraryRegistry.begin()->second;
159 unloadModuleLibrary(mli->ShortLibraryName);
162 // delete any lasting modules
163 while (!_ModuleInstances.getAToBMap().empty())
165 deleteModule(_ModuleInstances.getAToBMap().begin()->second);
168 // there should not be proxies or gateway lasting
169 // nlassert(_ModuleProxyInstances.getAToBMap().empty());
171 _Instance = NULL;
174 virtual void applicationExit()
176 TModuleInstances::TAToBMap::const_iterator first(_ModuleInstances.getAToBMap().begin()), last(_ModuleInstances.getAToBMap().end());
177 for (; first != last; ++first)
179 IModule *module = first->second;
181 module->onApplicationExit();
185 virtual void setUniqueNameRoot(const std::string &uniqueNameRoot)
187 _UniqueNameRoot = uniqueNameRoot;
190 virtual const std::string &getUniqueNameRoot()
192 if (_UniqueNameRoot.empty())
194 string hostName;
195 if (IService::isServiceInitialized())
196 hostName = IService::getInstance()->getHostName();
197 else
198 hostName = ::NLNET::CInetAddress::localHost().hostName();
199 int pid = ::getpid();
201 _UniqueNameRoot = hostName+":"+toString(pid);
204 return _UniqueNameRoot;
208 void addModuleFactoryRegistry(TLocalModuleFactoryRegistry &moduleFactoryRegistry)
210 vector<string> moduleList;
211 moduleFactoryRegistry.fillFactoryList(moduleList);
212 // fill the module factory registry
213 vector<string>::iterator first(moduleList.begin()), last(moduleList.end());
214 for (; first != last; ++first)
216 const std::string &className = *first;
217 IModuleFactory *factory = moduleFactoryRegistry.getFactory(className);
218 if (_ModuleFactoryRegistry.find(*first) != _ModuleFactoryRegistry.end())
220 // a module class of that name already exist
221 nlinfo("CModuleManger : add module factory : module class '%s' is already registered; ignoring new factory @%p",
222 className.c_str(),
223 factory);
225 else
227 // store the factory
228 nlinfo("Adding module '%s' factory", className.c_str());
229 _ModuleFactoryRegistry.insert(make_pair(className, factory));
234 virtual bool loadModuleLibrary(const std::string &libraryName)
236 // build the short name
237 string path = CFile::getPath(libraryName);
238 string shortName = CLibrary::cleanLibName(libraryName);
240 if (_ModuleLibraryRegistry.find(shortName) != _ModuleLibraryRegistry.end())
242 // this lib is already loaded !
243 nlwarning("CModuleManager : trying to load library '%s' in '%s'\n"
244 "but it is already loaded as '%s', ignoring.",
245 shortName.c_str(),
246 libraryName.c_str(),
247 _ModuleLibraryRegistry[shortName]->FullPathLibraryName.c_str());
248 return false;
251 // now, load the library
252 string fullName = NLMISC::CPath::standardizePath(path)+CLibrary::makeLibName(shortName);
253 CUniquePtr<TModuleLibraryInfo> mli(new TModuleLibraryInfo);
254 if (!mli->LibraryHandler.loadLibrary(fullName, false, true, true))
256 nlwarning("CModuleManager : failed to load the library '%s' in '%s'",
257 shortName.c_str(),
258 fullName.c_str());
259 return false;
261 // the lib is loaded, check that it is a 'pure' nel library
262 if (!mli->LibraryHandler.isLibraryPure())
264 nlwarning("CModuleManager : the library '%s' is not a pure Nel library",
265 shortName.c_str());
266 return false;
268 // Check that the lib is a pure module library
269 CNelModuleLibrary *modLib = dynamic_cast<CNelModuleLibrary *>(mli->LibraryHandler.getNelLibraryInterface());
270 if (modLib == NULL)
272 nlwarning("CModuleManager : the library '%s' is not a pure Nel Module library",
273 shortName.c_str());
274 return false;
277 // ok, all is fine ! we can store the loaded library info
279 mli->FullPathLibraryName = fullName;
280 TLocalModuleFactoryRegistry &lmfr = modLib->getLocalModuleFactoryRegistry();
281 lmfr.fillFactoryList(mli->ModuleFactoryList);
282 mli->ModuleLibrary = modLib;
283 mli->ShortLibraryName = shortName;
285 pair<TModuleLibraryInfos::iterator, bool> ret = _ModuleLibraryRegistry.insert(make_pair(shortName, mli.release()));
286 if (!ret.second)
288 nlwarning("CModuleManager : failed to store module library information !");
289 return false;
292 // fill the module factory registry
293 addModuleFactoryRegistry(lmfr);
295 return true;
298 virtual bool unloadModuleLibrary(const std::string &libraryName)
300 string shorName = CLibrary::cleanLibName(libraryName);
301 TModuleLibraryInfos::iterator it(_ModuleLibraryRegistry.find(shorName));
302 if (it == _ModuleLibraryRegistry.end())
304 nlwarning("CModuleManager : failed to unload library '%s' : unknown or not loaded library", shorName.c_str());
305 return false;
308 // by erasing this entry, we delete the CLibrary object that hold the library
309 // module, thus destroying any factory the belong into and deleting the
310 // instantiated module !
311 // Wow, that's pretty much for a single line ;)
312 _ModuleLibraryRegistry.erase(it);
314 return true;
317 /** Register a module factory in the manager
319 // virtual void registerModuleFactory(class IModuleFactory *moduleFactory)
320 // {
321 // nlstop;
322 // }
323 /** Unregister a module factory
325 virtual void unregisterModuleFactory(class IModuleFactory *moduleFactory)
327 // we need to remove the factory from the registry
328 TModuleFactoryRegistry::iterator it(_ModuleFactoryRegistry.find(moduleFactory->getModuleClassName()));
330 if (it == _ModuleFactoryRegistry.end())
332 nlwarning("The module factory for class '%s' in not registered.", moduleFactory->getModuleClassName().c_str());
333 return;
335 else if (it->second != moduleFactory)
337 nlinfo("The module factory @%p for class '%s' is not the registered one, ignoring.",
338 moduleFactory,
339 moduleFactory->getModuleClassName().c_str());
340 return;
343 nlinfo("ModuleManager : unregistering factory for module class '%s'", moduleFactory->getModuleClassName().c_str());
345 // remove the factory
346 _ModuleFactoryRegistry.erase(it);
350 /** Fill the vector with the list of available module.
351 * Note that the vector is not cleared before being filled.
353 virtual void getAvailableModuleClassList(std::vector<std::string> &moduleClassList)
355 TModuleFactoryRegistry::iterator first(_ModuleFactoryRegistry.begin()), last(_ModuleFactoryRegistry.end());
356 for (; first != last; ++first)
358 moduleClassList.push_back(first->first);
362 /** Create a new module instance.
363 * The method create a module of the specified class with the
364 * specified local name.
365 * The class MUST be available in the factory and the
366 * name MUST be unique OR empty.
367 * If the name is empty, the method generate a name using
368 * the module class and a number.
370 virtual IModule *createModule(const std::string &className, const std::string &localName, const std::string &paramString)
372 TModuleFactoryRegistry::iterator it(_ModuleFactoryRegistry.find(className));
373 if (it == _ModuleFactoryRegistry.end())
375 nlwarning("createModule : unknown module class '%s'", className.c_str());
376 return NULL;
379 string moduleName = localName;
380 if (moduleName.empty())
382 // we need to generate a name
383 uint i=0;
386 moduleName = className+toString(i++);
387 } while (_ModuleInstances.getB(moduleName) != NULL);
389 else
391 // check that the module name is unique
392 if (_ModuleInstances.getB(moduleName) != NULL)
394 nlwarning("createModule : the name '%s' is already used by another module, can't instantiate the module", moduleName.c_str());
395 return NULL;
399 IModuleFactory *mf = it->second;
400 // sanity check
401 nlassert(mf->getModuleClassName() == className);
402 CUniquePtr<IModule> module(mf->createModule());
403 if (module.get() == NULL)
405 nlwarning("createModule : factory failed to create a module instance for class '%s'", className.c_str());
407 return NULL;
410 CModuleBase *modBase = dynamic_cast<CModuleBase*>(module.get());
411 if (modBase == NULL)
413 nlwarning("Invalid module returned by factory for class '%s'", className.c_str());
414 return NULL;
417 // init the module basic data
418 modBase->_ModuleName = moduleName;
419 modBase->_ModuleId = ++_LastGeneratedId;
421 // init the module with parameter string
422 TParsedCommandLine mii;
423 mii.parseParamList(paramString);
424 bool initResult = module->initModule(mii);
426 // store the module in the manager
427 _ModuleInstances.add(moduleName, module.get());
428 _ModuleIds.add(modBase->_ModuleId, module.get());
430 if (initResult)
432 // ok, all is fine, return the module
433 return module.release();
435 else
437 // error during initialization, delete the module
438 nlwarning("Create module : the new module '%s' of class '%s' has failed to initilize properly.",\
439 moduleName.c_str(),
440 className.c_str());
442 deleteModule(module.release());
443 return NULL;
447 void deleteModule(IModule *module)
449 nlassert(module != NULL);
451 // remove module from trackers
452 nlassert(_ModuleInstances.getA(module) != NULL);
453 nlassert(_ModuleIds.getA(module) != NULL);
455 _ModuleInstances.removeWithB(module);
456 _ModuleIds.removeWithB(module);
458 // unplug the module if needed
459 vector<IModuleSocket *> sockets;
460 module->getPluggedSocketList(sockets);
461 for (uint i=0; i<sockets.size(); ++i)
463 module->unplugModule(sockets[i]);
466 // ask the factory to delete the module
467 CModuleBase *modBase = dynamic_cast<CModuleBase *>(module);
468 nlassert(modBase != NULL);
469 modBase->getFactory()->deleteModule(module);
472 /** Lookup in the created module for a module having the
473 * specified local name.
475 virtual IModule *getLocalModule(const std::string &moduleName)
477 TModuleInstances::TAToBMap::const_iterator it(_ModuleInstances.getAToBMap().find(moduleName));
479 if (it == _ModuleInstances.getAToBMap().end())
480 return NULL;
481 else
482 return it->second;
485 virtual void updateModules()
487 H_AUTO(CModuleManager_updateModules);
488 // module are updated in creation order (i.e in module ID order)
489 TModuleIds::TAToBMap::const_iterator first(_ModuleIds.getAToBMap().begin()), last(_ModuleIds.getAToBMap().end());
490 for (; first != last; ++first)
492 TModulePtr module = first->second;
494 CModuleBase *modBase = dynamic_cast<CModuleBase *>(module.getPtr());
495 if (modBase != NULL)
497 // look for module task to run
498 while (!modBase->_ModuleTasks.empty())
500 CModuleTask *task = modBase->_ModuleTasks.front();
501 task->resume();
502 // check for finished task
503 if (task->isFinished())
505 LNETL6_DEBUG("NLNETL6: updateModule : task %p is finished, delete and remove from task list", task);
506 // delete the task and resume the next one if any
507 delete task;
508 modBase->_ModuleTasks.erase(modBase->_ModuleTasks.begin());
510 else
512 // no more work for this update
513 break;
519 H_AUTO(CModuleManager_updateModules_2);
520 // update the module internal
521 first->second->onModuleUpdate();
526 /** Lookup in the created socket for a socket having the
527 * specified local name.
529 virtual IModuleSocket *getModuleSocket(const std::string &socketName)
531 TModuleSockets::iterator it(_ModuleSocketsRegistry.find(socketName));
532 if (it == _ModuleSocketsRegistry.end())
533 return NULL;
534 else
535 return it->second;
537 /** Register a socket in the manager.
539 virtual void registerModuleSocket(IModuleSocket *moduleSocket)
541 nlassert(moduleSocket != NULL);
542 TModuleSockets::iterator it(_ModuleSocketsRegistry.find(moduleSocket->getSocketName()));
543 nlassert(it == _ModuleSocketsRegistry.end());
545 nldebug("Registering module socket '%s'", moduleSocket->getSocketName().c_str());
546 _ModuleSocketsRegistry.insert(make_pair(moduleSocket->getSocketName(), moduleSocket));
548 /** Unregister a socket in the manager.
550 virtual void unregisterModuleSocket(IModuleSocket *moduleSocket)
552 nlassert(moduleSocket != NULL);
553 TModuleSockets::iterator it(_ModuleSocketsRegistry.find(moduleSocket->getSocketName()));
554 nlassert(it != _ModuleSocketsRegistry.end());
556 nldebug("Unregistering module socket '%s'", moduleSocket->getSocketName().c_str());
558 _ModuleSocketsRegistry.erase(it);
561 /** Lookup in the created gateway for a gateway having the
562 * specified local name.
564 virtual IModuleGateway *getModuleGateway(const std::string &gatewayName)
566 TModuleGateways::iterator it(_ModuleGatewaysRegistry.find(gatewayName));
567 if (it == _ModuleGatewaysRegistry.end())
568 return NULL;
569 else
570 return it->second;
572 /** Register a gateway in the manager.
574 virtual void registerModuleGateway(IModuleGateway *moduleGateway)
576 nlassert(moduleGateway != NULL);
577 TModuleGateways::iterator it(_ModuleGatewaysRegistry.find(moduleGateway->getGatewayName()));
578 nlassert(it == _ModuleGatewaysRegistry.end());
580 nldebug("Registering module gateway '%s'", moduleGateway->getGatewayName().c_str());
581 _ModuleGatewaysRegistry.insert(make_pair(moduleGateway->getGatewayName(), moduleGateway));
583 /** Unregister a socket in the manager.
585 virtual void unregisterModuleGateway(IModuleGateway *moduleGateway)
587 nlassert(moduleGateway != NULL);
588 TModuleGateways::iterator it(_ModuleGatewaysRegistry.find(moduleGateway->getGatewayName()));
589 nlassert(it != _ModuleGatewaysRegistry.end());
591 nldebug("Unregistering module gateway '%s'", moduleGateway->getGatewayName().c_str());
593 _ModuleGatewaysRegistry.erase(it);
596 /** Get a module proxy with the module ID */
597 virtual TModuleProxyPtr getModuleProxy(TModuleId moduleProxyId)
599 const TModuleProxyPtr *pproxy = _ModuleProxyIds.getB(moduleProxyId);
601 if (pproxy == NULL)
602 return NULL;
603 else
604 return *pproxy;
607 /** Called by a module that is begin destroyed.
608 * This remove module information from the
609 * the manager
611 // virtual void onModuleDeleted(IModule *module)
612 // {
613 // // not needed ? to remove
614 // }
616 virtual IModuleProxy *createModuleProxy(
617 IModuleGateway *gateway,
618 CGatewayRoute *route,
619 uint32 distance,
620 IModule *localModule,
621 const std::string &moduleClassName,
622 const std::string &moduleFullyQualifiedName,
623 const std::string &moduleManifest,
624 TModuleId foreignModuleId)
626 CUniquePtr<CModuleProxy> modProx(new CModuleProxy(localModule, ++_LastGeneratedId, moduleClassName, moduleFullyQualifiedName, moduleManifest));
627 modProx->_Gateway = gateway;
628 modProx->_Route = route;
629 modProx->_Distance = distance;
630 modProx->_ForeignModuleId = foreignModuleId;
632 nldebug("Creating module proxy (ID : %u, foreign ID : %u, name : '%s', class : '%s' at %u hop",
633 modProx->getModuleProxyId(),
634 modProx->getForeignModuleId(),
635 modProx->getModuleName().c_str(),
636 modProx->getModuleClassName().c_str(),
637 modProx->_Distance);
639 // _ModuleProxyInstances.add(moduleFullyQualifiedName, TModuleProxyPtr(modProx.get()));
640 _ModuleProxyIds.add(modProx->getModuleProxyId(), TModuleProxyPtr(modProx.get()));
642 return modProx.release();
645 virtual void releaseModuleProxy(TModuleId moduleProxyId)
647 TModuleProxyIds::TAToBMap::const_iterator it(_ModuleProxyIds.getAToBMap().find(moduleProxyId));
648 nlassert(it != _ModuleProxyIds.getAToBMap().end());
649 CRefPtr<IModuleProxy> sanityCheck(it->second.getPtr());
651 nldebug("Releasing module proxy ('%s', ID : %u)",
652 it->second->getModuleName().c_str(),
653 moduleProxyId);
655 // remove the smart ptr, must delete the proxy
656 // _ModuleProxyInstances.removeWithB(it->second);
657 _ModuleProxyIds.removeWithB(it->second);
659 nlassertex(sanityCheck == NULL, ("Someone has kept a smart pointer on the proxy '%s' of class '%s'", sanityCheck->getModuleName().c_str(), sanityCheck->getModuleClassName().c_str()));
662 virtual uint32 getNbModule()
664 return (uint32)_ModuleInstances.getAToBMap().size();
667 virtual uint32 getNbModuleProxy()
669 return (uint32)_ModuleProxyIds.getAToBMap().size();
674 NLMISC_COMMAND_HANDLER_TABLE_BEGIN(CModuleManager)
675 NLMISC_COMMAND_HANDLER_ADD(CModuleManager, dump, "dump various information about module manager state", "");
676 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>");
677 NLMISC_COMMAND_HANDLER_ADD(CModuleManager, unloadLibrary, "unload a pure nel library module (give the undecorated name, any path will be removed", "<undecoratedLibName>");
678 NLMISC_COMMAND_HANDLER_ADD(CModuleManager, createModule, "create a new module instance", "<moduleClass> <instanceName> [*<moduleArg>]");
679 NLMISC_COMMAND_HANDLER_ADD(CModuleManager, deleteModule, "delete a module instance", "<instanceName>");
680 NLMISC_COMMAND_HANDLER_TABLE_END
682 NLMISC_CLASS_COMMAND_DECL(deleteModule)
684 nlunreferenced(rawCommandString);
685 nlunreferenced(quiet);
686 nlunreferenced(human);
688 if (args.size() != 1)
689 return false;
691 TModulePtr const *module = _ModuleInstances.getB(args[0]);
692 if (module == NULL)
694 log.displayNL("Unknow module '%s'", args[0].c_str());
695 return false;
698 nlinfo("Deleting module '%s'", args[0].c_str());
700 CRefPtr<IModule> sanityCheck(*module);
701 deleteModule(*module);
702 if (sanityCheck != NULL)
704 log.displayNL("Failed to delete the module instance !");
705 return false;
707 return true;
710 NLMISC_CLASS_COMMAND_DECL(unloadLibrary)
712 nlunreferenced(rawCommandString);
713 nlunreferenced(log);
714 nlunreferenced(quiet);
715 nlunreferenced(human);
717 if (args.size() != 1)
718 return false;
720 unloadModuleLibrary(args[0]);
722 return true;
725 NLMISC_CLASS_COMMAND_DECL(loadLibrary)
727 nlunreferenced(log);
728 nlunreferenced(quiet);
729 nlunreferenced(human);
731 if (args.size() < 1)
732 return false;
734 CSString libName = rawCommandString;
735 // remove the command name
736 libName.strtok(" \t");
738 // load the library
739 return this->loadModuleLibrary(libName);
742 NLMISC_CLASS_COMMAND_DECL(createModule)
744 nlunreferenced(log);
745 nlunreferenced(quiet);
746 nlunreferenced(human);
748 if (args.size() < 2)
749 return false;
751 CSString moduleArgs = rawCommandString;
752 // remove the command name
753 moduleArgs.strtok(" \t");
754 // retrieve module class
755 string moduleClass = moduleArgs.strtok(" \t");
756 // retrieve module instance name
757 string moduleName = moduleArgs.strtok(" \t");
759 nlinfo("Creating module '%s' of class '%s' with params '%s'",
760 moduleName.c_str(),
761 moduleClass.c_str(),
762 moduleArgs.c_str());
763 // create the module instance
764 IModule *module = createModule(moduleClass, moduleName, moduleArgs);
766 return module != NULL;
769 NLMISC_CLASS_COMMAND_DECL(dump)
771 nlunreferenced(rawCommandString);
772 nlunreferenced(args);
773 nlunreferenced(quiet);
774 nlunreferenced(human);
776 log.displayNL("Dumping CModuleManager internal states :");
778 std::vector<std::string> moduleList;
779 TLocalModuleFactoryRegistry::instance().fillFactoryList(moduleList);
780 log.displayNL(" List of %u local modules classes :", moduleList.size());
781 for (uint i=0; i<moduleList.size(); ++i)
783 if (_ModuleFactoryRegistry.find(moduleList[i]) == _ModuleFactoryRegistry.end())
785 log.displayNL(" %s : UNAVAILABLE !", moduleList[i].c_str());
787 else
789 IModuleFactory *modFact = TLocalModuleFactoryRegistry::instance().getFactory(moduleList[i]);
790 log.displayNL(" %s : OK\tInit params : '%s'", moduleList[i].c_str(), modFact->getInitStringHelp().c_str());
795 log.displayNL(" List of %u loaded module libraries :", _ModuleLibraryRegistry.size());
796 TModuleLibraryInfos::iterator first(_ModuleLibraryRegistry.begin()), last(_ModuleLibraryRegistry.end());
797 for (; first != last; ++first)
799 TModuleLibraryInfo &mli = *(first->second);
800 log.displayNL(" Library '%s' loaded from '%s', contains %u modules classes:",
801 first->first.c_str(),
802 mli.FullPathLibraryName.c_str(),
803 mli.ModuleFactoryList.size());
805 vector<string>::iterator f2(mli.ModuleFactoryList.begin()), l2(mli.ModuleFactoryList.end());
806 for (uint i=0; i<mli.ModuleFactoryList.size(); ++i)
808 if (_ModuleFactoryRegistry.find(mli.ModuleFactoryList[i]) == _ModuleFactoryRegistry.end())
810 log.displayNL(" %s : UNAVAILABLE, this class is already registered !", mli.ModuleFactoryList[i].c_str());
812 else
814 log.displayNL(" %s : OK", mli.ModuleFactoryList[i].c_str());
821 log.displayNL(" List of %u module instances :", _ModuleInstances.getAToBMap().size());
822 TModuleInstances::TAToBMap::const_iterator first(_ModuleInstances.getAToBMap().begin()), last(_ModuleInstances.getAToBMap().end());
823 for (; first != last; ++first)
825 IModule *module = first->second;
826 log.displayNL(" ID:%5u : \tname = '%s' \tclass = '%s'",
827 module->getModuleId(),
828 module->getModuleName().c_str(),
829 module->getModuleClassName().c_str());
833 log.displayNL(" List of %u module proxies :", _ModuleProxyIds.getAToBMap().size());
834 TModuleProxyIds::TAToBMap::const_iterator first(_ModuleProxyIds.getAToBMap().begin()), last(_ModuleProxyIds.getAToBMap().end());
835 for (; first != last; ++first)
837 IModuleProxy *modProx = first->second;
838 if (modProx->getGatewayRoute() != NULL)
840 log.displayNL(" ID:%5u (Foreign ID : %u) : \tname = '%s' \tclass = '%s'",
841 modProx->getModuleProxyId(),
842 modProx->getForeignModuleId(),
843 modProx->getModuleName().c_str(),
844 modProx->getModuleClassName().c_str());
846 else
848 log.displayNL(" ID:%5u (Local proxy for module ID : %u) : \tname = '%s' \tclass = '%s'",
849 modProx->getModuleProxyId(),
850 modProx->getForeignModuleId(),
851 modProx->getModuleName().c_str(),
852 modProx->getModuleClassName().c_str());
856 return true;
861 bool IModuleManager::isInitialized()
863 return CModuleManager::isInitialized();
866 IModuleManager &IModuleManager::getInstance()
868 return CModuleManager::getInstance();
871 void IModuleManager::releaseInstance()
873 CModuleManager::releaseInstance();
876 NLMISC_SAFE_SINGLETON_IMPL(CModuleManager);
879 extern void forceGatewayLink();
880 extern void forceLocalGatewayLink();
881 extern void forceGatewayTransportLink();
882 extern void forceGatewayL5TransportLink();
885 void forceLink()
887 forceGatewayLink();
888 forceLocalGatewayLink();
889 forceGatewayTransportLink();
890 forceGatewayL5TransportLink();
893 } // namespace NLNET