Skip to content

Commit

Permalink
#5231: Decouple CounterManager from the corresponding statusbar eleme…
Browse files Browse the repository at this point in the history
…nt handling
  • Loading branch information
codereader committed May 25, 2020
1 parent 194f0a3 commit f9b0ce8
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 111 deletions.
20 changes: 6 additions & 14 deletions include/icounter.h
@@ -1,19 +1,11 @@
#ifndef ICOUNTER_H_
#define ICOUNTER_H_
#pragma once

#include <cstddef>
#include "imodule.h"

class ICounter {
class ICounter
{
public:
class Observer
{
public:
virtual ~Observer() {}
// Gets called by the Counter class on count change
virtual void countChanged() = 0;
};

/** Destructor */
virtual ~ICounter() {}

Expand All @@ -35,7 +27,7 @@ enum CounterType
counterEntities,
};

const std::string MODULE_COUNTER("Counters");
const char* const MODULE_COUNTER("Counters");

/** greebo: This abstract class defines the interface to the core application.
* Use this to access methods from the main codebase in radiant/
Expand All @@ -46,6 +38,8 @@ class ICounterManager :
public:
// Returns the Counter object of the given type
virtual ICounter& getCounter(CounterType counter) = 0;

virtual sigc::signal<void>& signal_countersChanged() = 0;
};

inline ICounterManager& GlobalCounters()
Expand All @@ -58,5 +52,3 @@ inline ICounterManager& GlobalCounters()
);
return _counters;
}

#endif /*ICOUNTER_H_*/
89 changes: 37 additions & 52 deletions radiant/map/CounterManager.cpp
@@ -1,36 +1,60 @@
#include "CounterManager.h"

#include "i18n.h"
#include "iuimanager.h"
#include "selectionlib.h"
#include "string/string.h"
#include "module/StaticModule.h"

#include <fmt/format.h>

namespace map
{

Counter::Counter(CounterManager& owner) :
_owner(owner),
_count(0)
{}

void Counter::increment()
{
++_count;

_owner.onCounterChanged();
}

void Counter::decrement()
{
--_count;

_owner.onCounterChanged();
}

std::size_t Counter::get() const
{
return _count;
}

CounterManager::CounterManager()
{
// Create the counter objects
_counters[counterBrushes] = CounterPtr(new Counter(this));
_counters[counterPatches] = CounterPtr(new Counter(this));
_counters[counterEntities] = CounterPtr(new Counter(this));
_counters[counterBrushes] = std::make_shared<Counter>(*this);
_counters[counterPatches] = std::make_shared<Counter>(*this);
_counters[counterEntities] = std::make_shared<Counter>(*this);
}

ICounter& CounterManager::getCounter(CounterType counter)
{
if (_counters.find(counter) == _counters.end()) {
if (_counters.find(counter) == _counters.end())
{
throw std::runtime_error("Counter ID not found.");
}

return *_counters[counter];
}

void CounterManager::countChanged()
sigc::signal<void>& CounterManager::signal_countersChanged()
{
return _signalCountersChanged;
}

void CounterManager::onCounterChanged()
{
// Don't immediately update the counter text, this is low priority stuff
requestIdleCallback();
_signalCountersChanged.emit();
}

// RegisterableModule implementation
Expand All @@ -43,50 +67,11 @@ const std::string& CounterManager::getName() const
const StringSet& CounterManager::getDependencies() const
{
static StringSet _dependencies;

if (_dependencies.empty())
{
_dependencies.insert(MODULE_UIMANAGER);
_dependencies.insert(MODULE_SELECTIONSYSTEM);
}

return _dependencies;
}

void CounterManager::initialiseModule(const ApplicationContext& ctx)
{
// Add the statusbar command text item
GlobalUIManager().getStatusBarManager().addTextElement(
"MapCounters",
"", // no icon
IStatusBarManager::POS_BRUSHCOUNT,
_("Number of brushes/patches/entities in this map\n(Number of selected items shown in parentheses)")
);

_selectionChangedConn = GlobalSelectionSystem().signal_selectionChanged().connect(
[this] (const ISelectable&) { requestIdleCallback(); }
);
}

void CounterManager::shutdownModule()
{
_selectionChangedConn.disconnect();
}

void CounterManager::onIdle()
{
const SelectionInfo& info = GlobalSelectionSystem().getSelectionInfo();

std::string text =
fmt::format(_("Brushes: {0:d} ({1:d}) Patches: {2:d} ({3:d}) Entities: {4:d} ({5:d})"),
_counters[counterBrushes]->get(),
info.brushCount,
_counters[counterPatches]->get(),
info.patchCount,
_counters[counterEntities]->get(),
info.entityCount);

GlobalUIManager().getStatusBarManager().setText("MapCounters", text);
}

// Register the counter module in the registry
Expand Down
55 changes: 18 additions & 37 deletions radiant/map/CounterManager.h
@@ -1,59 +1,43 @@
#pragma once

#include "icounter.h"
#include "iuimanager.h"
#include "wxutil/event/SingleIdleCallback.h"

#include <sigc++/connection.h>
#include <map>
#include <memory>

namespace map {
namespace map
{

class CounterManager;

class Counter :
public ICounter
{
Observer* _observer;
private:
CounterManager& _owner;
std::size_t _count;

public:
Counter(Observer* observer = NULL) :
_observer(observer),
_count(0)
{}
Counter(CounterManager& owner);

virtual ~Counter() {}

void increment() {
++_count;

if (_observer != NULL) {
_observer->countChanged();
}
}

void decrement() {
--_count;

if (_observer != NULL) {
_observer->countChanged();
}
}

std::size_t get() const {
return _count;
}
void increment() override;
void decrement() override;

std::size_t get() const override;
};
typedef std::shared_ptr<Counter> CounterPtr;

class CounterManager :
public ICounterManager,
public ICounter::Observer,
protected wxutil::SingleIdleCallback
public ICounterManager
{
private:
typedef std::map<CounterType, CounterPtr> CounterMap;
CounterMap _counters;

sigc::connection _selectionChangedConn;
sigc::signal<void> _signalCountersChanged;

public:
CounterManager();
Expand All @@ -62,16 +46,13 @@ class CounterManager :

ICounter& getCounter(CounterType counter) override;

// ICounter::Observer implementation
void countChanged() override;
sigc::signal<void>& signal_countersChanged() override;

void onCounterChanged();

const std::string& getName() const override;
const StringSet& getDependencies() const override;
void initialiseModule(const ApplicationContext& ctx) override;
void shutdownModule() override;

protected:
void onIdle() override;
};

} // namespace map
58 changes: 54 additions & 4 deletions radiant/uimanager/UIManager.cpp
Expand Up @@ -5,6 +5,7 @@
#include "itextstream.h"
#include "iregistry.h"
#include "iradiant.h"
#include "icounter.h"
#include "imainframe.h"
#include "icommandsystem.h"
#include "ieventmanager.h"
Expand All @@ -13,6 +14,7 @@
#include "debugging/debugging.h"
#include "ui/filters/FilterMenu.h"
#include "wxutil/dialog/MessageBox.h"
#include "selectionlib.h"

#include "animationpreview/MD5AnimationViewer.h"
#include "LocalBitmapArtProvider.h"
Expand Down Expand Up @@ -71,7 +73,8 @@ const std::string& UIManager::ArtIdPrefix() const
return LocalBitmapArtProvider::ArtIdPrefix();
}

const std::string& UIManager::getName() const {
const std::string& UIManager::getName() const
{
static std::string _name(MODULE_UIMANAGER);
return _name;
}
Expand All @@ -80,29 +83,34 @@ const StringSet& UIManager::getDependencies() const
{
static StringSet _dependencies;

if (_dependencies.empty()) {
if (_dependencies.empty())
{
_dependencies.insert(MODULE_EVENTMANAGER);
_dependencies.insert(MODULE_XMLREGISTRY);
_dependencies.insert(MODULE_RADIANT_APP);
_dependencies.insert(MODULE_SELECTIONSYSTEM);
_dependencies.insert(MODULE_COMMANDSYSTEM);
_dependencies.insert(MODULE_COUNTER);
}

return _dependencies;
}

void UIManager::initialiseModule(const ApplicationContext& ctx)
{
rMessage() << "UIManager::initialiseModule called" << std::endl;
rMessage() << getName() << "::initialiseModule called" << std::endl;

_bitmapArtProvider = new LocalBitmapArtProvider();
wxArtProvider::Push(_bitmapArtProvider);

_dialogManager = DialogManagerPtr(new DialogManager);
_dialogManager = std::make_shared<DialogManager>();

_menuManager = std::make_shared<MenuManager>();
_menuManager->loadFromRegistry();

_toolbarManager = std::make_shared<ToolbarManager>();
_toolbarManager->initialise();

ColourSchemeManager::Instance().loadColourSchemes();

GlobalCommandSystem().addCommand("AnimationPreview", MD5AnimationViewer::Show);
Expand All @@ -121,18 +129,60 @@ void UIManager::initialiseModule(const ApplicationContext& ctx)
_("Describes available Mouse Commands")
);

// Add the counter element
GlobalUIManager().getStatusBarManager().addTextElement(
"MapCounters",
"", // no icon
IStatusBarManager::POS_BRUSHCOUNT,
_("Number of brushes/patches/entities in this map\n(Number of selected items shown in parentheses)")
);

wxFileSystem::AddHandler(new wxLocalFSHandler);
wxXmlResource::Get()->InitAllHandlers();

std::string fullPath = ctx.getRuntimeDataPath() + "ui/";
wxXmlResource::Get()->Load(fullPath + "*.xrc");

_selectionChangedConn = GlobalSelectionSystem().signal_selectionChanged().connect(
[this](const ISelectable&) { requestIdleCallback(); }
);

_countersChangedConn = GlobalCounters().signal_countersChanged().connect(
[this]() { requestIdleCallback(); }
);

updateCounterStatusBar();
}

void UIManager::shutdownModule()
{
_countersChangedConn.disconnect();
_selectionChangedConn.disconnect();
_menuManager->clear();
}

void UIManager::onIdle()
{
updateCounterStatusBar();
}

void UIManager::updateCounterStatusBar()
{
const SelectionInfo& info = GlobalSelectionSystem().getSelectionInfo();
auto& counterMgr = GlobalCounters();

std::string text =
fmt::format(_("Brushes: {0:d} ({1:d}) Patches: {2:d} ({3:d}) Entities: {4:d} ({5:d})"),
counterMgr.getCounter(counterBrushes).get(),
info.brushCount,
counterMgr.getCounter(counterPatches).get(),
info.patchCount,
counterMgr.getCounter(counterEntities).get(),
info.entityCount);

GlobalUIManager().getStatusBarManager().setText("MapCounters", text);
}

module::StaticModule<UIManager> uiManagerModule;

} // namespace ui

0 comments on commit f9b0ce8

Please sign in to comment.