Gerando eventos assíncronos javascript do plug -in do navegador (npapi)
-
20-09-2019 - |
Pergunta
Estou escrevendo um plugin de navegador da web (npapi.)
Meu plug -in inicia um tópico de trabalhador e, à medida que o trabalhador progride, gostaria de repassar os eventos de volta ao JavaScript. Mas, devido ao modelo de Threading NPAPI, não é legal que o tópico do trabalhador seja diretamente para o NPAPI, para que o tópico do trabalhador não possa invocar o JavaScript.
Uma solução para isso é a função NPN_PLUGINTHREADASYNCCALL. Mas essa é uma função relativamente nova. Por exemplo, é suportado apenas do Firefox 3.
Existe alguma maneira de obter execução de entrega/javascript de evento assíncrono de um plug -in NPAPI sem usar npn_pluginthreadasynccall? O que as pessoas fizeram antes que essa função fosse adicionada?
Solução
A resposta é sim e não...
Se você precisar oferecer suporte a navegadores mais antigos (pré -Firefox 3), poderá implementar o NPN_PLUGINTHREADASYNCCALL FUNCIONAR. No Windows, você pode fazer isso criando uma estrutura de dados que pode conter o ponteiro da função e o ponteiro vazio* opaco e depois postar uma mensagem personalizada na janela principal com um ponteiro para sua estrutura de dados como LPARAM.
A janela principal WinProc é executada no thread da interface do usuário, que é o thread que pode conversar com o JavaScript. Portanto, quando você recebe essa mensagem no seu WinProc, basta lançar o LPARAM de volta ao ponteiro, chamar o método com os dados opacos e depois libertar a estrutura de dados.
No Mac, você pode fazer uma coisa semelhante com uma fila para armazenar os eventos e, em seguida, no evento NULL (que é enviado pelo Mac OS sobre cada tick), verifique se há alguma coisa nele. Nesse caso, retire -o, chame o método, liberte -o e continue.
Provavelmente também existe uma maneira de fazer isso no Linux, mas não sei o que é.
Você pode encontrar um exemplo da versão do Windows no Projeto Firebreath.
O manuseio da mensagem WinProc está neste arquivo:https://github.com/firebreath/firebreath/blob/master/src/pluginwindow/win/pluginwindowwin.cpp
O evento e a estrutura de dados são definidos em seu arquivo de cabeçalho:https://github.com/firebreath/firebreath/blob/master/src/pluginwindow/win/pluginwindowwin.h
E o método para disparar esse evento está aqui:
void ActiveXBrowserHost::ScheduleAsyncCall(void (*func)(void *), void *userData)
{
if (m_hWnd != NULL)
::PostMessage(m_hWnd, WM_ASYNCTHREADINVOKE, NULL,
(LPARAM)new FB::WINDOWS_ASYNC_EVENT(func, userData));
}