Further work on better exceptions.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2020-07-26 17:41:11 +02:00
parent 29eb7c603a
commit 36f1e5beeb
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
12 changed files with 30 additions and 37 deletions

View File

@ -137,9 +137,7 @@ void Battle::AddVolatileScript(const ArbUt::StringView& key) {
} }
script = _library->LoadScript(ScriptCategory::Battle, key); script = _library->LoadScript(ScriptCategory::Battle, key);
if (script == nullptr) { if (script == nullptr) {
std::stringstream ss; THROW_CREATURE("Invalid volatile script requested for battle: '" << key.c_str() << "'.");
ss << "Invalid volatile script requested for battle: '" << key.c_str() << "'.";
throw CreatureException(ss.str());
} }
return _volatile.Add(script.GetRaw()); return _volatile.Add(script.GetRaw());
} }

View File

@ -30,7 +30,7 @@ void BattleSide::SetChoice(BaseTurnChoice* choice) {
AssertNotNull(choice) AssertNotNull(choice)
auto find = std::find(_creatures.begin(), _creatures.end(), choice->GetUser()); auto find = std::find(_creatures.begin(), _creatures.end(), choice->GetUser());
if (find == _creatures.end()) if (find == _creatures.end())
throw CreatureException("User not found"); THROW_CREATURE("User not found");
uint8_t index = std::distance(_creatures.begin(), find); uint8_t index = std::distance(_creatures.begin(), find);
_choices[index] = std::shared_ptr<BaseTurnChoice>(choice); _choices[index] = std::shared_ptr<BaseTurnChoice>(choice);
_choicesSet++; _choicesSet++;

View File

@ -59,7 +59,7 @@ namespace CreatureLib::Battling {
if (_creatures[i] == c) if (_creatures[i] == c)
return i; return i;
} }
throw CreatureException("Unable to find creature on field."); THROW_CREATURE("Unable to find creature on field.");
} }
void MarkSlotAsUnfillable(const ArbUt::BorrowedPtr<Creature>& creature) noexcept { void MarkSlotAsUnfillable(const ArbUt::BorrowedPtr<Creature>& creature) noexcept {

View File

@ -22,7 +22,7 @@ CreateCreature CreateCreature::WithGender(Library::Gender gender) {
CreateCreature CreateCreature::WithAttack(const ArbUt::StringView& attackName, AttackLearnMethod learnMethod) { CreateCreature CreateCreature::WithAttack(const ArbUt::StringView& attackName, AttackLearnMethod learnMethod) {
if (_attacks.Count() >= _library->GetSettings()->GetMaximalMoves()) if (_attacks.Count() >= _library->GetSettings()->GetMaximalMoves())
throw CreatureException("You have already set the maximum amount of allowed moves."); THROW_CREATURE("You have already set the maximum amount of allowed moves.");
auto attackData = _library->GetAttackLibrary()->Get(attackName.GetHash()); auto attackData = _library->GetAttackLibrary()->Get(attackName.GetHash());
_attacks.Append(std::tuple(attackData, learnMethod)); _attacks.Append(std::tuple(attackData, learnMethod));
@ -50,7 +50,7 @@ Creature* CreateCreature::Create() {
ArbUt::BorrowedPtr<const Library::Item> heldItem; ArbUt::BorrowedPtr<const Library::Item> heldItem;
if (!this->_heldItem.Empty()) { if (!this->_heldItem.Empty()) {
if (!_library->GetItemLibrary()->TryGet(this->_heldItem.GetHash(), heldItem)) { if (!_library->GetItemLibrary()->TryGet(this->_heldItem.GetHash(), heldItem)) {
throw CreatureException("Invalid held item."); THROW_CREATURE("Invalid held item '" << this->_heldItem.c_str() << "'.");
} }
} }
auto experience = _library->GetGrowthRateLibrary()->CalculateExperience(species->GetGrowthRate(), _level); auto experience = _library->GetGrowthRateLibrary()->CalculateExperience(species->GetGrowthRate(), _level);

View File

@ -227,14 +227,14 @@ ArbUt::BorrowedPtr<const Library::SpeciesVariant> Battling::Creature::GetDisplay
void Battling::Creature::SetHeldItem(const ArbUt::BasicStringView& itemName) { void Battling::Creature::SetHeldItem(const ArbUt::BasicStringView& itemName) {
ArbUt::BorrowedPtr<const Library::Item> item; ArbUt::BorrowedPtr<const Library::Item> item;
if (!_library->GetItemLibrary()->TryGet(itemName.GetHash(), item)) { if (!_library->GetItemLibrary()->TryGet(itemName.GetHash(), item)) {
throw CreatureException("Item not found."); THROW_CREATURE("Item not found '" << itemName.c_str() << "'.");
} }
_heldItem = item; _heldItem = item;
} }
void Battling::Creature::SetHeldItem(uint32_t itemNameHash) { void Battling::Creature::SetHeldItem(uint32_t itemNameHash) {
ArbUt::BorrowedPtr<const Library::Item> item; ArbUt::BorrowedPtr<const Library::Item> item;
if (!_library->GetItemLibrary()->TryGet(itemNameHash, item)) { if (!_library->GetItemLibrary()->TryGet(itemNameHash, item)) {
throw CreatureException("Item not found."); THROW_CREATURE("Item not found.");
} }
_heldItem = item; _heldItem = item;
} }
@ -247,9 +247,7 @@ void Battling::Creature::AddVolatileScript(const ArbUt::StringView& name) {
} }
script = this->_library->LoadScript(ScriptCategory::Creature, name); script = this->_library->LoadScript(ScriptCategory::Creature, name);
if (script == nullptr) { if (script == nullptr) {
std::stringstream ss; THROW_CREATURE("Invalid volatile script requested for creature: '" << name.c_str() << "'.");
ss << "Invalid volatile script requested for creature: '" << name.c_str() << "'.";
throw CreatureException(ss.str());
} }
_volatile.Add(script.GetRaw()); _volatile.Add(script.GetRaw());
} }

View File

@ -66,7 +66,7 @@ namespace CreatureLib::Battling {
return _hits[i * _numberHits + hit]; return _hits[i * _numberHits + hit];
} }
} }
throw CreatureException("Invalid target requested."); THROW_CREATURE("Invalid target requested.");
} }
HitData* GetTargetIteratorBegin(Creature* creature) { HitData* GetTargetIteratorBegin(Creature* creature) {
@ -75,7 +75,7 @@ namespace CreatureLib::Battling {
return &_hits[i * _numberHits * sizeof(HitData)]; return &_hits[i * _numberHits * sizeof(HitData)];
} }
} }
throw CreatureException("Invalid target requested."); THROW_CREATURE("Invalid target requested.");
} }
bool IsCreatureTarget(Creature* creature) noexcept { bool IsCreatureTarget(Creature* creature) noexcept {

View File

@ -13,5 +13,5 @@ CreatureLib::Library::SpeciesVariant::GetTalentIndex(const ArbUt::StringView& ta
return TalentIndex(true, i); return TalentIndex(true, i);
} }
} }
throw CreatureException("The given talent is not a valid talent for this creature."); THROW_CREATURE("The given talent is not a valid talent for this creature.");
} }

