1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
#include "FavouritesManager.h"
#include "iregistry.h"
#include "idecltypes.h"
#include "module/StaticModule.h"
namespace game
{
namespace
{
constexpr const char* const RKEY_MEDIABROWSER_LEGACY_ROOT = "user/ui/mediaBrowser/favourites";
constexpr const char* const RKEY_FAVOURITES_ROOT = "user/ui/favourites";
constexpr const char* const RKEY_LEGACY_SUBPATH_MATERIALS = "/materials";
constexpr const char* const RKEY_LEGACY_SUBPATH_ENTITYDEFS = "/entityDefs";
constexpr const char* const RKEY_LEGACY_SUBPATH_SOUNDSHADERS = "/soundShaders";
constexpr const char* const RKEY_LEGACY_SUBPATH_MODELS = "/models";
constexpr const char* const RKEY_LEGACY_SUBPATH_PARTICLES = "/particles";
}
void FavouritesManager::addFavourite(const std::string& typeName, const std::string& identifier)
{
if (typeName.empty() || identifier.empty()) return;
auto set = _favouritesByType.find(typeName);
if (set == _favouritesByType.end())
{
set = _favouritesByType.emplace(typeName, FavouriteSet(typeName)).first;
}
if (set->second.get().emplace(identifier).second)
{
// Fire signal only when something got added
set->second.signal_setChanged().emit();
}
}
void FavouritesManager::removeFavourite(const std::string& typeName, const std::string& identifier)
{
if (typeName.empty() || identifier.empty()) return;
auto set = _favouritesByType.find(typeName);
if (set == _favouritesByType.end())
{
return;
}
if (set->second.get().erase(identifier) > 0)
{
// Fire signal only when something got removed
set->second.signal_setChanged().emit();
}
}
bool FavouritesManager::isFavourite(const std::string& typeName, const std::string& identifier)
{
if (typeName.empty() || identifier.empty()) return false;
auto set = _favouritesByType.find(typeName);
return set != _favouritesByType.end() ? set->second.get().count(identifier) > 0 : false;
}
std::set<std::string> FavouritesManager::getFavourites(const std::string& typeName)
{
if (typeName.empty())
{
return std::set<std::string>();
}
auto set = _favouritesByType.find(typeName);
return set != _favouritesByType.end() ? set->second.get() : std::set<std::string>();
}
sigc::signal<void>& FavouritesManager::getSignalForType(const std::string& typeName)
{
if (typeName.empty())
{
throw std::invalid_argument("No signal for empty typenames");
}
auto set = _favouritesByType.find(typeName);
if (set == _favouritesByType.end())
{
set = _favouritesByType.emplace(typeName, FavouriteSet(typeName)).first;
}
return set->second.signal_setChanged();
}
const std::string& FavouritesManager::getName() const
{
static std::string _name(MODULE_FAVOURITES_MANAGER);
return _name;
}
const StringSet& FavouritesManager::getDependencies() const
{
static StringSet _dependencies;
if (_dependencies.empty())
{
_dependencies.emplace(MODULE_XMLREGISTRY);
}
return _dependencies;
}
void FavouritesManager::initialiseModule(const IApplicationContext&)
{
// Up to version 2.10.0, the MediaBrowser favourites were stored in this path
importLegacySet(RKEY_MEDIABROWSER_LEGACY_ROOT, decl::getTypeName(decl::Type::Material));
// Load from the legacy paths (pre-3.1.0)
std::string root = RKEY_FAVOURITES_ROOT;
importLegacySet(root + RKEY_LEGACY_SUBPATH_MATERIALS, decl::getTypeName(decl::Type::Material));
importLegacySet(root + RKEY_LEGACY_SUBPATH_ENTITYDEFS, decl::getTypeName(decl::Type::EntityDef));
importLegacySet(root + RKEY_LEGACY_SUBPATH_SOUNDSHADERS, decl::getTypeName(decl::Type::SoundShader));
importLegacySet(root + RKEY_LEGACY_SUBPATH_PARTICLES, decl::getTypeName(decl::Type::Particle));
importLegacySet(root + RKEY_LEGACY_SUBPATH_MODELS, "model");
// Load the rest of the types from the remaining regular paths
auto nodes = GlobalRegistry().findXPath(root + "/*");
for (const auto& node : nodes)
{
auto typeName = node.getName();
if (typeName.empty()) continue;
// Ensure a set with that typename exists
auto set = _favouritesByType.find(typeName);
if (set == _favouritesByType.end())
{
set = _favouritesByType.emplace(typeName, FavouriteSet(typeName)).first;
}
// Append all favourites in that node to the set
set->second.loadFromRegistry(root);
}
}
void FavouritesManager::importLegacySet(const std::string& path, const std::string& targetTypeName)
{
auto oldSet = FavouriteSet(); // untyped set to be able to use the raw path
oldSet.loadFromRegistry(path);
for (const auto& identifier : oldSet.get())
{
addFavourite(targetTypeName, identifier);
}
GlobalRegistry().deleteXPath(path);
}
void FavouritesManager::shutdownModule()
{
std::string root = RKEY_FAVOURITES_ROOT;
GlobalRegistry().deleteXPath(RKEY_FAVOURITES_ROOT);
// Save favourites to registry
for (const auto& [_, set] :_favouritesByType)
{
set.saveToRegistry(root);
}
// Clear observers
for (auto& pair : _favouritesByType)
{
pair.second.signal_setChanged().clear();
}
}
module::StaticModuleRegistration<FavouritesManager> favouritesManagerModule;
}
|