Allow mapping CSheetId from string literals, avoiding std::string allocation

feature/pre-code-move
kaetemi 5 years ago committed by Jan Boon
parent 4645d1837d
commit 45a43384da

@ -58,19 +58,43 @@ public :
*/ */
explicit CSheetId( uint32 sheetRef = 0 ); explicit CSheetId( uint32 sheetRef = 0 );
/**
* Constructor
*/
explicit CSheetId( int sheetRef );
/** /**
* Constructor * Constructor
*/ */
explicit CSheetId( const std::string& sheetName ); explicit CSheetId( const std::string& sheetName );
/**
* Operator=
*/
explicit CSheetId( const char *sheetName );
/** /**
* Constructor, uses defaultType as extension when sheetName * Constructor, uses defaultType as extension when sheetName
* contains no file extension. * contains no file extension.
*/ */
explicit CSheetId( const std::string& sheetName, const std::string &defaultType ); explicit CSheetId( const std::string& sheetName, const std::string &defaultType );
/**
* Constructor, uses defaultType as extension when sheetName
* contains no file extension.
*/
explicit CSheetId( const std::string& sheetName, const char *defaultType );
/**
* Constructor, uses defaultType as extension when sheetName
* contains no file extension.
*/
explicit CSheetId( const char *sheetName, const char *defaultType );
// build from a string and returns true if the build succeed // build from a string and returns true if the build succeed
bool buildSheetId(const std::string& sheetName); bool buildSheetId(const char *sheetName, size_t sheetNameLen);
inline bool buildSheetId(const char *sheetName) { return buildSheetId(sheetName, strlen(sheetName)); }
inline bool buildSheetId(const std::string &sheetName) { return buildSheetId(sheetName.c_str(), sheetName.size()); }
// build from a SubSheetId and a type // build from a SubSheetId and a type
void buildSheetId(uint32 shortId, uint32 type); void buildSheetId(uint32 shortId, uint32 type);
@ -93,17 +117,22 @@ public :
/** /**
* Return the **whole** sheet id (id+type) * Return the **whole** sheet id (id+type)
*/ */
uint32 asInt() const { return _Id.Id; } inline uint32 asInt() const { return _Id.Id; }
/** /**
* Return the sheet type (sub part of the sheetid) * Return the sheet type (sub part of the sheetid)
*/ */
uint32 getSheetType() const { return _Id.IdInfos.Type; } inline uint32 getSheetType() const { return _Id.IdInfos.Type; }
/** /**
* Return the sheet sub id (sub part of the sheetid) * Return the sheet sub id (sub part of the sheetid)
*/ */
uint32 getShortId() const { return _Id.IdInfos.Id; } inline uint32 getShortId() const { return _Id.IdInfos.Id; }
/**
* Operator bool
*/
inline operator bool() const { return _Id.Id; }
/** /**
* Operator= * Operator=
@ -115,11 +144,21 @@ public :
*/ */
CSheetId& operator=( const std::string& sheetName ); CSheetId& operator=( const std::string& sheetName );
/**
* Operator=
*/
CSheetId& operator=( const char *sheetName );
/** /**
* Operator= * Operator=
*/ */
CSheetId& operator=( uint32 sheetRef ); CSheetId& operator=( uint32 sheetRef );
/**
* Operator=
*/
CSheetId& operator=( int sheetRef );
/** /**
* Operator< * Operator<
*/ */
@ -218,9 +257,12 @@ private :
} }
}; };
typedef CStaticMap<uint32, CChar> TSheetIdToNameMap;
typedef CStaticMap<CChar, uint32, CCharComp> TSheetNameToIdMap;
static CChar _AllStrings; static CChar _AllStrings;
static CStaticMap<uint32, CChar> _SheetIdToName; static TSheetIdToNameMap _SheetIdToName;
static CStaticMap<CChar,uint32, CCharComp> _SheetNameToId; static TSheetNameToIdMap _SheetNameToId;
static std::vector<std::string> _FileExtensions; static std::vector<std::string> _FileExtensions;
static bool _Initialised; static bool _Initialised;

@ -184,11 +184,11 @@
// https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=vs-2019 // https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=vs-2019
// https://gcc.gnu.org/projects/cxx-status.html // https://gcc.gnu.org/projects/cxx-status.html
#if (defined(_MSC_VER) && (_MSC_VER >= 1910)) || (defined(__GNUC__ ) && (__GNUC__ >= 8)) #if (defined(_MSC_VER) && (_MSC_VER >= 1910) && (!defined(_HAS_CXX17) || _HAS_CXX17)) || (defined(__GNUC__ ) && (__GNUC__ >= 8) && (__cplusplus >= 201703L))
# define NL_CPP17 # define NL_CPP17
#endif #endif
#if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || (defined(__GNUC__ ) && (__GNUC__ >= 6)) #if (defined(_MSC_VER) && (_MSC_VER >= 1900)) || (defined(__GNUC__ ) && (__GNUC__ >= 6) && (__cplusplus >= 201402L))
# define NL_CPP14 # define NL_CPP14
#endif #endif

