1 // -*- coding: utf-8 -*- 2 // 3 // AddonManager.hxx --- Manager class for FlightGear add-ons 4 // Copyright (C) 2017 Florent Rougon 5 // 6 // This program is free software; you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation; either version 2 of the License, or 9 // (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License along 17 // with this program; if not, write to the Free Software Foundation, Inc., 18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 20 #ifndef FG_ADDONMANAGER_HXX 21 #define FG_ADDONMANAGER_HXX 22 23 #include <string> 24 #include <map> 25 #include <memory> // std::unique_ptr, std::shared_ptr 26 #include <vector> 27 28 #include <simgear/misc/sg_path.hxx> 29 #include <simgear/props/props.hxx> 30 31 #include "addon_fwd.hxx" 32 #include "Addon.hxx" 33 #include "AddonVersion.hxx" 34 35 namespace flightgear 36 { 37 38 namespace addons 39 { 40 41 class AddonManager 42 { 43 public: 44 AddonManager(const AddonManager&) = delete; 45 AddonManager& operator=(const AddonManager&) = delete; 46 AddonManager(AddonManager&&) = delete; 47 AddonManager& operator=(AddonManager&&) = delete; 48 // The instance is created by createInstance() -> private constructor 49 // but it should be deleted by its owning std::unique_ptr -> public destructor 50 ~AddonManager() = default; 51 52 // Static creator 53 static const std::unique_ptr<AddonManager>& createInstance(); 54 // Singleton accessor 55 static const std::unique_ptr<AddonManager>& instance(); 56 // Reset the static smart pointer, i.e., shut down the AddonManager. 57 static void reset(); 58 59 // Register an add-on and return its id. 60 // 'addonPath': directory containing the add-on to register 61 // 62 // This comprises the following steps, where $path = addonPath.realpath(): 63 // - load add-on metadata from $path/addon-metadata.xml and register it 64 // inside _idToAddonMap (this step is done via registerAddonMetadata()); 65 // - load $path/addon-config.xml into the Property Tree; 66 // - append $path to the list of aircraft paths; 67 // - make part of the add-on metadata available in the Property Tree under 68 // the /addons node (/addons/by-id/<addonId>/{id,version,path,...}); 69 // - append a ref to the Addon instance to _registeredAddons. 70 std::string registerAddon(const SGPath& addonPath); 71 // Return the list of registered add-ons in registration order (which, BTW, 72 // is the same as load order). 73 std::vector<AddonRef> registeredAddons() const; 74 bool isAddonRegistered(const std::string& addonId) const; 75 76 // A loaded add-on is one whose addon-main.nas file has been loaded. The 77 // returned vector is sorted by add-on id (cheap sorting based on UTF-8 code 78 // units, only guaranteed correct for ASCII chars). 79 std::vector<AddonRef> loadedAddons() const; 80 bool isAddonLoaded(const std::string& addonId) const; 81 82 AddonRef getAddon(const std::string& addonId) const; 83 AddonVersionRef addonVersion(const std::string& addonId) const; 84 SGPath addonBasePath(const std::string& addonId) const; 85 86 // Base node pertaining to the add-on in the Global Property Tree 87 SGPropertyNode_ptr addonNode(const std::string& addonId) const; 88 89 // Add the 'menu' nodes defined by each registered add-on to 90 // /sim/menubar/default 91 void addAddonMenusToFGMenubar() const; 92 93 private: 94 // Constructor called from createInstance() only 95 explicit AddonManager() = default; 96 97 static void loadConfigFileIfExists(const SGPath& configFile); 98 // Register add-on metadata inside _idToAddonMap and return the add-on id 99 std::string registerAddonMetadata(const SGPath& addonPath); 100 101 // Map each add-on id to the corresponding Addon instance. 102 std::map<std::string, AddonRef> _idToAddonMap; 103 // The order in _registeredAddons is the registration order. 104 std::vector<AddonRef> _registeredAddons; 105 // 0 for the first loaded add-on, 1 for the second, etc. 106 // Also note that add-ons are loaded in their registration order. 107 int _loadSequenceNumber = 0; 108 }; 109 110 } // of namespace addons 111 112 } // of namespace flightgear 113 114 #endif // of FG_ADDONMANAGER_HXX 115