Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add xmake support and a default logger #12

Merged
merged 6 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions AddressLibDecoder/xmake.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
target("addresslibdecoder")
-- set build by default
set_default(false)

-- set build group
set_group("tool")

-- add packages
add_packages("rsm-mmio")

-- add source files
add_files("src/**.cpp")
9 changes: 9 additions & 0 deletions AddressLibGen/xmake.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
target("addresslibgen")
-- set build by default
set_default(false)

-- set build group
set_group("tool")

-- add source files
add_files("src/**.cpp")
9 changes: 7 additions & 2 deletions CommonLibF4/include/F4SE/API.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ namespace F4SE

class Trampoline;

void Init(const LoadInterface* a_intfc) noexcept;
void Init(const LoadInterface* a_intfc, bool a_log = true) noexcept;

[[nodiscard]] std::string_view GetPluginName() noexcept;
[[nodiscard]] std::string_view GetPluginAuthor() noexcept;
[[nodiscard]] REL::Version GetPluginVersion() noexcept;

[[nodiscard]] REL::Version GetF4SEVersion() noexcept;
[[nodiscard]] PluginHandle GetPluginHandle() noexcept;
[[nodiscard]] std::uint32_t GetReleaseIndex() noexcept;
[[nodiscard]] std::optional<PluginInfo> GetPluginInfo(stl::zstring a_plugin) noexcept;
[[nodiscard]] std::optional<PluginInfo> GetPluginInfo(std::string_view a_plugin) noexcept;
[[nodiscard]] std::string_view GetSaveFolderName() noexcept;

[[nodiscard]] const MessagingInterface* GetMessagingInterface() noexcept;
[[nodiscard]] const ScaleformInterface* GetScaleformInterface() noexcept;
Expand Down
1 change: 1 addition & 0 deletions CommonLibF4/include/F4SE/Impl/PCH.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <filesystem>
#include <functional>
#include <initializer_list>
#include <intrin.h>
#include <iterator>
#include <limits>
#include <map>
Expand Down
6 changes: 6 additions & 0 deletions CommonLibF4/include/F4SE/Interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace F4SE
std::uint32_t(F4SEAPI* GetPluginHandle)(void);
std::uint32_t(F4SEAPI* GetReleaseIndex)(void);
const void*(F4SEAPI* GetPluginInfo)(const char*); // 0.6.22+
const char*(F4SEAPI* GetSaveFolderName)(void); // 0.7.1+
};

struct F4SEMessagingInterface
Expand Down Expand Up @@ -125,6 +126,7 @@ namespace F4SE
[[nodiscard]] REL::Version F4SEVersion() const noexcept { return MakeVersion(GetProxy().f4seVersion); }
[[nodiscard]] PluginHandle GetPluginHandle() const { return GetProxy().GetPluginHandle(); }
[[nodiscard]] std::uint32_t GetReleaseIndex() const { return GetProxy().GetReleaseIndex(); }
[[nodiscard]] std::string_view GetSaveFolderName() const { return GetProxy().GetSaveFolderName(); }
[[nodiscard]] bool IsEditor() const noexcept { return GetProxy().isEditor != 0; }
[[nodiscard]] REL::Version RuntimeVersion() const noexcept { return MakeVersion(GetProxy().runtimeVersion); }
};
Expand Down Expand Up @@ -478,3 +480,7 @@ namespace F4SE
static_assert(offsetof(PluginVersionData, reserved) == 0x25C);
static_assert(sizeof(PluginVersionData) == 0x45C);
}

#define F4SE_EXPORT extern "C" [[maybe_unused]] __declspec(dllexport)
#define F4SE_PLUGIN_PRELOAD(...) F4SE_EXPORT bool F4SEPlugin_Preload(__VA_ARGS__)
#define F4SE_PLUGIN_LOAD(...) F4SE_EXPORT bool F4SEPlugin_Load(__VA_ARGS__)
2 changes: 2 additions & 0 deletions CommonLibF4/include/F4SE/Logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ namespace F4SE::log
F4SE_MAKE_SOURCE_LOGGER(critical, critical);

[[nodiscard]] std::optional<std::filesystem::path> log_directory();

void init();
}

#undef F4SE_MAKE_SOURCE_LOGGER
36 changes: 29 additions & 7 deletions CommonLibF4/include/REL/Relocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,25 +280,25 @@ namespace REL

[[nodiscard]] constexpr value_type build() const noexcept { return _impl[3]; }

[[nodiscard]] std::string string() const
[[nodiscard]] constexpr std::string string(const std::string_view a_separator = "."sv) const
{
std::string result;
for (auto&& ver : _impl) {
result += std::to_string(ver);
result += '-';
result.append(a_separator.data(), a_separator.size());
}
result.pop_back();
result.erase(result.size() - a_separator.size(), a_separator.size());
return result;
}

[[nodiscard]] std::wstring wstring() const
[[nodiscard]] constexpr std::wstring wstring(const std::wstring_view a_separator = L"."sv) const
{
std::wstring result;
for (auto&& ver : _impl) {
result += std::to_wstring(ver);
result += L'-';
result.append(a_separator.data(), a_separator.size());
}
result.pop_back();
result.erase(result.size() - a_separator.size(), a_separator.size());
return result;
}

Expand Down Expand Up @@ -609,7 +609,7 @@ namespace REL
const auto version = Module::get().version();
const auto path = std::format(
"Data/F4SE/Plugins/version-{}.bin",
version.string());
version.string("-"sv));
if (!_mmap.open(path)) {
stl::report_and_fail(std::format("failed to open: {}", path));
}
Expand Down Expand Up @@ -793,6 +793,28 @@ namespace REL
};
}

