Changeset View
Changeset View
Standalone View
Standalone View
source/simulation2/system/ParamNode.cpp
/* Copyright (C) 2015 Wildfire Games. | /* Copyright (C) 2017 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | void CParamNode::ApplyLayer(const XMBFile& xmb, const XMBElement& element, const wchar_t* sourceIdentifier /*= NULL*/) | ||||
std::string name = xmb.GetElementString(element.GetNodeName()); // TODO: is GetElementString inefficient? | std::string name = xmb.GetElementString(element.GetNodeName()); // TODO: is GetElementString inefficient? | ||||
CStrW value = element.GetText().FromUTF8(); | CStrW value = element.GetText().FromUTF8(); | ||||
bool hasSetValue = false; | bool hasSetValue = false; | ||||
// Look for special attributes | // Look for special attributes | ||||
int at_disable = xmb.GetAttributeID("disable"); | int at_disable = xmb.GetAttributeID("disable"); | ||||
int at_replace = xmb.GetAttributeID("replace"); | int at_replace = xmb.GetAttributeID("replace"); | ||||
int at_filtered = xmb.GetAttributeID("filtered"); | |||||
int at_merge = xmb.GetAttributeID("merge"); | |||||
int at_op = xmb.GetAttributeID("op"); | int at_op = xmb.GetAttributeID("op"); | ||||
int at_datatype = xmb.GetAttributeID("datatype"); | int at_datatype = xmb.GetAttributeID("datatype"); | ||||
enum op { | enum op { | ||||
INVALID, | INVALID, | ||||
ADD, | ADD, | ||||
MUL | MUL | ||||
} op = INVALID; | } op = INVALID; | ||||
bool replacing = false; | bool replacing = false; | ||||
bool filtering = false; | |||||
bool merging = false; | |||||
{ | { | ||||
XERO_ITER_ATTR(element, attr) | XERO_ITER_ATTR(element, attr) | ||||
{ | { | ||||
if (attr.Name == at_disable) | if (attr.Name == at_disable) | ||||
{ | { | ||||
m_Childs.erase(name); | m_Childs.erase(name); | ||||
return; | return; | ||||
} | } | ||||
else if (attr.Name == at_replace) | else if (attr.Name == at_replace) | ||||
{ | { | ||||
m_Childs.erase(name); | m_Childs.erase(name); | ||||
replacing = true; | replacing = true; | ||||
} | } | ||||
else if (attr.Name == at_filtered) | |||||
{ | |||||
filtering = true; | |||||
} | |||||
else if (attr.Name == at_merge) | |||||
{ | |||||
if (m_Childs.find(name) == m_Childs.end()) | |||||
return; | |||||
merging = true; | |||||
} | |||||
else if (attr.Name == at_op) | else if (attr.Name == at_op) | ||||
{ | { | ||||
if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"add") | if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"add") | ||||
op = ADD; | op = ADD; | ||||
else if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"mul") | else if (std::wstring(attr.Value.begin(), attr.Value.end()) == L"mul") | ||||
op = MUL; | op = MUL; | ||||
else | else | ||||
LOGWARNING("Invalid op '%ls'", attr.Value); | LOGWARNING("Invalid op '%ls'", attr.Value); | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | void CParamNode::ApplyLayer(const XMBFile& xmb, const XMBElement& element, const wchar_t* sourceIdentifier /*= NULL*/) | ||||
// Add this element as a child node | // Add this element as a child node | ||||
CParamNode& node = m_Childs[name]; | CParamNode& node = m_Childs[name]; | ||||
if (op != INVALID) | if (op != INVALID) | ||||
{ | { | ||||
// TODO: Support parsing of data types other than fixed; log warnings in other cases | // TODO: Support parsing of data types other than fixed; log warnings in other cases | ||||
fixed oldval = node.ToFixed(); | fixed oldval = node.ToFixed(); | ||||
fixed mod = fixed::FromString(CStrW(value)); | fixed mod = fixed::FromString(CStrW(value)); | ||||
switch (op) | switch (op) | ||||
{ | { | ||||
case ADD: | case ADD: | ||||
node.m_Value = (oldval + mod).ToString().FromUTF8(); | node.m_Value = (oldval + mod).ToString().FromUTF8(); | ||||
break; | break; | ||||
case MUL: | case MUL: | ||||
node.m_Value = (oldval.Multiply(mod)).ToString().FromUTF8(); | node.m_Value = (oldval.Multiply(mod)).ToString().FromUTF8(); | ||||
break; | break; | ||||
} | } | ||||
hasSetValue = true; | hasSetValue = true; | ||||
} | } | ||||
if (!hasSetValue) | |||||
if (!hasSetValue && !merging) | |||||
node.m_Value = value; | node.m_Value = value; | ||||
// We also need to reset node's script val, even if it has no children | // We also need to reset node's script val, even if it has no children | ||||
// or if the attributes change. | // or if the attributes change. | ||||
node.ResetScriptVal(); | node.ResetScriptVal(); | ||||
// For the filtered case | |||||
ChildrenMap childs; | |||||
// Recurse through the element's children | // Recurse through the element's children | ||||
XERO_ITER_EL(element, child) | XERO_ITER_EL(element, child) | ||||
{ | { | ||||
node.ApplyLayer(xmb, child, sourceIdentifier); | node.ApplyLayer(xmb, child, sourceIdentifier); | ||||
if (filtering) | |||||
{ | |||||
std::string childname = xmb.GetElementString(child.GetNodeName()); | |||||
if (node.m_Childs.find(childname) != node.m_Childs.end()) | |||||
childs[childname] = std::move(node.m_Childs[childname]); | |||||
} | |||||
} | } | ||||
if (filtering) | |||||
node.m_Childs.swap(childs); | |||||
// Add the element's attributes, prefixing names with "@" | // Add the element's attributes, prefixing names with "@" | ||||
XERO_ITER_ATTR(element, attr) | XERO_ITER_ATTR(element, attr) | ||||
{ | { | ||||
// Skip special attributes | // Skip special attributes | ||||
if (attr.Name == at_replace || attr.Name == at_op) | if (attr.Name == at_replace || attr.Name == at_op || attr.Name == at_merge || attr.Name == at_filtered) | ||||
continue; | continue; | ||||
// Add any others | // Add any others | ||||
std::string attrName = xmb.GetAttributeString(attr.Name); | std::string attrName = xmb.GetAttributeString(attr.Name); | ||||
node.m_Childs["@" + attrName].m_Value = attr.Value.FromUTF8(); | node.m_Childs["@" + attrName].m_Value = attr.Value.FromUTF8(); | ||||
} | } | ||||
} | } | ||||
void CParamNode::CopyFilteredChildrenOfChild(const CParamNode& src, const char* name, const std::set<std::string>& permitted) | |||||
{ | |||||
ResetScriptVal(); | |||||
ChildrenMap::iterator dstChild = m_Childs.find(name); | |||||
ChildrenMap::const_iterator srcChild = src.m_Childs.find(name); | |||||
if (dstChild == m_Childs.end() || srcChild == src.m_Childs.end()) | |||||
return; // error | |||||
ChildrenMap::const_iterator it = srcChild->second.m_Childs.begin(); | |||||
for (; it != srcChild->second.m_Childs.end(); ++it) | |||||
if (permitted.count(it->first)) | |||||
dstChild->second.m_Childs[it->first] = it->second; | |||||
} | |||||
const CParamNode& CParamNode::GetChild(const char* name) const | const CParamNode& CParamNode::GetChild(const char* name) const | ||||
{ | { | ||||
ChildrenMap::const_iterator it = m_Childs.find(name); | ChildrenMap::const_iterator it = m_Childs.find(name); | ||||
if (it == m_Childs.end()) | if (it == m_Childs.end()) | ||||
return g_NullNode; | return g_NullNode; | ||||
return it->second; | return it->second; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 208 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator