Порядок создания callback-обработчиков

Страницы: 1
RSS
Порядок создания callback-обработчиков
 
В какой момент должны быть созданы обработчики callback-ов, чтобы они вызывались? Экспериментально, если создавать некоторые функции обработчиков (например, main) внутри OnInit, то они работают, некоторые (например, OnQuote) - не работают. Возможно, адрес каких-то обработчикаов кешируется в какой-то момент и его последующие изменения в адресах функцииLua не учитываются?
 
К сожалению, связывание обработчиков идет в момент запуска скрипта и создание обработчика в процессе работы скрипта уже ни к чему не приводит.

На мой взгляд это недоработка и связывание должно быть динамическим, но "начальник всегда прав" (((
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
Цитата
s_mike@rambler.ru написал:
К сожалению, связывание обработчиков идет в момент запуска скрипта и создание обработчика в процессе работы скрипта уже ни к чему не приводит.

На мой взгляд это недоработка и связывание должно быть динамическим, но "начальник всегда прав" (((
В этом есть резон, например, чтобы не обращаться при каждом OnQuote в Lua за текущим адресом обработчика. Однако, часть работает так, часть - по-другому, логики не прослеживается. Если это из соображений скорости, то хорошим выходом было бы создание API, типа UpdateCallbackHandlers, которую скриптер мог бы вызывать эксплицитно, если что-то поменял.
 
Сделать стандартный обработчик с вызовам вашей "потом сгенерированной" функции - вот и решение.
Любопытно, кстати: зачем генерировать обработчики в run-time?
 
Цитата
swerg написал:
Любопытно, кстати: зачем генерировать обработчики в run-time?
Один из случаев, который был бы удобен многим, чтобы упрощать слежение корректности стейта. Сейчас, например, если есть поведение, зависящее от стейта, то нужно в каждом коллбеке делать проверки на то, от чего он зависит. Если бы можно было переназначать обработчики, то вся вариативность бы укладывалась бы в одом if-е в каком-нибудь OnInit, где инициализируются и переменные, и функции обратного вызова. Таким образом, можно было бы добиться инкапсуляции данных и поведения "для бедных" в Lua.
 
я пользуюсь такой штукой:

все колбеки у меня описаны в теле основного макроса.
затем, если мне надо без перезпуска этого макроса изменить текст какой-то процедуры, я по нажатию на определенную кнопку, запускаю командой dofile внешний файл lua, в котором в свою очередь идет вызов:
dofile (getScriptPath().."\\. .\\хххххххх.lua")
где хххххххх имя основного файла.
Таким образом он его снова перекомпилирует, и если его текст был изменен, то все функции начинают работать "по-новому".
У меня все перекрасно работает. можете попробовать
 
Цитата
Sergey Denegin написал:
я пользуюсь такой штукой:
...
Таким образом он его снова перекомпилирует, и если его текст был изменен, то все функции начинают работать "по-новому".
У меня все перекрасно работает. можете попробовать
У меня сама проблема решена (в С++), я скорее хотел прояснить, как же оно на самом деле задумано, с учетом того, что некоторые колбеки успешно переопределяются. В документации ничего про то, когда их можно определять, я не нашел.
 
вот таким образом у меня легко получается переопределить колбек, например OnAllTrade
 
Цитата
El El написал:
Цитата
swerg   написал:
Любопытно, кстати: зачем генерировать обработчики в run-time?
Один из случаев, который был бы удобен многим, чтобы упрощать слежение корректности стейта. Сейчас, например, если есть поведение, зависящее от стейта, то нужно в каждом коллбеке делать проверки на то, от чего он зависит. Если бы можно было переназначать обработчики, то вся вариативность бы укладывалась бы в одом if-е в каком-нибудь OnInit, где инициализируются и переменные, и функции обратного вызова. Таким образом, можно было бы добиться инкапсуляции данных и поведения "для бедных" в Lua.
можно как-то на примере?
 
Цитата
swerg написал:
Цитата
El El   написал:
Цитата
swerg   написал:
Любопытно, кстати: зачем генерировать обработчики в run-time?
Один из случаев, который был бы удобен многим, чтобы упрощать слежение корректности стейта. Сейчас, например, если есть поведение, зависящее от стейта, то нужно в каждом коллбеке делать проверки на то, от чего он зависит. Если бы можно было переназначать обработчики, то вся вариативность бы укладывалась бы в одом if-е в каком-нибудь OnInit, где инициализируются и переменные, и функции обратного вызова. Таким образом, можно было бы добиться инкапсуляции данных и поведения "для бедных" в Lua.
можно как-то на примере?

Было бы:
Код
Инициализация_скрипта:
  x = внешние_данные
  if (x == A)
    дополнительная манипуляция над данными
    if (x.z == 1)
       манипуляция_состоянием1...
       OnAllTr ade = My_OnAllTrade1
       OnQu ote = My_OnQuote1
       ...
    if (x.z == 2)
       манипуляция_состоянием2...
       OnAllTr ade = My_OnAllTrade1
       OnQu ote = My_OnQuote2
       ...
    if (x.z == 3)
       манипуляция_состоянием3
       OnAllTr ade = My_OnAllTrade1
       OnQu ote = My_OnQuote2
       ...
  else ...  
Это эквивалентно динамическому полиморфизму в ООП языках.

Сейчас пришлось бы делать так:
Код
Инициализация_скрипта:
  x = внешние_данные

OnQuote:
  if (x == A)
     манипуляция над частью данных
     if (x.z == 1)        
       OnAllTr ade = My_OnAllTrade1
       OnQu ote = My_OnQuote1
       ...
     if (x.z == 2)
       ...
     if (x.z == 3)

OnAllTrade:
  разбор для всех тех же случаев
В итоге получается, что вся вариативность поведения разбросана внутри каждого коллбека и нужно раздублировать все проверки на состояние внутри.
Чуть более сложный сценарий, в зависимости от состояния переназначать коллбеки, например, чтоб не вызывался один OnAllTrade, пока не сработал другой колбек (сейчас альтернатива, опять же, засунуть все в один OnAllTrade и делать там разбор случаев).
Вобщем-то даже в Lua при всей ее примитивности заложена философия first-class функций, и такая работа с функциями, как динамическое переназначение на имя другой лямбды, вполне в ее духе.
 
Цитата
El El написал:
Цитата
swerg   написал:
Цитата
El El   написал:
Цитата
swerg   написал:
Любопытно, кстати: зачем генерировать обработчики в run-time?
Один из случаев, который был бы удобен многим, чтобы упрощать слежение корректности стейта. Сейчас, например, если есть поведение, зависящее от стейта, то нужно в каждом коллбеке делать проверки на то, от чего он зависит. Если бы можно было переназначать обработчики, то вся вариативность бы укладывалась бы в одом if-е в каком-нибудь OnInit, где инициализируются и переменные, и функции обратного вызова. Таким образом, можно было бы добиться инкапсуляции данных и поведения "для бедных" в Lua.
можно как-то на примере?
Было бы:
Код
  Инициализация_скрипта:
  x  =  внешние_данные
   if  (x  =  =  A)
    дополнительная манипуляция над данными
     if  (x.z  =  =   1 )
       манипуляция_состоянием 1  .. .
       OnAllTr ade  =  My_OnAllTrade1
       OnQu ote  =  My_OnQuote1
        .. .
     if  (x.z  =  =   2 )
       манипуляция_состоянием 2  .. .
       OnAllTr ade  =  My_OnAllTrade1
       OnQu ote  =  My_OnQuote2
        .. .
     if  (x.z  =  =   3 )
       манипуляция_состоянием 3 
       OnAllTr ade  =  My_OnAllTrade1
       OnQu ote  =  My_OnQuote2
        .. .
   else   .. .  
  
Это эквивалентно динамическому полиморфизму в ООП языках.

Сейчас пришлось бы делать так:
Код
  Инициализация_скрипта:
  x  =  внешние_данные

OnQuote:
   if  (x  =  =  A)
     манипуляция над частью данных
      if  (x.z  =  =   1 )        
       OnAllTr ade  =  My_OnAllTrade1
       OnQu ote  =  My_OnQuote1
        .. .
      if  (x.z  =  =   2 )
        .. .
      if  (x.z  =  =   3 )

OnAllTrade:
  разбор для всех тех же случаев
  
В итоге получается, что вся вариативность поведения разбросана внутри каждого коллбека и нужно раздублировать все проверки на состояние внутри.
Чуть более сложный сценарий, в зависимости от состояния переназначать коллбеки, например, чтоб не вызывался один OnAllTrade, пока не сработал другой колбек (сейчас альтернатива, опять же, засунуть все в один OnAllTrade и делать там разбор случаев).
Вобщем-то даже в Lua при всей ее примитивности заложена философия first-class функций, и такая работа с функциями, как динамическое переназначение на имя другой лямбды, вполне в ее духе.
Как варианты:
1)Можно вынести разбор состояний в функцию
2) Можно ввести глобальный флаг и не разбирать снова если это тоже самое.
 
Есть еще одно решение.
Lua позволяет запускать функции с помощью вызова _G

Т.е. если в вашем примере есть три функции My_OnAllTrade1, My_OnAllTrade2, My_OnAllTrade3
То в обычном OnQuote делается такой вызов:
_G["My_OnAllTrade"..x.z]

Вуаля! в зависимости от значения переменной x.z он будет вызывать разные функции. Я так делаю, все работает.  
 
Не совсем правильно написал - нужно будет делать вызов:
_G["My_OnAllTrade"..x.z] (ххх)
где xxx или пустота, либо параметры, передаваемые в процедуру
Страницы: 1
Читают тему
Наверх