Minor improvements
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user