Crafter.Debug/examples/Basic/implementations/Basic.DebugCommands.cpp

51 lines
2.8 KiB
C++
Raw Permalink Normal View History

// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
module Basic.DebugCommands;
import std;
import Crafter.Debug;
import Basic.World;
namespace Debug = Crafter::Debug;
namespace Basic {
struct SpawnArgs {
Debug::Required<float> y;
float x = 0;
float vy = 0;
float radius = 0.1f;
};
struct BallArgs {
Debug::Required<std::int32_t> id;
};
}
void Basic::RegisterDebug(World& world) {
// Commands run on the main thread, between ticks, so they touch the
// world as the simulation does.
Debug::Command("World_Spawn", "Drop a ball from height y (m), moving at vy (m/s, up is positive); returns its id.",
[&world](const SpawnArgs& args) -> Debug::Result<std::int32_t> {
if (args.radius <= 0) return Debug::Error{ "BadRadius", "radius must be above 0" };
if (*args.y - args.radius <= world.floor.top) {
return Debug::Error{ "BelowFloor", std::format("y must clear the floor's top ({} m) by the radius", world.floor.top) };
}
return world.Spawn(args.x, *args.y, args.vy, args.radius);
});
Debug::Command("World_Reset", "Remove every ball and drop the scene's five again.", [&world] { world.Reset(); });
Debug::Command("World_Clear", "Remove every ball.", [&world] { world.Clear(); });
Debug::Command("Ball_Get", "One ball's position, velocity and state.", [&world](const BallArgs& args) -> Debug::Result<Ball> {
if (const Ball* ball = world.Find(*args.id)) return *ball;
return Debug::Error{ "NoBall", std::format("no ball {}; `get balls` lists them", *args.id) };
});
Debug::Watch("physics.gravity", world.physics.gravity, { .min = -50, .max = 0, .help = "m/s^2" });
Debug::Watch("physics.restitution", world.physics.restitution, { .min = 0, .max = 1, .help = "share of speed kept by a bounce" });
Debug::Watch("physics.substeps", world.physics.substeps, { .min = 1, .max = 16, .help = "collision checks per tick" });
Debug::Watch("floor.top", world.floor.top, { .help = "m" });
Debug::Watch("floor.thickness", world.floor.thickness, { .min = 0.01, .max = 10, .help = "m" });
Debug::Watch("world.time", [&world] { return world.Time(); }, { .help = "simulated seconds since the last reset" });
Debug::Watch("world.count", [&world] { return world.Balls().size(); }, { .help = "balls in the scene" });
Debug::Watch("world.lost", [&world] { return world.Lost(); }, { .help = "balls below the floor" });
Debug::Watch("world.fastest", [&world] { return world.Fastest(); }, { .help = "m/s, last tick" });
Debug::Watch("balls", [&world] { return std::vector<Ball>(world.Balls().begin(), world.Balls().end()); });
}