Half done with Scene Component Parsing

This commit is contained in:
2023-03-23 21:43:02 -07:00
parent 3782e731b2
commit 8c50c10be0
19 changed files with 308 additions and 411 deletions

View File

@@ -11,6 +11,7 @@ set(
${D}/File.cpp
${D}/Language.cpp
${D}/CodeGen.cpp
${D}/Directory.cpp
CACHE INTERNAL
${DAWN_CACHE_TARGET}

View File

@@ -0,0 +1,60 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Directory.hpp"
using namespace Dawn;
Directory::Directory(std::string dirname) {
this->filename = File::normalizeSlashes(dirname);
}
bool_t Directory::open() {
if(this->handle) return true;
this->handle = opendir(this->filename.c_str());
return this->handle != nullptr;
}
bool_t Directory::isOpen() {
return this->handle != nullptr;
}
void Directory::close() {
if(this->handle) {
closedir(this->handle);
this->handle = nullptr;
}
}
bool_t Directory::exists() {
return this->open();
}
void Directory::mkdirp() {
File::mkdirp(this->filename);
}
std::map<std::string, enum DirectoryChildType> Directory::readDirectory() {
if(!this->open()) return {};
std::map<std::string, enum DirectoryChildType> children;
struct dirent *dp;
while((dp = readdir(this->handle)) != NULL) {
if(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) {
continue;
}
//Skip anything that isn't a file or directory (symlinks, etc.)
if(dp->d_type != DT_DIR && dp->d_type != DT_REG) continue;
std::string fn = std::string(dp->d_name);
children[fn] = dp->d_type == DT_DIR ? DIRECTORY_CHILD_TYPE_DIRECTORY : DIRECTORY_CHILD_TYPE_FILE;
}
this->close();
return children;
}
Directory::~Directory() {
this->close();
}

View File

@@ -0,0 +1,59 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "util/File.hpp"
namespace Dawn {
enum DirectoryChildType {
DIRECTORY_CHILD_TYPE_FILE,
DIRECTORY_CHILD_TYPE_DIRECTORY
};
class Directory {
public:
std::string filename;
DIR *handle = nullptr;
Directory(std::string dir);
/**
* Opens a connection to the directory.
* @return True if success, otherwise for failure.
*/
bool_t open();
/**
* Returns if the directory is open.
* @return True if open, otherwise false.
*/
bool_t isOpen();
/**
* Closes the directory.
*/
void close();
/**
* Returns if the directory exists.
* @return True if exists, otherwise false.
*/
bool_t exists();
/**
* Creates the directory and all parent directories.
*/
void mkdirp();
/**
* Reads the directory and returns a list of files.
*
* @return List of filenames/directories within this directory.
*/
std::map<std::string, enum DirectoryChildType> readDirectory();
~Directory();
};
}

View File

@@ -1,193 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "File.hpp"
using namespace Dawn;
std::string File::normalizeSlashes(std::string str) {
size_t i = 0;
while(i < str.size()) {
auto c = str[i];
if(c == '\\' || c == '/') str[i] = FILE_PATH_SEP;
++i;
}
return str;
}
void File::mkdirp(std::string path) {
std::string buffer;
char c;
size_t i = 0;
bool inFile;
bool hasMore;
inFile = false;
hasMore = false;
while(c = path[i]) {
if((c == '\\' || c == '/') && i > 0) {
fileMkdir(buffer.c_str(), 0755);
inFile = false;
hasMore = false;
buffer += FILE_PATH_SEP;
i++;
continue;
}
if(c == '.') inFile = true;
hasMore = true;
buffer += c;
i++;
}
if(!inFile && hasMore) {
fileMkdir(buffer.c_str(), 0755);
}
}
//
File::File(std::string filename) {
this->filename = File::normalizeSlashes(filename);
}
bool_t File::open(enum FileMode mode) {
assertNull(this->file);
this->mode = mode;
this->file = fopen(
this->filename.c_str(),
mode == FILE_MODE_READ ? "rb" : "wb"
);
if(this->file == NULL) return false;
if(mode == FILE_MODE_READ) {
fseek(this->file, 0, SEEK_END);
this->length = ftell(this->file);
fseek(this->file, 0, SEEK_SET);
if(this->length <= 0) {
this->close();
return false;
}
} else {
this->length = 0;
}
return true;
}
bool_t File::isOpen() {
return this->file != nullptr;
}
bool_t File::exists() {
if(this->file != nullptr) return true;
FILE *f = fopen(this->filename.c_str(), "rb");
if(f == NULL || f == nullptr) return false;
fclose(f);
return true;
}
void File::close() {
assertNotNull(this->file);
fclose(this->file);
this->file = nullptr;
}
bool_t File::mkdirp() {
File::mkdirp(this->filename);
return true;
}
bool_t File::readString(std::string *out) {
assertNotNull(out);
if(!this->isOpen()) {
if(!this->open(FILE_MODE_READ)) return false;
}
assertTrue(this->mode == FILE_MODE_READ);
out->clear();
size_t i = 0;
char buffer[FILE_BUFFER_SIZE + 1];// +1 for null term
while(i != this->length) {
size_t amt = mathMin<size_t>(FILE_BUFFER_SIZE, (this->length - i));
auto amtRead = fread(buffer, sizeof(char), amt, this->file);
if(amtRead != amt) return false;
i += amtRead;
buffer[amtRead] = '\0';
out->append(buffer);
}
return true;
}
size_t File::readAhead(char *buffer, size_t max, char needle) {
assertNotNull(buffer);
assertTrue(max > 0);
if(!this->isOpen()) {
if(!this->open(FILE_MODE_READ)) return 0;
}
assertTrue(this->mode == FILE_MODE_READ);
// Buffer
size_t pos = ftell(this->file);
size_t amountLeftToRead = mathMin<size_t>(max, this->length - pos);
char temporary[FILE_BUFFER_SIZE];
size_t n = 0;
while(amountLeftToRead > 0) {
size_t toRead = mathMin<size_t>(amountLeftToRead, FILE_BUFFER_SIZE);
amountLeftToRead -= toRead;
// Read bytes
size_t read = fread(temporary, sizeof(char), toRead, this->file);
// Read error?
if(toRead != read) return 0;
// Did we read the needle?
size_t i = 0;
while(i < read) {
char c = temporary[i++];
if(c == needle) {
return n;
} else {
buffer[n++] = c;
}
}
}
// Needle was not found.
return -1;
}
bool_t File::writeString(std::string in) {
if(!this->isOpen()) {
if(!this->open(FILE_MODE_WRITE)) return false;
}
assertTrue(this->mode == FILE_MODE_WRITE);
return this->writeRaw((char *)in.c_str(), in.size()) && this->length == in.size();
}
bool_t File::writeRaw(char *data, size_t len) {
if(!this->isOpen()) {
if(!this->open(FILE_MODE_WRITE)) return false;
}
assertTrue(this->mode == FILE_MODE_WRITE);
this->length = fwrite(data, sizeof(char_t), len, this->file);
return true;
}
void File::setPosition(size_t n) {
fseek(this->file, 0, SEEK_SET);
fseek(this->file, n, SEEK_CUR);
}
File::~File() {
if(this->file != nullptr) this->close();
}

View File

@@ -1,140 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "assert/assert.hpp"
#include "util/mathutils.hpp"
#if defined(_MSC_VER)
#include <direct.h>
#include <windows.h>
#define getcwd _getcwd
#define FILE_PATH_SEP '\\'
#define fileMkdir(path, perms) _mkdir(path)
#elif defined(__GNUC__)
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#define FILE_PATH_SEP '/'
#define fileMkdir(path, perms) mkdir(path, perms)
#endif
#include <errno.h>
#define FILE_BUFFER_SIZE 512
namespace Dawn {
enum FileMode {
FILE_MODE_READ,
FILE_MODE_WRITE
};
class File {
private:
enum FileMode mode;
public:
static std::string normalizeSlashes(std::string str);
static void mkdirp(std::string path);
std::string filename;
size_t length;
FILE *file = nullptr;
/**
* Constructs a new File interface class.
*
* @param filename Filename that you want to interface with.
*/
File(std::string filename);
/**
* Opens a connection to the file.
*
* @param mode File mode to use for this interface.
* @return True if success, otherwise for failure.
*/
bool_t open(enum FileMode mode);
/**
* Returns whether or not the file connection is currently opened.
*
* @return True if the connection is open, otherwise if it's not.
*/
bool_t isOpen();
/**
* Returns whether or not the file exists. Will open the connection if it
* does exist.
*
* @return True if exists, otherwsie if it doesn't.
*/
bool_t exists();
/**
* Closes the currently open interface to the file. Done automatically
* when this object is disposed.
*/
void close();
/**
* Makes all directories above this file's filename.
*
* @return True if successful, otherwise false.
*/
bool_t mkdirp();
/**
* Reads the entire contents of a file to the given output string buffer.
* This is a bit dangerous since the length of the file isn't checked
* against the memory to be consumed.
*
* @param out Pointer to a string where the output data will be stored.
* @return True if the read was successful, otherwise false.
*/
bool_t readString(std::string *out);
/**
* Reads ahead from the current position to a specific needle (character).
*
* @param buffer Buffer to output read chars to.
* @param max Max length of the buffer / amount of chars to read ahead.
* @param needle The character (needle) to look for.
* @return Amount of chars read, or <= 0 on error.
*/
size_t readAhead(
char *buffer,
size_t max,
char needle
);
/**
* Writes the entire contents of a string to a file.
*
* @param in String to write to this file.
* @return True if written successfully, otherwise false.
*/
bool_t writeString(std::string in);
/**
* Write raw bytes to the file.
*
* @param data Data to write.
* @return True if written successfully, otherwise false.
*/
bool_t writeRaw(char *data, size_t );
/**
* Set the position of the cursor of the file reader.
*
* @param pos Position to set.
*/
void setPosition(size_t pos);
/**
* Destruct the File manager.
*/
~File();
};
}