[C] 关于页面内运行各种步骤的方案

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
#include <stdarg.h>
 
// 睡眠函数,单位ms
void msleep(int ms)
{
    usleep(1000 * ms);
}
 
// 获取系统运行的时间,单位ms
uint32_t get_tick_count(void)
{
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    long uptime_ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
    return (uint32_t)uptime_ms;
}
 
#define println(fmt, args...) fprintf(stderr, "[%d] " fmt "\n", get_tick_count(), ##args)
 
static void step0_func_init(void);
static void step0_func_loop(void);
 
static void step1_func_init(void);
static void step1_func_loop(void);
 
static void step2_func_init(void);
static void step2_func_loop(void);
 
static void step3_func_init(void);
static void step3_func_loop(void);
 
 
typedef struct
{
    void (*step_func_init)(void);
    void (*step_func_loop)(void);
} pg_step_fun_t;

typedef struct
{
    void (*all_step_init)(void);
    pg_step_fun_t *func_list;
    uint8_t flag_force_init;   // 强制初始化
    uint8_t max_step_num;      // 最大步骤数
    uint8_t pg_step;           // 当前步骤
    uint8_t pg_step_old;       // 上一次步骤
    uint8_t pg_step_save;      // 步骤发生改变时,保存上一次步骤
    uint8_t dev_state_changed; // 设备状态改变标志
    uint16_t loop_cnt;         // 循环计数
    uint32_t tick_enter;       // 进入当前步骤的tick
    uint32_t tick_curr;        // 当前tick时间戳
} pg_param_t;
 
static pg_param_t g_param;
 
#define MAX_STEP_NUM 4 // 最大步骤数
// 本页面各步骤的初始化和循环函数列表定义
static pg_step_fun_t g_func_list[MAX_STEP_NUM] =
    {
        {step0_func_init, step0_func_loop},
        {step1_func_init, step1_func_loop},
        {step2_func_init, step2_func_loop},
        {step3_func_init, step3_func_loop},
};
 
 //当进入步骤时,会调用此函数【公用部分】
static void all_step_init(void)
{
    println("all_step_init.");
}
 
static void step0_func_init(void)
{
    println("step0_func_init.");
}
static void step0_func_loop(void)
{
    // 每跑100个循环打印一次
    if (g_param.loop_cnt % 100 == 0)
    {
        println("step0_func_loop.");
    }
    // 运行5秒后跳到step1
    if (g_param.tick_curr - g_param.tick_enter > 5000)
    {
        g_param.pg_step = 1;
    }
}
 
static void step1_func_init(void)
{
    println("step1_func_init.");
}
 
static void step1_func_loop(void)
{
    // println("step1_func_loop.");
    // 运行2秒后跳到step2
    if (g_param.tick_curr - g_param.tick_enter > 2000)
    {
        g_param.pg_step = 2;
    }
}
 
static void step2_func_init(void)
{
    println("step2_func_init.");
}
static void step2_func_loop(void)
{
    // 运行2秒后跳到step3
    if (g_param.tick_curr - g_param.tick_enter > 2000)
    {
        g_param.pg_step = 3;
    }
}
 
static void step3_func_init(void)
{
    println("step3_func_init.");
}
static void step3_func_loop(void)
{
    // 每跑50个循环后跳到step0
    if (g_param.loop_cnt > 50)
    {
        g_param.pg_step = 0;
        println("recall step0 here.");
    }
}
 
static void processing_step(pg_param_t *param)
{
    if (param->flag_force_init || param->pg_step != param->pg_step_old)
    {
        param->flag_force_init = 0;
        param->pg_step_save = param->pg_step_old;
        param->pg_step_old = param->pg_step;
        if (param->pg_step <= param->max_step_num)
        {
            param->loop_cnt = 0;
            param->tick_enter = get_tick_count();
            if(param->all_step_init != NULL)
                param->all_step_init();
            param->func_list[param->pg_step].step_func_init();
        }
    }
    if (param->pg_step <= param->max_step_num)
    {
        param->func_list[param->pg_step].step_func_loop();
        param->loop_cnt++;
    }
}
 
void jump_to_step(uint8_t step)
{
    g_param.pg_step = step;
    g_param.flag_force_init = 1;
}
 
// 页面内有N个步骤,每个步骤有初始化和循环函数,根据当前步骤,调用对应的初始化和循环函数
// 该设计模式可适用于LVGL,页面内嵌套子页面。
int main()
{
    println("_________SOFT BUILD: %s %s______", __DATE__, __TIME__);
 
    g_param.max_step_num = MAX_STEP_NUM;
    g_param.func_list = g_func_list;
    g_param.all_step_init = all_step_init;
 
    println("start testing step logic....");
    jump_to_step(3); // 首次运行,跳到step3
 
    while (1)
    {
        g_param.tick_curr = get_tick_count();
        processing_step(&g_param);
        msleep(10);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值