From 09dc26ae7975adbea266784b8ba49f8c002c3ba9 Mon Sep 17 00:00:00 2001 From: Patedam Date: Sat, 1 Mar 2025 21:17:10 -0500 Subject: [PATCH] Adding IOStream + String library (needed to have proper iostream) --- Juliet/Juliet.vcxproj | 8 ++ Juliet/include/Core/Common/CoreTypes.h | 8 -- Juliet/include/Core/Common/String.h | 132 ++++++++++++++++++ .../include/Core/HAL/Filesystem/Filesystem.h | 6 +- Juliet/include/Core/HAL/IO/IOStream.h | 12 ++ Juliet/include/Core/HotReload/HotReload.h | 12 +- Juliet/include/Core/Memory/Utils.h | 15 ++ Juliet/src/Core/Common/String.cpp | 88 ++++++++++++ Juliet/src/Core/HAL/Filesystem/Filesystem.cpp | 13 +- .../Core/HAL/Filesystem/Filesystem_Platform.h | 2 +- .../HAL/Filesystem/Win32/Win32Filesystem.cpp | 25 ++-- Juliet/src/Core/HAL/IO/IOStream.cpp | 24 ++++ Juliet/src/Core/HAL/IO/IOStream_Private.h | 12 ++ .../src/Core/HAL/IO/Win32/Win32IOStream.cpp | 68 +++++++++ Juliet/src/Core/HotReload/HotReload.cpp | 19 ++- .../Core/HotReload/Win32/Win32HotReload.cpp | 24 ++-- Juliet/src/Core/Memory/Allocator.cpp | 1 - Juliet/src/TODO.txt | 7 +- JulietApp/JulietApp.vcxproj | 4 +- JulietApp/main.cpp | 5 +- .../JulietShaderCompiler.vcxproj | 14 +- JulietShaderCompiler/main.cpp | 64 ++++----- 22 files changed, 464 insertions(+), 99 deletions(-) create mode 100644 Juliet/include/Core/Common/String.h create mode 100644 Juliet/include/Core/HAL/IO/IOStream.h create mode 100644 Juliet/src/Core/Common/String.cpp create mode 100644 Juliet/src/Core/HAL/IO/IOStream.cpp create mode 100644 Juliet/src/Core/HAL/IO/IOStream_Private.h create mode 100644 Juliet/src/Core/HAL/IO/Win32/Win32IOStream.cpp diff --git a/Juliet/Juliet.vcxproj b/Juliet/Juliet.vcxproj index e9444ce..70407d8 100644 --- a/Juliet/Juliet.vcxproj +++ b/Juliet/Juliet.vcxproj @@ -114,9 +114,13 @@ + + + + @@ -156,6 +160,7 @@ + @@ -173,6 +178,7 @@ + @@ -185,6 +191,8 @@ + + diff --git a/Juliet/include/Core/Common/CoreTypes.h b/Juliet/include/Core/Common/CoreTypes.h index ddad9b3..85d34de 100644 --- a/Juliet/include/Core/Common/CoreTypes.h +++ b/Juliet/include/Core/Common/CoreTypes.h @@ -24,14 +24,6 @@ struct ByteBuffer size_t Size; }; -template -struct StringBuffer -{ - CharType* Data; - size_t Size; -}; -#define StringBufferParam(str) { (str), sizeof(str) } - using FunctionPtr = auto (*)(void) -> void; // Limits diff --git a/Juliet/include/Core/Common/String.h b/Juliet/include/Core/Common/String.h new file mode 100644 index 0000000..9a8ed22 --- /dev/null +++ b/Juliet/include/Core/Common/String.h @@ -0,0 +1,132 @@ +#pragma once +#include + +namespace Juliet +{ +#define ConstString(str) { const_cast((str)), sizeof(str) - 1 } +#define CStr(str) ((str).Data) +#define InplaceString(name, size) \ + char name##_[size]; \ + String name = { name##_, sizeof(name##_) } + + struct String + { + char* Data; + size_t Size; + }; + + struct String16 + { + char16_t* Data; + size_t Size; + }; + + inline size_t StringLength(String str) + { + return str.Size; + } + + inline size_t StringLength(const char* str) + { + size_t counter = 0; + if (str) + { + while (*str++) + { + ++counter; + } + } + + return counter; + } + + inline bool StringIsValid(String str) + { + return str.Size > 0 && str.Data != nullptr && *str.Data; + } + + inline String WrapString(const char* str) + { + String result = {}; + result.Data = const_cast(str); + result.Size = StringLength(str); + return result; + } + + inline String FindChar(String str, char c) + { + String result = str; + while (result.Size) + { + if (*result.Data != c) + { + ++result.Data; + --result.Size; + } + else + { + return result; + } + } + return {}; + } + + inline bool ContainsChar(String str, char c) + { + return StringIsValid(FindChar(str, c)); + } + + // Return: + // - < 0 if str1 < str2 + // - = 0 : Both strings are equals + // - > 0 if str1 > str2 + inline int32 StringCompare(String str1, String str2) + { + size_t len1 = StringLength(str1); + size_t len2 = StringLength(str2); + size_t minLen = Min(len1, len2); + int32 result = MemCompare(CStr(str1), CStr(str2), minLen); + if (result == 0) + { + if (len1 > len2) + { + return 1; + } + if (len1 < len2) + { + return -1; + } + return 0; + } + return result; + } + + inline int8 StringCompareCaseInsensitive(String str1, String str2) + { + return 0; + } + + // Do not allocate anything, you must allocate your out buffer yourself + // TODO: Version taking arena that can allocate + extern JULIET_API bool ConvertString(String from, String to, String in, String& out); + +} // namespace Juliet + +#ifdef UNIT_TEST +namespace Juliet::UnitTest +{ + inline void TestFindChar() + { + String s1 = ConstString(""); + String s2 = ConstString("abcdefabcdef"); + String s3 = ConstString("11111111111111111111"); + + Assert(FindChar(s1, 'x').Data == nullptr); + Assert(FindChar(s2, 'y').Data == nullptr); + Assert(FindChar(s2, 'a').Data - s2.Data == 0); + Assert(FindChar(s2, 'd').Data - s2.Data == 3); + Assert(FindChar(s2, 'f').Data - s2.Data == 5); + Assert(FindChar(s3, '1').Data - s3.Data == 0); + } +} // namespace Juliet::UnitTest +#endif diff --git a/Juliet/include/Core/HAL/Filesystem/Filesystem.h b/Juliet/include/Core/HAL/Filesystem/Filesystem.h index 0da2d87..4e52792 100644 --- a/Juliet/include/Core/HAL/Filesystem/Filesystem.h +++ b/Juliet/include/Core/HAL/Filesystem/Filesystem.h @@ -1,7 +1,9 @@ #pragma once +#include + namespace Juliet { // Returns the path to the application directory - extern JULIET_API char * GetBasePath(); -} \ No newline at end of file + extern JULIET_API String GetBasePath(); +} // namespace Juliet diff --git a/Juliet/include/Core/HAL/IO/IOStream.h b/Juliet/include/Core/HAL/IO/IOStream.h new file mode 100644 index 0000000..564e413 --- /dev/null +++ b/Juliet/include/Core/HAL/IO/IOStream.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include + +namespace Juliet +{ + // Opaque type + struct IOStream; + + extern JULIET_API IOStream* IOFromFile(String filename, String mode); +} // namespace Juliet diff --git a/Juliet/include/Core/HotReload/HotReload.h b/Juliet/include/Core/HotReload/HotReload.h index b61447c..da236a8 100644 --- a/Juliet/include/Core/HotReload/HotReload.h +++ b/Juliet/include/Core/HotReload/HotReload.h @@ -1,5 +1,7 @@ #pragma once +#include + namespace Juliet { // Fwd Declare @@ -7,9 +9,9 @@ namespace Juliet struct HotReloadCode { - StringBuffer DLLFullPath; - StringBuffer LockFullPath; - StringBuffer TransientDLLName; + String DLLFullPath; + String LockFullPath; + String TransientDLLName; uint64 LastWriteTime; @@ -24,8 +26,8 @@ namespace Juliet bool IsValid : 1; }; - extern JULIET_API void InitHotReloadCode(HotReloadCode& code, StringBuffer dllName, - StringBuffer transientDllName, StringBuffer lockFilename); + extern JULIET_API void InitHotReloadCode(HotReloadCode& code, String dllName, + String transientDllName, String lockFilename); extern JULIET_API void ShutdownHotReloadCode(HotReloadCode& code); extern JULIET_API void LoadCode(HotReloadCode& code); diff --git a/Juliet/include/Core/Memory/Utils.h b/Juliet/include/Core/Memory/Utils.h index af25026..30eb822 100644 --- a/Juliet/include/Core/Memory/Utils.h +++ b/Juliet/include/Core/Memory/Utils.h @@ -1,3 +1,18 @@ #pragma once #define ArraySize(array) (sizeof(array) / sizeof(array[0])) + +namespace Juliet +{ + inline int32 MemCompare(const void* leftValue, const void* rightValue, size_t size) + { + const unsigned char* left = static_cast(leftValue); + const unsigned char* right = static_cast(rightValue); + while (size && *left == *right) + { + ++left; + ++right; + } + return size ? *left - *right : 0; + } +} \ No newline at end of file diff --git a/Juliet/src/Core/Common/String.cpp b/Juliet/src/Core/Common/String.cpp new file mode 100644 index 0000000..2ae7519 --- /dev/null +++ b/Juliet/src/Core/Common/String.cpp @@ -0,0 +1,88 @@ +#include + +#include +#include + +namespace Juliet +{ + namespace + { + enum class Encoding : uint8 + { + Unknown = 0, + ASCII, + LATIN1, + UTF8, + UTF16, + UTF32, + UCS2, + UCS4, + }; + + struct + { + const char* name; + Encoding format; + } Encodings[] = { + /* *INDENT-OFF* */ // clang-format off + { "ASCII", Encoding::ASCII }, + { "US-ASCII", Encoding::ASCII }, + { "8859-1", Encoding::LATIN1 }, + { "ISO-8859-1", Encoding::LATIN1 }, + #if defined(JULIET_WIN32) + { "WCHAR_T", Encoding::UTF16 }, + #else + { "WCHAR_T", Encoding::UCS4 }, + #endif + { "UTF8", Encoding::UTF8 }, + { "UTF-8", Encoding::UTF8 }, + { "UTF16", Encoding::UTF16 }, + { "UTF-16", Encoding::UTF16 }, + { "UTF32", Encoding::UTF32 }, + { "UTF-32", Encoding::UTF32 }, + { "UCS2", Encoding::UCS2 }, + { "UCS-2", Encoding::UCS2 }, + { "UCS-2-INTERNAL", Encoding::UCS2 }, + { "UCS4", Encoding::UCS4 }, + { "UCS-4", Encoding::UCS4 }, + { "UCS-4-INTERNAL", Encoding::UCS4 }, + /* *INDENT-ON* */ // clang-format on + }; + + } // namespace + + bool ConvertString(String from, String to, String in, String& out) + { + Assert(in.Size <= out.Size); + Assert(StringIsValid(from)); + Assert(StringIsValid(to)); + Assert(StringIsValid(in)); + +for (size_t idx = 0; idx < ArraySize(Encodings); ++idx) +{ + +} + // for (i = 0; i < SDL_arraysize(encodings); ++i) { + // if (SDL_strcasecmp(fromcode, encodings[i].name) == 0) { + // src_fmt = encodings[i].format; + // if (dst_fmt != ENCODING_UNKNOWN) { + // break; + // } + // } + // if (SDL_strcasecmp(tocode, encodings[i].name) == 0) { + // dst_fmt = encodings[i].format; + // if (src_fmt != ENCODING_UNKNOWN) { + // break; + // } + // } + // } + // if (src_fmt != ENCODING_UNKNOWN && dst_fmt != ENCODING_UNKNOWN) { + // SDL_iconv_t cd = (SDL_iconv_t)SDL_malloc(sizeof(*cd)); + // if (cd) { + // cd->src_fmt = src_fmt; + // cd->dst_fmt = dst_fmt; + // return cd; + // } + // } + } +} // namespace Juliet diff --git a/Juliet/src/Core/HAL/Filesystem/Filesystem.cpp b/Juliet/src/Core/HAL/Filesystem/Filesystem.cpp index 08b2d67..ce0ea2b 100644 --- a/Juliet/src/Core/HAL/Filesystem/Filesystem.cpp +++ b/Juliet/src/Core/HAL/Filesystem/Filesystem.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -9,11 +10,12 @@ namespace Juliet { namespace { - char* CachedBasePath = nullptr; + String CachedBasePath = {}; } - char* GetBasePath() + + String GetBasePath() { - if (CachedBasePath == nullptr) + if (!StringIsValid(CachedBasePath)) { CachedBasePath = Platform::GetBasePath(); } @@ -24,9 +26,10 @@ namespace Juliet void ShutdownFilesystem() { - if (CachedBasePath != nullptr) + if (StringIsValid(CachedBasePath)) { - SafeFree(CachedBasePath); + CachedBasePath.Size = 0; + SafeFree(CachedBasePath.Data); } } } // namespace Juliet diff --git a/Juliet/src/Core/HAL/Filesystem/Filesystem_Platform.h b/Juliet/src/Core/HAL/Filesystem/Filesystem_Platform.h index 2a2bcf0..c67597a 100644 --- a/Juliet/src/Core/HAL/Filesystem/Filesystem_Platform.h +++ b/Juliet/src/Core/HAL/Filesystem/Filesystem_Platform.h @@ -2,5 +2,5 @@ namespace Juliet::Platform { - extern char* GetBasePath(); + extern String GetBasePath(); } diff --git a/Juliet/src/Core/HAL/Filesystem/Win32/Win32Filesystem.cpp b/Juliet/src/Core/HAL/Filesystem/Win32/Win32Filesystem.cpp index 70c83f3..9ee32df 100644 --- a/Juliet/src/Core/HAL/Filesystem/Win32/Win32Filesystem.cpp +++ b/Juliet/src/Core/HAL/Filesystem/Win32/Win32Filesystem.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -11,10 +12,10 @@ namespace Juliet::Platform // TODO : Move into string file // Use portable code + pass the memory array into parameter and not use new // From: https://stackoverflow.com/questions/215963/how-do-you-properly-use-widechartomultibyte - char* WideCharToUTF8(wchar_t* wcharStr) + char* WideCharToUTF8(char16_t* wcharStr) { - char* result = nullptr; - size_t length = WideCharToMultiByte(CP_UTF8, 0, wcharStr, -1, nullptr, 0, nullptr, nullptr); + char* result = nullptr; + size_t length = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast(wcharStr), -1, nullptr, 0, nullptr, nullptr); if (length <= 0) { return nullptr; @@ -26,7 +27,7 @@ namespace Juliet::Platform return nullptr; } - if (WideCharToMultiByte(CP_UTF8, 0, wcharStr, -1, result, length, nullptr, nullptr) <= 0) + if (WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast(wcharStr), -1, result, length, nullptr, nullptr) <= 0) { delete[] result; return nullptr; @@ -36,27 +37,28 @@ namespace Juliet::Platform } } // namespace - char* GetBasePath() + String GetBasePath() { // Allocate a buffer that could fit the module size. // Max Path is a good start but could be bigger if the path include long path prefix - StringBuffer buffer{ .Data = nullptr, .Size = MAX_PATH }; - buffer.Data = static_cast(Calloc(MAX_PATH, sizeof(WCHAR))); + String16 buffer{ .Data = nullptr, .Size = MAX_PATH }; + buffer.Data = static_cast(Calloc(MAX_PATH, sizeof(WCHAR))); if (buffer.Data == nullptr) { - return nullptr; + return {}; } size_t moduleFilenameLength = 0; while (true) { - moduleFilenameLength = GetModuleFileNameW(nullptr, buffer.Data, static_cast(buffer.Size)); + moduleFilenameLength = + GetModuleFileNameW(nullptr, reinterpret_cast(buffer.Data), static_cast(buffer.Size)); // If the module filename length is bigger than the buffer size, we need to reallocate a bigger buffer if (moduleFilenameLength >= buffer.Size - 1) { buffer.Size *= 2; - buffer.Data = static_cast(Realloc(buffer.Data, buffer.Size * sizeof(WCHAR))); + buffer.Data = static_cast(Realloc(buffer.Data, buffer.Size * sizeof(WCHAR))); } else { @@ -85,6 +87,7 @@ namespace Juliet::Platform // TODO: Add utils to Convert to/from UTF8W char* basePath = WideCharToUTF8(buffer.Data); SafeFree(buffer.Data); - return basePath; + + return WrapString(basePath); } } // namespace Juliet::Platform diff --git a/Juliet/src/Core/HAL/IO/IOStream.cpp b/Juliet/src/Core/HAL/IO/IOStream.cpp new file mode 100644 index 0000000..060835a --- /dev/null +++ b/Juliet/src/Core/HAL/IO/IOStream.cpp @@ -0,0 +1,24 @@ +#include + +#include +#include +#include + +namespace Juliet +{ + IOStream* IOFromFile(String filename, String mode) + { + if (!StringIsValid(filename)) + { + Log(LogLevel::Error, LogCategory::Core, "Trying to open IOStream on invalid filename"); + return nullptr; + } + if (!StringIsValid(mode)) + { + Log(LogLevel::Error, LogCategory::Core, "Trying to open IOStream with invalid mode"); + return nullptr; + } + + return Internal::IOFromFile(filename, mode); + } +} // namespace Juliet diff --git a/Juliet/src/Core/HAL/IO/IOStream_Private.h b/Juliet/src/Core/HAL/IO/IOStream_Private.h new file mode 100644 index 0000000..038411c --- /dev/null +++ b/Juliet/src/Core/HAL/IO/IOStream_Private.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace Juliet +{ + struct IOStream; +} +namespace Juliet::Internal +{ + extern JULIET_API IOStream* IOFromFile(String filename, String mode); +} diff --git a/Juliet/src/Core/HAL/IO/Win32/Win32IOStream.cpp b/Juliet/src/Core/HAL/IO/Win32/Win32IOStream.cpp new file mode 100644 index 0000000..d3c12f0 --- /dev/null +++ b/Juliet/src/Core/HAL/IO/Win32/Win32IOStream.cpp @@ -0,0 +1,68 @@ +#include + +#include +#include +#include + +namespace Juliet::Internal +{ + IOStream* IOFromFile(String filename, String mode) + { + HANDLE hFile; + + // "r" = reading, file must exist + // "w" = writing, truncate existing, file may not exist + // "r+"= reading or writing, file must exist + // "a" = writing, append file may not exist + // "a+"= append + read, file may not exist + // "w+" = read, write, truncate. file may not exist + +#if _DEBUG + // Making sure the mode is valid + String modeView = mode; + size_t modeLength = StringLength(modeView); + Assert(!ContainsChar(mode, 'b') && "Binary mode note supported"); + Assert((modeLength <= 2) && + "Mode should have at most 2 characters, one being either r,w or a and the other can only be +"); + if (modeLength == 1) + { + Assert(modeView.Data[0] == 'r' || modeView.Data[0] == 'w' || + modeView.Data[0] == 'a' && "Invalid Mode. First char is not r,w or a"); + } + else + { + Assert(modeView.Data[1] == '+' && "Invalid Mode. Second char is not +"); + } +#endif + + DWORD openExisting = ContainsChar(mode, 'r') ? OPEN_EXISTING : 0; + DWORD createAlways = ContainsChar(mode, 'w') ? CREATE_ALWAYS : 0; + DWORD openAlways = ContainsChar(mode, 'a') ? OPEN_ALWAYS : 0; + + bool hasPlus = ContainsChar(mode, '+'); + DWORD canRead = openExisting || hasPlus ? GENERIC_READ : 0; + DWORD canWrite = createAlways || openAlways || hasPlus ? GENERIC_WRITE : 0; + + if (!canRead && !canWrite) + { + Log(LogLevel::Error, LogCategory::Core, "IOFromFile: Invalid Mode (cannot read nor write)"); + return nullptr; + } + +// Prevent opening a dialog box when file doesnt exits (windows does that) +// old_error_mode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS); + { + // LPWSTR str = WIN_UTF8ToStringW(filename); + // h = CreateFileW(str, + // (w_right | r_right), + // (w_right) ? 0 : FILE_SHARE_READ, + // NULL, + // (must_exist | truncate | a_mode), + // FILE_ATTRIBUTE_NORMAL, + // NULL); + // SDL_free(str); + } + + return nullptr; + } +} // namespace Juliet::Internal diff --git a/Juliet/src/Core/HotReload/HotReload.cpp b/Juliet/src/Core/HotReload/HotReload.cpp index 0f02b95..1b84e0a 100644 --- a/Juliet/src/Core/HotReload/HotReload.cpp +++ b/Juliet/src/Core/HotReload/HotReload.cpp @@ -9,33 +9,32 @@ namespace Juliet { - void InitHotReloadCode(HotReloadCode& code, StringBuffer dllName, - StringBuffer transientDllName, StringBuffer lockFilename) + void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename) { // Get the app base path and build the dll path from there. - const char* basePath = GetBasePath(); - size_t basePathLength = strlen(basePath); + String basePath = GetBasePath(); + size_t basePathLength = StringLength(basePath); // Assign Transient dll path code.TransientDLLName = transientDllName; // First allocate all the full path. // TODO: Add path composition into filesystem + string format + string builder - const size_t dllFullPathLength = basePathLength + dllName.Size; + const size_t dllFullPathLength = basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings code.DLLFullPath.Data = static_cast(Calloc(dllFullPathLength, sizeof(char))); - int writtenSize = snprintf(code.DLLFullPath.Data, dllFullPathLength, "%s%s", basePath, dllName.Data); + int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName)); if (writtenSize < static_cast(dllFullPathLength) - 1) { SafeFree(code.DLLFullPath.Data); Log(LogLevel::Error, LogCategory::Core, "Cannot create DLL Full Path"); return; } - code.DLLFullPath.Size = writtenSize + 1; + code.DLLFullPath.Size = writtenSize; // Lock filename path - const size_t lockPathLength = basePathLength + lockFilename.Size; + const size_t lockPathLength = basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings code.LockFullPath.Data = static_cast(Calloc(lockPathLength, sizeof(char))); - writtenSize = snprintf(code.LockFullPath.Data, lockPathLength, "%s%s", basePath, lockFilename.Data); + writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename)); if (writtenSize < static_cast(lockPathLength) - 1) { code.LockFullPath.Size = 0; @@ -43,7 +42,7 @@ namespace Juliet Log(LogLevel::Error, LogCategory::Core, "Cannot create lock file full path"); return; } - code.LockFullPath.Size = writtenSize + 1; + code.LockFullPath.Size = writtenSize; LoadCode(code); } diff --git a/Juliet/src/Core/HotReload/Win32/Win32HotReload.cpp b/Juliet/src/Core/HotReload/Win32/Win32HotReload.cpp index 5c24a2d..601cb15 100644 --- a/Juliet/src/Core/HotReload/Win32/Win32HotReload.cpp +++ b/Juliet/src/Core/HotReload/Win32/Win32HotReload.cpp @@ -25,7 +25,7 @@ namespace Juliet constexpr size_t kMaxAttempts = 256; constexpr size_t kMaxDLLID = 256; - constexpr size_t kTempDLLBufferSizeForID = 6; // ID numbers + \0 + constexpr size_t kTempDLLBufferSizeForID = 5; // Max ID numbers } // namespace void LoadCode(HotReloadCode& code) @@ -48,20 +48,21 @@ namespace Juliet // We'll see for better later. // Get the app base path and build the dll path from there. - const char* basePath = GetBasePath(); - size_t basePathLength = strlen(basePath); + String basePath = GetBasePath(); + size_t basePathLength = StringLength(basePath); - const size_t tempDllMaxBufferSize = basePathLength + code.TransientDLLName.Size + kTempDLLBufferSizeForID; - auto tempDllPath = static_cast(Calloc(tempDllMaxBufferSize, sizeof(char))); + const size_t tempDllMaxBufferSize = + basePathLength + StringLength(code.TransientDLLName) + /* _ */ 1 + kTempDLLBufferSizeForID + 1 /* \0 */; + auto tempDllPath = static_cast(Calloc(tempDllMaxBufferSize, sizeof(char))); for (uint32 attempt = 0; attempt < kMaxAttempts; ++attempt) { // int to char - char idToStr[kTempDLLBufferSizeForID]; + char idToStr[kTempDLLBufferSizeForID + 1]; int idLength = snprintf(idToStr, sizeof(idToStr), "%u", code.UniqueID); - int writtenSize = snprintf(tempDllPath, tempDllMaxBufferSize, "%s%u_%s", basePath, code.UniqueID, - code.TransientDLLName.Data); - if (writtenSize < static_cast(basePathLength + idLength + code.TransientDLLName.Size)) + int writtenSize = snprintf(tempDllPath, tempDllMaxBufferSize, "%s%s_%s", CStr(basePath), idToStr, + CStr(code.TransientDLLName)); + if (writtenSize < static_cast(basePathLength + idLength + code.TransientDLLName.Size) - 1) { SafeFree(tempDllPath); Log(LogLevel::Error, LogCategory::Core, "Cannot create temp full path"); @@ -107,7 +108,10 @@ namespace Juliet void UnloadCode(HotReloadCode& code) { code.IsValid = false; - UnloadDynamicLibrary(code.Dll); + if (code.Dll) + { + UnloadDynamicLibrary(code.Dll); + } code.Dll = nullptr; code.LastWriteTime = 0; diff --git a/Juliet/src/Core/Memory/Allocator.cpp b/Juliet/src/Core/Memory/Allocator.cpp index 42a7644..e8e4856 100644 --- a/Juliet/src/Core/Memory/Allocator.cpp +++ b/Juliet/src/Core/Memory/Allocator.cpp @@ -1,4 +1,3 @@ -#include #include #include diff --git a/Juliet/src/TODO.txt b/Juliet/src/TODO.txt index 5f914c3..fd983a9 100644 --- a/Juliet/src/TODO.txt +++ b/Juliet/src/TODO.txt @@ -1,3 +1,4 @@ -Rename DX12 files to D3D12 - -- Create Simple vector class to make the vector stuff a bit more easier than writing Capacity and Count \ No newline at end of file +- Rename DX12 files to D3D12 +- Create Simple vector class to make the vector stuff a bit more easier than writing Capacity and Count +- Make a string struct instead of StringBuffer. + - Support wchar and char (template is ok) conversions, printf, compare, etc. diff --git a/JulietApp/JulietApp.vcxproj b/JulietApp/JulietApp.vcxproj index b24df86..ec4f47d 100644 --- a/JulietApp/JulietApp.vcxproj +++ b/JulietApp/JulietApp.vcxproj @@ -12,8 +12,8 @@ - {b7b12dcc-1a69-4371-a9fe-d6e7671497b0} - Game + {b7b12dcc-1a69-4371-a9fe-d6e7671497b0} + Game {1bbc0b92-e4d8-4838-974b-439c5c501e82} diff --git a/JulietApp/main.cpp b/JulietApp/main.cpp index daba1c3..7085e20 100644 --- a/JulietApp/main.cpp +++ b/JulietApp/main.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -13,6 +12,7 @@ #include #include +#include #include #include @@ -58,12 +58,11 @@ void JulietApplication::Init() if (Running) { AttachToWindow(GraphicsDevice, MainWindow); - // Game = LoadDynamicLibrary("Game.dll"); GameCode.Functions = reinterpret_cast(&Game); GameCode.FunctionCount = ArraySize(GameFunctionTable); GameCode.FunctionNames = GameFunctionTable; - InitHotReloadCode(GameCode, StringBufferParam("Game.dll"), StringBufferParam("Game_Temp.dll"), StringBufferParam("lock.tmp")); + InitHotReloadCode(GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp")); if ((Running = GameCode.IsValid)) { Game.Init(); diff --git a/JulietShaderCompiler/JulietShaderCompiler.vcxproj b/JulietShaderCompiler/JulietShaderCompiler.vcxproj index 68be6e2..24080bb 100644 --- a/JulietShaderCompiler/JulietShaderCompiler.vcxproj +++ b/JulietShaderCompiler/JulietShaderCompiler.vcxproj @@ -66,6 +66,7 @@ true pch.h $(SolutionDir)Juliet\include\;$(SolutionDir)JulietShaderCompiler; + stdcpp20 Console @@ -85,6 +86,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true pch.h + stdcpp20 Console @@ -102,12 +104,12 @@ - - PreserveNewest - - - PreserveNewest - + + PreserveNewest + + + PreserveNewest + diff --git a/JulietShaderCompiler/main.cpp b/JulietShaderCompiler/main.cpp index 09158c6..92e644c 100644 --- a/JulietShaderCompiler/main.cpp +++ b/JulietShaderCompiler/main.cpp @@ -1,49 +1,49 @@ - -//#include -//#include -//#include +#include +#include +#include +#include // Must be before everything else. // Cannot include DX12Includes because we redefine everything. // TODO : Separate lib // TODO : Only when not shipping // Check if we just load the dll and not link against? +#include -//#include -//#pragma comment(lib, "dxcompiler.lib") +#pragma comment(lib, "dxcompiler.lib") -//using namespace Juliet; +using namespace Juliet; void Compile() { - // IDxcCompiler3* compiler = nullptr; - // DxcCreateInstance(&CLSID_DxcCompiler, IID_IDxcCompiler3, reinterpret_cast(&compiler)); - // - // IDxcUtils* utils = nullptr; - // DxcCreateInstance(&CLSID_DxcUtils, &IID_IDxcUtils, reinterpret_cast(&utils)); - // - // if (compiler == nullptr) - // { - // Juliet::Log(LogLevel::Error, LogCategory::Graphics, "Cannot create DXCompiler instance"); - // } - // - // if (utils == nullptr) - // { - // Log(LogLevel::Error, LogCategory::Graphics, "Cannot create IDxcUtils instance"); - // compiler->lpVtbl->Release(compiler); - // } - // - // IDxcIncludeHandler* includeHandler; - // utils->lpVtbl->CreateDefaultIncludeHandler(utils, &includeHandler); - // if (includeHandler == nullptr) - // { - // compiler->lpVtbl->Release(compiler); - // utils->lpVtbl->Release(utils); - // } + IDxcCompiler3* compiler = nullptr; + DxcCreateInstance(&CLSID_DxcCompiler, IID_IDxcCompiler3, reinterpret_cast(&compiler)); + + IDxcUtils* utils = nullptr; + DxcCreateInstance(&CLSID_DxcUtils, &IID_IDxcUtils, reinterpret_cast(&utils)); + + if (compiler == nullptr) + { + Juliet::Log(LogLevel::Error, LogCategory::Graphics, "Cannot create DXCompiler instance"); + } + + if (utils == nullptr) + { + Log(LogLevel::Error, LogCategory::Graphics, "Cannot create IDxcUtils instance"); + compiler->lpVtbl->Release(compiler); + } + + IDxcIncludeHandler* includeHandler; + utils->lpVtbl->CreateDefaultIncludeHandler(utils, &includeHandler); + if (includeHandler == nullptr) + { + compiler->lpVtbl->Release(compiler); + utils->lpVtbl->Release(utils); + } } int main(int argc, char* argv[]) { - + auto* stream = IOFromFile(ConstString("bleeblou"), ConstString("w")); return 0; }