Skip to content

Commit

Permalink
Merge pull request #3 from Jaskowicz1/file_manager_cleanup
Browse files Browse the repository at this point in the history
refactor: cleaning up file management
  • Loading branch information
Jaskowicz1 authored May 2, 2024
2 parents 0218585 + 5c20cef commit 544f132
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 143 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ _build
build
cmake-build-debug
cmake-build-release
cmake-build-debug-visual-studio
cmake-build-release-visual-studio
out

# Just for testing video, please remove later.
Expand Down
63 changes: 63 additions & 0 deletions include/engine/utilities/file_management.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,73 @@

#include "video_manager.h"

#ifdef _WIN32
#include <windows.h>
#endif

namespace utilities {

constexpr std::string_view hexwave_project_ext = ".hexw";

#ifndef _WIN32
/**
* @brief Linux File Reader.
*
* @note linux_file will automatically close and free up memory when it is no longer required.
*/
class linux_file {
FILE* f{nullptr};

public:
linux_file() = default;
linux_file(FILE *file) : f{file} {}
linux_file(const linux_file&) = delete;
linux_file(linux_file&& other) noexcept : f{std::exchange(other.f, nullptr)} {}

linux_file &operator=(const linux_file&) = delete;
linux_file &operator=(linux_file&& other) noexcept {
f = std::exchange(other.f, nullptr);
return *this;
}

operator FILE *() {return f;}

~linux_file() {
if(f != nullptr) {
pclose(f);
f = nullptr;
}
};
};
#endif

/**
* @brief Save the current project
*
* @param manager The video manager with the videos.
*
* @return bool true if project was able to save
*/
bool save_project(video_manager& manager);

/**
* @brief Load a project.
*
* @brief The video manager to load the videos to.
*
* @return bool true if project was loaded successfully.
*/
bool load_project(video_manager& manager);

/**
* @brief Opens a file prompt to retrieve a file path.
*
* @param is_save Is this prompt a save prompt?
* @param title The title of the prompt.
* @param linux_filters Filters for Linux (usually formatted as `name | filter`)
* @param windows_filters Filters for Windows (usually formatted as `name\0filter\0name\0filter\0`)
*
* @return std::string File path (includes file name, for example `/opt/hexwave/testing.hexw`
*/
std::string get_file_from_prompt(const bool is_save, const std::string& title, const std::string& linux_filters, const char* windows_filters);
}
1 change: 1 addition & 0 deletions include/engine/utilities/input_manager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#pragma once
146 changes: 62 additions & 84 deletions src/engine/utilities/file_management.cpp
Original file line number Diff line number Diff line change
@@ -1,57 +1,21 @@
#include <fstream>
#include <sstream>
#include <vector>
#include <set>
#include "utilities/file_management.h"

#ifdef _WIN32
#include <windows.h>
#endif

