169 lines
4.9 KiB
C++
169 lines
4.9 KiB
C++
#include <chrono>
|
|
#include <mutex>
|
|
#include <raylib.h>
|
|
|
|
#include "config.hpp"
|
|
#include "input_handler.hpp"
|
|
#include "mass_spring_system.hpp"
|
|
#include "threaded_physics.hpp"
|
|
#include "renderer.hpp"
|
|
#include "state_manager.hpp"
|
|
#include "user_interface.hpp"
|
|
|
|
#ifdef TRACY
|
|
#include <tracy/Tracy.hpp>
|
|
#endif
|
|
|
|
// TODO: Add state space generation time to debug overlay
|
|
|
|
// TODO: Implement state discovery/enumeration
|
|
// - Find all possible initial board states (single one for each possible statespace).
|
|
// Currently wer're just finding all states given the initial state
|
|
// - Would allow to generate random puzzles with a certain move count
|
|
|
|
// TODO: Move selection accordingly when undoing moves (need to diff two states and get the moved blocks)
|
|
|
|
// TODO: Click states in the graph to display them in the board
|
|
|
|
// For profiling explore_state_space
|
|
auto main2(int argc, char* argv[]) -> int
|
|
{
|
|
// Supercompo
|
|
const puzzle p = puzzle(
|
|
"S:[4x5] G:[1,3] M:[F] B:[{_ 2X2 _ _} {1x1 _ _ 1x1} {1x2 2x1 _ 1x2} {_ 2x1 _ _} {1x1 2x1 _ 1x1}]");
|
|
|
|
for (int i = 0; i < 50; ++i) {
|
|
auto space = p.explore_state_space();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
auto main(int argc, char* argv[]) -> int
|
|
{
|
|
std::string preset_file;
|
|
if (argc != 2) {
|
|
preset_file = "default.puzzle";
|
|
} else {
|
|
preset_file = argv[1];
|
|
}
|
|
|
|
#ifdef BACKWARD
|
|
infoln("Backward stack-traces enabled.");
|
|
#else
|
|
infoln("Backward stack-traces disabled.");
|
|
#endif
|
|
|
|
#ifdef TRACY
|
|
infoln("Tracy adapter enabled.");
|
|
#else
|
|
infoln("Tracy adapter disabled.");
|
|
#endif
|
|
|
|
#ifdef THREADPOOL
|
|
infoln("Thread-pool enabled.");
|
|
#else
|
|
infoln("Thread-pool disabled.");
|
|
#endif
|
|
|
|
// RayLib window setup
|
|
SetTraceLogLevel(LOG_ERROR);
|
|
SetConfigFlags(FLAG_VSYNC_HINT);
|
|
SetConfigFlags(FLAG_MSAA_4X_HINT);
|
|
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
|
SetConfigFlags(FLAG_WINDOW_ALWAYS_RUN);
|
|
InitWindow(INITIAL_WIDTH * 2, INITIAL_HEIGHT + MENU_HEIGHT, "MassSprings");
|
|
|
|
// Game setup
|
|
threaded_physics physics;
|
|
state_manager state(physics, preset_file);
|
|
orbit_camera camera;
|
|
input_handler input(state, camera);
|
|
user_interface gui(input, state, camera);
|
|
renderer renderer(camera, state, input, gui);
|
|
|
|
std::chrono::time_point last = std::chrono::high_resolution_clock::now();
|
|
std::chrono::duration<double> fps_accumulator(0);
|
|
int loop_iterations = 0;
|
|
|
|
int fps = 0;
|
|
int ups = 0; // Read from physics
|
|
Vector3 mass_center; // Read from physics
|
|
std::vector<Vector3> masses; // Read from physics
|
|
size_t mass_count = 0;
|
|
size_t spring_count = 0;
|
|
|
|
// Game loop
|
|
while (!WindowShouldClose()) {
|
|
#ifdef TRACY
|
|
FrameMarkStart("MainThread");
|
|
#endif
|
|
|
|
// Time tracking
|
|
std::chrono::time_point now = std::chrono::high_resolution_clock::now();
|
|
std::chrono::duration<double> delta_time = now - last;
|
|
fps_accumulator += delta_time;
|
|
last = now;
|
|
|
|
// Input update
|
|
input.handle_input();
|
|
|
|
// Read positions from physics thread
|
|
#ifdef TRACY
|
|
FrameMarkStart("MainThreadConsumeLock");
|
|
#endif
|
|
{
|
|
#ifdef TRACY
|
|
std::unique_lock<LockableBase(std::mutex)> lock(physics.state.data_mtx);
|
|
#else
|
|
std::unique_lock<std::mutex> lock(physics.state.data_mtx);
|
|
#endif
|
|
|
|
ups = physics.state.ups;
|
|
mass_center = physics.state.mass_center;
|
|
mass_count = physics.state.mass_count;
|
|
spring_count = physics.state.spring_count;
|
|
|
|
// Only copy data if any has been produced
|
|
if (physics.state.data_ready) {
|
|
masses = physics.state.masses;
|
|
|
|
physics.state.data_ready = false;
|
|
physics.state.data_consumed = true;
|
|
|
|
lock.unlock();
|
|
// Notify the physics thread that data has been consumed
|
|
physics.state.data_consumed_cnd.notify_all();
|
|
}
|
|
}
|
|
#ifdef TRACY
|
|
FrameMarkEnd("MainThreadConsumeLock");
|
|
#endif
|
|
|
|
// Update the camera after the physics, so target lock is smooth
|
|
size_t current_index = state.get_current_index();
|
|
if (masses.size() > current_index) {
|
|
const Vector3& current_mass = masses[current_index];
|
|
camera.update(current_mass, mass_center, input.camera_lock, input.camera_mass_center_lock);
|
|
}
|
|
|
|
// Rendering
|
|
renderer.render(masses, fps, ups, mass_count, spring_count);
|
|
|
|
if (fps_accumulator.count() > 1.0) {
|
|
// Update each second
|
|
fps = loop_iterations;
|
|
loop_iterations = 0;
|
|
fps_accumulator = std::chrono::duration<double>(0);
|
|
}
|
|
++loop_iterations;
|
|
|
|
#ifdef TRACY
|
|
FrameMark; FrameMarkEnd("MainThread");
|
|
#endif
|
|
}
|
|
|
|
CloseWindow();
|
|
|
|
return 0;
|
|
} |