diff options
author | Jacques Lucke <jacques@blender.org> | 2021-08-19 14:28:15 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-08-19 14:28:15 +0300 |
commit | fd7edc9b05bb47b74e890ec4beafa626d4ccbc54 (patch) | |
tree | 2c9a792f537f8b81845a5a157878942f902110f2 /source/blender | |
parent | ecf7c90840881f564a5da15f0f59fe65a8699763 (diff) |
cleanup
Diffstat (limited to 'source/blender')
3 files changed, 266 insertions, 186 deletions
diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt index f25a089ae50..c783127e8d8 100644 --- a/source/blender/functions/CMakeLists.txt +++ b/source/blender/functions/CMakeLists.txt @@ -38,6 +38,7 @@ set(SRC intern/multi_function_network_optimization.cc intern/multi_function_network_to_procedure.cc intern/multi_function_procedure.cc + intern/multi_function_procedure_builder.cc intern/multi_function_procedure_executor.cc FN_cpp_type.hh diff --git a/source/blender/functions/FN_multi_function_procedure_builder.hh b/source/blender/functions/FN_multi_function_procedure_builder.hh index 0bd4841c6c6..347ad52397b 100644 --- a/source/blender/functions/FN_multi_function_procedure_builder.hh +++ b/source/blender/functions/FN_multi_function_procedure_builder.hh @@ -35,60 +35,13 @@ class MFInstructionCursor { public: MFInstructionCursor() = default; - MFInstructionCursor(MFCallInstruction &instruction) : instruction_(&instruction) - { - } - - MFInstructionCursor(MFDestructInstruction &instruction) : instruction_(&instruction) - { - } + MFInstructionCursor(MFCallInstruction &instruction); + MFInstructionCursor(MFDestructInstruction &instruction); + MFInstructionCursor(MFBranchInstruction &instruction, bool branch_output); - MFInstructionCursor(MFBranchInstruction &instruction, bool branch_output) - : instruction_(&instruction), branch_output_(branch_output) - { - } - - static MFInstructionCursor Entry() - { - MFInstructionCursor cursor; - cursor.is_entry_ = true; - return cursor; - } + static MFInstructionCursor Entry(); - void insert(MFProcedure &procedure, MFInstruction *new_instruction) - { - if (instruction_ == nullptr) { - if (is_entry_) { - procedure.set_entry(*new_instruction); - } - else { - /* The cursors points at nothing, nothing to do. */ - } - } - else { - switch (instruction_->type()) { - case MFInstructionType::Call: { - static_cast<MFCallInstruction *>(instruction_)->set_next(new_instruction); - break; - } - case MFInstructionType::Branch: { - MFBranchInstruction &branch_instruction = *static_cast<MFBranchInstruction *>( - instruction_); - if (branch_output_) { - branch_instruction.set_branch_true(new_instruction); - } - else { - branch_instruction.set_branch_false(new_instruction); - } - break; - } - case MFInstructionType::Destruct: { - static_cast<MFDestructInstruction *>(instruction_)->set_next(new_instruction); - break; - } - } - } - } + void insert(MFProcedure &procedure, MFInstruction *new_instruction); }; struct MFProcedureBuilderBranch; @@ -100,151 +53,46 @@ class MFProcedureBuilder { public: MFProcedureBuilder(MFProcedure &procedure, - MFInstructionCursor initial_cursor = MFInstructionCursor::Entry()) - : procedure_(&procedure), cursors_({initial_cursor}) - { - } + MFInstructionCursor initial_cursor = MFInstructionCursor::Entry()); - MFProcedureBuilder(Span<MFProcedureBuilder *> builders) - : MFProcedureBuilder(*builders[0]->procedure_) - { - this->set_cursor(builders); - } + MFProcedureBuilder(Span<MFProcedureBuilder *> builders); MFProcedureBuilder(MFProcedureBuilderBranch &branch); - void set_cursor(const MFInstructionCursor &cursor) - { - cursors_ = {cursor}; - } - - void set_cursor(Span<MFInstructionCursor> cursors) - { - cursors_ = cursors; - } - + void set_cursor(const MFInstructionCursor &cursor); + void set_cursor(Span<MFInstructionCursor> cursors); + void set_cursor(Span<MFProcedureBuilder *> builders); void set_cursor_after_branch(MFProcedureBuilderBranch &branch); - void set_cursor(Span<MFProcedureBuilder *> builders) - { - cursors_.clear(); - for (MFProcedureBuilder *builder : builders) { - cursors_.extend(builder->cursors_); - } - } - - void insert_destruct(MFVariable &variable) - { - MFDestructInstruction &instruction = procedure_->new_destruct_instruction(); - instruction.set_variable(&variable); - this->insert_at_cursors(&instruction); - cursors_ = {MFInstructionCursor{instruction}}; - } - - void insert_destruct(Span<MFVariable *> variables) - { - for (MFVariable *variable : variables) { - this->insert_destruct(*variable); - } - } + void insert_destruct(MFVariable &variable); + void insert_destruct(Span<MFVariable *> variables); MFProcedureBuilderBranch insert_branch(MFVariable &condition); - MFCallInstruction &insert_call(const MultiFunction &fn) - { - MFCallInstruction &instruction = procedure_->new_call_instruction(fn); - this->insert_at_cursors(&instruction); - cursors_ = {MFInstructionCursor{instruction}}; - return instruction; - } - - MFCallInstruction &insert_call(const MultiFunction &fn, Span<MFVariable *> variables) - { - MFCallInstruction &instruction = this->insert_call(fn); - instruction.set_params(variables); - return instruction; - } + MFCallInstruction &insert_call(const MultiFunction &fn); + MFCallInstruction &insert_call(const MultiFunction &fn, Span<MFVariable *> variables); Vector<MFVariable *> insert_call_with_new_variables( - const MultiFunction &fn, Span<MFVariable *> input_and_mutable_variables = {}) - { - Vector<MFVariable *> output_variables; - MFCallInstruction &instruction = this->insert_call(fn); - for (const int param_index : fn.param_indices()) { - const MFParamType param_type = fn.param_type(param_index); - switch (param_type.interface_type()) { - case MFParamType::Input: - case MFParamType::Mutable: { - MFVariable *variable = input_and_mutable_variables.first(); - instruction.set_param_variable(param_index, variable); - input_and_mutable_variables = input_and_mutable_variables.drop_front(1); - break; - } - case MFParamType::Output: { - MFVariable &variable = procedure_->new_variable(param_type.data_type()); - instruction.set_param_variable(param_index, &variable); - output_variables.append(&variable); - break; - } - } - } - /* All passed in variables should have been dropped in the loop above. */ - BLI_assert(input_and_mutable_variables.is_empty()); - return output_variables; - } + const MultiFunction &fn, Span<MFVariable *> input_and_mutable_variables = {}); template<int OutputN> std::array<MFVariable *, OutputN> insert_call_with_new_variables( - const MultiFunction &fn, Span<MFVariable *> input_and_mutable_variables = {}) - { - Vector<MFVariable *> output_variables = this->insert_call_with_new_variables( - fn, input_and_mutable_variables); - BLI_assert(output_variables.size() == OutputN); - - std::array<MFVariable *, OutputN> output_array; - initialized_copy_n(output_variables.data(), OutputN, output_array.data()); - return output_array; - } + const MultiFunction &fn, Span<MFVariable *> input_and_mutable_variables = {}); - void add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable) - { - procedure_->add_parameter(interface_type, variable); - } + void add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable); - MFVariable &add_parameter(MFParamType param_type, std::string name = "") - { - MFVariable &variable = procedure_->new_variable(param_type.data_type(), std::move(name)); - this->add_parameter(param_type.interface_type(), variable); - return variable; - } + MFVariable &add_parameter(MFParamType param_type, std::string name = ""); - MFVariable &add_input_parameter(MFDataType data_type, std::string name = "") - { - return this->add_parameter(MFParamType(MFParamType::Input, data_type), std::move(name)); - } + MFVariable &add_input_parameter(MFDataType data_type, std::string name = ""); - template<typename T> MFVariable &add_single_input_parameter(std::string name = "") - { - return this->add_parameter(MFParamType::ForSingleInput(CPPType::get<T>()), std::move(name)); - } + template<typename T> MFVariable &add_single_input_parameter(std::string name = ""); - template<typename T> MFVariable &add_single_mutable_parameter(std::string name = "") - { - return this->add_parameter(MFParamType::ForMutableSingle(CPPType::get<T>()), std::move(name)); - } + template<typename T> MFVariable &add_single_mutable_parameter(std::string name = ""); - void add_output_parameter(MFVariable &variable) - { - this->add_parameter(MFParamType::Output, variable); - } + void add_output_parameter(MFVariable &variable); private: - void insert_at_cursors(MFInstruction *instruction) - { - for (MFInstructionCursor &cursor : cursors_) { - cursor.insert(*procedure_, instruction); - } - } + void insert_at_cursors(MFInstruction *instruction); }; struct MFProcedureBuilderBranch { @@ -252,27 +100,131 @@ struct MFProcedureBuilderBranch { MFProcedureBuilder branch_false; }; -MFProcedureBuilder::MFProcedureBuilder(MFProcedureBuilderBranch &branch) +/* -------------------------------------------------------------------- + * MFInstructionCursor inline methods. + */ + +inline MFInstructionCursor::MFInstructionCursor(MFCallInstruction &instruction) + : instruction_(&instruction) +{ +} + +inline MFInstructionCursor::MFInstructionCursor(MFDestructInstruction &instruction) + : instruction_(&instruction) +{ +} + +inline MFInstructionCursor::MFInstructionCursor(MFBranchInstruction &instruction, + bool branch_output) + : instruction_(&instruction), branch_output_(branch_output) +{ +} + +inline MFInstructionCursor MFInstructionCursor::Entry() +{ + MFInstructionCursor cursor; + cursor.is_entry_ = true; + return cursor; +} + +/* -------------------------------------------------------------------- + * MFProcedureBuilder inline methods. + */ + +inline MFProcedureBuilder::MFProcedureBuilder(MFProcedureBuilderBranch &branch) : MFProcedureBuilder(*branch.branch_true.procedure_) { this->set_cursor_after_branch(branch); } -void MFProcedureBuilder::set_cursor_after_branch(MFProcedureBuilderBranch &branch) +inline MFProcedureBuilder::MFProcedureBuilder(MFProcedure &procedure, + MFInstructionCursor initial_cursor) + : procedure_(&procedure), cursors_({initial_cursor}) +{ +} + +inline MFProcedureBuilder::MFProcedureBuilder(Span<MFProcedureBuilder *> builders) + : MFProcedureBuilder(*builders[0]->procedure_) +{ + this->set_cursor(builders); +} + +inline void MFProcedureBuilder::set_cursor(const MFInstructionCursor &cursor) +{ + cursors_ = {cursor}; +} + +inline void MFProcedureBuilder::set_cursor(Span<MFInstructionCursor> cursors) +{ + cursors_ = cursors; +} + +inline void MFProcedureBuilder::set_cursor_after_branch(MFProcedureBuilderBranch &branch) { this->set_cursor({&branch.branch_false, &branch.branch_true}); } -MFProcedureBuilderBranch MFProcedureBuilder::insert_branch(MFVariable &condition) +inline void MFProcedureBuilder::set_cursor(Span<MFProcedureBuilder *> builders) +{ + cursors_.clear(); + for (MFProcedureBuilder *builder : builders) { + cursors_.extend(builder->cursors_); + } +} + +template<int OutputN> +inline std::array<MFVariable *, OutputN> MFProcedureBuilder::insert_call_with_new_variables( + const MultiFunction &fn, Span<MFVariable *> input_and_mutable_variables) +{ + Vector<MFVariable *> output_variables = this->insert_call_with_new_variables( + fn, input_and_mutable_variables); + BLI_assert(output_variables.size() == OutputN); + + std::array<MFVariable *, OutputN> output_array; + initialized_copy_n(output_variables.data(), OutputN, output_array.data()); + return output_array; +} + +inline void MFProcedureBuilder::add_parameter(MFParamType::InterfaceType interface_type, + MFVariable &variable) +{ + procedure_->add_parameter(interface_type, variable); +} + +inline MFVariable &MFProcedureBuilder::add_parameter(MFParamType param_type, std::string name) +{ + MFVariable &variable = procedure_->new_variable(param_type.data_type(), std::move(name)); + this->add_parameter(param_type.interface_type(), variable); + return variable; +} + +inline MFVariable &MFProcedureBuilder::add_input_parameter(MFDataType data_type, std::string name) +{ + return this->add_parameter(MFParamType(MFParamType::Input, data_type), std::move(name)); +} + +template<typename T> +inline MFVariable &MFProcedureBuilder::add_single_input_parameter(std::string name) { - MFBranchInstruction &instruction = procedure_->new_branch_instruction(); - instruction.set_condition(&condition); - this->insert_at_cursors(&instruction); - - MFProcedureBuilderBranch branch{*procedure_, *procedure_}; - branch.branch_true.set_cursor(MFInstructionCursor{instruction, true}); - branch.branch_false.set_cursor(MFInstructionCursor{instruction, false}); - return branch; + return this->add_parameter(MFParamType::ForSingleInput(CPPType::get<T>()), std::move(name)); +} + +template<typename T> +inline MFVariable &MFProcedureBuilder::add_single_mutable_parameter(std::string name) +{ + return this->add_parameter(MFParamType::ForMutableSingle(CPPType::get<T>()), std::move(name)); +} + +inline void MFProcedureBuilder::add_output_parameter(MFVariable &variable) +{ + this->add_parameter(MFParamType::Output, variable); +} + +inline void MFProcedureBuilder::insert_at_cursors(MFInstruction *instruction) +{ + for (MFInstructionCursor &cursor : cursors_) { + cursor.insert(*procedure_, instruction); + } } } // namespace blender::fn diff --git a/source/blender/functions/intern/multi_function_procedure_builder.cc b/source/blender/functions/intern/multi_function_procedure_builder.cc new file mode 100644 index 00000000000..9b920cf4192 --- /dev/null +++ b/source/blender/functions/intern/multi_function_procedure_builder.cc @@ -0,0 +1,127 @@ +/* + * 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. + */ + +#include "FN_multi_function_procedure_builder.hh" + +namespace blender::fn { + +void MFInstructionCursor::insert(MFProcedure &procedure, MFInstruction *new_instruction) +{ + if (instruction_ == nullptr) { + if (is_entry_) { + procedure.set_entry(*new_instruction); + } + else { + /* The cursors points at nothing, nothing to do. */ + } + } + else { + switch (instruction_->type()) { + case MFInstructionType::Call: { + static_cast<MFCallInstruction *>(instruction_)->set_next(new_instruction); + break; + } + case MFInstructionType::Branch: { + MFBranchInstruction &branch_instruction = *static_cast<MFBranchInstruction *>( + instruction_); + if (branch_output_) { + branch_instruction.set_branch_true(new_instruction); + } + else { + branch_instruction.set_branch_false(new_instruction); + } + break; + } + case MFInstructionType::Destruct: { + static_cast<MFDestructInstruction *>(instruction_)->set_next(new_instruction); + break; + } + } + } +} + +void MFProcedureBuilder::insert_destruct(MFVariable &variable) +{ + MFDestructInstruction &instruction = procedure_->new_destruct_instruction(); + instruction.set_variable(&variable); + this->insert_at_cursors(&instruction); + cursors_ = {MFInstructionCursor{instruction}}; +} + +void MFProcedureBuilder::insert_destruct(Span<MFVariable *> variables) +{ + for (MFVariable *variable : variables) { + this->insert_destruct(*variable); + } +} + +MFCallInstruction &MFProcedureBuilder::insert_call(const MultiFunction &fn) +{ + MFCallInstruction &instruction = procedure_->new_call_instruction(fn); + this->insert_at_cursors(&instruction); + cursors_ = {MFInstructionCursor{instruction}}; + return instruction; +} + +MFCallInstruction &MFProcedureBuilder::insert_call(const MultiFunction &fn, + Span<MFVariable *> variables) +{ + MFCallInstruction &instruction = this->insert_call(fn); + instruction.set_params(variables); + return instruction; +} + +Vector<MFVariable *> MFProcedureBuilder::insert_call_with_new_variables( + const MultiFunction &fn, Span<MFVariable *> input_and_mutable_variables) +{ + Vector<MFVariable *> output_variables; + MFCallInstruction &instruction = this->insert_call(fn); + for (const int param_index : fn.param_indices()) { + const MFParamType param_type = fn.param_type(param_index); + switch (param_type.interface_type()) { + case MFParamType::Input: + case MFParamType::Mutable: { + MFVariable *variable = input_and_mutable_variables.first(); + instruction.set_param_variable(param_index, variable); + input_and_mutable_variables = input_and_mutable_variables.drop_front(1); + break; + } + case MFParamType::Output: { + MFVariable &variable = procedure_->new_variable(param_type.data_type()); + instruction.set_param_variable(param_index, &variable); + output_variables.append(&variable); + break; + } + } + } + /* All passed in variables should have been dropped in the loop above. */ + BLI_assert(input_and_mutable_variables.is_empty()); + return output_variables; +} + +MFProcedureBuilderBranch MFProcedureBuilder::insert_branch(MFVariable &condition) +{ + MFBranchInstruction &instruction = procedure_->new_branch_instruction(); + instruction.set_condition(&condition); + this->insert_at_cursors(&instruction); + + MFProcedureBuilderBranch branch{*procedure_, *procedure_}; + branch.branch_true.set_cursor(MFInstructionCursor{instruction, true}); + branch.branch_false.set_cursor(MFInstructionCursor{instruction, false}); + return branch; +} + +} // namespace blender::fn |