Changed the scene parent<=>child relationship to connections.

The parent<=>child relationship of scenes was removed. Instead, this commit introduces the concept of a connection.

A connection is used to connect two scenes. Depending on which entity the connect-method is called, one is defined as the "outgoing" scene, the other as the ingoing scene:

```
$a->connect($b);
```

In this case, $a will be the outgoing part of the connection, $b the incoming.

Furthermore, in order to support action groups, this commit introduces SceneConnectionGroups which can be created in scenes and checked wether they exist or not. Using these, it is possible to specifiy to which part of the scenes are connected to each other.

```
$a->getConnectionGroup("scene-A/marketsquare")->connect($b);
```

In this case, $a will have the action to access $b under the ActionGroup of scene-A/marketsquare. On the other hand, $b, which doesn't have a connection group specified, will have the connection back to $a in the default group.

Connect also accepts the return value of getConnectionGroup as the argument, thus allowing the connection _to_ a certain part of $b as well:

```
$a->connect($b->getConnectionGroup("scene-B/back"));
```

The tests for scenes were updates in order to reflect this change.
This commit is contained in:
Vassyli
2017-03-02 17:12:30 +01:00
parent e82e72a183
commit 2970bd09d7
13 changed files with 901 additions and 325 deletions
+1
View File
@@ -1,5 +1,6 @@
### Project related
vendor/
.idea/
logs/*
+1 -1
View File
@@ -12,7 +12,7 @@
"bin/daenerys"
],
"require": {
"php": "^7.0.0",
"php": "^7.1.0",
"composer/composer": "*",
"gedmo/doctrine-extensions": "*",
"doctrine/orm": "^2.5",
Generated
+180 -178
View File
@@ -4,8 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "30e4866a38047b4a1fd9c55cf08f22ec",
"content-hash": "db8bc30537b2e353991fb5f1034910bf",
"content-hash": "ce7af760f4497e0fc967f624e5e6cfcf",
"packages": [
{
"name": "behat/transliterator",
@@ -45,7 +44,7 @@
"slug",
"transliterator"
],
"time": "2015-09-28 16:26:35"
"time": "2015-09-28T16:26:35+00:00"
},
{
"name": "composer/ca-bundle",
@@ -103,20 +102,20 @@
"ssl",
"tls"
],
"time": "2016-11-02 18:11:27"
"time": "2016-11-02T18:11:27+00:00"
},
{
"name": "composer/composer",
"version": "1.3.1",
"version": "1.3.2",
"source": {
"type": "git",
"url": "https://github.com/composer/composer.git",
"reference": "91dbca556764dcece45e1ba3aab14de2deaa9fec"
"reference": "e7569edb4a5eadcbb2e4ad5ed753282260f281df"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/composer/zipball/91dbca556764dcece45e1ba3aab14de2deaa9fec",
"reference": "91dbca556764dcece45e1ba3aab14de2deaa9fec",
"url": "https://api.github.com/repos/composer/composer/zipball/e7569edb4a5eadcbb2e4ad5ed753282260f281df",
"reference": "e7569edb4a5eadcbb2e4ad5ed753282260f281df",
"shasum": ""
},
"require": {
@@ -180,7 +179,7 @@
"dependency",
"package"
],
"time": "2017-01-07 17:08:51"
"time": "2017-01-27T17:23:42+00:00"
},
{
"name": "composer/semver",
@@ -242,7 +241,7 @@
"validation",
"versioning"
],
"time": "2016-08-30 16:08:34"
"time": "2016-08-30T16:08:34+00:00"
},
{
"name": "composer/spdx-licenses",
@@ -303,7 +302,7 @@
"spdx",
"validator"
],
"time": "2016-09-28 07:17:45"
"time": "2016-09-28T07:17:45+00:00"
},
{
"name": "d11wtq/boris",
@@ -339,20 +338,20 @@
"MIT"
],
"description": "A tiny, but robust REPL (Read-Evaluate-Print-Loop) for PHP.",
"time": "2015-03-01 08:05:19"
"time": "2015-03-01T08:05:19+00:00"
},
{
"name": "doctrine/annotations",
"version": "v1.3.1",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
"reference": "bd4461328621bde0ae6b1b2675fbc6aca4ceb558"
"reference": "54cacc9b81758b14e3ce750f205a393d52339e97"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/bd4461328621bde0ae6b1b2675fbc6aca4ceb558",
"reference": "bd4461328621bde0ae6b1b2675fbc6aca4ceb558",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97",
"reference": "54cacc9b81758b14e3ce750f205a393d52339e97",
"shasum": ""
},
"require": {
@@ -361,7 +360,7 @@
},
"require-dev": {
"doctrine/cache": "1.*",
"phpunit/phpunit": "^5.6.1"
"phpunit/phpunit": "^5.7"
},
"type": "library",
"extra": {
@@ -407,7 +406,7 @@
"docblock",
"parser"
],
"time": "2016-12-30 15:59:45"
"time": "2017-02-24T16:22:25+00:00"
},
{
"name": "doctrine/cache",
@@ -477,32 +476,33 @@
"cache",
"caching"
],
"time": "2016-10-29 11:16:17"
"time": "2016-10-29T11:16:17+00:00"
},
{
"name": "doctrine/collections",
"version": "v1.3.0",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/collections.git",
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
"reference": "1a4fb7e902202c33cce8c55989b945612943c2ba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba",
"reference": "1a4fb7e902202c33cce8c55989b945612943c2ba",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
"php": "^5.6 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
"doctrine/coding-standard": "~0.1@dev",
"phpunit/phpunit": "^5.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
"dev-master": "1.3.x-dev"
}
},
"autoload": {
@@ -543,7 +543,7 @@
"collections",
"iterator"
],
"time": "2015-04-14 22:21:58"
"time": "2017-01-03T10:49:41+00:00"
},
{
"name": "doctrine/common",
@@ -616,20 +616,20 @@
"persistence",
"spl"
],
"time": "2017-01-13 14:02:13"
"time": "2017-01-13T14:02:13+00:00"
},
{
"name": "doctrine/dbal",
"version": "v2.5.8",
"version": "v2.5.12",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "6314d55f60f85f0295c90688397b75c13faf9f0e"
"reference": "7b9e911f9d8b30d43b96853dab26898c710d8f44"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/6314d55f60f85f0295c90688397b75c13faf9f0e",
"reference": "6314d55f60f85f0295c90688397b75c13faf9f0e",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/7b9e911f9d8b30d43b96853dab26898c710d8f44",
"reference": "7b9e911f9d8b30d43b96853dab26898c710d8f44",
"shasum": ""
},
"require": {
@@ -687,7 +687,7 @@
"persistence",
"queryobject"
],
"time": "2017-01-17 17:48:38"
"time": "2017-02-08T12:53:47+00:00"
},
{
"name": "doctrine/inflector",
@@ -754,7 +754,7 @@
"singularize",
"string"
],
"time": "2015-11-06 14:35:42"
"time": "2015-11-06T14:35:42+00:00"
},
{
"name": "doctrine/instantiator",
@@ -808,7 +808,7 @@
"constructor",
"instantiate"
],
"time": "2015-06-14 21:17:01"
"time": "2015-06-14T21:17:01+00:00"
},
{
"name": "doctrine/lexer",
@@ -862,7 +862,7 @@
"lexer",
"parser"
],
"time": "2014-09-09 13:34:57"
"time": "2014-09-09T13:34:57+00:00"
},
{
"name": "doctrine/orm",
@@ -938,7 +938,7 @@
"database",
"orm"
],
"time": "2016-12-18 15:42:34"
"time": "2016-12-18T15:42:34+00:00"
},
{
"name": "gedmo/doctrine-extensions",
@@ -1017,7 +1017,7 @@
"tree",
"uploadable"
],
"time": "2016-12-21 13:46:54"
"time": "2016-12-21T13:46:54+00:00"
},
{
"name": "justinrainbow/json-schema",
@@ -1083,7 +1083,7 @@
"json",
"schema"
],
"time": "2016-12-22 16:43:46"
"time": "2016-12-22T16:43:46+00:00"
},
{
"name": "monolog/monolog",
@@ -1161,7 +1161,7 @@
"logging",
"psr-3"
],
"time": "2016-11-26 00:15:39"
"time": "2016-11-26T00:15:39+00:00"
},
{
"name": "psr/log",
@@ -1208,7 +1208,7 @@
"psr",
"psr-3"
],
"time": "2016-10-10 12:19:37"
"time": "2016-10-10T12:19:37+00:00"
},
{
"name": "seld/cli-prompt",
@@ -1256,7 +1256,7 @@
"input",
"prompt"
],
"time": "2016-04-18 09:31:41"
"time": "2016-04-18T09:31:41+00:00"
},
{
"name": "seld/jsonlint",
@@ -1302,7 +1302,7 @@
"parser",
"validator"
],
"time": "2016-11-14 17:59:58"
"time": "2016-11-14T17:59:58+00:00"
},
{
"name": "seld/phar-utils",
@@ -1346,20 +1346,20 @@
"keywords": [
"phra"
],
"time": "2015-10-13 18:44:15"
"time": "2015-10-13T18:44:15+00:00"
},
{
"name": "symfony/console",
"version": "v3.2.2",
"version": "v3.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "4f9e449e76996adf310498a8ca955c6deebe29dd"
"reference": "0e5e6899f82230fcb1153bcaf0e106ffaa44b870"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/4f9e449e76996adf310498a8ca955c6deebe29dd",
"reference": "4f9e449e76996adf310498a8ca955c6deebe29dd",
"url": "https://api.github.com/repos/symfony/console/zipball/0e5e6899f82230fcb1153bcaf0e106ffaa44b870",
"reference": "0e5e6899f82230fcb1153bcaf0e106ffaa44b870",
"shasum": ""
},
"require": {
@@ -1409,20 +1409,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2017-01-08 20:47:33"
"time": "2017-02-16T14:07:22+00:00"
},
{
"name": "symfony/debug",
"version": "v3.2.2",
"version": "v3.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "810ba5c1c5352a4ddb15d4719e8936751dff0b05"
"reference": "9b98854cb45bc59d100b7d4cc4cf9e05f21026b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/810ba5c1c5352a4ddb15d4719e8936751dff0b05",
"reference": "810ba5c1c5352a4ddb15d4719e8936751dff0b05",
"url": "https://api.github.com/repos/symfony/debug/zipball/9b98854cb45bc59d100b7d4cc4cf9e05f21026b9",
"reference": "9b98854cb45bc59d100b7d4cc4cf9e05f21026b9",
"shasum": ""
},
"require": {
@@ -1466,11 +1466,11 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2017-01-02 20:32:22"
"time": "2017-02-16T16:34:18+00:00"
},
{
"name": "symfony/filesystem",
"version": "v3.2.2",
"version": "v3.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
@@ -1515,11 +1515,11 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
"time": "2017-01-08 20:47:33"
"time": "2017-01-08T20:47:33+00:00"
},
{
"name": "symfony/finder",
"version": "v3.2.2",
"version": "v3.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
@@ -1564,7 +1564,7 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2017-01-02 20:32:22"
"time": "2017-01-02T20:32:22+00:00"
},
{
"name": "symfony/polyfill-mbstring",
@@ -1623,20 +1623,20 @@
"portable",
"shim"
],
"time": "2016-11-14 01:06:16"
"time": "2016-11-14T01:06:16+00:00"
},
{
"name": "symfony/process",
"version": "v3.2.2",
"version": "v3.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "350e810019fc52dd06ae844b6a6d382f8a0e8893"
"reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/350e810019fc52dd06ae844b6a6d382f8a0e8893",
"reference": "350e810019fc52dd06ae844b6a6d382f8a0e8893",
"url": "https://api.github.com/repos/symfony/process/zipball/0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856",
"reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856",
"shasum": ""
},
"require": {
@@ -1672,20 +1672,20 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2017-01-02 20:32:22"
"time": "2017-02-16T14:07:22+00:00"
},
{
"name": "symfony/yaml",
"version": "v3.2.2",
"version": "v3.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "50eadbd7926e31842893c957eca362b21592a97d"
"reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/50eadbd7926e31842893c957eca362b21592a97d",
"reference": "50eadbd7926e31842893c957eca362b21592a97d",
"url": "https://api.github.com/repos/symfony/yaml/zipball/9724c684646fcb5387d579b4bfaa63ee0b0c64c8",
"reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8",
"shasum": ""
},
"require": {
@@ -1727,7 +1727,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2017-01-03 13:51:32"
"time": "2017-02-16T22:46:52+00:00"
}
],
"packages-dev": [
@@ -1780,20 +1780,20 @@
"issues": "https://github.com/Block8/php-docblock-checker/issues",
"source": "https://github.com/Block8/php-docblock-checker"
},
"time": "2016-07-31 06:01:25"
"time": "2016-07-31T06:01:25+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.5.5",
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108"
"reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/399c1f9781e222f6eb6cc238796f5200d1b7f108",
"reference": "399c1f9781e222f6eb6cc238796f5200d1b7f108",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe",
"reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe",
"shasum": ""
},
"require": {
@@ -1822,7 +1822,7 @@
"object",
"object graph"
],
"time": "2016-10-31 17:19:45"
"time": "2017-01-26T22:05:40+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@@ -1876,7 +1876,7 @@
"reflection",
"static analysis"
],
"time": "2015-12-27 11:43:31"
"time": "2015-12-27T11:43:31+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
@@ -1921,7 +1921,7 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"time": "2016-09-30 07:12:33"
"time": "2016-09-30T07:12:33+00:00"
},
{
"name": "phpdocumentor/type-resolver",
@@ -1968,7 +1968,7 @@
"email": "me@mikevanriel.com"
}
],
"time": "2016-11-25 06:54:22"
"time": "2016-11-25T06:54:22+00:00"
},
{
"name": "phpspec/prophecy",
@@ -2031,36 +2031,33 @@
"spy",
"stub"
],
"time": "2016-11-21 14:58:47"
"time": "2016-11-21T14:58:47+00:00"
},
{
"name": "phpunit/dbunit",
"version": "2.0.3",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/dbunit.git",
"reference": "5c35d74549c21ba55d0ea74ba89d191a51f8cf25"
"reference": "f2f8bec1d6ad7ad0bcdb47c1ed56d9d42d3e39ab"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/5c35d74549c21ba55d0ea74ba89d191a51f8cf25",
"reference": "5c35d74549c21ba55d0ea74ba89d191a51f8cf25",
"url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/f2f8bec1d6ad7ad0bcdb47c1ed56d9d42d3e39ab",
"reference": "f2f8bec1d6ad7ad0bcdb47c1ed56d9d42d3e39ab",
"shasum": ""
},
"require": {
"ext-pdo": "*",
"ext-simplexml": "*",
"php": "^5.4 || ^7.0",
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0",
"symfony/yaml": "^2.1 || ^3.0"
"php": "^7.0",
"phpunit/phpunit": "^6.0",
"symfony/yaml": "^3.0"
},
"bin": [
"dbunit"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
"dev-master": "3.0.x-dev"
}
},
"autoload": {
@@ -2075,55 +2072,55 @@
"authors": [
{
"name": "Sebastian Bergmann",
"email": "sb@sebastian-bergmann.de",
"email": "sebastian@phpunit.de",
"role": "lead"
}
],
"description": "DbUnit port for PHP/PHPUnit to support database interaction testing.",
"description": "PHPUnit extension for database interaction testing",
"homepage": "https://github.com/sebastianbergmann/dbunit/",
"keywords": [
"database",
"testing",
"xunit"
],
"time": "2016-12-02 14:39:14"
"time": "2017-02-03T08:50:36+00:00"
},
{
"name": "phpunit/php-code-coverage",
"version": "4.0.4",
"version": "5.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a"
"reference": "531553c4795a1df54114342d68ca337d5d81c8a0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c14196e64a78570034afd0b7a9f3757ba71c2a0a",
"reference": "c14196e64a78570034afd0b7a9f3757ba71c2a0a",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/531553c4795a1df54114342d68ca337d5d81c8a0",
"reference": "531553c4795a1df54114342d68ca337d5d81c8a0",
"shasum": ""
},
"require": {
"php": "^5.6 || ^7.0",
"phpunit/php-file-iterator": "~1.3",
"phpunit/php-text-template": "~1.2",
"phpunit/php-token-stream": "^1.4.2",
"sebastian/code-unit-reverse-lookup": "~1.0",
"sebastian/environment": "^1.3.2 || ^2.0",
"sebastian/version": "~1.0|~2.0"
"ext-dom": "*",
"ext-xmlwriter": "*",
"php": "^7.0",
"phpunit/php-file-iterator": "^1.3",
"phpunit/php-text-template": "^1.2",
"phpunit/php-token-stream": "^1.4.11 || ^2.0",
"sebastian/code-unit-reverse-lookup": "^1.0",
"sebastian/environment": "^2.0",
"sebastian/version": "^2.0"
},
"require-dev": {
"ext-xdebug": ">=2.1.4",
"phpunit/phpunit": "^5.4"
"ext-xdebug": "^2.5",
"phpunit/phpunit": "^6.0"
},
"suggest": {
"ext-dom": "*",
"ext-xdebug": ">=2.4.0",
"ext-xmlwriter": "*"
"ext-xdebug": "^2.5.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
"dev-master": "5.0.x-dev"
}
},
"autoload": {
@@ -2149,7 +2146,7 @@
"testing",
"xunit"
],
"time": "2016-12-20 15:22:42"
"time": "2017-03-01T09:14:18+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -2196,7 +2193,7 @@
"filesystem",
"iterator"
],
"time": "2016-10-03 07:40:28"
"time": "2016-10-03T07:40:28+00:00"
},
{
"name": "phpunit/php-text-template",
@@ -2237,29 +2234,34 @@
"keywords": [
"template"
],
"time": "2015-06-21 13:50:34"
"time": "2015-06-21T13:50:34+00:00"
},
{
"name": "phpunit/php-timer",
"version": "1.0.8",
"version": "1.0.9",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
"reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
"reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
"reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
"reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
"php": "^5.3.3 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "~4|~5"
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"classmap": [
"src/"
@@ -2281,20 +2283,20 @@
"keywords": [
"timer"
],
"time": "2016-05-12 18:03:57"
"time": "2017-02-26T11:10:40+00:00"
},
{
"name": "phpunit/php-token-stream",
"version": "1.4.9",
"version": "1.4.11",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
"reference": "3b402f65a4cc90abf6e1104e388b896ce209631b"
"reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b",
"reference": "3b402f65a4cc90abf6e1104e388b896ce209631b",
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7",
"reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7",
"shasum": ""
},
"require": {
@@ -2330,20 +2332,20 @@
"keywords": [
"tokenizer"
],
"time": "2016-11-15 14:06:22"
"time": "2017-02-27T10:12:30+00:00"
},
{
"name": "phpunit/phpunit",
"version": "5.7.5",
"version": "6.0.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe"
"reference": "47ee3fa1bca5c50f1d25105201eb20df777bd7b6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50fd2be8f3e23e91da825f36f08e5f9633076ffe",
"reference": "50fd2be8f3e23e91da825f36f08e5f9633076ffe",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/47ee3fa1bca5c50f1d25105201eb20df777bd7b6",
"reference": "47ee3fa1bca5c50f1d25105201eb20df777bd7b6",
"shasum": ""
},
"require": {
@@ -2352,33 +2354,33 @@
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-xml": "*",
"myclabs/deep-copy": "~1.3",
"php": "^5.6 || ^7.0",
"myclabs/deep-copy": "^1.3",
"php": "^7.0",
"phpspec/prophecy": "^1.6.2",
"phpunit/php-code-coverage": "^4.0.3",
"phpunit/php-file-iterator": "~1.4",
"phpunit/php-text-template": "~1.2",
"phpunit/php-code-coverage": "^5.0",
"phpunit/php-file-iterator": "^1.4",
"phpunit/php-text-template": "^1.2",
"phpunit/php-timer": "^1.0.6",
"phpunit/phpunit-mock-objects": "^3.2",
"sebastian/comparator": "~1.2.2",
"sebastian/diff": "~1.2",
"sebastian/environment": "^1.3.4 || ^2.0",
"sebastian/exporter": "~2.0",
"sebastian/global-state": "^1.0 || ^2.0",
"sebastian/object-enumerator": "~2.0",
"sebastian/resource-operations": "~1.0",
"sebastian/version": "~1.0|~2.0",
"symfony/yaml": "~2.1|~3.0"
"phpunit/phpunit-mock-objects": "^4.0",
"sebastian/comparator": "^1.2.4 || ^2.0",
"sebastian/diff": "^1.2",
"sebastian/environment": "^2.0",
"sebastian/exporter": "^2.0 || ^3.0",
"sebastian/global-state": "^1.1 || ^2.0",
"sebastian/object-enumerator": "^2.0 || ^3.0",
"sebastian/resource-operations": "^1.0",
"sebastian/version": "^2.0"
},
"conflict": {
"phpdocumentor/reflection-docblock": "3.0.2"
"phpdocumentor/reflection-docblock": "3.0.2",
"phpunit/dbunit": "<3.0"
},
"require-dev": {
"ext-pdo": "*"
},
"suggest": {
"ext-xdebug": "*",
"phpunit/php-invoker": "~1.1"
"phpunit/php-invoker": "^1.1"
},
"bin": [
"phpunit"
@@ -2386,7 +2388,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.7.x-dev"
"dev-master": "6.0.x-dev"
}
},
"autoload": {
@@ -2412,33 +2414,33 @@
"testing",
"xunit"
],
"time": "2016-12-28 07:18:51"
"time": "2017-03-02T15:24:03+00:00"
},
{
"name": "phpunit/phpunit-mock-objects",
"version": "3.4.3",
"version": "4.0.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
"reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24"
"reference": "3819745c44f3aff9518fd655f320c4535d541af7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
"reference": "3ab72b65b39b491e0c011e2e09bb2206c2aa8e24",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3819745c44f3aff9518fd655f320c4535d541af7",
"reference": "3819745c44f3aff9518fd655f320c4535d541af7",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.6 || ^7.0",
"php": "^7.0",
"phpunit/php-text-template": "^1.2",
"sebastian/exporter": "^1.2 || ^2.0"
"sebastian/exporter": "^2.0"
},
"conflict": {
"phpunit/phpunit": "<5.4.0"
"phpunit/phpunit": "<6.0"
},
"require-dev": {
"phpunit/phpunit": "^5.4"
"phpunit/phpunit": "^6.0"
},
"suggest": {
"ext-soap": "*"
@@ -2446,7 +2448,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2.x-dev"
"dev-master": "4.0.x-dev"
}
},
"autoload": {
@@ -2471,7 +2473,7 @@
"mock",
"xunit"
],
"time": "2016-12-08 20:27:08"
"time": "2017-02-02T10:36:38+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
@@ -2516,20 +2518,20 @@
],
"description": "Looks up which function or method a line of code belongs to",
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
"time": "2016-02-13 06:45:14"
"time": "2016-02-13T06:45:14+00:00"
},
{
"name": "sebastian/comparator",
"version": "1.2.2",
"version": "1.2.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f"
"reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f",
"reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
"reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
"shasum": ""
},
"require": {
@@ -2580,7 +2582,7 @@
"compare",
"equality"
],
"time": "2016-11-19 09:18:40"
"time": "2017-01-29T09:50:25+00:00"
},
{
"name": "sebastian/diff",
@@ -2632,7 +2634,7 @@
"keywords": [
"diff"
],
"time": "2015-12-08 07:14:41"
"time": "2015-12-08T07:14:41+00:00"
},
{
"name": "sebastian/environment",
@@ -2682,7 +2684,7 @@
"environment",
"hhvm"
],
"time": "2016-11-26 07:53:53"
"time": "2016-11-26T07:53:53+00:00"
},
{
"name": "sebastian/exporter",
@@ -2749,7 +2751,7 @@
"export",
"exporter"
],
"time": "2016-11-19 08:54:04"
"time": "2016-11-19T08:54:04+00:00"
},
{
"name": "sebastian/global-state",
@@ -2800,20 +2802,20 @@
"keywords": [
"global state"
],
"time": "2015-10-12 03:26:01"
"time": "2015-10-12T03:26:01+00:00"
},
{
"name": "sebastian/object-enumerator",
"version": "2.0.0",
"version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
"reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35"
"reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35",
"reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35",
"url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7",
"reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7",
"shasum": ""
},
"require": {
@@ -2846,7 +2848,7 @@
],
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
"time": "2016-11-19 07:35:10"
"time": "2017-02-18T15:18:39+00:00"
},
{
"name": "sebastian/recursion-context",
@@ -2899,7 +2901,7 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"time": "2016-11-19 07:33:16"
"time": "2016-11-19T07:33:16+00:00"
},
{
"name": "sebastian/resource-operations",
@@ -2941,7 +2943,7 @@
],
"description": "Provides a list of PHP built-in functions that operate on resources",
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
"time": "2015-07-28 20:34:47"
"time": "2015-07-28T20:34:47+00:00"
},
{
"name": "sebastian/version",
@@ -2984,7 +2986,7 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"time": "2016-10-03 07:35:21"
"time": "2016-10-03T07:35:21+00:00"
},
{
"name": "webmozart/assert",
@@ -3034,7 +3036,7 @@
"check",
"validate"
],
"time": "2016-11-23 20:04:58"
"time": "2016-11-23T20:04:58+00:00"
}
],
"aliases": [],
@@ -3043,7 +3045,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": "^7.0.0"
"php": "^7.1.0"
},
"platform-dev": []
}
+5
View File
@@ -76,4 +76,9 @@ class ActionGroup
{
$this->actions = $actions;
}
public function addAction(Action $action)
{
$this->actions[] = $action;
}
}
+55 -12
View File
@@ -9,7 +9,8 @@ use Monolog\Logger;
use LotGD\Core\Models\ {
Character,
Viewpoint,
Scene
Scene,
SceneConnection
};
use LotGD\Core\Exceptions\ {
ActionNotFoundException,
@@ -36,6 +37,10 @@ class Game
/**
* Construct a game. You probably want to use Bootstrap to do this.
* @param Configuration $configuration
* @param Logger $logger
* @param EntityManagerInterface $entityManager
* @param string $cwd
*/
public function __construct(
Configuration $configuration,
@@ -136,9 +141,9 @@ class Game
/**
* Returns the logger instance to write logs.
* @return \Monolog\Logger
* @return Logger
*/
public function getLogger(): \Monolog\Logger
public function getLogger(): Logger
{
return $this->logger;
}
@@ -161,6 +166,7 @@ class Game
/**
* Returns the currently configured user character.
* @return Character
* @throws CharacterNotFoundException
*/
public function getCharacter(): Character
{
@@ -182,6 +188,7 @@ class Game
/**
* Return the viewpoint for the current user.
* @return Viewpoint
* @throws InvalidConfigurationException
*/
public function getViewpoint(): Viewpoint
{
@@ -236,19 +243,53 @@ class Game
// Generate the default set of actions: the default group with
// all children.
$this->getLogger()->addDebug("Building default action group...");
$defaultGroup = new ActionGroup(ActionGroup::DefaultGroup, '', 0);
$as = array_map(function ($c) {
$actionGroups = [
ActionGroup::DefaultGroup => new ActionGroup(ActionGroup::DefaultGroup, '', 0),
];
$scene->getConnections()->map(function(SceneConnection $connection) use ($scene, $actionGroups) {
if ($connection->getOutgoingScene() === $scene) {
// current scene is outgoing, use incoming.
$connectedScene = $connection->getIncomingScene();
$connectionGroupName = $connection->getOutgoingConnectionGroupName();
} else {
// current scene is not outgoing, thus incoming, use outgoing.
$connectedScene = $connection->getOutgoingScene();
$connectionGroupName = $connection->getIncomingConnectionGroupName();
}
$this->getLogger()->addDebug(" Adding navigation action for child sceneId={$connectedScene->getId()}");
$action = new Action($connectedScene->getId());
if ($connectionGroupName === null) {
$actionGroups[ActionGroup::DefaultGroup]->addAction($action);
} else {
if (isset($actionGroups[$connectionGroupName])) {
$actionGroups[$connectionGroupName]->addAction($action);
} else {
$connectionGroup = $scene->getConnectionGroup($connectionGroupName);
$actionGroup = new ActionGroup($connectionGroupName->getName(), $connectionGroupName->getTitle(), 0);
$actionGroup->addAction($action);
$actionGroups[$connectionGroupName] = $actionGroup;
}
}
});
/*$as = array_map(function ($c) {
$id = $c->getId();
$this->getLogger()->addDebug(" Adding navigation action for child sceneId={$id}");
return new Action($c->getId());
}, $scene->getChildren()->toArray());
$defaultGroup->setActions($as);
$count = count($as);
$this->getLogger()->addDebug("Total actions: {$count}");
}, $scene->getChildren()->toArray());*/
//$defaultGroup->setActions($as);
//$count = count($as);
$counts = implode(", ", array_map(function($k, $v) {
return $k .count($v);
}, array_keys($actionGroups), array_values($actionGroups)));
$this->getLogger()->addDebug("Total actions: {$counts}");
$hiddenGroup = new ActionGroup(ActionGroup::HiddenGroup, '', 100);
$actionGroups[ActionGroup::HiddenGroup] = new ActionGroup(ActionGroup::HiddenGroup, '', 100);
$viewpoint->setActionGroups([$defaultGroup, $hiddenGroup]);
$viewpoint->setActionGroups(array_values($actionGroups));
// Let and installed listeners (ie modules) make modifications to the
// new viewpoint, including the ability to redirect the user to
@@ -275,7 +316,9 @@ class Game
* Take the specified navigation action for the currently configured
* user. This action must be present in the current user's viewpoint.
* @param string $actionId The identifier of the action to take.
* @param array $paramters
* @param array $parameters
* @throws ActionNotFoundException
* @throws SceneNotFoundException
*/
public function takeAction(string $actionId, array $parameters = [])
{
+208 -76
View File
@@ -7,8 +7,8 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Column;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Tools\Model\Creator;
use LotGD\Core\Tools\Model\Deletor;
use LotGD\Core\Tools\Model\SceneBasics;
@@ -20,7 +20,7 @@ use LotGD\Core\Tools\Model\SceneBasics;
* @Entity
* @Table(name="scenes")
*/
class Scene implements CreateableInterface
class Scene implements CreateableInterface, SceneConnectable
{
use Creator;
use Deletor;
@@ -30,18 +30,19 @@ class Scene implements CreateableInterface
private $id;
/**
* @ManyToMany(targetEntity="Scene", mappedBy="children", cascade={"persist"})
* @OneToMany(targetEntity="SceneConnectionGroup", mappedBy="scene", cascade={"persist", "remove"})
*/
private $parents = null;
private $connectionGroups = null;
/**
* @ManyToMany(targetEntity="Scene", inversedBy="parents", cascade={"persist", "remove"})
* @JoinTable(name="paths",
* joinColumns={@JoinColumn(name="scene_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="child_scene_id", referencedColumnName="id")}
* )
* @OneToMany(targetEntity="SceneConnection", mappedBy="outgoingScene", cascade={"persist"})
*/
private $children = [];
private $outgoingConnections = null;
/**
* @OneToMany(targetEntity="SceneConnection", mappedBy="incomingScene", cascade={"persist"})
*/
private $incomingConnections = null;
/**
* @var array
@@ -53,13 +54,17 @@ class Scene implements CreateableInterface
"template"
];
/* @var ?ArrayCollection */
private $connectedScenes = null;
/**
* Constructor for a scene.
*/
public function __construct()
{
$this->children = new ArrayCollection();
$this->parents = new ArrayCollection();
$this->connectionGroups = new ArrayCollection();
$this->outgoingConnections = new ArrayCollection();
$this->incomingConnections = new ArrayCollection();
}
/**
@@ -72,88 +77,215 @@ class Scene implements CreateableInterface
}
/**
* Set the parents to the given Collection.
* @param Collection $parents
*/
public function setParents(Collection $parents)
{
// Super slow, but presumably these are short collections :)
// We should probably move to a set collection at some point.
$oldParents = $this->parents;
$additions = $parents->filter(function($element) use ($oldParents) {
return !$oldParents->contains($element);
});
$removals = $this->parents->filter(function($element) use ($parents) {
return !$parents->contains($element);
});
foreach ($additions as $a) {
$this->addParent($a);
}
foreach ($removals as $r) {
$this->removeParent($r);
}
$this->parents = $parents;
}
/**
* Adds a parent to this scene.
* @param \LotGD\Core\Models\Scene $parent
*/
public function addParent(Scene $parent)
{
if (!$this->parents->contains($parent)) {
$this->parents->add($parent);
$parent->addChild($this);
}
}
/**
* Removes a parent from this scene.
* @param Scene $parent
*/
public function removeParent(Scene $parent)
{
$this->parents->removeElement($parent);
$parent->removeChild($this);
}
/**
* Returns all the possible parents of this scene.
* Filters all connection groups for a specific name.
* @param string $name
* @return Collection
*/
public function getParents(): Collection
private function filterConnectionGroupCollectionByName(string $name): Collection
{
return $this->parents;
return $this->connectionGroups->filter(function(SceneConnectionGroup $group) use ($name) {
if ($group->getName() === $name) {
return true;
} else {
return false;
}
});
}
/**
* Returns a list of all children registered for this scene.
* @return Collection
* Returns true if this scene has a connection group with a given name associated.
* @param string $name
* @return bool
*/
public function getChildren(): Collection
public function hasConnectionGroup(string $name): bool
{
return $this->children;
return count($this->filterConnectionGroupCollectionByName($name)) === 1 ? true : false;
}
/**
* Registers a child for this scene.
* @param \LotGD\Core\Models\Scene $child
* Returns a connection group entity associated with this scene by a given name.
* @param string $name
* @return \LotGD\Core\Models\SceneConnectionGroup
*/
protected function addChild(Scene $child)
public function getConnectionGroup(string $name): SceneConnectionGroup
{
if (!$this->children->contains($child)) {
$this->children->add($child);
return $this->filterConnectionGroupCollectionByName($name)->first();
}
/**
* Adds a connection group to this scene.
* @param SceneConnectionGroup $group
* @throws ArgumentException
*/
public function addConnectionGroup(SceneConnectionGroup $group): void
{
if ($this->connectionGroups->contains($group) === true) {
throw new ArgumentException("This entity already owns the given connection group.");
}
if ($group->getScene()) {
throw new ArgumentException("The given connection group is already owned by another scene entity.");
}
$group->setScene($this);
$this->connectionGroups->add($group);
}
/**
* Removes a connection group from this scene.
* @param \LotGD\Core\Models\SceneConnectionGroup $group
* @throws ArgumentException
*/
public function dropConnectionGroup(SceneConnectionGroup $group): void
{
if ($this->connectionGroups->contains($group) === false) {
throw new ArgumentException("This entity does not own the given connection group.");
}
$this->connectionGroups->removeElement($group);
}
/**
* Lazy loading helper function - loads all scenes that are connected to this scene.
*/
private function loadConnectedScenes(): void
{
if ($this->connectedScenes === null) {
$connectedScenes = new ArrayCollection();
foreach ($this->outgoingConnections as $connection) {
$incomingScene = $connection->getIncomingScene();
if ($connectedScenes->contains($incomingScene) === false) {
$connectedScenes->add($incomingScene);
}
}
foreach ($this->incomingConnections as $connection) {
$outgoingScenes = $connection->getOutgoingScene();
if ($connectedScenes->contains($outgoingScenes) === false) {
$connectedScenes->add($outgoingScenes);
}
}
$this->connectedScenes = $connectedScenes;
}
}
/**
* Removes a child from this scene.
* @param \LotGD\Core\Models\Scene $child
* Returns a list of scenes that are connected to this scene.
*
* This procedure can get slow, especially if there are a lot of scenes connected
* to one. Use this method only for the installation and removal of modules,
* or for administrative purposes (like a scene graph).
* @return ArrayCollection
*/
protected function removeChild(Scene $child)
public function getConnectedScenes(): ArrayCollection
{
$this->children->removeElement($child);
$this->loadConnectedScenes();
return $this->connectedScenes;
}
/**
* Checks if the given scene is connected to this entity.
* @param \LotGD\Core\Models\Scene $scene
* @return bool True if yes.
*/
public function isConnectedTo(Scene $scene): bool
{
$this->loadConnectedScenes();
if ($this->connectedScenes->contains($scene)) {
return true;
} else {
return false;
}
}
/**
* Returns all collections of this entity.
* @return Collection
*/
public function getConnections(): Collection
{
return new ArrayCollection(
$this->outgoingConnections->toArray(),
$this->incomingConnections->toArray()
);
}
/**
* Adds a connection to the outgoing connections.
* @param \LotGD\Core\Models\SceneConnection $connection
*/
public function addOutgoingConnection(SceneConnection $connection): void
{
$this->outgoingConnections->add($connection);
// If we already have loaded all connected scenes, we need to add the entry manually.
if ($this->connectedScenes !== null) {
$this->connectedScenes->add($connection->getIncomingScene());
}
}
/**
* Adds a connection to the incoming connections.
* @param \LotGD\Core\Models\SceneConnection $connection
*/
public function addIncomingConnection(SceneConnection $connection): void
{
$this->incomingConnections->add($connection);
// If we already have loaded all connected scenes, we need to add the entry manually.
if ($this->connectedScenes !== null) {
$this->connectedScenes->add($connection->getOutgoingScene());
}
}
/**
* @inheritDoc
*/
public function connect(
SceneConnectable $connectable,
int $directionality = self::Bidirectional
): SceneConnection {
if ($connectable instanceof self) {
if ($this === $connectable) {
throw new ArgumentException("Cannot connect a scene to itself.");
}
if ($this->isConnectedTo($connectable)) {
throw new ArgumentException(
"The given scene (ID {$connectable->getId()}) is already connected to this (ID {$this->getId()}) one."
);
}
$connection = new SceneConnection($this, $connectable, $directionality);
$outgoingScene = $this;
$incomingScene = $connectable;
} else {
if ($this === $connectable->getScene()) {
throw new ArgumentException("Cannot connect a scene to itself.");
}
if ($this->isConnectedTo($connectable->getScene())) {
throw new ArgumentException(
"The given scene (ID {$connectable->getId()}) is already connected to this (ID {$this->getId()}) one."
);
}
$connection = new SceneConnection($this, $connectable->getScene(), $directionality);
$connection->setIncomingConnectionGroupName($connectable->getName());
$outgoingScene = $this;
$incomingScene = $connectable->getScene();
}
$outgoingScene->addOutgoingConnection($connection);
$incomingScene->addIncomingConnection($connection);
return $connection;
}
}
+19
View File
@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
interface SceneConnectable
{
public const Bidirectional = 0;
public const Unidirectional = 1;
public const Xordirectional = 2;
/**
* Creates an outgoing connection for this scene to the given connectable.
* @param SceneConnectable $connectable
* @param int $directionality
* @return SceneConnection
*/
public function connect(SceneConnectable $connectable, int $directionality): SceneConnection;
}
+114
View File
@@ -0,0 +1,114 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
/**
*
* @Entity
* @Table(name="scene_connections")
*/
class SceneConnection
{
/**
* @Id
* @ManyToOne(targetEntity="Scene", inversedBy="outgoingConnections", cascade={"persist"})
* @JoinColumn(name="outgoing_scene_id", referencedColumnName="id")
*/
private $outgoingScene;
/**
* @Id
* @ManyToOne(targetEntity="Scene", inversedBy="incomingConnections", cascade={"persist"})
* @JoinColumn(name="incoming_scene_id", referencedColumnName="id")
*/
private $incomingScene;
/**
* @Column(type="integer", options={"default":0})
*/
private $directionality = 0;
/**
* @Column(type="string", nullable=True)
*/
private $outgoingConnectionGroupName;
/**
* @Column(type="string", nullable=True)
*/
private $incomingConnectionGroupName;
/**
*
* @param \LotGD\Core\Models\Scene $outgoing
* @param \LotGD\Core\Models\Scene $incoming
* @param int $directionality
*/
public function __construct(
Scene $outgoing,
Scene $incoming,
int $directionality
) {
$this->outgoingScene = $outgoing;
$this->incomingScene = $incoming;
$this->directionality = $directionality;
}
/**
* Sets the connection group name identifier of the outgoing connection.
* @param null|string $name The identifier name of the outgoing connection group.
*/
public function setOutgoingConnectionGroupName(?string $name): void
{
$this->outgoingConnectionGroupName = $name;
}
/**
* Returns the connection from name identifier of the outgoing connection.
* @return null|string
*/
public function getOutgoingConnectionGroupName(): ?string
{
return $this->outgoingConnectionGroupName;
}
/**
* Returns the outgoing Scene of this connection.
* @return Scene
*/
public function getOutgoingScene(): Scene
{
return $this->outgoingScene;
}
/**
* Sets the connection group name identifier of the incoming connection.
* @param null|string $name The identifier name of the incoming connection group.
*/
public function setIncomingConnectionGroupName(?string $name)
{
$this->incomingConnectionGroupName = $name;
}
/**
* Returns the connection group name identifier of the incoming connection.
* @return null|string
*/
public function getIncomingConnectionGroupName(): ?string
{
return $this->incomingConnectionGroupName;
}
/**
* Returns the incoming Scene of this connection.
* @return Scene
*/
public function getIncomingScene(): Scene
{
return $this->incomingScene;
}
}
+90
View File
@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Tools\Model\Creator;
use LotGD\Core\Tools\Model\Deletor;
/**
*
* @Entity
* @Table(name="scene_connection_groups")
*/
class SceneConnectionGroup implements SceneConnectable
{
/**
* @Id
* @ManyToOne(targetEntity="Scene", inversedBy="outgoingConnections", cascade={"persist"})
* @JoinColumn(name="scene_id", referencedColumnName="id")
*/
private $scene;
/**
* @Id
* @Column(type="string")
*/
private $name;
/**
* @Column(type="string", length=255)
*/
private $title;
/**
* SceneConnectionGroup constructor.
* @param string $name Soft-identifier of the connection group, e.g. lotgd/core
* @param string $title
*/
public function __construct(string $name, string $title)
{
$this->name = $name;
$this->title = $title;
}
/**
* Returns the scene associated with this connection group.
* @return \LotGD\Core\Models\Scene
*/
public function getScene(): ?Scene
{
return $this->scene;
}
/**
* Sets the scene associated with this connection group.
* @param \LotGD\Core\Models\Scene $scene
*/
public function setScene(Scene $scene): void
{
$this->scene = $scene;
}
/**
* Returns the name-identifier of this connection group.
* @return string
*/
public function getName(): string
{
return $this->name;
}
/**
* @inheritDoc
*/
public function connect(SceneConnectable $connectable, int $directionality = null): SceneConnection
{
if ($directionality === null) {
$connection = $this->scene->connect($connectable);
} else {
$connection = $this->scene->connect($connectable, $directionality);
}
$connection->setOutgoingConnectionGroupName($this->name);
return $connection;
}
}
+195 -45
View File
@@ -5,7 +5,10 @@ namespace LotGD\Core\Tests\Models;
use Doctrine\Common\Collections\ArrayCollection;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Models\Scene;
use LotGD\Core\Models\SceneConnectionGroup;
use LotGD\Core\Models\SceneConnection;
use LotGD\Core\Tests\CoreModelTestCase;
/**
@@ -31,68 +34,215 @@ class SceneModelTest extends CoreModelTestCase
$this->assertEquals("The Forest", $scene->getTitle());
$this->assertEquals("This is a very dangerous and dark forest", $scene->getDescription());
$this->assertInstanceOf(Scene::class, $scene->getParents()[0]);
$this->assertCount(1, $scene->getParents());
$this->assertCount(0, $scene->getChildren());
$em->flush();
}
/**
* Test if parent<=>child relationship is working.
*/
public function testChildParentRelationships()
public function testIfHasConnectionGroupReturnsTrueIfConnectionGroupExists()
{
$em = $this->getEntityManager();
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$parentScene = $em->getRepository(Scene::class)->find(1);
$childScene = $em->getRepository(Scene::class)->find(2);
$this->assertContains($parentScene, $childScene->getParents());
$this->assertContains($childScene, $parentScene->getChildren());
$em->flush();
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/outside"));
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/market"));
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/empty"));
}
/**
* Test if the scene can be removed.
*/
public function testMoveScene()
public function testIfHasConnectionGroupReturnsFalseIfConnectionGroupDoesNotExist()
{
$em = $this->getEntityManager();
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$parentScene1 = $em->getRepository(Scene::class)->find(1);
$parentScene2 = $em->getRepository(Scene::class)->find(4);
$this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/outside"));
$this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/market"));
$this->assertFalse($scene2->hasConnectionGroup("lotgd/tests/village/empty"));
$orphanScene = $em->getRepository(scene::class)->find(5);
$this->assertCount(0, $orphanScene->getParents());
$this->assertCount(0, $orphanScene->getChildren());
// Assign orphanScene to parentScene1 and check relationships
$orphanScene->addParent($parentScene1);
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$this->assertCount(1, $orphanScene->getParents());
$this->assertCount(3, $parentScene1->getChildren());
$this->assertContains($parentScene1, $orphanScene->getParents());
$this->assertContains($orphanScene, $parentScene1->getChildren());
$this->assertFalse($scene1->hasConnectionGroup("lotgd/tests/village/23426"));
}
// Add the scene now to parentScene2 and check relationships
$orphanScene->addParent($parentScene2);
public function testIfAddConnectionGroupWorks()
{
$connectionGroup = new SceneConnectionGroup("lotgd/tests/village/new", "New Street");
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$this->assertCount(3, $parentScene1->getChildren());
$this->assertCount(1, $parentScene2->getChildren());
$this->assertContains($parentScene2, $orphanScene->getParents());
$this->assertContains($orphanScene, $parentScene2->getChildren());
$this->assertFalse($scene->hasConnectionGroup("lotgd/tests/village/new"));
// Make an orphan out of it again
$orphanScene->setParents(new ArrayCollection());
$scene->addConnectionGroup($connectionGroup);
$this->assertCount(2, $parentScene1->getChildren());
$this->assertCount(0, $parentScene2->getChildren());
$this->assertCount(0, $orphanScene->getParents());
$this->assertNotContains($orphanScene, $parentScene1->getChildren());
$this->assertNotContains($orphanScene, $parentScene2->getChildren());
$this->getEntityManager()->flush();
$em->flush();
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/new"));
}
public function testIfAddConnectionGroupThrowsArgumentExceptionIfGroupIsAlreadyAssignedToItself()
{
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]);
$this->expectException(ArgumentException::class);
$scene->addConnectionGroup($connectionGroup);
}
public function testIfAddConnectionGroupThrowsArgumentExceptionIfGroupIsAlreadyAssignedToSomwhereElse()
{
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]);
$this->expectException(ArgumentException::class);
$scene->addConnectionGroup($connectionGroup);
}
public function testifDropConnectionGroupWorks()
{
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]);
$this->assertTrue($scene->hasConnectionGroup("lotgd/tests/village/outside"));
$scene->dropConnectionGroup($connectionGroup);
$this->getEntityManager()->flush();
$this->assertFalse($scene->hasConnectionGroup("lotgd/tests/village/outside"));
}
public function testIfDropConnectionGroupThrowsArgumentExceptionIfEntityIsRemovedFromNonOwningScene()
{
$scene = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$connectionGroup = $this->getEntityManager()->getRepository(SceneConnectionGroup::class)->findOneBy(["scene" => 1, "name" => "lotgd/tests/village/outside"]);
$this->expectException(ArgumentException::class);
$scene->dropConnectionGroup($connectionGroup);
}
public function testIfGetConnectedScenesReturnsConnectedScenes()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$this->assertCount(3, $scene1->getConnectedScenes());
$this->assertCount(1, $scene2->getConnectedScenes());
$this->assertTrue($scene1->getConnectedScenes()->contains($scene2));
$this->assertTrue($scene2->getConnectedScenes()->contains($scene1));
$this->assertFalse($scene1->getConnectedScenes()->contains($scene1));
$this->assertFalse($scene2->getConnectedScenes()->contains($scene2));
}
public function testIfIsConnectedToReturnsExpectedReturnValue()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$scene5 = $this->getEntityManager()->getRepository(Scene::class)->find(5);
$this->assertTrue($scene1->isConnectedTo($scene2));
$this->assertTrue($scene2->isConnectedTo($scene1));
$this->assertFalse($scene1->isConnectedTo($scene5));
$this->assertFalse($scene2->isConnectedTo($scene5));
$this->assertFalse($scene5->isConnectedTo($scene1));
$this->assertFalse($scene5->isConnectedTo($scene2));
}
public function testIfTwoScenesCanGetConnected()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5);
$scene1->connect($scene2);
$this->assertTrue($scene1->getConnectedScenes()->contains($scene2));
$this->assertTrue($scene2->getConnectedScenes()->contains($scene1));
$this->assertFalse($scene1->getConnectedScenes()->contains($scene1));
$this->assertFalse($scene2->getConnectedScenes()->contains($scene2));
$this->getEntityManager()->flush();
}
public function testIfASceneConnectionGroupCanGetConnectedToAScene()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5);
$scene1->getConnectionGroup("lotgd/tests/village/outside")->connect($scene2);
$this->assertTrue($scene1->isConnectedTo($scene2));
$this->assertTrue($scene2->isConnectedTo($scene1));
$this->assertFalse($scene1->isConnectedTo($scene1));
$this->assertFalse($scene2->isConnectedTo($scene2));
$this->getEntityManager()->flush();
}
public function testIfASceneCanGetConnectedToASceneConnectionGroup()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5);
$scene2->connect($scene1->getConnectionGroup("lotgd/tests/village/outside"));
$this->assertTrue($scene1->isConnectedTo($scene2));
$this->assertTrue($scene2->isConnectedTo($scene1));
$this->assertFalse($scene1->isConnectedTo($scene1));
$this->assertFalse($scene2->isConnectedTo($scene2));
$this->getEntityManager()->flush();
}
public function testIfASceneConnectionGroupCanGetConnectedToAnotherSceneConnectionGroup()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(5);
$scene2->addConnectionGroup(new SceneConnectionGroup("test/orphaned", "Orphan group"));
$scene1
->getConnectionGroup("lotgd/tests/village/outside")
->connect(
$scene2->getConnectionGroup("test/orphaned")
);
$this->assertTrue($scene1->isConnectedTo($scene2));
$this->assertTrue($scene2->isConnectedTo($scene1));
$this->assertFalse($scene1->isConnectedTo($scene1));
$this->assertFalse($scene2->isConnectedTo($scene2));
$this->getEntityManager()->flush();
}
public function testIfConnectingASceneToItselfThrowsAnException()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$this->expectException(ArgumentException::class);
$scene1->connect($scene1);
$this->expectException(ArgumentException::class);
$scene1->connect($scene1->getConnectionGroup("lotgd/tests/village/outside"));
$this->expectException(ArgumentException::class);
$scene1->getConnectionGroup("lotgd/tests/village/outside")->connect($scene1);
$this->expectException(ArgumentException::class);
$scene1->getConnectionGroup("lotgd/tests/village/outside")->connect($scene1->getConnectionGroup("lotgd/tests/village/outside"));
$this->assertFalse($scene1->isConnectedTo($scene1));
}
public function testIfConnectingASceneToAnotherAlreadyConnectedSceneThrowsAnException()
{
$scene1 = $this->getEntityManager()->getRepository(Scene::class)->find(1);
$scene2 = $this->getEntityManager()->getRepository(Scene::class)->find(2);
$this->expectException(ArgumentException::class);
$scene1->connect($scene2);
$this->expectException(ArgumentException::class);
$scene1->getConnectionGroup("lotgd/tests/village/hidden")->connect($scene2);
$this->expectException(ArgumentException::class);
$scene1->connect($scene2->getConnectionGroup("lotgd/tests/forest/category"));
$this->expectException(ArgumentException::class);
$scene1->getConnectionGroup("lotgd/tests/village/hidden")->connect($scene2->getConnectionGroup("lotgd/tests/forest/category"));
}
}
+5 -5
View File
@@ -36,10 +36,10 @@ scenes:
title: "The Weaponry"
description: "This is the place where you can buy awesome weapons"
template: "lotgd/tests/weaponry"
paths:
scene_connections:
-
scene_id: 1
child_scene_id: 2
outgoing_scene_id: 1
incoming_scene_id: 2
-
scene_id: 1
child_scene_id: 3
outgoing_scene_id: 1
incoming_scene_id: 3
+23 -3
View File
@@ -24,10 +24,30 @@ scenes:
title: "Orphan"
description: "This is an orphan scene"
template: "lotgd/tests/orphan"
paths:
scene_connection_groups:
-
scene_id: 1
child_scene_id: 2
name: "lotgd/tests/village/outside"
title: "Outside"
-
scene_id: 1
child_scene_id: 3
name: "lotgd/tests/village/market"
title: "Market"
-
scene_id: 1
name: "lotgd/tests/village/empty"
title: "Empty"
-
scene_id: 2
name: "lotgd/tests/forest/category"
title: "Empty"
scene_connections:
-
outgoing_scene_id: 1
incoming_scene_id: 2
-
outgoing_scene_id: 1
incoming_scene_id: 3
-
outgoing_scene_id: 1
incoming_scene_id: 4
+5 -5
View File
@@ -32,10 +32,10 @@ scenes:
title: "The Weaponry"
description: "This is the place where you can buy awesome weapons"
template: "lotgd/tests/weaponry"
paths:
scene_connections:
-
scene_id: 1
child_scene_id: 2
outgoing_scene_id: 1
incoming_scene_id: 2
-
scene_id: 1
child_scene_id: 3
outgoing_scene_id: 1
incoming_scene_id: 3