2024-07-10 17:38:16 +00:00
|
|
|
#include <ROOT/RNTupleReader.hxx>
|
|
|
|
#include <ROOT/RNTuple.hxx>
|
|
|
|
#include <TFile.h>
|
|
|
|
|
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdint>
|
|
|
|
#include <chrono>
|
|
|
|
|
2024-07-10 20:30:49 +00:00
|
|
|
// @Platform
|
2024-07-10 17:38:16 +00:00
|
|
|
#include <sys/mman.h>
|
2024-07-10 20:30:49 +00:00
|
|
|
#include <sys/inotify.h>
|
2024-07-10 17:38:16 +00:00
|
|
|
#include <unistd.h>
|
2024-07-10 20:30:49 +00:00
|
|
|
#include <limits.h> // for NAME_MAX
|
2024-07-10 17:38:16 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
#include <sanitizer/asan_interface.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#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>
|
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
#include "defer.hpp"
|
|
|
|
#include "mem.h"
|
2024-07-10 18:11:42 +00:00
|
|
|
#include "app_state.h"
|
2024-07-10 17:38:16 +00:00
|
|
|
|
|
|
|
namespace chr = std::chrono;
|
|
|
|
|
|
|
|
#include "mem.cpp"
|
|
|
|
#include "render.cpp"
|
|
|
|
#include "mainloop.cpp"
|
|
|
|
|
|
|
|
using namespace ROOT::Experimental;
|
|
|
|
|
2024-07-10 19:47:37 +00:00
|
|
|
internal
|
|
|
|
b8 init_imgui(GLFWwindow* window) {
|
2024-07-10 17:38:16 +00:00
|
|
|
IMGUI_CHECKVERSION();
|
|
|
|
ImGui::CreateContext();
|
|
|
|
ImGuiIO& io = ImGui::GetIO(); (void) io;
|
|
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
|
|
|
|
|
|
|
ImGui::StyleColorsDark();
|
|
|
|
|
|
|
|
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
2024-07-11 06:49:20 +00:00
|
|
|
ImGui_ImplOpenGL3_Init("#version 400");
|
2024-07-10 17:38:16 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2024-07-10 19:47:37 +00:00
|
|
|
internal
|
|
|
|
void glfw_error_callback(i32 error, const char *description) {
|
2024-07-10 17:38:16 +00:00
|
|
|
fprintf(stderr, "GLFW error %d: %s\n", error, description);
|
|
|
|
}
|
|
|
|
|
2024-07-10 19:47:37 +00:00
|
|
|
internal
|
|
|
|
GLFWwindow* init_glfw(i32 desired_win_width, i32 desired_win_height)
|
2024-07-10 17:38:16 +00:00
|
|
|
{
|
|
|
|
glfwSetErrorCallback(glfw_error_callback);
|
|
|
|
glfwInit();
|
|
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
2024-07-11 06:49:20 +00:00
|
|
|
// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
2024-07-10 17:38:16 +00:00
|
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
|
|
glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE);
|
|
|
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
|
|
|
glfwWindowHint(GLFW_DECORATED, GLFW_TRUE);
|
|
|
|
glfwWindowHint(GLFW_DEPTH_BITS, 32);
|
2024-07-11 06:49:20 +00:00
|
|
|
#ifndef NDEBUG
|
2024-07-10 17:38:16 +00:00
|
|
|
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
GLFWwindow *window = glfwCreateWindow(
|
|
|
|
desired_win_width, desired_win_height,
|
|
|
|
"RNTuple Viewer",
|
|
|
|
nullptr,
|
|
|
|
nullptr
|
|
|
|
);
|
|
|
|
|
|
|
|
glfwMakeContextCurrent(window);
|
|
|
|
//glfwSetFramebufferSizeCallback(window, resize_keep_ratio);
|
|
|
|
|
|
|
|
return window;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
if (argc < 3) {
|
|
|
|
fprintf(stderr, "Usage: %s <ntuple_name> <ntuple_file.root>\n", argv[0]);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Collect arguments
|
|
|
|
const char *ntpl_name = argv[1];
|
|
|
|
const char *fname = argv[2];
|
|
|
|
|
|
|
|
// Allocate program memory
|
|
|
|
Arena *arena = arena_alloc();
|
|
|
|
if (!arena) {
|
|
|
|
fprintf(stderr, "Failed to allocate memory\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
defer { arena_release(arena); };
|
|
|
|
|
|
|
|
// 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-10 20:30:49 +00:00
|
|
|
// Open and map te file
|
2024-07-10 17:38:16 +00:00
|
|
|
FILE *file = fopen(fname, "rb");
|
|
|
|
defer { fclose(file); };
|
|
|
|
|
2024-07-10 20:30:49 +00:00
|
|
|
int fd = fileno(file);
|
|
|
|
size_t fsize = file_size(file);
|
|
|
|
// @Platform
|
2024-07-10 17:38:16 +00:00
|
|
|
void *fmem = mmap(0, fsize, PROT_READ, MAP_SHARED_VALIDATE, fd, 0);
|
|
|
|
if (!fmem) {
|
|
|
|
fprintf(stderr, "Failed to open file %s\n", fname);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
defer { munmap(fmem, fsize); };
|
|
|
|
|
2024-07-10 20:30:49 +00:00
|
|
|
// @Platform: watch file for changes (to adapt the displayed file size - otherwise
|
|
|
|
// we may try to access invalid memory when the file gets shrunk)
|
|
|
|
int inot = inotify_init1(IN_NONBLOCK);
|
|
|
|
if (inot == -1) {
|
|
|
|
fprintf(stderr, "Failed to init inotify: %s (%d)\n", strerror(errno), errno);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (inotify_add_watch(inot, fname, IN_MODIFY) == -1) {
|
|
|
|
fprintf(stderr, "Failed to add inotify watch: %s (%d)\n", strerror(errno), errno);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
defer { close(inot); };
|
|
|
|
|
2024-07-10 17:38:16 +00:00
|
|
|
// Open the TFile
|
2024-07-10 20:30:49 +00:00
|
|
|
#if 0
|
2024-07-10 17:38:16 +00:00
|
|
|
TFile *tfile = TFile::Open(fname, "READ");
|
|
|
|
if (!tfile) {
|
|
|
|
fprintf(stderr, "Failed to open TFile.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
defer { delete tfile; };
|
|
|
|
|
|
|
|
// Get the RNTuple information
|
|
|
|
const RNTuple *anchor = tfile->Get<RNTuple>(ntpl_name);
|
|
|
|
if (!anchor) {
|
|
|
|
fprintf(stderr, "RNTuple '%s' not found in %s.\n", ntpl_name, fname);
|
|
|
|
return 1;
|
|
|
|
}
|
2024-07-10 20:30:49 +00:00
|
|
|
#endif
|
2024-07-10 17:38:16 +00:00
|
|
|
|
|
|
|
// Start main loop
|
2024-07-10 18:11:42 +00:00
|
|
|
App_State app {};
|
2024-07-10 20:30:49 +00:00
|
|
|
app.inspected_file = file;
|
|
|
|
app.inspected_fmem = (u8*)fmem;
|
2024-07-10 18:11:42 +00:00
|
|
|
app.inspected_file_size = fsize;
|
2024-07-10 20:30:49 +00:00
|
|
|
app.inot = inot;
|
2024-07-10 18:11:42 +00:00
|
|
|
|
|
|
|
run_main_loop(window, arena, app);
|
2024-07-10 17:38:16 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|