cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=c96383e42c8d8b2de64ebbe14fc9fe02eb09f037

commit c96383e42c8d8b2de64ebbe14fc9fe02eb09f037
Author: Cedric BAIL <ced...@osg.samsung.com>
Date:   Fri May 6 15:33:36 2016 -0700

    ecore: add Efl.Loop.Fd.
    
    This allow you to monitor fd and get notification using Eo events. I
    have not implemented the buffered read as used by X. I think that if
    this is useful, we should just do another class to handle bufferred fd.
---
 src/Makefile_Ecore.am        |   2 +
 src/lib/ecore/Ecore_Eo.h     |   2 +
 src/lib/ecore/efl_loop_fd.c  | 177 +++++++++++++++++++++++++++++++++++++++++++
 src/lib/ecore/efl_loop_fd.eo |  46 +++++++++++
 4 files changed, 227 insertions(+)

diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index fbbd4f3..197dbd2 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -10,6 +10,7 @@ ecore_eolian_files_legacy = \
 ecore_eolian_files = \
        lib/ecore/efl_loop.eo \
        lib/ecore/efl_loop_user.eo \
+       lib/ecore/efl_loop_fd.eo \
        lib/ecore/ecore_parent.eo \
        $(ecore_eolian_files_legacy)
 
@@ -60,6 +61,7 @@ lib/ecore/ecore_idler.c \
 lib/ecore/ecore_job.c \
 lib/ecore/ecore_main.c \
 lib/ecore/efl_loop_user.c \