View File

@ -25,9 +25,7 @@ namespace CreatureLib::Library {
inline EffectParameterType GetType() const noexcept { return _type; } inline EffectParameterType GetType() const noexcept { return _type; }
bool AsBool() const { bool AsBool() const {
if (_type != EffectParameterType::Bool) { if (_type != EffectParameterType::Bool) {
std::stringstream ss; THROW_CREATURE("Cast effect parameter to bool, but was " << EffectParameterTypeHelper::ToString(_type));
ss << "Cast effect parameter to bool, but was " << EffectParameterTypeHelper::ToString(_type);
throw CreatureException(ss.str());
} }
return std::get<bool>(_value); return std::get<bool>(_value);
} }
@ -36,9 +34,7 @@ namespace CreatureLib::Library {
if (_type == EffectParameterType::Float) { if (_type == EffectParameterType::Float) {
return static_cast<int64_t>(std::get<float>(_value)); return static_cast<int64_t>(std::get<float>(_value));
} }
std::stringstream ss; THROW_CREATURE("Cast effect parameter to int, but was " << EffectParameterTypeHelper::ToString(_type));
ss << "Cast effect parameter to int, but was " << EffectParameterTypeHelper::ToString(_type);
throw CreatureException(ss.str());
} }
return std::get<int64_t>(_value); return std::get<int64_t>(_value);
} }
@ -47,17 +43,15 @@ namespace CreatureLib::Library {
if (_type == EffectParameterType::Int) { if (_type == EffectParameterType::Int) {
return static_cast<float>(std::get<int64_t>(_value)); return static_cast<float>(std::get<int64_t>(_value));
} }
std::stringstream ss; THROW_CREATURE("Cast effect parameter to float, but was "
ss << "Cast effect parameter to float, but was " << EffectParameterTypeHelper::ToString(_type); << EffectParameterTypeHelper::ToString(_type));
throw CreatureException(ss.str());
} }
return std::get<float>(_value); return std::get<float>(_value);
} }
const ArbUt::StringView& AsString() const { const ArbUt::StringView& AsString() const {
if (_type != EffectParameterType::String) { if (_type != EffectParameterType::String) {
std::stringstream ss; THROW_CREATURE("Cast effect parameter to string, but was "
ss << "Cast effect parameter to string, but was " << EffectParameterTypeHelper::ToString(_type); << EffectParameterTypeHelper::ToString(_type));
throw CreatureException(ss.str());
} }
return std::get<ArbUt::StringView>(_value); return std::get<ArbUt::StringView>(_value);
} }

View File

