diff --git a/Source/Engine/Content/AssetReference.h b/Source/Engine/Content/AssetReference.h
index 6aee12246..b9d54f30a 100644
--- a/Source/Engine/Content/AssetReference.h
+++ b/Source/Engine/Content/AssetReference.h
@@ -9,9 +9,6 @@
///
class FLAXENGINE_API AssetReferenceBase
{
-public:
- typedef Delegate<> EventType;
-
protected:
Asset* _asset = nullptr;
@@ -19,17 +16,17 @@ public:
///
/// The asset loaded event (fired when asset gets loaded or is already loaded after change).
///
- EventType Loaded;
+ Action Loaded;
///
/// The asset unloading event (should cleanup refs to it).
///
- EventType Unload;
+ Action Unload;
///
/// Action fired when field gets changed (link a new asset or change to the another value).
///
- EventType Changed;
+ Action Changed;
public:
NON_COPYABLE(AssetReferenceBase);
diff --git a/Source/Engine/Graphics/Async/Tasks/GPUCopyResourceTask.h b/Source/Engine/Graphics/Async/Tasks/GPUCopyResourceTask.h
index 86c723530..f57327fa4 100644
--- a/Source/Engine/Graphics/Async/Tasks/GPUCopyResourceTask.h
+++ b/Source/Engine/Graphics/Async/Tasks/GPUCopyResourceTask.h
@@ -26,12 +26,12 @@ public:
, _srcResource(src)
, _dstResource(dst)
{
- _srcResource.OnUnload.Bind(this);
- _dstResource.OnUnload.Bind(this);
+ _srcResource.Released.Bind(this);
+ _dstResource.Released.Bind(this);
}
private:
- void OnResourceUnload(GPUResourceReference* ref)
+ void OnResourceReleased()
{
Cancel();
}
@@ -47,14 +47,11 @@ protected:
// [GPUTask]
Result run(GPUTasksContext* context) override
{
- if (_srcResource.IsMissing() || _dstResource.IsMissing())
+ if (!_srcResource || !_dstResource)
return Result::MissingResources;
-
context->GPU->CopyResource(_dstResource, _srcResource);
-
return Result::Ok;
}
-
void OnEnd() override
{
_srcResource.Unlink();
diff --git a/Source/Engine/Graphics/Async/Tasks/GPUCopySubresourceTask.h b/Source/Engine/Graphics/Async/Tasks/GPUCopySubresourceTask.h
index ab8f1ffad..193eb965d 100644
--- a/Source/Engine/Graphics/Async/Tasks/GPUCopySubresourceTask.h
+++ b/Source/Engine/Graphics/Async/Tasks/GPUCopySubresourceTask.h
@@ -31,12 +31,12 @@ public:
, _srcSubresource(srcSubresource)
, _dstSubresource(dstSubresource)
{
- _srcResource.OnUnload.Bind(this);
- _dstResource.OnUnload.Bind(this);
+ _srcResource.Released.Bind(this);
+ _dstResource.Released.Bind(this);
}
private:
- void OnResourceUnload(GPUResourceReference* ref)
+ void OnResourceReleased()
{
Cancel();
}
@@ -52,14 +52,11 @@ protected:
// [GPUTask]
Result run(GPUTasksContext* context) override
{
- if (_srcResource.IsMissing() || _dstResource.IsMissing())
+ if (!_srcResource || !_dstResource)
return Result::MissingResources;
-
context->GPU->CopySubresource(_dstResource, _dstSubresource, _srcResource, _srcSubresource);
-
return Result::Ok;
}
-
void OnEnd() override
{
_srcResource.Unlink();
diff --git a/Source/Engine/Graphics/Async/Tasks/GPUUploadBufferTask.h b/Source/Engine/Graphics/Async/Tasks/GPUUploadBufferTask.h
index d2f20449c..3d38ce58b 100644
--- a/Source/Engine/Graphics/Async/Tasks/GPUUploadBufferTask.h
+++ b/Source/Engine/Graphics/Async/Tasks/GPUUploadBufferTask.h
@@ -31,7 +31,7 @@ public:
, _buffer(buffer)
, _offset(offset)
{
- _buffer.OnUnload.Bind(this);
+ _buffer.Released.Bind(this);
if (copyData)
_data.Copy(data);
@@ -40,7 +40,7 @@ public:
}
private:
- void OnResourceUnload(BufferReference* ref)
+ void OnResourceReleased()
{
Cancel();
}
@@ -56,14 +56,11 @@ protected:
// [GPUTask]
Result run(GPUTasksContext* context) override
{
- if (_buffer.IsMissing())
+ if (!_buffer)
return Result::MissingResources;
-
context->GPU->UpdateBuffer(_buffer, _data.Get(), _data.Length(), _offset);
-
return Result::Ok;
}
-
void OnEnd() override
{
_buffer.Unlink();
diff --git a/Source/Engine/Graphics/Async/Tasks/GPUUploadTextureMipTask.h b/Source/Engine/Graphics/Async/Tasks/GPUUploadTextureMipTask.h
index 6e9cca7fd..2aff3511b 100644
--- a/Source/Engine/Graphics/Async/Tasks/GPUUploadTextureMipTask.h
+++ b/Source/Engine/Graphics/Async/Tasks/GPUUploadTextureMipTask.h
@@ -35,7 +35,7 @@ public:
, _rowPitch(rowPitch)
, _slicePitch(slicePitch)
{
- _texture.OnUnload.Bind(this);
+ _texture.Released.Bind(this);
if (copyData)
_data.Copy(data);
@@ -44,7 +44,7 @@ public:
}
private:
- void OnResourceUnload(GPUTextureReference* ref)
+ void OnResourceReleased()
{
Cancel();
}
diff --git a/Source/Engine/Graphics/GPUDevice.cpp b/Source/Engine/Graphics/GPUDevice.cpp
index f0056e26c..2a54c7c4d 100644
--- a/Source/Engine/Graphics/GPUDevice.cpp
+++ b/Source/Engine/Graphics/GPUDevice.cpp
@@ -3,6 +3,7 @@
#include "GPUDevice.h"
#include "RenderTargetPool.h"
#include "GPUPipelineState.h"
+#include "GPUResourceProperty.h"
#include "GPUSwapChain.h"
#include "RenderTask.h"
#include "RenderTools.h"
@@ -25,6 +26,39 @@
#include "Engine/Renderer/RenderList.h"
#include "Engine/Scripting/Enums.h"
+GPUResourcePropertyBase::~GPUResourcePropertyBase()
+{
+ const auto e = _resource;
+ if (e)
+ {
+ _resource = nullptr;
+ e->Releasing.Unbind(this);
+ }
+}
+
+void GPUResourcePropertyBase::OnSet(GPUResource* resource)
+{
+ auto e = _resource;
+ if (e != resource)
+ {
+ if (e)
+ e->Releasing.Unbind(this);
+ _resource = e = resource;
+ if (e)
+ e->Releasing.Bind(this);
+ }
+}
+
+void GPUResourcePropertyBase::OnReleased()
+{
+ auto e = _resource;
+ if (e)
+ {
+ _resource = nullptr;
+ e->Releasing.Unbind(this);
+ }
+}
+
GPUPipelineState* GPUPipelineState::Spawn(const SpawnParams& params)
{
return GPUDevice::Instance->CreatePipelineState();
diff --git a/Source/Engine/Graphics/GPUResourceProperty.h b/Source/Engine/Graphics/GPUResourceProperty.h
index b3c56007d..0b5d73c40 100644
--- a/Source/Engine/Graphics/GPUResourceProperty.h
+++ b/Source/Engine/Graphics/GPUResourceProperty.h
@@ -8,28 +8,39 @@
///
/// GPU Resource container utility object.
///
-template
-class GPUResourceProperty
+class FLAXENGINE_API GPUResourcePropertyBase
{
-private:
- T* _resource;
+protected:
+ GPUResource* _resource = nullptr;
-private:
- // Disable copy actions
- GPUResourceProperty(const GPUResourceProperty& other) = delete;
+public:
+ NON_COPYABLE(GPUResourcePropertyBase);
+
+ GPUResourcePropertyBase() = default;
+ ~GPUResourcePropertyBase();
public:
///
- /// Action fired when resource gets unloaded (reference gets cleared bu async tasks should stop execution).
+ /// Action fired when resource gets released (reference gets cleared bu async tasks should stop execution).
///
- Delegate OnUnload;
+ Action Released;
+protected:
+ void OnSet(GPUResource* resource);
+ void OnReleased();
+};
+
+///
+/// GPU Resource container utility object.
+///
+template
+class GPUResourceProperty : public GPUResourcePropertyBase
+{
public:
///
/// Initializes a new instance of the class.
///
GPUResourceProperty()
- : _resource(nullptr)
{
}
@@ -38,9 +49,37 @@ public:
///
/// The resource.
GPUResourceProperty(T* resource)
- : _resource(nullptr)
{
- Set(resource);
+ OnSet(resource);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The other value.
+ GPUResourceProperty(const GPUResourceProperty& other)
+ {
+ OnSet(other.Get());
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The other value.
+ GPUResourceProperty(GPUResourceProperty&& other)
+ {
+ OnSet(other.Get());
+ other.OnSet(nullptr);
+ }
+
+ GPUResourceProperty& operator=(GPUResourceProperty&& other)
+ {
+ if (&other != this)
+ {
+ OnSet(other._resource);
+ other.OnSet(nullptr);
+ }
+ return *this;
}
///
@@ -48,13 +87,6 @@ public:
///
~GPUResourceProperty()
{
- // Check if object has been binded
- if (_resource)
- {
- // Unlink
- _resource->Releasing.template Unbind(this);
- _resource = nullptr;
- }
}
public:
@@ -63,43 +95,34 @@ public:
return Get() == other;
}
- FORCE_INLINE bool operator==(GPUResourceProperty& other) const
+ FORCE_INLINE bool operator==(const 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);
+ OnSet(&other);
return *this;
}
FORCE_INLINE GPUResourceProperty& operator=(T* other)
{
- Set(other);
+ OnSet(other);
return *this;
}
///
/// Implicit conversion to GPU Resource
///
- /// Resource
FORCE_INLINE operator T*() const
{
- return _resource;
+ return (T*)_resource;
}
///
/// Implicit conversion to resource
///
- /// True if resource has been binded, otherwise false
FORCE_INLINE operator bool() const
{
return _resource != nullptr;
@@ -108,37 +131,17 @@ public:
///
/// Implicit conversion to resource
///
- /// Resource
FORCE_INLINE T* operator->() const
{
- return _resource;
+ return (T*)_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;
+ return (T*)_resource;
}
public:
@@ -148,19 +151,7 @@ public:
/// 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);
- }
+ OnSet(value);
}
///
@@ -168,22 +159,7 @@ public:
///
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);
- }
+ OnSet(nullptr);
}
};
diff --git a/Source/Engine/Graphics/Textures/StreamingTexture.cpp b/Source/Engine/Graphics/Textures/StreamingTexture.cpp
index e1be01252..173b0ef85 100644
--- a/Source/Engine/Graphics/Textures/StreamingTexture.cpp
+++ b/Source/Engine/Graphics/Textures/StreamingTexture.cpp
@@ -329,11 +329,11 @@ public:
, _dataLock(_streamingTexture->GetOwner()->LockData())
{
_streamingTexture->_streamingTasks.Add(this);
- _texture.OnUnload.Bind(this);
+ _texture.Released.Bind(this);
}
private:
- void onResourceUnload2(GPUTextureReference* ref)
+ void OnResourceReleased2()
{
// Unlink texture
if (_streamingTexture)