AsyncLoader.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Resource/Common.h>
  7. #include <AnKi/Util/Thread.h>
  8. #include <AnKi/Util/List.h>
  9. namespace anki {
  10. // Forward
  11. class AsyncLoader;
  12. /// @addtogroup resource
  13. /// @{
  14. /// @memberof AsyncLoader
  15. enum class AsyncLoaderPriority : U8
  16. {
  17. kHigh,
  18. kMedium,
  19. kLow,
  20. kCount,
  21. kFirst = 0
  22. };
  23. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(AsyncLoaderPriority)
  24. /// @memberof AsyncLoader
  25. class AsyncLoaderTaskContext
  26. {
  27. public:
  28. Bool m_resubmitTask = false; ///< Resubmit the same task at the end of the queue.
  29. AsyncLoaderPriority m_priority = AsyncLoaderPriority::kCount;
  30. };
  31. /// Interface for tasks for the AsyncLoader.
  32. /// @memberof AsyncLoader
  33. class AsyncLoaderTask : public IntrusiveListEnabled<AsyncLoaderTask>
  34. {
  35. public:
  36. virtual ~AsyncLoaderTask()
  37. {
  38. }
  39. virtual Error operator()(AsyncLoaderTaskContext& ctx) = 0;
  40. };
  41. /// Asynchronous resource loader.
  42. class AsyncLoader : public MakeSingleton<AsyncLoader>
  43. {
  44. public:
  45. AsyncLoader();
  46. ~AsyncLoader();
  47. /// Create a new asynchronous loading task.
  48. template<typename TTask, typename... TArgs>
  49. TTask* newTask(TArgs&&... args)
  50. {
  51. return newInstance<TTask>(ResourceMemoryPool::getSingleton(), std::forward<TArgs>(args)...);
  52. }
  53. /// Submit a task.
  54. void submitTask(AsyncLoaderTask* task, AsyncLoaderPriority priority);
  55. /// Get the total number of completed tasks.
  56. U32 getTasksInFlightCount() const
  57. {
  58. return m_tasksInFlightCount.load();
  59. }
  60. private:
  61. Thread m_thread;
  62. Mutex m_mtx;
  63. ConditionVariable m_condVar;
  64. Array<IntrusiveList<AsyncLoaderTask>, U32(AsyncLoaderPriority::kCount)> m_taskQueues;
  65. Bool m_quit = false;
  66. Atomic<U32> m_tasksInFlightCount = {0};
  67. /// Thread callback
  68. static Error threadCallback(ThreadCallbackInfo& info);
  69. Error threadWorker();
  70. void stop();
  71. };
  72. /// @}
  73. } // end namespace anki