Warning and and precompiled headers fixes and cleanup (#408)

This commit is contained in:
casey langen 2021-01-25 19:03:57 -08:00 committed by GitHub
parent 05e7a690b2
commit edce1d7c88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
232 changed files with 2395 additions and 1840 deletions

View File

@ -21,7 +21,7 @@ jobs:
- run: apt-get update
- run: DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles" apt-get install -y git ssh sshpass build-essential clang cmake libboost-thread1.71-dev libboost-system1.71-dev libboost-filesystem1.71-dev libboost-date-time1.71-dev libboost-atomic1.71-dev libboost-chrono1.71-dev libogg-dev libvorbis-dev libavutil-dev libavformat-dev libswresample-dev libncursesw5-dev libasound2-dev libpulse-dev pulseaudio libmicrohttpd-dev libmp3lame-dev libcurl4-openssl-dev libev-dev libssl-dev libtag1-dev libsystemd-dev
- checkout
- run: cmake -DGENERATE_DEB=1 -DDEB_ARCHITECTURE=amd64 -DDEB_PLATFORM=ubuntu -DDEB_DISTRO=focal -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release .
- run: cmake -DENABLE_PCH=true -DGENERATE_DEB=1 -DDEB_ARCHITECTURE=amd64 -DDEB_PLATFORM=ubuntu -DDEB_DISTRO=focal -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release .
- run: make -j2
- run: make package
- run: ./script/copy-artifacts-to-host.sh /root/project/*.deb
@ -35,7 +35,7 @@ jobs:
- run: apt-get update
- run: DEBIAN_FRONTEND="noninteractive" TZ="America/Los_Angeles" apt-get install -y git ssh sshpass build-essential clang cmake libboost-thread1.71-dev libboost-system1.71-dev libboost-filesystem1.71-dev libboost-date-time1.71-dev libboost-atomic1.71-dev libboost-chrono1.71-dev libogg-dev libvorbis-dev libavutil-dev libavformat-dev libswresample-dev libncursesw5-dev libasound2-dev libpulse-dev pulseaudio libmicrohttpd-dev libmp3lame-dev libcurl4-openssl-dev libev-dev libssl-dev libtag1-dev libsystemd-dev
- checkout
- run: cmake -DGENERATE_DEB=1 -DDEB_ARCHITECTURE=amd64 -DDEB_PLATFORM=ubuntu -DDEB_DISTRO=groovy -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release .
- run: cmake -DENABLE_PCH=true -DGENERATE_DEB=1 -DDEB_ARCHITECTURE=amd64 -DDEB_PLATFORM=ubuntu -DDEB_DISTRO=groovy -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release .
- run: make -j2
- run: make package
- run: ./script/copy-artifacts-to-host.sh /root/project/*.deb

1
.gitignore vendored
View File

@ -22,6 +22,7 @@ bin32
bin64
ipch
build
local-circle-ci.yml
CPack*
_CPack*
*.snap

View File

@ -19,7 +19,7 @@ A cross-platform, terminal-based audio engine, library, player and server writte
%autosetup -n %{name}-%{version}
%build
cmake -D CMAKE_INSTALL_PREFIX:PATH=%{_prefix} -DCMAKE_BUILD_TYPE=Release .
cmake -DCMAKE_INSTALL_PREFIX:PATH=%{_prefix} -DCMAKE_BUILD_TYPE=Release -DENABLE_PCH=true .
make -j2
%install

View File

@ -4,6 +4,6 @@ SCRIPT_DIR=`dirname "$0"`
rm -rf bin
${SCRIPT_DIR}/clean-nix.sh
cmake -DGENERATE_DEB=1 -DDEB_ARCHITECTURE=armhf -DDEB_PLATFORM=rpi -DDEB_DISTRO=buster -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release .
cmake -DENABLE_PCH=true -DGENERATE_DEB=1 -DDEB_ARCHITECTURE=armhf -DDEB_PLATFORM=rpi -DDEB_DISTRO=buster -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release .
make -j4
cpack

View File

@ -13,6 +13,10 @@ if [[ -z "${PW}" ]]; then
exit
fi
# pre-process the yml file, and change max processes from 2 to 7
circleci config process .circleci/config.yml > local-circle-ci.yml
sed -i 's/-j2/-j7/g' local-circle-ci.yml
ALL_JOBS=(
"build_ubuntu_bionic"
"build_ubuntu_focal"
@ -27,7 +31,7 @@ REPO="https://github.com/clangen/musikcube"
for JOB in ${ALL_JOBS[@]}; do
circleci local execute \
-c .circleci/config.yml \
-c local-circle-ci.yml \
-e CIRCLE_BRANCH=${BRANCH} \
-e CIRCLE_REPOSITORY_URL=${REPO} \
-e MUSIKCUBE_BUILD_HOST_IP=${IP} \

View File

@ -87,3 +87,8 @@ set_target_properties(musikcore PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${musikcube_SOURCE_DIR}/bin)
target_link_libraries(musikcore ${musikcube_LINK_LIBS})
if (ENABLE_PCH MATCHES "true")
message(STATUS "[musikcore] enabling precompiled headers")
include(./pch.cmake)
endif()

View File

@ -100,8 +100,10 @@ void Buffer::SetSamples(long samples) {
}
void Buffer::CopyFormat(Buffer* fromBuffer) noexcept {
this->channels = fromBuffer->Channels();
this->sampleRate = fromBuffer->SampleRate();
if (fromBuffer) {
this->channels = fromBuffer->Channels();
this->sampleRate = fromBuffer->SampleRate();
}
}
void Buffer::ResizeBuffer() {

View File

@ -46,22 +46,20 @@ using namespace musik::core;
using namespace musik::core::prefs;
using namespace musik::core::sdk;
MasterTransport::MasterTransport()
MasterTransport::MasterTransport() noexcept
: prefs(Preferences::ForComponent(components::Playback)) {
this->type = (Type) this->prefs->GetInt(keys::Transport, (int) Type::Gapless);
this->type = static_cast<Type>(this->prefs->GetInt(
keys::Transport, static_cast<int>(Type::Gapless)));
this->SwitchTo(this->type);
}
MasterTransport::~MasterTransport() {
}
void MasterTransport::SwitchTo(Type type) {
if (!this->transport || this->type != type) {
this->type = type;
this->prefs->SetInt(keys::Transport, (int) this->type);
this->prefs->SetInt(keys::Transport, static_cast<int>(this->type));
double volume = this->transport ? this->transport->Volume() : -1;
const double volume = this->transport ? this->transport->Volume() : -1;
switch (this->type) {
case Type::Gapless:
@ -69,15 +67,14 @@ void MasterTransport::SwitchTo(Type type) {
/* hacky -- we know it's a crossfade transport, stop it
immediately without fading out so we don't block the UI
for a second or so. */
static_cast<CrossfadeTransport*>
(this->transport.get())->StopImmediately();
dynamic_cast<CrossfadeTransport*>(this->transport.get())->StopImmediately();
}
this->transport.reset(new GaplessTransport());
this->transport = std::make_shared<GaplessTransport>();
break;
case Type::Crossfade:
this->transport.reset(new CrossfadeTransport());
this->transport = std::make_shared<CrossfadeTransport>();
break;
}
@ -99,7 +96,7 @@ void MasterTransport::SwitchTo(Type type) {
}
}
MasterTransport::Type MasterTransport::GetType() {
MasterTransport::Type MasterTransport::GetType() noexcept {
return this->type;
}

View File

@ -46,36 +46,35 @@ namespace musik { namespace core { namespace audio {
public:
using Type = musik::core::sdk::TransportType;
MasterTransport();
virtual ~MasterTransport();
MasterTransport() noexcept;
virtual void Start(const std::string& uri, Gain gain, StartMode mode);
virtual void PrepareNextTrack(const std::string& uri, Gain gain);
void Start(const std::string& uri, Gain gain, StartMode mode) override;
void PrepareNextTrack(const std::string& uri, Gain gain) override;
virtual std::string Uri();
std::string Uri() override;
virtual void Stop();
virtual bool Pause();
virtual bool Resume();
void Stop() override;
bool Pause() override;
bool Resume() override;
virtual double Position();
virtual void SetPosition(double seconds);
double Position() override;
void SetPosition(double seconds) override;
virtual double Volume();
virtual void SetVolume(double volume);
double Volume() override;
void SetVolume(double volume) override;
virtual double GetDuration();
double GetDuration() override;
virtual bool IsMuted();
virtual void SetMuted(bool muted);
bool IsMuted() override;
void SetMuted(bool muted) override;
virtual void ReloadOutput();
void ReloadOutput() override;
virtual musik::core::sdk::PlaybackState GetPlaybackState();
virtual musik::core::sdk::StreamState GetStreamState();
musik::core::sdk::PlaybackState GetPlaybackState() override;
musik::core::sdk::StreamState GetStreamState() override;
void SwitchTo(Type type);
Type GetType();
Type GetType() noexcept;
private:
void OnStreamEvent(musik::core::sdk::StreamState type, std::string url);

View File

@ -84,7 +84,7 @@ IStreamPtr Stream::Create(int samplesPerChannel, double bufferLengthSeconds, Str
return IStreamPtr(new Stream(samplesPerChannel, bufferLengthSeconds, options));
}
IStream* Stream::CreateUnmanaged(int samplesPerChannel, double bufferLengthSeconds, StreamFlags options) {
musik::core::audio::IStream* Stream::CreateUnmanaged(int samplesPerChannel, double bufferLengthSeconds, StreamFlags options) {
return new Stream(samplesPerChannel, bufferLengthSeconds, options);
}

View File

@ -46,9 +46,11 @@
#include <musikcore/library/LocalMetadataProxy.h>
#include <musikcore/support/PreferenceKeys.h>
#pragma warning(push, 0)
#include <boost/locale.hpp>
#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
#include <boost/filesystem.hpp>
#pragma warning(pop)
#include <thread>

View File

@ -101,7 +101,7 @@ using namespace musik::core::audio;
#define DEVICE(x) static_cast<IDevice*>(x.opaque)
#define DEVICELIST(x) static_cast<IDeviceList*>(x.opaque)
#define OUTPUT(x) static_cast<IOutput*>(x.opaque)
#define AUDIOSTREAM(x) static_cast<IStream*>(x.opaque)
#define AUDIOSTREAM(x) static_cast<musik::core::audio::IStream*>(x.opaque)
#define PLAYER(x) static_cast<mcsdk_player_context_internal*>(x.opaque)
#define INDEXER(x) static_cast<mcsdk_svc_indexer_context_internal*>(x.opaque)->indexer
#define LIBRARY(x) static_cast<ILibrary*>(x.opaque)

View File

@ -39,15 +39,24 @@
#include <memory>
#pragma warning(push, 0)
#include <boost/filesystem.hpp>
#pragma warning(pop)
#include <musikcore/support/NarrowCast.h>
#include <musikcore/support/DeleteDefaults.h>
#ifdef WIN32
#ifndef WINVER
#define WIN32_LEAN_AND_MEAN
#define WINVER 0x0502
#define _WIN32_WINNT 0x0502
#define NOMINMAX
#define WINVER 0x0601
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0601
#endif
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#endif

View File

@ -36,13 +36,16 @@
#include <musikcore/db/Connection.h>
#include <musikcore/db/SqliteExtensions.h>
#pragma warning(push, 0)
#include <sqlite/sqlite3.h>
#pragma warning(pop)
static std::mutex globalMutex;
using namespace musik::core::db;
Connection::Connection()
Connection::Connection() noexcept
: connection(nullptr)
, transactionCounter(0) {
this->UpdateReferenceCount(true);
@ -70,7 +73,7 @@ int Connection::Open(const std::string &database, unsigned int options, unsigned
return error;
}
int Connection::Close() {
int Connection::Close() noexcept {
if (sqlite3_close(this->connection) == SQLITE_OK) {
this->connection = 0;
return Okay;
@ -92,7 +95,7 @@ int Connection::Execute(const char* sql) {
}
}
int error = this->StepStatement(stmt);
const int error = this->StepStatement(stmt);
if (error != SQLITE_OK && error != SQLITE_DONE) {
sqlite3_finalize(stmt);
return Error;
@ -104,16 +107,16 @@ int Connection::Execute(const char* sql) {
return Okay;
}
void Connection::Checkpoint() {
void Connection::Checkpoint() noexcept {
sqlite3_wal_checkpoint(this->connection, nullptr);
}
int64_t Connection::LastInsertedId() {
int64_t Connection::LastInsertedId() noexcept {
return sqlite3_last_insert_rowid(this->connection);
}
int Connection::LastModifiedRowCount() {
return (int) sqlite3_changes(this->connection);
int Connection::LastModifiedRowCount() noexcept {
return narrow_cast<int>(sqlite3_changes(this->connection));
}
void Connection::Initialize(unsigned int cache) {
@ -168,6 +171,6 @@ void Connection::UpdateReferenceCount(bool init) {
}
}
int Connection::StepStatement(sqlite3_stmt *stmt) {
int Connection::StepStatement(sqlite3_stmt *stmt) noexcept {
return sqlite3_step(stmt);
}

View File

@ -55,25 +55,26 @@ namespace musik { namespace core { namespace db {
class Connection {
public:
Connection();
Connection(const Connection&) = delete;
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(Connection)
Connection() noexcept;
~Connection();
int Open(const std::string &database, unsigned int options = 0, unsigned int cache = 0);
int Close();
int Close() noexcept;
int Execute(const char* sql);
int64_t LastInsertedId();
int64_t LastInsertedId() noexcept;
int LastModifiedRowCount();
int LastModifiedRowCount() noexcept;
void Interrupt();
void Checkpoint();
void Checkpoint() noexcept;
private:
void Initialize(unsigned int cache);
void UpdateReferenceCount(bool init);
int StepStatement(sqlite3_stmt *stmt);
int StepStatement(sqlite3_stmt *stmt) noexcept;
friend class Statement;
friend class ScopedTransaction;

View File

@ -49,7 +49,7 @@ ScopedTransaction::~ScopedTransaction() {
this->End();
}
void ScopedTransaction::Cancel() {
void ScopedTransaction::Cancel() noexcept {
this->canceled = true;
}

View File

@ -43,12 +43,12 @@ namespace musik { namespace core { namespace db {
class ScopedTransaction {
public:
ScopedTransaction(Connection &connection);
ScopedTransaction(const ScopedTransaction&) = delete;
DELETE_CLASS_DEFAULTS(ScopedTransaction)
ScopedTransaction(Connection &connection);
~ScopedTransaction();
void Cancel();
void Cancel() noexcept;
void CommitAndRestart();
private:

View File

@ -33,8 +33,12 @@
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#pragma warning(push, 0)
#include <sqlite/sqlite3.h>
#include <musikcore/db/SqliteExtensions.h>
#pragma warning(pop)
#include <unordered_map>
#include <regex>

View File

@ -36,44 +36,45 @@
#include <musikcore/db/Statement.h>
#include <musikcore/db/Connection.h>
#pragma warning(push, 0)
#include <sqlite/sqlite3.h>
#pragma warning(pop)
using namespace musik::core::db;
Statement::Statement(const char* sql, Connection &connection)
Statement::Statement(const char* sql, Connection &connection) noexcept
: connection(&connection)
, stmt(nullptr)
, modifiedRows(0) {
std::unique_lock<std::mutex> lock(connection.mutex);
sqlite3_prepare_v2(
this->connection->connection, sql, -1, &this->stmt, nullptr);
sqlite3_prepare_v2(this->connection->connection, sql, -1, &this->stmt, nullptr);
}
Statement::Statement(Connection &connection)
Statement::Statement(Connection &connection) noexcept
: connection(&connection)
, stmt(nullptr) {
}
Statement::~Statement() {
Statement::~Statement() noexcept {
sqlite3_finalize(this->stmt);
}
void Statement::Reset() {
void Statement::Reset() noexcept {
sqlite3_reset(this->stmt);
}
void Statement::Unbind() {
void Statement::Unbind() noexcept {
sqlite3_clear_bindings(this->stmt);
}
void Statement::ResetAndUnbind() {
void Statement::ResetAndUnbind() noexcept {
sqlite3_reset(this->stmt);
sqlite3_clear_bindings(this->stmt);
}
int Statement::Step() {
int result = this->connection->StepStatement(this->stmt);
const int result = this->connection->StepStatement(this->stmt);
if (result == SQLITE_OK) {
this->modifiedRows = this->connection->LastModifiedRowCount();
@ -82,15 +83,15 @@ int Statement::Step() {
return result;
}
void Statement::BindInt32(int position, int bindInt) {
void Statement::BindInt32(int position, int bindInt) noexcept {
sqlite3_bind_int(this->stmt, position + 1, bindInt);
}
void Statement::BindInt64(int position, int64_t bindInt) {
sqlite3_bind_int64(this->stmt, position + 1, (sqlite3_int64) bindInt);
void Statement::BindInt64(int position, int64_t bindInt) noexcept {
sqlite3_bind_int64(this->stmt, position + 1, static_cast<sqlite3_int64>(bindInt));
}
void Statement::BindFloat(int position, float bindFloat) {
void Statement::BindFloat(int position, float bindFloat) noexcept {
sqlite3_bind_double(this->stmt, position + 1, bindFloat);
}
@ -109,32 +110,27 @@ void Statement::BindText(int position, const std::string& bindText) {
SQLITE_TRANSIENT);
}
void Statement::BindNull(int position) {
void Statement::BindNull(int position) noexcept {
sqlite3_bind_null(this->stmt, position + 1);
}
const int Statement::ColumnInt32(int column) {
const int Statement::ColumnInt32(int column) noexcept {
return sqlite3_column_int(this->stmt, column);
}
const int64_t Statement::ColumnInt64(int column) {
const int64_t Statement::ColumnInt64(int column) noexcept {
return sqlite3_column_int64(this->stmt, column);
}
const float Statement::ColumnFloat(int column) {
return (float) sqlite3_column_double(this->stmt, column);
const float Statement::ColumnFloat(int column) noexcept {
return static_cast<float>(sqlite3_column_double(this->stmt, column));
}
const char* Statement::ColumnText(int column) {
const char* text = (char*) sqlite3_column_text(this->stmt, column);
const char* Statement::ColumnText(int column) noexcept {
const char* text = reinterpret_cast<const char*>(sqlite3_column_text(this->stmt, column));
return text ? text : "";
}
const wchar_t* Statement::ColumnTextW(int column) {
const wchar_t* text = (wchar_t*) sqlite3_column_text16(this->stmt, column);
return text ? text : L"";
}
const bool Statement::IsNull(int column) {
const bool Statement::IsNull(int column) noexcept {
return sqlite3_column_type(this->stmt, column) == SQLITE_NULL;
}

View File

@ -45,33 +45,33 @@ namespace musik { namespace core { namespace db {
class Statement {
public:
Statement(const char* sql, Connection &connection);
Statement(const Statement&) = delete;
virtual ~Statement();
DELETE_CLASS_DEFAULTS(Statement)
void BindInt32(int position, int bindInt);
void BindInt64(int position, int64_t bindInt);
void BindFloat(int position, float bindFloat);
Statement(const char* sql, Connection &connection) noexcept;
virtual ~Statement() noexcept;
void BindInt32(int position, int bindInt) noexcept;
void BindInt64(int position, int64_t bindInt) noexcept;
void BindFloat(int position, float bindFloat) noexcept;
void BindText(int position, const std::string& bindText);
void BindNull(int position);
void BindNull(int position) noexcept;
const int ColumnInt32(int column);
const int64_t ColumnInt64(int column);
const float ColumnFloat(int column);
const char* ColumnText(int column);
const wchar_t* ColumnTextW(int column);
const bool IsNull(int column);
const int ColumnInt32(int column) noexcept;
const int64_t ColumnInt64(int column) noexcept;
const float ColumnFloat(int column) noexcept;
const char* ColumnText(int column) noexcept;
const bool IsNull(int column) noexcept;
int Step();
void Reset();
void Unbind();
void ResetAndUnbind();
void Reset() noexcept;
void Unbind() noexcept;
void ResetAndUnbind() noexcept;
private:
friend class Connection;
Statement(Connection &connection);
Statement(Connection &connection) noexcept;
sqlite3_stmt *stmt;
Connection *connection;

View File

@ -200,43 +200,48 @@ void musik::debug::Stop() {
backends.clear();
}
static void enqueue(debug_level level, const std::string& tag, const std::string& string) {
std::unique_lock<std::recursive_mutex> lock(mutex);
static void enqueue(debug_level level, const std::string& tag, const std::string& string) noexcept {
try {
std::unique_lock<std::recursive_mutex> lock(mutex);
if (queue) {
queue->push(new log_queue::log_entry(level, tag, string));
if (queue) {
queue->push(new log_queue::log_entry(level, tag, string));
}
}
catch (...) {
fprintf(stderr, "[%d] [%s] %s", static_cast<int>(level), tag.c_str(), string.c_str());
}
}
void musik::debug::verbose(const std::string& tag, const std::string& string) {
void musik::debug::verbose(const std::string& tag, const std::string& string) noexcept {
enqueue(debug_level::verbose, tag, string);
}
void musik::debug::v(const std::string& tag, const std::string& string) {
void musik::debug::v(const std::string& tag, const std::string& string) noexcept {
enqueue(debug_level::verbose, tag, string);
}
void musik::debug::info(const std::string& tag, const std::string& string) {
void musik::debug::info(const std::string& tag, const std::string& string) noexcept {
enqueue(debug_level::info, tag, string);
}
void musik::debug::i(const std::string& tag, const std::string& string) {
void musik::debug::i(const std::string& tag, const std::string& string) noexcept {
enqueue(debug_level::info, tag, string);
}
void musik::debug::warning(const std::string& tag, const std::string& string) {
void musik::debug::warning(const std::string& tag, const std::string& string) noexcept {
enqueue(debug_level::warning, tag, string);
}
void musik::debug::w(const std::string& tag, const std::string& string) {
void musik::debug::w(const std::string& tag, const std::string& string) noexcept {
enqueue(debug_level::warning, tag, string);
}
void musik::debug::error(const std::string& tag, const std::string& string) {
void musik::debug::error(const std::string& tag, const std::string& string) noexcept {
enqueue(debug_level::error, tag, string);
}
void musik::debug::e(const std::string& tag, const std::string& string) {
void musik::debug::e(const std::string& tag, const std::string& string) noexcept {
enqueue(debug_level::error, tag, string);
}

View File

@ -84,13 +84,13 @@ namespace musik {
static void Start(std::vector<IBackend*> backends = { new SimpleFileBackend() });
static void Stop();
static void verbose(const std::string& tag, const std::string& string);
static void v(const std::string& tag, const std::string& string);
static void info(const std::string& tag, const std::string& string);
static void i(const std::string& tag, const std::string& string);
static void warning(const std::string& tag, const std::string& string);
static void w(const std::string& tag, const std::string& string);
static void error(const std::string& tag, const std::string& string);
static void e(const std::string& tag, const std::string& string);
static void verbose(const std::string& tag, const std::string& string) noexcept;
static void v(const std::string& tag, const std::string& string) noexcept;
static void info(const std::string& tag, const std::string& string) noexcept;
static void i(const std::string& tag, const std::string& string) noexcept;
static void warning(const std::string& tag, const std::string& string) noexcept;
static void w(const std::string& tag, const std::string& string) noexcept;
static void error(const std::string& tag, const std::string& string) noexcept;
static void e(const std::string& tag, const std::string& string) noexcept;
};
}

View File

@ -34,7 +34,10 @@
#include "pch.hpp"
#pragma warning(push, 0)
#include <boost/filesystem.hpp>
#pragma warning(pop)
#include <musikcore/support/PreferenceKeys.h>
#include <musikcore/support/Common.h>
@ -70,7 +73,7 @@ static nlohmann::json loadLocaleData(const std::string& fn) {
return nlohmann::json();
}
Locale::Locale() {
Locale::Locale() noexcept {
this->prefs = Preferences::ForComponent(components::Settings);
this->selectedLocale = prefs->GetString(keys::Locale, DEFAULT_LOCALE);
}
@ -119,7 +122,7 @@ bool Locale::SetSelectedLocale(const std::string& locale) {
auto it = std::find_if(
this->locales.begin(),
this->locales.end(),
[locale](std::string compare) {
[locale](std::string compare) noexcept {
return locale == compare;
});

View File

@ -37,8 +37,11 @@
#include <musikcore/config.h>
#include <musikcore/support/Preferences.h>
#include <unordered_map>
#pragma warning(push, 0)
#include <sigslot/sigslot.h>
#include <nlohmann/json.hpp>
#pragma warning(pop)
namespace musik { namespace core { namespace i18n {
@ -65,7 +68,9 @@ namespace musik { namespace core { namespace i18n {
int Dimension(const char* key, int defaultValue);
private:
Locale();
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(Locale)
Locale() noexcept;
std::vector<std::string> locales;
std::shared_ptr<musik::core::Preferences> prefs;

View File

@ -67,13 +67,10 @@ IDataStream* DataStreamFactory::OpenDataStream(const char* uri, OpenFlags flags)
typedef musik::core::PluginFactory::ReleaseDeleter<IDataStream> StreamDeleter;
if (uri) {
DataStreamFactoryVector::iterator it =
DataStreamFactory::Instance()->dataStreamFactories.begin();
/* plugins get the first crack at the uri */
for (; it != DataStreamFactory::Instance()->dataStreamFactories.end(); it++) {
if ((*it)->CanRead(uri)) {
IDataStream* dataStream = (*it)->Open(uri, flags);
for (const auto factory : DataStreamFactory::Instance()->dataStreamFactories) {
if (factory->CanRead(uri)) {
IDataStream* dataStream = factory->Open(uri, flags);
if (dataStream) {
return dataStream;

View File

@ -51,6 +51,8 @@ namespace musik { namespace core { namespace io {
private:
typedef std::vector<std::shared_ptr<musik::core::sdk::IDataStreamFactory> > DataStreamFactoryVector;
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(DataStreamFactory)
DataStreamFactory();
static DataStreamFactory* Instance();

View File

@ -47,12 +47,12 @@ static const std::string TAG = "LocalFileStream";
using namespace musik::core::io;
using namespace musik::core::sdk;
LocalFileStream::LocalFileStream()
LocalFileStream::LocalFileStream() noexcept
: file(nullptr)
, filesize(-1) {
}
LocalFileStream::~LocalFileStream() {
LocalFileStream::~LocalFileStream() noexcept {
try {
this->Close();
}
@ -61,7 +61,7 @@ LocalFileStream::~LocalFileStream() {
}
}
bool LocalFileStream::Seekable() {
bool LocalFileStream::Seekable() noexcept {
return true;
}
@ -71,7 +71,7 @@ bool LocalFileStream::Open(const char *filename, OpenFlags flags) {
debug::info(TAG, "opening file: " + std::string(filename));
boost::filesystem::path file(filename);
bool exists = boost::filesystem::exists(file);
const bool exists = boost::filesystem::exists(file);
if (flags & OpenFlags::Read && !exists) {
debug::error(TAG, "open with OpenFlags::Read failed because file doesn't exist. " + this->uri);
@ -84,7 +84,7 @@ bool LocalFileStream::Open(const char *filename, OpenFlags flags) {
}
boost::system::error_code ec;
this->filesize = (long) boost::filesystem::file_size(file, ec);
this->filesize = narrow_cast<long>(boost::filesystem::file_size(file, ec));
if (ec && flags & OpenFlags::Write) {
this->filesize = 0;
@ -127,11 +127,11 @@ bool LocalFileStream::Open(const char *filename, OpenFlags flags) {
return false;
}
void LocalFileStream::Interrupt() {
void LocalFileStream::Interrupt() noexcept {
}
bool LocalFileStream::Close() {
bool LocalFileStream::Close() noexcept {
auto file = this->file.exchange(nullptr);
if (file) {
if (fclose(file) == 0) {
@ -142,34 +142,34 @@ bool LocalFileStream::Close() {
return false;
}
void LocalFileStream::Release() {
void LocalFileStream::Release() noexcept {
delete this;
}
PositionType LocalFileStream::Read(void* buffer, PositionType readBytes) {
PositionType LocalFileStream::Read(void* buffer, PositionType readBytes) noexcept {
if (!this->file.load()) {
return 0;
}
return (PositionType) fread(buffer, 1, readBytes, this->file);
return narrow_cast<PositionType>(fread(buffer, 1, readBytes, this->file));
}
PositionType LocalFileStream::Write(void* buffer, PositionType writeBytes) {
PositionType LocalFileStream::Write(void* buffer, PositionType writeBytes) noexcept {
if (!this->file.load()) {
return 0;
}
long position = ftell(this->file);
size_t written = fwrite(buffer, 1, writeBytes, this->file);
const long position = ftell(this->file);
const size_t written = fwrite(buffer, 1, writeBytes, this->file);
if (written + position > this->filesize) {
this->filesize = (int) written + position;
this->filesize = narrow_cast<int>(written) + position;
}
return (PositionType) written;
return narrow_cast<PositionType>(written);
}
bool LocalFileStream::SetPosition(PositionType position) {
bool LocalFileStream::SetPosition(PositionType position) noexcept {
if (!this->file.load()) {
return false;
}
@ -177,7 +177,7 @@ bool LocalFileStream::SetPosition(PositionType position) {
return fseek(this->file, position, SEEK_SET) == 0;
}
PositionType LocalFileStream::Position() {
PositionType LocalFileStream::Position() noexcept {
if (!this->file.load()) {
return -1;
}
@ -185,18 +185,18 @@ PositionType LocalFileStream::Position() {
return ftell(this->file);
}
bool LocalFileStream::Eof() {
bool LocalFileStream::Eof() noexcept {
return !this->file.load() || feof(this->file) != 0;
}
long LocalFileStream::Length() {
long LocalFileStream::Length() noexcept {
return this->filesize;
}
const char* LocalFileStream::Type() {
const char* LocalFileStream::Type() noexcept {
return this->extension.c_str();
}
const char* LocalFileStream::Uri() {
const char* LocalFileStream::Uri() noexcept {
return this->uri.c_str();
}

View File

@ -45,25 +45,27 @@ namespace musik { namespace core { namespace io {
using PositionType = musik::core::sdk::PositionType;
using OpenFlags = musik::core::sdk::OpenFlags;
LocalFileStream();
virtual ~LocalFileStream();
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(LocalFileStream)
virtual bool Open(const char *filename, OpenFlags flags);
virtual bool Close();
virtual void Interrupt();
virtual void Release();
virtual bool Readable() { return (flags & OpenFlags::Read) != 0; }
virtual bool Writable() { return (flags & OpenFlags::Write) != 0; }
virtual PositionType Read(void* buffer, PositionType readBytes);
virtual PositionType Write(void* buffer, PositionType writeBytes);
virtual bool SetPosition(PositionType position);
virtual PositionType Position();
virtual bool Eof();
virtual long Length();
virtual bool Seekable();
virtual const char* Type();
virtual const char* Uri();
virtual bool CanPrefetch() { return true; }
LocalFileStream() noexcept;
virtual ~LocalFileStream() noexcept;
bool Open(const char *filename, OpenFlags flags) override;
bool Close() noexcept override;
void Interrupt() noexcept override;
void Release() noexcept override;
bool Readable() noexcept override { return (flags & OpenFlags::Read) != 0; }
bool Writable() noexcept override { return (flags & OpenFlags::Write) != 0; }
PositionType Read(void* buffer, PositionType readBytes) noexcept override;
PositionType Write(void* buffer, PositionType writeBytes) noexcept override;
bool SetPosition(PositionType position) noexcept override;
PositionType Position() noexcept override;
bool Eof() noexcept override;
long Length() noexcept override;
bool Seekable() noexcept override;
const char* Type() noexcept override;
const char* Uri() noexcept override;
bool CanPrefetch() noexcept override { return true; }
private:
OpenFlags flags { OpenFlags::None };

View File

@ -35,14 +35,15 @@
#include <string>
#include <vector>
#include <sigslot/sigslot.h>
#include <functional>
#include <limits>
#include <sigslot/sigslot.h>
#include <musikcore/library/IIndexer.h>
#include <musikcore/library/IQuery.h>
#include <musikcore/sdk/ITrack.h>
#include <musikcore/runtime/IMessageQueue.h>
#include <limits>
namespace musik { namespace core {

View File

@ -40,6 +40,7 @@
#include <musikcore/library/IIndexer.h>
#include <musikcore/db/Connection.h>
#include <musikcore/support/DeleteDefaults.h>
namespace musik { namespace core { namespace db {
@ -53,7 +54,10 @@ namespace musik { namespace core { namespace db {
Canceled = 5
} Status;
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS_WITH_DEFAULT_CTOR(IQuery)
virtual ~IQuery() { }
virtual int GetStatus() = 0;
virtual int GetId() = 0;
virtual int GetOptions() = 0;
@ -62,7 +66,10 @@ namespace musik { namespace core { namespace db {
class ISerializableQuery: public IQuery {
public:
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS_WITH_DEFAULT_CTOR(ISerializableQuery)
virtual ~ISerializableQuery() { }
virtual std::string SerializeQuery() = 0;
virtual std::string SerializeResult() = 0;
virtual void DeserializeResult(const std::string& data) = 0;

View File

@ -55,11 +55,12 @@
#include <musikcore/audio/Stream.h>
#include <algorithm>
#include <boost/bind.hpp>
#include <atomic>
#pragma warning(push, 0)
#include <boost/bind.hpp>
#pragma warning(pop)
#define STRESS_TEST_DB 0
constexpr const char* TAG = "Indexer";

View File

@ -42,12 +42,15 @@
#include <musikcore/library/IIndexer.h>
#include <musikcore/support/Preferences.h>
#pragma warning(push, 0)
#include <sigslot/sigslot.h>
#include <boost/thread/thread.hpp>
#include <boost/thread/condition.hpp>
#include <boost/filesystem.hpp>
#include <boost/asio/io_service.hpp>
#pragma warning(pop)
#include <thread>
#include <deque>

View File

@ -45,9 +45,9 @@
#include <thread>
#include <mutex>
#include <condition_variable>
#include <string>
#include <sigslot/sigslot.h>
#include <string>
namespace musik { namespace core { namespace library {

View File

@ -57,7 +57,10 @@
#include <musikcore/support/Common.h>
#include <vector>
#include <map>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
#define TAG "LocalMetadataProxy"

View File

@ -55,16 +55,13 @@ namespace musik { namespace core { namespace library { namespace query {
Regex = 2
};
QueryBase()
QueryBase() noexcept
: status(IQuery::Idle)
, options(0)
, queryId(nextId())
, cancel(false) {
}
virtual ~QueryBase() {
}
bool Run(musik::core::db::Connection &db) {
this->SetStatus(Running);
try {
@ -84,47 +81,45 @@ namespace musik { namespace core { namespace library { namespace query {
return false;
}
virtual void Cancel() {
virtual void Cancel() noexcept {
this->cancel = true;
}
virtual bool IsCanceled() {
virtual bool IsCanceled() noexcept {
return cancel;
}
/* IQuery */
virtual int GetStatus() {
int GetStatus() override {
std::unique_lock<std::mutex> lock(this->stateMutex);
return this->status;
}
virtual int GetId() {
int GetId() noexcept override {
return this->queryId;
}
virtual int GetOptions() {
int GetOptions() override {
std::unique_lock<std::mutex> lock(this->stateMutex);
return this->options;
}
virtual std::string Name() = 0;
/* ISerializableQuery */
virtual std::string SerializeQuery() {
std::string SerializeQuery() override {
throw std::runtime_error("not implemented");
}
virtual std::string SerializeResult() {
std::string SerializeResult() override {
throw std::runtime_error("not implemented");
}
virtual void DeserializeResult(const std::string& data) {
void DeserializeResult(const std::string& data) override {
throw std::runtime_error("not implemented");
}
virtual void Invalidate() {
void Invalidate() override {
this->SetStatus(IQuery::Failed);
}
@ -142,7 +137,7 @@ namespace musik { namespace core { namespace library { namespace query {
virtual bool OnRun(musik::core::db::Connection& db) = 0;
private:
static int nextId() {
static int nextId() noexcept {
static std::atomic<int> next(0);
return ++next;
}

View File

@ -44,10 +44,15 @@
#include <musikcore/library/LibraryFactory.h>
#include <musikcore/library/QueryRegistry.h>
#include <musikcore/runtime/Message.h>
#include <musikcore/support/NarrowCast.h>
#include <musikcore/debug.h>
#include <nlohmann/json.hpp>
#include <chrono>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
static const std::string TAG = "RemoteLibrary";
using namespace musik::core;
@ -99,7 +104,7 @@ RemoteLibrary::RemoteLibrary(std::string name, int id, MessageQueue* messageQueu
, messageQueue(messageQueue)
, wsc(messageQueue, this) {
this->identifier = std::to_string(id);
this->thread = new std::thread(std::bind(&RemoteLibrary::ThreadProc, this));
this->thread = std::make_unique<std::thread>(std::bind(&RemoteLibrary::ThreadProc, this));
this->ReloadConnectionFromPreferences();
if (this->messageQueue) {
this->messageQueue->Register(this);
@ -124,13 +129,12 @@ const std::string& RemoteLibrary::Name() {
void RemoteLibrary::Close() {
this->wsc.Disconnect();
std::thread* thread = nullptr;
std::unique_ptr<std::thread> thread;
{
std::unique_lock<std::recursive_mutex> lock(this->queueMutex);
if (this->thread) {
thread = this->thread;
this->thread = nullptr;
thread = std::unique_ptr<std::thread>(std::move(this->thread));
this->queryQueue.clear();
this->exit = true;
}
@ -140,7 +144,6 @@ void RemoteLibrary::Close() {
this->queueCondition.notify_all();
this->syncQueryCondition.notify_all();
thread->join();
delete thread;
}
}
@ -165,7 +168,7 @@ bool RemoteLibrary::IsQueryInFlight(Query query) {
return true;
}
}
for (auto queryContext : this->queryQueue) {
for (const auto& queryContext : this->queryQueue) {
if (queryContext->query == query) {
return true;
}
@ -210,7 +213,7 @@ int RemoteLibrary::EnqueueAndWait(QueryPtr query, size_t timeoutMs, Callback cal
break;
}
else {
auto result = this->syncQueryCondition.wait_for(lock, timeoutMs * milliseconds(1));
const auto result = this->syncQueryCondition.wait_for(lock, timeoutMs * milliseconds(1));
if (result == std::cv_status::timeout) {
break;
}
@ -226,7 +229,7 @@ int RemoteLibrary::EnqueueAndWait(QueryPtr query, size_t timeoutMs, Callback cal
RemoteLibrary::QueryContextPtr RemoteLibrary::GetNextQuery() {
std::unique_lock<std::recursive_mutex> lock(this->queueMutex);
while (!this->queryQueue.size() && !this->exit) {
while (this->queryQueue.empty() && !this->exit) {
this->queueCondition.wait(lock);
}
if (this->exit) {
@ -325,7 +328,7 @@ void RemoteLibrary::RunQueryOnLoopback(QueryContextPtr context) {
void RemoteLibrary::RunQueryOnWebSocketClient(QueryContextPtr context) {
if (context->query) {
const std::string messageId = wsc.EnqueueQuery(context->query);
if (messageId.size()) {
if (!messageId.empty()) {
queriesInFlight[messageId] = context;
}
else {
@ -353,8 +356,10 @@ musik::core::IIndexer* RemoteLibrary::Indexer() {
void RemoteLibrary::ProcessMessage(musik::core::runtime::IMessage &message) {
if (message.Type() == MESSAGE_QUERY_COMPLETED) {
auto context = static_cast<QueryCompletedMessage*>(&message)->GetContext();
this->NotifyQueryCompleted(context);
auto context = dynamic_cast<QueryCompletedMessage*>(&message)->GetContext();
if (context) {
this->NotifyQueryCompleted(context);
}
}
else if (message.Type() == MESSAGE_RECONNECT_SOCKET) {
if (this->wsc.ConnectionState() == Client::State::Disconnected) {
@ -362,7 +367,7 @@ void RemoteLibrary::ProcessMessage(musik::core::runtime::IMessage &message) {
}
}
else if (message.Type() == MESSAGE_UPDATE_CONNECTION_STATE) {
auto updatedState = (ConnectionState)message.UserData1();
const auto updatedState = static_cast<ConnectionState>(message.UserData1());
this->connectionState = updatedState;
this->ConnectionStateChanged(this->connectionState);
}
@ -384,7 +389,7 @@ void RemoteLibrary::OnClientStateChanged(Client* client, State newState, State o
if (this->messageQueue) {
const auto reason = this->wsc.LastConnectionError();
bool attemptReconnect =
const bool attemptReconnect =
newState == State::Disconnected &&
reason != WebSocketClient::ConnectionError::InvalidPassword &&
reason != WebSocketClient::ConnectionError::IncompatibleVersion;
@ -414,20 +419,20 @@ std::string RemoteLibrary::GetTrackUri(musik::core::sdk::ITrack* track, const st
char buffer[4096];
buffer[0] = 0;
int size = track->Uri(buffer, sizeof(buffer));
const int size = track->Uri(buffer, sizeof(buffer));
if (size) {
std::string originalUri = buffer;
std::string::size_type lastDot = originalUri.find_last_of(".");
const std::string::size_type lastDot = originalUri.find_last_of(".");
if (lastDot != std::string::npos) {
type = originalUri.substr(lastDot).c_str();
type = originalUri.substr(lastDot);
}
}
auto prefs = Preferences::ForComponent(core::prefs::components::Settings);
auto host = prefs->GetString(core::prefs::keys::RemoteLibraryHostname, "127.0.0.1");
auto port = (unsigned short) prefs->GetInt(core::prefs::keys::RemoteLibraryHttpPort, 7905);
const auto port = narrow_cast<unsigned short>(prefs->GetInt(core::prefs::keys::RemoteLibraryHttpPort, 7905));
auto password = prefs->GetString(core::prefs::keys::RemoteLibraryPassword, "");
auto useTls = prefs->GetBool(core::prefs::keys::RemoteLibraryHttpTls, false);
const auto useTls = prefs->GetBool(core::prefs::keys::RemoteLibraryHttpTls, false);
const std::string scheme = useTls ? "https://" : "http://";
@ -436,7 +441,7 @@ std::string RemoteLibrary::GetTrackUri(musik::core::sdk::ITrack* track, const st
if (prefs->GetBool(core::prefs::keys::RemoteLibraryTranscoderEnabled)) {
auto const bitrate = prefs->GetInt(core::prefs::keys::RemoteLibraryTranscoderBitrate);
auto const format = prefs->GetString(core::prefs::keys::RemoteLibraryTranscoderFormat);
if (bitrate > 0 && bitrate < 9999 && format.size()) {
if (bitrate > 0 && bitrate < 9999 && !format.empty()) {
uri += "?bitrate=" + std::to_string(bitrate) + "&format=" + format;
type = "." + format;
}
@ -461,8 +466,8 @@ const net::WebSocketClient& RemoteLibrary::WebSocketClient() const {
void RemoteLibrary::ReloadConnectionFromPreferences() {
auto prefs = Preferences::ForComponent(core::prefs::components::Settings);
auto host = prefs->GetString(core::prefs::keys::RemoteLibraryHostname, "127.0.0.1");
auto port = (unsigned short) prefs->GetInt(core::prefs::keys::RemoteLibraryWssPort, 7905);
const auto port = narrow_cast<unsigned short>(prefs->GetInt(core::prefs::keys::RemoteLibraryWssPort, 7905));
auto password = prefs->GetString(core::prefs::keys::RemoteLibraryPassword, "");
auto useTls = prefs->GetBool(core::prefs::keys::RemoteLibraryWssTls, false);
const auto useTls = prefs->GetBool(core::prefs::keys::RemoteLibraryWssTls, false);
this->wsc.Connect(host, port, password, useTls);
}

View File

@ -133,7 +133,7 @@ namespace musik { namespace core { namespace library {
std::unordered_map<std::string, QueryContextPtr> queriesInFlight;
std::thread* thread;
std::unique_ptr<std::thread> thread;
std::condition_variable_any queueCondition, syncQueryCondition;
std::recursive_mutex queueMutex;
std::atomic<ConnectionState> connectionState{ ConnectionState::Disconnected };

View File

@ -35,10 +35,13 @@
#include "pch.hpp"
#include "AlbumListQuery.h"
#include <musikcore/library/LocalLibraryConstants.h>
#include <musikcore/db/Statement.h>
#include <musikcore/library/LocalLibraryConstants.h>
#include <musikcore/library/query/util/Serialization.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using namespace musik::core;
using namespace musik::core::db;
@ -46,8 +49,6 @@ using namespace musik::core::library::query;
using namespace musik::core::library::query::serialization;
using namespace musik::core::library::constants;
#define RESET_RESULT(x) x.reset(new MetadataMapList())
const std::string AlbumListQuery::kQueryName = "AlbumListQuery";
AlbumListQuery::AlbumListQuery(const std::string& filter)
@ -74,7 +75,7 @@ AlbumListQuery::AlbumListQuery(
const category::PredicateList predicates,
const std::string& filter)
{
RESET_RESULT(result);
result = std::make_shared<MetadataMapList>();
if (filter.size()) {
std::string wild = filter;
@ -89,7 +90,7 @@ AlbumListQuery::~AlbumListQuery() {
}
MetadataMapListPtr AlbumListQuery::GetResult() {
MetadataMapListPtr AlbumListQuery::GetResult() noexcept {
return this->result;
}
@ -98,7 +99,7 @@ musik::core::sdk::IMapList* AlbumListQuery::GetSdkResult() {
}
bool AlbumListQuery::OnRun(Connection& db) {
RESET_RESULT(result);
result = std::make_shared<MetadataMapList>();
category::ArgumentList args;
@ -123,9 +124,9 @@ bool AlbumListQuery::OnRun(Connection& db) {
Apply(stmt, args);
while (stmt.Step() == Row) {
int64_t albumId = stmt.ColumnInt64(0);
const int64_t albumId = stmt.ColumnInt64(0);
std::string albumName = stmt.ColumnText(1);
std::shared_ptr<MetadataMap> row(new MetadataMap(albumId, albumName, "album"));
auto row = std::make_shared<MetadataMap>(albumId, albumName, "album");
row->Set(constants::Track::ALBUM_ID, stmt.ColumnText(0));
row->Set(constants::Track::ALBUM, albumName);
@ -170,7 +171,7 @@ void AlbumListQuery::DeserializeResult(const std::string& data) {
std::shared_ptr<AlbumListQuery> AlbumListQuery::DeserializeQuery(const std::string& data) {
nlohmann::json options = nlohmann::json::parse(data)["options"];
std::shared_ptr<AlbumListQuery> result(new AlbumListQuery());
auto result = std::make_shared<AlbumListQuery>();
result->filter = options.value("filter", "");
PredicateListFromJson(options["regularPredicateList"], result->regular);
PredicateListFromJson(options["extendedPredicateList"], result->extended);

View File

@ -38,6 +38,7 @@
#include <musikcore/library/query/util/CategoryQueryUtil.h>
#include <musikcore/library/metadata/MetadataMapList.h>
#include <musikcore/db/Connection.h>
#include <musikcore/support/DeleteDefaults.h>
namespace musik { namespace core { namespace library { namespace query {
@ -45,6 +46,8 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(AlbumListQuery)
AlbumListQuery(
const std::string& filter = "");
@ -64,20 +67,21 @@ namespace musik { namespace core { namespace library { namespace query {
virtual ~AlbumListQuery();
/* IQuery */
std::string Name() { return kQueryName; }
musik::core::MetadataMapListPtr GetResult();
std::string Name() override { return kQueryName; }
musik::core::MetadataMapListPtr GetResult() noexcept;
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<AlbumListQuery> DeserializeQuery(const std::string& data);
/* AlbumListQuery */
musik::core::sdk::IMapList* GetSdkResult();
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
std::string filter;
category::PredicateList regular, extended;

View File

@ -33,10 +33,15 @@
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include "AllCategoriesQuery.h"
#include <musikcore/library/query/util/Serialization.h>
#include <musikcore/db/Statement.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using musik::core::db::Statement;
using musik::core::db::Row;
@ -48,13 +53,10 @@ using namespace musik::core::library::query::serialization;
const std::string AllCategoriesQuery::kQueryName = "AllCategoriesQuery";
AllCategoriesQuery::AllCategoriesQuery() {
this->result.reset(new SdkValueList());
this->result = std::make_shared<SdkValueList>();
}
AllCategoriesQuery::~AllCategoriesQuery() {
}
AllCategoriesQuery::Result AllCategoriesQuery::GetResult() {
AllCategoriesQuery::Result AllCategoriesQuery::GetResult() noexcept {
return this->result;
}
@ -63,7 +65,7 @@ musik::core::sdk::IValueList* AllCategoriesQuery::GetSdkResult() {
}
bool AllCategoriesQuery::OnRun(Connection& db) {
this->result.reset(new SdkValueList());
this->result = std::make_shared<SdkValueList>();
Statement stmt("SELECT DISTINCT name FROM meta_keys ORDER BY name", db);
this->result->Add(std::make_shared<SdkValue>("album", 0, "category"));

View File

@ -34,6 +34,7 @@
#pragma once
#include <musikcore/support/DeleteDefaults.h>
#include <musikcore/library/QueryBase.h>
#include <musikcore/library/query/util/SdkWrappers.h>
#include <musikcore/sdk/IValueList.h>
@ -46,22 +47,25 @@ namespace musik { namespace core { namespace library { namespace query {
using Result = SdkValueList::Shared;
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(AllCategoriesQuery)
AllCategoriesQuery();
virtual ~AllCategoriesQuery();
std::string Name() { return kQueryName; }
virtual Result GetResult();
virtual Result GetResult() noexcept;
musik::core::sdk::IValueList* GetSdkResult();
/* IQuery */
std::string Name() override { return kQueryName; }
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<AllCategoriesQuery> DeserializeQuery(const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
Result result;

View File

@ -41,7 +41,10 @@
#include <musikcore/runtime/Message.h>
#include <musikcore/support/Messages.h>
#include <musikcore/db/Statement.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using musik::core::db::Statement;
using musik::core::db::Row;
@ -70,7 +73,7 @@ AppendPlaylistQuery::AppendPlaylistQuery(
musik::core::ILibraryPtr library,
const int64_t playlistId,
std::shared_ptr<musik::core::TrackList> tracks,
const int offset)
const int offset) noexcept
: library(library)
, sharedTracks(tracks)
, rawTracks(nullptr)
@ -83,7 +86,7 @@ AppendPlaylistQuery::AppendPlaylistQuery(
musik::core::ILibraryPtr library,
const int64_t playlistId,
musik::core::sdk::ITrackList *tracks,
const int offset)
const int offset) noexcept
: library(library)
, rawTracks(tracks)
, playlistId(playlistId)
@ -94,7 +97,7 @@ AppendPlaylistQuery::AppendPlaylistQuery(
bool AppendPlaylistQuery::OnRun(musik::core::db::Connection &db) {
this->result = false;
ITrackList* tracks = sharedTracks ? sharedTracks.get() : rawTracks;
const ITrackList* tracks = sharedTracks ? sharedTracks.get() : rawTracks;
if (!tracks || !tracks->Count() || playlistId == 0) {
this->result = true;
@ -129,11 +132,14 @@ bool AppendPlaylistQuery::OnRun(musik::core::db::Connection &db) {
Statement insertTrack(INSERT_PLAYLIST_TRACK_QUERY.c_str(), db);
for (size_t i = 0; i < tracks->Count(); i++) {
auto id = tracks->GetId(i);
auto target = TrackPtr(new LibraryTrack(id, this->library));
const auto id = tracks->GetId(i);
auto target = std::make_shared<LibraryTrack>(id, this->library);
std::shared_ptr<TrackMetadataQuery> query(
new TrackMetadataQuery(target, this->library, TrackMetadataQuery::Type::IdsOnly));
std::shared_ptr<TrackMetadataQuery> query =
std::make_shared<TrackMetadataQuery>(
target,
this->library,
TrackMetadataQuery::Type::IdsOnly);
this->library->EnqueueAndWait(query);
@ -167,7 +173,7 @@ void AppendPlaylistQuery::SendPlaylistMutationBroadcast() {
/* ISerializableQuery */
std::string AppendPlaylistQuery::SerializeQuery() {
ITrackList* tracks = rawTracks ? rawTracks : sharedTracks.get();
const ITrackList* tracks = rawTracks ? rawTracks : sharedTracks.get();
nlohmann::json output = {
{ "name", kQueryName },
{ "options", {

View File

@ -45,31 +45,33 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
DELETE_CLASS_DEFAULTS(AppendPlaylistQuery)
AppendPlaylistQuery(
musik::core::ILibraryPtr library,
const int64_t playlistId,
std::shared_ptr<musik::core::TrackList> tracks,
const int offset = -1);
const int offset = -1) noexcept;
AppendPlaylistQuery(
musik::core::ILibraryPtr library,
const int64_t playlistId,
musik::core::sdk::ITrackList *tracks,
const int offset = -1);
const int offset = -1) noexcept;
virtual ~AppendPlaylistQuery() { }
std::string Name() { return kQueryName; }
/* IQuery */
std::string Name() override { return kQueryName; }
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<AppendPlaylistQuery> DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
void SendPlaylistMutationBroadcast();

View File

@ -65,9 +65,6 @@ static std::string getMatchType(CategoryListQuery::MatchType matchType) {
return matchType == CategoryListQuery::MatchType::Regex ? "REGEXP" : "LIKE";
}
CategoryListQuery::CategoryListQuery() {
}
CategoryListQuery::CategoryListQuery(
MatchType matchType,
const std::string& trackField,
@ -91,7 +88,7 @@ CategoryListQuery::CategoryListQuery(
: matchType(matchType)
, trackField(trackField)
, filter(filter) {
result.reset(new SdkValueList());
result = std::make_shared<SdkValueList>();
if (this->filter.size() && this->matchType == MatchType::Substring) {
/* transform "FilteR" => "%filter%" */
@ -115,10 +112,7 @@ CategoryListQuery::CategoryListQuery(
}
}
CategoryListQuery::~CategoryListQuery() {
}
CategoryListQuery::Result CategoryListQuery::GetResult() {
CategoryListQuery::Result CategoryListQuery::GetResult() noexcept {
return this->result;
}
@ -137,7 +131,7 @@ int CategoryListQuery::GetIndexOf(int64_t id) {
}
void CategoryListQuery::QueryPlaylist(musik::core::db::Connection& db) {
bool filtered = this->filter.size();
const bool filtered = this->filter.size();
std::string query = filtered
? kFilteredPlaylistsQuery
@ -236,7 +230,7 @@ void CategoryListQuery::ProcessResult(musik::core::db::Statement &stmt) {
}
bool CategoryListQuery::OnRun(Connection& db) {
result.reset(new SdkValueList());
result = std::make_shared<SdkValueList>();
switch (this->outputType) {
case OutputType::Playlist: QueryPlaylist(db); break;
@ -284,7 +278,7 @@ std::shared_ptr<CategoryListQuery> CategoryListQuery::DeserializeQuery(const std
result->trackField = options.value("trackField", "");
result->filter = options.value("filter", "");
result->matchType = options.value("matchType", MatchType::Substring);
result->outputType = (OutputType)options.value("outputType", OutputType::Regular);
result->outputType = static_cast<OutputType>(options.value("outputType", OutputType::Regular));
PredicateListFromJson(options["regularPredicateList"], result->regular);
PredicateListFromJson(options["extendedPredicateList"], result->extended);
return result;

View File

@ -51,6 +51,8 @@ namespace musik { namespace core { namespace library { namespace query {
using Result = SdkValueList::Shared;
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS_WITH_DEFAULT_CTOR(CategoryListQuery)
CategoryListQuery(
MatchType matchType,
const std::string& trackField,
@ -68,27 +70,22 @@ namespace musik { namespace core { namespace library { namespace query {
const category::PredicateList predicate,
const std::string& filter = "");
virtual ~CategoryListQuery();
std::string Name() { return kQueryName; }
/* IQuery */
virtual Result GetResult();
virtual int GetIndexOf(int64_t id);
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
static std::shared_ptr<CategoryListQuery> DeserializeQuery(const std::string& data);
Result GetResult() noexcept;
int GetIndexOf(int64_t id);
musik::core::sdk::IValueList* GetSdkResult();
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* IQuery */
std::string Name() override { return kQueryName; }
private:
CategoryListQuery();
/* ISerializableQuery */
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<CategoryListQuery> DeserializeQuery(const std::string& data);
protected:
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
enum class OutputType: int {
Regular = 1,

View File

@ -41,10 +41,11 @@
#include <musikcore/library/LocalLibraryConstants.h>
#include <musikcore/library/query/util/Serialization.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string.hpp>
#include <nlohmann/json.hpp>
#pragma warning(pop)
using musik::core::db::Statement;
using musik::core::db::Row;
@ -94,8 +95,8 @@ CategoryTrackListQuery::CategoryTrackListQuery(
TrackSortType sortType)
{
this->library = library;
this->result.reset(new musik::core::TrackList(library));
this->headers.reset(new std::set<size_t>());
this->result = std::make_shared<TrackList>(library);
this->headers = std::make_shared<std::set<size_t>>();
this->hash = category::Hash(predicates);
this->sortType = sortType;
@ -106,12 +107,8 @@ CategoryTrackListQuery::CategoryTrackListQuery(
this->parseHeaders = kTrackSortTypeWithAlbumGrouping.find(sortType) != kTrackSortTypeWithAlbumGrouping.end();
}
CategoryTrackListQuery::~CategoryTrackListQuery() {
}
void CategoryTrackListQuery::ScanPredicateListsForQueryType() {
if (this->extended.size() == 1 && this->extended[0].first == Playlists::TABLE_NAME) {
if (this->extended.size() == 1 && this->extended.at(0).first == Playlists::TABLE_NAME) {
this->type = Type::Playlist;
}
else {
@ -119,22 +116,22 @@ void CategoryTrackListQuery::ScanPredicateListsForQueryType() {
}
}
CategoryTrackListQuery::Result CategoryTrackListQuery::GetResult() {
CategoryTrackListQuery::Result CategoryTrackListQuery::GetResult() noexcept {
return this->result;
}
CategoryTrackListQuery::Headers CategoryTrackListQuery::GetHeaders() {
CategoryTrackListQuery::Headers CategoryTrackListQuery::GetHeaders() noexcept {
return this->headers;
}
size_t CategoryTrackListQuery::GetQueryHash() {
size_t CategoryTrackListQuery::GetQueryHash() noexcept {
return this->hash;
}
void CategoryTrackListQuery::PlaylistQuery(musik::core::db::Connection &db) {
/* playlists are a special case. we already have a query for this, so
delegate to that. */
GetPlaylistQuery query(this->library, this->extended[0].second);
GetPlaylistQuery query(this->library, this->extended.at(0).second);
query.Run(db);
this->result = query.GetResult();
}
@ -175,7 +172,7 @@ void CategoryTrackListQuery::ProcessResult(musik::core::db::Statement& trackQuer
size_t index = 0;
while (trackQuery.Step() == Row) {
int64_t id = trackQuery.ColumnInt64(0);
const int64_t id = trackQuery.ColumnInt64(0);
std::string album = trackQuery.ColumnText(1);
if (this->parseHeaders && album != lastAlbum) {
@ -190,8 +187,8 @@ void CategoryTrackListQuery::ProcessResult(musik::core::db::Statement& trackQuer
bool CategoryTrackListQuery::OnRun(Connection& db) {
if (result) {
result.reset(new musik::core::TrackList(this->library));
headers.reset(new std::set<size_t>());
result = std::make_shared<TrackList>(library);
headers = std::make_shared<std::set<size_t>>();
}
switch (this->type) {

View File

@ -49,6 +49,8 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
DELETE_CLASS_DEFAULTS(CategoryTrackListQuery)
CategoryTrackListQuery(
musik::core::ILibraryPtr library,
const std::string& filter = "",
@ -73,23 +75,24 @@ namespace musik { namespace core { namespace library { namespace query {
const std::string& filter = "",
TrackSortType sortType = TrackSortType::Album);
virtual ~CategoryTrackListQuery();
/* IQuery */
std::string Name() override { return kQueryName; }
virtual std::string Name() { return kQueryName; }
virtual Result GetResult();
virtual Headers GetHeaders();
virtual size_t GetQueryHash();
/* TrackListQueryBase */
Result GetResult() noexcept override;
Headers GetHeaders() noexcept override;
size_t GetQueryHash() noexcept override;
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<CategoryTrackListQuery> DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
enum class Type: int { Playlist = 0, Regular = 1 };

View File

@ -40,7 +40,9 @@
#include <musikcore/support/Messages.h>
#include <musikcore/runtime/Message.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using namespace musik::core;
using namespace musik::core::db;
@ -55,14 +57,11 @@ static std::string DELETE_PLAYLIST_TRACKS_QUERY =
static std::string DELETE_PLAYLIST_QUERY =
"DELETE FROM playlists WHERE id=?;";
DeletePlaylistQuery::DeletePlaylistQuery(musik::core::ILibraryPtr library, int64_t playlistId) {
DeletePlaylistQuery::DeletePlaylistQuery(musik::core::ILibraryPtr library, int64_t playlistId) noexcept {
this->library = library;
this->playlistId = playlistId;
}
DeletePlaylistQuery::~DeletePlaylistQuery() {
}
bool DeletePlaylistQuery::OnRun(musik::core::db::Connection &db) {
ScopedTransaction transaction(db);

View File

@ -34,6 +34,7 @@
#pragma once
#include <musikcore/support/DeleteDefaults.h>
#include <musikcore/library/ILibrary.h>
#include <musikcore/library/QueryBase.h>
#include <musikcore/db/Connection.h>
@ -44,23 +45,25 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
DELETE_CLASS_DEFAULTS(DeletePlaylistQuery)
DeletePlaylistQuery(
musik::core::ILibraryPtr library,
const int64_t playlistId);
const int64_t playlistId) noexcept;
virtual ~DeletePlaylistQuery();
virtual std::string Name() { return kQueryName; }
/* IQuery */
std::string Name() override { return kQueryName; }
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<DeletePlaylistQuery> DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
void SendPlaylistMutationBroadcast();

View File

@ -58,18 +58,14 @@ DirectoryTrackListQuery::DirectoryTrackListQuery(
this->library = library;
this->directory = directory;
this->filter = filter;
this->result.reset(new musik::core::TrackList(library));
this->headers.reset(new std::set<size_t>());
this->result = std::make_shared<TrackList>(library);
this->headers = std::make_shared<std::set<size_t>>();
this->hash = std::hash<std::string>()(directory + "-" + filter);
}
DirectoryTrackListQuery::~DirectoryTrackListQuery() {
}
bool DirectoryTrackListQuery::OnRun(Connection& db) {
result.reset(new musik::core::TrackList(this->library));
headers.reset(new std::set<size_t>());
this->result = std::make_shared<TrackList>(library);
this->headers = std::make_shared<std::set<size_t>>();
std::string query =
" SELECT t.id, al.name "
@ -87,7 +83,7 @@ bool DirectoryTrackListQuery::OnRun(Connection& db) {
std::string lastAlbum;
size_t index = 0;
while (select.Step() == db::Row) {
int64_t id = select.ColumnInt64(0);
const int64_t id = select.ColumnInt64(0);
std::string album = select.ColumnText(1);
if (!album.size()) {

View File

@ -43,27 +43,31 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(DirectoryTrackListQuery)
DirectoryTrackListQuery(
musik::core::ILibraryPtr library,
const std::string& directory,
const std::string& filter = "");
virtual ~DirectoryTrackListQuery();
/* IQuery */
std::string Name() override { return kQueryName; }
virtual std::string Name() { return kQueryName; }
virtual Result GetResult() { return this->result; }
virtual Headers GetHeaders() { return this->headers; }
virtual size_t GetQueryHash() { return this->hash; }
/* TrackListQueryBase */
Result GetResult() noexcept override { return this->result; }
Headers GetHeaders() noexcept override { return this->headers; }
size_t GetQueryHash() noexcept override { return this->hash; }
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<DirectoryTrackListQuery> DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
musik::core::ILibraryPtr library;

View File

@ -40,7 +40,9 @@
#include <musikcore/library/query/util/Serialization.h>
#include <musikcore/db/Statement.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using musik::core::db::Statement;
using musik::core::db::Row;
@ -58,31 +60,27 @@ const std::string GetPlaylistQuery::kQueryName = "GetPlaylistQuery";
GetPlaylistQuery::GetPlaylistQuery(ILibraryPtr library, int64_t playlistId) {
this->library = library;
this->playlistId = playlistId;
this->result.reset(new musik::core::TrackList(library));
this->headers.reset(new std::set<size_t>());
this->result = std::make_shared<TrackList>(library);
this->headers = std::make_shared<std::set<size_t>>();
this->hash = std::hash<int64_t>()(this->playlistId);
}
GetPlaylistQuery::~GetPlaylistQuery() {
}
GetPlaylistQuery::Result GetPlaylistQuery::GetResult() {
GetPlaylistQuery::Result GetPlaylistQuery::GetResult() noexcept {
return this->result;
}
GetPlaylistQuery::Headers GetPlaylistQuery::GetHeaders() {
GetPlaylistQuery::Headers GetPlaylistQuery::GetHeaders() noexcept {
return this->headers;
}
size_t GetPlaylistQuery::GetQueryHash() {
size_t GetPlaylistQuery::GetQueryHash() noexcept {
return this->hash;
}
bool GetPlaylistQuery::OnRun(Connection& db) {
if (result) {
result.reset(new musik::core::TrackList(this->library));
headers.reset(new std::set<size_t>());
this->result = std::make_shared<TrackList>(library);
this->headers = std::make_shared<std::set<size_t>>();
}
std::string query =

View File

@ -46,27 +46,30 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
DELETE_CLASS_DEFAULTS(GetPlaylistQuery)
GetPlaylistQuery(
musik::core::ILibraryPtr library,
int64_t playlistId);
virtual ~GetPlaylistQuery();
/* IQuery */
std::string Name() override { return kQueryName; }
virtual std::string Name() { return kQueryName; }
virtual Result GetResult();
virtual Headers GetHeaders();
virtual size_t GetQueryHash();
/* TrackListQueryBase */
Result GetResult() noexcept override;
Headers GetHeaders() noexcept override;
size_t GetQueryHash() noexcept override;
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<GetPlaylistQuery> DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
musik::core::ILibraryPtr library;

View File

@ -34,7 +34,10 @@
#include "pch.hpp"
#include "LyricsQuery.h"
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using namespace musik::core::db;
using namespace musik::core::library::query;
@ -48,10 +51,6 @@ LyricsQuery::LyricsQuery(const std::string& trackExternalId) {
this->trackExternalId = trackExternalId;
}
LyricsQuery::~LyricsQuery() {
}
std::string LyricsQuery::GetResult() {
return this->result;
}

View File

@ -42,21 +42,24 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
DELETE_CLASS_DEFAULTS(LyricsQuery)
LyricsQuery(const std::string& trackExternalId);
virtual ~LyricsQuery();
std::string GetResult();
/* IQuery */
std::string Name() { return kQueryName; }
virtual std::string GetResult();
std::string Name() override { return kQueryName; }
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<LyricsQuery> DeserializeQuery(const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
std::string trackExternalId;
std::string result;

View File

@ -34,7 +34,10 @@
#include "pch.hpp"
#include "MarkTrackPlayedQuery.h"
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using namespace musik::core::db;
using namespace musik::core::library::query;
@ -42,13 +45,10 @@ using namespace musik::core::sdk;
const std::string MarkTrackPlayedQuery::kQueryName = "MarkTrackPlayedQuery";
MarkTrackPlayedQuery::MarkTrackPlayedQuery(const int64_t trackId) {
MarkTrackPlayedQuery::MarkTrackPlayedQuery(const int64_t trackId) noexcept {
this->trackId = trackId;
}
MarkTrackPlayedQuery::~MarkTrackPlayedQuery() {
}
bool MarkTrackPlayedQuery::OnRun(musik::core::db::Connection &db) {
Statement stmt(
"UPDATE tracks "

View File

@ -42,18 +42,24 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
MarkTrackPlayedQuery(const int64_t trackId);
virtual ~MarkTrackPlayedQuery();
std::string Name() { return "MarkTrackPlayedQuery"; }
DELETE_CLASS_DEFAULTS(MarkTrackPlayedQuery)
MarkTrackPlayedQuery(const int64_t trackId) noexcept;
/* IQuery */
std::string Name() override { return "MarkTrackPlayedQuery"; }
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<MarkTrackPlayedQuery> DeserializeQuery(const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
int64_t trackId;
bool result{ false };
};

View File

@ -55,24 +55,20 @@ NowPlayingTrackListQuery::NowPlayingTrackListQuery(
ILibraryPtr library, musik::core::audio::PlaybackService& playback)
: library(library)
, playback(playback) {
this->result.reset(new musik::core::TrackList(library));
this->headers.reset(new std::set<size_t>());
this->result = std::make_shared<TrackList>(library);
this->headers = std::make_shared<std::set<size_t>>();
this->hash = 0;
}
NowPlayingTrackListQuery::~NowPlayingTrackListQuery() {
}
NowPlayingTrackListQuery::Result NowPlayingTrackListQuery::GetResult() {
NowPlayingTrackListQuery::Result NowPlayingTrackListQuery::GetResult() noexcept {
return this->result;
}
NowPlayingTrackListQuery::Headers NowPlayingTrackListQuery::GetHeaders() {
NowPlayingTrackListQuery::Headers NowPlayingTrackListQuery::GetHeaders() noexcept {
return this->headers;
}
size_t NowPlayingTrackListQuery::GetQueryHash() {
size_t NowPlayingTrackListQuery::GetQueryHash() noexcept {
if (this->hash == 0) {
this->hash = std::hash<std::string>()(this->Name());
}
@ -82,8 +78,8 @@ size_t NowPlayingTrackListQuery::GetQueryHash() {
bool NowPlayingTrackListQuery::OnRun(Connection& db) {
if (result) {
result.reset(new musik::core::TrackList(this->library));
headers.reset(new std::set<size_t>());
this->result = std::make_shared<TrackList>(library);
this->headers = std::make_shared<std::set<size_t>>();
}
this->playback.CopyTo(*result);

View File

@ -45,19 +45,23 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
DELETE_CLASS_DEFAULTS(NowPlayingTrackListQuery)
NowPlayingTrackListQuery(
musik::core::ILibraryPtr library,
musik::core::audio::PlaybackService& playback);
virtual ~NowPlayingTrackListQuery();
/* IQuery */
std::string Name() override { return kQueryName; }
virtual std::string Name() { return kQueryName; }
virtual Result GetResult();
virtual Headers GetHeaders();
virtual size_t GetQueryHash();
/* TrackListQueryBase */
Result GetResult() noexcept override;
Headers GetHeaders() noexcept override;
size_t GetQueryHash() noexcept override;
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
musik::core::ILibraryPtr library;

View File

@ -47,7 +47,7 @@ const std::string PersistedPlayQueueQuery::kQueryName = "PersistedPlayQueueQuery
PersistedPlayQueueQuery::PersistedPlayQueueQuery(
musik::core::ILibraryPtr library,
musik::core::audio::PlaybackService& playback,
Type type)
Type type) noexcept
: library(library)
, playback(playback)
, type(type)
@ -55,10 +55,6 @@ PersistedPlayQueueQuery::PersistedPlayQueueQuery(
}
PersistedPlayQueueQuery::~PersistedPlayQueueQuery() {
}
bool PersistedPlayQueueQuery::OnRun(musik::core::db::Connection &db) {
if (this->type == Type::Save) {
ScopedTransaction transaction(db);

View File

@ -57,12 +57,14 @@ namespace musik { namespace core { namespace library { namespace query {
return new PersistedPlayQueueQuery(library, playback, Type::Restore);
}
virtual ~PersistedPlayQueueQuery();
DELETE_CLASS_DEFAULTS(PersistedPlayQueueQuery)
virtual std::string Name() { return kQueryName; }
/* IQuery */
std::string Name() override { return kQueryName; }
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
enum class Type { Save, Restore };
@ -70,7 +72,7 @@ namespace musik { namespace core { namespace library { namespace query {
PersistedPlayQueueQuery(
musik::core::ILibraryPtr library,
musik::core::audio::PlaybackService& playback,
Type type);
Type type) noexcept;
musik::core::ILibraryPtr library;
musik::core::audio::PlaybackService& playback;

View File

@ -251,12 +251,9 @@ SavePlaylistQuery::SavePlaylistQuery(musik::core::ILibraryPtr library) {
this->categoryId = -1;
}
SavePlaylistQuery::~SavePlaylistQuery() {
}
/* METHODS */
int64_t SavePlaylistQuery::GetPlaylistId() const {
int64_t SavePlaylistQuery::GetPlaylistId() const noexcept {
return playlistId;
}
@ -300,8 +297,7 @@ bool SavePlaylistQuery::AddTracksToPlaylist(
bool SavePlaylistQuery::AddCategoryTracksToPlaylist(
musik::core::db::Connection &db, int64_t playlistId)
{
auto query = std::shared_ptr<CategoryTrackListQuery>(
new CategoryTrackListQuery(library, categoryType, categoryId));
auto query = std::make_shared<CategoryTrackListQuery>(library, categoryType, categoryId);
this->library->EnqueueAndWait(query);
@ -378,7 +374,7 @@ bool SavePlaylistQuery::ReplacePlaylist(musik::core::db::Connection &db) {
bool SavePlaylistQuery::AppendToPlaylist(musik::core::db::Connection& db) {
ScopedTransaction transaction(db);
bool result = this->tracks.Exists()
const bool result = this->tracks.Exists()
? this->AddTracksToPlaylist(db, this->playlistId, this->tracks)
: this->AddCategoryTracksToPlaylist(db, this->playlistId);
@ -426,18 +422,18 @@ void SavePlaylistQuery::SendPlaylistMutationBroadcast() {
/* SUPPORTING TYPES */
SavePlaylistQuery::TrackListWrapper::TrackListWrapper() {
SavePlaylistQuery::TrackListWrapper::TrackListWrapper() noexcept {
this->rawTracks = nullptr;
}
SavePlaylistQuery::TrackListWrapper::TrackListWrapper(
std::shared_ptr<musik::core::TrackList> shared)
std::shared_ptr<musik::core::TrackList> shared) noexcept
{
this->rawTracks = nullptr;
this->sharedTracks = shared;
}
bool SavePlaylistQuery::TrackListWrapper::Exists() {
bool SavePlaylistQuery::TrackListWrapper::Exists() noexcept {
return this->sharedTracks || this->rawTracks;
}
@ -458,8 +454,8 @@ TrackPtr SavePlaylistQuery::TrackListWrapper::Get(
TrackPtr result = std::make_shared<LibraryTrack>(rawTracks->GetId(index), library);
if (rawTracks) {
std::shared_ptr<TrackMetadataQuery> query(
new TrackMetadataQuery(result, library, TrackMetadataQuery::Type::IdsOnly));
auto query = std::make_shared<TrackMetadataQuery>(
result, library, TrackMetadataQuery::Type::IdsOnly);
library->EnqueueAndWait(query);
}
@ -467,7 +463,7 @@ TrackPtr SavePlaylistQuery::TrackListWrapper::Get(
return result;
}
ITrackList* SavePlaylistQuery::TrackListWrapper::Get() {
ITrackList* SavePlaylistQuery::TrackListWrapper::Get() noexcept {
if (sharedTracks) {
return sharedTracks.get();
}

View File

@ -88,21 +88,23 @@ namespace musik { namespace core { namespace library { namespace query {
const std::string& categoryType,
int64_t categoryId);
virtual std::string Name() { return kQueryName; }
DELETE_CLASS_DEFAULTS(SavePlaylistQuery)
virtual ~SavePlaylistQuery();
int64_t GetPlaylistId() const noexcept;
int64_t GetPlaylistId() const;
/* IQuery */
std::string Name() override { return kQueryName; }
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<SavePlaylistQuery> DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
SavePlaylistQuery(
@ -147,13 +149,15 @@ namespace musik { namespace core { namespace library { namespace query {
void SendPlaylistMutationBroadcast();
struct TrackListWrapper {
TrackListWrapper();
TrackListWrapper(std::shared_ptr<musik::core::TrackList> shared);
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(TrackListWrapper)
bool Exists();
TrackListWrapper() noexcept;
TrackListWrapper(std::shared_ptr<musik::core::TrackList> shared) noexcept;
bool Exists() noexcept;
size_t Count();
TrackPtr Get(musik::core::ILibraryPtr library, size_t index);
musik::core::sdk::ITrackList* Get();
musik::core::sdk::ITrackList* Get() noexcept;
std::shared_ptr<musik::core::TrackList> sharedTracks;
musik::core::sdk::ITrackList* rawTracks;

View File

@ -41,10 +41,12 @@
#include <musikcore/library/LocalLibraryConstants.h>
#include <musikcore/db/Statement.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string.hpp>
#include <nlohmann/json.hpp>
#pragma warning(pop)
using musik::core::db::Statement;
using musik::core::db::Row;
@ -78,23 +80,20 @@ SearchTrackListQuery::SearchTrackListQuery(
this->parseHeaders = kTrackSortTypeWithAlbumGrouping.find(sort) != kTrackSortTypeWithAlbumGrouping.end();
this->displayString = _TSTR(kTrackListOrderByToDisplayKey.find(sort)->second);
this->orderBy = kTrackListSortOrderBy.find(sort)->second;
this->result.reset(new musik::core::TrackList(library));
this->headers.reset(new std::set<size_t>());
this->result = std::make_shared<TrackList>(library);
this->headers = std::make_shared<std::set<size_t>>();
this->hash = 0;
}
SearchTrackListQuery::~SearchTrackListQuery() {
}
SearchTrackListQuery::Result SearchTrackListQuery::GetResult() {
SearchTrackListQuery::Result SearchTrackListQuery::GetResult() noexcept {
return this->result;
}
SearchTrackListQuery::Headers SearchTrackListQuery::GetHeaders() {
SearchTrackListQuery::Headers SearchTrackListQuery::GetHeaders() noexcept {
return this->headers;
}
size_t SearchTrackListQuery::GetQueryHash() {
size_t SearchTrackListQuery::GetQueryHash() noexcept {
this->hash = std::hash<std::string>()(this->filter);
return this->hash;
}
@ -105,12 +104,12 @@ std::string SearchTrackListQuery::GetSortDisplayString() {
bool SearchTrackListQuery::OnRun(Connection& db) {
if (result) {
result.reset(new musik::core::TrackList(this->library));
headers.reset(new std::set<size_t>());
this->result = std::make_shared<TrackList>(library);
this->headers = std::make_shared<std::set<size_t>>();
}
bool useRegex = (matchType == MatchType::Regex);
bool hasFilter = (this->filter.size() > 0);
const bool useRegex = (matchType == MatchType::Regex);
const bool hasFilter = (this->filter.size() > 0);
std::string lastAlbum;
size_t index = 0;
std::string query;
@ -154,7 +153,7 @@ bool SearchTrackListQuery::OnRun(Connection& db) {
}
while (trackQuery.Step() == Row) {
int64_t id = trackQuery.ColumnInt64(0);
const int64_t id = trackQuery.ColumnInt64(0);
std::string album = trackQuery.ColumnText(1);
if (!album.size()) {

View File

@ -43,31 +43,34 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
DELETE_CLASS_DEFAULTS(SearchTrackListQuery)
SearchTrackListQuery(
musik::core::ILibraryPtr library,
MatchType matchType,
const std::string& filter,
TrackSortType sort);
virtual ~SearchTrackListQuery();
virtual std::string Name() { return kQueryName; }
std::string GetSortDisplayString();
virtual Result GetResult();
virtual Headers GetHeaders();
virtual size_t GetQueryHash();
/* IQuery */
std::string Name() override { return kQueryName; }
/* TrackListQueryBase */
Result GetResult() noexcept override;
Headers GetHeaders() noexcept override;
size_t GetQueryHash() noexcept override;
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<SearchTrackListQuery> DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
private:
musik::core::ILibraryPtr library;

View File

@ -34,7 +34,10 @@
#include "pch.hpp"
#include "SetTrackRatingQuery.h"
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using namespace musik::core::db;
using namespace musik::core::library::query;
@ -42,14 +45,11 @@ using namespace musik::core::sdk;
const std::string SetTrackRatingQuery::kQueryName = "SetTrackRatingQuery";
SetTrackRatingQuery::SetTrackRatingQuery(int64_t trackId, int rating) {
SetTrackRatingQuery::SetTrackRatingQuery(int64_t trackId, int rating) noexcept {
this->trackId = trackId;
this->rating = std::max(0, std::min(5, rating));
}
SetTrackRatingQuery::~SetTrackRatingQuery() {
}
bool SetTrackRatingQuery::OnRun(musik::core::db::Connection &db) {
Statement stmt("UPDATE tracks SET rating=? WHERE id=?", db);
stmt.BindInt32(0, this->rating);

View File

@ -42,18 +42,22 @@ namespace musik { namespace core { namespace library { namespace query {
public:
static const std::string kQueryName;
SetTrackRatingQuery(int64_t trackId, int rating);
virtual ~SetTrackRatingQuery();
std::string Name() { return kQueryName; }
DELETE_CLASS_DEFAULTS(SetTrackRatingQuery)
SetTrackRatingQuery(int64_t trackId, int rating) noexcept;
/* IQuery */
std::string Name() override { return kQueryName; }
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<SetTrackRatingQuery> DeserializeQuery(const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection &db);
/* QueryBase */
bool OnRun(musik::core::db::Connection &db) override;
int64_t trackId;
int rating;

View File

@ -40,7 +40,9 @@
#include <musikcore/library/track/TrackList.h>
#include <musikcore/library/query/util/Serialization.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
namespace musik { namespace core { namespace library { namespace query {
@ -49,18 +51,19 @@ namespace musik { namespace core { namespace library { namespace query {
typedef std::shared_ptr<musik::core::TrackList> Result;
typedef std::shared_ptr<std::set<size_t> > Headers;
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(TrackListQueryBase)
TrackListQueryBase() {
this->limit = -1;
this->offset = 0;
}
virtual ~TrackListQueryBase() { };
virtual std::string Name() = 0;
/* virtual methods we define */
virtual Result GetResult() = 0;
virtual Headers GetHeaders() = 0;
virtual size_t GetQueryHash() = 0;
virtual void SetLimitAndOffset(int limit, int offset = 0) {
virtual void SetLimitAndOffset(int limit, int offset = 0) noexcept {
this->limit = limit;
this->offset = offset;
}
@ -89,7 +92,7 @@ namespace musik { namespace core { namespace library { namespace query {
return output.dump();
}
void ExtractLimitAndOffsetFromDeserializedQuery(nlohmann::json& options) {
void ExtractLimitAndOffsetFromDeserializedQuery(const nlohmann::json& options) {
this->limit = options.value("limit", -1);
this->offset = options.value("offset", 0);
}
@ -119,27 +122,30 @@ namespace musik { namespace core { namespace library { namespace query {
class WrappedTrackList : public musik::core::sdk::ITrackList {
public:
WrappedTrackList(Result wrapped) {
WrappedTrackList(Result wrapped) noexcept {
this->wrapped = wrapped;
}
virtual void Release() {
virtual ~WrappedTrackList() {
}
void Release() noexcept override {
delete this;
}
virtual size_t Count() const {
size_t Count() const override {
return this->wrapped->Count();
}
virtual int64_t GetId(size_t index) const {
int64_t GetId(size_t index) const override {
return this->wrapped->GetId(index);
}
virtual int IndexOf(int64_t id) const {
int IndexOf(int64_t id) const override {
return this->wrapped->IndexOf(id);
}
virtual musik::core::sdk::ITrack* GetTrack(size_t index) const {
musik::core::sdk::ITrack* GetTrack(size_t index) const override {
return this->wrapped->GetTrack(index);
}

View File

@ -39,7 +39,10 @@
#include <musikcore/library/track/LibraryTrack.h>
#include <musikcore/library/query/util/TrackQueryFragments.h>
#include <musikcore/sdk/ReplayGain.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using namespace musik::core;
using namespace musik::core::db;
@ -58,7 +61,7 @@ TrackMetadataBatchQuery::TrackMetadataBatchQuery(std::unordered_set<int64_t> tra
bool TrackMetadataBatchQuery::OnRun(Connection& db) {
std::string idList;
size_t i = 0;
for (int64_t id : this->trackIds) {
for (const int64_t id : this->trackIds) {
idList += std::to_string(id);
if (i < this->trackIds.size() - 1) {
idList += ",";
@ -108,7 +111,7 @@ std::string TrackMetadataBatchQuery::SerializeResult() {
void TrackMetadataBatchQuery::DeserializeResult(const std::string& data) {
this->SetStatus(IQuery::Failed);
auto input = nlohmann::json::parse(data)["result"];
for (auto& kv : input.items()) {
for (const auto& kv : input.items()) {
int64_t id = std::atoll(kv.key().c_str());
auto track = std::make_shared<LibraryTrack>(id, this->library);
TrackFromJson(kv.value(), track, false);
@ -122,7 +125,6 @@ std::shared_ptr<TrackMetadataBatchQuery> TrackMetadataBatchQuery::DeserializeQue
{
using SetType = std::unordered_set <int64_t>;
auto json = nlohmann::json::parse(data);
auto parsedTrack = std::make_shared<LibraryTrack>(-1LL, library);
SetType trackIds;
JsonArrayToSet<SetType, int64_t>(json["options"]["trackIds"], trackIds);
return std::make_shared<TrackMetadataBatchQuery>(trackIds, library);

View File

@ -48,28 +48,29 @@ class TrackMetadataBatchQuery: public QueryBase {
using IdToTrackMap = std::unordered_map<int64_t, TrackPtr>;
DELETE_CLASS_DEFAULTS(TrackMetadataBatchQuery)
TrackMetadataBatchQuery(
std::unordered_set<int64_t> trackIds,
musik::core::ILibraryPtr library);
virtual ~TrackMetadataBatchQuery() {
}
const IdToTrackMap& Result() {
const IdToTrackMap& Result() noexcept {
return this->result;
}
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
/* IQuery */
std::string Name() override { return kQueryName; }
/* ISerializableQuery */
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<TrackMetadataBatchQuery> DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection& db);
virtual std::string Name() { return kQueryName; }
/* QueryBase */
bool OnRun(musik::core::db::Connection& db) override;
private:
musik::core::ILibraryPtr library;

View File

@ -39,7 +39,10 @@
#include <musikcore/library/track/LibraryTrack.h>
#include <musikcore/library/query/util/TrackQueryFragments.h>
#include <musikcore/sdk/ReplayGain.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using namespace musik::core;
using namespace musik::core::db;
@ -50,7 +53,7 @@ using namespace musik::core::sdk;
const std::string TrackMetadataQuery::kQueryName = "TrackMetadataQuery";
TrackMetadataQuery::TrackMetadataQuery(TrackPtr target, ILibraryPtr library, Type type) {
TrackMetadataQuery::TrackMetadataQuery(TrackPtr target, ILibraryPtr library, Type type) noexcept {
this->result = target;
this->library = library;
this->type = type;
@ -59,7 +62,7 @@ TrackMetadataQuery::TrackMetadataQuery(TrackPtr target, ILibraryPtr library, Typ
bool TrackMetadataQuery::OnRun(Connection& db) {
result->SetMetadataState(MetadataState::Loading);
bool queryById = this->result->GetId() != 0;
const bool queryById = this->result->GetId() != 0;
std::string query;
@ -77,7 +80,7 @@ bool TrackMetadataQuery::OnRun(Connection& db) {
Statement trackQuery(query.c_str(), db);
if (queryById) {
trackQuery.BindInt64(0, (int64_t) this->result->GetId());
trackQuery.BindInt64(0, this->result->GetId());
}
else {
const std::string& externalId = this->result->GetString("external_id");

View File

@ -46,28 +46,32 @@ class TrackMetadataQuery : public QueryBase {
enum class Type: int { Full = 0, IdsOnly = 1 };
DELETE_CLASS_DEFAULTS(TrackMetadataQuery)
TrackMetadataQuery(
musik::core::TrackPtr target,
musik::core::ILibraryPtr library,
Type type = Type::Full);
virtual ~TrackMetadataQuery() { }
Type type = Type::Full) noexcept;
TrackPtr Result() {
return this->result;
}
/* ISerializableQuery */
virtual std::string SerializeQuery();
virtual std::string SerializeResult();
virtual void DeserializeResult(const std::string& data);
/* IQuery */
std::string Name() override {
return kQueryName;
}
/* ISerializableQuery */
std::string SerializeQuery() override;
std::string SerializeResult() override;
void DeserializeResult(const std::string& data) override;
static std::shared_ptr<TrackMetadataQuery> DeserializeQuery(
musik::core::ILibraryPtr library, const std::string& data);
protected:
virtual bool OnRun(musik::core::db::Connection& db);
virtual std::string Name() { return kQueryName; }
/* QueryBase */
bool OnRun(musik::core::db::Connection& db) override;
private:
Type type;

View File

@ -34,7 +34,10 @@
#pragma once
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
#include "CategoryQueryUtil.h"
#include <musikcore/library/metadata/MetadataMapList.h>
#include <musikcore/library/query/util/SdkWrappers.h>

View File

@ -64,7 +64,7 @@ static std::unordered_map<std::string, int64_t> metadataIdCache;
static std::unordered_map<int, int64_t> thumbnailIdCache; /* albumId:thumbnailId */
/* http://stackoverflow.com/a/2351171 */
static size_t hash32(const char* str) {
static size_t hash32(const char* str) noexcept {
unsigned int h;
unsigned char *p;
h = 0;
@ -183,7 +183,7 @@ void IndexerTrack::SetThumbnail(const char *data, long size) {
int64_t IndexerTrack::GetThumbnailId() {
std::string key = this->GetString("album") + "-" + this->GetString("album_artist");
size_t id = hash32(key.c_str());
const size_t id = hash32(key.c_str());
auto it = thumbnailIdCache.find((int) id);
if (it != thumbnailIdCache.end()) {
return it->second;
@ -267,8 +267,8 @@ bool IndexerTrack::NeedsToBeIndexed(
this->SetValue("extension", file.leaf().string().substr(lastDot + 1).c_str());
}
size_t fileSize = (size_t) boost::filesystem::file_size(file);
size_t fileTime = (size_t) boost::filesystem::last_write_time(file);
const size_t fileSize = (size_t) boost::filesystem::file_size(file);
const size_t fileTime = (size_t) boost::filesystem::last_write_time(file);
this->SetValue("filesize", std::to_string(fileSize).c_str());
this->SetValue("filetime", std::to_string(fileTime).c_str());
@ -280,12 +280,12 @@ bool IndexerTrack::NeedsToBeIndexed(
stmt.BindText(0, this->GetString("filename"));
bool fileDifferent = true;
const bool fileDifferent = true;
if (stmt.Step() == db::Row) {
this->trackId = stmt.ColumnInt64(0);
int dbFileSize = stmt.ColumnInt32(2);
int dbFileTime = stmt.ColumnInt32(3);
const int dbFileSize = stmt.ColumnInt32(2);
const int dbFileTime = stmt.ColumnInt32(3);
if (fileSize == dbFileSize && fileTime == dbFileTime) {
return false;
@ -309,7 +309,7 @@ static int64_t writeToTracksTable(
return 0;
}
int sourceId = track.GetInt32("source_id", 0);
const int sourceId = track.GetInt32("source_id", 0);
/* if there's no ID specified, but we have an external ID, let's
see if we can find the corresponding ID. this can happen when
@ -436,7 +436,7 @@ int64_t IndexerTrack::SaveThumbnail(db::Connection& connection, const std::strin
int64_t thumbnailId = 0;
if (this->internalMetadata->thumbnailData) {
int64_t sum = Checksum(this->internalMetadata->thumbnailData, this->internalMetadata->thumbnailSize);
const int64_t sum = Checksum(this->internalMetadata->thumbnailData, this->internalMetadata->thumbnailSize);
db::Statement thumbs("SELECT id FROM thumbnails WHERE filesize=? AND checksum=?", connection);
thumbs.BindInt32(0, this->internalMetadata->thumbnailSize);
@ -588,9 +588,9 @@ void IndexerTrack::ProcessNonStandardMetadata(db::Connection& connection) {
}
static std::string createTrackExternalId(IndexerTrack& track) {
size_t hash1 = (size_t) hash32(track.GetString("filename").c_str());
size_t hash1 = hash32(track.GetString("filename").c_str());
size_t hash2 = (size_t) hash32(
size_t hash2 = hash32(
(track.GetString("title") +
track.GetString("album") +
track.GetString("artist") +
@ -821,9 +821,9 @@ bool IndexerTrack::Save(db::Connection &dbConnection, std::string libraryDirecto
thumbnailId = this->GetThumbnailId();
}
int64_t albumId = this->SaveAlbum(dbConnection, thumbnailId);
int64_t genreId = this->SaveGenre(dbConnection);
int64_t artistId = this->SaveArtist(dbConnection);
const int64_t albumId = this->SaveAlbum(dbConnection, thumbnailId);
const int64_t genreId = this->SaveGenre(dbConnection);
const int64_t artistId = this->SaveArtist(dbConnection);
int64_t albumArtistId = this->SaveSingleValueField(dbConnection, "album_artist", "artists");
/* ensure we have a correct source id */

View File

@ -43,33 +43,33 @@ namespace musik { namespace core {
class IndexerTrack: public Track {
public:
IndexerTrack(int64_t trackId);
virtual ~IndexerTrack(void);
virtual ~IndexerTrack();
/* ITagStore */
virtual void SetValue(const char* metakey, const char* value);
virtual void ClearValue(const char* metakey);
virtual bool Contains(const char* metakey);
virtual void SetThumbnail(const char *data, long size);
virtual bool ContainsThumbnail();
virtual void SetReplayGain(const musik::core::sdk::ReplayGain& replayGain);
void SetValue(const char* metakey, const char* value) override;
void ClearValue(const char* metakey) override;
bool Contains(const char* metakey) override;
void SetThumbnail(const char *data, long size) override;
bool ContainsThumbnail() override;
void SetReplayGain(const musik::core::sdk::ReplayGain& replayGain) override;
/* ITrack */
virtual std::string GetString(const char* metakey);
virtual int GetString(const char* key, char* dst, int size);
virtual long long GetInt64(const char* key, long long defaultValue = 0LL);
virtual int GetInt32(const char* key, unsigned int defaultValue = 0);
virtual double GetDouble(const char* key, double defaultValue = 0.0f);
virtual std::string Uri();
virtual int Uri(char* dst, int size);
virtual musik::core::sdk::ReplayGain GetReplayGain();
virtual musik::core::sdk::MetadataState GetMetadataState();
std::string GetString(const char* metakey) override;
int GetString(const char* key, char* dst, int size) override;
long long GetInt64(const char* key, long long defaultValue = 0LL) override;
int GetInt32(const char* key, unsigned int defaultValue = 0) override;
double GetDouble(const char* key, double defaultValue = 0.0f) override;
std::string Uri() override;
int Uri(char* dst, int size) override;
musik::core::sdk::ReplayGain GetReplayGain() override;
musik::core::sdk::MetadataState GetMetadataState() override;
virtual MetadataIteratorRange GetValues(const char* metakey);
virtual MetadataIteratorRange GetAllValues();
virtual TrackPtr Copy();
virtual int64_t GetId();
virtual void SetId(int64_t trackId) { this->trackId = trackId; }
virtual void SetMetadataState(musik::core::sdk::MetadataState state);
MetadataIteratorRange GetValues(const char* metakey) override;
MetadataIteratorRange GetAllValues() override;
TrackPtr Copy() override;
int64_t GetId() override;
void SetId(int64_t trackId) noexcept override { this->trackId = trackId; }
void SetMetadataState(musik::core::sdk::MetadataState state) override;
bool NeedsToBeIndexed(
const boost::filesystem::path &file,

View File

@ -40,7 +40,7 @@
using namespace musik::core;
using namespace musik::core::sdk;
LibraryTrack::LibraryTrack()
LibraryTrack::LibraryTrack() noexcept
: id(0)
, libraryId(0)
, gain(nullptr)
@ -158,15 +158,15 @@ void LibraryTrack::SetReplayGain(const ReplayGain& replayGain) {
*this->gain = replayGain;
}
MetadataState LibraryTrack::GetMetadataState() {
MetadataState LibraryTrack::GetMetadataState() noexcept {
return this->state;
}
void LibraryTrack::SetMetadataState(musik::core::sdk::MetadataState state) {
void LibraryTrack::SetMetadataState(musik::core::sdk::MetadataState state) noexcept {
this->state = state;
}
ReplayGain LibraryTrack::GetReplayGain() {
ReplayGain LibraryTrack::GetReplayGain() noexcept {
if (this->gain) {
return *gain;
}
@ -195,22 +195,20 @@ Track::MetadataIteratorRange LibraryTrack::GetValues(const char* metakey) {
return this->metadata.equal_range(metakey);
}
Track::MetadataIteratorRange LibraryTrack::GetAllValues() {
Track::MetadataIteratorRange LibraryTrack::GetAllValues() noexcept {
return Track::MetadataIteratorRange(
this->metadata.begin(),
this->metadata.end());
return Track::MetadataIteratorRange();
}
int64_t LibraryTrack::GetId() {
int64_t LibraryTrack::GetId() noexcept {
return this->id;
}
int LibraryTrack::LibraryId() {
int LibraryTrack::LibraryId() noexcept {
return this->libraryId;
}
TrackPtr LibraryTrack::Copy() {
return TrackPtr(new LibraryTrack(this->id, this->libraryId));
return std::make_shared<LibraryTrack>(this->id, this->libraryId);
}

View File

@ -45,40 +45,40 @@ namespace musik { namespace core {
class LibraryTrack: public Track {
public:
LibraryTrack();
LibraryTrack() noexcept;
LibraryTrack(int64_t id, int libraryId);
LibraryTrack(int64_t id, musik::core::ILibraryPtr library);
virtual ~LibraryTrack();
virtual int LibraryId();
int LibraryId() noexcept override;
virtual int64_t GetId();
virtual void SetId(int64_t id) { this->id = id; }
int64_t GetId() noexcept override;
void SetId(int64_t id) noexcept override { this->id = id; }
virtual std::string GetString(const char* metakey);
virtual std::string Uri();
std::string GetString(const char* metakey) override;
std::string Uri() override;
/* ITagStore */
virtual void SetValue(const char* metakey, const char* value);
virtual void ClearValue(const char* metakey);
virtual bool Contains(const char* metakey);
virtual void SetThumbnail(const char *data, long size);
virtual bool ContainsThumbnail();
virtual void SetReplayGain(const musik::core::sdk::ReplayGain& replayGain);
void SetValue(const char* metakey, const char* value) override;
void ClearValue(const char* metakey) override;
bool Contains(const char* metakey) override;
void SetThumbnail(const char* data, long size) override;
bool ContainsThumbnail() override;
void SetReplayGain(const musik::core::sdk::ReplayGain& replayGain) override;
/* ITrack */
virtual long long GetInt64(const char* key, long long defaultValue = 0LL);
virtual int GetInt32(const char* key, unsigned int defaultValue = 0);
virtual double GetDouble(const char* key, double defaultValue = 0.0f);
virtual int GetString(const char* key, char* dst, int size);
virtual int Uri(char* dst, int size);
virtual musik::core::sdk::ReplayGain GetReplayGain();
virtual musik::core::sdk::MetadataState GetMetadataState();
virtual void SetMetadataState(musik::core::sdk::MetadataState state);
long long GetInt64(const char* key, long long defaultValue = 0LL) override;
int GetInt32(const char* key, unsigned int defaultValue = 0) override;
double GetDouble(const char* key, double defaultValue = 0.0f) override;
int GetString(const char* key, char* dst, int size) override;
int Uri(char* dst, int size) override;
musik::core::sdk::ReplayGain GetReplayGain() noexcept override;
musik::core::sdk::MetadataState GetMetadataState() noexcept override;
void SetMetadataState(musik::core::sdk::MetadataState state) noexcept override;
virtual MetadataIteratorRange GetValues(const char* metakey);
virtual MetadataIteratorRange GetAllValues();
virtual TrackPtr Copy();
MetadataIteratorRange GetValues(const char* metakey) override;
MetadataIteratorRange GetAllValues() noexcept override;
TrackPtr Copy() override;
private:
int64_t id;

View File

@ -44,21 +44,22 @@ using namespace musik::core::sdk;
class SdkWrapper : public Track {
public:
SdkWrapper(TrackPtr track) {
DELETE_CLASS_DEFAULTS(SdkWrapper)
SdkWrapper(TrackPtr track) noexcept {
this->track = track;
this->count = 1;
}
virtual ~SdkWrapper() {
}
virtual void Retain() override {
void Retain() noexcept override {
++this->count;
}
virtual void Release() override {
int c = this->count.fetch_sub(1);
void Release() noexcept override {
const int c = this->count.fetch_sub(1);
if (c == 1) { /* fetched before sub */
this->count = 0;
this->track.reset();
@ -66,66 +67,66 @@ class SdkWrapper : public Track {
}
}
virtual int64_t GetId() override {
int64_t GetId() override {
return track->GetId();
}
virtual int GetString(const char* key, char* dst, int size) override {
int GetString(const char* key, char* dst, int size) override {
return track->GetString(key, dst, size);
}
virtual long long GetInt64(const char* key, long long defaultValue) override {
long long GetInt64(const char* key, long long defaultValue) override {
return track->GetInt64(key, defaultValue);
}
virtual int GetInt32(const char* key, unsigned int defaultValue) override {
int GetInt32(const char* key, unsigned int defaultValue) override {
return track->GetInt32(key, defaultValue);
}
virtual double GetDouble(const char* key, double defaultValue) override {
double GetDouble(const char* key, double defaultValue) override {
return track->GetDouble(key, defaultValue);
}
virtual int Uri(char* dst, int size) override {
int Uri(char* dst, int size) override {
return track->Uri(dst, size);
}
virtual IResource::Class GetClass() override {
IResource::Class GetClass() override {
return track->GetClass();
}
virtual const char* GetType() override {
const char* GetType() override {
return track->GetType();
}
virtual size_t GetValue(char* dst, size_t size) override {
size_t GetValue(char* dst, size_t size) override {
return track->GetValue(dst, size);
}
virtual ReplayGain GetReplayGain() override {
ReplayGain GetReplayGain() override {
return track->GetReplayGain();
}
virtual MetadataState GetMetadataState() override {
MetadataState GetMetadataState() override {
return track->GetMetadataState();
}
/* pure virtual methods defined by Track, but not defined in ITrack. therefore,
these methods cannot be called by the SDK, and should throw. */
#define NO_IMPL throw std::runtime_error("not implemented");
virtual void SetValue(const char* key, const char* value) override { NO_IMPL }
virtual void ClearValue(const char* key) override { NO_IMPL }
virtual void SetThumbnail(const char *data, long size) override { NO_IMPL }
virtual bool Contains(const char* key) override { NO_IMPL }
virtual bool ContainsThumbnail() override { NO_IMPL }
virtual void SetReplayGain(const ReplayGain& replayGain) override { NO_IMPL }
virtual void SetId(int64_t id) override { NO_IMPL }
virtual std::string GetString(const char* metakey) override { NO_IMPL }
virtual std::string Uri() override { NO_IMPL }
virtual MetadataIteratorRange GetValues(const char* metakey) override { NO_IMPL }
virtual MetadataIteratorRange GetAllValues() override { NO_IMPL }
virtual TrackPtr Copy() override { NO_IMPL }
virtual void SetMetadataState(MetadataState state) override { NO_IMPL }
void SetValue(const char* key, const char* value) override { NO_IMPL }
void ClearValue(const char* key) override { NO_IMPL }
void SetThumbnail(const char *data, long size) override { NO_IMPL }
bool Contains(const char* key) override { NO_IMPL }
bool ContainsThumbnail() override { NO_IMPL }
void SetReplayGain(const ReplayGain& replayGain) override { NO_IMPL }
void SetId(int64_t id) override { NO_IMPL }
std::string GetString(const char* metakey) override { NO_IMPL }
std::string Uri() override { NO_IMPL }
MetadataIteratorRange GetValues(const char* metakey) override { NO_IMPL }
MetadataIteratorRange GetAllValues() override { NO_IMPL }
TrackPtr Copy() override { NO_IMPL }
void SetMetadataState(MetadataState state) override { NO_IMPL }
#undef NO_IMPL
private:
@ -135,27 +136,24 @@ class SdkWrapper : public Track {
/* * * * Track * * * */
Track::~Track() {
}
int64_t Track::GetId() {
return 0;
}
ILibraryPtr Track::Library() {
ILibraryPtr Track::Library() noexcept {
static ILibraryPtr nullLibrary;
return nullLibrary;
}
int Track::LibraryId() {
int Track::LibraryId() noexcept{
return 0;
}
void Track::Retain() {
void Track::Retain() noexcept {
/* nothing. SdkWrapper implements as necessary */
}
void Track::Release() {
void Track::Release() noexcept {
/* same as Retain() */
}
@ -179,11 +177,11 @@ size_t Track::GetValue(char* dst, size_t count) {
template<typename T>
struct NoDeleter {
void operator()(T* t) {
void operator()(T* t) noexcept {
}
};
TagStore::TagStore(TrackPtr track) {
TagStore::TagStore(TrackPtr track) noexcept {
this->count = 1;
this->track = track;
}
@ -213,8 +211,8 @@ void TagStore::SetThumbnail(const char *data, long size) {
this->track->SetThumbnail(data, size);
}
void TagStore::Release() {
int c = this->count.fetch_sub(1);
void TagStore::Release() noexcept {
const int c = this->count.fetch_sub(1);
if (c == 1) { /* fetched before sub */
this->count = 0;
this->track.reset();
@ -226,6 +224,6 @@ void TagStore::SetReplayGain(const ReplayGain& replayGain) {
this->track->SetReplayGain(replayGain);
}
void TagStore::Retain() {
void TagStore::Retain() noexcept {
++this->count;
}

View File

@ -34,6 +34,7 @@
#pragma once
#include <musikcore/support/DeleteDefaults.h>
#include <musikcore/sdk/ITagStore.h>
#include <musikcore/library/ILibrary.h>
#include <musikcore/sdk/ITrack.h>
@ -54,39 +55,37 @@ namespace musik { namespace core {
typedef std::multimap<std::string, std::string> MetadataMap;
typedef std::pair<MetadataMap::iterator, MetadataMap::iterator> MetadataIteratorRange;
virtual ~Track();
virtual musik::core::ILibraryPtr Library();
virtual int LibraryId();
virtual musik::core::ILibraryPtr Library() noexcept;
virtual int LibraryId() noexcept;
/* ITrack is a ready only interface; we use the ITagStore interface
for writing. we replicate the interface here, and have TagStore pass
through to us */
virtual void SetValue(const char* key, const char* value) = 0;
virtual void ClearValue(const char* key) = 0;
virtual void SetThumbnail(const char *data, long size) = 0;
virtual void SetThumbnail(const char* data, long size) = 0;
virtual bool Contains(const char* key) = 0;
virtual bool ContainsThumbnail() = 0;
virtual void SetReplayGain(const musik::core::sdk::ReplayGain& replayGain) = 0;
/* IResource */
virtual int64_t GetId() override;
virtual Class GetClass() override;
virtual const char* GetType() override;
int64_t GetId() override;
Class GetClass() override;
const char* GetType() override;
/* IValue */
virtual size_t GetValue(char* dst, size_t size) override;
size_t GetValue(char* dst, size_t size) override;
/* IMap */
virtual void Release() override;
virtual int GetString(const char* key, char* dst, int size) override = 0;
virtual long long GetInt64(const char* key, long long defaultValue = 0LL) override = 0;
virtual int GetInt32(const char* key, unsigned int defaultValue = 0) override = 0;
virtual double GetDouble(const char* key, double defaultValue = 0.0f) override = 0;
void Release() noexcept override;
int GetString(const char* key, char* dst, int size) override = 0;
long long GetInt64(const char* key, long long defaultValue = 0LL) override = 0;
int GetInt32(const char* key, unsigned int defaultValue = 0) override = 0;
double GetDouble(const char* key, double defaultValue = 0.0f) override = 0;
/* ITrack */
virtual void Retain() override;
virtual int Uri(char* dst, int size) override = 0;
void Retain() noexcept override;
int Uri(char* dst, int size) override = 0;
/* implementation specific */
virtual void SetId(int64_t id) = 0;
@ -103,21 +102,25 @@ namespace musik { namespace core {
class TagStore : public musik::core::sdk::ITagStore {
public:
TagStore(TrackPtr track);
DELETE_CLASS_DEFAULTS(TagStore)
TagStore(TrackPtr track) noexcept;
TagStore(Track& track);
virtual ~TagStore() noexcept { }
template <typename T> T As() {
return dynamic_cast<T>(track.get());
}
virtual void Retain() override;
virtual void Release() override;
virtual void SetValue(const char* key, const char* value) override;
virtual void ClearValue(const char* key) override;
virtual bool Contains(const char* key) override;
virtual bool ContainsThumbnail() override;
virtual void SetThumbnail(const char *data, long size) override;
virtual void SetReplayGain(const musik::core::sdk::ReplayGain& replayGain) override;
void Retain() noexcept override;
void Release() noexcept override;
void SetValue(const char* key, const char* value) override;
void ClearValue(const char* key) override;
bool Contains(const char* key) override;
bool ContainsThumbnail() override;
void SetThumbnail(const char* data, long size) override;
void SetReplayGain(const musik::core::sdk::ReplayGain& replayGain) override;
private:
TrackPtr track;

View File

@ -44,6 +44,7 @@
#include <musikcore/library/query/util/SdkWrappers.h>
#include <musikcore/db/Connection.h>
#include <musikcore/db/Statement.h>
#include <musikcore/support/NarrowCast.h>
#include <unordered_set>
#include <map>
@ -53,8 +54,8 @@ using namespace musik::core::library;
using namespace musik::core::library::query;
using namespace musik::core::sdk;
static const size_t kDefaultCacheSize = 50;
static const int64_t kCacheWindowTimeoutMs = 150LL;
static constexpr size_t kDefaultCacheSize = 50;
static constexpr int64_t kCacheWindowTimeoutMs = 150LL;
TrackList::TrackList(ILibraryPtr library)
: library(library)
@ -70,16 +71,12 @@ TrackList::TrackList(TrackList* other)
TrackList::TrackList(ILibraryPtr library, const int64_t* trackIds, size_t trackIdCount)
: library(library)
, cacheSize(kDefaultCacheSize) {
if (trackIdCount > 0) {
if (trackIds != nullptr && trackIdCount > 0) {
this->ids.insert(this->ids.end(), &trackIds[0], &trackIds[trackIdCount]);
}
}
TrackList::~TrackList() {
}
size_t TrackList::Count() const {
size_t TrackList::Count() const noexcept {
return ids.size();
}
@ -88,7 +85,7 @@ void TrackList::Add(const int64_t id) {
}
bool TrackList::Insert(int64_t id, size_t index) {
if (index < (int) this->ids.size()) {
if (index < narrow_cast<int>(this->ids.size())) {
this->ids.insert(this->ids.begin() + index, id);
return true;
}
@ -97,20 +94,20 @@ bool TrackList::Insert(int64_t id, size_t index) {
}
bool TrackList::Swap(size_t index1, size_t index2) {
auto size = this->ids.size();
const auto size = this->ids.size();
if (index1 < size && index2 < size) {
auto temp = this->ids[index1];
this->ids[index1] = this->ids[index2];
this->ids[index2] = temp;
auto temp = this->ids.at(index1);
this->ids.at(index1) = this->ids.at(index2);
this->ids.at(index2) = temp;
return true;
}
return false;
}
bool TrackList::Move(size_t from, size_t to) {
auto size = this->ids.size();
const auto size = this->ids.size();
if (from < size && to < size && from != to) {
auto temp = this->ids[from];
auto temp = this->ids.at(from);
this->ids.erase(this->ids.begin() + from);
this->ids.insert(this->ids.begin() + to, temp);
return true;
@ -119,7 +116,7 @@ bool TrackList::Move(size_t from, size_t to) {
}
bool TrackList::Delete(size_t index) {
if (index < (int) this->ids.size()) {
if (index < narrow_cast<int>(this->ids.size())) {
this->ids.erase(this->ids.begin() + index);
return true;
}
@ -153,17 +150,17 @@ TrackPtr TrackList::Get(size_t index, bool async) const {
auto cached = this->GetFromCache(id);
if (cached) { return cached; }
int half = ((int) this->cacheSize - 1) / 2;
int remain = (int) this->cacheSize - 1;
int from = (int) index - half;
const int half = (narrow_cast<int>(this->cacheSize) - 1) / 2;
int remain = narrow_cast<int>(this->cacheSize) - 1;
const int from = narrow_cast<int>(index) - half;
remain -= from > 0 ? half : (half + from);
int to = (int) index + remain;
const int to = narrow_cast<int>(index) + remain;
this->CacheWindow(std::max(0, from), to, async);
cached = this->GetFromCache(id);
if (async && !cached) {
auto loadingTrack = std::make_shared<LibraryTrack>(this->ids[index], this->library);
auto loadingTrack = std::make_shared<LibraryTrack>(this->ids.at(index), this->library);
loadingTrack->SetMetadataState(MetadataState::Loading);
return loadingTrack;
}
@ -211,24 +208,24 @@ void TrackList::CopyTo(TrackList& to) {
int TrackList::IndexOf(int64_t id) const {
auto it = std::find(this->ids.begin(), this->ids.end(), id);
return (it == this->ids.end()) ? -1 : it - this->ids.begin();
return narrow_cast<int>((it == this->ids.end()) ? -1 : it - this->ids.begin());
}
void TrackList::Shuffle() {
std::random_shuffle(this->ids.begin(), this->ids.end());
}
void TrackList::Clear() {
void TrackList::Clear() noexcept {
this->ClearCache();
this->ids.clear();
}
void TrackList::ClearCache() {
void TrackList::ClearCache() noexcept {
this->cacheList.clear();
this->cacheMap.clear();
}
void TrackList::Swap(TrackList& tl) {
void TrackList::Swap(TrackList& tl) noexcept {
std::swap(tl.ids, this->ids);
}
@ -271,7 +268,7 @@ void TrackList::PruneCache() const {
void TrackList::CacheWindow(size_t from, size_t to, bool async) const {
std::unordered_set<int64_t> idsNotInCache;
for (size_t i = from; i <= std::min(to, this->ids.size() - 1); i++) {
auto id = this->ids[i];
auto id = this->ids.at(i);
if (this->cacheMap.find(id) == this->cacheMap.end()) {
if (async && currentWindow.Contains(i)) {
continue;
@ -307,7 +304,8 @@ void TrackList::CacheWindow(size_t from, size_t to, bool async) const {
}
this->currentWindow.Reset();
if (this->nextWindow.Valid()) {
size_t from = nextWindow.from, to = nextWindow.to;
const size_t from = nextWindow.from;
const size_t to = nextWindow.to;
nextWindow.Reset();
this->CacheWindow(from, to, true);
}
@ -317,7 +315,7 @@ void TrackList::CacheWindow(size_t from, size_t to, bool async) const {
this->library->EnqueueAndWait(query, kCacheWindowTimeoutMs, completion);
auto status = query->GetStatus();
const auto status = query->GetStatus();
if (status != IQuery::Idle && status != IQuery::Running) {
completion(query);
}
@ -349,11 +347,11 @@ ITrackList* TrackList::GetSdkValue() {
template <typename T>
struct NoDeleter {
void operator()(T* t) {
void operator()(T* t) noexcept {
}
};
TrackListEditor::TrackListEditor(std::shared_ptr<TrackList> trackList) {
TrackListEditor::TrackListEditor(std::shared_ptr<TrackList> trackList) noexcept {
this->trackList = trackList;
}
@ -361,9 +359,6 @@ TrackListEditor::TrackListEditor(TrackList& trackList) {
this->trackList = std::shared_ptr<TrackList>(&trackList, NoDeleter<TrackList>());
}
TrackListEditor::~TrackListEditor() {
}
void TrackListEditor::Add(const int64_t id) {
this->trackList->Add(id);
}

View File

@ -59,14 +59,12 @@ namespace musik { namespace core {
TrackList(TrackList* other);
TrackList(ILibraryPtr library, const int64_t* trackIds, size_t trackIdCount);
virtual ~TrackList();
/* ITrackList */
virtual size_t Count() const;
virtual int64_t GetId(size_t index) const;
virtual int IndexOf(int64_t id) const;
virtual musik::core::sdk::ITrack* GetTrack(size_t index) const;
virtual void Release() { /* not used now */ }
size_t Count() const noexcept override;
int64_t GetId(size_t index) const override;
int IndexOf(int64_t id) const override;
musik::core::sdk::ITrack* GetTrack(size_t index) const override;
void Release() noexcept override { /* not used now */ }
/* TrackListEditor passes through to us */
void Add(const int64_t id);
@ -74,14 +72,14 @@ namespace musik { namespace core {
bool Swap(size_t index1, size_t index2);
bool Move(size_t from, size_t to);
bool Delete(size_t index);
void Clear();
void Clear() noexcept;
void Shuffle();
/* implementation specific */
TrackPtr Get(size_t index, bool async = false) const;
TrackPtr GetWithTimeout(size_t index, size_t timeoutMs) const;
void ClearCache();
void Swap(TrackList& list);
void ClearCache() noexcept;
void Swap(TrackList& list) noexcept;
void CopyFrom(const TrackList& from);
void CopyTo(TrackList& to);
void CacheWindow(size_t from, size_t to, bool async) const;
@ -94,10 +92,10 @@ namespace musik { namespace core {
struct QueryWindow {
size_t from{ 0 };
size_t to{ 0 };
bool Contains(size_t i) { return to > 0 && i >= from && i <= to; }
void Reset() { from = to = 0; }
bool Valid() { return to > 0 && to > from; }
void Set(size_t from, size_t to) { this->from = from; this->to = to; }
bool Contains(size_t i) noexcept { return to > 0 && i >= from && i <= to; }
void Reset() noexcept { from = to = 0; }
bool Valid() noexcept { return to > 0 && to > from; }
void Set(size_t from, size_t to) noexcept { this->from = from; this->to = to; }
};
typedef std::list<int64_t> CacheList;
@ -121,19 +119,19 @@ namespace musik { namespace core {
class TrackListEditor : public musik::core::sdk::ITrackListEditor {
public:
TrackListEditor(std::shared_ptr<TrackList> trackList);
TrackListEditor(std::shared_ptr<TrackList> trackList) noexcept;
TrackListEditor(TrackList& trackList);
virtual ~TrackListEditor();
virtual ~TrackListEditor() { }
virtual void Add(const int64_t id);
virtual bool Insert(int64_t id, size_t index);
virtual bool Swap(size_t index1, size_t index2);
virtual bool Move(size_t from, size_t to);
virtual bool Delete(size_t index);
virtual void Clear();
virtual void Shuffle();
virtual void Release() { /* nothing yet */ }
void Add(const int64_t id) override;
bool Insert(int64_t id, size_t index) override;
bool Swap(size_t index1, size_t index2) override;
bool Move(size_t from, size_t to) override;
bool Delete(size_t index) override;
void Clear() override;
void Shuffle() override;
void Release() noexcept override { /* nothing yet */ }
private:
std::shared_ptr<TrackList> trackList;

View File

@ -705,9 +705,11 @@
<ClInclude Include="sdk\String.h" />
<ClInclude Include="support\Auddio.h" />
<ClInclude Include="support\Common.h" />
<ClInclude Include="support\DeleteDefaults.h" />
<ClInclude Include="support\Duration.h" />
<ClInclude Include="support\LastFm.h" />
<ClInclude Include="support\Messages.h" />
<ClInclude Include="support\NarrowCast.h" />
<ClInclude Include="support\Playback.h" />
<ClInclude Include="support\PreferenceKeys.h" />
<ClInclude Include="support\Preferences.h" />

View File

@ -648,5 +648,11 @@
<ClInclude Include="db\SqliteExtensions.h">
<Filter>src\db</Filter>
</ClInclude>
<ClInclude Include="support\NarrowCast.h">
<Filter>src\support</Filter>
</ClInclude>
<ClInclude Include="support\DeleteDefaults.h">
<Filter>src\support</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -35,9 +35,13 @@
#pragma once
#include <musikcore/config.h>
#pragma warning(push, 0)
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#pragma warning(pop)
#include <atomic>
#include <memory>
#include <functional>

View File

@ -40,7 +40,10 @@
#include <musikcore/support/Preferences.h>
#include <musikcore/runtime/Message.h>
#include <musikcore/version.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
using namespace musik::core;
using namespace musik::core::net;

149
src/musikcore/pch.cmake Normal file
View File

@ -0,0 +1,149 @@
target_precompile_headers(musikcore
PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:<boost/asio/basic_socket_streambuf.hpp$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<set$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<vector$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<map$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<string$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<algorithm$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<unordered_map$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<thread$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<cmath$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<string$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<boost/filesystem.hpp$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<boost/algorithm/string/case_conv.hpp$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<boost/algorithm/string.hpp$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<nlohmann/json.hpp$<ANGLE-R>>"
"$<$<COMPILE_LANGUAGE:CXX>:<sigslot/sigslot.h$<ANGLE-R>>"
PUBLIC
"$<$<COMPILE_LANGUAGE:CXX>:config.h>"
"$<$<COMPILE_LANGUAGE:CXX>:i18n/Locale.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/Buffer.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/Crossfader.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/CrossfadeTransport.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/GaplessTransport.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/IStream.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/ITransport.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/MasterTransport.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/Outputs.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/PlaybackService.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/Player.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/Stream.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/Streams.h>"
"$<$<COMPILE_LANGUAGE:CXX>:audio/Visualizer.h>"
"$<$<COMPILE_LANGUAGE:CXX>:db/Connection.h>"
"$<$<COMPILE_LANGUAGE:CXX>:db/ScopedTransaction.h>"
"$<$<COMPILE_LANGUAGE:CXX>:db/SqliteExtensions.h>"
"$<$<COMPILE_LANGUAGE:CXX>:db/Statement.h>"
"$<$<COMPILE_LANGUAGE:CXX>:debug.h>"
"$<$<COMPILE_LANGUAGE:CXX>:io/DataStreamFactory.h>"
"$<$<COMPILE_LANGUAGE:CXX>:io/LocalFileStream.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/IIndexer.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/ILibrary.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/Indexer.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/IQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/LibraryFactory.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/LocalLibrary.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/LocalLibraryConstants.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/LocalMetadataProxy.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/MasterLibrary.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/metadata/MetadataMap.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/metadata/MetadataMapList.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/AlbumListQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/AllCategoriesQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/AppendPlaylistQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/CategoryListQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/CategoryTrackListQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/DeletePlaylistQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/DirectoryTrackListQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/GetPlaylistQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/LyricsQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/MarkTrackPlayedQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/NowPlayingTrackListQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/PersistedPlayQueueQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/SavePlaylistQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/SearchTrackListQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/SetTrackRatingQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/TrackListQueryBase.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/TrackMetadataBatchQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/TrackMetadataQuery.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/util/CategoryQueryUtil.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/util/SdkWrappers.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/util/Serialization.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/util/TrackQueryFragments.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/query/util/TrackSort.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/QueryBase.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/QueryRegistry.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/RemoteLibrary.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/track/IndexerTrack.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/track/LibraryTrack.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/track/Track.h>"
"$<$<COMPILE_LANGUAGE:CXX>:library/track/TrackList.h>"
"$<$<COMPILE_LANGUAGE:CXX>:net/RawWebSocketClient.h>"
"$<$<COMPILE_LANGUAGE:CXX>:net/WebSocketClient.h>"
"$<$<COMPILE_LANGUAGE:CXX>:plugin/PluginFactory.h>"
"$<$<COMPILE_LANGUAGE:CXX>:plugin/Plugins.h>"
"$<$<COMPILE_LANGUAGE:CXX>:runtime/IMessage.h>"
"$<$<COMPILE_LANGUAGE:CXX>:runtime/IMessageQueue.h>"
"$<$<COMPILE_LANGUAGE:CXX>:runtime/IMessageTarget.h>"
"$<$<COMPILE_LANGUAGE:CXX>:runtime/Message.h>"
"$<$<COMPILE_LANGUAGE:CXX>:runtime/MessageQueue.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/constants.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/DataBuffer.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/Filesystem.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IAllocator.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IAnalyzer.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IBlockingEncoder.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IBuffer.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IBufferProvider.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IDataStream.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IDataStreamFactory.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IDebug.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IDecoder.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IDecoderFactory.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IDevice.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IDSP.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IEncoder.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IEncoderFactory.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IEnvironment.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IIndexerNotifier.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IIndexerSource.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IIndexerWriter.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IMap.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IMapList.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IMetadataProxy.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IOutput.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IPcmVisualizer.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IPlaybackRemote.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IPlaybackService.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IPlugin.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IPreferences.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IResource.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/ISchema.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/ISpectrumVisualizer.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IStreamingEncoder.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/ITagReader.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/ITagStore.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/ITrack.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/ITrackList.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/ITrackListEditor.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IValue.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IValueList.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/IVisualizer.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/ReplayGain.h>"
"$<$<COMPILE_LANGUAGE:CXX>:sdk/String.h>"
"$<$<COMPILE_LANGUAGE:CXX>:support/Auddio.h>"
"$<$<COMPILE_LANGUAGE:CXX>:support/Common.h>"
"$<$<COMPILE_LANGUAGE:CXX>:support/DeleteDefaults.h>"
"$<$<COMPILE_LANGUAGE:CXX>:support/Duration.h>"
"$<$<COMPILE_LANGUAGE:CXX>:support/LastFm.h>"
"$<$<COMPILE_LANGUAGE:CXX>:support/Messages.h>"
"$<$<COMPILE_LANGUAGE:CXX>:support/NarrowCast.h>"
"$<$<COMPILE_LANGUAGE:CXX>:support/Playback.h>"
"$<$<COMPILE_LANGUAGE:CXX>:support/PreferenceKeys.h>"
"$<$<COMPILE_LANGUAGE:CXX>:support/Preferences.h>"
"$<$<COMPILE_LANGUAGE:CXX>:utfutil.h>"
"$<$<COMPILE_LANGUAGE:CXX>:version.h>"
)

View File

@ -32,13 +32,6 @@
//
//////////////////////////////////////////////////////////////////////////////
#ifdef WIN32
#include <musikcore/config.h>
#include <sigslot/sigslot.h>
#include <musikcore/db/Connection.h>
#include <musikcore/db/Statement.h>
#endif
#include <set>
#include <vector>
#include <map>
@ -50,8 +43,142 @@
#include <cmath>
#include <string>
#include <musikcore/utfutil.h>
#pragma warning(push, 0)
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string.hpp>
#include <nlohmann/json.hpp>
#include <sigslot/sigslot.h>
#pragma warning(pop)
#include <musikcore/config.h>
#include <musikcore/i18n/Locale.h>
#include <musikcore/audio/Buffer.h>
#include <musikcore/audio/Crossfader.h>
#include <musikcore/audio/CrossfadeTransport.h>
#include <musikcore/audio/GaplessTransport.h>
#include <musikcore/audio/IStream.h>
#include <musikcore/audio/ITransport.h>
#include <musikcore/audio/MasterTransport.h>
#include <musikcore/audio/Outputs.h>
#include <musikcore/audio/PlaybackService.h>
#include <musikcore/audio/Player.h>
#include <musikcore/audio/Stream.h>
#include <musikcore/audio/Streams.h>
#include <musikcore/audio/Visualizer.h>
#include <musikcore/db/Connection.h>
#include <musikcore/db/ScopedTransaction.h>
#include <musikcore/db/SqliteExtensions.h>
#include <musikcore/db/Statement.h>
#include <musikcore/debug.h>
#include <musikcore/io/DataStreamFactory.h>
#include <musikcore/io/LocalFileStream.h>
#include <musikcore/library/IIndexer.h>
#include <musikcore/library/ILibrary.h>
#include <musikcore/library/Indexer.h>
#include <musikcore/library/IQuery.h>
#include <musikcore/library/LibraryFactory.h>
#include <musikcore/library/LocalLibrary.h>
#include <musikcore/library/LocalLibraryConstants.h>
#include <musikcore/library/LocalMetadataProxy.h>
#include <musikcore/library/MasterLibrary.h>
#include <musikcore/library/metadata/MetadataMap.h>
#include <musikcore/library/metadata/MetadataMapList.h>
#include <musikcore/library/query/AlbumListQuery.h>
#include <musikcore/library/query/AllCategoriesQuery.h>
#include <musikcore/library/query/AppendPlaylistQuery.h>
#include <musikcore/library/query/CategoryListQuery.h>
#include <musikcore/library/query/CategoryTrackListQuery.h>
#include <musikcore/library/query/DeletePlaylistQuery.h>
#include <musikcore/library/query/DirectoryTrackListQuery.h>
#include <musikcore/library/query/GetPlaylistQuery.h>
#include <musikcore/library/query/LyricsQuery.h>
#include <musikcore/library/query/MarkTrackPlayedQuery.h>
#include <musikcore/library/query/NowPlayingTrackListQuery.h>
#include <musikcore/library/query/PersistedPlayQueueQuery.h>
#include <musikcore/library/query/SavePlaylistQuery.h>
#include <musikcore/library/query/SearchTrackListQuery.h>
#include <musikcore/library/query/SetTrackRatingQuery.h>
#include <musikcore/library/query/TrackListQueryBase.h>
#include <musikcore/library/query/TrackMetadataBatchQuery.h>
#include <musikcore/library/query/TrackMetadataQuery.h>
#include <musikcore/library/query/util/CategoryQueryUtil.h>
#include <musikcore/library/query/util/SdkWrappers.h>
#include <musikcore/library/query/util/Serialization.h>
#include <musikcore/library/query/util/TrackQueryFragments.h>
#include <musikcore/library/query/util/TrackSort.h>
#include <musikcore/library/QueryBase.h>
#include <musikcore/library/QueryRegistry.h>
#include <musikcore/library/RemoteLibrary.h>
#include <musikcore/library/track/IndexerTrack.h>
#include <musikcore/library/track/LibraryTrack.h>
#include <musikcore/library/track/Track.h>
#include <musikcore/library/track/TrackList.h>
#include <musikcore/net/RawWebSocketClient.h>
#include <musikcore/net/WebSocketClient.h>
#include <musikcore/plugin/PluginFactory.h>
#include <musikcore/plugin/Plugins.h>
#include <musikcore/runtime/IMessage.h>
#include <musikcore/runtime/IMessageQueue.h>
#include <musikcore/runtime/IMessageTarget.h>
#include <musikcore/runtime/Message.h>
#include <musikcore/runtime/MessageQueue.h>
#include <musikcore/sdk/constants.h>
#include <musikcore/sdk/DataBuffer.h>
#include <musikcore/sdk/Filesystem.h>
#include <musikcore/sdk/IAllocator.h>
#include <musikcore/sdk/IAnalyzer.h>
#include <musikcore/sdk/IBlockingEncoder.h>
#include <musikcore/sdk/IBuffer.h>
#include <musikcore/sdk/IBufferProvider.h>
#include <musikcore/sdk/IDataStream.h>
#include <musikcore/sdk/IDataStreamFactory.h>
#include <musikcore/sdk/IDebug.h>
#include <musikcore/sdk/IDecoder.h>
#include <musikcore/sdk/IDecoderFactory.h>
#include <musikcore/sdk/IDevice.h>
#include <musikcore/sdk/IDSP.h>
#include <musikcore/sdk/IEncoder.h>
#include <musikcore/sdk/IEncoderFactory.h>
#include <musikcore/sdk/IEnvironment.h>
#include <musikcore/sdk/IIndexerNotifier.h>
#include <musikcore/sdk/IIndexerSource.h>
#include <musikcore/sdk/IIndexerWriter.h>
#include <musikcore/sdk/IMap.h>
#include <musikcore/sdk/IMapList.h>
#include <musikcore/sdk/IMetadataProxy.h>
#include <musikcore/sdk/IOutput.h>
#include <musikcore/sdk/IPcmVisualizer.h>
#include <musikcore/sdk/IPlaybackRemote.h>
#include <musikcore/sdk/IPlaybackService.h>
#include <musikcore/sdk/IPlugin.h>
#include <musikcore/sdk/IPreferences.h>
#include <musikcore/sdk/IResource.h>
#include <musikcore/sdk/ISchema.h>
#include <musikcore/sdk/ISpectrumVisualizer.h>
#include <musikcore/sdk/IStreamingEncoder.h>
#include <musikcore/sdk/ITagReader.h>
#include <musikcore/sdk/ITagStore.h>
#include <musikcore/sdk/ITrack.h>
#include <musikcore/sdk/ITrackList.h>
#include <musikcore/sdk/ITrackListEditor.h>
#include <musikcore/sdk/IValue.h>
#include <musikcore/sdk/IValueList.h>
#include <musikcore/sdk/IVisualizer.h>
#include <musikcore/sdk/ReplayGain.h>
#include <musikcore/sdk/String.h>
#include <musikcore/support/Auddio.h>
#include <musikcore/support/Common.h>
#include <musikcore/support/DeleteDefaults.h>
#include <musikcore/support/Duration.h>
#include <musikcore/support/LastFm.h>
#include <musikcore/support/Messages.h>
#include <musikcore/support/NarrowCast.h>
#include <musikcore/support/Playback.h>
#include <musikcore/support/PreferenceKeys.h>
#include <musikcore/support/Preferences.h>
#include <musikcore/utfutil.h>
#include <musikcore/version.h>

View File

@ -55,6 +55,7 @@
#include <musikcore/sdk/IIndexerNotifier.h>
#include <musikcore/sdk/IEnvironment.h>
using namespace musik;
using namespace musik::core;
using namespace musik::core::audio;
using namespace musik::core::library::query;
@ -71,7 +72,7 @@ static const std::string SUPEREQ_PLUGIN_GUID = "6f0ed53b-0f13-4220-9b0a-ca496b64
static IMessageQueue* messageQueue = nullptr;
static ILibraryPtr defaultLibrary;
static IPlaybackService* playback = nullptr;
static IPlaybackService* playbackService = nullptr;
static LocalMetadataProxy* metadataProxy = nullptr;
static std::shared_ptr<Preferences> playbackPrefs;
@ -192,8 +193,8 @@ static class Environment: public IEnvironment {
std::string currentDeviceId = currentDevice ? currentDevice->Id() : "";
if (newName != currentName || newDeviceId != currentDeviceId) {
outputs::SelectOutput(output);
if (::playback) {
playback->ReloadOutput();
if (::playbackService) {
playbackService->ReloadOutput();
}
}
saveEnvironment();
@ -213,8 +214,8 @@ static class Environment: public IEnvironment {
auto currentType = GetTransportType();
if (currentType != type) {
::playbackPrefs->SetInt(prefs::keys::Transport.c_str(), (int) type);
if (::playback) {
::playback->ReloadOutput();
if (::playbackService) {
::playbackService->ReloadOutput();
}
saveEnvironment();
}
@ -339,8 +340,8 @@ static class Environment: public IEnvironment {
}
virtual void ReloadPlaybackOutput() override {
if (playback) {
playback->ReloadOutput();
if (playbackService) {
playbackService->ReloadOutput();
}
}
@ -352,7 +353,7 @@ static class Environment: public IEnvironment {
namespace musik { namespace core { namespace plugin {
void Init(IMessageQueue* messageQueue, IPlaybackService* playback, ILibraryPtr library) {
void Init(IMessageQueue* messageQueue, IPlaybackService* playbackService, ILibraryPtr library) {
/* preferences */
Preferences::LoadPluginPreferences();
@ -367,7 +368,7 @@ namespace musik { namespace core { namespace plugin {
delete metadataProxy;
::messageQueue = messageQueue;
::defaultLibrary = library;
::playback = playback;
::playbackService = playbackService;
::playbackPrefs = Preferences::ForComponent(prefs::components::Playback);
/* even if the local client is connected to a remote server, the metadata proxy
@ -417,7 +418,7 @@ namespace musik { namespace core { namespace plugin {
::messageQueue = nullptr;
::metadataProxy = nullptr;
::defaultLibrary.reset();
::playback = nullptr;
::playbackService = nullptr;
::playbackPrefs.reset();
/* indexer */

View File

@ -43,7 +43,7 @@ using namespace musik::core::runtime;
using LockT = std::unique_lock<std::mutex>;
MessageQueue::MessageQueue() {
MessageQueue::MessageQueue() noexcept {
this->nextMessageTime.store(1);
}
@ -57,7 +57,7 @@ void MessageQueue::WaitAndDispatch(int64_t timeoutMillis) {
system_clock::now().time_since_epoch());
if (timeoutMillis >= 0) {
auto timeoutDuration = milliseconds(timeoutMillis);
const auto timeoutDuration = milliseconds(timeoutMillis);
if (waitTime > timeoutDuration) {
waitTime = timeoutDuration;
}
@ -80,15 +80,11 @@ void MessageQueue::WaitAndDispatch(int64_t timeoutMillis) {
this->Dispatch();
}
MessageQueue::~MessageQueue() {
}
void MessageQueue::Dispatch() {
milliseconds now = duration_cast<milliseconds>(
const milliseconds now = duration_cast<milliseconds>(
system_clock::now().time_since_epoch());
int64_t nextTime = nextMessageTime.load();
const int64_t nextTime = nextMessageTime.load();
if (nextTime > now.count() || nextTime < 0) {
return; /* short circuit before any iteration. */
@ -131,7 +127,7 @@ void MessageQueue::Dispatch() {
Iterator it = this->dispatch.begin();
while (it != this->dispatch.end()) {
this->Dispatch((*it)->message);
this->Dispatch((*it)->message.get());
delete *it;
it++;
}
@ -246,7 +242,7 @@ void MessageQueue::Post(IMessagePtr message, int64_t delayMs) {
void MessageQueue::Enqueue(IMessagePtr message, int64_t delayMs) {
delayMs = std::max((int64_t) 0, delayMs);
milliseconds now = duration_cast<milliseconds>(
const milliseconds now = duration_cast<milliseconds>(
system_clock::now().time_since_epoch());
EnqueuedMessage *m = new EnqueuedMessage();
@ -286,7 +282,7 @@ void MessageQueue::Debounce(IMessagePtr message, int64_t delayMs) {
Post(message, delayMs);
}
void MessageQueue::Dispatch(IMessagePtr message) {
void MessageQueue::Dispatch(IMessage* message) {
if (message->Target()) {
message->Target()->ProcessMessage(*message);
}

View File

@ -47,8 +47,12 @@ namespace musik { namespace core { namespace runtime {
class MessageQueue : public IMessageQueue {
public:
MessageQueue();
virtual ~MessageQueue();
MessageQueue(const MessageQueue&) = delete;
MessageQueue(const MessageQueue&&) = delete;
MessageQueue& operator=(const MessageQueue&) = delete;
MessageQueue& operator=(const MessageQueue&&) = delete;
MessageQueue() noexcept;
void Post(IMessagePtr message, int64_t delayMs = 0) override;
void Broadcast(IMessagePtr message, int64_t messageMs = 0) override;
@ -63,7 +67,7 @@ namespace musik { namespace core { namespace runtime {
void Dispatch() override;
protected:
int64_t GetNextMessageTime() {
int64_t GetNextMessageTime() noexcept {
return nextMessageTime.load();
}
@ -71,6 +75,7 @@ namespace musik { namespace core { namespace runtime {
typedef std::weak_ptr<IMessageTarget> IWeakMessageTarget;
void Enqueue(IMessagePtr message, int64_t delayMs);
void Dispatch(IMessage* message);
struct EnqueuedMessage {
IMessagePtr message;
@ -91,8 +96,6 @@ namespace musik { namespace core { namespace runtime {
std::set<IMessageTarget*> targets;
std::condition_variable_any waitForDispatch;
std::atomic<int64_t> nextMessageTime;
void Dispatch(IMessagePtr message);
};
} } }

View File

@ -32,7 +32,12 @@
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#pragma warning(push, 0)
#include <curl/curl.h>
#pragma warning(pop)
#include <functional>
#include <algorithm>
#include <thread>

View File

@ -35,12 +35,16 @@
#include "pch.hpp"
#include "Auddio.h"
#include "Common.h"
#include <musikcore/support/NarrowCast.h>
#include <musikcore/sdk/HttpClient.h>
#include <musikcore/support/Preferences.h>
#include <musikcore/support/PreferenceKeys.h>
#include <curl/curl.h>
#include <sstream>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#include <curl/curl.h>
#pragma warning(pop)
/* https://api.audd.io/findLyrics/?q=the%20beatles%20sgt%20pepper%20reprise */
@ -56,7 +60,11 @@ static std::shared_ptr<AuddioClient> createClient() {
static std::string encode(std::string value) {
static CURL* curl = curl_easy_init();
if (curl && value.c_str()) {
char* encoded = curl_easy_escape(curl, value.c_str(), value.size());
char* encoded = curl_easy_escape(
curl,
value.c_str(),
narrow_cast<int>(value.size()));
if (encoded) {
value = encoded;
curl_free(encoded);

View File

@ -35,7 +35,7 @@
#include "pch.hpp"
#include <musikcore/support/Common.h>
#include <musikcore/config.h>
#include <utf8/utf8.h>
#include <cstdlib>
#include <iostream>
#include <fstream>
@ -45,6 +45,10 @@
#include <cctype>
#include <algorithm>
#pragma warning(push, 0)
#include <utf8/utf8.h>
#pragma warning(pop)
#ifdef WIN32
#include <shellapi.h>
#elif __APPLE__
@ -137,7 +141,8 @@ namespace musik { namespace core {
#else
std::string pathToProc = u8fmt("/proc/%d/exe", (int) getpid());
readlink(pathToProc.c_str(), pathbuf, PATH_MAX);
#endif
#endif
result.assign(pathbuf);
size_t last = result.find_last_of("/");
result = result.substr(0, last); /* remove filename component */
@ -260,7 +265,7 @@ namespace musik { namespace core {
}
*target = (char*)malloc(sizeof(char) * (fileSize + (nullTerminate ? 1 : 0)));
size = fread(*target, sizeof(char), fileSize, file);
size = narrow_cast<int>(fread(*target, sizeof(char), fileSize, file));
if (size == fileSize) {
if (nullTerminate) {

View File

@ -0,0 +1,55 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2020 musikcube team
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the author nor the names of other contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once
#define DELETE_CLASS_DEFAULTS(ClassName) \
ClassName() = delete; \
ClassName(const ClassName&) = delete; \
ClassName(const ClassName&&) = delete; \
ClassName& operator=(const ClassName&) = delete; \
ClassName& operator=(const ClassName&&) = delete;
#define DELETE_COPY_AND_ASSIGNMENT_DEFAULTS_WITH_DEFAULT_CTOR(ClassName) \
ClassName() noexcept = default; \
ClassName(const ClassName&) = delete; \
ClassName(const ClassName&&) = delete; \
ClassName& operator=(const ClassName&) = delete; \
ClassName& operator=(const ClassName&&) = delete;
#define DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(ClassName) \
ClassName(const ClassName&) = delete; \
ClassName(const ClassName&&) = delete; \
ClassName& operator=(const ClassName&) = delete; \
ClassName& operator=(const ClassName&&) = delete;

View File

@ -33,15 +33,21 @@
//////////////////////////////////////////////////////////////////////////////
#include "pch.hpp"
#include "LastFm.h"
#include <curl/curl.h>
#include <musikcore/support/Preferences.h>
#include <musikcore/sdk/HttpClient.h>
#include <musikcore/support/PreferenceKeys.h>
#include <nlohmann/json.hpp>
#include <sstream>
#include <map>
#pragma warning(push, 0)
#include <curl/curl.h>
#include <nlohmann/json.hpp>
#pragma warning(pop)
extern "C" {
#include <md5.h>
}

View File

@ -34,10 +34,12 @@
#pragma once
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#define WINVER 0x0502
#define _WIN32_WINNT 0x0502
#define NOMINMAX
#include <windows.h>
#endif
#include <cassert>
/* https://stackoverflow.com/a/46229281 */
template<class To, class From>
To narrow_cast(From v) {
To r = static_cast<To>(v);
assert(static_cast<From>(r) == v);
return r;
}

View File

@ -41,7 +41,10 @@
#include <musikcore/config.h>
#include <musikcore/db/Connection.h>
#include <musikcore/sdk/IPreferences.h>
#pragma warning(push, 0)
#include <nlohmann/json.hpp>
#pragma warning(pop)
namespace musik { namespace core {
class Preferences : public musik::core::sdk::IPreferences {
@ -69,28 +72,28 @@ namespace musik { namespace core {
/* IPreferences (for plugin use) */
virtual void Release() override;
virtual bool GetBool(const char* key, bool defaultValue = false) override;
virtual int GetInt(const char* key, int defaultValue = 0) override;
virtual double GetDouble(const char* key, double defaultValue = 0.0f) override;
virtual int GetString(const char* key, char* dst, size_t size, const char* defaultValue = "") override;
bool GetBool(const char* key, bool defaultValue = false) override;
int GetInt(const char* key, int defaultValue = 0) override;
double GetDouble(const char* key, double defaultValue = 0.0f) override;
int GetString(const char* key, char* dst, size_t size, const char* defaultValue = "") override;
virtual void SetBool(const char* key, bool value) override;
virtual void SetInt(const char* key, int value) override;
virtual void SetDouble(const char* key, double value) override;
virtual void SetString(const char* key, const char* value) override;
void SetBool(const char* key, bool value) override;
void SetInt(const char* key, int value) override;
void SetDouble(const char* key, double value) override;
void SetString(const char* key, const char* value) override;
virtual void Save() override;
void Save() override;
/* easier interface for internal use */
virtual bool GetBool(const std::string& key, bool defaultValue = false);
virtual int GetInt(const std::string& key, int defaultValue = 0);
virtual double GetDouble(const std::string& key, double defaultValue = 0.0f);
virtual std::string GetString(const std::string& key, const std::string& defaultValue = "");
bool GetBool(const std::string& key, bool defaultValue = false);
int GetInt(const std::string& key, int defaultValue = 0);
double GetDouble(const std::string& key, double defaultValue = 0.0f);
std::string GetString(const std::string& key, const std::string& defaultValue = "");
virtual void SetBool(const std::string& key, bool value);
virtual void SetInt(const std::string& key, int value);
virtual void SetDouble(const std::string& key, double value);
virtual void SetString(const std::string& key, const char* value);
void SetBool(const std::string& key, bool value);
void SetInt(const std::string& key, int value);
void SetDouble(const std::string& key, double value);
void SetString(const std::string& key, const char* value);
void GetKeys(std::vector<std::string>& target);
bool HasKey(const std::string& key);

View File

@ -2,12 +2,19 @@
#include <string>
#include <wchar.h>
#include <utf8/utf8.h>
#include <algorithm>
#include <memory>
#ifdef WIN32
#include <wcwidth.h>
#pragma warning(push, 0)
#include <utf8/utf8.h>
#ifdef WIN32
#include <wcwidth.h>
#endif
#pragma warning(pop)
#ifdef max
#undef max
#endif
inline std::wstring u8to16(const std::string& u8) {

View File

@ -107,3 +107,8 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
else()
target_link_libraries(musikcube ${musikcube_LINK_LIBS} curses panel musikcore)
endif()
if (ENABLE_PCH MATCHES "true")
message(STATUS "[musikcube] enabling precompiled headers")
include(./pch.cmake)
endif()

View File

@ -66,7 +66,7 @@ using namespace cursespp;
namespace keys = musik::cube::prefs::keys;
namespace components = musik::core::prefs::components;
static size_t MAX_CATEGORY_WIDTH = 40;
static int MAX_CATEGORY_WIDTH = 40;
static int MIN_LIST_TITLE_HEIGHT = 26;
#define DEFAULT_CATEGORY constants::Track::ARTIST
@ -127,10 +127,10 @@ BrowseLayout::~BrowseLayout() {
}
void BrowseLayout::OnLayout() {
size_t cx = this->GetWidth(), cy = this->GetHeight();
size_t x = 0, y = 0;
int cx = this->GetWidth(), cy = this->GetHeight();
int x = 0, y = 0;
size_t categoryWidth = std::min(MAX_CATEGORY_WIDTH, cx / 4);
int categoryWidth = std::min(MAX_CATEGORY_WIDTH, cx / 4);
this->categoryList->MoveAndResize(x, y, categoryWidth, cy);

Some files were not shown because too many files have changed in this diff Show More