From 29925c78baf5060bf3a6d473653c0049884f361b Mon Sep 17 00:00:00 2001 From: Dirk Wilden Date: Tue, 9 Mar 2010 17:49:22 +0000 Subject: [PATCH] changed the updatedObject stuff git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@8694 383ad7c9-94d9-4d36-a494-682f7c89f535 --- BasePlugin/BaseInterface.hh | 25 +++++++ Core/Core.cc | 3 + Core/Core.hh | 5 +- Core/PluginCommunication.cc | 10 +-- Core/PluginLoader.cc | 32 +++++++- common/BaseObject.cc | 2 +- common/BaseObject.hh | 3 +- common/Types.hh | 3 + common/TypesInternal.hh | 3 + common/UpdateType.cc | 142 ++++++++++++++++++++++++++++++++++++ common/UpdateType.hh | 50 +++++++++++++ 11 files changed, 267 insertions(+), 11 deletions(-) create mode 100644 common/UpdateType.cc create mode 100644 common/UpdateType.hh diff --git a/BasePlugin/BaseInterface.hh b/BasePlugin/BaseInterface.hh index 3852a81f..beb1518d 100644 --- a/BasePlugin/BaseInterface.hh +++ b/BasePlugin/BaseInterface.hh @@ -123,6 +123,18 @@ class BaseInterface { */ virtual void updatedObject(int ) {}; + /** \brief An object has been changed or added by this plugin + * + * Emit this Signal, if you updated any part of an object.\n + * If you changed the element itself (geometry, topology,..) you also have to emit this signal.\n + * Dont emit this Signal in BaseInterface::slotObjectUpdated() as this causes an endless Loop!! + * Give the id of the new object as parameter or -1 if you updated all objects or deleted an object. + * + * @param _identifier id of the object or -1 if refering to all or deleted objects. + * @param _type the type states which part of the object (topology, selection, ..) has to be updated + */ + virtual void updatedObject(int /*_identifier*/, const UpdateType /*_type*/) {}; + /** \brief A scenegraph node has been shown or hidden * * Emit this Signal, if you changed the visibility of a scenegraph node directly (not via object->show/hide). @@ -146,6 +158,19 @@ class BaseInterface { */ virtual void slotObjectUpdated( int /*_identifier*/ ) {}; + /** \brief An object has been updated by another plugin + * + * This slot is called by the main aplication if the number or status of existing objects changed or if + * an existing object has been changed. This could mean, that objects are added or deleted + * or that an existing object with the given id has been modified. + * If you store local information about one of these Objects, you should check if its still valid!\n + * Dont emit BaseInterface::updatedObject(int) in this slot as this causes an endless Loop!! + * You dont need to call updateView as the core triggers a redraw itself. + * @param _identifier Identifier of the updated/new object or -1 if one is deleted. + * @param _type the type states which part of the object (topology, selection, ..) had been updated + */ + virtual void slotObjectUpdated( int /*_identifier*/, const UpdateType /*_type*/ ) {}; + /** \brief Called if the whole scene is cleared * * This slot is called if the main application cleared the whole scene. No objects will remain in memory diff --git a/Core/Core.cc b/Core/Core.cc index 9cb6aea3..9ed2ca52 100644 --- a/Core/Core.cc +++ b/Core/Core.cc @@ -189,6 +189,9 @@ Core() : // Initialize the build in dataTypes initializeTypes(); + + // Initialize the build in updateTypes + initializeUpdateTypes(); } /** \brief Second initialization stage diff --git a/Core/Core.hh b/Core/Core.hh index c46dd824..7ed87d2c 100644 --- a/Core/Core.hh +++ b/Core/Core.hh @@ -166,6 +166,9 @@ signals: /// When this Signal is emitted all Plugins are informed that the object list changed void signalObjectUpdated(int); + /// When this Signal is emitted all Plugins are informed that some type of update was performed on an object + void signalObjectUpdated(int, const UpdateType); + /// When this Signal is emitted when a Wheel Event occures void PluginWheelEvent(QWheelEvent * , const std::string & ); @@ -267,7 +270,7 @@ signals: /** Called by the plugins if they changed something in the object list (deleted, added,...) * @param _identifier Id of the object */ - void slotObjectUpdated(int _identifier); + void slotObjectUpdated(int _identifier, const UpdateType _type = UPDATE_ALL); /// Called when a plugin changes the visibility of an object void slotVisibilityChanged(int _id); diff --git a/Core/PluginCommunication.cc b/Core/PluginCommunication.cc index 4143dc5c..6eb913bb 100644 --- a/Core/PluginCommunication.cc +++ b/Core/PluginCommunication.cc @@ -71,15 +71,15 @@ /** This function is called by a plugin if it changed something in the object list (source,target,...). The information is passed to all plugins. * @param _identifier Id of the updated object */ -void Core::slotObjectUpdated(int _identifier) { +void Core::slotObjectUpdated(int _identifier, UpdateType _type) { if ( OpenFlipper::Options::doSlotDebugging() ) { if ( sender() != 0 ) { if ( sender()->metaObject() != 0 ) { - emit log(LOGINFO,"updatedObject( " + QString::number(_identifier) + tr(" ) called by ") + - QString( sender()->metaObject()->className() ) ); + emit log(LOGINFO,"updatedObject( " + QString::number(_identifier) + ", " + updateTypeName(_type) + + tr(" ) called by ") + QString( sender()->metaObject()->className() ) ); } } else { - emit log(LOGINFO,"updatedObject( " + QString::number(_identifier) + tr(" ) called by Core") ); + emit log(LOGINFO,"updatedObject( " + QString::number(_identifier) + ", " + updateTypeName(_type) + tr(" ) called by Core") ); } } @@ -99,7 +99,7 @@ void Core::slotObjectUpdated(int _identifier) { emit signalObjectUpdated(_identifier); if ( object != 0 ) - object->update(); + object->update(_type); // Reenable redraws OpenFlipper::Options::redrawDisabled(false); diff --git a/Core/PluginLoader.cc b/Core/PluginLoader.cc index aa03c7f2..6327d803 100644 --- a/Core/PluginLoader.cc +++ b/Core/PluginLoader.cc @@ -356,6 +356,8 @@ void Core::loadPlugin(QString filename, bool silent){ PluginInfo info; QString supported; + emit log(LOGOUT,tr("Location : \t %2").arg(filename) ); + // Check if it is a BasePlugin BaseInterface* basePlugin = qobject_cast< BaseInterface * >(plugin); if ( basePlugin ) { @@ -465,13 +467,37 @@ void Core::loadPlugin(QString filename, bool silent){ connect(plugin,SIGNAL(updateView()),this,SLOT(updateView())); + if ( checkSignal(plugin,"updatedObject(int)") && checkSignal(plugin,"updatedObject(int,const UpdateType)") ){ + + log(LOGERR,tr("Plugin uses deprecated and(!) new updatedObject. Only new updatedObject will be active.")); + connect(plugin,SIGNAL(updatedObject(int,const UpdateType)),this,SLOT(slotObjectUpdated(int,const UpdateType)), Qt::DirectConnection); + + } else { + + if ( checkSignal(plugin,"updatedObject(int)") ){ + log(LOGWARN,tr("Plugin uses deprecated updatedObject.")); + connect(plugin,SIGNAL(updatedObject(int)),this,SLOT(slotObjectUpdated(int)), Qt::DirectConnection); + } - if ( checkSignal(plugin,"updatedObject(int)") ) - connect(plugin,SIGNAL(updatedObject(int)),this,SLOT(slotObjectUpdated(int)), Qt::DirectConnection); + if ( checkSignal(plugin,"updatedObject(int,const UpdateType)") ) + connect(plugin,SIGNAL(updatedObject(int,const UpdateType)),this,SLOT(slotObjectUpdated(int,const UpdateType)), Qt::DirectConnection); + } - if ( checkSlot( plugin , "slotObjectUpdated(int)" ) ) + if ( checkSlot( plugin , "slotObjectUpdated(int)" ) && checkSlot( plugin , "slotObjectUpdated(int,const UpdateType)" ) ){ + + log(LOGERR,tr("Plugin uses deprecated and(!) new slotObjectUpdated. Only new slotObjectUpdated will be active.")); connect(this,SIGNAL(signalObjectUpdated(int)),plugin,SLOT(slotObjectUpdated(int)), Qt::DirectConnection); + + } else { + + if ( checkSlot( plugin , "slotObjectUpdated(int)" ) ){ + log(LOGWARN,tr("Plugin uses deprecated slotObjectUpdated.")); + connect(this,SIGNAL(signalObjectUpdated(int)),plugin,SLOT(slotObjectUpdated(int)), Qt::DirectConnection); + } + if ( checkSlot( plugin , "slotObjectUpdated(int,const UpdateType)" ) ) + connect(this,SIGNAL(signalObjectUpdated(int,const UpdateType)),plugin,SLOT(slotObjectUpdated(int,const UpdateType)), Qt::DirectConnection); + } if ( checkSignal(plugin,"objectPropertiesChanged(int)")) { emit log (LOGERR,tr("Signal objectPropertiesChanged(int) is deprecated. " )); diff --git a/common/BaseObject.cc b/common/BaseObject.cc index 608dd9d5..9c303b77 100644 --- a/common/BaseObject.cc +++ b/common/BaseObject.cc @@ -711,7 +711,7 @@ void BaseObject::setName(QString _name ) { // =============================================================================== // Content // =============================================================================== -void BaseObject::update() { +void BaseObject::update(UpdateType _type) { } void BaseObject::dumpTree() { diff --git a/common/BaseObject.hh b/common/BaseObject.hh index 7ab07026..cde73ba9 100644 --- a/common/BaseObject.hh +++ b/common/BaseObject.hh @@ -62,6 +62,7 @@ #include #include +#include #include #include #include @@ -282,7 +283,7 @@ class DLLEXPORTONLY BaseObject : public QObject { * the corresponding scenegraph nodes or trigger other data handling which has to be done * when the object changes. */ - virtual void update(); + virtual void update(UpdateType _type = UPDATE_ALL); /// Debugging function, writing the subtree to output void dumpTree(); diff --git a/common/Types.hh b/common/Types.hh index 792e05cb..550d8643 100644 --- a/common/Types.hh +++ b/common/Types.hh @@ -65,6 +65,9 @@ // This include defines all required datatype handling functions #include +// This include defines all functions for handling updateTypes +#include + #include "BaseObject.hh" #include "GroupObject.hh" #include "BaseObjectData.hh" diff --git a/common/TypesInternal.hh b/common/TypesInternal.hh index 3600b1db..fb9f753a 100644 --- a/common/TypesInternal.hh +++ b/common/TypesInternal.hh @@ -71,6 +71,9 @@ typedef std::vector DataContainer; DLLEXPORT void initializeTypes(); +DLLEXPORT +void initializeUpdateTypes(); + //============================================================================= #endif // TYPESINTERNAL_HH defined //============================================================================= diff --git a/common/UpdateType.cc b/common/UpdateType.cc new file mode 100644 index 00000000..472145ed --- /dev/null +++ b/common/UpdateType.cc @@ -0,0 +1,142 @@ +#include "TypesInternal.hh" +#include "UpdateType.hh" +#include +#include +#include + + +/** This field defines the start id for custom updatetypes. + */ +static unsigned int nextUpdateTypeId_ = 16; + +/** This map maps an updateType id to an typeName + */ +static std::map< UpdateType, QString > updateTypeToString; + +/** This map maps an updateType name to its id in the types vector + */ +static std::map< QString , unsigned int > stringToUpdateTypeInfo; + +/** This map maps an updateType id to its id in the types vector + */ +static std::map< UpdateType , unsigned int > updateTypeToTypeInfo; + +class UpdateTypeInfo { + + public: + + UpdateTypeInfo(UpdateType _type, QString _name, bool _needsScenegraphReset ) : + type(_type), + name(_name), + resetNeeded(_needsScenegraphReset) + { + } + + /// The id of the UpdateType + UpdateType type; + + /// The name of the UpdateType + QString name; + + /// is a sceneGraph reset needed for this update + bool resetNeeded; +}; + +static std::vector< UpdateTypeInfo > updateTypes; + + +// functions ------------------------------------------------- + + +void initializeUpdateTypes() { + + stringToUpdateTypeInfo["All"] = updateTypes.size(); + updateTypeToTypeInfo[UPDATE_ALL] = updateTypes.size(); + updateTypes.push_back( UpdateTypeInfo(UPDATE_ALL, "All", true) ); + + stringToUpdateTypeInfo["ObjectSelection"] = updateTypes.size(); + updateTypeToTypeInfo[UPDATE_OBJECT_SELECTION] = updateTypes.size(); + updateTypes.push_back( UpdateTypeInfo(UPDATE_OBJECT_SELECTION, "ObjectSelection", false) ); + + stringToUpdateTypeInfo["Visibility"] = updateTypes.size(); + updateTypeToTypeInfo[UPDATE_VISIBILITY] = updateTypes.size(); + updateTypes.push_back( UpdateTypeInfo(UPDATE_VISIBILITY, "Visibility", true) ); + + stringToUpdateTypeInfo["Geometry"] = updateTypes.size(); + updateTypeToTypeInfo[UPDATE_GEOMETRY] = updateTypes.size(); + updateTypes.push_back( UpdateTypeInfo(UPDATE_GEOMETRY, "Geometry", true) ); + + stringToUpdateTypeInfo["Topology"] = updateTypes.size(); + updateTypeToTypeInfo[UPDATE_TOPOLOGY] = updateTypes.size(); + updateTypes.push_back( UpdateTypeInfo(UPDATE_TOPOLOGY, "Topology", true) ); + + stringToUpdateTypeInfo["Selection"] = updateTypes.size(); + updateTypeToTypeInfo[UPDATE_SELECTION] = updateTypes.size(); + updateTypes.push_back( UpdateTypeInfo(UPDATE_SELECTION, "Selection", true) ); + + + updateTypeToString[UPDATE_ALL] = "All"; + updateTypeToString[UPDATE_OBJECT_SELECTION] = "ObjectSelection"; + updateTypeToString[UPDATE_VISIBILITY] = "Visibility"; + updateTypeToString[UPDATE_GEOMETRY] = "Geometry"; + updateTypeToString[UPDATE_TOPOLOGY] = "Topology"; + updateTypeToString[UPDATE_SELECTION] = "Selection"; +} + +/// Adds a updateType and returns the id for the new type +UpdateType addUpdateType(QString _name, bool _resetNeeded) { + + //first check if it's already available + std::map::iterator index = stringToUpdateTypeInfo.find( _name ); + + if ( index != stringToUpdateTypeInfo.end() ) + return updateTypes[ index->second ].type; + else { + + unsigned int type = nextUpdateTypeId_; + + stringToUpdateTypeInfo[ _name ] = updateTypes.size(); + updateTypeToTypeInfo[ type ] = updateTypes.size(); + updateTypes.push_back( UpdateTypeInfo(type, _name, _resetNeeded ) ); + + updateTypeToString[type] = _name; + + nextUpdateTypeId_ *= 2; + return( type ); + } +} + +/// Get the id of a type with given name +UpdateType updateType(QString _name) { + + std::map::iterator index = stringToUpdateTypeInfo.find( _name ); + + if ( index != stringToUpdateTypeInfo.end() ) + return updateTypes[ index->second ].type; + else { + #ifdef DEBUG + std::cerr << "Unknown UpdateType with name " << _name.toStdString() << std::endl; + #endif + return UPDATE_ALL; + } +} + +/// Get the name of a type with given id +QString updateTypeName(UpdateType _id) { + + std::map::iterator name = updateTypeToString.find(_id); + + if ( name != updateTypeToString.end() ) + return name->second; + else { + #ifdef DEBUG + std::cerr << "Unable to retrieve updateTypeName for id " << _id << std::endl; + #endif + return "Unknown"; + } +} + +/// Return the number of registered types +uint updateTypeCount() { + return updateTypes.size(); +} \ No newline at end of file diff --git a/common/UpdateType.hh b/common/UpdateType.hh new file mode 100644 index 00000000..438d79d2 --- /dev/null +++ b/common/UpdateType.hh @@ -0,0 +1,50 @@ + +#ifndef UPDATETYPE_HH +#define UPDATETYPE_HH + +// TYPE + +typedef uint UpdateType; + + +/// Identifier for all updates +const UpdateType UPDATE_ALL(UINT_MAX); + +const UpdateType UPDATE_OBJECT_SELECTION(0); +const UpdateType UPDATE_VISIBILITY(1); +const UpdateType UPDATE_GEOMETRY(2); +const UpdateType UPDATE_TOPOLOGY(4); +const UpdateType UPDATE_SELECTION(8); + +// FUNCTIONS + +/** Adds a datatype and returns the id for the new type +* +* @param _name Internal name for the new DataType +* @param _readableName Human readable Name for this type ( Use tr to make it translatable ) +*/ +DLLEXPORT +UpdateType addUpdateType(QString _name); + +/// Given a dataType Identifier string this function will return the id of the datatype +DLLEXPORT +UpdateType updateType(QString _name); + +/** \brief Get the name of a type with given id +* +* The ids are organized in a bitfield. So use either the macro for getting the type id or +* use the id directly (they have to be power of 2! ... Bitfield) +*/ +DLLEXPORT +QString updateTypeName(UpdateType _id); + +/** \brief Get the number of registered types +* +* This function will return the number of types registered to the core. You can use it to +* iterate over all types. +*/ +DLLEXPORT +uint updateTypeCount(); + + +#endif // UPDATETYPE_HH -- GitLab