Files
stc32g128k/App/appmgr.c

262 lines
6.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "appmgr.h"
#include "../Drivers/lcd.h"
/* =========================================================================
* 应用管理器内部变量
* ========================================================================= */
// 应用注册表:存储所有已注册的应用
static WristbandApp app_registry[APP_ID_MAX];
// 当前活跃的前台应用指针
static WristbandApp *active_app = NULL;
// 默认应用(时钟)
#define DEFAULT_APP_ID APP_ID_CLOCK
/* =========================================================================
* 应用生命周期辅助函数
* ========================================================================= */
static void AppManager_ExecuteOnStart(WristbandApp *app)
{
if (app != NULL && app->OnStart != NULL)
{
app->OnStart();
app->is_active = 1;
app->is_running = 1;
}
}
static void AppManager_ExecuteOnClose(WristbandApp *app)
{
if (app != NULL && app->onClose != NULL)
{
app->onClose();
app->is_active = 0;
app->is_running = 0;
}
}
static void AppManager_ExecuteOnRun(WristbandApp *app)
{
if (app != NULL && app->onRun != NULL && app->is_running)
{
// CPU占用控制记录开始时间
u16 start_tick = ms_tick;
// 执行应用的onRun回调
app->onRun();
// 检测执行时间是否超限
u16 elapsed_ticks = ms_tick - start_tick;
if (elapsed_ticks > APP_ONRUN_MAX_TICKS)
{
// 应用执行时间过长,强制标记为非活跃
// 但不直接关闭,允许应用在下一次循环中恢复
app->is_running = 0;
}
}
}
static EventResult AppManager_ExecuteOnEvent(WristbandApp *app, SystemEvent evt)
{
if (app != NULL && app->onEvent != NULL)
{
return app->onEvent(evt);
}
return EVENT_IGNORED;
}
/* =========================================================================
* 应用管理器核心实现
* ========================================================================= */
void AppManager_Init(void)
{
u8 i;
// 初始化所有应用描述符
for (i = 0; i < APP_ID_MAX; i++)
{
app_registry[i].app_id = (AppID)i;
app_registry[i].app_type = APP_TYPE_FOREGROUND;
app_registry[i].app_name = "UNREGISTERED";
app_registry[i].OnStart = NULL;
app_registry[i].onRun = NULL;
app_registry[i].onClose = NULL;
app_registry[i].onEvent = NULL;
app_registry[i].is_active = 0;
app_registry[i].is_running = 0;
}
// 默认启动时钟应用
active_app = &app_registry[DEFAULT_APP_ID];
AppManager_ExecuteOnStart(active_app);
}
void AppManager_StartApp(AppID app_id)
{
// 参数有效性检查
if (app_id >= APP_ID_MAX)
{
return;
}
// 获取目标应用指针
WristbandApp *target_app = &app_registry[app_id];
// 目标应用必须是前台应用
if (target_app->app_type != APP_TYPE_FOREGROUND)
{
return;
}
// 目标应用必须已注册有OnStart回调
if (target_app->OnStart == NULL)
{
return;
}
// 如果目标应用已经是活跃应用,直接返回
if (active_app == target_app)
{
return;
}
// 关闭当前活跃应用
if (active_app != NULL)
{
AppManager_ExecuteOnClose(active_app);
}
// 切换到新应用
active_app = target_app;
// 启动新应用
AppManager_ExecuteOnStart(active_app);
}
void AppManager_CloseApp(void)
{
// 关闭当前活跃应用
if (active_app != NULL)
{
AppManager_ExecuteOnClose(active_app);
active_app = NULL;
}
// 启动默认应用(时钟)
active_app = &app_registry[DEFAULT_APP_ID];
AppManager_ExecuteOnStart(active_app);
}
AppID AppManager_GetActiveAppID(void)
{
if (active_app != NULL)
{
return active_app->app_id;
}
return DEFAULT_APP_ID;
}
void AppManager_DispatchEvent(SystemEvent evt)
{
EventResult result;
// 步骤1优先分发给当前活跃的前台应用
if (active_app != NULL && active_app->is_active)
{
result = AppManager_ExecuteOnEvent(active_app, evt);
// 前台应用已处理,无需继续分发
if (result == EVENT_HANDLED)
{
return;
}
}
// 步骤2前台未处理分发给所有后台应用
// 遍历应用注册表,找到所有后台应用
u8 i;
for (i = 0; i < APP_ID_MAX; i++)
{
WristbandApp *bg_app = &app_registry[i];
// 跳过前台应用和未注册应用
if (bg_app->app_type != APP_TYPE_BACKGROUND ||
bg_app->onEvent == NULL ||
!bg_app->is_running)
{
continue;
}
// 调用后台应用的事件处理函数
result = AppManager_ExecuteOnEvent(bg_app, evt);
// 如果后台应用处理了事件,停止继续分发
if (result == EVENT_HANDLED)
{
return;
}
}
// 步骤3所有应用都未处理事件被丢弃
// 可以在这里添加日志记录(如果需要)
}
void AppManager_RunActiveApp(void)
{
// 执行当前活跃应用的onRun回调带CPU占用控制
if (active_app != NULL && active_app->is_active)
{
AppManager_ExecuteOnRun(active_app);
}
}
void AppManager_BroadcastToBackground(SystemEvent evt)
{
// 广播事件给所有后台应用
u8 i;
for (i = 0; i < APP_ID_MAX; i++)
{
WristbandApp *bg_app = &app_registry[i];
// 仅发送给后台应用
if (bg_app->app_type == APP_TYPE_BACKGROUND &&
bg_app->onEvent != NULL &&
bg_app->is_running)
{
AppManager_ExecuteOnEvent(bg_app, evt);
}
}
}
/* =========================================================================
* 应用注册接口(供各应用模块调用)
* ========================================================================= */
void AppManager_RegisterApp(AppID app_id, AppType app_type, char *app_name,
AppStartFunc on_start, AppRunFunc on_run,
AppCloseFunc on_close, AppEventFunc on_event)
{
if (app_id >= APP_ID_MAX)
{
return;
}
WristbandApp *app = &app_registry[app_id];
app->app_type = app_type;
app->app_name = app_name;
app->OnStart = on_start;
app->onRun = on_run;
app->onClose = on_close;
app->onEvent = on_event;
// 后台应用默认处于运行状态
if (app_type == APP_TYPE_BACKGROUND)
{
app->is_running = 1;
}
}