Skip to content

Commit

Permalink
Adds a GameBuilder to allow better dependency injection
Browse files Browse the repository at this point in the history
  • Loading branch information
Vassyli committed Jun 23, 2017
1 parent 329430c commit 867843d
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 15 deletions.
7 changes: 6 additions & 1 deletion src/Bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ public function getGame(string $cwd): Game
$pdo = $this->connectToDatabase($dsn, $user, $password);
$entityManager = $this->createEntityManager($pdo);

$this->game = new Game($config, $this->logger, $entityManager, $cwd);
$this->game = (new GameBuilder())
->withConfiguration($config)
->withLogger($this->logger)
->withEntityManager($entityManager)
->withCwd($cwd)
->create();

return $this->game;
}
Expand Down
12 changes: 12 additions & 0 deletions src/Exceptions/BuilderException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);

namespace LotGD\Core\Exceptions;

/**
* Exception if a builder is missing an argument
*/
class BuilderException extends CoreException
{

}
48 changes: 36 additions & 12 deletions src/Game.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,24 +85,36 @@ public function getCWD(): string
*/
public function getModuleManager(): ModuleManager
{
if ($this->moduleManager === null) {
$this->moduleManager = new ModuleManager($this);
}
return $this->moduleManager;
}

/**
* Sets the game's module manager.
* @param ModuleManager $moduleManager
*/
public function setModuleManager(ModuleManager $moduleManager): void
{
$this->moduleManager = $moduleManager;
}

/**
* Returns the game's composer manager.
* @return ComposerManager The game's composer manager.
*/
public function getComposerManager(): ComposerManager
{
if ($this->composerManager === null) {
$this->composerManager = new ComposerManager($this->cwd);
}
return $this->composerManager;
}

/**
* Sets the game's composer manager.
* @param ComposerManager $composerManager
*/
public function setComposerManager(ComposerManager $composerManager): void
{
$this->composerManager = $composerManager;
}

/**
* Returns the game's entity manager.
* @return EntityManagerInterface The game's database entity manager.
Expand All @@ -118,24 +130,36 @@ public function getEntityManager(): EntityManagerInterface
*/
public function getEventManager(): EventManager
{
if ($this->eventManager === null) {
$this->eventManager = new EventManager($this);
}
return $this->eventManager;
}

/**
* Sets the game's event manager.
* @param EventManager $eventManager
*/
public function setEventManager(EventManager $eventManager): void
{
$this->eventManager = $eventManager;
}

/**
* Returns the game's dice bag.
* @return DiceBag
*/
public function getDiceBag(): DiceBag
{
if ($this->diceBag === null) {
$this->diceBag = new DiceBag();
}
return $this->diceBag;
}

/**
* Sets the game's dice bag.
* @param DiceBag $diceBag
*/
public function setDiceBag(DiceBag $diceBag): void
{
$this->diceBag = $diceBag;
}

