diff options
author | HampusM <hampus@hampusmat.com> | 2022-03-29 17:14:47 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-06-13 17:56:57 +0200 |
commit | 6bea1363c9b3f01fec5b54fd0f3a3ee91fa16672 (patch) | |
tree | 5b0aa2cd6c36cab3e0c16346c5111b1c29eef22e /src | |
parent | ea8cc60dc4af9b88d13f4a143986a3fad7e1691a (diff) |
refactor: replace repeated code in factories
Diffstat (limited to 'src')
-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; |