From f25bab7af8787f5e54423a739750b854359d3473 Mon Sep 17 00:00:00 2001 From: Vassyli Date: Mon, 25 Jan 2021 19:36:23 +0100 Subject: [PATCH] Adds commands to add and remove scene connection groups. --- .../Scene/SceneAddConnectionGroupCommand.php | 83 +++++++++++++++++ .../SceneRemoveConnectionGroupCommand.php | 89 +++++++++++++++++++ src/Console/Main.php | 6 ++ src/Models/Scene.php | 4 + src/Models/SceneConnection.php | 18 ++-- src/Models/SceneConnectionGroup.php | 16 ++-- 6 files changed, 204 insertions(+), 12 deletions(-) create mode 100644 src/Console/Command/Scene/SceneAddConnectionGroupCommand.php create mode 100644 src/Console/Command/Scene/SceneRemoveConnectionGroupCommand.php diff --git a/src/Console/Command/Scene/SceneAddConnectionGroupCommand.php b/src/Console/Command/Scene/SceneAddConnectionGroupCommand.php new file mode 100644 index 0000000..e33df2c --- /dev/null +++ b/src/Console/Command/Scene/SceneAddConnectionGroupCommand.php @@ -0,0 +1,83 @@ +setName('scene:addConnectionGroup') + ->setDescription('Add a connection group to an existing scene.') + ->setDefinition( + new InputDefinition([ + new InputArgument("id", InputArgument::REQUIRED, "ID of the scene"), + new InputArgument("groupName", InputArgument::REQUIRED, "Internal id of the group."), + new InputArgument("groupTitle", InputArgument::REQUIRED, "Title of the group (what the character can see"), + ]), + ) + ; + } + + /** + * @inheritDoc + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $em = $this->game->getEntityManager(); + + $io = new SymfonyStyle($input, $output); + + $sceneId = $input->getArgument("id"); + $groupName = $input->getArgument("groupName"); + $groupTitle = $input->getArgument("groupTitle"); + + // Search scene + /** @var ?Scene $scene */ + $scene = $em->getRepository(Scene::class)->find($sceneId); + + if (!$scene) { + $io->error("The requested scene with the ID {$sceneId} was not found"); + return Command::FAILURE; + } + + // Make scene connection group + $connectionGroup = new SceneConnectionGroup($groupName, $groupTitle); + + // Add + try { + $scene->addConnectionGroup($connectionGroup); + } catch(ArgumentException $e) { + $io->error($e->getMessage()); + return Command::FAILURE; + } + + $em->flush(); + + $io->success("Group successfully added"); + + return Command::SUCCESS; + } +} diff --git a/src/Console/Command/Scene/SceneRemoveConnectionGroupCommand.php b/src/Console/Command/Scene/SceneRemoveConnectionGroupCommand.php new file mode 100644 index 0000000..062abed --- /dev/null +++ b/src/Console/Command/Scene/SceneRemoveConnectionGroupCommand.php @@ -0,0 +1,89 @@ +setName('scene:removeConnectionGroup') + ->setDescription('Removes a connection group from an existing scene.') + ->setDefinition( + new InputDefinition([ + new InputArgument("id", InputArgument::REQUIRED, "ID of the scene"), + new InputArgument("groupName", InputArgument::REQUIRED, "Internal id of the group."), + ]), + ) + ; + } + + /** + * @inheritDoc + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $em = $this->game->getEntityManager(); + + $io = new SymfonyStyle($input, $output); + + $sceneId = $input->getArgument("id"); + $groupName = $input->getArgument("groupName"); + + // Search scene + /** @var ?Scene $scene */ + $scene = $em->getRepository(Scene::class)->find($sceneId); + + if (!$scene) { + $io->error("The requested scene with the ID {$sceneId} was not found"); + return Command::FAILURE; + } + + if (!$scene->hasConnectionGroup($groupName)) { + $io->error("The scene {$sceneId} oes not have a connection group with the name {$groupName}"); + return Command::FAILURE; + } + + $connectionGroup = $scene->getConnectionGroup($groupName); + + # Mark for removal + $em->remove($connectionGroup); + + # Update outgoing connections if they refer to the deleted connectionGroup + $connections = $scene->getConnections(); + /** @var SceneConnection $connection */ + foreach ($connections as $connection) { + if ($connection->getIncomingScene() === $scene and $connection->getIncomingConnectionGroupName() === $groupName) { + $connection->setIncomingConnectionGroupName(null); + $io->comment("Updated connection to {$connection->getOutgoingScene()->getTitle()}"); + } + + if ($connection->getOutgoingScene() === $scene and $connection->getOutgoingConnectionGroupName() === $groupName) { + $connection->setOutgoingConnectionGroupName(null); + $io->comment("Updated connection to {$connection->getIncomingScene()->getTitle()}"); + } + } + + $em->flush(); + + $io->success("Group successfully added"); + + return Command::SUCCESS; + } +} diff --git a/src/Console/Main.php b/src/Console/Main.php index 894d274..7b4df49 100644 --- a/src/Console/Main.php +++ b/src/Console/Main.php @@ -13,9 +13,12 @@ use LotGD\Core\Console\Command\Database\DatabaseSchemaUpdateCommand; use LotGD\Core\Console\Command\Module\ModuleRegisterCommand; use LotGD\Core\Console\Command\Module\ModuleValidateCommand; use LotGD\Core\Console\Command\Scene\SceneAddCommand; +use LotGD\Core\Console\Command\Scene\SceneAddConnectionGroupCommand; use LotGD\Core\Console\Command\Scene\SceneConnectCommand; use LotGD\Core\Console\Command\Scene\SceneListCommand; use LotGD\Core\Console\Command\Scene\SceneDisconnectCommand; +use LotGD\Core\Console\Command\Scene\SceneRemoveConnectionGroupCommand; +use LotGD\Core\Console\Command\Scene\SceneShowCommand; use LotGD\Core\Console\Command\SceneTemplates\SceneTemplateListCommand; use LotGD\Core\Game; use Symfony\Component\Console\Application; @@ -56,6 +59,9 @@ class Main $this->application->add(new SceneAddCommand($this->game)); $this->application->add(new SceneConnectCommand($this->game)); $this->application->add(new SceneDisconnectCommand($this->game)); + $this->application->add(new SceneShowCommand($this->game)); + $this->application->add(new SceneAddConnectionGroupCommand($this->game)); + $this->application->add(new SceneRemoveConnectionGroupCommand($this->game)); $this->application->add(new SceneTemplateListCommand($this->game)); // Add additional ones diff --git a/src/Models/Scene.php b/src/Models/Scene.php index b5ff9f5..2ff8ff6 100644 --- a/src/Models/Scene.php +++ b/src/Models/Scene.php @@ -152,6 +152,10 @@ class Scene implements CreateableInterface, SceneConnectable throw new ArgumentException("The given connection group is already owned by another scene entity."); } + if ($this->hasConnectionGroup($group->getName())) { + throw new ArgumentException("Cannot add a second group with the same name to this scene."); + } + $group->setScene($this); $this->connectionGroups->add($group); } diff --git a/src/Models/SceneConnection.php b/src/Models/SceneConnection.php index 9b74252..482f331 100644 --- a/src/Models/SceneConnection.php +++ b/src/Models/SceneConnection.php @@ -3,7 +3,11 @@ declare(strict_types=1); namespace LotGD\Core\Models; +use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\JoinColumn; +use Doctrine\ORM\Mapping\ManyToOne; use Doctrine\ORM\Mapping\Table; /** @@ -18,34 +22,34 @@ class SceneConnection * @ManyToOne(targetEntity="Scene", inversedBy="outgoingConnections") * @JoinColumn(name="outgoingScene", referencedColumnName="id") */ - private $outgoingScene; + private ?Scene $outgoingScene = null; /** * @Id * @ManyToOne(targetEntity="Scene", inversedBy="incomingConnections") * @JoinColumn(name="incomingScene", referencedColumnName="id") */ - private $incomingScene; + private ?Scene $incomingScene = null; /** * @Column(type="integer", options={"default"=0}) */ - private $directionality = 0; + private int $directionality = 0; /** * @Column(type="string", nullable=True) */ - private $outgoingConnectionGroupName; + private ?string $outgoingConnectionGroupName; /** * @Column(type="string", nullable=True) */ - private $incomingConnectionGroupName; + private ?string $incomingConnectionGroupName; /** * - * @param \LotGD\Core\Models\Scene $outgoing - * @param \LotGD\Core\Models\Scene $incoming + * @param Scene $outgoing + * @param Scene $incoming * @param int $directionality */ public function __construct( diff --git a/src/Models/SceneConnectionGroup.php b/src/Models/SceneConnectionGroup.php index a92d01e..d014112 100644 --- a/src/Models/SceneConnectionGroup.php +++ b/src/Models/SceneConnectionGroup.php @@ -3,8 +3,13 @@ declare(strict_types=1); namespace LotGD\Core\Models; +use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\JoinColumn; +use Doctrine\ORM\Mapping\ManyToOne; use Doctrine\ORM\Mapping\Table; +use LotGD\Core\Exceptions\ArgumentException; /** * @@ -18,18 +23,18 @@ class SceneConnectionGroup implements SceneConnectable * @ManyToOne(targetEntity="Scene", inversedBy="outgoingConnections", cascade={"persist"}) * @JoinColumn(name="scene", referencedColumnName="id") */ - private $scene; + private ?Scene $scene = null; /** * @Id * @Column(type="string") */ - private $name; + private string $name; /** * @Column(type="string", length=255) */ - private $title; + private string $title; /** * SceneConnectionGroup constructor. @@ -44,7 +49,7 @@ class SceneConnectionGroup implements SceneConnectable /** * Returns the scene associated with this connection group. - * @return \LotGD\Core\Models\Scene + * @return Scene */ public function getScene(): ?Scene { @@ -53,7 +58,7 @@ class SceneConnectionGroup implements SceneConnectable /** * Sets the scene associated with this connection group. - * @param \LotGD\Core\Models\Scene $scene + * @param Scene $scene */ public function setScene(Scene $scene): void { @@ -100,6 +105,7 @@ class SceneConnectionGroup implements SceneConnectable * @param SceneConnectable $connectable * @param int|null $directionality * @return SceneConnection + * @throws ArgumentException */ public function connect(SceneConnectable $connectable, int $directionality = null): SceneConnection {