#include "bootstrap.hpp" // Interfaces #include "interfaces/argument_parser.hpp" #include "interfaces/cursor.hpp" #include "interfaces/engine.hpp" #include "interfaces/game.hpp" #include "interfaces/generation_tracker.hpp" #include "interfaces/input.hpp" #include "interfaces/matrix.hpp" #include "interfaces/randomization.hpp" #include "interfaces/scene.hpp" #include "interfaces/status_updater.hpp" #include "interfaces/statusline.hpp" #include "interfaces/window.hpp" // Implementations #include "argument_parser.hpp" #include "engine/data/bounds.hpp" #include "engine/data/vector2.hpp" #include "engine/engine.hpp" #include "engine/graphics/matrix.hpp" #include "engine/graphics/scene.hpp" #include "engine/graphics/window.hpp" #include "engine/user/cursor.hpp" #include "engine/user/input.hpp" #include "game/game.hpp" #include "game/generation_tracker.hpp" #include "game/status_updater.hpp" #include "game/statusline.hpp" #include "randomization/generator.hpp" #include "randomization/seed_generator.hpp" #include "util/function.hpp" #include #include #include #include template concept abstract = std::is_abstract_v; template requires abstract && std::derived_from && std::constructible_from auto construct_as_interface(Params &&...parameters) -> std::shared_ptr { return std::dynamic_pointer_cast(std::make_shared(parameters...)); } auto bootstrap() noexcept -> Container { auto container = Container(); container.bind().to(); container.bind().to(); container.bind().to(); container.bind().to(); container.bind().to(); container.bind().to_factory(normalize_lambda( [&container](const std::shared_ptr &window, const std::shared_ptr &scene, const std::shared_ptr &cursor_controller) { auto statusline = container.get()(cursor_controller, window); auto generation_tracker = container.get()(true); auto status_updater = container.get()(statusline, generation_tracker); return construct_as_interface(window, scene, cursor_controller, statusline, generation_tracker, status_updater); })); container.bind().to_factory( [](const uint32_t &seed) { return construct_as_interface( seed); }); container.bind().to_factory( []() { return construct_as_interface( std::make_shared()); }); container.bind>().to_factory( [](const Bounds &bounds) { return construct_as_interface, Matrix>(bounds); }); container.bind().to_factory(normalize_lambda( [&container](const std::shared_ptr &cursor_controller, const std::shared_ptr &window) { auto matrix_factory = container.get>(); return construct_as_interface(matrix_factory, cursor_controller, window); })); container.bind().to_factory( [](const std::shared_ptr &cursor_controller, const std::shared_ptr &window) { return construct_as_interface(cursor_controller, window); }); container.bind().to_factory( [](const std::shared_ptr &statusline, const std::shared_ptr &generation_tracker) { return construct_as_interface( statusline, generation_tracker); }); container.bind().to_factory( [](bool is_paused) { return construct_as_interface( is_paused); }); return container; }