1
+ /*
2
+ * FXGL - JavaFX Game Library. The MIT License (MIT).
3
+ * Copyright (c) AlmasB ([email protected] ).
4
+ * See LICENSE for details.
5
+ */
6
+ @file:Suppress(" JAVA_MODULE_DOES_NOT_DEPEND_ON_MODULE" )
7
+ package com.almasb.fxgl.core
8
+
9
+ import org.hamcrest.MatcherAssert.assertThat
10
+ import org.hamcrest.Matchers
11
+ import org.hamcrest.Matchers.`is`
12
+ import org.hamcrest.Matchers.greaterThan
13
+ import org.hamcrest.Matchers.lessThan
14
+ import org.hamcrest.Matchers.both
15
+ import org.junit.jupiter.api.Assertions.assertEquals
16
+ import org.junit.jupiter.api.Test
17
+ import kotlin.system.measureTimeMillis
18
+
19
+ /* *
20
+ *
21
+ * @author Jean-Rene Lavoie ([email protected] )
22
+ */
23
+ class AsyncServiceTest {
24
+
25
+ @Test
26
+ fun `Async Service with Unit (Kotlin Void)` () {
27
+ val service = object : AsyncService <Unit >() {
28
+ override fun onGameUpdateAsync (tpf : Double ) {
29
+ Thread .sleep(100 ) // Processing takes more time than a normal tick
30
+ }
31
+ }
32
+
33
+ // On first call, it'll launch the async process and continue the game loop without affecting the tick
34
+ // If it takes less than 5 millis, it's running async
35
+ assertThat(measureTimeMillis { service.onGameUpdate(1.0 ) }.toDouble(), lessThan(7.0 ))
36
+
37
+ // On the second call, it must wait until the first call is resolved before calling it again (to prevent major desync)
38
+ // We expect it to take more than 80 millis
39
+ assertThat(measureTimeMillis { service.onGameUpdate(1.0 ) }.toDouble(), greaterThan(80.0 ))
40
+ }
41
+
42
+ @Test
43
+ fun `Async Service with T (String)` () {
44
+ var postUpdateValue = " "
45
+ val service = object : AsyncService <String >() {
46
+ override fun onGameUpdateAsync (tpf : Double ): String {
47
+ return " Done"
48
+ }
49
+
50
+ override fun onPostGameUpdateAsync (result : String ) {
51
+ postUpdateValue = result
52
+ }
53
+ }
54
+
55
+ // On first call, we don't have the postUpdateValue yet
56
+ service.onGameUpdate(1.0 )
57
+ assertEquals(postUpdateValue, " " )
58
+
59
+ // On second update, we updated the postUpdateValue
60
+ service.onGameUpdate(1.0 )
61
+ assertEquals(postUpdateValue, " Done" )
62
+ }
63
+
64
+ @Test
65
+ fun `Async Service parallel` () {
66
+ val services = listOf (
67
+ object : AsyncService <Unit >() {
68
+ override fun onGameUpdateAsync (tpf : Double ) {
69
+ Thread .sleep(100 ) // Processing takes more time than a normal tick
70
+ }
71
+ },
72
+ object : AsyncService <Unit >() {
73
+ override fun onGameUpdateAsync (tpf : Double ) {
74
+ Thread .sleep(100 ) // Processing takes more time than a normal tick
75
+ }
76
+ },
77
+ object : AsyncService <Unit >() {
78
+ override fun onGameUpdateAsync (tpf : Double ) {
79
+ Thread .sleep(100 ) // Processing takes more time than a normal tick
80
+ }
81
+ }
82
+ )
83
+
84
+ // 3 services started in parallel without additional latency
85
+ assertThat(measureTimeMillis {
86
+ services.forEach { service ->
87
+ service.onGameUpdate(1.0 )
88
+ }
89
+ }.toDouble(), lessThan(7.0 ))
90
+
91
+ // 3 services resolved in approximately 1/3 of what it would take if they were sequentially resolved
92
+ assertThat(measureTimeMillis {
93
+ services.forEach { service ->
94
+ service.onGameUpdate(1.0 )
95
+ }
96
+ }.toDouble(), `is `(both(greaterThan(80.0 )).and (lessThan(120.0 ))))
97
+ }
98
+
99
+ }
0 commit comments