Просмотр исходного кода

Merge pull request #106738 from BastiaanOlij/openxr_add_future_result

OpenXR Futures: Add return value support
Thaddeus Crews 3 месяцев назад
Родитель
Сommit
6c9765d87e

+ 14 - 0
modules/openxr/doc_classes/OpenXRFutureResult.xml

@@ -21,12 +21,26 @@
 				Return the [code]XrFutureEXT[/code] value this result relates to.
 			</description>
 		</method>
+		<method name="get_result_value" qualifiers="const">
+			<return type="Variant" />
+			<description>
+				Returns the result value of our asynchronous function (if set by the extension). The type of this result value depends on the function being called. Consult the documentation of the relevant function.
+			</description>
+		</method>
 		<method name="get_status" qualifiers="const">
 			<return type="int" enum="OpenXRFutureResult.ResultStatus" />
 			<description>
 				Returns the status of this result.
 			</description>
 		</method>
+		<method name="set_result_value">
+			<return type="void" />
+			<param index="0" name="result_value" type="Variant" />
+			<description>
+				Stores the result value we expose to the user.
+				[b]Note:[/b] This method should only be called by an OpenXR extension that implements an asynchronous function.
+			</description>
+		</method>
 	</methods>
 	<signals>
 		<signal name="completed">

+ 16 - 4
modules/openxr/extensions/openxr_future_extension.cpp

@@ -40,6 +40,9 @@ void OpenXRFutureResult::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_future"), &OpenXRFutureResult::_get_future);
 	ClassDB::bind_method(D_METHOD("cancel_future"), &OpenXRFutureResult::cancel_future);
 
+	ClassDB::bind_method(D_METHOD("set_result_value", "result_value"), &OpenXRFutureResult::set_result_value);
+	ClassDB::bind_method(D_METHOD("get_result_value"), &OpenXRFutureResult::get_result_value);
+
 	ADD_SIGNAL(MethodInfo("completed", PropertyInfo(Variant::OBJECT, "result", PROPERTY_HINT_RESOURCE_TYPE, "OpenXRFutureResult")));
 
 	BIND_ENUM_CONSTANT(RESULT_RUNNING);
@@ -52,10 +55,10 @@ void OpenXRFutureResult::_mark_as_finished() {
 	status = RESULT_FINISHED;
 
 	// Perform our callback
-	on_success_callback.call((uint64_t)future);
+	on_success_callback.call(this); // Note, `this` will be converted to a variant that will be refcounted!
 
-	// Emit our signal
-	emit_signal(SNAME("completed"), this);
+	// Emit our signal, we assume our callback has provided us with the correct result value by calling set_result_value.
+	emit_signal(SNAME("completed"), result_value);
 }
 
 void OpenXRFutureResult::_mark_as_cancelled() {
@@ -65,7 +68,8 @@ void OpenXRFutureResult::_mark_as_cancelled() {
 	// There is no point in doing a callback for cancellation as its always user invoked.
 
 	// But we do emit our signal to make sure any await finishes.
-	emit_signal(SNAME("completed"), this);
+	Variant no_result;
+	emit_signal(SNAME("completed"), no_result);
 }
 
 OpenXRFutureResult::ResultStatus OpenXRFutureResult::get_status() const {
@@ -80,6 +84,14 @@ uint64_t OpenXRFutureResult::_get_future() const {
 	return (uint64_t)future;
 }
 
+void OpenXRFutureResult::set_result_value(const Variant &p_result_value) {
+	result_value = p_result_value;
+}
+
+Variant OpenXRFutureResult::get_result_value() const {
+	return result_value;
+}
+
 void OpenXRFutureResult::cancel_future() {
 	ERR_FAIL_COND(status != RESULT_RUNNING);
 

+ 4 - 0
modules/openxr/extensions/openxr_future_extension.h

@@ -74,6 +74,9 @@ public:
 	ResultStatus get_status() const;
 	XrFutureEXT get_future() const;
 
+	void set_result_value(const Variant &p_result_value);
+	Variant get_result_value() const;
+
 	void cancel_future();
 
 	OpenXRFutureResult(XrFutureEXT p_future, const Callable &p_on_success);
@@ -81,6 +84,7 @@ public:
 private:
 	ResultStatus status = RESULT_RUNNING;
 	XrFutureEXT future;
+	Variant result_value;
 	Callable on_success_callback;
 
 	uint64_t _get_future() const;