1 /**
2 Copyright: Copyright (c) 2015-2018 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 
7 module pluginlib.interfaces;
8 
9 import voxelman.log;
10 import std.conv : to;
11 import std.string : format;
12 import pluginlib;
13 
14 mixin template IdAndSemverFrom(string pinfoModuleName)
15 {
16 	mixin("import pinfo = " ~ pinfoModuleName ~ ";");
17 	override string id() @property { return pinfo.id; }
18 	override string semver() @property { return pinfo.semver; }
19 }
20 
21 /// Basic plugin interface
22 abstract class IPlugin
23 {
24 	/// Unique identifier ("exampleplugin")
25 	string id() @property;
26 	/// Human readable name ("Example plugin")
27 	//string name() @property;
28 	/// Valid semver version string. i.e. 0.1.0-rc.1
29 	string semver() @property;
30 	/// Register resource managers provided by this plugin
31 	void registerResourceManagers(void delegate(IResourceManager) registerResourceManager) {}
32 	/// Get references to resource managers and call their methods.
33 	/// Resources are loaded before preInit
34 	void registerResources(IResourceManagerRegistry resmanRegistry) {}
35 	/// Private initialization using resources loaded by resource managers
36 	void preInit() {}
37 	/// Get references to other plugins. Other plugins may call this plugin from now
38 	void init(IPluginManager pluginman) {}
39 	/// Called after init. Do something with data retrieved at previous stage
40 	void postInit() {}
41 }
42 
43 interface IPluginManager
44 {
45 	/// Returns reference to plugin instance if pluginId was registered.
46 	IPlugin findPlugin(TypeInfo pluginType);
47 	IPlugin findPluginById(string pluginId);
48 
49 	/// Returns null if plugin is not loaded, P otherwise
50 	final P findPlugin(P)()
51 	{
52 		import std.exception : enforce;
53 		IPlugin plugin = findPlugin(typeid(P));
54 		if (!plugin) return null;
55 
56 		P exactPlugin = cast(P)plugin;
57 		enforce(exactPlugin, format("Cannot cast plugin to '%s'", typeid(P)));
58 		return exactPlugin;
59 	}
60 
61 	/// Guaranteed to return not null reference to P
62 	final P getPlugin(P)()
63 	{
64 		import std.exception : enforce;
65 		IPlugin plugin = findPlugin(typeid(P));
66 		P exactPlugin = cast(P)plugin;
67 		enforce(exactPlugin, format("Cannot find plugin '%s'", typeid(P)));
68 		return exactPlugin;
69 	}
70 }
71 
72 /// Basic plugin interface
73 /// Resource manager version is the same as plugin's one that registered it
74 abstract class IResourceManager
75 {
76 	/// Unique identifier ("config")
77 	string id() @property;
78 	/// Human readable name ("Config resource manager")
79 	//string name() @property;
80 	/// Load/create needed resources
81 	void preInit() {}
82 	/// Get references to other plugins
83 	void init(IResourceManagerRegistry resmanRegistry) {}
84 	/// Called after init. Do something with data retrieved at previous stage
85 	void loadResources() {}
86 	/// Called after loadResources. Do something with data retrieved at previous stage
87 	void postInit() {}
88 }
89 
90 interface IResourceManagerRegistry
91 {
92 	/// Returns reference to ResourceManager instance if resmanId was registered
93 	IResourceManager findResourceManager(TypeInfo rmType);
94 
95 	/// Guaranteed to return not null reference to RM
96 	final RM getResourceManager(RM)()
97 	{
98 		import std.exception : enforce;
99 		IResourceManager resman = findResourceManager(typeid(RM));
100 		RM exactResman = cast(RM)resman;
101 		enforce(exactResman, format("Cannot find resource manager '%s'", typeid(RM)));
102 		return exactResman;
103 	}
104 }