1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-14 13:41:12 +00:00

Const Ref Callable for custom sort/search

This commit is contained in:
mashumafi
2022-03-27 21:57:20 -04:00
parent a0071029f2
commit 9c2bfeb2fb
5 changed files with 34 additions and 32 deletions

View File

@@ -97,24 +97,29 @@ public:
_FORCE_INLINE_ bool has(const T &p_val) const { return find(p_val) != -1; } _FORCE_INLINE_ bool has(const T &p_val) const { return find(p_val) != -1; }
template <class C> void sort() {
void sort_custom() { sort_custom<_DefaultComparator<T>>();
}
template <class Comparator, bool Validate = SORT_ARRAY_VALIDATE_ENABLED, class... Args>
void sort_custom(Args &&...args) {
int len = _cowdata.size(); int len = _cowdata.size();
if (len == 0) { if (len == 0) {
return; return;
} }
T *data = ptrw(); T *data = ptrw();
SortArray<T, C> sorter; SortArray<T, Comparator, Validate> sorter{ args... };
sorter.sort(data, len); sorter.sort(data, len);
} }
void sort() { int bsearch(const T &p_value, bool p_before) {
sort_custom<_DefaultComparator<T>>(); return bsearch_custom<_DefaultComparator<T>>(p_value, p_before);
} }
int bsearch(const T &p_value, bool p_before) { template <class Comparator, class Value, class... Args>
SearchArray<T> search; int bsearch_custom(const Value &p_value, bool p_before, Args &&...args) {
SearchArray<T, Comparator> search{ args... };
return search.bisect(ptrw(), size(), p_value, p_before); return search.bisect(ptrw(), size(), p_value, p_before);
} }

View File

@@ -484,24 +484,8 @@ void Array::sort() {
_p->array.sort_custom<_ArrayVariantSort>(); _p->array.sort_custom<_ArrayVariantSort>();
} }
struct _ArrayVariantSortCustom { void Array::sort_custom(const Callable &p_callable) {
Callable func; _p->array.sort_custom<CallableComparator, true>(p_callable);
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
const Variant *args[2] = { &p_l, &p_r };
Callable::CallError err;
Variant res;
func.call(args, 2, res, err);
ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false,
"Error calling sorting method: " + Variant::get_callable_error_text(func, args, 1, err));
return res;
}
};
void Array::sort_custom(Callable p_callable) {
SortArray<Variant, _ArrayVariantSortCustom, true> avs;
avs.compare.func = p_callable;
avs.sort(_p->array.ptrw(), _p->array.size());
} }
void Array::shuffle() { void Array::shuffle() {
@@ -524,13 +508,10 @@ int Array::bsearch(const Variant &p_value, bool p_before) {
return avs.bisect(_p->array.ptrw(), _p->array.size(), p_value, p_before); return avs.bisect(_p->array.ptrw(), _p->array.size(), p_value, p_before);
} }
int Array::bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before) { int Array::bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before) {
ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1); ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1);
SearchArray<Variant, _ArrayVariantSortCustom> avs; return _p->array.bsearch_custom<CallableComparator>(p_value, p_before, p_callable);
avs.compare.func = p_callable;
return avs.bisect(_p->array.ptrw(), _p->array.size(), p_value, p_before);
} }
void Array::reverse() { void Array::reverse() {

View File

@@ -82,10 +82,10 @@ public:
Variant back() const; Variant back() const;
void sort(); void sort();
void sort_custom(Callable p_callable); void sort_custom(const Callable &p_callable);
void shuffle(); void shuffle();
int bsearch(const Variant &p_value, bool p_before = true); int bsearch(const Variant &p_value, bool p_before = true);
int bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before = true); int bsearch_custom(const Variant &p_value, const Callable &p_callable, bool p_before = true);
void reverse(); void reverse();
int find(const Variant &p_value, int p_from = 0) const; int find(const Variant &p_value, int p_from = 0) const;

View File

@@ -429,3 +429,13 @@ Signal::Signal(ObjectID p_object, const StringName &p_name) {
object = p_object; object = p_object;
name = p_name; name = p_name;
} }
bool CallableComparator::operator()(const Variant &p_l, const Variant &p_r) const {
const Variant *args[2] = { &p_l, &p_r };
Callable::CallError err;
Variant res;
func.call(args, 2, res, err);
ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false,
"Error calling compare method: " + Variant::get_callable_error_text(func, args, 1, err));
return res;
}

View File

@@ -170,4 +170,10 @@ public:
Signal() {} Signal() {}
}; };
struct CallableComparator {
const Callable &func;
bool operator()(const Variant &p_l, const Variant &p_r) const;
};
#endif // CALLABLE_H #endif // CALLABLE_H