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

multi_function_procedure_builder.cc « intern « functions « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 858172e774d4c91ba5ed662c5d57226a119dce20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include "FN_multi_function_procedure_builder.hh"

namespace blender::fn {

void MFProcedureBuilder::add_destruct(MFVariable &variable)
{
  MFDestructInstruction &instruction = procedure_->new_destruct_instruction();
  instruction.set_variable(&variable);
  this->link_to_cursors(&instruction);
  cursors_ = {MFInstructionCursor{instruction}};
}

void MFProcedureBuilder::add_destruct(Span<MFVariable *> variables)
{
  for (MFVariable *variable : variables) {
    this->add_destruct(*variable);
  }
}

MFReturnInstruction &MFProcedureBuilder::add_return()
{
  MFReturnInstruction &instruction = procedure_->new_return_instruction();
  this->link_to_cursors(&instruction);
  cursors_ = {};
  return instruction;
}

MFCallInstruction &MFProcedureBuilder::add_call_with_no_variables(const MultiFunction &fn)
{
  MFCallInstruction &instruction = procedure_->new_call_instruction(fn);
  this->link_to_cursors(&instruction);
  cursors_ = {MFInstructionCursor{instruction}};
  return instruction;
}

MFCallInstruction &MFProcedureBuilder::add_call_with_all_variables(
    const MultiFunction &fn, Span<MFVariable *> param_variables)
{
  MFCallInstruction &instruction = this->add_call_with_no_variables(fn);
  instruction.set_params(param_variables);
  return instruction;
}

Vector<MFVariable *> MFProcedureBuilder::add_call(const MultiFunction &fn,
                                                  Span<MFVariable *> input_and_mutable_variables)
{
  Vector<MFVariable *> output_variables;
  MFCallInstruction &instruction = this->add_call_with_no_variables(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(),
                                                        fn.param_name(param_index));
        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;
}

MFProcedureBuilder::Branch MFProcedureBuilder::add_branch(MFVariable &condition)
{
  MFBranchInstruction &instruction = procedure_->new_branch_instruction();
  instruction.set_condition(&condition);
  this->link_to_cursors(&instruction);
  /* Clear cursors because this builder ends here. */
  cursors_.clear();

  Branch branch{*procedure_, *procedure_};
  branch.branch_true.set_cursor(MFInstructionCursor{instruction, true});
  branch.branch_false.set_cursor(MFInstructionCursor{instruction, false});
  return branch;
}

MFProcedureBuilder::Loop MFProcedureBuilder::add_loop()
{
  MFDummyInstruction &loop_begin = procedure_->new_dummy_instruction();
  MFDummyInstruction &loop_end = procedure_->new_dummy_instruction();
  this->link_to_cursors(&loop_begin);
  cursors_ = {MFInstructionCursor{loop_begin}};

  Loop loop;
  loop.begin = &loop_begin;
  loop.end = &loop_end;

  return loop;
}

void MFProcedureBuilder::add_loop_continue(Loop &loop)
{
  this->link_to_cursors(loop.begin);
  /* Clear cursors because this builder ends here. */
  cursors_.clear();
}

void MFProcedureBuilder::add_loop_break(Loop &loop)
{
  this->link_to_cursors(loop.end);
  /* Clear cursors because this builder ends here. */
  cursors_.clear();
}

}  // namespace blender::fn