forked from Mirrors/openclonk
202 lines
6.9 KiB
C++
202 lines
6.9 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 1998-2000, Matthes Bender
|
|
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
|
|
* Copyright (c) 2009-2013, The OpenClonk Team and contributors
|
|
*
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
* "COPYING" for details.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
* See accompanying file "TRADEMARK" for details.
|
|
*
|
|
* To redistribute this file separately, substitute the full license texts
|
|
* for the above references.
|
|
*/
|
|
|
|
/* Dynamic object list */
|
|
|
|
#ifndef INC_C4ObjectList
|
|
#define INC_C4ObjectList
|
|
|
|
#include <C4Id.h>
|
|
|
|
class C4ObjectLink
|
|
{
|
|
public:
|
|
C4Object *Obj;
|
|
C4ObjectLink *Prev,*Next;
|
|
};
|
|
|
|
class C4ObjectListChangeListener
|
|
{
|
|
public:
|
|
virtual void OnObjectRemove(C4ObjectList * pList, C4ObjectLink * pLnk) = 0;
|
|
virtual void OnObjectAdded(C4ObjectList * pList, C4ObjectLink * pLnk) = 0;
|
|
virtual void OnObjectRename(C4ObjectList * pList, C4ObjectLink * pLnk) = 0;
|
|
virtual ~C4ObjectListChangeListener() { }
|
|
};
|
|
|
|
extern C4ObjectListChangeListener & ObjectListChangeListener;
|
|
|
|
class C4ObjectList
|
|
{
|
|
public:
|
|
C4ObjectList();
|
|
C4ObjectList(const C4ObjectList &List);
|
|
virtual ~C4ObjectList();
|
|
|
|
C4ObjectLink *First, *Last;
|
|
int Mass;
|
|
std::list<int32_t> *pEnumerated;
|
|
|
|
enum SortType { stNone=0, stMain, stContents, stReverse };
|
|
|
|
// An iterator which survives if an object is removed from the list
|
|
class iterator
|
|
{
|
|
public:
|
|
~iterator();
|
|
iterator& operator++ (); // prefix ++
|
|
iterator operator++ (int); // postfix ++
|
|
iterator(const iterator & iter);
|
|
C4Object * operator* ();
|
|
bool operator== (const iterator & iter) const;
|
|
bool operator!= (const iterator & iter) const;
|
|
// advance until end reached or link with target Obj found - return false in former case, true in latter
|
|
bool find(C4Object* target);
|
|
// return whether the iterator has reached the end
|
|
bool atEnd() const;
|
|
// advance the iterator position, either going forward or backward depending on the reverse flag
|
|
bool advance();
|
|
// reset the iterator to either the beginning or the end of the list, depending on the reverse flag
|
|
bool reset();
|
|
|
|
iterator& operator=(const iterator & iter);
|
|
private:
|
|
iterator(const C4ObjectList & List, const C4ObjectLink * pLink, bool reverse);
|
|
const C4ObjectList & List;
|
|
// instead of pointing to the current link make a copy of it
|
|
C4ObjectLink link;
|
|
iterator * Next;
|
|
bool reverse;
|
|
friend class C4ObjectList;
|
|
};
|
|
iterator begin() const;
|
|
const iterator end() const;
|
|
|
|
// Helper object returned by reverse() - allows for iterating the C4ObjectList in reverse order, still using the for (x : list) syntax
|
|
class ReverseView
|
|
{
|
|
private:
|
|
const C4ObjectList& list;
|
|
public:
|
|
ReverseView(const C4ObjectList& list): list(list) {}
|
|
// return an iterator at the end of the list
|
|
iterator begin() const;
|
|
// return an iterator at the position before the first item in the list
|
|
iterator end() const;
|
|
};
|
|
|
|
// Return a temporary object allowing for reverse-order iteration of the C4ObjectList
|
|
const ReverseView reverse() const { return ReverseView(*this); }
|
|
|
|
virtual void Default();
|
|
virtual void Clear();
|
|
void Sort();
|
|
void Copy(const C4ObjectList &rList);
|
|
void DrawIfCategory(C4TargetFacet &cgo, int iPlayer, uint32_t dwCat, bool fInvert); // draw all objects that match dwCat (or don't match if fInvert)
|
|
void Draw(C4TargetFacet &cgo, int iPlayer, int MinPlane, int MaxPlane); // draw all objects
|
|
void DrawSelectMark(C4TargetFacet &cgo) const;
|
|
void UpdateGraphics(bool fGraphicsChanged);
|
|
void UpdateFaces(bool bUpdateShape);
|
|
void ClearInfo(C4ObjectInfo *pInfo);
|
|
|
|
typedef int SortProc(C4Object *, C4Object *);
|
|
|
|
virtual bool Add(C4Object *nObj, SortType eSort, C4ObjectList *pLstSorted = NULL);
|
|
bool AddSortCustom(C4Object *nObj, SortProc &pSortProc);
|
|
virtual bool Remove(C4Object *pObj);
|
|
|
|
virtual bool AssignInfo();
|
|
virtual bool ValidateOwners();
|
|
StdStrBuf GetNameList(C4DefList &rDefs) const;
|
|
StdStrBuf GetDataString();
|
|
bool IsClear() const;
|
|
bool DenumeratePointers();
|
|
bool Write(char *szTarget);
|
|
void CompileFunc(StdCompiler *pComp, C4ValueNumbers * = 0);
|
|
void CompileFunc(StdCompiler *pComp, bool fSkipPlayerObjects, C4ValueNumbers *);
|
|
void Denumerate(C4ValueNumbers *);
|
|
|
|
bool IsContained(const C4Object *pObj) const;
|
|
int ClearPointers(C4Object *pObj);
|
|
int ObjectCount(C4ID id=C4ID::None) const;
|
|
int MassCount();
|
|
int ListIDCount(int32_t dwCategory) const;
|
|
|
|
C4Object* GetObject(int Index=0) const;
|
|
C4Object* GetFirstObject() const { return First ? First->Obj : NULL; }
|
|
C4Object* GetLastObject() const { return Last ? Last->Obj : NULL; }
|
|
C4Object* Find(C4Def * def, int iOwner=ANY_OWNER, DWORD dwOCF=OCF_All);
|
|
C4Object* FindOther(C4ID id, int iOwner=ANY_OWNER);
|
|
|
|
const C4ObjectLink* GetLink(const C4Object *pObj) const;
|
|
C4ObjectLink* GetLink(const C4Object *pObj)
|
|
{ return const_cast<C4ObjectLink*>(const_cast<const C4ObjectList*>(this)->GetLink(pObj)); }
|
|
|
|
C4ID GetListID(int32_t dwCategory, int Index) const;
|
|
|
|
bool ShiftContents(C4Object *pNewFirst); // cycle list so pNewFirst is at front
|
|
|
|
void DeleteObjects(); // delete all objects and links
|
|
|
|
void UpdateScriptPointers(); // update pointers to C4AulScript *
|
|
|
|
bool CheckSort(C4ObjectList *pList); // check that all objects of this list appear in the other list in the same order
|
|
void CheckCategorySort(); // assertwhether sorting by category is done right
|
|
|
|
protected:
|
|
virtual void InsertLinkBefore(C4ObjectLink *pLink, C4ObjectLink *pBefore);
|
|
virtual void InsertLink(C4ObjectLink *pLink, C4ObjectLink *pAfter);
|
|
virtual void RemoveLink(C4ObjectLink *pLnk);
|
|
mutable iterator * FirstIter;
|
|
iterator * AddIter(iterator * iter) const;
|
|
void RemoveIter(iterator * iter) const;
|
|
|
|
friend class iterator;
|
|
};
|
|
|
|
class C4NotifyingObjectList: public C4ObjectList
|
|
{
|
|
public:
|
|
C4NotifyingObjectList() { }
|
|
C4NotifyingObjectList(const C4NotifyingObjectList &List): C4ObjectList(List) { }
|
|
C4NotifyingObjectList(const C4ObjectList &List): C4ObjectList(List) { }
|
|
virtual ~C4NotifyingObjectList() { }
|
|
protected:
|
|
virtual void InsertLinkBefore(C4ObjectLink *pLink, C4ObjectLink *pBefore);
|
|
virtual void InsertLink(C4ObjectLink *pLink, C4ObjectLink *pAfter);
|
|
virtual void RemoveLink(C4ObjectLink *pLnk);
|
|
};
|
|
|
|
// This iterator is used to return objects of same ID and picture as grouped.
|
|
// It's taking advantage of the fact that object lists are sorted by ID.
|
|
// Used by functions such as C4ObjectList::DrawIDList, or the menu-filling of
|
|
// activation/selling menus
|
|
class C4ObjectListIterator
|
|
{
|
|
private:
|
|
C4ObjectList & rList; // iterated list
|
|
C4ObjectList::iterator pCurr; // link to last returned object
|
|
C4ObjectList::iterator pCurrID; // link to head of link group with same ID
|
|
|
|
C4ObjectListIterator(const C4ObjectListIterator &rCopy); // no copy ctor
|
|
public:
|
|
C4ObjectListIterator(C4ObjectList &rList) : rList(rList), pCurr(rList.end()), pCurrID(rList.begin()) {} // ctor
|
|
C4Object *GetNext(int32_t *piCount); // get next object; return NULL if end is reached
|
|
};
|
|
|
|
#endif
|