Functions: simplify multi-function parameters
The use of `std::variant` allows combining the four vectors into one which more closely matches the intend and avoids a workaround used before. Note that this uses `std::get_if` instead of `std::get` because `std::get` is only available since macOS 10.14.
This commit is contained in:
parent
fc9c39e320
commit
42b88c0088
Notes:
blender-bot
2023-02-14 08:45:09 +01:00
Referenced by commit a5b27f9858
, Functions: simplify multi-function signature type
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
|
||||
#include <mutex>
|
||||
#include <variant>
|
||||
|
||||
#include "BLI_generic_pointer.hh"
|
||||
#include "BLI_generic_vector_array.hh"
|
||||
|
@ -28,10 +29,8 @@ class MFParamsBuilder {
|
|||
const MFSignature *signature_;
|
||||
IndexMask mask_;
|
||||
int64_t min_array_size_;
|
||||
Vector<GVArray> virtual_arrays_;
|
||||
Vector<GMutableSpan> mutable_spans_;
|
||||
Vector<const GVVectorArray *> virtual_vector_arrays_;
|
||||
Vector<GVectorArray *> vector_arrays_;
|
||||
Vector<std::variant<GVArray, GMutableSpan, const GVVectorArray *, GVectorArray *>>
|
||||
actual_params_;
|
||||
|
||||
std::mutex mutex_;
|
||||
Vector<std::pair<int, GMutableSpan>> dummy_output_spans_;
|
||||
|
@ -41,10 +40,7 @@ class MFParamsBuilder {
|
|||
MFParamsBuilder(const MFSignature &signature, const IndexMask mask)
|
||||
: signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size())
|
||||
{
|
||||
virtual_arrays_.reserve(signature.virtual_array_num);
|
||||
mutable_spans_.reserve(signature.span_num);
|
||||
virtual_vector_arrays_.reserve(signature.virtual_vector_array_num);
|
||||
vector_arrays_.reserve(signature.vector_array_num);
|
||||
actual_params_.reserve(signature.param_types.size());
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -58,32 +54,41 @@ class MFParamsBuilder {
|
|||
template<typename T> void add_readonly_single_input_value(T value, StringRef expected_name = "")
|
||||
{
|
||||
this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get<T>()), expected_name);
|
||||
virtual_arrays_.append_unchecked_as(
|
||||
varray_tag::single{}, CPPType::get<T>(), min_array_size_, &value);
|
||||
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
|
||||
varray_tag::single{},
|
||||
CPPType::get<T>(),
|
||||
min_array_size_,
|
||||
&value);
|
||||
}
|
||||
template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "")
|
||||
{
|
||||
this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get<T>()), expected_name);
|
||||
virtual_arrays_.append_unchecked_as(
|
||||
varray_tag::single_ref{}, CPPType::get<T>(), min_array_size_, value);
|
||||
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
|
||||
varray_tag::single_ref{},
|
||||
CPPType::get<T>(),
|
||||
min_array_size_,
|
||||
value);
|
||||
}
|
||||
void add_readonly_single_input(const GSpan span, StringRef expected_name = "")
|
||||
{
|
||||
this->assert_current_param_type(MFParamType::ForSingleInput(span.type()), expected_name);
|
||||
BLI_assert(span.size() >= min_array_size_);
|
||||
virtual_arrays_.append_unchecked_as(varray_tag::span{}, span);
|
||||
actual_params_.append_unchecked_as(std::in_place_type<GVArray>, varray_tag::span{}, span);
|
||||
}
|
||||
void add_readonly_single_input(GPointer value, StringRef expected_name = "")
|
||||
{
|
||||
this->assert_current_param_type(MFParamType::ForSingleInput(*value.type()), expected_name);
|
||||
virtual_arrays_.append_unchecked_as(
|
||||
varray_tag::single_ref{}, *value.type(), min_array_size_, value.get());
|
||||
actual_params_.append_unchecked_as(std::in_place_type<GVArray>,
|
||||
varray_tag::single_ref{},
|
||||
*value.type(),
|
||||
min_array_size_,
|
||||
value.get());
|
||||
}
|
||||
void add_readonly_single_input(GVArray varray, StringRef expected_name = "")
|
||||
{
|
||||
this->assert_current_param_type(MFParamType::ForSingleInput(varray.type()), expected_name);
|
||||
BLI_assert(varray.size() >= min_array_size_);
|
||||
virtual_arrays_.append_unchecked_as(std::move(varray));
|
||||
actual_params_.append_unchecked_as(std::in_place_type<GVArray>, std::move(varray));
|
||||
}
|
||||
|
||||
void add_readonly_vector_input(const GVectorArray &vector_array, StringRef expected_name = "")
|
||||
|
@ -101,7 +106,7 @@ class MFParamsBuilder {
|
|||
{
|
||||
this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name);
|
||||
BLI_assert(ref.size() >= min_array_size_);
|
||||
virtual_vector_arrays_.append_unchecked(&ref);
|
||||
actual_params_.append_unchecked_as(std::in_place_type<const GVVectorArray *>, &ref);
|
||||
}
|
||||
|
||||
template<typename T> void add_uninitialized_single_output(T *value, StringRef expected_name = "")
|
||||
|
@ -113,7 +118,7 @@ class MFParamsBuilder {
|
|||
{
|
||||
this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name);
|
||||
BLI_assert(ref.size() >= min_array_size_);
|
||||
mutable_spans_.append_unchecked(ref);
|
||||
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, ref);
|
||||
}
|
||||
void add_ignored_single_output(StringRef expected_name = "")
|
||||
{
|
||||
|
@ -124,7 +129,7 @@ class MFParamsBuilder {
|
|||
const CPPType &type = param_type.data_type().single_type();
|
||||
/* An empty span indicates that this is ignored. */
|
||||
const GMutableSpan dummy_span{type};
|
||||
mutable_spans_.append_unchecked(dummy_span);
|
||||
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, dummy_span);
|
||||
}
|
||||
|
||||
void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "")
|
||||
|
@ -132,14 +137,14 @@ class MFParamsBuilder {
|
|||
this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()),
|
||||
expected_name);
|
||||
BLI_assert(vector_array.size() >= min_array_size_);
|
||||
vector_arrays_.append_unchecked(&vector_array);
|
||||
actual_params_.append_unchecked_as(std::in_place_type<GVectorArray *>, &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_unchecked(ref);
|
||||
actual_params_.append_unchecked_as(std::in_place_type<GMutableSpan>, ref);
|
||||
}
|
||||
|
||||
void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "")
|
||||
|
@ -147,7 +152,7 @@ class MFParamsBuilder {
|
|||
this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()),
|
||||
expected_name);
|
||||
BLI_assert(vector_array.size() >= min_array_size_);
|
||||
vector_arrays_.append_unchecked(&vector_array);
|
||||
actual_params_.append_unchecked_as(std::in_place_type<GVectorArray *>, &vector_array);
|
||||
}
|
||||
|
||||
GMutableSpan computed_array(int param_index)
|
||||
|
@ -155,8 +160,7 @@ class MFParamsBuilder {
|
|||
BLI_assert(ELEM(signature_->param_types[param_index].category(),
|
||||
MFParamCategory::SingleOutput,
|
||||
MFParamCategory::SingleMutable));
|
||||
int data_index = signature_->data_index(param_index);
|
||||
return mutable_spans_[data_index];
|
||||
return *std::get_if<GMutableSpan>(&actual_params_[param_index]);
|
||||
}
|
||||
|
||||
GVectorArray &computed_vector_array(int param_index)
|
||||
|
@ -164,8 +168,7 @@ class MFParamsBuilder {
|
|||
BLI_assert(ELEM(signature_->param_types[param_index].category(),
|
||||
MFParamCategory::VectorOutput,
|
||||
MFParamCategory::VectorMutable));
|
||||
int data_index = signature_->data_index(param_index);
|
||||
return *vector_arrays_[data_index];
|
||||
return **std::get_if<GVectorArray *>(&actual_params_[param_index]);
|
||||
}
|
||||
|
||||
ResourceScope &resource_scope()
|
||||
|
@ -205,8 +208,7 @@ class MFParamsBuilder {
|
|||
|
||||
int current_param_index() const
|
||||
{
|
||||
return virtual_arrays_.size() + mutable_spans_.size() + virtual_vector_arrays_.size() +
|
||||
vector_arrays_.size();
|
||||
return actual_params_.size();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -227,8 +229,7 @@ class MFParams {
|
|||
const GVArray &readonly_single_input(int param_index, StringRef name = "")
|
||||
{
|
||||
this->assert_correct_param(param_index, name, MFParamCategory::SingleInput);
|
||||
int data_index = builder_->signature_->data_index(param_index);
|
||||
return builder_->virtual_arrays_[data_index];
|
||||
return *std::get_if<GVArray>(&builder_->actual_params_[param_index]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -240,8 +241,7 @@ class MFParams {
|
|||
bool single_output_is_required(int param_index, StringRef name = "")
|
||||
{
|
||||
this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput);
|
||||
int data_index = builder_->signature_->data_index(param_index);
|
||||
return !builder_->mutable_spans_[data_index].is_empty();
|
||||
return !std::get_if<GMutableSpan>(&builder_->actual_params_[param_index])->is_empty();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -252,14 +252,13 @@ class MFParams {
|
|||
GMutableSpan uninitialized_single_output(int param_index, StringRef name = "")
|
||||
{
|
||||
this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput);
|
||||
int data_index = builder_->signature_->data_index(param_index);
|
||||
GMutableSpan span = builder_->mutable_spans_[data_index];
|
||||
GMutableSpan span = *std::get_if<GMutableSpan>(&builder_->actual_params_[param_index]);
|
||||
if (!span.is_empty()) {
|
||||
return span;
|
||||
}
|
||||
/* The output is ignored by the caller, but the multi-function does not handle this case. So
|
||||
* create a temporary buffer that the multi-function can write to. */
|
||||
return this->ensure_dummy_single_output(data_index);
|
||||
return this->ensure_dummy_single_output(param_index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -274,8 +273,7 @@ class MFParams {
|
|||
GMutableSpan uninitialized_single_output_if_required(int param_index, StringRef name = "")
|
||||
{
|
||||
this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput);
|
||||
int data_index = builder_->signature_->data_index(param_index);
|
||||
return builder_->mutable_spans_[data_index];
|
||||
return *std::get_if<GMutableSpan>(&builder_->actual_params_[param_index]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -287,8 +285,7 @@ class MFParams {
|
|||
const GVVectorArray &readonly_vector_input(int param_index, StringRef name = "")
|
||||
{
|
||||
this->assert_correct_param(param_index, name, MFParamCategory::VectorInput);
|
||||
int data_index = builder_->signature_->data_index(param_index);
|
||||
return *builder_->virtual_vector_arrays_[data_index];
|
||||
return **std::get_if<const GVVectorArray *>(&builder_->actual_params_[param_index]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -299,8 +296,7 @@ class MFParams {
|
|||
GVectorArray &vector_output(int param_index, StringRef name = "")
|
||||
{
|
||||
this->assert_correct_param(param_index, name, MFParamCategory::VectorOutput);
|
||||
int data_index = builder_->signature_->data_index(param_index);
|
||||
return *builder_->vector_arrays_[data_index];
|
||||
return **std::get_if<GVectorArray *>(&builder_->actual_params_[param_index]);
|
||||
}
|
||||
|
||||
template<typename T> MutableSpan<T> single_mutable(int param_index, StringRef name = "")
|
||||
|
@ -310,8 +306,7 @@ class MFParams {
|
|||
GMutableSpan single_mutable(int param_index, StringRef name = "")
|
||||
{
|
||||
this->assert_correct_param(param_index, name, MFParamCategory::SingleMutable);
|
||||
int data_index = builder_->signature_->data_index(param_index);
|
||||
return builder_->mutable_spans_[data_index];
|
||||
return *std::get_if<GMutableSpan>(&builder_->actual_params_[param_index]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -322,8 +317,7 @@ class MFParams {
|
|||
GVectorArray &vector_mutable(int param_index, StringRef name = "")
|
||||
{
|
||||
this->assert_correct_param(param_index, name, MFParamCategory::VectorMutable);
|
||||
int data_index = builder_->signature_->data_index(param_index);
|
||||
return *builder_->vector_arrays_[data_index];
|
||||
return **std::get_if<GVectorArray *>(&builder_->actual_params_[param_index]);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -349,7 +343,7 @@ class MFParams {
|
|||
#endif
|
||||
}
|
||||
|
||||
GMutableSpan ensure_dummy_single_output(int data_index);
|
||||
GMutableSpan ensure_dummy_single_output(int param_index);
|
||||
};
|
||||
|
||||
} // namespace blender::fn
|
||||
|
|
|
@ -28,20 +28,6 @@ struct MFSignature {
|
|||
Vector<MFParamType> param_types;
|
||||
Vector<int> param_data_indices;
|
||||
bool depends_on_context = false;
|
||||
|
||||
/**
|
||||
* Number of elements of each of these types that has to be passed into the multi-function as an
|
||||
* input or output.
|
||||
*/
|
||||
int span_num = 0;
|
||||
int virtual_array_num = 0;
|
||||
int virtual_vector_array_num = 0;
|
||||
int vector_array_num = 0;
|
||||
|
||||
int data_index(int param_index) const
|
||||
{
|
||||
return param_data_indices[param_index];
|
||||
}
|
||||
};
|
||||
|
||||
class MFSignatureBuilder {
|
||||
|
@ -81,15 +67,6 @@ class MFSignatureBuilder {
|
|||
{
|
||||
signature_.param_names.append(name);
|
||||
signature_.param_types.append(MFParamType(MFParamType::Input, data_type));
|
||||
|
||||
switch (data_type.category()) {
|
||||
case MFDataType::Single:
|
||||
signature_.param_data_indices.append(signature_.virtual_array_num++);
|
||||
break;
|
||||
case MFDataType::Vector:
|
||||
signature_.param_data_indices.append(signature_.virtual_vector_array_num++);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output Parameter Types */
|
||||
|
@ -114,15 +91,6 @@ class MFSignatureBuilder {
|
|||
{
|
||||
signature_.param_names.append(name);
|
||||
signature_.param_types.append(MFParamType(MFParamType::Output, data_type));
|
||||
|
||||
switch (data_type.category()) {
|
||||
case MFDataType::Single:
|
||||
signature_.param_data_indices.append(signature_.span_num++);
|
||||
break;
|
||||
case MFDataType::Vector:
|
||||
signature_.param_data_indices.append(signature_.vector_array_num++);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mutable Parameter Types */
|
||||
|
@ -147,15 +115,6 @@ class MFSignatureBuilder {
|
|||
{
|
||||
signature_.param_names.append(name);
|
||||
signature_.param_types.append(MFParamType(MFParamType::Mutable, data_type));
|
||||
|
||||
switch (data_type.category()) {
|
||||
case MFDataType::Single:
|
||||
signature_.param_data_indices.append(signature_.span_num++);
|
||||
break;
|
||||
case MFDataType::Vector:
|
||||
signature_.param_data_indices.append(signature_.vector_array_num++);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void add(const char *name, const MFParamType ¶m_type)
|
||||
|
|
|
@ -4,18 +4,18 @@
|
|||
|
||||
namespace blender::fn {
|
||||
|
||||
GMutableSpan MFParams::ensure_dummy_single_output(int data_index)
|
||||
GMutableSpan MFParams::ensure_dummy_single_output(int param_index)
|
||||
{
|
||||
/* Lock because we are actually modifying #builder_ and it may be used by multiple threads. */
|
||||
std::lock_guard lock{builder_->mutex_};
|
||||
|
||||
for (const std::pair<int, GMutableSpan> &items : builder_->dummy_output_spans_) {
|
||||
if (items.first == data_index) {
|
||||
if (items.first == param_index) {
|
||||
return items.second;
|
||||
}
|
||||
}
|
||||
|
||||
const CPPType &type = builder_->mutable_spans_[data_index].type();
|
||||
const CPPType &type = std::get_if<GMutableSpan>(&builder_->actual_params_[param_index])->type();
|
||||
void *buffer = builder_->scope_.linear_allocator().allocate(
|
||||
builder_->min_array_size_ * type.size(), type.alignment());
|
||||
if (!type.is_trivially_destructible()) {
|
||||
|
@ -23,7 +23,7 @@ GMutableSpan MFParams::ensure_dummy_single_output(int data_index)
|
|||
[&type, buffer, mask = builder_->mask_]() { type.destruct_indices(buffer, mask); });
|
||||
}
|
||||
const GMutableSpan span{type, buffer, builder_->min_array_size_};
|
||||
builder_->dummy_output_spans_.append({data_index, span});
|
||||
builder_->dummy_output_spans_.append({param_index, span});
|
||||
return span;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue