00001 #include "ComponentLoader.hpp"
00002 #include <rtt/TaskContext.hpp>
00003 #include <rtt/Logger.hpp>
00004 #include <boost/filesystem.hpp>
00005 #include <boost/version.hpp>
00006 #include <rtt/os/StartStopManager.hpp>
00007 #include <rtt/plugin/PluginLoader.hpp>
00008 #include <rtt/types/TypekitRepository.hpp>
00009
00010 #ifdef HAS_ROSLIB
00011 #include <rospack/rospack.h>
00012 #endif
00013
00014 #ifndef _WIN32
00015 # include <dlfcn.h>
00016 #endif
00017
00018 #include <vector>
00019 #include <set>
00020
00021 using namespace RTT;
00022 using namespace RTT::detail;
00023 using namespace std;
00024 using namespace boost::filesystem;
00025
00026 namespace RTT
00027 {
00028
00029
00030 FactoryMap* ComponentFactories::Factories = 0;
00031 }
00032
00033
00034 #ifdef __APPLE__
00035 static const std::string SO_EXT(".dylib");
00036 static const std::string SO_POSTFIX("");
00037 #else
00038 # ifdef _WIN32
00039 static const std::string SO_EXT(".dll");
00040 # ifdef _DEBUG
00041 static const std::string SO_POSTFIX("d");
00042 # else
00043 static const std::string SO_POSTFIX("");
00044 # endif // _DEBUG
00045 # else
00046 static const std::string SO_EXT(".so");
00047 static const std::string SO_POSTFIX("");
00048 # endif
00049 #endif
00050
00051
00052 static const std::string FULL_COMPONENT_SUFFIX(string("-") + string(OROCOS_TARGET_NAME) + SO_POSTFIX + SO_EXT);
00053
00054
00055 # ifdef _WIN32
00056 static const std::string delimiters(";");
00057 static const char default_delimiter(';');
00058 # else
00059 static const std::string delimiters(":;");
00060 static const char default_delimiter(':');
00061 # endif
00062
00063
00064 #ifndef RTT_UNUSED
00065 #ifdef __GNUC__
00066 #define RTT_UNUSED __attribute__((unused))
00067 #else
00068 #define RTT_UNUSED
00069 #endif
00070 #endif
00071
00080 static RTT_UNUSED bool isExtensionVersion(const std::string& ext)
00081 {
00082 bool isExtensionVersion = false;
00083
00084 if (!ext.empty() && ('.' == ext[0]))
00085 {
00086 std::istringstream iss;
00087 int i;
00088
00089 iss.str(ext.substr((size_t)1));
00090 iss >> std::dec >> std::noskipws >> i;
00091 isExtensionVersion = !iss.fail() && iss.eof();
00092 }
00093
00094 return isExtensionVersion;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 static bool isLoadableLibrary(const path& filename)
00119 {
00120 bool isLoadable = false;
00121
00122 #if defined(__APPLE__)
00123 std::string ext;
00124 #if BOOST_VERSION >= 104600
00125 ext = filename.extension().string();
00126 #else
00127 ext = filename.extension();
00128 #endif
00129
00130 if (0 == ext.compare(SO_EXT))
00131 {
00132
00133
00134
00135 path name = filename.stem();
00136 path ext = name.extension();
00137 isLoadable =
00138
00139 !name.empty() &&
00140
00141 (ext.empty() || !isExtensionVersion(ext.string()));
00142 }
00143
00144
00145 #else
00146
00147
00148
00149 isLoadable =
00150 (filename.extension() == SO_EXT) &&
00151 !filename.stem().empty();
00152 #endif
00153
00154 return isLoadable;
00155 }
00156
00157 namespace {
00158
00159
00160 static vector<string> splitPaths(string const& str)
00161 {
00162 vector<string> paths;
00163
00164
00165 string::size_type lastPos = str.find_first_not_of(delimiters, 0);
00166
00167 string::size_type pos = str.find_first_of(delimiters, lastPos);
00168
00169 while (string::npos != pos || string::npos != lastPos)
00170 {
00171
00172 if ( !str.substr(lastPos, pos - lastPos).empty() )
00173 paths.push_back(str.substr(lastPos, pos - lastPos));
00174
00175 lastPos = str.find_first_not_of(delimiters, pos);
00176
00177 pos = str.find_first_of(delimiters, lastPos);
00178 }
00179 if ( paths.empty() )
00180 paths.push_back(".");
00181 return paths;
00182 }
00183
00184 static void removeDuplicates(string& path_list)
00185 {
00186 vector<string> paths;
00187 set<string> seen;
00188 string result;
00189
00190
00191 paths = splitPaths( path_list );
00192
00193
00194 for(vector<string>::const_iterator it = paths.begin(); it != paths.end(); ++it)
00195 {
00196 if (seen.count(*it))
00197 continue;
00198 else
00199 seen.insert(*it);
00200
00201 result = result + *it + default_delimiter;
00202 }
00203
00204
00205 if (result.size() > 0 && result.at(result.size() - 1) == default_delimiter)
00206 result = result.substr(0, result.size() - 1);
00207
00208 path_list.swap(result);
00209 }
00210
00217 static string makeShortFilename(string const& str) {
00218 string ret = str;
00219 if (str.substr(0,3) == "lib")
00220 ret = str.substr(3);
00221 if (ret.rfind(FULL_COMPONENT_SUFFIX) != string::npos)
00222 ret = ret.substr(0, ret.rfind(FULL_COMPONENT_SUFFIX) );
00223 return ret;
00224 }
00225
00226 }
00227
00228 static RTT_UNUSED bool hasEnding(string const &fullString, string const &ending)
00229 {
00230 if (fullString.length() > ending.length()) {
00231 return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
00232 } else {
00233 return false;
00234 }
00235 }
00236
00237 namespace RTT {
00238 extern char const* default_comp_path_build;
00239 }
00240
00241 namespace {
00245 int loadComponents()
00246 {
00247 std::string default_comp_path = ::default_comp_path_build;
00248
00249 char* paths = getenv("RTT_COMPONENT_PATH");
00250 string component_paths;
00251 if (paths) {
00252 component_paths = paths;
00253
00254 if ( !default_comp_path.empty() )
00255 component_paths = component_paths + default_delimiter + default_comp_path;
00256 removeDuplicates( component_paths );
00257 log(Info) <<"RTT_COMPONENT_PATH was set to: " << paths << " . Searching in: "<< component_paths<< endlog();
00258 } else {
00259 component_paths = default_comp_path;
00260 removeDuplicates( component_paths );
00261 log(Info) <<"No RTT_COMPONENT_PATH set. Using default: " << component_paths <<endlog();
00262 }
00263
00264 ComponentLoader::Instance()->setComponentPath(component_paths);
00265 return 0;
00266 }
00267
00268 os::InitFunction component_loader( &loadComponents );
00269
00270 void unloadComponents()
00271 {
00272 ComponentLoader::Release();
00273 }
00274
00275 os::CleanupFunction component_unloader( &unloadComponents );
00276 }
00277
00278 static boost::shared_ptr<ComponentLoader> instance2;
00279
00280 boost::shared_ptr<ComponentLoader> ComponentLoader::Instance() {
00281 if (!instance2)
00282 instance2.reset( new ComponentLoader() );
00283 return instance2;
00284 }
00285
00286 void ComponentLoader::Release() {
00287 instance2.reset();
00288 }
00289
00290
00291
00292 bool ComponentLoader::import( std::string const& path_list )
00293 {
00294 if (path_list.empty() ) {
00295 log(Error) << "import paths: No paths were given for loading ( path_list = '' )."<<endlog();
00296 return false;
00297 }
00298
00299
00300 vector<string> paths;
00301 paths = splitPaths( path_list );
00302
00303 bool all_good = true, found = false;
00304
00305 for (vector<string>::iterator it = paths.begin(); it != paths.end(); ++it)
00306 {
00307
00308 path p = path(*it);
00309 if (is_directory(p))
00310 {
00311 log(Info) << "Importing directory " << p.string() << " ..."<<endlog();
00312 for (directory_iterator itr(p); itr != directory_iterator(); ++itr)
00313 {
00314 log(Debug) << "Scanning file " << itr->path().string() << " ...";
00315 if (is_regular_file(itr->status()) && isLoadableLibrary(itr->path()) ) {
00316 found = true;
00317 std::string libname;
00318 #if BOOST_VERSION >= 104600
00319 libname = itr->path().filename().string();
00320 #else
00321 libname = itr->path().filename();
00322 #endif
00323 if(!isCompatibleComponent(libname))
00324 {
00325 log(Debug) << "not a compatible component: ignored."<<endlog();
00326 }
00327 else
00328 {
00329 found = true;
00330 all_good = loadInProcess( itr->path().string(), makeShortFilename(libname ), true) && all_good;
00331 }
00332 } else {
00333 if (!is_regular_file(itr->status()))
00334 log(Debug) << "not a regular file: ignored."<<endlog();
00335 else
00336 log(Debug) << "not a " + SO_EXT + " library: ignored."<<endlog();
00337 }
00338 }
00339 log(Debug) << "Looking for plugins or typekits in directory " << p.string() << " ..."<<endlog();
00340 try {
00341 found = PluginLoader::Instance()->loadTypekits( p.string() ) || found;
00342 found = PluginLoader::Instance()->loadPlugins( p.string() ) || found;
00343 } catch (std::exception& e) {
00344 all_good = false;
00345 log(Error) << e.what() <<endlog();
00346 }
00347 }
00348 else {
00349
00350 log(Debug) << "No such directory: " << p<< endlog();
00351 }
00352 #if 0
00353
00354 p = path(*it) / OROCOS_TARGET_NAME;
00355 if (is_directory(p))
00356 {
00357 log(Info) << "Importing component libraries from directory " << p.string() << " ..."<<endlog();
00358 for (directory_iterator itr(p); itr != directory_iterator(); ++itr)
00359 {
00360 log(Debug) << "Scanning file " << itr->path().string() << " ...";
00361 if (is_regular_file(itr->status()) && isLoadableLibrary(itr->path()) ) {
00362 found = true;
00363 #if BOOST_VERSION >= 104600
00364 all_good = loadInProcess( itr->path().string(), makeShortFilename(itr->path().filename().string() ), true) && all_good;
00365 #else
00366 all_good = loadInProcess( itr->path().string(), makeShortFilename(itr->path().filename() ), true) && all_good;
00367 #endif
00368 }else {
00369 if (!is_regular_file(itr->status()))
00370 log(Debug) << "not a regular file: ignored."<<endlog();
00371 else
00372 log(Debug) << "not a " + SO_EXT + " library: ignored."<<endlog();
00373 }
00374 }
00375 log(Info) << "Importing plugins and typekits from directory " << p.string() << " ..."<<endlog();
00376 try {
00377 found = PluginLoader::Instance()->loadTypekits( p.string() ) || found;
00378 found = PluginLoader::Instance()->loadPlugins( p.string() ) || found;
00379 } catch (std::exception& e) {
00380 all_good = false;
00381 log(Error) << e.what() <<endlog();
00382 }
00383 }
00384 #endif
00385 }
00386 if (!all_good)
00387 throw std::runtime_error("Some found plugins could not be loaded !");
00388 return found;
00389 }
00390
00391
00392
00393 bool ComponentLoader::import( std::string const& package, std::string const& path_list )
00394 {
00395
00396 path arg( package );
00397 if (is_regular_file(arg) && isLoadableLibrary(arg)) {
00398 #if BOOST_VERSION >= 104600
00399 return loadInProcess(arg.string(), makeShortFilename( arg.filename().string() ), true);
00400 #else
00401 return loadInProcess(arg.string(), makeShortFilename( arg.filename() ), true);
00402 #endif
00403 }
00404
00405
00406 if ( arg.is_complete() ) {
00407
00408 bool ret = import(package);
00409
00410 if ( arg.parent_path().leaf() != OROCOS_TARGET_NAME )
00411 ret = import( (arg / OROCOS_TARGET_NAME).string() ) || ret;
00412
00413 if (ret)
00414 return true;
00415
00416 log(Error) << "Could not import absolute path '"<<package << "': nothing found."<<endlog();
00417 return false;
00418 }
00419
00420 if ( isImported(package) ) {
00421 log(Info) <<"Component package '"<< package <<"' already imported." <<endlog();
00422 return true;
00423 }
00424
00425
00426 return importInstalledPackage(package, path_list);
00427 }
00428
00429 bool ComponentLoader::importInstalledPackage(std::string const& package, std::string const& path_list)
00430 {
00431 string paths;
00432 string trypaths;
00433 vector<string> tryouts;
00434 if (path_list.empty())
00435 paths = component_path + default_delimiter + ".";
00436 else
00437 paths = path_list;
00438
00439 bool path_found = false;
00440
00441
00442
00443 vector<string> vpaths;
00444 vpaths = splitPaths(paths);
00445 trypaths = paths;
00446 paths.clear();
00447
00448 path p( package );
00449 if (is_directory( p )) {
00450 path_found = true;
00451
00452 paths += p.string() + default_delimiter + (p / OROCOS_TARGET_NAME).string() + default_delimiter;
00453 if ( p.is_complete() ) {
00454
00455
00456
00457 }
00458 }
00459
00460 for(vector<string>::iterator it = vpaths.begin(); it != vpaths.end(); ++it) {
00461 p = *it;
00462 p = p / package;
00463
00464 if (is_directory( p )) {
00465 path_found = true;
00466 paths += p.string() + default_delimiter ;
00467 } else
00468 tryouts.push_back( p.string() );
00469 p = *it;
00470 p = p / OROCOS_TARGET_NAME / package;
00471
00472 if (is_directory( p )) {
00473 path_found = true;
00474 paths += p.string() + default_delimiter ;
00475 } else
00476 tryouts.push_back( p.string() );
00477 }
00478 if ( path_found )
00479 paths.erase( paths.size() - 1 );
00480
00481
00482 if (path_found) {
00483 if ( import(paths) ) {
00484 loadedPackages.push_back( package );
00485 return true;
00486 } else {
00487 log(Error) << "Failed to import components, types or plugins from package or directory '"<< package <<"' found in:"<< endlog();
00488 log(Error) << paths << endlog();
00489 return false;
00490 }
00491 }
00492 log(Error) << "No such package or directory found in search path: " << package << ". Search path is: "<< endlog();
00493 log(Error) << trypaths << endlog();
00494 for(vector<string>::iterator it=tryouts.begin(); it != tryouts.end(); ++it)
00495 log(Error) << *it << endlog();
00496 return false;
00497 }
00498
00499 bool ComponentLoader::reloadLibrary(std::string const& name)
00500 {
00501 path arg = name;
00502
00503 #if BOOST_VERSION >= 104600
00504 if (is_regular_file( arg ) && reloadInProcess( arg.string(), makeShortFilename( arg.filename().string() ) ) )
00505 #else
00506 if (is_regular_file( arg ) && reloadInProcess( arg.string(), makeShortFilename( arg.filename() ) ) )
00507 #endif
00508 return true;
00509
00510 return false;
00511 }
00512
00513 bool ComponentLoader::loadLibrary( std::string const& name )
00514 {
00515 path arg = name;
00516
00517 #if BOOST_VERSION >= 104600
00518 if (is_regular_file( arg ) && loadInProcess( arg.string(), makeShortFilename( arg.filename().string() ), true ) )
00519 #else
00520 if (is_regular_file( arg ) && loadInProcess( arg.string(), makeShortFilename( arg.filename() ), true ) )
00521 #endif
00522 return true;
00523
00524 if ( arg.is_complete() )
00525 return false;
00526
00527
00528 vector<string> paths = splitPaths( component_path );
00529 vector<string> tryouts( paths.size() * 4 );
00530 tryouts.clear();
00531 path dir = arg.parent_path();
00532 #if BOOST_VERSION >= 104600
00533 string file = arg.filename().string();
00534 #else
00535 string file = arg.filename();
00536 #endif
00537
00538 for (vector<string>::iterator it = paths.begin(); it != paths.end(); ++it)
00539 {
00540 path p = path(*it) / dir / (file + FULL_COMPONENT_SUFFIX);
00541 tryouts.push_back( p.string() );
00542 if (is_regular_file( p ) && loadInProcess( p.string(), makeShortFilename(file), true ) )
00543 return true;
00544 p = path(*it) / dir / ("lib" + file + FULL_COMPONENT_SUFFIX);
00545 tryouts.push_back( p.string() );
00546 if (is_regular_file( p ) && loadInProcess( p.string(), makeShortFilename(file), true ) )
00547 return true;
00548 p = path(*it) / OROCOS_TARGET_NAME / dir / (file + FULL_COMPONENT_SUFFIX);
00549 tryouts.push_back( p.string() );
00550 if (is_regular_file( p ) && loadInProcess( p.string(), makeShortFilename(file), true ) )
00551 return true;
00552 p = path(*it) / OROCOS_TARGET_NAME / dir / ("lib" + file + FULL_COMPONENT_SUFFIX);
00553 tryouts.push_back( p.string() );
00554 if (is_regular_file( p ) && loadInProcess( p.string(), makeShortFilename(file), true ) )
00555 return true;
00556 }
00557 log(Debug) << "No such library found in path: " << name << ". Tried:"<< endlog();
00558 for(vector<string>::iterator it=tryouts.begin(); it != tryouts.end(); ++it)
00559 log(Debug) << *it << endlog();
00560 return false;
00561 }
00562
00563 bool ComponentLoader::isImported(string type_name)
00564 {
00565 if (ComponentFactories::Instance().find(type_name) != ComponentFactories::Instance().end() )
00566 return true;
00567 if (find(loadedPackages.begin(), loadedPackages.end(), type_name) != loadedPackages.end())
00568 return true;
00569
00570
00571 if ( type_name == "ocl" && TypekitRepository::hasTypekit("OCLTypekit")) {
00572 return true;
00573 }
00574 return false;
00575 }
00576
00577 bool ComponentLoader::reloadInProcess(string file, string libname)
00578 {
00579 path p(file);
00580
00581
00582
00583
00584
00585 std::vector<LoadedLib>::iterator lib = loadedLibs.begin();
00586 while (lib != loadedLibs.end()) {
00587
00588 if ( lib->filename == file) {
00589 log(Info) <<"Component library "<< lib->filename <<" already loaded... " ;
00590
00591 bool can_unload = true;
00592 CompList::iterator cit;
00593 for( std::vector<std::string>::iterator ctype = lib->components_type.begin(); ctype != lib->components_type.end() && can_unload; ++ctype) {
00594 for ( cit = comps.begin(); cit != comps.end(); ++cit) {
00595 if( (*ctype) == cit->second.type ) {
00596
00597 log(Info) << "can NOT reload library because of the instance " << cit->second.type <<"::"<<cit->second.instance->getName() <<endlog();
00598 can_unload = false;
00599 }
00600 }
00601 }
00602 if( can_unload ) {
00603 log(Info) << "try to RELOAD"<<endlog();
00604 dlclose(lib->handle);
00605
00606 std::vector<LoadedLib>::iterator lib_un = lib;
00607 loadedLibs.erase(lib_un);
00608 return loadInProcess(file, libname, true);
00609 }
00610 else
00611 return false;
00612 }
00613 else lib++;
00614 }
00615 log(Error) << "Can't reload Component library "<< file << " since it was not loaded or is not a component library." <<endlog();
00616 return false;
00617 }
00618
00619
00620 bool ComponentLoader::loadInProcess(string file, string libname, bool log_error) {
00621 path p(file);
00622 char* error;
00623 void* handle;
00624 bool success=false;
00625
00626
00627 if(!isCompatibleComponent(file))
00628 {
00629 if(log_error)
00630 log(Error) << "Could not load library '"<< p.string() <<"': incompatible." <<endlog();
00631 return false;
00632 }
00633
00634 handle = dlopen ( p.string().c_str(), RTLD_NOW);
00635
00636 if (!handle) {
00637 if ( log_error ) {
00638 log(Error) << "Could not load library '"<< p.string() <<"':"<<endlog();
00639 log(Error) << dlerror() << endlog();
00640 }
00641 return false;
00642 }
00643
00644
00645 log(Debug)<<"Succesfully loaded "<<libname<<endlog();
00646 LoadedLib loading_lib(file, libname, handle);
00647 dlerror();
00648
00649
00650 FactoryMap* (*getfactory)(void) = 0;
00651 vector<string> (*getcomponenttypes)(void) = 0;
00652 FactoryMap* fmap = 0;
00653 getfactory = (FactoryMap*(*)(void))( dlsym(handle, "getComponentFactoryMap") );
00654 if ((error = dlerror()) == NULL) {
00655
00656 fmap = (*getfactory)();
00657 ComponentFactories::Instance().insert( fmap->begin(), fmap->end() );
00658 log(Info) << "Loaded multi component library '"<< file <<"'"<<endlog();
00659 getcomponenttypes = (vector<string>(*)(void))(dlsym(handle, "getComponentTypeNames"));
00660 if ((error = dlerror()) == NULL) {
00661 log(Debug) << "Components:";
00662 vector<string> ctypes = getcomponenttypes();
00663 for (vector<string>::iterator it = ctypes.begin(); it != ctypes.end(); ++it)
00664 log(Debug) <<" "<< *it;
00665 log(Debug) << endlog();
00666 }
00667 loadedLibs.push_back(loading_lib);
00668 success = true;
00669 }
00670
00671
00672 dlerror();
00673
00674 RTT::TaskContext* (*factory)(std::string) = 0;
00675 std::string(*tname)(void) = 0;
00676 factory = (RTT::TaskContext*(*)(std::string))(dlsym(handle, "createComponent") );
00677 string create_error;
00678 error = dlerror();
00679 if (error) create_error = error;
00680 tname = (std::string(*)(void))(dlsym(handle, "getComponentType") );
00681 string gettype_error;
00682 error = dlerror();
00683 if (error) gettype_error = error;
00684 if ( factory && tname ) {
00685 std::string cname = (*tname)();
00686 if ( ComponentFactories::Instance().count(cname) == 1 ) {
00687 log(Warning) << "Component type name "<<cname<<" already used: overriding."<<endlog();
00688 }
00689 ComponentFactories::Instance()[cname] = factory;
00690 log(Info) << "Loaded component type '"<< cname <<"'"<<endlog();
00691 loading_lib.components_type.push_back( cname );
00692 loadedLibs.push_back(loading_lib);
00693 success = true;
00694 }
00695
00696 if (success) return true;
00697
00698 log(Error) <<"Unloading "<< loading_lib.filename <<": not a valid component library:" <<endlog();
00699 if (!create_error.empty())
00700 log(Error) << " " << create_error << endlog();
00701 if (!gettype_error.empty())
00702 log(Error) << " " << gettype_error << endlog();
00703 dlclose(handle);
00704 return false;
00705 }
00706
00707 std::vector<std::string> ComponentLoader::listComponentTypes() const {
00708 vector<string> names;
00709 FactoryMap::iterator it;
00710 for( it = ComponentFactories::Instance().begin(); it != ComponentFactories::Instance().end(); ++it) {
00711 names.push_back( it->first );
00712 }
00713 return names;
00714 }
00715
00716 std::string ComponentLoader::getComponentPath() const {
00717 string ret = component_path;
00718
00719 if ( ret.length() && ret[ ret.length() -1 ] != default_delimiter )
00720 ret += default_delimiter;
00721 return ret;
00722 }
00723
00724 void ComponentLoader::setComponentPath( std::string const& newpath ) {
00725 component_path = newpath;
00726 }
00727
00728
00729 RTT::TaskContext *ComponentLoader::loadComponent(const std::string & name, const std::string & type)
00730 {
00731 TaskContext* instance = 0;
00732 RTT::TaskContext* (*factory)(std::string name) = 0;
00733 log(Debug) << "Trying to create component "<< name <<" of type "<< type << endlog();
00734
00735
00736 if ( ComponentFactories::Instance().count(type) == 1 ) {
00737 factory = ComponentFactories::Instance()[ type ];
00738 if (factory == 0 ) {
00739 log(Error) <<"Found empty factory for Component type "<<type<<endlog();
00740 return 0;
00741 }
00742 }
00743
00744 if ( factory ) {
00745 log(Debug) <<"Found factory for Component type "<<type<<endlog();
00746 } else {
00747 log(Error) << "Unable to create Orocos Component '"<<type<<"': unknown component type." <<endlog();
00748 return 0;
00749 }
00750
00751 comps[name].type = type;
00752
00753 try {
00754 comps[name].instance = instance = (*factory)(name);
00755 } catch(...) {
00756 log(Error) <<"The constructor of component type "<<type<<" threw an exception!"<<endlog();
00757 }
00758
00759 if ( instance == 0 ) {
00760 log(Error) <<"Failed to load component with name "<<name<<": refused to be created."<<endlog();
00761 }
00762 return instance;
00763 }
00764
00765 bool ComponentLoader::unloadComponent( RTT::TaskContext* tc ) {
00766 if (!tc)
00767 return false;
00768 CompList::iterator it;
00769 it = comps.find( tc->getName() );
00770
00771 if ( it != comps.end() ) {
00772 delete tc;
00773 comps.erase(it);
00774 return true;
00775 }
00776 log(Error) <<"Refusing to unload a component I didn't load myself."<<endlog();
00777 return false;
00778 }
00779
00780 std::vector<std::string> ComponentLoader::listComponents() const
00781 {
00782 vector<string> names( comps.size() );
00783 for(map<string,ComponentData>::const_iterator it = comps.begin(); it != comps.end(); ++it)
00784 names.push_back( it->first );
00785 return names;
00786 }
00787
00788 bool ComponentLoader::isCompatibleComponent(std::string const& filepath)
00789 {
00790 path p(filepath);
00791
00792 #if BOOST_VERSION >= 104600
00793 string libname = p.filename().string();
00794 #else
00795 string libname = p.filename();
00796 #endif
00797
00798
00799
00800 #ifdef _WIN32
00801
00802
00803
00804 if(!hasEnding(libname, FULL_COMPONENT_SUFFIX))
00805 {
00806
00807 return false;
00808 }
00809 #endif // _WIN32
00810
00811
00812
00813
00814
00815 return true;
00816 }
00817
00818 const FactoryMap& ComponentLoader::getFactories() const
00819 {
00820 return ComponentFactories::Instance();
00821 }
00822
00823 void ComponentLoader::addFactory(std::string const& name, ComponentLoaderSignature factory)
00824 {
00825 ComponentFactories::Instance()[name] = factory;
00826 }