You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
5.6 KiB

// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2020 Intel Corporation. All Rights Reserved.
#pragma once
#include <librealsense2/rs.hpp>
#include "rect.h"
#include "animated.h"
#include <functional>
#include <string>
#include <map>
#include "rendering.h"
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <imgui.h>
#include <rsutils/concurrency/concurrency.h>
namespace rs2
{
class device_model;
class ux_window;
class stream_dashboard
{
public:
stream_dashboard(std::string name, int size) : q(size), name(name), t([this](){ thread_function(); }) {}
virtual ~stream_dashboard()
{
stop = true;
t.join();
}
std::string get_name() const { return name; }
void add_frame(rs2::frame f) { q.enqueue(f); }
virtual void draw(ux_window& win, rect r) = 0;
virtual int get_height() const { return 150; }
virtual void clear(bool full = false) {}
void close() { to_close = true; }
bool closing() const { return to_close; }
protected:
virtual void process_frame(rs2::frame f) = 0;
void write_shared_data(std::function<void()> action)
{
std::lock_guard<std::mutex> lock(m);
action();
}
template<class T>
T read_shared_data(std::function<T()> action)
{
std::lock_guard<std::mutex> lock(m);
T res = action();
return res;
}
void add_point(float x, float y) { xy.push_back(std::make_pair(x, y)); }
void draw_dashboard(ux_window& win, rect& r);
private:
void thread_function()
{
while(!stop)
{
rs2::frame f;
if (q.try_wait_for_frame(&f, 100))
process_frame(f);
}
}
std::string name;
rs2::frame_queue q;
std::mutex m;
std::atomic<int> stop { false };
std::thread t;
std::vector<std::pair<float, float>> xy;
bool to_close = false;
};
class frame_drops_dashboard : public stream_dashboard
{
public:
frame_drops_dashboard(std::string name, int* frame_drop_count, int* total)
: stream_dashboard(name, 30),
last_time(glfwGetTime()), frame_drop_count(frame_drop_count), total(total)
{
clear(true);
}
void process_frame(rs2::frame f) override;
void draw(ux_window& win, rect r) override;
int get_height() const override;
void clear(bool full) override;
private:
std::map<int, double> stream_to_time;
int drops = 0;
double last_time;
std::deque<int> drops_history;
int *frame_drop_count, *total;
int counter = 0;
int method = 0;
};
class output_model
{
public:
struct log_entry
{
std::string line = "";
std::string filename = "";
rs2_log_severity severity = RS2_LOG_SEVERITY_FATAL;
int line_number = 0;
double time_added = 0.0;
std::string timestamp = "";
bool selected = false;
};
void update_dashboards(rs2::frame f);
output_model();
~output_model();
void add_log(rs2_log_severity severity, std::string filename, int line_number, std::string line);
void draw(ux_window& win, rect view_rect, std::vector<std::unique_ptr<device_model>> & device_models);
int get_output_height() const { return default_log_h; }
int get_dashboard_width() const { return default_dashboard_w; }
void run_command(std::string command, std::vector<std::unique_ptr<device_model>> & device_models);
bool user_defined_command(std::string command, std::vector<std::unique_ptr<device_model>> & device_models);
private:
void open(ux_window& win);
void foreach_log(std::function<void(log_entry& line)> action);
bool round_indicator(ux_window& win, std::string icon, int count,
ImVec4 color, std::string tooltip, bool& highlighted, std::string suffix = "");
bool new_log = false;
std::recursive_mutex m;
single_consumer_queue<log_entry> incoming_log_queue;
std::deque<log_entry> notification_logs;
animated<int> default_log_h { 36 };
bool is_output_open = true;
animated< int > default_dashboard_w { 0 };
bool is_dashboard_open = true;
bool enable_firmware_logs = false;
bool errors_selected = false;
bool warnings_selected = false;
bool info_selected = false;
bool errors_highlighted = false;
bool warnings_highlighted = false;
bool info_highlighted = false;
bool drops_highlighted = false;
int number_of_errors = 0;
int number_of_warnings = 0;
int number_of_info = 0;
int number_of_drops = 0;
int total_frames = 0;
animated<int> search_width { 0, std::chrono::milliseconds(400) };
bool search_open = false;
std::deque<std::string> autocomplete;
std::mutex devices_mutex;
std::vector<rs2::device> devices;
std::string search_line { "" };
std::string command_line { "" };
std::deque<std::string> commands_histroy;
int history_offset = 0;
bool command_focus = true;
std::vector<std::shared_ptr<stream_dashboard>> dashboards;
std::map<std::string, std::function<std::shared_ptr<stream_dashboard>(std::string)>> available_dashboards;
std::atomic<int> to_stop { 0 };
std::thread fw_logger;
void thread_loop();
};
}