222 lines
10 KiB
C++
222 lines
10 KiB
C++
#pragma once
|
|
|
|
#include <stdexcept>
|
|
#include <limits>
|
|
|
|
namespace SHADE
|
|
{
|
|
/*---------------------------------------------------------------------------------*/
|
|
/* Forward Declarations */
|
|
/*---------------------------------------------------------------------------------*/
|
|
template<typename T>
|
|
class ResourceLibrary;
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
/* Type Definitions */
|
|
/*---------------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Exception thrown when an invalid Handle was dereferenced.
|
|
/// </summary>
|
|
class InvalidHandleException : std::runtime_error
|
|
{
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Constructors */
|
|
/*-----------------------------------------------------------------------------*/
|
|
using std::runtime_error::runtime_error;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Base implementation of the Handle that is not templated to allow for holding
|
|
/// generic non-type-specific Handles.
|
|
/// </summary>
|
|
class HandleBase
|
|
{
|
|
public:
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Type Definitions */
|
|
/*-----------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Native ID type of a handle
|
|
/// </summary>
|
|
union Id
|
|
{
|
|
/*-------------------------------------------------------------------------*/
|
|
/* Data */
|
|
/*-------------------------------------------------------------------------*/
|
|
uint64_t Raw = std::numeric_limits<uint64_t>::max();
|
|
struct
|
|
{
|
|
uint32_t Index;
|
|
uint32_t Version;
|
|
} Data;
|
|
};
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Usage Functions */
|
|
/*-----------------------------------------------------------------------------*/
|
|
inline Id GetId() const;
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Overloaded Operators */
|
|
/*-----------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Converts to true if this is a valid Handle.
|
|
/// </summary>
|
|
inline operator bool() const;
|
|
|
|
protected:
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Constants */
|
|
/*-----------------------------------------------------------------------------*/
|
|
static constexpr Id INVALID_ID {};
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Data Members */
|
|
/*-----------------------------------------------------------------------------*/
|
|
Id id = INVALID_ID;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Generic implementation of a Handle object
|
|
/// </summary>
|
|
/// <typeparam name="T">Type of the handle.</typeparam>
|
|
template<typename T>
|
|
class Handle : public HandleBase
|
|
{
|
|
public:
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Constructors */
|
|
/*-----------------------------------------------------------------------------*/
|
|
Handle() = default;
|
|
~Handle() = default;
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Usage Functions */
|
|
/*-----------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Deallocates the object pointed to by this function.
|
|
/// </summary>
|
|
void Free();
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Overloaded Operators */
|
|
/*-----------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Returns the underlying object pointed to by the Handle.
|
|
/// </summary>
|
|
/// <exception cref="InvalidHandleException">
|
|
/// Thrown when this is an Invalid Handle.
|
|
/// </exception>
|
|
/// <returns>Reference to the object pointed to by this Handle.</returns>
|
|
T& operator*();
|
|
/// <summary>
|
|
/// Returns the underlying object pointed to by the Handle as read-only.
|
|
/// </summary>
|
|
/// <exception cref="InvalidHandleException">
|
|
/// Thrown when this is an Invalid Handle.
|
|
/// </exception>
|
|
/// <returns>Const reference to the object pointed to by this Handle.</returns>
|
|
const T& operator*() const;
|
|
/// <summary>
|
|
/// Provides access to members of the underlying object pointed to by the Handle.
|
|
/// </summary>
|
|
/// <exception cref="InvalidHandleException">
|
|
/// Thrown when this is an Invalid Handle.
|
|
/// </exception>
|
|
/// <returns>Pointer to the object pointed to by this Handle.</returns>
|
|
T* operator->();
|
|
/// <summary>
|
|
/// Provides read-only access to members of the underlying object pointed to by
|
|
/// the Handle.
|
|
/// </summary>
|
|
/// <exception cref="InvalidHandleException">
|
|
/// Thrown when this is an Invalid Handle.
|
|
/// </exception>
|
|
/// <returns>Const pointer to the object pointed to by this Handle.</returns>
|
|
const T* operator->() const;
|
|
|
|
protected:
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Data Members */
|
|
/*-----------------------------------------------------------------------------*/
|
|
ResourceLibrary<T>* library = nullptr;
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Friend Declarations */
|
|
/*-----------------------------------------------------------------------------*/
|
|
friend class ResourceLibrary<T>;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Interface that needs to be implemented by classes that want to store a Handle to
|
|
/// themselves after construction by Resource Managers.
|
|
/// </summary>
|
|
template<typename T>
|
|
class ISelfHandle
|
|
{
|
|
public:
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Constructors */
|
|
/*-----------------------------------------------------------------------------*/
|
|
ISelfHandle() = default;
|
|
ISelfHandle(const ISelfHandle& rhs);
|
|
ISelfHandle(ISelfHandle&& rhs);
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Overloaded Operators */
|
|
/*-----------------------------------------------------------------------------*/
|
|
ISelfHandle& operator=(const ISelfHandle& rhs);
|
|
ISelfHandle& operator=(ISelfHandle&& rhs);
|
|
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Usage Functions */
|
|
/*-----------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// Retrieves the Handle of this object.
|
|
/// </summary>
|
|
/// <returns>Handle to this object.</returns>
|
|
Handle<T> GetHandle() const;
|
|
/// <summary>
|
|
/// Used to set the Handle for this object. Should only be used by
|
|
/// ResourceLibrary.
|
|
/// </summary>
|
|
/// <param name="rscLib">Required to lock usage to ResourceLibrary only.</param>
|
|
/// <param name="hdl">Handle to set.</param>
|
|
void SetHandle(const ResourceLibrary<T>& rscLib, Handle<T> hdl);
|
|
|
|
private:
|
|
/*-----------------------------------------------------------------------------*/
|
|
/* Data Members */
|
|
/*-----------------------------------------------------------------------------*/
|
|
Handle<T> handle;
|
|
};
|
|
|
|
}
|
|
|
|
namespace std
|
|
{
|
|
/*---------------------------------------------------------------------------------*/
|
|
/* Type Definitions */
|
|
/*---------------------------------------------------------------------------------*/
|
|
/// <summary>
|
|
/// std::hash template specialization for Handle<T>
|
|
/// </summary>
|
|
/// <typeparam name="T">Type for the Handle.</typeparam>
|
|
template<typename T>
|
|
struct hash<SHADE::Handle<T>>
|
|
{
|
|
std::size_t operator() (const SHADE::Handle<T>& hdl) const;
|
|
};
|
|
/// <summary>
|
|
/// std::hash template specialization for std::pair<Handle<T1>, Handle<T2>>
|
|
/// </summary>
|
|
/// <typeparam name="T">Type for the first Handle.</typeparam>
|
|
/// <typeparam name="T">Type for the second Handle.</typeparam>
|
|
template<typename T1, typename T2>
|
|
struct hash<std::pair<SHADE::Handle<T1>, SHADE::Handle<T2>>>
|
|
{
|
|
std::size_t operator() (std::pair<SHADE::Handle<T1>, SHADE::Handle<T2>> const& pair) const;
|
|
};
|
|
}
|
|
|
|
#include "Handle.hpp" |