]> SALOME platform Git repositories - modules/shaper.git/blob - src/Events/Events_Loop.cpp
Salome HOME
Fix for the issue #1647 : problem with OB when sub-features are created.
[modules/shaper.git] / src / Events / Events_Loop.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        Events_Loop.hxx
4 // Created:     Thu Mar 13 2014
5 // Author:      Mikhail PONIKAROV
6
7 #include <Events_Loop.h>
8 #include <Events_MessageGroup.h>
9
10 #include <string>
11 #include <cstring>
12
13 using namespace std;
14
15 Events_Loop* Events_Loop::loop()
16 {
17   // initialized on initialization of the application
18   static Events_Loop MAIN_LOOP;
19   return &MAIN_LOOP;
20 }
21
22 Events_ID Events_Loop::eventByName(const char* theName)
23 {
24   ///! All events created in this session, uniquely identified by the text and char pointer
25   static map<string, char*> CREATED_EVENTS;
26   char* aResult;
27   string aName(theName);
28   map<string, char*>::iterator aFound = CREATED_EVENTS.find(aName);
29   if (aFound == CREATED_EVENTS.end()) {  //not created yet
30 #ifdef WIN32
31     aResult = _strdup(theName);  // copy to make unique internal pointer
32 #else
33     aResult = strdup(theName);  // copy to make unique internal pointer
34 #endif
35     CREATED_EVENTS[aName] = aResult;
36   } else
37     aResult = aFound->second;
38
39   return Events_ID(aResult);
40 }
41
42 void Events_Loop::send(const std::shared_ptr<Events_Message>& theMessage, bool isGroup)
43 {
44   if (myImmediateListeners.find(theMessage->eventID().eventText()) != myImmediateListeners.end()) {
45     myImmediateListeners[theMessage->eventID().eventText()]->processEvent(theMessage);
46   }
47   // if it is grouped message, just accumulate it
48   if (isGroup && myFlushed.find(theMessage->eventID().myID) == myFlushed.end()) {
49     std::shared_ptr<Events_MessageGroup> aGroup = 
50       std::dynamic_pointer_cast<Events_MessageGroup>(theMessage);
51     if (aGroup) {
52       std::map<char*, std::shared_ptr<Events_Message> >::iterator aMyGroup = myGroups.find(
53           aGroup->eventID().eventText());
54       if (aMyGroup == myGroups.end()) {  // create a new group of messages for accumulation
55         myGroups[aGroup->eventID().eventText()] = aGroup->newEmpty();
56         aMyGroup = myGroups.find(aGroup->eventID().eventText());
57       }
58       std::shared_ptr<Events_MessageGroup> aStored =
59         std::dynamic_pointer_cast<Events_MessageGroup>(aMyGroup->second);
60       aStored->Join(aGroup);
61       return;
62     }
63   }
64
65   map<char*, map<void*, list<Events_Listener*> > >::iterator aFindID = myListeners.find(
66       theMessage->eventID().eventText());
67   if (aFindID != myListeners.end()) {
68     map<void*, list<Events_Listener*> >::iterator aFindSender = aFindID->second.find(
69         theMessage->sender());
70     if (aFindSender != aFindID->second.end()) {
71       list<Events_Listener*>& aListeners = aFindSender->second;
72       for (list<Events_Listener*>::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++)
73         (*aL)->processEvent(theMessage);
74     }
75     if (theMessage->sender()) {  // also call for NULL senders registered
76       aFindSender = aFindID->second.find(NULL);
77       if (aFindSender != aFindID->second.end()) {
78         list<Events_Listener*>& aListeners = aFindSender->second;
79         for (list<Events_Listener*>::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++)
80           (*aL)->processEvent(theMessage);
81       }
82     }
83   }
84 }
85
86 void Events_Loop::registerListener(Events_Listener* theListener, const Events_ID theID,
87                                    void* theSender, bool theImmediate)
88 {
89   if (theImmediate) { // just register as an immediate
90     myImmediateListeners[theID.eventText()] = theListener;
91     return;
92   }
93   map<char*, map<void*, list<Events_Listener*> > >::iterator aFindID = myListeners.find(
94       theID.eventText());
95   if (aFindID == myListeners.end()) {  // create container associated with ID
96     myListeners[theID.eventText()] = map<void*, list<Events_Listener*> >();
97     aFindID = myListeners.find(theID.eventText());
98   }
99
100   map<void*, list<Events_Listener*> >::iterator aFindSender = aFindID->second.find(theSender);
101   if (aFindSender == aFindID->second.end()) {  // create container associated with sender
102     aFindID->second[theSender] = list<Events_Listener*>();
103     aFindSender = aFindID->second.find(theSender);
104   }
105   // check that listener was not registered wit hsuch parameters before
106   list<Events_Listener*>& aListeners = aFindSender->second;
107   for (list<Events_Listener*>::iterator aL = aListeners.begin(); aL != aListeners.end(); aL++)
108     if (*aL == theListener)
109       return;  // avoid duplicates
110
111   aListeners.push_back(theListener);
112 }
113
114 void Events_Loop::removeListener(Events_Listener* theListener)
115 {
116   // remove the listener in myListeners map
117   std::map<char*, std::map<void*, std::list<Events_Listener*> > >::const_reverse_iterator
118                                                           anIt = myListeners.rbegin();
119   while(anIt != myListeners.rend()) {
120     std::map<void*, std::list<Events_Listener*> > aLMap = anIt->second;
121     std::map<void*, std::list<Events_Listener*> >::const_reverse_iterator aLIt = aLMap.rbegin();
122     while (aLIt != aLMap.rend()) {
123       std::list<Events_Listener*> aListeners = aLIt->second;
124       std::list<Events_Listener*>::const_reverse_iterator aLsIt = aListeners.rbegin();
125       for (; aLsIt != aListeners.rend(); aLsIt++) {
126         if (*aLsIt == theListener) {
127           aListeners.remove(theListener);
128           aLMap[aLIt->first] = aListeners;
129           myListeners[anIt->first] = aLMap;
130           break;
131         }
132       }
133       if (aListeners.empty()) {
134         aLMap.erase(aLIt->first);
135         myListeners[anIt->first] = aLMap;
136         if (aLMap.empty())
137           break; // avoid incrementation of the iterator if the the container is empty
138       }
139       aLIt++;
140     }
141     if (anIt->second.empty()) {
142       myListeners.erase(anIt->first);
143       if (myListeners.empty())
144         break; // avoid incrementation of the iterator if the the container is empty
145     }
146     anIt++;
147   }
148
149   // remove the listener in myImmediateListeners map
150   std::map<char*, Events_Listener*>::const_reverse_iterator anImIt = myImmediateListeners.rbegin();
151   while(anImIt != myImmediateListeners.rend()) {
152     if (anImIt->second == theListener) {
153       myImmediateListeners.erase(anImIt->first);
154       if (myImmediateListeners.empty())
155         break; // avoid incrementation of the iterator if the the container is empty
156     }
157     anImIt++;
158   }
159 }
160
161 void Events_Loop::flush(const Events_ID& theID)
162 {
163   if (!myFlushActive)
164     return;
165   std::map<char*, std::shared_ptr<Events_Message> >::iterator aMyGroup;
166   for(aMyGroup = myGroups.find(theID.eventText());
167     aMyGroup != myGroups.end(); aMyGroup = myGroups.find(theID.eventText()))
168   {  // really sends
169     bool aWasFlushed = myFlushed.find(theID.myID) != myFlushed.end();
170     if (!aWasFlushed)
171       myFlushed.insert(theID.myID);
172     std::shared_ptr<Events_Message> aGroup = aMyGroup->second;
173     myGroups.erase(aMyGroup);
174     send(aGroup, false);
175
176     if (!aWasFlushed)
177       // TODO: Stabilization fix. Check later.
178       if(myFlushed.find(theID.myID) != myFlushed.end()) {
179         myFlushed.erase(myFlushed.find(theID.myID));
180       }
181   }
182 }
183
184 void Events_Loop::eraseMessages(const Events_ID& theID)
185 {
186   std::map<char*, std::shared_ptr<Events_Message> >::iterator aMyGroup =
187     myGroups.find(theID.eventText());
188   if (aMyGroup != myGroups.end()) {
189     myGroups.erase(aMyGroup);
190   }
191 }
192
193
194 bool Events_Loop::activateFlushes(const bool theActivate)
195 {
196   bool isActive = myFlushActive;
197   myFlushActive = theActivate;
198   return isActive;
199 }
200
201 void Events_Loop::clear(const Events_ID& theID)
202 {
203   std::map<char*, std::shared_ptr<Events_Message>>::iterator aMyGroup =
204     myGroups.find(theID.eventText());
205   if (aMyGroup != myGroups.end()) {  // really sends
206     myGroups.erase(aMyGroup);
207   }
208 }
209
210 void Events_Loop::autoFlush(const Events_ID& theID, const bool theAuto)
211 {
212   if (theAuto)
213     myFlushed.insert(theID.myID);
214   else
215     myFlushed.erase(myFlushed.find(theID.myID));
216 }
217
218 bool Events_Loop::isFlushed(const Events_ID& theID)
219 {
220   return myFlushed.find(theID.myID) != myFlushed.end();
221 }
222
223 void Events_Loop::setFlushed(const Events_ID& theID, const bool theValue)
224 {
225   if (theValue)
226     myFlushed.insert(theID.myID);
227   else
228     myFlushed.erase(myFlushed.find(theID.myID));
229 }