для моей диссертации мне нужно подключить датчик трекинга головы к существующему программному обеспечению автосимулятора. Автомобильный симулятор способен получать команды TCL через DDE, и до сих пор я успешно установил канал связи. Идея состоит в том, чтобы использовать данные датчика для настройки текущего представления в окне симулятора.
Данные датчика обрабатываются с помощью приложения c ++, которое также действует как клиент DDE и отправляет командную строку на сервер DDE (симулятор). Используя пример от Microsoft (см. Здесь: http://support.microsoft.com/kb/279721/en-us) Я отправляю командную строку со следующей строкой:
DdeClientTransaction((LPBYTE)hData, 0xFFFFFFFF, hConv, 0L, 0, XTYP_EXECUTE,
TIMEOUT_ASYNC, NULL);
Переменная hData
представлять после того, как какая-то другая функция вызывает строку для передачи интерпретатору TCL на симуляторе. Командная строка, которую я отправляю рекурсивно, является эксклюзивной для симулятора и выглядит следующим образом:
"Movie eval {dict set View(0:0) xrot %s; dict set View(0:0) yrot %s; dict set View(0:0) zrot %s;}"
Если вам интересно %s
являются заполнителями для рыскания, тангажа и крена хедтрекера.
Все работает правильно. Однако у меня возникло ощущение, что интерпретатор TCL симулятора иногда замедляется и в итоге зависает весь симулятор.
На стороне DDE, DdeClientTransaction
-функция возвращает значение, была ли транзакция успешной / занятой, и я использую это, чтобы избежать спама на сервере DDE (симуляторе), поэтому я подозреваю, что проблема заключается в замедлении интерпретатора TCL.
Теперь у меня вопрос: есть ли команда TCL, которую я могу добавить в свою командную строку, или другой способ заставить интерпретатор обрабатывать следующую полученную команду через DDE, как только она будет выполнена с предыдущей, и в случае, если в очереди будет больше команд, просто обработайте самый новый?
Я заметил, что отправка update;
:
"Movie eval {dict set View(0:0) xrot %s; dict set View(0:0) yrot %s; dict set View(0:0) zrot %s; update;}"
более стабильный, но я не совсем понимаю, что он делает.
Что за update
делает это обрабатывать события немедленно. Он истощает очередь событий из всего, что там в данный момент, и продолжает идти до тех пор, пока ему не придётся переходить в состояние ожидания следующего события. (Внутренне, update
это тонкая оболочка вокруг API-функции под названием Tcl_DoOneEvent()
.)
Обычно это не рекомендуется. Проблема в том, что если событие, вызвавшее update
случиться внутри его сценария обработки происходит снова, update
будет стрелять снова, и вы можете легко в конечном итоге update
внутри update
внутри update
внутри … который довольно быстро заполнит стек C-уровня всеми вызовами Tcl_DoOneEvent()
который в свою очередь — окольно — перезванивает Tcl_Eval()
…
Если что-то вялое, это, как правило, признак того, что ваши обработчики событий обрабатывают слишком долго. Лучшая вещь было бы, если бы вы могли сократить количество времени, в течение которого работает любой обработчик, и, возможно, также уменьшить скорость, с которой вы отправляете события в систему. Это позволит свести к минимуму промежуток времени между запуском вашего маленького скрипта и перерисовкой в ответ.
Но это может быть довольно сложно сделать. (Я не знаю, это зависит от того, что еще происходит и т. Д.)
Перерисовки обычно происходят в неактивных событиях, которые представляют собой особую очередь событий, которая очищается только при Tcl_DoOneEvent()
больше нечего делать. Вы можете попытаться навести порядок с меньшей вероятностью катастрофы изменяя update
в update idletasks
, который будет просто истощать бездействующую очередь событий. (NB: Вы можете добавить вещи в очередь ожидания, используя after idle
; Большую часть времени вам не нужно этого делать.) Он не будет обрабатывать перерисовки, вызванные внешними событиями (такими как иконизация или изменение размера окна), но это часто менее важно для быстрой обработки.
Я полагаю, вы можете попробовать поиграть с after idle
, но я подозреваю, что это может быть неудовлетворительным для вас. Я знаю только несколько мест, в которых есть какой-то реальный смысл использовать (и это когда вы делаете низкоуровневую работу с реализацией виджетов).