Add base for menu eventhandlerset parsing

This commit is contained in:
Jan 2021-11-06 16:28:24 +01:00
parent b15efd4a4c
commit bf19208351
19 changed files with 334 additions and 46 deletions

View File

@ -1274,7 +1274,7 @@ namespace IW4
SetLocalVarData* setLocalVarData; SetLocalVarData* setLocalVarData;
}; };
enum EventType : char enum EventType : unsigned char
{ {
EVENT_UNCONDITIONAL = 0x0, EVENT_UNCONDITIONAL = 0x0,
EVENT_IF = 0x1, EVENT_IF = 0x1,

View File

@ -2456,7 +2456,7 @@ namespace IW5
SetLocalVarData* setLocalVarData; SetLocalVarData* setLocalVarData;
}; };
enum EventType enum EventType : unsigned char
{ {
EVENT_UNCONDITIONAL = 0x0, EVENT_UNCONDITIONAL = 0x0,
EVENT_IF = 0x1, EVENT_IF = 0x1,
@ -2472,7 +2472,7 @@ namespace IW5
struct MenuEventHandler struct MenuEventHandler
{ {
EventData eventData; EventData eventData;
unsigned char eventType; EventType eventType;
}; };
struct MenuEventHandlerSet struct MenuEventHandlerSet

View File

@ -0,0 +1,19 @@
#include "CommonEventHandlerCondition.h"
using namespace menu;
CommonEventHandlerCondition::CommonEventHandlerCondition()
= default;
CommonEventHandlerCondition::CommonEventHandlerCondition(std::unique_ptr<ICommonExpression> condition, std::unique_ptr<CommonEventHandlerSet> conditionElements,
std::unique_ptr<CommonEventHandlerSet> elseElements)
: m_condition(std::move(condition)),
m_condition_elements(std::move(conditionElements)),
m_else_elements(std::move(elseElements))
{
}
CommonEventHandlerElementType CommonEventHandlerCondition::GetType()
{
return CommonEventHandlerElementType::CONDITION;
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <memory>
#include "CommonEventHandlerSet.h"
#include "ICommonEventHandlerElement.h"
#include "Parsing/Menu/Domain/Expression/ICommonExpression.h"
namespace menu
{
class CommonEventHandlerCondition final : public ICommonEventHandlerElement
{
public:
std::unique_ptr<ICommonExpression> m_condition;
std::unique_ptr<CommonEventHandlerSet> m_condition_elements;
std::unique_ptr<CommonEventHandlerSet> m_else_elements;
CommonEventHandlerCondition();
explicit CommonEventHandlerCondition(std::unique_ptr<ICommonExpression> condition, std::unique_ptr<CommonEventHandlerSet> conditionElements,
std::unique_ptr<CommonEventHandlerSet> elseElements);
CommonEventHandlerElementType GetType() override;
};
}

View File

@ -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;
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <string>
#include "ICommonEventHandlerElement.h"
namespace menu
{
class CommonEventHandlerScript final : public ICommonEventHandlerElement
{
public:
std::string m_script;
CommonEventHandlerScript();
explicit CommonEventHandlerScript(std::string script);
CommonEventHandlerElementType GetType() override;
};
}

View File

@ -0,0 +1,11 @@
#include "CommonEventHandlerSet.h"
using namespace menu;
CommonEventHandlerSet::CommonEventHandlerSet()
= default;
CommonEventHandlerSet::CommonEventHandlerSet(std::vector<std::unique_ptr<ICommonEventHandlerElement>> elements)
: m_elements(std::move(elements))
{
}

View File

@ -0,0 +1,18 @@
#pragma once
#include <memory>
#include <vector>
#include "ICommonEventHandlerElement.h"
namespace menu
{
class CommonEventHandlerSet
{
public:
std::vector<std::unique_ptr<ICommonEventHandlerElement>> m_elements;
CommonEventHandlerSet();
explicit CommonEventHandlerSet(std::vector<std::unique_ptr<ICommonEventHandlerElement>> elements);
};
}

View File

@ -0,0 +1,17 @@
#include "CommonEventHandlerSetLocalVar.h"
using namespace menu;
CommonEventHandlerSetLocalVar::CommonEventHandlerSetLocalVar()
= default;
CommonEventHandlerSetLocalVar::CommonEventHandlerSetLocalVar(std::string varName, std::unique_ptr<ICommonExpression> value)
: m_var_name(std::move(varName)),
m_value(std::move(value))
{
}
CommonEventHandlerElementType CommonEventHandlerSetLocalVar::GetType()
{
return CommonEventHandlerElementType::SET_LOCAL_VAR;
}

View File

@ -0,0 +1,21 @@
#pragma once
#include <memory>
#include <string>
#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<ICommonExpression> m_value;
CommonEventHandlerSetLocalVar();
CommonEventHandlerSetLocalVar(std::string varName, std::unique_ptr<ICommonExpression> value);
CommonEventHandlerElementType GetType() override;
};
}

View File

@ -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;
};
}

