Fixing adaptive incremental build.

Moved more functions into engine.cpp
This commit is contained in:
2026-08-09 15:48:53 -04:00
parent 7c18804df6
commit 697579e72f
10 changed files with 149 additions and 159 deletions
@@ -26,8 +26,6 @@ namespace Juliet
virtual struct GraphicsDevice* GetGraphicsDevice() = 0; virtual struct GraphicsDevice* GetGraphicsDevice() = 0;
// Render Lifecycle (Engine-Managed Render Loop) // Render Lifecycle (Engine-Managed Render Loop)
virtual void OnPreRender(CommandList* cmd) = 0;
virtual void OnRender(RenderPass* pass, CommandList* cmd, const Camera& camera) = 0;
virtual ColorTargetInfo GetColorTargetInfo(Texture* swapchainTexture) = 0; virtual ColorTargetInfo GetColorTargetInfo(Texture* swapchainTexture) = 0;
virtual DepthStencilTargetInfo* GetDepthTargetInfo() = 0; virtual DepthStencilTargetInfo* GetDepthTargetInfo() = 0;
}; };
+1 -1
View File
@@ -53,7 +53,7 @@ namespace Juliet
JULIET_API void ShutdownMeshRendererGraphics(); JULIET_API void ShutdownMeshRendererGraphics();
JULIET_API void ShutdownMeshRenderer(); JULIET_API void ShutdownMeshRenderer();
JULIET_API void LoadMeshesOnGPU(NonNullPtr<CommandList> cmdList); JULIET_API void LoadMeshesOnGPU(NonNullPtr<CommandList> cmdList);
JULIET_API void RenderMeshes(NonNullPtr<RenderPass> pass, NonNullPtr<CommandList> cmdList, PushData& pushData); JULIET_API void RenderMeshes(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection);
// Lights // Lights
[[nodiscard]] JULIET_API LightID AddPointLight(const PointLight& light); [[nodiscard]] JULIET_API LightID AddPointLight(const PointLight& light);
+1 -1
View File
@@ -22,7 +22,7 @@ namespace Juliet
[[nodiscard]] JULIET_API bool InitializeSkyboxRenderer(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window); [[nodiscard]] JULIET_API bool InitializeSkyboxRenderer(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
JULIET_API void ShutdownSkyboxRenderer(); JULIET_API void ShutdownSkyboxRenderer();
JULIET_API void RenderSkybox(NonNullPtr<RenderPass> pass, NonNullPtr<CommandList> cmdList, const Matrix& viewProjection); JULIET_API void RenderSkybox(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection);
#if ALLOW_SHADER_HOT_RELOAD #if ALLOW_SHADER_HOT_RELOAD
JULIET_API void ReloadSkyboxShaders(); JULIET_API void ReloadSkyboxShaders();
+4 -10
View File
@@ -12,7 +12,6 @@
#include <Graphics/MeshRenderer.h> #include <Graphics/MeshRenderer.h>
#include <Graphics/RenderPass.h> #include <Graphics/RenderPass.h>
#include <Graphics/SkyboxRenderer.h> #include <Graphics/SkyboxRenderer.h>
#include <time.h>
#ifdef JULIET_ENABLE_IMGUI #ifdef JULIET_ENABLE_IMGUI
#include <Core/ImGui/ImGuiService.h> #include <Core/ImGui/ImGuiService.h>
@@ -120,9 +119,6 @@ namespace Juliet
if (swapChainTexture) if (swapChainTexture)
{ {
// Pre-render phase (buffer uploads, etc.)
EngineInstance.Application->OnPreRender(cmdList);
// Prepare debug display data (before render pass) // Prepare debug display data (before render pass)
DebugDisplay_Prepare(cmdList); DebugDisplay_Prepare(cmdList);
@@ -133,16 +129,14 @@ namespace Juliet
RenderPass* pass = BeginRenderPass(cmdList, colorInfo, depthInfo); RenderPass* pass = BeginRenderPass(cmdList, colorInfo, depthInfo);
Camera camera = *GetCurrentCamera(); Camera camera = *GetCurrentCamera();
Matrix viewProjectionMat = Camera_GetViewProjectionMatrix(camera);
// Application rendering RenderSkybox(cmdList, pass, viewProjectionMat);
EngineInstance.Application->OnRender(pass, cmdList, camera); RenderMeshes(cmdList, pass, viewProjectionMat);
// Debug display flush (inside render pass) // Debug display flush must happen after game rendering
DebugDisplay_Flush(cmdList, pass, camera); DebugDisplay_Flush(cmdList, pass, camera);
// Note: The MeshRenderer and SkyboxRenderer draw calls are still inside Application->OnRender
// They shouldn't be moved here directly without an interface since they require PushData.
#ifdef JULIET_ENABLE_IMGUI #ifdef JULIET_ENABLE_IMGUI
// ImGui rendering (always last before EndRenderPass) // ImGui rendering (always last before EndRenderPass)
ImGuiRenderer_Render(cmdList, pass); ImGuiRenderer_Render(cmdList, pass);
+6 -1
View File
@@ -237,7 +237,7 @@ namespace Juliet
TransitionBufferToReadable(cmdList, g_MeshRenderer.IndexBuffer); TransitionBufferToReadable(cmdList, g_MeshRenderer.IndexBuffer);
} }
void RenderMeshes(NonNullPtr<RenderPass> pass, NonNullPtr<CommandList> cmdList, PushData& pushData) void RenderMeshes(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection)
{ {
// First destroy any buffer that needs to be // First destroy any buffer that needs to be
if (g_MeshRenderer.LoadCopyBuffer) if (g_MeshRenderer.LoadCopyBuffer)
@@ -255,10 +255,15 @@ namespace Juliet
uint32 transformsDescriptorIndex = GetDescriptorIndex(g_MeshRenderer.Device, g_MeshRenderer.TransformsBuffer); uint32 transformsDescriptorIndex = GetDescriptorIndex(g_MeshRenderer.Device, g_MeshRenderer.TransformsBuffer);
PushData pushData = {};
pushData.ViewProjection = viewProjection;
pushData.BufferIndex = vertexDescriptorIndex; pushData.BufferIndex = vertexDescriptorIndex;
pushData.LightBufferIndex = lightDescriptorIndex; pushData.LightBufferIndex = lightDescriptorIndex;
pushData.TransformsBufferIndex = transformsDescriptorIndex; pushData.TransformsBufferIndex = transformsDescriptorIndex;
pushData.ActiveLightCount = static_cast<uint32>(g_MeshRenderer.PointLights.Count); pushData.ActiveLightCount = static_cast<uint32>(g_MeshRenderer.PointLights.Count);
pushData.GlobalLightDirection = { 0.0f, -1.0f, 0.0f };
pushData.GlobalLightColor = { 0.0f, 0.0f, 0.0f };
pushData.GlobalAmbientIntensity = 0.0f;
SetIndexBuffer(cmdList, g_MeshRenderer.IndexBuffer, IndexFormat::UInt16, g_MeshRenderer.Indices.Count, 0); SetIndexBuffer(cmdList, g_MeshRenderer.IndexBuffer, IndexFormat::UInt16, g_MeshRenderer.Indices.Count, 0);
+1 -1
View File
@@ -75,7 +75,7 @@ namespace Juliet
g_SkyboxRenderer = {}; g_SkyboxRenderer = {};
} }
void RenderSkybox(NonNullPtr<RenderPass> pass, NonNullPtr<CommandList> cmdList, const Matrix& viewProjection) void RenderSkybox(NonNullPtr<CommandList> cmdList, NonNullPtr<RenderPass> pass, const Matrix& viewProjection)
{ {
if (!g_SkyboxRenderer.Pipeline) if (!g_SkyboxRenderer.Pipeline)
{ {
-26
View File
@@ -537,32 +537,6 @@ void JulietApplication::Update(float deltaTime)
} }
} }
void JulietApplication::OnPreRender(CommandList* /*cmd*/) {}
void JulietApplication::OnRender(RenderPass* pass, CommandList* cmd, const Camera& camera)
{
PushData pushData = {};
pushData.ViewProjection = Camera_GetViewProjectionMatrix(camera);
#if 0
if (enableGlobalLight)
{
pushData.GlobalLightDirection = Normalize({ globalLightDir[0], globalLightDir[1], globalLightDir[2] });
pushData.GlobalLightColor = { globalLightColor[0], globalLightColor[1], globalLightColor[2] };
pushData.GlobalAmbientIntensity = globalAmbientIntensity;
}
else
#endif
{
pushData.GlobalLightDirection = { 0.0f, -1.0f, 0.0f };
pushData.GlobalLightColor = { 0.0f, 0.0f, 0.0f };
pushData.GlobalAmbientIntensity = 0.0f;
}
RenderSkybox(pass, cmd, pushData.ViewProjection);
RenderMeshes(pass, cmd, pushData);
}
ColorTargetInfo JulietApplication::GetColorTargetInfo(Texture* swapchainTexture) ColorTargetInfo JulietApplication::GetColorTargetInfo(Texture* swapchainTexture)
{ {
ColorTargetInfo info = {}; ColorTargetInfo info = {};
-2
View File
@@ -27,8 +27,6 @@ class JulietApplication : public Juliet::IApplication
Juliet::GraphicsDevice* GetGraphicsDevice() override { return GraphicsDevice; } Juliet::GraphicsDevice* GetGraphicsDevice() override { return GraphicsDevice; }
// Render Lifecycle // Render Lifecycle
void OnPreRender(Juliet::CommandList* cmd) override;
void OnRender(Juliet::RenderPass* pass, Juliet::CommandList* cmd, const Juliet::Camera& camera) override;
Juliet::ColorTargetInfo GetColorTargetInfo(Juliet::Texture* swapchainTexture) override; Juliet::ColorTargetInfo GetColorTargetInfo(Juliet::Texture* swapchainTexture) override;
Juliet::DepthStencilTargetInfo* GetDepthTargetInfo() override; Juliet::DepthStencilTargetInfo* GetDepthTargetInfo() override;
+1 -1
View File
@@ -153,7 +153,7 @@ if !TARGET_SHADER! equ 1 echo UNITY JulietShaderCompiler Intermediate\JulietShad
if !TARGET_JULIET! equ 1 echo UNITY_EXPLICIT Intermediate\External\imgui ImGui_Unity !UNITY_MAX_FILES! External\imgui\imgui.cpp^|External\imgui\imgui_demo.cpp^|External\imgui\imgui_draw.cpp^|External\imgui\imgui_tables.cpp^|External\imgui\imgui_widgets.cpp^|External\imgui\backends\imgui_impl_win32.cpp^|External\imgui\backends\imgui_impl_dx12.cpp>>"!PLAN_FILE!" if !TARGET_JULIET! equ 1 echo UNITY_EXPLICIT Intermediate\External\imgui ImGui_Unity !UNITY_MAX_FILES! External\imgui\imgui.cpp^|External\imgui\imgui_demo.cpp^|External\imgui\imgui_draw.cpp^|External\imgui\imgui_tables.cpp^|External\imgui\imgui_widgets.cpp^|External\imgui\backends\imgui_impl_win32.cpp^|External\imgui\backends\imgui_impl_dx12.cpp>>"!PLAN_FILE!"
set COMMON_FLAGS=/nologo /std:c++20 /W4 /utf-8 /DUNICODE /D_UNICODE /DWIN32_LEAN_AND_MEAN /D_CRT_SECURE_NO_WARNINGS /I"Juliet/include" /I"Juliet/src" /I"Game" /I"External/imgui" /I"External/imgui/backends" /DJULIET_WIN32 /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 /wd4626 /wd5026 /wd5027 /wd4530 set COMMON_FLAGS=/nologo /std:c++20 /W4 /utf-8 /DUNICODE /D_UNICODE /DWIN32_LEAN_AND_MEAN /D_CRT_SECURE_NO_WARNINGS /I"Juliet/include" /I"Juliet/src" /I"Game" /I"External/imgui" /I"External/imgui/backends" /DJULIET_WIN32 /DIMGUI_DEFINE_MATH_OPERATORS /wd5267 /wd4061 /wd4505 /wd4514 /wd4577 /wd4625 /wd4710 /wd4711 /wd4746 /wd4820 /wd5045 /wd5220 /wd5245 /wd4626 /wd5026 /wd5027 /wd4530
set COMPILE_ONLY_FLAGS=/Bt+ /EHa- set COMPILE_ONLY_FLAGS=/Bt+ /EHa-
echo !COMPILER! | findstr /i "clang-cl" >nul echo !COMPILER! | findstr /i "clang-cl" >nul
+74 -53
View File
@@ -284,6 +284,11 @@ typedef struct
int MaxFiles; int MaxFiles;
} UnityConfig; } UnityConfig;
static int CompareFilePaths(const void* a, const void* b)
{
return strcmp((const char*)a, (const char*)b);
}
static bool GenerateUnityFiles(const UnityConfig* ucfg) static bool GenerateUnityFiles(const UnityConfig* ucfg)
{ {
FilePathList* srcFiles = CreateFilePathList(); FilePathList* srcFiles = CreateFilePathList();
@@ -299,6 +304,9 @@ static bool GenerateUnityFiles(const UnityConfig* ucfg)
} }
} }
// Sort files to ensure deterministic index
qsort(srcFiles->Paths, srcFiles->Count, MAX_PATH_LEN, CompareFilePaths);
EnsureDirectoryExists(ucfg->OutputDir); EnsureDirectoryExists(ucfg->OutputDir);
SYSTEMTIME st; SYSTEMTIME st;
@@ -311,52 +319,64 @@ static bool GenerateUnityFiles(const UnityConfig* ucfg)
int64_t nowTime = liNow.QuadPart; int64_t nowTime = liNow.QuadPart;
int64_t oneHour = 3600LL * 10000000LL; int64_t oneHour = 3600LL * 10000000LL;
FilePathList* coldFiles = CreateFilePathList();
FilePathList* hotFiles = CreateFilePathList();
for (int i = 0; i < srcFiles->Count; i++)
{
if (StringContains(srcFiles->Paths[i], "_Unity")) continue;
int64_t fileTime = GetFileModTimeInt64(srcFiles->Paths[i]);
if (nowTime - fileTime < oneHour) {
FilePathListAdd(hotFiles, srcFiles->Paths[i]);
} else {
FilePathListAdd(coldFiles, srcFiles->Paths[i]);
}
}
int unityCount = 1;
bool anyChanged = false; bool anyChanged = false;
char currentUnityPath[MAX_PATH_LEN]; char currentUnityPath[MAX_PATH_LEN];
char* memBuf = (char*)ArenaPush(1024 * 1024); char* memBuf = (char*)ArenaPush(1024 * 1024);
// Process cold files (MaxFiles) // Determine hot/cold for each file
int fileIdx = 0; bool* isHot = (bool*)ArenaPush(srcFiles->Count * sizeof(bool));
for (int i = 0; i < srcFiles->Count; i++)
{
isHot[i] = false;
if (StringContains(srcFiles->Paths[i], "_Unity")) continue;
int64_t fileTime = GetFileModTimeInt64(srcFiles->Paths[i]);
if (nowTime - fileTime < oneHour) {
isHot[i] = true;
}
}
int numBuckets = (srcFiles->Count + ucfg->MaxFiles - 1) / ucfg->MaxFiles;
if (numBuckets == 0) numBuckets = 1; // Always at least one bucket
for (int b = 0; b < numBuckets; b++)
{
int startIdx = b * ucfg->MaxFiles;
int endIdx = startIdx + ucfg->MaxFiles;
if (endIdx > srcFiles->Count) endIdx = srcFiles->Count;
int memOffset = 0; int memOffset = 0;
int64_t maxIncludedTime = 0; int64_t maxIncludedTime = 0;
int coldCount = 0;
for (int i = 0; i < coldFiles->Count; i++) for (int i = startIdx; i < endIdx; i++)
{ {
if (isHot[i]) continue;
if (StringContains(srcFiles->Paths[i], "_Unity")) continue;
char absPath[MAX_PATH_LEN]; char absPath[MAX_PATH_LEN];
GetFullPathNameA(coldFiles->Paths[i], MAX_PATH_LEN, absPath, NULL); GetFullPathNameA(srcFiles->Paths[i], MAX_PATH_LEN, absPath, NULL);
for (int k = 0; absPath[k]; k++) { if (absPath[k] == '\\') absPath[k] = '/'; } for (int k = 0; absPath[k]; k++) { if (absPath[k] == '\\') absPath[k] = '/'; }
memOffset += sprintf_s(memBuf + memOffset, (1024 * 1024) - memOffset, "#include \"%s\"\n", absPath); memOffset += sprintf_s(memBuf + memOffset, (1024 * 1024) - memOffset, "#include \"%s\"\n", absPath);
fileIdx++; coldCount++;
int64_t fileTime = GetFileModTimeInt64(coldFiles->Paths[i]); int64_t fileTime = GetFileModTimeInt64(srcFiles->Paths[i]);
if (fileTime > maxIncludedTime) maxIncludedTime = fileTime; if (fileTime > maxIncludedTime) maxIncludedTime = fileTime;
}
if (fileIdx >= ucfg->MaxFiles || i == coldFiles->Count - 1) if (coldCount == 0)
{ {
snprintf(currentUnityPath, sizeof(currentUnityPath), "%s\\%s%d.cpp", ucfg->OutputDir, ucfg->Prefix, unityCount); memOffset += sprintf_s(memBuf + memOffset, (1024 * 1024) - memOffset, "// Empty bucket\n");
}
snprintf(currentUnityPath, sizeof(currentUnityPath), "%s\\%s%d.cpp", ucfg->OutputDir, ucfg->Prefix, b + 1);
FileContent exist = ReadEntireFile(currentUnityPath); FileContent exist = ReadEntireFile(currentUnityPath);
bool write = true; bool write = true;
if (exist.Data && exist.Size == memOffset && memcmp(exist.Data, memBuf, memOffset) == 0) write = false; if (exist.Data && exist.Size == memOffset && memcmp(exist.Data, memBuf, memOffset) == 0) write = false;
if (write) { WriteEntireFile(currentUnityPath, memBuf, memOffset); anyChanged = true; } if (write) { WriteEntireFile(currentUnityPath, memBuf, memOffset); anyChanged = true; }
// Touch Unity file if included files are newer // Touch Unity file if included files are newer
if (!write) { if (!write && coldCount > 0) {
int64_t unityTime = GetFileModTimeInt64(currentUnityPath); int64_t unityTime = GetFileModTimeInt64(currentUnityPath);
if (maxIncludedTime > unityTime) { if (maxIncludedTime > unityTime) {
HANDLE hFile = CreateFileA(currentUnityPath, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE hFile = CreateFileA(currentUnityPath, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
@@ -371,31 +391,27 @@ static bool GenerateUnityFiles(const UnityConfig* ucfg)
} }
} }
} }
unityCount++;
fileIdx = 0;
memOffset = 0;
maxIncludedTime = 0;
}
} }
// Process hot files (Standalone) // Process hot files
for (int i = 0; i < hotFiles->Count; i++) for (int i = 0; i < srcFiles->Count; i++)
{ {
if (!isHot[i]) continue;
char absPath[MAX_PATH_LEN]; char absPath[MAX_PATH_LEN];
GetFullPathNameA(hotFiles->Paths[i], MAX_PATH_LEN, absPath, NULL); GetFullPathNameA(srcFiles->Paths[i], MAX_PATH_LEN, absPath, NULL);
for (int k = 0; absPath[k]; k++) { if (absPath[k] == '\\') absPath[k] = '/'; } for (int k = 0; absPath[k]; k++) { if (absPath[k] == '\\') absPath[k] = '/'; }
memOffset = sprintf_s(memBuf, (1024 * 1024), "#include \"%s\"\n", absPath); int memOffset = sprintf_s(memBuf, (1024 * 1024), "#include \"%s\"\n", absPath);
snprintf(currentUnityPath, sizeof(currentUnityPath), "%s\\%s%d.cpp", ucfg->OutputDir, ucfg->Prefix, unityCount); snprintf(currentUnityPath, sizeof(currentUnityPath), "%s\\%s_Hot%d.cpp", ucfg->OutputDir, ucfg->Prefix, i);
FileContent exist = ReadEntireFile(currentUnityPath); FileContent exist = ReadEntireFile(currentUnityPath);
bool write = true; bool write = true;
if (exist.Data && exist.Size == memOffset && memcmp(exist.Data, memBuf, memOffset) == 0) write = false; if (exist.Data && exist.Size == memOffset && memcmp(exist.Data, memBuf, memOffset) == 0) write = false;
if (write) { WriteEntireFile(currentUnityPath, memBuf, memOffset); anyChanged = true; } if (write) { WriteEntireFile(currentUnityPath, memBuf, memOffset); anyChanged = true; }
if (!write) { if (!write) {
int64_t fileTime = GetFileModTimeInt64(hotFiles->Paths[i]); int64_t fileTime = GetFileModTimeInt64(srcFiles->Paths[i]);
int64_t unityTime = GetFileModTimeInt64(currentUnityPath); int64_t unityTime = GetFileModTimeInt64(currentUnityPath);
if (fileTime > unityTime) { if (fileTime > unityTime) {
HANDLE hFile = CreateFileA(currentUnityPath, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE hFile = CreateFileA(currentUnityPath, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
@@ -410,21 +426,32 @@ static bool GenerateUnityFiles(const UnityConfig* ucfg)
} }
} }
} }
unityCount++;
} }
// Delete remaining old unity files // Cleanup unused cold buckets
while (true) for (int b = numBuckets; b < numBuckets + 100; b++)
{
snprintf(currentUnityPath, sizeof(currentUnityPath), "%s\\%s%d.cpp", ucfg->OutputDir, ucfg->Prefix, unityCount);
if (FileExists(currentUnityPath))
{ {
snprintf(currentUnityPath, sizeof(currentUnityPath), "%s\\%s%d.cpp", ucfg->OutputDir, ucfg->Prefix, b + 1);
if (FileExists(currentUnityPath)) {
DeleteFileA(currentUnityPath); DeleteFileA(currentUnityPath);
anyChanged = true; anyChanged = true;
unityCount++; } else {
break;
}
}
// Cleanup unused hot files
for (int i = 0; i < srcFiles->Count + 1000; i++)
{
bool shouldExist = (i < srcFiles->Count && isHot[i]);
if (!shouldExist)
{
snprintf(currentUnityPath, sizeof(currentUnityPath), "%s\\%s_Hot%d.cpp", ucfg->OutputDir, ucfg->Prefix, i);
if (FileExists(currentUnityPath)) {
DeleteFileA(currentUnityPath);
anyChanged = true;
}
} }
else break;
} }
return anyChanged; return anyChanged;
@@ -1135,10 +1162,6 @@ static void GenerateProject(const char* projectName, const char* projectDir, con
int projectDirLen = (int)strlen(projectDir); int projectDirLen = (int)strlen(projectDir);
for (int i = 0; i < srcFiles->Count; i++) { for (int i = 0; i < srcFiles->Count; i++) {
const char* path = srcFiles->Paths[i]; const char* path = srcFiles->Paths[i];
const char* relPath = path;
if (strncmp(path, projectDir, projectDirLen) == 0 && (path[projectDirLen] == '\\' || path[projectDirLen] == '/')) {
relPath = path + projectDirLen + 1;
}
if (EndsWithNoCase(path, ".cpp") || EndsWithNoCase(path, ".c")) { if (EndsWithNoCase(path, ".cpp") || EndsWithNoCase(path, ".c")) {
offset += sprintf_s(buf + offset, (4 * 1024 * 1024) - offset, " <ClCompile Include=\"..\\%s\" />\n", path); offset += sprintf_s(buf + offset, (4 * 1024 * 1024) - offset, " <ClCompile Include=\"..\\%s\" />\n", path);
@@ -1258,7 +1281,7 @@ static void GenerateProject(const char* projectName, const char* projectDir, con
printf("Generated %s\n", filterOutPath); printf("Generated %s\n", filterOutPath);
} }
static void GenerateSolution(const char* slnName, const char** projectNames, const char** projectDirs, const char** projectGuids, int projCount) static void GenerateSolution(const char* slnName, const char** projectNames, const char** projectGuids, int projCount)
{ {
char* buf = (char*)ArenaPush(4 * 1024 * 1024); char* buf = (char*)ArenaPush(4 * 1024 * 1024);
int offset = 0; int offset = 0;
@@ -1501,19 +1524,17 @@ static int CommandGenVS(int argc, char* argv[])
for (int i = 0; i < slnCount; i++) { for (int i = 0; i < slnCount; i++) {
VSSolution* s = &solutions[i]; VSSolution* s = &solutions[i];
const char* pNames[16]; const char* pNames[16];
const char* pDirs[16];
const char* pGuids[16]; const char* pGuids[16];
for (int j = 0; j < s->ProjCount; j++) { for (int j = 0; j < s->ProjCount; j++) {
pNames[j] = s->Projects[j]; pNames[j] = s->Projects[j];
for (int k = 0; k < projCount; k++) { for (int k = 0; k < projCount; k++) {
if (strcmp(projects[k].Name, s->Projects[j]) == 0) { if (strcmp(projects[k].Name, s->Projects[j]) == 0) {
pDirs[j] = projects[k].Dir;
pGuids[j] = projects[k].Guid; pGuids[j] = projects[k].Guid;
break; break;
} }
} }
} }
GenerateSolution(s->Name, pNames, pDirs, pGuids, s->ProjCount); GenerateSolution(s->Name, pNames, pGuids, s->ProjCount);
} }
return 0; return 0;