/* * Event.h * * Created on: Sep 5, 2014 * Author: Cameron Karlsson * * See the license file included with this source. */ #ifndef EVENT_H_ #define EVENT_H_ #include #include #include namespace nmea { template class EventHandler; template class Event; template class EventHandler { friend Event; private: // Typenames typename Event::ListIterator _iterator; // Static members static uint64_t LastID; // Properties uint64_t ID; std::function handler; // Functions void _copy(const EventHandler& ref){ if (&ref != this){ _iterator = ref._iterator; handler = ref.handler; ID = ref.ID; } } public: // Typenames typedef void(*CFunctionPointer)(Args...); // Static members // (none) // Properties // (none) // Functions EventHandler(std::function h) : _iterator(), handler(h), ID(++LastID) {} EventHandler(const EventHandler& ref){ _copy(ref); } virtual ~EventHandler(){}; EventHandler& operator=(const EventHandler& ref){ _copy(ref); return *this; } void operator() (Args... args){ handler(args...); } bool operator==(const EventHandler& ref){ return ID == ref.ID; } bool operator!=(const EventHandler& ref){ return ID != ref.ID; } uint64_t getID(){ return ID; } // Returns function pointer to the underlying function // or null if it's not a function but implements operator() CFunctionPointer* getFunctionPointer(){ CFunctionPointer* ptr = handler.template target(); return ptr; } }; template uint64_t EventHandler::LastID = 0; template class Event { friend EventHandler; private: // Typenames typedef typename std::list>::iterator ListIterator; // Static members // (none) // Properties std::list> handlers; //Functions void _copy(const Event& ref){ if (&ref != this){ handlers = ref.handlers; } }; bool removeHandler(ListIterator handlerIter) { if (handlerIter == handlers.end()){ return false; } handlers.erase(handlerIter); return true; }; public: // Typenames // (none) // Static members // (none) // Properties bool enabled; // Functions Event() : enabled(true) {} virtual ~Event() {} Event(const Event& ref) { _copy(ref); } void call(Args... args) { if (!enabled) { return; } for (auto h = handlers.begin(); h != handlers.end(); h++) { (*h)(args...); } } EventHandler registerHandler(EventHandler handler) { bool found = false; for (auto h = handlers.begin(); h != handlers.end(); h++) { if ((*h) == handler) { found = true; break; } } if (!found) { ListIterator itr = handlers.insert(handlers.end(), handler); handler._iterator = itr; } return handler; } EventHandler registerHandler(std::function handler) { EventHandler wrapper(handler); ListIterator itr = handlers.insert(handlers.end(), wrapper); wrapper._iterator = itr; return wrapper; } bool removeHandler(EventHandler& handler) { bool sts = removeHandler(handler._iterator); handler._iterator = handlers.end(); return sts; }; void clear(){ for (auto h = handlers.begin(); h != handlers.end(); h++) { (*h)._iterator = handlers.end(); } handlers.clear(); }; void operator ()(Args... args) { return call(args...); }; EventHandler operator +=(EventHandler handler) { return registerHandler(handler); }; EventHandler operator +=(std::function handler) { return registerHandler(handler); }; bool operator -=(EventHandler& handler) { return removeHandler(handler); }; bool operator -=(uint64_t handlerID) { return removeHandler(handlerID); }; EventHandler& operator =(const EventHandler& ref){ _copy(ref); return *this; }; }; } #endif /* EVENT_H_ */