Make ChoiceQueue use smart pointers.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2020-05-31 18:00:39 +02:00
parent ff181204ae
commit 29cb4eac37
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
8 changed files with 32 additions and 35 deletions

View File

@ -12,7 +12,7 @@ export uint8_t CreatureLib_Battle_Construct(Battle*& out, const BattleLibrary* l
export void CreatureLib_Battle_Destruct(const Battle* p) { delete p; } export void CreatureLib_Battle_Destruct(const Battle* p) { delete p; }
export const BattleLibrary* CreatureLib_Battle_GetLibrary(const Battle* p) { return p->GetLibrary().GetRaw(); } export const BattleLibrary* CreatureLib_Battle_GetLibrary(const Battle* p) { return p->GetLibrary().GetRaw(); }
export uint8_t CreatureLib_Battle_CanUse(bool& out, Battle* p, const BaseTurnChoice* turnChoice) { export uint8_t CreatureLib_Battle_CanUse(bool& out, Battle* p, BaseTurnChoice* turnChoice) {
Try(out = p->CanUse(turnChoice);) Try(out = p->CanUse(turnChoice);)
} }
export uint8_t CreatureLib_Battle_TrySetChoice(bool& out, Battle* p, BaseTurnChoice* turnChoice) { export uint8_t CreatureLib_Battle_TrySetChoice(bool& out, Battle* p, BaseTurnChoice* turnChoice) {

View File

@ -5,8 +5,8 @@ bool CreatureLib::Battling::ChoiceQueue::MoveCreatureChoiceNext(CreatureLib::Bat
AssertNotNull(creature) AssertNotNull(creature)
// Find which index the creature choice is at. // Find which index the creature choice is at.
size_t choiceIndex = SIZE_MAX; size_t choiceIndex = SIZE_MAX;
for (size_t index = _current; index < _queue.size(); index++) { for (size_t index = _current; index < _queue.Count(); index++) {
if (_queue.at(index)->GetUser() == creature) { if (_queue.At(index)->GetUser() == creature) {
// If the creature choice is already next up, return. // If the creature choice is already next up, return.
if (index == _current) if (index == _current)
return false; return false;
@ -17,14 +17,15 @@ bool CreatureLib::Battling::ChoiceQueue::MoveCreatureChoiceNext(CreatureLib::Bat
if (choiceIndex == SIZE_MAX) if (choiceIndex == SIZE_MAX)
return false; return false;
auto& vec = _queue.GetStdList();
// Save the pointer to the creature choice. // Save the pointer to the creature choice.
auto creatureChoice = _queue[choiceIndex]; auto creatureChoice = _queue[choiceIndex];
// Starting at the position before the current creature choice, and iterating backwards up till the current choice. // Starting at the position before the current creature choice, and iterating backwards up till the current choice.
for (size_t i = choiceIndex - 1; i >= _current && i != SIZE_MAX; i--) { for (size_t i = choiceIndex - 1; i >= _current && i != SIZE_MAX; i--) {
// Place everything in one spot later. // Place everything in one spot later.
_queue[i + 1] = _queue[i]; vec[i + 1] = vec[i];
} }
// Set the creature choice up next. // Set the creature choice up next.
_queue[_current] = creatureChoice; vec[_current] = creatureChoice.GetRaw();
return true; return true;
} }

View File

@ -1,13 +1,14 @@
#ifndef CREATURELIB_CHOICEQUEUE_HPP #ifndef CREATURELIB_CHOICEQUEUE_HPP
#define CREATURELIB_CHOICEQUEUE_HPP #define CREATURELIB_CHOICEQUEUE_HPP
#include <Arbutils/Memory/UniquePtrList.hpp>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "../TurnChoices/BaseTurnChoice.hpp" #include "../TurnChoices/BaseTurnChoice.hpp"
namespace CreatureLib::Battling { namespace CreatureLib::Battling {
class ChoiceQueue { class ChoiceQueue {
std::vector<BaseTurnChoice*> _queue; ArbUt::UniquePtrList<BaseTurnChoice> _queue;
size_t _current = 0; size_t _current = 0;
public: public:
@ -15,17 +16,17 @@ namespace CreatureLib::Battling {
explicit ChoiceQueue(std::vector<BaseTurnChoice*> queue) : _queue(std::move(queue)) {} explicit ChoiceQueue(std::vector<BaseTurnChoice*> queue) : _queue(std::move(queue)) {}
BaseTurnChoice* Dequeue() { ArbUt::BorrowedPtr<BaseTurnChoice> Dequeue() {
auto b = _queue[_current]; auto b = _queue[_current];
_current++; _current++;
return b; return b;
} }
BaseTurnChoice* Peek() { return _queue[_current]; } ArbUt::BorrowedPtr<BaseTurnChoice> Peek() { return _queue[_current]; }
[[nodiscard]] bool HasNext() const { return _current < _queue.size(); } [[nodiscard]] bool HasNext() const { return _current < _queue.Count(); }
std::vector<BaseTurnChoice*>& GetInnerQueue() { return _queue; } ArbUt::UniquePtrList<BaseTurnChoice>& GetInnerQueue() { return _queue; }
bool MoveCreatureChoiceNext(Creature* creature); bool MoveCreatureChoiceNext(Creature* creature);
}; };

View File

@ -13,12 +13,11 @@ void TurnHandler::RunTurn(ChoiceQueue* queue) {
while (queue->HasNext()) { while (queue->HasNext()) {
auto item = queue->Dequeue(); auto item = queue->Dequeue();
ExecuteChoice(item); ExecuteChoice(item);
delete item;
} }
queue->HasCompletedQueue = true; queue->HasCompletedQueue = true;
} }
void TurnHandler::ExecuteChoice(BaseTurnChoice* choice) { void TurnHandler::ExecuteChoice(ArbUt::BorrowedPtr<BaseTurnChoice> choice) {
AssertNotNull(choice); AssertNotNull(choice);
auto choiceKind = choice->GetKind(); auto choiceKind = choice->GetKind();
if (choiceKind == TurnChoiceKind::Pass) { if (choiceKind == TurnChoiceKind::Pass) {
@ -42,18 +41,18 @@ void TurnHandler::ExecuteChoice(BaseTurnChoice* choice) {
switch (choiceKind) { switch (choiceKind) {
case TurnChoiceKind::Pass: throw NotReachableException(); case TurnChoiceKind::Pass: throw NotReachableException();
case TurnChoiceKind::Attack: return ExecuteAttackChoice(dynamic_cast<AttackTurnChoice*>(choice)); case TurnChoiceKind::Attack: return ExecuteAttackChoice(choice.ForceAs<AttackTurnChoice>());
case TurnChoiceKind::Switch: return ExecuteSwitchChoice(dynamic_cast<SwitchTurnChoice*>(choice)); case TurnChoiceKind::Switch: return ExecuteSwitchChoice(choice.ForceAs<SwitchTurnChoice>());
case TurnChoiceKind::Flee: return ExecuteFleeChoice(dynamic_cast<FleeTurnChoice*>(choice)); case TurnChoiceKind::Flee: return ExecuteFleeChoice(choice.ForceAs<FleeTurnChoice>());
case TurnChoiceKind::Item: throw NotImplementedException(); case TurnChoiceKind::Item: throw NotImplementedException();
} }
} }
void TurnHandler::ExecuteAttackChoice(AttackTurnChoice* choice) { void TurnHandler::ExecuteAttackChoice(ArbUt::BorrowedPtr<AttackTurnChoice> choice) {
AssertNotNull(choice) AssertNotNull(choice)
auto attackName = choice->GetAttack()->GetAttack()->GetName(); auto attackName = choice->GetAttack()->GetAttack()->GetName();
HOOK(ChangeAttack, choice, choice, &attackName); HOOK(ChangeAttack, choice, choice.GetRaw(), &attackName);
if (attackName != choice->GetAttack()->GetAttack()->GetName()) { if (attackName != choice->GetAttack()->GetAttack()->GetName()) {
// TODO: Change attack // TODO: Change attack
} }
@ -196,9 +195,9 @@ void TurnHandler::HandleAttackForTarget(ExecutingAttack* attack, Creature* targe
} }
} }
void TurnHandler::ExecuteSwitchChoice(CreatureLib::Battling::SwitchTurnChoice* choice) { void TurnHandler::ExecuteSwitchChoice(ArbUt::BorrowedPtr<SwitchTurnChoice> choice) {
bool preventSwitch = false; bool preventSwitch = false;
HOOK(PreventSelfSwitch, choice, choice, &preventSwitch); HOOK(PreventSelfSwitch, choice, choice.GetRaw(), &preventSwitch);
if (preventSwitch) { if (preventSwitch) {
return; return;
} }
@ -210,7 +209,7 @@ void TurnHandler::ExecuteSwitchChoice(CreatureLib::Battling::SwitchTurnChoice* c
auto userIndex = userSide->GetCreatureIndex(user); auto userIndex = userSide->GetCreatureIndex(user);
userSide->SetCreature(choice->GetNewCreature(), userIndex); userSide->SetCreature(choice->GetNewCreature(), userIndex);
} }
void TurnHandler::ExecuteFleeChoice(FleeTurnChoice* choice) { void TurnHandler::ExecuteFleeChoice(ArbUt::BorrowedPtr<FleeTurnChoice> choice) {
auto user = choice->GetUser(); auto user = choice->GetUser();
auto battle = user->GetBattle(); auto battle = user->GetBattle();
if (!battle->CanFlee()) { if (!battle->CanFlee()) {
@ -219,7 +218,7 @@ void TurnHandler::ExecuteFleeChoice(FleeTurnChoice* choice) {
// TODO: If any of the creatures on the users side has a script that prevents it from running, block. // TODO: If any of the creatures on the users side has a script that prevents it from running, block.
// TODO: If any of the creatures on any other side has a script that prevents this side from running, block. // TODO: If any of the creatures on any other side has a script that prevents this side from running, block.
if (battle->GetLibrary()->GetMiscLibrary()->CanFlee(choice)) { if (battle->GetLibrary()->GetMiscLibrary()->CanFlee(choice.GetRaw())) {
user->GetBattleSide()->MarkAsFled(); user->GetBattleSide()->MarkAsFled();
battle->ValidateBattleState(); battle->ValidateBattleState();
} }

View File

@ -11,13 +11,13 @@ namespace CreatureLib::Battling {
class Battle; class Battle;
class TurnHandler { class TurnHandler {
static void ExecuteChoice(BaseTurnChoice* choice); static void ExecuteChoice(ArbUt::BorrowedPtr<BaseTurnChoice> choice);
static void ExecuteAttackChoice(AttackTurnChoice* choice); static void ExecuteAttackChoice(ArbUt::BorrowedPtr<AttackTurnChoice> choice);
static void HandleAttackForTarget(ExecutingAttack* attack, Creature* target); static void HandleAttackForTarget(ExecutingAttack* attack, Creature* target);
static void ExecuteSwitchChoice(SwitchTurnChoice* choice); static void ExecuteSwitchChoice(ArbUt::BorrowedPtr<SwitchTurnChoice> choice);
static void ExecuteFleeChoice(FleeTurnChoice* choice); static void ExecuteFleeChoice(ArbUt::BorrowedPtr<FleeTurnChoice> choice);
public: public:
static void RunTurn(ChoiceQueue* queue); static void RunTurn(ChoiceQueue* queue);

View File

@ -9,11 +9,11 @@ using namespace CreatureLib::Battling;
const ArbUt::BorrowedPtr<const BattleLibrary>& Battle::GetLibrary() const noexcept { return _library; } const ArbUt::BorrowedPtr<const BattleLibrary>& Battle::GetLibrary() const noexcept { return _library; }
bool Battle::CanUse(const BaseTurnChoice* choice) { bool Battle::CanUse(const ArbUt::BorrowedPtr<BaseTurnChoice>& choice) {
AssertNotNull(choice) AssertNotNull(choice)
if (choice->GetKind() == TurnChoiceKind::Attack) { if (choice->GetKind() == TurnChoiceKind::Attack) {
// HOOK: change number of uses needed. // HOOK: change number of uses needed.
return dynamic_cast<const AttackTurnChoice*>(choice)->GetAttack()->GetRemainingUses() >= 1; return choice.ForceAs<AttackTurnChoice>()->GetAttack()->GetRemainingUses() >= 1;
} }
return true; return true;
} }

View File

@ -59,7 +59,7 @@ namespace CreatureLib::Battling {
[[nodiscard]] const ArbUt::BorrowedPtr<const BattleLibrary>& GetLibrary() const noexcept; [[nodiscard]] const ArbUt::BorrowedPtr<const BattleLibrary>& GetLibrary() const noexcept;
[[nodiscard]] uint32_t GetCurrentTurn() const noexcept { return _currentTurn; } [[nodiscard]] uint32_t GetCurrentTurn() const noexcept { return _currentTurn; }
virtual bool CanUse(const BaseTurnChoice* choice); virtual bool CanUse(const ArbUt::BorrowedPtr<BaseTurnChoice>& choice);
virtual bool TrySetChoice(BaseTurnChoice* choice); virtual bool TrySetChoice(BaseTurnChoice* choice);
bool CanFlee() const noexcept { return _canFlee; } bool CanFlee() const noexcept { return _canFlee; }

View File

@ -25,20 +25,16 @@ TEST_CASE("Move creature choice up next.", "[Battling]") {
auto choiceQueue = ChoiceQueue(choices); auto choiceQueue = ChoiceQueue(choices);
CHECK(choiceQueue.MoveCreatureChoiceNext(c4)); CHECK(choiceQueue.MoveCreatureChoiceNext(c4));
auto currentChoices = choiceQueue.GetInnerQueue(); auto& currentChoices = choiceQueue.GetInnerQueue();
CHECK(currentChoices[0]->GetUser() == c4); CHECK(currentChoices[0]->GetUser() == c4);
CHECK(currentChoices[1]->GetUser() == c1); CHECK(currentChoices[1]->GetUser() == c1);
CHECK(currentChoices[2]->GetUser() == c2); CHECK(currentChoices[2]->GetUser() == c2);
CHECK(currentChoices[3]->GetUser() == c3); CHECK(currentChoices[3]->GetUser() == c3);
CHECK_FALSE(choiceQueue.MoveCreatureChoiceNext(c4)); CHECK_FALSE(choiceQueue.MoveCreatureChoiceNext(c4));
delete choiceQueue.Dequeue(); choiceQueue.Dequeue();
delete choiceQueue.Dequeue(); choiceQueue.Dequeue();
CHECK_FALSE(choiceQueue.MoveCreatureChoiceNext(c1)); CHECK_FALSE(choiceQueue.MoveCreatureChoiceNext(c1));
delete choiceQueue.Dequeue();
delete choiceQueue.Dequeue();
delete c1; delete c1;
delete c2; delete c2;
delete c3; delete c3;