Add LogcatEntries helper

This commit is contained in:
blankie 2023-03-29 17:08:31 +07:00
parent 5ad0938b3e
commit 2a1233d95b
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
11 changed files with 89 additions and 70 deletions

View File

@ -3,6 +3,7 @@
#include "log.h"
#include "config.h"
#include "filters.h"
#include "logcat_entry.h"
#include "logcat_thread.h"
#include "windows/logs.h"
@ -12,8 +13,7 @@
#include "windows/debug.h"
#endif
static inline void check_for_logcat_items(LogcatThread& logcat_thread, const Config& active_config,
std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets) {
static inline void check_for_logcat_items(LogcatThread& logcat_thread, LogcatEntries& logcat_entries) {
LogcatThreadItem* logcat_thread_item;
while ((logcat_thread_item = logcat_thread.atomic_ring_buffer.get())) {
@ -21,9 +21,6 @@ static inline void check_for_logcat_items(LogcatThread& logcat_thread, const Con
log(std::move(*log_entry), false);
} else if (LogcatEntry* logcat_entry = std::get_if<LogcatEntry>(logcat_thread_item)) {
logcat_entries.push_back(std::move(*logcat_entry));
if (matches(logcat_entries.back(), active_config.filters, active_config.exclusions)) {
filtered_logcat_entry_offsets.push_back(logcat_entries.size() - 1);
}
} else {
throw std::runtime_error("Cannot handle all possible logcat thread item variants");
}
@ -37,17 +34,16 @@ void event_loop(ImFont* monospace_font, Config& active_config, LogcatThread& log
static bool show_settings_window = false;
static bool show_logs_window = false;
static size_t log_entries_read = 0;
static std::vector<LogcatEntry> logcat_entries;
static std::vector<size_t> filtered_logcat_entry_offsets;
static LogcatEntries logcat_entries(active_config);
check_for_logcat_items(logcat_thread, active_config, logcat_entries, filtered_logcat_entry_offsets);
check_for_logcat_items(logcat_thread, logcat_entries);
#ifndef NDEBUG
debug_window(logcat_thread, active_config, logcat_entries, filtered_logcat_entry_offsets);
debug_window(logcat_thread, logcat_entries);
#endif
if (show_settings_window) {
settings_window(monospace_font, active_config, inactive_config, logcat_entries, filtered_logcat_entry_offsets, &show_settings_window);
settings_window(monospace_font, active_config, inactive_config, logcat_entries, &show_settings_window);
}
if (show_logs_window) {
@ -59,8 +55,7 @@ void event_loop(ImFont* monospace_font, Config& active_config, LogcatThread& log
}
// log_entries must not be mutated until the show logs button
main_window(log_entries_read == log_entries.size(), monospace_font, logcat_thread,
logcat_entries, filtered_logcat_entry_offsets,
main_window(log_entries_read == log_entries.size(), monospace_font, logcat_thread, logcat_entries,
active_config, inactive_config,
&show_settings_window, &show_logs_window);
}

View File

@ -11,11 +11,10 @@ enum class ExportAmount : int {
Filtered = 1,
};
static inline void export_logcat_entries(File& file, const std::vector<LogcatEntry>& logcat_entries,
const std::vector<size_t>& filtered_logcat_entry_offsets, ExportAmount export_amount, bool export_buffers);
static inline void export_logcat_entries(File& file, const LogcatEntries& logcat_entries, ExportAmount export_amount, bool export_buffers);
static inline std::optional<File> save_file_picker();
void export_fragment(const std::vector<LogcatEntry>& logcat_entries, const std::vector<size_t>& filtered_logcat_entry_offsets) {
void export_fragment(const LogcatEntries& logcat_entries) {
static ExportAmount export_amount = ExportAmount::Filtered;
static bool export_buffers = true;
@ -27,7 +26,7 @@ void export_fragment(const std::vector<LogcatEntry>& logcat_entries, const std::
if (ImGui::Button("Export to File")) {
std::optional<File> file = save_file_picker();
if (file) {
export_logcat_entries(*file, logcat_entries, filtered_logcat_entry_offsets, export_amount, export_buffers);
export_logcat_entries(*file, logcat_entries, export_amount, export_buffers);
ImGui::CloseCurrentPopup();
}
}
@ -38,11 +37,10 @@ void export_fragment(const std::vector<LogcatEntry>& logcat_entries, const std::
}
}
static inline void export_logcat_entries(File& file, const std::vector<LogcatEntry>& logcat_entries,
const std::vector<size_t>& filtered_logcat_entry_offsets, ExportAmount export_amount, bool export_buffers) {
static inline void export_logcat_entries(File& file, const LogcatEntries& logcat_entries, ExportAmount export_amount, bool export_buffers) {
// TODO actually do the job
file.write(std::string("Count of all entries: ") + std::to_string(logcat_entries.size()) + '\n');
file.write(std::string("Count of filtered entries: ") + std::to_string(filtered_logcat_entry_offsets.size()) + '\n');
file.write(std::string("Count of all entries: ") + std::to_string(logcat_entries.size_all()) + '\n');
file.write(std::string("Count of filtered entries: ") + std::to_string(logcat_entries.size_filtered()) + '\n');
file.write(std::string("Export amount: ") + (export_amount == ExportAmount::All ? "all" : "filtered") + '\n');
file.write(std::string("Export buffers: ") + (export_buffers ? "true" : "false") + '\n');
}

View File

@ -1,8 +1,7 @@
#pragma once
#include <vector>
#include <stddef.h>
struct LogcatEntry; // forward declaration from ../logcat_entry.h
class LogcatEntries; // forward declaration from ../logcat_entry.h
void export_fragment(const std::vector<LogcatEntry>& logcat_entries, const std::vector<size_t>& filtered_logcat_entry_offsets);
void export_fragment(const LogcatEntries& logcat_entries);

View File

@ -3,6 +3,7 @@
#include <optional>
#include <stdexcept>
#include "config.h"
#include "logcat_entry.h"
#include "pcre2_wrapper.h"
@ -162,6 +163,23 @@ std::optional<Buffer> try_parse_buffer(char* buf, size_t length) {
}
void LogcatEntries::push_back(LogcatEntry entry) {
this->_logcat_entries.push_back(std::move(entry));
if (matches(this->_logcat_entries.back(), this->_config.filters, this->_config.exclusions)) {
this->_filtered_offsets.push_back(this->_logcat_entries.size() - 1);
}
}
void LogcatEntries::refresh() {
this->_filtered_offsets.clear();
for (size_t i = 0; i < this->_logcat_entries.size(); i++) {
if (matches(this->_logcat_entries[i], this->_config.filters, this->_config.exclusions)) {
this->_filtered_offsets.push_back(i);
}
}
}
void from_json(const nlohmann::json& j, Buffer& buffer) {
const std::string& str = j.get_ref<const nlohmann::json::string_t&>();

View File

@ -4,6 +4,8 @@
#include <optional>
#include <nlohmann/json.hpp>
struct Config; // forward declaration from config.h
enum class Buffer {
Unknown = 0b1,
Main = 0b10,
@ -34,6 +36,41 @@ struct LogcatEntry {
std::string message;
};
class LogcatEntries {
public:
// https://stackoverflow.com/a/2173764
LogcatEntries(const LogcatEntries&) = delete;
LogcatEntries& operator=(const LogcatEntries&) = delete;
LogcatEntries(const Config& config) : _config(config) {}
inline constexpr size_t size_all() const noexcept {
return this->_logcat_entries.size();
}
inline constexpr size_t size_filtered() const noexcept {
return this->_filtered_offsets.size();
}
inline constexpr void clear() noexcept {
this->_filtered_offsets.clear();
this->_logcat_entries.clear();
}
inline constexpr const LogcatEntry& at_all(size_t index) const noexcept {
return this->_logcat_entries[index];
}
inline constexpr const LogcatEntry& at_filtered(size_t index) const noexcept {
return this->_logcat_entries[this->_filtered_offsets[index]];
}
void push_back(LogcatEntry entry);
void refresh();
private:
std::vector<LogcatEntry> _logcat_entries;
std::vector<size_t> _filtered_offsets;
const Config& _config;
};
const char* to_string(Priority priority);
const char* to_string(Buffer buffer);
std::string to_string(const LogcatEntry& logcat_entry);

View File

@ -2,14 +2,11 @@
#include "../myimconfig.h"
#include "../log.h"
#include "../config.h"
#include "../filters.h"
#include "../logcat_entry.h"
#include "../logcat_thread.h"
#include "debug.h"
void debug_window(LogcatThread& logcat_thread, const Config& active_config,
std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets) {
void debug_window(LogcatThread& logcat_thread, LogcatEntries& logcat_entries) {
static bool show_demo_window = false;
static size_t add_log_entry_presses = 1;
static bool log_entry_every_second = false;
@ -54,14 +51,8 @@ void debug_window(LogcatThread& logcat_thread, const Config& active_config,
}
ImGui::Separator();
auto add_logcat_entry = [&](LogcatEntry logcat_entry) {
logcat_entries.push_back(std::move(logcat_entry));
if (matches(logcat_entries.back(), active_config.filters, active_config.exclusions)) {
filtered_logcat_entry_offsets.push_back(logcat_entries.size() - 1);
}
};
if (ImGui::Button("Add test entry (w/ user)")) {
add_logcat_entry({
logcat_entries.push_back({
.buffer = Buffer::Main,
.time = time(nullptr),
.user = "blankie",
@ -73,7 +64,7 @@ void debug_window(LogcatThread& logcat_thread, const Config& active_config,
});
}
if (ImGui::Button("Add test entry (w/o user)")) {
add_logcat_entry({
logcat_entries.push_back({
.buffer = Buffer::Crash,
.time = time(nullptr),
.pid = 420,

View File

@ -2,9 +2,7 @@
#include <vector>
struct Config; // forward declaration from ../config.h
struct LogcatEntry; // forward declaration from ../logcat_entry.h
class LogcatEntries; // forward declaration from ../logcat_entry.h
class LogcatThread; // forward declaration from ../logcat_thread.h
void debug_window(LogcatThread& logcat_thread, const Config& active_config,
std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets);
void debug_window(LogcatThread& logcat_thread, LogcatEntries& logcat_entries);

View File

@ -67,7 +67,7 @@ static inline void render_table_item(const LogcatEntry& logcat_entry, size_t log
if (ImGui::TableSetColumnIndex(7)) { ImGui::TextUnformatted(logcat_entry.message); table_item_popup(); }
}
static inline void render_table(ImFont* monospace_font, std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets) {
static inline void render_table(ImFont* monospace_font, const LogcatEntries& logcat_entries) {
static size_t copying_entry_index;
ImGui::TableSetupScrollFreeze(0, 1);
@ -84,20 +84,19 @@ static inline void render_table(ImFont* monospace_font, std::vector<LogcatEntry>
ImGui::PushFont(monospace_font);
ImGuiListClipper clipper;
clipper.Begin(static_cast<int>(filtered_logcat_entry_offsets.size()));
clipper.Begin(static_cast<int>(logcat_entries.size_filtered()));
while (clipper.Step()) {
for (int i_u = clipper.DisplayStart; i_u < clipper.DisplayEnd; i_u++) {
assert(i_u >= 0);
size_t i = static_cast<size_t>(i_u);
size_t logcat_entry_index = filtered_logcat_entry_offsets[i];
render_table_item(logcat_entries[logcat_entry_index], logcat_entry_index, &copying_entry_index);
render_table_item(logcat_entries.at_filtered(i), i, &copying_entry_index);
}
}
clipper.End();
if (ImGui::BeginPopup("copy_popup")) {
render_table_item_context_menu(logcat_entries[copying_entry_index]);
render_table_item_context_menu(logcat_entries.at_filtered(copying_entry_index));
ImGui::EndPopup();
}
@ -109,8 +108,7 @@ static inline void render_table(ImFont* monospace_font, std::vector<LogcatEntry>
ImGui::EndTable();
}
void main_window(bool latest_log_entries_read, ImFont* monospace_font, LogcatThread& logcat_thread,
std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets,
void main_window(bool latest_log_entries_read, ImFont* monospace_font, LogcatThread& logcat_thread, LogcatEntries& logcat_entries,
const Config& __restrict active_config, Config& __restrict inactive_config,
bool* __restrict show_settings_window, bool* __restrict show_logs_window) {
@ -150,7 +148,6 @@ void main_window(bool latest_log_entries_read, ImFont* monospace_font, LogcatThr
if (ImGui::Button("Start", !logcat_running)) {
logcat_entries.clear();
filtered_logcat_entry_offsets.clear();
logcat_thread.logcat_process_request.store(LogcatProcessRequest::Start);
}
ImGui::SameLine();
@ -160,7 +157,6 @@ void main_window(bool latest_log_entries_read, ImFont* monospace_font, LogcatThr
ImGui::SameLine();
if (ImGui::Button("Restart", logcat_running)) {
logcat_entries.clear();
filtered_logcat_entry_offsets.clear();
logcat_thread.logcat_process_request.store(LogcatProcessRequest::Start);
}
@ -175,7 +171,7 @@ void main_window(bool latest_log_entries_read, ImFont* monospace_font, LogcatThr
ImGui::OpenPopup("export_logcat");
}
if (ImGui::BeginPopup("export_logcat")) {
export_fragment(logcat_entries, filtered_logcat_entry_offsets);
export_fragment(logcat_entries);
ImGui::EndPopup();
}
@ -186,7 +182,7 @@ void main_window(bool latest_log_entries_read, ImFont* monospace_font, LogcatThr
// and Tables/Vertical scrolling, with clipping
const constexpr ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable;
if (ImGui::BeginTable("logcat", 8, flags)) {
render_table(monospace_font, logcat_entries, filtered_logcat_entry_offsets);
render_table(monospace_font, logcat_entries);
}
ImGui::End();
}

View File

@ -5,9 +5,8 @@ struct ImFont; // forward declaration from imgui/imgui.h
struct Config; // forward declaration from ../config.h
class LogcatThread; // forward declaration from ../logcat_thread.h
#include "../logcat_entry.h"
class LogcatEntries; // forward declaration from ../logcat_entry.h
void main_window(bool latest_log_entries_read, ImFont* monospace_font, LogcatThread& logcat_thread,
std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets,
void main_window(bool latest_log_entries_read, ImFont* monospace_font, LogcatThread& logcat_thread, LogcatEntries& logcat_entries,
const Config& __restrict active_config, Config& __restrict inactive_config,
bool* __restrict show_settings_window, bool* __restrict show_logs_window);

View File

@ -7,16 +7,6 @@
#include "../fragments/ok_buttons_fragment.h"
#include "settings.h"
static void update_logcat_entries(const Config& active_config,
const std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets) {
filtered_logcat_entry_offsets.clear();
for (size_t i=0; i < logcat_entries.size(); i++) {
if (matches(logcat_entries[i], active_config.filters, active_config.exclusions)) {
filtered_logcat_entry_offsets.push_back(i);
}
}
}
static void try_write_config(const Config& config) {
try {
write_config(config);
@ -41,8 +31,7 @@ static inline void settings_fragment(ImFont* monospace_font, Config& inactive_co
}
void settings_window(ImFont* monospace_font, Config& __restrict active_config, Config& __restrict inactive_config,
const std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets,
bool* p_open) {
LogcatEntries& logcat_entries, bool* p_open) {
if (!ImGui::BeginWithCloseShortcut("Settings", p_open)) {
ImGui::End();
return;
@ -67,7 +56,7 @@ void settings_window(ImFont* monospace_font, Config& __restrict active_config, C
ImGui::Separator();
ok_buttons_fragment(p_open, [&]() {
active_config = std::move(inactive_config);
update_logcat_entries(active_config, logcat_entries, filtered_logcat_entry_offsets);
logcat_entries.refresh();
try_write_config(active_config);
}, [&]() {
active_config.logcat_command = inactive_config.logcat_command;
@ -75,7 +64,7 @@ void settings_window(ImFont* monospace_font, Config& __restrict active_config, C
active_config.monospace_font_size = inactive_config.monospace_font_size;
copy_filters(active_config.filters, inactive_config.filters);
copy_filters(active_config.exclusions, inactive_config.exclusions);
update_logcat_entries(active_config, logcat_entries, filtered_logcat_entry_offsets);
logcat_entries.refresh();
try_write_config(active_config);
});
ImGui::End();

View File

@ -4,8 +4,7 @@
struct ImFont; // forward declaration from imgui/imgui.h
struct Config; // forward declaration from ../config.h
struct LogcatEntry; // forward declaration from ../logcat_entry.h
class LogcatEntries; // forward declaration from ../logcat_entry.h
void settings_window(ImFont* monospace_font, Config& __restrict active_config, Config& __restrict inactive_config,
const std::vector<LogcatEntry>& logcat_entries, std::vector<size_t>& filtered_logcat_entry_offsets,
bool* p_open);
LogcatEntries& logcat_entries, bool* p_open);