Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "ar_track_alvar/CaptureFactory.h"
00025
00026 #include "ar_track_alvar/CaptureFactory_private.h"
00027 #include "ar_track_alvar/CapturePlugin.h"
00028 #include "ar_track_alvar/DirectoryIterator.h"
00029
00030 namespace alvar {
00031
00032 CaptureFactoryPrivate::CaptureFactoryPrivate()
00033 : mPluginPaths()
00034 , mPluginPrefix()
00035 , mPluginPostfix()
00036 , mLoadedAllPlugins(false)
00037 , mPluginMap()
00038 , mCapturePluginMap()
00039 {
00040 setupPluginPaths();
00041
00042 mPluginPrefix = pluginPrefix();
00043 mPluginPrefix.append("alvarcaptureplugin");
00044
00045 mPluginPostfix.append(ALVAR_VERSION_NODOTS);
00046 #if _DEBUG
00047 mPluginPostfix.append("d");
00048 #endif
00049 mPluginPostfix.append(".");
00050 mPluginPostfix.append(pluginExtension());
00051 }
00052
00053 CaptureFactoryPrivate::~CaptureFactoryPrivate()
00054 {
00055 for (CapturePluginMap::iterator itr = mCapturePluginMap.begin(); itr != mCapturePluginMap.end(); itr++) {
00056 delete itr->second;
00057 }
00058 mCapturePluginMap.clear();
00059 mPluginMap.clear();
00060 }
00061
00062 void CaptureFactoryPrivate::loadPlugins()
00063 {
00064
00065 if (mLoadedAllPlugins) {
00066 return;
00067 }
00068
00069
00070 for (PluginPathsVector::iterator itr = mPluginPaths.begin(); itr != mPluginPaths.end(); ++itr) {
00071 DirectoryIterator directory(*itr);
00072
00073
00074 while (directory.hasNext()) {
00075 std::string entry = directory.next();
00076
00077
00078 int prefixIndex = entry.find(mPluginPrefix);
00079 int postfixIndex = entry.rfind(mPluginPostfix);
00080 if (prefixIndex == -1 || postfixIndex == -1) {
00081 continue;
00082 }
00083
00084
00085 entry = entry.substr(mPluginPrefix.size(), postfixIndex - mPluginPrefix.size());
00086 loadPlugin(entry, directory.currentPath());
00087 }
00088 }
00089
00090
00091 mLoadedAllPlugins = true;
00092 }
00093
00094 void CaptureFactoryPrivate::loadPlugin(const std::string &captureType)
00095 {
00096
00097 if (mPluginMap.find(captureType) != mPluginMap.end()) {
00098 return;
00099 }
00100
00101
00102 for (PluginPathsVector::iterator itr = mPluginPaths.begin(); itr != mPluginPaths.end(); ++itr) {
00103 DirectoryIterator directory(*itr);
00104
00105
00106 while (directory.hasNext()) {
00107 std::string entry = directory.next();
00108
00109
00110 int prefixIndex = entry.find(mPluginPrefix);
00111 int postfixIndex = entry.rfind(mPluginPostfix);
00112 if (prefixIndex == -1 || postfixIndex == -1) {
00113 continue;
00114 }
00115
00116
00117 entry = entry.substr(mPluginPrefix.size(), postfixIndex - mPluginPrefix.size());
00118 if (entry != captureType) {
00119 continue;
00120 }
00121
00122
00123 loadPlugin(entry, directory.currentPath());
00124
00125
00126 break;
00127 }
00128 }
00129 }
00130
00131 void CaptureFactoryPrivate::loadPlugin(const std::string &captureType, const std::string &filename)
00132 {
00133
00134 if (mPluginMap.find(captureType) != mPluginMap.end()) {
00135 return;
00136 }
00137
00138 try {
00139
00140 Plugin plugin(filename);
00141
00142
00143
00144
00145
00146 typedef void (*RegisterPlugin)(const std::string &captureType, CapturePlugin *&capturePlugin);
00147 RegisterPlugin registerPlugin = (RegisterPlugin)plugin.resolve("registerPlugin");
00148 CapturePlugin *capturePlugin = NULL;
00149 if (registerPlugin) {
00150 registerPlugin(captureType, capturePlugin);
00151 }
00152
00153
00154 if (capturePlugin == NULL) {
00155 return;
00156 }
00157
00158
00159 mPluginMap.insert(PluginMap::value_type(captureType, plugin));
00160 mCapturePluginMap.insert(CapturePluginMap::value_type(captureType, capturePlugin));
00161 }
00162 catch (AlvarException e) {
00163
00164 #if defined(_DEBUG) || !defined(NDEBUG)
00165 std::cout << e.what() << std::endl;
00166 #endif
00167 }
00168 }
00169
00170 CapturePlugin *CaptureFactoryPrivate::getPlugin(const std::string &captureType)
00171 {
00172
00173 CapturePluginMap::iterator itr;
00174 itr = mCapturePluginMap.find(captureType);
00175
00176
00177 if (itr == mCapturePluginMap.end()) {
00178 loadPlugin(captureType);
00179 itr = mCapturePluginMap.find(captureType);
00180 }
00181
00182
00183 CapturePlugin *capturePlugin = NULL;
00184 if (itr != mCapturePluginMap.end()) {
00185 capturePlugin = itr->second;
00186 }
00187 return capturePlugin;
00188 }
00189
00190
00191
00192 CaptureFactory *CaptureFactory::mInstance = NULL;
00193 Mutex CaptureFactory::mMutex;
00194 CaptureFactory::CaptureFactoryDestroyer CaptureFactory::mDestroyer;
00195
00196 CaptureFactory *CaptureFactory::instance()
00197 {
00198
00199
00200
00201
00202 Lock lock(&mMutex);
00203 if (mInstance == NULL) {
00204 mInstance = new CaptureFactory();
00205 mDestroyer.set(mInstance);
00206 }
00207 return mInstance;
00208 }
00209
00210 CaptureFactory::CaptureFactory()
00211 : d(new CaptureFactoryPrivate())
00212 {
00213 }
00214
00215 CaptureFactory::~CaptureFactory()
00216 {
00217 delete d;
00218 }
00219
00220 CaptureFactory::CapturePluginVector CaptureFactory::enumeratePlugins()
00221 {
00222
00223 d->loadPlugins();
00224
00225
00226 CaptureFactory::CapturePluginVector keys;
00227 for (CaptureFactoryPrivate::PluginMap::iterator itr = d->mPluginMap.begin(); itr != d->mPluginMap.end(); ++itr) {
00228 keys.push_back(itr->first);
00229 }
00230
00231 return keys;
00232 }
00233
00234 CaptureFactory::CaptureDeviceVector CaptureFactory::enumerateDevices(const std::string &captureType)
00235 {
00236 CaptureDeviceVector devices;
00237
00238
00239 if (captureType.empty()) {
00240 d->loadPlugins();
00241 for (CaptureFactoryPrivate::CapturePluginMap::iterator itr = d->mCapturePluginMap.begin(); itr != d->mCapturePluginMap.end(); ++itr) {
00242 CaptureDeviceVector pluginDevices = itr->second->enumerateDevices();
00243 devices.insert(devices.end(), pluginDevices.begin(), pluginDevices.end());
00244 }
00245 }
00246
00247 else {
00248 CapturePlugin *capturePlugin = d->getPlugin(captureType);
00249 if (capturePlugin) {
00250 devices = capturePlugin->enumerateDevices();
00251 }
00252 }
00253
00254 return devices;
00255 }
00256
00257 Capture *CaptureFactory::createCapture(const CaptureDevice captureDevice)
00258 {
00259
00260 CapturePlugin *capturePlugin = d->getPlugin(captureDevice.captureType());
00261
00262
00263 Capture *capture = NULL;
00264 if (capturePlugin) {
00265 capture = capturePlugin->createCapture(captureDevice);
00266 }
00267 return capture;
00268 }
00269
00270 }