À 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 pluginOn 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.
Olivier