+lib/ecore/efl_loop_fd.c \
 lib/ecore/ecore_pipe.c \
 lib/ecore/ecore_poller.c \
 lib/ecore/ecore_time.c \
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index 3106489..10e9c42 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -64,6 +64,8 @@ extern "C" {
 
 #include "efl_loop_user.eo.h"
 
+#include "efl_loop_fd.eo.h"
+
 /* We ue the factory pattern here, so you shouldn't call eo_add directly. */
 EAPI Eo *ecore_main_loop_get(void);
 
diff --git a/src/lib/ecore/efl_loop_fd.c b/src/lib/ecore/efl_loop_fd.c
new file mode 100644
index 0000000..fbef974
--- /dev/null
+++ b/src/lib/ecore/efl_loop_fd.c
@@ -0,0 +1,177 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <Ecore.h>
+
+#include "ecore_private.h"
+
+#define MY_CLASS EFL_LOOP_FD_CLASS
+
+typedef struct _Efl_Loop_Fd_Data Efl_Loop_Fd_Data;
+struct _Efl_Loop_Fd_Data
+{
+   Ecore_Fd_Handler *handler;
+
+   struct {
+      unsigned int read;
+      unsigned int write;
+      unsigned int error;
+   } references;
+
+   int fd;
+
+   Eina_Bool file : 1;
+};
+
+static Eina_Bool
+_efl_loop_fd_read_cb(void *data, Ecore_Fd_Handler *fd_handler)
+{
+   Eo *obj = data;
+
+   if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
+     {
+        eo_event_callback_call(obj, EFL_LOOP_FD_EVENT_READ, NULL);
+     }
+   if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
+     {
+        eo_event_callback_call(obj, EFL_LOOP_FD_EVENT_WRITE, NULL);
+     }
+   if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
+     {
+        eo_event_callback_call(obj, EFL_LOOP_FD_EVENT_ERROR, NULL);
+     }
+
+   return ECORE_CALLBACK_RENEW;
+}
+
+static void
+_efl_loop_fd_reset(Eo *obj, Efl_Loop_Fd_Data *pd)
+{
+   int flags = 0;
+
+   if (pd->handler) ecore_main_fd_handler_del(pd->handler);
+   pd->handler = NULL;
+   if (pd->fd < 0) return ;
+   flags |= pd->references.read > 0 ? ECORE_FD_READ : 0;
+   flags |= pd->references.write > 0 ? ECORE_FD_WRITE : 0;
+   flags |= pd->references.error > 0 ? ECORE_FD_ERROR : 0;
+   if (flags == 0) return ;
+
+   if (pd->file)
+     pd->handler = ecore_main_fd_handler_file_add(pd->fd, flags, 
_efl_loop_fd_read_cb, obj, NULL, NULL);
+   else
+     pd->handler = ecore_main_fd_handler_add(pd->fd, flags, 
_efl_loop_fd_read_cb, obj, NULL, NULL);
+}
+
+static void
+_efl_loop_fd_fd_set(Eo *obj, Efl_Loop_Fd_Data *pd, int fd)
+{
+   pd->fd = fd;
+   pd->file = EINA_FALSE;
+   _efl_loop_fd_reset(obj, pd);
+}
+
+static int
+_efl_loop_fd_fd_get(Eo *obj EINA_UNUSED, Efl_Loop_Fd_Data *pd)
+{
+   return pd->file ? -1 : pd->fd;
+}
+
+static void
+_efl_loop_fd_fd_file_set(Eo *obj, Efl_Loop_Fd_Data *pd, int fd)
+{
+   pd->fd = fd;
+   pd->file = EINA_TRUE;
+   _efl_loop_fd_reset(obj, pd);
+}
+
+static int
+_efl_loop_fd_fd_file_get(Eo *obj EINA_UNUSED, Efl_Loop_Fd_Data *pd)
+{
+   return pd->file ? pd->fd : -1;
+}
+
+static Eina_Bool
+_check_fd_event_catcher_add(void *data, const Eo_Event *event)
+{
+   const Eo_Callback_Array_Item *array = event->info;
+   Efl_Loop_Fd_Data *fd = data;
+   int i;
+
+   for (i = 0; array[i].desc != NULL; i++)
+     {
+        if (array[i].desc == EFL_LOOP_FD_EVENT_READ)
+          {
+             if (fd->references.read++ > 0) continue;
+             _efl_loop_fd_reset(event->obj, fd);
+          }
+        else if (array[i].desc == EFL_LOOP_FD_EVENT_WRITE)
+          {
+             if (fd->references.write++ > 0) continue;
+             _efl_loop_fd_reset(event->obj, fd);
+          }
+        if (array[i].desc == EFL_LOOP_FD_EVENT_ERROR)
+          {
+             if (fd->references.error++ > 0) continue;
+             _efl_loop_fd_reset(event->obj, fd);
+          }
+     }
+
+   return EO_CALLBACK_CONTINUE;
+}
+
+static Eina_Bool
+_check_fd_event_catcher_del(void *data, const Eo_Event *event)
+{
+   const Eo_Callback_Array_Item *array = event->info;
+   Efl_Loop_Fd_Data *fd = data;
+   int i;
+
+   for (i = 0; array[i].desc != NULL; i++)
+     {
+        if (array[i].desc == EFL_LOOP_FD_EVENT_READ)
+          {
+             if (fd->references.read++ > 0) continue;
+             _efl_loop_fd_reset(event->obj, fd);
+          }
+        else if (array[i].desc == EFL_LOOP_FD_EVENT_WRITE)
+          {
+             if (fd->references.write++ > 0) continue;
+             _efl_loop_fd_reset(event->obj, fd);
+          }
+        if (array[i].desc == EFL_LOOP_FD_EVENT_ERROR)
+          {
+             if (fd->references.error++ > 0) continue;
+             _efl_loop_fd_reset(event->obj, fd);
+          }
+     }
+
+   return EO_CALLBACK_CONTINUE;
+}
+
+EO_CALLBACKS_ARRAY_DEFINE(fd_watch,
+                          { EO_BASE_EVENT_CALLBACK_ADD, 
_check_fd_event_catcher_add },
+                          { EO_BASE_EVENT_CALLBACK_DEL, 
_check_fd_event_catcher_del });
+
+static Eo_Base *
+_efl_loop_fd_eo_base_constructor(Eo *obj, Efl_Loop_Fd_Data *pd)
+{
+   eo_constructor(eo_super(obj, MY_CLASS));
+
+   eo_event_callback_array_add(obj, fd_watch(), pd);
+
+   pd->fd = -1;
+
+   return obj;
+}
+
+static void
+_efl_loop_fd_eo_base_destructor(Eo *obj, Efl_Loop_Fd_Data *pd)
+{
+   eo_destructor(eo_super(obj, MY_CLASS));
+
+   ecore_main_fd_handler_del(pd->handler);
+}
+
+#include "efl_loop_fd.eo.c"
diff --git a/src/lib/ecore/efl_loop_fd.eo b/src/lib/ecore/efl_loop_fd.eo
new file mode 100644
index 0000000..1be9f0a
--- /dev/null
+++ b/src/lib/ecore/efl_loop_fd.eo
@@ -0,0 +1,46 @@
+import eina_types;
+
+class Efl.Loop.Fd (Efl.Loop_User)
+{
+   [[Fds are objects that what the activity on a given
+     file descriptor. This file descriptor can be a
+     network, a file, provided by a library.
+
+     The object will trigger relevant event depending
+     on what is happening.]]
+
+   legacy_prefix: null;
+   methods {
+      @property fd {
+         [[Define which file descriptor to watch. If it is a file, use file_fd 
variant.]]
+        set {
+           [[Define the fd to watch on.]]
+        }
+        get {
+        }
+        values {
+           fd: int; [[The file descriptor.]]
+        }
+      }
+      @property fd_file {
+         [[Define which file descriptor to watch when watching a file.]]
+        set {
+           [[Define the fd to watch on.]]
+        }
+        get {
+        }
+        values {
+           fd: int; [[The file descriptor.]]
+        }
+      }
+   }
+   events {
+      read;
+      write;
+      error;
+   }
+   implements {
+      Eo.Base.constructor;
+      Eo.Base.destructor;
+   }
+}

-- 


Reply via email to