X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FEvents%2FEvents_Loop.cpp;h=e68798aa43c31f7e341af66bd32d60aba00f37f0;hb=42cd47b33727c9b7f02b43960f8b2633001942ae;hp=6c8bb476070ed381339cef59b6a08774678a1f95;hpb=f11baf398313d8250c878ef7923879c527d1c0e1;p=modules%2Fshaper.git diff --git a/src/Events/Events_Loop.cpp b/src/Events/Events_Loop.cpp index 6c8bb4760..e68798aa4 100644 --- a/src/Events/Events_Loop.cpp +++ b/src/Events/Events_Loop.cpp @@ -1,8 +1,11 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + // File: Events_Loop.hxx // Created: Thu Mar 13 2014 // Author: Mikhail PONIKAROV #include +#include #include #include @@ -23,8 +26,12 @@ Events_ID Events_Loop::eventByName(const char* theName) char* aResult; string aName(theName); map::iterator aFound = CREATED_EVENTS.find(aName); - if (aFound == CREATED_EVENTS.end()) { //not created yet - aResult = strdup(theName); // copy to make unique internal pointer + if (aFound == CREATED_EVENTS.end()) { //not created yet +#ifdef WIN32 + aResult = _strdup(theName); // copy to make unique internal pointer +#else + aResult = strdup(theName); // copy to make unique internal pointer +#endif CREATED_EVENTS[aName] = aResult; } else aResult = aFound->second; @@ -32,51 +39,191 @@ Events_ID Events_Loop::eventByName(const char* theName) return Events_ID(aResult); } -void Events_Loop::send(Events_Message& theMessage) +void Events_Loop::send(const std::shared_ptr& theMessage, bool isGroup) { - // TO DO: make it in thread and wit husage of semaphores + if (myImmediateListeners.find(theMessage->eventID().eventText()) != myImmediateListeners.end()) { + myImmediateListeners[theMessage->eventID().eventText()]->processEvent(theMessage); + } + // if it is grouped message, just accumulate it + if (isGroup && myFlushed.find(theMessage->eventID().myID) == myFlushed.end()) { + std::shared_ptr aGroup = + std::dynamic_pointer_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()); + } + std::shared_ptr aStored = + std::dynamic_pointer_cast(aMyGroup->second); + aStored->Join(aGroup); + return; + } + } map > >::iterator aFindID = myListeners.find( - theMessage.eventID().eventText()); + theMessage->eventID().eventText()); if (aFindID != myListeners.end()) { map >::iterator aFindSender = aFindID->second.find( - theMessage.sender()); + theMessage->sender()); if (aFindSender != aFindID->second.end()) { list& aListeners = aFindSender->second; - for(list::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++) - (*aL)->processEvent(&theMessage); + for (list::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++) + (*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& aListeners = aFindSender->second; - for(list::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++) - (*aL)->processEvent(&theMessage); + for (list::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++) + (*aL)->processEvent(theMessage); } } } } void Events_Loop::registerListener(Events_Listener* theListener, const Events_ID theID, - void* theSender) + void* theSender, bool theImmediate) { + if (theImmediate) { // just register as an immediate + myImmediateListeners[theID.eventText()] = theListener; + return; + } map > >::iterator aFindID = myListeners.find( theID.eventText()); - if (aFindID == myListeners.end()) { // create container associated with ID + if (aFindID == myListeners.end()) { // create container associated with ID myListeners[theID.eventText()] = map >(); aFindID = myListeners.find(theID.eventText()); } map >::iterator aFindSender = aFindID->second.find(theSender); - if (aFindSender == aFindID->second.end()) { // create container associated with sender + if (aFindSender == aFindID->second.end()) { // create container associated with sender aFindID->second[theSender] = list(); aFindSender = aFindID->second.find(theSender); } // check that listener was not registered wit hsuch parameters before list& aListeners = aFindSender->second; - for(list::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++) + for (list::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++) if (*aL == theListener) - return; // avoid duplicates + return; // avoid duplicates aListeners.push_back(theListener); } + +void Events_Loop::removeListener(Events_Listener* theListener) +{ + // remove the listener in myListeners map + std::map > >::const_reverse_iterator + anIt = myListeners.rbegin(); + while(anIt != myListeners.rend()) { + std::map > aLMap = anIt->second; + std::map >::const_reverse_iterator aLIt = aLMap.rbegin(); + while (aLIt != aLMap.rend()) { + std::list aListeners = aLIt->second; + std::list::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 the container is empty + } + aLIt++; + } + if (anIt->second.empty()) { + myListeners.erase(anIt->first); + if (myListeners.empty()) + break; // avoid incrementation of the iterator if the the container is empty + } + anIt++; + } + + // remove the listener in myImmediateListeners map + std::map::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 the container is empty + } + anImIt++; + } +} + +void Events_Loop::flush(const Events_ID& theID) +{ + if (!myFlushActive) + return; + std::map >::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 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)); + } + } +} + +void Events_Loop::eraseMessages(const Events_ID& theID) +{ + std::map >::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>::iterator aMyGroup = + myGroups.find(theID.eventText()); + if (aMyGroup != myGroups.end()) { // really sends + myGroups.erase(aMyGroup); + } +} + +void Events_Loop::autoFlush(const Events_ID& theID, const bool theAuto) +{ + if (theAuto) + myFlushed.insert(theID.myID); + else + myFlushed.erase(myFlushed.find(theID.myID)); +} + +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)); +}