Удобная регистрация слушателей

Удобная регистрация слушателей

Слушатели событий используются в каждой второй программе. Они удобны тем, что для них не нужно отводить отдельного цикла с ловлей ивентов и ставить кучу if'ов.

У них есть один недостаток: если их не удалить в конце программы, то они продолжат обрабатывать сигналы и выполнять действия. А это почти никогда не является полезным.

Особенно раздражает это поведение, когда программа завершается с ошибкой и до отключения слушателей дело и не дошло.

Можно ставить pcall, но здесь мы заиспользуем потоки.

Потоки добавлены были в OpenOS 1.6.4 (OC 1.7+). Они задумывались как удобная имплементация многозадачности, но кроме того у них есть и одна интересная фича: все слушатели событий и таймеры, которые зарегистрированы в потоке, удаляются при его завершении.

Не важно, завершился ли поток из-за его отключения другим, ошибки или отсутствия команд для исполнения. Всё автоматически подчистится в любом случае.

Давайте воспользуемся ими для нашей цели. Для этого создадим один поток, в котором зарегистрируем всех слушателей и начнём сам главный цикл. В другом будем ловить нажатие Ctrl+C, потому что его поймать можно только через event.pull.

local event = require("event")
local thread = require("thread")

local mainThread = thread.create(function()
  event.listen("key_down", function(evt, addr, key, code, user)
    print("A key has been pressed!")
  end)

  while true do
    print("do something")
    os.sleep(0.5)
  end
end)

local intThread = thread.create(function()
  event.pull("interrupted")
end)

thread.waitForAny({mainThread, intThread})
os.exit(0)

Программа завершается, когда завершается любой из потоков: или закончился главный цикл, или был пойман Ctrl+C. Поэтому используем thread.waitForAny.

Кроме того, когда thread.waitForAny завершится, один из потоков может продолжать свою работу. Убить их и завершить программу позволяет функция os.exit.

Подробнее

results for ""

    No results matching ""