SET(PROJECT_HEADERS
Events.h
Events_Message.h
+ Events_MessageGroup.h
Events_Listener.h
Events_Loop.h
Events_Error.h
// Author: Mikhail PONIKAROV
#include <Events_Loop.h>
+#include <Events_MessageGroup.h>
#include <string>
#include <cstring>
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<Events_MessageGroup*>(&theMessage);
+ if (aGroup) {
+ std::map<char*, Events_MessageGroup*>::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<char*, map<void*, list<Events_Listener*> > >::iterator aFindID = myListeners.find(
theMessage.eventID().eventText());
aListeners.push_back(theListener);
}
+
+void Events_Loop::flush(const Events_ID& theID)
+{
+ std::map<char*, Events_MessageGroup*>::iterator aMyGroup =
+ myGroups.find(theID.eventText());
+ if (aMyGroup != myGroups.end()) { // really sends
+ Events_MessageGroup* aGroup = aMyGroup->second;
+ send(*aGroup);
+ myGroups.erase(aMyGroup);
+ delete aGroup;
+ }
+}
#include <map>
#include <list>
+class Events_MessageGroup;
+
/**\class Events_Lopp
* \ingroup EventsLoop
* \brief Base class that manages the receiving and sending of all
* control back immideately.
*/
class Events_Loop {
+ /// map from event ID to sender pointer to listeners that must be called for this
std::map<char*, std::map<void*, std::list<Events_Listener*> > >
- 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<char*, Events_MessageGroup*> myGroups;
//! The empty constructor, will be called at startup of the application, only once
Events_Loop() {};
//! 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
--- /dev/null
+// File: Events_MessageGroup.hxx
+// Created: Thu Mar 13 2014
+// Author: Mikhail PONIKAROV
+
+#ifndef Events_MessageGroup_HeaderFile
+#define Events_MessageGroup_HeaderFile
+
+#include <Events_Message.h>
+
+/**\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
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));
}
#include <Model_Events.h>
#include <Events_Loop.h>
-Model_FeatureDeletedMessage::Model_FeatureDeletedMessage(
- const boost::shared_ptr<ModelAPI_Document>& theDoc, const std::string& theGroup)
- : Events_Message(messageId(), 0), myDoc(theDoc), myGroup(theGroup)
-
-{
+// UPDATED methods
+Events_MessageGroup* Model_FeatureUpdatedMessage::newEmpty() {
+ boost::shared_ptr<ModelAPI_Feature> 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<Model_FeatureUpdatedMessage*>(&theJoined);
+ std::set<boost::shared_ptr<ModelAPI_Feature> >::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<ModelAPI_Document>& 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<boost::shared_ptr<ModelAPI_Feature> >& 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<boost::shared_ptr<ModelAPI_Feature> >& Model_FeaturesMovedMessage::features() const
+void Model_FeatureDeletedMessage::Join(Events_MessageGroup& theJoined)
{
- return myFeatures;
+ Model_FeatureDeletedMessage* aJoined = dynamic_cast<Model_FeatureDeletedMessage*>(&theJoined);
+ std::set<std::string>::iterator aGIter = aJoined->myGroups.begin();
+ for(; aGIter != aJoined->myGroups.end(); aGIter++) {
+ myGroups.insert(*aGIter);
+ }
}
-
#define Model_Events_HeaderFile
#include <Model.h>
-#include <Events_Message.h>
+#include <Events_MessageGroup.h>
#include <Events_Loop.h>
#include <boost/shared_ptr.hpp>
#include <string>
-#include <list>
+#include <set>
class ModelAPI_Feature;
class ModelAPI_Document;
/// 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<ModelAPI_Feature> 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<boost::shared_ptr<ModelAPI_Feature> > myFeatures; ///< which feature is changed
public:
/// sender is not important, all information is located in the feature
Model_FeatureUpdatedMessage(
const boost::shared_ptr<ModelAPI_Feature>& 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<ModelAPI_Feature> feature() const {return myFeature;}
+ std::set<boost::shared_ptr<ModelAPI_Feature> > 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<ModelAPI_Document> myDoc; ///< document owner of the feature
- std::string myGroup; ///< group identifier that contained the deleted feature
+ std::set<std::string> myGroups; ///< group identifiers that contained the deleted feature
public:
/// creates a message by initialization of fields
Model_FeatureDeletedMessage(const boost::shared_ptr<ModelAPI_Document>& theDoc,
boost::shared_ptr<ModelAPI_Document> 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<boost::shared_ptr<ModelAPI_Feature> > 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<std::string >& groups() const {return myGroups;}
- /// Sets a list of features
- MODEL_EXPORT void setFeatures(const std::list<boost::shared_ptr<ModelAPI_Feature> >& 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<boost::shared_ptr<ModelAPI_Feature> >& features() const;
+ //! Allows to join the given message with the current one
+ virtual void Join(Events_MessageGroup& theJoined);
};
#endif