~robot3d-team/robot3d/trunk

« back to all changes in this revision

Viewing changes to src/srCore/loadComponents.cpp

  • Committer: Anne van Rossum
  • Date: 2010-08-10 15:58:55 UTC
  • Revision ID: anne@gamix-20100810155855-kve7x2vwouagdij9
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * @file loadComponents.cpp
 
3
 *
 
4
 * This file loadComponents.cpp is created at Almende B.V. It is open-source software and part
 
5
 * of the Common Hybrid Agent Platform (CHAP). A toolbox with a lot of open-source tools.
 
6
 * Ranging from thread pools, and TCP/IP components to control architectures and learning
 
7
 * algorithms. This software is published under the GNU Lesser General Public license,
 
8
 *
 
9
 * It is not possible to add usage restrictions to an open-source license. Nevertheless,
 
10
 * we personally strongly object against this software used by the military, in the
 
11
 * bio-industry, for animal experimentation, or anything that violates the Universal
 
12
 * Declaration of Human Rights.
 
13
 *
 
14
 * @author      Anne C. van Rossum
 
15
 * @date        Aug 4, 2010
 
16
 * @project     Replicator FP7
 
17
 * @company     Almende B.V.
 
18
 * @case        
 
19
 */
 
20
 
 
21
 
 
22
// General files
 
23
#include <dlfcn.h>
 
24
#include <sstream>
 
25
 
 
26
// Delta3D files
 
27
#include <dtUtil/log.h>
 
28
 
 
29
// Robot3D files
 
30
#include <srCore/loadComponents.h>
 
31
#include <srCore/pluginEntryPointBase.h>
 
32
 
 
33
namespace srCore {
 
34
 
 
35
/* **************************************************************************************
 
36
 * Implementation of LoadComponents
 
37
 * **************************************************************************************/
 
38
 
 
39
LoadComponents::LoadComponents() {
 
40
        path.clear();
 
41
        initialised = false;
 
42
        handles.clear();
 
43
}
 
44
 
 
45
LoadComponents::~LoadComponents() {
 
46
        LOG_INFO("Close all dynamically linked libraries/components (symbols become unavailable)");
 
47
        std::vector<void *>::iterator i;
 
48
        for (i = handles.begin(); i != handles.end(); i++) {
 
49
                dlclose(*i);
 
50
        }
 
51
}
 
52
 
 
53
void LoadComponents::SetLibPath(const std::string &libpath) {
 
54
        path = libpath;
 
55
        std::ostringstream msg; msg.clear(); msg.str("");
 
56
        msg << "Set library path for additional plugins to " << libpath;
 
57
        LOG_INFO(msg.str());
 
58
        assert (boost::filesystem::is_directory(path));
 
59
}
 
60
 
 
61
/**
 
62
 * Get all the shared libraries (.so files) in the previously assigned path.
 
63
 * Do not call this function before you have set SetLibPath.
 
64
 */
 
65
void LoadComponents::GetLibraries() {
 
66
        assert (!path.empty());
 
67
        LOG_INFO("Try to find libraries in given library path");
 
68
        std::ostringstream msg;
 
69
        std::string file, extension;
 
70
        boost::filesystem::directory_iterator i(path), dir_end;
 
71
        for(; i != dir_end; ++i) {
 
72
                file = (*i).leaf();
 
73
                extension = boost::filesystem::extension(*i);
 
74
                if (std::string(extension).find(".so") != std::string::npos) {
 
75
                        msg.clear(); msg.str("");
 
76
                        msg << "Found file " << file;
 
77
                        LOG_DEBUG(msg.str());
 
78
                        file = path.string() + '/' + file;
 
79
                        boost::filesystem::complete(file);
 
80
                        library.push_back(file);
 
81
                }
 
82
        }
 
83
        initialised = true;
 
84
}
 
85
 
 
86
/**
 
87
 * Load additional components or more general, libraries, by searching through a given path that
 
88
 * comes from the \<scenario.xml\> file.
 
89
 * The plugins are loaded by dlopen and subsequently dlsym. The latter searches for a
 
90
 * CreatePluginEntryPoint. Check if that field indeed exist in unmangeled state in the library
 
91
 * to be loaded (by for example nm).
 
92
 *
 
93
 * @param application
 
94
 */
 
95
void LoadComponents::LoadLibs(dtGame::GameApplication &application) {
 
96
        assert (initialised);
 
97
        LOG_INFO("Load plugins");
 
98
        std::ostringstream msg;
 
99
 
 
100
        std::vector<std::string>::iterator i;
 
101
        for (i = library.begin(); i < library.end(); i++) {
 
102
                std::string lib = *i;
 
103
                //open the plugin library
 
104
                LOG_DEBUG("Open the library by \"dlopen\"");
 
105
                void *handle = dlopen(lib.c_str(), RTLD_NOW);// RTLD_LAZY);
 
106
                handles.push_back(handle);
 
107
                if (!handle) {
 
108
                        msg.clear(); msg.str("");
 
109
                        msg << "Library " << dlerror();
 
110
                        LOG_ERROR(msg.str());
 
111
                        continue;
 
112
                }
 
113
 
 
114
                //load "CreatePluginEntryPoint" in the plugin library
 
115
                LOG_DEBUG("Get entry point \"CreatePluginEntryPoint\"");
 
116
                PluginEntryPointBase* (*entrypoint)();
 
117
                entrypoint = (PluginEntryPointBase* (*)())dlsym(handle, "CreatePluginEntryPoint");
 
118
 
 
119
                //tell that everything went well
 
120
                char *error;
 
121
                if ((error = dlerror()) != NULL) {
 
122
                        msg.clear(); msg.str("");
 
123
                        msg << "No CreatePluginEntryPoint method found! (" << error << ")";
 
124
                        LOG_ERROR(msg.str());
 
125
                        continue;
 
126
                }
 
127
 
 
128
                //execute PluginEntryPointBase->StartPlugin
 
129
                msg.clear(); msg.str("");
 
130
                msg << "Run plugin " << lib;
 
131
                LOG_INFO(msg.str());
 
132
                (*entrypoint)()->StartPlugin(application);
 
133
        }
 
134
 
 
135
        std::vector<dtGame::GMComponent*> components;
 
136
        application.GetGameManager()->GetAllComponents(components);
 
137
 
 
138
 
 
139
        for(unsigned int i=0; i < components.size(); i++) {
 
140
                msg.clear(); msg.str("");
 
141
                msg << "Loaded component ";
 
142
                msg << components[i]->GetName();
 
143
                LOG_INFO(msg.str());
 
144
        }
 
145
}
 
146
 
 
147
 
 
148
} // end of namespace srAlmende