diff --git a/src/Common/Game/IW4/IW4_Assets.h b/src/Common/Game/IW4/IW4_Assets.h index b9be7141..67f4c689 100644 --- a/src/Common/Game/IW4/IW4_Assets.h +++ b/src/Common/Game/IW4/IW4_Assets.h @@ -1274,7 +1274,7 @@ namespace IW4 SetLocalVarData* setLocalVarData; }; - enum EventType : char + enum EventType : unsigned char { EVENT_UNCONDITIONAL = 0x0, EVENT_IF = 0x1, diff --git a/src/Common/Game/IW5/IW5_Assets.h b/src/Common/Game/IW5/IW5_Assets.h index d6876e47..7d505e8e 100644 --- a/src/Common/Game/IW5/IW5_Assets.h +++ b/src/Common/Game/IW5/IW5_Assets.h @@ -2456,7 +2456,7 @@ namespace IW5 SetLocalVarData* setLocalVarData; }; - enum EventType + enum EventType : unsigned char { EVENT_UNCONDITIONAL = 0x0, EVENT_IF = 0x1, @@ -2472,7 +2472,7 @@ namespace IW5 struct MenuEventHandler { EventData eventData; - unsigned char eventType; + EventType eventType; }; struct MenuEventHandlerSet diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.cpp b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.cpp new file mode 100644 index 00000000..a24210e6 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.cpp @@ -0,0 +1,19 @@ +#include "CommonEventHandlerCondition.h" + +using namespace menu; + +CommonEventHandlerCondition::CommonEventHandlerCondition() += default; + +CommonEventHandlerCondition::CommonEventHandlerCondition(std::unique_ptr condition, std::unique_ptr conditionElements, + std::unique_ptr elseElements) + : m_condition(std::move(condition)), + m_condition_elements(std::move(conditionElements)), + m_else_elements(std::move(elseElements)) +{ +} + +CommonEventHandlerElementType CommonEventHandlerCondition::GetType() +{ + return CommonEventHandlerElementType::CONDITION; +} diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.h b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.h new file mode 100644 index 00000000..afce98e7 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerCondition.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "CommonEventHandlerSet.h" +#include "ICommonEventHandlerElement.h" +#include "Parsing/Menu/Domain/Expression/ICommonExpression.h" + +namespace menu +{ + class CommonEventHandlerCondition final : public ICommonEventHandlerElement + { + public: + std::unique_ptr m_condition; + std::unique_ptr m_condition_elements; + std::unique_ptr m_else_elements; + + CommonEventHandlerCondition(); + explicit CommonEventHandlerCondition(std::unique_ptr condition, std::unique_ptr conditionElements, + std::unique_ptr elseElements); + + CommonEventHandlerElementType GetType() override; + }; +} diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerScript.cpp b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerScript.cpp new file mode 100644 index 00000000..75062478 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerScript.cpp @@ -0,0 +1,16 @@ +#include "CommonEventHandlerScript.h" + +using namespace menu; + +CommonEventHandlerScript::CommonEventHandlerScript() += default; + +CommonEventHandlerScript::CommonEventHandlerScript(std::string script) + : m_script(std::move(script)) +{ +} + +CommonEventHandlerElementType CommonEventHandlerScript::GetType() +{ + return CommonEventHandlerElementType::SCRIPT; +} diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerScript.h b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerScript.h new file mode 100644 index 00000000..76ac6fd4 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerScript.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#include "ICommonEventHandlerElement.h" + +namespace menu +{ + class CommonEventHandlerScript final : public ICommonEventHandlerElement + { + public: + std::string m_script; + + CommonEventHandlerScript(); + explicit CommonEventHandlerScript(std::string script); + + CommonEventHandlerElementType GetType() override; + }; +} diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSet.cpp b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSet.cpp new file mode 100644 index 00000000..bb7fd3da --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSet.cpp @@ -0,0 +1,11 @@ +#include "CommonEventHandlerSet.h" + +using namespace menu; + +CommonEventHandlerSet::CommonEventHandlerSet() += default; + +CommonEventHandlerSet::CommonEventHandlerSet(std::vector> elements) + : m_elements(std::move(elements)) +{ +} diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSet.h b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSet.h new file mode 100644 index 00000000..ac4da860 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSet.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include "ICommonEventHandlerElement.h" + +namespace menu +{ + class CommonEventHandlerSet + { + public: + std::vector> m_elements; + + CommonEventHandlerSet(); + explicit CommonEventHandlerSet(std::vector> elements); + }; +} diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.cpp b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.cpp new file mode 100644 index 00000000..68e38f12 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.cpp @@ -0,0 +1,17 @@ +#include "CommonEventHandlerSetLocalVar.h" + +using namespace menu; + +CommonEventHandlerSetLocalVar::CommonEventHandlerSetLocalVar() += default; + +CommonEventHandlerSetLocalVar::CommonEventHandlerSetLocalVar(std::string varName, std::unique_ptr value) + : m_var_name(std::move(varName)), + m_value(std::move(value)) +{ +} + +CommonEventHandlerElementType CommonEventHandlerSetLocalVar::GetType() +{ + return CommonEventHandlerElementType::SET_LOCAL_VAR; +} diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h new file mode 100644 index 00000000..3385b24b --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h @@ -0,0 +1,21 @@ +#pragma once +#include +#include + +#include "ICommonEventHandlerElement.h" +#include "Parsing/Menu/Domain/Expression/ICommonExpression.h" + +namespace menu +{ + class CommonEventHandlerSetLocalVar final : public ICommonEventHandlerElement + { + public: + std::string m_var_name; + std::unique_ptr m_value; + + CommonEventHandlerSetLocalVar(); + CommonEventHandlerSetLocalVar(std::string varName, std::unique_ptr value); + + CommonEventHandlerElementType GetType() override; + }; +} diff --git a/src/ObjLoading/Parsing/Menu/Domain/EventHandler/ICommonEventHandlerElement.h b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/ICommonEventHandlerElement.h new file mode 100644 index 00000000..c7d8f972 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/EventHandler/ICommonEventHandlerElement.h @@ -0,0 +1,26 @@ +#pragma once + +namespace menu +{ + enum class CommonEventHandlerElementType + { + SCRIPT, + CONDITION, + SET_LOCAL_VAR + }; + + class ICommonEventHandlerElement + { + protected: + ICommonEventHandlerElement() = default; + + public: + virtual ~ICommonEventHandlerElement() = default; + ICommonEventHandlerElement(const ICommonEventHandlerElement& other) = default; + ICommonEventHandlerElement(ICommonEventHandlerElement&& other) noexcept = default; + ICommonEventHandlerElement& operator=(const ICommonEventHandlerElement& other) = default; + ICommonEventHandlerElement& operator=(ICommonEventHandlerElement&& other) noexcept = default; + + virtual CommonEventHandlerElementType GetType() = 0; + }; +} \ No newline at end of file diff --git a/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp b/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp index 2789c868..c9839592 100644 --- a/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp +++ b/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp @@ -1,5 +1,6 @@ #include "MenuFileParser.h" +#include "Sequence/EventHandlerSetScopeSequences.h" #include "Sequence/FunctionScopeSequences.h" #include "Sequence/GlobalScopeSequences.h" #include "Sequence/ItemScopeSequences.h" @@ -11,7 +12,7 @@ using namespace menu; MenuFileParser::MenuFileParser(SimpleLexer* lexer, const FeatureLevel featureLevel) : AbstractParser(lexer, std::make_unique(featureLevel)) { - CreateTestCollections(); + CreateSequenceCollections(); } void MenuFileParser::AddSequence(std::vector& collection, std::unique_ptr test) @@ -20,37 +21,7 @@ void MenuFileParser::AddSequence(std::vector& collection, std::uniq m_all_tests.emplace_back(std::move(test)); } -void MenuFileParser::CreateNoScopeTests() -{ - NoScopeSequences noScopeSequences(m_all_tests, m_no_scope_tests); - noScopeSequences.AddSequences(m_state->m_feature_level); -} - -void MenuFileParser::CreateGlobalScopeTests() -{ - GlobalScopeSequences globalScopeSequences(m_all_tests, m_global_scope_tests); - globalScopeSequences.AddSequences(m_state->m_feature_level); -} - -void MenuFileParser::CreateFunctionScopeTests() -{ - FunctionScopeSequences functionPropertySequences(m_all_tests, m_function_scope_tests); - functionPropertySequences.AddSequences(m_state->m_feature_level); -} - -void MenuFileParser::CreateMenuScopeTests() -{ - MenuScopeSequences menuPropertySequences(m_all_tests, m_menu_scope_tests); - menuPropertySequences.AddSequences(m_state->m_feature_level); -} - -void MenuFileParser::CreateItemScopeTests() -{ - ItemScopeSequences itemPropertySequences(m_all_tests, m_item_scope_tests); - itemPropertySequences.AddSequences(m_state->m_feature_level); -} - -void MenuFileParser::CreateTestCollections() +void MenuFileParser::CreateSequenceCollections() { m_all_tests.clear(); m_no_scope_tests.clear(); @@ -58,16 +29,34 @@ void MenuFileParser::CreateTestCollections() m_function_scope_tests.clear(); m_menu_scope_tests.clear(); m_item_scope_tests.clear(); + m_event_handler_set_scope_tests.clear(); - CreateNoScopeTests(); - CreateGlobalScopeTests(); - CreateFunctionScopeTests(); - CreateMenuScopeTests(); - CreateItemScopeTests(); + const auto featureLevel = m_state->m_feature_level; + + NoScopeSequences noScopeSequences(m_all_tests, m_no_scope_tests); + noScopeSequences.AddSequences(featureLevel); + + GlobalScopeSequences globalScopeSequences(m_all_tests, m_global_scope_tests); + globalScopeSequences.AddSequences(featureLevel); + + MenuScopeSequences menuPropertySequences(m_all_tests, m_menu_scope_tests); + menuPropertySequences.AddSequences(featureLevel); + + ItemScopeSequences itemPropertySequences(m_all_tests, m_item_scope_tests); + itemPropertySequences.AddSequences(featureLevel); + + FunctionScopeSequences functionPropertySequences(m_all_tests, m_function_scope_tests); + functionPropertySequences.AddSequences(featureLevel); + + EventHandlerSetScopeSequences eventHandlerSetScopeSequences(m_all_tests, m_event_handler_set_scope_tests); + eventHandlerSetScopeSequences.AddSequences(featureLevel); } const std::vector& MenuFileParser::GetTestsForState() { + if (m_state->m_current_event_handler_set) + return m_event_handler_set_scope_tests; + if (m_state->m_current_item) return m_item_scope_tests; diff --git a/src/ObjLoading/Parsing/Menu/MenuFileParser.h b/src/ObjLoading/Parsing/Menu/MenuFileParser.h index c5d3d677..5224fc6a 100644 --- a/src/ObjLoading/Parsing/Menu/MenuFileParser.h +++ b/src/ObjLoading/Parsing/Menu/MenuFileParser.h @@ -16,14 +16,10 @@ namespace menu std::vector m_function_scope_tests; std::vector m_menu_scope_tests; std::vector m_item_scope_tests; + std::vector m_event_handler_set_scope_tests; void AddSequence(std::vector& collection, std::unique_ptr test); - void CreateNoScopeTests(); - void CreateGlobalScopeTests(); - void CreateFunctionScopeTests(); - void CreateMenuScopeTests(); - void CreateItemScopeTests(); - void CreateTestCollections(); + void CreateSequenceCollections(); protected: const std::vector& GetTestsForState() override; diff --git a/src/ObjLoading/Parsing/Menu/MenuFileParserState.cpp b/src/ObjLoading/Parsing/Menu/MenuFileParserState.cpp index 4b7139d8..966c2cb9 100644 --- a/src/ObjLoading/Parsing/Menu/MenuFileParserState.cpp +++ b/src/ObjLoading/Parsing/Menu/MenuFileParserState.cpp @@ -2,6 +2,12 @@ using namespace menu; +MenuFileParserState::EventHandlerConditionState::EventHandlerConditionState(std::unique_ptr condition) + : m_in_condition_elements(true), + m_condition(std::move(condition)) +{ +} + MenuFileParserState::MenuFileParserState(const FeatureLevel featureLevel) : m_feature_level(featureLevel), m_in_global_scope(false) diff --git a/src/ObjLoading/Parsing/Menu/MenuFileParserState.h b/src/ObjLoading/Parsing/Menu/MenuFileParserState.h index 51fc058c..f8f3c1b5 100644 --- a/src/ObjLoading/Parsing/Menu/MenuFileParserState.h +++ b/src/ObjLoading/Parsing/Menu/MenuFileParserState.h @@ -1,18 +1,31 @@ #pragma once +#include #include #include #include +#include +#include #include "Domain/CommonFunctionDef.h" #include "Domain/CommonMenuDef.h" #include "Domain/MenuFeatureLevel.h" +#include "Domain/EventHandler/CommonEventHandlerCondition.h" namespace menu { class MenuFileParserState { public: + class EventHandlerConditionState + { + public: + bool m_in_condition_elements; + std::unique_ptr m_condition; + + explicit EventHandlerConditionState(std::unique_ptr condition); + }; + const FeatureLevel m_feature_level; std::vector m_menus_to_load; @@ -26,6 +39,11 @@ namespace menu std::unique_ptr m_current_function; std::unique_ptr m_current_menu; std::unique_ptr m_current_item; + std::unique_ptr m_current_event_handler_set; + + std::function value)> m_event_handler_set_callback; + std::ostringstream m_current_script; + std::stack m_current_condition; explicit MenuFileParserState(FeatureLevel featureLevel); }; diff --git a/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp b/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp new file mode 100644 index 00000000..dce2f95c --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp @@ -0,0 +1,43 @@ +#include "EventHandlerSetScopeSequences.h" + +#include + +#include "Generic/GenericStringPropertySequence.h" +#include "Parsing/Menu/Matcher/MenuMatcherFactory.h" + +using namespace menu; + +namespace menu::event_handler_set_scope_sequences +{ + class SequenceCloseBlock final : public MenuFileParser::sequence_t + { + static constexpr auto CAPTURE_TOKEN = 1; + + public: + SequenceCloseBlock() + { + const MenuMatcherFactory create(this); + + AddMatchers({ + create.Char('}') + }); + } + + protected: + void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override + { + } + }; +} + +using namespace event_handler_set_scope_sequences; + +EventHandlerSetScopeSequences::EventHandlerSetScopeSequences(std::vector>& allSequences, std::vector& scopeSequences) + : AbstractScopeSequenceHolder(allSequences, scopeSequences) +{ +} + +void EventHandlerSetScopeSequences::AddSequences(FeatureLevel featureLevel) +{ + AddSequence(std::make_unique()); +} diff --git a/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.h b/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.h new file mode 100644 index 00000000..60c421a6 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.h @@ -0,0 +1,14 @@ +#pragma once + +#include "AbstractScopeSequenceHolder.h" + +namespace menu +{ + class EventHandlerSetScopeSequences final : AbstractScopeSequenceHolder + { + public: + EventHandlerSetScopeSequences(std::vector>& allSequences, std::vector& scopeSequences); + + void AddSequences(FeatureLevel featureLevel) override; + }; +} diff --git a/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericMenuEventHandlerSetPropertySequence.cpp b/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericMenuEventHandlerSetPropertySequence.cpp new file mode 100644 index 00000000..11f65a5f --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericMenuEventHandlerSetPropertySequence.cpp @@ -0,0 +1,24 @@ +#include "GenericMenuEventHandlerSetPropertySequence.h" + +#include + +#include "Parsing/Menu/Matcher/MenuMatcherFactory.h" + +using namespace menu; + +GenericMenuEventHandlerSetPropertySequence::GenericMenuEventHandlerSetPropertySequence(std::string keywordName, callback_t setCallback) + : m_set_callback(std::move(setCallback)) +{ + const MenuMatcherFactory create(this); + + AddMatchers({ + create.KeywordIgnoreCase(std::move(keywordName)), + create.Char('{') + }); +} + +void GenericMenuEventHandlerSetPropertySequence::ProcessMatch(MenuFileParserState* state, SequenceResult& result) const +{ + state->m_current_event_handler_set = std::make_unique(); + state->m_event_handler_set_callback = m_set_callback; +} diff --git a/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericMenuEventHandlerSetPropertySequence.h b/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericMenuEventHandlerSetPropertySequence.h new file mode 100644 index 00000000..4a4d51e7 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Sequence/Generic/GenericMenuEventHandlerSetPropertySequence.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +#include "Parsing/Menu/MenuFileParser.h" +#include "Parsing/Menu/Domain/EventHandler/CommonEventHandlerSet.h" + +namespace menu +{ + class GenericMenuEventHandlerSetPropertySequence final : public MenuFileParser::sequence_t + { + public: + using callback_t = std::function value)>; + + private: + static constexpr auto CAPTURE_VALUE = 1; + + const callback_t m_set_callback; + + protected: + void ProcessMatch(MenuFileParserState* state, SequenceResult& result) const override; + + public: + GenericMenuEventHandlerSetPropertySequence(std::string keywordName, callback_t setCallback); + }; +}