2009-12-19 12 views
8

J'écris un plugin navigateur web (NPAPI.)Génération async événements Javascript de plug-in du navigateur (NPAPI)

Mon plug-in démarre un thread de travail, et que le travailleur progresse, je voudrais passer les événements de retour à Javascript. Mais à cause du modèle de thread NPAPI, il n'est pas légal que le thread de travail rappelle directement NPAPI, donc le thread de travail ne peut pas appeler Javascript.

Une solution à cela est la fonction NPN_PluginThreadAsyncCall. Mais c'est une fonction relativement nouvelle. Par exemple, il est pris en charge uniquement à partir de Firefox 3.

Existe-t-il un moyen d'obtenir une exécution d'événement/javascript asynchrone à partir d'un plugin NPAPI sans utiliser NPN_PluginThreadAsyncCall? Qu'ont fait les gens avant que cette fonction ne soit ajoutée?

Répondre

5

La réponse est oui ... et non ...

Si vous avez besoin pour soutenir les anciens navigateurs (Firefox 3 avant), vous pouvez mettre en œuvre la même fonction NPN_PluginThreadAsyncCall. Sous Windows, vous pouvez le faire en créant une structure de données qui peut contenir le pointeur de fonction et le pointeur opaque void *, puis publier un message personnalisé dans la fenêtre principale avec un pointeur sur votre structure de données en tant que LPARAM.

La fenêtre principale WINPPROC s'exécute sur le thread UI, qui est le thread qui peut parler à Javascript. Ainsi, lorsque vous obtenez ce message dans votre WINPROC, vous retournez simplement la LPARAM au pointeur, appelez la méthode avec les données opaques, puis libérez la structure de données.

Sur Mac, vous pouvez faire une chose similaire avec une file d'attente pour stocker les événements, puis sur l'événement NULL (qui est envoyé par Mac OS à chaque tick) vérifier pour voir si quelque chose s'y trouve. Si c'est le cas, éteignez-le, appelez la méthode, libérez-la et continuez.

Il y a probablement un moyen de le faire sous Linux, mais je ne sais pas ce que c'est.

Vous trouverez un exemple de la version de Windows dans le firebreath project.

La manipulation du message WinProc est dans ce fichier: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.cpp

L'événement et la structure de données sont définies dans le fichier d'en-tête: https://github.com/firebreath/FireBreath/blob/master/src/PluginWindow/Win/PluginWindowWin.h

Et la méthode pour le tir de cet événement est ici:

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

Merci beaucoup! Il est extrêmement utile de savoir que le thread de boucle d'événement GUI de la plate-forme est sûr pour les appels NPAPI. Et je vais certainement vérifier Firebreath. Sur Macintosh, si vous pouvez compter sur Cocoa, un moyen facile d'exécuter du code sur le thread graphique est la méthode NSObject performSelectorOnMainThread. – Geoff

+0

Oui, je pense que quelqu'un m'a parlé de performSelectorOnMainThread, mais je n'ai pas eu besoin de l'utiliser jusqu'ici. Le pourcentage d'utilisateurs encore sur firefox 2 est si petit ces jours-ci que j'ai juste décidé de ne plus le supporter. Avec FireBreath, nous pourrions ajouter du support si quelqu'un en avait vraiment besoin (ou ils le pourraient), mais je n'en ai pas besoin pour aucun de mes trucs. =] Il y a plusieurs fonctionnalités vraiment sympa qui n'ont pas été implémentées jusqu'à Firefox 2; NPN_Enumerate et NPN_Construct, par exemple. De plus, firefox 2 a un bug connu qui ne permet pas de voir les plugins enregistrés dans HKCU dans windows, donc vous devez être administrateur. – taxilian