Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
206 lines
3.9 KiB
C++
206 lines
3.9 KiB
C++
// NameManager.cpp: implementation of the NameManager class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "mw4gameed2.h"
|
|
#include "NameManager.h"
|
|
|
|
#define NAMEARRAYSTARTSIZE 32
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
NameManager *NameManager::Instance;
|
|
|
|
NameManager::NameManager()
|
|
{
|
|
ArraySize=0;
|
|
NameArray=NULL;
|
|
StringCount=0;
|
|
Reset();
|
|
}
|
|
|
|
void NameManager::Delete()
|
|
{
|
|
for(int i=0;i<StringCount;i++)
|
|
{
|
|
delete NameArray[i];
|
|
}
|
|
|
|
delete NameArray;
|
|
NameArray=NULL;
|
|
}
|
|
|
|
|
|
void NameManager::Reset()
|
|
{
|
|
Delete();
|
|
ArraySize=NAMEARRAYSTARTSIZE;
|
|
NameArray=new CString *[ArraySize];
|
|
for(int i=0;i<ArraySize;i++) NameArray[i]=NULL;
|
|
StringCount=0;
|
|
}
|
|
|
|
void NameManager::GrowArray()
|
|
{
|
|
CString **new_array=new CString *[ArraySize*2];
|
|
int i;
|
|
for(i=0;i<ArraySize;i++) new_array[i]=NameArray[i];
|
|
for(i=ArraySize;i<ArraySize*2;i++) new_array[i]=NULL;
|
|
ArraySize*=2;
|
|
delete NameArray;
|
|
NameArray=new_array;
|
|
}
|
|
|
|
void NameManager::AddString(const CString &str)
|
|
{
|
|
ASSERT(str.CompareNoCase(""));
|
|
if( StringCount>=(ArraySize-1)) GrowArray();
|
|
ASSERT(NameArray[StringCount+1]==NULL);
|
|
int pos;
|
|
bool fnd;
|
|
fnd=FindString(str,&pos);
|
|
ASSERT(fnd==false && pos<=StringCount && pos>=0);
|
|
for(int i=StringCount;i>pos;i--) NameArray[i]=NameArray[i-1];
|
|
NameArray[pos]=new CString(str);
|
|
StringCount++;
|
|
}
|
|
|
|
bool NameManager::IsUnique(const CString &str)
|
|
{
|
|
int pos;
|
|
return !FindString(str,&pos);
|
|
}
|
|
|
|
bool NameManager::FindString(const CString &str,int *pos)
|
|
{
|
|
int low,high,mid=0;
|
|
low=0;
|
|
high=StringCount-1;
|
|
int diff;
|
|
|
|
while((high-low)>1)
|
|
{
|
|
mid=low+((high-low)/2);
|
|
ASSERT(NameArray[mid]!=NULL);
|
|
diff=NumStrCompare(*NameArray[mid],str);
|
|
if(diff<0)
|
|
{
|
|
low=mid;
|
|
}
|
|
else
|
|
if(diff>0)
|
|
{
|
|
high=mid;
|
|
}
|
|
else
|
|
{
|
|
*pos=mid;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if((high-low)==1)
|
|
{
|
|
diff=NumStrCompare(*NameArray[low],str);
|
|
if(diff==0) {*pos=low; return true;}
|
|
if(diff>0) {*pos=low; return false;}
|
|
diff=NumStrCompare(*NameArray[high],str);
|
|
if(diff==0) {*pos=high; return true;}
|
|
if(diff<0) *pos=high+1; else *pos=high;
|
|
return false;
|
|
|
|
}
|
|
|
|
*pos=mid;
|
|
return false;
|
|
}
|
|
|
|
void NameManager::RemoveString(int idx)
|
|
{
|
|
ASSERT(idx<StringCount);
|
|
ASSERT(StringCount<ArraySize);
|
|
ASSERT(idx>=0);
|
|
|
|
ASSERT(NameArray[idx]!=NULL);
|
|
delete NameArray[idx];
|
|
StringCount--;
|
|
for(int i=idx;i<StringCount;i++) NameArray[i]=NameArray[i+1];
|
|
NameArray[StringCount]=NULL;
|
|
}
|
|
|
|
int NameManager::Separate(const CString &newname,CString *basename)
|
|
{
|
|
int sidx;
|
|
for(sidx=newname.GetLength()-1;sidx>=0 && isdigit(newname[sidx]);sidx--);
|
|
|
|
if(sidx>=0 && newname[sidx]=='_')
|
|
{
|
|
*basename=newname.Left(sidx);
|
|
return atoi((LPCSTR)newname.Mid(sidx+1));
|
|
}
|
|
else
|
|
{
|
|
*basename=newname;
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
|
|
CString NameManager::MakeUnique(CString newname)
|
|
{
|
|
int pos;
|
|
if(FindString(newname,&pos))
|
|
{
|
|
CString basename,newbase;
|
|
Separate(newname,&basename);
|
|
|
|
int icr=999999;
|
|
do
|
|
{
|
|
newname.Format("%s_%04i",basename,icr);
|
|
icr*=2;
|
|
}
|
|
while(FindString(newname,&pos));
|
|
|
|
ASSERT(pos!=0);
|
|
|
|
icr=Separate(*NameArray[pos-1],&newbase);
|
|
ASSERT(!basename.CompareNoCase(newbase));
|
|
|
|
newname.Format("%s_%04i",basename,icr+1);
|
|
}
|
|
AddString(newname);
|
|
return newname;
|
|
}
|
|
|
|
int NameManager::NumStrCompare(const CString &str1,const CString &str2)
|
|
{
|
|
CString str1_base,str2_base;
|
|
int str1_num,str2_num;
|
|
|
|
|
|
str1_num=Separate(str1,&str1_base);
|
|
str2_num=Separate(str2,&str2_base);
|
|
|
|
int diff=str1_base.CompareNoCase(str2_base);
|
|
|
|
if(diff==0)
|
|
{
|
|
if(str1_num==str2_num)
|
|
{ // This fixes 01 and 001 case
|
|
return str1.GetLength()-str2.GetLength();
|
|
}
|
|
return str1_num-str2_num;
|
|
}
|
|
else return diff;
|
|
|
|
}
|
|
|
|
|
|
NameManager::~NameManager()
|
|
{
|
|
Delete();
|
|
}
|