Skip to content

Commit

Permalink
#6022: Change IFavouritesManager interface - moving away from accepti…
Browse files Browse the repository at this point in the history
…ng decl::Type enumerations, the interface now operates on type name strings.

Adjust implementation, adjust and extend unit tests.
  • Loading branch information
codereader committed Jul 23, 2022
1 parent e106b55 commit 500f838
Show file tree
Hide file tree
Showing 17 changed files with 330 additions and 222 deletions.
23 changes: 11 additions & 12 deletions include/idecltypes.h
Expand Up @@ -2,7 +2,6 @@

#include <stdexcept>
#include <string>
#include "i18n.h"

// Some X11 headers are defining this
#ifdef None
Expand Down Expand Up @@ -35,17 +34,17 @@ inline std::string getTypeName(Type type)
{
switch (type)
{
case Type::Undetermined: return _("Undetermined");
case Type::None: return _("None");
case Type::Material: return _("Material");
case Type::EntityDef: return _("EntityDef");
case Type::SoundShader: return _("SoundShader");
case Type::Model: return _("Model");
case Type::ModelDef: return _("ModelDef");
case Type::Particle: return _("Particle");
case Type::Skin: return _("Skin");
case Type::TestDecl: return _("TestDecl");
case Type::TestDecl2: return _("TestDecl2");
case Type::Undetermined: return "Undetermined";
case Type::None: return "None";
case Type::Material: return "Material";
case Type::EntityDef: return "EntityDef";
case Type::SoundShader: return "SoundShader";
case Type::Model: return "Model";
case Type::ModelDef: return "ModelDef";
case Type::Particle: return "Particle";
case Type::Skin: return "Skin";
case Type::TestDecl: return "TestDecl";
case Type::TestDecl2: return "TestDecl2";
default:
throw std::runtime_error("Unhandled decl type");
}
Expand Down
45 changes: 30 additions & 15 deletions include/ifavourites.h
Expand Up @@ -3,41 +3,56 @@
#include <set>
#include <sigc++/signal.h>
#include "imodule.h"
#include "idecltypes.h"

namespace decl
namespace game
{

/**
* Favourite Management interface keeping track of resources
* that have been tagged as favourite by the user.
*
* Each favourite obejct has a typename and a (unique) identifier.
* The typename is treated case-insensitively - it is used as tag identifier
* when persisting the set, therefore it must consist of word characters only.
*/
class IFavouritesManager :
public RegisterableModule
{
public:
virtual ~IFavouritesManager() {}

// Adds the given declaration (as identified by the given path) to
// the set of favourites
virtual void addFavourite(decl::Type type, const std::string& path) = 0;
/**
* Adds the given favourite object to the set of favourites
*
* @typeName: Type name of the favourite, like "prefab" or "material"
* Favourites with the same type name are grouped.
*
* @identifier: The identifier of this favourite object,
* like a file path or a declaration name
*/
virtual void addFavourite(const std::string& typeName, const std::string& identifier) = 0;

// Removes the given declaration from the favourites set
virtual void removeFavourite(decl::Type type, const std::string& path) = 0;
// Removes the favourite with the given type and identifier from the set of favourites
virtual void removeFavourite(const std::string& typeName, const std::string& identifier) = 0;

// Returns true if the given declaration is listed as favourite
virtual bool isFavourite(decl::Type type, const std::string& path) = 0;
// Returns true if the given type/name combination is listed as favourite
virtual bool isFavourite(const std::string& typeName, const std::string& identifier) = 0;

// Returns the whole set of favourites for the given declaration type
virtual std::set<std::string> getFavourites(decl::Type type) = 0;
// Returns the whole set of favourites for the given type name
virtual std::set<std::string> getFavourites(const std::string& typeName) = 0;

// Returns the changed signal for the given type - will be fired when the set changes
virtual sigc::signal<void>& getSignalForType(decl::Type type) = 0;
// Requesting a signal for an empty typename will trigger a std::invalid_argument exception
virtual sigc::signal<void>& getSignalForType(const std::string& typeName) = 0;
};

}

const char* const MODULE_FAVOURITES_MANAGER("FavouritesManager");
constexpr const char* const MODULE_FAVOURITES_MANAGER("FavouritesManager");

inline decl::IFavouritesManager& GlobalFavouritesManager()
inline game::IFavouritesManager& GlobalFavouritesManager()
{
static module::InstanceReference<decl::IFavouritesManager> _reference(MODULE_FAVOURITES_MANAGER);
static module::InstanceReference<game::IFavouritesManager> _reference(MODULE_FAVOURITES_MANAGER);
return _reference;
}

2 changes: 1 addition & 1 deletion libs/wxutil/EntityClassChooser.cpp
Expand Up @@ -90,7 +90,7 @@ class EntityClassTreePopulator:
_entityIcon.CopyFromBitmap(wxutil::GetLocalBitmap(ENTITY_ICON));

// Get the list of favourite eclasses
_favourites = GlobalFavouritesManager().getFavourites(decl::Type::EntityDef);
_favourites = GlobalFavouritesManager().getFavourites(decl::getTypeName(decl::Type::EntityDef));
}

