Skip to content

Commit

Permalink
Merge branch 'sdl2' into sdl2-graphics3
Browse files Browse the repository at this point in the history
  • Loading branch information
kazzmir committed Feb 1, 2024
2 parents ac54b72 + 0f1572d commit aaf8d41
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 102 deletions.
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
build
./paintown
build*
mingw-bin
paintown
.scon*
.tmp
peg_*.py
Expand All @@ -8,4 +9,5 @@ peg_*.py
*.log
*.swp
# mac
.DS_Store
.DS_Store
.vscode
217 changes: 128 additions & 89 deletions src/r-tech1/file-system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
#include "libs/7z/7zAlloc.h"
#include "libs/7z/7zCrc.h"

//#ifdef WINDOWS
#ifdef WINDOWS
#include <windows.h>
#endif
// https://github.com/gulrak/filesystem/
#include "libs/filesystem/fs-wrapper.h"
#include "libs/filesystem/glob.h"
Expand Down Expand Up @@ -462,20 +464,27 @@ System::System(){
System::~System(){
}

static int FileCounter = 0;
vector<Filesystem::AbsolutePath> System::getFiles(const Filesystem::AbsolutePath & dataPath, const Filesystem::RelativePath & find, bool caseInsensitive){
DebugLog3 << "Is find: " << find.path() << " a file? (" << find.isFile() << ")" << std::endl;
if (find.isFile()){
DebugLog2 << "File (" << find.getFilename().path() << ") passed returning directory: " << find.path() << std::endl;
return getFiles(dataPath, find.path(), caseInsensitive);
DebugLog3 << "File (" << find.getFilename().path() << ") passed returning directory: " << find.path() << std::endl;
std::vector<Filesystem::AbsolutePath> files = getFiles(dataPath, find.path(), caseInsensitive);
DebugLog3 << "Got total files: " << files.size() << " iteration: " << FileCounter << std::endl;
FileCounter++;
return files;
}

/* split the path into its consituent parts
* a/b/c -> a/b and c
* search for a/b, then search for c in the results
*/
* a/b/c -> a/b and c
* search for a/b, then search for c in the results
*/
Filesystem::RelativePath directory = find.getDirectory();
Filesystem::RelativePath file = find.getFilename();

DebugLog3 << "Checking directory: " << directory.path() << " for file: " << file.path() << std::endl;
vector<Filesystem::AbsolutePath> more = getFiles(dataPath, directory, caseInsensitive);
DebugLog3 << "Total files: " << more.size() << " found." << std::endl;
vector<Filesystem::AbsolutePath> out;
for (vector<Filesystem::AbsolutePath>::iterator it = more.begin(); it != more.end(); it++){
Filesystem::AbsolutePath path = *it;
Expand Down Expand Up @@ -1729,104 +1738,134 @@ vector<Filesystem::AbsolutePath> Filesystem::getFiles(const AbsolutePath & dataP
vector<AbsolutePath> more = virtualDirectory.findFiles(dataPath, find, caseInsensitive);
files.insert(files.end(), more.begin(), more.end());

// FIXME Can't seem to get glob to work in windows, it returns 0 files
try {
#ifndef WINDOWS
// Convert to type std::filesystem::path
//fs::path path = dataPath.path();
//path /= find;

DebugLog2 << "Looking for file: " << find << " in dataPath: " << dataPath.path() << " (" << find << ")" << std::endl;
// for (fs::path & globFile : glob::glob(path.generic_string())){
for (fs::path & globFile : glob::glob1(dataPath.path(), find, false)){
DebugLog2 << "Got datapath: " << dataPath.path().c_str() << " globFile: " << globFile.c_str() << std::endl;
files.push_back(AbsolutePath(dataPath.join(Filesystem::RelativePath(globFile.string()))));
}
#else
DebugLog2 << "Looking for file: " << find << " in dataPath: " << dataPath.path() << " (" << dataPath.path() + "/" + find << ")" << std::endl;
class Globber
{
public:
Globber(const std::string & pattern, const std::string & path):
pattern(createRegex(pattern)),
origin(path){
doMatches(path);
// Convert to type std::filesystem::path
//fs::path path = dataPath.path();
//path /= find;

DebugLog2 << "Looking for file: " << find << " in dataPath: " << dataPath.path() << " (" << find << ")" << std::endl;
// for (fs::path & globFile : glob::glob(path.generic_string())){
for (fs::path & globFile : glob::glob1(dataPath.path(), find, false)){
DebugLog2 << "Got datapath: " << dataPath.path().c_str() << " globFile: " << globFile.c_str() << std::endl;
files.push_back(AbsolutePath(dataPath.join(Filesystem::RelativePath(globFile.string()))));
}
~Globber(){
}
std::vector<std::string> matches;
private:
void doMatches(const std::string & path){
try {
for (const fs::directory_entry & entry : fs::directory_iterator(path)){
fs::path relative_path = fs::relative(entry, origin);
DebugLog2 << "Entry: " << entry.path() << " relative path: " << relative_path << std::endl;
if (fs::is_directory(entry)){
DebugLog2 << "Searching directory: " << entry.path() << std::endl;
doMatches(entry.path().string());
} else if (fs::is_regular_file(entry) && std::regex_match(relative_path.string(), pattern)) {
matches.emplace_back(entry.path().string());
DebugLog2 << "Found pattern match on entry: " << relative_path << std::endl;
} else {
DebugLog2 << "No match found for string: " << relative_path << std::endl;
#else
DebugLog2 << "Looking for file: " << find << " in dataPath: " << dataPath.path() << " (" << find << ")" << std::endl;
class Globber
{
private:
typedef struct {
std::string filename;
std::string path;
bool isDirectory;
} File;
public:
Globber(const std::string & pattern, const std::string & path):
pattern(createRegex(pattern)),
origin(path){
doMatches(path);
}
~Globber(){
}
std::vector<std::string> matches;
private:
void doMatches(const std::string & path){
try {

DebugLog3 << "String: " << origin << " path: " << path << std::endl;
for (const File & entry: this->getFiles(path)){
DebugLog3 << "Entry: " << entry.filename << std::endl;
bool matched = std::regex_match(entry.filename, pattern);

// Do not recurse
/*
if (entry.isDirectory && matched){
//DebugLog2 << "Searching directory: " << entry.path() << std::endl;
DebugLog2 << "Searching directory: " << entry.filename << std::endl;
//doMatches(entry.path().string());
doMatches(entry.path);
//} else if (fs::is_regular_file(entry) && std::regex_match(relative_path.string(), pattern)) {
} else if (matched){
*/
if (matched){
DebugLog3 << "Found pattern match on entry: " << entry.filename << std::endl;
matches.emplace_back(entry.filename);
} else {
DebugLog3 << "No match found for string: " << entry.path << std::endl;
}
}
} catch (...){
DebugLog2 << "Error parsing directories." << std::endl;
}
} catch (...){
DebugLog2 << "Error parsing directories." << std::endl;
}
}
std::string createRegex(const std::string & glob){
std::string regexStr = "^";
for (char ch : glob) {
switch (ch) {
case '*':
regexStr += ".*";
break;
case '?':
regexStr += ".";
break;
case '.':
regexStr += "\\.";
break;
default:
regexStr += ch;
// Function to iterate over a directory using Windows API
const std::vector<File> getFiles(const std::string & path) {
//DebugLog << "Starting get files from path: " << path << std::endl;
std::vector<File> files;

WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile((path + "\\*").c_str(), &findFileData);

if (hFind != INVALID_HANDLE_VALUE) {
do {
File file = {
std::string(findFileData.cFileName),
path + "/" + std::string(findFileData.cFileName),
(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0
};
if (file.isDirectory &&
(file.filename == "." || file.filename == "..")) {
// Skip directories . and ..
continue;
}
//DebugLog << "File: " << file.filename << std::endl;
files.emplace_back(file);
} while (FindNextFile(hFind, &findFileData) != 0);

FindClose(hFind);
} else {
DebugLog2 << "Error opening directory: " << GetLastError() << std::endl;
}
return files;
}
regexStr += "$";
DebugLog2 << "Regex string: " << regexStr << std::endl;
return regexStr;
}

std::regex pattern;
std::string origin;
};
std::string createRegex(const std::string & glob){
std::string regexStr = "^";
for (char ch : glob) {
switch (ch) {
case '*':
regexStr += ".*";
break;
case '?':
regexStr += ".";
break;
case '.':
regexStr += "\\.";
break;
default:
regexStr += ch;
}
}
regexStr += "$";
DebugLog3 << "Regex string: " << regexStr << std::endl;
return regexStr;
}

Globber glob(find, dataPath.path());
for (std::string globFile : glob.matches){
DebugLog2 << "Got datapath: " << dataPath.path().c_str() << " globFile: " << globFile.c_str() << std::endl;
files.push_back(AbsolutePath(dataPath.join(Filesystem::RelativePath(globFile))));
}
std::regex pattern;
std::string origin;
};

Globber glob(find, dataPath.path());
for (std::string globFile : glob.matches){
DebugLog2 << "Got datapath: " << dataPath.path() << " globFile: " << globFile << std::endl;
files.emplace_back(AbsolutePath(dataPath.join(Filesystem::RelativePath(globFile))));
}
DebugLog2 << "Got total matched files: " << files.size() << std::endl;
#endif
} catch(fs::filesystem_error &ex){
DebugLog2 << "Directory or dataPath: " << dataPath.path() << " does not exist. Reason: " << ex.what() << std::endl;
}
/*
for (map<AbsolutePath, Util::ReferenceCount<Storage::ZipContainer> >::iterator it = overlays.begin(); it != overlays.end(); it++){
AbsolutePath path = it->first;
if (it->second == NULL){
continue;
}
// Global::debug(0) << "Check " << path.path() << " (" << path.getDirectory().path() << ") vs directory " << dataPath.path() << " wildcard " << find << " to " << path.getFilename().path() << std::endl;
if (path.getDirectory() == dataPath &&
file_matches(path.getLastComponent().c_str(), find.c_str())){
// Global::debug(0) << "Found overlay " << path.path() << " in " << dataPath.path() << " for wildcard " << find << std::endl;
files.push_back(path);
}
}
*/

// Global::debug(0) << "Warning: Filesystem::getFiles() is not implemented yet for SDL" << endl;
return files;
#endif
}
Expand Down
70 changes: 63 additions & 7 deletions src/r-tech1/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <stdint.h>
#include <stdio.h>
#include <fstream>
#include "r-tech1/debug.h"

#ifdef USE_SDL
#include <SDL/SDL.h>
Expand Down Expand Up @@ -121,34 +122,89 @@ void System::startMemoryUsage(){

#else

// FIXME For the time being on cross-build, needs to be corrected
uint64_t System::getModificationTime(const std::string & path){
#ifndef WINDOWS
fs::file_time_type lastWriteTime = fs::last_write_time(filePath);
std::chrono::time_point<fs::file_clock> timePoint = time_point_cast<milliseconds>(lastWriteTime);
return static_cast<uint64_t>(timePoint.time_since_epoch().count());
#else
HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);

if (hFile != INVALID_HANDLE_VALUE) {
FILETIME modificationTime;
if (GetFileTime(hFile, nullptr, nullptr, &modificationTime)) {
CloseHandle(hFile);

uint64_t System::getModificationTime(const std::string & path){

// FIXME figure out how to convert to unit64_t and remove auto
//auto p = fs::path(path);
//auto time = fs::last_write_time(p);
ULARGE_INTEGER uli;
uli.LowPart = modificationTime.dwLowDateTime;
uli.HighPart = modificationTime.dwHighDateTime;

return 0;
return uli.QuadPart;
} else {
DebugLog2 << "Error getting file modification time: " << GetLastError() << std::endl;
CloseHandle(hFile);
return 0; // Return 0 or handle error as appropriate for your use case
}
} else {
DebugLog2 << "Error opening file: " << GetLastError() << std::endl;
return 0; // Return 0 or handle error as appropriate for your use case
}
#endif
}

void System::makeDirectory(const std::string & path){
#ifndef WINDOWS
fs::path p = fs::path(path);
fs::create_directory(p);
#else
if (CreateDirectory(path.c_str(), nullptr) || ERROR_ALREADY_EXISTS == GetLastError()) {
return;
} else {
DebugLog2 << "Error creating directory: " << GetLastError() << std::endl;
}
#endif
}

bool System::isDirectory(const std::string & path){
#ifndef WINDOWS
return fs::is_directory(fs::path(path));
#else
DWORD attributes = GetFileAttributes(path.c_str());
if (attributes != INVALID_FILE_ATTRIBUTES) {
return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
}
return false;
#endif
}

bool System::readable(const std::string & path){
#ifndef WINDOWS
fs::path p = fs::path(path);
fs::perms permissions = fs::status(p).permissions();

return ((permissions & fs::perms::owner_read) != fs::perms::none &&
(permissions & fs::perms::group_read) != fs::perms::none &&
(permissions & fs::perms::others_read) != fs::perms::none);
#else
DWORD attributes = GetFileAttributes(path.c_str());
if (attributes != INVALID_FILE_ATTRIBUTES) {
// Check if the file is readable
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile != INVALID_HANDLE_VALUE) {
CloseHandle(hFile);
return true;
} else {
DebugLog2 << "Error opening file: " << GetLastError() << std::endl;
return false;
}
}

// For directories, assume readable
return true;
}
return false;
#endif
}

uint64_t System::currentMilliseconds(){
Expand Down
5 changes: 5 additions & 0 deletions src/test/thread/futures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ void test2(){
}
}

#ifndef WINDOWS
int main(){
#else
#include <SDL2/SDL.h>
int main(int argv, char *args[]){
#endif
test1();
test2();
}
Loading

0 comments on commit aaf8d41

Please sign in to comment.