FileStateTests.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. /*******************************************************************************
  2. The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
  3. Technology released in source code form as part of the game integration package.
  4. The content of this file may not be used without valid licenses to the
  5. AUDIOKINETIC Wwise Technology.
  6. Note that the use of the game engine is subject to the Unreal(R) Engine End User
  7. License Agreement at https://www.unrealengine.com/en-US/eula/unreal
  8. License Usage
  9. Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
  10. this file in accordance with the end user license agreement provided with the
  11. software or, alternatively, in accordance with the terms contained
  12. in a written agreement between you and Audiokinetic Inc.
  13. Copyright (c) 2023 Audiokinetic Inc.
  14. *******************************************************************************/
  15. #include "Wwise/WwiseUnitTests.h"
  16. #if WWISE_UNIT_TESTS
  17. #include "Wwise/Mock/WwiseMockFileState.h"
  18. #include <atomic>
  19. WWISE_TEST_CASE(FileHandler_FileState_Smoke, "Wwise::FileHandler::FileState_Smoke", "[ApplicationContextMask][SmokeFilter]")
  20. {
  21. SECTION("Static")
  22. {
  23. static_assert(!std::is_constructible<FWwiseFileState>::value, "File State cannot be constructed through a default parameter");
  24. static_assert(!std::is_copy_constructible<FWwiseFileState>::value, "Cannot copy a File State");
  25. static_assert(!std::is_copy_assignable<FWwiseFileState>::value, "Cannot assign to a File State");
  26. static_assert(!std::is_move_constructible<FWwiseFileState>::value, "Cannot move-construct a File State");
  27. }
  28. SECTION("Instantiation")
  29. {
  30. FWwiseMockFileState(0);
  31. FWwiseMockFileState(1);
  32. FWwiseMockFileState(2);
  33. FWwiseMockFileState(3);
  34. }
  35. SECTION("Loading Streaming File")
  36. {
  37. FEventRef Done;
  38. FWwiseMockFileState File(10);
  39. File.bIsStreamedState = FWwiseMockFileState::OptionalBool::True;
  40. bool bDeleted{ false };
  41. File.IncrementCountAsync(EWwiseFileStateOperationOrigin::Loading, [&File, &Done, &bDeleted](bool bResult) mutable
  42. {
  43. CHECK(bResult);
  44. CHECK(File.State == FWwiseFileState::EState::Opened);
  45. File.DecrementCountAsync(EWwiseFileStateOperationOrigin::Loading,
  46. [&File, &bDeleted](FWwiseFileState::FDecrementCountCallback&& Callback) mutable
  47. {
  48. CHECK(File.State == FWwiseFileState::EState::Closed);
  49. bDeleted = true;
  50. Callback();
  51. },
  52. [&Done, &bDeleted]() mutable
  53. {
  54. CHECK(bDeleted);
  55. Done->Trigger();
  56. });
  57. });
  58. CHECK(Done->Wait(1000));
  59. }
  60. SECTION("Streaming File")
  61. {
  62. FEventRef Done;
  63. FWwiseMockFileState File(20);
  64. File.bIsStreamedState = FWwiseMockFileState::OptionalBool::True;
  65. bool bDeleted{ false };
  66. File.IncrementCountAsync(EWwiseFileStateOperationOrigin::Streaming, [&File, &Done, &bDeleted](bool bResult) mutable
  67. {
  68. CHECK(bResult);
  69. CHECK(File.State == FWwiseFileState::EState::Loaded);
  70. File.DecrementCountAsync(EWwiseFileStateOperationOrigin::Streaming,
  71. [&File, &bDeleted](FWwiseFileState::FDecrementCountCallback&& Callback) mutable
  72. {
  73. CHECK(File.State == FWwiseFileState::EState::Closed);
  74. bDeleted = true;
  75. Callback();
  76. },
  77. [&Done, &bDeleted]() mutable
  78. {
  79. CHECK(bDeleted);
  80. Done->Trigger();
  81. });
  82. });
  83. CHECK(Done->Wait(1000));
  84. }
  85. SECTION("Delete in Decrement")
  86. {
  87. FEventRef Done;
  88. auto* File = new FWwiseMockFileState(30);
  89. bool bDeleted{ false };
  90. File->IncrementCountAsync(EWwiseFileStateOperationOrigin::Loading, [File, &Done, &bDeleted](bool bResult) mutable
  91. {
  92. CHECK(bResult);
  93. CHECK(File->State == FWwiseFileState::EState::Loaded);
  94. File->DecrementCountAsync(EWwiseFileStateOperationOrigin::Loading,
  95. [File, &bDeleted](FWwiseFileState::FDecrementCountCallback&& Callback) mutable
  96. {
  97. CHECK(File->State == FWwiseFileState::EState::Closed);
  98. delete File;
  99. bDeleted = true;
  100. Callback();
  101. },
  102. [&Done, &bDeleted]() mutable
  103. {
  104. CHECK(bDeleted);
  105. Done->Trigger();
  106. });
  107. });
  108. CHECK(Done->Wait(1000));
  109. }
  110. SECTION("Ordered callbacks")
  111. {
  112. FEventRef Done;
  113. FWwiseMockFileState File(40);
  114. File.bIsStreamedState = FWwiseMockFileState::OptionalBool::True;
  115. int Order = 0;
  116. constexpr const int Count = 10;
  117. for (int NumOp = 0; NumOp < Count; ++NumOp)
  118. {
  119. File.IncrementCountAsync(EWwiseFileStateOperationOrigin::Loading, [NumOp, &Order](bool bResult) mutable
  120. {
  121. CHECK(NumOp*4+0 == Order);
  122. Order++;
  123. });
  124. File.DecrementCountAsync(EWwiseFileStateOperationOrigin::Loading,
  125. [](FWwiseFileState::FDecrementCountCallback&& Callback) mutable
  126. {
  127. Callback();
  128. },
  129. [NumOp, &Order]() mutable
  130. {
  131. CHECK(NumOp*4+1 == Order);
  132. Order++;
  133. });
  134. File.IncrementCountAsync(EWwiseFileStateOperationOrigin::Loading, [NumOp, &Order](bool bResult) mutable
  135. {
  136. CHECK(NumOp*4+2 == Order);
  137. Order++;
  138. });
  139. File.DecrementCountAsync(EWwiseFileStateOperationOrigin::Loading,
  140. [&Done](FWwiseFileState::FDecrementCountCallback&& Callback) mutable
  141. {
  142. Callback();
  143. Done->Trigger();
  144. },
  145. [NumOp, &Order]() mutable
  146. {
  147. CHECK(NumOp*4+3 == Order);
  148. Order++;
  149. });
  150. }
  151. CHECK(Done->Wait(10000));
  152. }
  153. }
  154. WWISE_TEST_CASE(FileHandler_FileState, "Wwise::FileHandler::FileState", "[ApplicationContextMask][ProductFilter]")
  155. {
  156. SECTION("Reloading Streaming File")
  157. {
  158. FEventRef Done;
  159. FWwiseMockFileState File(1000);
  160. File.bIsStreamedState = FWwiseMockFileState::OptionalBool::True;
  161. bool bDeleted{ false };
  162. bool bInitialDecrementDone{ false };
  163. File.IncrementCountAsync(EWwiseFileStateOperationOrigin::Loading, [&File, &bDeleted](bool bResult) mutable
  164. {
  165. CHECK(bResult);
  166. CHECK(File.State == FWwiseFileState::EState::Opened);
  167. });
  168. File.DecrementCountAsync(EWwiseFileStateOperationOrigin::Loading,
  169. [](FWwiseFileState::FDecrementCountCallback&& Callback) mutable
  170. {
  171. CHECK(false);
  172. Callback();
  173. },
  174. [&File, &bDeleted, &bInitialDecrementDone]() mutable
  175. {
  176. bInitialDecrementDone = true;
  177. });
  178. File.IncrementCountAsync(EWwiseFileStateOperationOrigin::Loading, [&File, &bDeleted](bool bResult) mutable
  179. {
  180. CHECK(bResult);
  181. });
  182. File.DecrementCountAsync(EWwiseFileStateOperationOrigin::Loading,
  183. [&File, &bDeleted](FWwiseFileState::FDecrementCountCallback&& Callback) mutable
  184. {
  185. CHECK(File.State == FWwiseFileState::EState::Closed);
  186. bDeleted = true;
  187. Callback();
  188. },
  189. [&Done, &bDeleted]() mutable
  190. {
  191. CHECK(bDeleted);
  192. Done->Trigger();
  193. });
  194. CHECK(Done->Wait(1000));
  195. CHECK(bInitialDecrementDone);
  196. }
  197. SECTION("Restreaming File")
  198. {
  199. FEventRef Done;
  200. FWwiseMockFileState File(1010);
  201. File.bIsStreamedState = FWwiseMockFileState::OptionalBool::True;
  202. bool bDeleted{ false };
  203. bool bInitialDecrementDone{ false };
  204. File.IncrementCountAsync(EWwiseFileStateOperationOrigin::Streaming, [&File, &bDeleted](bool bResult) mutable
  205. {
  206. });
  207. File.DecrementCountAsync(EWwiseFileStateOperationOrigin::Streaming,
  208. [](FWwiseFileState::FDecrementCountCallback&& Callback) mutable
  209. {
  210. // Delete State should never be called, since the last one should delete our object
  211. CHECK(false);
  212. Callback();
  213. },
  214. [&File, &bDeleted, &bInitialDecrementDone]() mutable
  215. {
  216. bInitialDecrementDone = true;
  217. });
  218. File.IncrementCountAsync(EWwiseFileStateOperationOrigin::Streaming, [&File, &bDeleted](bool bResult) mutable
  219. {
  220. });
  221. File.DecrementCountAsync(EWwiseFileStateOperationOrigin::Streaming,
  222. [&File, &bDeleted](FWwiseFileState::FDecrementCountCallback&& Callback) mutable
  223. {
  224. CHECK(File.State == FWwiseFileState::EState::Closed);
  225. bDeleted = true;
  226. Callback();
  227. },
  228. [&Done, &bDeleted]() mutable
  229. {
  230. CHECK(bDeleted);
  231. Done->Trigger();
  232. });
  233. CHECK(Done->Wait(1000));
  234. CHECK(bInitialDecrementDone);
  235. }
  236. }
  237. /*
  238. WWISE_TEST_CASE(FileHandler_FileState_Perf, "Wwise::FileHandler::FileState_Perf", "[ApplicationContextMask][PerfFilter]")
  239. {
  240. }
  241. */
  242. WWISE_TEST_CASE(FileHandler_FileState_Stress, "Wwise::FileHandler::FileState_Stress", "[ApplicationContextMask][StressFilter]")
  243. {
  244. SECTION("Stress Open and Streams")
  245. {
  246. constexpr const int StateCount = 10;
  247. constexpr const int LoadCount = 10;
  248. constexpr const int WiggleCount = 2;
  249. FEventRef Dones[StateCount];
  250. FWwiseMockFileState* Files[StateCount];
  251. for (int StateIter = 0; StateIter < StateCount; ++StateIter)
  252. {
  253. FEventRef& Done(Dones[StateIter]);
  254. Files[StateIter] = new FWwiseMockFileState(10000 + StateIter);
  255. FWwiseMockFileState& File = *Files[StateIter];
  256. File.bIsStreamedState = FWwiseMockFileState::OptionalBool::True;
  257. for (int LoadIter = 0; LoadIter < LoadCount; ++LoadIter)
  258. {
  259. const EWwiseFileStateOperationOrigin FirstOp = (StateIter&1)==0 ? EWwiseFileStateOperationOrigin::Loading : EWwiseFileStateOperationOrigin::Streaming;
  260. const EWwiseFileStateOperationOrigin SecondOp = (StateIter&1)==1 ? EWwiseFileStateOperationOrigin::Loading : EWwiseFileStateOperationOrigin::Streaming;
  261. FFunctionGraphTask::CreateAndDispatchWhenReady([Op = FirstOp, &Done, &File, WiggleCount]() mutable
  262. {
  263. for (int WiggleIter = 0; WiggleIter < WiggleCount; ++WiggleIter)
  264. {
  265. File.IncrementCountAsync(Op, [](bool){});
  266. File.DecrementCountAsync(Op, [](FWwiseFileState::FDecrementCountCallback&& InCallback){ InCallback(); }, []{});
  267. }
  268. File.IncrementCountAsync(Op, [Op, &Done, &File, WiggleCount](bool)
  269. {
  270. for (int WiggleIter = 0; WiggleIter < WiggleCount; ++WiggleIter)
  271. {
  272. File.DecrementCountAsync(Op, [](FWwiseFileState::FDecrementCountCallback&& InCallback){ InCallback(); }, []{});
  273. File.IncrementCountAsync(Op, [](bool){});
  274. }
  275. File.DecrementCountAsync(Op, [&Done](FWwiseFileState::FDecrementCountCallback&& InCallback)
  276. {
  277. Done->Trigger();
  278. InCallback();
  279. }, []{});
  280. });
  281. });
  282. FFunctionGraphTask::CreateAndDispatchWhenReady([Op = SecondOp, &Done, &File, WiggleCount]() mutable
  283. {
  284. for (int WiggleIter = 0; WiggleIter < WiggleCount; ++WiggleIter)
  285. {
  286. File.IncrementCountAsync(Op, [](bool){});
  287. File.DecrementCountAsync(Op, [](FWwiseFileState::FDecrementCountCallback&& InCallback){ InCallback(); }, []{});
  288. }
  289. File.IncrementCountAsync(Op, [Op, &Done, &File, WiggleCount](bool)
  290. {
  291. for (int WiggleIter = 0; WiggleIter < WiggleCount; ++WiggleIter)
  292. {
  293. File.DecrementCountAsync(Op, [](FWwiseFileState::FDecrementCountCallback&& InCallback){ InCallback(); }, []{});
  294. File.IncrementCountAsync(Op, [](bool){});
  295. }
  296. File.DecrementCountAsync(Op, [&Done](FWwiseFileState::FDecrementCountCallback&& InCallback)
  297. {
  298. Done->Trigger();
  299. InCallback();
  300. }, []{});
  301. });
  302. });
  303. }
  304. }
  305. for (int StateIter = 0; StateIter < StateCount; ++StateIter)
  306. {
  307. FEventRef& Done(Dones[StateIter]);
  308. FWwiseMockFileState* File = Files[StateIter];
  309. CHECK(Done->Wait(100000));
  310. delete File;
  311. }
  312. }
  313. }
  314. #endif // WWISE_UNIT_TESTS