2
0

CmCommandQueue.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include "CmCommandQueue.h"
  2. #include "CmException.h"
  3. #include "CmRenderSystemManager.h"
  4. #include "CmRenderSystem.h"
  5. #include "CmDebug.h"
  6. namespace CamelotEngine
  7. {
  8. CommandQueue::CommandQueue(CM_THREAD_ID_TYPE threadId, bool allowAllThreads)
  9. :mMyThreadId(threadId), mAllowAllThreads(allowAllThreads)
  10. {
  11. mCommands = new vector<Command>::type();
  12. }
  13. CommandQueue::~CommandQueue()
  14. {
  15. #if CM_DEBUG_MODE
  16. #if CM_THREAD_SUPPORT != 0
  17. if(!mAllowAllThreads && CM_THREAD_CURRENT_ID != mMyThreadId)
  18. {
  19. CM_EXCEPT(InternalErrorException, "Command queue accessed outside of its creation thread.");
  20. }
  21. #endif
  22. #endif
  23. if(mCommands != nullptr)
  24. delete mCommands;
  25. }
  26. AsyncOp CommandQueue::queueReturn(boost::function<void(AsyncOp&)> commandCallback, bool _notifyWhenComplete, UINT32 _callbackId)
  27. {
  28. #if CM_DEBUG_MODE
  29. #if CM_THREAD_SUPPORT != 0
  30. if(!mAllowAllThreads && CM_THREAD_CURRENT_ID != mMyThreadId)
  31. {
  32. CM_EXCEPT(InternalErrorException, "Command queue accessed outside of its creation thread.");
  33. }
  34. #endif
  35. #endif
  36. Command newCommand(commandCallback, _notifyWhenComplete, _callbackId);
  37. mCommands->push_back(newCommand);
  38. return newCommand.asyncOp;
  39. }
  40. void CommandQueue::queue(boost::function<void()> commandCallback, bool _notifyWhenComplete, UINT32 _callbackId)
  41. {
  42. #if CM_DEBUG_MODE
  43. #if CM_THREAD_SUPPORT != 0
  44. if(!mAllowAllThreads && CM_THREAD_CURRENT_ID != mMyThreadId)
  45. {
  46. CM_EXCEPT(InternalErrorException, "Command queue accessed outside of its creation thread.");
  47. }
  48. #endif
  49. #endif
  50. Command newCommand(commandCallback, _notifyWhenComplete, _callbackId);
  51. mCommands->push_back(newCommand);
  52. }
  53. vector<CommandQueue::Command>::type* CommandQueue::flush()
  54. {
  55. vector<Command>::type* oldCommands = nullptr;
  56. {
  57. CM_LOCK_MUTEX(mCommandBufferMutex);
  58. oldCommands = mCommands;
  59. mCommands = new vector<Command>::type();
  60. }
  61. return oldCommands;
  62. }
  63. void CommandQueue::playback(vector<CommandQueue::Command>::type* commands, boost::function<void(UINT32)> notifyCallback)
  64. {
  65. #if CM_DEBUG_MODE
  66. RenderSystem* rs = RenderSystemManager::getActive();
  67. if(rs->getRenderThreadId() != CM_THREAD_CURRENT_ID)
  68. CM_EXCEPT(InternalErrorException, "This method should only be called from the render thread.");
  69. #endif
  70. if(commands == nullptr)
  71. return;
  72. for(auto iter = commands->begin(); iter != commands->end(); ++iter)
  73. {
  74. Command& command = (*iter);
  75. if(command.returnsValue)
  76. {
  77. command.callbackWithReturnValue(command.asyncOp);
  78. if(!command.asyncOp.hasCompleted())
  79. {
  80. LOGDBG("Async operation return value wasn't resolved properly. Resolving automatically to nullptr. " \
  81. "Make sure to complete the operation before returning from the command callback method.");
  82. command.asyncOp.completeOperation(nullptr);
  83. }
  84. }
  85. else
  86. {
  87. command.callback();
  88. }
  89. if(command.notifyWhenComplete && !notifyCallback.empty())
  90. {
  91. notifyCallback(command.callbackId);
  92. }
  93. }
  94. delete commands;
  95. }
  96. void CommandQueue::playback(vector<Command>::type* commands)
  97. {
  98. playback(commands, boost::function<void(UINT32)>());
  99. }
  100. bool CommandQueue::isEmpty()
  101. {
  102. CM_LOCK_MUTEX(mCommandBufferMutex);
  103. if(mCommands != nullptr && mCommands->size() > 0)
  104. return false;
  105. return true;
  106. }
  107. }