Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include <list>
- #include <iostream>
- #include <algorithm>
- // use base class to resolve the problem of how to put into collection objects of different types
- template <typename TPropertyType>
- struct PropertyChangedDelegateBase
- {
- virtual ~PropertyChangedDelegateBase(){};
- virtual void operator()(const TPropertyType& t) = 0;
- };
- template <typename THandlerOwner, typename TPropertyType>
- struct PropertyChangedDelegate : public PropertyChangedDelegateBase<TPropertyType>
- {
- THandlerOwner* pHandlerOwner_;
- typedef void (THandlerOwner::*TPropertyChangeHandler)(const TPropertyType&);
- TPropertyChangeHandler handler_;
- public:
- PropertyChangedDelegate(THandlerOwner* pHandlerOwner, TPropertyChangeHandler handler) :
- pHandlerOwner_(pHandlerOwner), handler_(handler){}
- void operator()(const TPropertyType& t)
- {
- (pHandlerOwner_->*handler_)(t);
- }
- };
- template<typename TPropertyType>
- class PropertyChangedEvent
- {
- public:
- virtual ~PropertyChangedEvent(){};
- void add(PropertyChangedDelegateBase<TPropertyType>* const d)
- {
- std::list<PropertyChangedDelegateBase<TPropertyType>* const>::const_iterator it = std::find(observers_.begin(), observers_.end(), d);
- if(it != observers_.end())
- throw std::runtime_error("Observer already registered");
- observers_.push_back(d);
- }
- void remove(PropertyChangedDelegateBase<TPropertyType>* const d)
- {
- std::list<PropertyChangedDelegateBase<TPropertyType>* const>::const_iterator it = std::find(observers_.begin(), observers_.end(), d);
- if(it != observers_.end())
- observers_.remove(d);
- }
- // notify
- void operator()(const TPropertyType& newValue)
- {
- std::list<PropertyChangedDelegateBase<TPropertyType>* const>::const_iterator it = observers_.begin();
- for(; it != observers_.end(); ++it)
- {
- (*it)->operator()(newValue);
- }
- }
- protected:
- std::list<PropertyChangedDelegateBase<TPropertyType>* const> observers_;
- };
- class PropertyOwner
- {
- int property1_;
- float property2_;
- public:
- PropertyChangedEvent<int> property1ChangedEvent;
- PropertyChangedEvent<float> property2ChangedEvent;
- PropertyOwner() :
- property1_(0),
- property2_(0.0f)
- {}
- int property1() const {return property1_;}
- void property1(int n)
- {
- if(property1_ != n)
- {
- property1_ = n;
- property1ChangedEvent(n);
- }
- }
- float property2() const {return property2_;}
- void property2(float n)
- {
- if(property2_ != n)
- {
- property2_ = n;
- property2ChangedEvent(n);
- }
- }
- };
- struct PropertyObserver
- {
- void OnPropertyChanged(const int& newValue)
- {
- std::cout << "PropertyObserver::OnPropertyChanged() -> new value is: " << newValue << std::endl;
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- PropertyOwner propertyOwner;
- PropertyObserver propertyObserver;
- // register observers
- PropertyChangedDelegate<PropertyObserver, int> delegate(&propertyObserver, &PropertyObserver::OnPropertyChanged);
- propertyOwner.property1ChangedEvent.add(&delegate); // Ok!
- propertyOwner.property1ChangedEvent.add(&PropertyChangedDelegate<PropertyObserver, int>(&propertyObserver, &PropertyObserver::OnPropertyChanged)); // Error: Virtual pure function call (Debug only)
- propertyOwner.property1(1);
- return getchar();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement