@SET PATH=D:\NewGEOM\build-eclipse\bin;%PATH%
+@SET NEW_GEOM_CONFIG_FILE=%ROOT_DIR%\install\plugins
+@SET PATH=%ROOT_DIR%\install\plugins;%PATH%
+
rem -------- Visual Studio --------------------
rem Detect Visual Studio (either commercial or Express edition)
if "%VS100COMNTOOLS%" == "" (
myLibraryName = "";
#ifdef _DEBUG
- if (!Event_Loop::Loop()) {
+ if (!Event_Loop::loop()) {
std::cout << "Config_FeatureReader::importWorkbench: "
<< "No event loop registered" << std::endl;
}
myFetchWidgetCfg(false)
{
#ifdef _DEBUG
- if (!Event_Loop::Loop()) {
+ if (!Event_Loop::loop()) {
std::cout << "Config_FeatureReader::importWorkbench: "
<< "No event loop registered" << std::endl;
}
void Config_FeatureReader::processNode(xmlNodePtr theNode)
{
+ static Event_ID aMenuItemEvent = Event_Loop::eventByName("RegisterFeature");
if (isNode(theNode, NODE_FEATURE, NULL)) {
if (myFetchWidgetCfg) {
xmlBufferPtr buffer = xmlBufferCreate();
int size = xmlNodeDump(buffer, theNode->doc, theNode, 0, 1);
myWidgetCfg = std::string((char*) buffer->content);
} else {
- Event_Loop* aEvLoop = Event_Loop::Loop();
- Config_FeatureMessage aMessage(aEvLoop->EventByName("menu_item"), this);
+ Event_Loop* aEvLoop = Event_Loop::loop();
+ Config_FeatureMessage aMessage(aMenuItemEvent, this);
fillFeature(theNode, aMessage);
- aEvLoop->Send(aMessage);
+ aEvLoop->send(aMessage);
}
}
//The m_last* variables always defined before fillFeature() call. XML is a tree.
#include <libxml\parser.h>
#include <libxml\tree.h>
+/*
#ifdef WIN32
//For GetModuleFileNameW
#include <windows.h>
#endif
+*/
#ifdef _DEBUG
#include <iostream>
Config_XMLReader::Config_XMLReader(const std::string& theXmlFileName)
{
std::string prefix;
+ /* the problem: application may be launched using python execuable, to use environment variable
+ (at least for the current moment)
//Get path to *.xml files (typically ./bin/../plugins/)
#ifdef WIN32
HMODULE hModule = GetModuleHandleW(NULL);
//TODO(sbh): Find full path to binary on linux
prefix = "../plugins/";
#endif
+ */
+ char* anEnv = getenv("NEW_GEOM_CONFIG_FILE");
+ if (anEnv) {
+ prefix = std::string(anEnv) + "/";
+ }
myDocumentPath = prefix + theXmlFileName;
}
*/
void Config_XMLReader::readRecursively(xmlNodePtr theParent)
{
- static Event_ID aFeatureEvent = Event_Loop::EventByName("Feature");
-
if (!theParent)
return;
xmlNodePtr aNode = theParent->xmlChildrenNode;
processNode(aNode);
if (processChildren(aNode)) {
readRecursively(aNode);
- Config_FeatureMessage aMessage(aFeatureEvent, this);
}
}
}
public:
//! This method is called by loop when the event is started to process.
- virtual void ProcessEvent(const Event_Message* theMessage) = 0;
+ virtual void processEvent(const Event_Message* theMessage) = 0;
};
#endif
using namespace std;
-Event_Loop* Event_Loop::Loop()
+Event_Loop* Event_Loop::loop()
{
// initialized on initialization of the application
static Event_Loop MAIN_LOOP;
return &MAIN_LOOP;
}
-Event_ID Event_Loop::EventByName(const char* theName)
+Event_ID Event_Loop::eventByName(const char* theName)
{
///! All events created in this session, uniquely identified by the text and char pointer
static map<string, char*> CREATED_EVENTS;
return Event_ID(aResult);
}
-void Event_Loop::Send(Event_Message& theMessage)
+void Event_Loop::send(Event_Message& theMessage)
{
// TO DO: make it in thread and wit husage of semaphores
map<char*, map<void*, list<Event_Listener*> > >::iterator aFindID = myListeners.find(
- theMessage.EventID().EventText());
+ theMessage.eventID().eventText());
if (aFindID != myListeners.end()) {
map<void*, list<Event_Listener*> >::iterator aFindSender = aFindID->second.find(
- theMessage.Sender());
+ theMessage.sender());
if (aFindSender != aFindID->second.end()) {
list<Event_Listener*>& aListeners = aFindSender->second;
for(list<Event_Listener*>::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++)
- (*aL)->ProcessEvent(&theMessage);
+ (*aL)->processEvent(&theMessage);
}
- if (theMessage.Sender()) { // also call for NULL senders registered
+ if (theMessage.sender()) { // also call for NULL senders registered
aFindSender = aFindID->second.find(NULL);
if (aFindSender != aFindID->second.end()) {
list<Event_Listener*>& aListeners = aFindSender->second;
for(list<Event_Listener*>::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++)
- (*aL)->ProcessEvent(&theMessage);
+ (*aL)->processEvent(&theMessage);
}
}
}
}
-void Event_Loop::RegisterListener(Event_Listener* theListener, const Event_ID theID,
+void Event_Loop::registerListener(Event_Listener* theListener, const Event_ID theID,
void* theSender)
{
map<char*, map<void*, list<Event_Listener*> > >::iterator aFindID = myListeners.find(
- theID.EventText());
+ theID.eventText());
if (aFindID == myListeners.end()) { // create container associated with ID
- myListeners[theID.EventText()] = map<void*, list<Event_Listener*> >();
- aFindID = myListeners.find(theID.EventText());
+ myListeners[theID.eventText()] = map<void*, list<Event_Listener*> >();
+ aFindID = myListeners.find(theID.eventText());
}
map<void*, list<Event_Listener*> >::iterator aFindSender = aFindID->second.find(theSender);
Event_Loop() {};
public:
///! Returns the main object of the loop, one per application.
- EVENT_EXPORT static Event_Loop* Loop();
+ EVENT_EXPORT static Event_Loop* loop();
//! Returns the unique event by the given name. Call this method only on initialization of object
//! to speedup the events processing without parsing of the string.
- EVENT_EXPORT static Event_ID EventByName(const char* theName);
+ EVENT_EXPORT static Event_ID eventByName(const char* theName);
//! Allows to send an event
- EVENT_EXPORT void Send(Event_Message& theMessage);
+ EVENT_EXPORT void send(Event_Message& theMessage);
//! Registers (or adds if such listener is already registered) a listener
//! that will be called on the event and from the defined sender
- EVENT_EXPORT void RegisterListener(Event_Listener* theListener, const Event_ID theID,
+ EVENT_EXPORT void registerListener(Event_Listener* theListener, const Event_ID theID,
void* theSender = 0);
};
friend class Event_Loop;
public:
/// Returns the text-identifier of the event (for debugging reasons)
- char* EventText() const {return myID;}
+ char* eventText() const {return myID;}
/// Allows to compare identifiers
bool operator==(const Event_ID& theID) const {return myID == theID.myID;}
};
virtual ~Event_Message() {}
//! Returns identifier of the message
- const Event_ID& EventID() const {return myEventId;}
+ const Event_ID& eventID() const {return myEventId;}
//! Returns sender of the message or NULL if it is anonymous message
- void* Sender() {return mySender;}
+ void* sender() {return mySender;}
};
#endif
#include <Model_PluginManager.h>
#include <ModelAPI_Feature.h>
+#include <ModelAPI_Plugin.h>
#include <Model_Feature.h>
#include <Event_Loop.h>
#include <Config_FeatureMessage.h>
#include <Config_ModuleReader.h>
-#include <OSD_SharedLibrary.hxx>
-
using namespace std;
static Model_PluginManager* myImpl = new Model_PluginManager();
-boost::shared_ptr<ModelAPI_Feature> Model_PluginManager::CreateFeature(string theFeatureID)
+boost::shared_ptr<ModelAPI_Feature> Model_PluginManager::createFeature(string theFeatureID)
{
- if (this != myImpl) return myImpl->CreateFeature(theFeatureID);
+ if (this != myImpl) return myImpl->createFeature(theFeatureID);
LoadPluginsInfo();
if (myPlugins.find(theFeatureID) != myPlugins.end()) {
- string aLibName = myPlugins[theFeatureID];
-#ifdef WIN32
- aLibName += ".dll";
-#else
- aLibName += ".so";
-#endif
- Standard_CString aLibNameCStr = aLibName.c_str();
- OSD_SharedLibrary aLib(aLibNameCStr);
- if (aLib.DlOpen(OSD_RTLD_NOW)) {
- OSD_Function aFunc = aLib.DlSymb("CreateFeature");
+ if (myPluginObjs.find(myPlugins[theFeatureID]) == myPluginObjs.end()) {
+ // load plugin library if not yet done
+ myCurrentPluginName = myPlugins[theFeatureID];
+ loadLibrary(myCurrentPluginName);
+ }
+ if (myPluginObjs.find(myCurrentPluginName) != myPluginObjs.end()) {
+ return myPluginObjs[myCurrentPluginName]->createFeature(theFeatureID);
}
}
Model_PluginManager::Model_PluginManager()
{
myPluginsInfoLoaded = false;
- static Event_ID aFeatureEvent = Event_Loop::EventByName("Feature");
+ static Event_ID aFeatureEvent = Event_Loop::eventByName("RegisterFeature");
ModelAPI_PluginManager::SetPluginManager(boost::shared_ptr<ModelAPI_PluginManager>(this));
// register the configuration reading listener
- Event_Loop* aLoop = Event_Loop::Loop();
- aLoop->RegisterListener(myImpl, aFeatureEvent);
+ Event_Loop* aLoop = Event_Loop::loop();
+ aLoop->registerListener(this, aFeatureEvent);
}
-void Model_PluginManager::ProcessEvent(const Event_Message* theMessage)
+void Model_PluginManager::processEvent(const Event_Message* theMessage)
{
const Config_FeatureMessage* aMsg =
- dynamic_cast<const Config_FeatureMessage*>( theMessage );
+ dynamic_cast<const Config_FeatureMessage*>(theMessage);
if (aMsg) {
// proccess the plugin info, load plugin
if (myPlugins.find(aMsg->id()) == myPlugins.end()) {
- myPlugins[aMsg->id()] = "PartSetPlugin"; // TO DO: plugin name must be also imported from XMLs
+ myPlugins[aMsg->id()] = aMsg->pluginLibrary(); // TO DO: plugin name must be also imported from XMLs
}
}
// plugins information was started to load, so, it will be loaded
aXMLReader.setAutoImport(true);
aXMLReader.readAll();
}
+
+void Model_PluginManager::registerPlugin(ModelAPI_Plugin* thePlugin)
+{
+ myPluginObjs[myCurrentPluginName] = thePlugin;
+}
class Model_PluginManager : public ModelAPI_PluginManager, public Event_Listener
{
bool myPluginsInfoLoaded; ///< it true if plugins information is loaded
- std::map<std::string, std::string> myPlugins; ///< map of feature IDs to plugin name
+ /// map of feature IDs to plugin name and object
+ std::map<std::string, std::string> myPlugins;
+ std::map<std::string, ModelAPI_Plugin*> myPluginObjs; ///< instances of the already plugins
+ std::string myCurrentPluginName; ///< name of the plugin that must be loaded currently
public:
/// Creates the feature object using plugins functionality
- MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> CreateFeature(std::string theFeatureID);
+ MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Feature> createFeature(std::string theFeatureID);
+
+ /// Registers the plugin that creates features.
+ /// It is obligatory for each plugin to call this function on loading to be found by
+ /// the plugin manager on call of the feature)
+ virtual void registerPlugin(ModelAPI_Plugin* thePlugin);
/// Processes the configuration file reading
- MODEL_EXPORT virtual void ProcessEvent(const Event_Message* theMessage);
+ MODEL_EXPORT virtual void processEvent(const Event_Message* theMessage);
/// Is called only once, on startup of the application
Model_PluginManager();
ModelAPI.h
ModelAPI_Interface.h
ModelAPI_PluginManager.h
+ ModelAPI_Plugin.h
ModelAPI_Feature.h
ModelAPI_Document.h
)
//! Redoes last operation
MODELAPI_EXPORT virtual void Redo() = 0;
+protected:
/// Only for SWIG wrapping it is here
MODELAPI_EXPORT ModelAPI_Document()
{
/// Returns the kind of a feature (like "Point")
virtual std::string GetKind() = 0;
+protected:
/// Use plugin manager for features creation: this method is
/// defined here only for SWIG-wrapping
ModelAPI_Feature()
--- /dev/null
+// File: ModelAPI_Plugin.hxx
+// Created: 31 Mar 2014
+// Author: Mikhail PONIKAROV
+
+#ifndef ModelAPI_Plugin_HeaderFile
+#define ModelAPI_Plugin_HeaderFile
+
+#include "ModelAPI.h"
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+class ModelAPI_Feature;
+
+/**\class ModelAPI_Plugin
+ * \ingroup DataModel
+ * \brief Interface common for any plugin: allows to use plugin by the plugins manager.
+ */
+
+class MODELAPI_EXPORT ModelAPI_Plugin
+{
+public:
+ /// Creates the feature object of this plugin by the feature string ID
+ virtual boost::shared_ptr<ModelAPI_Feature> createFeature(std::string theFeatureID) = 0;
+
+protected:
+ /// Is needed for python wrapping by swig
+ ModelAPI_Plugin() {};
+};
+
+#endif
#include <ModelAPI_Document.h>
// to avoid unresolved ModelAPI_Feature()
#include <ModelAPI_Feature.h>
+// to avoid unresolved ModelAPI_Plugin()
+#include <ModelAPI_Plugin.h>
#ifdef WIN32
#include <windows.h>
using namespace std;
-/// loads the library with specific name, appends "lib*.dll" or "*.so" depending on the platform
-void loadLibrary(const string theLibName);
/// Converts library name to the operation system file name
string library(const string& theLibName);
MY_MANAGER = theManager;
}
-boost::shared_ptr<ModelAPI_PluginManager> ModelAPI_PluginManager::Get()
+boost::shared_ptr<ModelAPI_PluginManager> ModelAPI_PluginManager::get()
{
if (!MY_MANAGER) { // import Model library that implements this interface of ModelAPI
loadLibrary("Model");
return aLibName;
}
-void loadLibrary(const string theLibName)
+void ModelAPI_PluginManager::loadLibrary(const string theLibName)
{
string aFileName = library(theLibName);
if ( aFileName.empty() )
#include <boost/shared_ptr.hpp>
class ModelAPI_Feature;
+class ModelAPI_Plugin;
/**\class ModelAPI_PluginManager
* \ingroup DataModel
{
public:
/// Creates the feature object using plugins functionality
- virtual boost::shared_ptr<ModelAPI_Feature> CreateFeature(std::string theFeatureID) = 0;
+ virtual boost::shared_ptr<ModelAPI_Feature> createFeature(std::string theFeatureID) = 0;
/// Returns the real implementation (the alone instance per application) of the plugin manager
- static boost::shared_ptr<ModelAPI_PluginManager> Get();
+ static boost::shared_ptr<ModelAPI_PluginManager> get();
+
+ /// Registers the plugin that creates features.
+ /// It is obligatory for each plugin to call this function on loading to be found by
+ /// the plugin manager on call of the feature)
+ virtual void registerPlugin(ModelAPI_Plugin* thePlugin) = 0;
+
+ /// loads the library with specific name, appends "lib*.dll" or "*.so" depending on the platform
+ static void ModelAPI_PluginManager::loadLibrary(const std::string theLibName);
/// Is needed for python wrapping by swig, call Get to get an instance
ModelAPI_PluginManager();
SET(PROJECT_HEADERS
PartSetPlugin.h
+ PartSetPlugin_Plugin.h
PartSetPlugin_NewPart.h
)
SET(PROJECT_SOURCES
- PartSetPlugin.cxx
+ PartSetPlugin_Plugin.cxx
PartSetPlugin_NewPart.cxx
)
+++ /dev/null
-#include "PartSetPlugin.h"
-
-#include <PartSetPlugin_NewPart.h>
-#include <boost/shared_ptr.hpp>
-
-using namespace std;
-
-/// Standard method of the plugin that creates a specific feature instance by the feature kind
-PARTSETPLUGIN_EXPORT boost::shared_ptr<ModelAPI_Feature> CreateFeature(const string& theFeatureKind)
-{
- if (theFeatureKind == "new_part") {
- return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_NewPart());
- }
- // feature of such kind is not found
- return boost::shared_ptr<ModelAPI_Feature>();
-}
--- /dev/null
+#include "PartSetPlugin_Plugin.h"
+#include "PartSetPlugin_NewPart.h"
+#include <ModelAPI_PluginManager.h>
+
+using namespace std;
+
+// the only created instance of this plugin
+static PartSetPlugin_Plugin* MY_INSTANCE = new PartSetPlugin_Plugin();
+
+PartSetPlugin_Plugin::PartSetPlugin_Plugin()
+{
+ // register this plugin
+ ModelAPI_PluginManager::get()->registerPlugin(this);
+}
+
+boost::shared_ptr<ModelAPI_Feature> PartSetPlugin_Plugin::createFeature(string theFeatureID)
+{
+ if (theFeatureID == "new_part") {
+ return boost::shared_ptr<ModelAPI_Feature>(new PartSetPlugin_NewPart());
+ }
+ // feature of such kind is not found
+ return boost::shared_ptr<ModelAPI_Feature>();
+}
--- /dev/null
+// File: PartSetPlugin_Plugin.hxx
+// Created: 31 Mar 2014
+// Author: Mikhail PONIKAROV
+
+#ifndef PartSetPlugin_Plugin_HeaderFile
+#define PartSetPlugin_Plugin_HeaderFile
+
+
+#include "PartSetPlugin.h"
+#include "ModelAPI_Plugin.h"
+
+class PARTSETPLUGIN_EXPORT PartSetPlugin_Plugin: public ModelAPI_Plugin
+{
+public:
+ /// Creates the feature object of this plugin by the feature string ID
+ virtual boost::shared_ptr<ModelAPI_Feature> createFeature(std::string theFeatureID);
+
+public:
+ /// Is needed for python wrapping by swig
+ PartSetPlugin_Plugin();
+};
+
+#endif
{
initMenu();
//Initialize event listening
- Event_Loop* aLoop = Event_Loop::Loop();
- Event_ID aFeatureId = aLoop->EventByName("menu_item");
- aLoop->RegisterListener(this, aFeatureId);
- Event_ID aPartSetId = aLoop->EventByName("partset_module");
- aLoop->RegisterListener(this, aPartSetId);
+ Event_Loop* aLoop = Event_Loop::loop();
+ Event_ID aFeatureId = aLoop->eventByName("RegisterFeature");
+ aLoop->registerListener(this, aFeatureId);
+ Event_ID aPartSetId = aLoop->eventByName("partset_module");
+ aLoop->registerListener(this, aPartSetId);
activateModule();
myMainWindow->show();
QMdiSubWindow* aWnd = myMainWindow->viewer()->createView();
}
//******************************************************
-void XGUI_Workshop::ProcessEvent(const Event_Message* theMessage)
+void XGUI_Workshop::processEvent(const Event_Message* theMessage)
{
const Config_FeatureMessage* aFeatureMsg = dynamic_cast<const Config_FeatureMessage*>(theMessage);
if (aFeatureMsg) {
XGUI_Workbench* addWorkbench(const QString& theName);
- virtual void ProcessEvent(const Event_Message* theMessage);
+ virtual void processEvent(const Event_Message* theMessage);
public slots:
void onNew();