Minor improvements

This commit is contained in:
2024-04-22 18:10:58 +02:00
parent e795a8b037
commit 32b15f90ab
9 changed files with 36 additions and 91 deletions
+1
View File
@@ -236,6 +236,7 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/GrammarAndSpelling/GrammarChecking/RulesStates/=LanguageTool_002EEN_002EE_005FG/@EntryIndexedValue">DisabledByUser</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=EEA05B0ED8200E4BA9D2D3F1052EBFFD/@KeyIndexDefined">True</s:Boolean> <s:Boolean x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=EEA05B0ED8200E4BA9D2D3F1052EBFFD/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=EEA05B0ED8200E4BA9D2D3F1052EBFFD/Color/@EntryValue">Blue</s:String> <s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=EEA05B0ED8200E4BA9D2D3F1052EBFFD/Color/@EntryValue">Blue</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=EEA05B0ED8200E4BA9D2D3F1052EBFFD/MatchComments/@EntryValue">True</s:Boolean> <s:Boolean x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=EEA05B0ED8200E4BA9D2D3F1052EBFFD/MatchComments/@EntryValue">True</s:Boolean>
+1 -2
View File
@@ -587,8 +587,8 @@ bool Asset::IsInternalType() const
bool Asset::onLoad(LoadAssetTask* task) bool Asset::onLoad(LoadAssetTask* task)
{ {
// It may fail when task is cancelled and new one is created later (don't crash but just end with an error)
if (task->Asset.Get() != this || Platform::AtomicRead(&_loadingTask) == 0) if (task->Asset.Get() != this || Platform::AtomicRead(&_loadingTask) == 0)
// It may fail when task is cancelled and new one was created later (don't crash but just end with an error)
return true; return true;
Locker.Lock(); Locker.Lock();
@@ -601,7 +601,6 @@ bool Asset::onLoad(LoadAssetTask* task)
} }
const bool isLoaded = result == LoadResult::Ok; const bool isLoaded = result == LoadResult::Ok;
const bool failed = !isLoaded; const bool failed = !isLoaded;
LoadState state = LoadState::Loaded;
Platform::AtomicStore(&_loadState, (int64)(isLoaded ? LoadState::Loaded : LoadState::LoadFailed)); Platform::AtomicStore(&_loadState, (int64)(isLoaded ? LoadState::Loaded : LoadState::LoadFailed));
if (failed) if (failed)
{ {
+1 -1
View File
@@ -103,7 +103,7 @@ public:
public: public:
/// <summary> /// <summary>
/// Gets the path to the asset storage file. In Editor it reflects the actual file, in cooked Game, it fakes the Editor path to be informative for developers. /// Gets the path to the asset storage file. In Editor, it reflects the actual file, in cooked Game, it fakes the Editor path to be informative for developers.
/// </summary> /// </summary>
API_PROPERTY() virtual const String& GetPath() const = 0; API_PROPERTY() virtual const String& GetPath() const = 0;
+1 -5
View File
@@ -507,8 +507,7 @@ public:
/// </summary> /// </summary>
/// <param name="asset">The asset.</param> /// <param name="asset">The asset.</param>
InitAssetTask(BinaryAsset* asset) InitAssetTask(BinaryAsset* asset)
: ContentLoadTask(Type::Custom) : _asset(asset)
, _asset(asset)
, _dataLock(asset->Storage->Lock()) , _dataLock(asset->Storage->Lock())
{ {
} }
@@ -527,8 +526,6 @@ protected:
AssetReference<BinaryAsset> ref = _asset.Get(); AssetReference<BinaryAsset> ref = _asset.Get();
if (ref == nullptr) if (ref == nullptr)
return Result::MissingReferences; return Result::MissingReferences;
// Prepare
auto storage = ref->Storage; auto storage = ref->Storage;
auto factory = (BinaryAssetFactoryBase*)Content::GetAssetFactory(ref->GetTypeName()); auto factory = (BinaryAssetFactoryBase*)Content::GetAssetFactory(ref->GetTypeName());
ASSERT(factory); ASSERT(factory);
@@ -548,7 +545,6 @@ protected:
_dataLock.Release(); _dataLock.Release();
_asset = nullptr; _asset = nullptr;
// Base
ContentLoadTask::OnEnd(); ContentLoadTask::OnEnd();
} }
}; };
@@ -15,52 +15,11 @@ class ContentLoadTask : public Task
friend LoadingThread; friend LoadingThread;
public: public:
/// <summary>
/// Describes work type
/// </summary>
DECLARE_ENUM_3(Type, Custom, LoadAsset, LoadAssetData);
/// <summary> /// <summary>
/// Describes work result value /// Describes work result value
/// </summary> /// </summary>
DECLARE_ENUM_5(Result, Ok, AssetLoadError, MissingReferences, LoadDataError, TaskFailed); DECLARE_ENUM_5(Result, Ok, AssetLoadError, MissingReferences, LoadDataError, TaskFailed);
private:
/// <summary>
/// Task type
/// </summary>
Type _type;
protected:
/// <summary>
/// Initializes a new instance of the <see cref="ContentLoadTask"/> class.
/// </summary>
/// <param name="type">The task type.</param>
ContentLoadTask(const Type type)
: _type(type)
{
}
public:
/// <summary>
/// Gets a task type.
/// </summary>
FORCE_INLINE Type GetType() const
{
return _type;
}
public:
/// <summary>
/// Checks if async task is loading given asset resource
/// </summary>
/// <param name="asset">Target asset to check</param>
/// <returns>True if is loading that asset, otherwise false</returns>
bool IsLoading(Asset* asset) const
{
return _type == Type::LoadAsset && HasReference((Object*)asset);
}
protected: protected:
virtual Result run() = 0; virtual Result run() = 0;
@@ -4,6 +4,7 @@
#include "ContentLoadTask.h" #include "ContentLoadTask.h"
#include "Engine/Core/Log.h" #include "Engine/Core/Log.h"
#include "Engine/Core/Math/Math.h" #include "Engine/Core/Math/Math.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Platform/CPUInfo.h" #include "Engine/Platform/CPUInfo.h"
#include "Engine/Platform/Thread.h" #include "Engine/Platform/Thread.h"
#include "Engine/Platform/ConditionVariable.h" #include "Engine/Platform/ConditionVariable.h"
@@ -212,7 +213,7 @@ void ContentLoadingManagerService::Dispose()
String ContentLoadTask::ToString() const String ContentLoadTask::ToString() const
{ {
return String::Format(TEXT("Content Load Task {0} ({1})"), ToString(GetType()), (int32)GetState()); return String::Format(TEXT("Content Load Task ({})"), (int32)GetState());
} }
void ContentLoadTask::Enqueue() void ContentLoadTask::Enqueue()
@@ -15,28 +15,24 @@
class LoadAssetDataTask : public ContentLoadTask class LoadAssetDataTask : public ContentLoadTask
{ {
private: private:
WeakAssetReference<BinaryAsset> _asset; // Don't keep ref to the asset (so it can be unloaded if none using it, task will fail then) WeakAssetReference<BinaryAsset> _asset; // Don't keep ref to the asset (so it can be unloaded if none using it, task will fail then)
AssetChunksFlag _chunks; AssetChunksFlag _chunks;
FlaxStorage::LockData _dataLock; FlaxStorage::LockData _dataLock;
public: public:
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="LoadAssetDataTask"/> class. /// Initializes a new instance of the <see cref="LoadAssetDataTask"/> class.
/// </summary> /// </summary>
/// <param name="asset">The asset to load.</param> /// <param name="asset">The asset to load.</param>
/// <param name="chunks">The chunks to load.</param> /// <param name="chunks">The chunks to load.</param>
LoadAssetDataTask(BinaryAsset* asset, AssetChunksFlag chunks) LoadAssetDataTask(BinaryAsset* asset, AssetChunksFlag chunks)
: ContentLoadTask(Type::LoadAssetData) : _asset(asset)
, _asset(asset)
, _chunks(chunks) , _chunks(chunks)
, _dataLock(asset->Storage->Lock()) , _dataLock(asset->Storage->Lock())
{ {
} }
public: public:
// [ContentLoadTask] // [ContentLoadTask]
bool HasReference(Object* obj) const override bool HasReference(Object* obj) const override
{ {
@@ -44,7 +40,6 @@ public:
} }
protected: protected:
// [ContentLoadTask] // [ContentLoadTask]
Result run() override Result run() override
{ {
@@ -15,38 +15,35 @@
class LoadAssetTask : public ContentLoadTask class LoadAssetTask : public ContentLoadTask
{ {
public: public:
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="LoadAssetTask"/> class. /// Initializes a new instance of the <see cref="LoadAssetTask"/> class.
/// </summary> /// </summary>
/// <param name="asset">The asset to load.</param> /// <param name="asset">The asset to load.</param>
LoadAssetTask(Asset* asset) LoadAssetTask(Asset* asset)
: ContentLoadTask(Type::LoadAsset) : Asset(asset)
, Asset(asset)
{ {
} }
~LoadAssetTask() ~LoadAssetTask()
{ {
if (Asset) auto asset = Asset.Get();
if (asset)
{ {
Asset->Locker.Lock(); asset->Locker.Lock();
if (Platform::AtomicRead(&Asset->_loadingTask) == (intptr)this) if (Platform::AtomicRead(&asset->_loadingTask) == (intptr)this)
{ {
Platform::AtomicStore(&Asset->_loadState, (int64)Asset::LoadState::LoadFailed); Platform::AtomicStore(&asset->_loadState, (int64)Asset::LoadState::LoadFailed);
Platform::AtomicStore(&Asset->_loadingTask, 0); Platform::AtomicStore(&asset->_loadingTask, 0);
LOG(Error, "Loading asset \'{0}\' result: {1}.", ToString(), ToString(Result::TaskFailed)); LOG(Error, "Loading asset \'{0}\' result: {1}.", ToString(), ToString(Result::TaskFailed));
} }
Asset->Locker.Unlock(); asset->Locker.Unlock();
} }
} }
public: public:
WeakAssetReference<Asset> Asset; WeakAssetReference<Asset> Asset;
public: public:
// [ContentLoadTask] // [ContentLoadTask]
bool HasReference(Object* obj) const override bool HasReference(Object* obj) const override
{ {
@@ -54,7 +51,6 @@ public:
} }
protected: protected:
// [ContentLoadTask] // [ContentLoadTask]
Result run() override Result run() override
{ {
@@ -68,32 +64,36 @@ protected:
// Call loading // Call loading
if (ref->onLoad(this)) if (ref->onLoad(this))
return Result::AssetLoadError; return Result::AssetLoadError;
return Result::Ok; return Result::Ok;
} }
void OnFail() override void OnFail() override
{ {
if (Asset) auto asset = Asset.Get();
if (asset)
{ {
Asset->Locker.Lock();
if (Platform::AtomicRead(&Asset->_loadingTask) == (intptr)this)
Platform::AtomicStore(&Asset->_loadingTask, 0);
Asset->Locker.Unlock();
Asset = nullptr; Asset = nullptr;
asset->Locker.Lock();
if (Platform::AtomicRead(&asset->_loadingTask) == (intptr)this)
Platform::AtomicStore(&asset->_loadingTask, 0);
asset->Locker.Unlock();
} }
// Base // Base
ContentLoadTask::OnFail(); ContentLoadTask::OnFail();
} }
void OnEnd() override void OnEnd() override
{ {
if (Asset) auto asset = Asset.Get();
if (asset)
{ {
Asset->Locker.Lock();
if (Platform::AtomicRead(&Asset->_loadingTask) == (intptr)this)
Platform::AtomicStore(&Asset->_loadingTask, 0);
Asset->Locker.Unlock();
Asset = nullptr; Asset = nullptr;
asset->Locker.Lock();
if (Platform::AtomicRead(&asset->_loadingTask) == (intptr)this)
Platform::AtomicStore(&asset->_loadingTask, 0);
asset->Locker.Unlock();
asset = nullptr;
} }
// Base // Base
+6 -12
View File
@@ -7,7 +7,6 @@
#include "Engine/Core/NonCopyable.h" #include "Engine/Core/NonCopyable.h"
#include "Engine/Core/Enums.h" #include "Engine/Core/Enums.h"
#include "Engine/Core/Types/TimeSpan.h" #include "Engine/Core/Types/TimeSpan.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Platform/Platform.h" #include "Engine/Platform/Platform.h"
/// <summary> /// <summary>
@@ -188,8 +187,8 @@ public:
/// <param name="tasks">The tasks list to wait for.</param> /// <param name="tasks">The tasks list to wait for.</param>
/// <param name="timeoutMilliseconds">The maximum amount of milliseconds to wait for the task to finish it's job. Timeout smaller/equal 0 will result in infinite waiting.</param> /// <param name="timeoutMilliseconds">The maximum amount of milliseconds to wait for the task to finish it's job. Timeout smaller/equal 0 will result in infinite waiting.</param>
/// <returns>True if any task failed or has been canceled or has timeout, otherwise false.</returns> /// <returns>True if any task failed or has been canceled or has timeout, otherwise false.</returns>
template<class T = Task> template<class T = Task, typename AllocationType = HeapAllocation>
static bool WaitAll(Array<T*>& tasks, double timeoutMilliseconds = -1) static bool WaitAll(Array<T*, AllocationType>& tasks, double timeoutMilliseconds = -1)
{ {
for (int32 i = 0; i < tasks.Count(); i++) for (int32 i = 0; i < tasks.Count(); i++)
{ {
@@ -300,27 +299,22 @@ public:
/// <summary> /// <summary>
/// Cancels all the tasks from the list and clears it. /// Cancels all the tasks from the list and clears it.
/// </summary> /// </summary>
template<class T = Task> template<class T = Task, typename AllocationType = HeapAllocation>
static void CancelAll(Array<T*>& tasks) static void CancelAll(Array<T*, AllocationType>& tasks)
{ {
for (int32 i = 0; i < tasks.Count(); i++) for (int32 i = 0; i < tasks.Count(); i++)
{
tasks[i]->Cancel(); tasks[i]->Cancel();
}
tasks.Clear(); tasks.Clear();
} }
protected: protected:
/// <summary> /// <summary>
/// Executes this task. /// Executes this task. It should be called by the task consumer (thread pool or other executor of this task type). It calls run() and handles result).
/// It should be called by the task consumer (thread pool or other executor of this task type).
/// It calls run() and handles result).
/// </summary> /// </summary>
void Execute(); void Execute();
/// <summary> /// <summary>
/// Runs the task specified operations /// Runs the task specified operations. It does not handle any task related logic, but only performs the actual job.
/// Does not handles any task related logic, only performs the actual job.
/// </summary> /// </summary>
/// <returns>The task execution result. Returns true if failed, otherwise false.</returns> /// <returns>The task execution result. Returns true if failed, otherwise false.</returns>
virtual bool Run() = 0; virtual bool Run() = 0;