#include #include #include #include #include #include // @Platform #include #include #include #include // for NAME_MAX #ifdef DEBUG #include #endif #include #include #include #include #define GLFW_INCLUDE_NONE #include #include "types.h" #include "defer.hpp" #include "mem.h" #include "app_state.h" namespace chr = std::chrono; #include "mem.cpp" #include "render.cpp" #include "mainloop.cpp" using namespace ROOT::Experimental; internal b8 init_imgui(GLFWwindow* window) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void) io; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; ImGui::StyleColorsDark(); ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init("#version 400"); return true; } internal void glfw_error_callback(i32 error, const char *description) { fprintf(stderr, "GLFW error %d: %s\n", error, description); } internal GLFWwindow* init_glfw(i32 desired_win_width, i32 desired_win_height) { glfwSetErrorCallback(glfw_error_callback); glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 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); #ifndef NDEBUG 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 \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; } // Open and map te file FILE *file = fopen(fname, "rb"); defer { fclose(file); }; int fd = fileno(file); size_t fsize = file_size(file); // @Platform 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); }; // @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); }; // Open the TFile #if 0 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(ntpl_name); if (!anchor) { fprintf(stderr, "RNTuple '%s' not found in %s.\n", ntpl_name, fname); return 1; } #endif // Start main loop App_State app {}; app.inspected_file = file; app.inspected_fmem = (u8*)fmem; app.inspected_file_size = fsize; app.inot = inot; run_main_loop(window, arena, app); return 0; }