Хозяйке на заметку: OnStop()

Страницы: 1
RSS
Хозяйке на заметку: OnStop(), или "Зачем вы это делаете, мистер Андерсон?"
 
Код
stopflag = false

OnI nit = function()
   OnS top = function()
      message("Hello, I'm OnStop")
      stopflag = true
      return 10000
   end
end

main = function()
   while not stopflag do
      sleep(1000)
   end
end

Три дня в отладчике, три раза свой код переписал, "где ж я дедлок-то устроил". Ан нет, не я. Все колбеки как колбеки, OnStop почему-то кэшируется где-то до начала OnInit, так что в OnInit ее переопределять уже бесполезно. Зачем, зачем вы это делаете, мистер Андерсон?

П.С. Тут ответа мистера Андерсона в общем-то не требуется, равно как и желать особо нечего, ну так оно вот есть и есть, жаль только, что нигде об этом не написано. Теперь написано - здесь.

П.П.С. OnI nit, OnS top это не я так написал, это движок форума упорно поправляет.
 
Утро вечера мудренее. Вот так будет работать
Код
stopflag = false

main = function()
end

OnS top = function()
end

OnI nit = function()
   main = function()
      while not stopflag do
         sleep(1000)
      end
   end
   OnS top = function()
      message("Hello, I'm OnStop")
      stopflag = true
      return 10000
   end
end
Или, словами говоря, сначала создаем функции-заглушки, потом в процессе работы их можно переопределять на что угодно. Естественно, речь больше о lua_pushcclosure() / lua_setglobal(), скрипты просто иллюстрация.
 
В первом случае глобальная OnS top = nil, поэтому описанная  OnStop является локальной по области видимости внутри OnInit.
Quik видит  OnS top = nil.
То же самое будет и с переменными...
 
Олег, да, почему-то ожидалось, что раз эти функции описаны в доке, они должны существовать на момент запуска скрипта в виде каких-то внутренних заглушек, ан нет. Ну да ничего страшного, сами заглушек наделали, делов на копейку.
 
Как известно, QLua работает вот по такой модели: https://quik2dde.ru/viewtopic.php?id=16
В этой схеме не прописан один быть может не совсем очевидный нюанс, хотя понятно, что иначе и не сделать.

Сначала выполняется "скрипт целиком" ([BODY] на схеме). Выполняется он и в том смысле, что в глобальное пространство имён Lua-машины добавляются определённые в Lua-скрипте функции.
Далее QLua перебирает все объекты глобального хранилища, и находит там функции с предопределёнными названиями. Для всех найденных известных функций-callback'ов "в уме" QLua проставляет признак: "для этого события callback определён, а для этого - нет".

После, когда возникает какое-либо событие, которое должно привести к вызову callback-функции, сначала проверяется: а для этого события с этом скрипте мы нашли требуемую callback-функцию после выполнения [BODY]? Нашли - вызываем её, не нашли - не вызываем.

Соответственно, если мы в нашем Lua-скрипте определяем глобальную функцию OnStop только в тот момент, когда первый раз вызовется OnInit - то это будет уже "поздно". QLua уже пометил себе, что функция OnStop - не найдена, вызывать её не следует.

Вот и вся разгадка.

Осталось лишь узнать мнение начальника транспортного цеха, зачем он использует столь изощрённый синтаксис. Какова хитрая цель? Быть может все будет полезно?
 
Цитата
swerg написал:
Как известно, QLua работает вот по такой модели:  https://quik2dde.ru/viewtopic.php?id=16
Спасибо, информативная штука. Кстати, Ваша диаграммка сильно помогла в свое время разобраться в порядке вызова колбеков.

Цитата
swerg написал:
Осталось лишь узнать мнение начальника транспортного цеха, зачем он использует столь изощрённый синтаксис. Какова хитрая цель? Быть может все будет полезно?
Куда поедет выполнение скрипта, зависит от результатов OnInit. В частности, если оказалось, что "файл настроек не найден или поврежден", то main будет с юаем, циклом сообщений и всем таким, при других условиях другая, наконец, если все прошло по "основному сценарию", то вообще

Код
void _on_main_regular(void * lua_state)
{
   TRACE();
   set_exception_handler(_on_exception);
   _mainthread = thread::current();
   // enable OnStop callback
   _replace_callback(lua_state, "OnStop", ::cbid_on_stop);
   wait::all(_stopevent, wait::infinite);
}
Страницы: 1
Читают тему
Наверх