feat(array): make the API of lv_array module STL-like (#5300)

Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
Neo Xu
2024-01-18 20:45:46 +08:00
committed by GitHub
parent d939316e26
commit ed3e485b22
8 changed files with 334 additions and 153 deletions
+2 -2
View File
@@ -80,13 +80,13 @@ typedef enum {
**********************/
/**
* Init. the group module
* Init the group module
* @remarks Internal function, do not call directly.
*/
void _lv_group_init(void);
/**
* Deinit. the group module
* Deinit the group module
* @remarks Internal function, do not call directly.
*/
void _lv_group_deinit(void);
+28 -32
View File
@@ -25,10 +25,10 @@
#define CHECK_AND_RESIZE_PATH_CONTAINER(P, N) \
do { \
if ((lv_array_length(&(P)->ops) + (N)) > lv_array_capacity(&(P)->ops)) { \
if ((lv_array_size(&(P)->ops) + (N)) > lv_array_capacity(&(P)->ops)) { \
lv_array_resize(&(P)->ops, ((P)->ops.capacity << 1)); \
} \
if ((lv_array_length(&(P)->points) + (N)) > lv_array_capacity(&(P)->points)) { \
if ((lv_array_size(&(P)->points) + (N)) > lv_array_capacity(&(P)->points)) { \
lv_array_resize(&(P)->points, ((P)->points.capacity << 1)); \
} \
} while(0)
@@ -202,8 +202,8 @@ lv_vector_path_t * lv_vector_path_create(lv_vector_path_quality_t quality)
LV_ASSERT_MALLOC(path);
lv_memzero(path, sizeof(lv_vector_path_t));
path->quality = quality;
LV_ARRAY_INIT_CAPACITY(&path->ops, 8, uint8_t);
LV_ARRAY_INIT_CAPACITY(&path->points, 8, lv_fpoint_t);
lv_array_init(&path->ops, 8, sizeof(uint8_t));
lv_array_init(&path->points, 8, sizeof(lv_fpoint_t));
return path;
}
@@ -222,8 +222,8 @@ void lv_vector_path_clear(lv_vector_path_t * path)
void lv_vector_path_delete(lv_vector_path_t * path)
{
lv_array_destroy(&path->ops);
lv_array_destroy(&path->points);
lv_array_deinit(&path->ops);
lv_array_deinit(&path->points);
lv_free(path);
}
@@ -232,8 +232,8 @@ void lv_vector_path_move_to(lv_vector_path_t * path, const lv_fpoint_t * p)
CHECK_AND_RESIZE_PATH_CONTAINER(path, 1);
uint8_t op = LV_VECTOR_PATH_OP_MOVE_TO;
LV_ARRAY_APPEND_VALUE(&path->ops, op);
LV_ARRAY_APPEND(&path->points, p);
lv_array_push_back(&path->ops, &op);
lv_array_push_back(&path->points, p);
}
void lv_vector_path_line_to(lv_vector_path_t * path, const lv_fpoint_t * p)
@@ -246,8 +246,8 @@ void lv_vector_path_line_to(lv_vector_path_t * path, const lv_fpoint_t * p)
CHECK_AND_RESIZE_PATH_CONTAINER(path, 1);
uint8_t op = LV_VECTOR_PATH_OP_LINE_TO;
LV_ARRAY_APPEND_VALUE(&path->ops, op);
LV_ARRAY_APPEND(&path->points, p);
lv_array_push_back(&path->ops, &op);
lv_array_push_back(&path->points, p);
}
void lv_vector_path_quad_to(lv_vector_path_t * path, const lv_fpoint_t * p1, const lv_fpoint_t * p2)
@@ -260,9 +260,9 @@ void lv_vector_path_quad_to(lv_vector_path_t * path, const lv_fpoint_t * p1, con
CHECK_AND_RESIZE_PATH_CONTAINER(path, 2);
uint8_t op = LV_VECTOR_PATH_OP_QUAD_TO;
LV_ARRAY_APPEND_VALUE(&path->ops, op);
LV_ARRAY_APPEND(&path->points, p1);
LV_ARRAY_APPEND(&path->points, p2);
lv_array_push_back(&path->ops, &op);
lv_array_push_back(&path->points, p1);
lv_array_push_back(&path->points, p2);
}
void lv_vector_path_cubic_to(lv_vector_path_t * path, const lv_fpoint_t * p1, const lv_fpoint_t * p2,
@@ -276,10 +276,10 @@ void lv_vector_path_cubic_to(lv_vector_path_t * path, const lv_fpoint_t * p1, co
CHECK_AND_RESIZE_PATH_CONTAINER(path, 3);
uint8_t op = LV_VECTOR_PATH_OP_CUBIC_TO;
LV_ARRAY_APPEND_VALUE(&path->ops, op);
LV_ARRAY_APPEND(&path->points, p1);
LV_ARRAY_APPEND(&path->points, p2);
LV_ARRAY_APPEND(&path->points, p3);
lv_array_push_back(&path->ops, &op);
lv_array_push_back(&path->points, p1);
lv_array_push_back(&path->points, p2);
lv_array_push_back(&path->points, p3);
}
void lv_vector_path_close(lv_vector_path_t * path)
@@ -292,7 +292,7 @@ void lv_vector_path_close(lv_vector_path_t * path)
CHECK_AND_RESIZE_PATH_CONTAINER(path, 1);
uint8_t op = LV_VECTOR_PATH_OP_CLOSE;
LV_ARRAY_APPEND_VALUE(&path->ops, op);
lv_array_push_back(&path->ops, &op);
}
void lv_vector_path_append_rect(lv_vector_path_t * path, const lv_area_t * rect, float rx, float ry)
@@ -432,19 +432,15 @@ void lv_vector_path_append_circle(lv_vector_path_t * path, const lv_fpoint_t * c
void lv_vector_path_append_path(lv_vector_path_t * path, const lv_vector_path_t * subpath)
{
uint32_t ops_size = lv_array_length(&path->ops);
uint32_t nops_size = lv_array_length(&subpath->ops);
uint32_t point_size = lv_array_length(&path->points);
uint32_t npoint_size = lv_array_length(&subpath->points);
uint32_t ops_size = lv_array_size(&path->ops);
uint32_t nops_size = lv_array_size(&subpath->ops);
uint32_t point_size = lv_array_size(&path->points);
uint32_t npoint_size = lv_array_size(&subpath->points);
lv_array_resize(&path->ops, ops_size + nops_size);
uint8_t * start_ops = lv_array_get(&path->ops, ops_size - 1) + sizeof(lv_vector_path_op_t);
lv_memcpy(start_ops, lv_array_get(&subpath->ops, 0), nops_size * sizeof(lv_vector_path_op_t));
lv_array_concat(&path->ops, &subpath->ops);
path->ops.size = ops_size + nops_size;
lv_array_resize(&path->points, point_size + npoint_size);
uint8_t * start_pt = lv_array_get(&path->points, point_size - 1) + sizeof(lv_fpoint_t);
lv_memcpy(start_pt, lv_array_get(&subpath->points, 0), npoint_size * sizeof(lv_fpoint_t));
lv_array_concat(&path->points, &subpath->points);
path->points.size = point_size + npoint_size;
}
@@ -489,7 +485,7 @@ void lv_vector_dsc_delete(lv_vector_dsc_t * dsc)
_lv_vector_for_each_destroy_tasks(task_list, NULL, NULL);
dsc->tasks.task_list = NULL;
}
lv_array_destroy(&(dsc->current_dsc.stroke_dsc.dash_pattern));
lv_array_deinit(&(dsc->current_dsc.stroke_dsc.dash_pattern));
lv_free(dsc);
}
@@ -590,13 +586,13 @@ void lv_vector_dsc_set_stroke_dash(lv_vector_dsc_t * dsc, float * dash_pattern,
if(dash_pattern) {
lv_array_clear(dash_array);
if(lv_array_capacity(dash_array) == 0) {
LV_ARRAY_INIT_CAPACITY(dash_array, dash_count, float);
lv_array_init(dash_array, dash_count, sizeof(float));
}
else {
lv_array_resize(dash_array, dash_count);
}
for(uint16_t i = 0; i < dash_count; i++) {
LV_ARRAY_APPEND_VALUE(dash_array, dash_pattern[i]);
lv_array_push_back(dash_array, &dash_pattern[i]);
}
}
else { /*clear dash*/
@@ -747,7 +743,7 @@ void _lv_vector_for_each_destroy_tasks(lv_ll_t * task_list, vector_draw_task_cb
if(task->path) {
lv_vector_path_delete(task->path);
}
lv_array_destroy(&(task->dsc.stroke_dsc.dash_pattern));
lv_array_deinit(&(task->dsc.stroke_dsc.dash_pattern));
lv_free(task);
task = next_task;
+10 -10
View File
@@ -87,25 +87,25 @@ static void _set_paint_shape(Tvg_Paint * obj, const lv_vector_path_t * p)
{
uint32_t pidx = 0;
for(uint32_t i = 0; i < p->ops.size; i++) {
lv_vector_path_op_t * op = LV_ARRAY_GET(&p->ops, i, uint8_t);
lv_vector_path_op_t * op = lv_array_at(&p->ops, i);
switch(*op) {
case LV_VECTOR_PATH_OP_MOVE_TO: {
lv_fpoint_t * pt = LV_ARRAY_GET(&p->points, pidx, lv_fpoint_t);
lv_fpoint_t * pt = lv_array_at(&p->points, pidx);
tvg_shape_move_to(obj, pt->x, pt->y);
pidx += 1;
}
break;
case LV_VECTOR_PATH_OP_LINE_TO: {
lv_fpoint_t * pt = LV_ARRAY_GET(&p->points, pidx, lv_fpoint_t);
lv_fpoint_t * pt = lv_array_at(&p->points, pidx);
tvg_shape_line_to(obj, pt->x, pt->y);
pidx += 1;
}
break;
case LV_VECTOR_PATH_OP_QUAD_TO: {
lv_fpoint_t * pt1 = LV_ARRAY_GET(&p->points, pidx, lv_fpoint_t);
lv_fpoint_t * pt2 = LV_ARRAY_GET(&p->points, pidx + 1, lv_fpoint_t);
lv_fpoint_t * pt1 = lv_array_at(&p->points, pidx);
lv_fpoint_t * pt2 = lv_array_at(&p->points, pidx + 1);
lv_fpoint_t * last_pt = LV_ARRAY_GET(&p->points, pidx - 1, lv_fpoint_t);
lv_fpoint_t * last_pt = lv_array_at(&p->points, pidx - 1);
lv_fpoint_t cp[2];
cp[0].x = (last_pt->x + 2 * pt1->x) * (1.0f / 3.0f);
@@ -118,9 +118,9 @@ static void _set_paint_shape(Tvg_Paint * obj, const lv_vector_path_t * p)
}
break;
case LV_VECTOR_PATH_OP_CUBIC_TO: {
lv_fpoint_t * pt1 = LV_ARRAY_GET(&p->points, pidx, lv_fpoint_t);
lv_fpoint_t * pt2 = LV_ARRAY_GET(&p->points, pidx + 1, lv_fpoint_t);
lv_fpoint_t * pt3 = LV_ARRAY_GET(&p->points, pidx + 2, lv_fpoint_t);
lv_fpoint_t * pt1 = lv_array_at(&p->points, pidx);
lv_fpoint_t * pt2 = lv_array_at(&p->points, pidx + 1);
lv_fpoint_t * pt3 = lv_array_at(&p->points, pidx + 2);
tvg_shape_cubic_to(obj, pt1->x, pt1->y, pt2->x, pt2->y, pt3->x, pt3->y);
pidx += 3;
@@ -243,7 +243,7 @@ static void _set_paint_stroke(Tvg_Paint * obj, const lv_vector_stroke_dsc_t * ds
tvg_shape_set_stroke_join(obj, _lv_stroke_join_to_tvg(dsc->join));
if(!lv_array_is_empty(&dsc->dash_pattern)) {
float * dash_array = LV_ARRAY_GET(&dsc->dash_pattern, 0, float);
float * dash_array = lv_array_at(&dsc->dash_pattern, 0);
tvg_shape_set_stroke_dash(obj, dash_array, dsc->dash_pattern.size);
}
}
+8 -8
View File
@@ -236,25 +236,25 @@ static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src
uint32_t pidx = 0;
for(uint32_t i = 0; i < src->ops.size; i++) {
lv_vector_path_op_t * op = LV_ARRAY_GET(&src->ops, i, uint8_t);
lv_vector_path_op_t * op = lv_array_at(&src->ops, i);
switch(*op) {
case LV_VECTOR_PATH_OP_MOVE_TO: {
const lv_fpoint_t * pt = LV_ARRAY_GET(&src->points, pidx, lv_fpoint_t);
const lv_fpoint_t * pt = lv_array_at(&src->points, pidx);
CMP_BOUNDS(pt);
lv_vg_lite_path_move_to(dest, pt->x, pt->y);
pidx += 1;
}
break;
case LV_VECTOR_PATH_OP_LINE_TO: {
const lv_fpoint_t * pt = LV_ARRAY_GET(&src->points, pidx, lv_fpoint_t);
const lv_fpoint_t * pt = lv_array_at(&src->points, pidx);
CMP_BOUNDS(pt);
lv_vg_lite_path_line_to(dest, pt->x, pt->y);
pidx += 1;
}
break;
case LV_VECTOR_PATH_OP_QUAD_TO: {
const lv_fpoint_t * pt1 = LV_ARRAY_GET(&src->points, pidx, lv_fpoint_t);
const lv_fpoint_t * pt2 = LV_ARRAY_GET(&src->points, pidx + 1, lv_fpoint_t);
const lv_fpoint_t * pt1 = lv_array_at(&src->points, pidx);
const lv_fpoint_t * pt2 = lv_array_at(&src->points, pidx + 1);
CMP_BOUNDS(pt1);
CMP_BOUNDS(pt2);
lv_vg_lite_path_quad_to(dest, pt1->x, pt1->y, pt2->x, pt2->y);
@@ -262,9 +262,9 @@ static void lv_path_to_vg(lv_vg_lite_path_t * dest, const lv_vector_path_t * src
}
break;
case LV_VECTOR_PATH_OP_CUBIC_TO: {
const lv_fpoint_t * pt1 = LV_ARRAY_GET(&src->points, pidx, lv_fpoint_t);
const lv_fpoint_t * pt2 = LV_ARRAY_GET(&src->points, pidx + 1, lv_fpoint_t);
const lv_fpoint_t * pt3 = LV_ARRAY_GET(&src->points, pidx + 2, lv_fpoint_t);
const lv_fpoint_t * pt1 = lv_array_at(&src->points, pidx);
const lv_fpoint_t * pt2 = lv_array_at(&src->points, pidx + 1);
const lv_fpoint_t * pt3 = lv_array_at(&src->points, pidx + 2);
CMP_BOUNDS(pt1);
CMP_BOUNDS(pt2);
CMP_BOUNDS(pt3);
+2 -2
View File
@@ -169,12 +169,12 @@ struct _lv_anim_t {
**********************/
/**
* Init. the animation module
* Init the animation module
*/
void _lv_anim_core_init(void);
/**
* Deinit. the animation module
* Deinit the animation module
*/
void _lv_anim_core_deinit(void);
+88 -46
View File
@@ -45,63 +45,116 @@ void lv_array_init(lv_array_t * array, uint32_t capacity, uint32_t element_size)
LV_ASSERT_MALLOC(array->data);
}
void lv_array_destroy(lv_array_t * array)
void lv_array_deinit(lv_array_t * array)
{
if(array->data) {
lv_free(array->data);
array->data = NULL;
}
array->size = 0;
array->capacity = 0;
}
void lv_array_copy(lv_array_t * target, const lv_array_t * array)
void lv_array_copy(lv_array_t * target, const lv_array_t * source)
{
if(lv_array_is_empty(array)) {
if(lv_array_is_empty(source)) {
return;
}
lv_array_destroy(target);
lv_array_init(target, array->capacity, array->element_size);
lv_memcpy(target->data, array->data, array->size * array->element_size);
target->size = array->size;
lv_array_deinit(target);
lv_array_init(target, source->capacity, source->element_size);
lv_memcpy(target->data, source->data, source->size * source->element_size);
target->size = source->size;
}
void lv_array_clear(lv_array_t * array)
lv_result_t lv_array_remove(lv_array_t * array, uint32_t index)
{
array->size = 0;
if(index >= array->size) {
return LV_RESULT_INVALID;
}
/*Shortcut*/
if(index == array->size - 1) {
lv_array_resize(array, array->size - 1);
return LV_RESULT_OK;
}
uint8_t * start = lv_array_at(array, index);
uint8_t * remaining = start + array->element_size;
uint32_t remaining_size = (array->size - index - 1) * array->element_size;
lv_memcpy(start, remaining, remaining_size);
lv_array_resize(array, array->size - 1);
return LV_RESULT_OK;
}
lv_result_t lv_array_erase(lv_array_t * array, uint32_t start, uint32_t end)
{
if(end > array->size) {
end = array->size;
}
if(start >= end) {
return LV_RESULT_INVALID;
}
/*Shortcut*/
if(end == array->size) {
lv_array_resize(array, start);
return LV_RESULT_OK;
}
uint8_t * start_p = lv_array_at(array, start);
uint8_t * remaining = start_p + (end - start) * array->element_size;
uint32_t remaining_size = (array->size - end) * array->element_size;
lv_memcpy(start_p, remaining, remaining_size);
lv_array_resize(array, array->size - (end - start));
return LV_RESULT_OK;
}
void lv_array_resize(lv_array_t * array, uint32_t new_capacity)
{
if(new_capacity > array->size) {
if(new_capacity > array->capacity) {
uint8_t * data = lv_malloc(new_capacity * array->element_size);
lv_memcpy(data, array->data, array->size * array->element_size);
lv_free(array->data);
array->data = data;
array->capacity = new_capacity;
}
}
else {
uint8_t * data = lv_realloc(array->data, new_capacity * array->element_size);
LV_ASSERT_NULL(data);
array->data = data;
array->capacity = new_capacity;
if(array->size > new_capacity) {
array->size = new_capacity;
}
}
bool lv_array_append(lv_array_t * array, const uint8_t * element)
lv_result_t lv_array_concat(lv_array_t * array, const lv_array_t * other)
{
if(array->size >= array->capacity) {
// array is full
return false;
LV_ASSERT_NULL(array->data);
uint32_t size = other->size;
if(array->size + size > array->capacity) {
/*array is full*/
lv_array_resize(array, array->size + size);
}
LV_ASSERT_NULL(array->data);
uint8_t * data = (uint8_t *)(array->data + array->size * array->element_size);
lv_memcpy(data, element, array->element_size);
array->size++;
return true;
uint8_t * data = array->data + array->size * array->element_size;
lv_memcpy(data, other->data, array->element_size * size);
array->size += size;
return LV_RESULT_OK;
}
uint8_t * lv_array_get(const lv_array_t * array, uint32_t index)
lv_result_t lv_array_push_back(lv_array_t * array, const void * element)
{
if(index > (array->size - 1)) {
LV_ASSERT_NULL(array->data);
if(array->size == array->capacity) {
/*array is full*/
lv_array_resize(array, array->capacity + 1);
}
uint8_t * data = array->data + array->size * array->element_size;
lv_memcpy(data, element, array->element_size);
array->size++;
return LV_RESULT_OK;
}
void * lv_array_at(const lv_array_t * array, uint32_t index)
{
if(index >= array->size) {
return NULL;
}
@@ -109,22 +162,11 @@ uint8_t * lv_array_get(const lv_array_t * array, uint32_t index)
return array->data + index * array->element_size;
}
uint32_t lv_array_length(const lv_array_t * array)
lv_result_t lv_array_assign(lv_array_t * array, uint32_t index, const void * value)
{
return array->size;
}
uint8_t * data = lv_array_at(array, index);
if(data == NULL) return LV_RESULT_INVALID;
uint32_t lv_array_capacity(const lv_array_t * array)
{
return array->capacity;
}
bool lv_array_is_full(const lv_array_t * array)
{
return array->size == array->capacity;
}
bool lv_array_is_empty(const lv_array_t * array)
{
return array->size == 0;
lv_memcpy(data, value, array->element_size);
return LV_RESULT_OK;
}
+145 -28
View File
@@ -17,10 +17,12 @@ extern "C" {
#include <stddef.h>
#include <stdbool.h>
#include "lv_types.h"
/*********************
* DEFINES
*********************/
#define DEFAULT_CAPS 8
#define LV_ARRAY_DEFAULT_CAPACITY 8
/**********************
* TYPEDEFS
@@ -38,47 +40,162 @@ typedef struct {
* GLOBAL PROTOTYPES
**********************/
/**
* Init an array.
* @param array pointer to an `lv_array_t` variable to initialize
* @param capacity the initial capacity of the array
* @param element_size the size of an element in bytes
*/
void lv_array_init(lv_array_t * array, uint32_t capacity, uint32_t element_size);
void lv_array_copy(lv_array_t * target, const lv_array_t * array);
void lv_array_clear(lv_array_t * array);
/**
* Resize the array to the given capacity.
* @note if the new capacity is smaller than the current size, the array will be truncated.
* @param array pointer to an `lv_array_t` variable
* @param new_capacity the new capacity of the array
*/
void lv_array_resize(lv_array_t * array, uint32_t new_capacity);
void lv_array_destroy(lv_array_t * array);
/**
* Deinit the array, and free the allocated memory
* @param array pointer to an `lv_array_t` variable to deinitialize
*/
void lv_array_deinit(lv_array_t * array);
bool lv_array_append(lv_array_t * array, const uint8_t * element);
/**
* Return how many elements are stored in the array.
* @param array pointer to an `lv_array_t` variable
* @return the number of elements stored in the array
*/
static inline uint32_t lv_array_size(const lv_array_t * array)
{
return array->size;
}
uint8_t * lv_array_get(const lv_array_t * array, uint32_t index);
/**
* Return the capacity of the array, i.e. how many elements can be stored.
* @param array pointer to an `lv_array_t` variable
* @return the capacity of the array
*/
static inline uint32_t lv_array_capacity(const lv_array_t * array)
{
return array->capacity;
}
uint32_t lv_array_length(const lv_array_t * array);
/**
* Return if the array is empty
* @param array pointer to an `lv_array_t` variable
* @return true: array is empty; false: array is not empty
*/
static inline bool lv_array_is_empty(const lv_array_t * array)
{
return array->size == 0;
}
uint32_t lv_array_capacity(const lv_array_t * array);
/**
* Return if the array is full
* @param array pointer to an `lv_array_t` variable
* @return true: array is full; false: array is not full
*/
static inline bool lv_array_is_full(const lv_array_t * array)
{
return array->size == array->capacity;
}
bool lv_array_is_empty(const lv_array_t * array);
/**
* Copy an array to another.
* @note this will create a new array with the same capacity and size as the source array.
* @param target pointer to an `lv_array_t` variable to copy to
* @param source pointer to an `lv_array_t` variable to copy from
*/
void lv_array_copy(lv_array_t * target, const lv_array_t * source);
/**
* Remove all elements in array.
* @param array pointer to an `lv_array_t` variable
*/
static inline void lv_array_clear(lv_array_t * array)
{
array->size = 0;
}
/**
* Remove the element at the specified position in the array.
* @param array pointer to an `lv_array_t` variable
* @param index the index of the element to remove
* @return LV_RESULT_OK: success, otherwise: error
*/
lv_result_t lv_array_remove(lv_array_t * array, uint32_t index);
/**
* Remove from the array either a single element or a range of elements ([start, end)).
* @note This effectively reduces the container size by the number of elements removed.
* @note When start equals to end, the function has no effect.
* @param array pointer to an `lv_array_t` variable
* @param start the index of the first element to be removed
* @param end the index of the first element that is not to be removed
* @return LV_RESULT_OK: success, otherwise: error
*/
lv_result_t lv_array_erase(lv_array_t * array, uint32_t start, uint32_t end);
/**
* Concatenate two arrays. Adds new elements to the end of the array.
* @note The destination array is automatically expanded as necessary.
* @param array pointer to an `lv_array_t` variable
* @param other pointer to the array to concatenate
* @return LV_RESULT_OK: success, otherwise: error
*/
lv_result_t lv_array_concat(lv_array_t * array, const lv_array_t * other);
/**
* Push back element. Adds a new element to the end of the array.
* If the array capacity is not enough for the new element, the array will be resized automatically.
* @param array pointer to an `lv_array_t` variable
* @param element pointer to the element to add
* @return LV_RESULT_OK: success, otherwise: error
*/
lv_result_t lv_array_push_back(lv_array_t * array, const void * element);
/**
* Assigns one content to the array, replacing its current content.
* @param array pointer to an `lv_array_t` variable
* @param index the index of the element to replace
* @param value pointer to the elements to add
* @return true: success; false: error
*/
lv_result_t lv_array_assign(lv_array_t * array, uint32_t index, const void * value);
/**
* Returns a pointer to the element at position n in the array.
* @param array pointer to an `lv_array_t` variable
* @param index the index of the element to return
* @return a pointer to the requested element, NULL if `index` is out of range
*/
void * lv_array_at(const lv_array_t * array, uint32_t index);
/**
* Returns a pointer to the first element in the array.
* @param array pointer to an `lv_array_t` variable
* @return a pointer to the first element in the array
*/
static inline void * lv_array_front(const lv_array_t * array)
{
return lv_array_at(array, 0);
}
/**
* Returns a pointer to the last element in the array.
* @param array pointer to an `lv_array_t` variable
*/
static inline void * lv_array_back(const lv_array_t * array)
{
return lv_array_at(array, lv_array_size(array) - 1);
}
bool lv_array_is_full(const lv_array_t * array);
/**********************
* MACROS
**********************/
#define LV_ARRAY_INIT(array, type) lv_array_init((array), DEFAULT_CAPS, sizeof(type))
#define LV_ARRAY_INIT_CAPACITY(array, caps, type) lv_array_init((array), (caps), sizeof(type))
#define LV_ARRAY_APPEND_VALUE(array, element) lv_array_append((array), (uint8_t*)&(element))
#define LV_ARRAY_APPEND(array, element) lv_array_append((array), (uint8_t*)(element))
#define LV_ARRAY_GET(array, index, type) (type*)lv_array_get((array), (index))
#define LV_ARRAY_SET(array, index, data, type) \
do { \
type* elem = (type*)lv_array_get((array), (index)); \
*elem = *((type*)(data)); \
} while(0)
#ifdef __cplusplus
} /*extern "C"*/
#endif
+51 -25
View File
@@ -7,70 +7,96 @@ static lv_array_t array;
void setUp(void)
{
LV_ARRAY_INIT(&array, int32_t);
lv_array_init(&array, LV_ARRAY_DEFAULT_CAPACITY, sizeof(int32_t));
}
void tearDown(void)
{
lv_array_destroy(&array);
lv_array_deinit(&array);
}
void test_array_append_values(void)
{
for(int32_t i = 0; i < 10; i++) {
LV_ARRAY_APPEND_VALUE(&array, i);
const int32_t new_size = LV_ARRAY_DEFAULT_CAPACITY + 2;
TEST_ASSERT_EQUAL_UINT32(0, lv_array_size(&array));
for(int32_t i = 0; i < new_size; i++) {
lv_array_push_back(&array, &i);
}
TEST_ASSERT_EQUAL_UINT32(8, lv_array_length(&array));
/*push back will automatically extent the array size.*/
TEST_ASSERT_EQUAL_UINT32(new_size, lv_array_size(&array));
}
void test_array_set_get(void)
{
uint32_t v = 100;
LV_ARRAY_SET(&array, 0, &v, uint32_t);
uint32_t * r = LV_ARRAY_GET(&array, 0, uint32_t);
int32_t v = 100;
lv_array_push_back(&array, &v);
int32_t * r = lv_array_at(&array, 0);
TEST_ASSERT_EQUAL_UINT32(100, *r);
}
void test_array_len(void)
void test_array_size(void)
{
for(int32_t i = 0; i < 10; i++) {
LV_ARRAY_APPEND_VALUE(&array, i);
lv_array_push_back(&array, &i);
}
TEST_ASSERT_EQUAL_UINT32(1, lv_array_is_full(&array) ? 1 : 0);
TEST_ASSERT_EQUAL_UINT32(8, lv_array_length(&array));
lv_array_clear(&array);
TEST_ASSERT_EQUAL_UINT32(1, lv_array_is_empty(&array) ? 1 : 0);
TEST_ASSERT_EQUAL_UINT32(0, lv_array_length(&array));
TEST_ASSERT_EQUAL_UINT32(0, lv_array_size(&array));
}
void test_array_resize(void)
{
for(int32_t i = 0; i < 10; i++) {
LV_ARRAY_APPEND_VALUE(&array, i);
for(int32_t i = 0; i < LV_ARRAY_DEFAULT_CAPACITY; i++) {
lv_array_push_back(&array, &i);
}
TEST_ASSERT_EQUAL_UINT32(LV_ARRAY_DEFAULT_CAPACITY, lv_array_size(&array));
lv_array_resize(&array, 12);
TEST_ASSERT_EQUAL_UINT32(8, lv_array_length(&array));
TEST_ASSERT_EQUAL_UINT32(LV_ARRAY_DEFAULT_CAPACITY, lv_array_size(&array));
TEST_ASSERT_EQUAL_UINT32(12, lv_array_capacity(&array));
lv_array_resize(&array, 6);
TEST_ASSERT_EQUAL_UINT32(6, lv_array_length(&array));
TEST_ASSERT_EQUAL_UINT32(6, lv_array_size(&array));
TEST_ASSERT_EQUAL_UINT32(6, lv_array_capacity(&array));
}
void test_array_copy(void)
{
for(int32_t i = 0; i < 10; i++) {
LV_ARRAY_APPEND_VALUE(&array, i);
for(int32_t i = 0; i < LV_ARRAY_DEFAULT_CAPACITY; i++) {
lv_array_push_back(&array, &i);
}
lv_array_t array2;
lv_memset(&array2, 0, sizeof(lv_array_t));
TEST_ASSERT_EQUAL_UINT32(8, lv_array_length(&array));
uint32_t array_size = lv_array_size(&array);
lv_array_t array2 = { 0 };
lv_array_copy(&array2, &array);
TEST_ASSERT_EQUAL_UINT32(8, lv_array_length(&array2));
uint32_t * r = LV_ARRAY_GET(&array2, 1, uint32_t);
TEST_ASSERT_EQUAL_UINT32(array_size, lv_array_size(&array2));
uint32_t * r = lv_array_at(&array2, 1);
TEST_ASSERT_EQUAL_UINT32(1, *r);
lv_array_destroy(&array2);
lv_array_deinit(&array2);
}
void test_array_concat(void)
{
lv_array_t a, b;
lv_array_init(&a, 4, sizeof(int32_t));
lv_array_init(&b, 4, sizeof(int32_t));
for(int32_t i = 0; i < 4; i++) {
lv_array_push_back(&a, &i);
lv_array_push_back(&b, &i);
}
TEST_ASSERT_TRUE(lv_array_concat(&a, &b) == LV_RESULT_OK);
TEST_ASSERT_EQUAL_UINT32(8, lv_array_size(&a));
for(int32_t i = 0; i < 8; i++) {
int32_t * v = lv_array_at(&a, i);
TEST_ASSERT_EQUAL_INT32(i % 4, *v);
}
lv_array_deinit(&a);
lv_array_deinit(&b);
}
#endif