1.完善和优化界面显示,数据懒加载,等待光标等,修复启动时界面卡的问题。
2.SVData的Push的限制和检查,因发现Glass呆在机器中时,不管机台是否运行都在不停压入数据。
已修改5个文件
133 ■■■■ 文件已修改
SourceCode/Bond/Servo/CGlass.cpp 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CMaster.cpp 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CPageGlassList.cpp 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/Model.cpp 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/ServoDlg.cpp 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
SourceCode/Bond/Servo/CGlass.cpp
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "CGlass.h"
#include "Log.h"
@@ -384,7 +384,7 @@
        if (s.size() > maxLen) s.resize(maxLen);
    }
    // —— 时间戳 & 工具 ——
    // 状态时间戳:排队/开始/结束
    void CGlass::markQueued() 
    {
        m_state = GlsState::Queued;
@@ -432,29 +432,44 @@
        return strOut;
    }
    // ========== SV数据管理接口实现 ==========
    // ========== SV数据口袋 ==========
    static constexpr size_t MAX_SV_DATA_KEEP = 4800;
    void CGlass::addSVData(int machineId, const std::string& dataType, const SVDataItem& dataItem) {
        m_svDatas[machineId][dataType].push_back(dataItem);
        auto& vec = m_svDatas[machineId][dataType];
        vec.push_back(dataItem);
        if (vec.size() > MAX_SV_DATA_KEEP) {
            vec.erase(vec.begin(), vec.begin() + (vec.size() - MAX_SV_DATA_KEEP));
        }
    }
    void CGlass::addSVData(int machineId, const std::string& dataType, double value) {
        auto now = std::chrono::system_clock::now();
        m_svDatas[machineId][dataType].emplace_back(now, value);
        auto& vec = m_svDatas[machineId][dataType];
        vec.emplace_back(now, value);
        if (vec.size() > MAX_SV_DATA_KEEP) {
            vec.erase(vec.begin(), vec.begin() + (vec.size() - MAX_SV_DATA_KEEP));
        }
    }
    void CGlass::addSVData(int machineId, const std::string& dataType, int64_t timestamp, double value) {
        // 将int64_t时间戳转换为system_clock::time_point
        // int64_t时间转成system_clock::time_point
        std::chrono::system_clock::time_point timePoint{
            std::chrono::milliseconds(timestamp)  // 假设timestamp是毫秒
            // 如果是秒,使用:std::chrono::seconds(timestamp)
            std::chrono::milliseconds(timestamp)  // timestamp精度:毫秒
            // 如果需要精度更高,可能要使用其他时间单位,如std::chrono::seconds(timestamp)
        };
        m_svDatas[machineId][dataType].emplace_back(timePoint, value);
        auto& vec = m_svDatas[machineId][dataType];
        vec.emplace_back(timePoint, value);
        if (vec.size() > MAX_SV_DATA_KEEP) {
            vec.erase(vec.begin(), vec.begin() + (vec.size() - MAX_SV_DATA_KEEP));
        }
    }
    void CGlass::addSVData(int machineId, const std::string& dataType, const std::vector<SVDataItem>& dataItems) {
        auto& dataList = m_svDatas[machineId][dataType];
        dataList.insert(dataList.end(), dataItems.begin(), dataItems.end());
        if (dataList.size() > MAX_SV_DATA_KEEP) {
            dataList.erase(dataList.begin(), dataList.begin() + (dataList.size() - MAX_SV_DATA_KEEP));
        }
    }
    std::vector<SVDataItem> CGlass::getSVData(int machineId, const std::string& dataType) const {
@@ -515,7 +530,6 @@
        auto machineIt = m_svDatas.find(machineId);
        if (machineIt != m_svDatas.end()) {
            machineIt->second.erase(dataType);
            // 如果该机器没有其他数据了,也清除机器条目
            if (machineIt->second.empty()) {
                m_svDatas.erase(machineIt);
            }
SourceCode/Bond/Servo/CMaster.cpp
@@ -138,11 +138,18 @@
    int CMaster::init()
    {
        const ULONGLONG boot_master_begin = GetTickCount64();
        LOGI("<Master>正在初始化...");
        LOGI("[BOOT][MASTER] init begin");
        //     cclink
        if (m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1)) != 0) {
        const ULONGLONG boot_cclink_begin = GetTickCount64();
        const int cc_ret = m_cclink.Connect(CC_LINK_IE_CONTROL_CHANNEL(1));
        LOGI("[BOOT][MASTER] CC-Link connect ret=%d, cost=%llu ms",
            cc_ret,
            (unsigned long long)(GetTickCount64() - boot_cclink_begin));
        if (cc_ret != 0) {
            LOGE("连接CC-Link失败.");
        }
        else {
@@ -231,11 +238,21 @@
        // 读缓存数据
            const ULONGLONG boot_cache_begin = GetTickCount64();
            const ULONGLONG boot_read_begin = GetTickCount64();
        readCache();
            LOGI("[BOOT][MASTER] readCache finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_read_begin));
            const ULONGLONG boot_state_begin = GetTickCount64();
        loadState();
            LOGI("[BOOT][MASTER] loadState finished, cost=%llu ms", (unsigned long long)(GetTickCount64() - boot_state_begin));
        if (m_listener.onControlJobChanged) {
            notifyControlJobChanged();
        }
            LOGI("[BOOT][MASTER] cache/state loaded, cost=%llu ms (since init %llu ms)",
                (unsigned long long)(GetTickCount64() - boot_cache_begin),
                (unsigned long long)(GetTickCount64() - boot_master_begin));
        // 定时器
@@ -258,6 +275,8 @@
        LOGI("<Master>初始化完成.");
            LOGI("[BOOT][MASTER] init finished, total cost=%llu ms",
                (unsigned long long)(GetTickCount64() - boot_master_begin));
        return 0;
    }
@@ -1675,6 +1694,14 @@
            }
        };
        listener.onSVDataReport = [&](void* pEquipment, void* pData) {
            const bool allowSvLog =
                (m_state == MASTERSTATE::RUNNING ||
                    m_state == MASTERSTATE::RUNNING_CONTINUOUS_TRANSFER ||
                    m_state == MASTERSTATE::RUNNING_BATCH ||
                    m_state == MASTERSTATE::STARTING);
            if (!allowSvLog) {
                return;
            }
            CSVData* pSVData = (CSVData*)pData;
            auto rawData = pSVData->getSVRawData();
            std::vector<CParam> params;
SourceCode/Bond/Servo/CPageGlassList.cpp
@@ -1088,9 +1088,10 @@
{
    CDialogEx::OnInitDialog();
    // 定时器:1=初始化订阅,2=周期刷新(只增量)
    // 定时器:1=初始化订阅,2=周期刷新(只增量),3=延迟加载首屏数据
    SetTimer(1, 3000, nullptr);
    SetTimer(2, 2000, nullptr);
    SetTimer(3, 10, nullptr);
    // 下拉框控件
    InitStatusCombo();
@@ -1140,7 +1141,6 @@
    m_listCtrl.SetPopupFullTextColumns({ 11, 12 });
    Resize();
    OnBnClickedButtonSearch(); // 触发一次查询与首屏填充
    return TRUE;  // return TRUE unless you set the focus to a control
}
@@ -1200,6 +1200,10 @@
    else if (nIDEvent == 2) {
        UpdateWipData();  // 只做增量,不重建
    }
    else if (nIDEvent == 3) {
        KillTimer(3);
        OnBnClickedButtonSearch(); // 延迟首屏查询,避免卡住 OnInitDialog
    }
    CDialogEx::OnTimer(nIDEvent);
}
@@ -1229,6 +1233,8 @@
void CPageGlassList::OnBnClickedButtonSearch()
{
    CWaitCursor wait; // 显示等待光标,提示正在加载
    // 获取关键字输入框内容
    CString strKeyword;
    GetDlgItemText(IDC_EDIT_KEYWORD, strKeyword);
SourceCode/Bond/Servo/Model.cpp
@@ -184,6 +184,7 @@
int CModel::init()
{
    const ULONGLONG boot_model_begin = GetTickCount64();
    CString strIniFile;
    CString strUnitId;
    strIniFile.Format(_T("%s\\ServoConfiguration.ini"), (LPTSTR)(LPCTSTR)m_strWorkDir);
@@ -214,6 +215,7 @@
    CLog::GetLog()->SetLogsDir(strLogDir);
    CLog::GetLog()->SetEquipmentId((LPTSTR)(LPCTSTR)strUnitId);
    LOGI("\r\n\r\n~~~ Prog Start! ~~~");
    LOGI("[BOOT][MODEL] init begin");
    SECSListener listener;
@@ -419,6 +421,8 @@
    }
    strVarialbleFile.Format(_T("%s\\HsmsPassive.cache"), (LPTSTR)(LPCTSTR)m_strWorkDir);
    m_hsmsPassive.loadCacheFromFile(strVarialbleFile);
    LOGI("[BOOT][MODEL] HSMS config loaded, cost=%llu ms",
        (unsigned long long)(GetTickCount64() - boot_model_begin));
    SERVO::MasterListener masterListener;
@@ -922,6 +926,8 @@
    char szBuffer[MAX_PATH];
    sprintf_s(szBuffer, MAX_PATH, "%s\\AlarmList.csv", (LPTSTR)(LPCTSTR)m_strWorkDir);
    alarmManager.readAlarmFile(szBuffer);
    LOGI("[BOOT][MODEL] Alarm list loaded, cost=%llu ms",
        (unsigned long long)(GetTickCount64() - boot_model_begin));
    // Glass数据库
@@ -930,6 +936,8 @@
    GlassLogDb::Init(path);
    LOGI("[BOOT][MODEL] init finished, total cost=%llu ms",
        (unsigned long long)(GetTickCount64() - boot_model_begin));
    return 0;
}
SourceCode/Bond/Servo/ServoDlg.cpp
@@ -363,6 +363,8 @@
BOOL CServoDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    const ULONGLONG boot_ui_begin = GetTickCount64();
    CWaitCursor wait; // 整个初始化期显示等待光标,避免用户误以为卡死
    // 将“关于...”菜单项添加到系统菜单中。
@@ -398,13 +400,19 @@
    // model init
    const ULONGLONG boot_model_begin = GetTickCount64();
    theApp.m_model.init();
    LOGI("[BOOT][UI] m_model.init finished, cost=%llu ms (since OnInit start %llu ms)",
        (unsigned long long)(GetTickCount64() - boot_model_begin),
        (unsigned long long)(GetTickCount64() - boot_ui_begin));
    SetTimer(TIMER_ID_LOGIN, 1500, nullptr);
    LOGI("[BOOT][UI] after model.init, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
    // 菜单
    CMenu menu;
    menu.LoadMenu(IDR_MENU_APP);
    SetMenu(&menu);
    LOGI("[BOOT][UI] menu loaded, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
    // toolbar
@@ -417,23 +425,46 @@
    ASSERT(hMenu);
    ::EnableMenuItem(hMenu, ID_OPEATOR_SWITCH, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
    m_pTopToolbar->GetBtn(IDC_BUTTON_JOBS)->EnableWindow(TRUE);
    LOGI("[BOOT][UI] toolbar created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
    // Tab
    const ULONGLONG boot_pages_begin = GetTickCount64();
    m_pPageGraph1 = new CPageGraph1();
    m_pPageGraph1->Create(IDD_PAGE_GRAPH1, this);
    LOGI("[BOOT][UI] page Graph1 created, cost=%llu ms (elapsed=%llu ms)",
        (unsigned long long)(GetTickCount64() - boot_pages_begin),
        (unsigned long long)(GetTickCount64() - boot_ui_begin));
    m_pPageGraph2 = new CPageGraph2();
    m_pPageGraph2->Create(IDD_PAGE_GRAPH2, this);
    LOGI("[BOOT][UI] page Graph2 created, cost=%llu ms (elapsed=%llu ms)",
        (unsigned long long)(GetTickCount64() - boot_pages_begin),
        (unsigned long long)(GetTickCount64() - boot_ui_begin));
    m_pPageGlassList = new CPageGlassList();
    m_pPageGlassList->Create(IDD_PAGE_GLASS_LIST, this);
    LOGI("[BOOT][UI] page GlassList created, cost=%llu ms (elapsed=%llu ms)",
        (unsigned long long)(GetTickCount64() - boot_pages_begin),
        (unsigned long long)(GetTickCount64() - boot_ui_begin));
    m_pPageRecipe = new CPageRecipe();
    m_pPageRecipe->Create(IDD_PAGE_RECIPE, this);
    LOGI("[BOOT][UI] page Recipe created, cost=%llu ms (elapsed=%llu ms)",
        (unsigned long long)(GetTickCount64() - boot_pages_begin),
        (unsigned long long)(GetTickCount64() - boot_ui_begin));
    m_pPageAlarm = new CPageAlarm();
    m_pPageAlarm->Create(IDD_DIALOG_ALARM, this);
    LOGI("[BOOT][UI] page Alarm created, cost=%llu ms (elapsed=%llu ms)",
        (unsigned long long)(GetTickCount64() - boot_pages_begin),
        (unsigned long long)(GetTickCount64() - boot_ui_begin));
    m_pPageLog = new CPageLog();
    m_pPageLog->Create(IDD_DIALOG_LOG, this);
    LOGI("[BOOT][UI] page Log created, cost=%llu ms (elapsed=%llu ms)",
        (unsigned long long)(GetTickCount64() - boot_pages_begin),
        (unsigned long long)(GetTickCount64() - boot_ui_begin));
    m_pPageTransferLog = new CPageTransferLog();
    m_pPageTransferLog->Create(IDD_PAGE_TRANSFER_LOG, this);
    LOGI("[BOOT][UI] page TransferLog created, cost=%llu ms (elapsed=%llu ms)",
        (unsigned long long)(GetTickCount64() - boot_pages_begin),
        (unsigned long long)(GetTickCount64() - boot_ui_begin));
    CHmTab* m_pTab = CHmTab::Hook(GetDlgItem(IDC_TAB1)->m_hWnd);
    m_pTab->SetPaddingLeft(20);
@@ -448,6 +479,7 @@
    m_pTab->SetCurSel(0);
    m_pTab->SetBkgndColor(RGB(222, 222, 222));
    ShowChildPage(0);
    LOGI("[BOOT][UI] pages/tabs created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
    // 读取面板宽
    CString strIniFile;
@@ -467,11 +499,13 @@
    m_pPanelAttributes = new CPanelAttributes();
    m_pPanelAttributes->Create(IDD_PANEL_ATTRIBUTES, this);
    
    LOGI("[BOOT][UI] panels created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
    // statusbar
    m_pMyStatusbar = new CMyStatusbar();
    m_pMyStatusbar->Create(IDD_STATUSBAR, this);
    m_pMyStatusbar->ShowWindow(SW_SHOW);
    LOGI("[BOOT][UI] statusbar created, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
@@ -488,10 +522,23 @@
    InitRxWindows();
    Resize();
    // 加载历史缓存提示
    {
        CWaitCursor wait;
        if (m_pMyStatusbar != nullptr) {
            m_pMyStatusbar->setRunTimeText(_T("正在加载历史缓存..."));
            m_pMyStatusbar->UpdateWindow();
        }
        LOGI("[BOOT][UI] before master.init, elapsed=%llu ms", (unsigned long long)(GetTickCount64() - boot_ui_begin));
    // 相当于延时调用master的初始化
    const ULONGLONG boot_master_begin = GetTickCount64();
    theApp.m_model.m_master.init();
    LOGI("[BOOT][UI] m_master.init finished, cost=%llu ms (since OnInit start %llu ms)",
        (unsigned long long)(GetTickCount64() - boot_master_begin),
        (unsigned long long)(GetTickCount64() - boot_ui_begin));
    theApp.m_model.loadPortParams();
    }
    // 初始化master以后需要控件绑定数据
@@ -504,6 +551,9 @@
    //SystemLogManager::getInstance.
    LOGI("[BOOT][UI] OnInitDialog finished, total cost=%llu ms",
        (unsigned long long)(GetTickCount64() - boot_ui_begin));
    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}