bool utilities::save_project(video_manager& manager) {

char filename[1024];

// Linux only, will ALWAYS be false on Windows.
bool file_fail{ false };

#ifndef _WIN32 // !_WIN32

FILE* f = popen(R"(zenity --file-selection --save --title="Save project" --file-filter=*.hexw)", "r");

// Might be possible to just not use fgets, should look into this.
// Will be true if we failed to gather the data from the file.
file_fail = (fgets(filename, 1024, f) == nullptr);

pclose(f);
f = nullptr;

#else // _WIN32

OPENFILENAME ofn{};

ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = filename;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(filename);
ofn.lpstrFilter = "Hexwave Project\0*.hexw\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

GetSaveFileName(&ofn);
std::string filename{get_file_from_prompt(true, "Save Project", "Hexwave Project | *.hexw", "Hexwave Project\0*.hexw\0")};

#endif

if (file_fail || std::strlen(filename) == 0) {
if(filename.empty()) {
return false;
}

auto len = std::strlen(filename);
if (len > 0 && filename[len - 1] == '\n') {
filename[len - 1] = 0;
// Does filename NOT end in ".hexw"?
if(filename.compare(filename.size() - hexwave_project_ext.size(), hexwave_project_ext.size(), hexwave_project_ext) != 0) {
// because file doesn't end in ".hexw", we need to add ".hexw" to it to ensure all files end in that.
filename.append(hexwave_project_ext);
}

json j;
Expand All @@ -72,51 +36,12 @@ bool utilities::save_project(video_manager& manager) {

bool utilities::load_project(video_manager& manager) {

char filename[1024];

// Linux only, will ALWAYS be false on Windows.
bool file_fail{ false };

#ifndef _WIN32 // !_WIN32

FILE* f = popen(R"(zenity --file-selection --title="Open project" --file-filter=*.hexw)", "r");

// Might be possible to just not use fgets, should look into this.
// Will be true if fgets is nullptr (invalid).
file_fail = (fgets(filename, 1024, f) == nullptr);

pclose(f);
f = nullptr;

#else // _WIN32

OPENFILENAME ofn{};

ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = filename;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(filename);
ofn.lpstrFilter = "Hexwave Project\0*.hexw\0All\0*.*\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

GetOpenFileName(&ofn);

#endif
std::string filename{get_file_from_prompt(false, "Open Project", "Hexwave Project | *.hexw", "Hexwave Project\0*.hexw\0")};

if (file_fail || std::strlen(filename) == 0) {
if(filename.empty()) {
return false;
}

auto len = std::strlen(filename);
if (len > 0 && filename[len - 1] == '\n') {
filename[len - 1] = 0;
}

std::ifstream project_file(filename);

if (!project_file.good()) {
Expand Down Expand Up @@ -150,3 +75,56 @@ bool utilities::load_project(video_manager& manager) {

return true;
}

std::string utilities::get_file_from_prompt(const bool is_save, const std::string& title,
const std::string& linux_filters, const char* windows_filters) {
char filename[1024];

#ifndef _WIN32 // !_WIN32

std::string clause("zenity --file-selection" + std::string(is_save ? " --save" : "") + " --title=" + title + " --file-filter='" + linux_filters + "' --file-filter='All | *.*'");

linux_file f{popen(clause.c_str(), "r")};

// Might be possible to just not use fgets, should look into this.
// Will be true if fgets is nullptr (invalid).
if(fgets(filename, 1024, f) == nullptr) {
return "";
}

#else // _WIN32

OPENFILENAME ofn{};

ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = nullptr;
ofn.lpstrFile = filename;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(filename);
ofn.lpstrFilter = windows_filters;
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = nullptr;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = nullptr;
ofn.lpstrTitle = std::string(title).c_str();
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

if(is_save) {
GetSaveFileName(&ofn);
} else {
GetOpenFileName(&ofn);
}

#endif

if(std::strlen(filename) == 0) {
return "";
}

auto len = std::strlen(filename);
if (len > 0 && filename[len - 1] == '\n') {
filename[len - 1] = 0;
}

return filename;
}
1 change: 1 addition & 0 deletions src/engine/utilities/input_manager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "utilities/input_manager.h"
70 changes: 13 additions & 57 deletions src/engine/video_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <iostream>
#include <fstream>
#include "video_manager.h"
#include "utilities/file_management.h"
#include "imgui.h"
#include "imgui_internal.h"
#include "ImGuiNotify.hpp"
Expand Down Expand Up @@ -52,19 +53,15 @@ void video_manager::add_option(video& vid, const std::string_view id, const std:
vid.options.emplace(id, opt);
}

static void testing() {
ImGui::OpenPopup("add_video_popup");
}


void video_manager::render_window(video_reader& reader) {
if(ImGui::Begin("Videos")) {
if (ImGui::Button("Add Video")) {
testing();
ImGui::OpenPopup("add_video_popup");
}
ImGui::SameLine();
if (ImGui::Button("Remove ALL Videos")) {
//remove_all_videos();
remove_all_videos();
}

static std::string vid_id_interacting_with;
Expand Down Expand Up @@ -228,58 +225,16 @@ void video_manager::render_window(video_reader& reader) {
ImGui::SameLine();

if (ImGui::Button(std::string("Select Video").c_str())) {
std::string video_path{utilities::get_file_from_prompt(false, "Open Video File", "Video Files | *.mp4 *.mov *.wmv *.avi *.mkv *.webm", "MP4\0*.mp4\0MOV\0*.mov\0WMV\0*.wmv\0AVI\0*.avi\0MKV\0*.mkv\0WEBM\0*.webm\0All\0*.*\0")};

// This entire section of code below to do with selecting a video should REALLY be a static class under file_management.
// This is kinda poor tbh.

char temp_path[1024];

// Linux only, will ALWAYS be false on Windows.
bool file_fail{ false };

#ifndef _WIN32 // !_WIN32

FILE* f = popen(R"(zenity --file-selection --title="Open project" --file-filter=*.*)", "r");

// Might be possible to just not use fgets, should look into this.
// Will be true if fgets is nullptr (invalid).
file_fail = (fgets(temp_path, 1024, f) == nullptr);

pclose(f);
f = nullptr;

#else // _WIN32
std::ifstream video_file(video_path);

OPENFILENAME ofn{};

ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = temp_path;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(temp_path);
ofn.lpstrFilter = "MP4\0*.mp4\0MOV\0*.mov\0WMV\0*.wmv\0AVI\0*.avi\0MKV\0*.mkv\0WEBM\0*.webm\0All\0*.*\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

GetOpenFileName(&ofn);

#endif

if (!file_fail && std::strlen(temp_path) != 0) {
auto len = std::strlen(temp_path);
if (len > 0 && temp_path[len - 1] == '\n') {
temp_path[len - 1] = 0;
}

std::ifstream video_file(temp_path);

if (video_file.good()) {
// Copy temp path to path if the path was valid.
memcpy(path, temp_path, sizeof(temp_path));
}
if (video_file.good()) {
const char* temp_path = video_path.c_str();
// Copy temp path to path if the path was valid.
std::memcpy(path, temp_path, std::strlen(temp_path));
} else {
ImGui::InsertNotification({ ImGuiToastType::Error, 3000, "Failed to open video file, please make sure it's a valid video!" });
}
}

Expand All @@ -297,6 +252,8 @@ void video_manager::render_window(video_reader& reader) {
} else {
ImGui::InsertNotification({ImGuiToastType::Error, 5000, "Invalid path! Check the path of the video and make sure it's the right file type!"});
}
} else {
ImGui::InsertNotification({ ImGuiToastType::Error, 3000, "Failed to add video! Ensure that ID, name, linked_id, and path, are not empty!" });
}
}

Expand Down Expand Up @@ -604,7 +561,6 @@ bool video_manager::read_video_frame(GLFWwindow* window, video_reader* state, ui
}

uint8_t* dest[4] = { frame_buffer, NULL, NULL, NULL };
std::cout << "WIDTH BE LIKE: " << state->width << "\n";
int dest_linesize[4] = { state->width * 4, 0, 0, 0 };
sws_scale(state->sws_scaler_ctx, state->av_frame->data, state->av_frame->linesize, 0, state->height, dest, dest_linesize);

Expand Down
Loading

0 comments on commit 544f132

Please sign in to comment.