- Added basic filesystem method to get the base path of the app
- Added hot reload support of the game dll - various changes and refactor
This commit is contained in:
@@ -48,10 +48,9 @@
|
||||
<PropertyGroup Label="UserMacros"/>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)Juliet\include\;$(SolutionDir)Game;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)\bin\$(Platform)\$(Configuration)\;$(LibraryPath)</LibraryPath>
|
||||
<OutDir>$(SolutionDir)\bin\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)Intermediate\$(ProjectName)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
@@ -66,10 +65,15 @@
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)Juliet\include\;$(SolutionDir)Game;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Juliet.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetName)_$(Random).pdb</ProgramDatabaseFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@@ -83,24 +87,21 @@
|
||||
<PreprocessorDefinitions>NDEBUG;CPPDYNAMICLIBRARYTEMPLATE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)Juliet\include\;$(SolutionDir)Game;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>Juliet.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp"/>
|
||||
<ClCompile Include="game.cpp" />
|
||||
<ClCompile Include="Entity\EntityManager.cpp"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Juliet\Juliet.vcxproj">
|
||||
<Project>{1bbc0b92-e4d8-4838-974b-439c5c501e82}</Project>
|
||||
<Name>Juliet</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Entity\Entity.h"/>
|
||||
<ClInclude Include="Entity\EntityManager.h"/>
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
#include <cstdio>
|
||||
#include <windows.h> // TODO: remove because our dll should not be platform dependant
|
||||
|
||||
#include <Entity/Entity.h>
|
||||
#include <Entity/EntityManager.h>
|
||||
|
||||
// Test code
|
||||
namespace Game
|
||||
{
|
||||
struct Door
|
||||
{
|
||||
DECLARE_ENTITY()
|
||||
bool IsOpened;
|
||||
};
|
||||
DEFINE_ENTITY(Door);
|
||||
|
||||
struct Rock
|
||||
{
|
||||
DECLARE_ENTITY()
|
||||
int Health;
|
||||
};
|
||||
DEFINE_ENTITY(Rock);
|
||||
|
||||
} // namespace Game
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
using namespace Game;
|
||||
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
// Entity Use case
|
||||
InitEntityManager();
|
||||
auto& manager = GetEntityManager();
|
||||
Door* door = MakeEntity<Door>(manager, 10.0f, 2.0f);
|
||||
door->IsOpened = true;
|
||||
|
||||
Entity* ent = door->Base;
|
||||
Door* stillDoor = DownCast<Door>(ent);
|
||||
Assert(door == stillDoor);
|
||||
|
||||
Rock* rock = MakeEntity<Rock>(manager, 1.f, 2.f);
|
||||
rock->Health = 100;
|
||||
Assert(door->Base != rock->Base);
|
||||
|
||||
printf("Door is %s\n", door->IsOpened ? "Opened" : "Closed");
|
||||
printf("Rock has %d health points\n", rock->Health);
|
||||
|
||||
// Have to manually free for now because im not using arenas or anything
|
||||
free(door->Base);
|
||||
free(door);
|
||||
free(rock->Base);
|
||||
free(rock);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DLL_THREAD_ATTACH: break;
|
||||
case DLL_THREAD_DETACH: break;
|
||||
case DLL_PROCESS_DETACH: break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
69
Game/game.cpp
Normal file
69
Game/game.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <cstdio>
|
||||
#include <windows.h> // TODO: remove because our dll should not be platform dependant
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Entity/Entity.h>
|
||||
#include <Entity/EntityManager.h>
|
||||
#include <Graphics/Graphics.h>
|
||||
|
||||
// Test code
|
||||
namespace Game
|
||||
{
|
||||
struct Door
|
||||
{
|
||||
DECLARE_ENTITY()
|
||||
bool IsOpened;
|
||||
};
|
||||
DEFINE_ENTITY(Door);
|
||||
|
||||
struct Rock
|
||||
{
|
||||
DECLARE_ENTITY()
|
||||
int Health;
|
||||
};
|
||||
DEFINE_ENTITY(Rock);
|
||||
|
||||
} // namespace Game
|
||||
|
||||
using namespace Juliet;
|
||||
|
||||
extern "C" __declspec(dllexport) void __cdecl GameInit()
|
||||
{
|
||||
using namespace Game;
|
||||
|
||||
// Entity Use case
|
||||
InitEntityManager();
|
||||
auto& manager = GetEntityManager();
|
||||
Door* door = MakeEntity<Door>(manager, 10.0f, 2.0f);
|
||||
door->IsOpened = true;
|
||||
|
||||
Entity* ent = door->Base;
|
||||
Door* stillDoor = DownCast<Door>(ent);
|
||||
Assert(door == stillDoor);
|
||||
|
||||
Rock* rock = MakeEntity<Rock>(manager, 1.f, 2.f);
|
||||
rock->Health = 100;
|
||||
Assert(door->Base != rock->Base);
|
||||
|
||||
printf("Door is %s\n", door->IsOpened ? "Opened" : "Closed");
|
||||
printf("Rock has %d health points\n", rock->Health);
|
||||
|
||||
// Have to manually free for now because im not using arenas or anything
|
||||
free(door->Base);
|
||||
free(door);
|
||||
free(rock->Base);
|
||||
free(rock);
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void __cdecl GameShutdown()
|
||||
{
|
||||
printf("Shutting down game...\n");
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void __cdecl GameUpdate(float deltaTime)
|
||||
{
|
||||
printf("Updating game...\n");
|
||||
}
|
||||
@@ -11,6 +11,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JulietApp", "JulietApp\Juli
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Game", "Game\Game.vcxproj", "{B7B12DCC-1A69-4371-A9FE-D6E7671497B0}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{1BBC0B92-E4D8-4838-974B-439C5C501E82} = {1BBC0B92-E4D8-4838-974B-439C5C501E82}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
||||
@@ -113,16 +113,16 @@
|
||||
<ClInclude Include="include\Core\Common\NonNullPtr.h"/>
|
||||
<ClInclude Include="include\Core\Common\Singleton.h"/>
|
||||
<ClInclude Include="include\Core\Container\Vector.h"/>
|
||||
<ClInclude Include="include\Core\DynLib\DynamicLibrary.h"/>
|
||||
<ClInclude Include="include\Core\HAL\Display\Display.h"/>
|
||||
<ClInclude Include="include\Core\HAL\Event\SystemEvent.h"/>
|
||||
<ClInclude Include="include\Core\HAL\Keyboard\Keyboard.h"/>
|
||||
<ClInclude Include="include\Core\HAL\Keyboard\KeyCode.h"/>
|
||||
<ClInclude Include="include\Core\HAL\Keyboard\ScanCode.h"/>
|
||||
<ClInclude Include="include\Core\HAL\Mouse\Mouse.h"/>
|
||||
<ClInclude Include="include\Core\JulietInit.h"/>
|
||||
<ClInclude Include="include\Core\Logging\LogManager.h"/>
|
||||
<ClInclude Include="include\Core\Logging\LogTypes.h"/>
|
||||
<ClInclude Include="include\Core\HAL\Display\Display.h" />
|
||||
<ClInclude Include="include\Core\HAL\Event\SystemEvent.h" />
|
||||
<ClInclude Include="include\Core\HAL\Keyboard\Keyboard.h" />
|
||||
<ClInclude Include="include\Core\HAL\Keyboard\KeyCode.h" />
|
||||
<ClInclude Include="include\Core\HAL\Keyboard\ScanCode.h" />
|
||||
<ClInclude Include="include\Core\HAL\Mouse\Mouse.h" />
|
||||
<ClInclude Include="include\Core\HotReload\HotReload.h" />
|
||||
<ClInclude Include="include\Core\JulietInit.h" />
|
||||
<ClInclude Include="include\Core\Logging\LogManager.h" />
|
||||
<ClInclude Include="include\Core\Logging\LogTypes.h" />
|
||||
<ClInclude Include="include\Core\Math\Shape.h" />
|
||||
<ClInclude Include="include\Core\Memory\Allocator.h" />
|
||||
<ClInclude Include="include\Core\Memory\Utils.h" />
|
||||
@@ -152,6 +152,8 @@
|
||||
<ClInclude Include="src\Core\HAL\Event\Mouse_Private.h" />
|
||||
<ClInclude Include="src\Core\HAL\Event\Win32ScanCode.h" />
|
||||
<ClInclude Include="src\Core\HAL\Event\WindowEvent.h" />
|
||||
<ClInclude Include="src\Core\HAL\Filesystem\Filesystem_Platform.h" />
|
||||
<ClInclude Include="src\Core\HAL\Filesystem\Filesystem_Private.h" />
|
||||
<ClInclude Include="src\Core\Networking\SocketPlatformImpl.h" />
|
||||
<ClInclude Include="src\Core\HAL\Win32.h" />
|
||||
<ClInclude Include="src\Graphics\D3D12\D3D12Common.h" />
|
||||
@@ -168,69 +170,20 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Core\Application\ApplicationManager.cpp" />
|
||||
<ClCompile Include="src\Core\Common\CoreUtils.cpp" />
|
||||
<ClCompile Include="src\Core\DynLib\Win32\DynamicLibrary.cpp">
|
||||
<RuntimeLibrary>MultiThreadedDebugDll</RuntimeLibrary>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SupportJustMyCode>true</SupportJustMyCode>
|
||||
<AssemblerOutput>NoListing</AssemblerOutput>
|
||||
<AssemblerListingLocation>W:\Classified\Juliet\Intermediate\Juliet\x64\Debug\</AssemblerListingLocation>
|
||||
<UndefineAllPreprocessorDefinitions>false</UndefineAllPreprocessorDefinitions>
|
||||
<BrowseInformationFile>W:\Classified\Juliet\Intermediate\Juliet\x64\Debug\</BrowseInformationFile>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<ConformanceMode>Default</ConformanceMode>
|
||||
<DiagnosticsFormat>Column</DiagnosticsFormat>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<EnableASAN>false</EnableASAN>
|
||||
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<LanguageStandard_C>Default</LanguageStandard_C>
|
||||
<ModuleDependenciesFile>W:\Classified\Juliet\Intermediate\Juliet\x64\Debug\</ModuleDependenciesFile>
|
||||
<OmitDefaultLibName>false</OmitDefaultLibName>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<ObjectFileName>W:\Classified\Juliet\Intermediate\Juliet\x64\Debug\</ObjectFileName>
|
||||
<CallingConvention>Cdecl</CallingConvention>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>W:\Classified\Juliet\Intermediate\Juliet\x64\Debug\Juliet.pch</PrecompiledHeaderOutputFile>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<PreprocessKeepComments>false</PreprocessKeepComments>
|
||||
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
|
||||
<ScanSourceForModuleDependencies>false</ScanSourceForModuleDependencies>
|
||||
<ShowIncludes>false</ShowIncludes>
|
||||
<SourceDependenciesFile>W:\Classified\Juliet\Intermediate\Juliet\x64\Debug\</SourceDependenciesFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||
<TrackerLogDirectory>W:\Classified\Juliet\Intermediate\Juliet\x64\Debug\Juliet.tlog\</TrackerLogDirectory>
|
||||
<MinimalRebuildFromTracking>true</MinimalRebuildFromTracking>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<XMLDocumentationFileName>W:\Classified\Juliet\Intermediate\Juliet\x64\Debug\</XMLDocumentationFileName>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<IntelJCCErratum>false</IntelJCCErratum>
|
||||
<BuildStlModules>false</BuildStlModules>
|
||||
<TreatExternalTemplatesAsInternal>true</TreatExternalTemplatesAsInternal>
|
||||
<PreprocessorDefinitions>_DEBUG;JULIET_EXPORT;JULIET_WIN32;_WINDLL;_UNICODE;UNICODE;</PreprocessorDefinitions>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<LinkCompiled>true</LinkCompiled>
|
||||
<ClangClMode>true</ClangClMode>
|
||||
<MSCVersion>Default</MSCVersion>
|
||||
<AdditionalOptions>--target=amd64-pc-windows-msvc</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Core\HAL\Display\Display.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\Display\Win32\Win32DisplayDevice.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\Display\Win32\Win32DisplayEvent.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\Display\Win32\Win32Window.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\DynLib\Win32\DynamicLibrary.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\Event\Keyboard.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\Event\KeyboardMapping.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\Event\Mouse.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\Event\SystemEvent.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\Event\WindowEvent.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\Filesystem\Filesystem.cpp" />
|
||||
<ClCompile Include="src\Core\HAL\Filesystem\Win32\Win32Filesystem.cpp" />
|
||||
<ClCompile Include="src\Core\HotReload\HotReload.cpp" />
|
||||
<ClCompile Include="src\Core\HotReload\Win32\Win32HotReload.cpp" />
|
||||
<ClCompile Include="src\Core\Juliet.cpp" />
|
||||
<ClCompile Include="src\Core\Logging\LogManager.cpp" />
|
||||
<ClCompile Include="src\Core\Memory\Allocator.cpp" />
|
||||
|
||||
@@ -24,6 +24,14 @@ struct ByteBuffer
|
||||
size_t Size;
|
||||
};
|
||||
|
||||
template <typename CharType>
|
||||
struct StringBuffer
|
||||
{
|
||||
CharType* Data;
|
||||
size_t Size;
|
||||
};
|
||||
#define StringBufferParam(str) { (str), sizeof(str) }
|
||||
|
||||
using FunctionPtr = auto (*)(void) -> void;
|
||||
|
||||
// Limits
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/Common/CoreTypes.h>
|
||||
#include <core/Common/NonNullPtr.h>
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <Juliet.h>
|
||||
|
||||
namespace Juliet
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <core/Common/NonNullPtr.h>
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
struct DynamicLibrary
|
||||
{
|
||||
};
|
||||
struct DynamicLibrary;
|
||||
|
||||
extern JULIET_API DynamicLibrary* LoadDynamicLibrary(const char* filename);
|
||||
extern JULIET_API FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName);
|
||||
7
Juliet/include/Core/HAL/Filesystem/Filesystem.h
Normal file
7
Juliet/include/Core/HAL/Filesystem/Filesystem.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
// Returns the path to the application directory
|
||||
extern JULIET_API char * GetBasePath();
|
||||
}
|
||||
36
Juliet/include/Core/HotReload/HotReload.h
Normal file
36
Juliet/include/Core/HotReload/HotReload.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
// Fwd Declare
|
||||
struct DynamicLibrary;
|
||||
|
||||
struct HotReloadCode
|
||||
{
|
||||
StringBuffer<char> DLLFullPath;
|
||||
StringBuffer<char> LockFullPath;
|
||||
StringBuffer<const char> TransientDLLName;
|
||||
|
||||
uint64 LastWriteTime;
|
||||
|
||||
DynamicLibrary* Dll;
|
||||
|
||||
void** Functions;
|
||||
const char** FunctionNames;
|
||||
uint32 FunctionCount;
|
||||
|
||||
uint32 UniqueID;
|
||||
|
||||
bool IsValid : 1;
|
||||
};
|
||||
|
||||
extern JULIET_API void InitHotReloadCode(HotReloadCode& code, StringBuffer<const char> dllName,
|
||||
StringBuffer<const char> transientDllName, StringBuffer<const char> lockFilename);
|
||||
extern JULIET_API void ShutdownHotReloadCode(HotReloadCode& code);
|
||||
|
||||
extern JULIET_API void LoadCode(HotReloadCode& code);
|
||||
extern JULIET_API void UnloadCode(HotReloadCode& code);
|
||||
|
||||
extern JULIET_API void ReloadCode(HotReloadCode& code);
|
||||
extern JULIET_API bool ShouldReloadCode(const HotReloadCode& code);
|
||||
} // namespace Juliet
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Juliet.h>
|
||||
#include <Core/Common/CoreTypes.h>
|
||||
|
||||
// TODO : Juliet strings
|
||||
#include <string>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <core/Common/CoreTypes.h>
|
||||
#include <memory>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
@@ -21,8 +21,10 @@ namespace Juliet
|
||||
template <typename Type>
|
||||
void SafeFree(Type*& memory)
|
||||
{
|
||||
Assert(memory);
|
||||
free(memory);
|
||||
memory = nullptr;
|
||||
if (memory)
|
||||
{
|
||||
free(memory);
|
||||
memory = nullptr;
|
||||
}
|
||||
}
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -5,4 +5,13 @@
|
||||
namespace Juliet
|
||||
{
|
||||
using Thread = std::thread;
|
||||
|
||||
// TODO : Proper wait
|
||||
inline void wait_ms(int milliseconds)
|
||||
{
|
||||
clock_t start_time = clock();
|
||||
while (clock() < start_time + milliseconds)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Juliet::Win32
|
||||
ReleaseDC(state->Handle, state->HDC);
|
||||
DestroyWindow(state->Handle);
|
||||
|
||||
Free(state);
|
||||
SafeFree(state);
|
||||
}
|
||||
window->State = nullptr;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include <Core/DynLib/DynamicLibrary.h>
|
||||
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
||||
#include <Core/HAL/Win32.h>
|
||||
|
||||
namespace Juliet
|
||||
@@ -10,7 +10,7 @@ namespace Juliet
|
||||
// TODO : Move into string file
|
||||
// Use portable code + pass the memory array into parameter and not use new
|
||||
// This is from http://www.rohitab.com/discuss/topic/41257-char-to-lpcwstr/
|
||||
wchar_t* UTF8ToWideChar(const char* utf8)
|
||||
static wchar_t* UTF8ToWideChar(const char* utf8)
|
||||
{
|
||||
wchar_t* w;
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Juliet
|
||||
|
||||
FunctionPtr LoadFunction(NonNullPtr<DynamicLibrary> lib, const char* functionName)
|
||||
{
|
||||
auto function = (FunctionPtr)GetProcAddress(reinterpret_cast<HMODULE>(lib.Get()), functionName);
|
||||
auto function = reinterpret_cast<FunctionPtr>(GetProcAddress(reinterpret_cast<HMODULE>(lib.Get()), functionName));
|
||||
if (!function)
|
||||
{
|
||||
Log(LogLevel::Error, LogCategory::Core, "Failed loading %s", functionName);
|
||||
32
Juliet/src/Core/HAL/Filesystem/Filesystem.cpp
Normal file
32
Juliet/src/Core/HAL/Filesystem/Filesystem.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem_Private.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem_Platform.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
namespace
|
||||
{
|
||||
char* CachedBasePath = nullptr;
|
||||
}
|
||||
char* GetBasePath()
|
||||
{
|
||||
if (CachedBasePath == nullptr)
|
||||
{
|
||||
CachedBasePath = Platform::GetBasePath();
|
||||
}
|
||||
return CachedBasePath;
|
||||
}
|
||||
|
||||
void InitFilesystem() {}
|
||||
|
||||
void ShutdownFilesystem()
|
||||
{
|
||||
if (CachedBasePath != nullptr)
|
||||
{
|
||||
SafeFree(CachedBasePath);
|
||||
}
|
||||
}
|
||||
} // namespace Juliet
|
||||
6
Juliet/src/Core/HAL/Filesystem/Filesystem_Platform.h
Normal file
6
Juliet/src/Core/HAL/Filesystem/Filesystem_Platform.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace Juliet::Platform
|
||||
{
|
||||
extern char* GetBasePath();
|
||||
}
|
||||
7
Juliet/src/Core/HAL/Filesystem/Filesystem_Private.h
Normal file
7
Juliet/src/Core/HAL/Filesystem/Filesystem_Private.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
extern void InitFilesystem();
|
||||
extern void ShutdownFilesystem();
|
||||
}
|
||||
90
Juliet/src/Core/HAL/Filesystem/Win32/Win32Filesystem.cpp
Normal file
90
Juliet/src/Core/HAL/Filesystem/Win32/Win32Filesystem.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include <Core/HAL/Filesystem/Filesystem_Platform.h>
|
||||
#include <Core/HAL/Win32.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
|
||||
namespace Juliet::Platform
|
||||
{
|
||||
namespace
|
||||
{
|
||||
// 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* result = nullptr;
|
||||
size_t length = WideCharToMultiByte(CP_UTF8, 0, wcharStr, -1, nullptr, 0, nullptr, nullptr);
|
||||
if (length <= 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
result = new char[length];
|
||||
if (!result)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, wcharStr, -1, result, length, nullptr, nullptr) <= 0)
|
||||
{
|
||||
delete[] result;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
char* 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<WCHAR> buffer{ .Data = nullptr, .Size = MAX_PATH };
|
||||
buffer.Data = static_cast<WCHAR*>(Calloc(MAX_PATH, sizeof(WCHAR)));
|
||||
if (buffer.Data == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t moduleFilenameLength = 0;
|
||||
while (true)
|
||||
{
|
||||
moduleFilenameLength = GetModuleFileNameW(nullptr, buffer.Data, static_cast<uint32>(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<WCHAR*>(Realloc(buffer.Data, buffer.Size * sizeof(WCHAR)));
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (moduleFilenameLength == 0)
|
||||
{
|
||||
SafeFree(buffer.Data);
|
||||
Log(LogLevel::Error, LogCategory::Core, "Filesystem: Cannot locate executable path");
|
||||
}
|
||||
|
||||
size_t idx = 0;
|
||||
for (idx = moduleFilenameLength - 1; idx > 0; --idx)
|
||||
{
|
||||
if (buffer.Data[idx] == '\\')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert(idx > 0 && "Path is not absolute!");
|
||||
buffer.Data[idx + 1] = '\0'; // Chop chop
|
||||
|
||||
// TODO: Add utils to Convert to/from UTF8W
|
||||
char* basePath = WideCharToUTF8(buffer.Data);
|
||||
SafeFree(buffer.Data);
|
||||
return basePath;
|
||||
}
|
||||
} // namespace Juliet::Platform
|
||||
70
Juliet/src/Core/HotReload/HotReload.cpp
Normal file
70
Juliet/src/Core/HotReload/HotReload.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||
#include <Core/HotReload/HotReload.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Core/Thread/Thread.h>
|
||||
|
||||
#define MAX_TRIES 100
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
void InitHotReloadCode(HotReloadCode& code, StringBuffer<const char> dllName,
|
||||
StringBuffer<const char> transientDllName, StringBuffer<const char> lockFilename)
|
||||
{
|
||||
// Get the app base path and build the dll path from there.
|
||||
const char* basePath = GetBasePath();
|
||||
size_t basePathLength = strlen(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;
|
||||
code.DLLFullPath.Data = static_cast<char*>(Calloc(dllFullPathLength, sizeof(char)));
|
||||
int writtenSize = snprintf(code.DLLFullPath.Data, dllFullPathLength, "%s%s", basePath, dllName.Data);
|
||||
if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
|
||||
{
|
||||
SafeFree(code.DLLFullPath.Data);
|
||||
Log(LogLevel::Error, LogCategory::Core, "Cannot create DLL Full Path");
|
||||
return;
|
||||
}
|
||||
code.DLLFullPath.Size = writtenSize + 1;
|
||||
|
||||
// Lock filename path
|
||||
const size_t lockPathLength = basePathLength + lockFilename.Size;
|
||||
code.LockFullPath.Data = static_cast<char*>(Calloc(lockPathLength, sizeof(char)));
|
||||
writtenSize = snprintf(code.LockFullPath.Data, lockPathLength, "%s%s", basePath, lockFilename.Data);
|
||||
if (writtenSize < static_cast<int>(lockPathLength) - 1)
|
||||
{
|
||||
code.LockFullPath.Size = 0;
|
||||
SafeFree(code.LockFullPath.Data);
|
||||
Log(LogLevel::Error, LogCategory::Core, "Cannot create lock file full path");
|
||||
return;
|
||||
}
|
||||
code.LockFullPath.Size = writtenSize + 1;
|
||||
|
||||
LoadCode(code);
|
||||
}
|
||||
|
||||
void ShutdownHotReloadCode(HotReloadCode& code)
|
||||
{
|
||||
UnloadCode(code);
|
||||
|
||||
code.DLLFullPath.Size = 0;
|
||||
SafeFree(code.DLLFullPath.Data);
|
||||
code.LockFullPath.Size = 0;
|
||||
SafeFree(code.LockFullPath.Data);
|
||||
}
|
||||
|
||||
void ReloadCode(HotReloadCode& code)
|
||||
{
|
||||
UnloadCode(code);
|
||||
for (uint32 tryItr = 0; !code.IsValid && tryItr < MAX_TRIES; ++tryItr)
|
||||
{
|
||||
LoadCode(code);
|
||||
wait_ms(100);
|
||||
}
|
||||
}
|
||||
} // namespace Juliet
|
||||
134
Juliet/src/Core/HotReload/Win32/Win32HotReload.cpp
Normal file
134
Juliet/src/Core/HotReload/Win32/Win32HotReload.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||
#include <Core/HAL/Win32.h>
|
||||
#include <Core/HotReload/HotReload.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
|
||||
#define MAX_ATTEMPT 256
|
||||
#define MAX_DLL_ID 32767
|
||||
#define TEMP_DLL_BUFFER_SIZE_FOR_ID 6 // MAX_DLL_ID + _
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
namespace
|
||||
{
|
||||
FILETIME GetLastWriteTime(const char* filename)
|
||||
{
|
||||
FILETIME lastWriteTime = {};
|
||||
|
||||
WIN32_FILE_ATTRIBUTE_DATA Data;
|
||||
if (GetFileAttributesExA(filename, GetFileExInfoStandard, &Data))
|
||||
{
|
||||
lastWriteTime = Data.ftLastWriteTime;
|
||||
}
|
||||
|
||||
return lastWriteTime;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void LoadCode(HotReloadCode& code)
|
||||
{
|
||||
// TODO : Create and use a TransientAllocator
|
||||
// Create temp dll name
|
||||
|
||||
char* lockFilename = code.LockFullPath.Data;
|
||||
WIN32_FILE_ATTRIBUTE_DATA Ignored;
|
||||
if (!GetFileAttributesExA(lockFilename, GetFileExInfoStandard, &Ignored))
|
||||
{
|
||||
const char* dllName = code.DLLFullPath.Data;
|
||||
|
||||
FILETIME lastWriteTime = GetLastWriteTime(dllName);
|
||||
ULARGE_INTEGER result{ .LowPart = lastWriteTime.dwLowDateTime, .HighPart = lastWriteTime.dwHighDateTime };
|
||||
code.LastWriteTime = result.QuadPart;
|
||||
|
||||
// Create filename for the temp dll until we find a valid id.
|
||||
// This is not infinite, in a big session we could reach the 128 attempts and fail...
|
||||
// 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);
|
||||
|
||||
StringBuffer<char> tempDllPath = {};
|
||||
const size_t tempDllMaxBufferSize = basePathLength + code.TransientDLLName.Size + TEMP_DLL_BUFFER_SIZE_FOR_ID;
|
||||
tempDllPath.Data = static_cast<char*>(Calloc(tempDllMaxBufferSize, sizeof(char)));
|
||||
|
||||
char idToStr[TEMP_DLL_BUFFER_SIZE_FOR_ID];
|
||||
for (uint32 attempt = 0; attempt < MAX_ATTEMPT; ++attempt)
|
||||
{
|
||||
// int to char
|
||||
int idLength = snprintf(idToStr, sizeof(idToStr), "%u", code.UniqueID);
|
||||
|
||||
int writtenSize = snprintf(tempDllPath.Data, tempDllMaxBufferSize, "%s%u_%s", basePath, code.UniqueID,
|
||||
code.TransientDLLName.Data);
|
||||
if (writtenSize < static_cast<int>(basePathLength + idLength + code.TransientDLLName.Size))
|
||||
{
|
||||
SafeFree(tempDllPath.Data);
|
||||
Log(LogLevel::Error, LogCategory::Core, "Cannot create temp full path");
|
||||
return;
|
||||
}
|
||||
tempDllPath.Size = writtenSize + 1;
|
||||
|
||||
if (++code.UniqueID >= MAX_DLL_ID)
|
||||
{
|
||||
code.UniqueID = 0;
|
||||
}
|
||||
if (CopyFileA(dllName, tempDllPath.Data, false))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
code.Dll = LoadDynamicLibrary(tempDllPath.Data);
|
||||
if (code.Dll)
|
||||
{
|
||||
code.IsValid = true;
|
||||
for (size_t FunctionIndex = 0; FunctionIndex < code.FunctionCount; ++FunctionIndex)
|
||||
{
|
||||
if (auto function = reinterpret_cast<void*>(LoadFunction(code.Dll, code.FunctionNames[FunctionIndex])))
|
||||
{
|
||||
code.Functions[FunctionIndex] = function;
|
||||
}
|
||||
else
|
||||
{
|
||||
code.IsValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SafeFree(tempDllPath.Data);
|
||||
tempDllPath = {};
|
||||
}
|
||||
|
||||
if (!code.IsValid)
|
||||
{
|
||||
UnloadCode(code);
|
||||
}
|
||||
}
|
||||
|
||||
void UnloadCode(HotReloadCode& code)
|
||||
{
|
||||
code.IsValid = false;
|
||||
UnloadDynamicLibrary(code.Dll);
|
||||
code.Dll = nullptr;
|
||||
|
||||
code.LastWriteTime = 0;
|
||||
ZeroDynArray(code.FunctionCount, code.Functions);
|
||||
}
|
||||
|
||||
bool ShouldReloadCode(const HotReloadCode& code)
|
||||
{
|
||||
ULARGE_INTEGER largeInt = {};
|
||||
FILETIME codeLastWriteTime = {};
|
||||
largeInt.QuadPart = code.LastWriteTime;
|
||||
codeLastWriteTime.dwHighDateTime = largeInt.HighPart;
|
||||
codeLastWriteTime.dwLowDateTime = largeInt.LowPart;
|
||||
|
||||
FILETIME lastWriteTime = GetLastWriteTime(code.DLLFullPath.Data);
|
||||
int compare = CompareFileTime(&lastWriteTime, &codeLastWriteTime);
|
||||
return compare != 0;
|
||||
}
|
||||
} // namespace Juliet
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <Core/Common/EnumUtils.h>
|
||||
#include <Core/HAL/Display/Display_Private.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem_Private.h>
|
||||
#include <Core/JulietInit.h>
|
||||
|
||||
namespace Juliet
|
||||
@@ -40,6 +41,10 @@ namespace Juliet
|
||||
|
||||
void JulietInit(JulietInit_Flags flags)
|
||||
{
|
||||
// Mandatory systems
|
||||
InitFilesystem();
|
||||
|
||||
// Optional systems
|
||||
if ((flags | JulietInit_Flags::Display) != JulietInit_Flags::None)
|
||||
{
|
||||
InitializeDisplaySystem();
|
||||
@@ -55,6 +60,8 @@ namespace Juliet
|
||||
DecrementSystemRefCount(JulietInit_Flags::Display);
|
||||
ShutdownDisplaySystem();
|
||||
}
|
||||
|
||||
ShutdownFilesystem();
|
||||
}
|
||||
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -37,22 +37,11 @@ namespace Juliet
|
||||
EngineInstance.Application = nullptr;
|
||||
}
|
||||
|
||||
// Todo: proper fixed tick
|
||||
void wait_ms(int milliseconds)
|
||||
{
|
||||
clock_t start_time = clock();
|
||||
while (clock() < start_time + milliseconds)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void RunEngine()
|
||||
{
|
||||
while (EngineInstance.Application->IsRunning())
|
||||
{
|
||||
EngineInstance.Application->Update();
|
||||
|
||||
wait_ms(16);
|
||||
}
|
||||
}
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -392,7 +392,7 @@ namespace Juliet::D3D12
|
||||
}
|
||||
}
|
||||
|
||||
Free(commandList->PresentDatas);
|
||||
SafeFree(commandList->PresentDatas);
|
||||
Free(commandList.Get());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include <core/Common/NonNullPtr.h>
|
||||
#include <Core/DynLib/DynamicLibrary.h>
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
#include <Graphics/D3D12/D3D12RenderPass.h>
|
||||
#include <Graphics/D3D12/D3D12Synchronization.h>
|
||||
@@ -200,10 +200,10 @@ namespace Juliet::D3D12
|
||||
}
|
||||
|
||||
// Clean allocations
|
||||
Free(driver->AvailableCommandLists);
|
||||
Free(driver->SubmittedCommandLists);
|
||||
//Free(driver->WindowData); // TODO Should free the vector of WindowData, but we have only one for now
|
||||
Free(driver->AvailableFences);
|
||||
SafeFree(driver->AvailableCommandLists);
|
||||
SafeFree(driver->SubmittedCommandLists);
|
||||
// Free(driver->WindowData); // TODO Should free the vector of WindowData, but we have only one for now
|
||||
SafeFree(driver->AvailableFences);
|
||||
|
||||
if (driver->IndirectDrawCommandSignature)
|
||||
{
|
||||
@@ -310,7 +310,7 @@ namespace Juliet::D3D12
|
||||
|
||||
Internal::DestroySwapChain(d3d12Driver, d3d12Driver->WindowData);
|
||||
|
||||
Free(d3d12Driver->WindowData);
|
||||
SafeFree(d3d12Driver->WindowData);
|
||||
d3d12Driver->WindowData = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#include "EditorMain.h"
|
||||
@@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
class EditorMain
|
||||
{
|
||||
};
|
||||
|
||||
@@ -11,21 +11,70 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Editor\EditorMain_win32.cpp"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Editor\EditorMain_win32.h"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Game\Game.vcxproj">
|
||||
<Project>{b7b12dcc-1a69-4371-a9fe-d6e7671497b0}</Project>
|
||||
<Name>Game</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Juliet\Juliet.vcxproj">
|
||||
<Project>{1bbc0b92-e4d8-4838-974b-439c5c501e82}</Project>
|
||||
<Name>Juliet</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="main.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<RuntimeLibrary>MultiThreadedDebugDll</RuntimeLibrary>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SupportJustMyCode>true</SupportJustMyCode>
|
||||
<AssemblerOutput>NoListing</AssemblerOutput>
|
||||
<AssemblerListingLocation>W:\Classified\Juliet\Intermediate\JulietApp\x64\Debug\</AssemblerListingLocation>
|
||||
<UndefineAllPreprocessorDefinitions>false</UndefineAllPreprocessorDefinitions>
|
||||
<BrowseInformationFile>W:\Classified\Juliet\Intermediate\JulietApp\x64\Debug\</BrowseInformationFile>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<ConformanceMode>Default</ConformanceMode>
|
||||
<DiagnosticsFormat>Column</DiagnosticsFormat>
|
||||
<ExceptionHandling>false</ExceptionHandling>
|
||||
<EnableASAN>false</EnableASAN>
|
||||
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<LanguageStandard_C>Default</LanguageStandard_C>
|
||||
<ModuleDependenciesFile>W:\Classified\Juliet\Intermediate\JulietApp\x64\Debug\</ModuleDependenciesFile>
|
||||
<OmitDefaultLibName>false</OmitDefaultLibName>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<ObjectFileName>W:\Classified\Juliet\Intermediate\JulietApp\x64\Debug\</ObjectFileName>
|
||||
<CallingConvention>Cdecl</CallingConvention>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>W:\Classified\Juliet\Intermediate\JulietApp\x64\Debug\JulietApp.pch</PrecompiledHeaderOutputFile>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<PreprocessKeepComments>false</PreprocessKeepComments>
|
||||
<PreprocessSuppressLineNumbers>false</PreprocessSuppressLineNumbers>
|
||||
<ScanSourceForModuleDependencies>false</ScanSourceForModuleDependencies>
|
||||
<ShowIncludes>false</ShowIncludes>
|
||||
<SourceDependenciesFile>W:\Classified\Juliet\Intermediate\JulietApp\x64\Debug\</SourceDependenciesFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<SmallerTypeCheck>false</SmallerTypeCheck>
|
||||
<StructMemberAlignment>Default</StructMemberAlignment>
|
||||
<TrackerLogDirectory>W:\Classified\Juliet\Intermediate\JulietApp\x64\Debug\JulietApp.tlog\</TrackerLogDirectory>
|
||||
<MinimalRebuildFromTracking>true</MinimalRebuildFromTracking>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<XMLDocumentationFileName>W:\Classified\Juliet\Intermediate\JulietApp\x64\Debug\</XMLDocumentationFileName>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<IntelJCCErratum>false</IntelJCCErratum>
|
||||
<BuildStlModules>false</BuildStlModules>
|
||||
<TreatExternalTemplatesAsInternal>true</TreatExternalTemplatesAsInternal>
|
||||
<PreprocessorDefinitions>_DEBUG;JULIET_WIN32;_UNICODE;UNICODE;</PreprocessorDefinitions>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<LinkCompiled>true</LinkCompiled>
|
||||
<ClangClMode>true</ClangClMode>
|
||||
<MSCVersion>Default</MSCVersion>
|
||||
<AdditionalOptions>--target=amd64-pc-windows-msvc </AdditionalOptions>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
|
||||
@@ -1,31 +1,52 @@
|
||||
#include <Editor/EditorMain_win32.h>
|
||||
#include <main.h>
|
||||
|
||||
#include <Core/Application/ApplicationManager.h>
|
||||
#include <Core/HAL/Display/Display.h>
|
||||
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
||||
#include <Core/HAL/Event/SystemEvent.h>
|
||||
#include <Core/HAL/Filesystem/Filesystem.h>
|
||||
#include <Core/JulietInit.h>
|
||||
#include <Core/Logging/LogManager.h>
|
||||
#include <Core/Logging/LogTypes.h>
|
||||
#include <Graphics/GraphicsConfig.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
// TODO : Replace with message box from framework + call main and not winmain + subsystem
|
||||
#include <Core/DynLib/DynamicLibrary.h>
|
||||
#include <Graphics/Graphics.h>
|
||||
#include <Graphics/GraphicsConfig.h>
|
||||
#include <Graphics/RenderPass.h>
|
||||
#include <Windows.h>
|
||||
|
||||
#include <Core/Memory/Utils.h>
|
||||
#include <cstdlib>
|
||||
|
||||
// TODO : Replace with message box from framework + call main and not winmain + subsystem
|
||||
// TODO : Think how to do the draw pipeline.
|
||||
// Ex: Expose a Draw method ?
|
||||
// Store a graphics context ?
|
||||
// For now. Put everything in Update down below.
|
||||
// Should split update from draw, update should have a != timestep than graphics (60fps or more)
|
||||
|
||||
// TODO : Remove main.h. Useless
|
||||
// May be remove that Application class, useless too.
|
||||
|
||||
using namespace Juliet;
|
||||
|
||||
void Win32EditorApplication::Init()
|
||||
namespace
|
||||
{
|
||||
Log(LogLevel::Message, LogCategory::Editor, "Initializing Editor Application...");
|
||||
using GameInit_t = void (*)(void);
|
||||
using GameShutdown_t = void (*)(void);
|
||||
using GameUpdate_t = void (*)(float deltaTime);
|
||||
struct GameFunctionTable
|
||||
{
|
||||
GameInit_t Init = nullptr;
|
||||
GameShutdown_t Shutdown = nullptr;
|
||||
GameUpdate_t Update = nullptr;
|
||||
} Game;
|
||||
const char* GameFunctionTable[] = { "GameInit", "GameShutdown", "GameUpdate" };
|
||||
} // namespace
|
||||
|
||||
void JulietApplication::Init()
|
||||
{
|
||||
Log(LogLevel::Message, LogCategory::Editor, "Initializing Juliet Application...");
|
||||
|
||||
Log(LogLevel::Message, LogCategory::Editor, "%s", GetBasePath());
|
||||
|
||||
GraphicsConfig config;
|
||||
GraphicsDevice = CreateGraphicsDevice(config);
|
||||
@@ -37,18 +58,25 @@ void Win32EditorApplication::Init()
|
||||
if (Running)
|
||||
{
|
||||
AttachToWindow(GraphicsDevice, MainWindow);
|
||||
Game = LoadDynamicLibrary("Game.dll");
|
||||
//Game = LoadDynamicLibrary("Game.dll");
|
||||
|
||||
GameCode.Functions = reinterpret_cast<void**>(&Game);
|
||||
GameCode.FunctionCount = ArraySize(GameFunctionTable);
|
||||
GameCode.FunctionNames = GameFunctionTable;
|
||||
InitHotReloadCode(GameCode, StringBufferParam("Game.dll"),StringBufferParam("Game_Temp.dll"), StringBufferParam("lock.tmp"));
|
||||
if ((Running = GameCode.IsValid))
|
||||
{
|
||||
Game.Init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Win32EditorApplication::Shutdown()
|
||||
void JulietApplication::Shutdown()
|
||||
{
|
||||
Log(LogLevel::Message, LogCategory::Editor, "Shutdown Editor Application...");
|
||||
Log(LogLevel::Message, LogCategory::Editor, "Shutting down Juliet Application...");
|
||||
|
||||
if (Game)
|
||||
{
|
||||
UnloadDynamicLibrary(Game);
|
||||
}
|
||||
Game.Shutdown();
|
||||
ShutdownHotReloadCode(GameCode);
|
||||
|
||||
if (MainWindow && GraphicsDevice)
|
||||
{
|
||||
@@ -64,9 +92,11 @@ void Win32EditorApplication::Shutdown()
|
||||
{
|
||||
DestroyGraphicsDevice(GraphicsDevice);
|
||||
}
|
||||
|
||||
Log(LogLevel::Message, LogCategory::Editor, "Juliet App shutdown Completed");
|
||||
}
|
||||
|
||||
void Win32EditorApplication::Update()
|
||||
void JulietApplication::Update()
|
||||
{
|
||||
SystemEvent evt;
|
||||
while (GetEvent(evt))
|
||||
@@ -80,6 +110,13 @@ void Win32EditorApplication::Update()
|
||||
}
|
||||
}
|
||||
|
||||
Game.Update(0.0f);
|
||||
|
||||
if (ShouldReloadCode(GameCode))
|
||||
{
|
||||
ReloadCode(GameCode);
|
||||
}
|
||||
|
||||
// Draw here for now
|
||||
// 1) Acquire a Command Buffer
|
||||
CommandList* cmdList = AcquireCommandList(GraphicsDevice, QueueType::Graphics);
|
||||
@@ -114,24 +151,24 @@ void Win32EditorApplication::Update()
|
||||
SubmitCommandLists(cmdList);
|
||||
}
|
||||
|
||||
bool Win32EditorApplication::IsRunning()
|
||||
bool JulietApplication::IsRunning()
|
||||
{
|
||||
return Running;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
Win32EditorApplication EditorApplication;
|
||||
JulietApplication EditorApplication;
|
||||
}
|
||||
|
||||
Win32EditorApplication& GetEditorApplication()
|
||||
JulietApplication& GetEditorApplication()
|
||||
{
|
||||
return EditorApplication;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
CreateMutex(0, false, L"Local\\Juliet.Editor");
|
||||
CreateMutex(0, false, L"Local\\Juliet.App");
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
MessageBox(nullptr, L"An instance of Juliet is already running.", L"Juliet", MB_OK | MB_ICONEXCLAMATION);
|
||||
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/Application/IApplication.h>
|
||||
#include <Core/DynLib/DynamicLibrary.h>
|
||||
#include <Core/HAL/Display/Display.h>
|
||||
#include <Core/HAL/DynLib/DynamicLibrary.h>
|
||||
#include <Core/HotReload/HotReload.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
@@ -10,7 +11,7 @@ namespace Juliet
|
||||
struct Window;
|
||||
} // namespace Juliet
|
||||
|
||||
class Win32EditorApplication : public Juliet::IApplication
|
||||
class JulietApplication : public Juliet::IApplication
|
||||
{
|
||||
protected:
|
||||
void Init() override;
|
||||
@@ -21,9 +22,9 @@ class Win32EditorApplication : public Juliet::IApplication
|
||||
private:
|
||||
Juliet::Window* MainWindow = {};
|
||||
Juliet::GraphicsDevice* GraphicsDevice = {};
|
||||
Juliet::DynamicLibrary* Game = {};
|
||||
Juliet::HotReloadCode GameCode = {};
|
||||
|
||||
bool Running = false;
|
||||
};
|
||||
|
||||
Win32EditorApplication& GetEditorApplication();
|
||||
JulietApplication& GetEditorApplication();
|
||||
BIN
ShellGameBuild.lnk
Normal file
BIN
ShellGameBuild.lnk
Normal file
Binary file not shown.
16
misc/build_game.bat
Normal file
16
misc/build_game.bat
Normal file
@@ -0,0 +1,16 @@
|
||||
@echo off
|
||||
|
||||
del /s ..\Game*.pdb > NUL 2> NUL
|
||||
|
||||
pushd %~dp0\..\bin\x64\Debug
|
||||
echo WAITING FOR PDB > lock.tmp
|
||||
popd
|
||||
|
||||
pushd %~dp0
|
||||
msbuild -p:Random=%random% /p:SolutionDir=..\ ..\Game\Game.vcxproj
|
||||
popd
|
||||
|
||||
pushd %~dp0\..\bin\x64\Debug
|
||||
del lock.tmp
|
||||
popd
|
||||
|
||||
8
misc/shell.bat
Normal file
8
misc/shell.bat
Normal file
@@ -0,0 +1,8 @@
|
||||
@echo off
|
||||
|
||||
pushd .
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
|
||||
popd
|
||||
|
||||
set path=W:\Classified\Juliet\misc;%path%
|
||||
set _NO_DEBUG_HEAP=1
|
||||
Reference in New Issue
Block a user