2009-12-19 8 views
8

Sto scrivendo un plugin per browser web (NPAPI.)Generazione asincrona eventi JavaScript dal browser plugin (NPAPI)

mio plug-in inizia un thread di lavoro e il lavoratore va avanti, mi piacerebbe passare eventi indietro in Javascript. Ma a causa del modello di threading NPAPI, non è legale per il thread worker richiamare direttamente in NPAPI, quindi il thread worker non può richiamare Javascript.

Una soluzione è la funzione NPN_PluginThreadAsyncCall. Ma questa è una funzione relativamente nuova. Ad esempio, è supportato solo da Firefox 3 in poi.

C'è un modo per ottenere l'erogazione di eventi asincroni/l'esecuzione javascript da un plug-in NPAPI senza utilizzare NPN_PluginThreadAsyncCall? Cosa facevano le persone prima che questa funzione fosse aggiunta?

risposta

5

La risposta è sì ... e no ...

Se avete bisogno di supportare i browser più vecchi (pre Firefox 3), è possibile implementare la funzione NPN_PluginThreadAsyncCall da soli. Su Windows, puoi farlo creando una struttura dati in grado di contenere il puntatore della funzione e il puntatore opaco vuoto * e quindi postare un messaggio personalizzato nella finestra principale con un puntatore alla struttura dati come LPARAM.

La finestra principale WINPPROC viene eseguita sul thread dell'interfaccia utente, che è il thread che può parlare con Javascript. Quindi, quando si ottiene quel messaggio nel WINPROC, si esegue semplicemente il cast di LPARAM sul puntatore, si chiama il metodo con i dati opachi e quindi si libera la struttura di dati.

Su Mac, puoi fare una cosa simile con una coda per memorizzare gli eventi, e poi sull'evento NULL (che viene inviato da Mac OS su ogni spunta) controlla se c'è qualcosa dentro. Se è così, fai un salto, chiama il metodo, liberalo e continua.

Probabilmente c'è anche un modo per farlo su linux, ma non so cosa sia.

È possibile trovare un esempio della versione di Windows in firebreath project.

La gestione del messaggio WinProc è in questo file: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.cpp

L'evento e la struttura dei dati sono definiti nel suo file di intestazione: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.h

E il metodo per la cottura di quell'evento è qui:

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)); 
} 
+1

Grazie! È estremamente utile sapere che il thread del ciclo di eventi della GUI della piattaforma è sicuro per le chiamate NPAPI. E controllerò sicuramente Firebreath. FWIW, su Mac, se puoi dipendere da Cocoa, un modo semplice per eseguire codice sul thread GUI è il metodo NSObject performSelectorOnMainThread. – Geoff

+0

Sì, penso che qualcuno mi abbia parlato di performSelectorOnMainThread, ma non ho avuto bisogno di usarlo finora. La percentuale di utenti ancora su firefox 2 è così piccola in questi giorni che ho deciso di non supportarla più. Con FireBreath, potremmo aggiungere supporto se qualcuno ne avesse avuto bisogno abbastanza (o potrebbero farlo), ma non ne ho bisogno per nessuna delle mie cose. =] Ci sono molte funzioni davvero belle che non sono state implementate fino a Firefox 2; NPN_Enumerate e NPN_Construct, ad esempio. Inoltre, firefox 2 ha un bug noto che non può vedere i plugin registrati in HKCU in Windows, quindi devi essere amministratore. – taxilian

Problemi correlati