优化扫描流程以匹配待纸扫描;历史及滚轴张数增加各速度模式下的耗时毫秒数

This commit is contained in:
gb 2024-02-07 16:26:23 +08:00
parent d35cea52c5
commit 13eaabd931
6 changed files with 400 additions and 221 deletions

View File

@ -32,7 +32,7 @@ static std::string device_opt_json[] = {
scanner_hw::scanner_hw() : mb_events_("motorboard-event") scanner_hw::scanner_hw() : mb_events_("motorboard-event")
{ {
set_where("hardware"); set_where("hardware");
// mb_events_.enable_wait_log(false); mb_events_.enable_wait_log(false);
memset(&img_base_, 0, sizeof(img_base_)); memset(&img_base_, 0, sizeof(img_base_));
img_base_.bpp = 8; img_base_.bpp = 8;
img_base_.bppc = 8; img_base_.bppc = 8;
@ -348,13 +348,13 @@ void scanner_hw::init_version(std::string& text)
} }
jsn->release(); jsn->release();
} }
void scanner_hw::thread_image_capture(void) void scanner_hw::thread_image_capture(bool paper_ready)
{ {
PACKIMAGE img(img_base_); PACKIMAGE img(img_base_);
safe_fifo<int> avail_mem("v4l2-mem"); safe_fifo<int> avail_mem("v4l2-mem");
int used_v4l2_mem = 0, times = 0, minh = 210 * dpi_ / 25.4, int used_v4l2_mem = 0, times = 0, minh = 210 * dpi_ / 25.4,
err = SCANNER_ERR_OK; err = SCANNER_ERR_OK;
uint8_t scanmode = count_mode_ ? devui::SCAN_COUNT_MODE : devui::SCAN_NORMAL; devui::SCANSTREAM scanstream;
chronograph watch; chronograph watch;
std::pair<int, int> mbev; std::pair<int, int> mbev;
std::function<IMAGE_HANDLER_PROTO> img_callback(img_handler_); std::function<IMAGE_HANDLER_PROTO> img_callback(img_handler_);
@ -369,95 +369,101 @@ void scanner_hw::thread_image_capture(void)
utils::to_log(LOG_LEVEL_DEBUG, "scanning thread working ...\n"); utils::to_log(LOG_LEVEL_DEBUG, "scanning thread working ...\n");
motor_->clear_error(); motor_->clear_error();
motor_->start(); if(paper_ready)
// to_lifter_ = 0;
while(scanning_ && times++ < 5)
{
if(mb_events_.take(mbev, true, to_lifter_)
&& mbev.first == MOTOR_BORD_EVENT_LIFTER_READY)
{
utils::to_log(LOG_LEVEL_DEBUG, "take first motorboard event: %d - 0x%08x\n", mbev.first, mbev.second);
break;
}
else
utils::to_log(LOG_LEVEL_FATAL, "Wait Lifter event(%d - 0x%08x) before scanning failed.\n", mbev.first, mbev.second);
motor_->start(); motor_->start();
} scanstream.mode = count_mode_ ? devui::SCAN_COUNT_MODE : devui::SCAN_NORMAL;
times = 0; scanstream.speed = sp_;
devui::send_message(devui::UI_STATUS_SCANNING, &scanmode, sizeof(scanmode)); devui::send_message(devui::UI_STATUS_SCANNING, (uint8_t*)&scanstream, sizeof(scanstream));
while(scanning_ && mbev.first == MOTOR_BORD_EVENT_LIFTER_READY) // auto scan cycle ... while(scanning_) // auto scan cycle ...
{ {
times++; int attempt = 0;
watch.reset(); while(paper_ready && scanning_ && attempt++ < 5)
motor_->pick_paper();
// scanning ONE turn ...
while(scanning_ && motor_->wait_paper_out(to_paper_out_))
{ {
if(mb_events_.take(mbev) && mbev.first == MOTOR_BORD_EVENT_ERROR) if(mb_events_.take(mbev, true, to_lifter_)
{ && mbev.first == MOTOR_BORD_EVENT_LIFTER_READY)
err = trans_motorboard_err_2_hg_error(mbev.second);
if(err != SCANNER_ERR_DEVICE_DOUBLE_FEEDING)
break;
}
else if(mbev.first == MOTOR_BORD_EVENT_SCAN_DONE)
{ {
utils::to_log(LOG_LEVEL_DEBUG, "take first motorboard event: %d - 0x%08x\n", mbev.first, mbev.second);
break; break;
} }
else else
{ utils::to_log(LOG_LEVEL_FATAL, "Wait Lifter event(%d - 0x%08x) before scanning failed.\n", mbev.first, mbev.second);
err = SCANNER_ERR_OK; motor_->start();
} }
if(mbev.first == MOTOR_BORD_EVENT_LIFTER_READY)
img.pos.paper_ind++; {
devui::send_message(devui::UI_STATUS_PAPER_CNT, nullptr, 0); times++;
if(!count_mode_)
{
img.height = get_image_real_height(minh);
size_t size = 0;
int ind = -1;
void* frame = camera_->read_frame(to_stream_, size, ind);
dyn_mem_shared_ptr mem = nullptr;
if(!frame)
{
if(err == SCANNER_ERR_OK)
err = SCANNER_ERR_DEVICE_CIS_STREAM;
break;
}
img.prc_time = watch.elapse_ms();
mem = new dyn_mem_shared(frame, size, put_v4l2_mem, (void*)ind);
used_v4l2_mem++;
img.pos.status = hg_err_2_image_status(err);
img_handler_(mem, true, &img);
mem->release();
if((!scan_cntless_ && img.pos.paper_ind == scan_count_) || is_scan_fatal())
break;
// retrieve V4L2 memory ...
retrieve_v4l2_mem(&avail_mem, &used_v4l2_mem);
if(used_v4l2_mem >= camera_->get_mem_count())
{
err = SCANNER_ERR_DEVICE_CIS_OUT_OF_MEM;
stop_scan();
utils::to_log(LOG_LEVEL_FATAL, "Scanning stopped for that V4L2 is out of memory!\n");
break;
}
}
watch.reset(); watch.reset();
motor_->pick_paper(); motor_->pick_paper();
}
// retrieve v4l2-mem ... // scanning ONE turn ...
int ind = -1; while(scanning_ && motor_->wait_paper_out(to_paper_out_))
while(avail_mem.take(ind, false)) {
{ uint32_t pass = watch.elapse_ms();
used_v4l2_mem--; if(mb_events_.take(mbev) && mbev.first == MOTOR_BORD_EVENT_ERROR)
camera_->add_v4l2_memory(ind); {
err = trans_motorboard_err_2_hg_error(mbev.second);
if(err != SCANNER_ERR_DEVICE_DOUBLE_FEEDING)
break;
}
else if(mbev.first == MOTOR_BORD_EVENT_SCAN_DONE)
{
break;
}
else
{
err = SCANNER_ERR_OK;
}
img.pos.paper_ind++;
devui::send_message(devui::UI_STATUS_PAPER_CNT, (uint8_t*)&pass, sizeof(pass));
if(!count_mode_)
{
img.height = get_image_real_height(minh);
size_t size = 0;
int ind = -1;
void* frame = camera_->read_frame(to_stream_, size, ind);
dyn_mem_shared_ptr mem = nullptr;
if(!frame)
{
if(err == SCANNER_ERR_OK)
err = SCANNER_ERR_DEVICE_CIS_STREAM;
break;
}
img.prc_time = watch.elapse_ms();
mem = new dyn_mem_shared(frame, size, put_v4l2_mem, (void*)ind);
used_v4l2_mem++;
img.pos.status = hg_err_2_image_status(err);
img_handler_(mem, true, &img);
mem->release();
if((!scan_cntless_ && img.pos.paper_ind == scan_count_) || is_scan_fatal())
break;
// retrieve V4L2 memory ...
retrieve_v4l2_mem(&avail_mem, &used_v4l2_mem);
if(used_v4l2_mem >= camera_->get_mem_count())
{
err = SCANNER_ERR_DEVICE_CIS_OUT_OF_MEM;
stop_scan();
utils::to_log(LOG_LEVEL_FATAL, "Scanning stopped for that V4L2 is out of memory!\n");
break;
}
}
watch.reset();
motor_->pick_paper();
}
// retrieve v4l2-mem ...
int ind = -1;
while(avail_mem.take(ind, false))
{
used_v4l2_mem--;
camera_->add_v4l2_memory(ind);
}
} }
{ {
@ -781,7 +787,6 @@ int scanner_hw::open(std::function<IMAGE_HANDLER_PROTO> image_handler, std::stri
auto cb = [this](int ev, unsigned int data) -> void auto cb = [this](int ev, unsigned int data) -> void
{ {
printf("MBEV: %d-%x\n", ev, data);
mb_events_.save(std::make_pair(ev, data), true); mb_events_.save(std::make_pair(ev, data), true);
}; };
mb_events_.clear(); mb_events_.clear();
@ -880,12 +885,13 @@ int scanner_hw::start_scan(void)
((SMBMODE*)&val)->paper_jammed_out) ((SMBMODE*)&val)->paper_jammed_out)
return DEV_ERR(PAPER_JAMMED); return DEV_ERR(PAPER_JAMMED);
if(((SMBMODE*)&val)->feeding_paper_ready == 0 && !auto_scan_) bool paperok = ((SMBMODE*)&val)->feeding_paper_ready;
if(!paperok && !auto_scan_)
return DEV_ERR(NO_PAPER); return DEV_ERR(NO_PAPER);
scanning_ = true; scanning_ = true;
mb_events_.clear(); mb_events_.clear();
scan_thread_.reset(new std::thread(&scanner_hw::thread_image_capture, this)); scan_thread_.reset(new std::thread(&scanner_hw::thread_image_capture, this, paperok));
return SCANNER_ERR_OK; return SCANNER_ERR_OK;
} }
@ -960,4 +966,4 @@ int scanner_hw::hg_err_2_image_status(int hgerr)
bool scanner_hw::is_scanning(void) bool scanner_hw::is_scanning(void)
{ {
return scanning_; return scanning_;
} }

View File

@ -99,7 +99,7 @@ class scanner_hw : public sane_opt_provider
void init(void); void init(void);
void init_version(std::string& text); void init_version(std::string& text);
void thread_image_capture(void); void thread_image_capture(bool paper_ready);
int get_image_real_height(int minh); int get_image_real_height(int minh);
bool is_scan_fatal(void); bool is_scan_fatal(void);
void retrieve_v4l2_mem(safe_fifo<int>* mem, int* used); void retrieve_v4l2_mem(safe_fifo<int>* mem, int* used);

View File

@ -23,8 +23,8 @@ namespace devui
UI_CMD_COUNT_PAPER = 0x10, UI_CMD_COUNT_PAPER = 0x10,
UI_CMD_STOP_SCAN, UI_CMD_STOP_SCAN,
UI_STATUS_SCANNING = 0x1000, // begin scanning. data: (enum scan) UI_STATUS_SCANNING = 0x1000, // begin scanning. data: (LPSCANSTREAM)
UI_STATUS_PAPER_CNT, // ONE paper has pass through. data: none UI_STATUS_PAPER_CNT, // ONE paper has pass through. data: (uint32_t*)milliseconds for paper pass through
}; };
#pragma pack(push) #pragma pack(push)
@ -44,6 +44,11 @@ namespace devui
return sizeof(*this); return sizeof(*this);
} }
}MSGSTREAM, *LPMSGSTREAM; }MSGSTREAM, *LPMSGSTREAM;
typedef struct _scan_stream
{
uint8_t mode; // see enum scan
uint32_t speed;
}SCANSTREAM, *LPSCANSTREAM;
#pragma pack(pop) #pragma pack(pop)
void init_ui(std::function<void(LPMSGSTREAM)> uicb, bool ui); void init_ui(std::function<void(LPMSGSTREAM)> uicb, bool ui);

