diff options
author | Jacques Lucke <jacques@blender.org> | 2020-07-08 16:04:28 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-07-08 16:10:30 +0300 |
commit | 34d175f3721521c35d333d676493848a02a96366 (patch) | |
tree | 1cf04954f4505f63bf48c0e1ff5df729bb6d43d5 /source/blender | |
parent | 840941215d42bb48fdc4724ed4d7058d275df740 (diff) |
Functions: initial hash/equals implementation for constant multi-functions
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/functions/FN_multi_function_builder.hh | 71 | ||||
-rw-r--r-- | source/blender/functions/intern/multi_function_builder.cc | 45 |
2 files changed, 94 insertions, 22 deletions
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; |