aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bootstrap.cpp51
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;