@ -40,6 +40,15 @@ vector<std::string> CSheetId::_FileExtensions;
bool CSheetId : : _Initialised = false ;
bool CSheetId : : _Initialised = false ;
bool CSheetId : : _RemoveUnknownSheet = true ;
bool CSheetId : : _RemoveUnknownSheet = true ;
bool CSheetId : : _DontHaveSheetKnowledge = false ;
bool CSheetId : : _DontHaveSheetKnowledge = false ;
std : : map < std : : string , uint32 > CSheetId : : _DevTypeNameToId ;
std : : vector < std : : vector < std : : string > > CSheetId : : _DevSheetIdToName ;
std : : map < std : : string , uint32 > CSheetId : : _DevSheetNameToId ;
# define NL_TEMP_YUBO_NO_SOUND_SHEET_ID
# ifdef NL_TEMP_YUBO_NO_SOUND_SHEET_ID
namespace { bool a_NoSoundSheetId = false ; }
# endif
const CSheetId CSheetId : : Unknown ( 0 ) ;
const CSheetId CSheetId : : Unknown ( 0 ) ;
@ -103,6 +112,18 @@ CSheetId::CSheetId( const string& sheetName )
} // CSheetId //
} // CSheetId //
CSheetId : : CSheetId ( const std : : string & sheetName , const std : : string & defaultType )
{
if ( CFile : : getExtension ( sheetName ) = = " " & & defaultType ! = " " )
{
std : : string withType = sheetName + " . " + 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
@ -111,7 +132,41 @@ CSheetId::CSheetId( const string& sheetName )
bool CSheetId : : buildSheetId ( const std : : string & sheetName )
bool CSheetId : : buildSheetId ( const std : : string & sheetName )
{
{
nlassert ( _Initialised ) ;
nlassert ( _Initialised ) ;
nlassert ( ! _DontHaveSheetKnowledge ) ;
// When no sheet_id.bin is loaded, use dynamically assigned IDs.
if ( _DontHaveSheetKnowledge )
{
std : : string sheetNameLc = toLower ( sheetName ) ;
std : : map < std : : string , uint32 > : : iterator it = _DevSheetNameToId . find ( sheetNameLc ) ;
if ( it = = _DevSheetNameToId . end ( ) )
{
// Create a new dynamic sheet ID.
// nldebug("SHEETID: Creating a dynamic sheet id for '%s'", sheetName.c_str());
std : : string sheetType = CFile : : getExtension ( sheetNameLc ) ;
std : : string sheetName = CFile : : getFilenameWithoutExtension ( sheetNameLc ) ;
std : : map < std : : string , uint32 > : : iterator tit = _DevTypeNameToId . find ( sheetType ) ;
uint32 typeId ;
if ( tit = = _DevTypeNameToId . end ( ) )
{
_FileExtensions . push_back ( sheetType ) ;
_DevSheetIdToName . push_back ( std : : vector < std : : string > ( ) ) ;
typeId = _FileExtensions . size ( ) - 1 ;
_DevTypeNameToId [ sheetType ] = typeId ;
}
else
{
typeId = tit - > second ;
}
_DevSheetIdToName [ typeId ] . push_back ( sheetName ) ;
_Id . IdInfos . Type = typeId ;
_Id . IdInfos . Id = _DevSheetIdToName [ typeId ] . size ( ) - 1 ;
// nldebug("SHEETID: Type %i, id %i, sheetid %i", _Id.IdInfos.Type, _Id.IdInfos.Id, _Id.Id);
_DevSheetNameToId [ sheetNameLc ] = _Id . Id ;
return true ;
}
_Id . Id = it - > second ;
return true ;
}
// try looking up the sheet name in _SheetNameToId
// try looking up the sheet name in _SheetNameToId
CStaticMap < CChar , uint32 , CCharComp > : : const_iterator itId ;
CStaticMap < CChar , uint32 , CCharComp > : : const_iterator itId ;
@ -143,6 +198,27 @@ bool CSheetId::buildSheetId(const std::string& sheetName)
return true ;
return true ;
}
}
}
}
# ifdef NL_TEMP_YUBO_NO_SOUND_SHEET_ID
if ( a_NoSoundSheetId & & sheetName . find ( " .sound " ) ! = std : : string : : npos )
{
std : : string sheetNameLc = toLower ( sheetName ) ;
std : : map < std : : string , uint32 > : : iterator it = _DevSheetNameToId . find ( sheetNameLc ) ;
if ( it = = _DevSheetNameToId . end ( ) )
{
uint32 typeId = ( ( 1 < < ( NL_SHEET_ID_TYPE_BITS ) ) - 1 ) ;
// nldebug("SHEETID: Creating a temporary sheet id for '%s'", sheetName.c_str());
_DevSheetIdToName [ 0 ] . push_back ( sheetName ) ;
_Id . IdInfos . Type = typeId ;
_Id . IdInfos . Id = _DevSheetIdToName [ 0 ] . size ( ) - 1 ;
_DevSheetNameToId [ sheetNameLc ] = _Id . Id ;
return true ;
}
_Id . Id = it - > second ;
return true ;
}
# endif
return false ;
return false ;
}
}
@ -283,7 +359,11 @@ void CSheetId::init(bool removeUnknownSheet)
{
{
// allow multiple calls to init in case libraries depending on sheetid call this init from their own
// allow multiple calls to init in case libraries depending on sheetid call this init from their own
if ( _Initialised )
if ( _Initialised )
{
if ( _DontHaveSheetKnowledge )
nlinfo ( " SHEETID: CSheetId is already initialized without sheet_id.bin " ) ;
return ;
return ;
}
// CFile::addFileChangeCallback ("sheet_id.bin", cbFileChange);
// CFile::addFileChangeCallback ("sheet_id.bin", cbFileChange);
@ -292,13 +372,33 @@ void CSheetId::init(bool removeUnknownSheet)
loadSheetId ( ) ;
loadSheetId ( ) ;
_Initialised = true ;
_Initialised = true ;
# ifdef NL_TEMP_YUBO_NO_SOUND_SHEET_ID
if ( typeFromFileExtension ( " sound " ) = = std : : numeric_limits < uint32 > : : max ( ) )
{
nlwarning ( " SHEETID: Loading without known sound sheet id, please update sheet_id.bin with .sound sheets " ) ;
nlassert ( _FileExtensions . size ( ) = = 1 < < ( NL_SHEET_ID_TYPE_BITS ) ) ;
_FileExtensions [ ( ( 1 < < ( NL_SHEET_ID_TYPE_BITS ) ) - 1 ) ] = = " sound " ;
_DevSheetIdToName . push_back ( std : : vector < std : : string > ( ) ) ;
a_NoSoundSheetId = true ;
}
# endif
} // init //
} // init //
void CSheetId : : initWithoutSheet ( )
void CSheetId : : initWithoutSheet ( )
{
{
if ( _Initialised )
{
nlassert ( _DontHaveSheetKnowledge ) ;
return ;
}
_Initialised = true ;
_Initialised = true ;
_DontHaveSheetKnowledge = true ;
_DontHaveSheetKnowledge = true ;
// Initialize id 0,0 as unknown.unknown
CSheetId unknownunknown = CSheetId ( " unknown.unknown " ) ;
nlassert ( unknownunknown = = CSheetId : : Unknown ) ;
}
}
@ -310,6 +410,10 @@ void CSheetId::initWithoutSheet()
void CSheetId : : uninit ( )
void CSheetId : : uninit ( )
{
{
delete [ ] _AllStrings . Ptr ;
delete [ ] _AllStrings . Ptr ;
_FileExtensions . clear ( ) ;
_DevTypeNameToId . clear ( ) ;
_DevSheetIdToName . clear ( ) ;
_DevSheetNameToId . clear ( ) ;
} // uninit //
} // uninit //
//-----------------------------------------------
//-----------------------------------------------
@ -343,22 +447,8 @@ CSheetId& CSheetId::operator=( const CSheetId& sheetId )
//-----------------------------------------------
//-----------------------------------------------
CSheetId & CSheetId : : operator = ( const string & sheetName )
CSheetId & CSheetId : : operator = ( const string & sheetName )
{
{
nlassert ( _Initialised ) ;
nlassert ( ! _DontHaveSheetKnowledge ) ;
CStaticMap < CChar , uint32 , CCharComp > : : const_iterator itId ;
if ( ! buildSheetId ( sheetName ) )
CChar c ;
c . Ptr = new char [ sheetName . size ( ) + 1 ] ;
strcpy ( c . Ptr , sheetName . c_str ( ) ) ;
toLower ( c . Ptr ) ;
itId = _SheetNameToId . find ( c ) ;
delete [ ] c . Ptr ;
if ( itId ! = _SheetNameToId . end ( ) )
{
_Id . Id = ( * itId ) . second ;
return * this ;
}
* this = Unknown ;
* this = Unknown ;
return * this ;
return * this ;
@ -408,6 +498,13 @@ string CSheetId::toString(bool ifNotFoundUseNumericId) const
{
{
if ( ! _Initialised ) init ( false ) ;
if ( ! _Initialised ) init ( false ) ;
if ( _DontHaveSheetKnowledge )
{
// FIXME: When someone punches in a fake sheet id this will
// fail.
return _DevSheetIdToName [ _Id . IdInfos . Type ] [ _Id . IdInfos . Id ] ;
}
CStaticMap < uint32 , CChar > : : const_iterator itStr = _SheetIdToName . find ( _Id . Id ) ;
CStaticMap < uint32 , CChar > : : const_iterator itStr = _SheetIdToName . find ( _Id . Id ) ;
if ( itStr ! = _SheetIdToName . end ( ) )
if ( itStr ! = _SheetIdToName . end ( ) )
{
{
@ -415,6 +512,12 @@ string CSheetId::toString(bool ifNotFoundUseNumericId) const
}
}
else
else
{
{
# ifdef NL_TEMP_YUBO_NO_SOUND_SHEET_ID
if ( a_NoSoundSheetId & & _Id . IdInfos . Type = = ( ( 1 < < ( NL_SHEET_ID_TYPE_BITS ) ) - 1 ) )
{
return _DevSheetIdToName [ 0 ] [ _Id . IdInfos . Id ] ;
}
# endif
// This nlwarning is commented out because the loggers are mutexed, therefore
// This nlwarning is commented out because the loggers are mutexed, therefore
// you couldn't use toString() within a nlwarning().
// you couldn't use toString() within a nlwarning().
//nlwarning("<CSheetId::toString> The sheet %08x is not in sheet_id.bin",_Id.Id);
//nlwarning("<CSheetId::toString> The sheet %08x is not in sheet_id.bin",_Id.Id);
@ -432,6 +535,8 @@ string CSheetId::toString(bool ifNotFoundUseNumericId) const
void CSheetId : : serial ( NLMISC : : IStream & f ) throw ( NLMISC : : EStream )
void CSheetId : : serial ( NLMISC : : IStream & f ) throw ( NLMISC : : EStream )
{
{
nlassert ( ! _DontHaveSheetKnowledge ) ;
f . serial ( _Id . Id ) ;
f . serial ( _Id . Id ) ;
# ifdef NL_DEBUG_SHEET_ID
# ifdef NL_DEBUG_SHEET_ID
@ -443,6 +548,24 @@ void CSheetId::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
# endif
# endif
}
}
void CSheetId : : serialString ( NLMISC : : IStream & f , const std : : string & defaultType ) throw ( NLMISC : : EStream )
{
nlassert ( _Initialised ) ;
if ( f . isReading ( ) )
{
std : : string sheetName ;
f . serial ( sheetName ) ;
* this = CSheetId ( sheetName , defaultType ) ;
}
else
{
// if this assert fails, you may be using an outdated id bin
nlassert ( * this ! = CSheetId : : Unknown ) ;
std : : string sheetName = toString ( ) ;
f . serial ( sheetName ) ;
}
}
//-----------------------------------------------
//-----------------------------------------------