Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef OBSERVER_H
- #define OBSERVER_H
- #include <set>
- #include <functional>
- /**
- * @class Observer
- *
- * Implementation of basic observer functional
- *
- * Usage:
- *
- * class TestObservedObjectDelegate
- * {
- * public:
- * virtual void onPropertyChanged(int value) {}
- * };
- *
- * class TestObservedObject: public Observed<TestObservedObjectDelegate>
- * {
- * int m_property = 0;
- * public:
- * int property() const { return m_property; }
- * void setPropery(int value)
- * {
- * if (m_property == value) return;
- * m_property = value;
- * visitDelegates(&TestObservedObjectDelegate::onPropertyChanged, m_property);
- * }
- * };
- *
- * class HandlePropChanged: public TestObservedObjectDelegate
- * {
- * TestObservedObject m_observedObject;
- * public:
- * HandlePropChanged()
- * {
- * m_observedObject.addDelegate(this);
- * }
- * ~HandlePropChanged()
- * {
- * m_observedObject.removeDelegate(this);
- * }
- * void onPropertyChanged(int value)
- * {
- * // handle on property changed
- * }
- * };
- *
- *
- */
- template<typename Delegate>
- class Observer
- {
- public:
- /**
- * @brief hasDelegate
- *
- * Check
- *
- * @param delegate
- * @return true,
- */
- bool hasDelegate(Delegate* delegate)
- {
- if (delegate == nullptr) return false;
- return m_delegates.find(delegate) != m_delegates.end();
- }
- /**
- * @brief addDelegate
- *
- * Added @class Delegate pointer to observer
- *
- * @param delegate
- */
- void addDelegate(Delegate* delegate)
- {
- if (delegate == nullptr) return;
- if (!hasDelegate(delegate))
- {
- m_delegates.insert(delegate);
- }
- }
- /**
- * @brief removeDelegate
- *
- * Remove @param delegate pointer if observer has @param delegate pointer
- *
- * @param delegate
- */
- void removeDelegate(Delegate* delegate)
- {
- if (delegate == nullptr) return;
- if (hasDelegate(delegate))
- {
- m_delegates.erase(delegate);
- }
- }
- /**
- * @brief visitDelegates
- *
- * Call function @param visitor for all delegates
- *
- * @param visitor
- */
- template<typename Lambda=std::function<void(Delegate*)>>
- void visitDelegates(Lambda visitor)
- {
- for (auto delegate: m_delegates) {
- std::invoke(visitor, delegate);
- }
- }
- template<typename Method, typename ...Args>
- void visitDelegates(Method method, Args&& ...args)
- {
- for (auto delegate: m_delegates) {
- std::invoke(method, delegate, std::forward<Args>(args)...);
- }
- }
- /**
- * @brief size
- * @return
- */
- size_t size()
- {
- return m_delegates.size();
- }
- private:
- std::set<Delegate*> m_delegates;
- };
- /**
- * @brief The Observed class
- *
- * Basic implementation of observed object
- */
- template<typename Delegate>
- class Observed
- {
- public:
- virtual ~Observed() = default;
- virtual bool hasDelegate(Delegate* delegate) { return m_observer.hasDelegate(delegate); }
- virtual void addDelegate(Delegate* delegate) { m_observer.addDelegate(delegate); }
- virtual void removeDelegate(Delegate* delegate) { m_observer.removeDelegate(delegate); }
- protected:
- template<typename Lambda=std::function<void(Delegate*)>>
- void visitDelegates(std::function<void(Delegate*)> visitor)
- {
- m_observer.visitDelegates(visitor);
- }
- template<typename Method, typename ...Args>
- void visitDelegates(Method method, Args&& ...args) {
- m_observer.visitDelegates(method, args...);
- }
- Observer<Delegate>& observer() { return m_observer; }
- private:
- Observer<Delegate> m_observer;
- };
- #define SETTER_BODY(field, value, notify) \
- if (field == value) return; \
- field = value; \
- visitDelegates(notify, this, field); \
- #endif // OBSERVER_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement