Skip to content

Commit f017f4e

Browse files
committed
Add return type to await()
1 parent 0012ba2 commit f017f4e

File tree

5 files changed

+140
-112
lines changed

5 files changed

+140
-112
lines changed

harness/tests/scripts/godot/tests/coroutine/CoroutineTest.gdj

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ supertypes = [
1212
]
1313
signals = [
1414
signal_without_parameter,
15-
signal_with_parameters
15+
signal_with_parameters,
16+
signal_with_many_parameters
1617
]
1718
properties = [
18-
int
19+
step
1920
]
2021
functions = [
2122
start_coroutine_without_parameter,
22-
start_coroutine_with_parameters
23+
start_coroutine_with_parameters,
24+
start_coroutine_with_many_parameters
2325
]

harness/tests/src/main/kotlin/godot/tests/coroutine/CoroutineTest.kt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import godot.Object
88
import godot.annotation.RegisterFunction
99
import godot.annotation.RegisterProperty
1010
import godot.annotation.RegisterSignal
11+
import godot.core.Vector2
1112
import godot.core.signal
1213
import godot.coroutines.GodotCoroutine
1314
import godot.coroutines.await
@@ -21,6 +22,9 @@ class CoroutineTest : Object() {
2122
@RegisterSignal
2223
val signalWithParameters by signal<Int, String>("int", "string")
2324

25+
@RegisterSignal
26+
val signalWithManyParameters by signal<Int, Float, Vector2, String>("int", "float", "vector2", "string")
27+
2428
@RegisterProperty
2529
var step: Int = 0
2630

@@ -34,7 +38,14 @@ class CoroutineTest : Object() {
3438
@RegisterFunction
3539
fun startCoroutineWithParameters() = GodotCoroutine {
3640
step = 3
37-
signalWithParameters.await()
38-
step = 4
41+
val (int, string) = signalWithParameters.await()
42+
step = int
43+
}
44+
45+
@RegisterFunction
46+
fun startCoroutineWithManyParameters() = GodotCoroutine {
47+
step = 5
48+
val list = signalWithManyParameters.await()
49+
step = list[0] as Int
3950
}
4051
}

harness/tests/test/unit/test_coroutines.gd

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,25 @@ extends "res://addons/gut/test.gd"
44
func test_coroutine_await():
55
var test_script: Object = CoroutineTest.new()
66

7-
assert_eq(test_script.int, 0, "Property should be 0 at first.")
7+
assert_eq(test_script.step, 0, "Property should be 0 at first.")
88

99
test_script.start_coroutine_without_parameter()
10-
assert_eq(test_script.int, 1, "Property should be 1 after coroutine started but waiting.")
10+
assert_eq(test_script.step, 1, "Property should be 1 after coroutine started but waiting.")
1111

1212
test_script.signal_without_parameter.emit()
1313
await get_tree().create_timer(1).timeout
14-
assert_eq(test_script.int, 2, "Property should be 2 after coroutine ran and signal triggered.")
14+
assert_eq(test_script.step, 2, "Property should be 2 after coroutine ran and signal triggered.")
1515

1616
test_script.start_coroutine_with_parameters()
17-
assert_eq(test_script.int, 3, "Property should be 3 after coroutine started but waiting.")
17+
assert_eq(test_script.step, 3, "Property should be 3 after coroutine started but waiting.")
1818

19-
test_script.signal_with_parameters.emit()
19+
test_script.signal_with_parameters.emit(4, "test")
2020
await get_tree().create_timer(1).timeout
21-
assert_eq(test_script.int, 4, "Property should be 4 after coroutine ran.")
21+
assert_eq(test_script.step, 4, "Property should be 4 after coroutine ran.")
22+
23+
test_script.start_coroutine_with_many_parameters()
24+
assert_eq(test_script.step, 5, "Property should be 3 after coroutine started but waiting.")
25+
26+
test_script.signal_with_many_parameters.emit(6, 0.1, Vector2(0,0), "test")
27+
await get_tree().create_timer(1).timeout
28+
assert_eq(test_script.step, 6, "Property should be 4 after coroutine ran.")

kt/api-generator/src/main/kotlin/godot/codegen/services/impl/AwaitGenerationService.kt

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package godot.codegen.services.impl
22

3+
import com.squareup.kotlinpoet.ANY
34
import com.squareup.kotlinpoet.AnnotationSpec
45
import com.squareup.kotlinpoet.ClassName
56
import com.squareup.kotlinpoet.FileSpec
67
import com.squareup.kotlinpoet.FunSpec
78
import com.squareup.kotlinpoet.KModifier
9+
import com.squareup.kotlinpoet.LIST
810
import com.squareup.kotlinpoet.MemberName
911
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
12+
import com.squareup.kotlinpoet.TypeName
1013
import com.squareup.kotlinpoet.TypeVariableName
1114
import com.squareup.kotlinpoet.UNIT
1215
import godot.codegen.services.IAwaitGenerationService
@@ -29,7 +32,6 @@ object AwaitGenerationService : IAwaitGenerationService {
2932
}.toList()
3033

3134
for (argCount in 0..maxArgumentCount) {
32-
3335
val parameters = allParameters.take(argCount)
3436

3537
val baseReceiver = ClassName(godotCorePackage, signal + argCount)
@@ -39,6 +41,14 @@ object AwaitGenerationService : IAwaitGenerationService {
3941
baseReceiver
4042
}
4143

44+
val returnType = when (argCount) {
45+
1 -> parameters[0]
46+
2 -> ClassName("kotlin", "Pair").parameterizedBy(parameters)
47+
3 -> ClassName("kotlin", "Triple").parameterizedBy(parameters)
48+
in 4 .. maxArgumentCount -> LIST.parameterizedBy(ANY.copy(nullable = true))
49+
else -> UNIT
50+
}
51+
4252
awaitFile.addFunction(
4353
FunSpec.builder("await")
4454
.addModifiers(KModifier.SUSPEND, KModifier.INLINE)
@@ -48,7 +58,8 @@ object AwaitGenerationService : IAwaitGenerationService {
4858
addTypeVariables(parameters)
4959
}
5060
}
51-
.generateBody(argCount)
61+
.generateBody(argCount, returnType)
62+
.returns(returnType)
5263
.build()
5364
)
5465
}
@@ -63,7 +74,8 @@ object AwaitGenerationService : IAwaitGenerationService {
6374
}
6475

