vitorsousa pushed a commit to branch master.

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

commit a6025b5d27f98b8595a1eb33f8f24fe998af8b90
Author: Vitor Sousa <vitorsousasi...@gmail.com>
Date:   Wed Mar 16 16:08:45 2016 -0300

    efl js: Finish Eina_Iterator binding
---
 src/bindings/js/eina_js/eina_js_compatibility.hh   |  22 ++++
 src/bindings/js/eina_js/eina_js_get_value.hh       |  14 ++-
 .../js/eina_js/eina_js_get_value_from_c.hh         |  16 ++-
 src/bindings/js/eina_js/eina_js_iterator.cc        |   1 +
 src/bindings/js/eina_js/eina_js_iterator.hh        |  50 ++++----
 src/tests/eolian_js/eolian_js_suite.js             | 127 +++++++++++++++++++++
 .../eolian_js/eolian_js_test_test_object_impl.c    | 122 ++++++++++++++++++++
 src/tests/eolian_js/test_object.eo                 |  42 +++++++
 8 files changed, 364 insertions(+), 30 deletions(-)

diff --git a/src/bindings/js/eina_js/eina_js_compatibility.hh 
b/src/bindings/js/eina_js/eina_js_compatibility.hh
index 7cc16a3..fb36e4e 100644
--- a/src/bindings/js/eina_js/eina_js_compatibility.hh
+++ b/src/bindings/js/eina_js/eina_js_compatibility.hh
@@ -134,6 +134,22 @@ struct container_wrapper
 };
 
 template <typename T>
