From 19c620fcbd4dea3d29a4d1e38e26231a3633b7f9 Mon Sep 17 00:00:00 2001 From: casey langen Date: Sun, 5 Feb 2017 13:32:09 -0800 Subject: [PATCH] * Started fleshing out ISimpleDataProvider interface, which is just a facade plugins can use to access existing queries. Started implementing it against the LocalLibrary in LocalSimpleDataProvider. * Added musik::core::plugins that can be used as a centralized place for initializing plugins with components they require, e.g. preferences and data providers. * Added some more constants to the SDK interface. --- src/core/CMakeLists.txt | 2 + src/core/core.vcxproj | 7 +- src/core/core.vcxproj.filters | 23 ++++- src/core/library/LocalLibrary.cpp | 48 +++++----- src/core/library/LocalLibrary.h | 9 +- src/core/library/LocalSimpleDataProvider.cpp | 95 ++++++++++++++++++++ src/core/library/LocalSimpleDataProvider.h | 58 ++++++++++++ src/core/plugin/Plugins.cpp | 78 ++++++++++++++++ src/core/plugin/Plugins.h | 44 +++++++++ src/core/sdk/ISimpleDataProvider.h | 49 ++++++++++ src/core/sdk/constants.h | 30 +++++++ src/musikbox/Main.cpp | 14 +-- 12 files changed, 416 insertions(+), 41 deletions(-) create mode 100644 src/core/library/LocalSimpleDataProvider.cpp create mode 100644 src/core/library/LocalSimpleDataProvider.h create mode 100644 src/core/plugin/Plugins.cpp create mode 100644 src/core/plugin/Plugins.h create mode 100644 src/core/sdk/ISimpleDataProvider.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 6dda3657f..821bbe049 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -18,6 +18,7 @@ set(CORE_SOURCES ./library/Indexer.cpp ./library/LibraryFactory.cpp ./library/LocalLibrary.cpp + ./library/LocalSimpleDataProvider.cpp ./library/query/local/GetPlaylistQuery.cpp ./library/query/local/CategoryListQuery.cpp ./library/query/local/CategoryTrackListQuery.cpp @@ -31,6 +32,7 @@ set(CORE_SOURCES ./library/track/TrackList.cpp ./library/track/RetainedTrack.cpp ./plugin/PluginFactory.cpp + ./plugin/Plugins.cpp ./runtime/Message.cpp ./runtime/MessageQueue.cpp ./support/Common.cpp diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index ce823abea..d48d0cf18 100755 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -99,6 +99,7 @@ + @@ -122,6 +123,7 @@ + @@ -148,6 +150,7 @@ + @@ -165,6 +168,7 @@ + @@ -196,6 +200,7 @@ + @@ -215,4 +220,4 @@ - + \ No newline at end of file diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index 0653d6002..5afe939af 100755 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -154,6 +154,12 @@ src\library\query\local + + src\library + + + src\plugin + @@ -198,9 +204,6 @@ src\sdk - - src\library\query - src\io @@ -384,5 +387,17 @@ src\library\query\local + + src\sdk + + + src\library\query\local + + + src\library + + + src\plugin + - + \ No newline at end of file diff --git a/src/core/library/LocalLibrary.cpp b/src/core/library/LocalLibrary.cpp index 0c7240e0b..fdef5633c 100644 --- a/src/core/library/LocalLibrary.cpp +++ b/src/core/library/LocalLibrary.cpp @@ -158,33 +158,31 @@ std::string LocalLibrary::GetDatabaseFilename() { return this->GetLibraryDirectory() + "musik.db"; } -int LocalLibrary::Enqueue(LocalQueryPtr query, unsigned int options) { - std::unique_lock lock(this->mutex); - - if (this->exit) { /* closed */ - return -1; - } - - if (options & ILibrary::QuerySynchronous) { - this->RunQuery(query, false); /* false = do not notify via QueryCompleted */ - } - else { - queryQueue.push_back(query); - queueCondition.notify_all(); - - if (VERBOSE_LOGGING) { - musik::debug::info(TAG, "query '" + query->Name() + "' enqueued"); - } - } - - return query->GetId(); -} - int LocalLibrary::Enqueue(IQueryPtr query, unsigned int options) { - LocalQueryPtr casted = std::dynamic_pointer_cast(query); - if (casted) { - return this->Enqueue(casted, options); + LocalQueryPtr localQuery = std::dynamic_pointer_cast(query); + + if (localQuery) { + std::unique_lock lock(this->mutex); + + if (this->exit) { /* closed */ + return -1; + } + + if (options & ILibrary::QuerySynchronous) { + this->RunQuery(localQuery, false); /* false = do not notify via QueryCompleted */ + } + else { + queryQueue.push_back(localQuery); + queueCondition.notify_all(); + + if (VERBOSE_LOGGING) { + musik::debug::info(TAG, "query '" + localQuery->Name() + "' enqueued"); + } + } + + return localQuery->GetId(); } + return -1; } diff --git a/src/core/library/LocalLibrary.h b/src/core/library/LocalLibrary.h index cc697e89c..61b41bb39 100644 --- a/src/core/library/LocalLibrary.h +++ b/src/core/library/LocalLibrary.h @@ -59,6 +59,7 @@ namespace musik { namespace core { namespace library { class LocalLibrary : public ILibrary, public musik::core::runtime::IMessageTarget, + public std::enable_shared_from_this, boost::noncopyable { public: @@ -71,7 +72,6 @@ namespace musik { namespace core { namespace library { virtual ~LocalLibrary(); /* ILibrary */ - virtual int Enqueue(LocalQueryPtr query, unsigned int options = 0); virtual int Enqueue(IQueryPtr query, unsigned int options = 0); virtual musik::core::IIndexer *Indexer(); @@ -83,19 +83,18 @@ namespace musik { namespace core { namespace library { /* IMessageTarget */ virtual void ProcessMessage(musik::core::runtime::IMessage &message); + /* implementation specific */ std::string GetLibraryDirectory(); std::string GetDatabaseFilename(); - static void CreateDatabase(db::Connection &db); - protected: - virtual void Exit(); - private: typedef std::list QueryList; LocalLibrary(std::string name, int id); /* ctor */ + void RunQuery(LocalQueryPtr query, bool notify = true); + virtual void Exit(); bool Exited(); void ThreadProc(); LocalQueryPtr GetNextQuery(); diff --git a/src/core/library/LocalSimpleDataProvider.cpp b/src/core/library/LocalSimpleDataProvider.cpp new file mode 100644 index 000000000..312e00b8c --- /dev/null +++ b/src/core/library/LocalSimpleDataProvider.cpp @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007-2016 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 + +#include "pch.hpp" +#include "LocalSimpleDataProvider.h" + +#include + +#include +#include + +#define TAG "LocalSimpleDataProvider" + +using namespace musik::core; +using namespace musik::core::db; +using namespace musik::core::db::local; +using namespace musik::core::sdk; + +LocalSimpleDataProvider::LocalSimpleDataProvider(musik::core::ILibraryPtr library) +: library(library) { + +} + +LocalSimpleDataProvider::~LocalSimpleDataProvider() { + +} + +ITrackList* LocalSimpleDataProvider::QueryTracks(const char* query) { + try { + std::shared_ptr search( + new SearchTrackListQuery(this->library, std::string(query ? query : ""))); + + this->library->Enqueue(search, ILibrary::QuerySynchronous); + + if (search->GetStatus() == IQuery::Finished) { + return search->GetSdkResult(); + } + } + catch (...) { + musik::debug::err(TAG, "QueryTracks failed"); + } + + return nullptr; +} + +IMetadataValueList* LocalSimpleDataProvider::QueryCategory(const char* type, const char* filter) { + try { + std::shared_ptr search( + new CategoryListQuery(type, std::string(filter ? filter : ""))); + + this->library->Enqueue(search, ILibrary::QuerySynchronous); + + if (search->GetStatus() == IQuery::Finished) { + return search->GetSdkResult(); + } + } + catch (...) { + musik::debug::err(TAG, "QueryCategory failed"); + } + + return nullptr; +} diff --git a/src/core/library/LocalSimpleDataProvider.h b/src/core/library/LocalSimpleDataProvider.h new file mode 100644 index 000000000..82e13f2f5 --- /dev/null +++ b/src/core/library/LocalSimpleDataProvider.h @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007-2016 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 + +#include +#include + +namespace musik { namespace core { namespace db { namespace local { + + class LocalSimpleDataProvider : public musik::core::sdk::ISimpleDataProvider { + public: + LocalSimpleDataProvider(musik::core::ILibraryPtr library); + + virtual ~LocalSimpleDataProvider(); + + virtual musik::core::sdk::ITrackList* + QueryTracks(const char* query = ""); + + virtual musik::core::sdk::IMetadataValueList* + QueryCategory(const char* type, const char* filter = ""); + + private: + musik::core::ILibraryPtr library; + }; + +} } } } diff --git a/src/core/plugin/Plugins.cpp b/src/core/plugin/Plugins.cpp new file mode 100644 index 000000000..cd83e5c60 --- /dev/null +++ b/src/core/plugin/Plugins.cpp @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007-2016 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. +// +////////////////////////////////////////////////////////////////////////////// + +#include "pch.hpp" +#include "Plugins.h" +#include "PluginFactory.h" + +#include +#include + +using namespace musik::core; +using namespace musik::core::db::local; + +typedef void(*SetSimpleDataProvider)(musik::core::sdk::ISimpleDataProvider*); +LocalSimpleDataProvider* dataProvider = nullptr; + +namespace musik { namespace core { namespace plugin { + + void InstallDependencies(musik::core::ILibraryPtr library) { + /* preferences */ + Preferences::LoadPluginPreferences(); + + /* data providers */ + delete dataProvider; + dataProvider = new LocalSimpleDataProvider(library); + + PluginFactory::Instance().QueryFunction( + "SetSimpleDataProvider", + [](musik::core::sdk::IPlugin* plugin, SetSimpleDataProvider func) { + func(dataProvider); + }); + } + + void UninstallDependencies() { + Preferences::SavePluginPreferences(); + + PluginFactory::Instance().QueryFunction( + "SetSimpleDataProvider", + [](musik::core::sdk::IPlugin* plugin, SetSimpleDataProvider func) { + func(nullptr); + }); + + delete dataProvider; + dataProvider = nullptr; + } + +} } } diff --git a/src/core/plugin/Plugins.h b/src/core/plugin/Plugins.h new file mode 100644 index 000000000..83ce46bed --- /dev/null +++ b/src/core/plugin/Plugins.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007-2016 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 + +#include + +namespace musik { namespace core { namespace plugin { + + void InstallDependencies(musik::core::ILibraryPtr library); + void UninstallDependencies(); + +} } } diff --git a/src/core/sdk/ISimpleDataProvider.h b/src/core/sdk/ISimpleDataProvider.h new file mode 100644 index 000000000..4bea4fe1a --- /dev/null +++ b/src/core/sdk/ISimpleDataProvider.h @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2007-2016 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 + +#include "ITrackList.h" +#include "IMetadataValueList.h" + +namespace musik { namespace core { namespace sdk { + + class ISimpleDataProvider { + public: + virtual ITrackList* QueryTracks(const char* query = nullptr) = 0; + virtual IMetadataValueList* QueryCategory(const char* type, const char* filter = "") = 0; + }; + +} } } + diff --git a/src/core/sdk/constants.h b/src/core/sdk/constants.h index 2ae3bddc4..5ade75561 100644 --- a/src/core/sdk/constants.h +++ b/src/core/sdk/constants.h @@ -78,5 +78,35 @@ namespace musik { ChannelSideRight = 256 }; + namespace category { + static const char* Album = "album"; + static const char* Artist = "artist"; + static const char* AlbumArtist = "album_artist"; + static const char* Genre = "genre"; + static const char* Playlist = "playlists"; + } + + namespace track { + static const char* Id = "id"; + static const char* TrackNum = "track"; + static const char* DiscNum = "disc"; + static const char* Bpm = "bpm"; + static const char* Duration = "duration"; + static const char* Filesize = "filesize"; + static const char* Year = "year"; + static const char* Title = "title"; + static const char* Filename = "filename"; + static const char* ThumbnailId = "thumbnail_id"; + static const char* Album = "album"; + static const char* AlbumArtist = "album_artist"; + static const char* Genre = "genre"; + static const char* Artist = "artist"; + static const char* Filetime = "filetime"; + static const char* GenreId = "visual_genre_id"; + static const char* ArtistId = "visual_artist_id"; + static const char* AlbumArtistId = "album_artist_id"; + static const char* AlbumId = "album_id"; + } + static const int SdkVersion = 3; } } } \ No newline at end of file diff --git a/src/musikbox/Main.cpp b/src/musikbox/Main.cpp index e726ea3ff..56d76a4d5 100644 --- a/src/musikbox/Main.cpp +++ b/src/musikbox/Main.cpp @@ -51,6 +51,7 @@ #include #include +#include #include #include @@ -68,6 +69,7 @@ using namespace musik::glue; using namespace musik::glue::audio; using namespace musik::core; using namespace musik::core::audio; +using namespace musik::core::db::local; using namespace musik::box; using namespace cursespp; @@ -106,11 +108,6 @@ int main(int argc, char* argv[]) musik::debug::init(); - Preferences::LoadPluginPreferences(); - - auto prefs = Preferences::ForComponent( - musik::core::prefs::components::Settings); - ILibraryPtr library = LibraryFactory::Libraries().at(0); library->SetMessageQueue(Window::MessageQueue()); @@ -119,9 +116,14 @@ int main(int argc, char* argv[]) GlobalHotkeys globalHotkeys(playback, library); + musik::core::plugin::InstallDependencies(library); + { App app("musikbox"); /* must be before layout creation */ + auto prefs = Preferences::ForComponent( + musik::core::prefs::components::Settings); + app.SetCustomColorsDisabled(prefs->GetBool( musik::box::prefs::keys::DisableCustomColors.c_str(), false)); @@ -170,9 +172,9 @@ int main(int argc, char* argv[]) } musik::core::audio::vis::HideSelectedVisualizer(); + musik::core::plugin::UninstallDependencies(); LibraryFactory::Instance().Shutdown(); - Preferences::SavePluginPreferences(); musik::debug::deinit();