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(¬ifier, &Notifier0::operator()); 296 } 297 removeObserver(Notifier0 & notifier)298 bool removeObserver(Notifier0& notifier) { 299 return removeObserver(¬ifier, &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(¬ifier, &Notifier1::operator()); 408 } 409 removeObserver(Notifier1 & notifier)410 bool removeObserver(Notifier1& notifier) { 411 return removeObserver(¬ifier, &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(¬ifier, &Notifier2::operator()); 538 } 539 removeObserver(Notifier2 & notifier)540 bool removeObserver(Notifier2& notifier) { 541 return removeObserver(¬ifier, &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(¬ifier, &Notifier3::operator()); 670 } 671 removeObserver(Notifier3 & notifier)672 bool removeObserver(Notifier3& notifier) { 673 return removeObserver(¬ifier, &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(¬ifier, &Notifier4::operator()); 804 } 805 removeObserver(Notifier4 & notifier)806 bool removeObserver(Notifier4& notifier) { 807 return removeObserver(¬ifier, &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(¬ifier, &Notifier5::operator()); 940 } 941 removeObserver(Notifier5 & notifier)942 bool removeObserver(Notifier5& notifier) { 943 return removeObserver(¬ifier, &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