Как использовать Lua библиотеку визуального интерфейса IUP внутри корутин (coroutines)?

Страницы: 1
RSS
Как использовать Lua библиотеку визуального интерфейса IUP внутри корутин (coroutines)?
 
В руководстве IUP есть два упоминания слова coroutine (сопрограмма)
To use IUP inside coroutines, define the global attribute «IUPLUA_THREADED».

Неудобство использования IUP в том, что он работает в модальном  режиме. Т.е. вывесив окно IUP, в Lua надо ждать, пока пользователь  закроет это окно. До этого момента получить что-либо в Lua из IUP  невозможно.
Использование корутин предполагает, что вызывающая корутину программа  может вернуть временно себе управление, не дожидаясь завершения  вызванной корутины. Т.е. до закрытия окна IUP, так что скрипт main() в  Quik Lua может выполняться с учётом параллельных манипуляций  пользователя в окне IUP.

Однако не удаётся найти примеры такого использования корутин с IUP.
Кто-нибудь может чего-то добавить?
 
Ростислав Дм. Кудряшов, Редко кто использует такой подход, посмотрите вот работу возможно она поможет Вам разобраться:  BetterQuik - intraday trading framework;  © 2017 Denis Kolodin; https://github.com/BetterQuik/framework. На мой не компетентный взгляд это лучшее что есть.
 
Насколько понял Вашу задачу. Задача заключается в том, чтобы использовать IUP с корутинами в Lua, чтобы интерфейс не блокировал основной поток выполнения программы, а позволял продолжать выполнение других операций в программе, пока окно IUP остаётся открытым. Возможно этот пример подойдет, нужно проверять, но разобраться поможет. Удачи.
Код
require "iuplua"

-- Указываем глобальный атрибут для работы с корутинами
iup.SetGlobal("IUPLUA_THREADED", "YES")

-- Функция для создания диалога с текстовым полем
function create_input_dialog()
    local text = iup.text{expand = "HORIZONTAL", value = ""}
    local ok_btn = iup.button{title = "OK", size = "50"}
    local cancel_btn = iup.button{title = "Cancel", size = "50"}
    
    local dlg = iup.dialog{
        iup.vbox{
            iup.label{title = "Введите текст:"},
            text,
            iup.hbox{ok_btn, cancel_btn}
        },
        title = "Ввод данных",
        size = "300x100"
    }
    
    return dlg, text, ok_btn, cancel_btn
end

-- Функция для асинхронного ввода через корутину
function async_input(coroutine_fn)
    return function(...)
        local co = coroutine.create(coroutine_fn)
        local success, result = coroutine.resume(co, ...)
        return result
    end
end

-- Основная функция диалога как корутина
function input_dialog_coroutine()
    local dlg, text, ok_btn, cancel_btn = create_input_dialog()
    
    -- Создаем promise-like объект для синхронизации
    local result = { waiting = true, value = nil }
    
    -- Callback для OK
    ok_btn.action = function()
        result.value = text.value
        result.waiting = false
        return iup.CLOSE
    end
    
    -- Callback для Cancel
    cancel_btn.action = function()
        result.value = nil
        result.waiting = false
        return iup.CLOSE
    end
    
    -- Показываем диалог (не модальный!)
    dlg:show()
    
    -- Ждем завершения в цикле (можно заменить на более изящное решение)
    while result.waiting do
        coroutine.yield()  -- Отдаем управление обратно
        iup.LoopStep()     -- Обрабатываем события IUP
    end
    
    dlg:destroy()
    return result.value
end

-- Пример использования в основном потоке Quik
function main()
    print("Начало работы скрипта")
    
    -- Запускаем диалог в корутине
    local co = coroutine.create(input_dialog_coroutine)
    
    -- Основной цикл обработки
    local timer = os.clock()
    while coroutine.status(co) ~= "dead" do
        -- Периодически возобновляем корутину
        if os.clock() - timer > 0.1 then  -- каждые 100 мс
            local success, input_text = coroutine.resume(co)
            if success and input_text then
                print("Пользователь ввел: " .. input_text)
                break
            elseif not success then
                print("Ошибка в корутине:", input_text)
                break
            end
            timer = os.clock()
        end
        
        -- Здесь может выполняться другой код
        -- Например, обработка данных из Quik
        process_quik_data()
        
        -- Небольшая пауза чтобы не грузить CPU
        os.execute("ping -n 1 127.0.0.1 > nul")  -- для Windows
        -- os.execute("sleep 0.1")  -- для Linux
    end
    
    print("Скрипт продолжает работу после диалога")
end

function process_quik_data()
    -- Здесь может быть код для работы с данными Quik
    -- который выполняется параллельно с открытым диалогом
end

-- Запуск основной функции
main()
 
Код работает!   Буду разбираться.
 
Разбираюсь. То что надо! Кнопку Cancel переназначил для модификации глобальной переменной и продолжения диалога. Эта глобальная переменная доступна функции process_quik_data(). Грандиозно. IUP как раз такой простенький интерфейс, какой нужен.Дополнительно открыл, что версия IUP-3.28 для Lua 5.3.5 32-бит работает с Quik 12.5.0.20, который давно уже 64 бит.
Страницы: 1
Читают тему
Наверх