2D Run-and-gun shooter inspired by One Man's Doomsday, Counter-Strike, and Metal Slug.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

200 строки
5.0 KiB

  1. #include "IZ_list.h"
  2. bool IZ_ListFindFilterAlwaysTrue(IZ_ListNode** _node, u64 _index, IZ_List* _list) {
  3. return true;
  4. }
  5. /**
  6. * Initializes a list.
  7. * @param list - The list to initialize.
  8. */
  9. void IZ_ListInitialize(IZ_List* list) {
  10. list->root = NULL;
  11. list->length = 0;
  12. list->iterator = NULL;
  13. }
  14. /**
  15. * Performs cleanup on a list.
  16. * @param list - The list to clean up.
  17. */
  18. void IZ_ListTeardown(IZ_List* list) {
  19. while (list->root) {
  20. IZ_ListDeleteFirstNode(list, IZ_ListFindFilterAlwaysTrue);
  21. }
  22. list->iterator = NULL;
  23. list->length = 0;
  24. }
  25. /**
  26. * Appends a node to the end of the list.
  27. * @param list - The list to append to.
  28. * @param node_value - The value of the node to append.
  29. * @return Pointer to the newly created node.
  30. */
  31. IZ_ListNode** IZ_ListAppendNode(IZ_List* list, void* node_value) {
  32. IZ_ListNode* new_node = SDL_malloc(sizeof(IZ_ListNode));
  33. new_node->value = node_value;
  34. new_node->next = NULL;
  35. if (!(list->root)) {
  36. list->root = new_node;
  37. list->length += 1;
  38. return &list->root;
  39. }
  40. IZ_ListNode* last_node = list->root;
  41. while (last_node->next) {
  42. last_node = last_node->next;
  43. }
  44. last_node->next = new_node;
  45. list->length += 1;
  46. return &last_node->next;
  47. }
  48. /**
  49. * Inserts a node at the specified index in the list.
  50. * @param list - The list to append to.
  51. * @param node_value - The value of the node to insert.
  52. * @param index - The index to insert the node at.
  53. * @return Pointer to the newly created node.
  54. */
  55. IZ_ListNode** IZ_ListInsertNodeAtIndex(IZ_List* list, void* node_value, u64 index) {
  56. if (index > list->length) {
  57. // we don't want to go out of bounds
  58. return NULL;
  59. }
  60. IZ_ListNode* new_node = SDL_malloc(sizeof(IZ_ListNode));
  61. new_node->value = node_value;
  62. new_node->next = NULL;
  63. if (!(list->root)) {
  64. list->root = new_node;
  65. list->length += 1;
  66. return &list->root;
  67. }
  68. if (index == 0) {
  69. new_node->next = list->root;
  70. list->root = new_node;
  71. list->length += 1;
  72. return &list->root;
  73. }
  74. IZ_ListNode* last_node = list->root;
  75. for (u64 i = 0; i < index - 1; i += 1) {
  76. last_node = last_node->next;
  77. }
  78. new_node->next = last_node->next;
  79. last_node->next = new_node;
  80. list->length += 1;
  81. return &last_node->next;
  82. }
  83. /**
  84. * Deletes the first node in the list that matches the filter.
  85. * @param list - The list to delete from.
  86. * @param filter - The filter to use to find the node to delete.
  87. */
  88. void IZ_ListDeleteFirstNode(IZ_List* list, IZ_ListFindPredicate filter) {
  89. if (!(list && list->root)) {
  90. // should we raise warnings here?
  91. return;
  92. }
  93. list->iterator = &list->root;
  94. IZ_ListNode* previous_node = NULL;
  95. u64 index = 0;
  96. do {
  97. if (!filter(list->iterator, index, list)) {
  98. previous_node = *list->iterator;
  99. list->iterator = &((*list->iterator)->next);
  100. index += 1;
  101. // we haven't found the node we're looking for, go to the next one
  102. continue;
  103. }
  104. if (previous_node) {
  105. // this is not the first node in the list
  106. previous_node->next = (*list->iterator)->next;
  107. } else {
  108. // this is the first node, set it as new root
  109. list->root = (*list->iterator)->next;
  110. // if there is only one item in the list, root, gets set to NULL
  111. }
  112. SDL_free(*list->iterator);
  113. list->iterator = NULL;
  114. if (list->length > 0) {
  115. // avoid underflow
  116. list->length -= 1;
  117. }
  118. return;
  119. } while (*list->iterator);
  120. }
  121. /**
  122. * Finds the first node in the list that matches the filter.
  123. * @param list - The list to search.
  124. * @param filter - The filter to use to find the node.
  125. * @return Pointer to the node that matches the filter.
  126. */
  127. IZ_ListNode** IZ_ListFindFirstNode(IZ_List* list, IZ_ListFindPredicate filter) {
  128. if (!(list && list->root)) {
  129. return NULL;
  130. }
  131. list->iterator = &list->root;
  132. u64 index = 0;
  133. do {
  134. if (filter(list->iterator, index, list)) {
  135. return list->iterator;
  136. }
  137. list->iterator = &((*list->iterator)->next);
  138. index += 1;
  139. } while (*list->iterator);
  140. return NULL;
  141. }
  142. void IZ_ListFilter(IZ_List* original_list, IZ_ListFindPredicate filter, IZ_List* out_filtered_list) {
  143. // we assume the new list is already initialized
  144. IZ_ListNode* node = original_list->root;
  145. u64 index;
  146. for (index = 0; node; index += 1) {
  147. if (!filter(&node, index, original_list)) {
  148. node = node->next;
  149. continue;
  150. }
  151. IZ_ListAppendNode(out_filtered_list, node->value);
  152. node = node->next;
  153. }
  154. }
  155. void IZ_ListSort(IZ_List* original_list, IZ_ListSortComparatorPredicate sort, IZ_List* out_sorted_list) {
  156. // we assume the new list is already initialized
  157. IZ_ListNode* original_node = original_list->root;
  158. u64 original_index;
  159. for (original_index = 0; original_node; original_index += 1) {
  160. if (!out_sorted_list->root) {
  161. IZ_ListAppendNode(out_sorted_list, original_node->value);
  162. original_node = original_node->next;
  163. continue;
  164. }
  165. IZ_ListNode* sorted_node = out_sorted_list->root;
  166. for (u64 sorted_index = 0; sorted_node; sorted_index += 1) {
  167. if (sort(&original_node, &sorted_node, original_index, original_list) < 0) {
  168. IZ_ListInsertNodeAtIndex(out_sorted_list, original_node->value, sorted_index);
  169. original_node = original_node->next;
  170. break;
  171. }
  172. sorted_node = sorted_node->next;
  173. }
  174. }
  175. }