Skip to content

Commit

Permalink
Correct paths for data files and interface to find them
Browse files Browse the repository at this point in the history
Update version to v0.21.28

Update version to v0.21.29

Update version to v0.21.30

Update version to v0.21.31

Update version to v0.21.32

Update version to v0.21.33

Update version to v0.21.34

Update version to v0.21.35

Update version to v0.21.36

Update version to v0.21.37

Update version to v0.21.38

Update version to v0.21.39

Update version to v0.21.40

Update version to v0.21.41
  • Loading branch information
Atraxus committed Oct 4, 2024
1 parent b35a5d2 commit fea08fb
Show file tree
Hide file tree
Showing 31 changed files with 215 additions and 98 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.25.2 FATAL_ERROR)

# ---- Project ----
project(RAYX VERSION 0.21.27)
project(RAYX VERSION 0.21.41)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_STANDARD 20)
Expand Down Expand Up @@ -38,8 +38,8 @@ elseif(UNIX AND NOT APPLE)
set(INSTALL_DATA_DIR "share/${PROJECT_NAME}")
set(INSTALL_FONTS_DIR "share/fonts/${PROJECT_NAME}")
elseif(WIN32)
set(INSTALL_DATA_DIR "Data")
set(INSTALL_FONTS_DIR "Fonts")
set(INSTALL_DATA_DIR ".")
set(INSTALL_FONTS_DIR ".")
endif()
# ------------------

Expand Down
32 changes: 22 additions & 10 deletions Intern/rayx-core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ endif()

target_compile_definitions(${PROJECT_NAME}
PRIVATE RAYX_BUILD_DLL
RAYX_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"
RAYX_PACKAGE_INSTALL_DIR="${CPACK_PACKAGE_INSTALL_DIRECTORY}"
RAYX_DATA_DIR="${INSTALL_DATA_DIR}"
RAYX_FONTS_DIR="${INSTALL_FONTS_DIR}"
PUBLIC ${COMPILE_PLATFORM}
RAYX_PROJECT_DIR="${CMAKE_SOURCE_DIR}"
$<$<CONFIG:Debug>:RAYX_DEBUG_MODE>
Expand Down Expand Up @@ -208,17 +212,25 @@ add_custom_command(
# -----------------

# ---- CPack ----
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/Data
DESTINATION ${INSTALL_DATA_DIR}
FILES_MATCHING PATTERN "*")
if(APPLE OR UNIX)
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
elseif(WIN32)
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION .
LIBRARY DESTINATION .
ARCHIVE DESTINATION .
)
endif()
install(DIRECTORY ${CMAKE_SOURCE_DIR}/Data/nff
DESTINATION ${INSTALL_DATA_DIR}/Data)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/Data/PALIK
DESTINATION ${INSTALL_DATA_DIR}/Data)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/Scripts
DESTINATION ${INSTALL_DATA_DIR}
FILES_MATCHING PATTERN "*")
DESTINATION ${INSTALL_DATA_DIR})
include(InstallRequiredSystemLibraries)
include(CPack)
# -----------------
41 changes: 0 additions & 41 deletions Intern/rayx-core/src/CanonicalizePath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,9 @@
#include <stdexcept>

#include "Debug/Debug.h"
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
#include <windows.h>
#elif defined(__linux__) || defined(__unix__) || defined(_POSIX_VERSION)
#include <limits.h>
#include <unistd.h>
#elif defined(__APPLE__)
#include <mach-o/dyld.h>
#endif

