CmCommandQueue.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #pragma once
  2. #include "CmPrerequisites.h"
  3. #include "CmAsyncOp.h"
  4. #include "CmCommonEnums.h"
  5. #include "boost/function.hpp"
  6. namespace CamelotEngine
  7. {
  8. /**
  9. * @brief Contains a list of commands that can be queued by one thread,
  10. * and executed by another.
  11. */
  12. class CommandQueue
  13. {
  14. public:
  15. struct Command
  16. {
  17. Command(boost::function<void(AsyncOp&)> _callback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
  18. :callbackWithReturnValue(_callback), returnsValue(true), notifyWhenComplete(_notifyWhenComplete), callbackId(_callbackId)
  19. { }
  20. Command(boost::function<void()> _callback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
  21. :callback(_callback), returnsValue(false), notifyWhenComplete(_notifyWhenComplete), callbackId(_callbackId)
  22. { }
  23. boost::function<void()> callback;
  24. boost::function<void(AsyncOp&)> callbackWithReturnValue;
  25. AsyncOp asyncOp;
  26. bool returnsValue;
  27. UINT32 callbackId;
  28. bool notifyWhenComplete;
  29. };
  30. /**
  31. * @brief Constructor.
  32. *
  33. * @param threadId Identifier for the thread the command queue will be used on.
  34. * @param allowAllThreads Only matters for debug purposes. If false, then the queue
  35. * will throw an exception if accessed outside of the creation thread
  36. * (If in debug mode).
  37. *
  38. * When you want to allow multiple threads to access it, set this to true,
  39. * and also make sure you sync access to the queue properly.
  40. *
  41. */
  42. CommandQueue(CM_THREAD_ID_TYPE threadId, bool allowAllThreads = false);
  43. ~CommandQueue();
  44. CM_THREAD_ID_TYPE getThreadId() const { return mMyThreadId; }
  45. /**
  46. * @brief Queue up a new command to execute. Make sure the provided function has all of its
  47. * parameters properly bound. Last parameter must be unbound and of AsyncOp&amp; type.
  48. * This is used to signal that the command is completed, and also for storing the return
  49. * value.
  50. *
  51. * @note Callback method also needs to call AsyncOp::markAsResolved once it is done
  52. * processing. (If it doesn't it will still be called automatically, but the return
  53. * value will default to nullptr)
  54. *
  55. * @param _notifyWhenComplete (optional) Call the notify method (provided in the call to CommandQueue::playback)
  56. * when the command is complete.
  57. * @param _callbackId (optional) Identifier for the callback so you can then later find it
  58. * if needed.
  59. *
  60. * @return Async operation object you can continuously check until the command completes. After
  61. * it completes AsyncOp::isResolved will return true and return data will be valid (if
  62. * the callback provided any).
  63. */
  64. AsyncOp queueReturn(boost::function<void(AsyncOp&)> commandCallback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0);
  65. /**
  66. * @brief Queue up a new command to execute. Make sure the provided function has all of its
  67. * parameters properly bound. Provided command is not expected to return a value. If you
  68. * wish to return a value from the callback use the other overload of queueCommand which
  69. * accepts AsyncOp parameter.
  70. *
  71. * @param _notifyWhenComplete (optional) Call the notify method (provided in the call to CommandQueue::playback)
  72. * when the command is complete.
  73. * @param _callbackId (optional) Identifier for the callback so you can then later find
  74. * it if needed.
  75. */
  76. void queue(boost::function<void()> commandCallback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0);
  77. /**
  78. * @brief Returns a copy of all queued commands and makes room for new ones. Must be called from the thread
  79. * that created the command queue. Returned commands MUST be passed to playbackCommands.
  80. */
  81. std::queue<Command>* flush();
  82. /**
  83. * @brief Plays all provided commands. Should only be called from the render thread. To get the
  84. * commands call flushCommands().
  85. *
  86. * @param notifyCallback Callback that will be called if a command that has "notifyOnComplete" flag set.
  87. * The callback will receive "callbackId" of the command.
  88. */
  89. void playback(std::queue<Command>* commands, boost::function<void(UINT32)> notifyCallback);
  90. /**
  91. * @brief Plays all provided commands. Should only be called from the render thread. To get
  92. * the commands call flushCommands().
  93. */
  94. void playback(std::queue<Command>* commands);
  95. /**
  96. * @brief Returns true if no commands are queued.
  97. */
  98. bool isEmpty();
  99. private:
  100. std::queue<Command>* mCommands;
  101. bool mAllowAllThreads;
  102. CM_THREAD_ID_TYPE mMyThreadId;
  103. CM_MUTEX(mCommandBufferMutex);
  104. };
  105. }