diff --git a/include/nong.hpp b/include/nong.hpp index a6041ae..6eee9d6 100644 --- a/include/nong.hpp +++ b/include/nong.hpp @@ -217,10 +217,17 @@ class JUKEBOX_DLL Nong final { ~Nong(); + enum class Type { + Local, + YT, + Hosted, + }; + SongMetadata* metadata() const; std::optional path() const; std::optional indexID() const; geode::Result toNongs() const; + Type type() const; template ReturnType visit( diff --git a/src/managers/index_manager.cpp b/src/managers/index_manager.cpp index 87c7583..1deaa5a 100644 --- a/src/managers/index_manager.cpp +++ b/src/managers/index_manager.cpp @@ -4,6 +4,7 @@ #include "index_manager.hpp" #include +#include #include #include "../../include/nong.hpp" @@ -102,7 +103,7 @@ Result<> IndexManager::loadIndex(std::filesystem::path path) { ytNong["name"].as_string(), ytNong["artist"].as_string(), std::nullopt, - ytNong["startOffset"].as_int() + ytNong.contains("startOffset") ? ytNong["startOffset"].as_int() : 0 ), ytNong["ytID"].as_string(), index.m_id, @@ -128,7 +129,7 @@ Result<> IndexManager::loadIndex(std::filesystem::path path) { hostedNong["name"].as_string(), hostedNong["artist"].as_string(), std::nullopt, - hostedNong["startOffset"].as_int() + hostedNong.contains("startOffset") ? hostedNong["startOffset"].as_int() : 0 ), hostedNong["url"].as_string(), index.m_id, @@ -309,11 +310,35 @@ Result> IndexManager::getNongs(int gdSongID) { } } - std::sort(nongs.begin(), nongs.end(), [defaultUniqueID = localNongs.value()->defaultSong()->metadata()->m_uniqueID](const Nong& a, const Nong& b) { + std::unordered_map sortedNongType = { + { Nong::Type::Local, 1 }, + { Nong::Type::Hosted, 2 }, + { Nong::Type::YT, 3 } + }; + + std::sort(nongs.begin(), nongs.end(), [&sortedNongType, defaultUniqueID = localNongs.value()->defaultSong()->metadata()->m_uniqueID](const Nong& a, const Nong& b) { // Place the object with isDefault == true at the front if (a.metadata()->m_uniqueID == defaultUniqueID) return true; if (b.metadata()->m_uniqueID == defaultUniqueID) return false; + // Next, those without an index + if (!a.indexID().has_value() && b.indexID().has_value()) return true; + if (a.indexID().has_value() && !b.indexID().has_value()) return false; + + // Next, compare whether path exists or not + if (a.path().has_value() && std::filesystem::exists(a.path().value())) { + if (!b.path().has_value() || !std::filesystem::exists(b.path().value())) { + return true; + } + } else if (b.path().has_value() && std::filesystem::exists(b.path().value())) { + return false; + } + + // Next, compare by type + if (a.type() != b.type()) { + return sortedNongType.at(a.type()) < sortedNongType.at(b.type()); + } + // Next, compare whether indexID exists or not (std::nullopt should be first) if (a.indexID().has_value() != b.indexID().has_value()) { return !a.indexID().has_value() && b.indexID().has_value(); diff --git a/src/nong.cpp b/src/nong.cpp index a8b248f..968f0ef 100644 --- a/src/nong.cpp +++ b/src/nong.cpp @@ -660,12 +660,6 @@ class Nong::Impl { private: friend class Nong; - enum class Type { - Local, - YT, - Hosted, - }; - Type m_type; std::unique_ptr m_localSong = nullptr; std::unique_ptr m_ytSong = nullptr; @@ -759,6 +753,10 @@ class Nong::Impl { } } } + + Type type() const { + return m_type; + } }; // Explicit template instantiation @@ -799,11 +797,11 @@ Nong::Nong(const Nong& other) Nong& Nong::operator=(const Nong& other) { m_impl->m_type = other.m_impl->m_type; - if (other.m_impl->m_type == Impl::Type::Local) { + if (other.m_impl->m_type == Type::Local) { m_impl->m_localSong = std::make_unique(*other.m_impl->m_localSong); - } else if (other.m_impl->m_type == Impl::Type::YT) { + } else if (other.m_impl->m_type == Type::YT) { m_impl->m_ytSong = std::make_unique(*other.m_impl->m_ytSong); - } else if (other.m_impl->m_type == Impl::Type::Hosted) { + } else if (other.m_impl->m_type == Type::Hosted) { m_impl->m_hostedSong = std::make_unique(*other.m_impl->m_hostedSong); } return *this; @@ -825,6 +823,10 @@ std::optional Nong::indexID() const { return m_impl->indexID(); } +Nong::Type Nong::type() const { + return m_impl->type(); +} + template ReturnType Nong::visit( std::function local,