[Bf-blender-cvs] [61609e90d51] functions-experimental-refactor: initial AttributesRef in functions2

Jacques Lucke noreply at git.blender.org
Sat Nov 2 21:33:00 CET 2019


Commit: 61609e90d5150f4c158c24d168d376ee25d966a3
Author: Jacques Lucke
Date:   Sat Nov 2 20:19:49 2019 +0100
Branches: functions-experimental-refactor
https://developer.blender.org/rB61609e90d5150f4c158c24d168d376ee25d966a3

initial AttributesRef in functions2

===================================================================

M	source/blender/blenlib/BLI_index_range.h
M	source/blender/functions2/CMakeLists.txt
A	source/blender/functions2/FN_attributes_ref.h
M	source/blender/functions2/FN_cpp_type.h
A	source/blender/functions2/intern/attributes_ref.cc
M	tests/gtests/blenlib/BLI_index_range_test.cc

===================================================================

diff --git a/source/blender/blenlib/BLI_index_range.h b/source/blender/blenlib/BLI_index_range.h
index a1fed5bd97c..dab4ea243a9 100644
--- a/source/blender/blenlib/BLI_index_range.h
+++ b/source/blender/blenlib/BLI_index_range.h
@@ -179,6 +179,11 @@ class IndexRange {
     return IndexRange(new_start, size);
   }
 
+  IndexRange slice(IndexRange range) const
+  {
+    return this->slice(range.start(), range.size());
+  }
+
   /**
    * Get read-only access to a memory buffer that contains the range as actual numbers.
    */