@ -1,6 +1,7 @@
#ifndef CREATURELIB_CREATUREEXCEPTION_HPP #ifndef CREATURELIB_CREATUREEXCEPTION_HPP
#define CREATURELIB_CREATUREEXCEPTION_HPP #define CREATURELIB_CREATUREEXCEPTION_HPP
#include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
@ -12,7 +13,9 @@ public:
}; };
#define THROW_CREATURE(message) \ #define THROW_CREATURE(message) \
{ \
std::stringstream ss; \ std::stringstream ss; \
ss << "[" << __FILENAME__ << ", " << __LINE__ << "] " << message; \ ss << "[" << __FILENAME__ << ":" << __LINE__ << "] " << message; \
throw CreatureException(ss.str()); throw CreatureException(ss.str()); \
}
#endif // CREATURELIB_CREATUREEXCEPTION_HPP #endif // CREATURELIB_CREATUREEXCEPTION_HPP

View File

@ -5,7 +5,7 @@ uint8_t CreatureLib::Library::GrowthRateLibrary::CalculateLevel(const ArbUt::Bas
uint32_t experience) const { uint32_t experience) const {
auto find = _growthRates.find(growthRate); auto find = _growthRates.find(growthRate);
if (find == _growthRates.end()) { if (find == _growthRates.end()) {
throw CreatureException("Invalid growth rate was requested."); THROW_CREATURE("Invalid growth rate was requested.");
} }
return find->second->CalculateLevel(experience); return find->second->CalculateLevel(experience);
} }
@ -13,7 +13,7 @@ uint8_t CreatureLib::Library::GrowthRateLibrary::CalculateLevel(const ArbUt::Bas
uint8_t CreatureLib::Library::GrowthRateLibrary::CalculateLevel(uint32_t hash, uint32_t experience) const { uint8_t CreatureLib::Library::GrowthRateLibrary::CalculateLevel(uint32_t hash, uint32_t experience) const {
auto find = _growthRates.find(hash); auto find = _growthRates.find(hash);
if (find == _growthRates.end()) { if (find == _growthRates.end()) {
throw CreatureException("Invalid growth rate was requested."); THROW_CREATURE("Invalid growth rate was requested.");
} }
return find->second->CalculateLevel(experience); return find->second->CalculateLevel(experience);
} }
@ -22,7 +22,7 @@ uint32_t CreatureLib::Library::GrowthRateLibrary::CalculateExperience(const ArbU
uint8_t level) const { uint8_t level) const {
auto find = _growthRates.find(growthRate); auto find = _growthRates.find(growthRate);
if (find == _growthRates.end()) { if (find == _growthRates.end()) {
throw CreatureException("Invalid growth rate was requested."); THROW_CREATURE("Invalid growth rate was requested.");
} }
return find->second->CalculateExperience(level); return find->second->CalculateExperience(level);
} }
@ -30,7 +30,7 @@ uint32_t CreatureLib::Library::GrowthRateLibrary::CalculateExperience(const ArbU
uint32_t CreatureLib::Library::GrowthRateLibrary::CalculateExperience(uint32_t hash, uint8_t level) const { uint32_t CreatureLib::Library::GrowthRateLibrary::CalculateExperience(uint32_t hash, uint8_t level) const {
auto find = _growthRates.find(hash); auto find = _growthRates.find(hash);
if (find == _growthRates.end()) { if (find == _growthRates.end()) {
throw CreatureException("Invalid growth rate was requested."); THROW_CREATURE("Invalid growth rate was requested.");
} }
return find->second->CalculateExperience(level); return find->second->CalculateExperience(level);
} }

View File

@ -133,7 +133,7 @@ TEST_CASE("Script Aggregator properly iterates when empty.", "[Battling, Scripti
auto vec = ArbUt::List<ScriptWrapper>{}; auto vec = ArbUt::List<ScriptWrapper>{};
auto aggr = ScriptAggregator(vec); auto aggr = ScriptAggregator(vec);
while (aggr.HasNext()) { while (aggr.HasNext()) {
throw CreatureException("Aggregator returned a script, but should have been empty."); THROW_CREATURE("Aggregator returned a script, but should have been empty.");
} }
CHECK(ran == 0); CHECK(ran == 0);
} }

View File

@ -6,11 +6,11 @@
TEST_CASE("When throwing exception, what() is readable", "[Utilities]") { TEST_CASE("When throwing exception, what() is readable", "[Utilities]") {
bool hasCaught = false; bool hasCaught = false;
try { try {
throw CreatureException("foobar"); THROW_CREATURE("foobar");
} catch (const std::exception& e) { } catch (const std::exception& e) {
hasCaught = true; hasCaught = true;
INFO(e.what()); INFO(e.what());
REQUIRE(strcmp(e.what(), "foobar") == 0); REQUIRE(std::string(e.what()) == "[ExceptionTests.cpp:9] foobar");
} }
REQUIRE(hasCaught); REQUIRE(hasCaught);
} }