// EntityClassVisitor implementation
Expand Down
4 changes: 2 additions & 2 deletions libs/wxutil/dataview/ResourceTreeView.cpp
Expand Up @@ -513,11 +513,11 @@ void ResourceTreeView::SetFavouriteRecursively(TreeModel::Row& row, bool isFavou
// Keep track of this choice
if (isFavourite)
{
GlobalFavouritesManager().addFavourite(_declType, row[_columns.fullName]);
GlobalFavouritesManager().addFavourite(decl::getTypeName(_declType), row[_columns.fullName]);
}
else
{
GlobalFavouritesManager().removeFavourite(_declType, row[_columns.fullName]);
GlobalFavouritesManager().removeFavourite(decl::getTypeName(_declType), row[_columns.fullName]);
}

row.SendItemChanged();
Expand Down
2 changes: 1 addition & 1 deletion radiant/ui/common/SoundChooser.cpp
Expand Up @@ -65,7 +65,7 @@ class SoundShaderPopulator :
_folderIcon.CopyFromBitmap(wxutil::GetLocalBitmap(FOLDER_ICON));

// Get the list of favourites
_favourites = GlobalFavouritesManager().getFavourites(decl::Type::SoundShader);
_favourites = GlobalFavouritesManager().getFavourites(decl::getTypeName(decl::Type::SoundShader));
}

