Compare commits

...
2 Commits
28 changed files with 223 additions and 413 deletions
+19 -23
View File
@@ -18,35 +18,33 @@
constexpr Juliet::Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \ constexpr Juliet::Class entityKind##entity(#entity, sizeof(#entity) / sizeof(char)); \
const Juliet::Class* entity::Kind = &entityKind##entity; const Juliet::Class* entity::Kind = &entityKind##entity;
namespace Game using DerivedType = void*;
{
using DerivedType = void*;
struct Entity final struct Entity final
{ {
EntityID ID; EntityID ID;
const Juliet::Class* Kind; const Juliet::Class* Kind;
DerivedType Derived; DerivedType Derived;
float X, Y; float X, Y;
}; };
template <typename EntityType> template <typename EntityType>
concept EntityConcept = requires(EntityType entity) { concept EntityConcept = requires(EntityType entity) {
requires std::same_as<decltype(entity.Kind), const Juliet::Class*>; requires std::same_as<decltype(entity.Kind), const Juliet::Class*>;
requires std::same_as<decltype(entity.Base), Entity*>; requires std::same_as<decltype(entity.Base), Entity*>;
}; };
template <typename EntityType> template <typename EntityType>
requires EntityConcept<EntityType> requires EntityConcept<EntityType>
bool IsA(const Entity* entity) bool IsA(const Entity* entity)
{ {
return entity->Kind == EntityType::Kind; return entity->Kind == EntityType::Kind;
} }
template <typename EntityType> template <typename EntityType>
requires EntityConcept<EntityType> requires EntityConcept<EntityType>
EntityType* MakeEntity(EntityManager& manager, float x, float y) EntityType* MakeEntity(EntityManager& manager, float x, float y)
{ {
auto* arena = manager.Arena; auto* arena = manager.Arena;
EntityType* result = Juliet::ArenaPushStruct<EntityType>(arena); EntityType* result = Juliet::ArenaPushStruct<EntityType>(arena);
Entity base; Entity base;
@@ -61,14 +59,12 @@ namespace Game
RegisterEntity(manager, &base); RegisterEntity(manager, &base);
return result; return result;
} }
template <typename EntityType> template <typename EntityType>
requires EntityConcept<EntityType> requires EntityConcept<EntityType>
EntityType* DownCast(Entity* entity) EntityType* DownCast(Entity* entity)
{ {
Assert(IsA<EntityType>(entity)); Assert(IsA<EntityType>(entity));
return static_cast<EntityType*>(entity->Derived); return static_cast<EntityType*>(entity->Derived);
} }
} // namespace Game
+20 -23
View File
@@ -2,33 +2,30 @@
#include <Entity/Entity.h> #include <Entity/Entity.h>
namespace Game EntityID EntityManager::ID = 0;
void InitEntityManager(Juliet::NonNullPtr<World> world)
{ {
namespace EntityManager* newManager = Juliet::ArenaPushStruct<EntityManager>(world->WorldArena);
{ world->EntityManager = newManager;
EntityManager Manager;
}
EntityID EntityManager::ID = 0; newManager->Entities.Create(world->WorldArena JULIET_DEBUG_PARAM("Entities"));
void InitEntityManager(Juliet::NonNullPtr<Juliet::Arena> arena) newManager->Arena = Juliet::ArenaAllocate({} JULIET_DEBUG_PARAM("Entity Arena"));
{ }
Manager.Arena = arena.Get();
Manager.Entities.Create(arena JULIET_DEBUG_PARAM("Entities"));
}
void ShutdownEntityManager() void ShutdownEntityManager()
{ {
Manager.Entities.Destroy(); GetEntityManager().Entities.Destroy();
} }
EntityManager& GetEntityManager() EntityManager& GetEntityManager()
{ {
return Manager; Juliet::NonNullPtr entityManager = GetGameState()->World->EntityManager;
} return *entityManager;
}
void RegisterEntity(EntityManager& /*manager*/, Entity* entity) void RegisterEntity(EntityManager& /*manager*/, Entity* entity)
{ {
entity->ID = EntityManager::ID++; entity->ID = EntityManager::ID++;
} }
} // namespace Game
+11 -12
View File
@@ -2,23 +2,22 @@
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Core/Container/Vector.h> #include <Core/Container/Vector.h>
#include <game.h>
namespace Game using EntityID = uint64_t;
struct Entity;
struct EntityManager
{ {
using EntityID = uint64_t;
struct Entity;
struct EntityManager
{
static EntityID ID; static EntityID ID;
Juliet::Arena* Arena; Juliet::Arena* Arena;
// TODO: Should be a pool // TODO: Should be a pool
Juliet::VectorArena<Entity, 1024> Entities; Juliet::VectorArena<Entity, 1024> Entities;
}; };
void InitEntityManager(Juliet::NonNullPtr<Juliet::Arena> arena); void InitEntityManager(Juliet::NonNullPtr<World> world);
void ShutdownEntityManager(); void ShutdownEntityManager();
EntityManager& GetEntityManager(); EntityManager& GetEntityManager();
void RegisterEntity(EntityManager& manager, Entity* entity); void RegisterEntity(EntityManager& manager, Entity* entity);
} // namespace Game
+1
View File
@@ -84,6 +84,7 @@
<ClCompile Include="game.cpp" /> <ClCompile Include="game.cpp" />
<ClInclude Include="Entity\Entity.h" /> <ClInclude Include="Entity\Entity.h" />
<ClInclude Include="Entity\EntityManager.h" /> <ClInclude Include="Entity\EntityManager.h" />
<ClInclude Include="game.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
+1
View File
@@ -15,5 +15,6 @@
<ClInclude Include="Entity\EntityManager.h"> <ClInclude Include="Entity\EntityManager.h">
<Filter>Entity</Filter> <Filter>Entity</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="game.h" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+35 -24
View File
@@ -3,6 +3,8 @@
#undef min #undef min
#undef max #undef max
#include <game.h>
#include <Core/HAL/Filesystem/Filesystem.h> #include <Core/HAL/Filesystem/Filesystem.h>
#include <Core/JulietInit.h> #include <Core/JulietInit.h>
#include <Core/Logging/LogManager.h> #include <Core/Logging/LogManager.h>
@@ -10,6 +12,12 @@
#include <Entity/Entity.h> #include <Entity/Entity.h>
#include <Entity/EntityManager.h> #include <Entity/EntityManager.h>
GameState* gGameState = nullptr;
GameState* GetGameState()
{
return gGameState;
}
// Test code // Test code
namespace Game namespace Game
{ {
@@ -26,30 +34,44 @@ namespace Game
int Health; int Health;
}; };
DEFINE_ENTITY(Rock); DEFINE_ENTITY(Rock);
} // namespace Game } // namespace Game
using namespace Juliet; extern "C" JULIET_API void __cdecl GameShutdown()
extern "C" JULIET_API void GameInit(GameInitParams* params)
{ {
// Example allocation in GameArena printf("Shutting down game...\n");
struct GameState
using namespace Juliet;
using namespace Game;
ShutdownEntityManager();
}
extern "C" JULIET_API void __cdecl GameUpdate(Juliet::GameData* params, [[maybe_unused]] float deltaTime)
{
using namespace Juliet;
using namespace Game;
gGameState = params->GameState;
if (!gGameState)
{ {
float TotalTime; Arena* gameStateArena = ArenaAllocate({ .ReserveSize = Megabytes(1) } JULIET_DEBUG_PARAM("Game Total Arena"));
int Score; auto* gameState = ArenaPushStruct<GameState>(gameStateArena);
}; gGameState = params->GameState = gameState;
gameState->TotalArena = gameStateArena;
auto* gameState = ArenaPushStruct<GameState>(params->GameArena);
gameState->TotalTime = 0.0f; gameState->TotalTime = 0.0f;
gameState->Score = 0; gameState->Score = 0;
printf("Game Arena Allocated: %p\n", static_cast<void*>(gameState)); 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 // Entity Use case
InitEntityManager(params->GameArena); InitEntityManager(gameState->World);
auto& manager = GetEntityManager(); auto& manager = GetEntityManager();
Door* door = MakeEntity<Door>(manager, 10.0f, 2.0f); Door* door = MakeEntity<Door>(manager, 10.0f, 2.0f);
door->IsOpened = true; door->IsOpened = true;
@@ -64,18 +86,7 @@ extern "C" JULIET_API void GameInit(GameInitParams* params)
printf("Door is %s\n", door->IsOpened ? "Opened" : "Closed"); printf("Door is %s\n", door->IsOpened ? "Opened" : "Closed");
printf("Rock has %d health points\n", rock->Health); 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"); // 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.ActiveCfg = Release|x64
{1720427b-c8ba-3195-f931-e97f6d6125c1}.Release|x64.Build.0 = 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.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.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.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.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.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.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.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.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.ActiveCfg = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
-3
View File
@@ -147,10 +147,7 @@
<ClInclude Include="include\Core\Common\CoreUtils.h" /> <ClInclude Include="include\Core\Common\CoreUtils.h" />
<ClInclude Include="include\Core\Common\CRC32.h" /> <ClInclude Include="include\Core\Common\CRC32.h" />
<ClInclude Include="include\Core\Common\EnumUtils.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\NonNullPtr.h" />
<ClInclude Include="include\Core\Common\Singleton.h" />
<ClInclude Include="include\Core\Common\String.h" /> <ClInclude Include="include\Core\Common\String.h" />
<ClInclude Include="include\Core\Container\Vector.h" /> <ClInclude Include="include\Core\Container\Vector.h" />
<ClInclude Include="include\Core\HAL\Display\Display.h" /> <ClInclude Include="include\Core\HAL\Display\Display.h" />
-9
View File
@@ -318,18 +318,9 @@
<ClInclude Include="include\Core\Common\EnumUtils.h"> <ClInclude Include="include\Core\Common\EnumUtils.h">
<Filter>include\Core\Common</Filter> <Filter>include\Core\Common</Filter>
</ClInclude> </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"> <ClInclude Include="include\Core\Common\NonNullPtr.h">
<Filter>include\Core\Common</Filter> <Filter>include\Core\Common</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="include\Core\Common\Singleton.h">
<Filter>include\Core\Common</Filter>
</ClInclude>
<ClInclude Include="include\Core\Common\String.h"> <ClInclude Include="include\Core\Common\String.h">
<Filter>include\Core\Common</Filter> <Filter>include\Core\Common</Filter>
</ClInclude> </ClInclude>
+17 -14
View File
@@ -15,7 +15,7 @@ namespace Juliet
class NonNullPtr class NonNullPtr
{ {
public: public:
inline NonNullPtr(Type* ptr) constexpr NonNullPtr(Type* ptr)
: InternalPtr(ptr) : InternalPtr(ptr)
{ {
Assert(ptr, "Tried to initialize a NonNullPtr with a null pointer"); Assert(ptr, "Tried to initialize a NonNullPtr with a null pointer");
@@ -23,14 +23,14 @@ namespace Juliet
template <typename OtherType> template <typename OtherType>
requires NonNullPtr_Convertible<OtherType*, Type*> requires NonNullPtr_Convertible<OtherType*, Type*>
NonNullPtr(const NonNullPtr<OtherType>& otherPtr) constexpr NonNullPtr(const NonNullPtr<OtherType>& otherPtr)
: InternalPtr(otherPtr.Get()) : InternalPtr(otherPtr.Get())
{ {
Assert(InternalPtr, "Fatal Error: Assigned a non null ptr using another NonNullPtr but its was null."); Assert(InternalPtr, "Fatal Error: Assigned a non null ptr using another NonNullPtr but its was null.");
} }
// Assignment // Assignment
NonNullPtr& operator=(Type* ptr) [[nodiscard]] constexpr NonNullPtr& operator=(Type* ptr)
{ {
Assert(ptr, "Tried to assign a null pointer to a NonNullPtr!"); Assert(ptr, "Tried to assign a null pointer to a NonNullPtr!");
InternalPtr = ptr; InternalPtr = ptr;
@@ -39,68 +39,71 @@ namespace Juliet
template <typename OtherType> template <typename OtherType>
requires NonNullPtr_Convertible<OtherType*, Type*> requires NonNullPtr_Convertible<OtherType*, Type*>
NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr) [[nodiscard]] constexpr NonNullPtr& operator=(const NonNullPtr<OtherType>& otherPtr)
{ {
InternalPtr = otherPtr.Get(); InternalPtr = otherPtr.Get();
return *this; return *this;
} }
// Accessors // Accessors
operator Type*() const [[nodiscard]] constexpr operator Type*() const
{ {
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null"); Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr; return InternalPtr;
} }
Type* Get() const [[nodiscard]] constexpr Type* Get() const
{ {
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null"); Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr; return InternalPtr;
} }
Type& operator*() const [[nodiscard]] constexpr Type& operator*() const
{ {
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null"); Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return *InternalPtr; return *InternalPtr;
} }
inline Type* operator->() const [[nodiscard]] constexpr Type* operator->() const
{ {
Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null"); Assert(InternalPtr, "NonNullPtr: Internal Pointer is Null");
return InternalPtr; return InternalPtr;
} }
// Comparisons // 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> template <typename OtherType>
requires NonNullPtr_SameType<Type, OtherType> requires NonNullPtr_SameType<Type, OtherType>
bool operator==(OtherType* otherRawPtr) const [[nodiscard]] constexpr bool operator==(OtherType* otherRawPtr) const
{ {
return InternalPtr == otherRawPtr; return InternalPtr == otherRawPtr;
} }
template <typename OtherType> template <typename OtherType>
requires NonNullPtr_SameType<Type, 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; return otherRawPtr == nonNullPtr.InternalPtr;
} }
// Forbid assigning a nullptr at compile time // Forbid assigning a nullptr at compile time
NonNullPtr(std::nullptr_t) constexpr NonNullPtr(std::nullptr_t)
: InternalPtr(nullptr) : InternalPtr(nullptr)
{ {
static_assert(sizeof(Type) == 0, "Trying to initialize a NonNullPtr with a nullptr value"); 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"); static_assert(sizeof(Type) == 0, "Trying to assign a NonNullPtr with a nullptr value");
return *this; return *this;
} }
explicit operator bool() const { return true; } [[nodiscard]] constexpr explicit operator bool() const { return InternalPtr != nullptr; }
private: private:
Type* InternalPtr; Type* InternalPtr;
+5
View File
@@ -18,12 +18,16 @@ namespace Juliet
Count = 0; Count = 0;
Capacity = 0; Capacity = 0;
Arena = arena; Arena = arena;
ArenaPosAtCreation = ArenaPos(Arena);
Reserve(ReserveSize); Reserve(ReserveSize);
} }
void Destroy() void Destroy()
{ {
Assert(ArenaPos(Arena) == ArenaPosAtCreation + sizeof(Type) * Capacity);
ArenaPopTo(Arena, ArenaPosAtCreation);
DataFirst = DataLast = Data = nullptr; DataFirst = DataLast = Data = nullptr;
Count = 0; Count = 0;
Capacity = 0; Capacity = 0;
@@ -203,6 +207,7 @@ namespace Juliet
Type* Data = nullptr; Type* Data = nullptr;
size_t Count = 0; size_t Count = 0;
size_t Capacity = 0; size_t Capacity = 0;
index_t ArenaPosAtCreation = 0;
JULIET_DEBUG_ONLY(const char* Name = "VectorArena";) JULIET_DEBUG_ONLY(const char* Name = "VectorArena";)
}; };
static_assert(std::is_standard_layout_v<VectorArena<int>>, static_assert(std::is_standard_layout_v<VectorArena<int>>,
+2 -2
View File
@@ -15,9 +15,9 @@ namespace Juliet
struct Arena; struct Arena;
struct GameInitParams struct GameData
{ {
Arena* GameArena; struct GameState* GameState;
Arena* ScratchArena; Arena* ScratchArena;
}; };
-18
View File
@@ -12,14 +12,6 @@ namespace Juliet
constexpr global uint64 g_Arena_Default_Commit_Size = Kilobytes(64); constexpr global uint64 g_Arena_Default_Commit_Size = Kilobytes(64);
constexpr global uint64 k_ArenaHeaderSize = 128; constexpr global uint64 k_ArenaHeaderSize = 128;
struct ArenaFreeNode
{
ArenaFreeNode* Next;
ArenaFreeNode* Previous;
index_t Position;
size_t Size;
};
#if JULIET_DEBUG #if JULIET_DEBUG
struct ArenaDebugInfo; struct ArenaDebugInfo;
#endif #endif
@@ -41,10 +33,6 @@ namespace Juliet
Arena* FreeBlockLast; Arena* FreeBlockLast;
ArenaFreeNode* FreeNodes;
bool AllowRealloc : 1;
JULIET_DEBUG_ONLY(uint16 LostNodeCount;) JULIET_DEBUG_ONLY(uint16 LostNodeCount;)
JULIET_DEBUG_ONLY(bool CanReserveMore : 1;) JULIET_DEBUG_ONLY(bool CanReserveMore : 1;)
@@ -66,9 +54,6 @@ namespace Juliet
uint64 ReserveSize = g_Arena_Default_Reserve_Size; uint64 ReserveSize = g_Arena_Default_Reserve_Size;
uint64 CommitSize = g_Arena_Default_Commit_Size; uint64 CommitSize = g_Arena_Default_Commit_Size;
// True: All push will be 32 bytes minimum
bool AllowRealloc = false;
// When false, will assert if a new block is reserved. // When false, will assert if a new block is reserved.
JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;) JULIET_DEBUG_ONLY(bool CanReserveMore : 1 = true;)
}; };
@@ -77,12 +62,9 @@ namespace Juliet
const std::source_location& loc = std::source_location::current()); const std::source_location& loc = std::source_location::current());
JULIET_API void ArenaRelease(NonNullPtr<Arena> arena); 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 // Raw Push, can be used but templated helpers exists below
[[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align, [[nodiscard]] JULIET_API void* ArenaPush(NonNullPtr<Arena> arena, size_t size, size_t align,
bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag)); bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag));
[[nodiscard]] JULIET_API void* ArenaReallocate(NonNullPtr<Arena> arena, void* oldPtr, size_t oldSize, size_t newSize,
size_t align, bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag));
JULIET_API void ArenaPopTo(NonNullPtr<Arena> arena, size_t position); JULIET_API void ArenaPopTo(NonNullPtr<Arena> arena, size_t position);
JULIET_API void ArenaPop(NonNullPtr<Arena> arena, size_t amount); JULIET_API void ArenaPop(NonNullPtr<Arena> arena, size_t amount);
JULIET_API void ArenaClear(NonNullPtr<Arena> arena); JULIET_API void ArenaClear(NonNullPtr<Arena> arena);
+5 -3
View File
@@ -11,7 +11,7 @@ namespace Juliet
{ {
void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename) 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. // Get the app base path and build the dll path from there.
String basePath = GetBasePath(); String basePath = GetBasePath();
@@ -25,7 +25,8 @@ namespace Juliet
const size_t dllFullPathLength = const size_t dllFullPathLength =
basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings 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)); int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName));
if (writtenSize < static_cast<int>(dllFullPathLength) - 1) if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
{ {
@@ -38,7 +39,8 @@ namespace Juliet
// Lock filename path // Lock filename path
const size_t lockPathLength = const size_t lockPathLength =
basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings 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)); writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename));
if (writtenSize < static_cast<int>(lockPathLength) - 1) if (writtenSize < static_cast<int>(lockPathLength) - 1)
{ {
@@ -112,11 +112,10 @@ namespace Juliet
else else
{ {
code.IsValid = false; code.IsValid = false;
break;
} }
} }
} }
// Scratch memory, no free needed
} }
if (!code.IsValid) if (!code.IsValid)
-104
View File
@@ -18,12 +18,6 @@ namespace Juliet
constexpr uint64 k_PageSize = Kilobytes(4); constexpr uint64 k_PageSize = Kilobytes(4);
} // namespace } // namespace
namespace
{
static_assert(sizeof(ArenaFreeNode) == 32, "ArenaFreeNode should be 32 bytes and not more");
constexpr size_t k_ArenaFreeNodeSize = sizeof(ArenaFreeNode);
} // namespace
// https://github.com/EpicGamesExt/raddebugger/blob/master/src/base/base_arena.c // https://github.com/EpicGamesExt/raddebugger/blob/master/src/base/base_arena.c
Arena* ArenaAllocate(const ArenaParams& params JULIET_DEBUG_ONLY(, const char* name), const std::source_location& loc) Arena* ArenaAllocate(const ArenaParams& params JULIET_DEBUG_ONLY(, const char* name), const std::source_location& loc)
@@ -51,9 +45,6 @@ namespace Juliet
arena->BasePosition = 0; arena->BasePosition = 0;
arena->Position = k_ArenaHeaderSize; arena->Position = k_ArenaHeaderSize;
arena->FreeNodes = nullptr;
arena->AllowRealloc = params.AllowRealloc;
#if JULIET_DEBUG #if JULIET_DEBUG
arena->CanReserveMore = params.CanReserveMore; arena->CanReserveMore = params.CanReserveMore;
arena->FirstDebugInfo = nullptr; arena->FirstDebugInfo = nullptr;
@@ -86,52 +77,6 @@ namespace Juliet
size_t positionPrePush = AlignPow2(current->Position, align); size_t positionPrePush = AlignPow2(current->Position, align);
size_t positionPostPush = positionPrePush + size; size_t positionPostPush = positionPrePush + size;
if (arena->AllowRealloc)
{
size = Max(size, k_ArenaFreeNodeSize);
for (ArenaFreeNode* freeNode = current->FreeNodes; freeNode != nullptr; freeNode = freeNode->Next)
{
if (size <= freeNode->Size)
{
index_t position = freeNode->Position;
size_t remainingSize = freeNode->Size - size;
if (remainingSize < k_ArenaFreeNodeSize)
{
ArenaFreeNode* previous = freeNode->Previous;
ArenaFreeNode* next = freeNode->Next;
if (previous)
{
previous->Next = next;
}
if (next)
{
next->Previous = previous;
}
#if JULIET_DEBUG
if (remainingSize > 0)
{
++current->LostNodeCount;
}
#endif
}
else
{
freeNode->Position += size;
}
auto* result = reinterpret_cast<Byte*>(current) + position;
if (shouldBeZeroed)
{
MemoryZero(result, size);
}
return result;
}
}
}
// If allowed and needed, add a new block and chain it to the arena. // If allowed and needed, add a new block and chain it to the arena.
if (current->Reserved < positionPostPush /* flags : chaining allowed */) if (current->Reserved < positionPostPush /* flags : chaining allowed */)
{ {
@@ -225,55 +170,6 @@ namespace Juliet
return result; return result;
} }
void* ArenaReallocate(NonNullPtr<Arena> arena, void* oldPtr, size_t oldSize, size_t newSize, size_t align,
bool shouldBeZeroed JULIET_DEBUG_ONLY(, const char* tag))
{
void* result = ArenaPush(arena, newSize, align, shouldBeZeroed JULIET_DEBUG_ONLY(, tag));
// Find the correct block to release
Arena* block = nullptr;
for (block = arena->Current; block != nullptr; block = block->Previous)
{
if ((reinterpret_cast<Byte*>(block) < static_cast<Byte*>(oldPtr)) &&
(static_cast<Byte*>(oldPtr) <= (reinterpret_cast<Byte*>(block) + block->Reserved)))
{
break;
}
}
Assert(block != nullptr);
// Copy old to new
MemCopy(result, oldPtr, std::min(oldSize, newSize));
// Zero the old memory
MemoryZero(oldPtr, oldSize);
if (oldSize >= sizeof(ArenaFreeNode))
{
ArenaFreeNode* freeNode = static_cast<ArenaFreeNode*>(oldPtr);
ptrdiff_t posPtr = static_cast<Byte*>(oldPtr) - reinterpret_cast<Byte*>(block);
index_t position = static_cast<index_t>(posPtr);
freeNode->Position = position;
freeNode->Size = oldSize;
// Insert at head of the free list
freeNode->Next = block->FreeNodes;
freeNode->Previous = nullptr;
if (block->FreeNodes)
{
block->FreeNodes->Previous = freeNode;
}
block->FreeNodes = freeNode;
#if JULIET_DEBUG
// Remove the debug info for the old allocation (since it's now free)
size_t oldOffset = static_cast<size_t>(static_cast<Byte*>(oldPtr) - reinterpret_cast<Byte*>(block));
DebugArenaRemoveAllocation(block, oldOffset);
#endif
}
return result;
}
void ArenaPopTo(NonNullPtr<Arena> arena, size_t position) void ArenaPopTo(NonNullPtr<Arena> arena, size_t position)
{ {
size_t clampedPosition = ClampBottom(k_ArenaHeaderSize, position); size_t clampedPosition = ClampBottom(k_ArenaHeaderSize, position);
@@ -117,60 +117,6 @@ namespace Juliet::UnitTest
ArenaRelease(testArena); ArenaRelease(testArena);
{
// Test reallocate
Arena* arena = ArenaAllocate({ .AllowRealloc = true } JULIET_DEBUG_ONLY(, "Test Realloc"));
char* charArray = ArenaPushArray<char>(arena, 128);
char* secondCharArray = ArenaPushArray<char>(arena, 128);
char* thirdCharArray = ArenaPushArray<char>(arena, 128);
secondCharArray = static_cast<char*>(ArenaReallocate(arena, secondCharArray, 128, 256, alignof(char), true JULIET_DEBUG_ONLY(, "ReallocChar")));
char* fourthCharArray = ArenaPushArray<char>(arena, 128);
Assert(charArray);
Assert(secondCharArray);
Assert(thirdCharArray);
Assert(fourthCharArray);
ArenaRelease(arena);
}
{
// Test Reallocate Shrink (Buffer Overflow Bug Check)
Arena* arena = ArenaAllocate({ .AllowRealloc = true } JULIET_DEBUG_ONLY(, "Test Shrink"));
size_t largeSize = 100;
char* large = ArenaPushArray<char>(arena, largeSize);
MemSet(large, 'A', largeSize);
size_t smallSize = 50;
char* smallData = static_cast<char*>(ArenaReallocate(arena, large, largeSize, smallSize, alignof(char), true JULIET_DEBUG_ONLY(, "ResizeSmall")));
for (size_t i = 0; i < smallSize; ++i)
{
Assert(smallData[i] == 'A');
}
// Allocate next block (should be immediately after 'small')
// Don't zero it, if overflow happened it will contain 'A's
char* next = static_cast<char*>(ArenaPush(arena, 50, alignof(char), false JULIET_DEBUG_ONLY(, "OverflowCheck")));
bool corrupted = false;
for(size_t i = 0; i < 50; ++i)
{
if (next[i] == 'A')
{
corrupted = true;
break;
}
}
Assert(!corrupted);
ArenaRelease(arena);
}
printf("All Paged MemoryArena tests passed.\n"); printf("All Paged MemoryArena tests passed.\n");
} }
} // namespace Juliet::UnitTest } // namespace Juliet::UnitTest
@@ -450,24 +450,6 @@ namespace Juliet::Debug
info = info->Next; info = info->Next;
ImGui::PopID(); ImGui::PopID();
} }
// Draw Free Nodes (Holes) if Realloc is enabled
if (arena->AllowRealloc && blk->FreeNodes)
{
ArenaFreeNode* freeNode = blk->FreeNodes;
while (freeNode)
{
float fxStart = pos.x + static_cast<float>(static_cast<double>(freeNode->Position) * scale);
float fWidth = static_cast<float>(static_cast<double>(freeNode->Size) * scale);
ImVec2 fMin(fxStart, pos.y + 1);
ImVec2 fMax(fxStart + fWidth, pos.y + blockHeight - 1);
dl->AddRectFilled(fMin, fMax, IM_COL32(50, 50, 50, 200));
freeNode = freeNode->Next;
}
}
} }
pos.y += blockHeight + blockSpacing; pos.y += blockHeight + blockSpacing;
+2 -1
View File
@@ -154,7 +154,8 @@ namespace Juliet
void InitializeEngine(JulietInit_Flags flags) void InitializeEngine(JulietInit_Flags flags)
{ {
EngineInstance.PlatformArena = ArenaAllocate({ .AllowRealloc = true } JULIET_DEBUG_PARAM("Platform Arena")); EngineInstance.PlatformArena =
ArenaAllocate({ .ReserveSize = Megabytes(128) } JULIET_DEBUG_PARAM("Platform Arena"));
InitializeLogManager(); InitializeLogManager();
@@ -549,8 +549,8 @@ namespace Juliet::D3D12
driver->D3D12SerializeVersionedRootSignatureFct = nullptr; driver->D3D12SerializeVersionedRootSignatureFct = nullptr;
Assert(ArenaPos(driver->DriverArena) == sizeof(D3D12Driver)); // Verify we didnt forget to release something
ArenaRelease(driver->DriverArena); ArenaRelease(driver->DriverArena);
Free(driver.Get());
} }
bool AttachToWindow(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window) bool AttachToWindow(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window)
@@ -698,10 +698,10 @@ namespace Juliet::D3D12
GraphicsDevice* CreateGraphicsDevice(bool enableDebug) 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 = driverArena;
driver->DriverArena = ArenaAllocate({} JULIET_DEBUG_ONLY(, "D3D12 Driver"));
#if JULIET_DEBUG #if JULIET_DEBUG
#ifdef IDXGIINFOQUEUE_SUPPORTED #ifdef IDXGIINFOQUEUE_SUPPORTED
@@ -517,13 +517,21 @@ namespace Juliet::D3D12
// Fix SRV format for Depth Buffers (TypeLess -> Typed) // Fix SRV format for Depth Buffers (TypeLess -> Typed)
if (createInfo.Format == TextureFormat::D32_FLOAT) if (createInfo.Format == TextureFormat::D32_FLOAT)
{
srvDesc.Format = DXGI_FORMAT_R32_FLOAT; srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
}
else if (createInfo.Format == TextureFormat::D16_UNORM) else if (createInfo.Format == TextureFormat::D16_UNORM)
{
srvDesc.Format = DXGI_FORMAT_R16_UNORM; srvDesc.Format = DXGI_FORMAT_R16_UNORM;
}
else if (createInfo.Format == TextureFormat::D24_UNORM_S8_UINT) else if (createInfo.Format == TextureFormat::D24_UNORM_S8_UINT)
{
srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
}
else if (createInfo.Format == TextureFormat::D32_FLOAT_S8_UINT) else if (createInfo.Format == TextureFormat::D32_FLOAT_S8_UINT)
{
srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; srvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
}
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
+2 -2
View File
@@ -58,7 +58,6 @@ namespace Juliet
{ {
if (GraphicsDevice* newDevice = chosenFactory->CreateGraphicsDevice(config.EnableDebug)) if (GraphicsDevice* newDevice = chosenFactory->CreateGraphicsDevice(config.EnableDebug))
{ {
newDevice->Name = chosenFactory->Name; newDevice->Name = chosenFactory->Name;
return newDevice; return newDevice;
} }
@@ -371,7 +370,8 @@ namespace Juliet
GraphicsBuffer* CreateGraphicsBuffer(NonNullPtr<GraphicsDevice> device, const BufferCreateInfo& createInfo) 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) GraphicsTransferBuffer* CreateGraphicsTransferBuffer(NonNullPtr<GraphicsDevice> device, const TransferBufferCreateInfo& createInfo)
+5 -16
View File
@@ -87,17 +87,16 @@ using namespace Juliet;
namespace namespace
{ {
using GameInit_t = void (*)(GameInitParams*);
using GameShutdown_t = void (*)(void); using GameShutdown_t = void (*)(void);
using GameUpdate_t = void (*)(float deltaTime); using GameUpdate_t = void (*)(GameData* params, float deltaTime);
struct GameFunctionTable struct GameFunctionTable
{ {
GameInit_t Init = nullptr;
GameShutdown_t Shutdown = nullptr; GameShutdown_t Shutdown = nullptr;
GameUpdate_t Update = nullptr; GameUpdate_t Update = nullptr;
} Game; } Game;
GameData Data;
const char* GameFunctionTable[] = { "GameInit", "GameShutdown", "GameUpdate" }; const char* GameFunctionTable[] = { "GameShutdown", "GameUpdate" };
LightID RedLightID = 0; LightID RedLightID = 0;
LightID BlueLightID = 0; LightID BlueLightID = 0;
@@ -178,13 +177,7 @@ void JulietApplication::Init(NonNullPtr<Arena>)
GameCode.FunctionCount = ArraySize(GameFunctionTable); GameCode.FunctionCount = ArraySize(GameFunctionTable);
GameCode.FunctionNames = GameFunctionTable; GameCode.FunctionNames = GameFunctionTable;
InitHotReloadCode(GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp")); InitHotReloadCode(GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp"));
if ((Running = GameCode.IsValid)) 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);
}
} }
} }
@@ -429,8 +422,6 @@ void JulietApplication::Update()
ImGui::End(); ImGui::End();
#endif #endif
ArenaClear(GameScratchArena);
Vector3 redLightPos = { 5.0f, 5.0f, 2.0f }; Vector3 redLightPos = { 5.0f, 5.0f, 2.0f };
Vector3 blueLightPos = { -5.0f, 0.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(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); 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)) if (ShouldReloadCode(GameCode))
{ {
@@ -545,8 +536,6 @@ void JulietApplication::Update()
Debug::DebugDrawMemoryArena(); Debug::DebugDrawMemoryArena();
#endif #endif
} }
ArenaClear(GameScratchArena);
} }
void JulietApplication::OnPreRender(CommandList* /*cmd*/) {} void JulietApplication::OnPreRender(CommandList* /*cmd*/) {}
-2
View File
@@ -43,8 +43,6 @@ class JulietApplication : public Juliet::IApplication
Juliet::HotReloadCode GameCode = {}; Juliet::HotReloadCode GameCode = {};
Juliet::GraphicsPipeline* GraphicsPipeline = {}; Juliet::GraphicsPipeline* GraphicsPipeline = {};
Juliet::Texture* DepthBuffer = {}; Juliet::Texture* DepthBuffer = {};
Juliet::Arena* GameArena = nullptr;
Juliet::Arena* GameScratchArena = nullptr;
int AutoCloseFrameCount = -1; int AutoCloseFrameCount = -1;
bool Running = false; 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.ActiveCfg = Release|x64
{c7df05fe-d5d5-db2a-af36-e7d71d325fda}.Release|x64.Build.0 = 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.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.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.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.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.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.ActiveCfg = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE 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.ActiveCfg = Release|x64
{767620a7-b286-e7a1-9f79-3e14ce9e5ab1}.Release|x64.Build.0 = 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.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.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.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.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.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.ActiveCfg = Release|x64
{652d3fea-b417-1d5e-9f79-3f32e9604ddc}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE 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" }; const char* configs[] = { "Debug", "Profile", "Release" };
for (int c = 0; c < 3; c++) { for (int c = 0; c < 3; c++) {
offset += sprintf_s(buf + offset, (4 * 1024 * 1024) - offset, offset += sprintf_s(buf + offset, (4 * 1024 * 1024) - offset,
" {%s}.%s|x64.ActiveCfg = %s|x64\n" " {%s}.%s|x64.ActiveCfg = %s|x64\n",
" {%s}.%s|x64.Build.0 = %s|x64\n",
projectGuids[i], configs[c], configs[c],
projectGuids[i], configs[c], configs[c]); 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]);
}
} }
} }