From a65afd75342682ae5600afb79e20591c2d193d66 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 15:12:26 +0200 Subject: [PATCH 01/23] SysInfo caching for Linux --- openVulkanoCpp/Host/Linux/SystemInfo.cpp | 102 ++++++++++++++++------- 1 file changed, 73 insertions(+), 29 deletions(-) diff --git a/openVulkanoCpp/Host/Linux/SystemInfo.cpp b/openVulkanoCpp/Host/Linux/SystemInfo.cpp index 708bf4c..41d396f 100644 --- a/openVulkanoCpp/Host/Linux/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Linux/SystemInfo.cpp @@ -73,7 +73,12 @@ namespace OpenVulkano size_t SystemInfo::GetSystemRam() { - return ReadMemInfo("MemTotal"); + static size_t ram; + if (ram == 0) + { + ram = ReadMemInfo("MemTotal"); + } + return ram; } size_t SystemInfo::GetSystemRamAvailable() @@ -98,27 +103,47 @@ 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() { - char* name = getlogin(); - if (!name) return "unknown"; - return name; + static std::string userName; + if (userName.emtpy()) + { + char* name = getlogin(); + if (!name) + { + userName = "unknown"; + } + else + { + userName = name; + } + } + return userName; } std::string SystemInfo::GetHostName() { - char hostname[HOST_NAME_MAX + 1]; - gethostname(hostname, HOST_NAME_MAX + 1); - return hostname; + static std::string hostName; + if (hostName.emtpy()) + { + char hostname[HOST_NAME_MAX + 1]; + gethostname(hostname, HOST_NAME_MAX + 1); + hostName = hostname; + } + return hostName; } std::string SystemInfo::GetDeviceName() @@ -128,30 +153,44 @@ namespace OpenVulkano std::string SystemInfo::GetDeviceVendorName() { - std::ifstream dmiStream("/sys/class/dmi/id/board_vendor"); - if (!dmiStream) + static std::string vendor; + if (vendor.emtpy()) { - 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() { - std::ifstream dmiStream("/sys/class/dmi/id/board_name"); - if (!dmiStream) + static std::string modelName; + if (modelName.emtpy()) { - 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 @@ -275,7 +314,12 @@ namespace OpenVulkano size_t SystemInfo::GetCpuThreadCount() { - return std::thread::hardware_concurrency(); + static size_t threadCount; + if (threadCount == 0) + { + threadCount = std::thread::hardware_concurrency(); + } + return threadCount; } int32_t SystemInfo::GetCpuTemperature() From 68befaace9a1d464d81cf7fde85fc6a80f228b66 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 15:12:37 +0200 Subject: [PATCH 02/23] SysInfo caching for MacOS --- openVulkanoCpp/Host/MacOS/SystemInfo.mm | 67 ++++++++++++++++++++----- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/openVulkanoCpp/Host/MacOS/SystemInfo.mm b/openVulkanoCpp/Host/MacOS/SystemInfo.mm index ad149f1..1d0711f 100644 --- a/openVulkanoCpp/Host/MacOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/MacOS/SystemInfo.mm @@ -24,7 +24,12 @@ namespace OpenVulkano size_t SystemInfo::GetSystemRam() { - return [NSProcessInfo processInfo].physicalMemory; + static size_t ram; + if (ram == 0) + { + ram = [NSProcessInfo processInfo].physicalMemory; + } + return ram; } size_t SystemInfo::GetSystemRamAvailable() @@ -67,12 +72,22 @@ namespace OpenVulkano std::string SystemInfo::GetHostName() { - return [[NSProcessInfo processInfo].hostName UTF8String]; + static std::string hostName; + if (hostName.empty()) + { + hostName = [[NSProcessInfo processInfo].hostName UTF8String]; + } + return hostName; } std::string SystemInfo::GetDeviceName() { - return "Mac"; //TODO + static std::string devName; + if (devName.empty()) + { + devName = "Mac"; //TODO + } + return devName; } std::string SystemInfo::GetDeviceVendorName() @@ -82,9 +97,14 @@ namespace OpenVulkano 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() @@ -94,15 +114,26 @@ namespace OpenVulkano 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() { - std::stringstream name; - name << GetOsName() << ' ' << GetOsVersion().major; - return name.str(); + static std::string hrName; + if (hrName.empty()) + { + std::stringstream name; + name << GetOsName() << ' ' << GetOsVersion().major; + hrName = name.str(); + } + return hrName; } DeviceType SystemInfo::GetDeviceType() @@ -112,12 +143,22 @@ namespace OpenVulkano size_t SystemInfo::GetCpuCoreCount() { - return [NSProcessInfo processInfo].processorCount; + static size_t coreCount; + if (coreCount == 0) + { + coreCount = [NSProcessInfo processInfo].processorCount; + } + return coreCount; } size_t SystemInfo::GetCpuThreadCount() { - return [NSProcessInfo processInfo].activeProcessorCount; + static size_t procCount; + if (procCount == 0) + { + procCount = [NSProcessInfo processInfo].activeProcessorCount; + } + return procCount; } int32_t SystemInfo::GetCpuTemperature() From 95f76e959916b849eb3f5c28839140238490aa98 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 15:12:45 +0200 Subject: [PATCH 03/23] SysInfo caching for Windows --- openVulkanoCpp/Host/Windows/SystemInfo.cpp | 254 ++++++++++++--------- 1 file changed, 149 insertions(+), 105 deletions(-) diff --git a/openVulkanoCpp/Host/Windows/SystemInfo.cpp b/openVulkanoCpp/Host/Windows/SystemInfo.cpp index 4d61fef..7832435 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() @@ -287,37 +361,62 @@ namespace OpenVulkano 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() { - 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() { - 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() { - 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() { - 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() @@ -327,87 +426,27 @@ namespace OpenVulkano 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() { - NTSTATUS(WINAPI *RtlGetVersion)(LPOSVERSIONINFOEXW); - OSVERSIONINFOEXW info; - *(FARPROC*)&RtlGetVersion = GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion"); - info.dwOSVersionInfoSize = sizeof(info); - RtlGetVersion(&info); - if (info.wProductType == VER_NT_WORKSTATION) + static std::string osName; + if (osName.empty()) { - 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); + osName = GetHumanReadableOSName(); } + return osName; } DeviceType SystemInfo::GetDeviceType() @@ -417,23 +456,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; + 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() From 15cc73f5e800d444b052ec8b9e8ad604ffd8f4c5 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 15:12:53 +0200 Subject: [PATCH 04/23] SysInfo caching for iOS --- openVulkanoCpp/Host/iOS/SystemInfo.mm | 87 +++++++++++++++++++++------ 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/openVulkanoCpp/Host/iOS/SystemInfo.mm b/openVulkanoCpp/Host/iOS/SystemInfo.mm index 6034484..e3ee351 100644 --- a/openVulkanoCpp/Host/iOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/iOS/SystemInfo.mm @@ -27,7 +27,12 @@ namespace OpenVulkano size_t SystemInfo::GetSystemRam() { - return [NSProcessInfo processInfo].physicalMemory; + static size_t ram; + if (ram == 0) + { + ram = [NSProcessInfo processInfo].physicalMemory; + } + return ram; } size_t SystemInfo::GetSystemRamAvailable() @@ -70,12 +75,22 @@ namespace OpenVulkano std::string SystemInfo::GetHostName() { - return [[NSProcessInfo processInfo].hostName UTF8String]; + static std::string hostName; + if (hostName.empty()) + { + hostName = [[NSProcessInfo processInfo].hostName UTF8String]; + } + return hostName; } std::string SystemInfo::GetDeviceName() { - return [[[UIDevice currentDevice] name] UTF8String]; + static std::string devName; + if (devName.empty()) + { + devName = [[[UIDevice currentDevice] name] UTF8String]; + } + return devName; } std::string SystemInfo::GetDeviceVendorName() @@ -98,43 +113,79 @@ namespace OpenVulkano std::string SystemInfo::GetOsName() { - return [[[UIDevice currentDevice] systemName] UTF8String]; + static std::string osName; + if (osName.empty()) + { + 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() { - 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 size_t coreCount; + if (coreCount == 0) + { + coreCount = [NSProcessInfo processInfo].processorCount; + } + return coreCount; } size_t SystemInfo::GetCpuThreadCount() { - return [NSProcessInfo processInfo].activeProcessorCount; + static size_t threadCount; + if (threadCount == 0) + { + threadCount = [NSProcessInfo processInfo].activeProcessorCount; + } + return threadCount; } int32_t SystemInfo::GetCpuTemperature() From 90440b3f34eb6402cc29ad3987afce36573ede19 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 15:31:20 +0200 Subject: [PATCH 05/23] Fixed a bunch of typos in linux's sysinfo --- openVulkanoCpp/Host/Linux/SystemInfo.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openVulkanoCpp/Host/Linux/SystemInfo.cpp b/openVulkanoCpp/Host/Linux/SystemInfo.cpp index 41d396f..64ad209 100644 --- a/openVulkanoCpp/Host/Linux/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Linux/SystemInfo.cpp @@ -119,7 +119,7 @@ namespace OpenVulkano std::string SystemInfo::GetUserName() { static std::string userName; - if (userName.emtpy()) + if (userName.empty()) { char* name = getlogin(); if (!name) @@ -137,7 +137,7 @@ namespace OpenVulkano std::string SystemInfo::GetHostName() { static std::string hostName; - if (hostName.emtpy()) + if (hostName.empty()) { char hostname[HOST_NAME_MAX + 1]; gethostname(hostname, HOST_NAME_MAX + 1); @@ -154,7 +154,7 @@ namespace OpenVulkano std::string SystemInfo::GetDeviceVendorName() { static std::string vendor; - if (vendor.emtpy()) + if (vendor.empty()) { std::ifstream dmiStream("/sys/class/dmi/id/board_vendor"); if (!dmiStream) @@ -175,7 +175,7 @@ namespace OpenVulkano std::string SystemInfo::GetDeviceModelName() { static std::string modelName; - if (modelName.emtpy()) + if (modelName.empty()) { std::ifstream dmiStream("/sys/class/dmi/id/board_name"); if (!dmiStream) From 947faebe9c2b2c3e8256e6aafded5d7ec4ef1e4d Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 16:10:10 +0200 Subject: [PATCH 06/23] Removed redundant if statements where possible --- openVulkanoCpp/Host/Linux/SystemInfo.cpp | 12 ++----- openVulkanoCpp/Host/MacOS/SystemInfo.mm | 41 +++++----------------- openVulkanoCpp/Host/Windows/SystemInfo.cpp | 10 ++---- openVulkanoCpp/Host/iOS/SystemInfo.mm | 38 ++++---------------- 4 files changed, 20 insertions(+), 81 deletions(-) diff --git a/openVulkanoCpp/Host/Linux/SystemInfo.cpp b/openVulkanoCpp/Host/Linux/SystemInfo.cpp index 64ad209..a47e77e 100644 --- a/openVulkanoCpp/Host/Linux/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Linux/SystemInfo.cpp @@ -73,11 +73,7 @@ namespace OpenVulkano size_t SystemInfo::GetSystemRam() { - static size_t ram; - if (ram == 0) - { - ram = ReadMemInfo("MemTotal"); - } + static const size_t ram = ReadMemInfo("MemTotal"); return ram; } @@ -314,11 +310,7 @@ namespace OpenVulkano size_t SystemInfo::GetCpuThreadCount() { - static size_t threadCount; - if (threadCount == 0) - { - threadCount = std::thread::hardware_concurrency(); - } + static const size_t threadCount = std::thread::hardware_concurrency(); return threadCount; } diff --git a/openVulkanoCpp/Host/MacOS/SystemInfo.mm b/openVulkanoCpp/Host/MacOS/SystemInfo.mm index 1d0711f..b5d4d41 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,11 +25,7 @@ namespace OpenVulkano size_t SystemInfo::GetSystemRam() { - static size_t ram; - if (ram == 0) - { - ram = [NSProcessInfo processInfo].physicalMemory; - } + static const size_t ram = [NSProcessInfo processInfo].physicalMemory; return ram; } @@ -72,21 +69,13 @@ namespace OpenVulkano std::string SystemInfo::GetHostName() { - static std::string hostName; - if (hostName.empty()) - { - hostName = [[NSProcessInfo processInfo].hostName UTF8String]; - } + static const std::string hostName = [[NSProcessInfo processInfo].hostName UTF8String]; return hostName; } std::string SystemInfo::GetDeviceName() { - static std::string devName; - if (devName.empty()) - { - devName = "Mac"; //TODO - } + static const std::string devName = "Mac"; //TODO return devName; } @@ -114,7 +103,7 @@ namespace OpenVulkano OsVersion SystemInfo::GetOsVersion() { - static OsVersion osVersion; + static OsVersion osVersion = {}; if (osVersion.major == 0 && osVersion.minor == 0) { NSOperatingSystemVersion sysVersion = [NSProcessInfo processInfo].operatingSystemVersion; @@ -126,13 +115,7 @@ namespace OpenVulkano std::string SystemInfo::GetOsNameHumanReadable() { - static std::string hrName; - if (hrName.empty()) - { - std::stringstream name; - name << GetOsName() << ' ' << GetOsVersion().major; - hrName = name.str(); - } + static const std::string hrName = fmt::format("{} {}", GetOsName(), GetOsVersion().major); return hrName; } @@ -143,21 +126,13 @@ namespace OpenVulkano size_t SystemInfo::GetCpuCoreCount() { - static size_t coreCount; - if (coreCount == 0) - { - coreCount = [NSProcessInfo processInfo].processorCount; - } + static const size_t coreCount = [NSProcessInfo processInfo].processorCount; return coreCount; } size_t SystemInfo::GetCpuThreadCount() { - static size_t procCount; - if (procCount == 0) - { - procCount = [NSProcessInfo processInfo].activeProcessorCount; - } + static size_t procCount = [NSProcessInfo processInfo].activeProcessorCount; return procCount; } diff --git a/openVulkanoCpp/Host/Windows/SystemInfo.cpp b/openVulkanoCpp/Host/Windows/SystemInfo.cpp index 7832435..2f4eecc 100644 --- a/openVulkanoCpp/Host/Windows/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Windows/SystemInfo.cpp @@ -426,7 +426,7 @@ namespace OpenVulkano OsVersion SystemInfo::GetOsVersion() { - static OsVersion osVersion; + static OsVersion osVersion = {}; if (osVersion.major == 0 && osVersion.minor == 0) { NTSTATUS(WINAPI * RtlGetVersion)(LPOSVERSIONINFOEXW); @@ -441,11 +441,7 @@ namespace OpenVulkano std::string SystemInfo::GetOsNameHumanReadable() { - static std::string osName; - if (osName.empty()) - { - osName = GetHumanReadableOSName(); - } + static const std::string osName = GetHumanReadableOSName(); return osName; } @@ -456,7 +452,7 @@ namespace OpenVulkano size_t SystemInfo::GetCpuCoreCount() { - static size_t coreCount; + static size_t coreCount = 0; if (coreCount == 0) { DWORD bufferSize = 0; diff --git a/openVulkanoCpp/Host/iOS/SystemInfo.mm b/openVulkanoCpp/Host/iOS/SystemInfo.mm index e3ee351..af0c922 100644 --- a/openVulkanoCpp/Host/iOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/iOS/SystemInfo.mm @@ -27,11 +27,7 @@ namespace OpenVulkano size_t SystemInfo::GetSystemRam() { - static size_t ram; - if (ram == 0) - { - ram = [NSProcessInfo processInfo].physicalMemory; - } + static const size_t ram = [NSProcessInfo processInfo].physicalMemory; return ram; } @@ -75,21 +71,13 @@ namespace OpenVulkano std::string SystemInfo::GetHostName() { - static std::string hostName; - if (hostName.empty()) - { - hostName = [[NSProcessInfo processInfo].hostName UTF8String]; - } + static const std::string hostName = [[NSProcessInfo processInfo].hostName UTF8String]; return hostName; } std::string SystemInfo::GetDeviceName() { - static std::string devName; - if (devName.empty()) - { - devName = [[[UIDevice currentDevice] name] UTF8String]; - } + static const std::string devName = [[[UIDevice currentDevice] name] UTF8String]; return devName; } @@ -113,17 +101,13 @@ namespace OpenVulkano std::string SystemInfo::GetOsName() { - static std::string osName; - if (osName.empty()) - { - osName = [[[UIDevice currentDevice] systemName] UTF8String]; - } + static const std::string osName = [[[UIDevice currentDevice] systemName] UTF8String]; return osName; } OsVersion SystemInfo::GetOsVersion() { - static OsVersion osv; + static OsVersion osv = {}; if (osv.major == 0 && osv.minor == 0) { NSOperatingSystemVersion osVersion = [NSProcessInfo processInfo].operatingSystemVersion; @@ -170,21 +154,13 @@ namespace OpenVulkano size_t SystemInfo::GetCpuCoreCount() { - static size_t coreCount; - if (coreCount == 0) - { - coreCount = [NSProcessInfo processInfo].processorCount; - } + static const size_t coreCount = [NSProcessInfo processInfo].processorCount; return coreCount; } size_t SystemInfo::GetCpuThreadCount() { - static size_t threadCount; - if (threadCount == 0) - { - threadCount = [NSProcessInfo processInfo].activeProcessorCount; - } + static const size_t threadCount = [NSProcessInfo processInfo].activeProcessorCount; return threadCount; } From fd316bc594750e538afc9a980f850e442afe229a Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 16:46:13 +0200 Subject: [PATCH 07/23] Changed Get*Name to return const std::string& --- openVulkanoCpp/Host/SystemInfo.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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(); From 718fadca15bf3155e487c842616745ec2695a2d6 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 16:46:39 +0200 Subject: [PATCH 08/23] SystemInfo changes for Linux --- openVulkanoCpp/Host/Linux/SystemInfo.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openVulkanoCpp/Host/Linux/SystemInfo.cpp b/openVulkanoCpp/Host/Linux/SystemInfo.cpp index a47e77e..19fe0cf 100644 --- a/openVulkanoCpp/Host/Linux/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Linux/SystemInfo.cpp @@ -112,7 +112,7 @@ namespace OpenVulkano return vramMax; } - std::string SystemInfo::GetUserName() + const std::string& SystemInfo::GetUserName() { static std::string userName; if (userName.empty()) @@ -130,7 +130,7 @@ namespace OpenVulkano return userName; } - std::string SystemInfo::GetHostName() + const std::string& SystemInfo::GetHostName() { static std::string hostName; if (hostName.empty()) @@ -142,12 +142,12 @@ namespace OpenVulkano return hostName; } - std::string SystemInfo::GetDeviceName() + const std::string& SystemInfo::GetDeviceName() { return GetHostName(); } - std::string SystemInfo::GetDeviceVendorName() + const std::string& SystemInfo::GetDeviceVendorName() { static std::string vendor; if (vendor.empty()) @@ -168,7 +168,7 @@ namespace OpenVulkano return vendor; } - std::string SystemInfo::GetDeviceModelName() + const std::string& SystemInfo::GetDeviceModelName() { static std::string modelName; if (modelName.empty()) @@ -283,7 +283,7 @@ namespace OpenVulkano OsInfo osInfo; } - std::string SystemInfo::GetOsName() + const std::string& SystemInfo::GetOsName() { return osInfo.osName; } @@ -293,7 +293,7 @@ namespace OpenVulkano return osInfo.version; } - std::string SystemInfo::GetOsNameHumanReadable() + const std::string& SystemInfo::GetOsNameHumanReadable() { return osInfo.osNameFormatted; } From dadc025ebea6b050752023344e91efe8cbce8863 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 16:46:50 +0200 Subject: [PATCH 09/23] SystemInfo changes for MacOS --- openVulkanoCpp/Host/MacOS/SystemInfo.mm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openVulkanoCpp/Host/MacOS/SystemInfo.mm b/openVulkanoCpp/Host/MacOS/SystemInfo.mm index b5d4d41..a5bf82f 100644 --- a/openVulkanoCpp/Host/MacOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/MacOS/SystemInfo.mm @@ -62,29 +62,29 @@ namespace OpenVulkano return 0; } - std::string SystemInfo::GetUserName() + const std::string& SystemInfo::GetUserName() { return ""; } - std::string SystemInfo::GetHostName() + const std::string& SystemInfo::GetHostName() { static const std::string hostName = [[NSProcessInfo processInfo].hostName UTF8String]; return hostName; } - std::string SystemInfo::GetDeviceName() + const std::string& SystemInfo::GetDeviceName() { static const std::string devName = "Mac"; //TODO return devName; } - std::string SystemInfo::GetDeviceVendorName() + const std::string& SystemInfo::GetDeviceVendorName() { return "Apple"; } - std::string SystemInfo::GetDeviceModelName() + const std::string& SystemInfo::GetDeviceModelName() { static std::string machine; if (machine.empty()) @@ -96,7 +96,7 @@ namespace OpenVulkano return machine; } - std::string SystemInfo::GetOsName() + const std::string& SystemInfo::GetOsName() { return "MacOS"; } @@ -113,7 +113,7 @@ namespace OpenVulkano return osVersion; } - std::string SystemInfo::GetOsNameHumanReadable() + const std::string& SystemInfo::GetOsNameHumanReadable() { static const std::string hrName = fmt::format("{} {}", GetOsName(), GetOsVersion().major); return hrName; From 305b841c552c7ee0a0b27f8ed80f1cb3c0752774 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 16:47:00 +0200 Subject: [PATCH 10/23] SystemInfo changes for Windows --- openVulkanoCpp/Host/Windows/SystemInfo.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openVulkanoCpp/Host/Windows/SystemInfo.cpp b/openVulkanoCpp/Host/Windows/SystemInfo.cpp index 2f4eecc..72e17ee 100644 --- a/openVulkanoCpp/Host/Windows/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Windows/SystemInfo.cpp @@ -359,7 +359,7 @@ namespace OpenVulkano return ReadAppMemInfo(APP_MEM_TYPE::VM_MAX); } - std::string SystemInfo::GetUserName() + const std::string& SystemInfo::GetUserName() { static std::string userName; if (userName.empty()) @@ -372,7 +372,7 @@ namespace OpenVulkano return userName; } - std::string SystemInfo::GetHostName() + const std::string& SystemInfo::GetHostName() { static std::string hostName; if (hostName.empty()) @@ -384,7 +384,7 @@ namespace OpenVulkano return hostName; } - std::string SystemInfo::GetDeviceName() + const std::string& SystemInfo::GetDeviceName() { static std::string devName; if (devName.empty()) @@ -397,7 +397,7 @@ namespace OpenVulkano return devName; } - std::string SystemInfo::GetDeviceVendorName() + const std::string& SystemInfo::GetDeviceVendorName() { static std::string vendorName; if (vendorName.empty()) @@ -408,7 +408,7 @@ namespace OpenVulkano return vendorName; } - std::string SystemInfo::GetDeviceModelName() + const std::string& SystemInfo::GetDeviceModelName() { static std::string deviceModelName; if (deviceModelName.empty()) @@ -419,7 +419,7 @@ namespace OpenVulkano return deviceModelName; } - std::string SystemInfo::GetOsName() + const std::string& SystemInfo::GetOsName() { return "Windows"; } @@ -439,7 +439,7 @@ namespace OpenVulkano return osVersion; } - std::string SystemInfo::GetOsNameHumanReadable() + const std::string& SystemInfo::GetOsNameHumanReadable() { static const std::string osName = GetHumanReadableOSName(); return osName; From 3748c9b150586993952ef04e63ec14ae96f243e2 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 16:47:05 +0200 Subject: [PATCH 11/23] SystemInfo changes for iOS --- openVulkanoCpp/Host/iOS/SystemInfo.mm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openVulkanoCpp/Host/iOS/SystemInfo.mm b/openVulkanoCpp/Host/iOS/SystemInfo.mm index af0c922..54efb7e 100644 --- a/openVulkanoCpp/Host/iOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/iOS/SystemInfo.mm @@ -64,29 +64,29 @@ namespace OpenVulkano return 0; } - std::string SystemInfo::GetUserName() + const std::string& SystemInfo::GetUserName() { return ""; } - std::string SystemInfo::GetHostName() + const std::string& SystemInfo::GetHostName() { static const std::string hostName = [[NSProcessInfo processInfo].hostName UTF8String]; return hostName; } - std::string SystemInfo::GetDeviceName() + const std::string& SystemInfo::GetDeviceName() { static const std::string devName = [[[UIDevice currentDevice] name] UTF8String]; return devName; } - std::string SystemInfo::GetDeviceVendorName() + const std::string& SystemInfo::GetDeviceVendorName() { return "Apple"; } - std::string SystemInfo::GetDeviceModelName() + const std::string& SystemInfo::GetDeviceModelName() { static std::string modelName; if (modelName.empty()) @@ -99,7 +99,7 @@ namespace OpenVulkano return modelName; } - std::string SystemInfo::GetOsName() + const std::string& SystemInfo::GetOsName() { static const std::string osName = [[[UIDevice currentDevice] systemName] UTF8String]; return osName; @@ -117,7 +117,7 @@ namespace OpenVulkano return osv; } - std::string SystemInfo::GetOsNameHumanReadable() + const std::string& SystemInfo::GetOsNameHumanReadable() { static std::string hrName; if (hrName.empty()) From b37b8dc6397cac92d870c8ae10669cf29b57f795 Mon Sep 17 00:00:00 2001 From: Vladyslav Baranovskyi Date: Fri, 20 Dec 2024 17:02:32 +0200 Subject: [PATCH 12/23] Introduced static variables in places where the return value is a plain string --- openVulkanoCpp/Host/MacOS/SystemInfo.mm | 9 ++++++--- openVulkanoCpp/Host/Windows/SystemInfo.cpp | 3 ++- openVulkanoCpp/Host/iOS/SystemInfo.mm | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/openVulkanoCpp/Host/MacOS/SystemInfo.mm b/openVulkanoCpp/Host/MacOS/SystemInfo.mm index a5bf82f..ca295f6 100644 --- a/openVulkanoCpp/Host/MacOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/MacOS/SystemInfo.mm @@ -64,7 +64,8 @@ namespace OpenVulkano const std::string& SystemInfo::GetUserName() { - return ""; + static const std::string userName = ""; + return userName; } const std::string& SystemInfo::GetHostName() @@ -81,7 +82,8 @@ namespace OpenVulkano const std::string& SystemInfo::GetDeviceVendorName() { - return "Apple"; + static const std::string vendorName = "Apple"; + return vendorName; } const std::string& SystemInfo::GetDeviceModelName() @@ -98,7 +100,8 @@ namespace OpenVulkano const std::string& SystemInfo::GetOsName() { - return "MacOS"; + static const std::string osName = "MacOS"; + return osName; } OsVersion SystemInfo::GetOsVersion() diff --git a/openVulkanoCpp/Host/Windows/SystemInfo.cpp b/openVulkanoCpp/Host/Windows/SystemInfo.cpp index 72e17ee..a7a9270 100644 --- a/openVulkanoCpp/Host/Windows/SystemInfo.cpp +++ b/openVulkanoCpp/Host/Windows/SystemInfo.cpp @@ -421,7 +421,8 @@ namespace OpenVulkano const std::string& SystemInfo::GetOsName() { - return "Windows"; + static const std::string osName = "Windows"; + return osName; } OsVersion SystemInfo::GetOsVersion() diff --git a/openVulkanoCpp/Host/iOS/SystemInfo.mm b/openVulkanoCpp/Host/iOS/SystemInfo.mm index 54efb7e..3182ba2 100644 --- a/openVulkanoCpp/Host/iOS/SystemInfo.mm +++ b/openVulkanoCpp/Host/iOS/SystemInfo.mm @@ -66,7 +66,8 @@ namespace OpenVulkano const std::string& SystemInfo::GetUserName() { - return ""; + static const std::string userName = ""; + return userName; } const std::string& SystemInfo::GetHostName() @@ -83,7 +84,8 @@ namespace OpenVulkano const std::string& SystemInfo::GetDeviceVendorName() { - return "Apple"; + static const std::string vendorName = "Apple"; + return vendorName; } const std::string& SystemInfo::GetDeviceModelName() From 56c3b81fe4712d55f1cfd75755431a4ff0eabf3d Mon Sep 17 00:00:00 2001 From: ohyzha Date: Fri, 20 Dec 2024 12:15:04 +0200 Subject: [PATCH 13/23] fix ODR violation --- openVulkanoCpp/Host/ResourceLoader.hpp | 2 ++ 1 file changed, 2 insertions(+) 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 From c24ef363924692d1e368d48fbcf299d39aef73dc Mon Sep 17 00:00:00 2001 From: ohyzha Date: Fri, 20 Dec 2024 12:18:38 +0200 Subject: [PATCH 14/23] add zip resource and new test --- .../Windows/EmbeddedResourceLoaderWindows.cpp | 2 +- resources/arch.zip | Bin 0 -> 23840 bytes resources/icon.rc | 1 + resources/resource.h | 1 + tests/Host/Windows/ResourceLoaderTests.cpp | 7 +++++++ 5 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 resources/arch.zip 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/resources/arch.zip b/resources/arch.zip new file mode 100644 index 0000000000000000000000000000000000000000..c693a63f7e05e3cb59c2dd8ba74f30b851c9143e GIT binary patch literal 23840 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 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()); +} From deebb0ef96bf7f0c4cbf730cf1db1d7033382692 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 20 Dec 2024 12:35:56 +0200 Subject: [PATCH 15/23] add build tasks for vs code --- .vscode/tasks.json | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .vscode/tasks.json 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 From 40d2a3ff8e2e42dc2d7f622b3c0d8c9508d977a6 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Fri, 20 Dec 2024 17:43:18 +0200 Subject: [PATCH 16/23] add possibility to explicitly specify archive type for ArchiveReader --- openVulkanoCpp/IO/Archive/ArchiveReader.cpp | 44 ++++++++++++++++----- openVulkanoCpp/IO/Archive/ArchiveReader.hpp | 11 +++--- openVulkanoCpp/IO/Archive/ArchiveType.hpp | 2 +- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/openVulkanoCpp/IO/Archive/ArchiveReader.cpp b/openVulkanoCpp/IO/Archive/ArchiveReader.cpp index b8efd2e..47f9e82 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, ArchiveType::Type 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, ArchiveType::Type 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, ArchiveType::Type 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, ArchiveType::Type archiveType) + : ArchiveReader(logger, archiveType) { OpenMemory(archiveBuffer, size); } @@ -51,7 +51,33 @@ namespace OpenVulkano m_archive = archive_read_new(); } ChkErr(archive_read_support_filter_all(m_archive)); - ChkErr(archive_read_support_format_all(m_archive)); + std::function pFunc; + switch (m_archiveType) + { + case ArchiveType::ZIP: + pFunc = archive_read_support_format_zip; + break; + case ArchiveType::SEVEN_ZIP: + pFunc = archive_read_support_format_7zip; + break; + case ArchiveType::CPIO: + pFunc = archive_read_support_format_cpio; + break; + case ArchiveType::ISO: + pFunc = archive_read_support_format_iso9660; + case ArchiveType::TAR: + pFunc = archive_read_support_format_tar; + break; + case ArchiveType::WARC: + pFunc = archive_read_support_format_warc; + break; + case ArchiveType::XAR: + pFunc = archive_read_support_format_xar; + break; + default: + pFunc = archive_read_support_format_all; + } + ChkErr(pFunc(m_archive)); m_open = true; } diff --git a/openVulkanoCpp/IO/Archive/ArchiveReader.hpp b/openVulkanoCpp/IO/Archive/ArchiveReader.hpp index 776a57c..7b78048 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; - + ArchiveType::Type m_archiveType; std::queue m_archivesToRead; public: - explicit ArchiveReader(const std::shared_ptr& logger = nullptr); + explicit ArchiveReader(const std::shared_ptr& logger = nullptr, ArchiveType::Type archiveType = ArchiveType::ANY); - explicit ArchiveReader(const char* archiveFile, const std::shared_ptr& logger = nullptr); + explicit ArchiveReader(const char* archiveFile, const std::shared_ptr& logger = nullptr, ArchiveType::Type archiveType = ArchiveType::ANY); - explicit ArchiveReader(const std::string& archiveFile, const std::shared_ptr& logger = nullptr); + explicit ArchiveReader(const std::string& archiveFile, const std::shared_ptr& logger = nullptr, ArchiveType::Type archiveType = ArchiveType::ANY); - 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, ArchiveType::Type archiveType = ArchiveType::ANY); ~ArchiveReader() override; diff --git a/openVulkanoCpp/IO/Archive/ArchiveType.hpp b/openVulkanoCpp/IO/Archive/ArchiveType.hpp index 739ba1f..91bdc03 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveType.hpp +++ b/openVulkanoCpp/IO/Archive/ArchiveType.hpp @@ -17,7 +17,7 @@ namespace OpenVulkano static inline constexpr std::string_view TYPE_NAMES[] = { ".tar", ".cpio", ".iso", ".zip", ".xar", ".7z", ".warc", ".shar" }; public: - enum Type { TAR = 0, CPIO, ISO, ZIP, XAR, SEVEN_ZIP, WARC, SHAR }; + enum Type { TAR = 0, CPIO, ISO, ZIP, XAR, SEVEN_ZIP, WARC, SHAR, ANY }; constexpr ArchiveType(Type type) : m_type(type) {} From f66ae662340c72d96bf161caacfd997cc4492cdf Mon Sep 17 00:00:00 2001 From: ohyzha Date: Fri, 20 Dec 2024 17:44:02 +0200 Subject: [PATCH 17/23] implement appended zip loader for executable --- openVulkanoCpp/Host/ExeAppendedZipLoader.cpp | 56 +++++++++++++++++++ openVulkanoCpp/Host/ExeAppendedZipLoader.hpp | 24 ++++++++ .../Host/Linux/ExeAppendedZipLoaderLinux.cpp | 30 ++++++++++ .../Host/Linux/ExeAppendedZipLoaderLinux.hpp | 18 ++++++ .../Windows/ExeAppendedZipLoaderWindows.cpp | 24 ++++++++ .../Windows/ExeAppendedZipLoaderWindows.hpp | 18 ++++++ tests/CMakeLists.txt | 11 ++++ tests/Host/ExeAppendedZipLoaderTests.cpp | 52 +++++++++++++++++ 8 files changed, 233 insertions(+) create mode 100644 openVulkanoCpp/Host/ExeAppendedZipLoader.cpp create mode 100644 openVulkanoCpp/Host/ExeAppendedZipLoader.hpp create mode 100644 openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.cpp create mode 100644 openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.hpp create mode 100644 openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.cpp create mode 100644 openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.hpp create mode 100644 tests/Host/ExeAppendedZipLoaderTests.cpp diff --git a/openVulkanoCpp/Host/ExeAppendedZipLoader.cpp b/openVulkanoCpp/Host/ExeAppendedZipLoader.cpp new file mode 100644 index 0000000..1ab4c03 --- /dev/null +++ b/openVulkanoCpp/Host/ExeAppendedZipLoader.cpp @@ -0,0 +1,56 @@ +/* + * 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 "ExeAppendedZipLoader.hpp" +#include "Base/Logger.hpp" +#include "IO/Archive/ArchiveReader.hpp" +#include +#include + +namespace OpenVulkano +{ + std::string ExeAppendedZipLoader::GetResourcePath(const std::string& resourceName) + { + return GetCurrentExecutablePath(); + } + + Array ExeAppendedZipLoader::GetResource(const std::string& exeName) + { + std::string ext = std::filesystem::path(exeName).extension().string(); + if (ext != ".exe" && ext != "") + { + Logger::DATA->debug("Given file {} is not a valid executable", exeName); + return {}; + } + + std::ifstream ifs(exeName, std::ios::in | std::ios::binary); + if (!ifs.is_open()) + { + Logger::DATA->debug("Could not open file {}.", exeName); + return {}; + } + ifs.seekg(0, std::ios_base::end); + size_t zipSize = ifs.tellg(); + ifs.seekg(0, std::ios_base::beg); + Array zipData(zipSize); + ifs.read(zipData.Data(), zipSize); + ifs.close(); + return zipData; + } + + std::vector>> ExeAppendedZipLoader::GetZipArchiveFiles(const std::string& exePath) + { + Array zipData = GetResource(exePath); + ArchiveReader reader(zipData.Data(), zipData.Size(), nullptr, ArchiveType::ZIP); + std::vector>> filesFromZip; + while (reader.HasNext()) + { + filesFromZip.push_back(*reader.GetNextFile()); + } + return filesFromZip; + } + +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/ExeAppendedZipLoader.hpp b/openVulkanoCpp/Host/ExeAppendedZipLoader.hpp new file mode 100644 index 0000000..9adede4 --- /dev/null +++ b/openVulkanoCpp/Host/ExeAppendedZipLoader.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 ExeAppendedZipLoader : public ResourceLoader + { + public: + std::string GetResourcePath(const std::string& resourceName) override; + Array GetResource(const std::string& exePath) override; + std::vector>> GetZipArchiveFiles(const std::string& exePath); + virtual std::string GetCurrentExecutablePath() const = 0; + }; +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.cpp b/openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.cpp new file mode 100644 index 0000000..90332b9 --- /dev/null +++ b/openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.cpp @@ -0,0 +1,30 @@ +/* + * 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 "ExeAppendedZipLoaderLinux.hpp" +#include +#include + +namespace OpenVulkano +{ + namespace + { + void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique()); + } + + std::string OpenVulkano::ExeAppendedZipLoaderLinux::GetCurrentExecutablePath() const + { + char dest[PATH_MAX]; + memset(dest, 0, sizeof(dest)); // readlink does not null terminate! + size_t sz = 0; + if ((sz = readlink("/proc/self/exe", dest, PATH_MAX)) != -1) + { + return std::string(dest, sz); + } + return ""; + } + +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.hpp b/openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.hpp new file mode 100644 index 0000000..c1ce15e --- /dev/null +++ b/openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.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/ExeAppendedZipLoader.hpp" + +namespace OpenVulkano +{ + class ExeAppendedZipLoaderLinux final : public ExeAppendedZipLoader + { + public: + std::string GetCurrentExecutablePath() const override; + }; +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.cpp b/openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.cpp new file mode 100644 index 0000000..30e1238 --- /dev/null +++ b/openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.cpp @@ -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/. + */ + +#include "ExeAppendedZipLoaderWindows.hpp" +#include + +namespace OpenVulkano +{ + namespace + { + void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique()); + } + + std::string OpenVulkano::ExeAppendedZipLoaderWindows::GetCurrentExecutablePath() const + { + CHAR nameBuf[MAX_PATH] = {}; + DWORD len = GetModuleFileNameA(NULL, nameBuf, MAX_PATH); + return std::string(nameBuf, len); + } + +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.hpp b/openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.hpp new file mode 100644 index 0000000..4e89e2e --- /dev/null +++ b/openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.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/ExeAppendedZipLoader.hpp" + +namespace OpenVulkano +{ + class ExeAppendedZipLoaderWindows final : public ExeAppendedZipLoader + { + public: + std::string GetCurrentExecutablePath() const override; + }; +} \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 71523b6..19d78dc 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 "ExeAppendedZipLoader") +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 AND NOT APPLE)) + 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/ExeAppendedZipLoaderTests.cpp b/tests/Host/ExeAppendedZipLoaderTests.cpp new file mode 100644 index 0000000..5923cef --- /dev/null +++ b/tests/Host/ExeAppendedZipLoaderTests.cpp @@ -0,0 +1,52 @@ +/* + * 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/ExeAppendedZipLoaderWindows.hpp" +#else + #include "Host/Linux/ExeAppendedZipLoaderLinux.hpp" +#endif + +#include "Base/Logger.hpp" +#include +#include +#include + +using namespace OpenVulkano; + +TEST_CASE("Load zip from exe") +{ + Logger::SetupLogger("", "tests.log"); +#ifdef _WIN32 + ExeAppendedZipLoaderWindows loader; +#else + ExeAppendedZipLoaderLinux loader; +#endif + Array zipData = loader.GetResource(loader.GetCurrentExecutablePath()); + REQUIRE(!zipData.Empty()); + + auto files = loader.GetZipArchiveFiles(loader.GetCurrentExecutablePath()); + REQUIRE(files.size() == 2); + + int i = 0; + for (const auto& [fileDesc, fileData] : files) + { + if (i == 0) + { + REQUIRE(fileDesc.path == "madvoxel_icon.ico"); + } + else if (i == 1) + { + REQUIRE(fileDesc.path == "text.txt"); + std::string s(fileData.Data(), fileData.Size()); + REQUIRE(s == "Hello world!"); + } + i++; + } + +} From 9d6756bbad20f2f1a616a2b63f42afa7f6a801cb Mon Sep 17 00:00:00 2001 From: ohyzha Date: Sat, 21 Dec 2024 16:14:33 +0200 Subject: [PATCH 18/23] rename files --- ...ndedZipLoader.cpp => ExeAppendedZipResourceLoader.cpp} | 8 ++++---- ...ndedZipLoader.hpp => ExeAppendedZipResourceLoader.hpp} | 2 +- ...derLinux.cpp => ExeAppendedZipResourceLoaderLinux.cpp} | 0 ...derLinux.hpp => ExeAppendedZipResourceLoaderLinux.hpp} | 0 ...indows.cpp => ExeAppendedZipResourceLoaderWindows.cpp} | 6 +++--- ...indows.hpp => ExeAppendedZipResourceLoaderWindows.hpp} | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) rename openVulkanoCpp/Host/{ExeAppendedZipLoader.cpp => ExeAppendedZipResourceLoader.cpp} (82%) rename openVulkanoCpp/Host/{ExeAppendedZipLoader.hpp => ExeAppendedZipResourceLoader.hpp} (91%) rename openVulkanoCpp/Host/Linux/{ExeAppendedZipLoaderLinux.cpp => ExeAppendedZipResourceLoaderLinux.cpp} (100%) rename openVulkanoCpp/Host/Linux/{ExeAppendedZipLoaderLinux.hpp => ExeAppendedZipResourceLoaderLinux.hpp} (100%) rename openVulkanoCpp/Host/Windows/{ExeAppendedZipLoaderWindows.cpp => ExeAppendedZipResourceLoaderWindows.cpp} (70%) rename openVulkanoCpp/Host/Windows/{ExeAppendedZipLoaderWindows.hpp => ExeAppendedZipResourceLoaderWindows.hpp} (70%) diff --git a/openVulkanoCpp/Host/ExeAppendedZipLoader.cpp b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp similarity index 82% rename from openVulkanoCpp/Host/ExeAppendedZipLoader.cpp rename to openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp index 1ab4c03..1fa0bac 100644 --- a/openVulkanoCpp/Host/ExeAppendedZipLoader.cpp +++ b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp @@ -4,7 +4,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -#include "ExeAppendedZipLoader.hpp" +#include "ExeAppendedZipResourceLoader.hpp" #include "Base/Logger.hpp" #include "IO/Archive/ArchiveReader.hpp" #include @@ -12,12 +12,12 @@ namespace OpenVulkano { - std::string ExeAppendedZipLoader::GetResourcePath(const std::string& resourceName) + std::string ExeAppendedZipResourceLoader::GetResourcePath(const std::string& resourceName) { return GetCurrentExecutablePath(); } - Array ExeAppendedZipLoader::GetResource(const std::string& exeName) + Array ExeAppendedZipResourceLoader::GetResource(const std::string& exeName) { std::string ext = std::filesystem::path(exeName).extension().string(); if (ext != ".exe" && ext != "") @@ -41,7 +41,7 @@ namespace OpenVulkano return zipData; } - std::vector>> ExeAppendedZipLoader::GetZipArchiveFiles(const std::string& exePath) + std::vector>> ExeAppendedZipResourceLoader::GetZipArchiveFiles(const std::string& exePath) { Array zipData = GetResource(exePath); ArchiveReader reader(zipData.Data(), zipData.Size(), nullptr, ArchiveType::ZIP); diff --git a/openVulkanoCpp/Host/ExeAppendedZipLoader.hpp b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.hpp similarity index 91% rename from openVulkanoCpp/Host/ExeAppendedZipLoader.hpp rename to openVulkanoCpp/Host/ExeAppendedZipResourceLoader.hpp index 9adede4..c9021d7 100644 --- a/openVulkanoCpp/Host/ExeAppendedZipLoader.hpp +++ b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.hpp @@ -13,7 +13,7 @@ namespace OpenVulkano { - class ExeAppendedZipLoader : public ResourceLoader + class ExeAppendedZipResourceLoader : public ResourceLoader { public: std::string GetResourcePath(const std::string& resourceName) override; diff --git a/openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.cpp b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp similarity index 100% rename from openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.cpp rename to openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp diff --git a/openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.hpp b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp similarity index 100% rename from openVulkanoCpp/Host/Linux/ExeAppendedZipLoaderLinux.hpp rename to openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp diff --git a/openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.cpp b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp similarity index 70% rename from openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.cpp rename to openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp index 30e1238..92dadc6 100644 --- a/openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.cpp +++ b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp @@ -4,17 +4,17 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -#include "ExeAppendedZipLoaderWindows.hpp" +#include "ExeAppendedZipResourceLoaderWindows.hpp" #include namespace OpenVulkano { namespace { - void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique()); + void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique()); } - std::string OpenVulkano::ExeAppendedZipLoaderWindows::GetCurrentExecutablePath() const + std::string OpenVulkano::ExeAppendedZipResourceLoaderWindows::GetCurrentExecutablePath() const { CHAR nameBuf[MAX_PATH] = {}; DWORD len = GetModuleFileNameA(NULL, nameBuf, MAX_PATH); diff --git a/openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.hpp b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.hpp similarity index 70% rename from openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.hpp rename to openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.hpp index 4e89e2e..c1ff2c0 100644 --- a/openVulkanoCpp/Host/Windows/ExeAppendedZipLoaderWindows.hpp +++ b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.hpp @@ -6,11 +6,11 @@ #pragma once -#include "Host/ExeAppendedZipLoader.hpp" +#include "Host/ExeAppendedZipResourceLoader.hpp" namespace OpenVulkano { - class ExeAppendedZipLoaderWindows final : public ExeAppendedZipLoader + class ExeAppendedZipResourceLoaderWindows final : public ExeAppendedZipResourceLoader { public: std::string GetCurrentExecutablePath() const override; From d3750f2b8ab851f1d2f21e56e7c529fb678b3433 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Sat, 21 Dec 2024 17:11:29 +0200 Subject: [PATCH 19/23] code review refactoring --- .../Host/ExeAppendedZipResourceLoader.cpp | 41 ++-------- .../Host/ExeAppendedZipResourceLoader.hpp | 6 +- .../ExeAppendedZipResourceLoaderLinux.cpp | 18 ++--- .../ExeAppendedZipResourceLoaderLinux.hpp | 4 +- .../ExeAppendedZipResourceLoaderWindows.cpp | 7 +- openVulkanoCpp/IO/Archive/ArchiveReader.cpp | 75 +++++++++++-------- openVulkanoCpp/IO/Archive/ArchiveReader.hpp | 14 ++-- openVulkanoCpp/IO/Archive/ArchiveType.hpp | 2 +- tests/CMakeLists.txt | 4 +- tests/Host/ExeAppendedZipLoaderTests.cpp | 34 +++------ 10 files changed, 88 insertions(+), 117 deletions(-) diff --git a/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp index 1fa0bac..a9c311d 100644 --- a/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp +++ b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp @@ -7,50 +7,21 @@ #include "ExeAppendedZipResourceLoader.hpp" #include "Base/Logger.hpp" #include "IO/Archive/ArchiveReader.hpp" +#include "Base/Utils.hpp" #include #include namespace OpenVulkano { - std::string ExeAppendedZipResourceLoader::GetResourcePath(const std::string& resourceName) + Array ExeAppendedZipResourceLoader::GetResource(const std::string& resourceName) { - return GetCurrentExecutablePath(); - } - - Array ExeAppendedZipResourceLoader::GetResource(const std::string& exeName) - { - std::string ext = std::filesystem::path(exeName).extension().string(); - if (ext != ".exe" && ext != "") - { - Logger::DATA->debug("Given file {} is not a valid executable", exeName); - return {}; - } - - std::ifstream ifs(exeName, std::ios::in | std::ios::binary); - if (!ifs.is_open()) - { - Logger::DATA->debug("Could not open file {}.", exeName); - return {}; - } - ifs.seekg(0, std::ios_base::end); - size_t zipSize = ifs.tellg(); - ifs.seekg(0, std::ios_base::beg); - Array zipData(zipSize); - ifs.read(zipData.Data(), zipSize); - ifs.close(); - return zipData; - } - - std::vector>> ExeAppendedZipResourceLoader::GetZipArchiveFiles(const std::string& exePath) - { - Array zipData = GetResource(exePath); + Array zipData = Utils::ReadFile(GetCurrentExecutablePath()); ArchiveReader reader(zipData.Data(), zipData.Size(), nullptr, ArchiveType::ZIP); - std::vector>> filesFromZip; - while (reader.HasNext()) + if (auto data = reader.GetFile(resourceName)) { - filesFromZip.push_back(*reader.GetNextFile()); + return data->second; } - return filesFromZip; + return {}; } } \ No newline at end of file diff --git a/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.hpp b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.hpp index c9021d7..a5a1863 100644 --- a/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.hpp +++ b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.hpp @@ -16,9 +16,9 @@ namespace OpenVulkano class ExeAppendedZipResourceLoader : public ResourceLoader { public: - std::string GetResourcePath(const std::string& resourceName) override; - Array GetResource(const std::string& exePath) override; - std::vector>> GetZipArchiveFiles(const std::string& exePath); + 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 index 90332b9..9f9f52b 100644 --- a/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp +++ b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp @@ -4,7 +4,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -#include "ExeAppendedZipLoaderLinux.hpp" +#include "ExeAppendedZipResourceLoaderLinux.hpp" #include #include @@ -12,19 +12,15 @@ namespace OpenVulkano { namespace { - void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique()); + void* HANDLE = ResourceLoader::RegisterResourceLoader(std::make_unique()); } - std::string OpenVulkano::ExeAppendedZipLoaderLinux::GetCurrentExecutablePath() const + std::string OpenVulkano::ExeAppendedZipResourceLoaderLinux::GetCurrentExecutablePath() const { - char dest[PATH_MAX]; - memset(dest, 0, sizeof(dest)); // readlink does not null terminate! - size_t sz = 0; - if ((sz = readlink("/proc/self/exe", dest, PATH_MAX)) != -1) - { - return std::string(dest, sz); - } - return ""; + 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; } } \ No newline at end of file diff --git a/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp index c1ce15e..73cfe31 100644 --- a/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp +++ b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp @@ -6,11 +6,11 @@ #pragma once -#include "Host/ExeAppendedZipLoader.hpp" +#include "Host/ExeAppendedZipResourceLoader.hpp" namespace OpenVulkano { - class ExeAppendedZipLoaderLinux final : public ExeAppendedZipLoader + class ExeAppendedZipResourceLoaderLinux final : public ExeAppendedZipResourceLoader { public: std::string GetCurrentExecutablePath() const override; diff --git a/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp index 92dadc6..8e50bda 100644 --- a/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp +++ b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp @@ -16,9 +16,10 @@ namespace OpenVulkano std::string OpenVulkano::ExeAppendedZipResourceLoaderWindows::GetCurrentExecutablePath() const { - CHAR nameBuf[MAX_PATH] = {}; - DWORD len = GetModuleFileNameA(NULL, nameBuf, MAX_PATH); - return std::string(nameBuf, len); + std::string exe(MAX_PATH, '\0'); + DWORD len = GetModuleFileNameA(NULL, exe.data(), MAX_PATH); + exe.resize(std::max(len, exe.size())); + return exe; } } \ No newline at end of file diff --git a/openVulkanoCpp/IO/Archive/ArchiveReader.cpp b/openVulkanoCpp/IO/Archive/ArchiveReader.cpp index 47f9e82..0ce6a92 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveReader.cpp +++ b/openVulkanoCpp/IO/Archive/ArchiveReader.cpp @@ -20,21 +20,21 @@ namespace OpenVulkano constexpr int BUFFER_SIZE = 16384; } - ArchiveReader::ArchiveReader(const std::shared_ptr& logger, ArchiveType::Type archiveType) + 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, ArchiveType::Type archiveType) + 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, ArchiveType::Type archiveType) + 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, ArchiveType::Type archiveType) + ArchiveReader::ArchiveReader(const void* archiveBuffer, const size_t size, const std::shared_ptr& logger, std::optional archiveType) : ArchiveReader(logger, archiveType) { OpenMemory(archiveBuffer, size); @@ -51,32 +51,7 @@ namespace OpenVulkano m_archive = archive_read_new(); } ChkErr(archive_read_support_filter_all(m_archive)); - std::function pFunc; - switch (m_archiveType) - { - case ArchiveType::ZIP: - pFunc = archive_read_support_format_zip; - break; - case ArchiveType::SEVEN_ZIP: - pFunc = archive_read_support_format_7zip; - break; - case ArchiveType::CPIO: - pFunc = archive_read_support_format_cpio; - break; - case ArchiveType::ISO: - pFunc = archive_read_support_format_iso9660; - case ArchiveType::TAR: - pFunc = archive_read_support_format_tar; - break; - case ArchiveType::WARC: - pFunc = archive_read_support_format_warc; - break; - case ArchiveType::XAR: - pFunc = archive_read_support_format_xar; - break; - default: - pFunc = archive_read_support_format_all; - } + std::function pFunc = GetCurrentFormatReadFunc(); ChkErr(pFunc(m_archive)); m_open = true; } @@ -182,6 +157,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; @@ -289,6 +291,19 @@ namespace OpenVulkano return std::nullopt; } + std::optional>> ArchiveReader::GetFile(const std::string& path) + { + while (HasNext()) + { + const std::pair> info = *GetNextFile(); + if (info.first.path == path) + { + return info; + } + } + 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 7b78048..b2f0642 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveReader.hpp +++ b/openVulkanoCpp/IO/Archive/ArchiveReader.hpp @@ -21,17 +21,17 @@ namespace OpenVulkano { bool m_open = false; bool m_eof = false; - ArchiveType::Type m_archiveType; + std::optional m_archiveType; std::queue m_archivesToRead; public: - explicit ArchiveReader(const std::shared_ptr& logger = nullptr, ArchiveType::Type archiveType = ArchiveType::ANY); + explicit ArchiveReader(const std::shared_ptr& logger = nullptr, std::optional archiveType = std::nullopt); - explicit ArchiveReader(const char* archiveFile, const std::shared_ptr& logger = nullptr, ArchiveType::Type archiveType = ArchiveType::ANY); + 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, ArchiveType::Type archiveType = ArchiveType::ANY); + 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, ArchiveType::Type archiveType = ArchiveType::ANY); + ArchiveReader(const void* archiveBuffer, size_t size, const std::shared_ptr& logger = nullptr, std::optional archiveType = std::nullopt); ~ArchiveReader() override; @@ -66,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/openVulkanoCpp/IO/Archive/ArchiveType.hpp b/openVulkanoCpp/IO/Archive/ArchiveType.hpp index 91bdc03..739ba1f 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveType.hpp +++ b/openVulkanoCpp/IO/Archive/ArchiveType.hpp @@ -17,7 +17,7 @@ namespace OpenVulkano static inline constexpr std::string_view TYPE_NAMES[] = { ".tar", ".cpio", ".iso", ".zip", ".xar", ".7z", ".warc", ".shar" }; public: - enum Type { TAR = 0, CPIO, ISO, ZIP, XAR, SEVEN_ZIP, WARC, SHAR, ANY }; + enum Type { TAR = 0, CPIO, ISO, ZIP, XAR, SEVEN_ZIP, WARC, SHAR }; constexpr ArchiveType(Type type) : m_type(type) {} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 19d78dc..85c0c4f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,7 +12,7 @@ if (NOT ENABLE_CURL) endif() if (APPLE) - list(FILTER SOURCES EXCLUDE REGEX "ExeAppendedZipLoader") + list(FILTER SOURCES EXCLUDE REGEX "ExeAppendedZipResourceLoader") endif() source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES}) @@ -21,7 +21,7 @@ list(APPEND SOURCES ${RESOURCES}) add_executable(OpenVulkano_Tests ${SOURCES}) # append zip file at the end of executable file -if (WIN32 OR (LINUX AND NOT APPLE)) +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() diff --git a/tests/Host/ExeAppendedZipLoaderTests.cpp b/tests/Host/ExeAppendedZipLoaderTests.cpp index 5923cef..16ff92f 100644 --- a/tests/Host/ExeAppendedZipLoaderTests.cpp +++ b/tests/Host/ExeAppendedZipLoaderTests.cpp @@ -7,9 +7,9 @@ #include #ifdef _WIN32 - #include "Host/Windows/ExeAppendedZipLoaderWindows.hpp" + #include "Host/Windows/ExeAppendedZipResourceLoaderWindows.hpp" #else - #include "Host/Linux/ExeAppendedZipLoaderLinux.hpp" + #include "Host/Linux/ExeAppendedZipResourceLoaderLinux.hpp" #endif #include "Base/Logger.hpp" @@ -23,30 +23,16 @@ TEST_CASE("Load zip from exe") { Logger::SetupLogger("", "tests.log"); #ifdef _WIN32 - ExeAppendedZipLoaderWindows loader; + ExeAppendedZipResourceLoaderWindows loader; #else - ExeAppendedZipLoaderLinux loader; + ExeAppendedZipResourceLoaderLinux loader; #endif - Array zipData = loader.GetResource(loader.GetCurrentExecutablePath()); - REQUIRE(!zipData.Empty()); + auto iconData = loader.GetResource("madvoxel_icon.ico"); + REQUIRE(!iconData.Empty()); - auto files = loader.GetZipArchiveFiles(loader.GetCurrentExecutablePath()); - REQUIRE(files.size() == 2); - - int i = 0; - for (const auto& [fileDesc, fileData] : files) - { - if (i == 0) - { - REQUIRE(fileDesc.path == "madvoxel_icon.ico"); - } - else if (i == 1) - { - REQUIRE(fileDesc.path == "text.txt"); - std::string s(fileData.Data(), fileData.Size()); - REQUIRE(s == "Hello world!"); - } - i++; - } + auto txtFile = loader.GetResource("text.txt"); + REQUIRE(!txtFile.Empty()); + std::string s(txtFile.Data(), txtFile.Size()); + REQUIRE(s == "Hello world!"); } From 82403b9aae0fe263258759f221f58a6020544f72 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Fri, 20 Dec 2024 19:26:27 +0200 Subject: [PATCH 20/23] fix linux build --- tests/Host/ExeAppendedZipLoaderTests.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Host/ExeAppendedZipLoaderTests.cpp b/tests/Host/ExeAppendedZipLoaderTests.cpp index 16ff92f..caf9e63 100644 --- a/tests/Host/ExeAppendedZipLoaderTests.cpp +++ b/tests/Host/ExeAppendedZipLoaderTests.cpp @@ -13,7 +13,6 @@ #endif #include "Base/Logger.hpp" -#include #include #include From d2811bc9b1c4c81b1c6d52ed994afb19baf4cb48 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Sat, 21 Dec 2024 17:43:17 +0200 Subject: [PATCH 21/23] fix linux build again --- .../Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp index 9f9f52b..e624bfb 100644 --- a/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp +++ b/openVulkanoCpp/Host/Linux/ExeAppendedZipResourceLoaderLinux.cpp @@ -18,9 +18,9 @@ namespace OpenVulkano std::string OpenVulkano::ExeAppendedZipResourceLoaderLinux::GetCurrentExecutablePath() const { std::string path(PATH_MAX, '\0'); - ssize_t sz = readlink("/proc/self/exe", path.data(), path.capacity())); + ssize_t sz = readlink("/proc/self/exe", path.data(), path.capacity()); path.resize(std::max(0, sz)); return path; } -} \ No newline at end of file +} From 58b62cff9a18c04dc16d7e8d327a56625a5625b4 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Sat, 21 Dec 2024 17:46:54 +0200 Subject: [PATCH 22/23] rename test file --- ...edZipLoaderTests.cpp => ExeAppendedZipResourceLoaderTests.cpp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/Host/{ExeAppendedZipLoaderTests.cpp => ExeAppendedZipResourceLoaderTests.cpp} (100%) diff --git a/tests/Host/ExeAppendedZipLoaderTests.cpp b/tests/Host/ExeAppendedZipResourceLoaderTests.cpp similarity index 100% rename from tests/Host/ExeAppendedZipLoaderTests.cpp rename to tests/Host/ExeAppendedZipResourceLoaderTests.cpp From 5852aac2730769a545d7c3fe4deb93b138ad0a55 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Sun, 22 Dec 2024 13:54:01 +0200 Subject: [PATCH 23/23] minor refactoring --- openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp | 3 +-- .../Windows/ExeAppendedZipResourceLoaderWindows.cpp | 2 +- openVulkanoCpp/IO/Archive/ArchiveReader.cpp | 12 +++++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp index a9c311d..93a2365 100644 --- a/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp +++ b/openVulkanoCpp/Host/ExeAppendedZipResourceLoader.cpp @@ -15,8 +15,7 @@ namespace OpenVulkano { Array ExeAppendedZipResourceLoader::GetResource(const std::string& resourceName) { - Array zipData = Utils::ReadFile(GetCurrentExecutablePath()); - ArchiveReader reader(zipData.Data(), zipData.Size(), nullptr, ArchiveType::ZIP); + ArchiveReader reader(GetCurrentExecutablePath(), nullptr, ArchiveType::ZIP); if (auto data = reader.GetFile(resourceName)) { return data->second; diff --git a/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp index 8e50bda..8800276 100644 --- a/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp +++ b/openVulkanoCpp/Host/Windows/ExeAppendedZipResourceLoaderWindows.cpp @@ -18,7 +18,7 @@ namespace OpenVulkano { std::string exe(MAX_PATH, '\0'); DWORD len = GetModuleFileNameA(NULL, exe.data(), MAX_PATH); - exe.resize(std::max(len, exe.size())); + exe.resize(len); return exe; } diff --git a/openVulkanoCpp/IO/Archive/ArchiveReader.cpp b/openVulkanoCpp/IO/Archive/ArchiveReader.cpp index 0ce6a92..b392842 100644 --- a/openVulkanoCpp/IO/Archive/ArchiveReader.cpp +++ b/openVulkanoCpp/IO/Archive/ArchiveReader.cpp @@ -51,8 +51,7 @@ namespace OpenVulkano m_archive = archive_read_new(); } ChkErr(archive_read_support_filter_all(m_archive)); - std::function pFunc = GetCurrentFormatReadFunc(); - ChkErr(pFunc(m_archive)); + ChkErr(GetCurrentFormatReadFunc()(m_archive)); m_open = true; } @@ -295,10 +294,13 @@ namespace OpenVulkano { while (HasNext()) { - const std::pair> info = *GetNextFile(); - if (info.first.path == path) + if (path == archive_entry_pathname(m_archiveEntry)) { - return info; + return GetNextFile(); + } + if (archive_read_next_header(m_archive, &m_archiveEntry) != ARCHIVE_OK) + { + return {}; } } return {};