tizen-core: Apply tizen-core to ecore idler 36/303736/49
authorChanggyu Choi <changyu.choi@samsung.com>
Tue, 16 Jan 2024 05:35:01 +0000 (14:35 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Thu, 28 Mar 2024 01:12:41 +0000 (10:12 +0900)
Change-Id: I6bc79967c6f8d18dce0c5a930f90cd2c912d09c7
Signed-off-by: Changgyu Choi <changyu.choi@samsung.com>
src/lib/ecore/ecore_idle_enterer.c
src/lib/ecore/ecore_idle_exiter.c
src/lib/ecore/ecore_idler.c
src/lib/ecore/ecore_internal.h
src/lib/ecore/meson.build
src/lib/ecore/tizen-core/tcore.cc
src/lib/ecore/tizen-core/tcore.h
src/lib/ecore/tizen-core/tcore_idler.cc [new file with mode: 0644]
src/lib/ecore/tizen-core/tcore_idler.h [new file with mode: 0644]

index 9ce4716..d9cba6a 100644 (file)
@@ -9,6 +9,10 @@
 #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 });
@@ -18,6 +22,11 @@ EAPI Ecore_Idle_Enterer *
 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);
 }
 
@@ -25,9 +34,13 @@ EAPI Ecore_Idle_Enterer *
 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);
@@ -39,5 +52,10 @@ ecore_idle_enterer_before_add(Ecore_Task_Cb func,
 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);
 }
index 9ca26c8..8ab655d 100644 (file)
@@ -9,6 +9,10 @@
 #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_exiter_callbacks,
                           { EFL_LOOP_EVENT_IDLE_EXIT, _ecore_factorized_idle_process },
                           { EFL_EVENT_DEL, _ecore_factorized_idle_event_del });
@@ -17,11 +21,24 @@ EAPI Ecore_Idle_Exiter *
 ecore_idle_exiter_add(Ecore_Task_Cb func,
                       const void   *data)
 {
-   return  _ecore_factorized_idle_add(ecore_idle_exiter_callbacks(), func, data);
+#ifdef USE_TIZEN_CORE
+   if (tcore_ready())
+      return tcore_idle_exiter_add(func, data);
+#endif // USE_TIZEN_CORE
+
+   Ecore_Idle_Exiter *ie = _ecore_factorized_idle_add(
+       ecore_idle_exiter_callbacks(), func, data);
+
+   return ie;
 }
 
 EAPI void *
 ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter)
 {
+#ifdef USE_TIZEN_CORE
+   if (tcore_ready())
+      return tcore_idle_exiter_del(idle_exiter);
+#endif // USE_TIZEN_CORE
+
    return _ecore_factorized_idle_del(idle_exiter);
 }
index ffd4579..091f898 100644 (file)
@@ -9,6 +9,10 @@
 #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;
@@ -23,12 +27,22 @@ struct _Ecore_Factorized_Idle
 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++;
@@ -49,6 +63,12 @@ _ecore_factorized_idle_del(Ecore_Idler *idler)
    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)
@@ -79,6 +99,11 @@ _ecore_factorized_idle_add(const Efl_Callback_Array_Item *desc,
         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);
@@ -109,11 +134,21 @@ EAPI Ecore_Idler *
 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);
 }
index 9f6e55e..b17ffc1 100644 (file)
@@ -38,7 +38,7 @@ efl_model_list_value_get(Eina_List *childrens,
 {
    Eina_Value v = EINA_VALUE_EMPTY;
    Eina_List *l;
-   Eo *child;
+   void *child;
 
    if (eina_list_count(childrens) < start + count)
      return eina_value_error_init(EFL_MODEL_ERROR_INCORRECT_VALUE);
index bccdff3..40ec5c1 100644 (file)
@@ -210,7 +210,8 @@ if get_option('tizen-core') == true
   ecore_ext_deps += dependency('dlog')
   ecore_src += files([
     'tizen-core/tcore.cc',
-    'tizen-core/tcore_events.cc'
+    'tizen-core/tcore_events.cc',
+    'tizen-core/tcore_idler.cc'
   ])
   config_h.set('USE_TIZEN_CORE', '1')
 endif
index 16e8208..93728df 100644 (file)
@@ -4,6 +4,7 @@
 #include <tizen_core_internal.h>
 
 #include "log_private.h"
+#include "tcore_idler.h"
 
 namespace {
 
@@ -47,6 +48,8 @@ class TCore {
     return tizen_core_get_glib_context(tizen_core_);
   }
 
+  tizen_core_h GetCore() const { return tizen_core_; }
+
  private:
   bool disposed_ = true;
   bool ready_ = false;
@@ -58,6 +61,8 @@ TCore core;
 
 }  // namespace
 
+tizen_core_h tcore_get_core(void) { return core.GetCore(); }
+
 void* tcore_get_glib_context(void) { return core.GetGLibContext(); }
 
 bool tcore_ready(void) { return core.IsReady(); }
index 562d057..a1fc6e7 100644 (file)
@@ -2,11 +2,14 @@
 #define _TCORE_H
 
 #include <stdbool.h>
+#include <tizen_core.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+tizen_core_h tcore_get_core(void);
+
 void *tcore_get_glib_context(void);
 
 bool tcore_ready(void);
diff --git a/src/lib/ecore/tizen-core/tcore_idler.cc b/src/lib/ecore/tizen-core/tcore_idler.cc
new file mode 100644 (file)
index 0000000..7971b38
--- /dev/null
@@ -0,0 +1,233 @@
+#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));
+}
diff --git a/src/lib/ecore/tizen-core/tcore_idler.h b/src/lib/ecore/tizen-core/tcore_idler.h
new file mode 100644 (file)
index 0000000..9655676
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _TCORE_IDLER_H
+#define _TCORE_IDLER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <Eo.h>
+#include <stdbool.h>
+
+#include "../Ecore.h"
+#include "../ecore_private.h"
+
+#include "tcore.h"
+
+Ecore_Idler *tcore_idler_add(Ecore_Task_Cb func, const void *data);
+
+void *tcore_idler_del(Ecore_Idler *idler);
+
+Ecore_Idle_Enterer *tcore_idle_enterer_add(Ecore_Task_Cb func,
+                                           const void *data);
+
+Ecore_Idle_Enterer *tcore_idle_enterer_before_add(Ecore_Task_Cb func,
+                                                  const void *data);
+
+void *tcore_idle_enterer_del(Ecore_Idle_Enterer *idle_enterer);
+
+Ecore_Idle_Exiter *tcore_idle_exiter_add(Ecore_Task_Cb func, const void *data);
+
+void *tcore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _TCORE_IDLER_H */