Guest User

Untitled

a guest
Oct 21st, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.24 KB | None | 0 0
  1. #pragma once
  2. #include <boost\assert.hpp>
  3. #include <boost\static_assert.hpp>
  4. #ifdef _DEBUG
  5. #include <boost\type_traits.hpp>
  6. #endif
  7. #include <vector>
  8.  
  9. namespace utils
  10. {
  11.     // these containers are static, so they are allocated on need and deallocated on software end
  12.     template<class eventC>
  13.     class ut_eventsContainer
  14.     {
  15.         // NOTE: i'd use boost static assert, but somehow it is bugged
  16.         // so it cannot be used in this version
  17.         /*
  18.         BOOST_STATIC_ASSERT_MSG(boost::is_same<eventC, eventC::eventC>::value,
  19.     "eventC and its class' eventC isn't same type");
  20.         */
  21.     private:
  22.         ut_eventsContainer() {}
  23.         ~ut_eventsContainer();
  24.         // copying not allowed because copies may expose references to be NULL
  25.         ut_eventsContainer(const ut_eventsContainer &) {}
  26.     public:
  27.         std::vector<eventC *> m_clients;
  28.  
  29.         static ut_eventsContainer &getInstance() {static ut_eventsContainer i; return i;}
  30.         // runs every event without args
  31.         void triggerEvents() const;
  32.         // runs every event with given args
  33.         void triggerEvents(typename eventC::eventT &args) const;
  34.     };
  35.  
  36.     template<class eventC, typename eventParam = eventC::eventT>
  37.     class ut_eventBase
  38.     {
  39.     public:
  40.         typedef eventC eventC;
  41.         typedef eventParam eventT;
  42.     protected:
  43.         // may be NULL
  44.         virtual void onEvent(eventT *) = 0;
  45.        
  46.         // compability with old code, tries dynamic cast
  47.         void registerEvent() {this->registerEvent(dynamic_cast<eventC *>(this));}
  48.         void registerEvent(eventC *ptr);
  49.         void unregisterEvent(const eventC *ptr) const;
  50.  
  51.         ut_eventsContainer<eventC> &m_server;
  52.         bool m_is_active;
  53.     public:
  54.         ut_eventBase() : m_is_active(false), m_server(ut_eventsContainer<eventC>::getInstance()) {}
  55.         virtual ~ut_eventBase() {}
  56.  
  57.         bool isActive() const {return this->m_is_active;}
  58.     };
  59.     template<typename eventParam>
  60.     class ut_event : public ut_eventBase<ut_event<eventParam>, eventParam>
  61.     {
  62.         friend class ut_eventsContainer<eventC>;
  63.     public:
  64.         typedef eventParam eventT;
  65.     private:
  66.         using ut_eventBase::unregisterEvent;
  67.     public:
  68.         ut_event() {}
  69.         template<typename eventParam>
  70.         ut_event(const ut_event<eventParam> &copy);
  71.         virtual ~ut_event() {this->unregisterEvent(this);}
  72.     };
  73. }
  74.  
  75. template<typename T>
  76. void utils::ut_eventsContainer<T>::triggerEvents() const
  77. {
  78.     for(size_t i = 0; i < this->m_clients.size(); i++)
  79.         if(this->m_clients[i]->isActive())
  80.             this->m_clients[i]->onEvent(NULL);
  81. }
  82. template<typename T>
  83. void utils::ut_eventsContainer<T>::triggerEvents(typename T::eventT &args) const
  84. {
  85.     for(size_t i = 0; i < this->m_clients.size(); i++)
  86.         if(this->m_clients[i]->isActive())
  87.             this->m_clients[i]->onEvent(&args);
  88. }
  89. template<typename T>
  90. utils::ut_eventsContainer<T>::~ut_eventsContainer()
  91. {
  92. #ifdef _DEBUG
  93.     std::string msg = "all the events did not unregister, in ";
  94.     msg += typeid(T).name();
  95.     BOOST_ASSERT_MSG(this->m_clients.size() == 0, msg.c_str());
  96. #endif
  97. }
  98.  
  99.  
  100. template<typename T, typename U>
  101. void utils::ut_eventBase<T, U>::unregisterEvent(const eventC *ptr) const
  102. {
  103.     BOOST_ASSERT_MSG(ptr != NULL, "ut_eventbase ptr is NULL");
  104.     for(std::vector<eventC *>::const_iterator i = this->m_server.m_clients.begin(); i != this->m_server.m_clients.end(); i++)
  105.         if(*i == ptr)
  106.         {
  107.             this->m_server.m_clients.erase(i);
  108.             return;
  109.         };
  110.     BOOST_ASSERT_MSG(false, "event did not found when unregistering");
  111. }
  112. template<typename T, typename U>
  113. void utils::ut_eventBase<T, U>::registerEvent(eventC *ptr)
  114. {
  115.     BOOST_ASSERT_MSG(ptr != NULL, "ut_eventbase ptr is NULL");
  116. #ifdef _DEBUG
  117.     for(std::vector<eventC *>::const_iterator i = this->m_server.m_clients.begin(); i != this->m_server.m_clients.end(); i++)
  118.         BOOST_ASSERT_MSG(*i != ptr, "event already registered!");
  119. #endif
  120.     this->m_server.m_clients.push_back(ptr);
  121.     this->m_is_active = true;
  122. }
  123.  
  124.  
  125. template<typename T> template<typename U>
  126. utils::ut_event<T>::ut_event(const ut_event<U> &copy)
  127. {
  128.     if(copy.m_is_active)
  129.         this->registerEvent(this);
  130. }
Add Comment
Please, Sign In to add comment