diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..a7d0901 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,52 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build OpenVulkano", + "type": "shell", + "command": "cmake", + "args": [ + "--build", + "${workspaceFolder}/build", + "--target", + "openVulkanoCpp" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + + { + "label": "Build OpenVulkano examples", + "type": "shell", + "command": "cmake", + "args": [ + "--build", + "${workspaceFolder}/build", + "--target", + "OpenVulkano_Examples" + ], + "group": { + "kind": "build", + "isDefault": true + } + }, + + { + "label": "Build OpenVulkano tests", + "type": "shell", + "command": "cmake", + "args": [ + "--build", + "${workspaceFolder}/build", + "--target", + "OpenVulkano_Examples" + ], + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp new file mode 100644 index 0000000..93a2365 --- /dev/null +++ b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp @@ -0,0 +1,26 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "ExeAppendedZipResourceLoader.hpp" +#include "Base/Logger.hpp" +#include "IO/Archive/ArchiveReader.hpp" +#include "Base/Utils.hpp" +#include +#include + +namespace OpenVulkano +{ + Array ExeAppendedZipResourceLoader::GetResource(const std::string& resourceName) + { + ArchiveReader reader(GetCurrentExecutablePath(), nullptr, ArchiveType::ZIP); + if (auto data = reader.GetFile(resourceName)) + { + return data->second; + } + return {}; + } + +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.hpp b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.hpp new file mode 100644 index 0000000..a5a1863 --- /dev/null +++ b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.hpp @@ -0,0 +1,24 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "Host/ResourceLoader.hpp" +#include "IO/FileDescription.hpp" +#include +#include + +namespace OpenVulkano +{ + class ExeAppendedZipResourceLoader : public ResourceLoader + { + public: + std::string GetResourcePath(const std::string& resourceName) final { return ""; } + Array GetResource(const std::string& resourceName) override; + protected: + virtual std::string GetCurrentExecutablePath() const = 0; + }; +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp new file mode 100644 index 0000000..e624bfb --- /dev/null +++ b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp @@ -0,0 +1,26 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "ExeAppendedZipResourceLoaderLinux.hpp" +#include +#include + +namespace OpenVulkano +{ + namespace + { + void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique()); + } + + std::string OpenVulkano::ExeAppendedZipResourceLoaderLinux::GetCurrentExecutablePath() const + { + std::string path(PATH_MAX, '\0'); + ssize_t sz = readlink("/proc/self/exe", path.data(), path.capacity()); + path.resize(std::max(0, sz)); + return path; + } + +} diff --git a/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp new file mode 100644 index 0000000..73cfe31 --- /dev/null +++ b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp @@ -0,0 +1,18 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "Host/ExeAppendedZipResourceLoader.hpp" + +namespace OpenVulkano +{ + class ExeAppendedZipResourceLoaderLinux final : public ExeAppendedZipResourceLoader + { + public: + std::string GetCurrentExecutablePath() const override; + }; +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/Linux/SystemInfo.cpp b/openVulkanoCpp/Host/Linux/SystemInfo.cpp index 708bf4c..19fe0cf 100644 --- a/openVulkanoCpp/Host/Linux/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Linux/SystemInfo.cpp @@ -73,7 +73,8 @@ namespace OpenVulkano size_t SystemInfo::GetSystemRam() { - return ReadMemInfo("MemTotal"); + static const size_t ram = ReadMemInfo("MemTotal"); + return ram; } size_t SystemInfo::GetSystemRamAvailable() @@ -98,60 +99,94 @@ namespace OpenVulkano size_t SystemInfo::GetAppVirtualMemoryMax() { - rlimit limit; - if (getrlimit(RLIMIT_AS, &limit) == 0) + static size_t vramMax; + if (vramMax == 0) { - return limit.rlim_cur; + rlimit limit; + if (getrlimit(RLIMIT_AS, &limit) == 0) + { + vramMax = limit.rlim_cur; + } + Logger::PERF->error("Failed to query max application memory"); } - Logger::PERF->error("Failed to query max application memory"); - return 0; + return vramMax; } - std::string SystemInfo::GetUserName() + const std::string& SystemInfo::GetUserName() { - char* name = getlogin(); - if (!name) return "unknown"; - return name; + static std::string userName; + if (userName.empty()) + { + char* name = getlogin(); + if (!name) + { + userName = "unknown"; + } + else + { + userName = name; + } + } + return userName; } - std::string SystemInfo::GetHostName() + const std::string& SystemInfo::GetHostName() { - char hostname[HOST_NAME_MAX + 1]; - gethostname(hostname, HOST_NAME_MAX + 1); - return hostname; + static std::string hostName; + if (hostName.empty()) + { + char hostname[HOST_NAME_MAX + 1]; + gethostname(hostname, HOST_NAME_MAX + 1); + hostName = hostname; + } + return hostName; } - std::string SystemInfo::GetDeviceName() + const std::string& SystemInfo::GetDeviceName() { return GetHostName(); } - std::string SystemInfo::GetDeviceVendorName() + const std::string& SystemInfo::GetDeviceVendorName() { - std::ifstream dmiStream("/sys/class/dmi/id/board_vendor"); - if (!dmiStream) + static std::string vendor; + if (vendor.empty()) { - Logger::PERF->error("Failed to read /sys/class/dmi/id/board_vendor"); - return "Unknown"; + std::ifstream dmiStream("/sys/class/dmi/id/board_vendor"); + if (!dmiStream) + { + Logger::PERF->error("Failed to read /sys/class/dmi/id/board_vendor"); + vendor = "Unknown"; + } + else + { + std::string motherboardName; + std::getline(dmiStream, motherboardName); + vendor = motherboardName; + } } - - std::string motherboardName; - std::getline(dmiStream, motherboardName); - return motherboardName; + return vendor; } - std::string SystemInfo::GetDeviceModelName() + const std::string& SystemInfo::GetDeviceModelName() { - std::ifstream dmiStream("/sys/class/dmi/id/board_name"); - if (!dmiStream) + static std::string modelName; + if (modelName.empty()) { - Logger::PERF->error("Failed to read /sys/class/dmi/id/board_name"); - return "Unknown"; + std::ifstream dmiStream("/sys/class/dmi/id/board_name"); + if (!dmiStream) + { + Logger::PERF->error("Failed to read /sys/class/dmi/id/board_name"); + modelName = "Unknown"; + } + else + { + std::string motherboardName; + std::getline(dmiStream, motherboardName); + modelName = motherboardName; + } } - - std::string motherboardName; - std::getline(dmiStream, motherboardName); - return motherboardName; + return modelName; } namespace @@ -248,7 +283,7 @@ namespace OpenVulkano OsInfo osInfo; } - std::string SystemInfo::GetOsName() + const std::string& SystemInfo::GetOsName() { return osInfo.osName; } @@ -258,7 +293,7 @@ namespace OpenVulkano return osInfo.version; } - std::string SystemInfo::GetOsNameHumanReadable() + const std::string& SystemInfo::GetOsNameHumanReadable() { return osInfo.osNameFormatted; } @@ -275,7 +310,8 @@ namespace OpenVulkano size_t SystemInfo::GetCpuThreadCount() { - return std::thread::hardware_concurrency(); + static const size_t threadCount = std::thread::hardware_concurrency(); + return threadCount; } int32_t SystemInfo::GetCpuTemperature() diff --git a/openVulkanoCpp/Host/MacOS/SystemInfo.mm b/openVulkanoCpp/Host/MacOS/SystemInfo.mm index ad149f1..ca295f6 100644 --- a/openVulkanoCpp/Host/MacOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/MacOS/SystemInfo.mm @@ -7,6 +7,7 @@ #include "Host/SystemInfo.hpp" #include "Base/Logger.hpp" #include +#include #include #include @@ -24,7 +25,8 @@ namespace OpenVulkano size_t SystemInfo::GetSystemRam() { - return [NSProcessInfo processInfo].physicalMemory; + static const size_t ram = [NSProcessInfo processInfo].physicalMemory; + return ram; } size_t SystemInfo::GetSystemRamAvailable() @@ -60,49 +62,64 @@ namespace OpenVulkano return 0; } - std::string SystemInfo::GetUserName() + const std::string& SystemInfo::GetUserName() { - return ""; + static const std::string userName = ""; + return userName; } - std::string SystemInfo::GetHostName() + const std::string& SystemInfo::GetHostName() { - return [[NSProcessInfo processInfo].hostName UTF8String]; + static const std::string hostName = [[NSProcessInfo processInfo].hostName UTF8String]; + return hostName; } - std::string SystemInfo::GetDeviceName() + const std::string& SystemInfo::GetDeviceName() { - return "Mac"; //TODO + static const std::string devName = "Mac"; //TODO + return devName; } - std::string SystemInfo::GetDeviceVendorName() + const std::string& SystemInfo::GetDeviceVendorName() { - return "Apple"; + static const std::string vendorName = "Apple"; + return vendorName; } - std::string SystemInfo::GetDeviceModelName() + const std::string& SystemInfo::GetDeviceModelName() { - struct utsname systemInfo; - uname(&systemInfo); - return systemInfo.machine; + static std::string machine; + if (machine.empty()) + { + struct utsname systemInfo; + uname(&systemInfo); + machine = systemInfo.machine; + } + return machine; } - std::string SystemInfo::GetOsName() + const std::string& SystemInfo::GetOsName() { - return "MacOS"; + static const std::string osName = "MacOS"; + return osName; } OsVersion SystemInfo::GetOsVersion() { - NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion; - return { static_cast(osVersion.majorVersion), static_cast(osVersion.minorVersion), static_cast(osVersion.patchVersion), 0 }; + static OsVersion osVersion = {}; + if (osVersion.major == 0 && osVersion.minor == 0) + { + NSOperatingSystemVersion sysVersion = [NSProcessInfo processInfo].operatingSystemVersion; + osVersion = { static_cast(sysVersion.majorVersion), static_cast(sysVersion.minorVersion), + static_cast(sysVersion.patchVersion), 0 }; + } + return osVersion; } - std::string SystemInfo::GetOsNameHumanReadable() + const std::string& SystemInfo::GetOsNameHumanReadable() { - std::stringstream name; - name << GetOsName() << ' ' << GetOsVersion().major; - return name.str(); + static const std::string hrName = fmt::format("{} {}", GetOsName(), GetOsVersion().major); + return hrName; } DeviceType SystemInfo::GetDeviceType() @@ -112,12 +129,14 @@ namespace OpenVulkano size_t SystemInfo::GetCpuCoreCount() { - return [NSProcessInfo processInfo].processorCount; + static const size_t coreCount = [NSProcessInfo processInfo].processorCount; + return coreCount; } size_t SystemInfo::GetCpuThreadCount() { - return [NSProcessInfo processInfo].activeProcessorCount; + static size_t procCount = [NSProcessInfo processInfo].activeProcessorCount; + return procCount; } int32_t SystemInfo::GetCpuTemperature() diff --git a/openVulkanoCpp/Host/ResourceLoader.hpp b/openVulkanoCpp/Host/ResourceLoader.hpp index 7b8000a..3cf051e 100644 --- a/openVulkanoCpp/Host/ResourceLoader.hpp +++ b/openVulkanoCpp/Host/ResourceLoader.hpp @@ -4,6 +4,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +#pragma once + #include "Data/Containers/Array.hpp" #include #include diff --git a/openVulkanoCpp/Host/SystemInfo.hpp b/openVulkanoCpp/Host/SystemInfo.hpp index b42ed10..7ab324c 100644 --- a/openVulkanoCpp/Host/SystemInfo.hpp +++ b/openVulkanoCpp/Host/SystemInfo.hpp @@ -36,16 +36,16 @@ namespace OpenVulkano static size_t GetAppRamAvailable(); static size_t GetAppRamUsed(); - static std::string GetUserName(); - static std::string GetHostName(); + static const std::string& GetUserName(); + static const std::string& GetHostName(); // Device name as given by the user - static std::string GetDeviceName(); - static std::string GetDeviceVendorName(); - static std::string GetDeviceModelName(); - static std::string GetOsName(); + static const std::string& GetDeviceName(); + static const std::string& GetDeviceVendorName(); + static const std::string& GetDeviceModelName(); + static const std::string& GetOsName(); static OsVersion GetOsVersion(); - static std::string GetOsNameHumanReadable(); + static const std::string& GetOsNameHumanReadable(); static DeviceType GetDeviceType(); static size_t GetCpuCoreCount(); diff --git a/openVulkanoCpp/Host/Windows/EmbeddedResourceLoaderWindows.cpp b/openVulkanoCpp/Host/Windows/EmbeddedResourceLoaderWindows.cpp index 5ff7694..def9d0e 100644 --- a/openVulkanoCpp/Host/Windows/EmbeddedResourceLoaderWindows.cpp +++ b/openVulkanoCpp/Host/Windows/EmbeddedResourceLoaderWindows.cpp @@ -52,7 +52,7 @@ namespace OpenVulkano std::string EmbeddedResourceLoaderWindows::GetResourceName(const char* resId) { - // check if resId was provided as interger and not CString + // check if resId was provided as interger or CString // https://stackoverflow.com/questions/3610565/why-does-makeintresource-work // first 64KB uintptr_t ptrT = reinterpret_cast(resId); diff --git a/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp new file mode 100644 index 0000000..8800276 --- /dev/null +++ b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp @@ -0,0 +1,25 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "ExeAppendedZipResourceLoaderWindows.hpp" +#include + +namespace OpenVulkano +{ + namespace + { + void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique()); + } + + std::string OpenVulkano::ExeAppendedZipResourceLoaderWindows::GetCurrentExecutablePath() const + { + std::string exe(MAX_PATH, '\0'); + DWORD len = GetModuleFileNameA(NULL, exe.data(), MAX_PATH); + exe.resize(len); + return exe; + } + +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.hpp b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.hpp new file mode 100644 index 0000000..c1ff2c0 --- /dev/null +++ b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.hpp @@ -0,0 +1,18 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "Host/ExeAppendedZipResourceLoader.hpp" + +namespace OpenVulkano +{ + class ExeAppendedZipResourceLoaderWindows final : public ExeAppendedZipResourceLoader + { + public: + std::string GetCurrentExecutablePath() const override; + }; +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/Windows/SystemInfo.cpp b/openVulkanoCpp/Host/Windows/SystemInfo.cpp index 4d61fef..a7a9270 100644 --- a/openVulkanoCpp/Host/Windows/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Windows/SystemInfo.cpp @@ -253,6 +253,80 @@ namespace OpenVulkano return res; } + std::string GetHumanReadableOSName() + { + NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW); + OSVERSIONINFOEXW info; + *(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); + info.dwOSVersionInfoSize = sizeof(info); + RtlGetVersion(&info); + if (info.wProductType == VER_NT_WORKSTATION) + { + if (info.dwMajorVersion == 10) + { + if (info.dwBuildNumber >= 22000) + return "Windows 11"; + return "Windows 10"; + } + else if (info.dwMajorVersion == 6) + { + switch (info.dwMinorVersion) + { + case 0: return "Windows Vista"; + case 1: return "Windows 7"; + case 2: return "Windows 8"; + case 3: return "Windows 8.1"; + } + } + + return "Windows " + std::to_string(info.dwMajorVersion) + "." + std::to_string(info.dwMinorVersion); + } + else + { + if (info.dwMajorVersion == 10) + { + switch (info.dwBuildNumber) + { + case 14393: + return "Windows Server 2016"; + case 16299: + return "Windows Server 1709"; + case 17134: + return "Windows Server 1803"; + case 17763: + return "Windows Server 2019"; + case 18362: + return "Windows Server 1903"; + case 18363: + return "Windows Server 1909"; + case 19041: + return "Windows Server 2004"; + case 19042: + return "Windows Server 20H2"; + case 20348: + return "Windows Server 2022"; + case 25398: + return "Windows Server 23H2"; + case 26100: + return "Windows Server 2025"; + default: + return "Windows Server"; + } + } + else if (info.dwMajorVersion == 6) + { + switch (info.dwMinorVersion) + { + case 0: return "Windows Server 2008"; + case 1: return "Windows Server 2008 R2"; + case 2: return "Windows Server 2012"; + case 3: return "Windows Server 2012 R2"; + } + } + + return "Windows Server " + std::to_string(info.dwMajorVersion) + "." + std::to_string(info.dwMinorVersion); + } + } } size_t SystemInfo::GetSystemRam() @@ -285,129 +359,91 @@ namespace OpenVulkano return ReadAppMemInfo(APP_MEM_TYPE::VM_MAX); } - std::string SystemInfo::GetUserName() + const std::string& SystemInfo::GetUserName() { - char username[UNLEN+1]; - DWORD username_len = UNLEN+1; - ::GetUserNameA(username, &username_len); - return username; + static std::string userName; + if (userName.empty()) + { + char username[UNLEN + 1]; + DWORD username_len = UNLEN + 1; + ::GetUserNameA(username, &username_len); + userName = username; + } + return userName; } - std::string SystemInfo::GetHostName() + const std::string& SystemInfo::GetHostName() { - char hostname[UNLEN+1]; - gethostname(hostname, UNLEN+1); - return hostname; + static std::string hostName; + if (hostName.empty()) + { + char hostname[UNLEN+1]; + gethostname(hostname, UNLEN+1); + hostName = hostname; + } + return hostName; } - std::string SystemInfo::GetDeviceName() + const std::string& SystemInfo::GetDeviceName() { - char computerName[UNLEN+1]; - DWORD computerName_len = UNLEN+1; - GetComputerNameA(computerName, &computerName_len); - return computerName; + static std::string devName; + if (devName.empty()) + { + char computerName[UNLEN+1]; + DWORD computerName_len = UNLEN+1; + GetComputerNameA(computerName, &computerName_len); + devName = computerName; + } + return devName; } - std::string SystemInfo::GetDeviceVendorName() + const std::string& SystemInfo::GetDeviceVendorName() { - std::optional res = GetWMIProperty("Manufacturer"); - return res ? *res : "Unknown"; + static std::string vendorName; + if (vendorName.empty()) + { + std::optional res = GetWMIProperty("Manufacturer"); + vendorName = res ? *res : "Unknown"; + } + return vendorName; } - std::string SystemInfo::GetDeviceModelName() + const std::string& SystemInfo::GetDeviceModelName() { - std::optional res = GetWMIProperty("Model"); - return res ? *res : "Unknown"; + static std::string deviceModelName; + if (deviceModelName.empty()) + { + std::optional res = GetWMIProperty("Model"); + deviceModelName = res ? *res : "Unknown"; + } + return deviceModelName; } - std::string SystemInfo::GetOsName() + const std::string& SystemInfo::GetOsName() { - return "Windows"; + static const std::string osName = "Windows"; + return osName; } OsVersion SystemInfo::GetOsVersion() { - NTSTATUS(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW); - OSVERSIONINFOEXW info; - *(FARPROC*) &RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); - info.dwOSVersionInfoSize = sizeof(info); - RtlGetVersion(&info); - return { (int)info.dwMajorVersion, (int)info.dwMinorVersion, 0, (int)info.dwBuildNumber }; + static OsVersion osVersion = {}; + if (osVersion.major == 0 && osVersion.minor == 0) + { + NTSTATUS(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW); + OSVERSIONINFOEXW info; + *(FARPROC*) &RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); + info.dwOSVersionInfoSize = sizeof(info); + RtlGetVersion(&info); + osVersion = { (int)info.dwMajorVersion, (int)info.dwMinorVersion, 0, (int)info.dwBuildNumber }; + } + return osVersion; } - std::string SystemInfo::GetOsNameHumanReadable() + const std::string& SystemInfo::GetOsNameHumanReadable() { - NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW); - OSVERSIONINFOEXW info; - *(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); - info.dwOSVersionInfoSize = sizeof(info); - RtlGetVersion(&info); - if (info.wProductType == VER_NT_WORKSTATION) - { - if (info.dwMajorVersion == 10) - { - if (info.dwBuildNumber >= 22000) - return "Windows 11"; - return "Windows 10"; - } - else if (info.dwMajorVersion == 6) - { - switch (info.dwMinorVersion) - { - case 0: return "Windows Vista"; - case 1: return "Windows 7"; - case 2: return "Windows 8"; - case 3: return "Windows 8.1"; - } - } - - return "Windows " + std::to_string(info.dwMajorVersion) + "." + std::to_string(info.dwMinorVersion); - } - else - { - if (info.dwMajorVersion == 10) - { - switch (info.dwBuildNumber) - { - case 14393: - return "Windows Server 2016"; - case 16299: - return "Windows Server 1709"; - case 17134: - return "Windows Server 1803"; - case 17763: - return "Windows Server 2019"; - case 18362: - return "Windows Server 1903"; - case 18363: - return "Windows Server 1909"; - case 19041: - return "Windows Server 2004"; - case 19042: - return "Windows Server 20H2"; - case 20348: - return "Windows Server 2022"; - case 25398: - return "Windows Server 23H2"; - case 26100: - return "Windows Server 2025"; - default: - return "Windows Server"; - } - } - else if (info.dwMajorVersion == 6) - { - switch (info.dwMinorVersion) - { - case 0: return "Windows Server 2008"; - case 1: return "Windows Server 2008 R2"; - case 2: return "Windows Server 2012"; - case 3: return "Windows Server 2012 R2"; - } - } - - return "Windows Server " + std::to_string(info.dwMajorVersion) + "." + std::to_string(info.dwMinorVersion); - } + static const std::string osName = GetHumanReadableOSName(); + return osName; } DeviceType SystemInfo::GetDeviceType() @@ -417,23 +453,28 @@ namespace OpenVulkano size_t SystemInfo::GetCpuCoreCount() { - DWORD bufferSize = 0; - GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP::RelationProcessorCore, nullptr, &bufferSize); - - std::vector buf(bufferSize); - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* info = reinterpret_cast(buf.data()); - GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP::RelationProcessorCore, info, &bufferSize); - - size_t physProcessorCount = 0; - BYTE* start = buf.data(); - BYTE* end = buf.data() + bufferSize; - while (start < end) + static size_t coreCount = 0; + if (coreCount == 0) { - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* current = reinterpret_cast(start); - physProcessorCount++; - start += current->Size; + DWORD bufferSize = 0; + GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP::RelationProcessorCore, nullptr, &bufferSize); + + std::vector buf(bufferSize); + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* info = reinterpret_cast(buf.data()); + GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP::RelationProcessorCore, info, &bufferSize); + + size_t physProcessorCount = 0; + BYTE* start = buf.data(); + BYTE* end = buf.data() + bufferSize; + while (start < end) + { + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* current = reinterpret_cast(start); + physProcessorCount++; + start += current->Size; + } + coreCount = physProcessorCount; } - return physProcessorCount; + return coreCount; } size_t SystemInfo::GetCpuThreadCount() diff --git a/openVulkanoCpp/Host/iOS/SystemInfo.mm b/openVulkanoCpp/Host/iOS/SystemInfo.mm index 6034484..3182ba2 100644 --- a/openVulkanoCpp/Host/iOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/iOS/SystemInfo.mm @@ -27,7 +27,8 @@ namespace OpenVulkano size_t SystemInfo::GetSystemRam() { - return [NSProcessInfo processInfo].physicalMemory; + static const size_t ram = [NSProcessInfo processInfo].physicalMemory; + return ram; } size_t SystemInfo::GetSystemRamAvailable() @@ -63,27 +64,31 @@ namespace OpenVulkano return 0; } - std::string SystemInfo::GetUserName() + const std::string& SystemInfo::GetUserName() { - return ""; + static const std::string userName = ""; + return userName; } - std::string SystemInfo::GetHostName() + const std::string& SystemInfo::GetHostName() { - return [[NSProcessInfo processInfo].hostName UTF8String]; + static const std::string hostName = [[NSProcessInfo processInfo].hostName UTF8String]; + return hostName; } - std::string SystemInfo::GetDeviceName() + const std::string& SystemInfo::GetDeviceName() { - return [[[UIDevice currentDevice] name] UTF8String]; + static const std::string devName = [[[UIDevice currentDevice] name] UTF8String]; + return devName; } - std::string SystemInfo::GetDeviceVendorName() + const std::string& SystemInfo::GetDeviceVendorName() { - return "Apple"; + static const std::string vendorName = "Apple"; + return vendorName; } - std::string SystemInfo::GetDeviceModelName() + const std::string& SystemInfo::GetDeviceModelName() { static std::string modelName; if (modelName.empty()) @@ -96,45 +101,69 @@ namespace OpenVulkano return modelName; } - std::string SystemInfo::GetOsName() + const std::string& SystemInfo::GetOsName() { - return [[[UIDevice currentDevice] systemName] UTF8String]; + static const std::string osName = [[[UIDevice currentDevice] systemName] UTF8String]; + return osName; } OsVersion SystemInfo::GetOsVersion() { - NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion; - return { static_cast(osVersion.majorVersion), static_cast(osVersion.minorVersion), static_cast(osVersion.patchVersion), 0 }; + static OsVersion osv = {}; + if (osv.major == 0 && osv.minor == 0) + { + NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion; + osv = { static_cast(osVersion.majorVersion), static_cast(osVersion.minorVersion), + static_cast(osVersion.patchVersion), 0 }; + } + return osv; } - std::string SystemInfo::GetOsNameHumanReadable() + const std::string& SystemInfo::GetOsNameHumanReadable() { - OsVersion osVersion = GetOsVersion(); - return fmt::format("{} {}.{}", GetOsName(), osVersion.major, osVersion.minor); + static std::string hrName; + if (hrName.empty()) + { + OsVersion osVersion = GetOsVersion(); + hrName = fmt::format("{} {}.{}", GetOsName(), osVersion.major, osVersion.minor); + } + return hrName; } DeviceType SystemInfo::GetDeviceType() { - switch ([UIDevice currentDevice].userInterfaceIdiom) + static DeviceType devType = DeviceType::Unknown; + if (devType == DeviceType::Unknown) { - case UIUserInterfaceIdiomPhone: return DeviceType::Phone; - case UIUserInterfaceIdiomPad: return DeviceType::Tablet; - case UIUserInterfaceIdiomTV: return DeviceType::TV; - case UIUserInterfaceIdiomMac: return DeviceType::PC; - case UIUserInterfaceIdiomVision: return DeviceType::VR; - default: break; + switch ([UIDevice currentDevice].userInterfaceIdiom) + { + case UIUserInterfaceIdiomPhone: + devType = DeviceType::Phone; + case UIUserInterfaceIdiomPad: + devType = DeviceType::Tablet; + case UIUserInterfaceIdiomTV: + devType = DeviceType::TV; + case UIUserInterfaceIdiomMac: + devType = DeviceType::PC; + case UIUserInterfaceIdiomVision: + devType = DeviceType::VR; + default: + break; + } } - return DeviceType::Unknown; + return devType; } size_t SystemInfo::GetCpuCoreCount() { - return [NSProcessInfo processInfo].processorCount; + static const size_t coreCount = [NSProcessInfo processInfo].processorCount; + return coreCount; } size_t SystemInfo::GetCpuThreadCount() { - return [NSProcessInfo processInfo].activeProcessorCount; + static const size_t threadCount = [NSProcessInfo processInfo].activeProcessorCount; + return threadCount; } int32_t SystemInfo::GetCpuTemperature() diff --git a/openVulkanoCpp/IO/Archive/ArchiveReader.cpp b/openVulkanoCpp/IO/Archive/ArchiveReader.cpp index b8efd2e..b392842 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveReader.cpp +++ b/openVulkanoCpp/IO/Archive/ArchiveReader.cpp @@ -20,22 +20,22 @@ namespace OpenVulkano constexpr int BUFFER_SIZE = 16384; } - ArchiveReader::ArchiveReader(const std::shared_ptr& logger) - : ArchiveBase(archive_read_new(), nullptr, logger) + ArchiveReader::ArchiveReader(const std::shared_ptr& logger, std::optional archiveType) + : ArchiveBase(archive_read_new(), nullptr, logger), m_archiveType(archiveType) {} - ArchiveReader::ArchiveReader(const std::string& archiveFile, const std::shared_ptr& logger) - : ArchiveReader(archiveFile.c_str(), logger) + ArchiveReader::ArchiveReader(const std::string& archiveFile, const std::shared_ptr& logger, std::optional archiveType) + : ArchiveReader(archiveFile.c_str(), logger, archiveType) {} - ArchiveReader::ArchiveReader(const char* archiveFile, const std::shared_ptr& logger) - : ArchiveReader(logger) + ArchiveReader::ArchiveReader(const char* archiveFile, const std::shared_ptr& logger, std::optional archiveType) + : ArchiveReader(logger, archiveType) { Open(archiveFile); } - ArchiveReader::ArchiveReader(const void* archiveBuffer, const size_t size, const std::shared_ptr& logger) - : ArchiveReader(logger) + ArchiveReader::ArchiveReader(const void* archiveBuffer, const size_t size, const std::shared_ptr& logger, std::optional archiveType) + : ArchiveReader(logger, archiveType) { OpenMemory(archiveBuffer, size); } @@ -51,7 +51,7 @@ namespace OpenVulkano m_archive = archive_read_new(); } ChkErr(archive_read_support_filter_all(m_archive)); - ChkErr(archive_read_support_format_all(m_archive)); + ChkErr(GetCurrentFormatReadFunc()(m_archive)); m_open = true; } @@ -156,6 +156,33 @@ namespace OpenVulkano } } + std::function ArchiveReader::GetCurrentFormatReadFunc() const + { + if (!m_archiveType) + { + return archive_read_support_format_all; + } + ArchiveType::Type type = *m_archiveType; + switch (type) + { + case ArchiveType::ZIP: + return archive_read_support_format_zip; + case ArchiveType::SEVEN_ZIP: + return archive_read_support_format_7zip; + case ArchiveType::CPIO: + return archive_read_support_format_cpio; + case ArchiveType::ISO: + return archive_read_support_format_iso9660; + case ArchiveType::TAR: + return archive_read_support_format_tar; + case ArchiveType::WARC: + return archive_read_support_format_warc; + case ArchiveType::XAR: + return archive_read_support_format_xar; + } + return archive_read_support_format_all; + } + size_t ArchiveReader::ExtractRemaining(std::string_view targetDir) { size_t count = 0; @@ -263,6 +290,22 @@ namespace OpenVulkano return std::nullopt; } + std::optional>> ArchiveReader::GetFile(const std::string& path) + { + while (HasNext()) + { + if (path == archive_entry_pathname(m_archiveEntry)) + { + return GetNextFile(); + } + if (archive_read_next_header(m_archive, &m_archiveEntry) != ARCHIVE_OK) + { + return {}; + } + } + return {}; + } + bool ArchiveReader::GetNextFileAsStream(const std::function& streamReader) { if (SkipTill(std::filesystem::file_type::regular)) diff --git a/openVulkanoCpp/IO/Archive/ArchiveReader.hpp b/openVulkanoCpp/IO/Archive/ArchiveReader.hpp index 776a57c..b2f0642 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveReader.hpp +++ b/openVulkanoCpp/IO/Archive/ArchiveReader.hpp @@ -8,6 +8,7 @@ #include "ArchiveBase.hpp" #include "Data/Containers/Array.hpp" +#include "ArchiveType.hpp" #include #include #include @@ -20,17 +21,17 @@ namespace OpenVulkano { bool m_open = false; bool m_eof = false; - + std::optional m_archiveType; std::queue m_archivesToRead; public: - explicit ArchiveReader(const std::shared_ptr& logger = nullptr); + explicit ArchiveReader(const std::shared_ptr& logger = nullptr, std::optional archiveType = std::nullopt); - explicit ArchiveReader(const char* archiveFile, const std::shared_ptr& logger = nullptr); + explicit ArchiveReader(const char* archiveFile, const std::shared_ptr& logger = nullptr, std::optional archiveType = std::nullopt); - explicit ArchiveReader(const std::string& archiveFile, const std::shared_ptr& logger = nullptr); + explicit ArchiveReader(const std::string& archiveFile, const std::shared_ptr& logger = nullptr, std::optional archiveType = std::nullopt); - ArchiveReader(const void* archiveBuffer, size_t size, const std::shared_ptr& logger = nullptr); + ArchiveReader(const void* archiveBuffer, size_t size, const std::shared_ptr& logger = nullptr, std::optional archiveType = std::nullopt); ~ArchiveReader() override; @@ -65,13 +66,15 @@ namespace OpenVulkano std::optional>> GetNextFileAsVector(); + std::optional>> GetFile(const std::string& path); + std::optional StreamNextFile(std::ostream& stream); bool GetNextFileAsStream(const std::function& streamReader); private: void ReadNextHeader(); - + std::function GetCurrentFormatReadFunc() const; void PrepOpen(); }; } diff --git a/resources/arch.zip b/resources/arch.zip new file mode 100644 index 0000000..c693a63 Binary files /dev/null and b/resources/arch.zip differ diff --git a/resources/icon.rc b/resources/icon.rc index 8699872..928955b 100644 --- a/resources/icon.rc +++ b/resources/icon.rc @@ -63,3 +63,4 @@ END // FOR REFERENCE SEE EmbeddedResourceLoaderWindows.cpp IDI_MADVOXEL_ICON ICON "madvoxel_icon.ico" MADVOXEL_ICON ICON "madvoxel_icon.ico" +ARCHIVE_RCDATA RCDATA "arch.zip" diff --git a/resources/resource.h b/resources/resource.h index 2c4237e..961a736 100644 --- a/resources/resource.h +++ b/resources/resource.h @@ -1 +1,2 @@ #define IDI_MADVOXEL_ICON 101 +#define ARCHIVE_RCDATA 102 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 71523b6..85c0c4f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,11 +10,22 @@ FilterPlatformPaths(SOURCES) if (NOT ENABLE_CURL) list(FILTER SOURCES EXCLUDE REGEX "WebResourceLoader") endif() + +if (APPLE) + list(FILTER SOURCES EXCLUDE REGEX "ExeAppendedZipResourceLoader") +endif() + source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES}) file(GLOB_RECURSE RESOURCES "${ROOT_FOLDER}/resources/*.rc" "${ROOT_FOLDER}/resources/*.h") list(APPEND SOURCES ${RESOURCES}) add_executable(OpenVulkano_Tests ${SOURCES}) +# append zip file at the end of executable file +if (WIN32 OR LINUX) + set(ZIP_FILE ${ROOT_FOLDER}/resources/arch.zip) + add_custom_command(TARGET OpenVulkano_Tests POST_BUILD COMMAND ${CMAKE_COMMAND} -E cat ${ZIP_FILE} >> $) +endif() + target_include_directories(OpenVulkano_Tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(OpenVulkano_Tests PRIVATE openVulkanoCpp) diff --git a/tests/Host/ExeAppendedZipResourceLoaderTests.cpp b/tests/Host/ExeAppendedZipResourceLoaderTests.cpp new file mode 100644 index 0000000..caf9e63 --- /dev/null +++ b/tests/Host/ExeAppendedZipResourceLoaderTests.cpp @@ -0,0 +1,37 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include + +#ifdef _WIN32 + #include "Host/Windows/ExeAppendedZipResourceLoaderWindows.hpp" +#else + #include "Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp" +#endif + +#include "Base/Logger.hpp" +#include +#include + +using namespace OpenVulkano; + +TEST_CASE("Load zip from exe") +{ + Logger::SetupLogger("", "tests.log"); +#ifdef _WIN32 + ExeAppendedZipResourceLoaderWindows loader; +#else + ExeAppendedZipResourceLoaderLinux loader; +#endif + auto iconData = loader.GetResource("madvoxel_icon.ico"); + REQUIRE(!iconData.Empty()); + + auto txtFile = loader.GetResource("text.txt"); + REQUIRE(!txtFile.Empty()); + + std::string s(txtFile.Data(), txtFile.Size()); + REQUIRE(s == "Hello world!"); +} diff --git a/tests/Host/Windows/ResourceLoaderTests.cpp b/tests/Host/Windows/ResourceLoaderTests.cpp index da9b48a..65192a9 100644 --- a/tests/Host/Windows/ResourceLoaderTests.cpp +++ b/tests/Host/Windows/ResourceLoaderTests.cpp @@ -42,3 +42,10 @@ TEST_CASE("Load icon") Array nonExistingRes2 = loader.GetResource("NON_EXISTING_ICON", RT_GROUP_ICON); REQUIRE((nonExistingRes.Empty() && nonExistingRes2.Empty())); } + +TEST_CASE("Load archive") +{ + EmbeddedResourceLoaderWindows loader; + Array zipData = loader.GetResource(MAKEINTRESOURCE(ARCHIVE_RCDATA), RT_RCDATA); + REQUIRE(!zipData.Empty()); +}