diff options
Diffstat (limited to 'src/bootstrap.cpp')
-rw-r--r-- | src/bootstrap.cpp | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/src/bootstrap.cpp b/src/bootstrap.cpp index e8315bd..49808d6 100644 --- a/src/bootstrap.cpp +++ b/src/bootstrap.cpp @@ -33,10 +33,22 @@ #include "util/function.hpp" +#include <concepts> #include <memory> #include <random> #include <string_view> +template <typename Type> +concept abstract = std::is_abstract_v<Type>; + +template <typename Interface, typename Impl, typename... Params> +requires abstract<Interface> && std::derived_from<Impl, Interface> && + std::constructible_from<Impl, Params...> +auto construct_as_interface(Params &&...parameters) -> std::shared_ptr<Interface> +{ + return std::dynamic_pointer_cast<Interface>(std::make_shared<Impl>(parameters...)); +} + Container bootstrap() noexcept { auto container = Container(); @@ -60,62 +72,63 @@ Container bootstrap() noexcept auto status_updater = container.get<IStatusUpdaterFactory>()(statusline, generation_tracker); - return std::dynamic_pointer_cast<IGame>( - std::make_shared<Game>(window, scene, cursor_controller, statusline, - generation_tracker, status_updater)); + return construct_as_interface<IGame, Game>(window, scene, cursor_controller, + statusline, generation_tracker, + status_updater); })); container.bind<IRandomNumberGeneratorFactory>().to_factory( [](const uint32_t &seed) { - return std::dynamic_pointer_cast<IRandomNumberGenerator>( - std::make_shared<RandomNumberGenerator>(seed)); + return construct_as_interface<IRandomNumberGenerator, RandomNumberGenerator>( + seed); }); container.bind<ISeedGeneratorFactory>().to_factory( []() { - return std::dynamic_pointer_cast<ISeedGenerator>( - std::make_shared<SeedGenerator>(std::make_unique<std::random_device>())); + return construct_as_interface<ISeedGenerator, SeedGenerator>( + std::make_shared<std::random_device>()); }); container.bind<IMatrixFactory<std::string_view>>().to_factory( [](const Bounds &bounds) { - return std::dynamic_pointer_cast<IMatrix<std::string_view>>( - std::make_shared<Matrix<std::string_view>>(bounds)); + return construct_as_interface<IMatrix<std::string_view>, + Matrix<std::string_view>>(bounds); }); container.bind<ISceneFactory>().to_factory(normalize_lambda( [&container](const std::shared_ptr<ICursorController> &cursor_controller, const std::shared_ptr<IWindow> &window) { - return std::dynamic_pointer_cast<IScene>( - std::make_shared<Scene>(container.get<IMatrixFactory<std::string_view>>(), - cursor_controller, window)); + auto matrix_factory = container.get<IMatrixFactory<std::string_view>>(); + + return construct_as_interface<IScene, Scene>(matrix_factory, + cursor_controller, window); })); container.bind<IStatusLineFactory>().to_factory( [](const std::shared_ptr<ICursorController> &cursor_controller, const std::shared_ptr<IWindow> &window) { - return std::dynamic_pointer_cast<IStatusLine>( - std::make_shared<StatusLine>(cursor_controller, window)); + return construct_as_interface<IStatusLine, StatusLine>(cursor_controller, + window); }); container.bind<IStatusUpdaterFactory>().to_factory( - [](const std::shared_ptr<IStatusLine> &status_line, + [](const std::shared_ptr<IStatusLine> &statusline, const std::shared_ptr<IGenerationTracker> &generation_tracker) { - return std::dynamic_pointer_cast<IStatusUpdater>( - std::make_shared<StatusUpdater>(status_line, generation_tracker)); + return construct_as_interface<IStatusUpdater, StatusUpdater>( + statusline, generation_tracker); }); container.bind<IGenerationTrackerFactory>().to_factory( [](bool is_paused) { - return std::dynamic_pointer_cast<IGenerationTracker>( - std::make_shared<GenerationTracker>(is_paused)); + return construct_as_interface<IGenerationTracker, GenerationTracker>( + is_paused); }); return container; |