// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Delegate.h" #include "GPUResource.h" /// /// GPU Resource container utility object. /// template class GPUResourceProperty { private: T* _resource; private: // Disable copy actions GPUResourceProperty(const GPUResourceProperty& other) = delete; public: /// /// Action fired when resource gets unloaded (reference gets cleared bu async tasks should stop execution). /// Delegate OnUnload; public: /// /// Initializes a new instance of the class. /// GPUResourceProperty() : _resource(nullptr) { } /// /// Initializes a new instance of the class. /// /// The resource. GPUResourceProperty(T* resource) : _resource(nullptr) { Set(resource); } /// /// Finalizes an instance of the class. /// ~GPUResourceProperty() { // Check if object has been binded if (_resource) { // Unlink _resource->Releasing.template Unbind(this); _resource = nullptr; } } public: FORCE_INLINE bool operator==(T* other) const { return Get() == other; } FORCE_INLINE bool operator==(GPUResourceProperty& other) const { return Get() == other.Get(); } GPUResourceProperty& operator=(const GPUResourceProperty& other) { if (this != &other) Set(other.Get()); return *this; } FORCE_INLINE GPUResourceProperty& operator=(T& other) { Set(&other); return *this; } FORCE_INLINE GPUResourceProperty& operator=(T* other) { Set(other); return *this; } /// /// Implicit conversion to GPU Resource /// /// Resource FORCE_INLINE operator T*() const { return _resource; } /// /// Implicit conversion to resource /// /// True if resource has been binded, otherwise false FORCE_INLINE operator bool() const { return _resource != nullptr; } /// /// Implicit conversion to resource /// /// Resource FORCE_INLINE T* operator->() const { return _resource; } /// /// Gets linked resource /// /// Resource FORCE_INLINE T* Get() const { return _resource; } /// /// Checks if resource has been binded /// /// True if resource has been binded, otherwise false FORCE_INLINE bool IsBinded() const { return _resource != nullptr; } /// /// Checks if resource is missing /// /// True if resource is missing, otherwise false FORCE_INLINE bool IsMissing() const { return _resource == nullptr; } public: /// /// Set resource /// /// Value to assign void Set(T* value) { if (_resource != value) { // Remove reference from the old one if (_resource) _resource->Releasing.template Unbind(this); // Change referenced object _resource = value; // Add reference to the new one if (_resource) _resource->Releasing.template Bind(this); } } /// /// Unlink resource /// void Unlink() { if (_resource) { // Remove reference from the old one _resource->Releasing.template Unbind(this); _resource = nullptr; } } private: void onResourceUnload() { if (_resource) { _resource = nullptr; OnUnload(this); } } }; typedef GPUResourceProperty GPUResourceReference; typedef GPUResourceProperty GPUTextureReference; typedef GPUResourceProperty BufferReference;