mirror of
https://github.com/clangen/musikcube.git
synced 2024-10-02 04:52:32 +00:00
Merge branch 'master' of github.com:clangen/musikcube
This commit is contained in:
commit
daaa7c268f
@ -102,6 +102,10 @@ namespace musik {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Shutdown() {
|
||||||
|
HideSelectedVisualizer();
|
||||||
|
}
|
||||||
|
|
||||||
ISpectrumVisualizer* SpectrumVisualizer() {
|
ISpectrumVisualizer* SpectrumVisualizer() {
|
||||||
return spectrumVisualizer;
|
return spectrumVisualizer;
|
||||||
}
|
}
|
||||||
|
@ -48,5 +48,6 @@ namespace musik { namespace core { namespace audio { namespace vis {
|
|||||||
void SetSelectedVisualizer(std::shared_ptr<musik::core::sdk::IVisualizer> visualizer);
|
void SetSelectedVisualizer(std::shared_ptr<musik::core::sdk::IVisualizer> visualizer);
|
||||||
std::shared_ptr<musik::core::sdk::IVisualizer> SelectedVisualizer();
|
std::shared_ptr<musik::core::sdk::IVisualizer> SelectedVisualizer();
|
||||||
void HideSelectedVisualizer();
|
void HideSelectedVisualizer();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
} } } }
|
} } } }
|
||||||
|
@ -158,7 +158,7 @@ mcsdk_export void mcsdk_env_init() {
|
|||||||
mcsdk_export void mcsdk_env_release() {
|
mcsdk_export void mcsdk_env_release() {
|
||||||
if (environment_initialized) {
|
if (environment_initialized) {
|
||||||
LibraryFactory::Instance().Shutdown();
|
LibraryFactory::Instance().Shutdown();
|
||||||
debug::Stop();
|
debug::Shutdown();
|
||||||
message_queue->Quit();
|
message_queue->Quit();
|
||||||
message_queue_thread.join();
|
message_queue_thread.join();
|
||||||
delete message_queue;
|
delete message_queue;
|
||||||
@ -227,7 +227,7 @@ mcsdk_export void mcsdk_context_release(mcsdk_context** context) {
|
|||||||
delete internal->playback;
|
delete internal->playback;
|
||||||
|
|
||||||
internal->playback = nullptr;
|
internal->playback = nullptr;
|
||||||
internal->library->Indexer()->Stop();
|
internal->library->Indexer()->Shutdown();
|
||||||
internal->library.reset();
|
internal->library.reset();
|
||||||
internal->preferences.reset();
|
internal->preferences.reset();
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ mcsdk_export void mcsdk_context_release(mcsdk_context** context) {
|
|||||||
|
|
||||||
mcsdk_export void mcsdk_set_plugin_context(mcsdk_context* context) {
|
mcsdk_export void mcsdk_set_plugin_context(mcsdk_context* context) {
|
||||||
if (plugin_context && plugin_context != context) {
|
if (plugin_context && plugin_context != context) {
|
||||||
plugin::Deinit();
|
plugin::Shutdown();
|
||||||
}
|
}
|
||||||
plugin_context = context;
|
plugin_context = context;
|
||||||
if (plugin_context) {
|
if (plugin_context) {
|
||||||
|
@ -1243,7 +1243,7 @@ mcsdk_export void mcsdk_svc_indexer_schedule(mcsdk_svc_indexer in, mcsdk_svc_ind
|
|||||||
}
|
}
|
||||||
|
|
||||||
mcsdk_export void mcsdk_svc_indexer_stop(mcsdk_svc_indexer in) {
|
mcsdk_export void mcsdk_svc_indexer_stop(mcsdk_svc_indexer in) {
|
||||||
INDEXER(in)->Stop();
|
INDEXER(in)->Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
mcsdk_export mcsdk_svc_indexer_state mcsdk_svc_indexer_get_state(mcsdk_svc_indexer in) {
|
mcsdk_export mcsdk_svc_indexer_state mcsdk_svc_indexer_get_state(mcsdk_svc_indexer in) {
|
||||||
|
@ -182,7 +182,7 @@ void musik::debug::Start(std::vector<musik::debug::IBackend*> backends) {
|
|||||||
info("LOG SESSION", "---------- START ----------");
|
info("LOG SESSION", "---------- START ----------");
|
||||||
}
|
}
|
||||||
|
|
||||||
void musik::debug::Stop() {
|
void musik::debug::Shutdown() {
|
||||||
std::unique_lock<std::recursive_mutex> lock(mutex);
|
std::unique_lock<std::recursive_mutex> lock(mutex);
|
||||||
|
|
||||||
cancel = true;
|
cancel = true;
|
||||||
|
@ -83,7 +83,7 @@ namespace musik {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void Start(std::vector<IBackend*> backends = { new SimpleFileBackend() });
|
static void Start(std::vector<IBackend*> backends = { new SimpleFileBackend() });
|
||||||
static void Stop();
|
static void Shutdown();
|
||||||
|
|
||||||
static void verbose(const std::string& tag, const std::string& string) noexcept;
|
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 v(const std::string& tag, const std::string& string) noexcept;
|
||||||
|
@ -64,7 +64,7 @@ namespace musik { namespace core {
|
|||||||
virtual void RemovePath(const std::string& path) = 0;
|
virtual void RemovePath(const std::string& path) = 0;
|
||||||
virtual void GetPaths(std::vector<std::string>& paths) = 0;
|
virtual void GetPaths(std::vector<std::string>& paths) = 0;
|
||||||
virtual void Schedule(SyncType type) = 0;
|
virtual void Schedule(SyncType type) = 0;
|
||||||
virtual void Stop() = 0;
|
virtual void Shutdown() = 0;
|
||||||
virtual State GetState() = 0;
|
virtual State GetState() = 0;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
@ -140,10 +140,10 @@ Indexer::Indexer(const std::string& libraryPath, const std::string& dbFilename)
|
|||||||
|
|
||||||
Indexer::~Indexer() {
|
Indexer::~Indexer() {
|
||||||
closeLogFile();
|
closeLogFile();
|
||||||
this->Stop();
|
this->Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Indexer::Stop() {
|
void Indexer::Shutdown() {
|
||||||
if (this->thread) {
|
if (this->thread) {
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(this->stateMutex);
|
boost::mutex::scoped_lock lock(this->stateMutex);
|
||||||
|
@ -80,7 +80,7 @@ namespace musik { namespace core {
|
|||||||
void RemovePath(const std::string& path) override;
|
void RemovePath(const std::string& path) override;
|
||||||
void GetPaths(std::vector<std::string>& paths) override;
|
void GetPaths(std::vector<std::string>& paths) override;
|
||||||
void Schedule(SyncType type) override;
|
void Schedule(SyncType type) override;
|
||||||
void Stop() override;
|
void Shutdown() override;
|
||||||
|
|
||||||
State GetState() noexcept override {
|
State GetState() noexcept override {
|
||||||
return this->state;
|
return this->state;
|
||||||
|
@ -72,7 +72,7 @@ class NullIndexer: public musik::core::IIndexer {
|
|||||||
void RemovePath(const std::string& path) noexcept override { }
|
void RemovePath(const std::string& path) noexcept override { }
|
||||||
void GetPaths(std::vector<std::string>& paths) noexcept override { }
|
void GetPaths(std::vector<std::string>& paths) noexcept override { }
|
||||||
void Schedule(SyncType type) noexcept override { }
|
void Schedule(SyncType type) noexcept override { }
|
||||||
void Stop() noexcept override { }
|
void Shutdown() noexcept override { }
|
||||||
State GetState() noexcept override { return StateIdle; }
|
State GetState() noexcept override { return StateIdle; }
|
||||||
} kNullIndexer;
|
} kNullIndexer;
|
||||||
|
|
||||||
|
@ -49,6 +49,10 @@ using ClientPtr = PiggyWebSocketClient::ClientPtr;
|
|||||||
using ClientMessage = PiggyWebSocketClient::ClientMessage;
|
using ClientMessage = PiggyWebSocketClient::ClientMessage;
|
||||||
using Connection = PiggyWebSocketClient::Connection;
|
using Connection = PiggyWebSocketClient::Connection;
|
||||||
using Message = PiggyWebSocketClient::Message;
|
using Message = PiggyWebSocketClient::Message;
|
||||||
|
using MessageQueue = PiggyWebSocketClient::MessageQueue;
|
||||||
|
|
||||||
|
std::recursive_mutex instanceMutex;
|
||||||
|
static std::shared_ptr<PiggyWebSocketClient> instance;
|
||||||
|
|
||||||
static const int64_t kLatencyTimeoutMs = INT_MAX;
|
static const int64_t kLatencyTimeoutMs = INT_MAX;
|
||||||
static const int64_t kReconnectIntervalMs = 10000;
|
static const int64_t kReconnectIntervalMs = 10000;
|
||||||
@ -60,7 +64,21 @@ static inline std::string generateSessionId() {
|
|||||||
return "musikcube-" + std::to_string((unsigned long) time(nullptr));
|
return "musikcube-" + std::to_string((unsigned long) time(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
PiggyWebSocketClient::PiggyWebSocketClient(IMessageQueue* messageQueue)
|
std::shared_ptr<PiggyWebSocketClient> PiggyWebSocketClient::Instance(MessageQueue* messageQueue) {
|
||||||
|
std::unique_lock<decltype(instanceMutex)> lock(instanceMutex);
|
||||||
|
if (!instance) {
|
||||||
|
instance = std::shared_ptr<PiggyWebSocketClient>(new PiggyWebSocketClient(messageQueue));
|
||||||
|
}
|
||||||
|
instance->SetMessageQueue(messageQueue);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PiggyWebSocketClient::Shutdown() {
|
||||||
|
std::unique_lock<decltype(instanceMutex)> lock(instanceMutex);
|
||||||
|
instance.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
PiggyWebSocketClient::PiggyWebSocketClient(MessageQueue* messageQueue)
|
||||||
: messageQueue(nullptr)
|
: messageQueue(nullptr)
|
||||||
, sessionId(generateSessionId()) {
|
, sessionId(generateSessionId()) {
|
||||||
this->SetMessageQueue(messageQueue);
|
this->SetMessageQueue(messageQueue);
|
||||||
@ -157,7 +175,11 @@ void PiggyWebSocketClient::Connect(const std::string& host, unsigned short port,
|
|||||||
void PiggyWebSocketClient::Reconnect() {
|
void PiggyWebSocketClient::Reconnect() {
|
||||||
std::unique_lock<decltype(this->mutex)> lock(this->mutex);
|
std::unique_lock<decltype(this->mutex)> lock(this->mutex);
|
||||||
|
|
||||||
|
/* Disconnect() will reset the internal URI to implicitly disable auto-reconnect;
|
||||||
|
go ahead and cache it, disconnect, then restore it. */
|
||||||
|
auto originalUri = this->uri;
|
||||||
this->Disconnect();
|
this->Disconnect();
|
||||||
|
this->uri = originalUri;
|
||||||
|
|
||||||
#if BOOST_VERSION < 106600
|
#if BOOST_VERSION < 106600
|
||||||
io.reset();
|
io.reset();
|
||||||
@ -195,6 +217,7 @@ void PiggyWebSocketClient::Disconnect() {
|
|||||||
{
|
{
|
||||||
std::unique_lock<decltype(this->mutex)> lock(this->mutex);
|
std::unique_lock<decltype(this->mutex)> lock(this->mutex);
|
||||||
oldThread = std::unique_ptr<std::thread>(std::move(this->thread));
|
oldThread = std::unique_ptr<std::thread>(std::move(this->thread));
|
||||||
|
this->uri = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldThread) {
|
if (oldThread) {
|
||||||
@ -235,7 +258,8 @@ void PiggyWebSocketClient::SetState(State state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PiggyWebSocketClient::SetMessageQueue(IMessageQueue* messageQueue) {
|
void PiggyWebSocketClient::SetMessageQueue(MessageQueue* messageQueue) {
|
||||||
|
std::unique_lock<decltype(this->mutex)> lock(this->mutex);
|
||||||
if (messageQueue == this->messageQueue) {
|
if (messageQueue == this->messageQueue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -253,7 +277,7 @@ void PiggyWebSocketClient::SetMessageQueue(IMessageQueue* messageQueue) {
|
|||||||
void PiggyWebSocketClient::ProcessMessage(IMessage& message) {
|
void PiggyWebSocketClient::ProcessMessage(IMessage& message) {
|
||||||
if (message.Type() == kReconnectMessage) {
|
if (message.Type() == kReconnectMessage) {
|
||||||
std::unique_lock<decltype(this->mutex)> lock(this->mutex);
|
std::unique_lock<decltype(this->mutex)> lock(this->mutex);
|
||||||
if (this->state == State::Disconnected) {
|
if (this->state == State::Disconnected && this->uri.length()) {
|
||||||
this->Reconnect();
|
this->Reconnect();
|
||||||
}
|
}
|
||||||
this->messageQueue->Post(runtime::Message::Create(this, kReconnectMessage), kReconnectIntervalMs);
|
this->messageQueue->Post(runtime::Message::Create(this, kReconnectMessage), kReconnectIntervalMs);
|
||||||
|
@ -57,6 +57,7 @@ namespace musik { namespace core { namespace net {
|
|||||||
using ClientMessage = websocketpp::config::asio_client::message_type::ptr;
|
using ClientMessage = websocketpp::config::asio_client::message_type::ptr;
|
||||||
using Connection = websocketpp::connection_hdl;
|
using Connection = websocketpp::connection_hdl;
|
||||||
using Message = std::shared_ptr<nlohmann::json>;
|
using Message = std::shared_ptr<nlohmann::json>;
|
||||||
|
using MessageQueue = musik::core::runtime::IMessageQueue;
|
||||||
|
|
||||||
enum class State: int {
|
enum class State: int {
|
||||||
Disconnected = 0,
|
Disconnected = 0,
|
||||||
@ -73,7 +74,9 @@ namespace musik { namespace core { namespace net {
|
|||||||
|
|
||||||
sigslot::signal3<PiggyWebSocketClient*, State, State> StateChanged;
|
sigslot::signal3<PiggyWebSocketClient*, State, State> StateChanged;
|
||||||
|
|
||||||
PiggyWebSocketClient(musik::core::runtime::IMessageQueue* messageQueue);
|
static std::shared_ptr<PiggyWebSocketClient> Instance(MessageQueue* messageQueue);
|
||||||
|
static void Shutdown();
|
||||||
|
|
||||||
PiggyWebSocketClient(const PiggyWebSocketClient&) = delete;
|
PiggyWebSocketClient(const PiggyWebSocketClient&) = delete;
|
||||||
virtual ~PiggyWebSocketClient();
|
virtual ~PiggyWebSocketClient();
|
||||||
|
|
||||||
@ -87,9 +90,12 @@ namespace musik { namespace core { namespace net {
|
|||||||
ConnectionError LastConnectionError() const;
|
ConnectionError LastConnectionError() const;
|
||||||
std::string Uri() const;
|
std::string Uri() const;
|
||||||
|
|
||||||
void SetMessageQueue(musik::core::runtime::IMessageQueue* messageQueue);
|
void SetMessageQueue(MessageQueue* messageQueue);
|
||||||
void ProcessMessage(musik::core::runtime::IMessage& message) override;
|
void ProcessMessage(musik::core::runtime::IMessage& message) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PiggyWebSocketClient(MessageQueue* messageQueue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetState(State state);
|
void SetState(State state);
|
||||||
void SetDisconnected(ConnectionError errorCode);
|
void SetDisconnected(ConnectionError errorCode);
|
||||||
@ -107,7 +113,7 @@ namespace musik { namespace core { namespace net {
|
|||||||
std::atomic<bool> quit{ false };
|
std::atomic<bool> quit{ false };
|
||||||
ConnectionError connectionError{ ConnectionError::None };
|
ConnectionError connectionError{ ConnectionError::None };
|
||||||
State state{ State::Disconnected };
|
State state{ State::Disconnected };
|
||||||
musik::core::runtime::IMessageQueue* messageQueue;
|
MessageQueue* messageQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
} } }
|
} } }
|
||||||
|
@ -412,7 +412,7 @@ namespace musik { namespace core { namespace plugin {
|
|||||||
return environment;
|
return environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Deinit() {
|
void Shutdown() {
|
||||||
/* preferences */
|
/* preferences */
|
||||||
Preferences::SavePluginPreferences();
|
Preferences::SavePluginPreferences();
|
||||||
|
|
||||||
|
@ -50,6 +50,6 @@ namespace musik { namespace core { namespace plugin {
|
|||||||
|
|
||||||
musik::core::sdk::IEnvironment& Environment();
|
musik::core::sdk::IEnvironment& Environment();
|
||||||
|
|
||||||
void Deinit();
|
void Shutdown();
|
||||||
|
|
||||||
} } }
|
} } }
|
||||||
|
@ -125,7 +125,7 @@ int main(int argc, char* argv[]) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (prefs->GetBool(core::prefs::keys::PiggyEnabled, false)) {
|
if (prefs->GetBool(core::prefs::keys::PiggyEnabled, false)) {
|
||||||
auto piggyClient = std::make_shared<PiggyWebSocketClient>(&Window::MessageQueue());
|
auto piggyClient = PiggyWebSocketClient::Instance(&Window::MessageQueue());
|
||||||
piggyClient->Connect(prefs->GetString(core::prefs::keys::PiggyHostname, "localhost"));
|
piggyClient->Connect(prefs->GetString(core::prefs::keys::PiggyHostname, "localhost"));
|
||||||
debuggerBackends.push_back(new PiggyDebugBackend(piggyClient));
|
debuggerBackends.push_back(new PiggyDebugBackend(piggyClient));
|
||||||
}
|
}
|
||||||
@ -226,21 +226,20 @@ int main(int argc, char* argv[]) {
|
|||||||
app.Run(mainLayout);
|
app.Run(mainLayout);
|
||||||
|
|
||||||
/* done with the app */
|
/* done with the app */
|
||||||
mainLayout->Stop();
|
mainLayout->Shutdown();
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
win32::HideMainWindow();
|
win32::HideMainWindow();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
library->Indexer()->Stop();
|
library->Indexer()->Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
audio::vis::HideSelectedVisualizer();
|
PiggyWebSocketClient::Shutdown();
|
||||||
plugin::Deinit();
|
|
||||||
|
|
||||||
LibraryFactory::Instance().Shutdown();
|
LibraryFactory::Instance().Shutdown();
|
||||||
|
vis::Shutdown();
|
||||||
debug::Stop();
|
plugin::Shutdown();
|
||||||
|
debug::Shutdown();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ void MainLayout::Start() {
|
|||||||
MessageQueue().RegisterForBroadcasts(this->shared_from_this());
|
MessageQueue().RegisterForBroadcasts(this->shared_from_this());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainLayout::Stop() {
|
void MainLayout::Shutdown() {
|
||||||
MessageQueue().UnregisterForBroadcasts(this);
|
MessageQueue().UnregisterForBroadcasts(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include <musikcore/support/Preferences.h>
|
#include <musikcore/support/Preferences.h>
|
||||||
#include <musikcore/runtime/IMessageTarget.h>
|
#include <musikcore/runtime/IMessageTarget.h>
|
||||||
#include <musikcore/library/MasterLibrary.h>
|
#include <musikcore/library/MasterLibrary.h>
|
||||||
|
#include <musikcore/net/PiggyWebSocketClient.h>
|
||||||
|
|
||||||
#include <app/util/ConsoleLogger.h>
|
#include <app/util/ConsoleLogger.h>
|
||||||
#include <app/util/UpdateCheck.h>
|
#include <app/util/UpdateCheck.h>
|
||||||
@ -66,7 +67,7 @@ namespace musik {
|
|||||||
virtual ~MainLayout();
|
virtual ~MainLayout();
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Shutdown();
|
||||||
|
|
||||||
/* IWindow */
|
/* IWindow */
|
||||||
bool KeyPress(const std::string& key) override;
|
bool KeyPress(const std::string& key) override;
|
||||||
|
@ -70,6 +70,7 @@ using namespace musik::core;
|
|||||||
using namespace musik::core::audio;
|
using namespace musik::core::audio;
|
||||||
using namespace musik::core::library::constants;
|
using namespace musik::core::library::constants;
|
||||||
using namespace musik::core::sdk;
|
using namespace musik::core::sdk;
|
||||||
|
using namespace musik::core::net;
|
||||||
using namespace musik::cube;
|
using namespace musik::cube;
|
||||||
using namespace cursespp;
|
using namespace cursespp;
|
||||||
|
|
||||||
@ -165,6 +166,8 @@ SettingsLayout::SettingsLayout(
|
|||||||
, indexer(library->Indexer())
|
, indexer(library->Indexer())
|
||||||
, playback(playback) {
|
, playback(playback) {
|
||||||
this->prefs = Preferences::ForComponent(core::prefs::components::Settings);
|
this->prefs = Preferences::ForComponent(core::prefs::components::Settings);
|
||||||
|
this->piggyClient = PiggyWebSocketClient::Instance(&MessageQueue());
|
||||||
|
this->piggyClient->StateChanged.connect(this, &SettingsLayout::OnPiggyClientStateChange);
|
||||||
this->UpdateServerAvailability();
|
this->UpdateServerAvailability();
|
||||||
this->InitializeWindows();
|
this->InitializeWindows();
|
||||||
}
|
}
|
||||||
@ -173,6 +176,18 @@ SettingsLayout::~SettingsLayout() {
|
|||||||
updateCheck.Cancel();
|
updateCheck.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsLayout::OnPiggyClientStateChange(
|
||||||
|
PiggyWebSocketClient* client,
|
||||||
|
PiggyWebSocketClient::State newState,
|
||||||
|
PiggyWebSocketClient::State oldState)
|
||||||
|
{
|
||||||
|
/* trigger a redraw on the main thread */
|
||||||
|
using State = PiggyWebSocketClient::State;
|
||||||
|
if (newState == State::Connected || newState == State::Disconnected) {
|
||||||
|
this->Post(core::message::EnvironmentUpdated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsLayout::OnCheckboxChanged(cursespp::Checkbox* cb, bool checked) {
|
void SettingsLayout::OnCheckboxChanged(cursespp::Checkbox* cb, bool checked) {
|
||||||
if (cb == syncOnStartupCheckbox.get()) {
|
if (cb == syncOnStartupCheckbox.get()) {
|
||||||
this->prefs->SetBool(core::prefs::keys::SyncOnStartup, checked);
|
this->prefs->SetBool(core::prefs::keys::SyncOnStartup, checked);
|
||||||
@ -451,8 +466,6 @@ void SettingsLayout::InitializeWindows() {
|
|||||||
this->appVersion = std::make_shared<TextLabel>();
|
this->appVersion = std::make_shared<TextLabel>();
|
||||||
this->appVersion->SetContentColor(Color::TextDisabled);
|
this->appVersion->SetContentColor(Color::TextDisabled);
|
||||||
this->appVersion->SetAlignment(text::AlignCenter);
|
this->appVersion->SetAlignment(text::AlignCenter);
|
||||||
std::string version = u8fmt("%s %s", VERSION, VERSION_COMMIT_HASH);
|
|
||||||
this->appVersion->SetText(u8fmt(_TSTR("console_version"), version.c_str()));
|
|
||||||
|
|
||||||
int order = 0;
|
int order = 0;
|
||||||
this->libraryTypeDropdown->SetFocusOrder(order++);
|
this->libraryTypeDropdown->SetFocusOrder(order++);
|
||||||
@ -639,9 +652,23 @@ void SettingsLayout::LoadPreferences() {
|
|||||||
this->localLibraryLayout->LoadPreferences();
|
this->localLibraryLayout->LoadPreferences();
|
||||||
this->remoteLibraryLayout->LoadPreferences();
|
this->remoteLibraryLayout->LoadPreferences();
|
||||||
|
|
||||||
|
/* version, status */
|
||||||
|
std::string piggyStatus = "";
|
||||||
|
if (this->piggyAvailable) {
|
||||||
|
if (this->piggyClient->ConnectionState() == PiggyWebSocketClient::State::Connected) {
|
||||||
|
piggyStatus = " (oo)";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
piggyStatus = " (..)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string version = u8fmt("%s %s%s", VERSION, VERSION_COMMIT_HASH, piggyStatus.c_str());
|
||||||
|
this->appVersion->SetText(u8fmt(_TSTR("console_version"), version.c_str()));
|
||||||
|
|
||||||
this->Layout();
|
this->Layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsLayout::UpdateServerAvailability() {
|
void SettingsLayout::UpdateServerAvailability() {
|
||||||
this->serverAvailable = !!ServerOverlay::FindServerPlugin().get();
|
this->serverAvailable = !!ServerOverlay::FindServerPlugin().get();
|
||||||
|
this->piggyAvailable = this->prefs->GetBool(core::prefs::keys::PiggyEnabled, false);
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include <musikcore/audio/PlaybackService.h>
|
#include <musikcore/audio/PlaybackService.h>
|
||||||
#include <musikcore/audio/MasterTransport.h>
|
#include <musikcore/audio/MasterTransport.h>
|
||||||
#include <musikcore/library/MasterLibrary.h>
|
#include <musikcore/library/MasterLibrary.h>
|
||||||
|
#include <musikcore/net/PiggyWebSocketClient.h>
|
||||||
#include <musikcore/support/Preferences.h>
|
#include <musikcore/support/Preferences.h>
|
||||||
|
|
||||||
#include <app/window/TrackListView.h>
|
#include <app/window/TrackListView.h>
|
||||||
@ -68,6 +69,7 @@ namespace musik { namespace cube {
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using MasterLibraryPtr = std::shared_ptr<musik::core::library::MasterLibrary>;
|
using MasterLibraryPtr = std::shared_ptr<musik::core::library::MasterLibrary>;
|
||||||
|
using PiggyWebSocketClient = musik::core::net::PiggyWebSocketClient;
|
||||||
|
|
||||||
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(SettingsLayout)
|
DELETE_COPY_AND_ASSIGNMENT_DEFAULTS(SettingsLayout)
|
||||||
|
|
||||||
@ -110,6 +112,11 @@ namespace musik { namespace cube {
|
|||||||
void OnLastFmDropdownActivate(cursespp::TextLabel* label);
|
void OnLastFmDropdownActivate(cursespp::TextLabel* label);
|
||||||
void OnAdvancedSettingsActivate(cursespp::TextLabel* label);
|
void OnAdvancedSettingsActivate(cursespp::TextLabel* label);
|
||||||
|
|
||||||
|
void OnPiggyClientStateChange(
|
||||||
|
PiggyWebSocketClient* client,
|
||||||
|
PiggyWebSocketClient::State newState,
|
||||||
|
PiggyWebSocketClient::State oldState);
|
||||||
|
|
||||||
cursespp::App& app;
|
cursespp::App& app;
|
||||||
MasterLibraryPtr library;
|
MasterLibraryPtr library;
|
||||||
musik::core::IIndexer* indexer;
|
musik::core::IIndexer* indexer;
|
||||||
@ -143,8 +150,10 @@ namespace musik { namespace cube {
|
|||||||
|
|
||||||
std::shared_ptr<LocalLibrarySettingsLayout> localLibraryLayout;
|
std::shared_ptr<LocalLibrarySettingsLayout> localLibraryLayout;
|
||||||
std::shared_ptr<RemoteLibrarySettingsLayout> remoteLibraryLayout;
|
std::shared_ptr<RemoteLibrarySettingsLayout> remoteLibraryLayout;
|
||||||
|
std::shared_ptr<PiggyWebSocketClient> piggyClient;
|
||||||
|
|
||||||
UpdateCheck updateCheck;
|
UpdateCheck updateCheck;
|
||||||
bool serverAvailable = false;
|
bool serverAvailable = false;
|
||||||
|
bool piggyAvailable = false;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
@ -298,10 +298,10 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
messageQueue.Run();
|
messageQueue.Run();
|
||||||
|
|
||||||
library->Indexer()->Stop();
|
library->Indexer()->Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin::Deinit();
|
plugin::Shutdown();
|
||||||
|
|
||||||
remove(getLockfileFn().c_str());
|
remove(getLockfileFn().c_str());
|
||||||
}
|
}
|
||||||
|
@ -460,7 +460,7 @@ void TaglibMetadataReader::ReadBasicData(const T* tag, const char* uri, ITagStor
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->SetTagValue("album", tag->album(), target);
|
this->SetTagValue("album", tag->album(), target);
|
||||||
this->SetSlashSeparatedValues("artist", tag->artist(), target);
|
this->SetTagValue("artist", tag->artist(), target);
|
||||||
this->SetTagValue("genre", tag->genre(), target);
|
this->SetTagValue("genre", tag->genre(), target);
|
||||||
this->SetTagValue("comment", tag->comment(), target);
|
this->SetTagValue("comment", tag->comment(), target);
|
||||||
|
|
||||||
@ -638,7 +638,7 @@ bool TaglibMetadataReader::ReadID3V2(TagLib::ID3v2::Tag *id3v2, ITagStore *track
|
|||||||
this->SetTagValues("org.writer", allTags["TOLY"], track);
|
this->SetTagValues("org.writer", allTags["TOLY"], track);
|
||||||
this->SetSlashSeparatedValues("publisher", allTags["TPUB"], track);
|
this->SetSlashSeparatedValues("publisher", allTags["TPUB"], track);
|
||||||
this->SetTagValues("mood", allTags["TMOO"], track);
|
this->SetTagValues("mood", allTags["TMOO"], track);
|
||||||
this->SetSlashSeparatedValues("org.artist", allTags["TOPE"], track);
|
this->SetTagValues("org.artist", allTags["TOPE"], track);
|
||||||
this->SetTagValues("language", allTags["TLAN"], track);
|
this->SetTagValues("language", allTags["TLAN"], track);
|
||||||
this->SetTagValues("lyrics", allTags["USLT"], track);
|
this->SetTagValues("lyrics", allTags["USLT"], track);
|
||||||
this->SetTagValues("disc", allTags["TPOS"], track);
|
this->SetTagValues("disc", allTags["TPOS"], track);
|
||||||
@ -696,8 +696,8 @@ bool TaglibMetadataReader::ReadID3V2(TagLib::ID3v2::Tag *id3v2, ITagStore *track
|
|||||||
|
|
||||||
/* artists */
|
/* artists */
|
||||||
|
|
||||||
this->SetSlashSeparatedValues("artist", allTags["TPE1"], track);
|
this->SetTagValues("artist", allTags["TPE1"], track);
|
||||||
this->SetSlashSeparatedValues("album_artist", allTags["TPE2"], track);
|
this->SetTagValues("album_artist", allTags["TPE2"], track);
|
||||||
this->SetSlashSeparatedValues("conductor", allTags["TPE3"], track);
|
this->SetSlashSeparatedValues("conductor", allTags["TPE3"], track);
|
||||||
this->SetSlashSeparatedValues("interpreted", allTags["TPE4"], track);
|
this->SetSlashSeparatedValues("interpreted", allTags["TPE4"], track);
|
||||||
|
|
||||||
@ -707,7 +707,7 @@ bool TaglibMetadataReader::ReadID3V2(TagLib::ID3v2::Tag *id3v2, ITagStore *track
|
|||||||
|
|
||||||
TagLib::ID3v2::FrameList::Iterator it = comments.begin();
|
TagLib::ID3v2::FrameList::Iterator it = comments.begin();
|
||||||
for (; it != comments.end(); ++it) {
|
for (; it != comments.end(); ++it) {
|
||||||
TagLib::ID3v2::CommentsFrame *comment
|
const TagLib::ID3v2::CommentsFrame *comment
|
||||||
= dynamic_cast<TagLib::ID3v2::CommentsFrame*> (*it);
|
= dynamic_cast<TagLib::ID3v2::CommentsFrame*> (*it);
|
||||||
|
|
||||||
TagLib::String temp = comment->description();
|
TagLib::String temp = comment->description();
|
||||||
@ -738,7 +738,7 @@ bool TaglibMetadataReader::ReadID3V2(TagLib::ID3v2::Tag *id3v2, ITagStore *track
|
|||||||
static_cast<TagLib::ID3v2::AttachedPictureFrame*>(pictures.front());
|
static_cast<TagLib::ID3v2::AttachedPictureFrame*>(pictures.front());
|
||||||
|
|
||||||
TagLib::ByteVector pictureData = picture->picture();
|
TagLib::ByteVector pictureData = picture->picture();
|
||||||
long long size = pictureData.size();
|
const long long size = pictureData.size();
|
||||||
|
|
||||||
if (size > 32) { /* noticed that some id3tags have like a 4-8 byte size with no thumbnail */
|
if (size > 32) { /* noticed that some id3tags have like a 4-8 byte size with no thumbnail */
|
||||||
track->SetThumbnail(pictureData.data(), size);
|
track->SetThumbnail(pictureData.data(), size);
|
||||||
@ -800,7 +800,7 @@ void TaglibMetadataReader::SetTagValues(
|
|||||||
void TaglibMetadataReader::SetSlashSeparatedValues(
|
void TaglibMetadataReader::SetSlashSeparatedValues(
|
||||||
const char* key, TagLib::String tagString, ITagStore *track)
|
const char* key, TagLib::String tagString, ITagStore *track)
|
||||||
{
|
{
|
||||||
if(!tagString.isEmpty()) {
|
if (!tagString.isEmpty()) {
|
||||||
std::string value(tagString.to8Bit(true));
|
std::string value(tagString.to8Bit(true));
|
||||||
std::vector<std::string> splitValues = str::split(value, "/");
|
std::vector<std::string> splitValues = str::split(value, "/");
|
||||||
std::vector<std::string>::iterator it = splitValues.begin();
|
std::vector<std::string>::iterator it = splitValues.begin();
|
||||||
@ -815,7 +815,7 @@ void TaglibMetadataReader::SetSlashSeparatedValues(
|
|||||||
const TagLib::ID3v2::FrameList &frame,
|
const TagLib::ID3v2::FrameList &frame,
|
||||||
ITagStore *track)
|
ITagStore *track)
|
||||||
{
|
{
|
||||||
if(!frame.isEmpty()) {
|
if (!frame.isEmpty()) {
|
||||||
TagLib::ID3v2::FrameList::ConstIterator value = frame.begin();
|
TagLib::ID3v2::FrameList::ConstIterator value = frame.begin();
|
||||||
for ( ; value != frame.end(); ++value) {
|
for ( ; value != frame.end(); ++value) {
|
||||||
TagLib::String tagString = (*value)->toString();
|
TagLib::String tagString = (*value)->toString();
|
||||||
|
Loading…
Reference in New Issue
Block a user