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