// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Threading/IRunnable.h" class Asset; class LoadingThread; class ContentLoadTask; /// /// Resources loading thread /// class LoadingThread : public IRunnable { protected: volatile int64 _exitFlag; Thread* _thread; int32 _totalTasksDoneCount; public: /// /// Init /// LoadingThread(); /// /// Destructor /// ~LoadingThread(); public: /// /// Gets the thread identifier. /// /// Thread ID uint64 GetID() const; public: /// /// Returns true if thread has empty exit flag, so it can continue it's work /// /// True if exit flag is empty, otherwise false FORCE_INLINE bool HasExitFlagClear() { return Platform::AtomicRead(&_exitFlag) == 0; } /// /// Set exit flag to true so thread must exit /// void NotifyExit(); /// /// Stops the calling thread execution until the loading thread ends its execution. /// void Join(); public: /// /// Starts thread execution. /// /// The thread name. /// True if cannot start, otherwise false bool Start(const String& name); /// /// Runs the specified task. /// /// The task. void Run(ContentLoadTask* task); public: // [IRunnable] String ToString() const override; int32 Run() override; void Exit() override; }; /// /// Content loading manager. /// class ContentLoadingManager { friend ContentLoadTask; friend LoadingThread; friend Asset; public: /// /// Checks if current execution context is thread used to load assets. /// /// True if execution is in Load Thread, otherwise false. FORCE_INLINE static bool IsInLoadThread() { return GetCurrentLoadThread() != nullptr; } /// /// Gets content loading thread handle if current thread is one of them. /// /// Current load thread or null if current thread is different. static LoadingThread* GetCurrentLoadThread(); public: /// /// Gets amount of enqueued tasks to perform. /// /// The tasks count. static int32 GetTasksCount(); };