View File

@ -1,5 +1,6 @@
#include "MenuFileParser.h" #include "MenuFileParser.h"
#include "Sequence/EventHandlerSetScopeSequences.h"
#include "Sequence/FunctionScopeSequences.h" #include "Sequence/FunctionScopeSequences.h"
#include "Sequence/GlobalScopeSequences.h" #include "Sequence/GlobalScopeSequences.h"
#include "Sequence/ItemScopeSequences.h" #include "Sequence/ItemScopeSequences.h"
@ -11,7 +12,7 @@ using namespace menu;
MenuFileParser::MenuFileParser(SimpleLexer* lexer, const FeatureLevel featureLevel) MenuFileParser::MenuFileParser(SimpleLexer* lexer, const FeatureLevel featureLevel)
: AbstractParser(lexer, std::make_unique<MenuFileParserState>(featureLevel)) : AbstractParser(lexer, std::make_unique<MenuFileParserState>(featureLevel))
{ {
CreateTestCollections(); CreateSequenceCollections();
} }
void MenuFileParser::AddSequence(std::vector<sequence_t*>& collection, std::unique_ptr<sequence_t> test) void MenuFileParser::AddSequence(std::vector<sequence_t*>& collection, std::unique_ptr<sequence_t> test)
@ -20,37 +21,7 @@ void MenuFileParser::AddSequence(std::vector<sequence_t*>& collection, std::uniq
m_all_tests.emplace_back(std::move(test)); m_all_tests.emplace_back(std::move(test));
} }
void MenuFileParser::CreateNoScopeTests() void MenuFileParser::CreateSequenceCollections()
{
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()
{ {
m_all_tests.clear(); m_all_tests.clear();
m_no_scope_tests.clear(); m_no_scope_tests.clear();
@ -58,16 +29,34 @@ void MenuFileParser::CreateTestCollections()
m_function_scope_tests.clear(); m_function_scope_tests.clear();
m_menu_scope_tests.clear(); m_menu_scope_tests.clear();
m_item_scope_tests.clear(); m_item_scope_tests.clear();
m_event_handler_set_scope_tests.clear();
CreateNoScopeTests(); const auto featureLevel = m_state->m_feature_level;
CreateGlobalScopeTests();
CreateFunctionScopeTests(); NoScopeSequences noScopeSequences(m_all_tests, m_no_scope_tests);
CreateMenuScopeTests(); noScopeSequences.AddSequences(featureLevel);
CreateItemScopeTests();
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::sequence_t*>& MenuFileParser::GetTestsForState() const std::vector<MenuFileParser::sequence_t*>& MenuFileParser::GetTestsForState()
{ {
if (m_state->m_current_event_handler_set)
return m_event_handler_set_scope_tests;
if (m_state->m_current_item) if (m_state->m_current_item)
return m_item_scope_tests; return m_item_scope_tests;

View File

@ -16,14 +16,10 @@ namespace menu
std::vector<sequence_t*> m_function_scope_tests; std::vector<sequence_t*> m_function_scope_tests;
std::vector<sequence_t*> m_menu_scope_tests; std::vector<sequence_t*> m_menu_scope_tests;
std::vector<sequence_t*> m_item_scope_tests; std::vector<sequence_t*> m_item_scope_tests;
std::vector<sequence_t*> m_event_handler_set_scope_tests;
void AddSequence(std::vector<sequence_t*>& collection, std::unique_ptr<sequence_t> test); void AddSequence(std::vector<sequence_t*>& collection, std::unique_ptr<sequence_t> test);
void CreateNoScopeTests(); void CreateSequenceCollections();
void CreateGlobalScopeTests();
void CreateFunctionScopeTests();
void CreateMenuScopeTests();
void CreateItemScopeTests();
void CreateTestCollections();
protected: protected:
const std::vector<sequence_t*>& GetTestsForState() override; const std::vector<sequence_t*>& GetTestsForState() override;

View File

@ -2,6 +2,12 @@
using namespace menu; using namespace menu;
MenuFileParserState::EventHandlerConditionState::EventHandlerConditionState(std::unique_ptr<CommonEventHandlerCondition> condition)
: m_in_condition_elements(true),
m_condition(std::move(condition))
{
}
MenuFileParserState::MenuFileParserState(const FeatureLevel featureLevel) MenuFileParserState::MenuFileParserState(const FeatureLevel featureLevel)
: m_feature_level(featureLevel), : m_feature_level(featureLevel),
m_in_global_scope(false) m_in_global_scope(false)

View File

@ -1,18 +1,31 @@
#pragma once #pragma once
#include <functional>
#include <map> #include <map>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <sstream>
#include <stack>
#include "Domain/CommonFunctionDef.h" #include "Domain/CommonFunctionDef.h"
#include "Domain/CommonMenuDef.h" #include "Domain/CommonMenuDef.h"
#include "Domain/MenuFeatureLevel.h" #include "Domain/MenuFeatureLevel.h"
#include "Domain/EventHandler/CommonEventHandlerCondition.h"
namespace menu namespace menu
{ {
class MenuFileParserState class MenuFileParserState
{ {
public: public:
class EventHandlerConditionState
{
public:
bool m_in_condition_elements;
std::unique_ptr<CommonEventHandlerCondition> m_condition;
explicit EventHandlerConditionState(std::unique_ptr<CommonEventHandlerCondition> condition);
};
const FeatureLevel m_feature_level; const FeatureLevel m_feature_level;
std::vector<std::string> m_menus_to_load; std::vector<std::string> m_menus_to_load;
@ -26,6 +39,11 @@ namespace menu
std::unique_ptr<CommonFunctionDef> m_current_function; std::unique_ptr<CommonFunctionDef> m_current_function;
std::unique_ptr<CommonMenuDef> m_current_menu; std::unique_ptr<CommonMenuDef> m_current_menu;
std::unique_ptr<CommonItemDef> m_current_item; std::unique_ptr<CommonItemDef> m_current_item;
std::unique_ptr<CommonEventHandlerSet> m_current_event_handler_set;
std::function<void(MenuFileParserState* state, std::unique_ptr<CommonEventHandlerSet> value)> m_event_handler_set_callback;
std::ostringstream m_current_script;
std::stack<EventHandlerConditionState> m_current_condition;
explicit MenuFileParserState(FeatureLevel featureLevel); explicit MenuFileParserState(FeatureLevel featureLevel);
}; };

View File

@ -0,0 +1,43 @@
#include "EventHandlerSetScopeSequences.h"
#include <sstream>
#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<SimpleParserValue>& result) const override
{
}
};
}
using namespace event_handler_set_scope_sequences;
EventHandlerSetScopeSequences::EventHandlerSetScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences)
: AbstractScopeSequenceHolder(allSequences, scopeSequences)
{
}
void EventHandlerSetScopeSequences::AddSequences(FeatureLevel featureLevel)
{
AddSequence(std::make_unique<SequenceCloseBlock>());
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "AbstractScopeSequenceHolder.h"
namespace menu
{
class EventHandlerSetScopeSequences final : AbstractScopeSequenceHolder
{
public:
EventHandlerSetScopeSequences(std::vector<std::unique_ptr<MenuFileParser::sequence_t>>& allSequences, std::vector<MenuFileParser::sequence_t*>& scopeSequences);
void AddSequences(FeatureLevel featureLevel) override;
};
}

View File

@ -0,0 +1,24 @@
#include "GenericMenuEventHandlerSetPropertySequence.h"
#include <utility>
#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<SimpleParserValue>& result) const
{
state->m_current_event_handler_set = std::make_unique<CommonEventHandlerSet>();
state->m_event_handler_set_callback = m_set_callback;
}

View File

@ -0,0 +1,27 @@
#pragma once
#include <string>
#include <functional>
#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<void(MenuFileParserState* state, std::unique_ptr<CommonEventHandlerSet> value)>;
private:
static constexpr auto CAPTURE_VALUE = 1;
const callback_t m_set_callback;
protected:
void ProcessMatch(MenuFileParserState* state, SequenceResult<SimpleParserValue>& result) const override;
public:
GenericMenuEventHandlerSetPropertySequence(std::string keywordName, callback_t setCallback);
};
}