Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <boost\assert.hpp>
- #include <boost\static_assert.hpp>
- #ifdef _DEBUG
- #include <boost\type_traits.hpp>
- #endif
- #include <vector>
- namespace utils
- {
- // these containers are static, so they are allocated on need and deallocated on software end
- template<class eventC>
- class ut_eventsContainer
- {
- // NOTE: i'd use boost static assert, but somehow it is bugged
- // so it cannot be used in this version
- /*
- BOOST_STATIC_ASSERT_MSG(boost::is_same<eventC, eventC::eventC>::value,
- "eventC and its class' eventC isn't same type");
- */
- private:
- ut_eventsContainer() {}
- ~ut_eventsContainer();
- // copying not allowed because copies may expose references to be NULL
- ut_eventsContainer(const ut_eventsContainer &) {}
- public:
- std::vector<eventC *> m_clients;
- static ut_eventsContainer &getInstance() {static ut_eventsContainer i; return i;}
- // runs every event without args
- void triggerEvents() const;
- // runs every event with given args
- void triggerEvents(typename eventC::eventT &args) const;
- };
- template<class eventC, typename eventParam = eventC::eventT>
- class ut_eventBase
- {
- public:
- typedef eventC eventC;
- typedef eventParam eventT;
- protected:
- // may be NULL
- virtual void onEvent(eventT *) = 0;
- // compability with old code, tries dynamic cast
- void registerEvent() {this->registerEvent(dynamic_cast<eventC *>(this));}
- void registerEvent(eventC *ptr);
- void unregisterEvent(const eventC *ptr) const;
- ut_eventsContainer<eventC> &m_server;
- bool m_is_active;
- public:
- ut_eventBase() : m_is_active(false), m_server(ut_eventsContainer<eventC>::getInstance()) {}
- virtual ~ut_eventBase() {}
- bool isActive() const {return this->m_is_active;}
- };
- template<typename eventParam>
- class ut_event : public ut_eventBase<ut_event<eventParam>, eventParam>
- {
- friend class ut_eventsContainer<eventC>;
- public:
- typedef eventParam eventT;
- private:
- using ut_eventBase::unregisterEvent;
- public:
- ut_event() {}
- template<typename eventParam>
- ut_event(const ut_event<eventParam> ©);
- virtual ~ut_event() {this->unregisterEvent(this);}
- };
- }
- template<typename T>
- void utils::ut_eventsContainer<T>::triggerEvents() const
- {
- for(size_t i = 0; i < this->m_clients.size(); i++)
- if(this->m_clients[i]->isActive())
- this->m_clients[i]->onEvent(NULL);
- }
- template<typename T>
- void utils::ut_eventsContainer<T>::triggerEvents(typename T::eventT &args) const
- {
- for(size_t i = 0; i < this->m_clients.size(); i++)
- if(this->m_clients[i]->isActive())
- this->m_clients[i]->onEvent(&args);
- }
- template<typename T>
- utils::ut_eventsContainer<T>::~ut_eventsContainer()
- {
- #ifdef _DEBUG
- std::string msg = "all the events did not unregister, in ";
- msg += typeid(T).name();
- BOOST_ASSERT_MSG(this->m_clients.size() == 0, msg.c_str());
- #endif
- }
- template<typename T, typename U>
- void utils::ut_eventBase<T, U>::unregisterEvent(const eventC *ptr) const
- {
- BOOST_ASSERT_MSG(ptr != NULL, "ut_eventbase ptr is NULL");
- for(std::vector<eventC *>::const_iterator i = this->m_server.m_clients.begin(); i != this->m_server.m_clients.end(); i++)
- if(*i == ptr)
- {
- this->m_server.m_clients.erase(i);
- return;
- };
- BOOST_ASSERT_MSG(false, "event did not found when unregistering");
- }
- template<typename T, typename U>
- void utils::ut_eventBase<T, U>::registerEvent(eventC *ptr)
- {
- BOOST_ASSERT_MSG(ptr != NULL, "ut_eventbase ptr is NULL");
- #ifdef _DEBUG
- for(std::vector<eventC *>::const_iterator i = this->m_server.m_clients.begin(); i != this->m_server.m_clients.end(); i++)
- BOOST_ASSERT_MSG(*i != ptr, "event already registered!");
- #endif
- this->m_server.m_clients.push_back(ptr);
- this->m_is_active = true;
- }
- template<typename T> template<typename U>
- utils::ut_event<T>::ut_event(const ut_event<U> ©)
- {
- if(copy.m_is_active)
- this->registerEvent(this);
- }
Add Comment
Please, Sign In to add comment