1 /*
2  Copyright (C) 2010-2014 Kristian Duske
3 
4  This file is part of TrenchBroom.
5 
6  TrenchBroom is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  TrenchBroom is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef TrenchBroom_Notifier_h
21 #define TrenchBroom_Notifier_h
22 
23 #include "CollectionUtils.h"
24 #include "Exceptions.h"
25 #include "SetAny.h"
26 
27 #include <algorithm>
28 #include <cassert>
29 #include <list>
30 
31 namespace TrenchBroom {
32     template <typename O>
33     class NotifierState {
34     private:
35         struct CompareObservers {
36         private:
37             const O* m_lhs;
38         public:
CompareObserversCompareObservers39             CompareObservers(const O* lhs) : m_lhs(lhs) {}
operatorCompareObservers40             bool operator()(const O* rhs) const {
41                 return (*m_lhs) == (*rhs);
42             }
43         };
44 
45         typedef std::list<O*> List;
46 
47         List m_observers;
48         List m_toAdd;
49         List m_toRemove;
50 
51         bool m_notifying;
52     public:
NotifierState()53         NotifierState() : m_notifying(false) {}
~NotifierState()54         ~NotifierState() {
55             ListUtils::clearAndDelete(m_observers);
56             ListUtils::clearAndDelete(m_toAdd);
57             ListUtils::clearAndDelete(m_toRemove);
58         }
59 
addObserver(O * observer)60         bool addObserver(O* observer) {
61             if (!m_observers.empty()) {
62                 typename List::iterator it = std::find_if(m_observers.begin(), m_observers.end(), CompareObservers(observer));
63                 if (it != m_observers.end()) {
64                     delete observer;
65                     return false;
66                 }
67             }
68 
69             if (m_notifying)
70                 m_toAdd.push_back(observer);
71             else
72                 m_observers.push_back(observer);
73             return true;
74         }
75 
removeObserver(O * observer)76         bool removeObserver(O* observer) {
77             typename List::iterator it = std::find_if(m_observers.begin(), m_observers.end(), CompareObservers(observer));
78             if (it == m_observers.end()) {
79                 delete observer;
80                 return false;
81             } else {
82                 (*it)->setSkip();
83             }
84 
85             if (m_notifying) {
86                 m_toRemove.push_back(observer);
87             } else {
88                 delete observer;
89                 delete *it;
90                 m_observers.erase(it);
91             }
92 
93             return true;
94         }
95 
notify()96         void notify() {
97             const SetBool notifying(m_notifying);
98 
99             typename List::const_iterator it, end;
100             for (it = m_observers.begin(), end = m_observers.end(); it != end; ++it) {
101                 O& observer = **it;
102                 if (!observer.skip())
103                     observer();
104             }
105 
106             removePending();
107             addPending();
108         }
109 
110         template <typename A1>
notify(A1 a1)111         void notify(A1 a1) {
112             const SetBool notifying(m_notifying);
113 
114             typename List::const_iterator it, end;
115             for (it = m_observers.begin(), end = m_observers.end(); it != end; ++it) {
116                 O& observer = **it;
117                 if (!observer.skip())
118                     observer(a1);
119             }
120 
121             removePending();
122             addPending();
123         }
124 
125         template <typename A1, typename A2>
notify(A1 a1,A2 a2)126         void notify(A1 a1, A2 a2) {
127             const SetBool notifying(m_notifying);
128 
129             typename List::const_iterator it, end;
130             for (it = m_observers.begin(), end = m_observers.end(); it != end; ++it) {
131                 O& observer = **it;
132                 if (!observer.skip())
133                     observer(a1, a2);
134             }
135 
136             removePending();
137             addPending();
138         }
139 
140         template <typename A1, typename A2, typename A3>
notify(A1 a1,A2 a2,A3 a3)141         void notify(A1 a1, A2 a2, A3 a3) {
142             const SetBool notifying(m_notifying);
143 
144             typename List::const_iterator it, end;
145             for (it = m_observers.begin(), end = m_observers.end(); it != end; ++it) {
146                 O& observer = **it;
147                 if (!observer.skip())
148                     observer(a1, a2, a3);
149             }
150 
151             removePending();
152             addPending();
153         }
154 
155         template <typename A1, typename A2, typename A3, typename A4>
notify(A1 a1,A2 a2,A3 a3,A4 a4)156         void notify(A1 a1, A2 a2, A3 a3, A4 a4) {
157             const SetBool notifying(m_notifying);
158 
159             typename List::const_iterator it, end;
160             for (it = m_observers.begin(), end = m_observers.end(); it != end; ++it) {
161                 O& observer = **it;
162                 if (!observer.skip())
163                     observer(a1, a2, a3, a4);
164             }
165 
166             removePending();
167             addPending();
168         }
169 
170         template <typename A1, typename A2, typename A3, typename A4, typename A5>
notify(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5)171         void notify(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
172             const SetBool notifying(m_notifying);
173 
174             typename List::const_iterator it, end;
175             for (it = m_observers.begin(), end = m_observers.end(); it != end; ++it) {
176                 O& observer = **it;
177                 if (!observer.skip())
178                     observer(a1, a2, a3, a4, a5);
179             }
180 
181             removePending();
182             addPending();
183         }
184     private:
addPending()185         void addPending() {
186             m_observers.insert(m_observers.end(), m_toAdd.begin(), m_toAdd.end());
187             m_toAdd.clear();
188         }
189 
removePending()190         void removePending() {
191             typename List::iterator it, end, elem;
192             for (it = m_toRemove.begin(), end = m_toRemove.end(); it != end; ++it) {
193                 elem = std::find_if(m_observers.begin(), m_observers.end(), CompareObservers(*it));
194                 assert(elem != m_observers.end());
195                 delete *elem;
196                 m_observers.erase(elem);
197             }
198 
199             ListUtils::clearAndDelete(m_toRemove);
200         }
201     };
202 
203     class Notifier0 {
204     private:
205         typedef Notifier0 N;
206 
207         class Observer {
208         private:
209             bool m_skip;
210         public:
Observer()211             Observer() : m_skip(false) {}
212 
skip()213             bool skip() const {
214                 return m_skip;
215             }
216 
setSkip()217             void setSkip() {
218                 m_skip = true;
219             }
220 
~Observer()221             virtual ~Observer() {}
222 
223             virtual void* receiver() const = 0;
224 
225             virtual void operator()() = 0;
226 
227             bool operator==(const Observer& rhs) const {
228                 if (receiver() != rhs.receiver())
229                     return false;
230                 return compareFunctions(rhs);
231             }
232         private:
233             virtual bool compareFunctions(const Observer& rhs) const = 0;
234         };
235 
236         template <typename R>
237         class CObserver : public Observer {
238         private:
239             typedef void (R::*F)();
240 
241             R* m_receiver;
242             F m_function;
243         public:
CObserver(R * receiver,F function)244             CObserver(R* receiver, F function) :
245             m_receiver(receiver),
246             m_function(function) {}
247 
operator()248             void operator()() {
249                 (m_receiver->*m_function)();
250             }
251 
receiver()252             void* receiver() const {
253                 return static_cast<void*>(m_receiver);
254             }
255 
function()256             F function() const {
257                 return m_function;
258             }
259 
compareFunctions(const Observer & rhs)260             bool compareFunctions(const Observer& rhs) const {
261                 const CObserver<R>& rhsR = static_cast<const CObserver<R>&>(rhs);
262                 return m_function == rhsR.function();
263             }
264         };
265     private:
266         NotifierState<Observer> m_state;
267     public:
268         class NotifyAfter {
269         private:
270             N& m_after;
271         public:
NotifyAfter(N & after)272             NotifyAfter(N& after) : m_after(after) {}
~NotifyAfter()273             virtual ~NotifyAfter() { m_after.notify(); }
274         };
275 
276         class NotifyBeforeAndAfter : public NotifyAfter {
277         public:
NotifyBeforeAndAfter(N & before,N & after)278             NotifyBeforeAndAfter(N& before, N& after) :
279             NotifyAfter(after) {
280                 before();
281             }
282         };
283 
284         template <typename R>
addObserver(R * receiver,void (R::* function)())285         bool addObserver(R* receiver, void (R::*function)()) {
286             return m_state.addObserver(new CObserver<R>(receiver, function));
287         }
288 
289         template <typename R>
removeObserver(R * receiver,void (R::* function)())290         bool removeObserver(R* receiver, void (R::*function)()) {
291             return m_state.removeObserver(new CObserver<R>(receiver, function));
292         }
293 
addObserver(Notifier0 & notifier)294         bool addObserver(Notifier0& notifier) {
295             return addObserver(&notifier, &Notifier0::operator());
296         }
297 
removeObserver(Notifier0 & notifier)298         bool removeObserver(Notifier0& notifier) {
299             return removeObserver(&notifier, &Notifier0::operator());
300         }
301 
notify()302         void notify() {
303             m_state.notify();
304         }
305 
operator()306         void operator()() {
307             notify();
308         }
309     };
310 
311     template <typename A1>
312     class Notifier1 {
313     private:
314         typedef Notifier1<A1> N;
315 
316         class Observer {
317         private:
318             bool m_skip;
319         public:
Observer()320             Observer() : m_skip(false) {}
321 
skip()322             bool skip() const {
323                 return m_skip;
324             }
325 
setSkip()326             void setSkip() {
327                 m_skip = true;
328             }
329 
~Observer()330             virtual ~Observer() {}
331 
332             virtual void* receiver() const = 0;
333 
334             virtual void operator()(A1 a1) = 0;
335 
336             bool operator==(const Observer& rhs) const {
337                 if (receiver() != rhs.receiver())
338                     return false;
339                 return compareFunctions(rhs);
340             }
341         private:
342             virtual bool compareFunctions(const Observer& rhs) const = 0;
343         };
344 
345         template <typename R>
346         class CObserver : public Observer {
347         private:
348             typedef void (R::*F)(A1 a1);
349 
350             R* m_receiver;
351             F m_function;
352         public:
CObserver(R * receiver,F function)353             CObserver(R* receiver, F function) :
354             m_receiver(receiver),
355             m_function(function) {}
356 
operator()357             void operator()(A1 a1) {
358                 (m_receiver->*m_function)(a1);
359             }
360 
receiver()361             void* receiver() const {
362                 return static_cast<void*>(m_receiver);
363             }
364 
function()365             F function() const {
366                 return m_function;
367             }
368 
compareFunctions(const Observer & rhs)369             bool compareFunctions(const Observer& rhs) const {
370                 const CObserver<R>& rhsR = static_cast<const CObserver<R>&>(rhs);
371                 return m_function == rhsR.function();
372             }
373         };
374     private:
375         NotifierState<Observer> m_state;
376     public:
377         class NotifyAfter {
378         private:
379             N& m_after;
380             A1& m_a1;
381         public:
NotifyAfter(N & after,A1 & a1)382             NotifyAfter(N& after, A1& a1) :
383             m_after(after),
384             m_a1(a1) {}
~NotifyAfter()385             virtual ~NotifyAfter() { m_after.notify(m_a1); }
386         };
387 
388         class NotifyBeforeAndAfter : public NotifyAfter {
389         public:
NotifyBeforeAndAfter(N & before,N & after,A1 & a1)390             NotifyBeforeAndAfter(N& before, N& after, A1& a1) :
391             NotifyAfter(after, a1) {
392                 before(a1);
393             }
394         };
395 
396         template <typename R>
addObserver(R * receiver,void (R::* function)(A1))397         bool addObserver(R* receiver, void (R::*function)(A1)) {
398             return m_state.addObserver(new CObserver<R>(receiver, function));
399         }
400 
401         template <typename R>
removeObserver(R * receiver,void (R::* function)(A1))402         bool removeObserver(R* receiver, void (R::*function)(A1)) {
403             return m_state.removeObserver(new CObserver<R>(receiver, function));
404         }
405 
addObserver(Notifier1 & notifier)406         bool addObserver(Notifier1& notifier) {
407             return addObserver(&notifier, &Notifier1::operator());
408         }
409 
removeObserver(Notifier1 & notifier)410         bool removeObserver(Notifier1& notifier) {
411             return removeObserver(&notifier, &Notifier1::operator());
412         }
413 
notify(A1 a1)414         void notify(A1 a1) {
415             m_state.notify(a1);
416         }
417 
operator()418         void operator()(A1 a1) {
419             notify(a1);
420         }
421 
422         template <typename I>
notify(I it,I end)423         void notify(I it, I end) {
424             while (it != end) {
425                 notify(*it);
426                 ++it;
427             }
428         }
429 
430         template <typename I>
operator()431         void operator()(I it, I end) {
432             while (it != end) {
433                 notify(*it);
434                 ++it;
435             }
436         }
437     };
438 
439     template <typename A1, typename A2>
440     class Notifier2 {
441     private:
442         typedef Notifier2<A1, A2> N;
443 
444         class Observer {
445         private:
446             bool m_skip;
447         public:
Observer()448             Observer() : m_skip(false) {}
449 
skip()450             bool skip() const {
451                 return m_skip;
452             }
453 
setSkip()454             void setSkip() {
455                 m_skip = true;
456             }
457 
~Observer()458             virtual ~Observer() {}
459 
460             virtual void* receiver() const = 0;
461 
462             virtual void operator()(A1 a1, A2 a2) = 0;
463 
464             bool operator==(const Observer& rhs) const {
465                 if (receiver() != rhs.receiver())
466                     return false;
467                 return compareFunctions(rhs);
468             }
469         private:
470             virtual bool compareFunctions(const Observer& rhs) const = 0;
471         };
472 
473         template <typename R>
474         class CObserver : public Observer {
475         private:
476             typedef void (R::*F)(A1 a1, A2 a2);
477 
478             R* m_receiver;
479             F m_function;
480         public:
CObserver(R * receiver,F function)481             CObserver(R* receiver, F function) :
482             m_receiver(receiver),
483             m_function(function) {}
484 
operator()485             void operator()(A1 a1, A2 a2) {
486                 (m_receiver->*m_function)(a1, a2);
487             }
488 
receiver()489             void* receiver() const {
490                 return static_cast<void*>(m_receiver);
491             }
492 
function()493             F function() const {
494                 return m_function;
495             }
496 
compareFunctions(const Observer & rhs)497             bool compareFunctions(const Observer& rhs) const {
498                 const CObserver<R>& rhsR = static_cast<const CObserver<R>&>(rhs);
499                 return m_function == rhsR.function();
500             }
501         };
502     private:
503         NotifierState<Observer> m_state;
504     public:
505         class NotifyAfter {
506         private:
507             N& m_after;
508             A1& m_a1;
509             A2& m_a2;
510         public:
NotifyAfter(N & after,A1 & a1,A2 & a2)511             NotifyAfter(N& after, A1& a1, A2& a2) :
512             m_after(after),
513             m_a1(a1),
514             m_a2(a2) {}
~NotifyAfter()515             virtual ~NotifyAfter() { m_after.notify(m_a1, m_a2); }
516         };
517 
518         class NotifyBeforeAndAfter : public NotifyAfter {
519         public:
NotifyBeforeAndAfter(N & before,N & after,A1 & a1,A2 & a2)520             NotifyBeforeAndAfter(N& before, N& after, A1& a1, A2& a2) :
521             NotifyAfter(after, a1, a2) {
522                 before(a1, a2);
523             }
524         };
525 
526         template <typename R>
addObserver(R * receiver,void (R::* function)(A1,A2))527         bool addObserver(R* receiver, void (R::*function)(A1, A2)) {
528             return m_state.addObserver(new CObserver<R>(receiver, function));
529         }
530 
531         template <typename R>
removeObserver(R * receiver,void (R::* function)(A1,A2))532         bool removeObserver(R* receiver, void (R::*function)(A1, A2)) {
533             return m_state.removeObserver(new CObserver<R>(receiver, function));
534         }
535 
addObserver(Notifier2 & notifier)536         bool addObserver(Notifier2& notifier) {
537             return addObserver(&notifier, &Notifier2::operator());
538         }
539 
removeObserver(Notifier2 & notifier)540         bool removeObserver(Notifier2& notifier) {
541             return removeObserver(&notifier, &Notifier2::operator());
542         }
543 
notify(A1 a1,A2 a2)544         void notify(A1 a1, A2 a2) {
545             m_state.notify(a1, a2);
546         }
547 
operator()548         void operator()(A1 a1, A2 a2) {
549             notify(a1, a2);
550         }
551 
552         template <typename I>
notify(I it,I end,A2 a2)553         void notify(I it, I end, A2 a2) {
554             while (it != end) {
555                 notify(*it, a2);
556                 ++it;
557             }
558         }
559 
560         template <typename I>
operator()561         void operator()(I it, I end, A2 a2) {
562             while (it != end) {
563                 notify(*it, a2);
564                 ++it;
565             }
566         }
567     };
568 
569     template <typename A1, typename A2, typename A3>
570     class Notifier3 {
571     private:
572         typedef Notifier3<A1, A2, A3> N;
573 
574         class Observer {
575         private:
576             bool m_skip;
577         public:
Observer()578             Observer() : m_skip(false) {}
579 
skip()580             bool skip() const {
581                 return m_skip;
582             }
583 
setSkip()584             void setSkip() {
585                 m_skip = true;
586             }
587 
~Observer()588             virtual ~Observer() {}
589 
590             virtual void* receiver() const = 0;
591 
592             virtual void operator()(A1 a1, A2 a2, A3 a3) = 0;
593 
594             bool operator==(const Observer& rhs) const {
595                 if (receiver() != rhs.receiver())
596                     return false;
597                 return compareFunctions(rhs);
598             }
599         private:
600             virtual bool compareFunctions(const Observer& rhs) const = 0;
601         };
602 
603         template <typename R>
604         class CObserver : public Observer {
605         private:
606             typedef void (R::*F)(A1 a1, A2 a2, A3 a3);
607 
608             R* m_receiver;
609             F m_function;
610         public:
CObserver(R * receiver,F function)611             CObserver(R* receiver, F function) :
612             m_receiver(receiver),
613             m_function(function) {}
614 
operator()615             void operator()(A1 a1, A2 a2, A3 a3) {
616                 (m_receiver->*m_function)(a1, a2, a3);
617             }
618 
receiver()619             void* receiver() const {
620                 return static_cast<void*>(m_receiver);
621             }
622 
function()623             F function() const {
624                 return m_function;
625             }
626 
compareFunctions(const Observer & rhs)627             bool compareFunctions(const Observer& rhs) const {
628                 const CObserver<R>& rhsR = static_cast<const CObserver<R>&>(rhs);
629                 return m_function == rhsR.function();
630             }
631         };
632     private:
633         NotifierState<Observer> m_state;
634     public:
635         class NotifyAfter {
636         private:
637             N& m_after;
638             A1& m_a1;
639             A2& m_a2;
640             A3& m_a3;
641         public:
NotifyAfter(N & after,A1 & a1,A2 & a2,A3 & a3)642             NotifyAfter(N& after, A1& a1, A2& a2, A3& a3) :
643             m_after(after),
644             m_a1(a1),
645             m_a2(a2),
646             m_a3(a3) {}
~NotifyAfter()647             virtual ~NotifyAfter() { m_after.notify(m_a1, m_a2, m_a3); }
648         };
649 
650         class NotifyBeforeAndAfter : public NotifyAfter {
651         public:
NotifyBeforeAndAfter(N & before,N & after,A1 & a1,A2 & a2,A3 & a3)652             NotifyBeforeAndAfter(N& before, N& after, A1& a1, A2& a2, A3& a3) :
653             NotifyAfter(after, a1, a2, a3) {
654                 before(a1, a2, a3);
655             }
656         };
657 
658         template <typename R>
addObserver(R * receiver,void (R::* function)(A1,A2,A3))659         bool addObserver(R* receiver, void (R::*function)(A1, A2, A3)) {
660             return m_state.addObserver(new CObserver<R>(receiver, function));
661         }
662 
663         template <typename R>
removeObserver(R * receiver,void (R::* function)(A1,A2,A3))664         bool removeObserver(R* receiver, void (R::*function)(A1, A2, A3)) {
665             return m_state.removeObserver(new CObserver<R>(receiver, function));
666         }
667 
addObserver(Notifier3 & notifier)668         bool addObserver(Notifier3& notifier) {
669             return addObserver(&notifier, &Notifier3::operator());
670         }
671 
removeObserver(Notifier3 & notifier)672         bool removeObserver(Notifier3& notifier) {
673             return removeObserver(&notifier, &Notifier3::operator());
674         }
675 
notify(A1 a1,A2 a2,A3 a3)676         void notify(A1 a1, A2 a2, A3 a3) {
677             m_state.notify(a1, a2, a3);
678         }
679 
operator()680         void operator()(A1 a1, A2 a2, A3 a3) {
681             notify(a1, a2, a3);
682         }
683 
684         template <typename I>
notify(I it,I end,A2 a2,A3 a3)685         void notify(I it, I end, A2 a2, A3 a3) {
686             while (it != end) {
687                 notify(*it, a2, a3);
688                 ++it;
689             }
690         }
691 
692         template <typename I>
operator()693         void operator()(I it, I end, A2 a2, A3 a3) {
694             while (it != end) {
695                 notify(*it, a2, a3);
696                 ++it;
697             }
698         }
699     };
700 
701     template <typename A1, typename A2, typename A3, typename A4>
702     class Notifier4 {
703     private:
704         typedef Notifier4<A1, A2, A3, A4> N;
705 
706         class Observer {
707         private:
708             bool m_skip;
709         public:
Observer()710             Observer() : m_skip(false) {}
711 
skip()712             bool skip() const {
713                 return m_skip;
714             }
715 
setSkip()716             void setSkip() {
717                 m_skip = true;
718             }
719 
~Observer()720             virtual ~Observer() {}
721 
722             virtual void* receiver() const = 0;
723 
724             virtual void operator()(A1 a1, A2 a2, A3 a3, A4 a4) = 0;
725 
726             bool operator==(const Observer& rhs) const {
727                 if (receiver() != rhs.receiver())
728                     return false;
729                 return compareFunctions(rhs);
730             }
731         private:
732             virtual bool compareFunctions(const Observer& rhs) const = 0;
733         };
734 
735         template <typename R>
736         class CObserver : public Observer {
737         private:
738             typedef void (R::*F)(A1 a1, A2 a2, A3 a3, A4 a4);
739 
740             R* m_receiver;
741             F m_function;
742         public:
CObserver(R * receiver,F function)743             CObserver(R* receiver, F function) :
744             m_receiver(receiver),
745             m_function(function) {}
746 
operator()747             void operator()(A1 a1, A2 a2, A3 a3, A4 a4) {
748                 (m_receiver->*m_function)(a1, a2, a3, a4);
749             }
750 
receiver()751             void* receiver() const {
752                 return static_cast<void*>(m_receiver);
753             }
754 
function()755             F function() const {
756                 return m_function;
757             }
758 
compareFunctions(const Observer & rhs)759             bool compareFunctions(const Observer& rhs) const {
760                 const CObserver<R>& rhsR = static_cast<const CObserver<R>&>(rhs);
761                 return m_function == rhsR.function();
762             }
763         };
764     private:
765         NotifierState<Observer> m_state;
766     public:
767         class NotifyAfter {
768         private:
769             N& m_after;
770             A1& m_a1;
771             A2& m_a2;
772             A3& m_a3;
773             A4& m_a4;
774         public:
NotifyAfter(N & after,A1 & a1,A2 & a2,A3 & a3,A4 & a4)775             NotifyAfter(N& after, A1& a1, A2& a2, A3& a3, A4& a4) :
776             m_after(after),
777             m_a1(a1),
778             m_a2(a2),
779             m_a3(a3),
780             m_a4(a4) {}
~NotifyAfter()781             virtual ~NotifyAfter() { m_after.notify(m_a1, m_a2, m_a3, m_a4); }
782         };
783 
784         class NotifyBeforeAndAfter : public NotifyAfter {
785         public:
NotifyBeforeAndAfter(N & before,N & after,A1 & a1,A2 & a2,A3 & a3,A4 & a4)786             NotifyBeforeAndAfter(N& before, N& after, A1& a1, A2& a2, A3& a3, A4& a4) :
787             NotifyAfter(after, a1, a2, a3, a4) {
788                 before(a1, a2, a3, a4);
789             }
790         };
791 
792         template <typename R>
addObserver(R * receiver,void (R::* function)(A1,A2,A3,A4))793         bool addObserver(R* receiver, void (R::*function)(A1, A2, A3, A4)) {
794             return m_state.addObserver(new CObserver<R>(receiver, function));
795         }
796 
797         template <typename R>
removeObserver(R * receiver,void (R::* function)(A1,A2,A3,A4))798         bool removeObserver(R* receiver, void (R::*function)(A1, A2, A3, A4)) {
799             return m_state.removeObserver(new CObserver<R>(receiver, function));
800         }
801 
addObserver(Notifier4 & notifier)802         bool addObserver(Notifier4& notifier) {
803             return addObserver(&notifier, &Notifier4::operator());
804         }
805 
removeObserver(Notifier4 & notifier)806         bool removeObserver(Notifier4& notifier) {
807             return removeObserver(&notifier, &Notifier4::operator());
808         }
809 
notify(A1 a1,A2 a2,A3 a3,A4 a4)810         void notify(A1 a1, A2 a2, A3 a3, A4 a4) {
811             m_state.notify(a1, a2, a3, a4);
812         }
813 
operator()814         void operator()(A1 a1, A2 a2, A3 a3, A4 a4) {
815             notify(a1, a2, a3, a4);
816         }
817 
818         template <typename I>
notify(I it,I end,A2 a2,A3 a3,A4 a4)819         void notify(I it, I end, A2 a2, A3 a3, A4 a4) {
820             while (it != end) {
821                 notify(*it, a2, a3, a4);
822                 ++it;
823             }
824         }
825 
826         template <typename I>
operator()827         void operator()(I it, I end, A2 a2, A3 a3, A4 a4) {
828             while (it != end) {
829                 notify(*it, a2, a3, a4);
830                 ++it;
831             }
832         }
833     };
834 
835     template <typename A1, typename A2, typename A3, typename A4, typename A5>
836     class Notifier5 {
837     private:
838         typedef Notifier5<A1, A2, A3, A4, A5> N;
839 
840         class Observer {
841         private:
842             bool m_skip;
843         public:
Observer()844             Observer() : m_skip(false) {}
845 
skip()846             bool skip() const {
847                 return m_skip;
848             }
849 
setSkip()850             void setSkip() {
851                 m_skip = true;
852             }
853 
~Observer()854             virtual ~Observer() {}
855 
856             virtual void* receiver() const = 0;
857 
858             virtual void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) = 0;
859 
860             bool operator==(const Observer& rhs) const {
861                 if (receiver() != rhs.receiver())
862                     return false;
863                 return compareFunctions(rhs);
864             }
865         private:
866             virtual bool compareFunctions(const Observer& rhs) const = 0;
867         };
868 
869         template <typename R>
870         class CObserver : public Observer {
871         private:
872             typedef void (R::*F)(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5);
873 
874             R* m_receiver;
875             F m_function;
876         public:
CObserver(R * receiver,F function)877             CObserver(R* receiver, F function) :
878             m_receiver(receiver),
879             m_function(function) {}
880 
operator()881             void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
882                 (m_receiver->*m_function)(a1, a2, a3, a4, a5);
883             }
884 
receiver()885             void* receiver() const {
886                 return static_cast<void*>(m_receiver);
887             }
888 
function()889             F function() const {
890                 return m_function;
891             }
892 
compareFunctions(const Observer & rhs)893             bool compareFunctions(const Observer& rhs) const {
894                 const CObserver<R>& rhsR = static_cast<const CObserver<R>&>(rhs);
895                 return m_function == rhsR.function();
896             }
897         };
898     private:
899         NotifierState<Observer> m_state;
900     public:
901         class NotifyAfter {
902         private:
903             N& m_after;
904             A1& m_a1;
905             A2& m_a2;
906             A3& m_a3;
907             A4& m_a4;
908             A5& m_a5;
909         public:
NotifyAfter(N & after,A1 & a1,A2 & a2,A3 & a3,A4 & a4,A5 & a5)910             NotifyAfter(N& after, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) :
911             m_after(after),
912             m_a1(a1),
913             m_a2(a2),
914             m_a3(a3),
915             m_a4(a4),
916             m_a5(a5) {}
~NotifyAfter()917             virtual ~NotifyAfter() { m_after.notify(m_a1, m_a2, m_a3, m_a4, m_a5); }
918         };
919 
920         class NotifyBeforeAndAfter : public NotifyAfter {
921         public:
NotifyBeforeAndAfter(N & before,N & after,A1 & a1,A2 & a2,A3 & a3,A4 & a4,A5 & a5)922             NotifyBeforeAndAfter(N& before, N& after, A1& a1, A2& a2, A3& a3, A4& a4, A5& a5) :
923             NotifyAfter(after, a1, a2, a3, a4, a5) {
924                 before(a1, a2, a3, a4, a5);
925             }
926         };
927 
928         template <typename R>
addObserver(R * receiver,void (R::* function)(A1,A2,A3,A4,A5))929         bool addObserver(R* receiver, void (R::*function)(A1, A2, A3, A4, A5)) {
930             return m_state.addObserver(new CObserver<R>(receiver, function));
931         }
932 
933         template <typename R>
removeObserver(R * receiver,void (R::* function)(A1,A2,A3,A4,A5))934         bool removeObserver(R* receiver, void (R::*function)(A1, A2, A3, A4, A5)) {
935             return m_state.removeObserver(new CObserver<R>(receiver, function));
936         }
937 
addObserver(Notifier5 & notifier)938         bool addObserver(Notifier5& notifier) {
939             return addObserver(&notifier, &Notifier5::operator());
940         }
941 
removeObserver(Notifier5 & notifier)942         bool removeObserver(Notifier5& notifier) {
943             return removeObserver(&notifier, &Notifier5::operator());
944         }
945 
notify(A1 a1,A2 a2,A3 a3,A4 a4,A5 a5)946         void notify(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
947             m_state.notify(a1, a2, a3, a4, a5);
948         }
949 
operator()950         void operator()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
951             notify(a1, a2, a3, a4, a5);
952         }
953 
954         template <typename I>
notify(I it,I end,A2 a2,A3 a3,A4 a4,A5 a5)955         void notify(I it, I end, A2 a2, A3 a3, A4 a4, A5 a5) {
956             while (it != end) {
957                 notify(*it, a2, a3, a4, a5);
958                 ++it;
959             }
960         }
961 
962         template <typename I>
operator()963         void operator()(I it, I end, A2 a2, A3 a3, A4 a4, A5 a5) {
964             while (it != end) {
965                 notify(*it, a2, a3, a4, a5);
966                 ++it;
967             }
968         }
969     };
970 }
971 
972 #endif
973