6576

66-
private fun FunSpec.Builder.generateBody(argCount: Int): FunSpec.Builder {
77+
private fun FunSpec.Builder.generateBody(argCount: Int, returnType: TypeName): FunSpec.Builder {
78+
// Build `p0, p1, ..., px`
6779
val lambdaParameters = buildString {
6880
for (i in 0 until argCount) {
6981
if (i != 0) {
@@ -73,12 +85,21 @@ object AwaitGenerationService : IAwaitGenerationService {
7385
}
7486
}
7587

88+
// Build what is inserted into the `resume()` method : `Unit`, `po`, `Pair(p0, P1)`, `Triple(p0, p1, p2)`, `listOf(p0, p1, p2, p3), etc..`
89+
val resumeParameters = when (argCount) {
90+
0 -> "Unit"
91+
1 -> lambdaParameters
92+
2 -> "Pair($lambdaParameters)"
93+
3 -> "Triple($lambdaParameters)"
94+
in 4 .. Int.MAX_VALUE -> "listOf($lambdaParameters)"
95+
else -> ""
96+
}
97+
7698
return this
77-
.addStatement("%M { cont: %T<%T> ->", suspendCancellableCoroutine, cancellableContinuationClass, UNIT)
78-
.addStatement(" %M(%T.ConnectFlags.CONNECT_ONE_SHOT.id.toInt()) { $lambdaParameters ->", connect, GODOT_OBJECT)
79-
.addStatement(" cont.%M(%T)", resume, UNIT)
80-
.addStatement(" }")
81-
.addStatement("}")
82-
.returns(UNIT)
99+
.beginControlFlow("return %M { cont: %T<%T> ->", suspendCancellableCoroutine, cancellableContinuationClass, returnType)
100+
.beginControlFlow("%M(%T.ConnectFlags.CONNECT_ONE_SHOT.id.toInt()) { $lambdaParameters ->", connect, GODOT_OBJECT)
101+
.addStatement("cont.%M($resumeParameters)", resume)
102+
.endControlFlow()
103+
.endControlFlow()
83104
}
84105
}

0 commit comments

Comments
 (0)