Add forced simulation command
This commit is contained in:
@@ -55,9 +55,14 @@ public final class LivingWorldCommandRoot {
|
||||
.executes(context -> listModules(
|
||||
context.getSource(), moduleRegistry))))
|
||||
.then(Commands.literal("simulate")
|
||||
.then(Commands.argument("ticks", IntegerArgumentType.integer(1, 1000))
|
||||
.executes(context -> placeholder(
|
||||
context.getSource(), "Forced simulation is not connected yet.")))));
|
||||
.then(Commands.argument(
|
||||
"ticks",
|
||||
IntegerArgumentType.integer(
|
||||
1, SimulationManager.MAX_FORCED_SIMULATION_TICKS))
|
||||
.executes(context -> SimulateCommand.execute(
|
||||
context.getSource(),
|
||||
simulationManager,
|
||||
IntegerArgumentType.getInteger(context, "ticks"))))));
|
||||
}
|
||||
|
||||
private static int showStatus(
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.livingworld.commands;
|
||||
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import com.livingworld.core.simulation.SimulationManager;
|
||||
|
||||
/**
|
||||
* Runs a bounded number of forced Living World simulation cycles.
|
||||
*/
|
||||
public final class SimulateCommand {
|
||||
|
||||
private SimulateCommand() {
|
||||
}
|
||||
|
||||
public static int execute(
|
||||
CommandSourceStack source,
|
||||
SimulationManager simulationManager,
|
||||
int ticks) {
|
||||
if (source == null) {
|
||||
throw new IllegalArgumentException("source must not be null");
|
||||
}
|
||||
if (simulationManager == null) {
|
||||
throw new IllegalArgumentException("simulationManager must not be null");
|
||||
}
|
||||
|
||||
if (ticks <= 0 || ticks > SimulationManager.MAX_FORCED_SIMULATION_TICKS) {
|
||||
source.sendFailure(Component.literal(
|
||||
"Ticks must be between 1 and "
|
||||
+ SimulationManager.MAX_FORCED_SIMULATION_TICKS + "."));
|
||||
return 0;
|
||||
}
|
||||
|
||||
try {
|
||||
simulationManager.runForcedSimulationTicks(ticks);
|
||||
source.sendSuccess(
|
||||
() -> Component.literal(
|
||||
"Ran " + ticks + " Living World simulation ticks."),
|
||||
true);
|
||||
return ticks;
|
||||
} catch (RuntimeException exception) {
|
||||
source.sendFailure(Component.literal(
|
||||
"Simulation failed: " + exception.getMessage()));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import com.livingworld.regions.Region;
|
||||
*/
|
||||
public final class SimulationManager {
|
||||
|
||||
public static final int MAX_FORCED_SIMULATION_TICKS = 1000;
|
||||
|
||||
private final SimulationScheduler scheduler;
|
||||
private final RegionManager regionManager;
|
||||
private final ModuleRegistry moduleRegistry;
|
||||
@@ -152,9 +154,12 @@ public final class SimulationManager {
|
||||
* Runs forced simulation ticks for debugging or testing.
|
||||
*/
|
||||
public void runForcedSimulationTicks(int ticks) {
|
||||
if (ticks <= 0 || ticks > 100) {
|
||||
if (ticks <= 0 || ticks > MAX_FORCED_SIMULATION_TICKS) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("forced ticks must be in range [1, 100], got: %d", ticks));
|
||||
String.format(
|
||||
"forced ticks must be in range [1, %d], got: %d",
|
||||
MAX_FORCED_SIMULATION_TICKS,
|
||||
ticks));
|
||||
}
|
||||
|
||||
for (int i = 0; i < ticks; i++) {
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.livingworld.core.simulation;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -86,6 +88,22 @@ class SimulationManagerTest {
|
||||
assertEquals(0, fixture.scheduler.getMinecraftTickCounter());
|
||||
}
|
||||
|
||||
@Test
|
||||
void forcedTicksAcceptSafeMaximumAndRejectValuesOutsideRange() {
|
||||
Fixture fixture = new Fixture(25);
|
||||
|
||||
assertDoesNotThrow(() -> fixture.manager.runForcedSimulationTicks(
|
||||
SimulationManager.MAX_FORCED_SIMULATION_TICKS));
|
||||
assertEquals(
|
||||
SimulationManager.MAX_FORCED_SIMULATION_TICKS,
|
||||
fixture.timeService.getSimulationTick());
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> fixture.manager.runForcedSimulationTicks(0));
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> fixture.manager.runForcedSimulationTicks(
|
||||
SimulationManager.MAX_FORCED_SIMULATION_TICKS + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void timeBudgetRequeuesJobsNotYetProcessed() {
|
||||
Fixture fixture = new Fixture(1);
|
||||
|
||||
Reference in New Issue
Block a user