// Invoked for each sound shader
Expand Down
44 changes: 22 additions & 22 deletions radiant/ui/favourites/FavouritesBrowser.cpp
Expand Up @@ -118,30 +118,30 @@ void FavouritesBrowser::constructPopupMenu()
void FavouritesBrowser::setupCategories()
{
_categories.emplace_back(FavouriteCategory{
decl::Type::Material, _("Materials"), "icon_texture.png",
decl::getTypeName(decl::Type::Material), _("Materials"), "icon_texture.png",
_iconList->Add(wxutil::GetLocalBitmap("icon_texture.png")),
nullptr
});
_categories.emplace_back(FavouriteCategory{
decl::Type::Model, _("Models"), "model16green.png",
"model", _("Models"), "model16green.png",
_iconList->Add(wxutil::GetLocalBitmap("icon_model.png")),
nullptr
});
_categories.emplace_back(FavouriteCategory{
decl::Type::EntityDef, _("EntityDefs"), "cmenu_add_entity.png",
decl::getTypeName(decl::Type::EntityDef), _("EntityDefs"), "cmenu_add_entity.png",
_iconList->Add(wxutil::GetLocalBitmap("cmenu_add_entity.png")),
nullptr
});
_categories.emplace_back(FavouriteCategory{
decl::Type::SoundShader, _("Sound Shaders"), "icon_sound.png",
decl::getTypeName(decl::Type::SoundShader), _("Sound Shaders"), "icon_sound.png",
_iconList->Add(wxutil::GetLocalBitmap("icon_sound.png")),
nullptr
});

// Subscribe to any favourite changes
for (auto& category : _categories)
{
changedConnections.emplace_back(GlobalFavouritesManager().getSignalForType(category.type).connect(
changedConnections.emplace_back(GlobalFavouritesManager().getSignalForType(category.typeName).connect(
sigc::mem_fun(this, &FavouritesBrowser::onFavouritesChanged)
));
}
Expand Down Expand Up @@ -195,7 +195,7 @@ void FavouritesBrowser::reloadFavourites()
continue;
}

auto favourites = GlobalFavouritesManager().getFavourites(category.type);
auto favourites = GlobalFavouritesManager().getFavourites(category.typeName);

for (const auto& fav : favourites)
{
Expand All @@ -206,7 +206,7 @@ void FavouritesBrowser::reloadFavourites()
auto index = _listView->InsertItem(_listView->GetItemCount(), displayName, category.iconIndex);

// Keep the item info locally, store a pointer to it in the list item user data
_listItems.emplace_back(FavouriteItem{ category.type, fav, leafName });
_listItems.emplace_back(FavouriteItem{ category.typeName, fav, leafName });
_listView->SetItemPtrData(index, reinterpret_cast<wxUIntPtr>(&(_listItems.back())));
}
}
Expand Down Expand Up @@ -250,15 +250,16 @@ void FavouritesBrowser::onItemActivated(wxListEvent& ev)

auto* data = reinterpret_cast<FavouriteItem*>(_listView->GetItemData(selection.front()));

switch (data->type)
if (data->typeName == decl::getTypeName(decl::Type::Material))
{
case decl::Type::Material:
onApplyTextureToSelection();
break;
case decl::Type::EntityDef:
}
else if (data->typeName == decl::getTypeName(decl::Type::EntityDef))
{
onCreateEntity();
break;
case decl::Type::SoundShader:
}
else if (data->typeName == decl::getTypeName(decl::Type::SoundShader))
{
if (testCreateSpeaker())
{
onCreateSpeaker();
Expand All @@ -267,7 +268,6 @@ void FavouritesBrowser::onItemActivated(wxListEvent& ev)
{
onApplySoundToSelection();
}
break;
}
}

Expand All @@ -287,14 +287,14 @@ std::vector<long> FavouritesBrowser::getSelectedItems()
return list;
}

decl::Type FavouritesBrowser::getSelectedDeclType()
std::string FavouritesBrowser::getSelectedTypeName()
{
auto selection = getSelectedItems();

if (selection.size() != 1) return decl::Type::None;
if (selection.size() != 1) return "";

auto* data = reinterpret_cast<FavouriteItem*>(_listView->GetItemData(selection.front()));
return data->type;
return data->typeName;
}

void FavouritesBrowser::onRemoveFromFavourite()
Expand All @@ -304,7 +304,7 @@ void FavouritesBrowser::onRemoveFromFavourite()
for (auto itemIndex : selection)
{
auto* data = reinterpret_cast<FavouriteItem*>(_listView->GetItemData(itemIndex));
GlobalFavouritesManager().removeFavourite(data->type, data->fullPath);
GlobalFavouritesManager().removeFavourite(data->typeName, data->fullPath);
}

// A repopulation has already been rescheduled
Expand All @@ -323,7 +323,7 @@ void FavouritesBrowser::onApplyTextureToSelection()

bool FavouritesBrowser::testSingleTextureSelected()
{
return getSelectedDeclType() == decl::Type::Material;
return getSelectedTypeName() == decl::getTypeName(decl::Type::Material);
}

void FavouritesBrowser::onApplySoundToSelection()
Expand All @@ -346,7 +346,7 @@ bool FavouritesBrowser::testApplySoundToSelection()
{
const SelectionInfo& info = GlobalSelectionSystem().getSelectionInfo();

return info.entityCount > 0 && getSelectedDeclType() == decl::Type::SoundShader;
return info.entityCount > 0 && getSelectedTypeName() == decl::getTypeName(decl::Type::SoundShader);
}

void FavouritesBrowser::onCreateEntity()
Expand Down Expand Up @@ -375,7 +375,7 @@ void FavouritesBrowser::onCreateEntity()

