From fa9096c0ab521aae45cab6c48a54290d14a221b9 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Wed, 29 Nov 2023 11:03:15 +0100 Subject: event tables --- src/Controller/Building.php | 18 +++----- src/Controller/Event.php | 23 ++++++---- src/Controller/Map.php | 2 +- src/Controller/Unit.php | 87 ++++++++++++++++------------------- src/Controller/Village.php | 44 ++++++++---------- src/EventRunner.php | 51 +++++++++++++++++---- src/Model/Event.php | 9 +++- src/Model/Event/BaseEvent.php | 17 ++++++- src/Model/Event/SendUnits.php | 91 +++++++++++++++++++++++++------------ src/Model/Event/TrainUnits.php | 27 +++++++++-- src/Model/Event/UpgradeBuilding.php | 23 +++++----- 11 files changed, 239 insertions(+), 153 deletions(-) (limited to 'src') diff --git a/src/Controller/Building.php b/src/Controller/Building.php index 6199286..876f474 100644 --- a/src/Controller/Building.php +++ b/src/Controller/Building.php @@ -2,7 +2,6 @@ namespace App\Controller; -use App\DB; use App\Model\Building as Model; use App\Model\Event; use App\Model\Event\UpgradeBuilding; @@ -28,18 +27,13 @@ class Building $village->updateResources(); // event - $event = new UpgradeBuilding(); - $event->type = 'UpgradeBuilding'; + $event = new Event(); $event->time = (new \DateTime())->add(\DateInterval::createFromDateString($building->getBuildTime() . ' seconds')); - $event->payload = json_encode([ - 'type' => $building->type, - 'village_id' => $building->villageId, - ]); - - DB::query( - 'insert into events (type, time, payload, village_id) VALUES (:type, :time, :payload, :id)', - ['type' => $event->type, 'time' => $event->time->format('c'), 'payload' => $event->payload, 'id' => $village->id] - ); + $event->villageId = $building->villageId; + $upgradeBuildingEvent = new UpgradeBuilding(); + $upgradeBuildingEvent->event = $event; + $upgradeBuildingEvent->type = $building->type; + $upgradeBuildingEvent->dbInsert(); return new RedirectResponse( Router::generate( diff --git a/src/Controller/Event.php b/src/Controller/Event.php index a6538fe..78de9d5 100644 --- a/src/Controller/Event.php +++ b/src/Controller/Event.php @@ -4,6 +4,7 @@ namespace App\Controller; use App\DB; use App\Model\Event as Model; +use App\Model\Event\SendUnits; use App\Model\Village; use App\Router; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -31,22 +32,24 @@ class Event $village = Village::get($event->villageId); if ($event->type === 'SendUnits') { - $payload = json_decode($event->payload, true); + /**@var SendUnits $sendUnitsEvent*/ + $sendUnitsEvent = DB::fetch(SendUnits::class, 'select * from events_send_units where event_id=:id', ['id' => $event->id]); - if ($payload['type'] === 'SendBack') { + if ($sendUnitsEvent->type === 'SendBack') { $cancelTimeDiff = $event->createdAt->diff(new \DateTime()); $cancelTime = (new \DateTime())->add($cancelTimeDiff); - $cancelPayload = array_replace_recursive($payload, [ - 'cancel' => [ - 'home' => $payload['destination'], - 'residence' => $payload['source'], - ], - ]); + $sendUnitsEvent->isCanceled = true; + $sendUnitsEvent->home = $sendUnitsEvent->destination; + $sendUnitsEvent->residence = $sendUnitsEvent->source; DB::query( - 'update events set time=:time, payload=:payload where id=:id', - ['time' => $cancelTime->format('c'), 'payload' => json_encode($cancelPayload), 'id' => $request->get('id')] + 'update events set time=:time, where id=:id', + ['time' => $cancelTime->format('c'), 'id' => $request->get('id')] + ); + DB::query( + 'update events_send_units set is_canceled=:is_canceled, home=:home, residence=:residence where id=:id', + ['is_canceled' => $sendUnitsEvent->isCanceled, 'home' => $sendUnitsEvent->home, 'residence' => $sendUnitsEvent->residence, 'id' => $sendUnitsEvent->id] ); } } diff --git a/src/Controller/Map.php b/src/Controller/Map.php index 59c1e4e..6967470 100644 --- a/src/Controller/Map.php +++ b/src/Controller/Map.php @@ -11,7 +11,7 @@ use Symfony\Component\Routing\Annotation\Route; class Map { #[Route(path: '/map/{x}/{y}/{range}', defaults: ['range' => 1], methods: ['GET'])] - public function train(Request $request): Response + public function region(Request $request): Response { $x = $request->get('x'); $y = $request->get('y'); diff --git a/src/Controller/Unit.php b/src/Controller/Unit.php index c57ff01..1774c17 100644 --- a/src/Controller/Unit.php +++ b/src/Controller/Unit.php @@ -3,6 +3,8 @@ namespace App\Controller; use App\DB; +use App\Model\Event\SendUnits; +use App\Model\Event\TrainUnits; use App\Model\Unit as Model; use App\Model\Event; use App\Model\Village; @@ -43,17 +45,13 @@ class Unit // event $event = new Event(); - $event->type = 'TrainUnits'; $event->time = (new \DateTime())->add(\DateInterval::createFromDateString($unit->getBuildTime($amount) . ' seconds')); - $event->payload = json_encode([ - 'type' => $request->get('type'), - 'amount' => $amount, - ]); - - DB::query( - 'insert into events (type, time, payload, village_id) VALUES (:type, :time, :payload, :id)', - ['type' => $event->type, 'time' => $event->time->format('c'), 'payload' => $event->payload, 'id' => $village->id] - ); + $event->villageId = $village->id; + $trainUnitsEvent = new TrainUnits(); + $trainUnitsEvent->event = $event; + $trainUnitsEvent->type = $request->get('type'); + $trainUnitsEvent->amount = $amount; + $trainUnitsEvent->dbInsert(); return new RedirectResponse( Router::generate( @@ -96,25 +94,22 @@ class Unit // event $event = new Event(); - $event->type = 'SendUnits'; $event->time = (new \DateTime())->add( \DateInterval::createFromDateString( Model::getTravelTime($unit, Village::getDistance($village->x, $village->y, $location->x, $location->y)) . ' seconds' ) ); - $event->payload = json_encode([ - 'type' => 'Recall', - 'unit' => $request->get('type'), - 'amount' => $amount, - 'source' => $location->id, - 'destination' => $village->id, - ]); - - DB::query( - 'insert into events (type, time, payload, village_id) VALUES (:type, :time, :payload, :id)', - ['type' => $event->type, 'time' => $event->time->format('c'), 'payload' => $event->payload, 'id' => $village->id] - ); + $event->villageId = $village->id; + $sendUnitsEvent = new SendUnits(); + $sendUnitsEvent->event = $event; + $sendUnitsEvent->type = 'Recall'; + $sendUnitsEvent->unit = $request->get('type'); + $sendUnitsEvent->amount = $amount; + $sendUnitsEvent->source = $location->id; + $sendUnitsEvent->destination = $village->id; + $sendUnitsEvent->dbInsert(); + return new RedirectResponse( Router::generate( @@ -157,25 +152,22 @@ class Unit // event $event = new Event(); - $event->type = 'SendUnits'; $event->time = (new \DateTime())->add( \DateInterval::createFromDateString( Model::getTravelTime($unit, Village::getDistance($village->x, $village->y, $location->x, $location->y)) . ' seconds' ) ); - $event->payload = json_encode([ - 'type' => 'SendBack', - 'unit' => $request->get('type'), - 'amount' => $amount, - 'source' => $village->id, - 'destination' => $location->id, - ]); - - DB::query( - 'insert into events (type, time, payload, village_id) VALUES (:type, :time, :payload, :id)', - ['type' => $event->type, 'time' => $event->time->format('c'), 'payload' => $event->payload, 'id' => $village->id] - ); + $event->villageId = $village->id; + $sendUnitsEvent = new SendUnits(); + $sendUnitsEvent->event = $event; + $sendUnitsEvent->type = 'SendBack'; + $sendUnitsEvent->unit = $request->get('type'); + $sendUnitsEvent->amount = $amount; + $sendUnitsEvent->source = $village->id; + $sendUnitsEvent->destination = $location->id; + $sendUnitsEvent->dbInsert(); + return new RedirectResponse( Router::generate( @@ -218,25 +210,22 @@ class Unit // event $event = new Event(); - $event->type = 'SendUnits'; $event->time = (new \DateTime())->add( \DateInterval::createFromDateString( Model::getTravelTime($unit, Village::getDistance($village->x, $village->y, $destination->x, $destination->y)) . ' seconds' ) ); - $event->payload = json_encode([ - 'type' => $request->get('type'), - 'unit' => $request->get('unit'), - 'amount' => $amount, - 'source' => $village->id, - 'destination' => $destination->id, - ]); - - DB::query( - 'insert into events (type, time, payload, village_id) VALUES (:type, :time, :payload, :id)', - ['type' => $event->type, 'time' => $event->time->format('c'), 'payload' => $event->payload, 'id' => $village->id] - ); + $event->villageId = $village->id; + $sendUnitsEvent = new SendUnits(); + $sendUnitsEvent->event = $event; + $sendUnitsEvent->type = $request->get('type'); + $sendUnitsEvent->unit = $request->get('unit'); + $sendUnitsEvent->amount = $amount; + $sendUnitsEvent->source = $village->id; + $sendUnitsEvent->destination = $destination->id; + $sendUnitsEvent->dbInsert(); + return new RedirectResponse( Router::generate( diff --git a/src/Controller/Village.php b/src/Controller/Village.php index 59e6d4b..16a8981 100644 --- a/src/Controller/Village.php +++ b/src/Controller/Village.php @@ -34,51 +34,46 @@ class Village $eventsBuilding = DB::query( << $village->id, 'type' => 'UpgradeBuilding'] + select * from events_upgrade_building as event + left join events on event.event_id = events.id + where events.village_id=:id + SQL, ['id' => $village->id] )->fetchAll(); foreach ($eventsBuilding as $row) { - $events[$row['type']][] = [ - 'event' => DB::convertToModel(UpgradeBuilding::class, $row), - 'data' => json_decode($row['payload']), - ]; + $events['UpgradeBuilding'][] = DB::convertToModel(UpgradeBuilding::class, $row); } $eventsUnits = DB::query( << 'TrainUnits', 'id' => $village->id] + select * from events_train_units as event + left join events on event.event_id = events.id + where village_id=:id + SQL, ['id' => $village->id] )->fetchAll(); foreach ($eventsUnits as $row) { - $events[$row['type']][] = [ - 'event' => DB::convertToModel(TrainUnits::class, $row), - 'data' => json_decode($row['payload'], true), - ]; + $events['TrainUnits'][] = DB::convertToModel(TrainUnits::class, $row); } $eventsUnitsSendOwn = DB::query( << 'SendUnits', 'id' => $village->id] + select * from events_send_units as event + left join events on event.event_id = events.id + where village_id=:id + SQL, ['id' => $village->id] )->fetchAll(); $eventsUnitsSendOther = DB::query( <<>'destination')::bigint=:id and (payload->>'cancel') is null - SQL, ['type' => 'SendUnits', 'id' => $village->id] + select * from events_send_units as event + left join events on event.event_id = events.id + where destination=:id and is_canceled=false + SQL, ['id' => $village->id] )->fetchAll(); foreach ([...$eventsUnitsSendOwn, ...$eventsUnitsSendOther] as $row) { - $events[$row['type']][] = [ - 'event' => DB::convertToModel(SendUnits::class, $row), - 'data' => json_decode($row['payload'], true), - ]; + $events['SendUnits'][] = DB::convertToModel(SendUnits::class, $row);; } $buildings = []; @@ -86,6 +81,7 @@ class Village $buildings[$building->type] = $building; } + return new Response(View::render('village.twig', [ 'village' => $village, 'events' => $events, diff --git a/src/EventRunner.php b/src/EventRunner.php index a071d32..7dd773d 100644 --- a/src/EventRunner.php +++ b/src/EventRunner.php @@ -9,7 +9,9 @@ use App\Model\Building\IronMine; use App\Model\Building\ResourceGenerator; use App\Model\Building\Storage; use App\Model\Building\WoodCutter; -use App\Model\Event; +use App\Model\Event\SendUnits; +use App\Model\Event\TrainUnits; +use App\Model\Event\UpgradeBuilding; use App\Model\Village; class EventRunner @@ -18,28 +20,57 @@ class EventRunner { // Events - $results = DB::query('select * from events where time < now()')->fetchAll(); + # Upgrade Building + + $results = DB::query(<<fetchAll(); foreach ($results as $row) { - /**@var Event $event*/ - $event = DB::convertToModel(Event::resolveType($row['type']), $row); + /**@var UpgradeBuilding $event*/ + $event = DB::convertToModel(UpgradeBuilding::class, $row); $event(); - DB::query( - 'delete from events where id=:id', - ['id' => $event->id] - ); + $event->dbDelete(); } - # Upgrade Building + # Train Units $results = DB::query(<<fetchAll(); + foreach ($results as $row) { + /**@var TrainUnits $event*/ + $event = DB::convertToModel(TrainUnits::class, $row); + $event(); + + $event->dbDelete(); + } + + # Send Units + + $results = DB::query(<<fetchAll(); + + foreach ($results as $row) { + /**@var SendUnits $event*/ + $event = DB::convertToModel(SendUnits::class, $row); + $event(); + + $event->dbDelete(); + } + // Resources diff --git a/src/Model/Event.php b/src/Model/Event.php index b4c131e..de6c82e 100644 --- a/src/Model/Event.php +++ b/src/Model/Event.php @@ -8,15 +8,20 @@ class Event { public int $id; - public string $type; + public ?string $type; public \DateTime $time; - public string $payload; + public ?string $payload; public int $villageId; public \DateTime $createdAt; public \DateTime $updatedAt; + public function __construct(?\DateTime $time = null, int $villageId = 0) + { + $this->time = $time ?? new \DateTime(); + $this->villageId = $villageId; + } /* OOP */ diff --git a/src/Model/Event/BaseEvent.php b/src/Model/Event/BaseEvent.php index d3cc3fb..0c1795b 100644 --- a/src/Model/Event/BaseEvent.php +++ b/src/Model/Event/BaseEvent.php @@ -2,6 +2,9 @@ namespace App\Model\Event; +use App\DB; +use App\Model\Event; + abstract class BaseEvent { public int $id; @@ -10,5 +13,17 @@ abstract class BaseEvent public \DateTime $createdAt; public \DateTime $updatedAt; - abstract function sqlInsert(): void; + public Event $event; + + abstract function dbInsert(): void; + abstract function dbDelete(): void; + + public function getEvent(): Event + { + if (! isset($this->event)) { + $this->event = DB::fetch(Event::class, 'select * from events where id=:id', ['id' => $this->eventId])[0]; + } + + return $this->event; + } } diff --git a/src/Model/Event/SendUnits.php b/src/Model/Event/SendUnits.php index bf81031..ea94442 100644 --- a/src/Model/Event/SendUnits.php +++ b/src/Model/Event/SendUnits.php @@ -3,45 +3,52 @@ namespace App\Model\Event; use App\DB; -use App\Model\Event; -class SendUnits extends Event +class SendUnits extends BaseEvent { + public string $type; + + public int $amount; + public string $unit; + + public int $source; + public int $destination; + + public ?int $home = null; + public ?int $residence = null; + + public bool $isCanceled = false; + /** * @return void */ public function __invoke(): void { - $payload = json_decode($this->payload, true); - - if (isset($payload['cancel'])) { - if ($payload['type'] === 'SendBack') { - $payload['source'] = $payload['cancel']['home']; - $payload['destination'] = $payload['cancel']['residence']; + if ($this->isCanceled) { + if ($this->type === 'SendBack') { + $this->source = $this->home; + $this->destination = $this->residence; - $this->borrow($payload); + $this->borrow(); } } else { - if ($payload['type'] === 'Recall' || $payload['type'] === 'SendBack') { - $this->return($payload); + if ($this->type === 'Recall' || $this->type === 'SendBack') { + $this->return(); } - else if ($payload['type'] === 'Borrow') { - $this->borrow($payload); + else if ($this->type === 'Borrow') { + $this->borrow(); } - else if ($payload['type'] === 'Gift') { - $this->gift($payload); + else if ($this->type === 'Gift') { + $this->gift(); } } } - /** - * @param array $payload - */ - private function return(array $payload): void + private function return(): void { DB::query( << $payload['amount'], 'type' => $payload['unit'], 'id' => $payload['destination']] + ['amount' => $this->amount, 'type' => $this->unit, 'id' => $this->destination] ); } - /** - * @param array $payload - */ - private function borrow(array $payload): void + private function borrow(): void { DB::query( << $payload['amount'], 'type' => $payload['unit'], 'home' => $payload['source'], 'residence' => $payload['destination']] + ['amount' => $this->amount, 'type' => $this->unit, 'home' => $this->source, 'residence' => $this->destination] ); } - /** - * @param array $payload - */ - private function gift(array $payload): void + private function gift(): void { DB::query( << $payload['amount'], 'type' => $payload['unit'], 'home' => $payload['destination'], 'residence' => $payload['destination']] + ['amount' => $this->amount, 'type' => $this->unit, 'home' => $this->destination, 'residence' => $this->residence] ); } + + public function dbInsert(): void + { + DB::query( + 'insert into events (time, village_id) VALUES (:time, :village_id)', + ['time' => $this->event->time->format('c'), 'village_id' => $this->event->villageId] + ); + + DB::query( + << DB::$connection->lastInsertId(), + 'type' => $this->type, + 'amount' => $this->amount, + 'unit' => $this->unit, + 'source' => $this->source, 'destination' => $this->destination, + 'home' => $this->home, 'residence' => $this->residence, + 'is_canceled' => $this->isCanceled ?: 0, // @see https://www.php.net/manual/de/pdostatement.execute.php#126013 + ] + ); + } + + public function dbDelete(): void + { + DB::query('delete from events where id=:id', ['id' => $this->eventId]); + DB::query('delete from events_send_units where id=:id', ['id' => $this->id]); + } } diff --git a/src/Model/Event/TrainUnits.php b/src/Model/Event/TrainUnits.php index 0090d0f..5b4eef9 100644 --- a/src/Model/Event/TrainUnits.php +++ b/src/Model/Event/TrainUnits.php @@ -3,10 +3,12 @@ namespace App\Model\Event; use App\DB; -use App\Model\Event; -class TrainUnits extends Event +class TrainUnits extends BaseEvent { + public int $amount; + public string $type; + /** * @return void */ @@ -21,7 +23,26 @@ class TrainUnits extends Event on conflict (type, home_village_id, residence_village_id) do update set amount = village_units.amount+:amount SQL, - ['amount' => $payload['amount'], 'type' => $payload['type'], 'id' => $this->villageId] + ['amount' => $this->amount, 'type' => $this->type, 'id' => $this->event->villageId] + ); + } + + public function dbInsert(): void + { + DB::query( + 'insert into events (time, village_id) VALUES (:time, :village_id)', + ['time' => $this->event->time->format('c'), 'village_id' => $this->event->villageId] ); + + DB::query( + 'insert into events_train_units (event_id, amount, type) VALUES (:event_id, :amount, :type)', + ['event_id' => DB::$connection->lastInsertId(), 'amount' => $this->amount, 'type' => $this->type] + ); + } + + public function dbDelete(): void + { + DB::query('delete from events where id=:id', ['id' => $this->eventId]); + DB::query('delete from events_upgrade_building where id=:id', ['id' => $this->id]); } } diff --git a/src/Model/Event/UpgradeBuilding.php b/src/Model/Event/UpgradeBuilding.php index f4f427d..a426a21 100644 --- a/src/Model/Event/UpgradeBuilding.php +++ b/src/Model/Event/UpgradeBuilding.php @@ -7,20 +7,15 @@ use App\Model\Event; class UpgradeBuilding extends BaseEvent { - public Event $event; public string $type; - public function __construct(Event $event, string $type) - { - $this->event = $event; - $this->type = $type; - } - /** * @return void */ public function __invoke(): void { + $this->getEvent(); + DB::query( << $this->event->time->format('c'), 'village_id' => $this->event->villageId] ); DB::query( - 'insert into events_upgrade_building (event_id, type) values (:event_id, :type)', - ['event_id' => DB::$connection->lastInsertId(), $this->type] + 'insert into events_upgrade_building (event_id, type) VALUES (:event_id, :type)', + ['event_id' => DB::$connection->lastInsertId(), 'type' => $this->type] ); } + + public function dbDelete(): void + { + DB::query('delete from events where id=:id', ['id' => $this->eventId]); + DB::query('delete from events_upgrade_building where id=:id', ['id' => $this->id]); + } } -- cgit v1.2.3