From: mpv Date: Thu, 22 May 2014 08:43:09 +0000 (+0400) Subject: Implementation of mechanism of grouping of messages X-Git-Tag: V_0.2~26^2~1^2^2~8 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;ds=sidebyside;h=fa5a0aa458d68a4d4c46c298c34c4e6b99b84dae;p=modules%2Fshaper.git Implementation of mechanism of grouping of messages --- diff --git a/src/Events/CMakeLists.txt b/src/Events/CMakeLists.txt index 89a27f31c..af4155f42 100644 --- a/src/Events/CMakeLists.txt +++ b/src/Events/CMakeLists.txt @@ -3,6 +3,7 @@ INCLUDE(Common) SET(PROJECT_HEADERS Events.h Events_Message.h + Events_MessageGroup.h Events_Listener.h Events_Loop.h Events_Error.h diff --git a/src/Events/Events_Loop.cpp b/src/Events/Events_Loop.cpp index 6c8bb4760..e8d6a716a 100644 --- a/src/Events/Events_Loop.cpp +++ b/src/Events/Events_Loop.cpp @@ -3,6 +3,7 @@ // Author: Mikhail PONIKAROV #include +#include #include #include @@ -34,7 +35,20 @@ Events_ID Events_Loop::eventByName(const char* theName) void Events_Loop::send(Events_Message& theMessage) { - // TO DO: make it in thread and wit husage of semaphores + // if it is grouped message, just accumulate it + Events_MessageGroup* aGroup = dynamic_cast(&theMessage); + if (aGroup) { + std::map::iterator aMyGroup = + myGroups.find(aGroup->eventID().eventText()); + if (aMyGroup == myGroups.end()) { // create a new group of messages for accumulation + myGroups[aGroup->eventID().eventText()] = aGroup->newEmpty(); + aMyGroup = myGroups.find(aGroup->eventID().eventText()); + } + aMyGroup->second->Join(*aGroup); + return; + } + + // TO DO: make it in thread and with usage of semaphores map > >::iterator aFindID = myListeners.find( theMessage.eventID().eventText()); @@ -80,3 +94,15 @@ void Events_Loop::registerListener(Events_Listener* theListener, const Events_ID aListeners.push_back(theListener); } + +void Events_Loop::flush(const Events_ID& theID) +{ + std::map::iterator aMyGroup = + myGroups.find(theID.eventText()); + if (aMyGroup != myGroups.end()) { // really sends + Events_MessageGroup* aGroup = aMyGroup->second; + send(*aGroup); + myGroups.erase(aMyGroup); + delete aGroup; + } +} diff --git a/src/Events/Events_Loop.h b/src/Events/Events_Loop.h index 893ecb199..f5721c8b4 100644 --- a/src/Events/Events_Loop.h +++ b/src/Events/Events_Loop.h @@ -11,6 +11,8 @@ #include #include +class Events_MessageGroup; + /**\class Events_Lopp * \ingroup EventsLoop * \brief Base class that manages the receiving and sending of all @@ -22,8 +24,12 @@ * control back immideately. */ class Events_Loop { + /// map from event ID to sender pointer to listeners that must be called for this std::map > > - myListeners; ///< map from event ID to sender pointer to listeners that must be called for this + myListeners; + + /// map from event ID to groupped messages (accumulated on flush) + std::map myGroups; //! The empty constructor, will be called at startup of the application, only once Events_Loop() {}; @@ -41,6 +47,9 @@ public: //! that will be called on the event and from the defined sender EVENTS_EXPORT void registerListener(Events_Listener* theListener, const Events_ID theID, void* theSender = 0); + + //! Initializes sending of a group-message by the given ID + EVENTS_EXPORT void flush(const Events_ID& theID); }; #endif diff --git a/src/Events/Events_MessageGroup.h b/src/Events/Events_MessageGroup.h new file mode 100644 index 000000000..b95f64d87 --- /dev/null +++ b/src/Events/Events_MessageGroup.h @@ -0,0 +1,33 @@ +// File: Events_MessageGroup.hxx +// Created: Thu Mar 13 2014 +// Author: Mikhail PONIKAROV + +#ifndef Events_MessageGroup_HeaderFile +#define Events_MessageGroup_HeaderFile + +#include + +/**\class Events_Message + * \ingroup EventsLoop + * \brief Message that allows to group messages and send them later as a group of messages. + * + * Loop detects such messages and accumulates them without sending. On "flush" loop sends it + * as a group-message. + */ +class EVENTS_EXPORT Events_MessageGroup : public Events_Message { + +public: + + //! Creates the message + Events_MessageGroup(const Events_ID theID, const void* theSender = 0) + : Events_Message(theID, theSender) {} + //! do nothing in the destructor yet + virtual ~Events_MessageGroup() {} + + //! Creates a new empty group (to store it in the loop before flush) + virtual Events_MessageGroup* newEmpty() = 0; + //! Allows to join the given message with the current one + virtual void Join(Events_MessageGroup& theJoined) = 0; +}; + +#endif diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 37f1a8673..67953331d 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -593,4 +593,7 @@ void Model_Document::synchronizeFeatures() aFLabIter.Next(); } } + // after all updates, sends a message that groups of features were created or updated + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_CREATED)); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_DELETED)); } diff --git a/src/Model/Model_Events.cpp b/src/Model/Model_Events.cpp index cbf485997..76655e1ee 100644 --- a/src/Model/Model_Events.cpp +++ b/src/Model/Model_Events.cpp @@ -5,38 +5,46 @@ #include #include -Model_FeatureDeletedMessage::Model_FeatureDeletedMessage( - const boost::shared_ptr& theDoc, const std::string& theGroup) - : Events_Message(messageId(), 0), myDoc(theDoc), myGroup(theGroup) - -{ +// UPDATED methods +Events_MessageGroup* Model_FeatureUpdatedMessage::newEmpty() { + boost::shared_ptr anEmptyFeature; + return new Model_FeatureUpdatedMessage(anEmptyFeature, eventID()); } -const Events_ID Model_FeatureDeletedMessage::messageId() +void Model_FeatureUpdatedMessage::Join(Events_MessageGroup& theJoined) { - static Events_ID MY_ID = Events_Loop::eventByName(EVENT_FEATURE_DELETED); - return MY_ID; + Model_FeatureUpdatedMessage* aJoined = dynamic_cast(&theJoined); + std::set >::iterator aFIter = aJoined->myFeatures.begin(); + for(; aFIter != aJoined->myFeatures.end(); aFIter++) { + myFeatures.insert(*aFIter); + } } -Model_FeaturesMovedMessage::Model_FeaturesMovedMessage() -: Events_Message(messageId(), 0) -{ +// DELETED methods +Events_MessageGroup* Model_FeatureDeletedMessage::newEmpty() { + return new Model_FeatureDeletedMessage(myDoc, ""); } -const Events_ID Model_FeaturesMovedMessage::messageId() +Model_FeatureDeletedMessage::Model_FeatureDeletedMessage( + const boost::shared_ptr& theDoc, const std::string& theGroup) + : Events_MessageGroup(messageId(), 0), myDoc(theDoc) + { - static Events_ID MY_ID = Events_Loop::eventByName(EVENT_FEATURES_MOVED); - return MY_ID; + if (!theGroup.empty()) + myGroups.insert(theGroup); } -void Model_FeaturesMovedMessage::setFeatures( - const std::list >& theFeatures) +const Events_ID Model_FeatureDeletedMessage::messageId() { - myFeatures = theFeatures; + static Events_ID MY_ID = Events_Loop::eventByName(EVENT_FEATURE_DELETED); + return MY_ID; } -const std::list >& Model_FeaturesMovedMessage::features() const +void Model_FeatureDeletedMessage::Join(Events_MessageGroup& theJoined) { - return myFeatures; + Model_FeatureDeletedMessage* aJoined = dynamic_cast(&theJoined); + std::set::iterator aGIter = aJoined->myGroups.begin(); + for(; aGIter != aJoined->myGroups.end(); aGIter++) { + myGroups.insert(*aGIter); + } } - diff --git a/src/Model/Model_Events.h b/src/Model/Model_Events.h index c9c60b65f..0e750f5a6 100644 --- a/src/Model/Model_Events.h +++ b/src/Model/Model_Events.h @@ -6,11 +6,11 @@ #define Model_Events_HeaderFile #include -#include +#include #include #include #include -#include +#include class ModelAPI_Feature; class ModelAPI_Document; @@ -24,24 +24,29 @@ static const char * EVENT_FEATURE_DELETED = "FeatureDeleted"; /// Event ID that data of feature is updated (comes with Model_FeaturesMovedMessage) static const char * EVENT_FEATURES_MOVED = "FeaturesMoved"; -/// Message that feature was changed (used for Object Browser update) -class Model_FeatureUpdatedMessage : public Events_Message { - boost::shared_ptr myFeature; ///< which feature is changed +/// Message that feature was changed (used for Object Browser update): moved, updated and deleted +class Model_FeatureUpdatedMessage : public Events_MessageGroup { + std::set > myFeatures; ///< which feature is changed public: /// sender is not important, all information is located in the feature Model_FeatureUpdatedMessage( const boost::shared_ptr& theFeature, - const Events_ID& theEvent) : Events_Message(theEvent, 0), myFeature(theFeature) - {} + const Events_ID& theEvent) : Events_MessageGroup(theEvent, 0) + {if (theFeature) myFeatures.insert(theFeature);} /// Returns the feature that has been updated - boost::shared_ptr feature() const {return myFeature;} + std::set > features() const {return myFeatures;} + + //! Creates a new empty group (to store it in the loop before flush) + virtual Events_MessageGroup* newEmpty(); + //! Allows to join the given message with the current one + virtual void Join(Events_MessageGroup& theJoined); }; /// Message that feature was deleted (used for Object Browser update) -class Model_FeatureDeletedMessage : public Events_Message { +class Model_FeatureDeletedMessage : public Events_MessageGroup { boost::shared_ptr myDoc; ///< document owner of the feature - std::string myGroup; ///< group identifier that contained the deleted feature + std::set myGroups; ///< group identifiers that contained the deleted feature public: /// creates a message by initialization of fields Model_FeatureDeletedMessage(const boost::shared_ptr& theDoc, @@ -54,24 +59,13 @@ public: boost::shared_ptr document() const {return myDoc;} /// Returns the group where the feature was deleted - const std::string& group() const {return myGroup;} -}; - -/// Message that features were moved (used for the feature preview update) -class Model_FeaturesMovedMessage : public Events_Message { - std::list > myFeatures; ///< which features are moved -public: - /// creates a message by initialization of fields - MODEL_EXPORT Model_FeaturesMovedMessage(); - - /// Returns the ID of this message (EVENT_FEATURES_MOVED) - static const Events_ID messageId(); + const std::set& groups() const {return myGroups;} - /// Sets a list of features - MODEL_EXPORT void setFeatures(const std::list >& theFeatures); + //! Creates a new empty group (to store it in the loop before flush) + virtual Events_MessageGroup* newEmpty(); - /// Returns a list of features - MODEL_EXPORT const std::list >& features() const; + //! Allows to join the given message with the current one + virtual void Join(Events_MessageGroup& theJoined); }; #endif