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

View File

@ -1,13 +1,14 @@
#ifndef CREATURELIB_CHOICEQUEUE_HPP
#define CREATURELIB_CHOICEQUEUE_HPP
#include <Arbutils/Memory/UniquePtrList.hpp>
#include <utility>
#include <vector>
#include "../TurnChoices/BaseTurnChoice.hpp"
namespace CreatureLib::Battling {
class ChoiceQueue {
std::vector<BaseTurnChoice*> _queue;
ArbUt::UniquePtrList<BaseTurnChoice> _queue;
size_t _current = 0;
public:
@ -15,17 +16,17 @@ namespace CreatureLib::Battling {
explicit ChoiceQueue(std::vector<BaseTurnChoice*> queue) : _queue(std::move(queue)) {}
BaseTurnChoice* Dequeue() {
ArbUt::BorrowedPtr<BaseTurnChoice> Dequeue() {
auto b = _queue[_current];
_current++;
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);
};

View File

@ -13,12 +13,11 @@ void TurnHandler::RunTurn(ChoiceQueue* queue) {
while (queue->HasNext()) {
auto item = queue->Dequeue();
ExecuteChoice(item);
delete item;
}
queue->HasCompletedQueue = true;
}
void TurnHandler::ExecuteChoice(BaseTurnChoice* choice) {
void TurnHandler::ExecuteChoice(ArbUt::BorrowedPtr<BaseTurnChoice> choice) {
AssertNotNull(choice);
auto choiceKind = choice->GetKind();
if (choiceKind == TurnChoiceKind::Pass) {
@ -42,18 +41,18 @@ void TurnHandler::ExecuteChoice(BaseTurnChoice* choice) {
switch (choiceKind) {
case TurnChoiceKind::Pass: throw NotReachableException();
case TurnChoiceKind::Attack: return ExecuteAttackChoice(dynamic_cast<AttackTurnChoice*>(choice));
case TurnChoiceKind::Switch: return ExecuteSwitchChoice(dynamic_cast<SwitchTurnChoice*>(choice));
case TurnChoiceKind::Flee: return ExecuteFleeChoice(dynamic_cast<FleeTurnChoice*>(choice));
case TurnChoiceKind::Attack: return ExecuteAttackChoice(choice.ForceAs<AttackTurnChoice>());
case TurnChoiceKind::Switch: return ExecuteSwitchChoice(choice.ForceAs<SwitchTurnChoice>());
case TurnChoiceKind::Flee: return ExecuteFleeChoice(choice.ForceAs<FleeTurnChoice>());
case TurnChoiceKind::Item: throw NotImplementedException();
}
}
void TurnHandler::ExecuteAttackChoice(AttackTurnChoice* choice) {
void TurnHandler::ExecuteAttackChoice(ArbUt::BorrowedPtr<AttackTurnChoice> choice) {
AssertNotNull(choice)
auto attackName = choice->GetAttack()->GetAttack()->GetName();
HOOK(ChangeAttack, choice, choice, &attackName);
HOOK(ChangeAttack, choice, choice.GetRaw(), &attackName);
if (attackName != choice->GetAttack()->GetAttack()->GetName()) {
// 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;
HOOK(PreventSelfSwitch, choice, choice, &preventSwitch);
HOOK(PreventSelfSwitch, choice, choice.GetRaw(), &preventSwitch);
if (preventSwitch) {
return;
}
@ -210,7 +209,7 @@ void TurnHandler::ExecuteSwitchChoice(CreatureLib::Battling::SwitchTurnChoice* c
auto userIndex = userSide->GetCreatureIndex(user);
userSide->SetCreature(choice->GetNewCreature(), userIndex);
}
void TurnHandler::ExecuteFleeChoice(FleeTurnChoice* choice) {
void TurnHandler::ExecuteFleeChoice(ArbUt::BorrowedPtr<FleeTurnChoice> choice) {
auto user = choice->GetUser();
auto battle = user->GetBattle();
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 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();
battle->ValidateBattleState();
}

View File

@ -11,13 +11,13 @@ namespace CreatureLib::Battling {
class Battle;
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 ExecuteSwitchChoice(SwitchTurnChoice* choice);
static void ExecuteFleeChoice(FleeTurnChoice* choice);
static void ExecuteSwitchChoice(ArbUt::BorrowedPtr<SwitchTurnChoice> choice);
static void ExecuteFleeChoice(ArbUt::BorrowedPtr<FleeTurnChoice> choice);
public:
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; }
bool Battle::CanUse(const BaseTurnChoice* choice) {
bool Battle::CanUse(const ArbUt::BorrowedPtr<BaseTurnChoice>& choice) {
AssertNotNull(choice)
if (choice->GetKind() == TurnChoiceKind::Attack) {
// HOOK: change number of uses needed.
return dynamic_cast<const AttackTurnChoice*>(choice)->GetAttack()->GetRemainingUses() >= 1;
return choice.ForceAs<AttackTurnChoice>()->GetAttack()->GetRemainingUses() >= 1;
}
return true;
}

View File

@ -59,7 +59,7 @@ namespace CreatureLib::Battling {
[[nodiscard]] const ArbUt::BorrowedPtr<const BattleLibrary>& GetLibrary() const noexcept;
[[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);
bool CanFlee() const noexcept { return _canFlee; }

View File

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