From: Lukasz Stanislawski Date: Wed, 31 Aug 2016 06:37:01 +0000 (+0200) Subject: event bus implementation X-Git-Tag: submit/tizen/20161113.192141~62 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=014812e0e9c2c96e1866f2f548b50a508705cce6;p=profile%2Fmobile%2Fapps%2Fnative%2Fclock.git event bus implementation Create global bus for application events. Allows multiple observers to register on one particular event. Change-Id: I4da624c7cf492224ba53431fd6e03781eb3c81a5 --- diff --git a/clock/inc/Utils/EventBus.h b/clock/inc/Utils/EventBus.h new file mode 100644 index 0000000..94ade98 --- /dev/null +++ b/clock/inc/Utils/EventBus.h @@ -0,0 +1,108 @@ +/* + * 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 +#include +#include + +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); + + /** + * @brief Deregisters handler for given event type + */ + static void DeregisterHandler(int type, std::function); + + /** + * @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>> callbacks_; + }; +} /* utils */ + +#endif diff --git a/clock/src/Utils/EventBus.cpp b/clock/src/Utils/EventBus.cpp new file mode 100644 index 0000000..d28c847 --- /dev/null +++ b/clock/src/Utils/EventBus.cpp @@ -0,0 +1,54 @@ +#include "Utils/EventBus.h" +#include + +using namespace utils; + +int EventBus::RegisterNewEventType() +{ + EventBus &bus = GetInstance(); + return ++bus.current_event_id_; +} + +void EventBus::RegisterHandler(int type, std::function func) +{ + EventBus &bus = GetInstance(); + bus.callbacks_[type].push_back(func); +} + +void EventBus::DeregisterHandler(int type, std::function 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() == func.target()) { + 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() +{ +}