1 /*
2  * Stellarium
3  * Copyright (C) 2006 Fabien Chereau
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
18  */
19 
20 #ifndef STELMODULEMGR_HPP
21 #define STELMODULEMGR_HPP
22 
23 #include <QObject>
24 #include <QMap>
25 #include <QList>
26 #include "StelModule.hpp"
27 #include "StelPluginInterface.hpp"
28 
29 //! @def GETSTELMODULE(m)
30 //! Return a pointer on a StelModule from its QMetaObject name @a m
31 #define GETSTELMODULE( m ) qobject_cast< m *>(StelApp::getInstance().getModuleMgr().getModule( #m ))
32 
33 //! @class StelModuleMgr
34 //! Manage a collection of StelModules including both core and plugin modules.
35 //! The order in which some actions like draw or update are called for each module can be retrieved with the getCallOrders() method.
36 class StelModuleMgr : public QObject
37 {
38 	Q_OBJECT
39 
40 public:
41 	StelModuleMgr();
42 	~StelModuleMgr();
43 
44 	//! Regenerate calling lists if necessary
45 	void update();
46 
47 	//! Register a new StelModule to the list
48 	//! The module is later referenced by its QObject name.
49 	void registerModule(StelModule* m, bool generateCallingLists=false);
50 
51 	//! Unregister and delete a StelModule. The program will hang if other modules depend on the removed one
52 	//! @param moduleID the unique ID of the module, by convention equal to the class name
53 	//! @param alsoDelete if true also delete the StelModule instance, otherwise it has to be deleted by external code.
54 	void unloadModule(const QString& moduleID, bool alsoDelete=true);
55 
56 	//! Load dynamically a module
57 	//! @param moduleID the name of the module = name of the dynamic library file without extension
58 	//! (e.g "mymodule" for mymodule.so or mymodule.dll)
59 	//! @return the loaded module or Q_NULLPTR in case of error. The returned Stelmodule still needs to be initialized
60 	StelModule* loadPlugin(const QString& moduleID);
61 
62 	QObjectList loadExtensions(const QString& moduleID);
63 
64 	//! Unload all plugins
65 	void unloadAllPlugins();
66 
67 	//! Define whether a plugin should be loaded at startup.
68 	//! @param key the key of the plugin as in the PluginDescriptor class.
69 	//! @param b the value to set.
70 	void setPluginLoadAtStartup(const QString& key, bool b);
71 
72 	bool isPluginLoaded(const QString& moduleID);
73 
74 	QString getStandardSupportLinksInfo(QString moduleName, bool furtherInfo = false);
75 
76 	//! Get the corresponding module or Q_NULLPTR if can't find it.
77 	//! @param moduleID the QObject name of the module instance, by convention it is equal to the class name.
78 	//! @param noWarning if true, don't display any warning if the module is not found.
79 	StelModule* getModule(const QString& moduleID, bool noWarning=false) const;
80 
81 	//! Get the list of all the currently registered modules
getAllModules() const82 	QList<StelModule*> getAllModules() const {return modules.values();}
83 
84 	//! Get the list of modules in the correct order for calling the given action
getCallOrders(StelModule::StelModuleActionName action)85 	const QList<StelModule*>& getCallOrders(StelModule::StelModuleActionName action)
86 	{
87 		return callOrders[action];
88 	}
89 
90 	//! Contains the information read from the module.ini file
91 	struct PluginDescriptor
92 	{
PluginDescriptorStelModuleMgr::PluginDescriptor93 		PluginDescriptor() : loadAtStartup(false), loaded(false), pluginInterface(Q_NULLPTR) {;}
94 		//! The static info for the plugin.
95 		StelPluginInfo info;
96 		//! If true, the module is automatically loaded at startup
97 		bool loadAtStartup;
98 		//! True if the plugin is currently loaded.
99 		bool loaded;
100 
101 	private:
102 		friend class StelModuleMgr;
103 		StelPluginInterface* pluginInterface;
104 	};
105 
106 	//! Return the list of all the external module found in the modules directories
107 	QList<PluginDescriptor> getPluginsList();
108 
109 	//! Returns the list of all currently registered extensions.
110 	//! If using this method, you probably also want to subscribe to
111 	//! the extensionsAdded() signal to handle all possible initialization orders.
getExtensionList() const112 	QObjectList getExtensionList() const { return extensions; }
113 signals:
114 	//! Called whenever new plugin extensions are added
115 	void extensionsAdded(QObjectList newExtensions);
116 
117 private:
118 	//! Generate properly sorted calling lists for each action (e,g, draw, update)
119 	//! according to modules orders dependencies
120 	void generateCallingLists();
121 
122 	//! The main module list associating name:pointer
123 	QMap<QString, StelModule*> modules;
124 
125 	//! All currently known extensions
126 	QObjectList extensions;
127 
128 	//! The list of all module in the correct order for each action
129 	QMap<StelModule::StelModuleActionName, QList<StelModule*> > callOrders;
130 
131 	//! True if modules were removed, and therefore the calling list need to be regenerated
132 	bool callingListsToRegenerate;
133 
134 	QMap<QString, StelModuleMgr::PluginDescriptor> pluginDescriptorList;
135 	bool pluginDescriptorListLoaded;
136 };
137 
138 #endif // STELMODULEMGR_HPP
139