Merge branch 'develop' into user/mbleyer/bug_223
This commit is contained in:
Коммит
c430a64df6
|
@ -32,6 +32,7 @@ typedef struct _dewrapper_context_t
|
||||||
THREAD_HANDLE thread;
|
THREAD_HANDLE thread;
|
||||||
LOCK_HANDLE lock;
|
LOCK_HANDLE lock;
|
||||||
COND_HANDLE condition;
|
COND_HANDLE condition;
|
||||||
|
volatile bool thread_started;
|
||||||
volatile bool thread_stop;
|
volatile bool thread_stop;
|
||||||
k4a_result_t thread_start_result;
|
k4a_result_t thread_start_result;
|
||||||
|
|
||||||
|
@ -191,6 +192,7 @@ static int depth_engine_thread(void *param)
|
||||||
// The Start routine is blocked waiting for this thread to complete startup, so we signal it here and share our
|
// The Start routine is blocked waiting for this thread to complete startup, so we signal it here and share our
|
||||||
// startup status.
|
// startup status.
|
||||||
Lock(dewrapper->lock);
|
Lock(dewrapper->lock);
|
||||||
|
dewrapper->thread_started = true;
|
||||||
dewrapper->thread_start_result = result;
|
dewrapper->thread_start_result = result;
|
||||||
Condition_Post(dewrapper->condition);
|
Condition_Post(dewrapper->condition);
|
||||||
Unlock(dewrapper->lock);
|
Unlock(dewrapper->lock);
|
||||||
|
@ -519,6 +521,7 @@ k4a_result_t dewrapper_start(dewrapper_t dewrapper_handle,
|
||||||
dewrapper->fps = config->camera_fps;
|
dewrapper->fps = config->camera_fps;
|
||||||
dewrapper->depth_mode = config->depth_mode;
|
dewrapper->depth_mode = config->depth_mode;
|
||||||
dewrapper->thread_stop = false;
|
dewrapper->thread_stop = false;
|
||||||
|
dewrapper->thread_started = false;
|
||||||
|
|
||||||
THREADAPI_RESULT tresult = ThreadAPI_Create(&dewrapper->thread, depth_engine_thread, dewrapper);
|
THREADAPI_RESULT tresult = ThreadAPI_Create(&dewrapper->thread, depth_engine_thread, dewrapper);
|
||||||
result = K4A_RESULT_FROM_BOOL(tresult == THREADAPI_OK);
|
result = K4A_RESULT_FROM_BOOL(tresult == THREADAPI_OK);
|
||||||
|
@ -527,9 +530,12 @@ k4a_result_t dewrapper_start(dewrapper_t dewrapper_handle,
|
||||||
{
|
{
|
||||||
Lock(dewrapper->lock);
|
Lock(dewrapper->lock);
|
||||||
locked = true;
|
locked = true;
|
||||||
int infinite_timeout = 0;
|
if (!dewrapper->thread_started)
|
||||||
COND_RESULT cond_result = Condition_Wait(dewrapper->condition, dewrapper->lock, infinite_timeout);
|
{
|
||||||
result = K4A_RESULT_FROM_BOOL(cond_result == COND_OK);
|
int infinite_timeout = 0;
|
||||||
|
COND_RESULT cond_result = Condition_Wait(dewrapper->condition, dewrapper->lock, infinite_timeout);
|
||||||
|
result = K4A_RESULT_FROM_BOOL(cond_result == COND_OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (K4A_SUCCEEDED(result) && K4A_FAILED(dewrapper->thread_start_result))
|
if (K4A_SUCCEEDED(result) && K4A_FAILED(dewrapper->thread_start_result))
|
||||||
|
|
|
@ -14,6 +14,7 @@ set(SOURCE_FILES
|
||||||
k4aimudatagraph.cpp
|
k4aimudatagraph.cpp
|
||||||
k4aimusamplesource.cpp
|
k4aimusamplesource.cpp
|
||||||
k4aimuwindow.cpp
|
k4aimuwindow.cpp
|
||||||
|
k4alogdockcontrol.cpp
|
||||||
k4amicrophone.cpp
|
k4amicrophone.cpp
|
||||||
k4amicrophonelistener.cpp
|
k4amicrophonelistener.cpp
|
||||||
k4apointcloudrenderer.cpp
|
k4apointcloudrenderer.cpp
|
||||||
|
@ -26,6 +27,7 @@ set(SOURCE_FILES
|
||||||
k4avideowindow.cpp
|
k4avideowindow.cpp
|
||||||
k4aviewer.cpp
|
k4aviewer.cpp
|
||||||
k4aviewerimage.cpp
|
k4aviewerimage.cpp
|
||||||
|
k4aviewerlogmanager.cpp
|
||||||
k4aviewererrormanager.cpp
|
k4aviewererrormanager.cpp
|
||||||
k4aviewersettingsmanager.cpp
|
k4aviewersettingsmanager.cpp
|
||||||
k4awindowmanager.cpp
|
k4awindowmanager.cpp
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
// Associated header
|
||||||
|
//
|
||||||
|
#include "k4alogdockcontrol.h"
|
||||||
|
|
||||||
|
// System headers
|
||||||
|
//
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
// Library headers
|
||||||
|
//
|
||||||
|
|
||||||
|
// Project headers
|
||||||
|
//
|
||||||
|
#include "k4aimguiextensions.h"
|
||||||
|
|
||||||
|
using namespace k4aviewer;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// Maximum number of log entries to keep in memory
|
||||||
|
//
|
||||||
|
constexpr static size_t MaxLines = 10000;
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
|
||||||
|
// Get a string representation of a log level suitable for printing
|
||||||
|
// in the log box (fields are fixed-width)
|
||||||
|
//
|
||||||
|
const char *LogLevelToString(k4a_log_level_t logLevel)
|
||||||
|
{
|
||||||
|
switch(logLevel)
|
||||||
|
{
|
||||||
|
case K4A_LOG_LEVEL_CRITICAL: return "critical";
|
||||||
|
case K4A_LOG_LEVEL_ERROR: return "error ";
|
||||||
|
case K4A_LOG_LEVEL_WARNING: return "warning ";
|
||||||
|
case K4A_LOG_LEVEL_INFO: return "info ";
|
||||||
|
case K4A_LOG_LEVEL_TRACE: return "trace ";
|
||||||
|
|
||||||
|
default: return "[unknown]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ImVec4 &LogLevelToColor(k4a_log_level_t logLevel)
|
||||||
|
{
|
||||||
|
static const ImVec4 critical = ImVec4(1.f, 0.f, 0.f, 1.f);
|
||||||
|
static const ImVec4 error = ImVec4(1.f, .3f, 0.f, 1.f);
|
||||||
|
static const ImVec4 warning = ImVec4(1.f, 1.f, 0.f, 1.f);
|
||||||
|
static const ImVec4 info = ImVec4(1.f, 1.f, 1.f, 1.f);
|
||||||
|
static const ImVec4 trace = ImVec4(.5f, .5f, .5f, 1.f);
|
||||||
|
|
||||||
|
switch(logLevel)
|
||||||
|
{
|
||||||
|
case K4A_LOG_LEVEL_CRITICAL: return critical;
|
||||||
|
case K4A_LOG_LEVEL_ERROR: return error;
|
||||||
|
case K4A_LOG_LEVEL_WARNING: return warning;
|
||||||
|
case K4A_LOG_LEVEL_INFO: return info;
|
||||||
|
case K4A_LOG_LEVEL_TRACE: return trace;
|
||||||
|
|
||||||
|
default: return warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String mappings used for the combo box used to select error levels
|
||||||
|
//
|
||||||
|
const std::vector<std::pair<k4a_log_level_t, std::string>> LogLevelLabels = {
|
||||||
|
{K4A_LOG_LEVEL_CRITICAL, "Critical"},
|
||||||
|
{K4A_LOG_LEVEL_ERROR, "Error"},
|
||||||
|
{K4A_LOG_LEVEL_WARNING, "Warning"},
|
||||||
|
{K4A_LOG_LEVEL_INFO, "Info"},
|
||||||
|
{K4A_LOG_LEVEL_TRACE, "Trace"}
|
||||||
|
};
|
||||||
|
|
||||||
|
// clang-format on
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
K4ALogDockControl::K4ALogDockControl() : m_logListener(std::make_shared<LogListener>())
|
||||||
|
{
|
||||||
|
K4AViewerLogManager::Instance().RegisterListener(m_logListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void K4ALogDockControl::LogListener::Log(k4a_log_level_t severity, const char *file, int line, const char *msg)
|
||||||
|
{
|
||||||
|
if (severity > m_minSeverity)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
|
m_entries.emplace_back(severity, file, line, msg);
|
||||||
|
if (m_entries.size() > MaxLines)
|
||||||
|
{
|
||||||
|
m_entries.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
K4ADockControlStatus K4ALogDockControl::Show()
|
||||||
|
{
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
if (ImGui::Button("Clear Log"))
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_logListener->m_mutex);
|
||||||
|
m_logListener->m_entries.clear();
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
const bool copy = ImGui::Button("Copy Log to Clipboard");
|
||||||
|
|
||||||
|
m_logListener->m_updated |= ImGuiExtensions::K4AComboBox("Severity",
|
||||||
|
"",
|
||||||
|
ImGuiComboFlags_None,
|
||||||
|
LogLevelLabels,
|
||||||
|
&m_logListener->m_minSeverity);
|
||||||
|
m_logListener->m_updated |= ImGui::InputText("Search", &m_filterString[0], m_filterString.size());
|
||||||
|
m_logListener->m_updated |= ImGui::Checkbox("Show line info", &m_showLineInfo);
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
ImGui::BeginChild("LogTextScrollArea", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||||
|
|
||||||
|
if (copy)
|
||||||
|
{
|
||||||
|
ImGui::LogToClipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool updated = false;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_logListener->m_mutex);
|
||||||
|
for (const LogEntry &entry : m_logListener->m_entries)
|
||||||
|
{
|
||||||
|
std::stringstream lineBuilder;
|
||||||
|
lineBuilder << "[ " << LogLevelToString(entry.Severity) << " ] ";
|
||||||
|
|
||||||
|
if (m_showLineInfo)
|
||||||
|
{
|
||||||
|
lineBuilder << "( " << entry.File << ":" << entry.Line << " ) ";
|
||||||
|
}
|
||||||
|
|
||||||
|
lineBuilder << ": " << entry.Msg.c_str();
|
||||||
|
std::string lineStr = lineBuilder.str();
|
||||||
|
if (m_filterString[0] != '\0' && lineStr.find(&m_filterString[0]) == std::string::npos)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ImGui::TextColored(LogLevelToColor(entry.Severity), "%s", lineStr.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
updated = m_logListener->m_updated;
|
||||||
|
m_logListener->m_updated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (copy)
|
||||||
|
{
|
||||||
|
ImGui::LogFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updated)
|
||||||
|
{
|
||||||
|
ImGui::SetScrollHere(1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndChild();
|
||||||
|
|
||||||
|
return K4ADockControlStatus::Ok;
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#ifndef K4ALOGDOCKCONTROL_H
|
||||||
|
#define K4ALOGDOCKCONTROL_H
|
||||||
|
|
||||||
|
// System headers
|
||||||
|
//
|
||||||
|
#include <array>
|
||||||
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Library headers
|
||||||
|
//
|
||||||
|
|
||||||
|
// Project headers
|
||||||
|
//
|
||||||
|
#include "ik4adockcontrol.h"
|
||||||
|
#include "k4aviewerlogmanager.h"
|
||||||
|
|
||||||
|
namespace k4aviewer
|
||||||
|
{
|
||||||
|
|
||||||
|
class K4ALogDockControl : public IK4ADockControl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
K4ALogDockControl();
|
||||||
|
~K4ALogDockControl() override = default;
|
||||||
|
|
||||||
|
K4ALogDockControl(K4ALogDockControl &) = delete;
|
||||||
|
K4ALogDockControl(K4ALogDockControl &&) = delete;
|
||||||
|
K4ALogDockControl operator=(K4ALogDockControl &) = delete;
|
||||||
|
K4ALogDockControl operator=(K4ALogDockControl &&) = delete;
|
||||||
|
|
||||||
|
K4ADockControlStatus Show() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct LogEntry
|
||||||
|
{
|
||||||
|
LogEntry() = default;
|
||||||
|
LogEntry(k4a_log_level_t severity, const char *file, int line, const char *msg) :
|
||||||
|
Severity(severity),
|
||||||
|
File(file),
|
||||||
|
Line(line),
|
||||||
|
Msg(msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
k4a_log_level_t Severity;
|
||||||
|
std::string File;
|
||||||
|
int Line;
|
||||||
|
std::string Msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LogListener : public IK4AViewerLogListener
|
||||||
|
{
|
||||||
|
void Log(k4a_log_level_t severity, const char *file, int line, const char *msg) override;
|
||||||
|
~LogListener() override = default;
|
||||||
|
|
||||||
|
std::list<LogEntry> m_entries;
|
||||||
|
bool m_updated = false;
|
||||||
|
std::mutex m_mutex;
|
||||||
|
k4a_log_level_t m_minSeverity = K4A_LOG_LEVEL_WARNING;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<LogListener> m_logListener;
|
||||||
|
std::array<char, 100> m_filterString = { { '\0' } };
|
||||||
|
bool m_showLineInfo = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace k4aviewer
|
||||||
|
|
||||||
|
#endif
|
|
@ -17,6 +17,7 @@
|
||||||
// Project headers
|
// Project headers
|
||||||
//
|
//
|
||||||
#include "k4aaudiomanager.h"
|
#include "k4aaudiomanager.h"
|
||||||
|
#include "k4alogdockcontrol.h"
|
||||||
#include "k4asourceselectiondockcontrol.h"
|
#include "k4asourceselectiondockcontrol.h"
|
||||||
#include "k4aviewererrormanager.h"
|
#include "k4aviewererrormanager.h"
|
||||||
#include "k4aviewerutil.h"
|
#include "k4aviewerutil.h"
|
||||||
|
@ -145,6 +146,7 @@ K4AViewer::K4AViewer(const K4AViewerOptions &args)
|
||||||
}
|
}
|
||||||
|
|
||||||
K4AWindowManager::Instance().PushLeftDockControl(std14::make_unique<K4ASourceSelectionDockControl>());
|
K4AWindowManager::Instance().PushLeftDockControl(std14::make_unique<K4ASourceSelectionDockControl>());
|
||||||
|
K4AWindowManager::Instance().PushBottomDockControl(std14::make_unique<K4ALogDockControl>());
|
||||||
}
|
}
|
||||||
|
|
||||||
K4AViewer::~K4AViewer()
|
K4AViewer::~K4AViewer()
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
// Associated header
|
||||||
|
//
|
||||||
|
#include "k4aviewerlogmanager.h"
|
||||||
|
|
||||||
|
// System headers
|
||||||
|
//
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Library headers
|
||||||
|
//
|
||||||
|
|
||||||
|
// Project headers
|
||||||
|
//
|
||||||
|
|
||||||
|
using namespace k4aviewer;
|
||||||
|
|
||||||
|
K4AViewerLogManager &K4AViewerLogManager::Instance()
|
||||||
|
{
|
||||||
|
static K4AViewerLogManager instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
K4AViewerLogManager::K4AViewerLogManager()
|
||||||
|
{
|
||||||
|
if (k4a_set_debug_message_handler(&LoggerCallback, this, K4A_LOG_LEVEL_TRACE) != K4A_RESULT_SUCCEEDED)
|
||||||
|
{
|
||||||
|
Log(K4A_LOG_LEVEL_ERROR, __FILE__, __LINE__, "Failed to initialize K4A logging!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
K4AViewerLogManager::~K4AViewerLogManager()
|
||||||
|
{
|
||||||
|
(void)k4a_set_debug_message_handler(nullptr, nullptr, K4A_LOG_LEVEL_TRACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void K4AViewerLogManager::Log(k4a_log_level_t severity, const char *file, int line, const char *msg)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
for (auto wpListener = m_listeners.begin(); wpListener != m_listeners.end();)
|
||||||
|
{
|
||||||
|
std::shared_ptr<IK4AViewerLogListener> spListener = wpListener->lock();
|
||||||
|
if (spListener)
|
||||||
|
{
|
||||||
|
spListener->Log(severity, file, line, msg);
|
||||||
|
++wpListener;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto toDelete = wpListener;
|
||||||
|
++wpListener;
|
||||||
|
m_listeners.erase(toDelete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void K4AViewerLogManager::RegisterListener(std::shared_ptr<IK4AViewerLogListener> listener)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
m_listeners.emplace_back(std::move(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
void K4AViewerLogManager::LoggerCallback(void *context,
|
||||||
|
k4a_log_level_t level,
|
||||||
|
const char *file,
|
||||||
|
int line,
|
||||||
|
const char *msg)
|
||||||
|
{
|
||||||
|
K4AViewerLogManager *instance = reinterpret_cast<K4AViewerLogManager *>(context);
|
||||||
|
instance->Log(level, file, line, msg);
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
#ifndef K4AVIEWERLOGMANAGER_H
|
||||||
|
#define K4AVIEWERLOGMANAGER_H
|
||||||
|
|
||||||
|
// System headers
|
||||||
|
//
|
||||||
|
#include <list>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
// Library headers
|
||||||
|
//
|
||||||
|
#include <k4a/k4a.hpp>
|
||||||
|
|
||||||
|
// Project headers
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace k4aviewer
|
||||||
|
{
|
||||||
|
class IK4AViewerLogListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Log(k4a_log_level_t severity, const char *file, int line, const char *msg) = 0;
|
||||||
|
virtual ~IK4AViewerLogListener() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
class K4AViewerLogManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static K4AViewerLogManager &Instance();
|
||||||
|
|
||||||
|
void Log(k4a_log_level_t severity, const char *file, int line, const char *msg);
|
||||||
|
|
||||||
|
void RegisterListener(std::shared_ptr<IK4AViewerLogListener> listener);
|
||||||
|
|
||||||
|
private:
|
||||||
|
K4AViewerLogManager();
|
||||||
|
~K4AViewerLogManager();
|
||||||
|
|
||||||
|
static void LoggerCallback(void *context, k4a_log_level_t level, const char *file, int line, const char *msg);
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
std::list<std::weak_ptr<IK4AViewerLogListener>> m_listeners;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace k4aviewer
|
||||||
|
|
||||||
|
#endif
|
|
@ -61,7 +61,7 @@ private:
|
||||||
ImVec2 m_regionSize = ImVec2(0.f, 0.f);
|
ImVec2 m_regionSize = ImVec2(0.f, 0.f);
|
||||||
|
|
||||||
// The actual size/location of the dock window, in absolute window coordinates.
|
// The actual size/location of the dock window, in absolute window coordinates.
|
||||||
// Must be within by m_viewRegion*
|
// Must be within by m_region*
|
||||||
//
|
//
|
||||||
ImVec2 m_size = ImVec2(0.f, 0.f);
|
ImVec2 m_size = ImVec2(0.f, 0.f);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче