2
0

AsyncLoader.h 2.2 KB

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