CmAsyncOp.h 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #pragma once
  2. #include "CmPrerequisitesUtil.h"
  3. #include "CmException.h"
  4. #include "boost/any.hpp"
  5. namespace CamelotFramework
  6. {
  7. /**
  8. * @brief Asynchronous operation. Contains uninitialized data until
  9. * hasCompleted returns true.
  10. *
  11. * @note You are allowed (and meant to) to copy this by value.
  12. */
  13. class CM_UTILITY_EXPORT AsyncOp
  14. {
  15. private:
  16. struct AsyncOpData
  17. {
  18. AsyncOpData()
  19. :mIsCompleted(false)
  20. { }
  21. boost::any mReturnValue;
  22. volatile bool mIsCompleted;
  23. };
  24. public:
  25. AsyncOp()
  26. :mData(cm_shared_ptr<AsyncOpData, ScratchAlloc>())
  27. {}
  28. /**
  29. * @brief True if the async operation has completed.
  30. */
  31. bool hasCompleted() const { return mData->mIsCompleted; }
  32. /**
  33. * @brief Mark the async operation as completed.
  34. */
  35. void completeOperation(boost::any returnValue);
  36. /**
  37. * @brief Mark the async operation as completed, without setting a return value;
  38. */
  39. void completeOperation();
  40. /**
  41. * @brief Retrieves the value returned by the async operation.
  42. */
  43. template <typename T>
  44. T getReturnValue() const
  45. {
  46. #if CM_DEBUG_MODE
  47. if(!hasCompleted())
  48. CM_EXCEPT(InternalErrorException, "Trying to get AsyncOp return value but the operation hasn't completed.");
  49. #endif
  50. // Be careful if boost returns bad_any_cast. It doesn't support casting of polymorphic types. Provided and returned
  51. // types must be EXACT. (You'll have to cast the data yourself when completing the operation)
  52. return boost::any_cast<T>(mData->mReturnValue);
  53. }
  54. private:
  55. std::shared_ptr<AsyncOpData> mData;
  56. };
  57. }