Using memory arena in the game that supports hot reload

This commit is contained in:
2026-07-28 15:44:41 -04:00
parent 39586c968a
commit 4081539ee4
24 changed files with 219 additions and 217 deletions
-4
View File
@@ -18,8 +18,6 @@
constexpr Juliet::Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \
const Juliet::Class* entity::Kind = &entityKind##entity;
namespace Game
{
using DerivedType = void*;
struct Entity final
@@ -70,5 +68,3 @@ namespace Game
Assert(IsA<EntityType>(entity));
return static_cast<EntityType*>(entity->Derived);
}
} // namespace Game
+10 -13
View File
@@ -2,33 +2,30 @@
#include <Entity/Entity.h>
namespace Game
{
namespace
{
EntityManager Manager;
}
EntityID EntityManager::ID = 0;
void InitEntityManager(Juliet::NonNullPtr<Juliet::Arena> arena)
void InitEntityManager(Juliet::NonNullPtr<World> world)
{
Manager.Arena = arena.Get();
Manager.Entities.Create(arena JULIET_DEBUG_PARAM("Entities"));
EntityManager* newManager = Juliet::ArenaPushStruct<EntityManager>(world->WorldArena);
world->EntityManager = newManager;
newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities"));
newManager->Arena = Juliet::ArenaAllocate({} JULIET_DEBUG_PARAM("Entity Arena"));
}
void ShutdownEntityManager()
{
Manager.Entities.Destroy();
GetEntityManager().Entities.Destroy();
}
EntityManager& GetEntityManager()
{
return Manager;
Juliet::NonNullPtr entityManager = GetGameState()->World->EntityManager;
return *entityManager;
}
void RegisterEntity(EntityManager& /*manager*/, Entity* entity)
{
entity->ID = EntityManager::ID++;
}
} // namespace Game
+3 -4
View File
@@ -2,9 +2,8 @@
#include <Core/Common/CoreTypes.h>
#include <Core/Container/Vector.h>
#include <game.h>
namespace Game
{
using EntityID = uint64_t;
struct Entity;
@@ -13,12 +12,12 @@ namespace Game
static EntityID ID;
Juliet::Arena* Arena;
// TODO: Should be a pool
Juliet::VectorArena<Entity, 1024> Entities;
};
void InitEntityManager(Juliet::NonNullPtr<Juliet::Arena> arena);
void InitEntityManager(Juliet::NonNullPtr<World> world);
void ShutdownEntityManager();
EntityManager& GetEntityManager();
void RegisterEntity(EntityManager& manager, Entity* entity);
} // namespace Game
+1
View File
@@ -84,6 +84,7 @@
<ClCompile Include="game.cpp" />
<ClInclude Include="Entity\Entity.h" />
<ClInclude Include="Entity\EntityManager.h" />
<ClInclude Include="game.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
+1
View File
@@ -15,5 +15,6 @@
<ClInclude Include="Entity\EntityManager.h">
<Filter>Entity</Filter>
</ClInclude>
<ClInclude Include="game.h" />
</ItemGroup>
</Project>
+32 -21
View File
@@ -3,6 +3,8 @@
#undef min
#undef max
#include <game.h>
#include <Core/HAL/Filesystem/Filesystem.h>
#include <Core/JulietInit.h>
#include <Core/Logging/LogManager.h>
@@ -10,6 +12,12 @@
#include <Entity/Entity.h>
#include <Entity/EntityManager.h>
GameState* gGameState = nullptr;
GameState* GetGameState()
{
return gGameState;
}
// Test code
namespace Game
{
@@ -26,30 +34,44 @@ namespace Game
int Health;
};
DEFINE_ENTITY(Rock);
} // namespace Game
extern "C" JULIET_API void __cdecl GameShutdown()
{
printf("Shutting down game...\n");
using namespace Juliet;
using namespace Game;
extern "C" JULIET_API void GameInit(GameInitParams* params)
ShutdownEntityManager();
}
extern "C" JULIET_API void __cdecl GameUpdate(Juliet::GameData* params, [[maybe_unused]] float deltaTime)
{
// Example allocation in GameArena
struct GameState
using namespace Juliet;
using namespace Game;
gGameState = params->GameState;
if (!gGameState)
{
float TotalTime;
int Score;
};
Arena* gameStateArena = ArenaAllocate({ .ReserveSize = Megabytes(1) } JULIET_DEBUG_PARAM("Game Total Arena"));
auto* gameState = ArenaPushStruct<GameState>(gameStateArena);
gGameState = params->GameState = gameState;
gameState->TotalArena = gameStateArena;
auto* gameState = ArenaPushStruct<GameState>(params->GameArena);
gameState->TotalTime = 0.0f;
gameState->Score = 0;
printf("Game Arena Allocated: %p\n", static_cast<void*>(gameState));
using namespace Game;
// Bootstrap world
auto* worldArena = ArenaAllocate({ .ReserveSize = Megabytes(1) } JULIET_DEBUG_PARAM("World Arena"));
World* world = ArenaPushStruct<World>(worldArena JULIET_DEBUG_PARAM("World"));
gameState->World = world;
gameState->World->WorldArena = worldArena;
// Entity Use case
InitEntityManager(params->GameArena);
InitEntityManager(gameState->World);
auto& manager = GetEntityManager();
Door* door = MakeEntity<Door>(manager, 10.0f, 2.0f);
door->IsOpened = true;
@@ -66,16 +88,5 @@ extern "C" JULIET_API void GameInit(GameInitParams* params)
printf("Rock has %d health points\n", rock->Health);
}
extern "C" JULIET_API void __cdecl GameShutdown()
{
printf("Shutting down game...\n");
using namespace Game;
ShutdownEntityManager();
}
extern "C" JULIET_API void __cdecl GameUpdate([[maybe_unused]] float deltaTime)
{
// printf("Updating game...\n");
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include <Core/Memory/MemoryArena.h>
struct EntityManager;
struct World
{
Juliet::Arena* WorldArena;
EntityManager* EntityManager;
};
struct GameState
{
Juliet::Arena* TotalArena;
World* World;
float TotalTime;
int Score;
};
extern GameState* GetGameState();
-9
View File
@@ -24,23 +24,14 @@ Global
{1720427b-c8ba-3195-f931-e97f6d6125c1}.Release|x64.ActiveCfg = Release|x64
{1720427b-c8ba-3195-f931-e97f6d6125c1}.Release|x64.Build.0 = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.ActiveCfg = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.Build.0 = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.ActiveCfg = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.Build.0 = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.ActiveCfg = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.Build.0 = Release|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Debug|x64.ActiveCfg = Debug|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Debug|x64.Build.0 = Debug|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Profile|x64.ActiveCfg = Profile|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Profile|x64.Build.0 = Profile|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Release|x64.ActiveCfg = Release|x64
{b568a67e-05a1-9907-ff4b-a129119528bd}.Release|x64.Build.0 = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.ActiveCfg = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.Build.0 = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.ActiveCfg = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.Build.0 = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.ActiveCfg = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
-3
View File
@@ -147,10 +147,7 @@
<ClInclude Include="include\Core\Common\CoreUtils.h" />
<ClInclude Include="include\Core\Common\CRC32.h" />
<ClInclude Include="include\Core\Common\EnumUtils.h" />
<ClInclude Include="include\Core\Common\NonCopyable.h" />
<ClInclude Include="include\Core\Common\NonMovable.h" />
<ClInclude Include="include\Core\Common\NonNullPtr.h" />
<ClInclude Include="include\Core\Common\Singleton.h" />
<ClInclude Include="include\Core\Common\String.h" />
<ClInclude Include="include\Core\Container\Vector.h" />
<ClInclude Include="include\Core\HAL\Display\Display.h" />
-9
View File
@@ -318,18 +318,9 @@
<ClInclude Include="include\Core\Common\EnumUtils.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\NonCopyable.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\NonMovable.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\NonNullPtr.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\Singleton.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\String.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
+17 -14
View File
@@ -15,7 +15,7 @@ namespace Juliet
class NonNullPtr
{
public:
inline NonNullPtr(Type* ptr)
constexpr NonNullPtr(Type* ptr)
: InternalPtr(ptr)
{
Assert(ptr, "Tried to initialize a NonNullPtr with a null pointer");
@@ -23,14 +23,14 @@ namespace Juliet
template <typename OtherType>
requires NonNullPtr_Convertible<OtherType*, Type*>
NonNullPtr(const NonNullPtr<OtherType>& otherPtr)
constexpr NonNullPtr(const NonNullPtr<OtherType>& otherPtr)
: InternalPtr(otherPtr.Get())
{
Assert(InternalPtr, "Fatal Error: Assigned a non null ptr using another NonNullPtr but its was null.");
}
// Assignment
NonNullPtr& operator=(Type* ptr)
[[nodiscard]] constexpr NonNullPtr& operator=(Type* ptr)
{
Assert(ptr, "Tried to assign a null pointer to a NonNullPtr!");
InternalPtr = ptr;
@@ -39,68 +39,71 @@ namespace Juliet
template <typename OtherType>
requires NonNullPtr_Convertible<OtherType*, Type*>
NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr)
[[nodiscard]] constexpr NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr)
{
InternalPtr = otherPtr.Get();
return *this;
}
// Accessors
operator Type*() const
[[nodiscard]] constexpr operator Type*() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr;
}
Type* Get() const
[[nodiscard]] constexpr Type* Get() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr;
}
Type& operator*() const
[[nodiscard]] constexpr Type& operator*() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return *InternalPtr;
}
inline Type* operator->() const
[[nodiscard]] constexpr Type* operator->() const
{
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr;
}
// Comparisons
bool operator==(const NonNullPtr& otherPtr) const { return InternalPtr == otherPtr.InternalPtr; }
[[nodiscard]] constexpr bool operator==(const NonNullPtr& otherPtr) const
{
return InternalPtr == otherPtr.InternalPtr;
}
template <typename OtherType>
requires NonNullPtr_SameType<Type, OtherType>
bool operator==(OtherType* otherRawPtr) const
[[nodiscard]] constexpr bool operator==(OtherType* otherRawPtr) const
{
return InternalPtr == otherRawPtr;
}
template <typename OtherType>
requires NonNullPtr_SameType<Type, OtherType>
friend bool operator==(OtherType* otherRawPtr, const NonNullPtr& nonNullPtr)
[[nodiscard]] constexpr friend bool operator==(OtherType* otherRawPtr, const NonNullPtr& nonNullPtr)
{
return otherRawPtr == nonNullPtr.InternalPtr;
}
// Forbid assigning a nullptr at compile time
NonNullPtr(std::nullptr_t)
constexpr NonNullPtr(std::nullptr_t)
: InternalPtr(nullptr)
{
static_assert(sizeof(Type) == 0, "Trying to initialize a NonNullPtr with a nullptr value");
}
NonNullPtr& operator=(std::nullptr_t)
[[nodiscard]] constexpr NonNullPtr& operator=(std::nullptr_t)
{
static_assert(sizeof(Type) == 0, "Trying to assign a NonNullPtr with a nullptr value");
return *this;
}
explicit operator bool() const { return true; }
[[nodiscard]] constexpr explicit operator bool() const { return InternalPtr != nullptr; }
private:
Type* InternalPtr;
+5
View File
@@ -18,12 +18,16 @@ namespace Juliet
Count = 0;
Capacity = 0;
Arena = arena;
ArenaPosAtCreation = ArenaPos(Arena);
Reserve(ReserveSize);
}
void Destroy()
{
Assert(ArenaPos(Arena) == ArenaPosAtCreation + sizeof(Type) * Capacity);
ArenaPopTo(Arena, ArenaPosAtCreation);
DataFirst = DataLast = Data = nullptr;
Count = 0;
Capacity = 0;
@@ -203,6 +207,7 @@ namespace Juliet
Type* Data = nullptr;
size_t Count = 0;
size_t Capacity = 0;
index_t ArenaPosAtCreation = 0;
JULIET_DEBUG_ONLY(const char* Name = "VectorArena";)
};
static_assert(std::is_standard_layout_v<VectorArena<int>>,
+2 -2
View File
@@ -15,9 +15,9 @@ namespace Juliet
struct Arena;
struct GameInitParams
struct GameData
{
Arena* GameArena;
struct GameState* GameState;
Arena* ScratchArena;
};
-1
View File
@@ -77,7 +77,6 @@ namespace Juliet
const std::source_location& loc = std::source_location::current());
JULIET_API void ArenaRelease(NonNullPtr<Arena> arena);
// Raw Push, can be used but templated helpers exists below
// Raw Push, can be used but templated helpers exists below
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag));
+5 -3
View File
@@ -11,7 +11,7 @@ namespace Juliet
{
void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename)
{
code.Arena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Hot Reload"));
code.Arena = ArenaAllocate({ .ReserveSize = Megabytes(1) } JULIET_DEBUG_ONLY(, "Hot Reload"));
// Get the app base path and build the dll path from there.
String basePath = GetBasePath();
@@ -25,7 +25,8 @@ namespace Juliet
const size_t dllFullPathLength =
basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings
code.DLLFullPath.Data = static_cast<char*>(ArenaPush(code.Arena, dllFullPathLength, alignof(char), true JULIET_DEBUG_ONLY(, "DLL Path")));
code.DLLFullPath.Data =
static_cast<char*>(ArenaPush(code.Arena, dllFullPathLength, alignof(char), true JULIET_DEBUG_ONLY(, "DLL Path")));
int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName));
if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
{
@@ -38,7 +39,8 @@ namespace Juliet
// Lock filename path
const size_t lockPathLength =
basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings
code.LockFullPath.Data = static_cast<char*>(ArenaPush(code.Arena, lockPathLength, alignof(char), true JULIET_DEBUG_ONLY(, "Lock File Path")));
code.LockFullPath.Data =
static_cast<char*>(ArenaPush(code.Arena, lockPathLength, alignof(char), true JULIET_DEBUG_ONLY(, "Lock File Path")));
writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename));
if (writtenSize < static_cast<int>(lockPathLength) - 1)
{
@@ -112,11 +112,10 @@ namespace Juliet
else
{
code.IsValid = false;
break;
}
}
}
// Scratch memory, no free needed
}
if (!code.IsValid)
@@ -549,8 +549,8 @@ namespace Juliet::D3D12
driver->D3D12SerializeVersionedRootSignatureFct = nullptr;
Assert(ArenaPos(driver->DriverArena) == sizeof(D3D12Driver)); // Verify we didnt forget to release something
ArenaRelease(driver->DriverArena);
Free(driver.Get());
}
bool AttachToWindow(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window)
@@ -698,10 +698,10 @@ namespace Juliet::D3D12
GraphicsDevice* CreateGraphicsDevice(bool enableDebug)
{
auto driver = static_cast<D3D12Driver*>(Calloc(1, sizeof(D3D12Driver)));
Arena* driverArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "D3D12 Driver Arena"));
D3D12Driver* driver = ArenaPushStruct<D3D12Driver>(driverArena JULIET_DEBUG_PARAM("D3D12Driver struct"));
// TODO : Convert everything to arena
driver->DriverArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "D3D12 Driver"));
driver->DriverArena = driverArena;
#if JULIET_DEBUG
#ifdef IDXGIINFOQUEUE_SUPPORTED
@@ -517,13 +517,21 @@ namespace Juliet::D3D12
// Fix SRV format for Depth Buffers (TypeLess -> Typed)
if (createInfo.Format == TextureFormat::D32_FLOAT)
{
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
}
else if (createInfo.Format == TextureFormat::D16_UNORM)
{
srvDesc.Format = DXGI_FORMAT_R16_UNORM;
}
else if (createInfo.Format == TextureFormat::D24_UNORM_S8_UINT)
{
srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
}
else if (createInfo.Format == TextureFormat::D32_FLOAT_S8_UINT)
{
srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
}
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+2 -2
View File
@@ -58,7 +58,6 @@ namespace Juliet
{
if (GraphicsDevice* newDevice = chosenFactory->CreateGraphicsDevice(config.EnableDebug))
{
newDevice->Name = chosenFactory->Name;
return newDevice;
}
@@ -371,7 +370,8 @@ namespace Juliet
GraphicsBuffer* CreateGraphicsBuffer(NonNullPtr<GraphicsDevice> device, const BufferCreateInfo& createInfo)
{
return device->CreateGraphicsBuffer(device->Driver, createInfo.Size, createInfo.Stride, createInfo.Usage, createInfo.IsDynamic);
return device->CreateGraphicsBuffer(device->Driver, createInfo.Size, createInfo.Stride, createInfo.Usage,
createInfo.IsDynamic);
}
GraphicsTransferBuffer* CreateGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, const TransferBufferCreateInfo& createInfo)
+5 -16
View File
@@ -87,17 +87,16 @@ using namespace Juliet;
namespace
{
using GameInit_t = void (*)(GameInitParams*);
using GameShutdown_t = void (*)(void);
using GameUpdate_t = void (*)(float deltaTime);
using GameUpdate_t = void (*)(GameData* params, float deltaTime);
struct GameFunctionTable
{
GameInit_t Init = nullptr;
GameShutdown_t Shutdown = nullptr;
GameUpdate_t Update = nullptr;
} Game;
GameData Data;
const char* GameFunctionTable[] = { "GameInit", "GameShutdown", "GameUpdate" };
const char* GameFunctionTable[] = { "GameShutdown", "GameUpdate" };
LightID RedLightID = 0;
LightID BlueLightID = 0;
@@ -178,13 +177,7 @@ void JulietApplication::Init(NonNullPtr<Arena>)
GameCode.FunctionCount = ArraySize(GameFunctionTable);
GameCode.FunctionNames = GameFunctionTable;
InitHotReloadCode(GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp"));
if ((Running = GameCode.IsValid))
{
GameInitParams params;
params.GameArena = GameArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Game Arena"));
params.ScratchArena = GameScratchArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "Scratch Arena"));
Game.Init(&params);
}
Running = GameCode.IsValid;
}
}
@@ -429,8 +422,6 @@ void JulietApplication::Update()
ImGui::End();
#endif
ArenaClear(GameScratchArena);
Vector3 redLightPos = { 5.0f, 5.0f, 2.0f };
Vector3 blueLightPos = { -5.0f, 0.0f, 2.0f };
@@ -497,7 +488,7 @@ void JulietApplication::Update()
DebugDisplay_DrawSphere(blueLightPos, 0.5f, { 0.0f, 0.0f, 1.0f, 1.0f }, true);
DebugDisplay_DrawSphere(redLightPos, 0.5f, { 1.0f, 0.0f, 0.0f, 1.0f }, true);
Game.Update(0.0f);
Game.Update(&Data, 0.0f);
if (ShouldReloadCode(GameCode))
{
@@ -545,8 +536,6 @@ void JulietApplication::Update()
Debug::DebugDrawMemoryArena();
#endif
}
ArenaClear(GameScratchArena);
}
void JulietApplication::OnPreRender(CommandList* /*cmd*/) {}
-2
View File
@@ -43,8 +43,6 @@ class JulietApplication : public Juliet::IApplication
Juliet::HotReloadCode GameCode = {};
Juliet::GraphicsPipeline* GraphicsPipeline = {};
Juliet::Texture* DepthBuffer = {};
Juliet::Arena* GameArena = nullptr;
Juliet::Arena* GameScratchArena = nullptr;
int AutoCloseFrameCount = -1;
bool Running = false;
-6
View File
@@ -22,17 +22,11 @@ Global
{c7df05fe-d5d5-db2a-af36-e7d71d325fda}.Release|x64.ActiveCfg = Release|x64
{c7df05fe-d5d5-db2a-af36-e7d71d325fda}.Release|x64.Build.0 = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.ActiveCfg = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.Build.0 = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.ActiveCfg = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.Build.0 = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.ActiveCfg = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.Build.0 = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.ActiveCfg = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.Build.0 = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.ActiveCfg = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.Build.0 = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.ActiveCfg = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
-6
View File
@@ -22,17 +22,11 @@ Global
{767620a7-b286-e7a1-9f79-3e14ce9e5ab1}.Release|x64.ActiveCfg = Release|x64
{767620a7-b286-e7a1-9f79-3e14ce9e5ab1}.Release|x64.Build.0 = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.ActiveCfg = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Debug|x64.Build.0 = Debug|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.ActiveCfg = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Profile|x64.Build.0 = Profile|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.ActiveCfg = Release|x64
{a93aa30f-8f29-02fe-57e2-cd3626948b68}.Release|x64.Build.0 = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.ActiveCfg = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Debug|x64.Build.0 = Debug|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.ActiveCfg = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Profile|x64.Build.0 = Profile|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.ActiveCfg = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+7 -3
View File
@@ -1091,10 +1091,14 @@ static void GenerateSolution(const char* slnName, const char** projectNames, con
const char* configs[] = { "Debug", "Profile", "Release" };
for (int c = 0; c < 3; c++) {
offset += sprintf_s(buf + offset, (4 * 1024 * 1024) - offset,
" {%s}.%s|x64.ActiveCfg = %s|x64\n"
" {%s}.%s|x64.Build.0 = %s|x64\n",
projectGuids[i], configs[c], configs[c],
" {%s}.%s|x64.ActiveCfg = %s|x64\n",
projectGuids[i], configs[c], configs[c]);
if (i == 0) {
offset += sprintf_s(buf + offset, (4 * 1024 * 1024) - offset,
" {%s}.%s|x64.Build.0 = %s|x64\n",
projectGuids[i], configs[c], configs[c]);
}
}
}