@ -52,7 +52,7 @@ std::map<std::string, uint32> CSheetId::_DevTypeNameToId;
std::vector<std::vector<std::string>> CSheetId::_DevSheetIdToName; std::vector<std::vector<std::string>> CSheetId::_DevSheetIdToName;
std::map<std::string, uint32> CSheetId::_DevSheetNameToId; std::map<std::string, uint32> CSheetId::_DevSheetNameToId;
const CSheetId CSheetId::Unknown(0); const CSheetId CSheetId::Unknown((uint32)0);
void CSheetId::cbFileChange(const std::string &filename) void CSheetId::cbFileChange(const std::string &filename)
{ {
@ -74,7 +74,35 @@ CSheetId::CSheetId(uint32 sheetRef)
// For now, all static CSheetId are 0 (eg: CSheetId::Unknown) // For now, all static CSheetId are 0 (eg: CSheetId::Unknown)
if (sheetRef) if (sheetRef)
{ {
CStaticMap<uint32, CChar>::iterator it(_SheetIdToName.find(sheetRef)); TSheetIdToNameMap::iterator it(_SheetIdToName.find(sheetRef));
if (it != _SheetIdToName.end())
{
_DebugSheetName = it->second.Ptr;
}
else
_DebugSheetName = NULL;
}
else
{
_DebugSheetName = NULL;
}
#endif
}
//-----------------------------------------------
// CSheetId
//
//-----------------------------------------------
CSheetId::CSheetId(int sheetRef)
{
_Id.Id = (uint32)sheetRef;
#ifdef NL_DEBUG_SHEET_ID
// Yoyo: don't access the static map, because of order of static ctor call.
// For now, all static CSheetId are 0 (eg: CSheetId::Unknown)
if (sheetRef)
{
TSheetIdToNameMap::iterator it(_SheetIdToName.find(sheetRef));
if (it != _SheetIdToName.end()) if (it != _SheetIdToName.end())
{ {
_DebugSheetName = it->second.Ptr; _DebugSheetName = it->second.Ptr;
@ -95,7 +123,7 @@ CSheetId::CSheetId(uint32 sheetRef)
//----------------------------------------------- //-----------------------------------------------
CSheetId::CSheetId(const string &sheetName) CSheetId::CSheetId(const string &sheetName)
{ {
if (!buildSheetId(sheetName)) if (!buildSheetId(sheetName.c_str(), sheetName.size()))
{ {
if (sheetName.empty()) if (sheetName.empty())
nlwarning("SHEETID: Try to create an CSheetId with empty name. TODO: check why."); nlwarning("SHEETID: Try to create an CSheetId with empty name. TODO: check why.");
@ -115,6 +143,25 @@ CSheetId::CSheetId(const string &sheetName)
} // CSheetId // } // CSheetId //
//-----------------------------------------------
// CSheetId
//
//-----------------------------------------------
CSheetId::CSheetId(const char *sheetName)
{
if (!buildSheetId(sheetName, strlen(sheetName)))
{
if (!sheetName[0])
nlwarning("SHEETID: Try to create an CSheetId with empty name. TODO: check why.");
else
nlwarning("SHEETID: The sheet '%s' is not in sheet_id.bin, setting it to Unknown", sheetName);
*this = Unknown;
}
// nldebug("LIST_SHEET_ID: %s (%s)", toString().c_str(), sheetName.c_str());
} // CSheetId //
CSheetId::CSheetId(const std::string &sheetName, const std::string &defaultType) CSheetId::CSheetId(const std::string &sheetName, const std::string &defaultType)
{ {
// Don't use this function without defaultType, use the one above. // Don't use this function without defaultType, use the one above.
@ -132,11 +179,47 @@ CSheetId::CSheetId(const std::string &sheetName, const std::string &defaultType)
} }
} }
static std::string s_Dot = ".";
CSheetId::CSheetId(const std::string &sheetName, const char *defaultType)
{
// Don't use this function without defaultType, use the one above.
nlassert(defaultType[0]);
if (sheetName.rfind('.') == std::string::npos)
{
std::string withType = sheetName + s_Dot + defaultType;
*this = CSheetId(withType);
// nldebug("SHEETID: Constructing CSheetId from name '%s' without explicit type, defaulting as '%s' to '%s'", sheetName.c_str(), defaultType.c_str(), withType.c_str());
}
else
{
*this = CSheetId(sheetName);
}
}
CSheetId::CSheetId(const char *sheetName, const char *defaultType)
{
// Don't use this function without defaultType, use the one above.
nlassert(defaultType[0]);
if (!strchr(sheetName, '.'))
{
std::string withType = sheetName + s_Dot + defaultType;
*this = CSheetId(withType);
// nldebug("SHEETID: Constructing CSheetId from name '%s' without explicit type, defaulting as '%s' to '%s'", sheetName.c_str(), defaultType.c_str(), withType.c_str());
}
else
{
*this = CSheetId(sheetName);
}
}
//----------------------------------------------- //-----------------------------------------------
// Build // Build
// //
//----------------------------------------------- //-----------------------------------------------
bool CSheetId::buildSheetId(const std::string &sheetName) bool CSheetId::buildSheetId(const char *sheetName, size_t sheetNameLen)
{ {
nlassert(_Initialised); nlassert(_Initialised);
@ -184,14 +267,23 @@ bool CSheetId::buildSheetId(const std::string &sheetName)
} }
// try looking up the sheet name in _SheetNameToId // try looking up the sheet name in _SheetNameToId
CStaticMap<CChar, uint32, CCharComp>::const_iterator itId; TSheetNameToIdMap::const_iterator itId;
CChar c; CChar c;
#ifdef alloca
#pragma warning(push)
#pragma warning(disable : 6255)
c.Ptr = (char *)alloca(sheetNameLen + 1);
#pragma warning(pop)
#else
c.Ptr = new char[sheetName.size() + 1]; c.Ptr = new char[sheetName.size() + 1];
strcpy(c.Ptr, sheetName.c_str()); #endif
strcpy(c.Ptr, sheetName);
toLower(c.Ptr); toLower(c.Ptr);
itId = _SheetNameToId.find(c); itId = _SheetNameToId.find(c);
delete[] c.Ptr; #ifndef alloca
delete[] c.Ptr; // Don't delete alloca
#endif
if (itId != _SheetNameToId.end()) if (itId != _SheetNameToId.end())
{ {
_Id.Id = itId->second; _Id.Id = itId->second;
@ -203,11 +295,10 @@ bool CSheetId::buildSheetId(const std::string &sheetName)
} }
// we failed to find the sheet name in the sheetname map so see if the string is numeric // we failed to find the sheet name in the sheetname map so see if the string is numeric
if (sheetName.size() > 1 && sheetName[0] == '#') if (sheetName[0] == '#' && sheetName[1])
{ {
uint32 numericId; uint32 numericId;
NLMISC::fromString((const char *)(sheetName.c_str() + 1), numericId); if (NLMISC::fromString((const char *)(sheetName + 1), numericId))
if (NLMISC::toString("#%u", numericId) == sheetName)
{ {
_Id.Id = numericId; _Id.Id = numericId;
return true; return true;
@ -316,7 +407,7 @@ void CSheetId::loadSheetId()
{ {
uint32 nSize = (uint32)_SheetIdToName.size(); uint32 nSize = (uint32)_SheetIdToName.size();
_SheetNameToId.reserve(nSize); _SheetNameToId.reserve(nSize);
CStaticMap<uint32, CChar>::iterator itStr; TSheetIdToNameMap::iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
// add entry to the inverse map // add entry to the inverse map
@ -428,7 +519,7 @@ CSheetId &CSheetId::operator=(const CSheetId &sheetId)
CSheetId &CSheetId::operator=(const string &sheetName) CSheetId &CSheetId::operator=(const string &sheetName)
{ {
if (!buildSheetId(sheetName)) if (!buildSheetId(sheetName.c_str(), sheetName.size()))
*this = Unknown; *this = Unknown;
// nldebug("LIST_SHEET_ID: %s (%s)", toString().c_str(), sheetName.c_str()); // nldebug("LIST_SHEET_ID: %s (%s)", toString().c_str(), sheetName.c_str());
@ -437,6 +528,22 @@ CSheetId &CSheetId::operator=(const string &sheetName)
} // operator= // } // operator= //
//-----------------------------------------------
// operator=
//
//-----------------------------------------------
CSheetId &CSheetId::operator=(const char *sheetName)
{
if (!buildSheetId(sheetName, strlen(sheetName)))
*this = Unknown;
// nldebug("LIST_SHEET_ID: %s (%s)", toString().c_str(), sheetName);
return *this;
} // operator= //
//----------------------------------------------- //-----------------------------------------------
// operator= // operator=
// //
@ -452,6 +559,21 @@ CSheetId &CSheetId::operator=(uint32 sheetRef)
} // operator= // } // operator= //
//-----------------------------------------------
// operator=
//
//-----------------------------------------------
CSheetId &CSheetId::operator=(int sheetRef)
{
if (!_Initialised)
init(false);
_Id.Id = (uint32)sheetRef;
return *this;
} // operator= //
//----------------------------------------------- //-----------------------------------------------
// operator< // operator<
// //
@ -499,7 +621,7 @@ string CSheetId::toString(bool ifNotFoundUseNumericId) const
} }
} }
CStaticMap<uint32, CChar>::const_iterator itStr = _SheetIdToName.find(_Id.Id); TSheetIdToNameMap::const_iterator itStr = _SheetIdToName.find(_Id.Id);
if (itStr != _SheetIdToName.end()) if (itStr != _SheetIdToName.end())
{ {
return string((*itStr).second.Ptr); return string((*itStr).second.Ptr);
@ -528,7 +650,7 @@ void CSheetId::serial(NLMISC::IStream &f)
f.serial(_Id.Id); f.serial(_Id.Id);
#ifdef NL_DEBUG_SHEET_ID #ifdef NL_DEBUG_SHEET_ID
CStaticMap<uint32, CChar>::iterator it(_SheetIdToName.find(_Id.Id)); TSheetIdToNameMap::iterator it(_SheetIdToName.find(_Id.Id));
if (it != _SheetIdToName.end()) if (it != _SheetIdToName.end())
_DebugSheetName = it->second.Ptr; _DebugSheetName = it->second.Ptr;
else else
@ -564,7 +686,7 @@ void CSheetId::display()
if (!_Initialised) if (!_Initialised)
init(false); init(false);
CStaticMap<uint32, CChar>::const_iterator itStr; TSheetIdToNameMap::const_iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
//nlinfo("%d %s",(*itStr).first,(*itStr).second.c_str()); //nlinfo("%d %s",(*itStr).first,(*itStr).second.c_str());
@ -582,7 +704,7 @@ void CSheetId::display(uint32 type)
if (!_Initialised) if (!_Initialised)
init(false); init(false);
CStaticMap<uint32, CChar>::const_iterator itStr; TSheetIdToNameMap::const_iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
// work out the type value for this entry in the map // work out the type value for this entry in the map
@ -608,7 +730,7 @@ void CSheetId::buildIdVector(std::vector<CSheetId> &result)
if (!_Initialised) if (!_Initialised)
init(false); init(false);
CStaticMap<uint32, CChar>::const_iterator itStr; TSheetIdToNameMap::const_iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
result.push_back((CSheetId)(*itStr).first); result.push_back((CSheetId)(*itStr).first);
@ -626,7 +748,7 @@ void CSheetId::buildIdVector(std::vector<CSheetId> &result, uint32 type)
init(false); init(false);
nlassert(type < (1 << (NL_SHEET_ID_TYPE_BITS))); nlassert(type < (1 << (NL_SHEET_ID_TYPE_BITS)));
CStaticMap<uint32, CChar>::const_iterator itStr; TSheetIdToNameMap::const_iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
// work out the type value for this entry in the map // work out the type value for this entry in the map
@ -652,7 +774,7 @@ void CSheetId::buildIdVector(std::vector<CSheetId> &result, std::vector<std::str
init(false); init(false);
nlassert(type < (1 << (NL_SHEET_ID_TYPE_BITS))); nlassert(type < (1 << (NL_SHEET_ID_TYPE_BITS)));
CStaticMap<uint32, CChar>::const_iterator itStr; TSheetIdToNameMap::const_iterator itStr;
for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr) for (itStr = _SheetIdToName.begin(); itStr != _SheetIdToName.end(); ++itStr)
{ {
// work out the type value for this entry in the map // work out the type value for this entry in the map
@ -737,7 +859,7 @@ void CSheetId::buildSheetId(uint32 shortId, uint32 type)
_Id.IdInfos.Type = type; _Id.IdInfos.Type = type;
#ifdef NL_DEBUG_SHEET_ID #ifdef NL_DEBUG_SHEET_ID
CStaticMap<uint32, CChar>::iterator it(_SheetIdToName.find(_Id.Id)); TSheetIdToNameMap::iterator it(_SheetIdToName.find(_Id.Id));
if (it != _SheetIdToName.end()) if (it != _SheetIdToName.end())
{ {
_DebugSheetName = it->second.Ptr; _DebugSheetName = it->second.Ptr;

Loading…
Cancel
Save