소스 검색

Merge pull request #45698 from KoBeWi/callables_are_love_callables_are_life

Change sort_custom/bsearch_custom to use Callables
Rémi Verschelde 4 년 전
부모
커밋
d93f75fae5
5개의 변경된 파일21개의 추가작업 그리고 28개의 파일을 삭제
  1. 10 14
      core/variant/array.cpp
  2. 3 2
      core/variant/array.h
  3. 2 2
      core/variant/variant_call.cpp
  4. 5 9
      doc/classes/Array.xml
  5. 1 1
      editor/plugins/tile_set_editor_plugin.cpp

+ 10 - 14
core/variant/array.cpp

@@ -35,6 +35,7 @@
 #include "core/object/script_language.h"
 #include "core/object/script_language.h"
 #include "core/templates/hashfuncs.h"
 #include "core/templates/hashfuncs.h"
 #include "core/templates/vector.h"
 #include "core/templates/vector.h"
+#include "core/variant/callable.h"
 #include "core/variant/variant.h"
 #include "core/variant/variant.h"
 
 
 class ArrayPrivate {
 class ArrayPrivate {
@@ -371,25 +372,22 @@ void Array::sort() {
 }
 }
 
 
 struct _ArrayVariantSortCustom {
 struct _ArrayVariantSortCustom {
-	Object *obj = nullptr;
-	StringName func;
+	Callable func;
 
 
 	_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
 	_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
 		const Variant *args[2] = { &p_l, &p_r };
 		const Variant *args[2] = { &p_l, &p_r };
 		Callable::CallError err;
 		Callable::CallError err;
-		bool res = obj->call(func, args, 2, err);
-		if (err.error != Callable::CallError::CALL_OK) {
-			res = false;
-		}
+		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;
 		return res;
 	}
 	}
 };
 };
-void Array::sort_custom(Object *p_obj, const StringName &p_function) {
-	ERR_FAIL_NULL(p_obj);
 
 
+void Array::sort_custom(Callable p_callable) {
 	SortArray<Variant, _ArrayVariantSortCustom, true> avs;
 	SortArray<Variant, _ArrayVariantSortCustom, true> avs;
-	avs.compare.obj = p_obj;
-	avs.compare.func = p_function;
+	avs.compare.func = p_callable;
 	avs.sort(_p->array.ptrw(), _p->array.size());
 	avs.sort(_p->array.ptrw(), _p->array.size());
 }
 }
 
 
@@ -438,13 +436,11 @@ int Array::bsearch(const Variant &p_value, bool p_before) {
 	return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
 	return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
 }
 }
 
 
-int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) {
+int Array::bsearch_custom(const Variant &p_value, 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);
-	ERR_FAIL_NULL_V(p_obj, 0);
 
 
 	_ArrayVariantSortCustom less;
 	_ArrayVariantSortCustom less;
-	less.obj = p_obj;
-	less.func = p_function;
+	less.func = p_callable;
 
 
 	return bisect(_p->array, p_value, p_before, less);
 	return bisect(_p->array, p_value, p_before, less);
 }
 }

+ 3 - 2
core/variant/array.h

@@ -37,6 +37,7 @@ class Variant;
 class ArrayPrivate;
 class ArrayPrivate;
 class Object;
 class Object;
 class StringName;
 class StringName;
