diff --git a/src/ObjCommon/Menu/GenericMenu.h b/src/ObjCommon/Menu/GenericMenu.h deleted file mode 100644 index e69de29b..00000000 diff --git a/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp b/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp index 072b3990..a9ae7f42 100644 --- a/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp +++ b/src/ObjLoading/AssetLoading/AssetLoadingManager.cpp @@ -18,19 +18,21 @@ AssetLoadingContext* AssetLoadingManager::GetAssetLoadingContext() const return &m_context; } -void AssetLoadingManager::AddAsset(const asset_type_t assetType, const std::string& assetName, void* asset, std::vector dependencies, std::vector usedScriptStrings, +XAssetInfoGeneric* AssetLoadingManager::AddAsset(const asset_type_t assetType, const std::string& assetName, void* asset, std::vector dependencies, std::vector usedScriptStrings, Zone* zone) { m_last_dependency_loaded = m_context.m_zone->m_pools->AddAsset(assetType, assetName, asset, std::move(dependencies), std::move(usedScriptStrings), zone); if (m_last_dependency_loaded == nullptr) std::cout << "Failed to add asset of type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\" to pool: \"" << assetName << "\"" << std::endl; + return m_last_dependency_loaded; } -void AssetLoadingManager::AddAsset(const asset_type_t assetType, const std::string& assetName, void* asset, std::vector dependencies, std::vector usedScriptStrings) +XAssetInfoGeneric* AssetLoadingManager::AddAsset(const asset_type_t assetType, const std::string& assetName, void* asset, std::vector dependencies, std::vector usedScriptStrings) { m_last_dependency_loaded = m_context.m_zone->m_pools->AddAsset(assetType, assetName, asset, std::move(dependencies), std::move(usedScriptStrings)); if (m_last_dependency_loaded == nullptr) std::cout << "Failed to add asset of type \"" << m_context.m_zone->m_pools->GetAssetTypeName(assetType) << "\" to pool: \"" << assetName << "\"" << std::endl; + return m_last_dependency_loaded; } XAssetInfoGeneric* AssetLoadingManager::LoadIgnoredDependency(const asset_type_t assetType, const std::string& assetName, IAssetLoader* loader) diff --git a/src/ObjLoading/AssetLoading/AssetLoadingManager.h b/src/ObjLoading/AssetLoading/AssetLoadingManager.h index 577d9ddc..3f2f931c 100644 --- a/src/ObjLoading/AssetLoading/AssetLoadingManager.h +++ b/src/ObjLoading/AssetLoading/AssetLoadingManager.h @@ -14,7 +14,7 @@ class AssetLoadingManager final : public IAssetLoadingManager XAssetInfoGeneric* LoadIgnoredDependency(asset_type_t assetType, const std::string& assetName, IAssetLoader* loader); XAssetInfoGeneric* LoadAssetDependency(asset_type_t assetType, const std::string& assetName, IAssetLoader* loader); - void AddAsset(asset_type_t assetType, const std::string& assetName, void* asset, std::vector dependencies, std::vector usedScriptStrings, Zone* zone); + XAssetInfoGeneric* AddAsset(asset_type_t assetType, const std::string& assetName, void* asset, std::vector dependencies, std::vector usedScriptStrings, Zone* zone); public: AssetLoadingManager(const std::unordered_map>& assetLoadersByType, AssetLoadingContext& context); @@ -23,6 +23,6 @@ public: _NODISCARD AssetLoadingContext* GetAssetLoadingContext() const override; - void AddAsset(asset_type_t assetType, const std::string& assetName, void* asset, std::vector dependencies, std::vector usedScriptStrings) override; + XAssetInfoGeneric* AddAsset(asset_type_t assetType, const std::string& assetName, void* asset, std::vector dependencies, std::vector usedScriptStrings) override; XAssetInfoGeneric* LoadDependency(asset_type_t assetType, const std::string& assetName) override; }; diff --git a/src/ObjLoading/AssetLoading/IAssetLoadingManager.h b/src/ObjLoading/AssetLoading/IAssetLoadingManager.h index 43bd6c95..e92aa920 100644 --- a/src/ObjLoading/AssetLoading/IAssetLoadingManager.h +++ b/src/ObjLoading/AssetLoading/IAssetLoadingManager.h @@ -18,10 +18,10 @@ public: _NODISCARD virtual AssetLoadingContext* GetAssetLoadingContext() const = 0; - virtual void AddAsset(asset_type_t assetType, const std::string& assetName, void* asset, std::vector dependencies, std::vector usedScriptStrings) = 0; - void AddAsset(const asset_type_t assetType, const std::string& assetName, void* asset) + virtual XAssetInfoGeneric* AddAsset(asset_type_t assetType, const std::string& assetName, void* asset, std::vector dependencies, std::vector usedScriptStrings) = 0; + XAssetInfoGeneric* AddAsset(const asset_type_t assetType, const std::string& assetName, void* asset) { - AddAsset(assetType, assetName, asset, std::vector(), std::vector()); + return AddAsset(assetType, assetName, asset, std::vector(), std::vector()); } virtual XAssetInfoGeneric* LoadDependency(asset_type_t assetType, const std::string& assetName) = 0; }; diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp index e8f885de..73a23d68 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp @@ -5,6 +5,7 @@ #include "ObjLoading.h" #include "Game/IW4/IW4.h" +#include "Game/IW4/Menu/MenuConverterIW4.h" #include "Parsing/Menu/MenuFileReader.h" #include "Pool/GlobalAssetPool.h" @@ -55,8 +56,8 @@ void AssetLoaderMenuList::AddResultsToZoneState(menu::ParsingResult* parsingResu zoneState->m_menus.emplace_back(std::move(menu)); } -void AssetLoaderMenuList::ProcessParsedResults(const std::string& assetName, MemoryManager* memory, IAssetLoadingManager* manager, menu::ParsingResult* parsingResult, - menu::MenuAssetZoneState* zoneState) +bool AssetLoaderMenuList::ProcessParsedResults(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, menu::ParsingResult* parsingResult, + menu::MenuAssetZoneState* zoneState, std::vector& menus, std::vector& menuListDependencies) { std::cout << "Successfully read menu list \"" << assetName << "\":\n"; @@ -72,12 +73,52 @@ void AssetLoaderMenuList::ProcessParsedResults(const std::string& assetName, Mem for (const auto& function : parsingResult->m_functions) std::cout << " " << function->m_name << "\n"; + for (const auto& menu : parsingResult->m_menus) + { + // TODO: Use command line arguments to activate legacy mode + MenuConverter converter(false, searchPath, memory, manager); + auto* menuAsset = converter.ConvertMenu(*menu); + if(menuAsset == nullptr) + { + std::cout << "Failed to convert menu \"" << menu->m_name << "\"\n"; + return false; + } + + menus.push_back(menuAsset); + auto* menuAssetInfo = manager->AddAsset(ASSET_TYPE_MENU, menu->m_name, menuAsset, std::move(converter.GetDependencies()), std::vector()); + + if (menuAssetInfo) + menuListDependencies.push_back(menuAssetInfo); + } + AddResultsToZoneState(parsingResult, zoneState); + + return true; +} + +MenuList* AssetLoaderMenuList::CreateMenuListAsset(const std::string& assetName, MemoryManager* memory, const std::vector& menus) +{ + auto* menuListAsset = memory->Create(); + menuListAsset->name = memory->Dup(assetName.c_str()); + menuListAsset->menuCount = static_cast(menus.size()); + + if (menuListAsset->menuCount > 0) + { + menuListAsset->menus = static_cast(memory->Alloc(sizeof(uintptr_t) * menuListAsset->menuCount)); + for(auto i = 0; i < menuListAsset->menuCount; i++) + menuListAsset->menus[i] = menus[i]; + } + else + menuListAsset->menus = nullptr; + + return menuListAsset; } bool AssetLoaderMenuList::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { std::deque menuFileQueue; + std::vector menus; + std::vector menuListDependencies; auto* zoneState = manager->GetAssetLoadingContext()->GetZoneAssetLoaderState(); menuFileQueue.push_back(assetName); @@ -107,7 +148,7 @@ bool AssetLoaderMenuList::LoadFromRaw(const std::string& assetName, ISearchPath* const auto menuFileResult = reader.ReadMenuFile(); if (menuFileResult) { - ProcessParsedResults(nextMenuFile, memory, manager, menuFileResult.get(), zoneState); + ProcessParsedResults(nextMenuFile, searchPath, memory, manager, menuFileResult.get(), zoneState, menus, menuListDependencies); AddMenuFilesToLoadToQueue(menuFileQueue, menuFileResult.get(), zoneState); } else @@ -116,5 +157,10 @@ bool AssetLoaderMenuList::LoadFromRaw(const std::string& assetName, ISearchPath* menuFileQueue.pop_front(); } + auto* menuListAsset = CreateMenuListAsset(assetName, memory, menus); + + if(menuListAsset) + manager->AddAsset(ASSET_TYPE_MENULIST, assetName, menuListAsset); + return true; } diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.h b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.h index 175086f1..e9ed0cbe 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.h +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.h @@ -16,7 +16,8 @@ namespace IW4 static bool ShouldLoadMenuFile(const std::string& menuFilePath, menu::MenuAssetZoneState* zoneState); static void AddMenuFilesToLoadToQueue(std::deque& queue, const menu::ParsingResult* parsingResult, menu::MenuAssetZoneState* zoneState); static void AddResultsToZoneState(menu::ParsingResult* parsingResult, menu::MenuAssetZoneState* zoneState); - static void ProcessParsedResults(const std::string& assetName, MemoryManager* memory, IAssetLoadingManager* manager, menu::ParsingResult* parsingResult, menu::MenuAssetZoneState* zoneState); + static bool ProcessParsedResults(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, menu::ParsingResult* parsingResult, menu::MenuAssetZoneState* zoneState, std::vector& menus, std::vector& menuListDependencies); + static MenuList* CreateMenuListAsset(const std::string& assetName, MemoryManager* memory, const std::vector& menus); public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; diff --git a/src/ObjLoading/Game/IW4/Menu/MenuConverterIW4.cpp b/src/ObjLoading/Game/IW4/Menu/MenuConverterIW4.cpp new file mode 100644 index 00000000..89c10875 --- /dev/null +++ b/src/ObjLoading/Game/IW4/Menu/MenuConverterIW4.cpp @@ -0,0 +1,244 @@ +#include "MenuConverterIW4.h" + +#include + +#include "Menu/AbstractMenuConverter.h" + +using namespace IW4; +using namespace menu; + +namespace IW4 +{ + class MenuConverterImpl : public AbstractMenuConverter + { + static void ApplyMenuDefaults(menuDef_t* menu) + { + memset(menu, 0, sizeof(menuDef_t)); + menu->window.foreColor[0] = 1.0f; + menu->window.foreColor[1] = 1.0f; + menu->window.foreColor[2] = 1.0f; + menu->window.foreColor[3] = 1.0f; + } + + static void ApplyItemDefaults(itemDef_s* item) + { + memset(item, 0, sizeof(itemDef_s)); + item->window.foreColor[0] = 1.0f; + item->window.foreColor[1] = 1.0f; + item->window.foreColor[2] = 1.0f; + item->window.foreColor[3] = 1.0f; + } + + _NODISCARD static rectDef_s ConvertRectDef(const CommonRect& rect) + { + return rectDef_s{ + static_cast(rect.x), + static_cast(rect.y), + static_cast(rect.w), + static_cast(rect.h), + static_cast(rect.horizontalAlign), + static_cast(rect.verticalAlign) + }; + } + + static void ConvertColor(float (&output)[4], const CommonColor& input) + { + output[0] = static_cast(input.r); + output[1] = static_cast(input.g); + output[2] = static_cast(input.b); + output[3] = static_cast(input.a); + } + + static void ApplyFlag(int& flags, const bool shouldApply, const int flagValue) + { + if (!shouldApply) + return; + + flags |= flagValue; + } + + _NODISCARD Material* ConvertMaterial(const std::string& materialName, const CommonMenuDef* menu, const CommonItemDef* item) const + { + if (materialName.empty()) + return nullptr; + + auto* materialDependency = m_manager->LoadDependency(ASSET_TYPE_MATERIAL, materialName); + if (!materialDependency) + throw MenuConversionException("Failed to load material \"" + materialName + "\"", menu, item); + + return static_cast(materialDependency->m_ptr); + } + + _NODISCARD Material* ConvertMaterial(const std::string& materialName, const CommonMenuDef* menu) const + { + return ConvertMaterial(materialName, menu, nullptr); + } + + _NODISCARD Statement_s* ConvertExpression(const ISimpleExpression* expression) const + { + if (!expression) + return nullptr; + + return nullptr; + } + + _NODISCARD Statement_s* ConvertOrApplyStatement(float& staticValue, const ISimpleExpression* expression, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const + { + if (m_legacy_mode) + return ConvertExpression(expression); + + if (!expression) + return nullptr; + + if (expression->IsStatic()) + { + const auto value = expression->Evaluate(); + switch (value.m_type) + { + case SimpleExpressionValue::Type::DOUBLE: + staticValue = static_cast(value.m_double_value); + break; + case SimpleExpressionValue::Type::INT: + staticValue = static_cast(value.m_int_value); + break; + case SimpleExpressionValue::Type::STRING: + throw MenuConversionException("Cannot convert string expression value to floating point", menu, item); + } + return nullptr; + } + + return ConvertExpression(expression); + } + + _NODISCARD MenuEventHandlerSet* ConvertEventHandlerSet(const CommonEventHandlerSet* eventHandlerSet) const + { + if (!eventHandlerSet) + return nullptr; + + return nullptr; + } + + _NODISCARD ItemKeyHandler* ConvertKeyHandler(const std::map>& keyHandlers) const + { + if (keyHandlers.empty()) + return nullptr; + + return nullptr; + } + + _NODISCARD itemDef_s* ConvertItem(const CommonItemDef& commonItem) const + { + auto* item = m_memory->Create(); + ApplyItemDefaults(item); + + item->window.name = m_memory->Dup(commonItem.m_name.c_str()); + item->text = m_memory->Dup(commonItem.m_text.c_str()); + + return item; + } + + _NODISCARD itemDef_s** ConvertMenuItems(const CommonMenuDef& commonMenu) const + { + if (commonMenu.m_items.empty()) + return nullptr; + + auto* items = static_cast(m_memory->Alloc(sizeof(void*) * commonMenu.m_items.size())); + memset(items, 0, sizeof(void*) * commonMenu.m_items.size()); + + for(auto i = 0u; i < commonMenu.m_items.size(); i++) + items[i] = ConvertItem(*commonMenu.m_items[i]); + + return items; + } + + public: + MenuConverterImpl(const bool legacyMode, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) + : AbstractMenuConverter(legacyMode, searchPath, memory, manager) + { + } + + _NODISCARD menuDef_t* ConvertMenu(const CommonMenuDef& commonMenu) const + { + auto* menu = m_memory->Create(); + ApplyMenuDefaults(menu); + + menu->window.name = m_memory->Dup(commonMenu.m_name.c_str()); + menu->fullScreen = commonMenu.m_full_screen; + ApplyFlag(menu->window.staticFlags, commonMenu.m_screen_space, WINDOW_FLAG_SCREEN_SPACE); + ApplyFlag(menu->window.staticFlags, commonMenu.m_decoration, WINDOW_FLAG_DECORATION); + menu->window.rect = ConvertRectDef(commonMenu.m_rect); + menu->window.style = commonMenu.m_style; + menu->window.border = commonMenu.m_border; + menu->window.borderSize = static_cast(commonMenu.m_border_size); + ConvertColor(menu->window.backColor, commonMenu.m_back_color); + ConvertColor(menu->window.foreColor, commonMenu.m_fore_color); + ConvertColor(menu->window.borderColor, commonMenu.m_border_color); + ConvertColor(menu->focusColor, commonMenu.m_focus_color); + menu->window.background = ConvertMaterial(commonMenu.m_background, &commonMenu); + menu->window.ownerDraw = commonMenu.m_owner_draw; + menu->window.ownerDrawFlags = commonMenu.m_owner_draw_flags; + ApplyFlag(menu->window.staticFlags, commonMenu.m_out_of_bounds_click, WINDOW_FLAG_OUT_OF_BOUNDS_CLICK); + menu->soundName = ConvertString(commonMenu.m_sound_loop); + ApplyFlag(menu->window.staticFlags, commonMenu.m_popup, WINDOW_FLAG_POPUP); + menu->fadeClamp = static_cast(commonMenu.m_fade_clamp); + menu->fadeCycle = commonMenu.m_fade_cycle; + menu->fadeAmount = static_cast(commonMenu.m_fade_amount); + menu->fadeInAmount = static_cast(commonMenu.m_fade_in_amount); + menu->blurRadius = static_cast(commonMenu.m_blur_radius); + ApplyFlag(menu->window.staticFlags, commonMenu.m_legacy_split_screen_scale, WINDOW_FLAG_LEGACY_SPLIT_SCREEN_SCALE); + ApplyFlag(menu->window.staticFlags, commonMenu.m_hidden_during_scope, WINDOW_FLAG_HIDDEN_DURING_SCOPE); + ApplyFlag(menu->window.staticFlags, commonMenu.m_hidden_during_flashbang, WINDOW_FLAG_HIDDEN_DURING_FLASH_BANG); + ApplyFlag(menu->window.staticFlags, commonMenu.m_hidden_during_ui, WINDOW_FLAG_HIDDEN_DURING_UI); + menu->allowedBinding = ConvertString(commonMenu.m_allowed_binding); + ApplyFlag(menu->window.staticFlags, commonMenu.m_text_only_focus, WINDOW_FLAG_TEXT_ONLY_FOCUS); + menu->visibleExp = ConvertExpression(commonMenu.m_visible_expression.get()); + menu->rectXExp = ConvertOrApplyStatement(menu->window.rect.x, commonMenu.m_rect_x_exp.get(), &commonMenu); + menu->rectYExp = ConvertOrApplyStatement(menu->window.rect.y, commonMenu.m_rect_y_exp.get(), &commonMenu); + menu->rectWExp = ConvertOrApplyStatement(menu->window.rect.w, commonMenu.m_rect_w_exp.get(), &commonMenu); + menu->rectHExp = ConvertOrApplyStatement(menu->window.rect.h, commonMenu.m_rect_h_exp.get(), &commonMenu); + menu->openSoundExp = ConvertExpression(commonMenu.m_open_sound_exp.get()); + menu->closeSoundExp = ConvertExpression(commonMenu.m_close_sound_exp.get()); + menu->onOpen = ConvertEventHandlerSet(commonMenu.m_on_open.get()); + menu->onClose = ConvertEventHandlerSet(commonMenu.m_on_close.get()); + menu->onCloseRequest = ConvertEventHandlerSet(commonMenu.m_on_request_close.get()); + menu->onESC = ConvertEventHandlerSet(commonMenu.m_on_esc.get()); + menu->onKey = ConvertKeyHandler(commonMenu.m_key_handlers); + menu->items = ConvertMenuItems(commonMenu); + + return menu; + } + + std::vector m_dependencies; + }; +} + +MenuConverter::MenuConverter(const bool legacyMode, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) + : m_legacy_mode(legacyMode), + m_search_path(searchPath), + m_memory(memory), + m_manager(manager) +{ +} + +std::vector& MenuConverter::GetDependencies() +{ + return m_dependencies; +} + +menuDef_t* MenuConverter::ConvertMenu(const CommonMenuDef& commonMenu) +{ + MenuConverterImpl impl(m_legacy_mode, m_search_path, m_memory, m_manager); + + try + { + auto* result = impl.ConvertMenu(commonMenu); + m_dependencies = std::move(impl.m_dependencies); + return result; + } + catch (const MenuConversionException& e) + { + MenuConverterImpl::PrintConversionExceptionDetails(e); + } + + return nullptr; +} diff --git a/src/ObjLoading/Game/IW4/Menu/MenuConverterIW4.h b/src/ObjLoading/Game/IW4/Menu/MenuConverterIW4.h new file mode 100644 index 00000000..e9fcef13 --- /dev/null +++ b/src/ObjLoading/Game/IW4/Menu/MenuConverterIW4.h @@ -0,0 +1,26 @@ +#pragma once + +#include "Utils/ClassUtils.h" +#include "AssetLoading/IAssetLoadingManager.h" +#include "Game/IW4/IW4.h" +#include "Parsing/Menu/Domain/CommonMenuDef.h" +#include "Utils/MemoryManager.h" +#include "SearchPath/ISearchPath.h" + +namespace IW4 +{ + class MenuConverter + { + bool m_legacy_mode; + ISearchPath* m_search_path; + MemoryManager* m_memory; + IAssetLoadingManager* m_manager; + std::vector m_dependencies; + + public: + MenuConverter(bool legacyMode, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager); + + std::vector& GetDependencies(); + _NODISCARD menuDef_t* ConvertMenu(const menu::CommonMenuDef& commonMenu); + }; +} diff --git a/src/ObjLoading/Menu/AbstractMenuConverter.cpp b/src/ObjLoading/Menu/AbstractMenuConverter.cpp new file mode 100644 index 00000000..03f4363b --- /dev/null +++ b/src/ObjLoading/Menu/AbstractMenuConverter.cpp @@ -0,0 +1,41 @@ +#include "AbstractMenuConverter.h" + +#include + +using namespace menu; + +AbstractMenuConverter::AbstractMenuConverter(const bool legacyMode, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager) + : m_legacy_mode(legacyMode), + m_search_path(searchPath), + m_memory(memory), + m_manager(manager) +{ +} + +void AbstractMenuConverter::PrintConversionExceptionDetails(const MenuConversionException& e) +{ + std::cout << "ERROR while converting menu:\n"; + std::cout << " Menu: " << e.m_menu->m_name << "\n"; + + if (e.m_item) + { + std::cout << "Item: "; + + if (!e.m_item->m_name.empty()) + { + std::cout << e.m_item->m_name << "\n"; + } + + std::cout << "\n"; + } + + std::cout << " Message: " << e.m_message << "\n"; +} + +const char* AbstractMenuConverter::ConvertString(const std::string& str) const +{ + if (str.empty()) + return nullptr; + + return m_memory->Dup(str.c_str()); +} diff --git a/src/ObjLoading/Menu/AbstractMenuConverter.h b/src/ObjLoading/Menu/AbstractMenuConverter.h new file mode 100644 index 00000000..3684cac8 --- /dev/null +++ b/src/ObjLoading/Menu/AbstractMenuConverter.h @@ -0,0 +1,26 @@ +#pragma once + +#include "MenuConversionException.h" +#include "AssetLoading/IAssetLoadingManager.h" +#include "SearchPath/ISearchPath.h" +#include "Utils/MemoryManager.h" +#include "Utils/ClassUtils.h" + +namespace menu +{ + class AbstractMenuConverter + { + protected: + bool m_legacy_mode; + ISearchPath* m_search_path; + MemoryManager* m_memory; + IAssetLoadingManager* m_manager; + + AbstractMenuConverter(bool legacyMode, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager); + + _NODISCARD const char* ConvertString(const std::string& str) const; + + public: + static void PrintConversionExceptionDetails(const MenuConversionException& e); + }; +} diff --git a/src/ObjLoading/Menu/MenuConversionException.cpp b/src/ObjLoading/Menu/MenuConversionException.cpp new file mode 100644 index 00000000..41467c67 --- /dev/null +++ b/src/ObjLoading/Menu/MenuConversionException.cpp @@ -0,0 +1,17 @@ +#include "MenuConversionException.h" + +using namespace menu; + +MenuConversionException::MenuConversionException(std::string message, const CommonMenuDef* menu) + : m_menu(menu), + m_item(nullptr), + m_message(std::move(message)) +{ +} + +MenuConversionException::MenuConversionException(std::string message, const CommonMenuDef* menu, const CommonItemDef* item) + : m_menu(menu), + m_item(item), + m_message(std::move(message)) +{ +} diff --git a/src/ObjLoading/Menu/MenuConversionException.h b/src/ObjLoading/Menu/MenuConversionException.h new file mode 100644 index 00000000..20e32b69 --- /dev/null +++ b/src/ObjLoading/Menu/MenuConversionException.h @@ -0,0 +1,16 @@ +#pragma once +#include "Parsing/Menu/Domain/CommonMenuDef.h" + +namespace menu +{ + class MenuConversionException final : public std::exception + { + public: + const CommonMenuDef* m_menu; + const CommonItemDef* m_item; + std::string m_message; + + explicit MenuConversionException(std::string message, const CommonMenuDef* menu); + MenuConversionException(std::string message, const CommonMenuDef* menu, const CommonItemDef* item); + }; +} diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.cpp b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.cpp index ccfc1503..968c0240 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.cpp +++ b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.cpp @@ -7,12 +7,12 @@ CommonExpressionFunctionCall::CommonExpressionFunctionCall(std::string functionN { } -bool CommonExpressionFunctionCall::IsStatic() +bool CommonExpressionFunctionCall::IsStatic() const { return false; } -SimpleExpressionValue CommonExpressionFunctionCall::Evaluate() +SimpleExpressionValue CommonExpressionFunctionCall::Evaluate() const { return SimpleExpressionValue(0); } diff --git a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.h b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.h index ed7d95cf..1571c700 100644 --- a/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.h +++ b/src/ObjLoading/Parsing/Menu/Domain/Expression/CommonExpressionFunctionCall.h @@ -13,7 +13,7 @@ namespace menu explicit CommonExpressionFunctionCall(std::string functionName); - bool IsStatic() override; - SimpleExpressionValue Evaluate() override; + _NODISCARD bool IsStatic() const override; + _NODISCARD SimpleExpressionValue Evaluate() const override; }; } diff --git a/src/Parser/Parsing/Simple/Expression/ISimpleExpression.h b/src/Parser/Parsing/Simple/Expression/ISimpleExpression.h index 35d80591..fe3e25ab 100644 --- a/src/Parser/Parsing/Simple/Expression/ISimpleExpression.h +++ b/src/Parser/Parsing/Simple/Expression/ISimpleExpression.h @@ -1,5 +1,7 @@ #pragma once +#include "Utils/ClassUtils.h" + class SimpleExpressionValue; class ISimpleExpression { @@ -12,8 +14,8 @@ public: ISimpleExpression& operator=(const ISimpleExpression& other) = default; ISimpleExpression& operator=(ISimpleExpression&& other) noexcept = default; - virtual bool IsStatic() = 0; - virtual SimpleExpressionValue Evaluate() = 0; + _NODISCARD virtual bool IsStatic() const = 0; + _NODISCARD virtual SimpleExpressionValue Evaluate() const = 0; }; // Include SimpleExpressionValue after definition to avoid "base class not defined" diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.cpp b/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.cpp index 032459df..395b1f6d 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.cpp +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.cpp @@ -443,14 +443,14 @@ bool SimpleExpressionBinaryOperation::Operand2NeedsParenthesis() const return operation && operation->m_operation_type->m_precedence > m_operation_type->m_precedence; } -bool SimpleExpressionBinaryOperation::IsStatic() +bool SimpleExpressionBinaryOperation::IsStatic() const { assert(m_operand1 && m_operand2); return m_operand1->IsStatic() && m_operand2->IsStatic(); } -SimpleExpressionValue SimpleExpressionBinaryOperation::Evaluate() +SimpleExpressionValue SimpleExpressionBinaryOperation::Evaluate() const { return m_operation_type->m_evaluation_function(m_operand1->Evaluate(), m_operand2->Evaluate()); } diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h b/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h index 44446a45..c7650944 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h @@ -93,6 +93,6 @@ public: _NODISCARD bool Operand1NeedsParenthesis() const; _NODISCARD bool Operand2NeedsParenthesis() const; - bool IsStatic() override; - SimpleExpressionValue Evaluate() override; + _NODISCARD bool IsStatic() const override; + _NODISCARD SimpleExpressionValue Evaluate() const override; }; diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionConditionalOperator.cpp b/src/Parser/Parsing/Simple/Expression/SimpleExpressionConditionalOperator.cpp index 5fb7775c..0de948e0 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionConditionalOperator.cpp +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionConditionalOperator.cpp @@ -11,12 +11,12 @@ SimpleExpressionConditionalOperator::SimpleExpressionConditionalOperator(std::un { } -bool SimpleExpressionConditionalOperator::IsStatic() +bool SimpleExpressionConditionalOperator::IsStatic() const { return m_condition->IsStatic() && m_true_value->IsStatic() && m_false_value->IsStatic(); } -SimpleExpressionValue SimpleExpressionConditionalOperator::Evaluate() +SimpleExpressionValue SimpleExpressionConditionalOperator::Evaluate() const { return m_condition->Evaluate().IsTruthy() ? m_true_value->Evaluate() : m_false_value->Evaluate(); } diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionConditionalOperator.h b/src/Parser/Parsing/Simple/Expression/SimpleExpressionConditionalOperator.h index fa472f0b..b36f7ca0 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionConditionalOperator.h +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionConditionalOperator.h @@ -8,8 +8,8 @@ public: std::unique_ptr m_true_value; std::unique_ptr m_false_value; - bool IsStatic() override; - SimpleExpressionValue Evaluate() override; + _NODISCARD bool IsStatic() const override; + _NODISCARD SimpleExpressionValue Evaluate() const override; SimpleExpressionConditionalOperator(); SimpleExpressionConditionalOperator(std::unique_ptr condition, std::unique_ptr trueExpression, std::unique_ptr falseExpression); diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.cpp b/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.cpp index 2041f1ce..d5b66977 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.cpp +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.cpp @@ -64,14 +64,14 @@ bool SimpleExpressionUnaryOperation::OperandNeedsParenthesis() const return dynamic_cast(m_operand.get()) != nullptr; } -bool SimpleExpressionUnaryOperation::IsStatic() +bool SimpleExpressionUnaryOperation::IsStatic() const { assert(m_operand); return m_operand->IsStatic(); } -SimpleExpressionValue SimpleExpressionUnaryOperation::Evaluate() +SimpleExpressionValue SimpleExpressionUnaryOperation::Evaluate() const { return m_operation_type->m_evaluation_function(m_operand->Evaluate()); } diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h b/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h index bfbe0302..3ca6a83e 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h @@ -46,6 +46,6 @@ public: _NODISCARD bool OperandNeedsParenthesis() const; - bool IsStatic() override; - SimpleExpressionValue Evaluate() override; + _NODISCARD bool IsStatic() const override; + _NODISCARD SimpleExpressionValue Evaluate() const override; }; diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.cpp b/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.cpp index 212b1b49..ac3497e0 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.cpp +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.cpp @@ -24,12 +24,12 @@ SimpleExpressionValue::SimpleExpressionValue(const int intValue) m_int_value = intValue; } -bool SimpleExpressionValue::IsStatic() +bool SimpleExpressionValue::IsStatic() const { return true; } -SimpleExpressionValue SimpleExpressionValue::Evaluate() +SimpleExpressionValue SimpleExpressionValue::Evaluate() const { return *this; } diff --git a/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.h b/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.h index d0608cf2..b0818aef 100644 --- a/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.h +++ b/src/Parser/Parsing/Simple/Expression/SimpleExpressionValue.h @@ -29,7 +29,7 @@ public: explicit SimpleExpressionValue(double doubleValue); explicit SimpleExpressionValue(int intValue); - bool IsStatic() override; - SimpleExpressionValue Evaluate() override; + _NODISCARD bool IsStatic() const override; + _NODISCARD SimpleExpressionValue Evaluate() const override; _NODISCARD bool IsTruthy() const; };