21 Commits

Author SHA1 Message Date
Vassyli 867843dddd Adds a GameBuilder to allow better dependency injection 2017-06-23 14:43:24 +02:00
Vassyli 329430c547 Fixed test 2017-06-12 16:00:44 +02:00
Vassyli d20a59e68a Updated composer; Added optional action title 2017-06-12 15:58:51 +02:00
Vassyli 29e474b9c1 Adds possibility to add parameters to actions. 2017-06-12 14:58:40 +02:00
Vassyli bbc960fd3d Added suggested change
Fixes #95
2017-04-25 22:31:37 +02:00
Vassyli 7e58c72526 Changes implemented to pass test. 2017-04-24 20:52:34 +02:00
Vassyli 1eeca4ef9e Adds failing test 2017-04-18 23:55:52 +02:00
Vassyli 201a3a032f Implemented suggested changes.
Fixes #94
2017-04-10 09:42:46 +02:00
Vassyli a790eab5ee Added documentation. 2017-04-10 09:42:46 +02:00
Vassyli e6e9e6e102 Added EventContextData containers. 2017-04-10 09:42:46 +02:00
Vassyli 214b1de95f Adds EventContextDataContainer 2017-04-10 09:42:46 +02:00
Vassyli f5380de501 Adds EventContext 2017-04-10 09:42:46 +02:00
Vassyli 70d29f67b8 Moved TimeKeeper.now to constructor.
Breaks BC intentionally.
2017-04-10 09:24:18 +02:00
Vassyli a33473d435 Add possibility to give gameOffsetSeconds also as a negative number 2017-04-10 09:24:18 +02:00
Vassyli d126b0207f Add tests for isNewDay 2017-04-10 09:24:18 +02:00
Vassyli f201784291 Changed TimeKeeper to keep a permanent "now" state. 2017-04-10 09:24:18 +02:00
Vassyli 39b9ec318a Changed isNewDay to accept null instead of DateTime
Fixes #93
2017-04-10 09:24:18 +02:00
Vassyli 5668c08f45 Renamed ViewpointRestorationPoint to ViewpointSnapshot 2017-03-31 08:55:00 +02:00
Vassyli a739aed94a Added simple test and fixed a bug uncovered by it. 2017-03-27 09:52:09 +02:00
Vassyli d408aa0755 Fixed Typo 2017-03-24 16:32:38 +01:00
Vassyli af98ab0f36 Added viewpoint restoration points
Added an API for model viewpoint to create a restoration point that can be saved. Changing the scene from the restoration point can replay a scene without doing the calculations done to render it.
2017-03-18 16:13:23 +01:00
27 changed files with 1323 additions and 248 deletions
Generated
+148 -135
View File
@@ -8,25 +8,29 @@
"packages": [
{
"name": "behat/transliterator",
"version": "v1.1.0",
"version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/Behat/Transliterator.git",
"reference": "868e05be3a9f25ba6424c2dd4849567f50715003"
"reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Behat/Transliterator/zipball/868e05be3a9f25ba6424c2dd4849567f50715003",
"reference": "868e05be3a9f25ba6424c2dd4849567f50715003",
"url": "https://api.github.com/repos/Behat/Transliterator/zipball/826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c",
"reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"chuyskywalker/rolling-curl": "^3.1",
"php-yaoi/php-yaoi": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
"dev-master": "1.2-dev"
}
},
"autoload": {
@@ -44,20 +48,20 @@
"slug",
"transliterator"
],
"time": "2015-09-28T16:26:35+00:00"
"time": "2017-04-04T11:38:05+00:00"
},
{
"name": "composer/ca-bundle",
"version": "1.0.6",
"version": "1.0.7",
"source": {
"type": "git",
"url": "https://github.com/composer/ca-bundle.git",
"reference": "a795611394b3c05164fd0eb291b492b39339cba4"
"reference": "b17e6153cb7f33c7e44eb59578dc12eee5dc8e12"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/a795611394b3c05164fd0eb291b492b39339cba4",
"reference": "a795611394b3c05164fd0eb291b492b39339cba4",
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/b17e6153cb7f33c7e44eb59578dc12eee5dc8e12",
"reference": "b17e6153cb7f33c7e44eb59578dc12eee5dc8e12",
"shasum": ""
},
"require": {
@@ -66,6 +70,7 @@
"php": "^5.3.2 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.5",
"psr/log": "^1.0",
"symfony/process": "^2.5 || ^3.0"
},
@@ -102,27 +107,27 @@
"ssl",
"tls"
],
"time": "2016-11-02T18:11:27+00:00"
"time": "2017-03-06T11:59:08+00:00"
},
{
"name": "composer/composer",
"version": "1.3.2",
"version": "1.4.2",
"source": {
"type": "git",
"url": "https://github.com/composer/composer.git",
"reference": "e7569edb4a5eadcbb2e4ad5ed753282260f281df"
"reference": "489e09ee6c3ba431fbeeef9147afdaeb6f91b647"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/composer/zipball/e7569edb4a5eadcbb2e4ad5ed753282260f281df",
"reference": "e7569edb4a5eadcbb2e4ad5ed753282260f281df",
"url": "https://api.github.com/repos/composer/composer/zipball/489e09ee6c3ba431fbeeef9147afdaeb6f91b647",
"reference": "489e09ee6c3ba431fbeeef9147afdaeb6f91b647",
"shasum": ""
},
"require": {
"composer/ca-bundle": "^1.0",
"composer/semver": "^1.0",
"composer/spdx-licenses": "^1.0",
"justinrainbow/json-schema": "^1.6 || ^2.0 || ^3.0 || ^4.0",
"justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0",
"php": "^5.3.2 || ^7.0",
"psr/log": "^1.0",
"seld/cli-prompt": "^1.0",
@@ -148,7 +153,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
"dev-master": "1.4-dev"
}
},
"autoload": {
@@ -179,7 +184,7 @@
"dependency",
"package"
],
"time": "2017-01-27T17:23:42+00:00"
"time": "2017-05-17T06:17:53+00:00"
},
{
"name": "composer/semver",
@@ -245,16 +250,16 @@
},
{
"name": "composer/spdx-licenses",
"version": "1.1.5",
"version": "1.1.6",
"source": {
"type": "git",
"url": "https://github.com/composer/spdx-licenses.git",
"reference": "96c6a07b05b716e89a44529d060bc7f5c263cb13"
"reference": "2603a0d7ddc00a015deb576fa5297ca43dee6b1c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/spdx-licenses/zipball/96c6a07b05b716e89a44529d060bc7f5c263cb13",
"reference": "96c6a07b05b716e89a44529d060bc7f5c263cb13",
"url": "https://api.github.com/repos/composer/spdx-licenses/zipball/2603a0d7ddc00a015deb576fa5297ca43dee6b1c",
"reference": "2603a0d7ddc00a015deb576fa5297ca43dee6b1c",
"shasum": ""
},
"require": {
@@ -302,7 +307,7 @@
"spdx",
"validator"
],
"time": "2016-09-28T07:17:45+00:00"
"time": "2017-04-03T19:08:52+00:00"
},
{
"name": "d11wtq/boris",
@@ -942,20 +947,20 @@
},
{
"name": "gedmo/doctrine-extensions",
"version": "v2.4.26",
"version": "v2.4.29",
"source": {
"type": "git",
"url": "https://github.com/Atlantic18/DoctrineExtensions.git",
"reference": "983dd85d6860f87fb7dffd0d9f7ad1462e20a09d"
"reference": "f65c02eae3bff1aa57709ea4c8ca26947df95b9c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Atlantic18/DoctrineExtensions/zipball/983dd85d6860f87fb7dffd0d9f7ad1462e20a09d",
"reference": "983dd85d6860f87fb7dffd0d9f7ad1462e20a09d",
"url": "https://api.github.com/repos/Atlantic18/DoctrineExtensions/zipball/f65c02eae3bff1aa57709ea4c8ca26947df95b9c",
"reference": "f65c02eae3bff1aa57709ea4c8ca26947df95b9c",
"shasum": ""
},
"require": {
"behat/transliterator": "~1.0",
"behat/transliterator": "~1.2",
"doctrine/common": "~2.4",
"php": ">=5.3.2"
},
@@ -963,9 +968,8 @@
"doctrine/common": ">=2.5.0",
"doctrine/mongodb-odm": ">=1.0.2",
"doctrine/orm": ">=2.5.0",
"phpunit/phpunit": "~4.4",
"phpunit/phpunit-mock-objects": "~2.3",
"symfony/yaml": "~2.6"
"phpunit/phpunit": "*",
"symfony/yaml": "~2.6|~3.0"
},
"suggest": {
"doctrine/mongodb-odm": "to use the extensions with the MongoDB ODM",
@@ -1017,28 +1021,29 @@
"tree",
"uploadable"
],
"time": "2016-12-21T13:46:54+00:00"
"time": "2017-05-29T17:33:48+00:00"
},
{
"name": "justinrainbow/json-schema",
"version": "4.1.0",
"version": "5.2.1",
"source": {
"type": "git",
"url": "https://github.com/justinrainbow/json-schema.git",
"reference": "d39c56a46b3ebe1f3696479966cd2b9f50aaa24f"
"reference": "429be236f296ca249d61c65649cdf2652f4a5e80"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/d39c56a46b3ebe1f3696479966cd2b9f50aaa24f",
"reference": "d39c56a46b3ebe1f3696479966cd2b9f50aaa24f",
"url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/429be236f296ca249d61c65649cdf2652f4a5e80",
"reference": "429be236f296ca249d61c65649cdf2652f4a5e80",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.1",
"json-schema/json-schema-test-suite": "1.2.0",
"phpdocumentor/phpdocumentor": "~2",
"phpdocumentor/phpdocumentor": "^2.7",
"phpunit/phpunit": "^4.8.22"
},
"bin": [
@@ -1047,7 +1052,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
"dev-master": "5.0.x-dev"
}
},
"autoload": {
@@ -1083,20 +1088,20 @@
"json",
"schema"
],
"time": "2016-12-22T16:43:46+00:00"
"time": "2017-05-16T21:06:09+00:00"
},
{
"name": "monolog/monolog",
"version": "1.22.0",
"version": "1.22.1",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "bad29cb8d18ab0315e6c477751418a82c850d558"
"reference": "1e044bc4b34e91743943479f1be7a1d5eb93add0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/bad29cb8d18ab0315e6c477751418a82c850d558",
"reference": "bad29cb8d18ab0315e6c477751418a82c850d558",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/1e044bc4b34e91743943479f1be7a1d5eb93add0",
"reference": "1e044bc4b34e91743943479f1be7a1d5eb93add0",
"shasum": ""
},
"require": {
@@ -1161,7 +1166,7 @@
"logging",
"psr-3"
],
"time": "2016-11-26T00:15:39+00:00"
"time": "2017-03-13T07:08:03+00:00"
},
{
"name": "psr/log",
@@ -1212,16 +1217,16 @@
},
{
"name": "seld/cli-prompt",
"version": "1.0.2",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/cli-prompt.git",
"reference": "8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4"
"reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4",
"reference": "8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4",
"url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/a19a7376a4689d4d94cab66ab4f3c816019ba8dd",
"reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd",
"shasum": ""
},
"require": {
@@ -1256,25 +1261,28 @@
"input",
"prompt"
],
"time": "2016-04-18T09:31:41+00:00"
"time": "2017-03-18T11:32:45+00:00"
},
{
"name": "seld/jsonlint",
"version": "1.5.0",
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/jsonlint.git",
"reference": "19495c181d6d53a0a13414154e52817e3b504189"
"reference": "791f8c594f300d246cdf01c6b3e1e19611e301d8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/19495c181d6d53a0a13414154e52817e3b504189",
"reference": "19495c181d6d53a0a13414154e52817e3b504189",
"url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/791f8c594f300d246cdf01c6b3e1e19611e301d8",
"reference": "791f8c594f300d246cdf01c6b3e1e19611e301d8",
"shasum": ""
},
"require": {
"php": "^5.3 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.5"
},
"bin": [
"bin/jsonlint"
],
@@ -1302,7 +1310,7 @@
"parser",
"validator"
],
"time": "2016-11-14T17:59:58+00:00"
"time": "2017-03-06T16:42:24+00:00"
},
{
"name": "seld/phar-utils",
@@ -1350,16 +1358,16 @@
},
{
"name": "symfony/console",
"version": "v3.2.4",
"version": "v3.3.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "0e5e6899f82230fcb1153bcaf0e106ffaa44b870"
"reference": "70d2a29b2911cbdc91a7e268046c395278238b2e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/0e5e6899f82230fcb1153bcaf0e106ffaa44b870",
"reference": "0e5e6899f82230fcb1153bcaf0e106ffaa44b870",
"url": "https://api.github.com/repos/symfony/console/zipball/70d2a29b2911cbdc91a7e268046c395278238b2e",
"reference": "70d2a29b2911cbdc91a7e268046c395278238b2e",
"shasum": ""
},
"require": {
@@ -1367,10 +1375,16 @@
"symfony/debug": "~2.8|~3.0",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"symfony/dependency-injection": "<3.3"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~3.3",
"symfony/dependency-injection": "~3.3",
"symfony/event-dispatcher": "~2.8|~3.0",
"symfony/filesystem": "~2.8|~3.0",
"symfony/http-kernel": "~2.8|~3.0",
"symfony/process": "~2.8|~3.0"
},
"suggest": {
@@ -1382,7 +1396,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
"dev-master": "3.3-dev"
}
},
"autoload": {
@@ -1409,20 +1423,20 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2017-02-16T14:07:22+00:00"
"time": "2017-06-02T19:24:58+00:00"
},
{
"name": "symfony/debug",
"version": "v3.2.4",
"version": "v3.3.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "9b98854cb45bc59d100b7d4cc4cf9e05f21026b9"
"reference": "e9c50482841ef696e8fa1470d950a79c8921f45d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/9b98854cb45bc59d100b7d4cc4cf9e05f21026b9",
"reference": "9b98854cb45bc59d100b7d4cc4cf9e05f21026b9",
"url": "https://api.github.com/repos/symfony/debug/zipball/e9c50482841ef696e8fa1470d950a79c8921f45d",
"reference": "e9c50482841ef696e8fa1470d950a79c8921f45d",
"shasum": ""
},
"require": {
@@ -1433,13 +1447,12 @@
"symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
},
"require-dev": {
"symfony/class-loader": "~2.8|~3.0",
"symfony/http-kernel": "~2.8|~3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
"dev-master": "3.3-dev"
}
},
"autoload": {
@@ -1466,20 +1479,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2017-02-16T16:34:18+00:00"
"time": "2017-06-01T21:01:25+00:00"
},
{
"name": "symfony/filesystem",
"version": "v3.2.4",
"version": "v3.3.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
"reference": "a0c6ef2dc78d33b58d91d3a49f49797a184d06f4"
"reference": "c709670bf64721202ddbe4162846f250735842c0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/a0c6ef2dc78d33b58d91d3a49f49797a184d06f4",
"reference": "a0c6ef2dc78d33b58d91d3a49f49797a184d06f4",
"url": "https://api.github.com/repos/symfony/filesystem/zipball/c709670bf64721202ddbe4162846f250735842c0",
"reference": "c709670bf64721202ddbe4162846f250735842c0",
"shasum": ""
},
"require": {
@@ -1488,7 +1501,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
"dev-master": "3.3-dev"
}
},
"autoload": {
@@ -1515,20 +1528,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
"time": "2017-01-08T20:47:33+00:00"
"time": "2017-05-28T14:08:56+00:00"
},
{
"name": "symfony/finder",
"version": "v3.2.4",
"version": "v3.3.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "8c71141cae8e2957946b403cc71a67213c0380d6"
"reference": "baea7f66d30854ad32988c11a09d7ffd485810c4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/8c71141cae8e2957946b403cc71a67213c0380d6",
"reference": "8c71141cae8e2957946b403cc71a67213c0380d6",
"url": "https://api.github.com/repos/symfony/finder/zipball/baea7f66d30854ad32988c11a09d7ffd485810c4",
"reference": "baea7f66d30854ad32988c11a09d7ffd485810c4",
"shasum": ""
},
"require": {
@@ -1537,7 +1550,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
"dev-master": "3.3-dev"
}
},
"autoload": {
@@ -1564,20 +1577,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:32:22+00:00"
"time": "2017-06-01T21:01:25+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.3.0",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
"reference": "f29dca382a6485c3cbe6379f0c61230167681937"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
"reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f29dca382a6485c3cbe6379f0c61230167681937",
"reference": "f29dca382a6485c3cbe6379f0c61230167681937",
"shasum": ""
},
"require": {
@@ -1589,7 +1602,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
"dev-master": "1.4-dev"
}
},
"autoload": {
@@ -1623,20 +1636,20 @@
"portable",
"shim"
],
"time": "2016-11-14T01:06:16+00:00"
"time": "2017-06-09T14:24:12+00:00"
},
{
"name": "symfony/process",
"version": "v3.2.4",
"version": "v3.3.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856"
"reference": "8e30690c67aafb6c7992d6d8eb0d707807dd3eaf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856",
"reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856",
"url": "https://api.github.com/repos/symfony/process/zipball/8e30690c67aafb6c7992d6d8eb0d707807dd3eaf",
"reference": "8e30690c67aafb6c7992d6d8eb0d707807dd3eaf",
"shasum": ""
},
"require": {
@@ -1645,7 +1658,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
"dev-master": "3.3-dev"
}
},
"autoload": {
@@ -1672,20 +1685,20 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2017-02-16T14:07:22+00:00"
"time": "2017-05-22T12:32:03+00:00"
},
{
"name": "symfony/yaml",
"version": "v3.2.4",
"version": "v3.3.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8"
"reference": "9752a30000a8ca9f4b34b5227d15d0101b96b063"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/9724c684646fcb5387d579b4bfaa63ee0b0c64c8",
"reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8",
"url": "https://api.github.com/repos/symfony/yaml/zipball/9752a30000a8ca9f4b34b5227d15d0101b96b063",
"reference": "9752a30000a8ca9f4b34b5227d15d0101b96b063",
"shasum": ""
},
"require": {
@@ -1700,7 +1713,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
"dev-master": "3.3-dev"
}
},
"autoload": {
@@ -1727,7 +1740,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2017-02-16T22:46:52+00:00"
"time": "2017-06-02T22:05:06+00:00"
}
],
"packages-dev": [
@@ -1784,16 +1797,16 @@
},
{
"name": "myclabs/deep-copy",
"version": "1.6.0",
"version": "1.6.1",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe"
"reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5a5a9fc8025a08d8919be87d6884d5a92520cefe",
"reference": "5a5a9fc8025a08d8919be87d6884d5a92520cefe",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8e6e04167378abf1ddb4d3522d8755c5fd90d102",
"reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102",
"shasum": ""
},
"require": {
@@ -1822,7 +1835,7 @@
"object",
"object graph"
],
"time": "2017-01-26T22:05:40+00:00"
"time": "2017-04-12T18:52:22+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@@ -1972,27 +1985,27 @@
},
{
"name": "phpspec/prophecy",
"version": "v1.6.2",
"version": "v1.7.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
"reference": "93d39f1f7f9326d746203c7c056f300f7f126073"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
"reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073",
"reference": "93d39f1f7f9326d746203c7c056f300f7f126073",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.3|^7.0",
"phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
"sebastian/comparator": "^1.1",
"sebastian/recursion-context": "^1.0|^2.0"
"sebastian/comparator": "^1.1|^2.0",
"sebastian/recursion-context": "^1.0|^2.0|^3.0"
},
"require-dev": {
"phpspec/phpspec": "^2.0",
"phpspec/phpspec": "^2.5|^3.2",
"phpunit/phpunit": "^4.8 || ^5.6.5"
},
"type": "library",
@@ -2031,7 +2044,7 @@
"spy",
"stub"
],
"time": "2016-11-21T14:58:47+00:00"
"time": "2017-03-02T20:05:34+00:00"
},
{
"name": "phpunit/dbunit",
@@ -2090,16 +2103,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "4.0.7",
"version": "4.0.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "09e2277d14ea467e5a984010f501343ef29ffc69"
"reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/09e2277d14ea467e5a984010f501343ef29ffc69",
"reference": "09e2277d14ea467e5a984010f501343ef29ffc69",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
"reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d",
"shasum": ""
},
"require": {
@@ -2149,7 +2162,7 @@
"testing",
"xunit"
],
"time": "2017-03-01T09:12:17+00:00"
"time": "2017-04-02T07:44:40+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -2339,16 +2352,16 @@
},
{
"name": "phpunit/phpunit",
"version": "5.7.15",
"version": "5.7.20",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "b99112aecc01f62acf3d81a3f59646700a1849e5"
"reference": "3cb94a5f8c07a03c8b7527ed7468a2926203f58b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b99112aecc01f62acf3d81a3f59646700a1849e5",
"reference": "b99112aecc01f62acf3d81a3f59646700a1849e5",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3cb94a5f8c07a03c8b7527ed7468a2926203f58b",
"reference": "3cb94a5f8c07a03c8b7527ed7468a2926203f58b",
"shasum": ""
},
"require": {
@@ -2366,7 +2379,7 @@
"phpunit/php-timer": "^1.0.6",
"phpunit/phpunit-mock-objects": "^3.2",
"sebastian/comparator": "^1.2.4",
"sebastian/diff": "~1.2",
"sebastian/diff": "^1.4.3",
"sebastian/environment": "^1.3.4 || ^2.0",
"sebastian/exporter": "~2.0",
"sebastian/global-state": "^1.1",
@@ -2417,7 +2430,7 @@
"testing",
"xunit"
],
"time": "2017-03-02T15:22:43+00:00"
"time": "2017-05-22T07:42:55+00:00"
},
{
"name": "phpunit/phpunit-mock-objects",
@@ -2480,23 +2493,23 @@
},
{
"name": "sebastian/code-unit-reverse-lookup",
"version": "1.0.0",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
"reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe"
"reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
"reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
"url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
"reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
"shasum": ""
},
"require": {
"php": ">=5.6"
"php": "^5.6 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "~5"
"phpunit/phpunit": "^5.7 || ^6.0"
},
"type": "library",
"extra": {
@@ -2521,7 +2534,7 @@
],
"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-13T06:45:14+00:00"
"time": "2017-03-04T06:30:41+00:00"
},
{
"name": "sebastian/comparator",
@@ -2589,23 +2602,23 @@
},
{
"name": "sebastian/diff",
"version": "1.4.1",
"version": "1.4.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
"reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
"reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
"reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4",
"reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
"php": "^5.3.3 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "~4.8"
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
},
"type": "library",
"extra": {
@@ -2637,7 +2650,7 @@
"keywords": [
"diff"
],
"time": "2015-12-08T07:14:41+00:00"
"time": "2017-05-22T07:24:03+00:00"
},
{
"name": "sebastian/environment",
+42 -2
View File
@@ -11,15 +11,21 @@ class Action
{
protected $id;
protected $destinationSceneId;
protected $title = null;
protected $parameters = [];
/**
* Construct a new action with the specified Scene as its destination.
* @param int $destinationSceneId
* @param string|null $title
* @param array $parameters
*/
public function __construct(int $destinationSceneId)
public function __construct(int $destinationSceneId, ?string $title = null, array $parameters = [])
{
$this->id = bin2hex(random_bytes(8));
$this->destinationSceneId = $destinationSceneId;
$this->title = $title;
$this->parameters = $parameters;
}
/**
@@ -35,10 +41,44 @@ class Action
/**
* Return the database ID of the destination scene, where the user will
* go if they take this action.
* @return string
* @return int
*/
public function getDestinationSceneId(): int
{
return $this->destinationSceneId;
}
/**
* @return null|string
*/
public function getTitle(): ?string
{
return $this->title;
}
/**
* @return null|string
*/
public function setTitle(?string $title)
{
$this->title = $title;
}
/**
* Returns all parameters for this action
* @return array
*/
public function getParameters(): array
{
return $this->parameters;
}
/**
* Sets all parameters for this action
* @param array $parameters
*/
public function setParameters(array $parameters): void
{
$this->parameters = $parameters;
}
}
+6 -1
View File
@@ -64,7 +64,12 @@ class Bootstrap
$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;
}
+3 -1
View File
@@ -1,6 +1,8 @@
<?php
declare(strict_types=1);
namespace LotGD\Core;
use LotGD\Core\Events\EventContext;
interface EventHandler
{
@@ -14,5 +16,5 @@ interface EventHandler
* the next handler is called. Otherwise, return null. Any changes made will be propogated
* to the event publisher as well.
*/
public static function handleEvent(Game $g, string $event, array &$context);
public static function handleEvent(Game $g, EventContext $context): EventContext;
}
+14 -2
View File
@@ -5,11 +5,13 @@ namespace LotGD\Core;
use Doctrine\ORM\EntityManagerInterface;
use LotGD\Core\Events\EventContext;
use LotGD\Core\Models\EventSubscription;
use LotGD\Core\EventHandler;
use LotGD\Core\Exceptions\ClassNotFoundException;
use LotGD\Core\Exceptions\SubscriptionNotFoundException;
use LotGD\Core\Exceptions\WrongTypeException;
use LotGD\Core\Events\EventContextData;
/**
* Manages a simple publish/subscribe system based on regular expressions
@@ -33,8 +35,10 @@ class EventManager
* are run.
*
* @param string $event The name of the event to publish.
* @param EventContextData $contextData The Data context
* @return EventContextData The changed data.
*/
public function publish(string $event, array &$context)
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
@@ -49,9 +53,17 @@ class EventManager
if (preg_match($s->getPattern(), $event)) {
$class = $s->getClass();
$this->g->getLogger()->addDebug(" Handling with {$class}.");
$c = $class::handleEvent($this->g, $event, $context);
$eventContext = new EventContext($event, $s->getPattern(), $contextData);
$returnedEventContext = $class::handleEvent($this->g, $eventContext);
// 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();
}
}
return $contextData;
}
/**
+109
View File
@@ -0,0 +1,109 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Events;
/**
* Class EventContext
* @package LotGD\Core
* @immutable
*/
class EventContext
{
private $matchingPattern;
private $event;
private $data;
/**
* EventContext constructor.
* @param string $event The published event
* @param string $matchingPattern The matching pattern
* @param EventContextData $data
*/
public function __construct(
string $event,
string $matchingPattern,
EventContextData $data
) {
$this->event = $event;
$this->matchingPattern = $matchingPattern;
$this->data = $data;
}
/**
* Returns the event of this context.
* @return string
*/
public function getEvent(): string
{
return $this->event;
}
/**
* Returns the matching pattern of this context.
* @return string
*/
public function getMatchingPattern(): string
{
return $this->matchingPattern;
}
/**
* Checks if the data in this event context has a certain subtype.
* @param string $type FQCN to be checked.
* @return bool
*/
public function hasDataType(string $type): bool
{
return $this->data instanceof $type ? true : false;
}
/**
* Returns the immutable data container.
* @return EventContextData
*/
public function getData(): EventContextData
{
return $this->data;
}
/**
* Returns a data field
* @param $field
* @return mixed
*/
public function getDataField($field)
{
return $this->data->get($field);
}
/**
* Sets a data field
* @param $field
* @param $value
*/
public function setDataField($field, $value)
{
$this->data = $this->data->set($field, $value);
}
/**
* Sets multiple data fields at once.
* @param $data
*/
public function setDataFields($data)
{
$this->data = $this->data->setFields($data);
}
/**
* Checks if given original data is the same as currently held within this context.
* @param EventContextData $originalData
* @return bool
*/
public function hasDataChanged(EventContextData $originalData): bool
{
return $this->data === $originalData ? false : true;
}
}
+136
View File
@@ -0,0 +1,136 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Events;
use LotGD\Core\Exceptions\ArgumentException;
/**
* 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
{
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."
);
}
}
+69
View File
@@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Events;
use Doctrine\Common\Util\Debug;
use Doctrine\DBAL\Schema\View;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Models\Character;
use LotGD\Core\Models\Scene;
use LotGD\Core\Models\Viewpoint;
/**
* NavigateToScene data container which can be used for navigational events.
*
* Fields are:
* referrer Scene|null
* viewpoint Viewpoint
* scene Scene
* parameters array
* redirect Scene|null
* @package LotGD\Core\Events
*/
class NavigateToSceneData extends EventContextData
{
/**
* NavigateToScene constructor.
* @param array $data Must contain fields referrer, viewpoint, scene, parameters and redirect; none more.
* @throws ArgumentException
*/
protected function __construct(array $data)
{
$mustHaveForm = ["referrer", "viewpoint", "scene", "parameters", "redirect"];
$doesHaveForm = array_keys($data);
sort($mustHaveForm); sort($doesHaveForm);
if ($doesHaveForm !== $mustHaveForm) {
throw new ArgumentException("A new NavigateToScene event must have referrer, viewpoint, scene, parameters and redirect.");
}
if ($data["referrer"] instanceof Scene === false and $data["referrer"] !== null) {
throw new ArgumentException(sprintf(
"data[referrer] must be an instance of %s, %s given.",
Scene::class,
get_class($data["referrer"])
));
}
if ($data["scene"] instanceof Scene === false) {
throw new ArgumentException(sprintf(
"data[scene] must be an instance of %s, %s given.",
Scene::class,
get_class($data["scene"])
));
}
if ($data["viewpoint"] instanceof Viewpoint === false) {
throw new ArgumentException(sprintf(
"data[viewpoint] must be an instance of %s, %s given.",
Viewpoint::class,
get_class($data["viewpoint"])
));
}
parent::__construct($data);
}
}
+50
View File
@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Events;
use LotGD\Core\Exceptions\ArgumentException;
use LotGD\Core\Models\Character;
use LotGD\Core\Models\Scene;
/**
* NewViewpoint data container which is used if no scene has ever been visited.
*
* Fields are:
* character Character
* scene Scene|null
* @package LotGD\Core\Events
*/
class NewViewpointData extends EventContextData
{
/**
* NewViewpoint constructor.
* @param array $data
* @throws ArgumentException In case $data contains invalid data.
*/
protected function __construct(array $data)
{
if (array_keys($data) !== ["character", "scene"]) {
throw new ArgumentException("A NewViewpoint event must have only character and scene.");
}
if (!$data["character"] instanceof Character) {
throw new ArgumentException(sprintf(
"NewViewpoint data[character] must be an instance of %s, %s given.",
Character::class,
get_class($data)
));
}
if ($data["scene"] !== null and !$data["scene"] instanceof Scene) {
throw new ArgumentException(sprintf(
"NewViewpoint data[scene] must be an instance of %s or null, %s given.",
Scene::class,
get_class($data)
));
}
parent::__construct($data);
}
}
+12
View File
@@ -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
{
}
+57 -22
View File
@@ -3,7 +3,10 @@ declare (strict_types=1);
namespace LotGD\Core;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use LotGD\Core\Events\NavigateToSceneData;
use LotGD\Core\Events\NewViewpointData;
use Monolog\Logger;
use LotGD\Core\Models\{
@@ -82,24 +85,36 @@ class Game
*/
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.
@@ -115,24 +130,36 @@ class Game
*/
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
@@ -152,7 +179,7 @@ class Game
$gameEpoch = $this->getConfiguration()->getGameEpoch();
$gameOffsetSeconds = $this->getConfiguration()->getGameOffsetSeconds();
$gameDaysPerDay = $this->getConfiguration()->getGameDaysPerDay();
$this->timeKeeper = new TimeKeeper($gameEpoch, $gameOffsetSeconds, $gameDaysPerDay);
$this->timeKeeper = new TimeKeeper($gameEpoch, new DateTime(), $gameOffsetSeconds, $gameDaysPerDay);
}
return $this->timeKeeper;
}
@@ -191,13 +218,14 @@ class Game
if ($v === null) {
// No viewpoint set up for this user. Run the hook to find the default
// scene.
$context = [
$contextData = NewViewpointData::create([
'character' => $this->getCharacter(),
'scene' => null
];
$this->getEventManager()->publish('h/lotgd/core/default-scene', $context);
]);
$s = $context['scene'];
$contextData = $this->getEventManager()->publish('h/lotgd/core/default-scene', $contextData);
$s = $contextData->get("scene");
if ($s === null) {
throw new InvalidConfigurationException("No subscriber to h/lotgd/core/default-scene returned a scene.");
}
@@ -291,17 +319,18 @@ 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.
$context = [
$contextData = NavigateToSceneData::create([
'referrer' => $referrer,
'viewpoint' => $viewpoint,
'scene' => $scene,
'parameters' => $parameters,
'redirect' => null
];
$hook = 'h/lotgd/core/navigate-to/' . $scene->getTemplate();
$this->getEventManager()->publish($hook, $context);
]);
$scene = $context['redirect'];
$hook = 'h/lotgd/core/navigate-to/' . $scene->getTemplate();
$contextData = $this->getEventManager()->publish($hook, $contextData);
$scene = $contextData->get('redirect');
if ($scene !== null) {
$id = $scene->getId();
$this->getLogger()->debug("Redirecting to sceneId={$id}");
@@ -328,6 +357,7 @@ class Game
if ($action === null) {
throw new ActionNotFoundException("Invalid actionId={$actionId} for current viewpoint.");
}
$actionParameters = $action->getParameters();
$sceneId = $action->getDestinationSceneId();
$scene = $this->getEntityManager()->getRepository(Scene::class)->find([
@@ -336,7 +366,12 @@ class Game
if ($scene == null) {
throw new SceneNotFoundException("Cannot find sceneId={$sceneId} specified by actionId={$actionId}.");
}
// action parameters overwrite other parameters since the former cannot be changed by the user
$parameters = array_merge($parameters, $actionParameters);
$this->navigateToScene($scene, $parameters);
$v->save($this->getEntityManager());
}
}
+156
View File
@@ -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;
}
}
+33 -1
View File
@@ -56,7 +56,7 @@ class Viewpoint implements CreateableInterface
}
/**
* Copies the static data from a scene to this Viewpoint entity
* Copies the static data from a scene to this Viewpoint entity.
* @param \LotGD\Core\Models\Scene $scene
*/
public function changeFromScene(Scene $scene)
@@ -71,6 +71,38 @@ class Viewpoint implements CreateableInterface
$this->setData([]);
}
/**
* Returns a restoration point that can be used to reconstruct the current viewpoint.
* @return ViewpointSnapshot
*/
public function getSnapshot(): ViewpointSnapshot
{
$snapshot = new ViewpointSnapshot(
$this->getTitle(),
$this->getDescription(),
$this->getTemplate(),
$this->getActionGroups(),
$this->getAttachments(),
$this->getData()
);
return $snapshot;
}
/**
* Changes the current viewpoint to the state saved in the given restoration point.
* @param ViewpointSnapshot $snapshot
*/
public function changeFromSnapshot(ViewpointSnapshot $snapshot)
{
$this->setTitle($snapshot->getTitle());
$this->setDescription($snapshot->getDescription());
$this->setTemplate($snapshot->getTemplate());
$this->setActionGroups($snapshot->getActionGroups());
$this->setAttachments($snapshot->getAttachments());
$this->setData($snapshot->getData());
}
/**
* Sets the template scene used to create this viewpoint.
* @param Scene $scene
+98
View File
@@ -0,0 +1,98 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
/**
* Represents a complete set of viewpoint data used to restore a saved viewpoint.
* @package LotGD\Core\Models
*/
class ViewpointSnapshot
{
private $title;
private $description;
private $template;
private $actionGroups;
private $attachments;
private $data;
/**
* ViewpointRestorationPoint constructor.
* @param string $title
* @param string $description
* @param string $template
* @param array $actionGroups
* @param array $attachments
* @param array $data
*/
public function __construct(
string $title,
string $description,
string $template,
array $actionGroups,
array $attachments,
array $data
)
{
$this->title = $title;
$this->description = $description;
$this->template = $template;
$this->actionGroups = $actionGroups;
$this->attachments = $attachments;
$this->data = $data;
}
/**
* Title of the viewpoint.
* @return string
*/
public function getTitle(): string
{
return $this->title;
}
/**
* Description of the viewpoint.
* @return string
*/
public function getDescription(): string
{
return $this->description;
}
/**
* Template of the viewpoint.
* @return string
*/
public function getTemplate(): string
{
return $this->template;
}
/**
* Action groups of the viewpoint.
* @return array
*/
public function getActionGroups(): array
{
return $this->actionGroups;
}
/**
* Attachements of the viewpoint.
* @return array
*/
public function getAttachments(): array
{
return $this->attachments;
}
/**
* Date of the viewpoint.
* @return array
*/
public function getData(): array
{
return $this->data;
}
}
-12
View File
@@ -9,18 +9,6 @@ use LotGD\Core\Models\Module as ModuleModel;
*/
interface Module extends EventHandler
{
/**
* Called when an event is published that is handled by this class.
*
* @param Game $g The game.
* @param string $event Name of this event.
* @param array $context Arbitrary dictionary representing context around this event.
* @return array|null Return an array if you want to make changes to the $context before
* the next handler is called. Otherwise, return null. Any changes made will be propogated
* to the event publisher as well.
*/
public static function handleEvent(Game $g, string $event, array &$context);
/**
* Lifecycle method called when this module is initially installed. Use
* this method to perform one-time setup operations like adding tables
+12 -7
View File
@@ -3,13 +3,13 @@ declare (strict_types=1);
namespace LotGD\Core;
use Composer\Package\PackageInterface;
use Doctrine\ORM\EntityManagerInterface;
use Throwable;
use LotGD\Core\PackageConfiguration;
use LotGD\Core\Exceptions\KeyNotFoundException;
use LotGD\Core\Exceptions\ClassNotFoundException;
use LotGD\Core\Exceptions\ModuleAlreadyExistsException;
use LotGD\Core\Exceptions\ModuleDoesNotExistException;
use LotGD\Core\Exceptions\SubscriptionNotFoundException;
use LotGD\Core\Exceptions\WrongTypeException;
use LotGD\Core\Models\Module as ModuleModel;
/**
@@ -52,7 +52,6 @@ class ModuleManager
// TODO: handle error cases here.
$this->g->getLogger()->debug("Creating module model for {$name}");
$m = new ModuleModel($name);
$m->save($this->g->getEntityManager());
$class = $library->getRootNamespace() . 'Module';
try {
@@ -77,8 +76,14 @@ class ModuleManager
// Run the module's onRegister handler.
$this->g->getLogger()->debug("Calling {$class}::onRegister");
$class::onRegister($this->g, $m);
$m->save($this->g->getEntityManager());
try {
$class::onRegister($this->g, $m);
$m->save($this->g->getEntityManager());
} catch (Throwable $e) {
$this->g->getLogger()->error("Calling {$class}::onRegister failed with exception: {$e->getMessage()}");
unset($m);
}
}
}
+32 -16
View File
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace LotGD\Core;
use DateTime;
use LotGD\Core\Exceptions\ArgumentException;
/**
* Configurable way to convert back and forth between real time and game time.
@@ -22,18 +23,33 @@ class TimeKeeper
private $secondsPerGameMinute;
private $secondsPerGameSecond;
private $now;
/**
* Construct a TimeKeeper with required configuration.
* @param DateTime $gameEpoch When in real time is game day 0.
* @param DateTime $now The current time.
* @param int $gameOffsetSeconds How many seconds from midnight on the epoch should the first game day start.
* @param int $gameDaysPerDay How many game days are in one real day.
*/
public function __construct(DateTime $gameEpoch, int $gameOffsetSeconds, int $gameDaysPerDay)
{
public function __construct(
DateTime $gameEpoch,
DateTime $now,
int $gameOffsetSeconds,
int $gameDaysPerDay
) {
$gameEpochCopy = clone($gameEpoch);
$this->adjustedEpoch = $gameEpochCopy->add(
$this->interval(0, 0, 0, 0, $gameOffsetSeconds)
);
if ($gameOffsetSeconds < 0) {
$this->adjustedEpoch = $gameEpochCopy->sub(
$this->interval(0, 0, 0, 0, $gameOffsetSeconds*-1)
);
} else {
$this->adjustedEpoch = $gameEpochCopy->add(
$this->interval(0, 0, 0, 0, $gameOffsetSeconds)
);
}
$this->theBeginning = new DateTime("0000-01-01 UTC");
$this->secondsPerGameDay = (float) $this->secondsPerDay / $gameDaysPerDay;
@@ -41,19 +57,23 @@ class TimeKeeper
$this->secondsPerGameHour = $this->secondsPerGameDay / 24;
$this->secondsPerGameMinute = $this->secondsPerGameHour / 60;
$this->secondsPerGameSecond = $this->secondsPerGameMinute / 60;
$this->now = $now;
}
/**
* Returns whether a user who is interating with the game now and last
* interacted at $lastInteractionTime should experience a New Day event.
* @param DateTime $lastInteractionTime
* @param DateTime|null $lastInteractionTime
* @return bool
*/
public function isNewDay(DateTime $lastInteractionTime): bool
public function isNewDay(?DateTime $lastInteractionTime): bool
{
if ($lastInteractionTime == null) {
return true;
}
$t1 = $this->gameTime();
$t1 = $this->getGameTime();
$t2 = $this->convertToGameTime($lastInteractionTime);
$d1 = $t1->format("Y-m-d");
$d2 = $t2->format("Y-m-d");
@@ -65,9 +85,9 @@ class TimeKeeper
* Return the current game time.
* @return DateTime
*/
public function gameTime(): DateTime
public function getGameTime(): DateTime
{
return $this->convertToGameTime(new DateTime());
return $this->convertToGameTime($this->now);
}
/**
@@ -75,9 +95,7 @@ class TimeKeeper
* @param DateTime $time Game time to convert.
* @return DateTime Real time corresponding to game time $time.
*/
public function convertFromGameTime(
DateTime $time
): DateTime {
public function convertFromGameTime(DateTime $time): DateTime {
// Game dates are in the distant past, better not use getTimestamp().
$i = $this->theBeginning->diff($time);
@@ -96,9 +114,7 @@ class TimeKeeper
* @param DateTime $time Real time to convert.
* @return DateTime Game time corresponding to real time $time.
*/
public function convertToGameTime(
DateTime $time
): DateTime {
public function convertToGameTime(DateTime $time): DateTime {
$timeUnix = $time->getTimestamp();
$epochUnix = $this->adjustedEpoch->getTimestamp();
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tests\FakeModule\Models;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
/**
* @Entity
* @Table(name="Users")
*/
class UserEntity
{
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @Column(type="string", length=50); */
private $name;
public function getId(): int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name)
{
$this->name = $name;
}
}
+28
View File
@@ -0,0 +1,28 @@
<?php
namespace LotGD\Core\Tests\DefectiveModule;
use LotGD\Core\Exceptions\CoreException;
use LotGD\Core\Game;
use LotGD\Core\Events\EventContext;
use LotGD\Core\Module as ModuleInterface;
use LotGD\Core\Models\Module as ModuleModel;
class DefectiveModuleException extends CoreException {}
class Module implements ModuleInterface {
public static function handleEvent(Game $g, EventContext $context): EventContext
{
return $context;
}
public static function onRegister(Game $g, ModuleModel $module)
{
throw new DefectiveModuleException("Exception");
}
public static function onUnregister(Game $g, ModuleModel $module)
{
}
}
+3
View File
@@ -0,0 +1,3 @@
entityNamespace: "LotGD\\Core\\Tests\\FakeModule\\Models\\"
subscriptionPatterns:
- "e/lotgd/core/tests/event"
+10 -4
View File
@@ -3,6 +3,8 @@ declare(strict_types=1);
namespace LotGD\Core\Tests;
use LotGD\Core\Events\EventContext;
use LotGD\Core\Events\EventContextData;
use LotGD\Core\Game;
use LotGD\Core\EventManager;
use LotGD\Core\EventHandler;
@@ -20,7 +22,9 @@ class EventManagerTestInvalidSubscriber
class EventManagerTestSubscriber implements EventHandler
{
public static function handleEvent(Game $g, string $event, array &$context) {}
public static function handleEvent(Game $g, EventContext $context): EventContext {
return $context;
}
}
class EventManagerTest extends CoreModelTestCase
@@ -129,9 +133,11 @@ class EventManagerTest extends CoreModelTestCase
$em = new EventManager($this->g);
$event = 'test.foo.something_here';
$context = array('foo' => 'bar');
$contextData = EventContextData::create(["foo" => "bar"]);
$em->publish($event, $context);
$this->assertEquals($context['foo'], 'baz');
// The event is expected to change foo from bar to baz.
$contextDataModified = $em->publish($event, $contextData);
$this->assertNotSame($contextData, $contextDataModified);
$this->assertEquals("baz", $contextDataModified->get("foo"));
}
}
+4 -2
View File
@@ -3,12 +3,14 @@
namespace LotGD\Core\Tests\FakeModule;
use LotGD\Core\Game;
use LotGD\Core\Events\EventContext;
use LotGD\Core\Module as ModuleInterface;
use LotGD\Core\Models\Module as ModuleModel;
class Module implements ModuleInterface {
public static function handleEvent(Game $g, string $event, array &$context) {
$context['foo'] = 'baz';
public static function handleEvent(Game $g, EventContext $context): EventContext
{
$context->setDataField("foo", "baz");
return $context;
}
public static function onRegister(Game $g, ModuleModel $module) {}
+100 -27
View File
@@ -8,26 +8,16 @@ use Doctrine\ORM\EntityManager;
use Monolog\Logger;
use Monolog\Handler\NullHandler;
use LotGD\Core\Action;
use LotGD\Core\ActionGroup;
use LotGD\Core\Bootstrap;
use LotGD\Core\Configuration;
use LotGD\Core\ComposerManager;
use LotGD\Core\DiceBag;
use LotGD\Core\EventHandler;
use LotGD\Core\EventManager;
use LotGD\Core\Game;
use LotGD\Core\TimeKeeper;
use LotGD\Core\ModuleManager;
use LotGD\Core\Models\Character;
use LotGD\Core\Models\Viewpoint;
use LotGD\Core\Models\Scene;
use LotGD\Core\Exceptions\ {
ActionNotFoundException,
CharacterNotFoundException,
InvalidConfigurationException
use LotGD\Core\{
Action, ActionGroup, Bootstrap, Configuration, ComposerManager, DiceBag, EventHandler, EventManager, Events\NewViewpointData, Game, GameBuilder, TimeKeeper, ModuleManager
};
use LotGD\Core\Tests\CoreModelTestCase;
use LotGD\Core\Models\{
Character, Viewpoint, Scene
};
use LotGD\Core\Exceptions\ {
ActionNotFoundException, CharacterNotFoundException, InvalidConfigurationException
};
use LotGD\Core\Events\EventContext;
class DefaultSceneProvider implements EventHandler
{
@@ -35,17 +25,22 @@ class DefaultSceneProvider implements EventHandler
public static $attachments = ['actions'];
public static $data = ['data'];
public static function handleEvent(Game $g, string $event, array &$context)
public static function handleEvent(Game $g, EventContext $context): EventContext
{
switch ($event) {
switch ($context->getEvent()) {
case 'h/lotgd/core/default-scene':
if (!isset($context['character'])) {
throw new \Exception("Key 'character' was expected on event h/lotgd/core/default-scene.");
if (!$context->hasDataType(NewViewpointData::class)) {
throw new \Exception(sprintf(
"Context was expected to be %s, %s instead.",
NewViewpointData::class,
get_class($context->getData())
));
}
$context['scene'] = $g->getEntityManager()->getRepository(Scene::class)->find(1);
$context->setDataField("scene", $g->getEntityManager()->getRepository(Scene::class)->find(1));
break;
case 'h/lotgd/core/navigate-to/lotgd/tests/village':
$v = $context['viewpoint'];
$v = $context->getDataField('viewpoint');
self::$actionGroups = [new ActionGroup('default', 'Title', 0)];
self::$actionGroups[0]->setActions([
@@ -57,7 +52,22 @@ class DefaultSceneProvider implements EventHandler
$v->setAttachments(self::$attachments);
$v->setData(self::$data);
break;
case 'h/lotgd/core/navigate-to/lotgd/tests/paramaters':
/* @var Viewpoint $v //*/
$v = $context->getDataField('viewpoint');
/* @var array //*/
$p = $context->getDataField('parameters');
if ($p["foo"] === "baz") {
$v->setDescription("Parameter is baz.");
} else {
$v->setDescription("Parameter is NOT baz.");
}
break;
}
return $context;
}
}
@@ -75,7 +85,12 @@ class GameTest extends CoreModelTestCase
$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()
@@ -124,7 +139,7 @@ class GameTest extends CoreModelTestCase
$c = $this->getEntityManager()->getRepository(Character::class)->find(1);
$this->g->setCharacter($c);
// There shouldnt be any listeners to provide a default scene.
// There should'nt be any listeners to provide a default scene.
$this->expectException(InvalidConfigurationException::class);
$this->g->getViewpoint();
}
@@ -191,6 +206,64 @@ class GameTest extends CoreModelTestCase
$this->assertSame($s->getTemplate(), $v->getTemplate());
}
public function testIfActionParametersAreRelayedToEvent()
{
/* @var $c Character */
$c = $this->getEntityManager()->getRepository(Character::class)->find(2);
$this->g->setCharacter($c);
// subscribe event
$this->g->getEventManager()->subscribe('#h/lotgd/core/navigate-to/lotgd/tests/paramaters#', DefaultSceneProvider::class, 'lotgd/core/tests');
$action = new Action(7, null, ["foo" => "baz"]);
$actionId = $action->getId();
$ag = new ActionGroup("group1", "Group 1", 5);
$ag->addAction($action);
$v = $c->getViewpoint();
$v->setDescription("Test");
$v->setActionGroups([$ag]);
$c->setViewpoint($v);
$this->g->takeAction($actionId);
$v = $c->getViewpoint();
$this->assertSame("Parameter is baz.", $v->getDescription());
// unsubscribe event
$this->g->getEventManager()->unsubscribe('#h/lotgd/core/navigate-to/lotgd/tests/paramaters#', DefaultSceneProvider::class, 'lotgd/core/tests');
}
public function testIfActionParametersTakePriorityToOtherParameters()
{
/* @var $c Character */
$c = $this->getEntityManager()->getRepository(Character::class)->find(2);
$this->g->setCharacter($c);
// subscribe event
$this->g->getEventManager()->subscribe('#h/lotgd/core/navigate-to/lotgd/tests/paramaters#', DefaultSceneProvider::class, 'lotgd/core/tests');
$action = new Action(7, null, ["foo" => "baz"]);
$actionId = $action->getId();
$ag = new ActionGroup("group1", "Group 1", 5);
$ag->addAction($action);
$v = $c->getViewpoint();
$v->setDescription("Test");
$v->setActionGroups([$ag]);
$c->setViewpoint($v);
$this->g->takeAction($actionId, ["foo" => "nobaz"]);
$v = $c->getViewpoint();
$this->assertSame("Parameter is baz.", $v->getDescription());
// unsubscribe event
$this->g->getEventManager()->unsubscribe('#h/lotgd/core/navigate-to/lotgd/tests/paramaters#', DefaultSceneProvider::class, 'lotgd/core/tests');
}
public function testIfActionsAreAddedAsExpected()
{
$viewpointToArray = function(Viewpoint $v) {
+76
View File
@@ -0,0 +1,76 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Tests\Models;
use LotGD\Core\Action;
use LotGD\Core\ActionGroup;
use LotGD\Core\Models\Scene;
use LotGD\Core\Models\Viewpoint;
use LotGD\Core\Tests\CoreModelTestCase;
class ViewpointRestorationTest extends CoreModelTestCase
{
/** @var string default data set */
protected $dataset = "viewpoints";
protected function getActionGroup()
{
static $actionGroup = null;
if ($actionGroup !== null) {
$actionGroup = new ActionGroup("main", "Title", 0);
$actionGroup->addAction(new Action(1));
$actionGroup->addAction(new Action(2));
$actionGroup->addAction(new Action(3));
}
return $actionGroup;
}
protected function getViewpoint()
{
$sceneMock = $this->createMock(Scene::class);
$sceneMock->method("getTitle")->willReturn("Scene Mock Title");
$sceneMock->method("getDescription")->willReturn("Scene Mock Description");
$sceneMock->method("getTemplate")->willReturn("lotgd/scene-mock-template");
$actionGroup = $this->getActionGroup();
$viewpoint = new Viewpoint();
$viewpoint->changeFromScene($sceneMock);
$viewpoint->setActionGroups([$actionGroup]);
return $viewpoint;
}
protected function getAlternativeViewpoint()
{
$sceneMock = $this->createMock(Scene::class);
$sceneMock->method("getTitle")->willReturn("Another Scene Mock Title");
$sceneMock->method("getDescription")->willReturn("Another Scene Mock Description");
$sceneMock->method("getTemplate")->willReturn("lotgd/scene-mock-template/another");
$viewpoint = new Viewpoint();
$viewpoint->changeFromScene($sceneMock);
return $viewpoint;
}
public function testIfViewpointAfterUnserializationIsEqualToBeforeItsSerialization()
{
$viewpoint = $this->getViewpoint();
$viewpointRestoration = $this->getViewpoint()->getSnapshot();
$serialized = serialize($viewpointRestoration);
$viewpointRestored = unserialize($serialized);
$newViewpoint = $this->getAlternativeViewpoint();
$newViewpoint->changeFromSnapshot($viewpointRestored);
$this->assertSame($viewpoint->getTitle(), $newViewpoint->getTitle());
$this->assertSame($viewpoint->getDescription(), $newViewpoint->getDescription());
$this->assertSame($viewpoint->getTemplate(), $newViewpoint->getTemplate());
$this->assertEquals($viewpoint->getActionGroups(), $newViewpoint->getActionGroups());;
$this->assertSame($viewpoint->getData(), $newViewpoint->getData());
$this->assertSame($viewpoint->getAttachments(), $newViewpoint->getAttachments());
}
}
+35 -2
View File
@@ -6,6 +6,7 @@ namespace LotGD\Core\Tests;
use Composer\Package\PackageInterface;
use Composer\Composer;
use Doctrine\Common\Util\Debug;
use LotGD\Core\Game;
use LotGD\Core\ComposerManager;
use LotGD\Core\EventHandler;
@@ -18,6 +19,7 @@ use LotGD\Core\Exceptions\ModuleAlreadyExistsException;
use LotGD\Core\Exceptions\ModuleDoesNotExistException;
use LotGD\Core\Tests\CoreModelTestCase;
use LotGD\Core\Tests\FakeModule\Module as FakeModule;
use LotGD\Core\Tests\DefectiveModule\Module as DefectiveModule;
class ModuleManagerTest extends CoreModelTestCase
{
@@ -135,8 +137,7 @@ class ModuleManagerTest extends CoreModelTestCase
{
$class = FakeModule::class;
$name = 'lotgd/tests2';
$subscriptions = array(
);
$subscriptions = [];
$library = $this->getMockBuilder(LibraryConfiguration::class)
->disableOriginalConstructor()
->getMock();
@@ -199,4 +200,36 @@ class ModuleManagerTest extends CoreModelTestCase
$this->assertGreaterThanOrEqual(-5, $timeDiff);
$this->assertEquals($name, $modules[1]->getLibrary());
}
public function testRegisteringDefectiveModule()
{
$class = DefectiveModule::class;
$name = "lotgd/tests3";
$subscriptions = [];
$library = $this->getMockBuilder(LibraryConfiguration::class)
->disableOriginalConstructor()
->getMock();
$library->method('getName')->willReturn($name);
$library->method('getRootNamespace')->willReturn('LotGD\\Core\\Tests\\DefectiveModule\\');
$library->method('getSubscriptionPatterns')->willReturn($subscriptions);
$eventManager = $this->getMockBuilder(EventManager::class)
->disableOriginalConstructor()
->getMock();
$this->game->method('getEventManager')->willReturn($eventManager);
$modulesBefore = $this->mm->getModules();
try {
// onRegister throws an exception. This exception needs to be captured and handled by mm->register without actually
// registering a real module...
$this->mm->register($library);
$exceptionCaptured = false;
} catch(\Throwable $e) {
$exceptionCaptured = true;
}
$modulesAfter = $this->mm->getModules();
$this->assertFalse($exceptionCaptured);
$this->assertCount(count($modulesBefore), $modulesAfter);
}
}
+51 -14
View File
@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace LotGD\Core\Tests;
use DateTime;
use LotGD\Core\TimeKeeper;
/**
@@ -22,7 +23,7 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
public function testConvertToBasicConversion() {
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$date = new \DateTime('2015-07-27 23:59:59 PDT');
$converted = $keeper->convertToGameTime($date);
@@ -37,7 +38,7 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
$date = new \DateTime('2015-07-27 05:59:59 PDT');
$this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01', $converted->format('Y-m-d'));
@@ -47,7 +48,7 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
$date = new \DateTime('2015-07-27 06:00:00 PDT');
$this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
@@ -57,21 +58,57 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
$date = new \DateTime('2015-07-27 11:59:59 PDT');
$this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
}
public function testDetectsNewDay() {
public function testIfIsNewDayReturnsTrueWithNullAsLastInteractionTime() {
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, 4);
$this->assertTrue($keeper->isNewDay(null));
}
public function testIfIsNewDayReturnsFalseIfLastInteractionTimeWasJustRecently()
{
// game days per day: 4, each day 6h.
$keeper = new TimeKeeper($this->gameEpoch, new DateTime("2017-01-02 11:59:59"), 3600*5, 4);
$time1 = new \DateTime("2017-01-02 06:00:00");
$time2 = new \DateTime("2017-01-02 11:59:59");
$time3 = new \DateTime("2017-01-02 09:00:00");
$time4 = new \DateTime("2017-01-02 09:59:30");
$this->assertFalse($keeper->isNewDay($time1));
$this->assertFalse($keeper->isNewDay($time2));
$this->assertFalse($keeper->isNewDay($time3));
$this->assertFalse($keeper->isNewDay($time4));
}
public function testIfIsNewDayReturnsFalseIfLastInteractionTimeWasOnLastGameDay()
{
// game days per day: 4, each day 6h.
// interestingly, it looks like new game day starts 01:00:00?
$keeper = new TimeKeeper($this->gameEpoch, new DateTime("2017-01-02 12:00:00"), 3600*5, 4);
$time1 = new \DateTime("2017-01-02 06:00:00");
$time2 = new \DateTime("2017-01-02 11:59:59");
$time3 = new \DateTime("2017-01-02 09:00:00");
$time4 = new \DateTime("2017-01-02 09:59:30");
$this->assertTrue($keeper->isNewDay($time1));
$this->assertTrue($keeper->isNewDay($time2));
$this->assertTrue($keeper->isNewDay($time3));
$this->assertTrue($keeper->isNewDay($time4));
}
public function testConvertToRespectsGameOffset() {
$date = new \DateTime('2015-07-27 01:01:15 PDT');
$this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01 00:01:15', $converted->format('Y-m-d H:i:s'));
@@ -82,7 +119,7 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
$this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-01 23:59:59', $converted->format('Y-m-d H:i:s'));
@@ -93,7 +130,7 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
$this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
@@ -104,7 +141,7 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
$this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertToGameTime($date);
$this->assertEquals('0000-01-02', $converted->format('Y-m-d'));
@@ -114,7 +151,7 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
$date = new \DateTime('0000-01-02 00:00:00 UTC');
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertFromGameTime($date);
$this->assertEquals("2015-07-28", $converted->format('Y-m-d'));
@@ -127,7 +164,7 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
$this->gameEpoch = $epoch;
$this->gameOffsetSeconds = 60*60;
$this->gameDaysPerDay = 1;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertFromGameTime($date);
$this->assertEquals("2015-07-29 00:59:59", $converted->format('Y-m-d H:i:s'));
@@ -139,14 +176,14 @@ class TimeKeeperTests extends \PHPUnit_Framework_TestCase {
$this->gameEpoch = $epoch;
$this->gameDaysPerDay = 4;
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$converted = $keeper->convertFromGameTime($date);
$this->assertEquals("2015-07-27 11:59:59", $converted->format('Y-m-d H:i:s'));
}
public function testGameTimeSanity() {
$keeper = new TimeKeeper($this->gameEpoch, $this->gameOffsetSeconds, $this->gameDaysPerDay);
$this->assertNotNull($keeper->gameTime());
$keeper = new TimeKeeper($this->gameEpoch, new DateTime(), $this->gameOffsetSeconds, $this->gameDaysPerDay);
$this->assertNotNull($keeper->getGameTime());
}
}
+5
View File
@@ -51,6 +51,11 @@ scenes:
title: "Child Scene 2"
description: "This is a parent scene that connects to two children."
template: "lotgd/tests/none"
-
id: 7
title: "Parameter test"
description: "This is a parameter test"
template: "lotgd/tests/paramaters"
scene_connection_groups:
-
scene: 4