+class Callable;
 
 
 class Array {
 class Array {
 	mutable ArrayPrivate *_p;
 	mutable ArrayPrivate *_p;
@@ -78,10 +79,10 @@ public:
 	Variant back() const;
 	Variant back() const;
 
 
 	void sort();
 	void sort();
-	void sort_custom(Object *p_obj, const StringName &p_function);
+	void sort_custom(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, Object *p_obj, const StringName &p_function, bool p_before = true);
+	int bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before = true);
 	void invert();
 	void invert();
 
 
 	int find(const Variant &p_value, int p_from = 0) const;
 	int find(const Variant &p_value, int p_from = 0) const;

+ 2 - 2
core/variant/variant_call.cpp

@@ -1298,10 +1298,10 @@ static void _register_variant_builtin_methods() {
 	bind_method(Array, pop_back, sarray(), varray());
 	bind_method(Array, pop_back, sarray(), varray());
 	bind_method(Array, pop_front, sarray(), varray());
 	bind_method(Array, pop_front, sarray(), varray());
 	bind_method(Array, sort, sarray(), varray());
 	bind_method(Array, sort, sarray(), varray());
-	bind_method(Array, sort_custom, sarray("obj", "func"), varray());
+	bind_method(Array, sort_custom, sarray("func"), varray());
 	bind_method(Array, shuffle, sarray(), varray());
 	bind_method(Array, shuffle, sarray(), varray());
 	bind_method(Array, bsearch, sarray("value", "before"), varray(true));
 	bind_method(Array, bsearch, sarray("value", "before"), varray(true));
-	bind_method(Array, bsearch_custom, sarray("value", "obj", "func", "before"), varray(true));
+	bind_method(Array, bsearch_custom, sarray("value", "func", "before"), varray(true));
 	bind_method(Array, invert, sarray(), varray());
 	bind_method(Array, invert, sarray(), varray());
 	bind_method(Array, duplicate, sarray("deep"), varray(false));
 	bind_method(Array, duplicate, sarray("deep"), varray(false));
 	bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false));
 	bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false));

+ 5 - 9
doc/classes/Array.xml

@@ -191,11 +191,9 @@
 			</return>
 			</return>
 			<argument index="0" name="value" type="Variant">
 			<argument index="0" name="value" type="Variant">
 			</argument>
 			</argument>
-			<argument index="1" name="obj" type="Object">
+			<argument index="1" name="func" type="Callable">
 			</argument>
 			</argument>
-			<argument index="2" name="func" type="StringName">
-			</argument>
-			<argument index="3" name="before" type="bool" default="true">
+			<argument index="2" name="before" type="bool" default="true">
 			</argument>
 			</argument>
 			<description>
 			<description>
 				Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search and a custom comparison method. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. The custom method receives two arguments (an element from the array and the value searched for) and must return [code]true[/code] if the first argument is less than the second, and return [code]false[/code] otherwise.
 				Finds the index of an existing value (or the insertion index that maintains sorting order, if the value is not yet present in the array) using binary search and a custom comparison method. Optionally, a [code]before[/code] specifier can be passed. If [code]false[/code], the returned index comes after all existing entries of the value in the array. The custom method receives two arguments (an element from the array and the value searched for) and must return [code]true[/code] if the first argument is less than the second, and return [code]false[/code] otherwise.
@@ -537,12 +535,10 @@
 		<method name="sort_custom">
 		<method name="sort_custom">
 			<return type="void">
 			<return type="void">
 			</return>
 			</return>
-			<argument index="0" name="obj" type="Object">
-			</argument>
-			<argument index="1" name="func" type="StringName">
+			<argument index="0" name="func" type="Callable">
 			</argument>
 			</argument>
 			<description>
 			<description>
-				Sorts the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code].
+				Sorts the array using a custom method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code].
 				[b]Note:[/b] you cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior.
 				[b]Note:[/b] you cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior.
 				[codeblocks]
 				[codeblocks]
 				[gdscript]
 				[gdscript]
@@ -553,7 +549,7 @@
 				        return false
 				        return false
 
 
 				var my_items = [[5, "Potato"], [9, "Rice"], [4, "Tomato"]]
 				var my_items = [[5, "Potato"], [9, "Rice"], [4, "Tomato"]]
-				my_items.sort_custom(MyCustomSorter, "sort_ascending")
+				my_items.sort_custom(MyCustomSorter.sort_ascending)
 				print(my_items) # Prints [[4, Tomato], [5, Potato], [9, Rice]].
 				print(my_items) # Prints [[4, Tomato], [5, Potato], [9, Rice]].
 				[/gdscript]
 				[/gdscript]
 				[csharp]
 				[csharp]

+ 1 - 1
editor/plugins/tile_set_editor_plugin.cpp

@@ -2173,7 +2173,7 @@ Array TileSetEditor::_get_tiles_in_current_texture(bool sorted) {
 		}
 		}
 	}
 	}
 	if (sorted) {
 	if (sorted) {
-		a.sort_custom(this, "_sort_tiles");
+		a.sort_custom(callable_mp(this, &TileSetEditor::_sort_tiles));
 	}
 	}
 	return a;
 	return a;
 }
 }