Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/functions/FN_multi_function_params.hh')
-rw-r--r--source/blender/functions/FN_multi_function_params.hh251
1 files changed, 251 insertions, 0 deletions
diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh
new file mode 100644
index 00000000000..ac4dca33cf0
--- /dev/null
+++ b/source/blender/functions/FN_multi_function_params.hh
@@ -0,0 +1,251 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __FN_MULTI_FUNCTION_PARAMS_HH__
+#define __FN_MULTI_FUNCTION_PARAMS_HH__
+
+/** \file
+ * \ingroup fn
+ *
+ * This file provides an MFParams and MFParamsBuilder structure.
+ *
+ * `MFParamsBuilder` is used by a function caller to be prepare all parameters that are passed into
+ * the function. `MFParams` is then used inside the called function to access the parameters.
+ */
+
+#include "FN_generic_vector_array.hh"
+#include "FN_multi_function_signature.hh"
+
+namespace blender::fn {
+
+class MFParamsBuilder {
+ private:
+ const MFSignature *signature_;
+ int64_t min_array_size_;
+ Vector<GVSpan> virtual_spans_;
+ Vector<GMutableSpan> mutable_spans_;
+ Vector<GVArraySpan> virtual_array_spans_;
+ Vector<GVectorArray *> vector_arrays_;
+
+ friend class MFParams;
+
+ public:
+ MFParamsBuilder(const MFSignature &signature, int64_t min_array_size)
+ : signature_(&signature), min_array_size_(min_array_size)
+ {
+ }
+
+ MFParamsBuilder(const class MultiFunction &fn, int64_t min_array_size);
+
+ template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "")
+ {
+ this->add_readonly_single_input(GVSpan::FromSingle(CPPType::get<T>(), value, min_array_size_),
+ expected_name);
+ }
+ void add_readonly_single_input(GVSpan ref, StringRef expected_name = "")
+ {
+ this->assert_current_param_type(MFParamType::ForSingleInput(ref.type()), expected_name);
+ BLI_assert(ref.size() >= min_array_size_);
+ virtual_spans_.append(ref);
+ }
+
+ void add_readonly_vector_input(GVArraySpan ref, StringRef expected_name = "")
+ {
+ this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name);
+ BLI_assert(ref.size() >= min_array_size_);
+ virtual_array_spans_.append(ref);
+ }
+
+ template<typename T> void add_uninitialized_single_output(T *value, StringRef expected_name = "")
+ {
+ this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1),
+ expected_name);
+ }
+ void add_uninitialized_single_output(GMutableSpan ref, StringRef expected_name = "")
+ {
+ this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name);
+ BLI_assert(ref.size() >= min_array_size_);
+ mutable_spans_.append(ref);
+ }
+
+ void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "")
+ {
+ this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()),
+ expected_name);
+ BLI_assert(vector_array.size() >= min_array_size_);
+ vector_arrays_.append(&vector_array);
+ }
+
+ void add_single_mutable(GMutableSpan ref, StringRef expected_name = "")
+ {
+ this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name);
+ BLI_assert(ref.size() >= min_array_size_);
+ mutable_spans_.append(ref);
+ }
+
+ void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "")
+ {
+ this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()),
+ expected_name);
+ BLI_assert(vector_array.size() >= min_array_size_);
+ vector_arrays_.append(&vector_array);
+ }
+
+ GMutableSpan computed_array(int param_index)
+ {
+ BLI_assert(ELEM(signature_->param_types[param_index].category(),
+ MFParamType::SingleOutput,
+ MFParamType::SingleMutable));
+ int data_index = signature_->data_index(param_index);
+ return mutable_spans_[data_index];
+ }
+
+ GVectorArray &computed_vector_array(int param_index)
+ {
+ BLI_assert(ELEM(signature_->param_types[param_index].category(),
+ MFParamType::VectorOutput,
+ MFParamType::VectorMutable));
+ int data_index = signature_->data_index(param_index);
+ return *vector_arrays_[data_index];
+ }
+
+ private:
+ void assert_current_param_type(MFParamType param_type, StringRef expected_name = "")
+ {
+ UNUSED_VARS_NDEBUG(param_type, expected_name);
+#ifdef DEBUG
+ int param_index = this->current_param_index();
+
+ if (expected_name != "") {
+ StringRef actual_name = signature_->param_names[param_index];
+ BLI_assert(actual_name == expected_name);
+ }
+
+ MFParamType expected_type = signature_->param_types[param_index];
+ BLI_assert(expected_type == param_type);
+#endif
+ }
+
+ int current_param_index() const
+ {
+ return virtual_spans_.size() + mutable_spans_.size() + virtual_array_spans_.size() +
+ vector_arrays_.size();
+ }
+};
+
+class MFParams {
+ private:
+ MFParamsBuilder *builder_;
+
+ public:
+ MFParams(MFParamsBuilder &builder) : builder_(&builder)
+ {
+ }
+
+ template<typename T> VSpan<T> readonly_single_input(int param_index, StringRef name = "")
+ {
+ return this->readonly_single_input(param_index, name).typed<T>();
+ }
+ GVSpan readonly_single_input(int param_index, StringRef name = "")
+ {
+ this->assert_correct_param(param_index, name, MFParamType::SingleInput);
+ int data_index = builder_->signature_->data_index(param_index);
+ return builder_->virtual_spans_[data_index];
+ }
+
+ template<typename T>
+ MutableSpan<T> uninitialized_single_output(int param_index, StringRef name = "")
+ {
+ return this->uninitialized_single_output(param_index, name).typed<T>();
+ }
+ GMutableSpan uninitialized_single_output(int param_index, StringRef name = "")
+ {
+ this->assert_correct_param(param_index, name, MFParamType::SingleOutput);
+ int data_index = builder_->signature_->data_index(param_index);
+ return builder_->mutable_spans_[data_index];
+ }
+
+ template<typename T> VArraySpan<T> readonly_vector_input(int param_index, StringRef name = "")
+ {
+ return this->readonly_vector_input(param_index, name).typed<T>();
+ }
+ GVArraySpan readonly_vector_input(int param_index, StringRef name = "")
+ {
+ this->assert_correct_param(param_index, name, MFParamType::VectorInput);
+ int data_index = builder_->signature_->data_index(param_index);
+ return builder_->virtual_array_spans_[data_index];
+ }
+
+ template<typename T> GVectorArrayRef<T> vector_output(int param_index, StringRef name = "")
+ {
+ return this->vector_output(param_index, name).typed<T>();
+ }
+ GVectorArray &vector_output(int param_index, StringRef name = "")
+ {
+ this->assert_correct_param(param_index, name, MFParamType::VectorOutput);
+ int data_index = builder_->signature_->data_index(param_index);
+ return *builder_->vector_arrays_[data_index];
+ }
+
+ template<typename T> MutableSpan<T> single_mutable(int param_index, StringRef name = "")
+ {
+ return this->single_mutable(param_index, name).typed<T>();
+ }
+ GMutableSpan single_mutable(int param_index, StringRef name = "")
+ {
+ this->assert_correct_param(param_index, name, MFParamType::SingleMutable);
+ int data_index = builder_->signature_->data_index(param_index);
+ return builder_->mutable_spans_[data_index];
+ }
+
+ template<typename T> GVectorArrayRef<T> vector_mutable(int param_index, StringRef name = "")
+ {
+ return this->vector_mutable(param_index, name).typed<T>();
+ }
+ GVectorArray &vector_mutable(int param_index, StringRef name = "")
+ {
+ this->assert_correct_param(param_index, name, MFParamType::VectorMutable);
+ int data_index = builder_->signature_->data_index(param_index);
+ return *builder_->vector_arrays_[data_index];
+ }
+
+ private:
+ void assert_correct_param(int param_index, StringRef name, MFParamType param_type)
+ {
+ UNUSED_VARS_NDEBUG(param_index, name, param_type);
+#ifdef DEBUG
+ BLI_assert(builder_->signature_->param_types[param_index] == param_type);
+ if (name.size() > 0) {
+ BLI_assert(builder_->signature_->param_names[param_index] == name);
+ }
+#endif
+ }
+
+ void assert_correct_param(int param_index, StringRef name, MFParamType::Category category)
+ {
+ UNUSED_VARS_NDEBUG(param_index, name, category);
+#ifdef DEBUG
+ BLI_assert(builder_->signature_->param_types[param_index].category() == category);
+ if (name.size() > 0) {
+ BLI_assert(builder_->signature_->param_names[param_index] == name);
+ }
+#endif
+ }
+};
+
+} // namespace blender::fn
+
+#endif /* __FN_MULTI_FUNCTION_PARAMS_HH__ */