Skip to content

Commit

Permalink
Refactor EID into a pseudo-UUID
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-spa committed Nov 28, 2024
1 parent 7706808 commit 073f9bd
Show file tree
Hide file tree
Showing 16 changed files with 144 additions and 128 deletions.
2 changes: 1 addition & 1 deletion src/engraving/dom/engravingitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2801,7 +2801,7 @@ void EngravingItem::LayoutData::setWidthDebugHook(double w)
void EngravingItem::LayoutData::dump(std::stringstream& ss) const
{
ss << "\n";
ss << m_item->typeName() << " id: " << m_item->eid().id() << "\n";
ss << m_item->typeName() << " id: " << m_item->eid().toStdString() << "\n";

ss << "skip: " << (m_isSkipDraw ? "yes" : "no") << "\n";
ss << "mag: " << m_mag << "\n";
Expand Down
39 changes: 12 additions & 27 deletions src/engraving/dom/engravingobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,6 @@ EngravingObject::EngravingObject(const ElementType& type, EngravingObject* paren
m_score = static_cast<Score*>(this);
}

// gen EID
if (type != ElementType::SCORE) {
Score* s = score();
if (s) {
MasterScore* ms = s->masterScore();
if (ms) {
m_eid = ms->eidRegister()->newEID(m_type);
}
}
}

// reg to debug
if (type != ElementType::SCORE) {
if (m_score && m_score->elementsProvider()) {
Expand All @@ -103,17 +92,6 @@ EngravingObject::EngravingObject(const EngravingObject& se)
}
m_links = 0;

// gen EID
if (m_type != ElementType::SCORE) {
Score* s = score();
if (s) {
MasterScore* ms = s->masterScore();
if (ms) {
m_eid = ms->eidRegister()->newEID(m_type);
}
}
}

// reg to debug
if (m_type != ElementType::SCORE) {
if (m_score && m_score->elementsProvider()) {
Expand Down Expand Up @@ -727,12 +705,19 @@ String EngravingObject::translatedTypeUserName() const
return typeUserName().translated();
}

void EngravingObject::setEID(EID id)
EID EngravingObject::eid() const
{
m_eid = id;
if (registerId()) {
masterScore()->eidRegister()->registerItemEID(id, this);
}
return masterScore()->eidRegister()->EIDFromItem(this);
}

void EngravingObject::setEID(EID id) const
{
masterScore()->eidRegister()->registerItemEID(id, this);
}

EID EngravingObject::assignNewEID() const
{
return masterScore()->eidRegister()->newEIDForItem(this);
}

//---------------------------------------------------------
Expand Down
8 changes: 4 additions & 4 deletions src/engraving/dom/engravingobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,9 @@ class EngravingObject
virtual TranslatableString typeUserName() const;
virtual String translatedTypeUserName() const;

inline EID eid() const { return m_eid; }
void setEID(EID id);
virtual bool registerId() const { return false; }
EID eid() const;
void setEID(EID id) const;
EID assignNewEID() const;

EngravingObject* parent() const;
void setParent(EngravingObject* p);
Expand Down Expand Up @@ -300,7 +300,7 @@ class EngravingObject
void doSetScore(Score* sc);

ElementType m_type = ElementType::INVALID;
mutable EID m_eid;

EngravingObject* m_parent = nullptr;
bool m_isParentExplicitlySet = false;
EngravingObjectList m_children;
Expand Down
2 changes: 0 additions & 2 deletions src/engraving/dom/measurebase.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,6 @@ class MeasureBase : public EngravingItem
bool isStartOfSystemLock() const;
bool isEndOfSystemLock() const;

bool registerId() const override { return true; }

protected:

MeasureBase(const ElementType& type, System* system = 0);
Expand Down
4 changes: 0 additions & 4 deletions src/engraving/dom/score.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,6 @@ Score::Score(MasterScore* parent, bool forcePartStyle /* = true */)
Score::validScores.insert(this);
m_masterScore = parent;

if (m_masterScore) {
setEID(m_masterScore->eidRegister()->newEID(type()));
}

if (DefaultStyle::defaultStyleForParts()) {
m_style = *DefaultStyle::defaultStyleForParts();
} else {
Expand Down
71 changes: 37 additions & 34 deletions src/engraving/infrastructure/eid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,55 +19,58 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <string>
#include <random>

#include "eid.h"

using namespace mu::engraving;

EID::EID(ElementType type, uint32_t id)
: m_type(type), m_id(id)
std::string EID::toStdString() const
{
std::stringstream ss;
ss << std::hex << m_first << '-' << m_second;
return ss.str();
}

struct _Data {
uint16_t type = 0;
uint16_t reserved = 0;
uint32_t id = 0;
};

union _Pack
EID EID::fromStdString(const std::string& s)
{
uint64_t val;
_Data data;
};
std::stringstream ss(s);
std::string str;
std::vector<std::string> strings;

uint64_t EID::toUint64() const
{
_Pack pack = { 0 };
pack.data.type = static_cast<uint16_t>(m_type);
pack.data.id = m_id;
return pack.val;
}
while (std::getline(ss, str, '-')) {
strings.push_back(str);
}

EID EID::fromUint64(uint64_t v)
{
_Pack pack = { 0 };
pack.val = v;
return EID(static_cast<ElementType>(pack.data.type), pack.data.id);
}
if (strings.size() != 2) {
return EID();
}

std::string EID::toStdString() const
{
return std::to_string(toUint64());
const std::string& first = strings[0];
const std::string& second = strings[1];

EID eid;
eid.m_first = strtoull(first.data(), nullptr, 16);
eid.m_second = strtoull(second.data(), nullptr, 16);

return eid;
}

EID EID::fromStdString(const std::string& s)
EID EID::fromStdString(const std::string_view& s)
{
uint64_t v = std::stoull(s);
return fromUint64(v);
return fromStdString(std::string(s));
}

EID EID::fromStdString(const std::string_view& s)
EID EID::createNew()
{
uint64_t v = std::stoull(s.data(), nullptr, 10);
return fromUint64(v);
static std::random_device s_device;
static std::mt19937_64 s_engine(s_device());
static std::uniform_int_distribution<uint64_t> s_unifDist;

EID eid;
eid.m_first = s_unifDist(s_engine);
eid.m_second = s_unifDist(s_engine);

return eid;
}
34 changes: 20 additions & 14 deletions src/engraving/infrastructure/eid.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#ifndef MU_ENGRAVING_EID_H
#define MU_ENGRAVING_EID_H

#include <bitset>
#include <cstdint>
#include <string>
#include <string_view>
Expand All @@ -34,33 +35,38 @@ namespace mu::engraving {
class EID
{
public:
EID(ElementType type = ElementType::INVALID, uint32_t id = 0);
bool isValid() const { return *this != EID(); }

bool isValid() const { return m_type != ElementType::INVALID && m_id != 0; }

ElementType type() const { return m_type; }
uint32_t id() const { return m_id; }

inline bool operator ==(const EID& other) const { return m_type == other.m_type && m_id == other.m_id; }
inline bool operator !=(const EID& other) const { return !this->operator ==(other); }

uint64_t toUint64() const;
static EID fromUint64(uint64_t v);
inline bool operator ==(const EID& other) const { return m_first == other.m_first && m_second == other.m_second; }
inline bool operator !=(const EID& other) const { return m_first != other.m_first || m_second != other.m_second; }

std::string toStdString() const;
static EID fromStdString(const std::string& v);
static EID fromStdString(const std::string_view& v);
static EID createNew();

private:
uint64_t m_first = uint64_t(-1);
uint64_t m_second = uint64_t(-1);

ElementType m_type = ElementType::INVALID;
uint32_t m_id = 0;
friend struct std::hash<EID>;
};
}

namespace std {
template<>
struct hash<mu::engraving::EID>
{
size_t operator()(const mu::engraving::EID& eid) const
{
return hash<uint64_t>()(eid.m_first) ^ (hash<uint64_t>()(eid.m_second) << 1);
}
};
}

inline muse::logger::Stream& operator<<(muse::logger::Stream& s, const mu::engraving::EID& v)
{
s << "[" << static_cast<int>(v.type()) << "] " << v.id();
s << v.toStdString();
return s;
}

Expand Down
37 changes: 22 additions & 15 deletions src/engraving/infrastructure/eidregister.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,41 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include "logger.h"
#include "eidregister.h"
#include "log.h"

using namespace mu::engraving;

void EIDRegister::init(uint32_t val)
EID EIDRegister::newEIDForItem(const EngravingObject* item)
{
m_lastID = val;
EID eid = EID::createNew();
registerItemEID(eid, const_cast<EngravingObject*>(item));
return eid;
}

EID EIDRegister::newEID(ElementType type)
void EIDRegister::registerItemEID(const EID& eid, const EngravingObject* item)
{
return EID(type, ++m_lastID);
IF_ASSERT_FAILED(eid.isValid() && item) {
return;
}

bool inserted = m_eidToItem.emplace(eid, const_cast<EngravingObject*>(item)).second;
assert(inserted);

inserted = m_itemToEid.emplace(const_cast<EngravingObject*>(item), eid).second;
assert(inserted);
}

void EIDRegister::registerItemEID(EID eid, EngravingObject* item)
EngravingObject* EIDRegister::itemFromEID(const EID& eid) const
{
bool inserted = m_register.emplace(eid.toUint64(), item).second;
#ifdef NDEBUG
UNUSED(inserted);
#else
assert(inserted);
#endif
auto iter = m_eidToItem.find(eid);
assert(iter != m_eidToItem.end());
return iter->second;
}

EngravingObject* EIDRegister::itemFromEID(EID eid)
EID EIDRegister::EIDFromItem(const EngravingObject* item) const
{
auto iter = m_register.find(eid.toUint64());
assert(iter != m_register.end());
return (*iter).second;
auto iter = m_itemToEid.find(const_cast<EngravingObject*>(item));
return iter == m_itemToEid.end() ? EID() : iter->second;
}
16 changes: 7 additions & 9 deletions src/engraving/infrastructure/eidregister.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#pragma once

#include <cstdint>
#include <map>
#include <unordered_map>

#include "eid.h"
#include "../types/types.h"
Expand All @@ -35,18 +35,16 @@ class EIDRegister
public:
EIDRegister() = default;

void init(uint32_t val);
uint32_t lastID() const { return m_lastID; }
EID newEIDForItem(const EngravingObject* item);
void registerItemEID(const EID& eid, const EngravingObject* item);

EID newEID(ElementType type);

void registerItemEID(EID eid, EngravingObject* item);
EngravingObject* itemFromEID(EID eid);
EngravingObject* itemFromEID(const EID& eid) const;
EID EIDFromItem(const EngravingObject* item) const;

private:
EIDRegister(const EIDRegister&) = delete;

uint32_t m_lastID = 0;
std::map<uint64_t, EngravingObject*> m_register;
std::unordered_map<EID, EngravingObject*> m_eidToItem;
std::unordered_map<EngravingObject*, EID> m_itemToEid;
};
}
5 changes: 1 addition & 4 deletions src/engraving/rw/read410/read410.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,7 @@ Err Read410::readScore(Score* score, XmlReader& e, rw::ReadInOutData* data)
} else if (tag == "Revision") {
e.skipCurrentElement();
} else if (tag == "LastEID") {
int val = e.readInt(nullptr);
if (score->isMaster()) {
score->masterScore()->eidRegister()->init(val);
}
e.skipCurrentElement();
} else if (tag == "Score") {
if (!readScore410(score, e, ctx)) {
if (e.error() == muse::XmlStreamReader::CustomError) {
Expand Down
4 changes: 1 addition & 3 deletions src/engraving/rw/write/measurewrite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ void MeasureWrite::writeMeasure(const Measure* measure, XmlWriter& xml, WriteCon
xml.tag("multiMeasureRest", measure->m_mmRestCount);
}
if (writeSystemElements) {
if (!MScore::testMode && !measure->score()->isPaletteScore()) {
xml.tag("eid", measure->eid().toUint64());
}
TWrite::writeItemEid(measure, xml);
if (measure->repeatStart()) {
xml.tag("startRepeat");
}
Expand Down
Loading

0 comments on commit 073f9bd

Please sign in to comment.