From 613f62d15ce1851a8b7017013e9cced1009ad431 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 30 Jun 2020 17:59:33 +0200 Subject: Functions: add two more customizable multi-functions --- .../blender/functions/FN_multi_function_builder.hh | 103 ++++++++++++++++++--- 1 file changed, 89 insertions(+), 14 deletions(-) (limited to 'source') diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 08d4ec672cd..9fcf31443b2 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -36,15 +36,15 @@ namespace fn { * 2. single output (SO) of type Out1 * * This example creates a function that adds 10 to the incoming values: - * CustomFunction_SI_SO fn("add 10", [](int value) { return value + 10; }); + * CustomMF_SI_SO fn("add 10", [](int value) { return value + 10; }); */ -template class CustomFunction_SI_SO : public MultiFunction { +template class CustomMF_SI_SO : public MultiFunction { private: using FunctionT = std::function, MutableSpan)>; FunctionT m_function; public: - CustomFunction_SI_SO(StringRef name, FunctionT function) : m_function(std::move(function)) + CustomMF_SI_SO(StringRef name, FunctionT function) : m_function(std::move(function)) { MFSignatureBuilder signature = this->get_builder(name); signature.single_input("In1"); @@ -52,8 +52,8 @@ template class CustomFunction_SI_SO : public MultiF } template - CustomFunction_SI_SO(StringRef name, ElementFuncT element_fn) - : CustomFunction_SI_SO(name, CustomFunction_SI_SO::create_function(element_fn)) + CustomMF_SI_SO(StringRef name, ElementFuncT element_fn) + : CustomMF_SI_SO(name, CustomMF_SI_SO::create_function(element_fn)) { } @@ -79,13 +79,13 @@ template class CustomFunction_SI_SO : public MultiF * 3. single output (SO) of type Out1 */ template -class CustomFunction_SI_SI_SO : public MultiFunction { +class CustomMF_SI_SI_SO : public MultiFunction { private: using FunctionT = std::function, VSpan, MutableSpan)>; FunctionT m_function; public: - CustomFunction_SI_SI_SO(StringRef name, FunctionT function) : m_function(std::move(function)) + CustomMF_SI_SI_SO(StringRef name, FunctionT function) : m_function(std::move(function)) { MFSignatureBuilder signature = this->get_builder(name); signature.single_input("In1"); @@ -94,8 +94,8 @@ class CustomFunction_SI_SI_SO : public MultiFunction { } template - CustomFunction_SI_SI_SO(StringRef name, ElementFuncT element_fn) - : CustomFunction_SI_SI_SO(name, CustomFunction_SI_SI_SO::create_function(element_fn)) + CustomMF_SI_SI_SO(StringRef name, ElementFuncT element_fn) + : CustomMF_SI_SI_SO(name, CustomMF_SI_SI_SO::create_function(element_fn)) { } @@ -109,31 +109,83 @@ class CustomFunction_SI_SI_SO : public MultiFunction { void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override { VSpan in1 = params.readonly_single_input(0); - VSpan in2 = params.readonly_single_input(1); + VSpan in2 = params.readonly_single_input(1); MutableSpan out1 = params.uninitialized_single_output(2); m_function(mask, in1, in2, out1); } }; +/** + * Generates a multi-function with the following parameters: + * 1. single input (SI) of type In1 + * 2. single input (SI) of type In2 + * 3. single input (SI) of type In3 + * 4. single output (SO) of type Out1 + */ +template +class CustomMF_SI_SI_SI_SO : public MultiFunction { + private: + using FunctionT = + std::function, VSpan, VSpan, MutableSpan)>; + FunctionT m_function; + + public: + CustomMF_SI_SI_SI_SO(StringRef name, FunctionT function) : m_function(std::move(function)) + { + MFSignatureBuilder signature = this->get_builder(name); + signature.single_input("In1"); + signature.single_input("In2"); + signature.single_input("In3"); + signature.single_output("Out1"); + } + + template + CustomMF_SI_SI_SI_SO(StringRef name, ElementFuncT element_fn) + : CustomMF_SI_SI_SI_SO(name, CustomMF_SI_SI_SI_SO::create_function(element_fn)) + { + } + + template static FunctionT create_function(ElementFuncT element_fn) + { + return [=](IndexMask mask, + VSpan in1, + VSpan in2, + VSpan in3, + MutableSpan out1) { + mask.foreach_index( + [&](uint i) { new ((void *)&out1[i]) Out1(element_fn(in1[i], in2[i], in3[i])); }); + }; + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + VSpan in1 = params.readonly_single_input(0); + VSpan in2 = params.readonly_single_input(1); + VSpan in3 = params.readonly_single_input(2); + MutableSpan out1 = params.uninitialized_single_output(3); + m_function(mask, in1, in2, in3, out1); + } +}; + /** * Generates a multi-function with the following parameters: * 1. single mutable (SM) of type Mut1 */ -template class CustomFunction_SM : public MultiFunction { +template class CustomMF_SM : public MultiFunction { private: using FunctionT = std::function)>; FunctionT m_function; public: - CustomFunction_SM(StringRef name, FunctionT function) : m_function(std::move(function)) + CustomMF_SM(StringRef name, FunctionT function) : m_function(std::move(function)) { MFSignatureBuilder signature = this->get_builder(name); signature.single_mutable("Mut1"); } template - CustomFunction_SM(StringRef name, ElementFuncT element_fn) - : CustomFunction_SM(name, CustomFunction_SM::create_function(element_fn)) + CustomMF_SM(StringRef name, ElementFuncT element_fn) + : CustomMF_SM(name, CustomMF_SM::create_function(element_fn)) { } @@ -151,6 +203,29 @@ template class CustomFunction_SM : public MultiFunction { } }; +/** + * Generates a multi-function that outputs a constant value. + */ +template class CustomMF_Constant : public MultiFunction { + private: + T m_value; + + public: + template CustomMF_Constant(U &&value) : m_value(std::forward(value)) + { + MFSignatureBuilder signature = this->get_builder("Constant"); + std::stringstream ss; + ss << m_value; + signature.single_output(ss.str()); + } + + void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override + { + MutableSpan output = params.uninitialized_single_output(0); + mask.foreach_index([&](uint i) { new (&output[i]) T(m_value); }); + } +}; + } // namespace fn } // namespace blender -- cgit v1.2.3