forked from 0ad/0ad
Faster parsing
This was SVN commit r1477.
This commit is contained in:
parent
01c35dd616
commit
e2062ccee1
@ -43,8 +43,7 @@ template <>
|
|||||||
bool __ParseString<CRect>(const CStr& Value, CRect &Output)
|
bool __ParseString<CRect>(const CStr& Value, CRect &Output)
|
||||||
{
|
{
|
||||||
// Use the parser to parse the values
|
// Use the parser to parse the values
|
||||||
CParser parser;
|
CParser& parser (CParserCache::Get("_$value_$value_$value_$value_"));
|
||||||
parser.InputTaskType("", "_$value_$value_$value_$value_");
|
|
||||||
|
|
||||||
string str = (const TCHAR*)Value;
|
string str = (const TCHAR*)Value;
|
||||||
|
|
||||||
@ -80,8 +79,7 @@ template <>
|
|||||||
bool __ParseString<CColor>(const CStr& Value, CColor &Output)
|
bool __ParseString<CColor>(const CStr& Value, CColor &Output)
|
||||||
{
|
{
|
||||||
// Use the parser to parse the values
|
// Use the parser to parse the values
|
||||||
CParser parser;
|
CParser& parser (CParserCache::Get("_$value_$value_$value_[$value_]"));
|
||||||
parser.InputTaskType("", "_$value_$value_$value_[$value_]");
|
|
||||||
|
|
||||||
string str = (const TCHAR*)Value;
|
string str = (const TCHAR*)Value;
|
||||||
|
|
||||||
@ -115,8 +113,7 @@ template <>
|
|||||||
bool __ParseString<CSize>(const CStr& Value, CSize &Output)
|
bool __ParseString<CSize>(const CStr& Value, CSize &Output)
|
||||||
{
|
{
|
||||||
// Use the parser to parse the values
|
// Use the parser to parse the values
|
||||||
CParser parser;
|
CParser& parser (CParserCache::Get("_$value_$value_"));
|
||||||
parser.InputTaskType("", "_$value_$value_");
|
|
||||||
|
|
||||||
string str = (const TCHAR*)Value;
|
string str = (const TCHAR*)Value;
|
||||||
|
|
||||||
@ -244,7 +241,6 @@ bool CClientArea::SetClientArea(const CStr& Value)
|
|||||||
// negligible in the loading time.
|
// negligible in the loading time.
|
||||||
|
|
||||||
// Setup parser to parse the value
|
// Setup parser to parse the value
|
||||||
CParser parser;
|
|
||||||
|
|
||||||
// One of the for values:
|
// One of the for values:
|
||||||
// will give outputs like (in argument):
|
// will give outputs like (in argument):
|
||||||
@ -253,13 +249,20 @@ bool CClientArea::SetClientArea(const CStr& Value)
|
|||||||
// (200) (percent) (100) <== percent PLUS pixel
|
// (200) (percent) (100) <== percent PLUS pixel
|
||||||
// (200) (percent) (-100) <== percent MINUS pixel
|
// (200) (percent) (-100) <== percent MINUS pixel
|
||||||
// (200) (percent) (100) (-100) <== Both PLUS and MINUS are used, INVALID
|
// (200) (percent) (100) (-100) <== Both PLUS and MINUS are used, INVALID
|
||||||
|
/*
|
||||||
string one_value = "_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]";
|
string one_value = "_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]";
|
||||||
string four_values = one_value + "$arg(delim)" +
|
string four_values = one_value + "$arg(delim)" +
|
||||||
one_value + "$arg(delim)" +
|
one_value + "$arg(delim)" +
|
||||||
one_value + "$arg(delim)" +
|
one_value + "$arg(delim)" +
|
||||||
one_value + "$arg(delim)_"; // it's easier to just end with another delimiter
|
one_value + "$arg(delim)_"; // it's easier to just end with another delimiter
|
||||||
|
*/
|
||||||
parser.InputTaskType("ClientArea", four_values);
|
const char* four_values =
|
||||||
|
"_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]" "$arg(delim)"
|
||||||
|
"_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]" "$arg(delim)"
|
||||||
|
"_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]" "$arg(delim)"
|
||||||
|
"_[-_$arg(_minus)]$value[$arg(percent)%_[+_$value]_[-_$arg(_minus)$value]_]" "$arg(delim)"
|
||||||
|
"_";
|
||||||
|
CParser& parser (CParserCache::Get(four_values));
|
||||||
|
|
||||||
CParserLine line;
|
CParserLine line;
|
||||||
line.ParseString(parser, _Value);
|
line.ParseString(parser, _Value);
|
||||||
@ -286,6 +289,7 @@ bool CClientArea::SetClientArea(const CStr& Value)
|
|||||||
{
|
{
|
||||||
if (valuenr!=3)
|
if (valuenr!=3)
|
||||||
{
|
{
|
||||||
|
assert(valuenr <= 2);
|
||||||
arg_start[valuenr+1] = i+1;
|
arg_start[valuenr+1] = i+1;
|
||||||
arg_count[valuenr] = arg_start[valuenr+1] - arg_start[valuenr] - 1;
|
arg_count[valuenr] = arg_start[valuenr+1] - arg_start[valuenr] - 1;
|
||||||
}
|
}
|
||||||
@ -376,24 +380,24 @@ void CInternalCGUIAccessorBase::HandleMessage(IGUIObject *pObject, const SGUIMes
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
#define TYPE(T) \
|
#define TYPE(T) \
|
||||||
template<> void CheckType<T>(const IGUIObject* obj, const CStr& setting) { \
|
template<> void CheckType<T>(const IGUIObject* obj, const CStr& setting) { \
|
||||||
if (((IGUIObject*)obj)->m_Settings[setting].m_Type != GUIST_##T) \
|
if (((IGUIObject*)obj)->m_Settings[setting].m_Type != GUIST_##T) \
|
||||||
{ \
|
{ \
|
||||||
debug_warn("EXCESSIVELY FATAL ERROR: Inconsistent types in GUI"); \
|
debug_warn("EXCESSIVELY FATAL ERROR: Inconsistent types in GUI"); \
|
||||||
throw "EXCESSIVELY FATAL ERROR: Inconsistent types in GUI"; /* TODO: better reporting */ \
|
throw "EXCESSIVELY FATAL ERROR: Inconsistent types in GUI"; /* TODO: better reporting */ \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
TYPE(bool)
|
TYPE(bool)
|
||||||
TYPE(int)
|
TYPE(int)
|
||||||
TYPE(float)
|
TYPE(float)
|
||||||
TYPE(CClientArea)
|
TYPE(CClientArea)
|
||||||
TYPE(CStr)
|
TYPE(CStr)
|
||||||
TYPE(CStrW)
|
TYPE(CStrW)
|
||||||
TYPE(CColor)
|
TYPE(CColor)
|
||||||
TYPE(CGUIString)
|
TYPE(CGUIString)
|
||||||
TYPE(EAlign)
|
TYPE(EAlign)
|
||||||
TYPE(EVAlign)
|
TYPE(EVAlign)
|
||||||
#undef TYPE
|
#undef TYPE
|
||||||
//#endif // #ifndef NDEBUG
|
#endif
|
||||||
|
@ -1067,3 +1067,23 @@ next [a] Null [a] <-- added NewNode
|
|||||||
|
|
||||||
return !Error;
|
return !Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CParserCache::CacheType CParserCache::m_Cached;
|
||||||
|
|
||||||
|
CParser& CParserCache::Get(const char* str)
|
||||||
|
{
|
||||||
|
CacheType::iterator it = m_Cached.find(str);
|
||||||
|
if (it == m_Cached.end())
|
||||||
|
{
|
||||||
|
CParser* parser = new CParser;
|
||||||
|
parser->InputTaskType("", str);
|
||||||
|
m_Cached[str] = parser;
|
||||||
|
return *parser;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CParser* parser = it->second;
|
||||||
|
return *parser;
|
||||||
|
}
|
||||||
|
}
|
@ -208,8 +208,8 @@ public:
|
|||||||
class CParser
|
class CParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CParser::CParser();
|
CParser();
|
||||||
CParser::~CParser();
|
~CParser();
|
||||||
|
|
||||||
std::vector<CParserTaskType> m_TaskTypes;
|
std::vector<CParserTaskType> m_TaskTypes;
|
||||||
|
|
||||||
@ -218,4 +218,31 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// CParserCache
|
||||||
|
// ---------------------------------------------------------------------| Class
|
||||||
|
// Provides access to CParser objects, caching them to avoid
|
||||||
|
// reconstructing the object every time a string needs to be parsed.
|
||||||
|
class CParserCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Returns a simple parser based on a single nameless task-type
|
||||||
|
static CParser& Get(const char* str);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Self-destructing std::map
|
||||||
|
template <typename T, typename P> class SDMap : public std::map<T,P>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~SDMap()
|
||||||
|
{
|
||||||
|
for (iterator it = begin(); it != end(); ++it) delete it->second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SDMap<std::string, CParser*> CacheType;
|
||||||
|
|
||||||
|
static CacheType m_Cached;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user