Advertisement
Guest User

Untitled

a guest
Mar 2nd, 2016
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.56 KB | None | 0 0
  1. #include "stdafx.h"
  2.  
  3. #include <list>
  4. #include <iostream>
  5. #include <algorithm>
  6.  
  7. // use base class to resolve the problem of how to put into collection objects of different types
  8. template <typename TPropertyType>
  9. struct PropertyChangedDelegateBase
  10. {
  11.     virtual ~PropertyChangedDelegateBase(){};
  12.     virtual void operator()(const TPropertyType& t) = 0;
  13. };
  14.  
  15. template <typename THandlerOwner, typename TPropertyType>
  16. struct PropertyChangedDelegate : public PropertyChangedDelegateBase<TPropertyType>
  17. {
  18.     THandlerOwner* pHandlerOwner_;
  19.  
  20.     typedef void (THandlerOwner::*TPropertyChangeHandler)(const TPropertyType&);
  21.     TPropertyChangeHandler handler_;
  22.  
  23. public:
  24.     PropertyChangedDelegate(THandlerOwner* pHandlerOwner, TPropertyChangeHandler handler) :
  25.       pHandlerOwner_(pHandlerOwner), handler_(handler){}
  26.  
  27.     void operator()(const TPropertyType& t)
  28.     {
  29.         (pHandlerOwner_->*handler_)(t);
  30.     }
  31. };
  32.  
  33. template<typename TPropertyType>
  34. class PropertyChangedEvent
  35. {
  36. public:
  37.     virtual ~PropertyChangedEvent(){};
  38.  
  39.     void add(PropertyChangedDelegateBase<TPropertyType>* const d)
  40.     {
  41.         std::list<PropertyChangedDelegateBase<TPropertyType>* const>::const_iterator it = std::find(observers_.begin(), observers_.end(), d);
  42.         if(it != observers_.end())
  43.             throw std::runtime_error("Observer already registered");
  44.  
  45.         observers_.push_back(d);
  46.     }
  47.  
  48.  
  49.     void remove(PropertyChangedDelegateBase<TPropertyType>* const d)
  50.     {      
  51.         std::list<PropertyChangedDelegateBase<TPropertyType>* const>::const_iterator it = std::find(observers_.begin(), observers_.end(), d);
  52.         if(it != observers_.end())
  53.             observers_.remove(d);
  54.     }  
  55.  
  56.     // notify
  57.     void operator()(const TPropertyType& newValue)
  58.     {
  59.         std::list<PropertyChangedDelegateBase<TPropertyType>* const>::const_iterator it = observers_.begin();
  60.         for(; it != observers_.end(); ++it)
  61.         {
  62.             (*it)->operator()(newValue);
  63.         }
  64.     }
  65.  
  66. protected:
  67.     std::list<PropertyChangedDelegateBase<TPropertyType>* const> observers_;
  68. };
  69.  
  70. class PropertyOwner
  71. {
  72.     int property1_;
  73.     float property2_;
  74.  
  75. public:
  76.     PropertyChangedEvent<int> property1ChangedEvent;
  77.     PropertyChangedEvent<float> property2ChangedEvent;
  78.  
  79.     PropertyOwner() :
  80.         property1_(0),
  81.         property2_(0.0f)
  82.     {}  
  83.  
  84.     int property1() const {return property1_;}
  85.     void property1(int n)
  86.     {
  87.         if(property1_ != n)
  88.         {
  89.             property1_ = n;
  90.             property1ChangedEvent(n);
  91.         }
  92.     }
  93.  
  94.     float property2() const {return property2_;}
  95.     void property2(float n)
  96.     {
  97.         if(property2_ != n)
  98.         {
  99.             property2_ = n;
  100.             property2ChangedEvent(n);
  101.         }
  102.     }
  103. };
  104.  
  105. struct PropertyObserver
  106. {  
  107.     void OnPropertyChanged(const int& newValue)
  108.     {
  109.         std::cout << "PropertyObserver::OnPropertyChanged() -> new value is: " << newValue << std::endl;
  110.     }
  111. };
  112.  
  113. int _tmain(int argc, _TCHAR* argv[])
  114. {
  115.     PropertyOwner propertyOwner;
  116.     PropertyObserver propertyObserver;
  117.  
  118.     // register observers
  119.     PropertyChangedDelegate<PropertyObserver, int> delegate(&propertyObserver, &PropertyObserver::OnPropertyChanged);
  120.  
  121.     propertyOwner.property1ChangedEvent.add(&delegate); // Ok!
  122.     propertyOwner.property1ChangedEvent.add(&PropertyChangedDelegate<PropertyObserver, int>(&propertyObserver, &PropertyObserver::OnPropertyChanged)); // Error: Virtual pure function call (Debug only)
  123.     propertyOwner.property1(1);
  124.  
  125.     return getchar();
  126. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement