Functions: introduce multi-function namespace
This moves all multi-function related code in the `functions` module into a new `multi_function` namespace. This is similar to how there is a `lazy_function` namespace. The main benefit of this is that many types names that were prefixed with `MF` (for "multi function") can be simplified. There is also a common shorthand for the `multi_function` namespace: `mf`. This is also similar to lazy-functions where the shortened namespace is called `lf`.
This commit is contained in:
		| @@ -8,182 +8,181 @@ | ||||
|  | ||||
| #include "FN_multi_function_procedure.hh" | ||||
|  | ||||
| namespace blender::fn { | ||||
| namespace blender::fn::multi_function { | ||||
|  | ||||
| /** | ||||
|  * Utility class to build a #MFProcedure. | ||||
|  * Utility class to build a #Procedure. | ||||
|  */ | ||||
| class MFProcedureBuilder { | ||||
| class ProcedureBuilder { | ||||
|  private: | ||||
|   /** Procedure that is being build. */ | ||||
|   MFProcedure *procedure_ = nullptr; | ||||
|   Procedure *procedure_ = nullptr; | ||||
|   /** Cursors where the next instruction should be inserted. */ | ||||
|   Vector<MFInstructionCursor> cursors_; | ||||
|   Vector<InstructionCursor> cursors_; | ||||
|  | ||||
|  public: | ||||
|   struct Branch; | ||||
|   struct Loop; | ||||
|  | ||||
|   MFProcedureBuilder(MFProcedure &procedure, | ||||
|                      MFInstructionCursor initial_cursor = MFInstructionCursor::ForEntry()); | ||||
|   ProcedureBuilder(Procedure &procedure, | ||||
|                    InstructionCursor initial_cursor = InstructionCursor::ForEntry()); | ||||
|  | ||||
|   MFProcedureBuilder(Span<MFProcedureBuilder *> builders); | ||||
|   ProcedureBuilder(Span<ProcedureBuilder *> builders); | ||||
|  | ||||
|   MFProcedureBuilder(Branch &branch); | ||||
|   ProcedureBuilder(Branch &branch); | ||||
|  | ||||
|   void set_cursor(const MFInstructionCursor &cursor); | ||||
|   void set_cursor(Span<MFInstructionCursor> cursors); | ||||
|   void set_cursor(Span<MFProcedureBuilder *> builders); | ||||
|   void set_cursor(const InstructionCursor &cursor); | ||||
|   void set_cursor(Span<InstructionCursor> cursors); | ||||
|   void set_cursor(Span<ProcedureBuilder *> builders); | ||||
|   void set_cursor_after_branch(Branch &branch); | ||||
|   void set_cursor_after_loop(Loop &loop); | ||||
|  | ||||
|   void add_destruct(MFVariable &variable); | ||||
|   void add_destruct(Span<MFVariable *> variables); | ||||
|   void add_destruct(Variable &variable); | ||||
|   void add_destruct(Span<Variable *> variables); | ||||
|  | ||||
|   MFReturnInstruction &add_return(); | ||||
|   ReturnInstruction &add_return(); | ||||
|  | ||||
|   Branch add_branch(MFVariable &condition); | ||||
|   Branch add_branch(Variable &condition); | ||||
|  | ||||
|   Loop add_loop(); | ||||
|   void add_loop_continue(Loop &loop); | ||||
|   void add_loop_break(Loop &loop); | ||||
|  | ||||
|   MFCallInstruction &add_call_with_no_variables(const MultiFunction &fn); | ||||
|   MFCallInstruction &add_call_with_all_variables(const MultiFunction &fn, | ||||
|                                                  Span<MFVariable *> param_variables); | ||||
|   CallInstruction &add_call_with_no_variables(const MultiFunction &fn); | ||||
|   CallInstruction &add_call_with_all_variables(const MultiFunction &fn, | ||||
|                                                Span<Variable *> param_variables); | ||||
|  | ||||
|   Vector<MFVariable *> add_call(const MultiFunction &fn, | ||||
|                                 Span<MFVariable *> input_and_mutable_variables = {}); | ||||
|   Vector<Variable *> add_call(const MultiFunction &fn, | ||||
|                               Span<Variable *> input_and_mutable_variables = {}); | ||||
|  | ||||
|   template<int OutputN> | ||||
|   std::array<MFVariable *, OutputN> add_call(const MultiFunction &fn, | ||||
|                                              Span<MFVariable *> input_and_mutable_variables = {}); | ||||
|   std::array<Variable *, OutputN> add_call(const MultiFunction &fn, | ||||
|                                            Span<Variable *> input_and_mutable_variables = {}); | ||||
|  | ||||
|   void add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable); | ||||
|   MFVariable &add_parameter(MFParamType param_type, std::string name = ""); | ||||
|   void add_parameter(ParamType::InterfaceType interface_type, Variable &variable); | ||||
|   Variable &add_parameter(ParamType param_type, std::string name = ""); | ||||
|  | ||||
|   MFVariable &add_input_parameter(MFDataType data_type, std::string name = ""); | ||||
|   template<typename T> MFVariable &add_single_input_parameter(std::string name = ""); | ||||
|   template<typename T> MFVariable &add_single_mutable_parameter(std::string name = ""); | ||||
|   Variable &add_input_parameter(DataType data_type, std::string name = ""); | ||||
|   template<typename T> Variable &add_single_input_parameter(std::string name = ""); | ||||
|   template<typename T> Variable &add_single_mutable_parameter(std::string name = ""); | ||||
|  | ||||
|   void add_output_parameter(MFVariable &variable); | ||||
|   void add_output_parameter(Variable &variable); | ||||
|  | ||||
|  private: | ||||
|   void link_to_cursors(MFInstruction *instruction); | ||||
|   void link_to_cursors(Instruction *instruction); | ||||
| }; | ||||
|  | ||||
| struct MFProcedureBuilder::Branch { | ||||
|   MFProcedureBuilder branch_true; | ||||
|   MFProcedureBuilder branch_false; | ||||
| struct ProcedureBuilder::Branch { | ||||
|   ProcedureBuilder branch_true; | ||||
|   ProcedureBuilder branch_false; | ||||
| }; | ||||
|  | ||||
| struct MFProcedureBuilder::Loop { | ||||
|   MFInstruction *begin = nullptr; | ||||
|   MFDummyInstruction *end = nullptr; | ||||
| struct ProcedureBuilder::Loop { | ||||
|   Instruction *begin = nullptr; | ||||
|   DummyInstruction *end = nullptr; | ||||
| }; | ||||
|  | ||||
| /* -------------------------------------------------------------------- | ||||
|  * MFProcedureBuilder inline methods. | ||||
|  * ProcedureBuilder inline methods. | ||||
|  */ | ||||
|  | ||||
| inline MFProcedureBuilder::MFProcedureBuilder(Branch &branch) | ||||
|     : MFProcedureBuilder(*branch.branch_true.procedure_) | ||||
| inline ProcedureBuilder::ProcedureBuilder(Branch &branch) | ||||
|     : ProcedureBuilder(*branch.branch_true.procedure_) | ||||
| { | ||||
|   this->set_cursor_after_branch(branch); | ||||
| } | ||||
|  | ||||
| inline MFProcedureBuilder::MFProcedureBuilder(MFProcedure &procedure, | ||||
|                                               MFInstructionCursor initial_cursor) | ||||
| inline ProcedureBuilder::ProcedureBuilder(Procedure &procedure, InstructionCursor initial_cursor) | ||||
|     : procedure_(&procedure), cursors_({initial_cursor}) | ||||
| { | ||||
| } | ||||
|  | ||||
| inline MFProcedureBuilder::MFProcedureBuilder(Span<MFProcedureBuilder *> builders) | ||||
|     : MFProcedureBuilder(*builders[0]->procedure_) | ||||
| inline ProcedureBuilder::ProcedureBuilder(Span<ProcedureBuilder *> builders) | ||||
|     : ProcedureBuilder(*builders[0]->procedure_) | ||||
| { | ||||
|   this->set_cursor(builders); | ||||
| } | ||||
|  | ||||
| inline void MFProcedureBuilder::set_cursor(const MFInstructionCursor &cursor) | ||||
| inline void ProcedureBuilder::set_cursor(const InstructionCursor &cursor) | ||||
| { | ||||
|   cursors_ = {cursor}; | ||||
| } | ||||
|  | ||||
| inline void MFProcedureBuilder::set_cursor(Span<MFInstructionCursor> cursors) | ||||
| inline void ProcedureBuilder::set_cursor(Span<InstructionCursor> cursors) | ||||
| { | ||||
|   cursors_ = cursors; | ||||
| } | ||||
|  | ||||
| inline void MFProcedureBuilder::set_cursor_after_branch(Branch &branch) | ||||
| inline void ProcedureBuilder::set_cursor_after_branch(Branch &branch) | ||||
| { | ||||
|   this->set_cursor({&branch.branch_false, &branch.branch_true}); | ||||
| } | ||||
|  | ||||
| inline void MFProcedureBuilder::set_cursor_after_loop(Loop &loop) | ||||
| inline void ProcedureBuilder::set_cursor_after_loop(Loop &loop) | ||||
| { | ||||
|   this->set_cursor(MFInstructionCursor{*loop.end}); | ||||
|   this->set_cursor(InstructionCursor{*loop.end}); | ||||
| } | ||||
|  | ||||
| inline void MFProcedureBuilder::set_cursor(Span<MFProcedureBuilder *> builders) | ||||
| inline void ProcedureBuilder::set_cursor(Span<ProcedureBuilder *> builders) | ||||
| { | ||||
|   cursors_.clear(); | ||||
|   for (MFProcedureBuilder *builder : builders) { | ||||
|   for (ProcedureBuilder *builder : builders) { | ||||
|     cursors_.extend(builder->cursors_); | ||||
|   } | ||||
| } | ||||
|  | ||||
| template<int OutputN> | ||||
| inline std::array<MFVariable *, OutputN> MFProcedureBuilder::add_call( | ||||
|     const MultiFunction &fn, Span<MFVariable *> input_and_mutable_variables) | ||||
| inline std::array<Variable *, OutputN> ProcedureBuilder::add_call( | ||||
|     const MultiFunction &fn, Span<Variable *> input_and_mutable_variables) | ||||
| { | ||||
|   Vector<MFVariable *> output_variables = this->add_call(fn, input_and_mutable_variables); | ||||
|   Vector<Variable *> output_variables = this->add_call(fn, input_and_mutable_variables); | ||||
|   BLI_assert(output_variables.size() == OutputN); | ||||
|  | ||||
|   std::array<MFVariable *, OutputN> output_array; | ||||
|   std::array<Variable *, 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) | ||||
| inline void ProcedureBuilder::add_parameter(ParamType::InterfaceType interface_type, | ||||
|                                             Variable &variable) | ||||
| { | ||||
|   procedure_->add_parameter(interface_type, variable); | ||||
| } | ||||
|  | ||||
| inline MFVariable &MFProcedureBuilder::add_parameter(MFParamType param_type, std::string name) | ||||
| inline Variable &ProcedureBuilder::add_parameter(ParamType param_type, std::string name) | ||||
| { | ||||
|   MFVariable &variable = procedure_->new_variable(param_type.data_type(), std::move(name)); | ||||
|   Variable &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) | ||||
| inline Variable &ProcedureBuilder::add_input_parameter(DataType data_type, std::string name) | ||||
| { | ||||
|   return this->add_parameter(MFParamType(MFParamType::Input, data_type), std::move(name)); | ||||
|   return this->add_parameter(ParamType(ParamType::Input, data_type), std::move(name)); | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| inline MFVariable &MFProcedureBuilder::add_single_input_parameter(std::string name) | ||||
| inline Variable &ProcedureBuilder::add_single_input_parameter(std::string name) | ||||
| { | ||||
|   return this->add_parameter(MFParamType::ForSingleInput(CPPType::get<T>()), std::move(name)); | ||||
|   return this->add_parameter(ParamType::ForSingleInput(CPPType::get<T>()), std::move(name)); | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| inline MFVariable &MFProcedureBuilder::add_single_mutable_parameter(std::string name) | ||||
| inline Variable &ProcedureBuilder::add_single_mutable_parameter(std::string name) | ||||
| { | ||||
|   return this->add_parameter(MFParamType::ForMutableSingle(CPPType::get<T>()), std::move(name)); | ||||
|   return this->add_parameter(ParamType::ForMutableSingle(CPPType::get<T>()), std::move(name)); | ||||
| } | ||||
|  | ||||
| inline void MFProcedureBuilder::add_output_parameter(MFVariable &variable) | ||||
| inline void ProcedureBuilder::add_output_parameter(Variable &variable) | ||||
| { | ||||
|   this->add_parameter(MFParamType::Output, variable); | ||||
|   this->add_parameter(ParamType::Output, variable); | ||||
| } | ||||
|  | ||||
| inline void MFProcedureBuilder::link_to_cursors(MFInstruction *instruction) | ||||
| inline void ProcedureBuilder::link_to_cursors(Instruction *instruction) | ||||
| { | ||||
|   for (MFInstructionCursor &cursor : cursors_) { | ||||
|   for (InstructionCursor &cursor : cursors_) { | ||||
|     cursor.set_next(*procedure_, instruction); | ||||
|   } | ||||
| } | ||||
|  | ||||
| }  // namespace blender::fn | ||||
| }  // namespace blender::fn::multi_function | ||||
|   | ||||
		Reference in New Issue
	
	Block a user