Advertisement
GeneralGDA

Auto Unsubscriber

Oct 15th, 2015
447
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.90 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <utility>
  4.  
  5. namespace tme
  6. {
  7.  
  8. template<typename Observer, typename Observable>
  9. class DoUnsubscribe final
  10. {
  11. public:
  12.  
  13.     void operator()(Observable& observable, const Observer&) const
  14.     {
  15.         observable.unsubscribe();
  16.     }
  17.  
  18. };
  19.  
  20. template <typename Observer, typename Observable, typename Unsubscribe = DoUnsubscribe<Observer, Observable>>
  21. class AutoUnsubscribe final
  22. {
  23. public:
  24.  
  25.     AutoUnsubscribe() = default;
  26.  
  27.     explicit AutoUnsubscribe(const Observer& observer)
  28.         : observer_(observer)
  29.     {
  30.     }
  31.  
  32.     explicit AutoUnsibescribe(Observer&& observer)
  33.         : observer_(std::move(observer))
  34.     {
  35.     }
  36.  
  37.     AutoUnsubscribe& plug(const Observer& observer)
  38.     {
  39.         unsubscribe();
  40.         observer_ = observer;
  41.         return *this;
  42.     }
  43.  
  44.     AutoUnsubscribe& plug(Observer&& observer)
  45.     {
  46.         unsubscribe();
  47.         observer_ = std::move(observer);
  48.         return *this;
  49.     }
  50.  
  51.     Observer subscribe(Observable& host)
  52.     {
  53.         UNI_ASSERT(nullptr == observable_);
  54.         observable_ = &host;
  55.         return observer_;
  56.     }
  57.  
  58.     ~AutoUnsubscribe()
  59.     {
  60.         unsubscribe();
  61.     }
  62.  
  63. private:
  64.  
  65.     void unsubscribe()
  66.     {
  67.         if (nullptr != observable_)
  68.         {
  69.             Unsubscribe{}(*observable_, observer_);
  70.         }
  71.     }
  72.  
  73.     Observer observer_;
  74.  
  75.     Observable* observable_ = nullptr;
  76.  
  77. };
  78.  
  79. } // namespace tme
  80.  
  81. /*
  82. usage
  83. */
  84. class SinkMessagesBuffer final : public UniLog::ILogMessageSink
  85. {
  86. public:
  87.  
  88.     using AutoUnsubscribe = tme::AutoUnsubscribe<std::function<void()>, SinkMessagesBuffer>;
  89.  
  90.     void subscribe_on_messages_deliver(AutoUnsubscribe& listener)
  91.     {
  92.         on_new_message_ = listener.subscribe(*this);
  93.     }
  94.    
  95.     void unsubscribe()
  96.     {
  97.         on_new_message_ = {};
  98.     }
  99.  
  100. // some other stuff
  101. private:
  102.    
  103.     std::function<void()> on_new_message_;
  104.  
  105. // some other stuff
  106. };
  107.  
  108. SinkMessagesBuffer log_buffer;
  109.  
  110. SinkMessagesBuffer::AutoUnsubscribe log_buffer_connection;
  111.  
  112. log_buffer->subscribe_on_messages_deliver(log_buffer_connection.plug([this]() { cool_stuff_on_event(); }));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement