cedric pushed a commit to branch master.

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

commit 75f43ca971bb476f4c3639a198b764e6520fc859
Author: Cedric BAIL <cedric.b...@free.fr>
Date:   Wed Apr 3 14:23:01 2019 -0700

    ecore: add an helper for Efl.Boolean_Model to get all the index with a 
requested value.
    
    Differential Revision: https://phab.enlightenment.org/D8569
---
 src/lib/ecore/efl_boolean_model.c  | 117 +++++++++++++++++++++++++++++++++++++
 src/lib/ecore/efl_boolean_model.eo |   8 +++
 2 files changed, 125 insertions(+)

diff --git a/src/lib/ecore/efl_boolean_model.c 
b/src/lib/ecore/efl_boolean_model.c
index da9d3bdf96..20aed0fe50 100644
--- a/src/lib/ecore/efl_boolean_model.c
+++ b/src/lib/ecore/efl_boolean_model.c
@@ -207,4 +207,121 @@ _efl_boolean_model_boolean_del(Eo *obj EINA_UNUSED,
    eina_stringshare_del(s);
 }
 
+typedef struct _Eina_Iterator_Boolean Eina_Iterator_Boolean;
+
+struct _Eina_Iterator_Boolean
+{
+   Eina_Iterator iterator;
+
+   Eo *obj;
+   Efl_Boolean_Model_Data *pd;
+   Efl_Boolean_Model_Value *v;
+
+   uint64_t index;
+   uint64_t total;
+
+   Eina_Bool request;
+};
+
+static inline Eina_Bool
+_lookup_next_chunk(uint64_t *index, uint64_t total,
+                   Efl_Boolean_Model_Value *v, unsigned char pattern)
+{
+   uint64_t upidx = *index >> 3;
+
+   while (upidx < v->buffer_count &&
+          v->buffer[upidx] == pattern)
+     upidx++;
+
+   *index = upidx << 3;
+   if (upidx == v->buffer_count &&
+       *index >= total) return EINA_FALSE;
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+efl_boolean_model_iterator_next(Eina_Iterator_Boolean *it, void **data)
+{
+   uint64_t upidx;
+
+   *data = &it->index;
+   it->index++;
+
+ retry:
+   if (it->index >= it->total) return EINA_FALSE;
+   if ((it->index >> 3) >= it->v->buffer_count)
+     {
+        if (it->v->default_value != it->request)
+          return EINA_FALSE;
+        return EINA_TRUE;
+     }
+
+   upidx = it->index >> 3;
+   while ((it->index >> 3) == upidx)
+     {
+        Eina_Bool flag = it->v->buffer[it->index >> 3] &
+          (((unsigned char)1) << (it->index & 0x7));
+
+        if (it->request == !!flag)
+          break;
+
+        it->index++;
+     }
+
+   if ((it->index >> 3) != upidx)
+     {
+        if (!_lookup_next_chunk(&it->index, it->total, it->v, it->request ? 
0x00 : 0xFF))
+          return EINA_FALSE;
+        goto retry;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eo *
+efl_boolean_model_iterator_get_container(Eina_Iterator_Boolean *it)
+{
+   return it->obj;
+}
+
+static void
+efl_boolean_model_iterator_free(Eina_Iterator_Boolean *it)
+{
+   efl_unref(it->obj);
+   EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_NONE);
+   free(it);
+}
+
+static Eina_Iterator *
+_efl_boolean_model_boolean_iterator_get(Eo *obj, Efl_Boolean_Model_Data *pd, 
const char *name, Eina_Bool request)
+{
+   Eina_Iterator_Boolean *itb;
+   Efl_Boolean_Model_Value *v;
+   Eina_Stringshare *s;
+
+   s = eina_stringshare_add(name);
+   v = eina_hash_find(pd->values, s);
+   eina_stringshare_del(s);
+   if (!v) return NULL;
+
+   itb = calloc(1, sizeof (Eina_Iterator_Boolean));
+   if (!itb) return NULL;
+
+   itb->obj = efl_ref(obj);
+   itb->pd = pd;
+   itb->v = v;
+   itb->index = 0;
+   itb->total = efl_model_children_count_get(obj);
+   itb->request = !!request;
+
+   itb->iterator.version = EINA_ITERATOR_VERSION;
+   itb->iterator.next = FUNC_ITERATOR_NEXT(efl_boolean_model_iterator_next);
+   itb->iterator.get_container = 
FUNC_ITERATOR_GET_CONTAINER(efl_boolean_model_iterator_get_container);
+   itb->iterator.free = FUNC_ITERATOR_FREE(efl_boolean_model_iterator_free);
+
+   EINA_MAGIC_SET(&itb->iterator, EINA_MAGIC_ITERATOR);
+   return &itb->iterator;
+}
+
+
 #include "efl_boolean_model.eo.c"
diff --git a/src/lib/ecore/efl_boolean_model.eo 
b/src/lib/ecore/efl_boolean_model.eo
index 19f8f02935..049344d2bb 100644
--- a/src/lib/ecore/efl_boolean_model.eo
+++ b/src/lib/ecore/efl_boolean_model.eo
@@ -15,6 +15,14 @@ class @beta Efl.Boolean_Model extends Efl.Composite_Model
             @in name: string;
         }
       }
+      boolean_iterator_get {
+         [[Get an iterator that will quickly find all the index with the 
requested value for a specific boolean.]]
+         params {
+            @in name: string;
+            @in request: bool;
+         }
+         return: iterator<ptr(uint64)>; [[The iterator that is valid until any 
change is made on the model.]]
+      }
    }
    implements {
       Efl.Model.properties { get; }

-- 


Reply via email to