#pragma once #include #include #include #include #include #include #include #include #include #include #include "Ball.hpp" #include "BatchRenderer.hpp" #include "DebugOverlay.hpp" #include "InputManager.hpp" #include "PhysicalObject.hpp" #include "ThreadPool.hpp" class Ball; class PhysicalObject; class Game { private: float m_timeScale = 1.f; sf::RenderWindow m_window; sf::Vector2f m_windowSize; std::vector> m_objects; sf::Clock m_clock; InputManager m_inputManager; sf::VertexArray m_debugLines; int m_drawCallCount = 0; DebugOverlay m_debugOverlay; bool m_toggleDebug = true; BatchRenderer m_batchRenderer; ThreadPool m_threadPool; struct CellHash { std::size_t operator()(const std::pair& k) const { return static_cast(k.first) * 73856093 ^ static_cast(k.second) * 19349663; } }; using Cell = std::pair; using Grid = std::unordered_map, CellHash>; void processKeyPressed(const sf::Event::KeyPressed& keyPressed); void processMousePressed(const sf::Event::MouseButtonPressed& mousePressed); void impulseBalls(const sf::Vector2f& mousePos); void spawnBall(const sf::Vector2f& mousePos); void update(); void render(); void updateBallsParallel(float dt); void resolveSpatialCollisionsParallel(const Grid& grid); Grid buildSpatialGrid(); public: Game(); void run(); size_t getThreadCount() const { return m_threadPool.getThreadCount(); } };