diff options
author | Manoj Rajagopalan <manoj@nanorex.com> | 2008-03-19 05:26:08 +0000 |
---|---|---|
committer | Manoj Rajagopalan <manoj@nanorex.com> | 2008-03-19 05:26:08 +0000 |
commit | 60ab1ecf7c57e00421a4d91932539e34a871bc91 (patch) | |
tree | 7bf2ab0b14fce17bd394396a09edd2b828f297de | |
parent | 48eafb6bce830297b025082648f430e6505c5743 (diff) | |
download | nanoengineer-60ab1ecf7c57e00421a4d91932539e34a871bc91.tar.gz nanoengineer-60ab1ecf7c57e00421a4d91932539e34a871bc91.zip |
NXGraphicsManager initial commit.
The part that verifies a loaded commit using qobject_cast is commented out for the moment
because that will include propagating changes to NXRenderingEngine, NXRendererPlugin and
related class-hierarchies and these in turn require extensive testing. This is next on the
agenda.
application.qrc still had a reference to a deleted nanoENGINEER-1.ico file and this was breaking builds. Corrected.
4 files changed, 337 insertions, 1 deletions
diff --git a/cad/plugins/NanoVision-1/include/Nanorex/Interface/NXGraphicsManager.h b/cad/plugins/NanoVision-1/include/Nanorex/Interface/NXGraphicsManager.h new file mode 100644 index 000000000..e47c92e12 --- /dev/null +++ b/cad/plugins/NanoVision-1/include/Nanorex/Interface/NXGraphicsManager.h @@ -0,0 +1,79 @@ +// Copyright 2008 Nanorex, Inc. See LICENSE file for details. + +#ifndef NX_GRAPHICSMANAGER_H +#define NX_GRAPHICSMANAGER_H + +#include "Nanorex/Utility/NXLogger.h" +#include "Nanorex/Utility/NXUtility.h" +#include "Nanorex/Utility/NXProperties.h" +#include "NXRenderingEngine.h" +#include "NXRendererPlugin.h" + +#include <QObject> + +#include <map> +#include <vector> +#include <string> + + +namespace Nanorex { + + +class NXGraphicsManager : public QObject { + + Q_OBJECT; + +private: + typedef std::map<std::string, NXRendererPlugin*> RenderStyleRendererPluginTable; + typedef std::map<std::string, std::string> StringMap; + +public: + + NXGraphicsManager(); + ~NXGraphicsManager(); + + /// Discover rendering engine based on user-prefs and concomitant + /// renderer-plugins + void loadPlugins(NXProperties *const properties); + + /// List of all styles supported + std::vector<std::string> getRenderStyles(void); + + NXRenderingEngine* getRenderingEngine(void); + + NXRendererPlugin* getRenderer(std::string const& renderStyleCode) const; + + std::string getRenderStyleName(std::string const& renderStyleCode); + + NXRendererPlugin* getDefaultRenderer(void); + +private: + + NXProperties properties; + NXRenderingEngine *renderingEngine; + + // Note: a render-style code, like "bas" is what we'd find in MMP files + // NE-1 uses 3-letter codes but the user could use arbitrarily long + // ones. We must provide a UI so that registering a new one does not + // clobber the old ones without prompting the user first. + + /// Map between render-style codes and plugins + /// E.g.: "bas" <---> (NXRendererPlugin*) nxBallAndStickOpenGLRendererInstance + RenderStyleRendererPluginTable renderStyleRendererPluginTable; + NXRendererPlugin *defaultPlugin; + + /// Map between render-style codes and proper display names + /// E.g.: "bas" <---> "Ball and Stick" + StringMap renderStyleNameTable; + + /// Map between render-style codes and the file-name for the library + /// providing the code + StringMap renderStyleFileNameTable; + + void loadRenderingEngine(NXProperties *const props); + void loadRendererPlugins(NXProperties *const props); +}; + +} // namespace Nanorex + +#endif // NX_GRAPHICSMANAGER_H diff --git a/cad/plugins/NanoVision-1/src/Interface/NXGraphicsManager.cpp b/cad/plugins/NanoVision-1/src/Interface/NXGraphicsManager.cpp new file mode 100644 index 000000000..c4381000c --- /dev/null +++ b/cad/plugins/NanoVision-1/src/Interface/NXGraphicsManager.cpp @@ -0,0 +1,256 @@ +// Copyright 2008 Nanorex, Inc. See LICENSE file for details. + +#include <Nanorex/Interface/NXGraphicsManager.h> +#include <Nanorex/Utility/NXStringTokenizer.h> + +#include <QDir> +#include <QFileInfo> +#include <QPluginLoader> + +#include <sstream> + +using namespace std; + +namespace Nanorex { + +NXGraphicsManager::NXGraphicsManager() + : properties(), + renderingEngine(NULL), + renderStyleRendererPluginTable(), + renderStyleNameTable(), + renderStyleFileNameTable() +{ +} + + +NXGraphicsManager::~NXGraphicsManager() +{ +} + + +void NXGraphicsManager::loadPlugins(NXProperties *const props) +{ + loadRenderingEngine(props); + loadRendererPlugins(props); +} + + +/// Called by findAndLoadPlugin() to load a plugin from an existing file. +/// Returns false if qobject_cast() failed indicating that plugin does not +/// match the expected interface. If successful, then the pointer referenced +/// by pluginStore is updated to point to the loaded instance. +/// This function is called to load both the rendering-engine and renderer-plugins +template<typename PluginType> + static bool loadPlugin(PluginType **pluginStore, + QFileInfo const fileInfo) +{ + QPluginLoader pluginLoader(fileInfo.absoluteFilePath()); + QObject *pluginObject = pluginLoader.instance(); + /// @fixme Uncomment and commit after testing builds with NXRenderingEngine + /// Qt-plugin modifications go through +/* if(pluginObject != (QObject*) 0) + *pluginStore = qobject_cast<PluginType*>(pluginObject); + else */ + *pluginStore = (PluginType*) 0; + + bool success = ((*pluginStore) != (PluginType*)0); + return success; +} + + +/// Locates and loads a plugin given the basename of the file and an initial +/// path to examine. If a load from the initial path is unsuccessful or if the +/// path provided is empty, then it retrieves the plugins-search-path +/// from application-settings and searches it in order for the first file it +/// could successfully find and load. If an engine could be successfully loaded +/// then it returns true and the plugin-pointer referenced by pluginStore is +/// updated to point to the loaded instance. cleanPath then holds the absolute +/// directory specification and absPath holds the full path to the library file. +template<typename PluginType> + static bool findAndLoadPlugin(string const& baseName, string const& path, + string const& pluginsSearchPath, + PluginType **pluginStore, QDir *cleanPath, + string *absPath) +{ +#if defined(WIN32) + string const fileExt = ".dll"; +#elif defined(__APPLE__) + string const fileExt = ".dylib"; +#else + string const fileExt = ".so"; +#endif + + string const fileName = baseName + fileExt; + bool pluginFoundAndLoaded = false; + + if(!path.empty()) { + // user-defined specific path for this plugin - search this first + *cleanPath = QDir(path.c_str()).absolutePath(); + QFileInfo fileInfo(cleanPath->absoluteFilePath(fileName.c_str())); + *absPath = qPrintable(fileInfo.absoluteFilePath()); + bool const pluginFound = fileInfo.exists(); + bool pluginLoaded = false; + if(pluginFound) + pluginLoaded = loadPlugin(pluginStore, fileInfo); + pluginFoundAndLoaded = pluginFound && pluginLoaded; + if(!pluginFoundAndLoaded) { + string const pluginNotFoundMsg = "Could not find renderer-plugin " + + fileName + " in specific path " + + qPrintable(cleanPath->absolutePath()) + + " - examining plugins-search-path from application-settings"; + NXLOG_WARNING("NXGraphicsManager", pluginNotFoundMsg); + } + } + + if(!pluginFoundAndLoaded) { + // either plugin was not found in given path or no specific path was + // provided for the plugin - search in plugin-paths list + NXStringTokenizer tokenizer(pluginsSearchPath, ";"); + while(!pluginFoundAndLoaded && tokenizer.hasMoreTokens()) { + string const token = tokenizer.getNextToken(); + *cleanPath = QDir(token.c_str()).absolutePath(); + QFileInfo fileInfo(cleanPath->absoluteFilePath(fileName.c_str())); + *absPath = qPrintable(fileInfo.absoluteFilePath()); + bool const pluginFound = fileInfo.exists(); + bool pluginLoaded = false; + if(pluginFound) + pluginLoaded = loadPlugin(pluginStore, fileInfo); + pluginFoundAndLoaded = pluginFound && pluginLoaded; + } + if(!pluginFoundAndLoaded) { + string const pluginNotFoundMsg = "Could not find renderer-plugin " + + fileName + " in paths " + pluginsSearchPath; + NXLOG_SEVERE("NXGraphicsManager", pluginNotFoundMsg); + } + } + + return pluginFoundAndLoaded; +} + + + +/// Loads the rendering-engine from application settings +void NXGraphicsManager::loadRenderingEngine(NXProperties *const props) +{ + /// @fixme What if pluginsSearchPath is empty? + + string baseName = props->getProperty("RenderingEngine.plugin"); + string filePath = props->getProperty("RenderingEngine.pluginPath"); + string const pluginsSearchPath = + props->getProperty("Miscellaneous/PluginsSearchPath"); + + QDir cleanPath; + string absPath; + bool renderingEngineLoaded = findAndLoadPlugin(baseName, filePath, + pluginsSearchPath, + &renderingEngine, + &cleanPath, &absPath); + + if(renderingEngineLoaded) { + properties.setProperty("RenderingEngine.plugin", + qPrintable(cleanPath.absolutePath())); + string const msg = "Rendering-engine loaded from file " + absPath; + NXLOG_INFO("NXGraphicsManager", msg); + } +} + + +void NXGraphicsManager::loadRendererPlugins(NXProperties *const props) +{ + string const pluginsSearchPath = + props->getProperty("Miscellaneous/PluginsSearchPath"); + + int pluginNum = 0; // counter + + while(true) { + ostringstream pluginKeyStream; + pluginKeyStream << "RenderStyle." << pluginNum; + ++pluginNum; + string const pluginKey = pluginKeyStream.str(); + string const pluginCode = props->getProperty(pluginKey + ".code"); + string pluginBaseName = props->getProperty(pluginKey + ".plugin"); + + // if code and plugin filename are absent then there are no more plugins + if(pluginCode.empty() && pluginBaseName.empty()) + break; + + // else if only one of them is mentioned then error condition + else if(pluginCode.empty() || pluginBaseName.empty()) { + // error condition, both are required, only one is present + string msg = "Both render-style code and plugin library filename " + "must be provided for " + pluginKey + " (check app-settings file)"; + NXLOG_SEVERE("NXGraphicsManager", msg); + // this could be a mistake with just this plugin-spec, continue + // with next plugin - maybe that one is ok + continue; + } + + // both code and plugin file have values - try to load + else { + string const pluginPath = + props->getProperty(pluginKey + ".pluginPath"); + + QDir cleanPath; + string absPath; + NXRendererPlugin *rendererPlugin = NULL; + bool const rendererPluginLoaded = + findAndLoadPlugin(pluginBaseName, pluginPath, pluginsSearchPath, + &rendererPlugin, &cleanPath, &absPath); + + // if successful, record entries in tables + if(rendererPluginLoaded) { + string pluginName = props->getProperty(pluginKey + ".name"); + if(pluginName.empty()) + pluginName = pluginCode; + properties.setProperty("Renderer."+pluginCode+".plugin", + absPath); + properties.setProperty("Renderer."+pluginCode+".name", + pluginName); + renderStyleRendererPluginTable[pluginCode] = rendererPlugin; + renderStyleNameTable[pluginCode] = pluginName; + renderStyleFileNameTable[pluginCode] = absPath; + // break out of plugin-search loop upon first successful load + break; + } + } + } +} + + +vector<string> NXGraphicsManager::getRenderStyles(void) +{ + vector<string> renderStyles; + RenderStyleRendererPluginTable::const_iterator renderStyleTableIter; + for(renderStyleTableIter = renderStyleRendererPluginTable.begin(); + renderStyleTableIter != renderStyleRendererPluginTable.end(); + ++renderStyleTableIter) + { + renderStyles.push_back(renderStyleTableIter->first); + } + return renderStyles; +} + + +NXRendererPlugin* + NXGraphicsManager::getRenderer(string const& renderStyleCode) const +{ + RenderStyleRendererPluginTable::const_iterator renderStyleCodeIter = + renderStyleRendererPluginTable.find(renderStyleCode); + if(renderStyleCodeIter == renderStyleRendererPluginTable.end()) + return (NXRendererPlugin*) NULL; + else + return renderStyleCodeIter->second; +} + + +string NXGraphicsManager::getRenderStyleName(string const& renderStyleCode) +{ + StringMap::const_iterator renderStyleCodeIter = + renderStyleNameTable.find(renderStyleCode); + if(renderStyleCodeIter == renderStyleNameTable.end()) + return string(); + else + return renderStyleCodeIter->second; +} + +} // namespace Nanorex diff --git a/cad/plugins/NanoVision-1/src/KDevelop/Interface/Interface.pro b/cad/plugins/NanoVision-1/src/KDevelop/Interface/Interface.pro index efb479b67..b13d000c7 100644 --- a/cad/plugins/NanoVision-1/src/KDevelop/Interface/Interface.pro +++ b/cad/plugins/NanoVision-1/src/KDevelop/Interface/Interface.pro @@ -8,6 +8,7 @@ HEADERS += \ ../../../include/Nanorex/Interface/NXDataImportExportPlugin.h \ ../../../include/Nanorex/Interface/NXDataStoreInfo.h \ ../../../include/Nanorex/Interface/NXEntityManager.h \ + ../../../include/Nanorex/Interface/NXGraphicsManager.h \ ../../../include/Nanorex/Interface/NXMoleculeData.h \ ../../../include/Nanorex/Interface/NXMoleculeSet.h \ ../../../include/Nanorex/Interface/NXNanoVisionResultCodes.h \ @@ -29,6 +30,7 @@ INCLUDEPATH += ../../../include \ SOURCES += ../../Interface/NXDataStoreInfo.cpp \ ../../Interface/NXEntityManager.cpp \ + ../../Interface/NXGraphicsManager.cpp \ ../../Interface/NXMoleculeData.cpp \ ../../Interface/NXMoleculeSet.cpp \ ../../Interface/NXNumbers.cpp \ diff --git a/cad/plugins/NanoVision-1/src/application.qrc b/cad/plugins/NanoVision-1/src/application.qrc index ba7e53d21..885ab31cf 100644 --- a/cad/plugins/NanoVision-1/src/application.qrc +++ b/cad/plugins/NanoVision-1/src/application.qrc @@ -8,7 +8,6 @@ <file>Icons/home.png</file> <file>Icons/results_tree.png</file> <file>Icons/nh5_file.png</file> - <file>Icons/nanoENGINEER-1.ico</file> <file>Icons/input_file.png</file> <file>Icons/input_files.png</file> <file>Icons/input_parameters.png</file> |