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:
authorJacques Lucke <jacques@blender.org>2021-09-14 15:52:44 +0300
committerJacques Lucke <jacques@blender.org>2021-09-14 15:52:44 +0300
commitfd60f6713a9d9e6f7d706b53bf1311f2f1cd9031 (patch)
treebb762d4ce5e5ad76a52d594249e8c6ec33b08312 /source/blender/functions/intern/multi_function_procedure_executor.cc
parent90a48fa06414ccf5fc5dd6092917413180ff30d1 (diff)
Functions: support optional outputs in multi-function
Sometimes not all outputs of a multi-function are required by the caller. In those cases it would be a waste of compute resources to calculate the unused values anyway. Now, the caller of a multi-function can specify when a specific output is not used. The called function can check if an output is unused and may ignore it. Multi-functions can still computed unused outputs as before if they don't want to check if a specific output is unused. The multi-function procedure system has been updated to support ignored outputs in call instructions. An ignored output just has no variable assigned to it. The field system has been updated to generate a multi-function procedure where unused outputs are ignored.
Diffstat (limited to 'source/blender/functions/intern/multi_function_procedure_executor.cc')
-rw-r--r--source/blender/functions/intern/multi_function_procedure_executor.cc31
1 files changed, 23 insertions, 8 deletions
diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc
index 38b26415779..b97282accdd 100644
--- a/source/blender/functions/intern/multi_function_procedure_executor.cc
+++ b/source/blender/functions/intern/multi_function_procedure_executor.cc
@@ -978,7 +978,7 @@ static bool evaluate_as_one(const MultiFunction &fn,
return false;
}
for (VariableState *state : param_variable_states) {
- if (!state->is_one()) {
+ if (state != nullptr && !state->is_one()) {
return false;
}
}
@@ -997,8 +997,13 @@ static void execute_call_instruction(const MFCallInstruction &instruction,
for (const int param_index : fn.param_indices()) {
const MFVariable *variable = instruction.params()[param_index];
- VariableState &variable_state = variable_states.get_variable_state(*variable);
- param_variable_states[param_index] = &variable_state;
+ if (variable == nullptr) {
+ param_variable_states[param_index] = nullptr;
+ }
+ else {
+ VariableState &variable_state = variable_states.get_variable_state(*variable);
+ param_variable_states[param_index] = &variable_state;
+ }
}
/* If all inputs to the function are constant, it's enough to call the function only once instead
@@ -1008,19 +1013,29 @@ static void execute_call_instruction(const MFCallInstruction &instruction,
for (const int param_index : fn.param_indices()) {
const MFParamType param_type = fn.param_type(param_index);
- VariableState &variable_state = *param_variable_states[param_index];
- variable_states.add_as_param__one(variable_state, params, param_type, mask);
+ VariableState *variable_state = param_variable_states[param_index];
+ if (variable_state == nullptr) {
+ params.add_ignored_single_output();
+ }
+ else {
+ variable_states.add_as_param__one(*variable_state, params, param_type, mask);
+ }
}
fn.call(IndexRange(1), params, context);
}
else {
- MFParamsBuilder params(fn, mask.min_array_size());
+ MFParamsBuilder params(fn, &mask);
for (const int param_index : fn.param_indices()) {
const MFParamType param_type = fn.param_type(param_index);
- VariableState &variable_state = *param_variable_states[param_index];
- variable_states.add_as_param(variable_state, params, param_type, mask);
+ VariableState *variable_state = param_variable_states[param_index];
+ if (variable_state == nullptr) {
+ params.add_ignored_single_output();
+ }
+ else {
+ variable_states.add_as_param(*variable_state, params, param_type, mask);
+ }
}
fn.call(mask, params, context);