Implement the identifier in a better and more safe way

This commit is contained in:
Jean Pierre Cimalando 2020-06-11 23:50:41 +02:00
parent c239629be1
commit e07912f7ce
6 changed files with 49 additions and 15 deletions

31
src/sfizz/NumericId.h Normal file
View file

@ -0,0 +1,31 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
/**
* @brief Numeric identifier
*
* It is a generic numeric identifier. The template wrapper serves to enforce a
* stronger compile-time check, such that one kind of identifier can't be
* mistaken for another kind, or for an unrelated integer such as an index.
*/
template <class T>
struct NumericId {
constexpr NumericId() = default;
explicit constexpr NumericId(int number)
: number(number)
{
}
constexpr bool valid() const noexcept
{
return number != -1;
}
const int number = -1;
};

View file

@ -16,6 +16,7 @@
#include "AudioBuffer.h"
#include "MidiState.h"
#include "FileId.h"
#include "NumericId.h"
#include "absl/types/optional.h"
#include <bitset>
#include <string>
@ -36,7 +37,7 @@ namespace sfz {
*/
struct Region {
Region(int regionNumber, const MidiState& midiState, absl::string_view defaultPath = "")
: regionNumber(regionNumber), midiState(midiState), defaultPath(std::move(defaultPath))
: id{regionNumber}, midiState(midiState), defaultPath(std::move(defaultPath))
{
ccSwitched.set();
@ -49,9 +50,9 @@ struct Region {
/**
* @brief Get the number which identifies this region
*/
int getIdNumber() const noexcept
NumericId<Region> getId() const noexcept
{
return regionNumber;
return id;
}
/**
@ -246,7 +247,7 @@ struct Region {
*/
float getGainToEffectBus(unsigned number) const noexcept;
const int regionNumber { -1 };
const NumericId<Region> id;
// Sound source: sample playback
FileId sampleId {}; // Sample

View file

@ -44,11 +44,11 @@ sfz::Synth::~Synth()
resources.filePool.emptyFileLoadingQueues();
}
void sfz::Synth::onVoiceStateChanged(int idNumber, Voice::State state)
void sfz::Synth::onVoiceStateChanged(NumericId<Voice> id, Voice::State state)
{
(void)idNumber;
(void)id;
(void)state;
DBG("Voice " << idNumber << ": state " << static_cast<int>(state));
DBG("Voice " << id.number << ": state " << static_cast<int>(state));
}
void sfz::Synth::onParseFullBlock(const std::string& header, const std::vector<Opcode>& members)

View file

@ -497,7 +497,7 @@ protected:
/**
* @brief The voice callback which is called during a change of state.
*/
void onVoiceStateChanged(int idNumber, Voice::State state) override;
void onVoiceStateChanged(NumericId<Voice> idNumber, Voice::State state) override;
protected:
/**

View file

@ -15,7 +15,7 @@
#include "absl/algorithm/container.h"
sfz::Voice::Voice(int voiceNumber, sfz::Resources& resources)
: voiceNumber(voiceNumber), stateListener(nullptr), resources(resources)
: id{voiceNumber}, stateListener(nullptr), resources(resources)
{
filters.reserve(config::filtersPerVoice);
equalizers.reserve(config::eqsPerVoice);
@ -773,6 +773,6 @@ void sfz::Voice::switchState(State s)
if (s != state) {
state = s;
if (stateListener)
stateListener->onVoiceStateChanged(voiceNumber, s);
stateListener->onVoiceStateChanged(id, s);
}
}

View file

@ -14,6 +14,7 @@
#include "AudioSpan.h"
#include "LeakDetector.h"
#include "OnePoleFilter.h"
#include "NumericId.h"
#include "absl/types/span.h"
#include <memory>
#include <random>
@ -41,12 +42,13 @@ public:
NoteOff,
CC
};
/**
* @brief Get the number which identifies this voice
* @brief Get the unique identifier of this voice in a synth
*/
int getIdNumber() const noexcept
NumericId<Voice> getId() const noexcept
{
return voiceNumber;
return id;
}
enum class State {
@ -56,7 +58,7 @@ public:
class StateListener {
public:
virtual void onVoiceStateChanged(int /*idNumber*/, State /*state*/) {}
virtual void onVoiceStateChanged(NumericId<Voice> /*id*/, State /*state*/) {}
};
/**
@ -299,7 +301,7 @@ private:
*/
void switchState(State s);
const int voiceNumber { -1 };
const NumericId<Voice> id;
StateListener* stateListener = nullptr;
Region* region { nullptr };