Added a new IDebug interface to the SDK -- plugins can opt-in to get an instance to one of these and write debug information to the standard location, just like the rest of the app.

This commit is contained in:
casey langen 2018-12-26 22:53:53 -08:00
parent 1b4b9127c4
commit cc134775ef
12 changed files with 140 additions and 8 deletions

View File

@ -10,6 +10,7 @@ musikcube:
* added the ability to customize the key used to quit the app. it is currently
not exposed in the ui, but it can be changed by editing
`~/.musikcube/settings.json` and updating the `AppQuitKey`.
* scrapped and re-implemented the debug log viewer, accessible via `ctrl+~`
* added feodra 29 support (dvdmuckle)
* fixed configuration script bugs that were causing breakage in FreeBSD
* migrated to non-bundled `taglib` for macOS and most Linux distributions
@ -19,6 +20,10 @@ musikcube:
musikdroid:
* updated to compile against the latest tooling
sdk:
* added a new `IDebug` interface plugins can request via `SetDebug` to write
log information to the standard location, just like the rest of the app.
--------------------------------------------------------------------------------
0.51.0

View File

@ -99,11 +99,8 @@ void GaplessTransport::PrepareNextTrack(const std::string& uri, Gain gain) {
}
void GaplessTransport::Start(const std::string& uri, Gain gain, StartMode mode) {
musik::debug::info(TAG, "we were asked to start the track at " + uri);
musik::debug::info(TAG, "starting track at " + uri);
Player* newPlayer = Player::Create(uri, this->output, Player::NoDrain, this, gain);
musik::debug::info(TAG, "Player created successfully");
this->StartWithPlayer(newPlayer, mode);
}

View File