/**
* Returns the logger instance to write logs.
* @return Logger
Expand Down
156 changes: 156 additions & 0 deletions src/GameBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php
declare(strict_types=1);

namespace LotGD\Core;


use Doctrine\ORM\EntityManagerInterface;
use Monolog\Logger;

use LotGD\Core\Exceptions\BuilderException;

/**
* The GameBuilder class is used to build a Game object with all dependencies that are needed.
*
* You must provide $cwd, $configuration, $entityManager and a logger instance using the with* methods.
* You can provide additional class *names* for additional dependency injections using the use* methods.
* @package LotGD\Core
*/
class GameBuilder
{
private $cwd;
private $configuration;
private $entityManager;
private $logger;

private $moduleManagerClass;
private $composerManagerClass;
private $eventManagerClass;
private $diceBagClass;

/**
* Creates the game instance with the prepared parameters.
* @return Game
* @throws BuilderException if at least one of cwd, configuration, entityManager or logger as not been set.
*/
public function create(): Game
{
if (isset($this->cwd, $this->configuration, $this->entityManager, $this->logger) === false) {
throw new BuilderException(
"For creating a game, you must set at least: cwd, configuration, entityManager and logger."
);
}

// construct the game
$game = new Game(
$this->configuration,
$this->logger,
$this->entityManager,
$this->cwd
);

// add additional managers to it
$moduleManager = $this->moduleManagerClass ?? ModuleManager::class;
$game->setModuleManager(new $moduleManager($game));

$composerManager = $this->composerManagerClass ?? ComposerManager::class;
$game->setComposerManager(new $composerManager($this->cwd));

$eventManager = $this->eventManagerClass ?? EventManager::class;
$game->setEventManager(new $eventManager($game));

$diceBag = $this->diceBagClass ?? DiceBag::class;
$game->setDiceBag(new $diceBag());


return $game;
}

/**
* Adds current working directory argument
* @param string $cwd
* @return self
*/
public function withCwd(string $cwd): self
{
$this->cwd = $cwd;
return $this;
}

/**
* Configuration
* @param Configuration $conf
* @return self
*/
public function withConfiguration(Configuration $conf): self
{
$this->configuration = $conf;
return $this;
}

/**
* Sets the logger for the game instance.
* @param EntityManagerInterface $em
* @return self
*/
public function withEntityManager(EntityManagerInterface $em): self
{
$this->entityManager = $em;
return $this;
}

/**
* Sets the logger for the game instance.
* @param Logger $logger
* @return self
*/
public function withLogger(Logger $logger): self
{
$this->logger = $logger;
return $this;
}

/**
* Sets the fqcn for the module manager to be used.
* @param string $moduleManagerFqcn
* @return self
*/
public function useModuleManager(string $moduleManagerFqcn): self
{
$this->moduleManagerClass = $moduleManagerFqcn;
return $this;
}

/**
* Sets the fqcn for the composer manager to be used.
* @param string $composerManagerFqcn
* @return self
*/
public function useComposerManager(string $composerManagerFqcn): self
{
$this->composerManagerClass = $composerManagerFqcn;
return $this;
}

/**
* Sets the fqcn for the event manager to be used.
* @param string $eventManagerFqcn
* @return GameBuilder
*/
public function useEventManager(string $eventManagerFqcn): self
{
$this->eventManagerClass = $eventManagerFqcn;
return $this;
}

/**
* Sets the fqcn for the dice bag to be used.
* @param string $diceBagFqcn
* @return GameBuilder
*/
public function useDiceBag(string $diceBagFqcn): self
{
$this->diceBagClass = $diceBagFqcn;
return $this;
}
}
9 changes: 7 additions & 2 deletions tests/GameTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Monolog\Handler\NullHandler;

use LotGD\Core\{
Action, ActionGroup, Bootstrap, Configuration, ComposerManager, DiceBag, EventHandler, EventManager, Events\NewViewpointData, Game, TimeKeeper, ModuleManager
Action, ActionGroup, Bootstrap, Configuration, ComposerManager, DiceBag, EventHandler, EventManager, Events\NewViewpointData, Game, GameBuilder, TimeKeeper, ModuleManager
};
use LotGD\Core\Models\{
Character, Viewpoint, Scene
Expand Down Expand Up @@ -85,7 +85,12 @@ public function setUp()
$logger = new Logger('test');
$logger->pushHandler(new NullHandler());

$this->g = new Game(new Configuration(getenv('LOTGD_TESTS_CONFIG_PATH')), $logger, $this->getEntityManager(), implode(DIRECTORY_SEPARATOR, [__DIR__, '..']));
$this->g = (new GameBuilder())
->withConfiguration(new Configuration(getenv('LOTGD_TESTS_CONFIG_PATH')))
->withLogger($logger)
->withEntityManager($this->getEntityManager())
->withCwd(implode(DIRECTORY_SEPARATOR, [__DIR__, '..']))
->create();
}

public function testBasicInjection()
Expand Down

0 comments on commit 867843d

Please sign in to comment.