View File

@ -210,39 +210,75 @@ int dev_menu::get_menu_text(std::vector<std::string>& text, int& sel)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ui_mgr // ui_mgr
enum namespace menu_command
{ {
MENU_CMD_ID_CANCEL = 0, enum
{
MENU_CMD_ID_CANCEL = 0,
MENU_CMD_ID_SEPARATE_LOW = 0x10, MENU_CMD_ID_SEPARATE_LOW = 0x10,
MENU_CMD_ID_SEPARATE_MID, MENU_CMD_ID_SEPARATE_MID,
MENU_CMD_ID_SEPARATE_HIGH, MENU_CMD_ID_SEPARATE_HIGH,
MENU_CMD_ID_SLEEP_NEVER = 0x20, MENU_CMD_ID_SLEEP_NEVER = 0x20,
MENU_CMD_ID_SLEEP_IMMEDIATELY, MENU_CMD_ID_SLEEP_IMMEDIATELY,
MENU_CMD_ID_SLEEP_5MIN, MENU_CMD_ID_SLEEP_5MIN,
MENU_CMD_ID_SLEEP_10MIN, MENU_CMD_ID_SLEEP_10MIN,
MENU_CMD_ID_SLEEP_20MIN, MENU_CMD_ID_SLEEP_20MIN,
MENU_CMD_ID_SLEEP_30MIN, MENU_CMD_ID_SLEEP_30MIN,
MENU_CMD_ID_SLEEP_1H, MENU_CMD_ID_SLEEP_1H,
MENU_CMD_ID_SLEEP_2H, MENU_CMD_ID_SLEEP_2H,
MENU_CMD_ID_SLEEP_4H, MENU_CMD_ID_SLEEP_4H,
MENU_CMD_ID_LIFTER_LOW = 0x30, MENU_CMD_ID_LIFTER_LOW = 0x30,
MENU_CMD_ID_LIFTER_MID, MENU_CMD_ID_LIFTER_MID,
MENU_CMD_ID_LIFTER_HIGH, MENU_CMD_ID_LIFTER_HIGH,
MENU_CMD_ID_COUNT_MODE = 0x40, MENU_CMD_ID_COUNT_MODE = 0x40,
MENU_CMD_ID_HANDLE_MODE = 0x50, MENU_CMD_ID_HANDLE_MODE = 0x50,
MENU_CMD_ID_CLEAR_PASSWAY = 0x60, MENU_CMD_ID_CLEAR_PASSWAY = 0x60,
MENU_CMD_ID_GET_HISTORY_COUNT = 0x70, MENU_CMD_ID_GET_HISTORY_COUNT = 0x70,
MENU_CMD_ID_CLEAR_ROLLER_CNT = 0x80, MENU_CMD_ID_CLEAR_ROLLER_CNT = 0x80,
MENU_CMD_ID_GET_ROLLER_COUNT, MENU_CMD_ID_GET_ROLLER_COUNT,
MENU_CMD_ID_SHUTDOWN = 0x90, MENU_CMD_ID_SHUTDOWN = 0x90,
MENU_CMD_ID_WELCOME = 0xa0, MENU_CMD_ID_WELCOME = 0xa0,
};
static std::string command_string(int cmd)
{
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_CANCEL);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SEPARATE_LOW);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SEPARATE_MID);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SEPARATE_HIGH);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_NEVER);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_IMMEDIATELY);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_5MIN);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_10MIN);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_20MIN);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_30MIN);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_1H);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_2H);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_4H);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_LIFTER_LOW);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_LIFTER_MID);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_LIFTER_HIGH);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_COUNT_MODE);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_HANDLE_MODE);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_CLEAR_PASSWAY);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_GET_HISTORY_COUNT);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_CLEAR_ROLLER_CNT);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_GET_ROLLER_COUNT);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SHUTDOWN);
RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_WELCOME);
char unk[40] = {0};
sprintf(unk, "Unknown menu command: %d", cmd);
return unk;
}
}; };
namespace welcome namespace welcome
{ {
@ -350,9 +386,15 @@ static uint8_t qiaoting[] = {128, 32
}; };
static uint8_t* pics[] = {ddjx, mugui, qiaoting}; static uint8_t* pics[] = {ddjx, mugui, qiaoting};
static int index_ = 0; static int index_ = -1;
static uint8_t* get_current_pic(void) static uint8_t* get_current_pic(void)
{ {
if(index_ == -1)
{
srand(time(nullptr));
index_ = rand() % _countof(pics);
}
uint8_t* cur = pics[index_++]; uint8_t* cur = pics[index_++];
index_ %= _countof(pics); index_ %= _countof(pics);
@ -363,6 +405,10 @@ static uint8_t qiaoting[] = {128, 32
ui_mgr::ui_mgr() : disp_data_("lcd-msg") ui_mgr::ui_mgr() : disp_data_("lcd-msg")
{ {
utils::init_log(LOG_TYPE_FILE);
perm_data_.reset(new permanent_data());
disp_data_.enable_wait_log(false);
init(); init();
auto ke = [this](int key) -> MENU_CMD_HANDLER_RET auto ke = [this](int key) -> MENU_CMD_HANDLER_RET
@ -373,10 +419,6 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
lcd_->Lcd_Initial_Lcd(false); lcd_->Lcd_Initial_Lcd(false);
lcd_->clear(); lcd_->clear();
srand(time(nullptr));
his_cnt_ = rand() % 1000000;
rol_cnt_ = his_cnt_ / (2 + (rand() % 5));
ready_.cnt = custom_font::get_string_font(WORDS_STATUS_READY, ready_.ptr); ready_.cnt = custom_font::get_string_font(WORDS_STATUS_READY, ready_.ptr);
ready_.x = (Lcd::LCD_WIDTH - ready_.ptr[0][0] * ready_.cnt) / 2; ready_.x = (Lcd::LCD_WIDTH - ready_.ptr[0][0] * ready_.cnt) / 2;
ready_.y = (Lcd::LCD_HEIGHT - ready_.ptr[0][1]) / 2; ready_.y = (Lcd::LCD_HEIGHT - ready_.ptr[0][1]) / 2;
@ -394,15 +436,21 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
{ {
if(pack->msg == devui::UI_STATUS_SCANNING) if(pack->msg == devui::UI_STATUS_SCANNING)
{ {
scanning_ = pack->data[0] != devui::SCAN_STOPPED; devui::LPSCANSTREAM scan = (devui::LPSCANSTREAM)pack->data;
scanning_ = scan->mode != devui::SCAN_STOPPED;
set_ready_status_enabled(!scanning_); set_ready_status_enabled(!scanning_);
if(scanning_) if(scanning_)
{ {
paper_cnt_ = 0; paper_cnt_ = 0;
if(pack->data[0] != devui::SCAN_PAUSED) if(pack->data[0] == devui::SCAN_PAUSED)
{
perm_data_->save();
}
else
{ {
DISPDATA dd; DISPDATA dd;
perm_data_->set_speed(scan->speed);
paper_total_ = 0; paper_total_ = 0;
memset(&dd, 0, sizeof(dd)); memset(&dd, 0, sizeof(dd));
dd.cnt = dd.mask = -1; dd.cnt = dd.mask = -1;
@ -423,6 +471,7 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
paper_cnt_++; paper_cnt_++;
paper_total_++; paper_total_++;
perm_data_->increase_count(*(uint32_t*)pack->data);
sprintf(num, "%03d", paper_cnt_); sprintf(num, "%03d", paper_cnt_);
dd.x = hold_pos_.x; dd.x = hold_pos_.x;
dd.y = hold_pos_.y; dd.y = hold_pos_.y;
@ -448,12 +497,17 @@ ui_mgr::~ui_mgr()
devui::uninit_ui(); devui::uninit_ui();
clear(); clear();
perm_data_.reset(nullptr);
utils::uninit();
} }
bool ui_mgr::do_menu_command(int cmd) bool ui_mgr::do_menu_command(int cmd)
{ {
bool holdui = false; bool holdui = false;
utils::to_log(LOG_LEVEL_DEBUG, "Do menu command: %s\n", menu_command::command_string(cmd).c_str());
if(handler_.count(cmd)) if(handler_.count(cmd))
holdui = handler_[cmd](cur_, cmd); holdui = handler_[cmd](cur_, cmd);
@ -478,29 +532,29 @@ void ui_mgr::init(void)
// 分纸强度(低中高) // 分纸强度(低中高)
{ {
child = new dev_menu(true); child = new dev_menu(true);
child->add_menu(WORDS_MENU_LOW, MENU_CMD_ID_SEPARATE_LOW); child->add_menu(WORDS_MENU_LOW, menu_command::MENU_CMD_ID_SEPARATE_LOW);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SEPARATE_LOW] = f; handler_[menu_command::MENU_CMD_ID_SEPARATE_LOW] = f;
} }
child->add_menu(WORDS_MENU_MID, MENU_CMD_ID_SEPARATE_MID); child->add_menu(WORDS_MENU_MID, menu_command::MENU_CMD_ID_SEPARATE_MID);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SEPARATE_MID] = f; handler_[menu_command::MENU_CMD_ID_SEPARATE_MID] = f;
} }
child->add_menu(WORDS_MENU_HIGH, MENU_CMD_ID_SEPARATE_HIGH); child->add_menu(WORDS_MENU_HIGH, menu_command::MENU_CMD_ID_SEPARATE_HIGH);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SEPARATE_HIGH] = f; handler_[menu_command::MENU_CMD_ID_SEPARATE_HIGH] = f;
} }
child->select(WORDS_MENU_MID); child->select(WORDS_MENU_MID);
root_->add_menu(WORDS_MENU_SEPARATE_STRENGTH, child); root_->add_menu(WORDS_MENU_SEPARATE_STRENGTH, child);
@ -509,77 +563,77 @@ void ui_mgr::init(void)
// 休眠时间不休眠5min, 10min, 20min, 30min, 1h, 2h, 4h // 休眠时间不休眠5min, 10min, 20min, 30min, 1h, 2h, 4h
{ {
child = new dev_menu(true); child = new dev_menu(true);
child->add_menu(WORDS_MENU_SLEEP_NONE, MENU_CMD_ID_SLEEP_NEVER); child->add_menu(WORDS_MENU_SLEEP_NONE, menu_command::MENU_CMD_ID_SLEEP_NEVER);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SLEEP_NEVER] = f; handler_[menu_command::MENU_CMD_ID_SLEEP_NEVER] = f;
} }
child->add_menu(WORDS_MENU_SLEEP_NOW, MENU_CMD_ID_SLEEP_IMMEDIATELY); child->add_menu(WORDS_MENU_SLEEP_NOW, menu_command::MENU_CMD_ID_SLEEP_IMMEDIATELY);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SLEEP_IMMEDIATELY] = f; handler_[menu_command::MENU_CMD_ID_SLEEP_IMMEDIATELY] = f;
} }
child->add_menu(WORDS_MENU_SLEEP_5_MIN, MENU_CMD_ID_SLEEP_5MIN); child->add_menu(WORDS_MENU_SLEEP_5_MIN, menu_command::MENU_CMD_ID_SLEEP_5MIN);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SLEEP_5MIN] = f; handler_[menu_command::MENU_CMD_ID_SLEEP_5MIN] = f;
} }
child->add_menu(WORDS_MENU_SLEEP_10_MIN, MENU_CMD_ID_SLEEP_10MIN); child->add_menu(WORDS_MENU_SLEEP_10_MIN, menu_command::MENU_CMD_ID_SLEEP_10MIN);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SLEEP_10MIN] = f; handler_[menu_command::MENU_CMD_ID_SLEEP_10MIN] = f;
} }
child->add_menu(WORDS_MENU_SLEEP_20_MIN, MENU_CMD_ID_SLEEP_20MIN); child->add_menu(WORDS_MENU_SLEEP_20_MIN, menu_command::MENU_CMD_ID_SLEEP_20MIN);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SLEEP_20MIN] = f; handler_[menu_command::MENU_CMD_ID_SLEEP_20MIN] = f;
} }
child->add_menu(WORDS_MENU_SLEEP_30_MIN, MENU_CMD_ID_SLEEP_30MIN); child->add_menu(WORDS_MENU_SLEEP_30_MIN, menu_command::MENU_CMD_ID_SLEEP_30MIN);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SLEEP_30MIN] = f; handler_[menu_command::MENU_CMD_ID_SLEEP_30MIN] = f;
} }
child->add_menu(WORDS_MENU_SLEEP_1_HOUR, MENU_CMD_ID_SLEEP_1H); child->add_menu(WORDS_MENU_SLEEP_1_HOUR, menu_command::MENU_CMD_ID_SLEEP_1H);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SLEEP_1H] = f; handler_[menu_command::MENU_CMD_ID_SLEEP_1H] = f;
} }
child->add_menu(WORDS_MENU_SLEEP_2_HOUR, MENU_CMD_ID_SLEEP_2H); child->add_menu(WORDS_MENU_SLEEP_2_HOUR, menu_command::MENU_CMD_ID_SLEEP_2H);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SLEEP_2H] = f; handler_[menu_command::MENU_CMD_ID_SLEEP_2H] = f;
} }
child->add_menu(WORDS_MENU_SLEEP_4_HOUR, MENU_CMD_ID_SLEEP_4H); child->add_menu(WORDS_MENU_SLEEP_4_HOUR, menu_command::MENU_CMD_ID_SLEEP_4H);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_SLEEP_4H] = f; handler_[menu_command::MENU_CMD_ID_SLEEP_4H] = f;
} }
child->select(WORDS_MENU_SLEEP_NONE); child->select(WORDS_MENU_SLEEP_NONE);
root_->add_menu(WORDS_MENU_POWER, child); root_->add_menu(WORDS_MENU_POWER, child);
@ -587,7 +641,7 @@ void ui_mgr::init(void)
} }
// 计数模式、手动模式、清理纸道、历史张数、滚轴张数、清除滚轴张数(确定,取消)、进入休眠、关机 // 计数模式、手动模式、清理纸道、历史张数、滚轴张数、清除滚轴张数(确定,取消)、进入休眠、关机
root_->add_menu(WORDS_MENU_COUNT_MODE, MENU_CMD_ID_COUNT_MODE); root_->add_menu(WORDS_MENU_COUNT_MODE, menu_command::MENU_CMD_ID_COUNT_MODE);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
@ -614,41 +668,34 @@ void ui_mgr::init(void)
hold_pos_.y = dd.y; hold_pos_.y = dd.y;
hold_pos_.x += 2; hold_pos_.x += 2;
disp_data_.save(dd, true); disp_data_.save(dd, true);
// auto test = [this](void) -> void
// {
// thread_test_hold_ui();
// };
// disp_thrd_.stop("thread_test_hold_ui");
// disp_thrd_.start(test, "thread_test_hold_ui");
devui::send_message(devui::UI_CMD_COUNT_PAPER); devui::send_message(devui::UI_CMD_COUNT_PAPER);
return true; return true;
}; };
handler_[MENU_CMD_ID_COUNT_MODE] = f; handler_[menu_command::MENU_CMD_ID_COUNT_MODE] = f;
} }
root_->add_menu(WORDS_MENU_MANUAL_MODE, MENU_CMD_ID_HANDLE_MODE); root_->add_menu(WORDS_MENU_MANUAL_MODE, menu_command::MENU_CMD_ID_HANDLE_MODE);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return true; return true;
}; };
handler_[MENU_CMD_ID_HANDLE_MODE] = f; handler_[menu_command::MENU_CMD_ID_HANDLE_MODE] = f;
} }
root_->add_menu(WORDS_MENU_CLEAR_PASSWAY, MENU_CMD_ID_CLEAR_PASSWAY); root_->add_menu(WORDS_MENU_CLEAR_PASSWAY, menu_command::MENU_CMD_ID_CLEAR_PASSWAY);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_CLEAR_PASSWAY] = f; handler_[menu_command::MENU_CMD_ID_CLEAR_PASSWAY] = f;
} }
root_->add_menu(WORDS_MENU_HISTORY_COUNT, MENU_CMD_ID_GET_HISTORY_COUNT); root_->add_menu(WORDS_MENU_HISTORY_COUNT, menu_command::MENU_CMD_ID_GET_HISTORY_COUNT);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
DISPDATA dd; DISPDATA dd;
char cnt[40] = {0};
memset(&dd, 0, sizeof(dd)); memset(&dd, 0, sizeof(dd));
dd.cnt = dd.mask = -1; dd.cnt = dd.mask = -1;
@ -660,15 +707,14 @@ void ui_mgr::init(void)
dd.y = dd.ptr[0][1]; dd.y = dd.ptr[0][1];
dd.x = dd.ptr[0][0] * 2; dd.x = dd.ptr[0][0] * 2;
sprintf(cnt, "%u", his_cnt_); dd.cnt = custom_font::get_string_font(std::to_string(perm_data_->history_count()).c_str(), dd.ptr);
dd.cnt = custom_font::get_string_font(cnt, dd.ptr);
disp_data_.save(dd, true); disp_data_.save(dd, true);
return true; return true;
}; };
handler_[MENU_CMD_ID_GET_HISTORY_COUNT] = f; handler_[menu_command::MENU_CMD_ID_GET_HISTORY_COUNT] = f;
} }
root_->add_menu(WORDS_MENU_ROLLER_COUNT, MENU_CMD_ID_GET_ROLLER_COUNT); root_->add_menu(WORDS_MENU_ROLLER_COUNT, menu_command::MENU_CMD_ID_GET_ROLLER_COUNT);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
@ -685,56 +731,56 @@ void ui_mgr::init(void)
dd.y = dd.ptr[0][1]; dd.y = dd.ptr[0][1];
dd.x = dd.ptr[0][0] * 2; dd.x = dd.ptr[0][0] * 2;
sprintf(cnt, "%u", rol_cnt_); sprintf(cnt, "%u", perm_data_->roller_count());
dd.cnt = custom_font::get_string_font(cnt, dd.ptr); dd.cnt = custom_font::get_string_font(cnt, dd.ptr);
disp_data_.save(dd, true); disp_data_.save(dd, true);
return true; return true;
}; };
handler_[MENU_CMD_ID_GET_ROLLER_COUNT] = f; handler_[menu_command::MENU_CMD_ID_GET_ROLLER_COUNT] = f;
} }
{ {
child = new dev_menu(false, false); child = new dev_menu(false, false);
child->add_menu(WORDS_MENU_YES, MENU_CMD_ID_CLEAR_ROLLER_CNT); child->add_menu(WORDS_MENU_YES, menu_command::MENU_CMD_ID_CLEAR_ROLLER_CNT);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
rol_cnt_ = 0; perm_data_->clear_roller_count();
return false; return false;
}; };
handler_[MENU_CMD_ID_CLEAR_ROLLER_CNT] = f; handler_[menu_command::MENU_CMD_ID_CLEAR_ROLLER_CNT] = f;
} }
child->add_menu(WORDS_MENU_NO, MENU_CMD_ID_CANCEL); child->add_menu(WORDS_MENU_NO, menu_command::MENU_CMD_ID_CANCEL);
root_->add_menu(WORDS_MENU_RESET_ROLLOER_CNT, child); root_->add_menu(WORDS_MENU_RESET_ROLLOER_CNT, child);
child->release(); child->release();
} }
// 升降台位置(低中高) // 升降台位置(低中高)
{ {
child = new dev_menu(true); child = new dev_menu(true);
child->add_menu(WORDS_MENU_LOW, MENU_CMD_ID_LIFTER_LOW); child->add_menu(WORDS_MENU_LOW, menu_command::MENU_CMD_ID_LIFTER_LOW);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_LIFTER_LOW] = f; handler_[menu_command::MENU_CMD_ID_LIFTER_LOW] = f;
} }
child->add_menu(WORDS_MENU_MID, MENU_CMD_ID_LIFTER_MID); child->add_menu(WORDS_MENU_MID, menu_command::MENU_CMD_ID_LIFTER_MID);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_LIFTER_MID] = f; handler_[menu_command::MENU_CMD_ID_LIFTER_MID] = f;
} }
child->add_menu(WORDS_MENU_HIGH, MENU_CMD_ID_LIFTER_HIGH); child->add_menu(WORDS_MENU_HIGH, menu_command::MENU_CMD_ID_LIFTER_HIGH);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
return false; return false;
}; };
handler_[MENU_CMD_ID_LIFTER_HIGH] = f; handler_[menu_command::MENU_CMD_ID_LIFTER_HIGH] = f;
} }
child->select(WORDS_MENU_LOW); child->select(WORDS_MENU_LOW);
root_->add_menu(WORDS_MENU_LIFTER_POS, child); root_->add_menu(WORDS_MENU_LIFTER_POS, child);
@ -742,7 +788,7 @@ void ui_mgr::init(void)
} }
{ {
child = new dev_menu(false, false); child = new dev_menu(false, false);
child->add_menu(WORDS_MENU_YES, MENU_CMD_ID_SHUTDOWN); child->add_menu(WORDS_MENU_YES, menu_command::MENU_CMD_ID_SHUTDOWN);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
@ -750,14 +796,14 @@ void ui_mgr::init(void)
return false; return false;
}; };
handler_[MENU_CMD_ID_SHUTDOWN] = f; handler_[menu_command::MENU_CMD_ID_SHUTDOWN] = f;
} }
child->add_menu(WORDS_MENU_NO, MENU_CMD_ID_CANCEL); child->add_menu(WORDS_MENU_NO, menu_command::MENU_CMD_ID_CANCEL);
root_->add_menu(WORDS_MENU_SHUTDOWN, child); root_->add_menu(WORDS_MENU_SHUTDOWN, child);
child->release(); child->release();
} }
root_->add_menu(WORDS_MENU_WELCOME, MENU_CMD_ID_WELCOME); root_->add_menu(WORDS_MENU_WELCOME, menu_command::MENU_CMD_ID_WELCOME);
{ {
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
{ {
@ -771,7 +817,7 @@ void ui_mgr::init(void)
return false; return false;
}; };
handler_[MENU_CMD_ID_WELCOME] = f; handler_[menu_command::MENU_CMD_ID_WELCOME] = f;
} }
cur_ = root_; cur_ = root_;
@ -864,41 +910,6 @@ void ui_mgr::enter(void)
} }
} }
void ui_mgr::thread_test_hold_ui(void)
{
uint32_t cnt = 99900 + (rand() % 100);
DISPDATA dd;
char number[40] = {0};
custom_font::font_size size = custom_font::FONT_SIZE_16;
dd.x = hold_pos_.x;
dd.y = hold_pos_.y;
dd.mask = 0;
printf("Start testing count from %d\n", cnt);
while(!menu_mode_)
{
rol_cnt_++;
his_cnt_++;
sprintf(number, "%d", cnt++);
if(size == custom_font::FONT_SIZE_16 && (Lcd::LCD_WIDTH - dd.x) / font_size_.cx < strlen(number))
{
{
// clear
dd.cnt = -1;
dd.mask = -1;
dd.ptr[0] = nullptr; // perform clear
disp_data_.save(dd, true);
dd.mask = 0;
}
size = custom_font::FONT_SIZE_8;
dd.y += Lcd::LCD_LINE_PER_PAGE;
}
dd.cnt = custom_font::get_string_font(number, dd.ptr, size);
disp_data_.save(dd, true);
std::this_thread::sleep_for(std::chrono::seconds(1));
}
printf("Finished testing count from %d\n", cnt);
}
void ui_mgr::thread_display(void) void ui_mgr::thread_display(void)
{ {
DISPDATA dd; DISPDATA dd;
@ -960,6 +971,7 @@ void ui_mgr::key_event(int key)
{ {
if(key == (int)KeyMonitor::HGKey::Key_Cancle) if(key == (int)KeyMonitor::HGKey::Key_Cancle)
{ {
utils::to_log(LOG_LEVEL_DEBUG, "Do menu command: %s\n", "Stop scanning Immediately");
devui::send_message(devui::UI_CMD_STOP_SCAN); devui::send_message(devui::UI_CMD_STOP_SCAN);
} }
@ -991,6 +1003,7 @@ void ui_mgr::key_event(int key)
else if(key == (int)KeyMonitor::HGKey::Key_Cancle) else if(key == (int)KeyMonitor::HGKey::Key_Cancle)
{ {
// stop scanning here ... // stop scanning here ...
utils::to_log(LOG_LEVEL_DEBUG, "Do menu command: %s\n", "Stop scanning Immediately");
devui::send_message(devui::UI_CMD_STOP_SCAN); devui::send_message(devui::UI_CMD_STOP_SCAN);
} }
else if(key == -1) // interrupted by status message, we return to main menu else if(key == -1) // interrupted by status message, we return to main menu

View File

@ -20,6 +20,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <thread> #include <thread>
#include <string.h>
#define MENU_ID_RETURN -1 // ID of menu item that return to parent #define MENU_ID_RETURN -1 // ID of menu item that return to parent
#define LINK_DEFINE(x, y) x##y #define LINK_DEFINE(x, y) x##y
@ -99,13 +100,168 @@ class ui_mgr : public refer
SIZE font_size_ = {16, 16}; SIZE font_size_ = {16, 16};
POINT hold_pos_ = {0, 0}; POINT hold_pos_ = {0, 0};
uint32_t his_cnt_;
uint32_t rol_cnt_;
std::map<int, MENU_CMD_CALLBACK> handler_; std::map<int, MENU_CMD_CALLBACK> handler_;
std::unique_ptr<Lcd> lcd_; std::unique_ptr<Lcd> lcd_;
std::unique_ptr<KeyMonitor> keyboard_; std::unique_ptr<KeyMonitor> keyboard_;
class permanent_data : public refer
{
uint64_t history_cnt_ = 0;
uint32_t roller_cnt_ = 0;
uint32_t adden_ = 0;
uint32_t speed_ = 0;
std::string root_;
const std::string his_name_ = "history-count";
const std::string rol_name_ = "roller-count";
#pragma pack(push)
#pragma pack(1)
typedef struct _speed_time
{
uint64_t ms;
uint32_t speed;
}SPEEDTM, *LPSPEEDTM;
typedef struct _times
{
uint64_t history;
uint64_t roller;
}TIMES;
#pragma pack(pop)
std::map<uint32_t, TIMES> speed_times_;
public:
permanent_data()
{
root_ = utils::get_local_data_path() + PATH_SEPARATOR + "record";
utils::create_folder(root_.c_str());
root_ += PATH_SEPARATOR;
char buf[1024] = {0}, *ptr = buf;
FILE *src = fopen((root_ + his_name_).c_str(), "rb");
int len = 0;
LPSPEEDTM pspt = nullptr;
if(src)
{
len = fread(buf, 1, sizeof(buf), src);
fclose(src);
history_cnt_ = *(uint64_t*)buf;
len -= sizeof(history_cnt_);
ptr = buf + sizeof(history_cnt_);
pspt = (LPSPEEDTM)ptr;
for(int i = 0; i < len / sizeof(*pspt); ++i)
{
TIMES t = {0};
t.history = pspt[i].ms;
speed_times_[pspt[i].speed] = t;
}
}
src = fopen((root_ + rol_name_).c_str(), "rb");
if(src)
{
memset(buf, 0, sizeof(buf));
len = fread(buf, 1, sizeof(buf), src);
fclose(src);
roller_cnt_ = *(uint32_t*)buf;
len -= sizeof(roller_cnt_);
ptr = buf + sizeof(roller_cnt_);
pspt = (LPSPEEDTM)ptr;
for(int i = 0; i < len / sizeof(*pspt); ++i)
{
if(speed_times_.count(pspt[i].speed))
{
speed_times_[pspt[i].speed].roller = pspt[i].ms;
}
else
{
TIMES t = {0};
t.roller = pspt[i].ms;
speed_times_[pspt[i].speed] = t;
}
}
}
}
protected:
virtual ~permanent_data()
{
save();
}
public:
uint64_t history_count(void)
{
return history_cnt_;
}
uint32_t roller_count(void)
{
return roller_cnt_;
}
uint32_t increase_count(uint32_t run_ms, uint64_t* hiscnt = nullptr)
{
++adden_;
++roller_cnt_;
++history_cnt_;
speed_times_[speed_].history += run_ms;
speed_times_[speed_].roller += run_ms;
if(hiscnt)
*hiscnt = history_cnt_;
return roller_cnt_;
}
uint32_t clear_roller_count(void)
{
roller_cnt_ = 0;
for(auto& v: speed_times_)
v.second.roller = 0;
return roller_cnt_;
}
void set_speed(uint32_t speed)
{
speed_ = speed;
if(speed_times_.count(speed) == 0)
{
TIMES t = {0};
speed_times_[speed] = t;
}
}
void save(void)
{
FILE *dst = fopen((root_ + his_name_).c_str(), "wb");
if(dst)
{
fwrite(&history_cnt_, 1, sizeof(history_cnt_), dst);
for(auto& v: speed_times_)
{
SPEEDTM stm = {0};
stm.speed = v.first;
stm.ms = v.second.history;
fwrite(&stm, 1, sizeof(stm), dst);
}
fclose(dst);
}
dst = fopen((root_ + rol_name_).c_str(), "wb");
if(dst)
{
fwrite(&roller_cnt_, 1, sizeof(roller_cnt_), dst);
for(auto& v: speed_times_)
{
SPEEDTM stm = {0};
stm.speed = v.first;
stm.ms = v.second.roller;
fwrite(&stm, 1, sizeof(stm), dst);
}
fclose(dst);
}
}
};
refer_guard<permanent_data> perm_data_;
bool do_menu_command(int cmd); // return whether should hold UI ? bool do_menu_command(int cmd); // return whether should hold UI ?
void init(void); void init(void);
void clear(void); void clear(void);
@ -128,7 +284,6 @@ class ui_mgr : public refer
safe_fifo<DISPDATA> disp_data_; safe_fifo<DISPDATA> disp_data_;
safe_thread disp_thrd_; safe_thread disp_thrd_;
void thread_test_hold_ui(void);
void thread_display(void); void thread_display(void);
void display_ready(void); void display_ready(void);
void set_ready_status_enabled(bool enable); void set_ready_status_enabled(bool enable);

View File

@ -61,7 +61,7 @@ add_defines("BUILD_AS_DEVICE")
add_defines("VER_MAIN=2") add_defines("VER_MAIN=2")
add_defines("VER_FAMILY=200") add_defines("VER_FAMILY=200")
add_defines("VER_DATE=20240207") add_defines("VER_DATE=20240207")
add_defines("VER_BUILD=31") add_defines("VER_BUILD=43")
target("conf") target("conf")
set_kind("phony") set_kind("phony")