chore(demos): add common entry for lv_demos (#4610)

Signed-off-by: XiaoweiYan <yanxiaowei@xiaomi.com>
Signed-off-by: YanXiaowei <yanxiaowei@xiaomi.com>
Co-authored-by: XiaoweiYan <yanxiaowei@xiaomi.com>
This commit is contained in:
bjsylvia 2023-10-11 04:28:17 +08:00 committed by GitHub
parent 3adaee8fde
commit 14c0869e68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 268 additions and 13 deletions

View File

@ -35,6 +35,18 @@
# define LV_DEMO_MUSIC_LARGE 0
# define LV_DEMO_MUSIC_AUTO_PLAY 0
#endif
/*Flex layout demo*/
#define LV_USE_DEMO_FLEX_LAYOUT 0
/*Smart-phone like multi-language demo*/
#define LV_USE_DEMO_MULTILANG 0
/*Widget transformation demo*/
#define LV_USE_DEMO_TRANSFORM 0
/*Demonstrate scroll settings*/
#define LV_USE_DEMO_SCROLL 0
...
```
@ -48,7 +60,58 @@
...
```
## Configure Demos Entry
"demos/lv_demos.c" provides `lv_demos_create` and `lv_demos_usage` to simplify the creation of demos.
If you build your main program named `lv_demos`, then you can run the widgets demo by running `lv_demos widgets` and the benchmark demo by running `lv_demos benchmark 1`.
For example:
```c
//! main.c
#include "lvgl.h"
#include "demos/lv_demos.h"
...
static lv_disp_t* hal_init(void)
{
lv_disp_t* disp = NULL;
...
/* TODO: init display and indev */
...
return disp;
}
int main(int argc, char ** argv)
{
lv_init();
lv_disp_t* disp = hal_init();
if (disp == NULL) {
LV_LOG_ERROR("lv_demos initialization failure!");
return 1;
}
if (!lv_demos_create(&argv[1], argc - 1)) {
lv_demos_usage();
goto demo_end;
}
while (1) {
uint32_t delay = lv_timer_handler();
if (delay < 1) delay = 1;
usleep(delay * 1000);
}
demo_end:
lv_deinit();
return 0;
}
```
## Demos

181
demos/lv_demos.c Normal file
View File

@ -0,0 +1,181 @@
/**
* @file lv_demos.c
*
*/
/*********************
* INCLUDES
*********************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "lv_demos.h"
/*********************
* DEFINES
*********************/
#define DEMO_BENCHMARK_NAME "benchmark"
#define DEMO_BENCHMARK_SCENE_NAME "benchmark_scene"
#define LV_DEMOS_COUNT (sizeof(demos_entry_info) / sizeof(demo_entry_info_t) - 1)
/**********************
* TYPEDEFS
**********************/
typedef void (*demo_method_cb)(void);
#if LV_USE_DEMO_BENCHMARK
typedef void (*demo_method_benchmark_cb)(lv_demo_benchmark_mode_t);
typedef void (*demo_method_benchmark_scene_cb)(lv_demo_benchmark_mode_t, uint16_t);
#endif
typedef struct {
const char * name;
union {
demo_method_cb entry_cb;
#if LV_USE_DEMO_BENCHMARK
demo_method_benchmark_cb entry_benchmark_cb;
demo_method_benchmark_scene_cb entry_benchmark_scene_cb;
#endif
};
int arg_count : 8;
} demo_entry_info_t;
/**********************
* STATIC PROTOTYPES
**********************/
static inline bool demo_is_benchmark(const demo_entry_info_t * entry)
{
return (entry) && entry->arg_count == 1 && strcmp(entry->name, DEMO_BENCHMARK_NAME) == 0 ? true : false;
}
static inline bool demo_is_benchmark_scene(const demo_entry_info_t * entry)
{
return (entry) && entry->arg_count == 2 && strcmp(entry->name, DEMO_BENCHMARK_SCENE_NAME) == 0 ? true : false;
}
/**********************
* STATIC VARIABLES
**********************/
static const demo_entry_info_t demos_entry_info[] = {
#if LV_USE_DEMO_WIDGETS
{ "widgets", .entry_cb = lv_demo_widgets },
#endif
#if LV_USE_DEMO_MUSIC
{ "music", .entry_cb = lv_demo_music },
#endif
#if LV_USE_DEMO_MULTILANG
{ "multilang", .entry_cb = lv_demo_multilang },
#endif
#if LV_USE_DEMO_STRESS
{ "stress", .entry_cb = lv_demo_stress },
#endif
#if LV_USE_DEMO_KEYPAD_AND_ENCODER
{ "keypad_encoder", .entry_cb = lv_demo_keypad_encoder },
#endif
#if LV_USE_DEMO_FLEX_LAYOUT
{ "flex_layout", .entry_cb = lv_demo_flex_layout },
#endif
#if LV_USE_DEMO_TRANSFORM
{ "transform", .entry_cb = lv_demo_transform },
#endif
#if LV_USE_DEMO_SCROLL
{ "scroll", .entry_cb = lv_demo_scroll },
#endif
#if LV_USE_DEMO_BENCHMARK
{ DEMO_BENCHMARK_NAME, .entry_benchmark_cb = lv_demo_benchmark, 1 },
{ DEMO_BENCHMARK_SCENE_NAME, .entry_benchmark_scene_cb = lv_demo_benchmark_run_scene, 2 },
#endif
{ "", .entry_cb = NULL }
};
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
bool lv_demos_create(char * info[], int size)
{
const int demos_count = LV_DEMOS_COUNT;
if(demos_count <= 0) {
LV_LOG_ERROR("Please enable some lv_demos firstly!");
return false;
}
const demo_entry_info_t * entry_info = NULL;
if(size <= 0) { /* default: first demo*/
entry_info = &demos_entry_info[0];
}
if(entry_info == NULL && info) {
const char * name = info[0];
for(int i = 0; i < demos_count; i++) {
if(strcmp(name, demos_entry_info[i].name) == 0 && size - 1 >= demos_entry_info[i].arg_count) {
entry_info = &demos_entry_info[i];
}
}
}
if(entry_info == NULL) {
LV_LOG_ERROR("lv_demos create(%s) failure!", size > 0 ? info[0] : "");
return false;
}
if(entry_info->arg_count == 0) {
if(entry_info->entry_cb) {
entry_info->entry_cb();
return true;
}
}
#if LV_USE_DEMO_BENCHMARK
else if(demo_is_benchmark(entry_info) && entry_info->entry_benchmark_cb) {
entry_info->entry_benchmark_cb((lv_demo_benchmark_mode_t)atoi(info[1]));
return true;
}
else if(demo_is_benchmark_scene(entry_info) && entry_info->entry_benchmark_scene_cb) {
entry_info->entry_benchmark_scene_cb((lv_demo_benchmark_mode_t)atoi(info[1]), (uint16_t)atoi(info[2]));
return true;
}
#endif
return false;
}
void lv_demos_show_help(void)
{
int i;
const int demos_count = LV_DEMOS_COUNT;
if(demos_count == 0) {
LV_LOG("lv_demos: no demo available!\n");
return;
}
LV_LOG("\nUsage: lv_demos demo [parameters]\n");
LV_LOG("\ndemo list:\n");
for(i = 0; i < demos_count; i++) {
if(demos_entry_info[i].arg_count == 0) {
LV_LOG(" %s \n", demos_entry_info[i].name);
}
else if(demo_is_benchmark(&demos_entry_info[i])) {
LV_LOG(" %s [0, 1, 2] \t\t\t(0 for Render&Driver, 1 for Real Render, 2 for Render Only)\n",
demos_entry_info[i].name);
}
else if(demo_is_benchmark_scene(&demos_entry_info[i])) {
LV_LOG(" %s [0, 1, 2] scene_no \t(0 for Render&Driver, 1 for Real Render, 2 for Render Only)\n",
demos_entry_info[i].name);
}
}
}

View File

@ -63,6 +63,18 @@ extern "C" {
* GLOBAL PROTOTYPES
**********************/
/**
* Call lv_demo_xxx.
* @param info the information which contains demo name and parameters
* needs by lv_demo_xxx.
* @size size of information.
*/
bool lv_demos_create(char * info[], int size);
/**
* Show help for lv_demos.
*/
void lv_demos_show_help(void);
/**********************
* MACROS

View File

@ -267,10 +267,15 @@ void lv_init(void)
LV_LOG_TRACE("finished");
}
#if LV_ENABLE_GLOBAL_CUSTOM || LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN
void lv_deinit(void)
{
/*Do nothing if already deinit*/
if(!lv_initialized) {
LV_LOG_WARN("lv_deinit: already deinit!");
return;
}
#if LV_ENABLE_GLOBAL_CUSTOM || LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN
#if LV_USE_SYSMON
_lv_sysmon_builtin_deinit();
#endif
@ -299,10 +304,6 @@ void lv_deinit(void)
lv_mem_deinit();
lv_initialized = false;
LV_LOG_INFO("lv_deinit done");
#if LV_USE_LOG
lv_log_register_print_cb(NULL);
#endif
@ -310,9 +311,13 @@ void lv_deinit(void)
#if LV_USE_OBJ_ID_BUILTIN
lv_objid_builtin_destroy();
#endif
}
#endif
lv_initialized = false;
LV_LOG_INFO("lv_deinit done");
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@ -35,17 +35,11 @@ extern "C" {
void lv_init(void);
#if LV_ENABLE_GLOBAL_CUSTOM || LV_USE_STDLIB_MALLOC == LV_STDLIB_BUILTIN
/**
* Deinit the 'lv' library
* Currently only implemented when not using custom allocators,
* or using custom 'lv_global'.
*/
void lv_deinit(void);
#endif
/**
* Returns whether the 'lv' library is currently initialized
*/