+
+void Events_Loop::removeListener(Events_Listener* theListener)
+{
+ // remove the listener in myListeners map
+ std::map<char*, std::map<void*, std::list<Events_Listener*> > >::const_reverse_iterator
+ anIt = myListeners.rbegin();
+ while(anIt != myListeners.rend()) {
+ std::map<void*, std::list<Events_Listener*> > aLMap = anIt->second;
+ std::map<void*, std::list<Events_Listener*> >::const_reverse_iterator aLIt = aLMap.rbegin();
+ while (aLIt != aLMap.rend()) {
+ std::list<Events_Listener*> aListeners = aLIt->second;
+ std::list<Events_Listener*>::const_reverse_iterator aLsIt = aListeners.rbegin();
+ for (; aLsIt != aListeners.rend(); aLsIt++) {
+ if (*aLsIt == theListener) {
+ aListeners.remove(theListener);
+ aLMap[aLIt->first] = aListeners;
+ myListeners[anIt->first] = aLMap;
+ break;
+ }
+ }
+ if (aListeners.empty()) {
+ aLMap.erase(aLIt->first);
+ myListeners[anIt->first] = aLMap;
+ if (aLMap.empty())
+ break; // avoid incrementation of the iterator if the container is empty
+ }
+ aLIt++;
+ }
+ if (anIt->second.empty()) {
+ myListeners.erase(anIt->first);
+ if (myListeners.empty())
+ break; // avoid incrementation of the iterator if the container is empty
+ }
+ anIt++;
+ }
+
+ // remove the listener in myImmediateListeners map
+ std::map<char*, Events_Listener*>::const_reverse_iterator anImIt = myImmediateListeners.rbegin();
+ while(anImIt != myImmediateListeners.rend()) {
+ if (anImIt->second == theListener) {
+ myImmediateListeners.erase(anImIt->first);
+ if (myImmediateListeners.empty())
+ break; // avoid incrementation of the iterator if the container is empty
+ }
+ anImIt++;
+ }
+}
+
+void Events_Loop::flush(const Events_ID& theID)
+{
+ if (!myFlushActive)
+ return;
+ bool hasEventsToFlush = !myGroups.empty();
+ std::map<char*, std::shared_ptr<Events_Message> >::iterator aMyGroup;
+ for(aMyGroup = myGroups.find(theID.eventText());
+ aMyGroup != myGroups.end(); aMyGroup = myGroups.find(theID.eventText()))
+ { // really sends
+ bool aWasFlushed = myFlushed.find(theID.myID) != myFlushed.end();
+ if (!aWasFlushed)
+ myFlushed.insert(theID.myID);
+ std::shared_ptr<Events_Message> aGroup = aMyGroup->second;
+ myGroups.erase(aMyGroup);
+ send(aGroup, false);
+
+ if (!aWasFlushed) {
+ // TODO: Stabilization fix. Check later.
+ if(myFlushed.find(theID.myID) != myFlushed.end()) {
+ myFlushed.erase(myFlushed.find(theID.myID));
+ }
+#ifdef _DEBUG
+ else {
+ bool aProblem = true;
+ }
+#endif
+ }
+ // send accumulated messages to "groupListeners"
+ std::map<char*, std::map<void*, std::list<Events_Listener*> > >::iterator aFindID =
+ myListeners.find(theID.eventText());
+ if (aFindID != myListeners.end()) {
+ std::map<void*, std::list<Events_Listener*> >::iterator aFindSender =
+ aFindID->second.begin();
+ for(; aFindSender != aFindID->second.end(); aFindSender++) {
+ std::list<Events_Listener*>::iterator aListener = aFindSender->second.begin();
+ for(; aListener != aFindSender->second.end(); aListener++) {
+ if ((*aListener)->groupMessages()) {
+ (*aListener)->flushGrouped(theID);
+ }
+ }
+ }
+ }
+ }
+ if (hasEventsToFlush && myGroups.empty() && myFlushed.empty()) {
+ // no more messages left in the queue, so, finalize the sketch processing
+ static Events_ID anID = Events_Loop::eventByName("SketchPrepared");
+ std::shared_ptr<Events_Message> aMsg(new Events_Message(anID, this));
+ Events_Loop::loop()->send(aMsg, false);
+ }
+}
+
+void Events_Loop::eraseMessages(const Events_ID& theID)
+{
+ std::map<char*, std::shared_ptr<Events_Message> >::iterator aMyGroup =
+ myGroups.find(theID.eventText());
+ if (aMyGroup != myGroups.end()) {
+ myGroups.erase(aMyGroup);
+ }
+}
+
+
+bool Events_Loop::activateFlushes(const bool theActivate)
+{
+ bool isActive = myFlushActive;
+ myFlushActive = theActivate;
+ return isActive;
+}
+
+void Events_Loop::clear(const Events_ID& theID)
+{
+ std::map<char*, std::shared_ptr<Events_Message>>::iterator aMyGroup =
+ myGroups.find(theID.eventText());
+ if (aMyGroup != myGroups.end()) { // really sends
+ myGroups.erase(aMyGroup);
+ }
+}
+
+bool Events_Loop::isFlushed(const Events_ID& theID)
+{
+ return myFlushed.find(theID.myID) != myFlushed.end();
+}
+
+void Events_Loop::setFlushed(const Events_ID& theID, const bool theValue)
+{
+ if (theValue)
+ myFlushed.insert(theID.myID);
+ else
+ myFlushed.erase(myFlushed.find(theID.myID));
+}
+
+bool Events_Loop::hasGrouppedEvent(const Events_ID& theID)
+{
+ return myGroups.find(theID.myID) != myGroups.end();
+}
\ No newline at end of file