This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

189 lines
5.4 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef DMEHANDLE_H
#define DMEHANDLE_H
#ifdef _WIN32
#pragma once
#endif
#include "datamodel/dmattribute.h"
#include "datamodel/dmattributevar.h"
#include "datamodel/dmelement.h"
#include "datamodel/idatamodel.h"
//-----------------------------------------------------------------------------
// Purpose: CDmeHandle is a templatized wrapper around DmElementHandle_t
//-----------------------------------------------------------------------------
template <class DmeType, bool Counted = false>
class CDmeHandle : public CDmeElementRefHelper {
public:
CDmeHandle() : m_handle(DMELEMENT_HANDLE_INVALID) {}
explicit CDmeHandle(CDmElement *pObject)
: m_handle(DMELEMENT_HANDLE_INVALID) {
Set(pObject);
}
CDmeHandle(DmElementHandle_t h) : m_handle(DMELEMENT_HANDLE_INVALID) {
Set(h);
}
CDmeHandle(const CDmeHandle<DmeType, Counted> &handle)
: m_handle(DMELEMENT_HANDLE_INVALID) {
Set(handle.m_handle);
}
template <class T, bool B>
CDmeHandle(const CDmeHandle<T, B> &handle)
: m_handle(DMELEMENT_HANDLE_INVALID) {
DmeType *p = (T *)NULL; // triggers compiler error if converting from
// invalid handle type
NOTE_UNUSED(p);
Set(handle.GetHandle());
}
~CDmeHandle() {
if (!g_pDataModel)
return; // some handles are static, and don't get destroyed until
// program termination
Unref(m_handle, Counted);
}
template <class T, bool B>
CDmeHandle &operator=(const CDmeHandle<T, B> &handle) {
DmeType *p = (T *)NULL; // triggers compiler error if converting from
// invalid handle type
NOTE_UNUSED(p);
Set(handle.GetHandle());
return *this;
}
DmeType *Get() {
return static_cast<DmeType *>(g_pDataModel->GetElement(m_handle));
}
const DmeType *Get() const {
return static_cast<DmeType *>(g_pDataModel->GetElement(m_handle));
}
DmElementHandle_t GetHandle() const { return m_handle; }
void Set(CDmElement *pObject) {
Set(pObject ? pObject->GetHandle() : DMELEMENT_HANDLE_INVALID);
}
void Set(DmElementHandle_t h) {
if (h == m_handle) return;
Unref(m_handle, Counted);
m_handle = h;
if (h != DMELEMENT_HANDLE_INVALID) {
CDmElement *pElement = g_pDataModel->GetElement(m_handle);
Assert(pElement);
if (pElement && !pElement->IsA(DmeType::GetStaticTypeSymbol())) {
m_handle = DMELEMENT_HANDLE_INVALID;
}
}
Ref(m_handle, Counted);
}
operator DmeType *() { return Get(); }
operator const DmeType *() const { return Get(); }
operator DmElementHandle_t() const { return m_handle; }
DmeType *operator->() { return Get(); }
const DmeType *operator->() const { return Get(); }
CDmeHandle &operator=(DmElementHandle_t h) {
Set(h);
return *this;
}
CDmeHandle &operator=(CDmElement *pObject) {
Set(pObject);
return *this;
}
bool operator==(const CDmeHandle<DmeType> &h) const {
return m_handle == h.m_handle;
}
bool operator!=(const CDmeHandle<DmeType> &h) const {
return !operator==(h);
}
bool operator<(const CDmeHandle<DmeType> &h) const {
return m_handle < h.m_handle;
}
bool operator==(DmeType *pObject) const {
DmElementHandle_t h =
pObject ? pObject->GetHandle() : DMELEMENT_HANDLE_INVALID;
return m_handle == h;
}
bool operator!=(DmeType *pObject) const { return !operator==(pObject); }
bool operator==(DmElementHandle_t h) const { return (m_handle == h); }
bool operator!=(DmElementHandle_t h) const { return (m_handle != h); }
operator bool() const { return (Get() != NULL); }
bool operator!() const { return (Get() == NULL); }
private:
DmElementHandle_t m_handle;
};
typedef CDmeHandle<CDmElement, true> CDmeCountedHandle;
//-----------------------------------------------------------------------------
// Vector of element handles
//-----------------------------------------------------------------------------
typedef CUtlVector<CDmeHandle<CDmElement> > DmeHandleVec_t;
//-----------------------------------------------------------------------------
// helper class for undo classes to allow them to hold onto refcounted element
// handles
//-----------------------------------------------------------------------------
template <typename T>
class CDmAttributeUndoStorageType {
public:
typedef T UndoStorageType;
};
template <>
class CDmAttributeUndoStorageType<DmElementHandle_t> {
public:
typedef CDmeCountedHandle UndoStorageType;
};
template <>
class CDmAttributeUndoStorageType<CUtlVector<DmElementHandle_t> > {
public:
typedef CUtlVector<CDmeCountedHandle> UndoStorageType;
};
#endif // DMEHANDLE_H