Gambas France BETA


Pas de compte ? Incription

Application modulaire : des plugins pour votre appli

À propos de ce code

Salut,
Je vous propose de discuter ici des possibilités et de l'intérêt du développement d'application modulaire en Gambas3.

I. Qu'est ce que c'est ?

Une application modulaire est un programme dont les fonctionnalités peuvent être augmentées/modifiées par l'ajout de plugins, ils ne sont pas indispensables à l'exécution.

II. Proposition de code

Je me suis penché sur la possibilité d'ajouter une référence à un composant externe lors de l'exécution. Tout est ici programmé en Gambas3.

1. Ajouter dynamiquement un composant

Ce code permet de parcourir le répertoire de l'application et d'insérer les plugins trouvées :
1
2
3
4
5
6
7
8
PUBLIC SUB Main()

DIM plugin AS STRING

FOR EACH plugin IN Dir(Application.Path, "*.plugin")
Component.Load(Application.Path &/ plugin)
NEXT
END
Remarque : Les plugins ne peuvent être chargés que s'ils se trouvent dans le répertoire de l'application, dans "/usr/bin/" ou "/bin/".

2. Référence dynamique à une classe

Pour qu'une classe soit référenciable à l'exécution, elle doit être reconnaissable par son nom, j'ai choisi ici de préfixer les classes des plugins par "export". Ce code crée une instance de chaque classe exportée de chaque plugin :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
PUBLIC SUB Main()

DIM plugin AS STRING
DIM cls AS Class, obj AS OBJECT

FOR EACH plugin IN Dir(Application.Path, "*.plugin")
Component.Load(plugin)
NEXT
FOR EACH cls IN Classes
IF NOT IsNull(cls.Component) THEN
IF cls.Component.Name LIKE "*.plugin" AND cls.Name LIKE "export*" THEN
obj = Object.New(cls.Name) 'Création d'un instance
ENDIF
ENDIF
NEXT
END


3. Programmation du plugin

S'il n'y a pas d'héritage, la programmation du plugin ne pose aucun problème, voici un exemple de plugin, ce code est celui de la class exportSample de l'application SamplePlugin, qui sera compilée dans "SamplePlugin.plugin" :
1
2
3
4
5
6
7
8
9
' Gambas class file

EXPORT 'indispensable pour que la classe soit visible de l'extérieur de l'application.

STATIC PUBLIC SUB _init()

DEBUG "Le plugin SamplePlugin a été chargé"

END


Exemple plus utile : ajout d'un bouton sur une fenêtre à partir d'un plugin


- Dans l'application principale :
Soit un formulaire Form1 contenant un bouton Button1, qui fait ce que vous voulez mais dont la propriété Public=True.
Soit un module MainModule qui est défini comme classe de démarrage.
Code de MainModule :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'Gambas module file

PUBLIC SUB Main()

DIM plugin AS STRING
DIM cls AS Class
DIM frm AS NEW Form1

FOR EACH plugin IN Dir(Application.Path, "*.plugin")
DEBUG Subst("Plugin trouvé : &1" plugin)
Component.Load(Application.Path &/ plugin)
NEXT
FOR EACH cls IN Classes
IF NOT IsNull(cls.Component) THEN
IF cls.Component.Name LIKE "*.plugin" AND cls.Name LIKE "export*" THEN
Object.New(cls.Name).pluginMain(frm, frm.Button1.X, frm.Button1.Y + frm.Button1.H, frm.Button1.W, frm.Button1.H)
ENDIF
ENDIF
NEXT

frm.show()
END

- Dans le plugin
On coche gb.gui dans la liste des composants à charger (Sinon ça ne se compilera pas à cause des références à Form et Button).
Soit une classe exportMonBouton dont voici le code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
' Gambas class file

EXPORT

PUBLIC SUB pluginMain(frm AS Form, X AS LONG, Y AS LONG, W AS LONG, H AS LONG)

DIM b2 AS NEW Button(frm) AS "PluginButton"
b2.X = X
b2.Y = Y
b2.W = W
b2.H = H
b2.Caption = "PluginButton"

END

PUBLIC SUB PluginButton_Click()

Message("Action du plugin")

END
Il suffit maintenant de compiler le plugin, de renommer l'exécutable en .plugin (l'IDE génère toujours des .gambas) et de le déplacer dans le répertoire de l'application principale.

Pour aller plus loin


Il est intéressant de noter que si la classe Class1 de l'application principale est exportée, on peut y accéder depuis le plugin avec la syntaxe
1
variable=Object.New("Class1")
De même pour les modules.

EDIT (13/02/12) : Un peu d'orthographe.

Commentaires

Commentaire de linuxos, Le 13/2/2012 à 21:13:54
C'est très bien tout ça ... ça me donne des idées..

Olivier