Files
@ r4548:6a33e364fba5
Branch filter:
Location: cpp/openttd-patchpack/source/yapf/autocopyptr.hpp - annotation
r4548:6a33e364fba5
2.8 KiB
text/x-c++hdr
(svn r6380) -Codechange: unify all ways to quit OTTD.
This means that in the intro menu the 'Quit' button immediatelly quits
and the 'Quit' in the menu of the normal game and scenario editor
immediatelly quits when the 'autosave_on_exit' patch is turned on.
This is the same way as the OS/window manager initiated quits, like
alt-F4 and the 'x' in the (OS/window manager drawn) title bar of OTTD.
This means that in the intro menu the 'Quit' button immediatelly quits
and the 'Quit' in the menu of the normal game and scenario editor
immediatelly quits when the 'autosave_on_exit' patch is turned on.
This is the same way as the OS/window manager initiated quits, like
alt-F4 and the 'x' in the (OS/window manager drawn) title bar of OTTD.
r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r4434:c817458d470e r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 r3900:1c2675abec23 | /* $Id$ */
#ifndef AUTOCOPYPTR_HPP
#define AUTOCOPYPTR_HPP
/** CAutoCopyPtrT - kind of CoW (Copy on Write) pointer.
It is non-invasive smart pointer (reference counter is held outside
of Tdata).
When copied, its new copy shares the same underlaying structure Tdata.
When dereferenced, its behavior depends on 2 factors:
- whether the data is shared (used by more than one pointer)
- type of access (read/write)
When shared pointer is dereferenced for write, new clone of Tdata
is made first.
Can't be used for polymorphic data types (interfaces).
*/
template <class Tdata_>
class CAutoCopyPtrT {
protected:
typedef Tdata_ Tdata;
struct CItem {
int m_ref_cnt; ///< reference counter
Tdata m_data; ///< custom data itself
FORCEINLINE CItem() : m_ref_cnt(1) {};
FORCEINLINE CItem(const Tdata& data) : m_ref_cnt(1), m_data(data) {};
FORCEINLINE CItem(const CItem& src) : m_ref_cnt(1), m_data(src.m_data) {};
};
mutable CItem* m_pI; ///< points to the ref-counted data
public:
FORCEINLINE CAutoCopyPtrT() : m_pI(NULL) {};
FORCEINLINE CAutoCopyPtrT(const Tdata& data) : m_pI(new CItem(data)) {};
FORCEINLINE CAutoCopyPtrT(const CAutoCopyPtrT& src) : m_pI(src.m_pI) {if (m_pI != NULL) m_pI->m_ref_cnt++;}
FORCEINLINE ~CAutoCopyPtrT() {if (m_pI == NULL || (--m_pI->m_ref_cnt) > 0) return; delete m_pI; m_pI = NULL;}
/** data accessor (read only) */
FORCEINLINE const Tdata& GetDataRO() const {if (m_pI == NULL) m_pI = new CItem(); return m_pI->m_data;}
/** data accessor (read / write) */
FORCEINLINE Tdata& GetDataRW() {CloneIfShared(); if (m_pI == NULL) m_pI = new CItem(); return m_pI->m_data;}
/** clone data if it is shared */
FORCEINLINE void CloneIfShared()
{
if (m_pI != NULL && m_pI->m_ref_cnt > 1) {
// we share data item with somebody, clone it to become an exclusive owner
CItem* pNewI = new CItem(*m_pI);
m_pI->m_ref_cnt--;
m_pI = pNewI;
}
}
/** assign pointer from the other one (maintaining ref counts) */
FORCEINLINE void Assign(const CAutoCopyPtrT& src)
{
if (m_pI == src.m_pI) return;
if (m_pI != NULL && (--m_pI->m_ref_cnt) <= 0) delete m_pI;
m_pI = src.m_pI;
if (m_pI != NULL) m_pI->m_ref_cnt++;
}
/** dereference operator (read only) */
FORCEINLINE const Tdata* operator -> () const {return &GetDataRO();}
/** dereference operator (read / write) */
FORCEINLINE Tdata* operator -> () {return &GetDataRW();}
/** assignment operator */
FORCEINLINE CAutoCopyPtrT& operator = (const CAutoCopyPtrT& src) {Assign(src); return *this;}
/** forwarding 'lower then' operator to the underlaying items */
FORCEINLINE bool operator < (const CAutoCopyPtrT& other) const
{
assert(m_pI != NULL);
assert(other.m_pI != NULL);
return (m_pI->m_data) < (other.m_pI->m_data);
}
};
#endif /* AUTOCOPYPTR_HPP */
|