Записывать сообщения в окно игрового приложения - PullRequest
0 голосов
/ 15 августа 2011

У меня есть приложение для высокоскоростного рендеринга, и я хочу выводить сообщения журнала в отдельное окно .Приложение является многопоточным, и все потоки могут что-то регистрировать в любой момент времени.

Я уже использую консоль для вывода, и это работало нормально!

Я сделал следующее:

  • Создание очереди logMessage
  • Всякий раз, когда потоку есть что сказать, он блокирует очередь и вставляет свое сообщение в очередь
  • Существует a«очищающий» поток , который спит до тех пор, пока какой-то поток не запишет что-либо (акт вызова log() в любом потоке, пробуждает очищающий поток), и его задача - сбросить все сообщения журнала в файл и консоль.

Это работало нормально как для ведения журнала файлов, так и для консоли: ни одному из них не кажется, что поток, который они получают для вызовов на печать, отличается от основного потока приложения.Однако любое другое окно, которое вы создаете, имеет значение .Так что теперь поток очистки не работает, когда я пытаюсь напечатать в отдельном окне RichText , которое я создал.

Так что это разочаровывает.Теперь единственное решение, которое кажется, состоит в том, чтобы переместить flush код потока в основной поток (то же самое, что запускает цикл рендеринга), что означает потенциально долгую задержку в отображении кадра(если вы ожидаете блокировки очередей журнала, чтобы их можно было выводить), чего я не хочу.

1 Ответ

0 голосов
/ 15 августа 2011

Похоже, что у вас есть что-то похожее на конфликт для вашей флеш-темы:

  • Это рабочий поток, который хочет иметь возможность спать, когда нет работы - вероятно, с помощью WaitForSingleObject для дескриптора события

  • Однако, если поток создает окно, он теперь должен вести себя как поток GUI - это означает, что ему нельзя блокировать или ждать, и вместо этого он должен вернуться к циклу сообщений (GetMessage / TranslateMessage / DispatchMessage) когда он закончил свою работу.

Один из подходов к разрешению этого очевидного конфликта заключается в следующем:

  • Используйте MsgWaitForMultipleObjects: это, в основном, версия WaitFor ..., которая активируется при возникновении события, или , если есть сообщение, которое необходимо обработать richedit - который затем обрабатывается с использованием GetMessage () и т. д., а когда закончите, вернитесь к MsgWaitFor ... и начните снова, ожидая сообщения о событии или графического интерфейса. Это позволяет потоку быть одновременно потоком GUI и рабочим потоком.

Другой подход (который, вероятно, требует больше работы, и я думаю, что приведенный выше, скорее всего, лучше подойдет для вашего существующего кода - но в любом случае упомяну это):

  • Вместо того, чтобы рабочий поток переходил в спящий режим с помощью WaitForSingleObject, используйте тот факт, что это поток GUI; фактически он в конечном итоге спит, вызывая GetMessage (), и проснется, если другой поток отправит ему сообщение. Это потребует наличия скрытого окна, которым владеет тема, в которую вы можете отправить сообщение. (Вы также можете использовать PostThreadMessage, чтобы избежать необходимости создавать скрытое окно, но у него есть некоторые хитрые проблемы, когда сообщения могут «потеряться», если поток отображает окно сообщения или диалоговое окно, поэтому скрытое окно является самым безопасным подход.)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...