diff --git a/source/blender/functions2/CMakeLists.txt b/source/blender/functions2/CMakeLists.txt
index 22f3cc677d0..ce8531a4ee0 100644
--- a/source/blender/functions2/CMakeLists.txt
+++ b/source/blender/functions2/CMakeLists.txt
@@ -29,12 +29,14 @@ set(SRC
   intern/vtree_multi_function_network/mappings_nodes.cc
   intern/vtree_multi_function_network/mappings_sockets.cc
   intern/vtree_multi_function_network/mappings.cc
+  intern/attributes_ref.cc
   intern/cpp_type.cc
   intern/cpp_types.cc
   intern/generic_tuple.cc
   intern/initialize.cc
   intern/multi_function_network.cc
 
+  FN_attributes_ref.h
   FN_cpp_type.h
   FN_generic_array_ref.h
   FN_generic_tuple.h
diff --git a/source/blender/functions2/FN_attributes_ref.h b/source/blender/functions2/FN_attributes_ref.h
new file mode 100644
index 00000000000..8bc60026def
--- /dev/null
+++ b/source/blender/functions2/FN_attributes_ref.h
@@ -0,0 +1,323 @@
+#ifndef __FN_ATTRIBUTES_REF_H__
+#define __FN_ATTRIBUTES_REF_H__
+
+#include "FN_cpp_type.h"
+
+#include "BLI_vector.h"
+#include "BLI_vector_set.h"
+#include "BLI_string_map.h"
+#include "BLI_optional.h"
+
+namespace FN {
+
+using BLI::ArrayRef;
+using BLI::IndexRange;
+using BLI::MutableArrayRef;
+using BLI::Optional;
+using BLI::StringMap;
+using BLI::Vector;
+using BLI::VectorSet;
+
+class AttributesInfo;
+
+class AttributesInfoBuilder {
+ private:
+  VectorSet<std::string> m_names;
+  Vector<const CPPType *> m_types;
+
+ public:
+  AttributesInfoBuilder() = default;
+
+  template<typename T> void add(StringRef name)
+  {
+    this->add(name, GET_TYPE<T>());
+  }
+
+  void add(StringRef name, const CPPType &type)
+  {
+    if (m_names.add(name)) {
+      m_types.append(&type);
+    }
+    else {
+      BLI_assert(m_types[m_names.index(name)] == &type);
+    }
+  }
+
+  uint size() const
+  {
+    return m_names.size();
+  }
+
+  ArrayRef<std::string> names() const
+  {
+    return m_names;
+  }
+
+  ArrayRef<const CPPType *> types() const
+  {
+    return m_types;
+  }
+
+  void add(const AttributesInfoBuilder &other);
+  void add(const AttributesInfo &other);
+};
+
+class AttributesInfo {
+ private:
+  StringMap<int> m_index_by_name;
+  Vector<std::string> m_name_by_index;
+  Vector<const CPPType *> m_type_by_index;
+
+ public:
+  AttributesInfo() = default;
+  AttributesInfo(const AttributesInfoBuilder &builder);
+
+  uint size() const
+  {
+    return m_name_by_index.size();
+  }
+
+  StringRefNull name_of(uint index) const
+  {
+    return m_name_by_index[index];
+  }
+
+  uint index_of(StringRef name) const
+  {
+    return m_index_by_name.lookup(name);
+  }
+
+  int index_of_try(StringRef name, const CPPType &type) const
+  {
+    int index = this->index_of_try(name);
+    if (index == -1) {
+      return -1;
+    }
+    else if (this->type_of((uint)index) == type) {
+      return index;
+    }
+    else {
+      return -1;
+    }
+  }
+
+  template<typename T> int index_of_try(StringRef name) const
+  {
+    return this->index_of_try(name, GET_TYPE<T>());
+  }
+
+  int index_of_try(StringRef name) const
+  {
+    return m_index_by_name.lookup_default(name, -1);
+  }
+
+  const CPPType &type_of(uint index) const
+  {
+    return *m_type_by_index[index];
+  }
+
+  const CPPType &type_of(StringRef name) const
+  {
+    return this->type_of(this->index_of(name));
+  }
+
+  ArrayRef<const CPPType *> types() const
+  {
+    return m_type_by_index;
+  }
+
+  IndexRange indices() const
+  {
+    return IndexRange(this->size());
+  }
+};
+
+class AttributesRef {
+ private:
+  const AttributesInfo *m_info;
+  ArrayRef<void *> m_buffers;
+  IndexRange m_range;
+
+ public:
+  AttributesRef(const AttributesInfo &info, ArrayRef<void *> buffers, uint size)
+      : AttributesRef(info, buffers, IndexRange(size))
+  {
+  }
+
+  AttributesRef(const AttributesInfo &info, ArrayRef<void *> buffers, IndexRange range)
+      : m_info(&info), m_buffers(buffers), m_range(range)
+  {
+  }
+
+  uint size() const
+  {
+    return m_range.size();
+  }
+
+  const AttributesInfo &info()
+  {
+    return *m_info;
+  }
+
+  void *get(uint index) const
+  {
+    void *ptr = m_buffers[index];
+    uint size = m_info->type_of(index).size();
+    return POINTER_OFFSET(ptr, m_range.start() * size);
+  }
+
+  template<typename T> MutableArrayRef<T> get(uint index) const
+  {
+    BLI_assert(m_info->type_of(index) == GET_TYPE<T>());
+    return MutableArrayRef<T>((T *)m_buffers[index] + m_range.start(), m_range.size());
+  }
+
+  template<typename T> MutableArrayRef<T> get(StringRef name) const
+  {
+    return this->get<T>(m_info->index_of(name));
+  }
+
+  template<typename T> Optional<MutableArrayRef<T>> try_get(StringRef name)
+  {
+    int index = m_info->index_of_try<T>(name);
+    if (index == -1) {
+      return {};
+    }
+    else {
+      return this->get<T>((uint)index);
+    }
+  }
+
+  AttributesRef slice(IndexRange range) const
+  {
+    return this->slice(range.start(), range.size());
+  }
+
+  AttributesRef slice(uint start, uint size) const
+  {
+    return AttributesRef(*m_info, m_buffers, m_range.slice(start, size));
+  }
+
+  AttributesRef take_front(uint n) const
+  {
+    return this->slice(0, n);
+  }
+};
+
+class AttributesRefGroup {
+ private:
+  const AttributesInfo *m_info;
+  Vector<ArrayRef<void *>> m_buffers;
+  Vector<IndexRange> m_ranges;
+  uint m_total_size;
+
+ public:
+  AttributesRefGroup(const AttributesInfo &info,
+                     Vector<ArrayRef<void *>> buffers,
+                     Vector<IndexRange> ranges);
+
+  template<typename T> void set(uint index, ArrayRef<T> data)
+  {
+    BLI_assert(data.size() == m_total_size);
+    BLI_assert(m_info->type_of(index) == GET_TYPE<T>());
+
+    uint offset = 0;
+    for (AttributesRef attributes : *this) {
+      MutableArrayRef<T> array = attributes.get<T>(index);
+      array.copy_from(data.slice(offset, array.size()));
+      offset += array.size();
+    }
+  }
+
+  const AttributesInfo &info() const
+  {
+    return *m_info;
+  }
+
+  template<typename T> void set(StringRef name, ArrayRef<T> data)
+  {
+    this->set(m_info->index_of(name), data);
+  }
+
+  template<typename T> void set_repeated(uint index, ArrayRef<T> data)
+  {
+    BLI_assert(m_total_size == 0 || data.size() > 0);
+    BLI_assert(m_info->type_of(index) == GET_TYPE<T>());
+
+    uint src_index = 0;
+    for (AttributesRef attributes : *this) {
+      MutableArrayRef<T> array = attributes.get<T>(index);
+
+      for (uint i = 0; i < attributes.size(); i++) {
+        array[i] = data[src_index];
+        src_index++;
+        if (src_index == data.size()) {
+          src_index = 0;
+        }
+      }
+    }
+  }
+
+  template<typename T> void set_repeated(StringRef name, ArrayRef<T> data)
+  {
+    this->set_repeated(m_info->index_of(name), data);
+  }
+
+  template<typename T> void fill(uint index, const T &value)
+  {
+    BLI_assert(m_info->type_of(index) == GET_TYPE<T>());
+
+    for (AttributesRef attributes : *this) {
+      MutableArrayRef<T> array = attributes.get<T>(index);
+      array.fill(value);
+    }
+  }
+
+  template<typename T> void fill(StringRef name, const T &value)
+  {
+    this->fill(m_info->index_of(name), value);
+  }
+
+  class Iterator {
+   private:
+    AttributesRefGroup *m_group;
+    uint m_current;
+
+   public:
+    Iterator(AttributesRefGroup &group, uint current) : m_group(&group), m_current(current)
+    {
+    }
+
+    Iterator &operator++()
+    {
+      m_current++;
+      return *this;
+    }
+
+    AttributesRef operator*()
+    {
+      return AttributesRef(
+          *m_group->m_info, m_group->m_buffers[m_current], m_group->m_ranges[m_current]);
+    }
+
+    friend bool operator!=(const Iterator &a, const Iterator &b)
+    {
+      BLI_assert(a.m_group == b.m_group);
+      return a.m_current != b.m_current;
+    }
+  };
+
+  Iterator begin()
+  {
+    return Iterator(*this, 0);
+  }
+
+  Iterator end()
+  {
+    return Iterator(*this, m_buffers.size());
+  }
+};
+
+}  // namespace FN
+
+#endif /* __FN_ATTRIBUTES_REF_H__ */
diff --git a/source/blender/functions2/FN_cpp_type.h b/source/blender/functions2/FN_cpp_type.h
index 8ab1e9f5ce4..76bc76c307e 100644
--- a/source/blender/functions2/FN_cpp_type.h
+++ b/source/blender/functions2/FN_cpp_type.h
@@ -138,6 +138,16 @@ class CPPType {
     return m_generalization->is_same_or_generalization(other);
   }
 
+  friend bool operator==(const CPPType &a, const CPPType &b)
+  {
+    return &a == &b;
+  }
+
+  friend bool operator!=(const CPPType &a, const CPPType &b)
+  {
+    return !(&a == &b);
+  }
+
  private:
   uint m_size;
   uint m_alignment;
diff --git a/source/blender/functions2/intern/attributes_ref.cc b/source/blender/functions2/intern/attributes_ref.cc
new file mode 100644
index 00000000000..2ac2a36a90c
--- /dev/null
+++ b/source/blender/functions2/intern/attributes_ref.cc
@@ -0,0 +1,39 @@
+#include "FN_attributes_ref.h"
+
+namespace FN {
+
+void AttributesInfoBuilder::add(const AttributesInfoBuilder &other)
+{
+  for (uint i = 0; i < other.size(); i++) {
+    this->add(other.m_names[i], *other.m_types[i]);
+  }
+}
+
+void AttributesInfoBuilder::add(const AttributesInfo &other)
+{
+  for (uint i = 0; i < other.size(); i++) {
+    this->add(other.name_of(i), other.type_of(i));
+  }
+}
+
+AttributesInfo::AttributesInfo(const AttributesInfoBuilder &builder)
+{
+  for (uint i = 0; i < builder.size(); i++) {
+    m_index_by_name.add_new(builder.names()[i], i);
+    m_name_by_index.append(builder.names()[i]);
+    m_type_by_index.append(builder.types()[i]);
+  }
+}
+
+AttributesRefGroup::AttributesRefGroup(const AttributesInfo &info,
+                                       Vector<ArrayRef<void *>> b

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list