Skip to content

Commit

Permalink
Implement the loader using GEEcore
Browse files Browse the repository at this point in the history
  • Loading branch information
wopss committed Jun 9, 2024
1 parent 28e476a commit dbe7582
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 30 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "deps/geecore"]
path = deps/geecore
url = https://github.com/WopsS/GEEcore.git
47 changes: 24 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ include(ConfigureDefaultOutputDirectories)
include(ConfigureResourceRc)
include(ConfigureVersionFromGit)

configure_version_from_git()
red3ext_configure_version_from_git()

project(
RED3ext
Expand All @@ -17,9 +17,9 @@ project(
# -----------------------------------------------------------------------------
# General configuration and variables
# -----------------------------------------------------------------------------
configure_default_output_directories()
red3ext_configure_default_output_directories()

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "ProgramDatabase")

Expand All @@ -37,6 +37,23 @@ option(RED3EXT_CI_RELEASE "When ON version metadata will not be appended to GIT_
option(RED3EXT_EXTRA_WARNINGS "Enable extra warnings." ON)
option(RED3EXT_TREAT_WARNINGS_AS_ERRORS "Treat compiler warnings as errors." OFF)

# -----------------------------------------------------------------------------
# Dependencies - Prerequirement
#
# Some of the dependencies are already included in GEEcore with INSTALL or EXPORT
# targets set to ON. Since this is distributed as a packaged application using
# a custom INSTALL target, it is not necessary to include these third-party libs
# in the install directory. Thus, this section disable the INSTALL / EXPORT
# behavior for these libraries.
# -----------------------------------------------------------------------------
include(deps/ConfigureAndIncludeFmt)
include(deps/ConfigureAndIncludeKangaru)

# -----------------------------------------------------------------------------
# Dependencies
# -----------------------------------------------------------------------------
include(deps/ConfigureAndIncludeGEEcore)

# -----------------------------------------------------------------------------
# Compiler options for all projects
# -----------------------------------------------------------------------------
Expand All @@ -55,39 +72,23 @@ add_compile_definitions(

add_compile_options(
# Enable correct reporting of C++ version, see https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus.
$<$<BOOL:MSVC>:/Zc:__cplusplus>
/Zc:__cplusplus
)

add_link_options(
# Generate debugging information (PDB) file.
$<$<BOOL:MSVC>:/DEBUG:FULL>
/DEBUG:FULL
)

# -----------------------------------------------------------------------------
# Options / configuration related only to this project
# -----------------------------------------------------------------------------
if(RED3EXT_EXTRA_WARNINGS)
if(MSVC)
add_compile_options(/W4)
else()
message(
FATAL_ERROR
"The compiler options to enable extra warnings is not known for \
'${CMAKE_CXX_COMPILER_ID}'"
)
endif()
add_compile_options(/W4)
endif()

if(RED3EXT_TREAT_WARNINGS_AS_ERRORS)
if(MSVC)
add_compile_options(/WX)
else()
message(
FATAL_ERROR
"The compiler option to treat warnings as errors is not known for \
'${CMAKE_CXX_COMPILER_ID}'"
)
endif()
add_compile_options(/WX)
endif()

# -----------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion cmake/ConfigureDefaultOutputDirectories.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
macro(configure_default_output_directories)
macro(red3ext_configure_default_output_directories)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/libs")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/libs")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
Expand Down
2 changes: 1 addition & 1 deletion cmake/ConfigureResourceRc.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function(configure_resource_rc TARGET DESCRIPTION)
function(red3ext_configure_resource_rc TARGET DESCRIPTION)
get_target_property(RED3EXT_RESOURCE_PRODUCT_NAME "${TARGET}" OUTPUT_NAME)

set(RED3EXT_RESOURCE_FILE_DESCRIPTION "${DESCRIPTION}")
Expand Down
2 changes: 1 addition & 1 deletion cmake/ConfigureVersionFromGit.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function(configure_version_from_git)
function(red3ext_configure_version_from_git)
find_package(Git)

__git_set_default_version_variables()
Expand Down
3 changes: 3 additions & 0 deletions cmake/deps/ConfigureAndIncludeFmt.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
option(FMT_INSTALL "" OFF)

# The rest is included by GEEcore.
10 changes: 10 additions & 0 deletions cmake/deps/ConfigureAndIncludeGEEcore.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
option(GEECORE_INSTALL "" OFF)

add_subdirectory(deps/geecore)

set_target_properties(fmt PROPERTIES FOLDER "Dependencies")
set_target_properties(GEEcore PROPERTIES FOLDER "Dependencies")

mark_as_advanced(
GEECORE_INSTALL
)
4 changes: 4 additions & 0 deletions cmake/deps/ConfigureAndIncludeKangaru.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
option(KANGARU_EXPORT "" OFF)
option(KANGARU_INSTALL "" OFF)

# The rest is included by GEEcore.
1 change: 1 addition & 0 deletions deps/geecore
Submodule geecore added at 4ccfac
2 changes: 1 addition & 1 deletion src/dll/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set_target_properties(
OUTPUT_NAME ${PROJECT_NAME}
)

configure_resource_rc(
red3ext_configure_resource_rc(
RED3ext.Dll
"A script extender for REDengine 3."
)
Expand Down
35 changes: 35 additions & 0 deletions src/loader/AppMetadata.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "AppMetadata.hpp"

#include <utility>

#include <Windows.h>
#include <wil/win32_helpers.h>

red3ext::AppMetadata::AppMetadata(const geecore::IHostImage& host_image)
: m_root_directory(compute_root_directory(host_image))
{
}

const std::wstring_view red3ext::AppMetadata::name() const
{
return L"RED3ext Loader";
}

const std::filesystem::path& red3ext::AppMetadata::root_directory() const noexcept
{
return m_root_directory;
}

std::filesystem::path red3ext::AppMetadata::module_path() const
{
return root_directory() / MODULE_NAME;
}

std::filesystem::path red3ext::AppMetadata::compute_root_directory(const geecore::IHostImage& host_image)
{
auto game_root = host_image.directory()
.parent_path() // Resolve to "bin" directory.
.parent_path(); // Resolve to game's root directory.

return game_root / APPLICATION_DIRECTORY;
}
41 changes: 41 additions & 0 deletions src/loader/AppMetadata.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <filesystem>
#include <string_view>

#include <kangaru/kangaru.hpp>

#include <geecore/IHostImage.hpp>
#include <geecore/ILoaderAppMetadata.hpp>
#include <geecore/SpecialMemberFunctions.hpp>

namespace red3ext
{
class AppMetadata : public geecore::ILoaderAppMetadata
{
public:
AppMetadata(const geecore::IHostImage& host_image);
~AppMetadata() final = default;

GEECORE_NOEXCEPT_COPYABLE_AND_MOVEABLE(AppMetadata);

const std::wstring_view name() const final;
const std::filesystem::path& root_directory() const noexcept final;

std::filesystem::path module_path() const final;

private:
static constexpr std::wstring_view APPLICATION_DIRECTORY = L"red3ext";
static constexpr std::wstring_view MODULE_NAME = L"RED3ext.dll";

static std::filesystem::path compute_root_directory(const geecore::IHostImage& host_image);

std::filesystem::path m_root_directory;
};

struct AppMetadataService
: kgr::single_service<AppMetadata, kgr::dependency<geecore::HostImageService>>
, kgr::overrides<geecore::LoaderAppMetadataService>
{
};
} // namespace red3ext
17 changes: 15 additions & 2 deletions src/loader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@ set_target_properties(
OUTPUT_NAME winmm
)

configure_resource_rc(
red3ext_configure_resource_rc(
RED3ext.Loader
"The loader for ${PROJECT_NAME}."
)

geecore_set_target_as_loader(RED3ext.Loader)

set(
RED3EXT_LOADER_HEADER_FILES
stdafx.hpp
Resource.hpp

AppMetadata.hpp
)

set(
RED3EXT_LOADER_SRC_FILES
Main.cpp
AppMetadata.cpp
)

source_group(CMake REGULAR_EXPRESSION cmake_pch.*)
Expand All @@ -37,7 +42,8 @@ source_group(
TREE
"${CMAKE_CURRENT_BINARY_DIR}"
FILES
${RED3EXT_RC_FILE}
"${RED3EXT_RC_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/GEEcore.def"
)

target_include_directories(
Expand All @@ -56,3 +62,10 @@ target_sources(
)

target_precompile_headers(RED3ext.Loader PRIVATE stdafx.hpp)

target_link_libraries(
RED3ext.Loader
PRIVATE
wopss::GEEcore
WIL::WIL
)
64 changes: 63 additions & 1 deletion src/loader/Main.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,78 @@
#include <exception>

#include <Windows.h>

#include <geecore/Common.hpp>
#include <geecore/Host.hpp>
#include <geecore/HostBuilder.hpp>
#include <geecore/MsgBox.hpp>
#include <geecore/MsgBoxPrimitives.hpp>

#include "AppMetadata.hpp"

BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved)
{
(void)(reserved);
GEECORE_UNUSED(reserved);

switch (reason)
{
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(module);

try
{
auto host = geecore::HostBuilder()
.add_module_image(module)
.add_service<red3ext::AppMetadataService>()
.add_loader_lifetime()
.set_as_default()
.build();

host->start();
}
catch (const std::exception& e)
{
geecore::Win32MsgBoxDriverAnsi driver;
geecore::MsgBoxExceptionlessAnsi(driver)
.with_title("RED3ext Loader: Application Exception")
.with_text(e.what())
.with_icon(geecore::MsgBoxIcon::Error)
.with_buttons(geecore::MsgBoxButtons::Ok)
.show();

return FALSE;
}
catch (...)
{
geecore::Win32MsgBoxDriver driver;
geecore::MsgBoxExceptionless(driver)
.with_title(L"RED3ext Loader: Unknown Application Exception")
.with_text(L"An unknown exception has occurred, preventing the application from starting up properly.")
.with_icon(geecore::MsgBoxIcon::Error)
.with_buttons(geecore::MsgBoxButtons::Ok)
.show();

return FALSE;
}

break;
}
case DLL_PROCESS_DETACH:
{
try
{
auto host = geecore::Host::instance();
if (host)
{
host->stop();
}
}
catch (...)
{
// Unfortunately, there are no specific actions we can take at this point.
}

break;
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/loader/stdafx.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
#pragma once

#include <exception>
#include <filesystem>
#include <string_view>
#include <utility>

#include <Windows.h>

#include <kangaru/kangaru.hpp>

#include <wil/win32_helpers.h>

0 comments on commit dbe7582

Please sign in to comment.