* @Author: luozheng 1732036298@qq.com\r
* @Date: 2024-04-07 18:15:53\r
* @LastEditors: luozheng 1732036298@qq.com\r
- * @LastEditTime: 2024-04-07 21:13:35\r
+ * @LastEditTime: 2024-04-08 20:43:16\r
* @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/countdown/src/CountDownModel.cpp\r
*/\r
#include "countdown/include/CountDownModel.h"\r
-#include <sstream>\r
-#include <sstream>\r
-#include <iomanip>\r
+#include <cmsis_os2.h>\r
+#include <ohos_types.h>\r
+#include <service/graphic_service.h>\r
+#include "wearable_log.h"\r
+#include "countdown/include/MainCountDownView.h"\r
+#include <cmsis_os.h>\r
namespace OHOS\r
{\r
/* -------------------------------------------------------------------------- */\r
- struct Time\r
- {\r
- int hour;\r
- int minute;\r
- int second;\r
- };\r
- // 解析时间字符串并返回 Time 结构体\r
- static Time ParseTimeString(const std::string &timeString)\r
- {\r
- Time time;\r
-\r
- std::stringstream ss(timeString);\r
- char delimiter;\r
+ // 声明定时器变量\r
+ static osTimerId_t g_timer = NULL;\r
+ int CountDownModel::g_CountDownTimes = {0};\r
+ static constexpr int32 NUM_TEN = 10; // 主要用于格式化输出,当小时、分钟或秒小于10时,在其前面添加一个’0’以保持常规时间格式,例如“09:05:03”。\r
+ static constexpr int16 NUM_TIME_MIN = 60;\r
+ static constexpr int16 NUM_TIME_HOUR = 3600;\r
+ static constexpr int32 NUM_TIME_DAY = 86400;\r
\r
- ss >> time.hour >> delimiter >> time.minute >> delimiter >> time.second;\r
-\r
- return time;\r
- }\r
- // 格式化时间:确保它是 “hh:mm:ss” 格式\r
- std::string FormatTime(int hours, int minutes, int seconds)\r
- {\r
- std::ostringstream oss;\r
- oss << std::setw(2) << std::setfill('0') << hours << ":"\r
- << std::setw(2) << std::setfill('0') << minutes << ":"\r
- << std::setw(2) << std::setfill('0') << seconds;\r
-\r
- return oss.str();\r
- }\r
/* -------------------------------------------------------------------------- */\r
// 定义了 GetInstance() 方法来获取 CountDownModel 的实例,确保只有一个全局实例存在。\r
CountDownModel *CountDownModel::GetInstance()\r
return &instance;\r
}\r
\r
+ // 函数用于解析"HH:MM:SS"格式的时间字符串,并更新g_CountDownTimes\r
+ void CountDownModel::ParseCountDownTime(const char *countdowntime)\r
+ {\r
+ int hours, minutes, seconds;\r
+\r
+ // 使用sscanf从字符串中读取格式化数据\r
+ // "%2d:%2d:%2d"用于检查两个数字,后面跟一个冒号,这样的模式重复两次,从而捕获三个整数\r
+ if (sscanf(countdowntime, "%2d:%2d:%2d", &hours, &minutes, &seconds) == 3)\r
+ {\r
+ // 解析成功,现在转换为总秒数\r
+ g_CountDownTimes = hours * NUM_TIME_HOUR + minutes * NUM_TIME_MIN + seconds;\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "g_CountDownTimes = %d", g_CountDownTimes);\r
+ }\r
+ else\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDownModel::ParseCountDownTime Parsing failure");\r
+ }\r
+ }\r
+\r
+ std::string CountDownModel::ParseRingTime(const std::string &timeStr)\r
+ {\r
+ int hours, minutes, seconds;\r
+ std::string formattedTime;\r
+ // 使用 sscanf 从字符串中读取时间数据\r
+ if (sscanf(timeStr.c_str(), "%2d:%2d:%2d", &hours, &minutes, &seconds) == 3)\r
+ {\r
+ // 如果小时部分为0,则格式化去掉小时部分\r
+ if (hours == 0)\r
+ {\r
+ formattedTime = (minutes < NUM_TEN ? "0" : "") + std::to_string(minutes) + ":" + (seconds < NUM_TEN ? "0" : "") + std::to_string(seconds);\r
+ }\r
+ else\r
+ {\r
+ // 如果小时部分不为0,保持原有格式\r
+ formattedTime = timeStr;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // 解析失败逻辑处理:可以选择记录错误、返回原字符串或其他合适的处理方式\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "TrimTimeFormat Parsing failure: Invalid format");\r
+ formattedTime = timeStr; // 例子中选择返回原字符串\r
+ }\r
+ return formattedTime;\r
+ }\r
+\r
// 设置倒计时时间\r
void CountDownModel::SetCountDownTime(const std::string &countdowntime)\r
{\r
CountTime = countdowntime;\r
+ ParseCountDownTime(CountTime.c_str());\r
}\r
\r
// 获取倒计时时间\r
// 设置响铃时间\r
void CountDownModel::SetRingTime(const std::string &ringtime)\r
{\r
- Time time = ParseTimeString(ringtime);\r
- if (time.hour == 0) // 如果倒计时时间小于一小时就只显示分钟和秒\r
- {\r
- std::string rt = ringtime.substr(3, 5); //"00:05:00":从第3个位置开始截图5个字符 ,substr不会修改原来的字符串\r
- RingTime = rt;\r
- return;\r
- }\r
- RingTime = ringtime;\r
+ RingTime = ParseRingTime(ringtime);\r
}\r
\r
// 获取响铃时间\r
return RingTime;\r
}\r
\r
+ /* ----------------------------------- 定时器 ---------------------------------- */\r
+\r
+ /*\r
+ * @brief 显示计时器(时、分、秒)\r
+ */\r
+ const char *CountDownModel::DisplayCountDownDuration()\r
+ {\r
+ countdownDuration.clear(); // 更正为clear(),更加表明意图,与erase()等价\r
+ std::string hours;\r
+ std::string minute;\r
+ std::string seconds;\r
+\r
+ if (g_CountDownTimes >= NUM_TIME_DAY)\r
+ {\r
+ g_CountDownTimes = 0;\r
+ }\r
+\r
+ int hour = g_CountDownTimes / NUM_TIME_HOUR;\r
+ int min = (g_CountDownTimes % NUM_TIME_HOUR) / NUM_TIME_MIN;\r
+ int sec = (g_CountDownTimes % NUM_TIME_HOUR) % NUM_TIME_MIN;\r
+\r
+ hours = (hour < NUM_TEN) ? "0" + std::to_string(hour) : std::to_string(hour);\r
+ minute = (min < NUM_TEN) ? "0" + std::to_string(min) : std::to_string(min);\r
+ seconds = (sec < NUM_TEN) ? "0" + std::to_string(sec) : std::to_string(sec);\r
+ countdownDuration = hours + ":" + minute + ":" + seconds;\r
+\r
+ return countdownDuration.c_str(); // 返回 std::string 的 c_str(),但需要注意生命周期\r
+ }\r
+ /*\r
+ * @brief 在这里添加定时器到期后的处理逻辑\r
+ */\r
+ static void CountDown_TimerCallbackProc(int data)\r
+ {\r
+ CountDownModel::g_CountDownTimes--; // 每次回调减少1秒\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "g_CountDownTimes:%d\n", CountDownModel::g_CountDownTimes);\r
+\r
+ if (MainCountDownView::GetInstance() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDown_TimerCallbackProc] GetInstance is NULL");\r
+ return;\r
+ }\r
+\r
+ if (MainCountDownView::GetInstance()->GetStartCountDownView()->GetShowCountDownTimelabel() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDown_TimerCallbackProc] GetShowCountDownTimelabel is NULL");\r
+ return;\r
+ }\r
+\r
+ if (CountDownModel::GetInstance()->DisplayCountDownDuration() == nullptr)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDown_TimerCallbackProc] DisplayCountDownDuration is NULL");\r
+ return;\r
+ }\r
+\r
+ // 检查倒计时是否结束\r
+ if (CountDownModel::g_CountDownTimes <= 0)\r
+ {\r
+ CountDownModel::GetInstance()->CountDown_StopTimer(); // 停止定时器\r
+ MainCountDownView::GetInstance()->GetStartCountDownView()->GetShowCountDownTimelabel()->SetText("倒计时结束");\r
+ // 进行倒计时结束时的额外操作,比如播放声音、显示通知等\r
+ }\r
+ else\r
+ {\r
+ // 更新显示\r
+ MainCountDownView::GetInstance()->GetStartCountDownView()->GetShowCountDownTimelabel()->SetText(CountDownModel::GetInstance()->DisplayCountDownDuration());\r
+ }\r
+ }\r
+\r
+ /*\r
+ * @brief 计时器回调函数\r
+ */\r
+ static void CountDown_TimerCallback(int data)\r
+ {\r
+ GraphicService::GetInstance()->PostGraphicEvent(std::bind(CountDown_TimerCallbackProc, data));\r
+ }\r
+\r
+ /*\r
+ * @brief 开启定时器函数\r
+ * @param interval 时间间隔,单位ms\r
+ */\r
+ void CountDownModel::CountDown_StartTimer(uint32_t interval)\r
+ {\r
+ /* -------------------------- 1.检查定时器是否已经存在,如果存在则返回 ------------------------- */\r
+ if (g_timer != NULL)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDownModel::CountDown_StartTimer Timer already exists!!");\r
+ return;\r
+ }\r
+\r
+ /* --------------------------------- 2.创建定时器 -------------------------------- */\r
+ g_timer = osTimerNew((osTimerFunc_t)CountDown_TimerCallback, osTimerPeriodic, NULL, NULL);\r
+ // 检查定时器创建是否成功\r
+ if (g_timer == NULL)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDownModel::CountDown_StartTimer Timer create failed!!");\r
+ return;\r
+ }\r
+\r
+ /* ----------------------------- 3.将毫秒转换为系统时钟节拍数 ---------------------------- */\r
+ int tick = osMs2Tick(interval);\r
+\r
+ /* --------------------------------- 4.启动定时器 -------------------------------- */\r
+ // g_timerStartTimestamp = GetCurrentTimestamp(); // 假设GetCurrentTimestamp()是获取当前时间戳的函数\r
+ osStatus_t ret = osTimerStart(g_timer, tick);\r
+ /* -------------------- 5.检查定时器启动是否成功,如果启动失败,删除定时器并置为 NULL -------------------- */\r
+ if (ret != osOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[CountDown_StartTimer] osTimerDelete failed, ret = %lx!!", ret);\r
+ if (g_timer != NULL)\r
+ {\r
+ ret = osTimerDelete(g_timer);\r
+ }\r
+ g_timer = NULL;\r
+ return;\r
+ }\r
+ return;\r
+ }\r
+\r
+ /*\r
+ * @brief 停止定时器\r
+ */\r
+ void CountDownModel::CountDown_StopTimer(void)\r
+ {\r
+ // 检查定时器是否存在\r
+ if (g_timer != NULL)\r
+ {\r
+ // 删除定时器并置为 NULL\r
+ osStatus_t ret = osTimerDelete(g_timer);\r
+ if (ret != osOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ScanTimerCallback osTimerDelete failed, ret = %lx!!", ret);\r
+ }\r
+ g_timer = NULL;\r
+ g_CountDownTimes = 0;\r
+ }\r
+ }\r
+ /*\r
+ * @brief 暂停定时器\r
+ */\r
+ void CountDownModel::CountDown_PauseTimer(void)\r
+ {\r
+ // 检查定时器是否存在\r
+ if (g_timer != NULL)\r
+ {\r
+ // 暂停定时器,但不删除它\r
+ osStatus_t ret = osTimerStop(g_timer);\r
+ if (ret != osOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDown_PauseTimer osTimerStop failed, ret = %lx!!", ret);\r
+ }\r
+ }\r
+ }\r
+\r
+ /*\r
+ * @brief 恢复定时器\r
+ */\r
+ void CountDownModel::CountDown_ResumeTimer(uint32_t interval)\r
+ {\r
+ // 检查定时器是否存在\r
+ if (g_timer != NULL)\r
+ {\r
+ int tick = osMs2Tick(interval);\r
+ // 恢复定时器\r
+ osStatus_t ret = osTimerStart(g_timer, tick);\r
+ if (ret != osOK)\r
+ {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CountDown_ResumeTimer osTimerStart failed, ret = %lx!!", ret);\r
+ }\r
+ }\r
+ }\r
+\r
}\r