Implemented suggested changes.

Fixes #94
This commit is contained in:
Vassyli
2017-04-10 09:42:09 +02:00
parent a790eab5ee
commit 201a3a032f
8 changed files with 146 additions and 160 deletions
+7 -6
View File
@@ -11,7 +11,7 @@ use LotGD\Core\EventHandler;
use LotGD\Core\Exceptions\ClassNotFoundException;
use LotGD\Core\Exceptions\SubscriptionNotFoundException;
use LotGD\Core\Exceptions\WrongTypeException;
use LotGD\Core\Events\EventContextDataContainer;
use LotGD\Core\Events\EventContextData;
/**
* Manages a simple publish/subscribe system based on regular expressions
@@ -35,9 +35,10 @@ class EventManager
* are run.
*
* @param string $event The name of the event to publish.
* @param EventContextDataContainer $contextData The Data context
* @param EventContextData $contextData The Data context
* @return EventContextData The changed data.
*/
public function publish(string $event, EventContextDataContainer $contextData): EventContextDataContainer
public function publish(string $event, EventContextData $contextData): EventContextData
{
// For right now, implement the naive approach of iterating every entry
// in the subscription database, checking the regular expression. We
@@ -56,9 +57,9 @@ class EventManager
$eventContext = new EventContext($event, $s->getPattern(), $contextData);
$returnedEventContext = $class::handleEvent($this->g, $eventContext);
if ($returnedEventContext->hasDataChanged($contextData)) {
$contextData = $returnedEventContext->getData();
}
// Overwrite contextData - contextData might be the same if nothing has changed,
// or might reference a completely new object the event handler changed a value.
$contextData = $returnedEventContext->getData();
}
}
+6 -7
View File
@@ -2,7 +2,6 @@
declare(strict_types=1);
namespace LotGD\Core\Events;
use LotGD\Core\Exceptions\ArgumentException;
/**
@@ -20,12 +19,12 @@ class EventContext
* EventContext constructor.
* @param string $event The published event
* @param string $matchingPattern The matching pattern
* @param EventContextDataContainer $data
* @param EventContextData $data
*/
public function __construct(
string $event,
string $matchingPattern,
EventContextDataContainer $data
EventContextData $data
) {
$this->event = $event;
$this->matchingPattern = $matchingPattern;
@@ -62,9 +61,9 @@ class EventContext
/**
* Returns the immutable data container.
* @return EventContextDataContainer
* @return EventContextData
*/
public function getData(): EventContextDataContainer
public function getData(): EventContextData
{
return $this->data;
}
@@ -100,10 +99,10 @@ class EventContext
/**
* Checks if given original data is the same as currently held within this context.
* @param EventContextDataContainer $originalData
* @param EventContextData $originalData
* @return bool
*/
public function hasDataChanged(EventContextDataContainer $originalData): bool
public function hasDataChanged(EventContextData $originalData): bool
{
return $this->data === $originalData ? false : true;
}
+124 -2
View File
@@ -3,12 +3,134 @@ declare(strict_types=1);
namespace LotGD\Core\Events;
use LotGD\Core\Exceptions\ArgumentException;
/**
* Data container for default, unspecific data without any sanitizing on the given fields.
* EventContextDataContainer to provide a basic structure for managing contextual data of an event.
*
* This class must be immutable and returns always a new instance of itself for any change.
* @package LotGD\Core\Events
* @immutable
*/
class EventContextData extends EventContextDataContainer
class EventContextData
{
private $data;
/**
* Creates a new instance of a data container.
*
* Sub types can change this method to force certain parameters.
* @param array $data
* @return EventContextData
*/
public static function create(array $data): self
{
return new static($data);
}
/**
* protected constructor..
* @see self::create
* @param array $data
*/
protected function __construct(array $data)
{
$this->data = $data;
}
/**
* Returns true if container has a certain field.
* @param string $field
* @return bool
*/
public function has(string $field): bool
{
return array_key_exists($field, $this->data);
}
/**
* Returns the value of a field.
* @param string $field
* @return mixed
*/
public function get(string $field)
{
if ($this->has($field)) {
return $this->data[$field];
} else {
$this->throwException($field);
}
}
/**
* Sets a field to a new value and returns a new data container
* @param string $field
* @param $value
* @return EventContextData
*/
public function set(string $field, $value): self
{
if ($this->has($field)) {
$data = $this->data;
$data[$field] = $value;
return new static($data);
} else {
$this->throwException($field);
}
}
/**
* Sets multiple fields at once
* @param array $data array of $field=>$value pairs
* @return EventContextData
*/
public function setFields(array $data): self
{
$data = $this->data;
foreach ($data as $field => $value) {
if ($this->has($field)) {
$data[$field] = $value;
} else {
$this->throwException($field);
}
}
return new static($data);
}
/**
* Returns a list of fields in this context
* @return array
*/
private function getListOfFields(): array
{
return array_keys($this->data);
}
/**
* Returns a comma separated string with all allowed fields, for debugging reasons.
* @return string
*/
private function getFormattedListOfFields(): string
{
return substr(
implode(", ", $this->getListOfFields()),
0,
-2
);
}
/**
* internal use only - throws an ArgumentException a field is given that's not valid.
* @param $field
* @throws ArgumentException
*/
private function throwException($field)
{
throw new ArgumentException(
"{$field} is not valid in this context, only {$this->getFormattedListOfFields()} are allowed."
);
}
}
-136
View File
@@ -1,136 +0,0 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Events;
use LotGD\Core\Exceptions\ArgumentException;
/**
* Abstract EventContextDataContainer to provide a basic structure for managing contextual data of an event.
*
* This class must be immutable and returns always a new instance of itself for any change.
* @package LotGD\Core\Events
* @immutable
*/
abstract class EventContextDataContainer
{
private $data;
/**
* Creates a new instance of a data container.
*
* Sub types can change this method to force certain parameters.
* @param array $data
* @return EventContextDataContainer
*/
public static function create(array $data): self
{
return new static($data);
}
/**
* protected constructor..
* @see self::create
* @param array $data
*/
protected function __construct(array $data)
{
$this->data = $data;
}
/**
* Returns true if container has a certain field.
* @param string $field
* @return bool
*/
public function has(string $field): bool
{
return array_key_exists($field, $this->data);
}
/**
* Returns the value of a field.
* @param string $field
* @return mixed
*/
public function get(string $field)
{
if ($this->has($field)) {
return $this->data[$field];
} else {
$this->throwException($field);
}
}
/**
* Sets a field to a new value and returns a new data container
* @param string $field
* @param $value
* @return EventContextDataContainer
*/
public function set(string $field, $value): self
{
if ($this->has($field)) {
$data = $this->data;
$data[$field] = $value;
return new static($data);
} else {
$this->throwException($field);
}
}
/**
* Sets multiple fields at once
* @param array $data array of $field=>$value pairs
* @return EventContextDataContainer
*/
public function setFields(array $data): self
{
$data = $this->data;
foreach ($data as $field => $value) {
if ($this->has($field)) {
$data[$field] = $value;
} else {
$this->throwException($field);
}
}
return new static($data);
}
/**
* Returns a list of fields in this context
* @return array
*/
private function getListOfFields(): array
{
return array_keys($this->data);
}
/**
* Returns a comma separated string with all allowed fields, for debugging reasons.
* @return string
*/
private function getFormattedListOfFields(): string
{
return substr(
implode(", ", $this->getListOfFields()),
0,
-2
);
}
/**
* internal use only - throws an ArgumentException a field is given that's not valid.
* @param $field
* @throws ArgumentException
*/
private function throwException($field)
{
throw new ArgumentException(
"{$field} is not valid in this context, only {$this->getFormattedListOfFields()} are allowed."
);
}
}
@@ -23,7 +23,7 @@ use LotGD\Core\Models\Viewpoint;
* redirect Scene|null
* @package LotGD\Core\Events
*/
class NavigateToScene extends EventContextDataContainer
class NavigateToSceneData extends EventContextData
{
/**
* NavigateToScene constructor.
@@ -16,7 +16,7 @@ use LotGD\Core\Models\Scene;
* scene Scene|null
* @package LotGD\Core\Events
*/
class NewViewpoint extends EventContextDataContainer
class NewViewpointData extends EventContextData
{
/**
* NewViewpoint constructor.
+4 -4
View File
@@ -5,8 +5,8 @@ namespace LotGD\Core;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use LotGD\Core\Events\NavigateToScene;
use LotGD\Core\Events\NewViewpoint;
use LotGD\Core\Events\NavigateToSceneData;
use LotGD\Core\Events\NewViewpointData;
use Monolog\Logger;
use LotGD\Core\Models\{
@@ -194,7 +194,7 @@ class Game
if ($v === null) {
// No viewpoint set up for this user. Run the hook to find the default
// scene.
$contextData = NewViewpoint::create([
$contextData = NewViewpointData::create([
'character' => $this->getCharacter(),
'scene' => null
]);
@@ -295,7 +295,7 @@ class Game
// Let and installed listeners (ie modules) make modifications to the
// new viewpoint, including the ability to redirect the user to
// a different scene, by setting $context['redirect'] to a new scene.
$contextData = NavigateToScene::create([
$contextData = NavigateToSceneData::create([
'referrer' => $referrer,
'viewpoint' => $viewpoint,
'scene' => $scene,
+3 -3
View File
@@ -9,7 +9,7 @@ use Monolog\Logger;
use Monolog\Handler\NullHandler;
use LotGD\Core\{
Action, ActionGroup, Bootstrap, Configuration, ComposerManager, DiceBag, EventHandler, EventManager, Events\NewViewpoint, Game, TimeKeeper, ModuleManager
Action, ActionGroup, Bootstrap, Configuration, ComposerManager, DiceBag, EventHandler, EventManager, Events\NewViewpointData, Game, TimeKeeper, ModuleManager
};
use LotGD\Core\Models\{
Character, Viewpoint, Scene
@@ -29,10 +29,10 @@ class DefaultSceneProvider implements EventHandler
{
switch ($context->getEvent()) {
case 'h/lotgd/core/default-scene':
if (!$context->hasDataType(NewViewpoint::class)) {
if (!$context->hasDataType(NewViewpointData::class)) {
throw new \Exception(sprintf(
"Context was expected to be %s, %s instead.",
NewViewpoint::class,
NewViewpointData::class,
get_class($context->getData())
));
}