Cleanup CGameItemPtr, add reference count to avoid glitches, kaetemi/ryzomclassic#194

ryzomclassic-develop
kaetemi 4 years ago
parent 66debd7ebe
commit 9eb7481c06

@ -256,16 +256,12 @@ private:
void keepTheThreeBestResistance( const CCraftParameters& p ); void keepTheThreeBestResistance( const CCraftParameters& p );
}; };
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// advance declaration of classes with circular references // advance declaration of classes with circular references
class CGameItem; class CGameItem;
class CGameItemEntry;
//class CGameItemManager; //class CGameItemManager;
/** /**
* CGameItemVector * CGameItemVector
* *
@ -278,7 +274,7 @@ class CGameItemVector
{ {
public: public:
uint32 size() const; uint32 size() const;
CGameItem& operator[](uint32 idx); CGameItemEntry& operator[](uint32 idx);
void extend(); void extend();
uint32 getUniqueIndex(const CGameItem& item); uint32 getUniqueIndex(const CGameItem& item);
virtual ~CGameItemVector(); virtual ~CGameItemVector();
@ -289,45 +285,9 @@ private:
CGameItemVector(); CGameItemVector();
private: private:
std::vector< CGameItem* > _Data; std::vector<CGameItemEntry *> m_Data;
};
#ifdef GAME_PTR_DEBUG
class CGameItemPtrArray
{
public:
CGameItemPtrArray()
{
}
CGameItemPtrArray(const CGameItemPtrArray&)
{
// do nothing
}
CGameItemPtrArray &operator=(const CGameItemPtrArray &)
{
// do nothing
}
#ifdef NL_CPP14
CGameItemPtrArray(CGameItemPtrArray &&)
{
// do nothing
}
CGameItemPtrArray &operator=(CGameItemPtrArray &&) noexcept
{
// do nothing
}
#endif
protected:
/// keep pointers pointing this item
std::vector<CGameItemPtr*> _Ptrs;
}; };
#endif
/** /**
* CGameItem * CGameItem
@ -336,17 +296,18 @@ protected:
* \author Nevrax France * \author Nevrax France
* \date 2002 * \date 2002
*/ */
class CGameItem class CGameItem
#ifdef GAME_PTR_DEBUG
: public CGameItemPtrArray
#endif
{ {
#if 0
NLMISC_COMMAND_FRIEND(testParanoidItemSystem); NLMISC_COMMAND_FRIEND(testParanoidItemSystem);
#endif
friend class CInventoryBase; friend class CInventoryBase;
friend class CRefInventory; friend class CRefInventory;
#if 0
NL_INSTANCE_COUNTER_DECL(CGameItem); NL_INSTANCE_COUNTER_DECL(CGameItem);
#endif
public: public:
/// returns true if the two param items are stackable /// returns true if the two param items are stackable
@ -752,10 +713,10 @@ protected:
/// The inventory that contains this item (NULL if none) /// The inventory that contains this item (NULL if none)
CInventoryPtr _Inventory; CInventoryPtr _Inventory;
/// The slot inside the inventory
uint32 _InventorySlot;
/// The inventory that reference this item (NULL if none) /// The inventory that reference this item (NULL if none)
CInventoryPtr _RefInventory; CInventoryPtr _RefInventory;
/// The slot inside the inventory
uint32 _InventorySlot;
/// The slot inside the reference inventory /// The slot inside the reference inventory
uint32 _RefInventorySlot; uint32 _RefInventorySlot;
@ -773,20 +734,12 @@ private:
static CGameItemVector _Items; static CGameItemVector _Items;
static uint32 _FirstFreeItem; static uint32 _FirstFreeItem;
#ifdef ITEM_DEBUG
static sint32 _NextAllocatorDataValue;
#endif
//--------------------------------------------------------------------
// instance data for singleton's allocator algorithms
sint32 _AllocatorData;
private: private:
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// singleton interface used by the CGameItemPtr class // singleton interface used by the CGameItemPtr class
// make CGameItemPtr a friend to give it decent access // make CGameItemPtr a friend to give it decent access
friend class CGameItemEntry;
friend class CGameItemPtr; friend class CGameItemPtr;
friend class CInventoryProxy; friend class CInventoryProxy;
friend class COldGuildInventoryLoader; friend class COldGuildInventoryLoader;
@ -807,32 +760,10 @@ private:
// return the CWeaponCraftParameters variable corresponding to protection type // return the CWeaponCraftParameters variable corresponding to protection type
float getMagicProtectionCraftParateters( PROTECTION_TYPE::TProtectionType protection ) const; float getMagicProtectionCraftParateters( PROTECTION_TYPE::TProtectionType protection ) const;
private:
#if 0
// singleton counter
static uint32 _BugTestCounter;
// instance debug data
uint32 _BugTestChecksum;
uint32 _BugTestUpdate;
#endif
public: public:
#if 0
// run through the items looking for bugs
static void testItemsForBugs();
// static void testPlayerInventoryForBugs(const std::vector<CGameItemPtr>& inventory);
#endif
static std::string showItemsStats(); static std::string showItemsStats();
#if 0 private :
// check a single item for bugs...
void checkItemForBugs();
#endif
public: // I've had to make these public for now 'cos I can't work out how to make the vector class a friend :o(
//private :
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// ctors and dtors are now private for better control over allocation etc // ctors and dtors are now private for better control over allocation etc
@ -877,7 +808,7 @@ private:
/** /**
* pseudo Destructor * pseudo Destructor
*/ */
void dtor(); //void dtor();
/// Copy all the item info and parameters from model into this /// Copy all the item info and parameters from model into this
// void copyItem(const CGameItemPtr &model); // void copyItem(const CGameItemPtr &model);
@ -921,22 +852,16 @@ public:
private: private:
/// Item unique id /// Item unique id
INVENTORIES::TItemId _ItemId; INVENTORIES::TItemId _ItemId;
/// Item stack size
uint32 _StackSize;
// true if the item is on the ground
// bool _IsOnTheGround;
/// item id /// item id
// NLMISC::CEntityId _ItemId; // NLMISC::CEntityId _ItemId;
/// looter id of the character currently looting this item (for items on the ground only) /// looter id of the character currently looting this item (for items on the ground only)
NLMISC::CEntityId _Looter; NLMISC::CEntityId _Looter;
/// sheet ref /// sheet ref
NLMISC::CSheetId _SheetId; NLMISC::CSheetId _SheetId;
/// Item stack size
uint32 _StackSize;
/// carrion sheet ref /// carrion sheet ref
// uint32 _CarrionSheetId; // uint32 _CarrionSheetId;
/// true if the object is destroyable
bool _Destroyable;
/// true if the object is dropable
bool _Dropable;
/// children /// children
// std::vector<CGameItemPtr> _Children; // std::vector<CGameItemPtr> _Children;
/// pointer on the parent item (NULL if no parent) /// pointer on the parent item (NULL if no parent)
@ -954,52 +879,64 @@ private:
/// current sap load /// current sap load
uint32 _SapLoad; uint32 _SapLoad;
/// all craft parameters /// all craft parameters
NLMISC::CDeepPtr<CItemCraftParameters> _CraftParameters; NLMISC::CDeepPtr<CItemCraftParameters> _CraftParameters;
/// entityId of the character who has created the Item via faber (if applicable, for item not created by playres, Creator = CEntityId::Unknown) /// entityId of the character who has created the Item via faber (if applicable, for item not created by playres, Creator = CEntityId::Unknown)
NLMISC::CEntityId _CreatorId; NLMISC::CEntityId _CreatorId;
/// number of item locked
uint32 _LockCount;
/// Position in the client inventory interface if item is owned by a player (sint16 juste because we need an "invalid" position (-1) for version compatibility) /// Position in the client inventory interface if item is owned by a player (sint16 juste because we need an "invalid" position (-1) for version compatibility)
// TODO : a virer
sint16 _ClientInventoryPosition;
/// Vector of CSheetId used for craft this item /// Vector of CSheetId used for craft this item
// std::vector< NLMISC::CSheetId > _RmUsedForCraft; // std::vector< NLMISC::CSheetId > _RmUsedForCraft;
/// vector of sheetId of CStaticBrick define spell of enchanted item /// vector of sheetId of CStaticBrick define spell of enchanted item
std::vector< NLMISC::CSheetId > _Enchantment; std::vector< NLMISC::CSheetId > _Enchantment;
/// pointer on the associated static form /// pointer on the associated static form
const CStaticItem* _Form; const CStaticItem* _Form;
/// string associated with this item /// string associated with this item
NLMISC::CDeepPtr<std::string> _PhraseId; NLMISC::CDeepPtr<std::string> _PhraseId;
/// skill modifiers against given ennemy types
std::vector<CTypeSkillMod> _TypeSkillMods;
NLMISC::CDeepPtr<std::string> _CustomText;
#ifdef RYZOM_FORGE_PET_NAME
// FIXME: Reuse _PhraseId string and add a m_Literal flag
ucstring _CustomName;
#endif
/// tick when the proc will be available again /// tick when the proc will be available again
NLMISC::TGameCycle _LatencyEndDate; NLMISC::TGameCycle _LatencyEndDate;
/// image of the item in bag / equipment /// image of the item in bag / equipment
// uint16 _SlotImage; // uint16 _SlotImage;
NLMISC::TGameCycle _TotalSaleCycle; NLMISC::TGameCycle _TotalSaleCycle;
/// number of item locked
uint32 _LockCount;
// required skill // required skill
bool _UseNewSystemRequirement;
SKILLS::ESkills _RequiredSkill; SKILLS::ESkills _RequiredSkill;
uint16 _RequiredSkillLevel;
SKILLS::ESkills _RequiredSkill2; SKILLS::ESkills _RequiredSkill2;
CHARACTERISTICS::TCharacteristics _RequiredCharac;
uint16 _RequiredSkillLevel;
uint16 _RequiredSkillLevel2; uint16 _RequiredSkillLevel2;
/// min required stat level and required stat /// min required stat level and required stat
CHARACTERISTICS::TCharacteristics _RequiredCharac;
uint16 _RequiredCharacLevel; uint16 _RequiredCharacLevel;
/// whether the item has any skill requirements /// whether the item has any skill requirements
bool _HasPrerequisit; bool _HasPrerequisit;
/// skill modifiers against given ennemy types bool _UseNewSystemRequirement;
std::vector<CTypeSkillMod> _TypeSkillMods;
NLMISC::CDeepPtr<std::string> _CustomText;
bool _LockedByOwner; bool _LockedByOwner;
bool _UnMovable; bool _UnMovable;
bool _Movable; bool _Movable;
uint8 _PetIndex; uint8 _PetIndex;
#ifdef RYZOM_FORGE_PET_NAME
ucstring _CustomName; /// true if the object is destroyable
#endif bool _Destroyable;
/// true if the object is dropable
bool _Dropable;
// true if the item is on the ground
// bool _IsOnTheGround;
}; };
/** /**
@ -1029,110 +966,128 @@ private:
#define QUANTUM (1<<LOG_QUANTUM) #define QUANTUM (1<<LOG_QUANTUM)
#define QUANTUM_MASK (QUANTUM-1) #define QUANTUM_MASK (QUANTUM-1)
class CGameItemEntry : public CGameItem
{
public:
CGameItemEntry()
{
PtrRefCount = 0;
}
~CGameItemEntry()
{
}
uint32 AllocatorNext;
uint32 VectorIdx;
sint PtrRefCount;
};
inline CGameItemVector::CGameItemVector() inline CGameItemVector::CGameItemVector()
{ {
} }
inline CGameItemVector::~CGameItemVector() inline CGameItemVector::~CGameItemVector()
{ {
for (uint32 i=0;i<_Data.size();++i) for (uint32 i = 0; i < m_Data.size(); ++i)
delete [] _Data[i]; delete[] m_Data[i];
} }
inline uint32 CGameItemVector::size() const inline uint32 CGameItemVector::size() const
{ {
return (uint32)_Data.size()<<LOG_QUANTUM; return (uint32)m_Data.size() << LOG_QUANTUM;
} }
inline CGameItem& CGameItemVector::operator[](uint32 idx) inline CGameItemEntry &CGameItemVector::operator[](uint32 idx)
{ {
return _Data[idx>>LOG_QUANTUM][idx&QUANTUM_MASK]; return m_Data[idx >> LOG_QUANTUM][idx & QUANTUM_MASK];
} }
inline void CGameItemVector::extend() inline void CGameItemVector::extend()
{ {
_Data.push_back(new CGameItem[QUANTUM]); uint32 baseIdx = size();
nlassert(_Data.back()!=NULL); CGameItemEntry *items = new CGameItemEntry[QUANTUM];
for (uint32 i=0;i<QUANTUM;++i) nlassert(items);
_Data.back()[i]._AllocatorData=size()-QUANTUM+i+1; m_Data.push_back(items);
egs_giinfo("Increased item vector size to %u items (%u bytes)",size(),size()*sizeof(CGameItem)); for (uint32 i = 0; i < QUANTUM; ++i)
{
items[i].AllocatorNext = baseIdx + i + 1;
items[i].VectorIdx = baseIdx + i;
}
egs_giinfo("Increased item vector size to %u items (%u bytes)", size(), size() * sizeof(CGameItem));
} }
inline uint32 CGameItemVector::getUniqueIndex(const CGameItem& item) inline uint32 CGameItemVector::getUniqueIndex(const CGameItem& item)
{ {
for (uint32 i=0;i<_Data.size();++i) return static_cast<const CGameItemEntry &>(item).VectorIdx;
{
uint32 lowidx= (uint32)(&item-_Data[i]);
if (lowidx<QUANTUM)
{
uint32 idx= lowidx+(i<<LOG_QUANTUM);
#ifdef ITEM_DEBUG
BOMB_IF(&(_Data[i][lowidx])!=&item, NLMISC::toString("Invalid item pointer (1): %p",&item), return ~0u );
BOMB_IF(&((*this)[idx])!=&item, NLMISC::toString("Code bug or Invalid item pointer (2): %p",&item), return ~0u );
#endif
return idx;
}
}
STOP(NLMISC::toString("invalid item pointer (3): %p",&item));
return ~0u;
} }
#undef LOG_QUANTUM #undef LOG_QUANTUM
#undef QUANTUM #undef QUANTUM
#undef QUANTUM_MASK #undef QUANTUM_MASK
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// ptr class added by sadge // ptr class added by sadge
// inline implementations // inline implementations
// ctor - default // link ptr to game item
inline CGameItemPtr::CGameItemPtr() inline void CGameItemPtr::incRef()
{ {
reset(); if (!m_Idx)
return;
++CGameItem::_Items[m_Idx].PtrRefCount;
} }
inline void CGameItemPtr::reset() // unlink ptr from item
inline void CGameItemPtr::decRef()
{ {
_idx = ~0u; // cannot unlink a pointer pointing on nothing
if (!m_Idx)
return;
#ifdef ITEM_DEBUG CGameItemEntry *entry = &CGameItem::_Items[m_Idx];
_debugPtr= NULL; sint count = --CGameItem::_Items[m_Idx].PtrRefCount;
_debug=0; if (!count)
#endif {
CGameItem::deleteItem(static_cast<CGameItem *>(entry));
}
nlassert(count >= 0);
}
// ctor - default
inline CGameItemPtr::CGameItemPtr() : m_Idx(0)
{
} }
// ctor - copy // ctor - copy
inline CGameItemPtr::CGameItemPtr(const CGameItemPtr &other) inline CGameItemPtr::CGameItemPtr(const CGameItemPtr &other) : m_Idx(other.m_Idx)
{ {
reset(); incRef();
*this=other;
} }
// ctor - initialise from a CGameItem* // ctor - initialise from a CGameItem*
inline CGameItemPtr::CGameItemPtr(const CGameItem *item) inline CGameItemPtr::CGameItemPtr(const CGameItem *item) : m_Idx(static_cast<const CGameItemEntry *>(item)->VectorIdx)
{ {
reset(); incRef();
*this=item;
} }
// dtor // dtor
inline CGameItemPtr::~CGameItemPtr() inline CGameItemPtr::~CGameItemPtr()
{ {
unlinkFromItem(); decRef();
} }
// equivalent to: new CGameItem // equivalent to: new CGameItem
inline CGameItem *CGameItemPtr::newItem(bool destroyable,bool dropable) inline CGameItem *CGameItemPtr::newItem(bool destroyable,bool dropable)
{ {
CGameItem *item=CGameItem::newItem(); CGameItem *item = CGameItem::newItem();
item->ctor(); item->ctor();
item->_Destroyable=destroyable; item->_Destroyable=destroyable;
item->_Dropable = dropable; item->_Dropable = dropable;
*this=item; *this=item;
#if 0
item->_BugTestUpdate=CGameItem::_BugTestCounter;
#endif
return item; return item;
} }
@ -1153,93 +1108,17 @@ inline CGameItem *CGameItemPtr::newItem( const NLMISC::CSheetId& sheetId, uint32
// item->ctor(id,sheetId,recommended,slotCount,destroyable,dropable); // item->ctor(id,sheetId,recommended,slotCount,destroyable,dropable);
item->ctor(sheetId, recommended, destroyable, dropable); item->ctor(sheetId, recommended, destroyable, dropable);
*this=item; *this=item;
#if 0
item->_BugTestUpdate = CGameItem::_BugTestCounter;
#endif
return item; return item;
} }
// equivalent to: delete (for a CGameItem*)
//inline void CGameItemPtr::deleteItem()
//{
// CGameItem *item=**this;
//
// BOMB_IF( item == NULL, "Attempt to delete an item that is not allocated or has been freed", return );
//
// // only unlink if the pointer 'this' is not the same as the inventory ptr for the item
// // after the unlink this == NULL
// if (! ( item->_Parent!=NULL &&
// item->Loc.Slot<item->_Parent->getChildren().size() &&
// &(item->_Parent->getChildren()[item->Loc.Slot])==this ) )
// unlinkFromItem();
//
// // call dtor now to unlink all children
// item->dtor();
// // check no one else is referencing us
// nlassert(item->_Ptrs.empty());
//
// CGameItem::deleteItem(item);
// item->_BugTestUpdate=CGameItem::_BugTestCounter;
//}
// link ptr to game item
inline void CGameItemPtr::linkToItem()
{
#ifdef GAME_PTR_DEBUG
if (_idx == ~0u)
return;
CGameItem *item=**this;
for (uint i = 0 ; i < item->_Ptrs.size() ; ++i)
{
nlassert(item->_Ptrs[i] != this);
}
item->_Ptrs.push_back(this);
#endif
}
// unlink ptr from item
inline void CGameItemPtr::unlinkFromItem()
{
// cannot unlink a pointer pointing on nothing
if (_idx == ~0u)
return;
#ifdef GAME_PTR_DEBUG
CGameItem *item=**this;
uint j=~0u;
for (uint i = 0 ; i < item->_Ptrs.size() ; ++i)
{
if (item->_Ptrs[i] == this)
{
nlassert(j==~0u);
j=i;
}
}
nlassert(j!=~0u);
item->_Ptrs.erase(item->_Ptrs.begin()+j);
#endif
// set the GameItemPtr to NULL
reset();
}
// = operator - for copying another CGameItemPtr // = operator - for copying another CGameItemPtr
inline const CGameItemPtr &CGameItemPtr::operator=(const CGameItemPtr &other) inline const CGameItemPtr &CGameItemPtr::operator=(const CGameItemPtr &other)
{ {
unlinkFromItem(); decRef();
_idx=other._idx; m_Idx = other.m_Idx;
#ifdef ITEM_DEBUG
_debug=other._debug;
_debugPtr=other._debugPtr;
#endif
linkToItem(); incRef();
return *this; return *this;
} }
@ -1247,135 +1126,76 @@ inline const CGameItemPtr &CGameItemPtr::operator=(const CGameItemPtr &other)
// = operator - for assignment of CGameItemPtr directly to a CGameItem // = operator - for assignment of CGameItemPtr directly to a CGameItem
inline const CGameItemPtr &CGameItemPtr::operator=(const CGameItem *item) inline const CGameItemPtr &CGameItemPtr::operator=(const CGameItem *item)
{ {
unlinkFromItem(); decRef();
if (item==NULL) if (!item)
_idx=~0u;
else
{ {
_idx=CGameItem::_Items.getUniqueIndex(*item); m_Idx = 0;
// this test would only have value if the implementation of std::vector<> doesn't guarantee a
// continuous memory address space for the vector's data
// It's not in the #IFDEF DEBUG because it may only be triggered in very obscure conditions
if (CGameItem::getItem(_idx)!=item)
{
nlwarning("**** BIG BAD NASTY BUG - BEGINS ****");
nlwarning("item: %p",item);
nlwarning("_idx: %i",_idx);
nlwarning("**** BIG BAD NASTY BUG - ENDS ****");
}
// nlassert(&CGameItem::getItem(_idx)==item);
} }
else
{
m_Idx = static_cast<const CGameItemEntry *>(item)->VectorIdx;
nlassert(CGameItem::getItem(m_Idx) == item);
#ifdef ITEM_DEBUG incRef();
_debugPtr= (CGameItem *)item; }
if (item==NULL)
_debug=0;
else
{
CGameItem * item = CGameItem::getItem(_idx);
if( item )
_debug=item->_AllocatorData;
}
#endif
linkToItem();
return *this; return *this;
} }
// * operator - returning the item referenced by this pointer // * operator - returning the item referenced by this pointer
inline CGameItem * CGameItemPtr::operator*() const inline CGameItem *CGameItemPtr::operator*() const
{ {
if (_idx == ~0u) CGameItemEntry *entry = static_cast<CGameItemEntry *>(CGameItem::getItem(m_Idx));
return NULL; BOMB_IF(!entry->VectorIdx, "Attempting to access an item an item that is not allocated or has been freed", return 0);
return static_cast<CGameItem *>(entry);
CGameItem* item= CGameItem::getItem(_idx);
#ifdef ITEM_DEBUG
BOMB_IF( CGameItem::getItem(_idx) !=_debugPtr, "CGameItemPtr do not reference the good item", return 0 );
BOMB_IF( _idx == ~0u, "Attempting to derefence a NULL pointer", return 0 );
if( item )
BOMB_IF( _debug!=CGameItem::getItem(_idx)->_AllocatorData, "Attempting to access an item that has been re-allocated", return 0 );
#endif
BOMB_IF(item==0, "Attempting to access an item an item that is not allocated or has been freed", return 0);
#if 0
item->_BugTestUpdate=CGameItem::_BugTestCounter;
#endif
return item;
} }
// -> operator - returning the item referenced by this pointer // -> operator - returning the item referenced by this pointer
inline CGameItem *CGameItemPtr::operator->() const inline CGameItem *CGameItemPtr::operator->() const
{ {
if (_idx == ~0u) // this is crash-safe even when m_Idx is wrong, it'll return item 0
return NULL; return CGameItem::getItem(m_Idx);
CGameItem* item= CGameItem::getItem(_idx);
#ifdef ITEM_DEBUG
BOMB_IF( CGameItem::getItem(_idx) !=_debugPtr, "CGameItemPtr do not reference the good item", return 0 );
BOMB_IF( _idx == ~0u, "Attempting to derefence a NULL pointer", return 0 );
if( item )
BOMB_IF( _debug!=CGameItem::getItem(_idx)->_AllocatorData, "Attempting to access an item that has been re-allocated", return 0 );
#endif
BOMB_IF(item==0, "Attempting to access an item an item that is not allocated or has been freed", return 0);
#if 0
item->_BugTestUpdate=CGameItem::_BugTestCounter;
#endif
return item;
} }
// () operator - returning the item referenced by this pointer // () operator - returning the item referenced by this pointer
inline CGameItem *CGameItemPtr::operator()() const inline CGameItem *CGameItemPtr::operator()() const
{ {
return operator->(); CGameItemEntry *entry = static_cast<CGameItemEntry *>(CGameItem::getItem(m_Idx));
BOMB_IF(!entry->VectorIdx, "Attempting to access an item an item that is not allocated or has been freed", return 0);
return static_cast<CGameItem *>(entry);
} }
// == operator - compare 2 CGameItemPtrs // == operator - compare 2 CGameItemPtrs
inline bool CGameItemPtr::operator==(const CGameItemPtr &other) const inline bool CGameItemPtr::operator==(const CGameItemPtr &other) const
{ {
#ifdef ITEM_DEBUG return (m_Idx == other.m_Idx);
//nlassert(CGameItem::getItem(_idx)==_debugPtr);
if(_idx==other._idx)
nlassert(_debug==other._debug);
#endif
return (_idx==other._idx);
} }
// == operator - compare CGameItemPtrs to CGameItem* // == operator - compare CGameItemPtrs to CGameItem*
inline bool CGameItemPtr::operator==(const CGameItem *item) const inline bool CGameItemPtr::operator==(const CGameItem *item) const
{ {
if (item==NULL) if (!item)
return operator*()==NULL; return m_Idx == 0;
return *this==CGameItemPtr(item); return CGameItem::getItem(m_Idx) == item;
} }
// != operator - compare 2 CGameItemPtrs // != operator - compare 2 CGameItemPtrs
inline bool CGameItemPtr::operator!=(const CGameItemPtr &other) const inline bool CGameItemPtr::operator!=(const CGameItemPtr &other) const
{ {
return !(*this==other); return !(*this == other);
} }
// != operator - compare CGameItemPtrs to CGameItem* // != operator - compare CGameItemPtrs to CGameItem*
inline bool CGameItemPtr::operator!=(const CGameItem *item) const inline bool CGameItemPtr::operator!=(const CGameItem *item) const
{ {
if (item==NULL) return !(*this == item);
return operator*()!=NULL;
return !(*this==item);
} }
inline bool CGameItemPtr::operator < (const CGameItemPtr &other) const inline bool CGameItemPtr::operator < (const CGameItemPtr &other) const
{ {
return _idx < other._idx; return m_Idx < other.m_Idx;
} }
#endif // GAME_ITEM_H #endif // GAME_ITEM_H

@ -54,7 +54,7 @@ public:
void deleteItem(); void deleteItem();
// * operator - returning the item referenced by this pointer // * operator - returning the item referenced by this pointer
CGameItem * operator*() const; CGameItem *operator*() const;
// -> operator - returning the item referenced by this pointer // -> operator - returning the item referenced by this pointer
CGameItem *operator->() const; CGameItem *operator->() const;
@ -74,27 +74,23 @@ public:
bool operator==(const CGameItem *item) const; bool operator==(const CGameItem *item) const;
bool operator!=(const CGameItem *item) const; bool operator!=(const CGameItem *item) const;
uint32 getUniqueIndex() { return _idx; } uint32 getUniqueIndex() { return m_Idx; }
// For set and map // For set and map
bool operator < (const CGameItemPtr &other) const; bool operator < (const CGameItemPtr &other) const;
// operator bool() { return m_Idx; }
// bool operator!() { return !m_Idx; }
private: private:
// link to item // link to item
void linkToItem(); void incRef();
// unlink from item // unlink from item
void unlinkFromItem(); void decRef();
// init
void reset();
// index into the CGameItem singleton's _Items vector // index into the CGameItem singleton's _Items vector
uint32 _idx; uint32 m_Idx;
#ifdef ITEM_DEBUG
// used for making sure that referenced items haven't been freed or reallocated
// contains a copy of a CGameItem's allocation index (which changes at every alloaction and free)
sint32 _debug;
CGameItem* _debugPtr;
#endif
}; };

Loading…
Cancel
Save