您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

716 行
15 KiB

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "../types.hpp"
  5. u32 hm_hash(u32 u);
  6. inline bool hm_objects_match(u32 a, u32 b);
  7. struct Key;
  8. u32 hm_hash(Key u);
  9. inline bool hm_objects_match(Key a, Key b);
  10. #define ZoneScoped
  11. #define ZoneScopedN(name)
  12. #define USE_FTB_MALLOC
  13. #include "../print.hpp"
  14. #include "../testing.hpp"
  15. #include "../bucket_allocator.hpp"
  16. #include "../error.hpp"
  17. #include "../hooks.hpp"
  18. #include "../hashmap.hpp"
  19. #include "../stacktrace.hpp"
  20. #include "../scheduler.cpp"
  21. #include "../error.hpp"
  22. u32 hm_hash(u32 u) {
  23. return ((u64)u * 2654435761) % 4294967296;
  24. }
  25. inline bool hm_objects_match(u32 a, u32 b) {
  26. return a == b;
  27. }
  28. struct Key {
  29. int x;
  30. int y;
  31. int z;
  32. };
  33. u32 hm_hash(Key u) {
  34. return ((u.y ^ (u.x << 1)) >> 1) ^ u.z;
  35. }
  36. inline bool hm_objects_match(Key a, Key b) {
  37. return a.x == b.x
  38. && a.y == b.y
  39. && a.z == b.z;
  40. }
  41. auto print_dots(FILE* f) -> u32 {
  42. return print_to_file(f, "...");
  43. }
  44. proc is_sorted = [](Array_List<s32> list) -> bool {
  45. for (u32 i = 0; i < list.count - 1; ++i) {
  46. if (list.data[i] > list.data[i+1])
  47. return false;
  48. }
  49. return true;
  50. };
  51. proc is_sorted_vp = [](Array_List<void*> list) -> bool {
  52. for (u32 i = 0; i < list.count - 1; ++i) {
  53. if (list.data[i] > list.data[i+1])
  54. return false;
  55. }
  56. return true;
  57. };
  58. auto test_printer() -> void {
  59. u32 arr[] = {1,2,3,4,1,1,3};
  60. f32 f_arr[] = {1.1,2.1,3.2};
  61. register_printer("dots", print_dots, Printer_Function_Type::_void);
  62. u32 u1 = -1;
  63. u64 u2 = -1;
  64. char* str;
  65. print_to_string(&str, " - %{dots[5]} %{->} <> %{->,2}\n", &u1, &arr, nullptr);
  66. print("---> %{->char}", str);
  67. print(" - %{dots[3]}\n");
  68. print(" - %{u32} %{u64}\n", u1, u2);
  69. print(" - %{u32} %{u32} %{u32}\n", 2, 5, 7);
  70. print(" - %{f32} %{f32} %{f32}\n", 2.0, 5.0, 7.0);
  71. print(" - %{u32} %{bool} %{->char}\n", 2, true, "hello");
  72. print(" - %{f32[3]}\n", f_arr);
  73. print(" - %{f32,3}\n", 44.9, 55.1, 66.2);
  74. print(" - %{u32[5]}\n", arr);
  75. print(" - %{u32[*]}\n", arr, 4);
  76. print(" - %{u32,5}\n", 1,2,3,4,1,2);
  77. print(" - %{unknown%d}\n", 1);
  78. print(" - %{s32,3}\n", -1,200,-300);
  79. print(" - %{->} <> %{->,2}\n", &u1, &arr, nullptr);
  80. print("%{->char}%{->char}%{->char}",
  81. true ? "general " : "",
  82. false ? "validation " : "",
  83. false ? "performance " : "");
  84. // print("%{->char}%{->char}\n\n", "hallo","");
  85. }
  86. auto test_hm() -> void {
  87. Hash_Map<u32, u32> h1;
  88. h1.alloc();
  89. defer { h1.dealloc(); };
  90. h1.set_object(1, 2);
  91. h1.set_object(2, 4);
  92. h1.set_object(3, 6);
  93. h1.set_object(4, 8);
  94. assert(h1.key_exists(1), "key shoud exist");
  95. assert(h1.key_exists(2), "key shoud exist");
  96. assert(h1.key_exists(3), "key shoud exist");
  97. assert(h1.key_exists(4), "key shoud exist");
  98. assert(!h1.key_exists(5), "key shoud not exist");
  99. assert(h1.get_object(1) == 2, "value should be correct");
  100. assert(h1.get_object(2) == 4, "value should be correct");
  101. assert(h1.get_object(3) == 6, "value should be correct");
  102. assert(h1.get_object(4) == 8, "value should be correct");
  103. Hash_Map<Key, u32> h2;
  104. h2.alloc();
  105. defer { h2.dealloc(); };
  106. h2.set_object({.x = 1, .y = 2, .z = 3}, 1);
  107. h2.set_object({.x = 3, .y = 3, .z = 3}, 3);
  108. assert(h2.key_exists({.x = 1, .y = 2, .z = 3}), "key shoud exist");
  109. assert(h2.key_exists({.x = 3, .y = 3, .z = 3}), "key shoud exist");
  110. assert(h2.get_object({.x = 1, .y = 2, .z = 3}) == 1, "value should be correct");
  111. assert(h2.get_object({.x = 3, .y = 3, .z = 3}) == 3, "value should be correct");
  112. h2.for_each([] (Key k, u32 v, u32 i) {
  113. print("%{s32} %{u32} %{u32}\n", k.x, v, i);
  114. });
  115. }
  116. proc test_stack_array_lists() -> testresult {
  117. Stack_Array_List<int> list(20);
  118. assert_equal_int(list.count, 0);
  119. assert_equal_int(list.length, 20);
  120. assert(list.data != NULL, "list should have some data allocated");
  121. // test sum of empty list
  122. int sum = 0;
  123. int iter = 0;
  124. for (auto e : list) {
  125. sum += e;
  126. iter++;
  127. }
  128. assert_equal_int(sum, 0);
  129. assert_equal_int(iter, 0);
  130. // append some elements
  131. list.append(1);
  132. list.append(2);
  133. list.append(3);
  134. list.append(4);
  135. assert_equal_int(list.count, 4);
  136. assert_equal_int(list.length, 20);
  137. // test sum again
  138. sum = 0;
  139. iter = 0;
  140. for (auto e : list) {
  141. sum += e;
  142. iter++;
  143. }
  144. assert_equal_int(sum, 10);
  145. assert_equal_int(iter, 4);
  146. // bracketed access
  147. list[0] = 11;
  148. list[1] = 3;
  149. list[2] = 2;
  150. list.append(5);
  151. // test sum again
  152. sum = 0;
  153. iter = 0;
  154. for (auto e : list) {
  155. sum += e;
  156. ++iter;
  157. }
  158. assert_equal_int(sum, 25);
  159. assert_equal_int(iter, 5);
  160. // assert memory correct
  161. assert_equal_int(list.data[0], 11);
  162. assert_equal_int(list.data[1], 3);
  163. assert_equal_int(list.data[2], 2);
  164. assert_equal_int(list.data[3], 4);
  165. assert_equal_int(list.data[4], 5);
  166. // removing some indices
  167. list.remove_index(4);
  168. // test sum again
  169. sum = 0;
  170. iter = 0;
  171. for (auto e : list) {
  172. sum += e;
  173. ++iter;
  174. }
  175. assert_equal_int(sum, 20);
  176. assert_equal_int(iter, 4);
  177. // removing some indices
  178. list.remove_index(1);
  179. list.remove_index(0);
  180. // test sum again
  181. sum = 0;
  182. iter = 0;
  183. for (auto e : list) {
  184. sum += e;
  185. ++iter;
  186. }
  187. assert_equal_int(sum, 6);
  188. assert_equal_int(iter, 2);
  189. return pass;
  190. }
  191. proc test_queue() -> testresult {
  192. Queue<int> q;
  193. q.alloc(4);
  194. defer {
  195. q.dealloc();
  196. };
  197. assert(q.is_empty(), "queue should start empty");
  198. assert_equal_int(q.get_count(), 0);
  199. q.push_back(1);
  200. q.push_back(2);
  201. q.push_back(3);
  202. assert_equal_int(q.get_count(), 3);
  203. assert_equal_int(q.get_next(), 1);
  204. assert_equal_int(q.get_count(), 2);
  205. assert(!q.is_empty(), "should not be empty");
  206. assert_equal_int(q.get_next(), 2);
  207. assert_equal_int(q.get_count(), 1);
  208. q.push_back(4);
  209. assert_equal_int(q.get_count(), 2);
  210. assert_equal_int(q.get_next(), 3);
  211. assert_equal_int(q.get_count(), 1);
  212. assert(!q.is_empty(), "should not be empty");
  213. assert_equal_int(q.get_next(), 4);
  214. assert(q.is_empty(), "should be empty");
  215. assert_equal_int(q.get_count(), 0);
  216. return pass;
  217. }
  218. proc test_array_lists_adding_and_removing() -> testresult {
  219. // test adding and removing
  220. Array_List<s32> list;
  221. list.alloc();
  222. defer {
  223. list.dealloc();
  224. };
  225. list.append(1);
  226. list.append(2);
  227. list.append(3);
  228. list.append(4);
  229. assert_equal_int(list.count, 4);
  230. list.remove_index(0);
  231. assert_equal_int(list.count, 3);
  232. assert_equal_int(list[0], 4);
  233. assert_equal_int(list[1], 2);
  234. assert_equal_int(list[2], 3);
  235. list.remove_index(2);
  236. assert_equal_int(list.count, 2);
  237. assert_equal_int(list[0], 4);
  238. assert_equal_int(list[1], 2);
  239. return pass;
  240. }
  241. proc test_array_lists_sorting() -> testresult {
  242. //
  243. //
  244. // Test simple numbers
  245. //
  246. //
  247. Array_List<s32> list;
  248. list.alloc();
  249. defer {
  250. list.dealloc();
  251. };
  252. list.append(1);
  253. list.append(2);
  254. list.append(3);
  255. list.append(4);
  256. list.sort();
  257. assert_equal_int(is_sorted(list), true);
  258. list.append(4);
  259. list.append(2);
  260. list.append(1);
  261. assert_equal_int(is_sorted(list), false);
  262. list.sort();
  263. assert_equal_int(is_sorted(list), true);
  264. list.clear();
  265. list.extend({
  266. 8023, 7529, 2392, 7110,
  267. 3259, 2484, 9695, 2199,
  268. 6729, 9009, 8429, 7208});
  269. assert_equal_int(is_sorted(list), false);
  270. list.sort();
  271. assert_equal_int(is_sorted(list), true);
  272. //
  273. //
  274. // Test adding and removing
  275. //
  276. //
  277. Array_List<s32> list1;
  278. list1.alloc();
  279. defer {
  280. list1.dealloc();
  281. };
  282. list1.append(1);
  283. list1.append(2);
  284. list1.append(3);
  285. list1.append(4);
  286. list1.sort();
  287. assert_equal_int(list1.count, 4);
  288. assert_equal_int(list1[0], 1);
  289. assert_equal_int(list1[1], 2);
  290. assert_equal_int(list1[2], 3);
  291. assert_equal_int(list1[3], 4);
  292. assert_equal_int(is_sorted(list1), true);
  293. list1.append(0);
  294. list1.append(5);
  295. assert_equal_int(list1.count, 6);
  296. list1.sort();
  297. assert_equal_int(list1[0], 0);
  298. assert_equal_int(list1[1], 1);
  299. assert_equal_int(list1[2], 2);
  300. assert_equal_int(list1[3], 3);
  301. assert_equal_int(list1[4], 4);
  302. assert_equal_int(list1[5], 5);
  303. assert_equal_int(is_sorted(list1), true);
  304. //
  305. //
  306. //
  307. //
  308. // pointer list
  309. Array_List<void*> al;
  310. al.alloc();
  311. defer {
  312. al.dealloc();
  313. };
  314. al.append((void*)0x1703102F100);
  315. al.append((void*)0x1703102F1D8);
  316. al.append((void*)0x1703102F148);
  317. al.append((void*)0x1703102F190);
  318. al.append((void*)0x1703102F190);
  319. al.append((void*)0x1703102F1D8);
  320. assert_equal_int(is_sorted_vp(al), false);
  321. al.sort();
  322. assert_equal_int(is_sorted_vp(al), true);
  323. assert_not_equal_int(al.sorted_find((void*)0x1703102F100), -1);
  324. assert_not_equal_int(al.sorted_find((void*)0x1703102F1D8), -1);
  325. assert_not_equal_int(al.sorted_find((void*)0x1703102F148), -1);
  326. assert_not_equal_int(al.sorted_find((void*)0x1703102F190), -1);
  327. assert_not_equal_int(al.sorted_find((void*)0x1703102F190), -1);
  328. assert_not_equal_int(al.sorted_find((void*)0x1703102F1D8), -1);
  329. return pass;
  330. }
  331. proc test_array_lists_searching() -> testresult {
  332. Array_List<s32> list1;
  333. list1.alloc();
  334. defer {
  335. list1.dealloc();
  336. };
  337. list1.append(1);
  338. list1.append(2);
  339. list1.append(3);
  340. list1.append(4);
  341. s32 index = list1.sorted_find(3);
  342. assert_equal_int(index, 2);
  343. index = list1.sorted_find(1);
  344. assert_equal_int(index, 0);
  345. index = list1.sorted_find(5);
  346. assert_equal_int(index, -1);
  347. return pass;
  348. }
  349. proc test_bucket_allocator() -> testresult {
  350. Bucket_Allocator<s32> ba;
  351. ba.alloc();
  352. defer {
  353. ba.dealloc();
  354. };
  355. s32* s1 = ba.allocate();
  356. s32* s2 = ba.allocate();
  357. s32* s3 = ba.allocate();
  358. s32* s4 = ba.allocate();
  359. s32* s5 = ba.allocate();
  360. *s1 = 1;
  361. *s2 = 2;
  362. *s3 = 3;
  363. *s4 = 4;
  364. *s5 = 5;
  365. s32 wrong_answers = 0;
  366. s32 counter = 1;
  367. ba.for_each([&](s32* s) -> void {
  368. if(counter != *s)
  369. ++wrong_answers;
  370. ++counter;
  371. });
  372. assert_equal_int(wrong_answers, 0);
  373. Bucket_Allocator<s32> ba2;
  374. ba2.alloc();
  375. defer {
  376. ba2.dealloc();
  377. };
  378. s1 = ba2.allocate();
  379. s2 = ba2.allocate();
  380. s3 = ba2.allocate();
  381. s32* s3_copy = ba2.allocate();
  382. s32* s3_copy2 = ba2.allocate();
  383. s32* s3_copy3 = ba2.allocate();
  384. *s3_copy = 3;
  385. ba2.free_object(s3_copy);
  386. s4 = ba2.allocate();
  387. ba2.free_object(s3_copy2);
  388. s5 = ba2.allocate();
  389. ba2.free_object(s3_copy3);
  390. *s1 = 1;
  391. *s2 = 2;
  392. *s3 = 3;
  393. *s4 = 4;
  394. *s5 = 5;
  395. wrong_answers = 0;
  396. counter = 1;
  397. ba2.for_each([&](s32* s) -> void {
  398. if(counter != *s)
  399. ++wrong_answers;
  400. ++counter;
  401. });
  402. assert_equal_int(wrong_answers, 0);
  403. return pass;
  404. }
  405. auto test_array_list_sort_many() -> testresult {
  406. Array_List<s32> list;
  407. list.alloc();
  408. defer {
  409. list.dealloc();
  410. };
  411. for (int i = 0; i < 10000; ++i) {
  412. list.append(rand());
  413. }
  414. assert_equal_int(is_sorted(list), false);
  415. list.sort();
  416. assert_equal_int(is_sorted(list), true);
  417. for (int i = 0; i < 10000; ++i) {
  418. assert_not_equal_int(list.sorted_find(list.data[i]), -1);
  419. }
  420. list.clear();
  421. for (int i = 0; i < 1111; ++i) {
  422. list.append(rand());
  423. }
  424. assert_equal_int(is_sorted(list), false);
  425. list.sort();
  426. assert_equal_int(is_sorted(list), true);
  427. for (int i = 0; i < 1111; ++i) {
  428. assert_not_equal_int(list.sorted_find(list.data[i]), -1);
  429. }
  430. list.clear();
  431. for (int i = 0; i < 3331; ++i) {
  432. list.append(rand());
  433. }
  434. assert_equal_int(is_sorted(list), false);
  435. list.sort();
  436. assert_equal_int(is_sorted(list), true);
  437. for (int i = 0; i < 3331; ++i) {
  438. assert_not_equal_int(list.sorted_find(list.data[i]), -1);
  439. }
  440. return pass;
  441. }
  442. auto test_hooks() -> testresult {
  443. s32 a = 0;
  444. s32 b = 0;
  445. s32 c = 0;
  446. Hook hook;
  447. hook << [&]() {
  448. a = 1;
  449. };
  450. hook << [&]() {
  451. // NOTE(Felix): assert correct execution order
  452. if (a == 1 && c == 0) {
  453. b = 2;
  454. }
  455. };
  456. hook << [&]() {
  457. c = 3;
  458. };
  459. assert_equal_int(a, 0);
  460. assert_equal_int(b, 0);
  461. assert_equal_int(c, 0);
  462. hook();
  463. assert_equal_int(a, 1);
  464. assert_equal_int(b, 2);
  465. assert_equal_int(c, 3);
  466. a = 0;
  467. b = 0;
  468. c = 0;
  469. // NOTE(Felix): hook should be empty now
  470. hook();
  471. assert_equal_int(a, 0);
  472. assert_equal_int(b, 0);
  473. assert_equal_int(c, 0);
  474. return pass;
  475. }
  476. auto test_scheduler_animations() -> testresult {
  477. using namespace Scheduler;
  478. Scheduler::init();
  479. defer { Scheduler::deinit(); };
  480. f32 val = 0;
  481. f32 from = 1;
  482. f32 to = 2;
  483. schedule_animation({
  484. .seconds_to_start = 1,
  485. .seconds_to_end = 2,
  486. .interpolant = &val,
  487. .interpolant_type = Interpolant_Type::F32,
  488. .from = &from,
  489. .to = &to,
  490. .interpolation_type = Interpolation_Type::Lerp
  491. });
  492. assert_equal_f64((f64)val, 0.0);
  493. update_all(1);
  494. assert_equal_f64((f64)val, 1.0);
  495. update_all(0.1);
  496. assert_equal_int(abs(val - 1.1) < 0.001, true);
  497. update_all(0.1);
  498. assert_equal_int(abs(val - 1.2) < 0.001, true);
  499. update_all(0.2);
  500. assert_equal_int(abs(val - 1.4) < 0.001, true);
  501. update_all(1);
  502. assert_equal_int(abs(val - 2) < 0.001, true);
  503. // testing custom type interpolation
  504. enum My_Interpolant_Type : u8 {
  505. S32
  506. };
  507. register_interpolator([](void* p_from, f32 t, void* p_to, void* p_interpolant) {
  508. s32 from = *(s32*)p_from;
  509. s32 to = *(s32*)p_to;
  510. s32* target = (s32*)p_interpolant;
  511. *target = from + (to - from) * t;
  512. }, (Interpolant_Type)My_Interpolant_Type::S32, sizeof(s32));
  513. s32 test = 0;
  514. s32 s_from = 1;
  515. s32 s_to = 11;
  516. schedule_animation({
  517. .seconds_to_start = 1,
  518. .seconds_to_end = 2,
  519. .interpolant = &test,
  520. .interpolant_type = (Interpolant_Type)My_Interpolant_Type::S32,
  521. .from = &s_from,
  522. .to = &s_to,
  523. .interpolation_type = Interpolation_Type::Lerp
  524. });
  525. assert_equal_int(test, 0);
  526. update_all(1);
  527. assert_equal_int(test, 1);
  528. update_all(0.1);
  529. assert_equal_int(test, 2);
  530. update_all(0.1);
  531. assert_equal_int(test, 3);
  532. update_all(0.2);
  533. assert_equal_int(test, 5);
  534. update_all(1);
  535. assert_equal_int(test, 11);
  536. return pass;
  537. }
  538. s32 main(s32, char**) {
  539. defer { print_malloc_stats(); };
  540. init_printer();
  541. defer { deinit_printer(); };
  542. testresult result;
  543. invoke_test(test_array_lists_adding_and_removing);
  544. invoke_test(test_array_lists_sorting);
  545. invoke_test(test_array_lists_searching);
  546. invoke_test(test_array_list_sort_many);
  547. invoke_test(test_stack_array_lists);
  548. invoke_test(test_bucket_allocator);
  549. invoke_test(test_queue);
  550. invoke_test(test_hooks);
  551. invoke_test(test_scheduler_animations);
  552. return 0;
  553. }