Carbon ReceiveNextEvent и вторичные потоки - PullRequest
2 голосов
/ 03 ноября 2010

Представьте себе кроссплатформенную библиотеку, которая должна создавать свои собственные окна, не полагаясь на WinForms / GTK # / WPF / MonoMac / и т. Д. (Это OpenTK на случай, если кому-то это интересно).

Вот в чем дело: Unices с поддержкой Windows и X11 поддерживает (или может работать с) несколько циклов событий, по одному на каждый поток. Это означает, что (а) вы можете создать одно окно для каждого потока и заставить их работать независимо, и (б) вы можете запустить окно WinForms (или GTK #, WPF, ...) в одном потоке и открыть окно OpenTK в другом, без помех.

Теперь, насколько мне известно, по общему признанию, Carbon не поддерживает это. События ОС доставляются только в «основной» цикл событий, и все вторичные потоки работают на парах (то есть ReceiveNextEvent всегда возвращает eventLoopTimedOutErr и не находит никаких событий). Сам OpenTK может работать с этим ограничением, без проблем, но это представляет интересную проблему для приложений, которые пытаются смешать OpenTK с другим набором инструментов (например, MonoMac) для представления окна конфигурации.

Два варианта:

  • отказаться от идеи как сумасшедшей и запретить смешивать OpenTK с различными наборами инструментов (плохо).
  • выбрать боевой топор и взломать Углерод в подчинение (хорошо).

Вот, куда вы пришли: можете ли вы придумать, как сделать эту работу? Представьте себе следующий сценарий:

  1. Поток # 1 (основной) запускает некоторый код инициализации по нашему выбору и порождает второй поток (мы можем изменить его свободно).
  2. Поток # 1 (основной) открывает собственное окно и запускает цикл RAEL (RunApplicationEventLoop). Это выходит из-под нашего прямого контроля, хотя мы все равно можем установить таймеры для запуска нашего кода, если это необходимо.
  3. Поток № 2 (вторичный) открывает окно OpenTK, которое быстро зависает (события доставляются только в поток № 1, а ReceiveNextEvent ничего не получает).

Можно ли отфильтровать события из потока № 1 и доставить их в поток № 2 при необходимости? Может ли CF как-то помочь здесь? Гуру Mac OS X, пожалуйста, помогите!

(Язык программирования не имеет значения, используйте все, с чем вы знакомы. Я бы предпочел решение на основе углерода, но Cocoa будет работать просто отлично.)

Ответы [ 2 ]

1 голос
/ 01 ноября 2011

Передача событий из одного потока в другой должна работать так же просто, как получение событий. Важным моментом является то, что многие API-интерфейсы, связанные с пользовательским интерфейсом, не являются поточно-ориентированными, даже несмотря на то, что основная обработка Carbon Event такова. Все, что связано с обновлением элементов управления и рисованием, должно быть возвращено в основной поток. Это потребовало бы много взад-вперед, и, возможно, не стоит пытаться заставить его работать.

0 голосов
/ 03 ноября 2010

Посмотрите на Application.AddMessageFilter и интерфейс IMessageFilter .Вы можете иметь возможность перехватывать и пересылать сообщения, используя собственную логику.Я использовал эту технику в прошлом (очень далеком прошлом), но это было так давно, что я не помню всех предостережений, которые сопровождают это.Я даже не уверен, что фильтр сообщений получит все сообщения..NET может не отфильтровывать их за кулисами перед отправкой на IMessageFilter, но это стоит попробовать.

...