template <class CharT>
struct std::formatter<REL::Version, CharT> : formatter<std::string, CharT>
{
template <class FormatContext>
constexpr auto format(const REL::Version& a_version, FormatContext& a_ctx) const
{
return formatter<std::string, CharT>::format(a_version.string(), a_ctx);
}
};

#ifdef FMT_VERSION
template<class CharT>
struct fmt::formatter<REL::Version, CharT> : formatter<std::string, CharT>
{
template<class FormatContext>
auto format(const REL::Version& a_version, FormatContext& a_ctx)
{
return formatter<std::string, CharT>::format(a_version.string(), a_ctx);
}
};
#endif

#undef REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE
#undef REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER
#undef REL_MAKE_MEMBER_FUNCTION_NON_POD_TYPE_HELPER_IMPL
Expand Down
49 changes: 40 additions & 9 deletions CommonLibF4/src/F4SE/API.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@ namespace F4SE
return singleton;
}

REL::Version f4seVersion;
std::string_view pluginName{};
std::string_view pluginAuthor{};
REL::Version pluginVersion{};

REL::Version f4seVersion{};
PluginHandle pluginHandle{ static_cast<PluginHandle>(-1) };
std::uint32_t releaseIndex{ 0 };
std::function<const void*(F4SEAPI)(const char*)> pluginInfoAccessor;
std::string_view saveFolderName{};

MessagingInterface* messagingInterface{ nullptr };
ScaleformInterface* scaleformInterface{ nullptr };
Expand All @@ -52,7 +57,7 @@ namespace F4SE
}
}

void Init(const LoadInterface* a_intfc) noexcept
void Init(const LoadInterface* a_intfc, const bool a_log) noexcept
{
if (!a_intfc) {
stl::report_and_fail("interface is null"sv);
Expand All @@ -64,16 +69,22 @@ namespace F4SE
auto& storage = detail::APIStorage::get();
const auto& intfc = *a_intfc;

if (const auto pluginVersionData = PluginVersionData::GetSingleton()) {
storage.pluginName = pluginVersionData->GetPluginName();
storage.pluginAuthor = pluginVersionData->GetAuthorName();
storage.pluginVersion = pluginVersionData->GetPluginVersion();
}

storage.f4seVersion = intfc.F4SEVersion();
storage.pluginHandle = intfc.GetPluginHandle();
storage.releaseIndex = intfc.GetReleaseIndex();
storage.pluginInfoAccessor = [&]() -> decltype(storage.pluginInfoAccessor) {
if (storage.f4seVersion >= REL::Version{ 0, 6, 22 }) {
return reinterpret_cast<const detail::F4SEInterface&>(intfc).GetPluginInfo;
} else {
return nullptr;
}
}();
storage.pluginInfoAccessor = reinterpret_cast<const detail::F4SEInterface&>(intfc).GetPluginInfo;
storage.saveFolderName = intfc.GetSaveFolderName();

if (a_log) {
log::init();
log::info("{} v{}", GetPluginName(), GetPluginVersion());
}

storage.messagingInterface = detail::QueryInterface<MessagingInterface>(a_intfc, LoadInterface::kMessaging);
storage.scaleformInterface = detail::QueryInterface<ScaleformInterface>(a_intfc, LoadInterface::kScaleform);
Expand All @@ -84,6 +95,21 @@ namespace F4SE
storage.trampolineInterface = detail::QueryInterface<TrampolineInterface>(a_intfc, LoadInterface::kTrampoline);
}

std::string_view GetPluginName() noexcept
{
return detail::APIStorage::get().pluginName;
}

std::string_view GetPluginAuthor() noexcept
{
return detail::APIStorage::get().pluginAuthor;
}

REL::Version GetPluginVersion() noexcept
{
return detail::APIStorage::get().pluginVersion;
}

REL::Version GetF4SEVersion() noexcept
{
return detail::APIStorage::get().f4seVersion;
Expand Down Expand Up @@ -113,6 +139,11 @@ namespace F4SE
return std::nullopt;
}

std::string_view GetSaveFolderName() noexcept
{
return detail::APIStorage::get().saveFolderName;
}

const MessagingInterface* GetMessagingInterface() noexcept
{
return detail::APIStorage::get().messagingInterface;
Expand Down
32 changes: 31 additions & 1 deletion CommonLibF4/src/F4SE/Logger.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
#include "F4SE/Logger.h"
#include "F4SE/API.h"
#include "F4SE/Interfaces.h"

#include "REX/W32/OLE32.h"
#include "REX/W32/SHELL32.h"

#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/msvc_sink.h>

namespace F4SE::log
{
std::optional<std::filesystem::path> log_directory()
Expand All @@ -16,7 +21,32 @@ namespace F4SE::log
}

std::filesystem::path path = knownPath.get();
path /= "My Games/Fallout4/F4SE"sv;
path /= std::format("My Games/{}/F4SE", F4SE::GetSaveFolderName());
return path;
}

void init()
{
auto path = log_directory();
if (!path)
return;

*path /= std::format("{}.log", F4SE::GetPluginName());

std::vector<spdlog::sink_ptr> sinks{
std::make_shared<spdlog::sinks::basic_file_sink_mt>(path->string(), true),
std::make_shared<spdlog::sinks::msvc_sink_mt>()
};

auto logger = std::make_shared<spdlog::logger>("global", sinks.begin(), sinks.end());
#ifndef NDEBUG
logger->set_level(spdlog::level::debug);
logger->flush_on(spdlog::level::debug);
#else
logger->set_level(spdlog::level::info);
logger->flush_on(spdlog::level::info);
#endif
spdlog::set_default_logger(std::move(logger));
spdlog::set_pattern("[%T.%e] [%=5t] [%L] %v");
}
}
Loading
Loading