__canvas(nullptr)
{
- __eventLoop = std::make_unique<DSEventLoop>();
+ __eventLoop = DSEventLoop::getInstance();
__wlCompositor = DSWaylandCompositor::getInstance();
__displayDevice = std::make_unique<DSDisplayDeviceTDMImpl>();
}
{
DSWaylandCompositor::releaseInstance();
DSBufferManager::releaseInstance();
+ DSEventLoop::releaseInstance();
}
bool DSCompositorPrivate::run()
protected:
private:
- std::unique_ptr<DSEventLoop> __eventLoop;
+ DSEventLoop *__eventLoop;
std::unique_ptr<IDSDisplayDevice> __displayDevice;
DSWaylandCompositor *__wlCompositor;
__displayDeviceHWC(nullptr),
__zone(nullptr),
__renderEngine(nullptr),
+ __eventLoop(nullptr),
__x(0),
__y(0),
__width(0),
if (!__renderEngine)
DSLOG_ERR("DSCanvasPrivate", "__RenderEngine is null.");
+ __eventLoop = DSEventLoop::getInstance();
+
// add idle enterer event on __onEventIdleEnterer for rendereing and displaying
- DSEventLoop::addIdleEnterer(this, __onEventIdleEnterer);
+ // TODO: Remove static function callback. use std::function<> at addIdleEnterer
+ __eventLoop->addIdleEnterer(this, &DSDisplayAreaPrivate::__onEventIdleEnterer);
// The size of DSDisplayArea is the one of DSOutput
__width = outputImpl->getResolutionWidth();
}
DSDisplayAreaPrivate::~DSDisplayAreaPrivate()
-{}
+{
+ DSEventLoop::releaseInstance();
+}
int DSDisplayAreaPrivate::getWidth()
{
std::shared_ptr<IDSDisplayDeviceHWC> __displayDeviceHWC;
std::shared_ptr<DSZone> __zone;
std::shared_ptr<IDSRenderEngine> __renderEngine;
+ DSEventLoop *__eventLoop;
int __x, __y;
int __width, __height;
std::list<std::shared_ptr<DSRenderView>> __renderViewList;
}
-#endif
\ No newline at end of file
+#endif
namespace display_server
{
-static std::list<Ecore_Idle_Enterer *> __ecoreIdleEntererList;
+//static std::list<Ecore_Idle_Enterer *> __ecoreIdleEntererList;
DSEventLoop::DSEventLoop()
: __running(false)
ecore_shutdown();
}
+DSEventLoop *DSEventLoop::__instance { nullptr };
+std::mutex DSEventLoop::__mutex;
+int DSEventLoop::__refCount { 0 };
+
+DSEventLoop *DSEventLoop::getInstance()
+{
+ std::lock_guard<std::mutex> lock(__mutex);
+
+ if (!__instance) {
+ __instance = new DSEventLoop();
+ if (!__instance) {
+ DSLOG_ERR("DSEventLoop", "new DSEventLoop() fails.");
+ return nullptr;
+ }
+ DSLOG_INF("DSEventLoop", "DSEventLoop instance has been created !");
+ }
+
+ ++__refCount;
+
+ return __instance;
+}
+
+void DSEventLoop::releaseInstance()
+{
+ std::lock_guard<std::mutex> lock(__mutex);
+
+ --__refCount;
+ DSLOG_INF("DSEventLoop", "__refCount=%d", __refCount);
+ if (__refCount <= 0) {
+ delete __instance;
+ __instance = nullptr;
+ DSLOG_INF("DSEventLoop", "DSEventLoop instance has been removed !");
+ }
+}
+
bool DSEventLoop::isRunning()
{
return __running;
#ifndef __DS_EVENT_LOOP_H__
#define __DS_EVENT_LOOP_H__
+#include "DSCore.h"
#include "DSObject.h"
#include <Ecore.h>
+#include <mutex>
namespace display_server
{
class DSEventLoop
{
public:
- DSEventLoop();
- virtual ~DSEventLoop();
+ static DSEventLoop *getInstance();
+ static void releaseInstance();
bool run();
bool quit();
bool isRunning();
// add Ecore_Idle_Enterer
- // TODO: make generalization, hiding Ecore_Idle_Enterer, Ecore_Task_Cb
- // TODO: need
- static void addIdleEnterer(DSObject *slot, Ecore_Task_Cb func);
+ void addIdleEnterer(DSObject *slot, Ecore_Task_Cb func);
private:
+ DSEventLoop(); // private constructor
+ ~DSEventLoop(); // private desctructor
+ DSEventLoop(DSEventLoop &other) = delete; // should not be cloneable
+ void operator=(const DSEventLoop &) = delete; // should not be assignable
+ static DSEventLoop *__instance; // singleton instance
+ static std::mutex __mutex; // mutex
+ static int __refCount;
+
bool __running;
+ std::list<Ecore_Idle_Enterer *> __ecoreIdleEntererList;
};
}
TEST_F(DSEventLoopTest, NewDSEventLoop)
{
- DSEventLoop *eventLoop = new DSEventLoop;
- delete eventLoop;
- EXPECT_TRUE(true);
+ DSEventLoop *eventLoop = DSEventLoop::getInstance();
+ EXPECT_TRUE(eventLoop != nullptr);
+ DSEventLoop::releaseInstance();
}
TEST_F(DSEventLoopTest, RunAndQuit)
{
- DSEventLoop eventLoop;
+ DSEventLoop *eventLoop = DSEventLoop::getInstance();
Ecore_Timer *timer = nullptr;
double delayInSecond = 1.0;
return EINA_FALSE;
};
- timer = ecore_timer_loop_add(delayInSecond, cb, &eventLoop);
+ timer = ecore_timer_loop_add(delayInSecond, cb, eventLoop);
EXPECT_TRUE(timer != nullptr);
if (timer != nullptr) {
- EXPECT_TRUE(eventLoop.run() == true);
+ EXPECT_TRUE(eventLoop->run() == true);
}
+
+ DSEventLoop::releaseInstance();
}
TEST_F(DSEventLoopTest, addIdleEnterer)
{
- DSEventLoop eventLoop;
+ DSEventLoop *eventLoop = DSEventLoop::getInstance();
Ecore_Timer *timer = nullptr;
double delayInSecond = 1.0;
auto idleCb = [](void *data) -> Eina_Bool {
EXPECT_TRUE(true);
+ DSLOG_ERR("soolim", "idleCB");
return EINA_TRUE;
};
- timer = ecore_timer_loop_add(delayInSecond, timerCb, &eventLoop);
+ timer = ecore_timer_loop_add(delayInSecond, timerCb, eventLoop);
EXPECT_TRUE(timer != nullptr);
- DSEventLoop::addIdleEnterer(nullptr, idleCb);
+ eventLoop->addIdleEnterer(nullptr, idleCb);
if (timer != nullptr) {
- EXPECT_TRUE(eventLoop.run() == true);
+ EXPECT_TRUE(eventLoop->run() == true);
}
+
+ DSEventLoop::releaseInstance();
}
MockWaylandCompositor()
: surfaceCreated(false)
{
+ __eventLoop = DSEventLoop::getInstance();
+
__waylandCompositor = DSWaylandCompositor::getInstance();
__waylandCompositor->create();
__waylandCompositor->registerCallbackSurfaceCreated(this, std::bind(&MockWaylandCompositor::onSurfaceCreated, this, std::placeholders::_1));
~MockWaylandCompositor()
{
DSWaylandCompositor::releaseInstance();
+ DSEventLoop::releaseInstance();
}
void onSurfaceCreated(std::shared_ptr<DSWaylandSurface> waylandSurface)
void run()
{
- __eventLoop.run();
+ __eventLoop->run();
}
void quit()
{
- __eventLoop.quit();
+ __eventLoop->quit();
}
bool surfaceCreated; // result of surfaceCreated
private:
DSWaylandCompositor *__waylandCompositor;
std::shared_ptr<DSWaylandSurface> __waylandSurface;
- DSEventLoop __eventLoop;
+ DSEventLoop *__eventLoop;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////