Skip to content

Commit 21f6236

Browse files
committed
Added sub-plugins tutorial
1 parent 187c4f7 commit 21f6236

File tree

1 file changed

+112
-1
lines changed
  • addons/source-python/docs/source-python/source/developing/module_tutorials

1 file changed

+112
-1
lines changed

addons/source-python/docs/source-python/source/developing/module_tutorials/plugins.rst

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,115 @@ other sub-modules or sub-packages).
156156
Adding 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

Comments
 (0)