#include "Ecore.h"
#include "ecore_private.h"
+#ifdef USE_TIZEN_CORE
+#include "tizen-core/tcore_idler.h"
+#endif // USE_TIZEN_CORE
+
EFL_CALLBACKS_ARRAY_DEFINE(ecore_idle_enterer_callbacks,
{ EFL_LOOP_EVENT_IDLE_ENTER, _ecore_factorized_idle_process },
{ EFL_EVENT_DEL, _ecore_factorized_idle_event_del });
ecore_idle_enterer_add(Ecore_Task_Cb func,
const void *data)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ return tcore_idle_enterer_add(func, data);
+#endif // USE_TIZEN_CORE
+
return _ecore_factorized_idle_add(ecore_idle_enterer_callbacks(), func, data);
}
ecore_idle_enterer_before_add(Ecore_Task_Cb func,
const void *data)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ return tcore_idle_enterer_before_add(func, data);
+#endif // USE_TIZEN_CORE
+
Ecore_Idle_Enterer *ie = NULL;
ie = _ecore_factorized_idle_add(ecore_idle_enterer_callbacks(), func, data);
-
// This avoid us duplicating code and should only be slightly slower
// due to a useless cycle of callback registration
efl_event_callback_array_del(_mainloop_singleton, ecore_idle_enterer_callbacks(), ie);
EAPI void *
ecore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ return tcore_idle_enterer_del(idle_enterer);
+#endif // USE_TIZEN_CORE
+
return _ecore_factorized_idle_del(idle_enterer);
}
#include "Ecore.h"
#include "ecore_private.h"
+#ifdef USE_TIZEN_CORE
+#include "tizen-core/tcore_idler.h"
+#endif // USE_TIZEN_CORE
+
struct _Ecore_Factorized_Idle
{
Ecore_Task_Cb func;
void
_ecore_factorized_idle_event_del(void *data, const Efl_Event *event EINA_UNUSED)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ return;
+#endif //USE_TIZEN_CORE
+
_ecore_factorized_idle_del(data);
}
void
_ecore_factorized_idle_process(void *data, const Efl_Event *event EINA_UNUSED)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ return;
+#endif //USE_TIZEN_CORE
+
Ecore_Factorized_Idle *idler = data;
idler->references++;
void *data;
if (!idler) return NULL;
+
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ return NULL;
+#endif // USE_TIZEN_CORE
+
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
if (idler->references > 0)
return NULL;
}
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ return NULL;
+#endif // USE_TIZEN_CORE
+
if (!idler_mp)
{
idler_mp = eina_mempool_add("chained_mempool", "Ecore_Idle*", NULL, sizeof (Ecore_Factorized_Idle), 23);
ecore_idler_add(Ecore_Task_Cb func,
const void *data)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ return tcore_idler_add(func, data);
+#endif // USE_TIZEN_CORE
+
return _ecore_factorized_idle_add(ecore_idler_callbacks(), func, data);
}
EAPI void *
ecore_idler_del(Ecore_Idler *idler)
{
+#ifdef USE_TIZEN_CORE
+ if (tcore_ready())
+ return tcore_idler_del(idler);
+#endif // USE_TIZEN_CORE
+
return _ecore_factorized_idle_del(idler);
}
--- /dev/null
+#undef EINA_SLSTR_INTERNAL
+#define EINA_SLSTR_INTERNAL
+
+#include "tcore_idler.h"
+
+#include <tizen_core.h>
+
+#include <algorithm>
+#include <list>
+#include <memory>
+#include <mutex>
+
+#include "eina_internal.h"
+#include "log_private.h"
+
+namespace {
+
+class IdlerManager {
+ public:
+ class IdleTask {
+ public:
+ IdleTask(Ecore_Task_Cb cb, const void* data)
+ : cb_(cb), data_(const_cast<void*>(data)) {}
+
+ bool Do() {
+ if (!cb_)
+ return false;
+
+ return static_cast<bool>(cb_(data_));
+ }
+
+ void* GetData() { return data_; }
+
+ private:
+ Ecore_Task_Cb cb_;
+ void* data_;
+ };
+
+ IdlerManager() = default;
+
+ ~IdlerManager() { Dispose(); }
+
+ IdleTask* AddEnterer(std::unique_ptr<IdleTask> task) {
+ return AddInternal(&enterers_, std::move(task));
+ }
+
+ IdleTask* AddIdler(std::unique_ptr<IdleTask> task) {
+ return AddInternal(&idlers_, std::move(task));
+ }
+
+ IdleTask* AddExiter(std::unique_ptr<IdleTask> task) {
+ return AddInternal(&exiters_, std::move(task));
+ }
+
+ IdleTask* AddBeforeEnterer(std::unique_ptr<IdleTask> task) {
+ return AddInternal(&before_enterers_, std::move(task));
+ }
+
+ void* RemoveEnterer(IdleTask* task) {
+ void* data = RemoveInternal(&before_enterers_, task);
+ if (data != nullptr)
+ return data;
+
+ return RemoveInternal(&enterers_, task);
+ }
+
+ void* RemoveIdler(IdleTask* task) { return RemoveInternal(&idlers_, task); }
+
+ void* RemoveExiter(IdleTask* task) { return RemoveInternal(&exiters_, task); }
+
+ private:
+ void ProcessEnterer() {
+ std::unique_lock<std::recursive_mutex> lock(GetMutex());
+ before_enterers_.remove_if(
+ [](const std::unique_ptr<IdleTask>& task) { return !task->Do(); });
+ enterers_.remove_if(
+ [](const std::unique_ptr<IdleTask>& task) { return !task->Do(); });
+
+ _ecore_throttle();
+ }
+
+ void ProcessIdler() {
+ std::unique_lock<std::recursive_mutex> lock(GetMutex());
+ idlers_.remove_if(
+ [](const std::unique_ptr<IdleTask>& task) { return !task->Do(); });
+ }
+
+ void ProcessExiter() {
+ std::unique_lock<std::recursive_mutex> lock(GetMutex());
+ _ecore_animator_run_reset();
+ eina_file_statgen_next();
+ exiters_.remove_if(
+ [](const std::unique_ptr<IdleTask>& task) { return !task->Do(); });
+
+ _ecore_animator_flush();
+ eina_slstr_local_clear();
+ }
+
+ bool IdlerExist() const {
+ std::unique_lock<std::recursive_mutex> lock(GetMutex());
+ return !idlers_.empty();
+ }
+
+ IdleTask* AddInternal(std::list<std::unique_ptr<IdleTask>>* list,
+ std::unique_ptr<IdleTask> task) {
+ std::unique_lock<std::recursive_mutex> lock(mutex_);
+ Init();
+ IdleTask* ret = task.get();
+ list->push_front(std::move(task));
+ return ret;
+ }
+
+ void* RemoveInternal(std::list<std::unique_ptr<IdleTask>>* list,
+ IdleTask* task) {
+ std::unique_lock<std::recursive_mutex> lock(mutex_);
+ auto it = std::find_if(list->begin(), list->end(),
+ [&](const std::unique_ptr<IdleTask>& _task) {
+ return _task.get() == task;
+ });
+
+ if (it == list->end())
+ return nullptr;
+
+ void* data = (*it)->GetData();
+ list->erase(it);
+
+ if (before_enterers_.empty() && enterers_.empty() && idlers_.empty() &&
+ exiters_.empty())
+ Dispose();
+
+ return data;
+ }
+
+ std::recursive_mutex& GetMutex() const { return mutex_; }
+
+ static bool SourcePrepareCb(tizen_core_source_h source, int* timeout,
+ void* user_data) {
+ IdlerManager* manager = static_cast<IdlerManager*>(user_data);
+ if (!manager->IdlerExist())
+ *timeout = -1;
+ else
+ *timeout = 0;
+ return false;
+ }
+
+ static bool SourceCheckCb(tizen_core_source_h source, void* user_data) {
+ auto* manager = static_cast<IdlerManager*>(user_data);
+ manager->ProcessEnterer();
+ if (!manager->IdlerExist()) return false;
+ return true;
+ }
+
+ static bool SourceDispatchCb(tizen_core_source_h source, void* user_data) {
+ auto* manager = static_cast<IdlerManager*>(user_data);
+ manager->ProcessIdler();
+ manager->ProcessExiter();
+ return true;
+ }
+
+ void Init() {
+ std::unique_lock<std::recursive_mutex> lock(GetMutex());
+ if (!disposed_) return;
+
+ tizen_core_source_create(&source_);
+ tizen_core_source_set_prepare_cb(source_, SourcePrepareCb, this);
+ tizen_core_source_set_check_cb(source_, SourceCheckCb, this);
+ tizen_core_source_set_dispatch_cb(source_, SourceDispatchCb, this);
+ tizen_core_add_source(tcore_get_core(), source_);
+ tizen_core_source_set_priority(source_, TIZEN_CORE_PRIORITY_HIGH_IDLE);
+ disposed_ = false;
+ }
+
+ void Dispose() {
+ std::unique_lock<std::recursive_mutex> lock(GetMutex());
+ if (disposed_) return;
+
+ if (source_) {
+ tizen_core_remove_source(tcore_get_core(), source_);
+ source_ = nullptr;
+ }
+
+ disposed_ = true;
+ }
+
+ private:
+ bool disposed_ = true;
+ mutable std::recursive_mutex mutex_;
+ std::list<std::unique_ptr<IdleTask>> before_enterers_;
+ std::list<std::unique_ptr<IdleTask>> enterers_;
+ std::list<std::unique_ptr<IdleTask>> idlers_;
+ std::list<std::unique_ptr<IdleTask>> exiters_;
+ tizen_core_source_h source_ = nullptr;
+};
+
+IdlerManager manager;
+
+} // namespace
+
+Ecore_Idler* tcore_idler_add(Ecore_Task_Cb func, const void* data) {
+ return reinterpret_cast<Ecore_Idler*>(
+ manager.AddIdler(std::make_unique<IdlerManager::IdleTask>(func, data)));
+}
+
+void* tcore_idler_del(Ecore_Idler* idler) {
+ return manager.RemoveIdler(reinterpret_cast<IdlerManager::IdleTask*>(idler));
+}
+
+Ecore_Idle_Enterer* tcore_idle_enterer_add(Ecore_Task_Cb func,
+ const void* data) {
+ return reinterpret_cast<Ecore_Idler*>(
+ manager.AddEnterer(std::make_unique<IdlerManager::IdleTask>(func, data)));
+}
+
+Ecore_Idle_Enterer* tcore_idle_enterer_before_add(Ecore_Task_Cb func,
+ const void* data) {
+ return reinterpret_cast<Ecore_Idler*>(manager.AddBeforeEnterer(
+ std::make_unique<IdlerManager::IdleTask>(func, data)));
+}
+
+void* tcore_idle_enterer_del(Ecore_Idle_Enterer* idle_enterer) {
+ return manager.RemoveEnterer(
+ reinterpret_cast<IdlerManager::IdleTask*>(idle_enterer));
+}
+
+Ecore_Idle_Exiter* tcore_idle_exiter_add(Ecore_Task_Cb func, const void* data) {
+ return reinterpret_cast<Ecore_Idler*>(
+ manager.AddExiter(std::make_unique<IdlerManager::IdleTask>(func, data)));
+}
+
+void* tcore_idle_exiter_del(Ecore_Idle_Exiter* idle_exiter) {
+ return manager.RemoveExiter(
+ reinterpret_cast<IdlerManager::IdleTask*>(idle_exiter));
+}