bool FavouritesBrowser::testCreateEntity()
{
if (getSelectedDeclType() != decl::Type::EntityDef)
if (getSelectedTypeName() != decl::getTypeName(decl::Type::EntityDef))
{
return false;
}
Expand Down Expand Up @@ -412,7 +412,7 @@ void FavouritesBrowser::onCreateSpeaker()

bool FavouritesBrowser::testCreateSpeaker()
{
if (getSelectedDeclType() != decl::Type::SoundShader)
if (getSelectedTypeName() != decl::getTypeName(decl::Type::SoundShader))
{
return false;
}
Expand Down
6 changes: 3 additions & 3 deletions radiant/ui/favourites/FavouritesBrowser.h
Expand Up @@ -23,7 +23,7 @@ class FavouritesBrowser :
// Holds the data used to construct the wxListItem
struct FavouriteItem
{
decl::Type type;
std::string typeName;
std::string fullPath;
std::string leafName;
};
Expand All @@ -34,7 +34,7 @@ class FavouritesBrowser :

struct FavouriteCategory
{
decl::Type type;
std::string typeName;
std::string displayName;
std::string iconName;
int iconIndex;
Expand Down Expand Up @@ -74,7 +74,7 @@ class FavouritesBrowser :

// Returns the list of all selected item indices
std::vector<long> getSelectedItems();
decl::Type getSelectedDeclType();
std::string getSelectedTypeName();

void onApplyTextureToSelection();
bool testSingleTextureSelected();
Expand Down
2 changes: 1 addition & 1 deletion radiant/ui/materials/MaterialPopulator.cpp
Expand Up @@ -150,7 +150,7 @@ MaterialPopulator::MaterialPopulator(const MaterialTreeView::TreeColumns& column
ThreadedResourceTreePopulator(columns),
_columns(columns)
{
_favourites = GlobalFavouritesManager().getFavourites(decl::Type::Material);
_favourites = GlobalFavouritesManager().getFavourites(decl::getTypeName(decl::Type::Material));
}

MaterialPopulator::~MaterialPopulator()
Expand Down
2 changes: 1 addition & 1 deletion radiant/ui/modelselector/ModelDataInserter.h
Expand Up @@ -50,7 +50,7 @@ class ModelDataInserter :
_skinIcon.CopyFromBitmap(wxutil::GetLocalBitmap(SKIN_ICON));

// Get the list of favourites
_favourites = GlobalFavouritesManager().getFavourites(decl::Type::Model);
_favourites = GlobalFavouritesManager().getFavourites("model");
}

virtual ~ModelDataInserter() {}
Expand Down
2 changes: 1 addition & 1 deletion radiant/ui/particles/ThreadedParticlesLoader.h
Expand Up @@ -29,7 +29,7 @@ class ThreadedParticlesLoader final :
_columns(columns)
{
// Get the list of favourites
_favourites = GlobalFavouritesManager().getFavourites(decl::Type::Particle);
_favourites = GlobalFavouritesManager().getFavourites(decl::getTypeName(decl::Type::Particle));
}

~ThreadedParticlesLoader()
Expand Down
4 changes: 2 additions & 2 deletions radiant/ui/texturebrowser/TextureBrowser.cpp
Expand Up @@ -354,7 +354,7 @@ TextureBrowser::TextureBrowser(wxWindow* parent) :

updateScroll();

GlobalFavouritesManager().getSignalForType(decl::Type::Material).connect(
GlobalFavouritesManager().getSignalForType(decl::getTypeName(decl::Type::Material)).connect(
sigc::mem_fun(this, &TextureBrowser::onFavouritesChanged));
}

Expand Down Expand Up @@ -690,7 +690,7 @@ void TextureBrowser::performUpdate()
CurrentPosition layout;
_entireSpaceHeight = 0;
// Update the favourites
_favourites = GlobalFavouritesManager().getFavourites(decl::Type::Material);
_favourites = GlobalFavouritesManager().getFavourites(decl::getTypeName(decl::Type::Material));

GlobalMaterialManager().foreachMaterial([&](const MaterialPtr& mat)
{
Expand Down

0 comments on commit 500f838

Please sign in to comment.