From bdd69e2e5968670a73ea2c8e83672e923f690b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=95=E6=98=8E=E6=B1=9F?= <246462502@qq.com> Date: Sat, 24 Feb 2024 15:06:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=AE=8C=E6=88=90ui=E8=AE=BE=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/tasks.json | 28 +++++++ app/jj_param.c | 88 +++++++++++++--------- app/jj_param.h | 40 ++++++---- app/main.c | 3 +- app/page/page.c | 14 ++-- app/page/page.h | 20 +++-- app/page/page_dparam.c | 71 ++++++++++++++++++ app/page/page_menu.c | 6 +- app/page/page_param.c | 133 --------------------------------- app/page/page_rtcam.c | 4 +- app/page/page_sparam.c | 163 +++++++++++++++++++++++++++++++++++++++++ 11 files changed, 364 insertions(+), 206 deletions(-) create mode 100644 .vscode/tasks.json create mode 100644 app/page/page_dparam.c delete mode 100644 app/page/page_param.c create mode 100644 app/page/page_sparam.c diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..ddfadc2 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc.exe 生成活动文件", + "command": "D:\\MinGW\\bin\\gcc.exe", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}\\${fileBasenameNoExtension}.exe" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "调试器生成的任务。" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/app/jj_param.c b/app/jj_param.c index ced4ada..1142af9 100644 --- a/app/jj_param.c +++ b/app/jj_param.c @@ -5,44 +5,34 @@ PARAM_INFO Param_Data[DATA_NUM]; soft_iic_info_struct eeprom_param; TYPE_UNION iic_buffer[DATA_IN_FLASH_NUM]; - -void jj_param_eeprom_init() -{ - soft_iic_init(&eeprom_param, K24C02_DEV_ADDR, K24C02_SOFT_IIC_DELAY, K24C02_SCL_PIN, K24C02_SDA_PIN); // eeprom 初始化 - // PARAM_REG(angle_Kp, &an_Kp, EFLOAT, 1, "an_P"); // 注冊 - // PARAM_REG(angle_Ki, &an_Ki, EFLOAT, 1, "an_I"); // 注冊 - // PARAM_REG(angle_Kd, &an_Kd, EFLOAT, 1, "an_D"); // 注冊 - // PARAM_REG(imgax_Kp, &im_Kp, EFLOAT, 1, "im_P"); // 注冊 - // PARAM_REG(imgax_Ki, &im_Ki, EFLOAT, 1, "im_I"); // 注冊 - // PARAM_REG(imgax_Kd, &im_Kd, EFLOAT, 1, "im_D"); // 注冊 - - for (uint8 i = 0; i < DATA_IN_FLASH_NUM; i++) { - - soft_iic_read_8bit_registers(&eeprom_param, 4 * i, (uint8 *)&iic_buffer[i], 4); - switch (Param_Data[i].type) { - case EFLOAT: - *((float *)(Param_Data[i].p_data)) = - iic_buffer[i].f32; - break; - case EUINT32: - *((uint32 *)(Param_Data[i].p_data)) = - iic_buffer[i].u32; - break; - case EINT32: - *((int32 *)(Param_Data[i].p_data)) = - iic_buffer[i].s32; - break; - default: - break; - } - system_delay_ms(10); - } -} +float data0 = 1.0f; +float data1 = 1.05f; +float data2 = 10.0f; +float data3 = 100.0f; +float data4 = 4.0f; +float data5 = 66.0f; +float data6 = 13.130f; /** - * @brief 参数更新 + * @brief 参数初始化注册 * */ -void jj_param_update() +void jj_param_eeprom_init(void) +{ + soft_iic_init(&eeprom_param, K24C02_DEV_ADDR, K24C02_SOFT_IIC_DELAY, K24C02_SCL_PIN, K24C02_SDA_PIN); // eeprom初始化 + PARAM_REG(angle_Kp, &data0, EFLOAT, 1, "an_P:"); // 注冊 + PARAM_REG(angle_Ki, &data1, EFLOAT, 1, "an_I:"); // 注冊 + PARAM_REG(angle_Kd, &data2, EFLOAT, 1, "an_D:"); // 注冊 + PARAM_REG(imgax_Kp, &data3, EFLOAT, 1, "im_P:"); // 注冊 + PARAM_REG(imgax_Ki, &data4, EFLOAT, 1, "im_I:"); // 注冊 + PARAM_REG(imgax_Kd, &data5, EFLOAT, 1, "im_D:"); + PARAM_REG(other, &data6, EFLOAT, 1, "add:"); + jj_param_read(); // 注冊 +} +/** + * @brief 参数写入 + * + */ +void jj_param_write(void) { for (uint8 i = 0; i < DATA_IN_FLASH_NUM; i++) { switch (Param_Data[i].type) { @@ -62,3 +52,31 @@ void jj_param_update() system_delay_ms(10); } } +/** + * @brief 参数读出 + * + */ +void jj_param_read(void) +{ + for (uint8 i = 0; i < DATA_IN_FLASH_NUM; i++) { + + soft_iic_read_8bit_registers(&eeprom_param, 4 * i, (uint8 *)&iic_buffer[i], 4); + switch (Param_Data[i].type) { + case EFLOAT: + *((float *)(Param_Data[i].p_data)) = + iic_buffer[i].f32; + break; + case EUINT32: + *((uint32 *)(Param_Data[i].p_data)) = + iic_buffer[i].u32; + break; + case EINT32: + *((int32 *)(Param_Data[i].p_data)) = + iic_buffer[i].s32; + break; + default: + break; + } + system_delay_ms(10); + } +} diff --git a/app/jj_param.h b/app/jj_param.h index 3fbe8bb..6faea53 100644 --- a/app/jj_param.h +++ b/app/jj_param.h @@ -6,22 +6,30 @@ #include "zf_driver_soft_iic.h" /** * @brief 注册需调参数 - * + * */ -#define PARAM_REG(_data_tag_, _p_data_, _type_, _cmd_,_text_) \ - Param_Data[_data_tag_].p_data = (void *)_p_data_; \ - Param_Data[_data_tag_].type = _type_; \ - Param_Data[_data_tag_].cmd = _cmd_; \ +#define PARAM_REG(_data_tag_, _p_data_, _type_, _cmd_, _text_) \ + Param_Data[_data_tag_].p_data = (void *)_p_data_; \ + Param_Data[_data_tag_].type = _type_; \ + Param_Data[_data_tag_].cmd = _cmd_; \ Param_Data[_data_tag_].text = _text_; - + typedef enum { - DATA_HEAD = -1, - angle_Kp, + + Page1_head=0, + + angle_Kp=Page1_head, angle_Ki, angle_Kd, - imgax_Kp, + other, + + Page2_head, + // 第二页参数 + imgax_Kp=Page2_head, imgax_Ki, imgax_Kd, + + Page3_head, DATA_IN_FLASH_NUM, DATA_NUM, } data_tag_t; @@ -30,26 +38,26 @@ typedef enum { EUINT32, EINT32, EFLOAT, -}ENUM_TYPE; +} ENUM_TYPE; -typedef union{ +typedef union { uint32_t u32; int32_t s32; float f32; uint8_t u8; -}TYPE_UNION; +} TYPE_UNION; typedef struct { void *p_data; ENUM_TYPE type; uint8_t cmd; char *text; -}PARAM_INFO; +} PARAM_INFO; extern soft_iic_info_struct eeprom_param; extern PARAM_INFO Param_Data[DATA_NUM]; extern TYPE_UNION iic_buffer[DATA_IN_FLASH_NUM]; -void jj_param_eeprom_init(); -void jj_param_update(); -void jj_param_show(); +void jj_param_eeprom_init(void); +void jj_param_write(void); +void jj_param_read(void); #endif \ No newline at end of file diff --git a/app/main.c b/app/main.c index 8e69e41..9421a54 100644 --- a/app/main.c +++ b/app/main.c @@ -43,8 +43,7 @@ int main(void) by_button_init(); jj_bt_init(); - // jj_param_eeprom_init(); - + jj_param_eeprom_init(); Page_Init(); pit_ms_init(TIM6_PIT, 2); diff --git a/app/page/page.c b/app/page/page.c index 942940c..01ef310 100644 --- a/app/page/page.c +++ b/app/page/page.c @@ -4,8 +4,8 @@ PAGE_LIST pagelist[page_max]; static uint8_t page_busy = 0; +int8_t new_page = page_menu; static int8_t now_page = page_menu; -static int8_t new_page = page_menu; /** * @brief 注册一个基本页面,包含一个初始化函数,循环函数,退出函数,事件函数 @@ -17,11 +17,11 @@ static int8_t new_page = page_menu; * @param eventCallback: 事件函数回调 * @retval 无 */ -void Page_Register(uint8_t pageID, char *pageText, +void Page_Register(uint8_t pageID, CallbackFunction_t setupCallback, CallbackFunction_t loopCallback, CallbackFunction_t exitCallback, EventFunction_t eventCallback) { - pagelist[pageID].Text = pageText; + pagelist[pageID].SetupCallback = setupCallback; pagelist[pageID].LoopCallback = loopCallback; pagelist[pageID].ExitCallback = exitCallback; @@ -123,9 +123,11 @@ void Page_Run(void) */ void Page_Init(void) { - PAGE_REG(page_menu); - PAGE_REG(page_rtcam); - PAGE_REG(page_param); + PAGE_REG(page_menu, "main"); + PAGE_REG(page_rtcam, "rtcam"); + PAGE_REG(page_param1, "Param1"); + PAGE_REG(page_param2, "param2"); + PAGE_REG(page_dparam, "dparam"); // PAGE_REG(page_argv); // PAGE_REG(page_sys); // PAGE_REG(page_run); diff --git a/app/page/page.h b/app/page/page.h index 3d51e41..39ef9eb 100644 --- a/app/page/page.h +++ b/app/page/page.h @@ -20,7 +20,9 @@ enum PageID { //...... page_menu, page_rtcam, - page_param, + page_param1, + page_param2, + page_dparam, // page_argv, // page_sys, // page_run, @@ -46,13 +48,15 @@ typedef struct { } PAGE_LIST; // 页面注册函数 -#define PAGE_REG(name) \ - do { \ - extern void PageRegister_##name(unsigned char pageID); \ - PageRegister_##name(name); \ - } while (0) +#define PAGE_REG(_name_, _text_) \ + do { \ + extern void PageRegister_##_name_(unsigned char pageID); \ + PageRegister_##_name_(_name_); \ + } while (0); \ + pagelist[_name_].Text = _text_ ; -void Page_Register(uint8_t pageID, char *pageText, + +void Page_Register(uint8_t pageID, CallbackFunction_t setupCallback, CallbackFunction_t loopCallback, CallbackFunction_t exitCallback, EventFunction_t eventCallback); @@ -65,5 +69,5 @@ void Page_Run(void); void Page_Init(void); extern PAGE_LIST pagelist[page_max]; - +extern int8_t new_page ; #endif diff --git a/app/page/page_dparam.c b/app/page/page_dparam.c new file mode 100644 index 0000000..ebcb4be --- /dev/null +++ b/app/page/page_dparam.c @@ -0,0 +1,71 @@ +#include "zf_common_headfile.h" +#include "page_ui_widget.h" +#include "page.h" +float ddata0=0.0f; +// #define LINE_HEAD 1 +// #define LINE_END 7 +// static int8_t Curser = LINE_HEAD; // 定义光标位置 +// static int8_t Curser_Last = LINE_HEAD; // 定义光标位置 +/*************************************************************************************** + * + * 以下为页面模板函数 + * + ***************************************************************************************/ + +/** + * @brief 页面初始化事件 + * @param 无 + * @retval 无 + */ +static void Setup() +{ + ips200_clear(); + // 显示参数名称 + ips200_show_string(0, 0, "Dparam"); + ips200_show_string(20, 18 + 2, "ddata0:"); +} + +/** + * @brief 页面退出事件 + * @param 无 + * @retval 无 + */ +static void Exit() +{ + +} + +/** + * @brief 页面循环执行的内容 + * @param 无 + * @retval 无 + */ +static void Loop() +{ + // 刷新参数数值 + ips200_show_float(80, 18 + 2, ddata0, 4, 5); + ddata0+=0.01f; +} + +/** + * @brief 页面事件 + * @param btn:发出事件的按键 + * @param event:事件编号 + * @retval 无 + */ +static void Event(page_event event) +{ + if (page_event_press_long == event) { + Page_Shift(page_menu); + } +} + +/** + * @brief 页面注册函数 + * + * @param pageID + */ +void PageRegister_page_dparam(unsigned char pageID) +{ + Page_Register(pageID, Setup, Loop, Exit, Event); +} diff --git a/app/page/page_menu.c b/app/page/page_menu.c index 8605e47..be60e04 100644 --- a/app/page/page_menu.c +++ b/app/page/page_menu.c @@ -57,9 +57,9 @@ static void Event(page_event event) Curser_Last = Curser; if (page_event_forward == event) { - Curser--; // 光标上移 + Curser++; // 光标上移 } else if (page_event_backward == event) { - Curser++; // 光标下移 + Curser--; // 光标下移 } else if (page_event_press_short == event) { if (page_max > Curser && page_menu < Curser) { Page_Shift(Curser); // 切换到光标选中的页面 @@ -82,7 +82,7 @@ static void Event(page_event event) */ void PageRegister_page_menu(unsigned char pageID) { - Page_Register(pageID, Text, Setup, Loop, Exit, Event); + Page_Register(pageID, Setup, Loop, Exit, Event); } /*************************************************************************************** diff --git a/app/page/page_param.c b/app/page/page_param.c deleted file mode 100644 index ef57df5..0000000 --- a/app/page/page_param.c +++ /dev/null @@ -1,133 +0,0 @@ -#include "jj_param.h" -#include "page_ui_widget.h" -#include "page.h" - -#define LINE_HEAD 0 -#define LINE_END DATA_NUM - 2 -static char Text[] = "Param"; -int event_flag = 0; -int32_t index_power = 0; -static int8_t Curser = LINE_HEAD; // 定义光标位置 -static int8_t Curser_Last = LINE_HEAD; // 定义光标位置 -void jj_param_show(); -/*************************************************************************************** - * - * 以下为页面模板函数 - * - ***************************************************************************************/ -/** - * @brief 页面初始化事件 - * @param 无 - * @retval 无 - */ -static void Setup() -{ - ips200_clear(); - Print_Curser(Curser, Curser_Last, RGB565_PURPLE); - for (int16 i = 0; i < DATA_NUM - 1; i++) { - ips200_show_string(10, i * 18 + 2, Param_Data[i].text); - if (Param_Data[i].type == EINT32) - ips200_show_int(50, i * 18 + 2, *((int32 *)(Param_Data[i].p_data)), 5); - else if (Param_Data[i].type == EFLOAT) - ips200_show_float(50, i * 18 + 2, *((float *)(Param_Data[i].p_data)), 4, 5); - } - ips200_show_int(50, (DATA_NUM-1)* 18 + 2, index_power, 5); - -} - -/** - * @brief 页面退出事件 - * @param 无 - * @retval 无 - */ -static void Exit() -{ -} - -/** - * @brief 页面循环执行的内容 - * @param 无 - * @retval 无 - */ -static void Loop() -{ -} -/** - * @brief 页面事件 - * @param btn:发出事件的按键 - * @param event:事件编号 - * @retval 无 - */ -static void Event(page_event event) -{ - - if (0 == event_flag) { - - Curser_Last = Curser; - if (page_event_forward == event) { - Curser--; // 光标上移 - } else if (page_event_backward == event) { - Curser++; // 光标下移 - } else if (page_event_press_short == event) { - event_flag = 1; // 选中参数 - Print_Curser(Curser, Curser_Last, RGB565_RED); - return; - } else if (page_event_press_long == event) { - jj_param_update(); - Page_Shift(page_menu); - return; - } - if (Curser < LINE_HEAD) { - Curser = LINE_END; - } else if (Curser > LINE_END) { - Curser = LINE_HEAD; - } - Print_Curser(Curser, Curser_Last, RGB565_PURPLE); - } else if (1 == event_flag) { - if (page_event_forward == event) { - if (Param_Data[Curser].type == EFLOAT) { - *((float *)(Param_Data[Curser].p_data)) += powf(10.0f,(float)index_power); - } else if (Param_Data[Curser].type == EINT32) { - *((int32 *)(Param_Data[Curser].p_data)) += 1; - } else if (Param_Data[Curser].type == EUINT32) { - *((uint32 *)(Param_Data[Curser].p_data)) += 1; - } - } else if (page_event_backward == event) { - if (Param_Data[Curser].type == EFLOAT) { - *((float *)(Param_Data[Curser].p_data)) -=powf(10.0f,(float)index_power); - } else if (Param_Data[Curser].type == EINT32) { - *((int32 *)(Param_Data[Curser].p_data)) -= 1; - } else if (Param_Data[Curser].type == EUINT32) { - *((uint32 *)(Param_Data[Curser].p_data)) -= 1; - } - } else if (page_event_press_short == event) { - index_power++; - if (index_power > 2) { - index_power = -2; - } - ips200_show_int(50, (DATA_NUM-1)* 18 + 2, index_power, 5); - } else if (page_event_press_long == event) { - event_flag = 0; - Print_Curser(Curser, Curser_Last, RGB565_PURPLE); - } - jj_param_show(); - } -} -void jj_param_show() -{ - if (EINT32 == Param_Data[Curser].type) - ips200_show_int(50, Curser * 18 + 2, *((int32 *)(Param_Data[Curser].p_data)), 5); - else if (EUINT32 == Param_Data[Curser].type) - ips200_show_uint(50, Curser * 18 + 2, *((int32 *)(Param_Data[Curser].p_data)), 5); - else if (EFLOAT == Param_Data[Curser].type) - ips200_show_float(50, Curser * 18 + 2, *((float *)(Param_Data[Curser].p_data)), 4, 5); -} -/** - * @brief 页面注册函数 - * - * @param pageID - */ -void PageRegister_page_param(unsigned char pageID) -{ - Page_Register(pageID, Text, Setup, Loop, Exit, Event); -} diff --git a/app/page/page_rtcam.c b/app/page/page_rtcam.c index 7b479bd..9d520ee 100644 --- a/app/page/page_rtcam.c +++ b/app/page/page_rtcam.c @@ -5,8 +5,6 @@ #define LINE_HEAD 11 #define LINE_END 16 -static char Text[] = "RealTime Image"; - static int8_t Curser = LINE_HEAD; // 定义光标位置 static int8_t Curser_Last = LINE_HEAD; // 定义光标位置 /*************************************************************************************** @@ -81,7 +79,7 @@ static void Event(page_event event) */ void PageRegister_page_rtcam(unsigned char pageID) { - Page_Register(pageID, Text, Setup, Loop, Exit, Event); + Page_Register(pageID, Setup, Loop, Exit, Event); } /*************************************************************************************** diff --git a/app/page/page_sparam.c b/app/page/page_sparam.c new file mode 100644 index 0000000..a062093 --- /dev/null +++ b/app/page/page_sparam.c @@ -0,0 +1,163 @@ +#include "jj_param.h" +#include "page_ui_widget.h" +#include "page.h" + +#define LINE_HEAD 1 + +static int16 pafrist; +static int16 paend; +static int16 palong; +static int event_flag = 0; +static int32_t index_power = 0; +static int8_t Curser = LINE_HEAD; // 定义光标位置 +static int8_t Curser_Last = LINE_HEAD; // 定义光标位置 +/*************************************************************************************** + * + * 以下为页面模板函数 + * + ***************************************************************************************/ +/** + * @brief 页面初始化事件 + * @param 无 + * @retval 无 + */ +static void Setup() +{ + ips200_clear(); + + if (new_page == page_param1) { + pafrist = 0; + paend = Page2_head; + ips200_show_string(0, 0, "Param1"); + } else if (new_page == page_param2) { + pafrist = Page2_head; + paend = Page3_head; + ips200_show_string(0, 0, "Param2"); + } + + palong = paend - pafrist; + if (Curser < LINE_HEAD) { + Curser = palong; + } else if (Curser > palong) { + Curser = LINE_HEAD; + } + Print_Curser(Curser, Curser_Last, RGB565_PURPLE); + for (int16 i = 0; i < palong; i++) { + ips200_show_string(20, i * 18 + 20, Param_Data[i + pafrist].text); + if (Param_Data[i].type == EINT32) + ips200_show_int(60, i * 18 + 20, *((int32 *)(Param_Data[i + pafrist].p_data)), 5); + else if (Param_Data[i].type == EFLOAT) + ips200_show_float(60, i * 18 + 20, *((float *)(Param_Data[i + pafrist].p_data)), 4, 5); + } + ips200_show_int(50, palong * 18 + 20, index_power, 5); +} + +/** + * @brief 页面退出事件 + * @param 无 + * @retval 无 + */ +static void Exit() +{ +} + +/** + * @brief 页面循环执行的内容 + * @param 无 + * @retval 无 + */ +static void Loop() +{ +} +/** + * @brief 页面事件 + * @param btn:发出事件的按键 + * @param event:事件编号 + * @retval 无 + */ +static void Event(page_event event) +{ + + if (0 == event_flag) { + + Curser_Last = Curser; + if (page_event_forward == event) { + Curser++; // 光标上移 + } else if (page_event_backward == event) { + Curser--; // 光标下移 + } else if (page_event_press_short == event) { + event_flag = 1; // 选中参数 + Print_Curser(Curser, Curser_Last, RGB565_RED); + return; + } else if (page_event_press_long == event) { + jj_param_write(); + Page_Shift(page_menu); + return; + } + if (Curser < LINE_HEAD) { + Curser = palong; + } else if (Curser > palong) { + Curser = LINE_HEAD; + } + Print_Curser(Curser, Curser_Last, RGB565_PURPLE); + } else if (1 == event_flag) { + if (page_event_forward == event) { + switch (Param_Data[Curser + pafrist - 1].type) { + case EFLOAT: + *((float *)(Param_Data[Curser + pafrist - 1].p_data)) += powf(10.0f, (float)index_power); + break; + case EINT32: + *((int32 *)(Param_Data[Curser + pafrist - 1].p_data)) += 1; + break; + case EUINT32: + *((uint32 *)(Param_Data[Curser + pafrist - 1].p_data)) += 1; + break; + default: + break; + } + } else if (page_event_backward == event) { + switch (Param_Data[Curser + pafrist - 1].type) { + case EFLOAT: + *((float *)(Param_Data[Curser + pafrist - 1].p_data)) -= powf(10.0f, (float)index_power); + break; + case EINT32: + *((int32 *)(Param_Data[Curser + pafrist - 1].p_data)) -= 1; + break; + case EUINT32: + *((uint32 *)(Param_Data[Curser + pafrist - 1].p_data)) -= 1; + break; + default: + break; + } + } else if (page_event_press_short == event) { + index_power++; + if (index_power > 2) { + index_power = -2; + } + ips200_show_int(50, palong * 18 + 20, index_power, 5); + } else if (page_event_press_long == event) { + event_flag = 0; + Print_Curser(Curser, Curser_Last, RGB565_PURPLE); + } + if (EINT32 == Param_Data[Curser + pafrist - 1].type) + ips200_show_int(60, Curser * 18 + 2, *((int32 *)(Param_Data[Curser + pafrist - 1].p_data)), 5); + else if (EUINT32 == Param_Data[Curser + pafrist - 1].type) + ips200_show_uint(60, Curser * 18 + 2, *((int32 *)(Param_Data[Curser + pafrist - 1].p_data)), 5); + else if (EFLOAT == Param_Data[Curser + pafrist - 1].type) + ips200_show_float(60, Curser * 18 + 2, *((float *)(Param_Data[Curser + pafrist - 1].p_data)), 4, 5); + } +} + +/** + * @brief 页面注册函数 + * + * @param pageID + */ +void PageRegister_page_param1(unsigned char pageID) +{ + Page_Register(pageID, Setup, Loop, Exit, Event); +} +void PageRegister_page_param2(unsigned char pageID) +{ + Page_Register(pageID, Setup, Loop, Exit, Event); +} \ No newline at end of file