+inline T get_c_container_data(void* ptr, typename std::enable_if<
+  std::is_pointer<T>::value
+>::type* = 0)
+{
+  return static_cast<T>(ptr);
+}
+
+template <typename T>
+inline T get_c_container_data(void* ptr, typename std::enable_if<
+  !std::is_pointer<T>::value
+>::type* = 0)
+{
+  return *static_cast<T*>(ptr);
+}
+
+template <typename T>
 T container_wrap(T&& v)
 {
   return std::forward<T>(v);
@@ -259,6 +275,12 @@ v8::Local<v8::Object> 
export_accessor(::efl::eina::accessor<W>&, v8::Isolate*, c
 template <typename T>
 ::efl::eina::accessor<T>& import_accessor(v8::Handle<v8::Object>);
 
+// Iterator
+template <typename T>
+inline v8::Local<v8::Object> export_iterator(Eina_Iterator*, v8::Isolate*, 
const char*);
+
+inline Eina_Iterator* import_iterator(v8::Handle<v8::Object>);
+
 // Wrap value functions
 template <typename R, typename T>
 typename std::remove_cv<typename std::remove_reference<R>::type>::type
diff --git a/src/bindings/js/eina_js/eina_js_get_value.hh 
b/src/bindings/js/eina_js/eina_js_get_value.hh
index 637b48a..5d62b28 100644
--- a/src/bindings/js/eina_js/eina_js_get_value.hh
+++ b/src/bindings/js/eina_js/eina_js_get_value.hh
@@ -333,18 +333,24 @@ inline const Eina_Array* get_value_from_javascript(
   return get_value_from_javascript(v, isolate, class_name, 
value_tag<complex_tag<Eina_Array *, I...>>{}, throw_js_exception);
 }
 
-template <typename...I>
+template <typename T, typename K>
 inline Eina_Iterator* get_value_from_javascript(
-  v8::Local<v8::Value>,
+  v8::Local<v8::Value> v,
   v8::Isolate* isolate,
   const char*,
-  value_tag<complex_tag<Eina_Iterator *, I...>> tag,
+  value_tag<complex_tag<Eina_Iterator *, T, K>> /*tag*/,
   bool throw_js_exception = true)
 {
+  if(v->IsNull())
+    return nullptr;
+  else if(v->IsObject())
+    {
+       return import_iterator(v->ToObject());
+    }
   if (throw_js_exception)
     eina::js::compatibility_throw
       (isolate, v8::Exception::TypeError
-       (eina::js::compatibility_new<v8::String>(isolate, "Not implemented 
yet")));
+       (eina::js::compatibility_new<v8::String>(isolate, "Type expected is 
different. Expected Eolian accessor type")));
   throw std::logic_error("");
 }
 
diff --git a/src/bindings/js/eina_js/eina_js_get_value_from_c.hh 
b/src/bindings/js/eina_js/eina_js_get_value_from_c.hh
index 9a0089e..204c497 100644
--- a/src/bindings/js/eina_js/eina_js_get_value_from_c.hh
+++ b/src/bindings/js/eina_js/eina_js_get_value_from_c.hh
@@ -207,18 +207,22 @@ get_value_from_c(efl::eina::js::complex_tag<const 
Eina_Array *, T, K> v, v8::Iso
 
 template <typename T, typename K>
 inline v8::Local<v8::Value>
-get_value_from_c(efl::eina::js::complex_tag<Eina_Iterator *, T, K>, 
v8::Isolate*, const char*)
+get_value_from_c(efl::eina::js::complex_tag<Eina_Iterator *, T, K> v, 
v8::Isolate* isolate, const char*)
 {
-  std::cerr << "get_value_from_c for Eina_Iterator not implemented. 
Aborting..." << std::endl;
-  std::abort();
+  bool own = false; // TODO: handle ownership
+  auto ptr = v.value;
+  auto obj = export_iterator<T>(ptr , isolate, K::class_name());
+  if (own && ptr)
+    efl::eina::js::make_weak(isolate, obj, [ptr]{ ::eina_iterator_free(ptr); 
});
+  return obj;
 }
 
 template <typename T, typename K>
 inline v8::Local<v8::Value>
-get_value_from_c(efl::eina::js::complex_tag<const Eina_Iterator *, T, K>, 
v8::Isolate*, const char*)
+get_value_from_c(efl::eina::js::complex_tag<const Eina_Iterator *, T, K> v, 
v8::Isolate* isolate, const char* class_name)
 {
-  std::cerr << "get_value_from_c for Eina_Iterator not implemented. 
Aborting..." << std::endl;
-  std::abort();
+  // TODO: implement const iterators?
+  return get_value_from_c(efl::eina::js::complex_tag<Eina_Iterator *, T, 
K>{const_cast<Eina_Iterator*>(v.value)}, isolate, class_name);
 }
 
 template <typename T, typename KT, typename U, typename KU>
diff --git a/src/bindings/js/eina_js/eina_js_iterator.cc 
b/src/bindings/js/eina_js/eina_js_iterator.cc
index d2480b8..40d0db3 100644
--- a/src/bindings/js/eina_js/eina_js_iterator.cc
+++ b/src/bindings/js/eina_js/eina_js_iterator.cc
@@ -23,6 +23,7 @@ void register_destroy_iterator(v8::Isolate *isolate,
 
         deleter_t deleter = 
compatibility_get_pointer_internal_field<deleter_t>(o, 1);
         deleter(compatibility_get_pointer_internal_field<>(o, 0));
+        compatibility_set_pointer_internal_field(o, 0, static_cast<void*>(0));
         return compatibility_return();
       };
 
diff --git a/src/bindings/js/eina_js/eina_js_iterator.hh 
b/src/bindings/js/eina_js/eina_js_iterator.hh
index ed0066b..7021a7b 100644
--- a/src/bindings/js/eina_js/eina_js_iterator.hh
+++ b/src/bindings/js/eina_js/eina_js_iterator.hh
@@ -18,12 +18,12 @@ namespace efl { namespace eina { namespace js {
    The iterator will have the `next` function, but the returned object won't
    have a `done` attribute, because the eina_iterator itself doesn't expose 
this
    information.*/
-template<class T>
-v8::Local<v8::Object> export_iterator(::efl::eina::iterator<T> *i,
-                                      v8::Isolate *isolate)
+template <typename T>
+inline v8::Local<v8::Object> export_iterator(Eina_Iterator *i,
+                                             v8::Isolate *isolate,
+                                             const char *class_name)
 {
-    typedef ::efl::eina::iterator<T> value_type;
-    typedef value_type *ptr_type;
+    using no_tag_type = typename remove_tag<T>::type;
     typedef void (*deleter_t)(void*);
 
     auto obj_tpl = compatibility_new<v8::ObjectTemplate>(isolate);
@@ -37,20 +37,33 @@ v8::Local<v8::Object> 
export_iterator(::efl::eina::iterator<T> *i,
           return compatibility_return();
 
         void *ptr = compatibility_get_pointer_internal_field(info.This(), 0);
-        auto &value = *static_cast<ptr_type>(ptr);
+        auto it = static_cast<Eina_Iterator*>(ptr);
+        void *value = nullptr;
+        auto done = !::eina_iterator_next(it, &value);
         v8::Local<v8::Object> o = 
compatibility_new<v8::Object>(info.GetIsolate());
-        o->Set(compatibility_new<v8::String>(info.GetIsolate(), "value"),
-               value_cast<v8::Local<v8::Value>>(*value, info.GetIsolate()));
-        ++value;
+        o->Set(compatibility_new<v8::String>(info.GetIsolate(), "done"),
+               compatibility_new<v8::Boolean>(info.GetIsolate(), done));
+        if (!done)
+          {
+             std::string obj_class_name;
+             if (info.Data()->IsString())
+               {
+                  v8::String::Utf8Value str(info.Data());
+                  obj_class_name = *str;
+               }
+             o->Set(compatibility_new<v8::String>(info.GetIsolate(), "value"),
+                    
get_value_from_c(js::wrap_value<T>(get_c_container_data<no_tag_type>(value), 
js::value_tag<T>{}),
+                                     info.GetIsolate(), 
obj_class_name.c_str()));
+          }
         return compatibility_return(o, info);
       };
 
     ret->Set(compatibility_new<v8::String>(isolate, "next"),
-             compatibility_new<v8::FunctionTemplate>(isolate, 
next)->GetFunction());
+             compatibility_new<v8::FunctionTemplate>(isolate, next, 
js::compatibility_new<v8::String>(isolate, class_name))->GetFunction());
 
     {
         deleter_t deleter = [](void *i) {
-            delete static_cast<ptr_type>(i);
+            ::eina_iterator_free(static_cast<Eina_Iterator*>(i));
         };
         compatibility_set_pointer_internal_field(ret, 0, i);
         compatibility_set_pointer_internal_field
@@ -62,15 +75,12 @@ v8::Local<v8::Object> 
export_iterator(::efl::eina::iterator<T> *i,
 
 /* Extracts and returns a copy from the internal iterator object from the JS
    object. */
-template<class T>
-::efl::eina::iterator<T> *import_iterator(v8::Handle<v8::Object> o)
-  ;
-// {
-//     typedef ::efl::eina::iterator<T> value_type;
-//     typedef value_type *ptr_type;
-
-//     return 
reinterpret_cast<ptr_type>(o->GetAlignedPointerFromInternalField(0));
-// }
+inline
+Eina_Iterator* import_iterator(v8::Handle<v8::Object> o)
+{
+    void* ptr = compatibility_get_pointer_internal_field(o, 0);
+    return static_cast<Eina_Iterator*>(ptr);
+}
 
 void register_destroy_iterator(v8::Isolate *isolate,
                                v8::Handle<v8::Object> global,
diff --git a/src/tests/eolian_js/eolian_js_suite.js 
b/src/tests/eolian_js/eolian_js_suite.js
index 9c66dba..66e5596 100755
--- a/src/tests/eolian_js/eolian_js_suite.js
+++ b/src/tests/eolian_js/eolian_js_suite.js
@@ -252,6 +252,8 @@ startTest("struct_values", function() {
   assert(ret.valueEnum === suite.Test.EnumEx.FOURTH);
 });
 
+// Events //
+
 startTest("event_simple", function() {
   var v = false;
   var obj = new TestObject(null);
@@ -332,6 +334,8 @@ startTest("event_stringarg", function() {
    assert(v);
 });
 
+// Array //
+
 // // TODO: disabled. Not implemented yet
 // startTest("integral_array", function() {
 //   var obj = new TestObject(null);
@@ -431,6 +435,8 @@ startTest("method_array_of_structs", function() {
   assert(s.valueEnum === suite.Test.EnumEx.THIRD);
 });
 
+// List //
+
 startTest("list_in_list_out", function() {
   var obj = new TestObject(null);
   var newList = obj.checkMethodListWith42();
@@ -524,6 +530,8 @@ startTest("method_list_of_structs", function() {
   assert(s.valueEnum === suite.Test.EnumEx.THIRD);
 });
 
+// Accessor //
+
 startTest("method_accessor_of_objects", function() {
   var obj = new TestObject(null);
   var acc = obj.checkMethodAccessorOfObjects(null);
@@ -606,6 +614,125 @@ startTest("method_accessor_of_structs", function() {
   assert(s.valueEnum === suite.Test.EnumEx.THIRD);
 });
 
+// Iterator //
+
+startTest("method_iterator_of_objects", function() {
+  var obj = new TestObject(null);
+  var it = obj.checkMethodIteratorOfObjects(null);
+  assert(it != null);
+  it = obj.checkMethodIteratorOfObjects(it);
+  assert(it != null);
+  var idx = 0;
+  for (var n = it.next(); !n.done; n = it.next()) {
+    var v = n.value;
+    assert(v != null);
+    var expectedValue = 1234;
+    v.checkMethodIntegralInA(expectedValue);
+    var actualValue = v.checkMethodIntegralOutA();
+    assert(actualValue == expectedValue, actualValue + " == " + expectedValue);
+    idx++;
+  }
+  assert(idx == 2, idx + " == 2");
+});
+
+startTest("method_iterator_of_strings", function() {
+  var obj = new TestObject(null);
+  var it = obj.checkMethodIteratorOfStrings(null);
+  assert(it != null);
+  it = obj.checkMethodIteratorOfStrings(it);
+  assert(it != null);
+  var cmp = ["foo", "bar"];
+  var idx = 0;
+  for (var n = it.next(); !n.done; n = it.next()) {
+    var v = n.value;
+    assert(v === cmp[idx], idx+": "+v+" === "+cmp[idx]);
+    idx++;
+  }
+  assert(idx == 2, idx + " == 2");
+});
+
+startTest("method_iterator_of_ints", function() {
+  var obj = new TestObject(null);
+  var it = obj.checkMethodIteratorOfInts(null);
+  assert(it != null);
+  it = obj.checkMethodIteratorOfInts(it);
+  assert(it != null);
+  var cmp = [42, 24];
+  var idx = 0;
+  for (var n = it.next(); !n.done; n = it.next()) {
+    var v = n.value;
+    assert(v === cmp[idx], idx+": "+v+" === "+cmp[idx]);
+    idx++;
+  }
+  assert(idx == 2, idx + " == 2");
+});
+
+startTest("method_iterator_of_bools", function() {
+  var obj = new TestObject(null);
+  var it = obj.checkMethodIteratorOfBools(null);
+  assert(it != null);
+  it = obj.checkMethodIteratorOfBools(it);
+  assert(it != null);
+  var cmp = [true, false];
+  var idx = 0;
+  for (var n = it.next(); !n.done; n = it.next()) {
+    var v = n.value;
+    assert(v === cmp[idx], idx+": "+v+" === "+cmp[idx]);
+    idx++;
+  }
+  assert(idx == 2, idx + " == 2");
+});
+
+startTest("method_iterator_of_doubles", function() {
+  var obj = new TestObject(null);
+  var it = obj.checkMethodIteratorOfDoubles(null);
+  assert(it != null);
+  it = obj.checkMethodIteratorOfDoubles(it);
+  assert(it != null);
+  var cmp = [42.0, 24.0];
+  var idx = 0;
+  for (var n = it.next(); !n.done; n = it.next()) {
+    var v = n.value;
+    assert(v === cmp[idx], idx+": "+v+" === "+cmp[idx]);
+    idx++;
+  }
+  assert(idx == 2, idx + " == 2");
+});
+
+startTest("method_iterator_of_enums", function() {
+  var obj = new TestObject(null);
+  var it = obj.checkMethodIteratorOfEnums(null);
+  assert(it != null);
+  it = obj.checkMethodIteratorOfEnums(it);
+  assert(it != null);
+  var cmp = [suite.Test.EnumEx.THIRD, suite.Test.EnumEx.FIRST];
+  var idx = 0;
+  for (var n = it.next(); !n.done; n = it.next()) {
+    var v = n.value;
+    assert(v === cmp[idx], idx+": "+v+" === "+cmp[idx]);
+    idx++;
+  }
+  assert(idx == 2, idx + " == 2");
+});
+
+startTest("method_iterator_of_structs", function() {
+  var obj = new TestObject(null);
+  var it = obj.checkMethodIteratorOfStructs(null);
+  assert(it != null);
+  it = obj.checkMethodIteratorOfStructs(it);
+  assert(it != null);
+  var cmp = [[42, suite.Test.EnumEx.THIRD], [24, suite.Test.EnumEx.FIRST]];
+  var idx = 0;
+  for (var n = it.next(); !n.done; n = it.next()) {
+    var v = n.value;
+    assert(v != null);
+    assert(v.valueInt === cmp[idx][0], idx+": "+v.valueInt+" === 
"+cmp[idx][0]);
+    assert(v.valueEnum === cmp[idx][1], idx+": "+v.valueEnum+" === 
"+cmp[idx][1]);
+    idx++;
+  }
+  assert(idx == 2, idx + " == 2");
+});
+
 // Combinations of complex types //
 
 // FIXME
diff --git a/src/tests/eolian_js/eolian_js_test_test_object_impl.c 
b/src/tests/eolian_js/eolian_js_test_test_object_impl.c
index aecfbbf..34981a1 100644
--- a/src/tests/eolian_js/eolian_js_test_test_object_impl.c
+++ b/src/tests/eolian_js/eolian_js_test_test_object_impl.c
@@ -587,6 +587,128 @@ _test_object_method_accessor_of_structs_check(Eo* obj 
EINA_UNUSED,
   return eina_array_accessor_new(arr);
 }
 
+// Iterator //
+
+EOLIAN static Eina_Iterator *
+_test_object_method_iterator_of_objects_check(Eo* obj,
+  Test_Object_Data *pd EINA_UNUSED,
+  Eina_Iterator *i_in)
+{
+  fprintf(stdout, "_test_object_method_iterator_of_objects_check(%p)\n", i_in);
+  fflush(stdout);
+  if (i_in) return i_in;
+  Eina_Array *arr = eina_array_new(2);
+  eina_array_push(arr, obj);
+  eina_array_push(arr, obj);
+  return eina_array_iterator_new(arr);
+}
+
+EOLIAN static Eina_Iterator *
+_test_object_method_iterator_of_strings_check(Eo* obj EINA_UNUSED,
+  Test_Object_Data *pd EINA_UNUSED,
+  Eina_Iterator *i_in)
+{
+  fprintf(stdout, "_test_object_method_iterator_of_strings_check(%p)\n", i_in);
+  fflush(stdout);
+  if (i_in) return i_in;
+  Eina_Array *arr = eina_array_new(2);
+  eina_array_push(arr, "foo");
+  eina_array_push(arr, "bar");
+  return eina_array_iterator_new(arr);
+}
+
+EOLIAN static Eina_Iterator *
+_test_object_method_iterator_of_ints_check(Eo* obj EINA_UNUSED,
+  Test_Object_Data *pd EINA_UNUSED,
+  Eina_Iterator *i_in)
+{
+  fprintf(stdout, "_test_object_method_iterator_of_ints_check(%p)\n", i_in);
+  fflush(stdout);
+  if (i_in) return i_in;
+  Eina_Array *arr = eina_array_new(2);
+  int *v = malloc(sizeof(int));
+  *v = 42;
+  eina_array_push(arr, v);
+  v = malloc(sizeof(int));
+  *v = 24;
+  eina_array_push(arr, v);
+  return eina_array_iterator_new(arr);
+}
+
+EOLIAN static Eina_Iterator *
+_test_object_method_iterator_of_bools_check(Eo* obj EINA_UNUSED,
+  Test_Object_Data *pd EINA_UNUSED,
+  Eina_Iterator *i_in)
+{
+  fprintf(stdout, "_test_object_method_iterator_of_bools_check(%p)\n", i_in);
+  fflush(stdout);
+  if (i_in) return i_in;
+  Eina_Array *arr = eina_array_new(2);
+  Eina_Bool *v = malloc(sizeof(Eina_Bool));
+  *v = EINA_TRUE;
+  eina_array_push(arr, v);
+  v = malloc(sizeof(Eina_Bool));
+  *v = EINA_FALSE;
+  eina_array_push(arr, v);
+  return eina_array_iterator_new(arr);
+}
+
+EOLIAN static Eina_Iterator *
+_test_object_method_iterator_of_doubles_check(Eo* obj EINA_UNUSED,
+  Test_Object_Data *pd EINA_UNUSED,
+  Eina_Iterator *i_in)
+{
+  fprintf(stdout, "_test_object_method_iterator_of_doubles_check(%p)\n", i_in);
+  fflush(stdout);
+  if (i_in) return i_in;
+  Eina_Array *arr = eina_array_new(2);
+  double *v = malloc(sizeof(double));
+  *v = 42.0;
+  eina_array_push(arr, v);
+  v = malloc(sizeof(double));
+  *v = 24.0;
+  eina_array_push(arr, v);
+  return eina_array_iterator_new(arr);
+}
+
+EOLIAN static Eina_Iterator *
+_test_object_method_iterator_of_enums_check(Eo* obj EINA_UNUSED,
+  Test_Object_Data *pd EINA_UNUSED,
+  Eina_Iterator *i_in)
+{
+  fprintf(stdout, "_test_object_method_iterator_of_enums_check(%p)\n", i_in);
+  fflush(stdout);
+  if (i_in) return i_in;
+  Eina_Array *arr = eina_array_new(2);
+  Test_Enum_Ex *v = malloc(sizeof(Test_Enum_Ex));
+  *v = TEST_ENUM_EX_THIRD;
+  eina_array_push(arr, v);
+  v = malloc(sizeof(Test_Enum_Ex));
+  *v = TEST_ENUM_EX_FIRST;
+  eina_array_push(arr, v);
+  return eina_array_iterator_new(arr);
+}
+
+EOLIAN static Eina_Iterator *
+_test_object_method_iterator_of_structs_check(Eo* obj EINA_UNUSED,
+  Test_Object_Data *pd EINA_UNUSED,
+  Eina_Iterator *i_in)
+{
+  fprintf(stdout, "_test_object_method_iterator_of_structs_check(%p)\n", i_in);
+  fflush(stdout);
+  if (i_in) return i_in;
+  Eina_Array *arr = eina_array_new(2);
+  Test_Struct_Ex *v = malloc(sizeof(Test_Struct_Ex));
+  v->value_int = 42;
+  v->value_enum = TEST_ENUM_EX_THIRD;
+  eina_array_push(arr, v);
+  v = malloc(sizeof(Test_Struct_Ex));
+  v->value_int = 24;
+  v->value_enum = TEST_ENUM_EX_FIRST;
+  eina_array_push(arr, v);
+  return eina_array_iterator_new(arr);
+}
+
 // Combinations of complex types
 
 EOLIAN static Eina_List *
diff --git a/src/tests/eolian_js/test_object.eo 
b/src/tests/eolian_js/test_object.eo
index 81043fe..4cbfbdc 100644
--- a/src/tests/eolian_js/test_object.eo
+++ b/src/tests/eolian_js/test_object.eo
@@ -251,6 +251,48 @@ class Test.Object (Eo.Base) {
            }
            return: accessor<Test.Struct_Ex> *;
        }
+       method_iterator_of_objects_check {
+           params {
+               @in i_in: iterator<Test.Object *> *;
+           }
+           return: iterator<Test.Object *> *;
+       }
+       method_iterator_of_strings_check {
+           params {
+               @in i_in: iterator<const(char) *> *;
+           }
+           return: iterator<const(char) *> *;
+       }
+       method_iterator_of_ints_check {
+           params {
+               @in i_in: iterator<int> *;
+           }
+           return: iterator<int> *;
+       }
+       method_iterator_of_bools_check {
+           params {
+               @in i_in: iterator<bool> *;
+           }
+           return: iterator<bool> *;
+       }
+       method_iterator_of_doubles_check {
+           params {
+               @in i_in: iterator<double> *;
+           }
+           return: iterator<double> *;
+       }
+       method_iterator_of_enums_check {
+           params {
+               @in i_in: iterator<Test.Enum_Ex> *;
+           }
+           return: iterator<Test.Enum_Ex> *;
+       }
+       method_iterator_of_structs_check {
+           params {
+               @in i_in: iterator<Test.Struct_Ex> *;
+           }
+           return: iterator<Test.Struct_Ex> *;
+       }
        method_array_of_arrays_of_ints_check {
            params {
                @in a_in: array<array<int> *> *;

-- 


Reply via email to