namespace RAYX {

std::filesystem::path getExecutablePath() {
char buffer[1024];
uint32_t length = static_cast<uint32_t>(sizeof(buffer));
memset(buffer, 0, length);

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
// Windows implementation
DWORD ret = GetModuleFileNameA(NULL, buffer, length);
if (ret == 0 || ret == length) {
// Handle error
throw std::runtime_error("Failed to get executable path.");
}
#elif defined(__linux__) || defined(__unix__) || defined(_POSIX_VERSION)
// Linux and Unix implementation
ssize_t ret = readlink("/proc/self/exe", buffer, length - 1);
if (ret == -1) {
// Handle error
throw std::runtime_error("Failed to get executable path.");
}
buffer[ret] = '\0'; // Ensure null-terminated string
#elif defined(__APPLE__)
// macOS implementation
if (_NSGetExecutablePath(buffer, &length) != 0) {
// Handle error
throw std::runtime_error("Buffer too small; should not happen.");
}
#else
#error "Platform not supported."
#endif

return std::filesystem::path(buffer).parent_path();
}

/// this function assumes that `base` is already an absolute path
std::filesystem::path canonicalize(const std::filesystem::path& relPath, const std::filesystem::path& base) {
if (!base.is_absolute()) {
Expand Down
3 changes: 0 additions & 3 deletions Intern/rayx-core/src/CanonicalizePath.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@

namespace RAYX {

/// Returns the path to the directory containing the executable.
std::filesystem::path RAYX_API getExecutablePath();

/// `relPath` is a path relative to the root of the RAY-X git repository (i.e.
/// where .git lies). canonicalizeRepositoryPath(relPath) yields an absolute
/// path representing the same path. Examples:
Expand Down
97 changes: 97 additions & 0 deletions Intern/rayx-core/src/Data/Locate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include "Locate.h"
#include <iostream>
#include <filesystem>
#include <vector>

#if defined(_WIN32)
#include <windows.h>
#elif defined(__APPLE__)
#include <cassert>
#else
#include <unistd.h>
#include <limits.h>
#endif

namespace RAYX {

// Check if a file exists
bool ResourceHandler::fileExists(const std::string& path) { return std::filesystem::exists(path); }
bool ResourceHandler::fileExists(const std::filesystem::path& path) { return std::filesystem::exists(path); }

std::filesystem::path ResourceHandler::getExecutablePath() {
#if defined(_WIN32)
// Start with a reasonable buffer size
std::vector<char> buffer(MAX_PATH);
while (true) {
// Try to get the module filename
DWORD size = GetModuleFileNameA(NULL, buffer.data(), buffer.size());
if (size == 0) {
return std::filesystem::path();
}
// If the buffer was large enough, we're done
if (size < buffer.size()) {
break;
}
// Otherwise, increase buffer size and try again
buffer.resize(buffer.size() * 2);
}
#elif defined(__linux__)
// Start with a reasonable buffer size, then grow dynamically if needed
std::vector<char> buffer(PATH_MAX);
ssize_t count;
while (true) {
count = readlink("/proc/self/exe", buffer.data(), buffer.size());
if (count == -1) {
return std::filesystem::path();
}
if (count < static_cast<ssize_t>(buffer.size())) {
buffer[count] = '\0'; // Null-terminate
break;
}
// If the buffer was too small, increase size and retry
buffer.resize(buffer.size() * 2);
}

#else
throw std::runtime_error("getExecutablePath is not implemented for this platform");
#endif
return std::filesystem::path(buffer.data());
}

// General method to get the full path based on the base directory (e.g., data or font directory)
std::filesystem::path ResourceHandler::getFullPath(const std::string& baseDir, const std::string& relativePath) {
#if defined(__linux__)
// First, check in /usr (package install)
std::string path = std::string("/usr/") + baseDir + "/" + relativePath;
if (fileExists(path)) return path;

// Next, check next to the executable (built from source)
std::string execDir = getExecutablePath().string();
execDir = execDir.substr(0, execDir.find_last_of("/\\"));
path = execDir + "/" + relativePath;
if (fileExists(path)) return path;

// Lastly, check in /usr/local (make install)
path = std::string("/usr/local/") + baseDir + "/" + relativePath;
if (fileExists(path)) return path;
#elif defined(_WIN32)
// On Windows, only look next to the executable
std::string execDir = getExecutablePath().string();
execDir = execDir.substr(0, execDir.find_last_of("/\\"));
std::filesystem::path path = std::filesystem::path(execDir + "\\" + relativePath);
if (fileExists(path)) return path;
#elif defined(__APPLE__)
static_assert(false, "macOS support is not implemented yet");

#endif
// Not found -> empty path
return std::filesystem::path();
}

// Retrieve the full path of a resource based on the platform
std::filesystem::path ResourceHandler::getResourcePath(const std::string& relativePath) { return getFullPath(RAYX_DATA_DIR, relativePath); }

// Retrieve the full path of a font based on the platform
std::filesystem::path ResourceHandler::getFontPath(const std::string& relativePath) { return getFullPath(RAYX_FONTS_DIR, relativePath); }

} // namespace RAYX
41 changes: 41 additions & 0 deletions Intern/rayx-core/src/Data/Locate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <filesystem>
#include <string>
#include <set>

#include "Core.h"

namespace RAYX {

class RAYX_API ResourceHandler {
public:
static ResourceHandler& getInstance() {
thread_local ResourceHandler instance;
return instance;
}

// Platform-specific implementations for resource path search
std::filesystem::path getExecutablePath();

// Retrieves a resource file's full path based on the relative path
std::filesystem::path getResourcePath(const std::string& relativePath);

// Retrieves a font file's full path based on the relative path
std::filesystem::path getFontPath(const std::string& relativePath);

private:
ResourceHandler() = default;
bool fileExists(const std::string& path);
bool fileExists(const std::filesystem::path& path);
std::filesystem::path getFullPath(const std::string& baseDir, const std::string& relativePath);

std::set<std::filesystem::path> lookUpPaths = {
#if defined(__linux__)
std::filesystem::path("/usr"), //
std::filesystem::path("/usr/local"), //
#endif
};
};

} // namespace RAYX
9 changes: 8 additions & 1 deletion Intern/rayx-core/src/Data/xml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,18 @@ bool paramPositionNoGroup(const rapidxml::xml_node<>* node, glm::dvec4* out) {

std::filesystem::path Parser::parseEnergyDistributionFile() const {
std::filesystem::path datpath = Parser::parseStr("photonEnergyDistributionFile");
// Check if the path is empty
if (datpath.empty()) {
// Since the photon energy distribution file is optional, return an empty path
RAYX_VERB << "No photon energy distribution file specified.";
return std::filesystem::path(); // Or handle as per your application's logic
}

std::filesystem::path combinedPath = rmlFile.parent_path() / datpath;
try {
combinedPath = std::filesystem::canonical(combinedPath);
} catch (const std::exception& e) {
RAYX_EXIT << "Failed to canonicalize datfile path: " << e.what();
RAYX_EXIT << "Failed to canonicalize datfile path: " << combinedPath.string() << " -- Error: " << e.what();
}

RAYX_VERB << "Combined datfile path: " << combinedPath;
Expand Down
6 changes: 3 additions & 3 deletions Intern/rayx-core/src/Material/NffTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <algorithm>
#include <fstream>

#include "CanonicalizePath.h"
#include "Data/Locate.h"
#include "Debug/Debug.h"

namespace RAYX {
Expand All @@ -14,7 +14,7 @@ bool NffTable::load(const char* element, NffTable* out) {

std::transform(elementString.begin(), elementString.end(), elementString.begin(), [](unsigned char c) { return std::tolower(c); });

std::string f = getExecutablePath().string() + "/Data/nff/" + elementString + ".nff";
std::filesystem::path f = ResourceHandler::getInstance().getResourcePath("Data/nff/" + elementString + ".nff");
RAYX_VERB << "Loading NffTable from " << f;
std::ifstream s(f);

Expand All @@ -39,7 +39,7 @@ bool NffTable::load(const char* element, NffTable* out) {
#else
if (sscanf(line.c_str(), "%le %le %le", &e.m_energy, &e.m_f1, &e.m_f2) != 3) {
#endif
RAYX_EXIT << "Failed to parse NffTable\"" << element << "\", at line " << lineidx << ": \"" << line << "\"";
RAYX_WARN << "Failed to parse NffTable\"" << element << "\", at line " << lineidx << ": \"" << line << "\"";
return false;
}
out->m_Lines.push_back(e);
Expand Down
6 changes: 3 additions & 3 deletions Intern/rayx-core/src/Material/PalikTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <algorithm>
#include <fstream>

#include "CanonicalizePath.h"
#include "Data/Locate.h"
#include "Debug/Debug.h"

namespace RAYX {
Expand All @@ -12,7 +12,7 @@ bool PalikTable::load(const char* element, PalikTable* out) {
std::string elementString = element;
std::transform(elementString.begin(), elementString.end(), elementString.begin(), [](unsigned char c) { return std::toupper(c); });

std::string f = getExecutablePath().string() + "/Data/PALIK/" + elementString + ".NKP";
std::filesystem::path f = ResourceHandler::getInstance().getResourcePath("Data/PALIK/" + elementString + ".NKP");
RAYX_VERB << "Loading PalikTable from " << f;
std::ifstream s(f);

Expand All @@ -39,7 +39,7 @@ bool PalikTable::load(const char* element, PalikTable* out) {
#else
if (sscanf(line.c_str(), "%le %le %le", &e.m_energy, &e.m_n, &e.m_k) != 3) {
#endif
RAYX_EXIT << "Failed to parse PalikTable \"" << element << "\", at line " << lineidx << ": \"" << line << "\"";
RAYX_WARN << "Failed to parse PalikTable \"" << element << "\", at line " << lineidx << ": \"" << line << "\"";
return false;
}
out->m_Lines.push_back(e);
Expand Down
33 changes: 16 additions & 17 deletions Intern/rayx-ui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ if(Vulkan_FOUND)
GLM_FORCE_DEPTH_ZERO_TO_ONE)

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(RESOURCE_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}/Assets)
set(RESOURCE_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG})
else()
set(RESOURCE_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}/Assets)
set(RESOURCE_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE})
endif()

message(STATUS "Resource directory: ${RESOURCE_DIR}")
Expand All @@ -56,26 +56,25 @@ if(Vulkan_FOUND)


# ---- CPack ----
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
if(APPLE OR UNIX)
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
elseif(WIN32)
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION .)
endif()

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}/Shaders
DESTINATION ${INSTALL_DATA_DIR}
FILES_MATCHING PATTERN "*_*.spv")
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}/Assets
DESTINATION ${INSTALL_DATA_DIR}
PATTERN "fonts" EXCLUDE)
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}/Assets/fonts
DESTINATION ${INSTALL_FONTS_DIR}
FILES_MATCHING PATTERN "*")
DESTINATION ${INSTALL_DATA_DIR})
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}/Textures
DESTINATION ${INSTALL_DATA_DIR})
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}/Fonts
DESTINATION ${INSTALL_FONTS_DIR})
else()
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}/Shaders
DESTINATION ${INSTALL_DATA_DIR}
FILES_MATCHING PATTERN "*_*.spv")
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}/Assets
DESTINATION ${INSTALL_DATA_DIR}
PATTERN "fonts" EXCLUDE)
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}/Assets/fonts
DESTINATION ${INSTALL_DATA_DIR})
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}/Textures
DESTINATION ${INSTALL_DATA_DIR})
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE}/Fonts
DESTINATION ${INSTALL_FONTS_DIR})
endif()

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
Loading

0 comments on commit fea08fb

Please sign in to comment.