AsyncLoader.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // Copyright (C) 2009-2021, 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. class AsyncLoaderTaskContext
  15. {
  16. public:
  17. /// Pause the async loader.
  18. Bool m_pause = false;
  19. /// Resubmit the same task at the end of the queue.
  20. Bool m_resubmitTask = false;
  21. };
  22. /// Interface for tasks for the AsyncLoader.
  23. class AsyncLoaderTask : public IntrusiveListEnabled<AsyncLoaderTask>
  24. {
  25. public:
  26. virtual ~AsyncLoaderTask()
  27. {
  28. }
  29. virtual ANKI_USE_RESULT Error operator()(AsyncLoaderTaskContext& ctx) = 0;
  30. };
  31. /// Asynchronous resource loader.
  32. class AsyncLoader
  33. {
  34. public:
  35. AsyncLoader();
  36. ~AsyncLoader();
  37. void init(const HeapAllocator<U8>& alloc);
  38. /// Submit a task.
  39. void submitTask(AsyncLoaderTask* task);
  40. /// Create a new asynchronous loading task.
  41. template<typename TTask, typename... TArgs>
  42. TTask* newTask(TArgs&&... args)
  43. {
  44. return m_alloc.template newInstance<TTask>(std::forward<TArgs>(args)...);
  45. }
  46. /// Create and submit a new asynchronous loading task.
  47. template<typename TTask, typename... TArgs>
  48. void submitNewTask(TArgs&&... args)
  49. {
  50. submitTask(newTask<TTask>(std::forward<TArgs>(args)...));
  51. }
  52. /// Pause the loader. This method will block the caller for the current async task to finish. The rest of the
  53. /// tasks in the queue will not be executed until resume is called.
  54. void pause();
  55. /// Resume the async loading.
  56. void resume();
  57. HeapAllocator<U8> getAllocator() const
  58. {
  59. return m_alloc;
  60. }
  61. /// Get the total number of completed tasks.
  62. U64 getCompletedTaskCount() const
  63. {
  64. return m_completedTaskCount.load();
  65. }
  66. private:
  67. HeapAllocator<U8> m_alloc;
  68. Thread m_thread;
  69. Barrier m_barrier = {2};
  70. Mutex m_mtx;
  71. ConditionVariable m_condVar;
  72. IntrusiveList<AsyncLoaderTask> m_taskQueue;
  73. Bool m_quit = false;
  74. Bool m_paused = false;
  75. Bool m_sync = false;
  76. Atomic<U64> m_completedTaskCount = {0};
  77. /// Thread callback
  78. static ANKI_USE_RESULT Error threadCallback(ThreadCallbackInfo& info);
  79. Error threadWorker();
  80. void stop();
  81. };
  82. /// @}
  83. } // end namespace anki