microui  4.0.0
microui
ui_rect_collection.h
1 /*
2  * C
3  *
4  * Copyright 2023-2024 MicroEJ Corp. All rights reserved.
5  * Use of this source code is governed by a BSD-style license that can be found with this software.
6  */
7 
8 #ifndef UI_RECT_COLLECTION_H
9 #define UI_RECT_COLLECTION_H
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 /*
15  * @brief Exposes the ui_rect_collection_t type that handles unordered ui_rect_t collections
16  */
17 
18 // --------------------------------------------------------------------------------
19 // Includes
20 // --------------------------------------------------------------------------------
21 
22 #include <assert.h>
23 
24 #include "ui_rect.h"
25 
26 // --------------------------------------------------------------------------------
27 // Defines
28 // --------------------------------------------------------------------------------
29 
30 /*
31  * @brief Defines the number of rectangles that collections can contain.
32  */
33 #ifndef UI_RECT_COLLECTION_MAX_LENGTH
34 #define UI_RECT_COLLECTION_MAX_LENGTH 8u
35 #endif
36 
37 // --------------------------------------------------------------------------------
38 // Typedefs
39 // --------------------------------------------------------------------------------
40 
41 /*
42  * @brief A rectangle collection contains an array of rectangles and a pointer to
43  * the latest rectangle.
44  */
45 typedef struct ui_rect_collection_t {
46  ui_rect_t data[UI_RECT_COLLECTION_MAX_LENGTH];
47  size_t length;
49 
50 // --------------------------------------------------------------------------------
51 // Public functions
52 // --------------------------------------------------------------------------------
53 
54 /*
55  * @brief Clears the collection: the latest rectangle points on the first rectangle.
56  *
57  * @param[in] collection the collection to clear
58  */
59 static inline void UI_RECT_COLLECTION_clear(ui_rect_collection_t* collection) {
60  collection->length = 0;
61 }
62 
63 /*
64  * @brief Initializes the collection.
65  *
66  * @param[in] collection the collection to initialize
67  */
68 static inline void UI_RECT_COLLECTION_init(ui_rect_collection_t* collection) {
69  UI_RECT_COLLECTION_clear(collection);
70 }
71 
72 /*
73  * @brief Gets the number of rectangles that have been added to the collection.
74  *
75  * @param[in] collection the collection to check
76  *
77  * @return the available number of rectangles in the collection
78  */
79 static inline size_t UI_RECT_COLLECTION_get_length(const ui_rect_collection_t* collection) {
80  return collection->length;
81 }
82 
83 /*
84  * @brief Tells if the collection is full.
85  *
86  * @param[in] collection the collection to check
87  *
88  * @return true when the collection is full
89  */
90 static inline bool UI_RECT_COLLECTION_is_full(const ui_rect_collection_t* collection) {
91  return UI_RECT_COLLECTION_get_length(collection) >= UI_RECT_COLLECTION_MAX_LENGTH;
92 }
93 
94 /*
95  * @brief Tells if the collection is empty.
96  *
97  * @param[in] collection the collection to check
98  *
99  * @return true when the collection is empty
100  */
101 static inline bool UI_RECT_COLLECTION_is_empty(const ui_rect_collection_t* collection) {
102  return collection->length == 0u;
103 }
104 
105 /*
106  * @brief Gets the last rectangle added to the collection or NULL if the collection is empty.
107  *
108  * @param[in] collection the collection where retrieve latest element
109  *
110  * @return a rectangle or NULL
111  */
112 static inline ui_rect_t* UI_RECT_COLLECTION_get_last(ui_rect_collection_t* collection) {
113  return UI_RECT_COLLECTION_is_empty(collection) ? NULL : (collection->data + collection->length - 1u);
114 }
115 
116 /*
117  * @brief Gets a pointer to the address after the last rectangle in the collection.
118  *
119  * @param[in] collection the collection
120  *
121  * @return a pointer to the address after the last element in the collection
122  */
123 static inline ui_rect_t* UI_RECT_COLLECTION_get_end(ui_rect_collection_t* collection) {
124  return collection->data + collection->length;
125 }
126 
127 /*
128  * @brief Adds a rectangle in the collection. The implementation assumes that caller ensure that
129  * the collection is not full. The rectangle is copied to the collection.
130  *
131  * @param[in] collection the collection where copying the rectangle
132  * @param[in] element the rectangle to add
133  */
134 static inline void UI_RECT_COLLECTION_add_rect(ui_rect_collection_t* collection, const ui_rect_t element) {
135  assert(!UI_RECT_COLLECTION_is_full(collection));
136  collection->data[collection->length] = element;
137  collection->length++;
138 }
139 
140 /*
141  * @brief Removes a rectangle from the collection. The behavior is undefined if the rectangle is not part of the collection.
142  *
143  * @param[in] collection the collection which contains the rectangle
144  * @param[in] element the rectangle to remove
145  */
146 static inline void UI_RECT_COLLECTION_remove_rect(ui_rect_collection_t* collection, ui_rect_t* element) {
147  assert(!UI_RECT_COLLECTION_is_empty(collection));
148  assert(element >= collection->data);
149  assert(element < (collection->data + collection->length));
150  *element = *UI_RECT_COLLECTION_get_last(collection);
151  collection->length--;
152 }
153 
154 /*
155  * @brief Removes all empty rectangles from the collection.
156  *
157  * @param[in] collection the collection
158  */
159 static inline void UI_RECT_COLLECTION_remove_empty_rects(ui_rect_collection_t* collection) {
160  for (size_t i = 0; i < collection->length;) {
161  if (UI_RECT_is_empty(&collection->data[i])) {
162  UI_RECT_COLLECTION_remove_rect(collection, &collection->data[i]);
163  } else {
164  i++;
165  }
166  }
167 }
168 
169 // --------------------------------------------------------------------------------
170 // EOF
171 // --------------------------------------------------------------------------------
172 
173 #ifdef __cplusplus
174 }
175 #endif
176 #endif // UI_RECT_COLLECTION_H