/googleclient/third_party/fcollada/files/FUtils/FUPluginManager.cpp
C++ | 232 lines | 182 code | 23 blank | 27 comment | 83 complexity | 1a915a6d115b217c02a185d42d3ea4c3 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.0, LGPL-3.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause, GPL-2.0, Apache-2.0, MIT, CPL-1.0
- /*
- Copyright (C) 2005-2007 Feeling Software Inc.
- Portions of the code are:
- Copyright (C) 2005-2007 Sony Computer Entertainment America
-
- MIT License: http://www.opensource.org/licenses/mit-license.php
- */
- #include "StdAfx.h"
- #include "FUPlugin.h"
- #include "FUPluginManager.h"
- #include "FUFileManager.h"
- #ifdef WIN32
- #include <io.h>
- #if defined(UNICODE)
- #define ffinddata _wfinddata_t
- #define ffindfirst _wfindfirst
- #define ffindclose _findclose
- #define ffindnext _wfindnext
- #else // UNICODE
- #define ffinddata _finddata_t
- #define ffindfirst _findfirst
- #define ffindclose _findclose
- #define ffindnext _findnext
- #endif
- #elif defined(__APPLE__) || defined(LINUX)
- #include <dlfcn.h>
- #include <dirent.h>
- #endif //WIN32
- //
- // FUPlugin
- //
- ImplementObjectType(FUPlugin);
- //
- // FUPluginManager
- //
- FUPluginManager::FUPluginManager(const fchar* _filter)
- {
- fstring applicationFolderName = FUFileManager::GetApplicationFolderName();
- LoadPluginsInFolderName(applicationFolderName, _filter);
- fstring moduleFolderName = FUFileManager::GetModuleFolderName();
- if (!moduleFolderName.empty() && !IsEquivalent(moduleFolderName, applicationFolderName))
- {
- LoadPluginsInFolderName(moduleFolderName, _filter);
- }
- }
- void FUPluginManager::LoadPluginsInFolderName(const fstring& folderName, const fchar* _filter)
- {
- // Append the wanted extension for the plugins.
- FUStringBuilder pluginFolder(folderName);
- fchar lastChar = folderName[pluginFolder.length() - 1];
- if (lastChar != '\\' && lastChar != '/') pluginFolder.append((fchar) '/');
- pluginFolder.append(FC("Plugins/"));
- pluginFolderName = pluginFolder.ToString();
- if (_filter == NULL || _filter[0] == 0) _filter = FC("*.*");
- do
- {
- const fchar* nextFilter = fstrchr(_filter, '|');
- fstring filter(_filter);
- if (nextFilter != NULL)
- {
- filter.erase(nextFilter - _filter);
- ++nextFilter; // skip the pipe.
- }
- _filter = nextFilter;
- // Windows-only for now.
- #if defined(WIN32)
- size_t filterLength = filter.length();
- // Iterate over all the filtered files within the given folder.
- ffinddata folderIterator;
- fstring searchString = pluginFolderName + filter;
- intptr_t folderHandle = ffindfirst(searchString.c_str(), &folderIterator);
- if (folderHandle != -1L)
- {
- int32 isDone = FALSE;
- while (isDone == FALSE)
- {
- bool keep = false;
- PluginLibrary* library = new PluginLibrary();
- library->filename = pluginFolderName + folderIterator.name;
- // work around for wildcards and 3 letter extensions that pick up 3+ letter extensions
- // e.g. "dir *.fvp" in command prompt on a directory with "a.fvp", "a.fvpa", and "a.dll" returns
- // "a.fvp" and "a.fvpa"
- bool checkModule = true;
- if (filterLength > 3)
- {
- if ((filter.at(filterLength-4) == FC('.')) && (filter.at(filterLength-3) != FC('*')) &&
- (filter.at(filterLength-2) != FC('*')) && (filter.at(filterLength-1) != FC('*')))
- {
- size_t filepathLength = fstrlen(folderIterator.name);
- checkModule = (folderIterator.name[filepathLength-4] == filter.at(filterLength-4)) &&
- (folderIterator.name[filepathLength-3] == filter.at(filterLength-3)) &&
- (folderIterator.name[filepathLength-2] == filter.at(filterLength-2)) &&
- (folderIterator.name[filepathLength-1] == filter.at(filterLength-1));
- }
- }
- library->module = LoadLibrary(library->filename.c_str());
- if (checkModule && (library->module != NULL))
- {
- // Retrieve the necessary callbacks
- library->getPluginCount = (GetPluginCount) GetProcAddress(library->module, "GetPluginCount");
- library->getPluginType = (GetPluginType) GetProcAddress(library->module, "GetPluginType");
- library->createPlugin = (CreatePlugin) GetProcAddress(library->module, "CreatePlugin");
- keep = library->createPlugin != NULL && library->getPluginType != NULL && library->getPluginCount != NULL;
- }
- // This is a valid library.
- if (keep) loadedLibraries.push_back(library);
- else { SAFE_DELETE(library); }
- isDone = ffindnext(folderHandle, &folderIterator);
- }
- ffindclose(folderHandle);
- }
- #elif defined(__APPLE__) || defined(LINUX)
- fm::string s_filter = TO_STRING(filter);
- if (s_filter.length() > 0 && s_filter.front() == '*') s_filter.erase(0, 1);
- if (s_filter.length() > 0 && s_filter.back() == '*') s_filter.pop_back();
- DIR* directory = opendir(TO_STRING(pluginFolderName).c_str());
- if (directory == NULL) continue;
- dirent* directoryEntry;
- while ((directoryEntry = readdir(directory)) != NULL)
- {
- if (directoryEntry->d_type == DT_DIR) continue; // skip sub-folders.
- if (strstr((const char*) directoryEntry->d_name, s_filter.c_str()) != NULL)
- {
- // We have a match.
- bool keep = false;
- PluginLibrary* library = new PluginLibrary();
- library->filename = pluginFolderName + TO_FSTRING((const char*) directoryEntry->d_name);
- fm::string libraryModuleFilename = TO_STRING(library->filename);
- DEBUG_OUT("Found dynamic library: %s\n", libraryModuleFilename.c_str());
- library->module = dlopen(libraryModuleFilename.c_str(), RTLD_NOW);
- if (library->module != NULL)
- {
- // Retrieve the necessary callbacks
- library->getPluginCount = (GetPluginCount) dlsym(library->module, "GetPluginCount");
- library->getPluginType = (GetPluginType) dlsym(library->module, "GetPluginType");
- library->createPlugin = (CreatePlugin) dlsym(library->module, "CreatePlugin");
- keep = library->createPlugin != NULL && library->getPluginType != NULL && library->getPluginCount != NULL;
- }
- // This is a valid library.
- if (keep) loadedLibraries.push_back(library);
- else { SAFE_DELETE(library); }
- }
- }
- closedir(directory);
- #endif // WIN32
- } while (_filter != NULL);
- }
- FUPluginManager::~FUPluginManager()
- {
- UnloadPlugins();
- FUAssert(loadedPlugins.empty(), return);
- // Detach all the plugin libraries.
- for (PluginLibraryList::iterator it = loadedLibraries.begin(); it != loadedLibraries.end(); ++it)
- {
- #if defined(WIN32)
- if ((*it)->module != NULL) FreeLibrary((*it)->module);
- #elif defined(LINUX) || defined(__APPLE__)
- if ((*it)->module != NULL) dlclose((*it)->module);
- #endif // WIN32
- }
- CLEAR_POINTER_VECTOR(loadedLibraries);
- }
- void FUPluginManager::LoadPlugins(const FUObjectType& pluginType)
- {
- for (PluginLibraryList::iterator it = loadedLibraries.begin(); it != loadedLibraries.end(); ++it)
- {
- #ifndef _DEBUG
- try
- #endif // _DEBUG
- {
- DEBUG_OUT("Loading plug-in: %s\n", TO_STRING((*it)->filename).c_str());
- FUAssert((*it)->createPlugin != NULL && (*it)->getPluginType != NULL && (*it)->getPluginCount != NULL, continue);
- uint32 pluginCount = (*((*it)->getPluginCount))();
- for (uint32 i = 0; i < pluginCount; ++i)
- {
- // Retrieve the types of all the plug-ins within this library.
- // Compare them against the wanted types and create the wanted plug-ins.
- const FUObjectType* type = (*((*it)->getPluginType))(i);
- if (type->Includes(pluginType))
- {
- FUPlugin* plugin = (*((*it)->createPlugin))(i);
- if (plugin == NULL) continue;
- loadedPlugins.push_back(plugin);
- }
- }
- }
- #ifndef _DEBUG
- catch (...)
- {
- fm::string _filename = TO_STRING((*it)->filename);
- ERROR_OUT("Unhandled exception when loading plugin: %s.", _filename.c_str());
- }
- #endif // _DEBUG
- }
- }
- void FUPluginManager::AddPluginLibrary(FUPluginManager::GetPluginCount fnGetPluginCount, FUPluginManager::GetPluginType fnGetPluginType, FUPluginManager::CreatePlugin fnCreatePlugin)
- {
- PluginLibrary* library = new PluginLibrary();
- library->getPluginCount = fnGetPluginCount;
- library->getPluginType = fnGetPluginType;
- library->createPlugin = fnCreatePlugin;
- library->filename.clear();
- library->module = NULL;
- loadedLibraries.push_back(library);
- }
- void FUPluginManager::UnloadPlugins()
- {
- loadedPlugins.clear();
- }