[Bf-blender-cvs] [34d175f3721] master: Functions: initial hash/equals implementation for constant multi-functions

Jacques Lucke noreply at git.blender.org
Wed Jul 8 15:11:23 CEST 2020


Commit: 34d175f3721521c35d333d676493848a02a96366
Author: Jacques Lucke
Date:   Wed Jul 8 15:04:28 2020 +0200
Branches: master
https://developer.blender.org/rB34d175f3721521c35d333d676493848a02a96366

Functions: initial hash/equals implementation for constant multi-functions

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

M	source/blender/functions/FN_multi_function_builder.hh
M	source/blender/functions/intern/multi_function_builder.cc

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

diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh
index 98f263a75fa..9be785f5a70 100644
--- a/source/blender/functions/FN_multi_function_builder.hh
+++ b/source/blender/functions/FN_multi_function_builder.hh
@@ -202,28 +202,7 @@ template<typename Mut1> class CustomMF_SM : public MultiFunction {
   }
 };
 
-/**
- * Generates a multi-function that outputs a constant value.
- */
-template<typename T> class CustomMF_Constant : public MultiFunction {
- private:
-  T value_;
-
- public:
-  template<typename U> CustomMF_Constant(U &&value) : value_(std::forward<U>(value))
-  {
-    MFSignatureBuilder signature = this->get_builder("Constant");
-    std::stringstream ss;
-    ss << value_;
-    signature.single_output<T>(ss.str());
-  }
-
-  void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
-  {
-    MutableSpan<T> output = params.uninitialized_single_output<T>(0);
-    mask.foreach_index([&](uint i) { new (&output[i]) T(value_); });
-  }
-};
+bool generic_values_are_equal(const CPPType &type, const void *a, const void *b);
 
 /**
  * A multi-function that outputs the same value every time. The value is not owned by an instance
@@ -234,9 +213,13 @@ class CustomMF_GenericConstant : public MultiFunction {
   const CPPType &type_;
   const void *value_;
 
+  template<typename T> friend class CustomMF_Constant;
+
  public:
   CustomMF_GenericConstant(const CPPType &type, const void *value);
   void call(IndexMask mask, MFParams params, MFContext context) const override;
+  uint32_t hash() const override;
+  bool equals(const MultiFunction &other) const override;
 };
 
 /**
@@ -252,6 +235,50 @@ class CustomMF_GenericConstantArray : public MultiFunction {
   void call(IndexMask mask, MFParams params, MFContext context) const override;
 };
 
+/**
+ * Generates a multi-function that outputs a constant value.
+ */
+template<typename T> class CustomMF_Constant : public MultiFunction {
+ private:
+  T value_;
+
+ public:
+  template<typename U> CustomMF_Constant(U &&value) : value_(std::forward<U>(value))
+  {
+    MFSignatureBuilder signature = this->get_builder("Constant");
+    std::stringstream ss;
+    ss << value_;
+    signature.single_output<T>(ss.str());
+  }
+
+  void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+  {
+    MutableSpan<T> output = params.uninitialized_single_output<T>(0);
+    mask.foreach_index([&](uint i) { new (&output[i]) T(value_); });
+  }
+
+  uint32_t hash() const override
+  {
+    return DefaultHash<T>{}(value_);
+  }
+
+  bool equals(const MultiFunction &other) const override
+  {
+    const CustomMF_Constant *other1 = dynamic_cast<const CustomMF_Constant *>(&other);
+    if (other1 != nullptr) {
+      return value_ == other1->value_;
+    }
+    const CustomMF_GenericConstant *other2 = dynamic_cast<const CustomMF_GenericConstant *>(
+        &other);
+    if (other2 != nullptr) {
+      if (CPPType::get<T>() == other2->type_) {
+        return generic_values_are_equal(other2->type_, (const void *)&value_, other2->value_);
+      }
+    }
+    return false;
+  }
+};
+
 }  // namespace blender::fn
 
 #endif /* __FN_MULTI_FUNCTION_BUILDER_HH__ */
diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc
index 1ada810a301..0a640b009cd 100644
--- a/source/blender/functions/intern/multi_function_builder.cc
+++ b/source/blender/functions/intern/multi_function_builder.cc
@@ -14,8 +14,12 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
+#include "FN_cpp_types.hh"
 #include "FN_multi_function_builder.hh"
 
+#include "BLI_float3.hh"
+#include "BLI_hash.hh"
+
 namespace blender::fn {
 
 CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, const void *value)
@@ -35,6 +39,47 @@ void CustomMF_GenericConstant::call(IndexMask mask,
   type_.fill_uninitialized_indices(value_, output.buffer(), mask);
 }
 
+uint CustomMF_GenericConstant::hash() const
+{
+  if (type_ == CPPType_float3) {
+    return DefaultHash<float3>{}(*(float3 *)value_);
+  }
+  if (type_ == CPPType_int32) {
+    return DefaultHash<int32_t>{}(*(int32_t *)value_);
+  }
+  if (type_ == CPPType_float) {
+    return DefaultHash<float>{}(*(float *)value_);
+  }
+  return MultiFunction::hash();
+}
+
+/* This should be moved into CPPType. */
+bool generic_values_are_equal(const CPPType &type, const void *a, const void *b)
+{
+  if (type == CPPType_float3) {
+    return *(float3 *)a == *(float3 *)b;
+  }
+  if (type == CPPType_int32) {
+    return *(int *)a == *(int *)b;
+  }
+  if (type == CPPType_float) {
+    return *(float *)a == *(float *)b;
+  }
+  return false;
+}
+
+bool CustomMF_GenericConstant::equals(const MultiFunction &other) const
+{
+  const CustomMF_GenericConstant *_other = dynamic_cast<const CustomMF_GenericConstant *>(&other);
+  if (_other == nullptr) {
+    return false;
+  }
+  if (type_ != _other->type_) {
+    return false;
+  }
+  return generic_values_are_equal(type_, value_, _other->value_);
+}
+
 static std::string gspan_to_string(GSpan array)
 {
   std::stringstream ss;



More information about the Bf-blender-cvs mailing list