If menu optimization is enabled, optimize away unnecessary if statements

This commit is contained in:
Jan 2022-01-01 23:12:27 +01:00
parent 8a3bbf948b
commit 98d62039eb

View File

@ -223,8 +223,11 @@ namespace IW4
OP_SUBTRACT OP_SUBTRACT
}; };
static bool IsOperation(const ISimpleExpression* expression) bool IsOperation(const ISimpleExpression* expression) const
{ {
if (!m_disable_optimizations && expression->IsStatic())
return false;
return dynamic_cast<const SimpleExpressionBinaryOperation*>(expression) || dynamic_cast<const SimpleExpressionUnaryOperation*>(expression); return dynamic_cast<const SimpleExpressionBinaryOperation*>(expression) || dynamic_cast<const SimpleExpressionUnaryOperation*>(expression);
} }
@ -537,11 +540,11 @@ namespace IW4
} }
} }
MenuEventHandler* ConvertEventHandlerSetLocalVar(const CommonEventHandlerSetLocalVar* setLocalVar, const CommonMenuDef* menu, const CommonItemDef* item) const void ConvertEventHandlerSetLocalVar(std::vector<MenuEventHandler*>& elements, const CommonEventHandlerSetLocalVar* setLocalVar, const CommonMenuDef* menu, const CommonItemDef* item) const
{ {
assert(setLocalVar); assert(setLocalVar);
if (!setLocalVar) if (!setLocalVar)
return nullptr; return;
auto* outputHandler = static_cast<MenuEventHandler*>(m_memory->Alloc(sizeof(MenuEventHandler) + sizeof(SetLocalVarData))); auto* outputHandler = static_cast<MenuEventHandler*>(m_memory->Alloc(sizeof(MenuEventHandler) + sizeof(SetLocalVarData)));
auto* outputSetLocalVar = reinterpret_cast<SetLocalVarData*>(reinterpret_cast<int8_t*>(outputHandler) + sizeof(MenuEventHandler)); auto* outputSetLocalVar = reinterpret_cast<SetLocalVarData*>(reinterpret_cast<int8_t*>(outputHandler) + sizeof(MenuEventHandler));
@ -552,29 +555,40 @@ namespace IW4
outputSetLocalVar->localVarName = m_memory->Dup(setLocalVar->m_var_name.c_str()); outputSetLocalVar->localVarName = m_memory->Dup(setLocalVar->m_var_name.c_str());
outputSetLocalVar->expression = ConvertExpression(setLocalVar->m_value.get(), menu, item); outputSetLocalVar->expression = ConvertExpression(setLocalVar->m_value.get(), menu, item);
return outputHandler; elements.push_back(outputHandler);
} }
MenuEventHandler* ConvertEventHandlerScript(const CommonEventHandlerScript* script) const void ConvertEventHandlerScript(std::vector<MenuEventHandler*>& elements, const CommonEventHandlerScript* script) const
{ {
assert(script); assert(script);
if (!script) if (!script)
return nullptr; return;
auto* outputHandler = m_memory->Create<MenuEventHandler>(); auto* outputHandler = m_memory->Create<MenuEventHandler>();
outputHandler->eventType = EVENT_UNCONDITIONAL; outputHandler->eventType = EVENT_UNCONDITIONAL;
outputHandler->eventData.unconditionalScript = m_memory->Dup(script->m_script.c_str()); outputHandler->eventData.unconditionalScript = m_memory->Dup(script->m_script.c_str());
return outputHandler; elements.push_back(outputHandler);
} }
void ConvertEventHandlerCondition(MenuEventHandler** eventHandlerArray, size_t& eventHandlerArrayIndex, const CommonEventHandlerCondition* condition, const CommonMenuDef* menu, void ConvertEventHandlerCondition(std::vector<MenuEventHandler*>& elements, const CommonEventHandlerCondition* condition, const CommonMenuDef* menu,
const CommonItemDef* item) const const CommonItemDef* item) const
{ {
assert(condition); assert(condition);
if (!condition) if (!condition || !condition->m_condition)
return; return;
if(!m_disable_optimizations && condition->m_condition->IsStatic())
{
const auto staticValueIsTruthy = condition->m_condition->Evaluate().IsTruthy();
if(staticValueIsTruthy)
ConvertEventHandlerElements(elements, condition->m_condition_elements.get(), menu, item);
else if(condition->m_else_elements)
ConvertEventHandlerElements(elements, condition->m_else_elements.get(), menu, item);
}
else
{
auto* outputHandler = static_cast<MenuEventHandler*>(m_memory->Alloc(sizeof(MenuEventHandler) + sizeof(ConditionalScript))); auto* outputHandler = static_cast<MenuEventHandler*>(m_memory->Alloc(sizeof(MenuEventHandler) + sizeof(ConditionalScript)));
auto* outputCondition = reinterpret_cast<ConditionalScript*>(reinterpret_cast<int8_t*>(outputHandler) + sizeof(MenuEventHandler)); auto* outputCondition = reinterpret_cast<ConditionalScript*>(reinterpret_cast<int8_t*>(outputHandler) + sizeof(MenuEventHandler));
@ -584,21 +598,20 @@ namespace IW4
outputCondition->eventExpression = ConvertExpression(condition->m_condition.get(), menu, item); outputCondition->eventExpression = ConvertExpression(condition->m_condition.get(), menu, item);
outputCondition->eventHandlerSet = ConvertEventHandlerSet(condition->m_condition_elements.get(), menu, item); outputCondition->eventHandlerSet = ConvertEventHandlerSet(condition->m_condition_elements.get(), menu, item);
eventHandlerArray[eventHandlerArrayIndex] = outputHandler; elements.push_back(outputHandler);
if (condition->m_else_elements) if (condition->m_else_elements)
{ {
eventHandlerArrayIndex++;
auto* outputElseHandler = m_memory->Create<MenuEventHandler>(); auto* outputElseHandler = m_memory->Create<MenuEventHandler>();
outputElseHandler->eventType = EVENT_ELSE; outputElseHandler->eventType = EVENT_ELSE;
outputElseHandler->eventData.elseScript = ConvertEventHandlerSet(condition->m_else_elements.get(), menu, item); outputElseHandler->eventData.elseScript = ConvertEventHandlerSet(condition->m_else_elements.get(), menu, item);
eventHandlerArray[eventHandlerArrayIndex] = outputElseHandler; elements.push_back(outputElseHandler);
}
} }
} }
void ConvertEventHandler(MenuEventHandler** eventHandlerArray, size_t& eventHandlerArrayIndex, const ICommonEventHandlerElement* eventHandler, const CommonMenuDef* menu, void ConvertEventHandler(std::vector<MenuEventHandler*>& elements, const ICommonEventHandlerElement* eventHandler, const CommonMenuDef* menu,
const CommonItemDef* item) const const CommonItemDef* item) const
{ {
assert(eventHandler); assert(eventHandler);
@ -608,31 +621,23 @@ namespace IW4
switch (eventHandler->GetType()) switch (eventHandler->GetType())
{ {
case CommonEventHandlerElementType::CONDITION: case CommonEventHandlerElementType::CONDITION:
ConvertEventHandlerCondition(eventHandlerArray, eventHandlerArrayIndex, dynamic_cast<const CommonEventHandlerCondition*>(eventHandler), menu, item); ConvertEventHandlerCondition(elements, dynamic_cast<const CommonEventHandlerCondition*>(eventHandler), menu, item);
break; break;
case CommonEventHandlerElementType::SCRIPT: case CommonEventHandlerElementType::SCRIPT:
eventHandlerArray[eventHandlerArrayIndex] = ConvertEventHandlerScript(dynamic_cast<const CommonEventHandlerScript*>(eventHandler)); ConvertEventHandlerScript(elements, dynamic_cast<const CommonEventHandlerScript*>(eventHandler));
break; break;
case CommonEventHandlerElementType::SET_LOCAL_VAR: case CommonEventHandlerElementType::SET_LOCAL_VAR:
eventHandlerArray[eventHandlerArrayIndex] = ConvertEventHandlerSetLocalVar(dynamic_cast<const CommonEventHandlerSetLocalVar*>(eventHandler), menu, item); ConvertEventHandlerSetLocalVar(elements, dynamic_cast<const CommonEventHandlerSetLocalVar*>(eventHandler), menu, item);
break; break;
} }
} }
_NODISCARD static size_t EventHandlerSetElementCount(const CommonEventHandlerSet* eventHandlerSet) void ConvertEventHandlerElements(std::vector<MenuEventHandler*>& elements, const CommonEventHandlerSet* eventHandlerSet, const CommonMenuDef* menu, const CommonItemDef* item) const
{ {
auto elementCount = 0u;
for (const auto& element : eventHandlerSet->m_elements) for (const auto& element : eventHandlerSet->m_elements)
{ ConvertEventHandler(elements, element.get(), menu, item);
auto* condition = dynamic_cast<const CommonEventHandlerCondition*>(element.get());
if (condition && condition->m_else_elements)
elementCount += 2;
else
elementCount++;
}
return elementCount;
} }
_NODISCARD MenuEventHandlerSet* ConvertEventHandlerSet(const CommonEventHandlerSet* eventHandlerSet, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const _NODISCARD MenuEventHandlerSet* ConvertEventHandlerSet(const CommonEventHandlerSet* eventHandlerSet, const CommonMenuDef* menu, const CommonItemDef* item = nullptr) const
@ -640,20 +645,16 @@ namespace IW4
if (!eventHandlerSet) if (!eventHandlerSet)
return nullptr; return nullptr;
const auto elementCount = EventHandlerSetElementCount(eventHandlerSet); std::vector<MenuEventHandler*> elements;
auto* outputSet = static_cast<MenuEventHandlerSet*>(m_memory->Alloc(sizeof(MenuEventHandlerSet) + sizeof(void*) * elementCount)); ConvertEventHandlerElements(elements, eventHandlerSet, menu, item);
auto* outputSet = static_cast<MenuEventHandlerSet*>(m_memory->Alloc(sizeof(MenuEventHandlerSet) + sizeof(void*) * elements.size()));
auto* outputElements = reinterpret_cast<MenuEventHandler**>(reinterpret_cast<int8_t*>(outputSet) + sizeof(MenuEventHandlerSet)); auto* outputElements = reinterpret_cast<MenuEventHandler**>(reinterpret_cast<int8_t*>(outputSet) + sizeof(MenuEventHandlerSet));
memcpy(outputElements, &elements[0], sizeof(void*) * elements.size());
outputSet->eventHandlerCount = static_cast<int>(elementCount); outputSet->eventHandlerCount = static_cast<int>(elements.size());
outputSet->eventHandlers = outputElements; outputSet->eventHandlers = outputElements;
auto eventHandlerIndex = 0u;
for (const auto& element : eventHandlerSet->m_elements)
{
ConvertEventHandler(outputElements, eventHandlerIndex, element.get(), menu, item);
eventHandlerIndex++;
}
return outputSet; return outputSet;
} }