2024-07-12 07:53:01 +00:00
|
|
|
// ************************************
|
|
|
|
// *
|
|
|
|
// * rntviewer
|
|
|
|
// *
|
|
|
|
// * A graphical RNTuple visualizer
|
|
|
|
// *
|
|
|
|
// * @author silverweed, 2024
|
|
|
|
// *
|
|
|
|
// ***********************************
|
2024-07-10 17:38:16 +00:00
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdint>
|
2024-07-25 15:49:44 +00:00
|
|
|
#include <cmath>
|
|
|
|
#include <cstring>
|
2024-07-25 16:23:58 +00:00
|
|
|
#include <cassert>
|
|
|
|
|
2024-07-18 13:32:32 +00:00
|
|
|
#include <byteswap.h>
|
2024-07-10 17:38:16 +00:00
|
|
|
#include <chrono>
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
#include <sanitizer/asan_interface.h>
|
|
|
|
#endif
|
|
|
|
|
2024-07-25 16:23:58 +00:00
|
|
|
#ifndef RNT_NO_GFX
|
2024-07-10 17:38:16 +00:00
|
|
|
#include <imgui/imgui.h>
|
|
|
|
#include <imgui/backends/imgui_impl_glfw.h>
|
|
|
|
#include <imgui/backends/imgui_impl_opengl3.h>
|
2024-07-10 19:41:48 +00:00
|
|
|
#include <imgui_club/imgui_memory_editor.h>
|
2024-07-10 17:38:16 +00:00
|
|
|
|
|
|
|
#define GLFW_INCLUDE_NONE
|
|
|
|
#include <GLFW/glfw3.h>
|
2024-07-25 16:23:58 +00:00
|
|
|
#endif
|
2024-07-10 17:38:16 +00:00
|
|
|
|
2024-07-25 15:18:50 +00:00
|
|
|
#define V_MAJOR "0"
|
|
|
|
#define V_MINOR "1"
|
|
|
|
|
2024-07-12 09:58:55 +00:00
|
|
|
#include "root/root_inc.h"
|
2024-07-12 07:53:01 +00:00
|
|
|
#include "root/RMicroFileReader.hxx"
|
2024-07-11 14:29:44 +00:00
|
|
|
|
2024-07-10 17:38:16 +00:00
|
|
|
#include "types.h"
|
|
|
|
#include "defer.hpp"
|
2024-07-16 15:28:17 +00:00
|
|
|
#include "prof.hpp"
|
2024-07-10 17:38:16 +00:00
|
|
|
#include "mem.h"
|
2024-07-11 12:00:43 +00:00
|
|
|
#include "str.h"
|
|
|
|
#include "rntuple.h"
|
|
|
|
#include "window.h"
|
2024-07-11 12:27:19 +00:00
|
|
|
#include "render.h"
|
2024-07-10 18:11:42 +00:00
|
|
|
#include "app_state.h"
|
2024-07-10 17:38:16 +00:00
|
|
|
|
2024-07-11 12:00:43 +00:00
|
|
|
// @Platform
|
|
|
|
#include "platform_linux.h"
|
|
|
|
|
2024-07-10 17:38:16 +00:00
|
|
|
namespace chr = std::chrono;
|
|
|
|
|
|
|
|
#include "mem.cpp"
|
2024-07-11 12:00:43 +00:00
|
|
|
#include "str.cpp"
|
|
|
|
#include "rntuple.cpp"
|
2024-07-25 16:23:58 +00:00
|
|
|
#include "render_term.cpp"
|
2024-07-25 15:26:39 +00:00
|
|
|
#include "argparse.cpp"
|
2024-07-10 17:38:16 +00:00
|
|
|
|
2024-07-25 16:23:58 +00:00
|
|
|
#ifndef RNT_NO_GFX
|
|
|
|
#include "render.cpp"
|
|
|
|
#include "mainloop.cpp"
|
|
|
|
#endif
|
2024-07-10 17:38:16 +00:00
|
|
|
|
2024-07-11 12:00:43 +00:00
|
|
|
internal
|
|
|
|
void app_cleanup(App_State &app)
|
|
|
|
{
|
|
|
|
os_stop_file_watch(app);
|
2024-07-16 12:34:51 +00:00
|
|
|
os_unmap_file(app.inspected_file.mem, app.inspected_file.size);
|
|
|
|
if (app.inspected_file.stream) fclose(app.inspected_file.stream);
|
2024-07-11 12:00:43 +00:00
|
|
|
}
|
|
|
|
|
2024-07-10 17:38:16 +00:00
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
2024-07-25 15:26:39 +00:00
|
|
|
// Prepare thread context
|
2024-07-16 15:50:30 +00:00
|
|
|
Thread_Ctx tctx;
|
|
|
|
tctx_init(tctx);
|
|
|
|
defer { tctx_release(); };
|
|
|
|
|
2024-07-10 17:38:16 +00:00
|
|
|
// Allocate program memory
|
|
|
|
Arena *arena = arena_alloc();
|
|
|
|
if (!arena) {
|
|
|
|
fprintf(stderr, "Failed to allocate memory\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
defer { arena_release(arena); };
|
|
|
|
|
2024-07-25 15:26:39 +00:00
|
|
|
// Parse cmdline
|
|
|
|
Cmdline_Args args = parse_args(argc, argv);
|
|
|
|
if (args.show_help_and_exit || !args.ntpl_name.size || !args.file_name.size) {
|
|
|
|
print_help(argv[0]);
|
2024-07-10 17:38:16 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-07-25 16:23:58 +00:00
|
|
|
#ifdef RNT_NO_GFX
|
|
|
|
if (!args.print_to_terminal) {
|
|
|
|
fprintf(stderr, "rntviewer was compiled without graphics support. Please use -t to enable terminal mode.");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2024-07-25 15:26:39 +00:00
|
|
|
// Create app state
|
2024-07-11 12:00:43 +00:00
|
|
|
App_State app {};
|
|
|
|
defer { app_cleanup(app); };
|
|
|
|
|
|
|
|
// Open and map the file
|
2024-07-25 15:01:08 +00:00
|
|
|
if (args.file_name.size) {
|
|
|
|
if (!os_open_and_map_file(args.file_name, app))
|
2024-07-16 09:12:50 +00:00
|
|
|
return 1;
|
2024-07-11 12:00:43 +00:00
|
|
|
|
|
|
|
// Watch file for changes (to adapt the displayed file size - otherwise
|
|
|
|
// we may try to access invalid memory when the file gets shrunk)
|
2024-07-25 15:26:39 +00:00
|
|
|
if (!args.print_to_terminal)
|
|
|
|
os_start_file_watch(args.file_name, app);
|
2024-07-10 17:38:16 +00:00
|
|
|
}
|
|
|
|
|
2024-07-25 15:01:08 +00:00
|
|
|
app.ntpl_name = args.ntpl_name;
|
2024-07-26 14:05:04 +00:00
|
|
|
app.base_display_addr = args.start_addr;
|
2024-07-29 22:03:35 +00:00
|
|
|
app.tfile_data = get_tfile_data(app.inspected_file, app.ntpl_name);
|
2024-07-18 13:32:32 +00:00
|
|
|
app.rndata = get_rntuple_data(arena, app.inspected_file, app.ntpl_name);
|
2024-07-25 15:01:08 +00:00
|
|
|
|
|
|
|
if (args.print_to_terminal) {
|
|
|
|
u64 nbytes_displayed = args.nbytes_displayed;
|
|
|
|
if (!nbytes_displayed)
|
|
|
|
nbytes_displayed = 1000;
|
|
|
|
String8 rendered = render_range_to_string(arena, app, nbytes_displayed, args.n_cols);
|
|
|
|
printf("%s\n", rendered.c());
|
|
|
|
return 0;
|
|
|
|
}
|
2024-07-10 18:11:42 +00:00
|
|
|
|
2024-07-25 16:23:58 +00:00
|
|
|
#ifndef RNT_NO_GFX
|
2024-07-25 15:26:39 +00:00
|
|
|
// Init imgui and GLFW
|
|
|
|
GLFWwindow *window = init_glfw(800, 600);
|
|
|
|
if (!window) {
|
|
|
|
fprintf(stderr, "Failed to init GLFW\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
defer { glfwTerminate(); };
|
|
|
|
|
|
|
|
if (!init_imgui(window)) {
|
|
|
|
fprintf(stderr, "Failed to init Imgui\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-07-25 16:23:58 +00:00
|
|
|
make_viewer(app, args.n_cols);
|
|
|
|
|
2024-07-11 12:00:43 +00:00
|
|
|
// Start main loop
|
2024-07-10 18:11:42 +00:00
|
|
|
run_main_loop(window, arena, app);
|
2024-07-25 16:23:58 +00:00
|
|
|
#endif
|
2024-07-10 17:38:16 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|