* 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.
This commit is contained in:
casey langen 2017-02-05 13:32:09 -08:00
parent 2590d37e4b
commit 19c620fcbd
12 changed files with 416 additions and 41 deletions

View File

@ -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

View File

@ -99,6 +99,7 @@
<ClCompile Include="library\Indexer.cpp" />
<ClCompile Include="library\LocalLibrary.cpp" />
<ClCompile Include="library\LibraryFactory.cpp" />
<ClCompile Include="library\LocalSimpleDataProvider.cpp" />
<ClCompile Include="library\query\local\CategoryListQuery.cpp" />
<ClCompile Include="library\query\local\CategoryTrackListQuery.cpp" />
<ClCompile Include="library\query\local\DeletePlaylistQuery.cpp" />
@ -122,6 +123,7 @@
<ClCompile Include="audio\Player.cpp" />
<ClCompile Include="audio\Stream.cpp" />
<ClCompile Include="plugin\PluginFactory.cpp" />
<ClCompile Include="plugin\Plugins.cpp" />
<ClCompile Include="runtime\Message.cpp" />
<ClCompile Include="runtime\MessageQueue.cpp" />
<ClCompile Include="support\Common.cpp" />
@ -148,6 +150,7 @@
<ClInclude Include="library\LocalLibrary.h" />
<ClInclude Include="library\LibraryFactory.h" />
<ClInclude Include="library\LocalLibraryConstants.h" />
<ClInclude Include="library\LocalSimpleDataProvider.h" />
<ClInclude Include="library\query\local\CategoryListQuery.h" />
<ClInclude Include="library\query\local\CategoryTrackListQuery.h" />
<ClInclude Include="library\query\local\DeletePlaylistQuery.h" />
@ -165,6 +168,7 @@
<ClInclude Include="pch.hpp" />
<ClInclude Include="config.h" />
<ClInclude Include="plugin\PluginFactory.h" />
<ClInclude Include="plugin\Plugins.h" />
<ClInclude Include="runtime\IMessage.h" />
<ClInclude Include="runtime\IMessageQueue.h" />
<ClInclude Include="runtime\IMessageTarget.h" />
@ -196,6 +200,7 @@
<ClInclude Include="audio\Stream.h" />
<ClInclude Include="sdk\IPreferences.h" />
<ClInclude Include="sdk\IRetainedTrack.h" />
<ClInclude Include="sdk\ISimpleDataProvider.h" />
<ClInclude Include="sdk\ISpectrumVisualizer.h" />
<ClInclude Include="sdk\ITrack.h" />
<ClInclude Include="sdk\ITrackList.h" />
@ -215,4 +220,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -154,6 +154,12 @@
<ClCompile Include="library\query\local\CategoryListQuery.cpp">
<Filter>src\library\query\local</Filter>
</ClCompile>
<ClCompile Include="library\LocalSimpleDataProvider.cpp">
<Filter>src\library</Filter>
</ClCompile>
<ClCompile Include="plugin\Plugins.cpp">
<Filter>src\plugin</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.hpp">
@ -198,9 +204,6 @@
<ClInclude Include="sdk\IDataStreamFactory.h">
<Filter>src\sdk</Filter>
</ClInclude>
<ClInclude Include="Library\query\local\LocalQueryBase.h">
<Filter>src\library\query</Filter>
</ClInclude>
<ClInclude Include="io\LocalFileStream.h">
<Filter>src\io</Filter>
</ClInclude>
@ -384,5 +387,17 @@
<ClInclude Include="library\query\local\CategoryListQuery.h">
<Filter>src\library\query\local</Filter>
</ClInclude>
<ClInclude Include="sdk\ISimpleDataProvider.h">
<Filter>src\sdk</Filter>
</ClInclude>
<ClInclude Include="Library\query\local\LocalQueryBase.h">
<Filter>src\library\query\local</Filter>
</ClInclude>
<ClInclude Include="library\LocalSimpleDataProvider.h">
<Filter>src\library</Filter>
</ClInclude>
<ClInclude Include="plugin\Plugins.h">
<Filter>src\plugin</Filter>
</ClInclude>
</ItemGroup>
</Project>
</Project>

View File

@ -158,33 +158,31 @@ std::string LocalLibrary::GetDatabaseFilename() {
return this->GetLibraryDirectory() + "musik.db";
}
int LocalLibrary::Enqueue(LocalQueryPtr query, unsigned int options) {
std::unique_lock<std::mutex> 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<LocalQuery>(query);
if (casted) {
return this->Enqueue(casted, options);
LocalQueryPtr localQuery = std::dynamic_pointer_cast<LocalQuery>(query);
if (localQuery) {
std::unique_lock<std::mutex> 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;
}

View File

@ -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<LocalLibrary>,
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<LocalQueryPtr> QueryList;
LocalLibrary(std::string name, int id); /* ctor */
void RunQuery(LocalQueryPtr query, bool notify = true);
virtual void Exit();
bool Exited();
void ThreadProc();
LocalQueryPtr GetNextQuery();

View File

@ -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 <core/debug.h>
#include <core/library/query/local/SearchTrackListQuery.h>
#include <core/library/query/local/CategoryListQuery.h>
#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<SearchTrackListQuery> 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<CategoryListQuery> 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;
}

View File

@ -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 <core/library/ILibrary.h>
#include <core/sdk/ISimpleDataProvider.h>
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;
};
} } } }

View File

@ -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 <core/support/Preferences.h>
#include <core/library/LocalSimpleDataProvider.h>
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>(
"SetSimpleDataProvider",
[](musik::core::sdk::IPlugin* plugin, SetSimpleDataProvider func) {
func(dataProvider);
});
}
void UninstallDependencies() {
Preferences::SavePluginPreferences();
PluginFactory::Instance().QueryFunction<SetSimpleDataProvider>(
"SetSimpleDataProvider",
[](musik::core::sdk::IPlugin* plugin, SetSimpleDataProvider func) {
func(nullptr);
});
delete dataProvider;
dataProvider = nullptr;
}
} } }

44
src/core/plugin/Plugins.h Normal file
View File

@ -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 <core/library/ILibrary.h>
namespace musik { namespace core { namespace plugin {
void InstallDependencies(musik::core::ILibraryPtr library);
void UninstallDependencies();
} } }

View File

@ -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;
};
} } }

View File

@ -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;
} } }

View File

@ -51,6 +51,7 @@
#include <glue/audio/MasterTransport.h>
#include <core/library/LibraryFactory.h>
#include <core/plugin/Plugins.h>
#include <core/support/PreferenceKeys.h>
#include <core/audio/Visualizer.h>
@ -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();