Работа OnClose

Страницы: 1
RSS
Работа OnClose
 
Есть колбек OnClose. Казалось бы, он должен помочь понять, что терминал остановлен. Но явно что-то пошло не так.

Берем простой скрипт. Закрываем терминал через "крестик".

Ожидание - 1. OnClose, сбрасываем флаг. 2. выходим из main.
Код
local sleep  = _G.sleep
local isRun  = true
local AddLabel          = _G.AddLabel
local GetLabelParams    = _G.GetLabelParams
local logFile

local function log_tostring(...)
    local n = select('#', ...)
    if n == 1 then
    return tostring(select(1, ...))
    end
    local t = {}
    for i = 1, n do
    t[#t + 1] = tostring((select(i, ...)))
    end
    return table.concat(t, " ")
end

local function log(...)
    if logFile==nil then return end
    logFile:write(tostring(os.date("%c",os.time())).." "..log_tostring(...).."\n");
    logFile:flush();
end

function _G.OnStop()
    isRun = false
    log("Script Stoped")
    if logFile then logFile:close() end
end

function _G.OnClose()
    isRun = false
    log("Script OnClose")
    if logFile then logFile:close() end
end

function _G.main()

    logFile = io.open(_G.getScriptPath().."\\labels_test.txt", "w")

    local t_id = _G.AllocTable()
    _G.AddColumn(t_id, 1, 'test', true, _G.QTABLE_STRING_TYPE, 20)
    _G.CreateWindow(t_id)

    local tag = 'virt_test'
    local label_params = {}
    label_params.YVALUE = 324
    label_params.TEXT = 'TEST    |||||||||||||||||||||||||||||||||||||||||||||'
    label_params.HINT = 'Еще текст'
    label_params.DATE = 20260512
    label_params.TIME = 135000
    label_params.FONT_FACE_NAME = 'Arial'
    label_params.ALIGNMENT = 'RIGHT'
    label_params.FONT_HEIGHT    = 10
    label_params.TRANSPARENT_BACKGROUND    = 1
    local data = {price = 324}
    local l_id = AddLabel(tag, label_params)
    sleep(1000)
    
    while isRun do
        local i = 1
        while isRun and i < 10 do
            label_params = GetLabelParams(tag, l_id)
            if label_params then
                data.price = tonumber(label_params.yvalue) or 0
            end
            log(os.clock(), i, 'IsWindowClosed', tostring(_G.IsWindowClosed(t_id)), 'label_params', tostring(label_params), tag, 'l_id', l_id, tostring(data.price))
            i = i+1
        end
        log(os.clock(), 'sleep')
        sleep(100)
    end
end

Выводит метку на график, создаём окно. Далее выводим данные метки с графика и закрыто ли окно. Смотрим лог:

Tue May 12 15:07:59 2026 30.832 sleep
Tue May 12 15:07:59 2026 30.946 1 IsWindowClosed false label_params table: 00000205F30168A0 virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 30.947 2 IsWindowClosed false label_params table: 00000205F3016BA0 virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 30.947 3 IsWindowClosed false label_params table: 00000205F3017BA0 virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 30.947 4 IsWindowClosed false label_params table: 00000205F3017160 virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 30.947 5 IsWindowClosed false label_params table: 00000205F3018020 virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 30.947 6 IsWindowClosed false label_params table: 00000205F30171A0 virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 30.947 7 IsWindowClosed false label_params table: 00000205F30171E0 virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 30.947 8 IsWindowClosed false label_params table: 00000205F3017F20 virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 30.948 9 IsWindowClosed false label_params table: 00000205F3017A60 virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 30.948 sleep

Окно ещё не уничтожено, но графика уже нет и данные метки не получены.
Tue May 12 15:07:59 2026 31.061 1 IsWindowClosed false label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 31.061 2 IsWindowClosed false label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 31.061 3 IsWindowClosed false label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 31.061 4 IsWindowClosed false label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 31.061 5 IsWindowClosed false label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 31.061 6 IsWindowClosed false label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 31.061 7 IsWindowClosed false label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 31.061 8 IsWindowClosed false label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 31.061 9 IsWindowClosed false label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:07:59 2026 31.061 sleep

А здесь уже и окна нет
Tue May 12 15:08:00 2026 31.173 1 IsWindowClosed true label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:08:00 2026 31.173 2 IsWindowClosed true label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:08:00 2026 31.173 3 IsWindowClosed true label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:08:00 2026 31.173 4 IsWindowClosed true label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:08:00 2026 31.173 5 IsWindowClosed true label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:08:00 2026 31.173 6 IsWindowClosed true label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:08:00 2026 31.173 7 IsWindowClosed true label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:08:00 2026 31.173 8 IsWindowClosed true label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:08:00 2026 31.173 9 IsWindowClosed true label_params nil virt_test l_id 13.0 324.0
Tue May 12 15:08:00 2026 31.173 sleep

Только сейчас OnClose
Tue May 12 15:08:00 2026 Script OnClose

Сама по себе схема, вроде, корректна, если бы OnClose мог выполнится параллельно, не обращая внимания на работу main. Но это не так. В итоге OnClose вызывается когда уже уничтожено окно скрипта и нет графика. Т.е. некоторое время (а точнее пока не вызовется C функция) у нас есть подвешенное состояние - мы не знаем окно, график закрыты пользователем или нет.
В итоге, если в это время считаем метку, а её нет, можем принять не верное решение. Аналогично и по окну скрипта.

Что хотелось бы: вместо колбека иметь глобальный флаг, состояние или иное, сигнализирующее, что терминал закрывается. При этом он должен быть установлен быстро, перед уничтожением объектов терминала. Аналогия из электротехники - логическое 1 или 0 на контакте. Если 0, то уже всё, логика работы совершенно иная.

Текущая же реализация может работать, если бы OnClose вызывался до уничтожения объектов.
 
до кучи...
В документации сказано:
Код
OnClose

Функция вызывается перед закрытием терминала QUIK и при выгрузке файла 
qlua.dll. 
Формат вызова: 
OnClose()


Под выгрузкой файла qlua.dll подразумевается отключение плагина QLua в окне 
«Версии компонентов и плагинов» (см. п. 1.9. Раздела 1 Руководства пользователя 
QUIK).
Но если  работает несколько скриптов,
то файл qlua.dll , если это dll ,
не будет выгружаться,
если есть хотя один работающий скрипт.
-----------------------  
Таким образом, этот колбек вызывается либо коггда терминал закрывается,
либо когда останавливается последний скрипт.
что не так?
 
Страницы: 1
Читают тему
Наверх