@ -118,7 +118,7 @@ namespace musik { namespace core { namespace audio {
return nullptr;
}
musik::debug::info(TAG, "about ready to play: " + uri);
musik::debug::info(TAG, "found a decoder for " + uri);
return decoder;
}

View File

@ -92,7 +92,6 @@ bool LocalFileStream::Open(const char *filename, unsigned int options) {
#endif
if (this->file.load()) {
debug::info(TAG, "opened successfully");
return true;
}
}

View File

@ -39,6 +39,7 @@
#include <core/support/Common.h>
#include <core/support/Preferences.h>
#include <core/debug.h>
#include <core/io/DataStreamFactory.h>
#include <core/audio/Buffer.h>
#include <core/audio/Streams.h>
@ -49,6 +50,7 @@
#include <core/runtime/Message.h>
#include <core/support/Messages.h>
#include <core/sdk/IDebug.h>
#include <core/sdk/IIndexerNotifier.h>
#include <core/sdk/IEnvironment.h>
@ -60,6 +62,7 @@ using namespace musik::core::runtime;
using namespace musik::core::sdk;
typedef void(*SetEnvironment)(IEnvironment*);
typedef void(*SetDebug)(IDebug*);
typedef void(*SetSimpleDataProvider)(ISimpleDataProvider*);
typedef void(*SetIndexerNotifier)(IIndexerNotifier*);
@ -79,7 +82,26 @@ static void saveEnvironment() {
}
}
static class Environment : public IEnvironment {
static class Debug: public IDebug {
public:
virtual void Verbose(const char* tag, const char* message) override {
musik::debug::verbose(tag, message);
}
virtual void Info(const char* tag, const char* message) override {
musik::debug::info(tag, message);
}
virtual void Warning(const char* tag, const char* message) override {
musik::debug::warning(tag, message);
}
virtual void Error(const char* tag, const char* message) override {
musik::debug::error(tag, message);
}
} debugger;
static class Environment: public IEnvironment {
public:
virtual size_t GetPath(PathType type, char* dst, int size) override {
std::string path;
@ -110,6 +132,10 @@ static class Environment : public IEnvironment {
return streams::GetEncoderForType(type);
}
virtual IDebug* GetDebug() override {
return &debugger;
}
virtual IPreferences* GetPreferences(const char* name) override {
return Preferences::Unmanaged(name ? name : std::string());
}
@ -266,6 +292,13 @@ namespace musik { namespace core { namespace plugin {
[](musik::core::sdk::IPlugin* plugin, SetEnvironment func) {
func(&environment);
});
/* debug */
PluginFactory::Instance().QueryFunction<SetDebug>(
"SetDebug",
[](musik::core::sdk::IPlugin* plugin, SetDebug func) {
func(&debugger);
});
}
void UninstallDependencies() {
@ -299,6 +332,13 @@ namespace musik { namespace core { namespace plugin {
[](musik::core::sdk::IPlugin* plugin, SetEnvironment func) {
func(nullptr);
});
/* debug */
PluginFactory::Instance().QueryFunction<SetDebug>(
"SetDebug",
[](musik::core::sdk::IPlugin* plugin, SetDebug func) {
func(nullptr);
});
}
} } }

47
src/core/sdk/IDebug.h Normal file
View File

@ -0,0 +1,47 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007-2017 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
namespace musik { namespace core { namespace sdk {
class IDebug {
public:
virtual void Verbose(const char* tag, const char* message) = 0;
virtual void Info(const char* tag, const char* message) = 0;
virtual void Warning(const char* tag, const char* message) = 0;
virtual void Error(const char* tag, const char* message) = 0;
};
} } }

View File

@ -41,6 +41,7 @@
#include "IPreferences.h"
#include "IOutput.h"
#include "ITrackList.h"
#include "IDebug.h"
namespace musik { namespace core { namespace sdk {
@ -52,6 +53,7 @@ namespace musik { namespace core { namespace sdk {
virtual IEncoder* GetEncoder(const char* type) = 0;
virtual IBuffer* GetBuffer(size_t samples, size_t rate = 44100, size_t channels = 2) = 0;
virtual IPreferences* GetPreferences(const char* name) = 0;
virtual IDebug* GetDebug() = 0;
virtual size_t GetOutputCount() = 0;
virtual IOutput* GetOutputAtIndex(size_t index) = 0;
virtual IOutput* GetOutputWithName(const char* name) = 0;

View File

@ -6,6 +6,7 @@
#include <cursespp/ToastOverlay.h>
#include <app/util/Hotkeys.h>
#include <app/util/Messages.h>
#include <app/version.h>
using namespace musik::cube;
using namespace musik::core;
@ -55,6 +56,18 @@ void ConsoleLayout::OnItemActivated(cursespp::ListWindow* window, size_t index)
ToastOverlay::Show(this->logger->Adapter()->StringAt(index), -1);
}
bool ConsoleLayout::KeyPress(const std::string& kn) {
if (kn == "^_") { /* ctrl+/ */
ToastOverlay::Show(u8fmt(_TSTR("console_version"), VERSION), -1);
return true;
}
else if (kn == "x") {
this->adapter->Clear();
return true;
}
return LayoutBase::KeyPress(kn);
}
void ConsoleLayout::SetShortcutsWindow(ShortcutsWindow* shortcuts) {
if (shortcuts) {
shortcuts->AddShortcut(Hotkeys::Get(Hotkeys::NavigateConsole), _TSTR("shortcuts_console"));

View File

@ -17,6 +17,7 @@ namespace musik { namespace cube {
virtual void OnLayout() override;
virtual void SetShortcutsWindow(cursespp::ShortcutsWindow* w) override;
virtual bool KeyPress(const std::string& kn) override;
protected:
void OnVisibilityChanged(bool visible) override;

View File

@ -36,6 +36,7 @@
"browse_no_subdirectories_toast": "there are no more sub-directories.\n\npress '%s' to play the selection.",
"console_list_title": "debug logs",
"console_version": "musikcube version %s",
"hotkeys_title": "key bindings",
"hotkeys_reset_defaults": "reset all",

View File

@ -33,13 +33,27 @@
//////////////////////////////////////////////////////////////////////////////
#include "FfmpegDecoder.h"
#include <core/sdk/IDebug.h>
#include <algorithm>
#ifdef WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
#define BUFFER_SIZE 4096
#define PROBE_SIZE 32768
using namespace musik::core::sdk;
static const char* TAG = "ffmpegdecoder";
static IDebug* debug = nullptr;
extern "C" DLLEXPORT void SetDebug(IDebug* debug) {
::debug = debug;
}
static int readCallback(void* opaque, uint8_t* buffer, int bufferSize) {
FfmpegDecoder* decoder = static_cast<FfmpegDecoder*>(opaque);
if (decoder && decoder->Stream()) {
@ -182,6 +196,9 @@ bool FfmpegDecoder::GetBuffer(IBuffer *buffer) {
return true;
}
}
::debug->Warning(TAG, "finished decoding.");
this->exhausted = true;
return false;
}
@ -214,6 +231,8 @@ void FfmpegDecoder::Reset() {
bool FfmpegDecoder::Open(musik::core::sdk::IDataStream *stream) {
if (stream->Seekable() && this->ioContext == nullptr) {
::debug->Info(TAG, "parsing data stream...");
this->stream = stream;
this->ioContext = avio_alloc_context(
@ -254,6 +273,7 @@ bool FfmpegDecoder::Open(musik::core::sdk::IDataStream *stream) {
}
if (this->streamId != -1) {
::debug->Info(TAG, "found audio!");
this->codecContext = this->formatContext->streams[this->streamId]->codec;
if (codecContext) {
this->codecContext->request_sample_fmt = AV_SAMPLE_FMT_FLT;
@ -262,8 +282,10 @@ bool FfmpegDecoder::Open(musik::core::sdk::IDataStream *stream) {
if (avcodec_open2(codecContext, codec, nullptr) < 0) {
goto reset_and_fail;
}
::debug->Info(TAG, "resolved a codec!");
}
else {
::debug->Error(TAG, "couldn't find a codec.");
goto reset_and_fail;
}
}
@ -274,16 +296,20 @@ bool FfmpegDecoder::Open(musik::core::sdk::IDataStream *stream) {
this->duration = (double) this->formatContext->duration / (double) AV_TIME_BASE;
return true;
}
else {
::debug->Error(TAG, "audio stream not found in input data.");
}
}
}
}
}
reset_and_fail:
::debug->Error(TAG, "failed to find compatible audio stream");
this->Reset();
return false;
}
bool FfmpegDecoder::Exhausted() {
return false;
return this->exhausted;
}

View File

@ -80,4 +80,5 @@ class FfmpegDecoder: public musik::core::sdk::IDecoder {
size_t rate, channels;
int streamId;
double duration;
bool exhausted{false};
};