From d27f1a89266e141a944f88e9080bdeca95c49da3 Mon Sep 17 00:00:00 2001
From: HampusM <hampus@hampusmat.com>
Date: Thu, 3 Mar 2022 20:40:29 +0100
Subject: refactor: add game initializer

---
 src/CMakeLists.txt                  |  1 +
 src/bootstrap.cpp                   |  3 ++
 src/engine/game_initializer.cpp     | 21 ++++++++++
 src/engine/game_initializer.hpp     | 26 ++++++++++++
 src/game/game.cpp                   | 82 ++++++++++++++++---------------------
 src/game/game.hpp                   | 11 ++---
 src/game_of_life.cpp                |  6 +--
 src/interfaces/game.hpp             |  5 ++-
 src/interfaces/game_initializer.hpp |  9 ++++
 9 files changed, 105 insertions(+), 59 deletions(-)
 create mode 100644 src/engine/game_initializer.cpp
 create mode 100644 src/engine/game_initializer.hpp
 create mode 100644 src/interfaces/game_initializer.hpp

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 13d0ce4..3351c07 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -14,6 +14,7 @@ file(GLOB SOURCES
 	conversion.cpp
 	argument_parser.cpp
 	game/game.cpp
+	engine/game_initializer.cpp
 	engine/graphics/vector2.cpp
 	engine/graphics/bounds.cpp
 	engine/graphics/scene.cpp
diff --git a/src/bootstrap.cpp b/src/bootstrap.cpp
index bd2cbbd..abee66e 100644
--- a/src/bootstrap.cpp
+++ b/src/bootstrap.cpp
@@ -4,6 +4,7 @@
 #include "interfaces/argument_parser.hpp"
 #include "interfaces/bounds.hpp"
 #include "interfaces/game.hpp"
+#include "interfaces/game_initializer.hpp"
 #include "interfaces/input.hpp"
 #include "interfaces/matrix.hpp"
 #include "interfaces/randomization.hpp"
@@ -12,6 +13,7 @@
 
 // Implementations
 #include "argument_parser.hpp"
+#include "engine/game_initializer.hpp"
 #include "engine/graphics/bounds.hpp"
 #include "engine/graphics/scene.hpp"
 #include "engine/graphics/string_matrix.hpp"
@@ -35,6 +37,7 @@ Container bootstrap()
 	container.bind<IScene>().to<Scene>();
 	container.bind<IInputHandler>().to<InputHandler>();
 	container.bind<CursorController>().to<CursorController>();
+	container.bind<IGameInitializer>().to<GameInitializer>();
 
 	container.bind<IRandomNumberGeneratorFactory>().to_factory(
 		[](const unsigned int &seed)
diff --git a/src/engine/game_initializer.cpp b/src/engine/game_initializer.cpp
new file mode 100644
index 0000000..9430999
--- /dev/null
+++ b/src/engine/game_initializer.cpp
@@ -0,0 +1,21 @@
+#include "game_initializer.hpp"
+
+#include <utility>
+
+GameInitializer::GameInitializer(std::shared_ptr<IScene> scene,
+								 std::shared_ptr<IInputHandler> input_handler,
+								 std::shared_ptr<IGame> game)
+	: _scene(std::move(scene)),
+	  _input_handler(std::move(input_handler)),
+	  _game(std::move(game))
+{
+}
+
+void GameInitializer::initialize()
+{
+	_scene->enter();
+
+	_input_handler->enter_raw_mode();
+
+	_game->run(*_scene, *_input_handler);
+}
diff --git a/src/engine/game_initializer.hpp b/src/engine/game_initializer.hpp
new file mode 100644
index 0000000..12b42de
--- /dev/null
+++ b/src/engine/game_initializer.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "DI/auto_wirable.hpp"
+#include "interfaces/game.hpp"
+#include "interfaces/game_initializer.hpp"
+#include "interfaces/input.hpp"
+#include "interfaces/scene.hpp"
+
+#include <memory>
+
+class GameInitializer
+	: public IGameInitializer,
+	  public AutoWirable<IGameInitializer, GameInitializer, IScene, IInputHandler, IGame>
+{
+public:
+	GameInitializer(std::shared_ptr<IScene> scene,
+					std::shared_ptr<IInputHandler> input_handler,
+					std::shared_ptr<IGame> game);
+
+	void initialize() override;
+
+private:
+	std::shared_ptr<IScene> _scene;
+	std::shared_ptr<IInputHandler> _input_handler;
+	std::shared_ptr<IGame> _game;
+};
diff --git a/src/game/game.cpp b/src/game/game.cpp
index ee3a2b8..559f9a0 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -2,58 +2,46 @@
 
 #include <utility>
 
-Game::Game(std::shared_ptr<IScene> scene, std::shared_ptr<IInputHandler> input_handler,
-		   std::shared_ptr<CursorController> cursor_controller)
-	: _scene(std::move(scene)),
-	  _input_handler(std::move(input_handler)),
-	  _cursor_controller(std::move(cursor_controller))
+Game::Game(std::shared_ptr<CursorController> cursor_controller)
+	: _cursor_controller(std::move(cursor_controller))
 {
 }
 
-void Game::run()
+void Game::run(IScene &scene, IInputHandler &input_handler)
 {
-	_scene->enter();
-
-	_input_handler->enter_raw_mode();
-
-	auto scene = _scene;
-	auto input_handler = _input_handler;
-
-	_input_handler->attach('q',
-						   [&input_handler, &scene]()
-						   {
-							   input_handler->leave_raw_mode();
-							   scene->leave();
-							   exit(EXIT_SUCCESS);
-						   });
+	input_handler.attach('q',
+						 [&input_handler, &scene]()
+						 {
+							 input_handler.leave_raw_mode();
+							 scene.leave();
+							 exit(EXIT_SUCCESS);
+						 });
 
 	auto cursor_controller = _cursor_controller;
 
-	_input_handler->attach('k',
-						   [&cursor_controller]()
-						   {
-							   cursor_controller->move<Direction::UP>(1U);
-						   });
-
-	_input_handler->attach('j',
-						   [&cursor_controller]()
-						   {
-							   cursor_controller->move<Direction::DOWN>(1U);
-						   });
-
-	_input_handler->attach('h',
-						   [&cursor_controller]()
-						   {
-							   cursor_controller->move<Direction::LEFT>(1U);
-						   });
-
-	_input_handler->attach('l',
-						   [&cursor_controller]()
-						   {
-							   cursor_controller->move<Direction::RIGHT>(1U);
-						   });
-
-	_input_handler->listen();
-
-	_scene->leave();
+	input_handler.attach('k',
+						 [&cursor_controller]()
+						 {
+							 cursor_controller->move<Direction::UP>(1U);
+						 });
+
+	input_handler.attach('j',
+						 [&cursor_controller]()
+						 {
+							 cursor_controller->move<Direction::DOWN>(1U);
+						 });
+
+	input_handler.attach('h',
+						 [&cursor_controller]()
+						 {
+							 cursor_controller->move<Direction::LEFT>(1U);
+						 });
+
+	input_handler.attach('l',
+						 [&cursor_controller]()
+						 {
+							 cursor_controller->move<Direction::RIGHT>(1U);
+						 });
+
+	input_handler.listen();
 }
diff --git a/src/game/game.hpp b/src/game/game.hpp
index dd0d3c8..c52399d 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -9,18 +9,13 @@
 
 #include <memory>
 
-class Game : public IGame,
-			 public AutoWirable<IGame, Game, IScene, IInputHandler, CursorController>
+class Game : public IGame, public AutoWirable<IGame, Game, CursorController>
 {
 public:
-	explicit Game(std::shared_ptr<IScene> scene,
-				  std::shared_ptr<IInputHandler> input_handler,
-				  std::shared_ptr<CursorController> cursor_controller);
+	explicit Game(std::shared_ptr<CursorController> cursor_controller);
 
-	void run() override;
+	void run(IScene &scene, IInputHandler &input_handler) override;
 
 private:
-	std::shared_ptr<IScene> _scene;
-	std::shared_ptr<IInputHandler> _input_handler;
 	std::shared_ptr<CursorController> _cursor_controller;
 };
diff --git a/src/game_of_life.cpp b/src/game_of_life.cpp
index 4d7ec52..98e6b65 100644
--- a/src/game_of_life.cpp
+++ b/src/game_of_life.cpp
@@ -1,6 +1,6 @@
 #include "bootstrap.hpp"
 #include "interfaces/argument_parser.hpp"
-#include "interfaces/game.hpp"
+#include "interfaces/game_initializer.hpp"
 #include "interfaces/randomization.hpp"
 
 #include <getopt.h>
@@ -29,7 +29,7 @@ int main(int argc, char *argv[])
 			random_number_generator_factory(seed_generator_factory()->random_seed());
 	}
 
-	auto game = container.get<IGame>();
+	auto game_initializer = container.get<IGameInitializer>();
 
-	game->run();
+	game_initializer->initialize();
 }
diff --git a/src/interfaces/game.hpp b/src/interfaces/game.hpp
index 114f019..eb13dc3 100644
--- a/src/interfaces/game.hpp
+++ b/src/interfaces/game.hpp
@@ -1,9 +1,12 @@
 #pragma once
 
+#include "interfaces/input.hpp"
+#include "interfaces/scene.hpp"
+
 class IGame
 {
 public:
 	virtual ~IGame() = default;
 
-	virtual void run() = 0;
+	virtual void run(IScene &scene, IInputHandler &input_handler) = 0;
 };
diff --git a/src/interfaces/game_initializer.hpp b/src/interfaces/game_initializer.hpp
new file mode 100644
index 0000000..5dea2e9
--- /dev/null
+++ b/src/interfaces/game_initializer.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "interfaces/game.hpp"
+
+class IGameInitializer
+{
+public:
+	virtual void initialize() = 0;
+};
-- 
cgit v1.2.3-18-g5258