270 lines
6.6 KiB
C++
270 lines
6.6 KiB
C++
#pragma once
|
||
|
||
/************************************************************************/
|
||
/*
|
||
/* 角色物品对象申请器
|
||
/*
|
||
/* 用于在角色获得物品的时候申请一个物品对象,销毁物品的时候释放一个物品对象。
|
||
/*
|
||
/************************************************************************/
|
||
|
||
//为了便于追踪物品的申请和是否
|
||
struct CItemData:
|
||
public CUserItem
|
||
{
|
||
bool btUsed; //是否在使用的标记
|
||
LPCSTR file; //申请的文件的位置
|
||
INT_PTR line; //申请的内存的行数
|
||
};
|
||
|
||
//物品来自
|
||
struct ItemLogInfo
|
||
{
|
||
LPCSTR file; //申请的文件的位置
|
||
INT_PTR line; //申请的物品的行数
|
||
INT_PTR nCount; //申请物品的数目
|
||
CUserItem* pItem;//申请的其中一个物品
|
||
};
|
||
|
||
class CUserItemAllocator :
|
||
public CSingleObjectAllocator<CItemData>
|
||
{
|
||
public:
|
||
typedef CSingleObjectAllocator<CItemData> Inherited;
|
||
|
||
public:
|
||
|
||
|
||
inline void CheckItemAllocThread(LPCSTR file, INT_PTR line )
|
||
{
|
||
UINT nCurThreadId= GetCurrentThreadId(); //当前的线程ID
|
||
if(m_itemAllocThreadId != 0)
|
||
{
|
||
if(m_itemAllocThreadId != nCurThreadId)
|
||
{
|
||
//在不同线程操作物品分配,可能引起不可预知的问题
|
||
OutputMsg(rmError,"[ItemTrace],AllocUserItem in different thread,old=[%d],curr=[%d],file=%s,line=%d",m_itemAllocThreadId,nCurThreadId,
|
||
file,line);
|
||
m_itemAllocThreadId = nCurThreadId;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
m_itemAllocThreadId = nCurThreadId;
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
* Comments: 增加物品的申请激励
|
||
* Param LPCSTR file: 文件名
|
||
* Param INT_PTR line: 行数
|
||
* @Return void:
|
||
*/
|
||
inline void AddItemLog( LPCSTR file, INT_PTR line, CUserItem* pItem)
|
||
{
|
||
for(INT_PTR i=0; i< m_itemLog.count() ;i++)
|
||
{
|
||
if(m_itemLog[i].file == file &&m_itemLog[i].line == line )
|
||
{
|
||
m_itemLog[i].nCount ++;
|
||
return;
|
||
}
|
||
}
|
||
ItemLogInfo log;
|
||
log.file= file;
|
||
log.line =line;
|
||
log.nCount =1;
|
||
log.pItem = pItem;
|
||
m_itemLog.add(log);
|
||
}
|
||
|
||
inline void DecItemLog( LPCSTR file, INT_PTR line)
|
||
{
|
||
for(INT_PTR i=0; i< m_itemLog.count() ;i++)
|
||
{
|
||
if(m_itemLog[i].file == file &&m_itemLog[i].line == line )
|
||
{
|
||
if(m_itemLog[i].nCount>0)
|
||
{
|
||
m_itemLog[i].nCount --;
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
OutputMsg(rmError,"DecItemLog not found,file=%s,line=%d",file,(int)line);
|
||
}
|
||
|
||
inline CUserItem::ItemSeries BuildMailSn()
|
||
{
|
||
CUserItem::ItemSeries series;
|
||
series.t.time = time(NULL);
|
||
series.t.btServer = (WORD)m_nServerIndex;
|
||
series.t.wSeries = (WORD)m_nMailSeries;
|
||
//单位时间内的系列号值递增
|
||
m_nMailSeries++;
|
||
return series;
|
||
}
|
||
|
||
inline CUserItem::ItemSeries BuildNeedBuySn()
|
||
{
|
||
CUserItem::ItemSeries series;
|
||
series.t.time = m_ItemTime;
|
||
series.t.btServer = (WORD)m_nServerIndex;
|
||
series.t.wSeries = (WORD)m_nNeedBuySeries;
|
||
// series.t.btSpid = (BYTE)(m_nSpId >0x7F? 0x7F:m_nSpId);
|
||
//单位时间内的系列号值递增
|
||
m_nNeedBuySeries++;
|
||
return series;
|
||
}
|
||
|
||
inline CUserItem* allocItem(const bool boNewSeries, LPCSTR file, INT_PTR line)
|
||
{
|
||
CheckItemAllocThread(file,line);
|
||
CItemData* pItem = allocObject();
|
||
|
||
if(pItem ==NULL)
|
||
{
|
||
OutputMsg(rmError,"alloc Item Fail");
|
||
return NULL;
|
||
}
|
||
if(pItem->btUsed)
|
||
{
|
||
OutputMsg(rmError,"[ItemTrace],allocItem item reused item,oldfile=%s,oldline=%d,itemId=%d,count=%d,curFile=%s,curLine=%d",
|
||
pItem->file?pItem->file:"" ,(int)pItem->line,(int)pItem->wItemId,(int)pItem->wCount,file,(int)line);
|
||
|
||
OutputMsg(rmTip,"realloc a new item");
|
||
return allocItem(boNewSeries,file,line);
|
||
}
|
||
|
||
if(boNewSeries)
|
||
{
|
||
memset(pItem, 0, sizeof(*pItem));
|
||
//产生物品系列号
|
||
pItem->series.t.time = m_ItemTime;
|
||
pItem->series.t.btServer = (BYTE)m_nServerIndex;
|
||
pItem->series.t.wSeries = (WORD)m_nItemSeries;
|
||
//单位时间内的系列号值递增
|
||
m_nItemSeries++;
|
||
}
|
||
pItem->file = file;
|
||
pItem->line =line;
|
||
pItem->btUsed =true;
|
||
m_nTotalAllocItemCount ++;
|
||
AddItemLog(file,line, (CUserItem*)pItem);
|
||
return (CUserItem*)pItem;
|
||
}
|
||
|
||
void DestroyUserItem(CUserItem *pUserItem, LPCSTR file, INT_PTR line)
|
||
{
|
||
CheckItemAllocThread(file,line);
|
||
CItemData *pUserData = (CItemData *)pUserItem;
|
||
if(pUserData->btUsed ==false)
|
||
{
|
||
OutputMsg(rmError,"[ItemTrace],DestroyUserItem item again,oldfile=%s,oldline=%d,itemId=%d,count=%d,curFile=%s,curLine=%d",
|
||
pUserData->file?pUserData->file:"" ,(int)pUserData->line,(int)pUserData->wItemId,(int)pUserData->wCount,file,(int)line);
|
||
return ;
|
||
}
|
||
pUserData->btUsed= false;
|
||
if(m_nTotalAllocItemCount >0)
|
||
{
|
||
m_nTotalAllocItemCount --;
|
||
}
|
||
DecItemLog(pUserData->file,pUserData->line);
|
||
freeObject(pUserData);
|
||
}
|
||
|
||
|
||
|
||
/* 更新物品系列号产生所必须的时间值
|
||
* 当时间值被更新后,序列值会原为1
|
||
* ★至少应当在1秒内更新一次时间值!
|
||
*/
|
||
inline VOID UpdateDateTime(const unsigned int time)
|
||
{
|
||
if ( time != m_ItemTime )
|
||
{
|
||
m_ItemTime = time;
|
||
m_nItemSeries = 1;
|
||
m_nMailSeries = 1;
|
||
m_nNeedBuySeries = 1;
|
||
}
|
||
}
|
||
//设置服务器ID,服务器ID将参与物品系列号的生成
|
||
inline VOID SetServerIndex(const INT_PTR nServerIndex)
|
||
{
|
||
m_nServerIndex = nServerIndex;
|
||
}
|
||
|
||
//设置运营商的ID
|
||
inline VOID SetSpid(const INT_PTR nSpid)
|
||
{
|
||
m_nSpId = nSpid;
|
||
}
|
||
|
||
//获取服务器ID
|
||
inline INT_PTR GetSpid()
|
||
{
|
||
return m_nSpId;
|
||
}
|
||
|
||
|
||
//获取服务器ID
|
||
inline INT_PTR GetServerIndex()
|
||
{
|
||
return m_nServerIndex;
|
||
}
|
||
|
||
CUserItemAllocator()
|
||
:Inherited(_T("CUserItemAllocator"))
|
||
, m_nSpId(0)
|
||
{
|
||
m_nServerIndex = 0;
|
||
UpdateDateTime(CMiniDateTime::now());
|
||
m_itemAllocThreadId =0;
|
||
m_nTotalAllocItemCount =0;
|
||
}
|
||
|
||
void TraceItem()
|
||
{
|
||
if(m_nTotalAllocItemCount >0)
|
||
{
|
||
OutputMsg(rmError,"Not free itemcount=%d",(int)m_nTotalAllocItemCount);
|
||
for(INT_PTR i=0; i< m_itemLog.count(); i++)
|
||
{
|
||
if(m_itemLog[i].nCount >0)
|
||
{
|
||
if(m_itemLog[i].pItem)
|
||
{
|
||
OutputMsg(rmError,"Item not free,file=%s,line=%d,count=%d,itemguid:%lld,itemid:%d",m_itemLog[i].file,(int)m_itemLog[i].line,(int)m_itemLog[i].nCount,m_itemLog[i].pItem->series,m_itemLog[i].pItem->wItemId);
|
||
}
|
||
else
|
||
{
|
||
OutputMsg(rmError,"Item not free,file=%s,line=%d,count=%d",m_itemLog[i].file,(int)m_itemLog[i].line,(int)m_itemLog[i].nCount);
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
~CUserItemAllocator()
|
||
{
|
||
TraceItem();
|
||
m_itemLog.empty();
|
||
}
|
||
|
||
protected:
|
||
CMiniDateTime m_ItemTime; //物品系列时间
|
||
INT_PTR m_nItemSeries; //物品系列值
|
||
INT_PTR m_nMailSeries; //邮件系列值
|
||
INT_PTR m_nNeedBuySeries; //求购单系列值
|
||
INT_PTR m_nServerIndex; //服务器ID
|
||
INT_PTR m_nSpId; //运营商的编号
|
||
UINT m_itemAllocThreadId; //线程的id
|
||
INT_PTR m_nTotalAllocItemCount; //总共申请的物品的数目
|
||
wylib::container::CBaseList<ItemLogInfo> m_itemLog;
|
||
|
||
};
|