Уведомление javascript о внешнем событии от XPcom - PullRequest
2 голосов
/ 25 января 2012

Я пытался найти решение относительно простого сценария. У меня есть JavaScript, работающий на HTML-странице, которая делает вызов XPcom, который я написал на C ++. Пока все хорошо.

Этот XPcom извлекает ссылку на службу наблюдателей (do_GetService("@mozilla.org/observer-service;1")); выдает уведомление, которое «видно» из javascript; XPcom создает поток Windows (AFX), передает копию ссылки на службу наблюдателя и возвращает вызывающей стороне javascript; ожидая, что поток XPcom отправит дополнительные уведомления в соответствующее время (на основе внешних событий).

Однако уведомления не приходят в javascript, и я изначально думал, что метод уведомления не будет доставлять уведомления из «другого» потока. Я использовал отладчик VStudio для подтверждения того, что последовательность программы соответствует ожидаемой; то есть внешнее событие принимается потоком и вызывается метод notify ... но событие notify не приходит.

Я прочитал довольно много публикаций в Интернете, и ничто не «пригвождает» тот конкретный сценарий, к которому я пытаюсь обратиться. Я не женат на идее использования notify:

  • Я пробовал уведомлять о событиях через NS_DispatchToCurrentThread, однако это тоже не работает, потому что у меня нет «события» со стороны javascript для доставки. Я могу создать свой собственный в контексте XPcom, и я могу «уведомить об этом»; но это было просто POC, чтобы доказать, что я могу доставлять события из XPcom; теперь мне нужно, чтобы сторона javascript уведомила меня о событии;
  • Я попытался передать новый объект как аргумент nsiSupports; но DispatchToCurrentThread хочет nsiRunnable, и я не могу понять, как передать один из них (файл idl не поддерживает);
  • Я также рассмотрел «обертывание» события каким-либо объектом, совместимым с nsiSupports; но я не уверен в деталях этого.

Цель довольно проста. доставлять асинхронные события или уведомления из потока XPcom в основной или даже вспомогательный поток JavaScript; но я получаю менее 10% тяги здесь. Кто-нибудь достиг этого? или есть идеи как это сделать?

Большое спасибо.

1 Ответ

1 голос
/ 25 января 2012

Вы правы, служба наблюдателя работает только в главном потоке (проверьте возвращаемое значение вашего Notify() вызова, оно должно быть NS_ERROR_UNEXPECTED).Вы также правы в том, что касается решения - отправьте событие в главный поток через NS_DispatchToMainThread().Что касается фактической реализации, функция NS_NewRunnableMethod() должна помочь (если вы не хотите создавать свою собственную реализацию nsIRunnable - например, для передачи параметров).Вы, вероятно, захотите сделать что-то вроде этого:

nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(xpcomComponent, &nsMyComponent::processEvent);
nsresult rv = NS_DispatchToMainThread(event);

Здесь xpcomComponent будет ссылкой на ваш экземпляр компонента XPCOM и nsMyComponent::processEvent его методом, который должен вызываться в главном потоке.Затем этот метод сможет уведомить наблюдателя.

...