Implement unique name generation for peripherals
MODIFY
src/io/iobase.cpp
src/io/iobase.cpp
namespace Ripes {
-std::map<std::type_index, int> IOBase::s_peripheralCount;
+std::map<unsigned, std::set<unsigned>> IOBase::s_peripheralIDs;
-IOBase::IOBase(QWidget* parent) : QWidget(parent) {
- incrementPeriphCounter(this);
+IOBase::IOBase(unsigned IOType, QWidget* parent) : QWidget(parent), m_type(IOType) {
+ m_id = claimPeripheralId(m_type);
connect(this, &IOBase::scheduleUpdate, this, QOverload<>::of(&QWidget::update));
}
+QString IOBase::cName() const {
+ QString cname = name();
+ for (const auto& ch : {' ', '-'}) {
+ cname.replace(ch, "_");
+ }
+ return cname.toUpper();
+}
+
+QString IOBase::name() const {
+ return baseName() + " " + QString::number(m_id);
+}
+
bool IOBase::setParameter(unsigned ID, const QVariant& value) {
const auto preSize = size();
m_parameters.at(ID).value = value;

MODIFY
src/io/iobase.h
src/io/iobase.h
#include <QVariant>
#include <QWidget>
-#include <typeindex>
-#include <typeinfo>
+#include <set>
#include "binutils.h"
@@ -37,15 +36,32 @@ class IOBase : public QWidget {
Q_OBJECT
public:
- IOBase(QWidget* parent);
+ IOBase(unsigned IOType /*ioregistry.h::IOType*/, QWidget* parent);
virtual ~IOBase() {
assert(m_didUnregister && "IO peripherals must call unregister() in their destructor!");
- decrementPeriphCounter(this);
+ unclaimPeripheralId(m_type, m_id);
};
const std::map<unsigned, IOParam>& parameters() const { return m_parameters; }
virtual QString description() const = 0;
- virtual QString name() const = 0;
+
+ /**
+ * @brief cName
+ * @returns unique name for this component, escaped to be suitable as a source constant definition
+ */
+ QString cName() const;
+
+ /**
+ * @brief name
+ * @returns unique name for this specific component
+ */
+ virtual QString name() const;
+
+ /**
+ * @brief baseName
+ * @return generic name for this IO type
+ */
+ virtual QString baseName() const = 0;
/**
* @brief registers
@@ -106,15 +122,24 @@ protected:
virtual void parameterChanged(unsigned ID) = 0;
std::map<unsigned, IOParam> m_parameters;
+ unsigned m_id;
- static std::map<std::type_index, int> s_peripheralCount;
- static void incrementPeriphCounter(const IOBase* p) {
- s_peripheralCount[typeid(p)]++;
- return;
+ static std::map<unsigned, std::set<unsigned>> s_peripheralIDs;
+ static unsigned claimPeripheralId(const unsigned& ioType) {
+ auto& currentIDs = s_peripheralIDs[ioType];
+
+ // Just scan linearly from 0 and up until a free ID is found. Not optimal, but # of peripherals is small so no
+ // reason to overengineer.
+ unsigned id = 0;
+ while (currentIDs.count(id) != 0) {
+ id++;
+ }
+ currentIDs.insert(id);
+ return id;
}
- static void decrementPeriphCounter(const IOBase* p) {
- Q_ASSERT(s_peripheralCount.at(typeid(p)) > 0);
- s_peripheralCount[typeid(p)]--;
+ static void unclaimPeripheralId(const unsigned& ioType, unsigned id) {
+ Q_ASSERT(s_peripheralIDs[ioType].count(id) > 0);
+ s_peripheralIDs[ioType].erase(id);
}
private:
@@ -123,6 +148,7 @@ private:
* Debug variable to ensure that inheriting class called unregister() on delete.
*/
bool m_didUnregister = false;
+ unsigned m_type;
};
} // namespace Ripes

MODIFY
src/io/ioledmatrix.cpp
src/io/ioledmatrix.cpp
#include "ioledmatrix.h"
+#include "ioregistry.h"
+
#include <QPainter>
#include <QPen>
namespace Ripes {
-IOLedMatrix::IOLedMatrix(QWidget* parent) : IOBase(parent) {
+IOLedMatrix::IOLedMatrix(QWidget* parent) : IOBase(IOType::LED_MATRIX, parent) {
constexpr unsigned defaultWidth = 25;
// Parameters
@@ -37,10 +39,6 @@ QString IOLedMatrix::description() const {
return desc.join('\n');
}
-QString IOLedMatrix::name() const {
- return "LED Matrix"; // Todo: generate unique name
-}
-
uint32_t IOLedMatrix::ioRead(uint32_t offset, unsigned size) {
return (m_ledRegs.at(offset / 4) >> (offset % 4)) & generateBitmask(size * 8);
}

MODIFY
src/io/ioledmatrix.h
src/io/ioledmatrix.h
@@ -19,7 +19,7 @@ public:
virtual uint32_t size() const override;
virtual QString description() const override;
- virtual QString name() const override;
+ virtual QString baseName() const override { return "LED Matrix"; }
virtual const std::vector<RegDesc>& registers() const override { return m_regDescs; };

MODIFY
src/io/ioregistry.h
src/io/ioregistry.h
namespace Ripes {
-enum class IOType { LED_MATRIX, SWITCHES, DPAD };
+enum IOType { LED_MATRIX, SWITCHES, DPAD };
template <typename T>
IOBase* createIO(QWidget* parent) {

MODIFY
src/io/ioswitches.cpp
src/io/ioswitches.cpp
#include "ioswitches.h"
+#include "ioregistry.h"
#include <QAbstractButton>
#include <QPainter>
@@ -135,7 +136,7 @@ void ToggleButton::enterEvent(QEvent* event) {
* IO Switches
*/
-IOSwitches::IOSwitches(QWidget* parent) : IOBase(parent) {
+IOSwitches::IOSwitches(QWidget* parent) : IOBase(IOType::SWITCHES, parent) {
constexpr unsigned defaultWidth = 25;
// Parameters
@@ -155,10 +156,6 @@ QString IOSwitches::description() const {
return desc.join('\n');
}
-QString IOSwitches::name() const {
- return "Switches"; // Todo: generate unique name
-}
-
void IOSwitches::updateSwitches() {
const unsigned nSwitches = m_parameters.at(SWITCHES).value.toInt();
for (int i = 0; i < nSwitches; i++) {

MODIFY
src/io/ioswitches.h
src/io/ioswitches.h
@@ -65,7 +65,7 @@ public:
virtual uint32_t size() const override { return 4; }
virtual QString description() const override;
- virtual QString name() const override;
+ virtual QString baseName() const override { return "Switches"; };
virtual const std::vector<RegDesc>& registers() const override { return m_regDescs; };

MODIFY
src/iotab.cpp
src/iotab.cpp
@@ -88,7 +88,7 @@ void IOTab::createPeripheral(IOType type) {
dw->setAllowedAreas(Qt::AllDockWidgetAreas);
mw->addDockWidget(Qt::TopDockWidgetArea, dw);
auto* mdiw = m_ui->mdiArea->addSubWindow(mw);
- mdiw->setWindowTitle(IOTypeTitles.at(type));
+ mdiw->setWindowTitle(peripheral->name());
peripheral->setFocus();
m_subWindows[peripheralTab] = mdiw;

Implement unique name generation for peripherals