--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _CLOCK_EVENT_BUS_H_
+#define _CLOCK_EVENT_BUS_H_
+
+#include <functional>
+#include <vector>
+#include <map>
+
+namespace utils {
+ class Event {
+ public:
+ Event(int type) : type_(type) {}
+ virtual ~Event() {}
+ int GetType() const { return type_; }
+ private:
+ int type_;
+ };
+ /**
+ * @brief EventBus class is not thread safe. Please avoid using EventBus in
+ * multithreaded applications.
+ *
+ * How to use Event bus:
+ *
+ * 1. Create new Event type class with static type identifier.
+ * 2. Define static variable identyfying type of your class
+ * 3. Define static function to get event type of your class
+ *
+ * Example:
+ *
+ * class DerivedEvent : public Event {
+ * public:
+ * DerivedEvent() : Event(EventType()) {}
+ * private:
+ * static int custom_type_;
+ * static int EventType() {
+ * if (custom_type_ == 0) {
+ * custom_type = EventBus::RegisterNewEventType();
+ * }
+ * return custom_type;
+ * }
+ * }
+ *
+ * how to register on evnet:
+ * EventBus::RegisterHandler(DerivedEvent::EventType(), some_callback)
+ *
+ * how to fire event
+ * EventBus::FireEvent(new DerivedEvent());
+ *
+ */
+ class EventBus {
+ public:
+ /**
+ * @brief Registers new data type
+ * @return new event type descriptor (> 1)
+ */
+ static int RegisterNewEventType();
+
+ /**
+ * @brief Registers handler for given event type
+ */
+ static void RegisterHandler(int type, std::function<void(Event*)>);
+
+ /**
+ * @brief Deregisters handler for given event type
+ */
+ static void DeregisterHandler(int type, std::function<void(Event*)>);
+
+ /**
+ * @brief Fire event. This means running all handlers registered
+ * with @RegisterHandler function.
+ *
+ * @param must be allocated with 'new' operator
+ */
+ static void FireEvent(Event*);
+
+ /**
+ * @brief Deleted copy constructor
+ */
+ EventBus(const EventBus &bus) = delete;
+
+ /**
+ * @brief Deleted assignment operator
+ */
+ void operator=(const EventBus &bus) = delete;
+ private:
+ static EventBus& GetInstance();
+ EventBus();
+ int current_event_id_;
+ std::map<int, std::vector<std::function<void(Event*)>>> callbacks_;
+ };
+} /* utils */
+
+#endif
--- /dev/null
+#include "Utils/EventBus.h"
+#include <algorithm>
+
+using namespace utils;
+
+int EventBus::RegisterNewEventType()
+{
+ EventBus &bus = GetInstance();
+ return ++bus.current_event_id_;
+}
+
+void EventBus::RegisterHandler(int type, std::function<void(Event*)> func)
+{
+ EventBus &bus = GetInstance();
+ bus.callbacks_[type].push_back(func);
+}
+
+void EventBus::DeregisterHandler(int type, std::function<void(Event*)> func)
+{
+ EventBus &bus = GetInstance();
+ auto it = bus.callbacks_[type].begin();
+
+ // std::function do not have default comprarison operator, so compare
+ // them by target type's name and by pointer to stored type
+ for (it = bus.callbacks_[type].begin(); it != bus.callbacks_[type].end(); ++it) {
+ if (it->target_type().name() == func.target_type().name() &&
+ it->target<void(Event*)>() == func.target<void(Event*)>()) {
+ break;
+ }
+ }
+
+ if (it != bus.callbacks_[type].end()) {
+ bus.callbacks_[type].erase(it);
+ }
+}
+
+void EventBus::FireEvent(Event *event)
+{
+ EventBus &bus = GetInstance();
+ for (auto func: bus.callbacks_[event->GetType()]) {
+ func(event);
+ }
+ delete event;
+}
+
+EventBus& EventBus::GetInstance()
+{
+ static EventBus bus;
+ return bus;
+}
+
+EventBus::EventBus()
+{
+}