1+ /*
2+ * FXGL - JavaFX Game Library. The MIT License (MIT).
3+ * Copyright (c) AlmasB (almaslvl@gmail.com).
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 (jeanrlavoie@gmail.com)
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