summaryrefslogtreecommitdiff
path: root/opendc-simulator/opendc-simulator-core/src
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-simulator/opendc-simulator-core/src')
-rw-r--r--opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/kotlin/SimulationBuilders.kt38
1 files changed, 30 insertions, 8 deletions
diff --git a/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/kotlin/SimulationBuilders.kt b/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/kotlin/SimulationBuilders.kt
index a291b4e2..c4cc0171 100644
--- a/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/kotlin/SimulationBuilders.kt
+++ b/opendc-simulator/opendc-simulator-core/src/main/kotlin/org/opendc/simulator/kotlin/SimulationBuilders.kt
@@ -29,10 +29,32 @@ import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/**
- * Executes a [body] inside an immediate execution dispatcher.
+ * Executes [body] as a simulation in a new coroutine.
+ *
+ * This function behaves similarly to [runBlocking], with the difference that the code that it runs will skip delays.
+ * This allows to use [delay] in without causing the simulation to take more time than necessary.
+ *
+ * ```
+ * @Test
+ * fun exampleSimulation() = runSimulation {
+ * val deferred = async {
+ * delay(1_000)
+ * async {
+ * delay(1_000)
+ * }.await()
+ * }
+ *
+ * deferred.await() // result available immediately
+ * }
+ * ```
+ *
+ * The simulation is run in a single thread, unless other [CoroutineDispatcher] are used for child coroutines.
+ * Because of this, child coroutines are not executed in parallel to [body].
+ * In order for the spawned-off asynchronous code to actually be executed, one must either [yield] or suspend the
+ * body some other way, or use commands that control scheduling (see [SimulationScheduler]).
*/
@OptIn(ExperimentalCoroutinesApi::class)
-public fun runBlockingSimulation(
+public fun runSimulation(
context: CoroutineContext = EmptyCoroutineContext,
scheduler: SimulationScheduler = SimulationScheduler(),
body: suspend SimulationCoroutineScope.() -> Unit
@@ -54,16 +76,16 @@ public fun runBlockingSimulation(
}
/**
- * Convenience method for calling [runBlockingSimulation] on an existing [SimulationCoroutineScope].
+ * Convenience method for calling [runSimulation] on an existing [SimulationCoroutineScope].
*/
-public fun SimulationCoroutineScope.runBlockingSimulation(block: suspend SimulationCoroutineScope.() -> Unit): Unit =
- runBlockingSimulation(coroutineContext, scheduler, block)
+public fun SimulationCoroutineScope.runSimulation(block: suspend SimulationCoroutineScope.() -> Unit): Unit =
+ runSimulation(coroutineContext, scheduler, block)
/**
- * Convenience method for calling [runBlockingSimulation] on an existing [SimulationCoroutineDispatcher].
+ * Convenience method for calling [runSimulation] on an existing [SimulationCoroutineDispatcher].
*/
-public fun SimulationCoroutineDispatcher.runBlockingSimulation(block: suspend SimulationCoroutineScope.() -> Unit): Unit =
- runBlockingSimulation(this, scheduler, block)
+public fun SimulationCoroutineDispatcher.runSimulation(block: suspend SimulationCoroutineScope.() -> Unit): Unit =
+ runSimulation(this, scheduler, block)
private fun CoroutineContext.checkArguments(scheduler: SimulationScheduler): Pair<CoroutineContext, SimulationController> {
val dispatcher = get(ContinuationInterceptor).run {