From 883d5d3f417bdf434eb0373ca3c8b16247a03998 Mon Sep 17 00:00:00 2001 From: William JCM Date: Wed, 23 Feb 2022 15:47:28 +0100 Subject: [PATCH] Mass,SaveTool: improve error handling. --- src/Mass/Mass.cpp | 79 ++++++++++++++++++++----- src/Mass/Mass.h | 4 +- src/SaveTool/SaveTool_MassViewer.cpp | 87 ++++++++++++++++++++-------- 3 files changed, 130 insertions(+), 40 deletions(-) diff --git a/src/Mass/Mass.cpp b/src/Mass/Mass.cpp index 84b6b45..7b81c68 100644 --- a/src/Mass/Mass.cpp +++ b/src/Mass/Mass.cpp @@ -35,8 +35,6 @@ #include "Mass.h" -std::string Mass::_lastError; - Mass::Mass(const std::string& path) { _folder = Utility::Directory::path(path); _filename = Utility::Directory::filename(path); @@ -50,28 +48,28 @@ auto Mass::lastError() -> std::string const& { auto Mass::getNameFromFile(const std::string& path) -> Containers::Optional { if(!Utility::Directory::exists(path)) { - _lastError = path + " couldn't be found."; + Utility::Error{} << path.c_str() << "couldn't be found."; return Containers::NullOpt; } UESaveFile mass{path}; if(!mass.valid()) { - _lastError = "The unit file seems to be corrupt."; + Utility::Error{} << "The unit file seems to be corrupt."; return Containers::NullOpt; } auto unit_data = mass.at("UnitData"); if(!unit_data) { - _lastError = "Couldn't find unit data in the file."; + Utility::Error{} << "Couldn't find unit data in the file."; return Containers::NullOpt; } auto name_prop = unit_data->at("Name_45_A037C5D54E53456407BDF091344529BB"); if(!name_prop) { - _lastError = "Couldn't find the name in the file."; + Utility::Error{} << "Couldn't find the name in the file."; return Containers::NullOpt; } @@ -378,7 +376,7 @@ auto Mass::writeJointSliders() -> bool { frame_prop->properties = std::move(temp); if(!_mass->saveToFile()) { - _lastError = "Couldn't write data to " + _filename; + _lastError = _mass->lastError(); return false; } @@ -445,7 +443,7 @@ auto Mass::writeFrameStyles() -> bool { } if(!_mass->saveToFile()) { - _lastError = "Couldn't write data to " + _filename; + _lastError = _mass->lastError(); return false; } @@ -482,18 +480,21 @@ auto Mass::writeEyeFlareColour() -> bool { auto unit_data = _mass->at("UnitData"); if(!unit_data) { _state = State::Invalid; + _lastError = "No unit data in " + _filename; return false; } auto frame = unit_data->at("Frame_3_F92B0F6A44A15088AF7F41B9FF290653"); if(!frame) { _state = State::Invalid; + _lastError = "No frame data in " + _filename; return false; } auto eye_flare_prop = frame->at("EyeFlareColor_36_AF79999C40FCA0E88A2F9A84488A38CA"); if(!eye_flare_prop) { _state = State::Invalid; + _lastError = "No eye flare property in " + _filename; return false; } @@ -502,7 +503,12 @@ auto Mass::writeEyeFlareColour() -> bool { eye_flare_prop->b = _frame.eyeFlare.b(); eye_flare_prop->a = _frame.eyeFlare.a(); - return _mass->saveToFile(); + if(!_mass->saveToFile()) { + _lastError = _mass->lastError(); + return false; + } + + return true; } auto Mass::frameCustomStyles() -> Containers::ArrayView { @@ -532,18 +538,21 @@ void Mass::getFrameCustomStyles() { auto Mass::writeFrameCustomStyle(UnsignedLong index) -> bool { if(index > _frame.customStyles.size()) { + _lastError = "Style index out of range."; return false; } auto unit_data = _mass->at("UnitData"); if(!unit_data) { _state = State::Invalid; + _lastError = "No unit data in " + _filename; return false; } auto frame_styles = unit_data->at("FrameStyle_44_04A44C9440363CCEC5443D98BFAF22AA"); if(!frame_styles) { _state = State::Invalid; + _lastError = "No frame styles in " + _filename; return false; } @@ -652,6 +661,14 @@ auto Mass::writeArmourPart(ArmourSlot slot) -> bool { } if(!part_prop) { + _lastError = "Couldn't find the armour part for slot "; + switch(slot) { + #define c(enumerator, strenum, name) case ArmourSlot::enumerator: \ + _lastError += "ArmourSlot::" #enumerator "."; \ + break; + #include "../Maps/ArmourSlots.hpp" + #undef c + } return false; } @@ -670,7 +687,12 @@ auto Mass::writeArmourPart(ArmourSlot slot) -> bool { writeAccessories(part.accessories, accs_array); } - return _mass->saveToFile(); + if(!_mass->saveToFile()) { + _lastError = _mass->lastError(); + return false; + } + + return true; } auto Mass::armourCustomStyles() -> Containers::ArrayView { @@ -700,17 +722,20 @@ void Mass::getArmourCustomStyles() { auto Mass::writeArmourCustomStyle(UnsignedLong index) -> bool { if(index > _armour.customStyles.size()) { + _lastError = "Style index out of range."; return false; } auto unit_data = _mass->at("UnitData"); if(!unit_data) { _state = State::Invalid; + _lastError = "Couldn't find unit data in " + _filename; return false; } auto armour_styles = unit_data->at("ArmorStyle_42_E2F6AC3647788CB366BD469B3B7E899E"); if(!armour_styles) { + _lastError = "Couldn't find armour custom styles in " + _filename; _state = State::Invalid; return false; } @@ -817,18 +842,21 @@ void Mass::getGlobalStyles() { auto Mass::writeGlobalStyle(UnsignedLong index) -> bool { if(index > _globalStyles.size()) { + _lastError = "Global style index out of range"; return false; } auto unit_data = _mass->at("UnitData"); if(!unit_data) { _state = State::Invalid; + _lastError = "No unit data found in " + _filename; return false; } auto global_styles = unit_data->at("GlobalStyles_57_6A681C114035241F7BDAAE9B43A8BF1B"); if(!global_styles) { _state = State::Invalid; + _lastError = "No global styles found in " + _filename; return false; } @@ -919,11 +947,17 @@ void Mass::getCustomStyles(Containers::ArrayView styles, ArrayPrope auto Mass::setCustomStyle(const CustomStyle& style, UnsignedLong index, ArrayProperty* style_array) -> bool { if(!style_array) { + _lastError = "Mass::setCustomStyle(): style_array is null."; return false; } auto style_prop = style_array->at(index); + if(!style_prop) { + _lastError = "Style index is out of range in " + _filename; + return false; + } + style_prop->at("Name_27_1532115A46EF2B2FA283908DF561A86B")->value = style.name; auto colour_prop = style_prop->at("Color_5_F0D383DF40474C9464AE48A0984A212E"); colour_prop->r = style.colour.r(); @@ -940,7 +974,12 @@ auto Mass::setCustomStyle(const CustomStyle& style, UnsignedLong index, ArrayPro style_prop->at("Rotation_25_EC2DFAD84AD0A6BD3FA841ACD52EDD6D")->value = style.rotation; style_prop->at("Scale_26_19DF0708409262183E1247B317137671")->value = style.scale; - return _mass->saveToFile(); + if(!_mass->saveToFile()) { + _lastError = _mass->lastError(); + return false; + } + + return true; } void Mass::getDecals(Containers::ArrayView decals, ArrayProperty* decal_array) { @@ -1162,17 +1201,20 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView auto unit_data = _mass->at("UnitData"); if(!unit_data) { _state = State::Invalid; + _lastError = "No unit data in " + _filename; return false; } auto prop = unit_data->at(prop_name); if(!prop) { _state = State::Invalid; + _lastError = std::string{prop_name} + " not found in " + _filename; return false; } if(prop->items.size() != weapon_array.size()) { _state = State::Invalid; + _lastError = "Weapon type array size mismatch."; return false; } @@ -1192,6 +1234,7 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView auto parts_prop = weapon_prop->at("Element_6_8E4617CC4B2C1F1490435599784EC6E0"); if(parts_prop->items.size() != weapon.parts.size()) { _state = State::Invalid; + _lastError = "Weapon parts array size mismatch."; return false; } @@ -1216,6 +1259,7 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView if(part_accs->items.size() != part.accessories.size()) { _state = State::Invalid; + _lastError = "Accessories array size mismatch."; return false; } @@ -1225,11 +1269,13 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView auto custom_styles = weapon_prop->at("Styles_10_8C3C82444B986AD7A99595AD4985912D"); if(!custom_styles) { _state = State::Invalid; + _lastError = "No custom styles found for weapon."; return false; } if(custom_styles->items.size() != weapon.customStyles.size()) { _state = State::Invalid; + _lastError = "Custom styles array size mismatch."; return false; } @@ -1243,7 +1289,7 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView #include "../Maps/DamageTypes.hpp" #undef c default: - Utility::Warning{} << "Invalid damage type enum value in writeWeaponType()."; + Utility::Warning{} << "Unknown damage type enum value in writeWeaponType()."; } weapon_prop->at("DualWield_20_B2EB2CEA4A6A233DC7575996B6DD1222")->value = weapon.dualWield; switch(weapon.effectColourMode) { @@ -1252,6 +1298,8 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView break; #include "../Maps/EffectColourModes.hpp" #undef c + default: + Utility::Warning{} << "Unknown effect colour mode in writeWeaponType()."; } auto effect_colour = weapon_prop->at("ColorEfx_26_D921B62946C493E487455A831F4520AC"); effect_colour->r = weapon.effectColour.r(); @@ -1260,7 +1308,12 @@ auto Mass::writeWeaponType(const char* prop_name, Containers::ArrayView effect_colour->a = weapon.effectColour.a(); } - return _mass->saveToFile(); + if(!_mass->saveToFile()) { + _lastError = _mass->lastError(); + return false; + } + + return true; } void Mass::getTuningCategory(const char* big_node_prop_name, Int& big_node_id, diff --git a/src/Mass/Mass.h b/src/Mass/Mass.h index f46a4e9..3edfc3c 100644 --- a/src/Mass/Mass.h +++ b/src/Mass/Mass.h @@ -56,7 +56,7 @@ class Mass { Mass(Mass&&) = default; Mass& operator=(Mass&&) = default; - static auto lastError() -> std::string const&; + auto lastError() -> std::string const&; static auto getNameFromFile(const std::string& path) -> Containers::Optional; @@ -156,7 +156,7 @@ class Mass { Containers::Optional _mass; - static std::string _lastError; + std::string _lastError; std::string _folder; std::string _filename; diff --git a/src/SaveTool/SaveTool_MassViewer.cpp b/src/SaveTool/SaveTool_MassViewer.cpp index 2bd8730..b19ba9b 100644 --- a/src/SaveTool/SaveTool_MassViewer.cpp +++ b/src/SaveTool/SaveTool_MassViewer.cpp @@ -319,7 +319,7 @@ void SaveTool::drawJointSliders() { else { if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { if(!_currentMass->writeJointSliders()) { - _queue.addToast(Toast::Type::Error, "Error: " + Mass::lastError()); + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } _jointsDirty = false; } @@ -368,7 +368,7 @@ void SaveTool::drawFrameStyles() { else { if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { if(!_currentMass->writeFrameStyles()) { - _queue.addToast(Toast::Type::Error, "Error: " + Mass::lastError()); + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } _stylesDirty = false; } @@ -399,7 +399,7 @@ void SaveTool::drawEyeColourPicker() { else { if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { if(!_currentMass->writeEyeFlareColour()) { - _queue.addToast(Toast::Type::Error, "Error writing the eye flare colour."); + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } _eyeFlareDirty = false; } @@ -432,7 +432,9 @@ void SaveTool::drawCustomFrameStyles() { _currentMass->getFrameCustomStyles(); break; case DCS_Save: - _currentMass->writeFrameCustomStyle(i); + if(!_currentMass->writeFrameCustomStyle(i)) { + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); + } break; default: break; @@ -576,7 +578,9 @@ void SaveTool::drawArmour() { ImGui::Separator(); if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { - _currentMass->writeArmourPart(part.slot); + if(!_currentMass->writeArmourPart(part.slot)) { + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); + } } } @@ -607,7 +611,9 @@ void SaveTool::drawCustomArmourStyles() { _currentMass->getArmourCustomStyles(); break; case DCS_Save: - _currentMass->writeArmourCustomStyle(i); + if(_currentMass->writeArmourCustomStyle(i)) { + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); + } break; default: break; @@ -713,28 +719,57 @@ void SaveTool::drawWeapons() { if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) { if(_meleeDirty) { - _currentMass->writeMeleeWeapons(); - _meleeDirty = false; + if(!_currentMass->writeMeleeWeapons()) { + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); + } + else { + _meleeDirty = false; + } } + if(_shieldsDirty) { - _currentMass->writeShields(); - _shieldsDirty = false; + if(!_currentMass->writeShields()) { + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); + } + else { + _shieldsDirty = false; + } } + if(_bShootersDirty) { - _currentMass->writeBulletShooters(); - _bShootersDirty = false; + if(!_currentMass->writeBulletShooters()) { + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); + } + else { + _bShootersDirty = false; + } } + if(_eShootersDirty) { - _currentMass->writeEnergyShooters(); - _eShootersDirty = false; + if(_currentMass->writeEnergyShooters()) { + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); + } + else { + _eShootersDirty = false; + } } + if(_bLaunchersDirty) { - _currentMass->writeBulletLaunchers(); - _bLaunchersDirty = false; + if(_currentMass->writeBulletLaunchers()) { + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); + } + else { + _bLaunchersDirty = false; + } } + if(_eLaunchersDirty) { - _currentMass->writeEnergyLaunchers(); - _eLaunchersDirty = false; + if(_currentMass->writeEnergyLaunchers()) { + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); + } + else { + _eLaunchersDirty = false; + } } } @@ -797,32 +832,32 @@ void SaveTool::drawWeapons() { switch(current_weapon->type) { case WeaponType::Melee: if(!_currentMass->writeMeleeWeapons()) { - _queue.addToast(Toast::Type::Error, "Couldn't save melee weapons"); + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; case WeaponType::Shield: if(!_currentMass->writeShields()) { - _queue.addToast(Toast::Type::Error, "Couldn't save shields"); + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; case WeaponType::BulletShooter: if(!_currentMass->writeBulletShooters()) { - _queue.addToast(Toast::Type::Error, "Couldn't save bullet shooters"); + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; case WeaponType::EnergyShooter: if(!_currentMass->writeEnergyShooters()) { - _queue.addToast(Toast::Type::Error, "Couldn't save energy shooters"); + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; case WeaponType::BulletLauncher: if(!_currentMass->writeBulletLaunchers()) { - _queue.addToast(Toast::Type::Error, "Couldn't save bullet launchers"); + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; case WeaponType::EnergyLauncher: if(!_currentMass->writeEnergyLaunchers()) { - _queue.addToast(Toast::Type::Error, "Couldn't save energy launchers"); + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); } break; default: @@ -1068,7 +1103,9 @@ void SaveTool::drawGlobalStyles() { _currentMass->getGlobalStyles(); break; case DCS_Save: - _currentMass->writeGlobalStyle(i); + if(!_currentMass->writeGlobalStyle(i)) { + _queue.addToast(Toast::Type::Error, _currentMass->lastError()); + } break; default: break;