IModule* ModuleManager::load( const std::string& moduleName ) { SystemState systemState = getSystem()->getState(); if( systemState < SystemState_Initializing ) throw IllegalStateException( "cannot load modules before the system is set up" ); if( systemState > SystemState_Running ) throw IllegalStateException( "cannot load modules while the system is being torn down" ); if( _loaders.empty() ) throw ModuleLoadException( "there are no installed module loaders" ); // check if the module was already loaded IModule* alreadyLoaded = findModule( moduleName ); if( alreadyLoaded ) return alreadyLoaded; /* Load and initialize ModuleParts. Notice that once we initialize a part, it may register a new ModulePartLoader that must also be considered. */ // the IModule is created on demand Module* module = NULL; // for error handling: whether a part was being loaded (true) or initialized (false) bool wasLoading = true; try { size_t numLoaders = _loaders.size(); for( size_t i = 0; i < numLoaders; ++i ) { IModulePartLoader* loader = _loaders[i].get(); if( !loader->canLoadModulePart( moduleName ) ) continue; // load the module part wasLoading = true; RefPtr<IModulePart> part( loader->loadModulePart( moduleName ) ); if( !part.isValid() ) throw ModuleLoadException( "loader returned a null IModulePart" ); if( !module ) module = createModule( moduleName ); module->addPart( part.get() ); // initialize the module part wasLoading = false; part->initialize( module ); // this module part may have added a new IModulePartLoader size_t newNumLoaders = _loaders.size(); assert( newNumLoaders >= numLoaders ); numLoaders = newNumLoaders; } } catch( std::exception& e ) { // any error while loading or initializing a part aborts the whole module if( module ) module->abort(); std::stringstream ss; if( wasLoading ) ss << "error loading module '" << moduleName << "': "; else ss << "exception raised by module '" << moduleName << "' during initialization: "; ss << e.what(); throw ModuleLoadException( ss.str() ); } if( !module ) { CORAL_THROW( ModuleLoadException, "no module loader recognized '" << moduleName << "' as a module (perhaps it was not compiled in " CORAL_BUILD_MODE " mode?)" ); } module->initialize(); syncModuleWithSystemState( module ); return module; }