Files
yaze/src/app/core/project.h
2024-08-07 15:06:50 -04:00

140 lines
3.8 KiB
C++

#ifndef YAZE_APP_CORE_PROJECT_H
#define YAZE_APP_CORE_PROJECT_H
#include <filesystem>
#include <fstream>
#include <string>
#include <string_view>
#include <vector>
#include "absl/status/status.h"
#include "absl/strings/match.h"
#include "app/core/common.h"
namespace yaze {
namespace app {
constexpr std::string kProjectFileExtension = ".yaze";
constexpr absl::string_view kProjectFileFilter =
"Yaze Project Files (*.yaze)\0*.yaze\0";
constexpr std::string kPreviousRomFilenameDelimiter = "PreviousRomFilename";
constexpr std::string kEndOfProjectFile = "EndOfProjectFile";
/**
* @struct Project
* @brief Represents a project in the application.
*
* A project is a collection of files and resources that are used in the
* creation of a Zelda3 hack that can be saved and loaded. This makes it so the
* user can have different rom file names for a single project and keep track of
* backups.
*/
struct Project : public core::ExperimentFlags {
/**
* @brief Creates a new project.
*
* @param project_name The name of the project.
* @param project_path The path to the project.
* @return An absl::Status indicating the success or failure of the project
* creation.
*/
absl::Status Create(const std::string &project_name) {
name = project_name;
project_opened_ = true;
return absl::OkStatus();
}
absl::Status Open(const std::string &project_path) {
filepath = project_path;
name = project_path.substr(project_path.find_last_of("/") + 1);
std::ifstream in(project_path);
if (!in.good()) {
return absl::InternalError("Could not open project file.");
}
std::string line;
std::getline(in, name);
std::getline(in, filepath);
std::getline(in, rom_filename_);
std::getline(in, code_folder_);
std::getline(in, labels_filename_);
while (std::getline(in, line)) {
if (line == kEndOfProjectFile) {
break;
}
if (absl::StrContains(line, kPreviousRomFilenameDelimiter)) {
size_t delimiter_pos = line.find(kPreviousRomFilenameDelimiter);
if (delimiter_pos != std::string::npos) {
std::string filename =
line.substr(delimiter_pos + kPreviousRomFilenameDelimiter.size());
previous_rom_filenames_.push_back(filename);
}
}
}
in.close();
return absl::OkStatus();
}
absl::Status Save() {
RETURN_IF_ERROR(CheckForEmptyFields());
std::ofstream out(filepath + "/" + name + ".yaze");
if (!out.good()) {
return absl::InternalError("Could not open project file.");
}
out << name << std::endl;
out << filepath << std::endl;
out << rom_filename_ << std::endl;
out << code_folder_ << std::endl;
out << labels_filename_ << std::endl;
for (const auto &filename : previous_rom_filenames_) {
out << kPreviousRomFilenameDelimiter << " " << filename << std::endl;
}
out << kEndOfProjectFile << std::endl;
out.close();
return absl::OkStatus();
}
absl::Status CheckForEmptyFields() {
if (name.empty() || filepath.empty() || rom_filename_.empty() ||
code_folder_.empty() || labels_filename_.empty()) {
return absl::InvalidArgumentError(
"Project fields cannot be empty. Please load a rom file, set your "
"code folder, and set your labels file. See HELP for more details.");
}
return absl::OkStatus();
}
absl::Status SerializeExperimentFlags() {
auto flags = mutable_flags();
// TODO: Serialize flags
return absl::OkStatus();
}
bool project_opened_ = false;
std::string name;
std::string filepath;
std::string rom_filename_ = "";
std::string code_folder_ = "";
std::string labels_filename_ = "";
std::vector<std::string> previous_rom_filenames_;
};
} // namespace app
} // namespace yaze
#endif // YAZE_APP_CORE_PROJECT_H