Faster parsing

This was SVN commit r1477.
This commit is contained in:
Ykkrosh 2004-12-08 18:15:39 +00:00
parent 01c35dd616
commit e2062ccee1
3 changed files with 83 additions and 32 deletions

View File

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

View File

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

View File

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