@@ -156,4 +156,115 @@ other sub-modules or sub-packages).
156156Adding sub-plugins
157157------------------
158158
159- .. todo :: Show how to add sub-plugins
159+ Adding sub-plugins to your plugin is done a very few steps. All you actually
160+ need is a new instance of the :class: `plugins.manager.PluginManager ` class.
161+ This instance allows you to load plugins from a specifc directory.
162+
163+ Imagine your plugin resides in ``../addons/source-python/plugins/my_plugin ``
164+ and within that directory you have created a new directory called ``plugins ``,
165+ which should contain all sub-plugins of ``my_plugin ``. Then the plugin manager
166+ could be created using the following code:
167+
168+ .. code :: python
169+
170+ from plugins.manager import PluginManager
171+
172+ my_plugin_manager = PluginManager(' my_plugin.plugins.' )
173+
174+
175+ That's all you need! Now you can load sub-plugins using ``my_plugin_manager ``
176+ from your sub-plugins directory with the following code:
177+
178+ .. code :: python
179+
180+ # Load the plugin 'my_sub_plugin' from
181+ # ../addons/source-python/plugins/my_plugin/plugins
182+ my_plugin_manager.load(' my_sub_plugin' )
183+
184+
185+ However, this doesn't print any messages like Source.Python does when you load
186+ a plugin via ``sp plugin load ``. If you would like to have those messages as
187+ well, without implementing them on your own, you can simply create an instance
188+ of ``plugins.command.SubCommandManager ``.
189+
190+ .. code :: python
191+
192+ from plugins.command import SubCommandManager
193+
194+ my_sub_command_manager = SubCommandManager(
195+ # Tell the sub command manager to use this plugin manager to load plugins
196+ my_plugin_manager,
197+
198+ # If you create sub-commands, they will use 'my_plugin' as the base
199+ # command like Source.Python uses 'sp'
200+ ' my_plugin'
201+ )
202+
203+
204+ Now, you can load your sub-plugin using the following code:
205+
206+ .. code :: python
207+
208+ my_sub_command_manager.load_plugin(' my_sub_plugin' )
209+
210+
211+ So far, so good. But what if you want to load your plugins via a server
212+ command? Well, just add it using the following code:
213+
214+ .. code :: python
215+
216+ @my_sub_command_manager.server_sub_command ([' plugin' , ' load' ])
217+ def plugin_load (command_info , plugin ):
218+ my_sub_command_manager.load_plugin(plugin)
219+
220+ @my_sub_command_manager.server_sub_command ([' plugin' , ' unload' ])
221+ def plugin_unload (command_info , plugin ):
222+ my_sub_command_manager.unload_plugin(plugin)
223+
224+
225+ Now you can also load your sub-plugins using ``my_plugin plugin load `` and
226+ unload them using ``my_plugin plugin unload ``.
227+
228+ There is only one last thing left to do. If your main plugin is being
229+ unloaded, you should also unload all of your sub-plugins. It doesn't cause any
230+ problems with Source.Python if you don't do that, because Source.Python also
231+ unloads all :class: `core.AutoUnload ` and :class: `core.WeakAutoUnload `
232+ instances of your sub-plugins. But if you don't do that the ``unload ``
233+ functions of your sub-plugins are never getting called. To avoid this issue
234+ use the following code:
235+
236+ .. code :: python
237+
238+ def unload ():
239+ for plugin in tuple (my_plugin_manager.values()):
240+ plugin.unload()
241+
242+
243+ Here is the full example code to implement sub-plugins:
244+
245+ .. code :: python
246+
247+ from plugins.manager import PluginManager
248+ from plugins.command import SubCommandManager
249+
250+ my_plugin_manager = PluginManager(' my_plugin.plugins.' )
251+ my_sub_command_manager = SubCommandManager(
252+ # Tell the sub command manager to use this plugin manager to load plugins
253+ my_plugin_manager,
254+
255+ # If you create sub-commands, they will use 'my_plugin' as the base
256+ # command like Source.Python uses 'sp'
257+ ' my_plugin'
258+ )
259+
260+ @my_sub_command_manager.server_sub_command ([' plugin' , ' load' ])
261+ def plugin_load (command_info , plugin ):
262+ my_sub_command_manager.load_plugin(plugin)
263+
264+ @my_sub_command_manager.server_sub_command ([' plugin' , ' unload' ])
265+ def plugin_unload (command_info , plugin ):
266+ my_sub_command_manager.unload_plugin(plugin)
267+
268+ def unload ():
269+ for plugin in tuple (my_plugin_manager.values()):
270+ plugin.unload()
0 commit comments