Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

loader.cc

Go to the documentation of this file.
00001 #include <dlfcn.h>
00002 #include "register.hh"
00003 #include <list>
00004 
00005 namespace anoid {
00006     namespace loader {
00007 
00008         using namespace std;
00009         using namespace config;
00010 
00011         Loader loader;
00012 
00013         Loader::Loader() {
00014         }
00015 
00016         Loader::~Loader() {
00017         }
00018 
00019         void Loader::includeInformation(Configuration &c) {
00020             cout << "Loading class information" << endl;
00021             if (c.getName() == "classes") {
00022                 list<Configuration *> classes = c.getChildren();
00023                 
00024                 list<DynamicLoadableModuleInfo *> unprocessed;
00025                 list<DynamicLoadableModuleInfo *> nextstep;
00026 
00027                 for (list<Configuration *>::iterator i = classes.begin(); i != classes.end(); ++i) {
00028                     if ((*i)->getName() == "class") {
00029                         DynamicLoadableModuleInfo *dlmi = new DynamicLoadableModuleInfo((*i)->getString("name"), (*i)->getString("url")); 
00030                         list<Configuration *> depends = (*i)->getChildren();
00031                         for (list<Configuration *>::iterator j = depends.begin(); j != depends.end(); ++j) {
00032                             if ((*j)->getName() == "requires")
00033                                 dlmi->requires.push_back((*j)->getString("ref"));
00034                             delete (*j);
00035                         }
00036                         nextstep.push_back(dlmi);
00037                     }
00038 
00039                     delete (*i);
00040                 }
00041 
00042                 while (unprocessed.size() != nextstep.size()) {
00043                     unprocessed = nextstep;
00044                     nextstep.clear();
00045                     for (list<DynamicLoadableModuleInfo *>::iterator i = unprocessed.begin(); i != unprocessed.end(); ++i) {
00046                         bool clean = true;
00047                         for (list<string>::iterator j = (*i)->requires.begin(); j != (*i)->requires.end(); ++j) {
00048                             if (modules.count(*j) == 0)
00049                                 clean = false;
00050                         }
00051                         if (clean) {
00052                             cout << "Registering " << (*i)->name << endl;
00053                             modules[(*i)->name] = (*i);
00054                         } else
00055                             nextstep.push_back(*i);
00056                     }
00057                 }
00058 
00059                 if (!unprocessed.empty()) {
00060                     for (list<DynamicLoadableModuleInfo *>::iterator i = unprocessed.begin(); i != unprocessed.end(); ++i) {
00061                         cerr << "Module `" << (*i)->name << "' has unsatisfied dependencies." << endl;
00062                     }
00063                 }
00064             }
00065         }
00066 
00067         void Loader::associate(const string &name, RegisterBase *factory) {
00068             cout << "Associating " << name << endl;
00069             if (factoryMap[name] == NULL) {
00070                 factoryMap[name] = factory;
00071             } // else error
00072         }
00073 
00074         void Loader::disassociate(const string &name) {
00075             factoryMap.erase(name);
00076         }
00077 
00078         void Loader::load(const std::string &name) {
00079             if (DLLMap[name] == NULL) {
00080                 DynamicLoadableModuleInfo *d = modules[name];
00081                 if (d) {
00082                     cout << "Loading " << name << endl;
00083                     for (list<string>::iterator i = d->requires.begin(); i != d->requires.end(); ++i) {
00084                         load(*i);
00085                     }
00086                     void *tmp = dlopen(d->location.c_str(), RTLD_NOW);
00087                     if (tmp) {
00088                         DLLMap[name] = tmp;
00089                     } else {
00090                         cerr << "Could not load library `" << name << "'." << endl
00091                             << "Loading failed with `" << dlerror() << "'." << endl;
00092                     }
00093                     cout << "Done loading " << name << endl;
00094                     return;
00095                 } else {
00096                     cerr << "Could not find module `" << name << "'." << endl;
00097                 }
00098             } // else error
00099 
00100         }
00101 
00102         void Loader::unload(const std::string &library) {
00103             void *tmp = DLLMap[library];
00104             if (tmp != NULL) {
00105                 dlclose(tmp);
00106             }
00107             DLLMap.erase(library);
00108         }
00109 
00110         Base *Loader::getInstance(const std::string &name) {
00111             RegisterBase *factory = factoryMap[name];
00112             if (factory == NULL) {
00113                 load(name);
00114                 factory = factoryMap[name];
00115             }
00116             if (factory != NULL) {
00117                 return factory->instantiate();
00118             } // else error
00119             return NULL;
00120         }
00121     };
00122 };

Anoid NG © Michael Westergaard, Martin Stig Stissing, Ronni Michael Laursen, and Kristian Bisgaard Lassen