<listOptionValue builtIn="false" value=""${SBI_SYSROOT}/usr/lib/glib-2.0/include""/>
</option>
<option id="sbi.gnu.c.compiler.option.frameworks_cflags.core.483995534" name="Tizen-Frameworks-Other-Cflags" superClass="sbi.gnu.c.compiler.option.frameworks_cflags.core" valueType="stringList">
- <listOptionValue builtIn="false" value="${TC_COMPILER_MISC}"/>
- <listOptionValue builtIn="false" value="${RS_COMPILER_MISC}"/>
+ <listOptionValue builtIn="false" value="$(TC_COMPILER_MISC)"/>
+ <listOptionValue builtIn="false" value="$(RS_COMPILER_MISC)"/>
<listOptionValue builtIn="false" value=" -fPIE"/>
- <listOptionValue builtIn="false" value="--sysroot="${SBI_SYSROOT}""/>
+ <listOptionValue builtIn="false" value="--sysroot="$(SBI_SYSROOT)""/>
<listOptionValue builtIn="false" value="-mthumb"/>
</option>
<option id="gnu.c.compiler.option.include.paths.717856518" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<option defaultValue="false" id="sbi.gnu.cpp.linker.option.shared_flag.core.354840357" name="Linker.Shared" superClass="sbi.gnu.cpp.linker.option.shared_flag.core" valueType="boolean"/>
<option defaultValue="false" id="sbi.gnu.cpp.linker.option.noundefined.core.306613058" name="Report unresolved symbol references (-Wl,--no-undefined)" superClass="sbi.gnu.cpp.linker.option.noundefined.core" valueType="boolean"/>
<option id="sbi.gnu.cpp.linker.option.frameworks_lflags.core.839443319" name="Tizen-Frameworks-Other-Lflags" superClass="sbi.gnu.cpp.linker.option.frameworks_lflags.core" valueType="stringList">
- <listOptionValue builtIn="false" value="${TC_LINKER_MISC}"/>
- <listOptionValue builtIn="false" value="${RS_LINKER_MISC}"/>
+ <listOptionValue builtIn="false" value="$(TC_LINKER_MISC)"/>
+ <listOptionValue builtIn="false" value="$(RS_LINKER_MISC)"/>
<listOptionValue builtIn="false" value="-pie -lpthread "/>
- <listOptionValue builtIn="false" value="--sysroot="${SBI_SYSROOT}""/>
- <listOptionValue builtIn="false" value="-Xlinker --version-script="${PROJ_PATH}/.exportMap""/>
- <listOptionValue builtIn="false" value="-L"${SBI_SYSROOT}/usr/lib""/>
+ <listOptionValue builtIn="false" value="--sysroot="$(SBI_SYSROOT)""/>
+ <listOptionValue builtIn="false" value="-Xlinker --version-script="$(PROJ_PATH)/.exportMap""/>
+ <listOptionValue builtIn="false" value="-L"$(SBI_SYSROOT)/usr/lib""/>
<listOptionValue builtIn="false" value="$(RS_LIBRARIES)"/>
+ <listOptionValue builtIn="false" value="-Xlinker -rpath="/opt/usr/apps/org.example.clocktest/lib""/>
</option>
<option id="gnu.cpp.link.option.paths.1558429204" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/lib}""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/TimerView.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/View/WorldClockView.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Controller/RingController.o""/>
- <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmEvent.o""/>
- <listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmProviderEvent.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/Timer.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/WorldClock.o""/>
<listOptionValue builtIn="false" value=""/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/DeleteAlarmPresenter.o""/>
// Otherwise, you define a test using TEST.
TEST(TestSuite, test01)
{
- ASSERT_TRUE(true);
}
-TEST(TestSuite, test02)
-{
- MockTurtle turtle;
- //presenter::AlarmPresenter *pres = new presenter::AlarmPresenter(nullptr, nullptr);
-
- EXPECT_CALL(turtle, PenUp())
- .Times(AtLeast(1));
-}
--- /dev/null
+#include "Utils/EventBus.h"
+
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <vector>
+#include "log.h"
+
+using namespace testing;
+using namespace utils;
+using std::placeholders::_1;
+
+class EventBusTestSuite : public testing::Test
+{
+ protected:
+ // virtual void SetUp() will be called before each test is run.
+ // You should define it if you need to initialize the variables.
+ // Otherwise, you don't have to provide it.
+ virtual void SetUp()
+ {
+
+ }
+ // virtual void TearDown() will be called after each test is run.
+ // You should define it if there is cleanup work to do.
+ // Otherwise, you don't have to provide it.
+ virtual void TearDown()
+ {
+
+ }
+};
+
+class Subscriber
+{
+ public:
+ Subscriber() : times_(0) {}
+ int times_;
+ void OnEvent(utils::Event *e);
+ void OnEvent2(utils::Event &e);
+};
+
+void Subscriber::OnEvent(utils::Event *event)
+{
+ times_++;
+}
+
+void Subscriber::OnEvent2(utils::Event &event)
+{
+ times_++;
+}
+
+class TestEvent : public utils::Event {
+};
+
+
+TEST(EventBusTestSuite, listener)
+{
+ Subscriber s1, s2;
+ TestEvent event;
+
+ Listener l1 = EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s1, _1));
+ Listener l2 = EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s2, _1));
+
+ EXPECT_EQ(s1.times_, 0);
+ EXPECT_EQ(s2.times_, 0);
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 1);
+ EXPECT_EQ(s2.times_, 1);
+}
+
+TEST(EventBusTestSuite, listener2)
+{
+ Subscriber s1, s2;
+ TestEvent event;
+
+ Listener l1 = EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s1, _1));
+ Listener l2 = EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s2, _1));
+
+ EXPECT_EQ(s1.times_, 0);
+ EXPECT_EQ(s2.times_, 0);
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 1);
+ EXPECT_EQ(s2.times_, 1);
+
+ l1.Unregister();
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 1);
+ EXPECT_EQ(s2.times_, 2);
+
+ l2.Unregister();
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 1);
+ EXPECT_EQ(s2.times_, 2);
+}
+
+TEST(EventBusTestSuite, listener_copy)
+{
+ Subscriber s1, s2;
+ TestEvent event;
+
+ Listener l1 = EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s1, _1));
+ Listener l2 = EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s2, _1));
+
+ EXPECT_EQ(s1.times_, 0);
+ EXPECT_EQ(s2.times_, 0);
+
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 1);
+ EXPECT_EQ(s2.times_, 1);
+
+ Listener l3 = l1;
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 3);
+ EXPECT_EQ(s2.times_, 2);
+
+ l1.Unregister();
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 4);
+ EXPECT_EQ(s2.times_, 3);
+
+ l3.Unregister();
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 4);
+ EXPECT_EQ(s2.times_, 4);
+
+ l2.Unregister();
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 4);
+ EXPECT_EQ(s2.times_, 4);
+}
+
+TEST(EventBusTestSuite, listener_in_vector)
+{
+ DBG("Last test start");
+ Subscriber s1, s2;
+ TestEvent event;
+ std::vector<Listener> listeners;
+
+ listeners.push_back(EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s1, _1)));
+ listeners.push_back(EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s2, _1)));
+
+ EXPECT_EQ(s1.times_, 0);
+ EXPECT_EQ(s2.times_, 0);
+
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 1);
+ EXPECT_EQ(s2.times_, 1);
+}
+
+TEST(EventBusTestSuite, listener_copy2)
+{
+ Subscriber s1, s2;
+ TestEvent event;
+
+ Listener l1 = EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s1, _1));
+ Listener l2 = EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s2, _1));
+
+ EXPECT_EQ(s1.times_, 0);
+ EXPECT_EQ(s2.times_, 0);
+
+ /* Unregister l1 subscription and make new subscription like l2 */
+ l1 = l2;
+
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 0);
+ EXPECT_EQ(s2.times_, 2);
+}
+
+TEST(EventBusTestSuite, listener_copy3)
+{
+ Subscriber s1, s2;
+ Listener l3;
+ TestEvent event;
+
+ Listener l1 = EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s1, _1));
+ Listener l2 = EventBus::AddListener<TestEvent>(std::bind(&Subscriber::OnEvent2, &s2, _1));
+
+ EXPECT_EQ(s1.times_, 0);
+ EXPECT_EQ(s2.times_, 0);
+
+ /* Unregister l1 subscription and make new subscription like empty subscription l3 */
+ l1 = l3;
+
+ EventBus::FireEvent(event);
+ EXPECT_EQ(s1.times_, 0);
+ EXPECT_EQ(s2.times_, 1);
+}
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/TimerView.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/View/WorldClockView.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Controller/RingController.o</targetObjectFile>
-<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmEvent.o</targetObjectFile>
-<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/AlarmProviderEvent.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/Timer.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Model/WorldClock.o</targetObjectFile>
<targetObjectFile>/home/l.stanislaws/Projects/clock/clock/Debug/src/Presenter/DeleteAlarmPresenter.o</targetObjectFile>
#ifndef _CLOCK_MAIN_CONTROLLER_H_
#define _CLOCK_MAIN_CONTROLLER_H_
+#include <vector>
+
#include "Utils/EventBus.h"
+#include "View/EditAlarmView.h"
+#include "Presenter/EditAlarmPresenter.h"
#include "View/AlarmView.h"
#include "View/StopWatchView.h"
/**
* @brief Creates new "Edit/Create" alarm page.
*/
- void CreateNewAlarmPage(utils::Event *e);
+ void CreateNewAlarmPage(utils::Event &e);
/**
* @brief Creates new "Delete" alarm page.
*/
- void CreateNewDeleteAlarmsPage(utils::Event *e);
+ void CreateNewDeleteAlarmsPage(utils::Event &e);
model::WorldClock *world_clock_model_;
model::StopWatch *stop_watch_model_;
presenter::WorldClockPresenter *world_clock_presenter_;
presenter::StopWatchPresenter *stop_watch_presenter_;
presenter::TimerPresenter *timer_presenter_;
+ presenter::EditAlarmPresenter *edit_presenter_;
+
+ view::EditAlarmView *edit_view_;
+ /**
+ * @brief Creates new "Edit" alarm page.
+ */
+ void CreateEditAlarmPage(utils::Event &e);
+
+ /**
+ * @brief global events subscriptions vector
+ */
+ std::vector<utils::Listener> listeners_;
};
}
namespace model {
class AlarmCreateRequestEvent : public utils::Event {
- public:
- AlarmCreateRequestEvent();
- static int EventType();
- private:
- static int custom_type_;
};
class AlarmDeleteRequestEvent : public utils::Event {
- public:
- AlarmDeleteRequestEvent();
- static int EventType();
- private:
- static int custom_type_;
};
class AlarmEditRequestEvent : public utils::Event {
public:
- AlarmEditRequestEvent(model::Alarm& alarm);
- static int EventType();
+ AlarmEditRequestEvent(model::Alarm& alarm) : alarm_(alarm) {}
Alarm &GetAlarm() const { return alarm_;}
private:
Alarm &alarm_;
- static int custom_type_;
};
class AlarmEditedEvent : public utils::Event {
public:
- AlarmEditedEvent(model::Alarm& alarm);
- static int EventType();
+ AlarmEditedEvent(model::Alarm& alarm) : alarm_(alarm) {}
Alarm &GetAlarm() const { return alarm_;}
private:
Alarm &alarm_;
- static int custom_type_;
};
} /* model */
namespace model {
class AlarmAddedEvent : public utils::Event {
public:
- AlarmAddedEvent(Alarm &alarm);
+ AlarmAddedEvent(Alarm &alarm) : alarm_(alarm) {}
Alarm& GetAlarm() { return alarm_; }
- static int EventType();
private:
Alarm &alarm_;
- static int custom_type_;
};
class AlarmRemovedEvent : public utils::Event {
public:
- AlarmRemovedEvent(Alarm &alarm);
+ AlarmRemovedEvent(Alarm &alarm) : alarm_(alarm) {}
Alarm& GetAlarm() { return alarm_; }
- static int EventType();
private:
Alarm &alarm_;
- static int custom_type_;
};
} /* model */
#include "View/AlarmView.h"
#include "Model/AlarmProvider.h"
#include "Model/AlarmProviderEvent.h"
+#include "Utils/EventBus.h"
#include <map>
+#include <vector>
namespace presenter {
class AlarmPresenter {
void OnItemSelected(int idx);
void OnAddButtonClicked();
void OnItemActiveStatusChanged(int idx);
- void OnAlarmAddedEvent(utils::Event *e);
- void OnAlarmRemovedEvent(utils::Event *e);
- void OnAlarmEditedEvent(utils::Event *e);
+ void OnAlarmAddedEvent(utils::Event &e);
+ void OnAlarmRemovedEvent(utils::Event &e);
+ void OnAlarmEditedEvent(utils::Event &e);
void OnDeleteItemClicked();
void UpdateBackgroundLabel();
std::map<int, std::reference_wrapper<model::Alarm>> alarms_;
+ std::vector<utils::Listener> listeners_;
};
} /* presenters */
#include <functional>
#include <vector>
#include <map>
+#include <list>
+#include <typeindex>
namespace utils {
+ /**
+ * @brief Base event class.
+ */
class Event {
public:
- Event(int type) : type_(type) {}
+ Event() {}
virtual ~Event() {}
- int GetType() const { return type_; }
+ };
+
+ /**
+ * @brief Listener class represents event subscription.
+ *
+ * Listeners are created with EventBus::AddListener function.
+ */
+ class Listener {
+ public:
+ /**
+ * @brief default constructor
+ *
+ * Creates listener without any subscription.
+ */
+ Listener() : owner_(nullptr) {}
+
+ /**
+ * @brief Copy constructor. Creates new event subscription.
+ */
+ Listener(const Listener&);
+
+ /**
+ * @brief Stealing constructor
+ */
+ Listener(Listener&& obj);
+
+ /**
+ * @brief Destructor
+ *
+ * Destructor Unregisters event subscription.
+ */
+ ~Listener();
+
+ /**
+ * @brief Unregister current event subscription.
+ */
+ void Unregister();
+
+ /**
+ * @brief Assignment operator.
+ *
+ * Assignment make two thins:
+ * 1. Unregisters current event subscription.
+ * 2. Creates new subscription identical to right value.
+ *
+ * example:
+ * Listener l1 = EventBus::AllListner(std::bind(&MyClass::MyMethod,
+ * obj1, _1));
+ * Listener l2 = EventBus::AllListner(std::bind(&MyClass::MyMethod,
+ * obj2, _1));
+ *
+ * // subscription on obj1 get unregistered, new registration on obj2
+ * // has been set in l1.
+ *
+ * l1 = l2;
+ *
+ * EventBus::FireEvent(...) // MyMethod on obj2 will be called 2 times.
+ */
+ Listener& operator=(const Listener&);
+
+ /**
+ * @brief Constructor used to create listener subscribed to event.
+ */
+ Listener(std::list<std::function<void(Event&)>> &owner,
+ std::list<std::function<void(Event&)>>::iterator it);
+
private:
- int type_;
+ std::list<std::function<void(Event&)>> *owner_;
+ std::list<std::function<void(Event&)>>::iterator it_;
};
+
/**
- * @brief EventBus class is not thread safe. Please avoid using EventBus in
- * multithreaded applications.
+ * @brief Global events dispatcher.
*
* 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
+ * 1. Create new Event type class
+ * 2. Register listener by invoking AddListener function
*
* 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 event:
+ * EventBus::AddListener<DerivedEvent>(std_function_object);
*
- * how to register on evnet:
- * EventBus::RegisterHandler(DerivedEvent::EventType(), some_callback)
+ * how to fire event:
+ * DerivedEvent ev;
+ * EventBus::FireEvent(ev);
*
- * how to fire event
- * EventBus::FireEvent(new DerivedEvent());
+ * @note EventBus class is not thread safe. Please avoid using EventBus in
+ * multithreaded applications.
*
*/
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*)>);
+ template <typename T>
+ static Listener AddListener(std::function<void(Event&)> func)
+ {
+ return AddListenerInternal(typeid(T), func);
+ }
/**
- * @brief Fire event. This means running all handlers registered
- * with @RegisterHandler function.
- *
- * @param must be allocated with 'new' operator
+ * @brief Fire event. This means running all listener registered
+ * with @AddListener function.
*/
- static void FireEvent(Event*);
+ static void FireEvent(Event&);
/**
- * @brief Deleted copy constructor
+ * @brief Deleted copy constructor.
*/
EventBus(const EventBus &bus) = delete;
/**
- * @brief Deleted assignment operator
+ * @brief Deleted assignment operator.
*/
void operator=(const EventBus &bus) = delete;
+
private:
+ static Listener AddListenerInternal(const std::type_index,
+ std::function<void(Event&)>);
static EventBus& GetInstance();
- EventBus();
- int current_event_id_;
- std::map<int, std::vector<std::function<void(Event*)>>> callbacks_;
+ EventBus() {}
+ std::map<std::type_index, std::list<std::function<void(Event&)>>> callbacks_;
};
} /* utils */
stop_watch_presenter_ = new StopWatchPresenter((StopWatchView *)MainView::GetInstance().GetView(STOP_WATCH), stop_watch_model_);
timer_presenter_ = new TimerPresenter((TimerView *)MainView::GetInstance().GetView(TIMER), timer_model_);
-
- EventBus::RegisterHandler(AlarmCreateRequestEvent::EventType(),
- std::bind(&MainController::CreateNewAlarmPage, this, _1));
- EventBus::RegisterHandler(AlarmDeleteRequestEvent::EventType(),
- std::bind(&MainController::CreateNewDeleteAlarmsPage, this, _1));
- EventBus::RegisterHandler(AlarmEditRequestEvent::EventType(),
- std::bind(&MainController::CreateNewAlarmPage, this, _1));
+ listeners_.push_back(utils::EventBus::AddListener<AlarmCreateRequestEvent>(
+ std::bind(&MainController::CreateNewAlarmPage, this, _1)));
+ listeners_.push_back(utils::EventBus::AddListener<AlarmDeleteRequestEvent>(
+ std::bind(&MainController::CreateNewDeleteAlarmsPage, this, _1)));
+ listeners_.push_back(utils::EventBus::AddListener<AlarmEditRequestEvent>(
+ std::bind(&MainController::CreateEditAlarmPage, this, _1)));
return 0;
}
delete timer_presenter_;
delete timer_model_;
- EventBus::DeregisterHandler(AlarmCreateRequestEvent::EventType(),
- std::bind(&MainController::CreateNewAlarmPage, this, _1));
- EventBus::DeregisterHandler(AlarmDeleteRequestEvent::EventType(),
- std::bind(&MainController::CreateNewDeleteAlarmsPage, this, _1));
- EventBus::DeregisterHandler(AlarmEditRequestEvent::EventType(),
- std::bind(&MainController::CreateNewAlarmPage, this, _1));
+ listeners_.clear();
}
-void MainController::CreateNewAlarmPage(Event *e)
+void MainController::CreateNewAlarmPage(Event &e)
{
- static EditAlarmView *view;
- static EditAlarmPresenter *presenter;
- Alarm *alarm;
-
- if (e->GetType() == AlarmCreateRequestEvent::EventType()) {
- alarm = nullptr;
- } else if (e->GetType() == AlarmEditRequestEvent::EventType()) {
- AlarmEditRequestEvent *ev = dynamic_cast<AlarmEditRequestEvent*>(e);
- alarm = &ev->GetAlarm();
- } else {
- ERR("Unhandled event type");
- return;
- }
+ delete edit_view_;
+ delete edit_presenter_;
- if (view) delete view;
- if (presenter) delete presenter;
+ edit_view_ = new EditAlarmView();
+ edit_presenter_ = new EditAlarmPresenter(nullptr, *edit_view_);
+}
+
+void MainController::CreateEditAlarmPage(Event &e)
+{
+ AlarmEditRequestEvent &ev = (AlarmEditRequestEvent&)e;
+
+ delete edit_view_;
+ delete edit_presenter_;
- view = new EditAlarmView();
- presenter = new EditAlarmPresenter(alarm, *view);
+ edit_view_ = new EditAlarmView();
+ edit_presenter_ = new EditAlarmPresenter(&ev.GetAlarm(), *edit_view_);
}
-void MainController::CreateNewDeleteAlarmsPage(Event *e)
+void MainController::CreateNewDeleteAlarmsPage(Event &e)
{
static DeleteAlarmView *view;
static DeleteAlarmPresenter *presenter;
+++ /dev/null
-#include "Model/AlarmEvent.h"
-
-using namespace model;
-using namespace utils;
-
-int AlarmCreateRequestEvent::custom_type_;
-int AlarmDeleteRequestEvent::custom_type_;
-int AlarmEditRequestEvent::custom_type_;
-int AlarmEditedEvent::custom_type_;
-
-AlarmCreateRequestEvent::AlarmCreateRequestEvent() :
- Event(AlarmCreateRequestEvent::EventType())
-{
-}
-
-int AlarmCreateRequestEvent::EventType()
-{
- if (custom_type_ == 0) {
- custom_type_ = EventBus::RegisterNewEventType();
- }
- return custom_type_;
-}
-
-AlarmDeleteRequestEvent::AlarmDeleteRequestEvent() :
- Event(AlarmDeleteRequestEvent::EventType())
-{
-}
-
-int AlarmDeleteRequestEvent::EventType()
-{
- if (custom_type_ == 0) {
- custom_type_ = EventBus::RegisterNewEventType();
- }
- return custom_type_;
-}
-
-AlarmEditRequestEvent::AlarmEditRequestEvent(Alarm &alarm) :
- Event(AlarmEditRequestEvent::EventType()),
- alarm_(alarm)
-{
-}
-
-int AlarmEditRequestEvent::EventType()
-{
- if (custom_type_ == 0) {
- custom_type_ = EventBus::RegisterNewEventType();
- }
- return custom_type_;
-}
-
-AlarmEditedEvent::AlarmEditedEvent(Alarm &alarm) :
- Event(AlarmEditedEvent::EventType()),
- alarm_(alarm)
-{
-}
-
-int AlarmEditedEvent::EventType()
-{
- if (custom_type_ == 0) {
- custom_type_ = EventBus::RegisterNewEventType();
- }
- return custom_type_;
-}
+++ /dev/null
-#include "Model/AlarmProviderEvent.h"
-
-using namespace model;
-using namespace utils;
-
-int AlarmAddedEvent::custom_type_;
-int AlarmRemovedEvent::custom_type_;
-
-AlarmAddedEvent::AlarmAddedEvent(Alarm &alarm) :
- Event(AlarmAddedEvent::EventType()), alarm_(alarm)
-{
-}
-
-int AlarmAddedEvent::EventType()
-{
- if (custom_type_ == 0) {
- custom_type_ = EventBus::RegisterNewEventType();
- }
- return custom_type_;
-}
-
-AlarmRemovedEvent::AlarmRemovedEvent(Alarm &alarm) :
- Event(AlarmRemovedEvent::EventType()), alarm_(alarm)
-{
-}
-
-int AlarmRemovedEvent::EventType()
-{
- if (custom_type_ == 0) {
- custom_type_ = EventBus::RegisterNewEventType();
- }
- return custom_type_;
-}
if (it == alarms.end()) {
alarms.push_back(alarm);
- EventBus::FireEvent(new AlarmAddedEvent(alarms.back()));
+ AlarmAddedEvent ev(alarms.back());
+ EventBus::FireEvent(ev);
}
Sync();
}
auto it = std::find(alarms.begin(), alarms.end(), alarm.get());
if (it != alarms.end()) {
- EventBus::FireEvent(new AlarmRemovedEvent(alarm));
+ AlarmRemovedEvent ev(alarm);
+ EventBus::FireEvent(ev);
alarm.get().Deactivate();
alarms.erase(it);
}
view->SetItemToggleCallback(std::bind(&AlarmPresenter::OnItemActiveStatusChanged, this, _1));
view->SetItemSelectCallback(std::bind(&AlarmPresenter::OnItemSelected, this, _1));
- EventBus::RegisterHandler(AlarmAddedEvent::EventType(),
- std::bind(&AlarmPresenter::OnAlarmAddedEvent, this, _1));
- EventBus::RegisterHandler(AlarmRemovedEvent::EventType(),
- std::bind(&AlarmPresenter::OnAlarmRemovedEvent, this, _1));
- EventBus::RegisterHandler(AlarmEditedEvent::EventType(),
- std::bind(&AlarmPresenter::OnAlarmEditedEvent, this, _1));
+ listeners_.push_back(EventBus::AddListener<AlarmAddedEvent>(
+ std::bind(&AlarmPresenter::OnAlarmAddedEvent, this, _1)));
+ listeners_.push_back(EventBus::AddListener<AlarmRemovedEvent>(
+ std::bind(&AlarmPresenter::OnAlarmRemovedEvent, this, _1)));
+ listeners_.push_back(EventBus::AddListener<AlarmEditedEvent>(
+ std::bind(&AlarmPresenter::OnAlarmEditedEvent, this, _1)));
ShowAll();
}
AlarmPresenter::~AlarmPresenter()
{
- EventBus::DeregisterHandler(AlarmAddedEvent::EventType(),
- std::bind(&AlarmPresenter::OnAlarmAddedEvent, this, _1));
- EventBus::DeregisterHandler(AlarmRemovedEvent::EventType(),
- std::bind(&AlarmPresenter::OnAlarmRemovedEvent, this, _1));
- EventBus::DeregisterHandler(AlarmEditedEvent::EventType(),
- std::bind(&AlarmPresenter::OnAlarmEditedEvent, this, _1));
}
void AlarmPresenter::ShowAll()
return;
Alarm &alarm = it->second.get();
+ AlarmEditRequestEvent ev(alarm);
- EventBus::FireEvent(new AlarmEditRequestEvent(alarm));
+ EventBus::FireEvent(ev);
}
void AlarmPresenter::OnAddButtonClicked()
{
- EventBus::FireEvent(new AlarmCreateRequestEvent());
+ AlarmCreateRequestEvent ev;
+ EventBus::FireEvent(ev);
}
void AlarmPresenter::OnItemActiveStatusChanged(int idx)
AlarmProvider::Sync();
}
-void AlarmPresenter::OnAlarmAddedEvent(Event *e)
+void AlarmPresenter::OnAlarmAddedEvent(Event &e)
{
- if (!e || (e->GetType() != AlarmAddedEvent::EventType()))
- return;
-
- AlarmAddedEvent *ev = dynamic_cast<AlarmAddedEvent*>(e);
+ AlarmAddedEvent &ev = dynamic_cast<AlarmAddedEvent&>(e);
int id = view->ItemAppend(
- ev->GetAlarm().GetTime(),
- ev->GetAlarm().GetName().c_str(),
- ev->GetAlarm().GetWeekFlags(),
- ev->GetAlarm().IsActivated());
- alarms_.insert(std::map<int, std::reference_wrapper<Alarm>>::value_type (id, std::reference_wrapper<Alarm>(ev->GetAlarm())));
+ ev.GetAlarm().GetTime(),
+ ev.GetAlarm().GetName().c_str(),
+ ev.GetAlarm().GetWeekFlags(),
+ ev.GetAlarm().IsActivated());
+ alarms_.insert(std::map<int, std::reference_wrapper<Alarm>>::value_type (id, std::reference_wrapper<Alarm>(ev.GetAlarm())));
UpdateBackgroundLabel();
}
void AlarmPresenter::OnDeleteItemClicked()
{
- EventBus::FireEvent(new AlarmDeleteRequestEvent());
+ AlarmDeleteRequestEvent ev;
+ EventBus::FireEvent(ev);
}
-void AlarmPresenter::OnAlarmRemovedEvent(Event *e)
+void AlarmPresenter::OnAlarmRemovedEvent(Event &e)
{
- if (!e || (e->GetType() != AlarmRemovedEvent::EventType()))
- return;
+ AlarmRemovedEvent &ev = dynamic_cast<AlarmRemovedEvent&>(e);
- AlarmRemovedEvent *ev = dynamic_cast<AlarmRemovedEvent*>(e);
for (auto it = alarms_.begin(); it != alarms_.end(); ++it) {
- if (ev->GetAlarm() == it->second.get()) {
+ if (ev.GetAlarm() == it->second.get()) {
view->RemoveItem(it->first);
alarms_.erase(it);
break;
view->HideNoAlarmsBackgroundLabel();
}
-void AlarmPresenter::OnAlarmEditedEvent(utils::Event *e)
+void AlarmPresenter::OnAlarmEditedEvent(utils::Event &e)
{
- AlarmEditedEvent *ev = dynamic_cast<AlarmEditedEvent*>(e);
+ AlarmEditedEvent &ev = dynamic_cast<AlarmEditedEvent&>(e);
+
auto it = alarms_.begin();
for (; it != alarms_.end(); ++it) {
- if (ev->GetAlarm() == it->second.get()) {
+ if (ev.GetAlarm() == it->second.get()) {
Alarm &alarm = it->second.get();
view->ItemUpdate(it->first, alarm.GetTime(), alarm.GetName().c_str(),
alarm.GetWeekFlags(), alarm.IsActivated());
alarm->Activate();
AlarmProvider::GetInstance()->Add(*alarm);
} else {
- EventBus::FireEvent(new AlarmEditedEvent(*alarm_));
+ AlarmEditedEvent ev(*alarm_);
+ EventBus::FireEvent(ev);
}
// delete local copy if needed
using namespace utils;
-int EventBus::RegisterNewEventType()
+EventBus& EventBus::GetInstance()
{
- EventBus &bus = GetInstance();
- return ++bus.current_event_id_;
+ static EventBus bus;
+ return bus;
}
-void EventBus::RegisterHandler(int type, std::function<void(Event*)> func)
+void EventBus::FireEvent(Event& event)
{
EventBus &bus = GetInstance();
- bus.callbacks_[type].push_back(func);
+
+ auto it = bus.callbacks_[typeid(event)].begin();
+ auto end = bus.callbacks_[typeid(event)].end();
+
+ for (; it != end; ++it) {
+ (*it)(event);
+ }
}
-void EventBus::DeregisterHandler(int type, std::function<void(Event*)> func)
+Listener EventBus::AddListenerInternal(const std::type_index type, std::function<void(Event&)> cb)
{
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;
- }
- }
+ bus.callbacks_[type].push_back(cb);
+ return Listener(bus.callbacks_[type], --bus.callbacks_[type].end());
+}
- if (it != bus.callbacks_[type].end()) {
- bus.callbacks_[type].erase(it);
- }
+Listener::Listener(std::list<std::function<void(Event&)>> &owner,
+ std::list<std::function<void(Event&)>>::iterator it)
+{
+ owner_ = std::addressof(owner);
+ it_ = it;
}
-void EventBus::FireEvent(Event *event)
+Listener::~Listener()
{
- EventBus &bus = GetInstance();
- DBG("Fire %d event", event->GetType());
- for (auto func: bus.callbacks_[event->GetType()]) {
- func(event);
+ Unregister();
+}
+
+void Listener::Unregister()
+{
+ if (owner_) {
+ owner_->erase(it_);
+ owner_ = nullptr;
}
- delete event;
}
-EventBus& EventBus::GetInstance()
+Listener::Listener(Listener&& ref)
{
- static EventBus bus;
- return bus;
+ owner_ = ref.owner_;
+ it_ = std::move(ref.it_);
+ ref.owner_ = nullptr;
}
-EventBus::EventBus()
+Listener::Listener(const Listener& ln)
{
+ owner_ = ln.owner_;
+ if (owner_) {
+ owner_->push_back(*ln.it_);
+ it_ = --owner_->end();
+ }
+}
+
+Listener& Listener::operator=(const Listener& ln)
+{
+ // unregister first, as subscription may be set.
+ Unregister();
+
+ owner_ = ln.owner_;
+ if (owner_) {
+ owner_->push_back(*ln.it_);
+ it_ = --owner_->end();
+ }
+ return *this;
}