Есть колбек OnClose. Казалось бы, он должен помочь понять, что терминал остановлен. Но явно что-то пошло не так.
Берем простой скрипт. Закрываем терминал через "крестик".
Ожидание - 1. OnClose, сбрасываем флаг. 2. выходим из main.
Выводит метку на график, создаём окно. Далее выводим данные метки с графика и закрыто ли окно. Смотрим лог:
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 вызывался до уничтожения объектов.
Берем простой скрипт. Закрываем терминал через "крестик".
Ожидание - 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 вызывался до уничтожения объектов.