Skip to content

Commit

Permalink
Lua: Add LuaLoader, Lua API improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Mar 6, 2024
1 parent 3d90c52 commit a49082f
Show file tree
Hide file tree
Showing 12 changed files with 1,025 additions and 148 deletions.
56 changes: 51 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -590,14 +590,60 @@ target_include_directories(sol2 INTERFACE
unset(CMKR_TARGET)
unset(CMKR_SOURCES)

# Target luavrlib
set(CMKR_TARGET luavrlib)
set(luavrlib_SOURCES "")

list(APPEND luavrlib_SOURCES
"lua-api/lib/src/ScriptContext.cpp"
"lua-api/lib/src/ScriptState.cpp"
"lua-api/lib/include/ScriptContext.hpp"
"lua-api/lib/include/ScriptState.hpp"
)

list(APPEND luavrlib_SOURCES
cmake.toml
)

set(CMKR_SOURCES ${luavrlib_SOURCES})
add_library(luavrlib STATIC)

if(luavrlib_SOURCES)
target_sources(luavrlib PRIVATE ${luavrlib_SOURCES})
endif()

source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${luavrlib_SOURCES})

target_compile_features(luavrlib PUBLIC
cxx_std_23
)

target_compile_options(luavrlib PUBLIC
"/bigobj"
"/EHa"
"/MP"
)

target_include_directories(luavrlib PUBLIC
"include/"
"lua-api/lib/include"
)

target_link_libraries(luavrlib PUBLIC
lua
sol2
kananlib
)

unset(CMKR_TARGET)
unset(CMKR_SOURCES)

# Target LuaVR
set(CMKR_TARGET LuaVR)
set(LuaVR_SOURCES "")

list(APPEND LuaVR_SOURCES
"lua-api/Main.cpp"
"lua-api/ScriptContext.cpp"
"lua-api/ScriptContext.hpp"
)

list(APPEND LuaVR_SOURCES
Expand Down Expand Up @@ -628,9 +674,7 @@ target_include_directories(LuaVR PUBLIC
)

target_link_libraries(LuaVR PUBLIC
lua
sol2
kananlib
luavrlib
)

set_target_properties(LuaVR PROPERTIES
Expand Down Expand Up @@ -669,6 +713,7 @@ list(APPEND uevr_SOURCES
"src/hooks/XInputHook.cpp"
"src/mods/FrameworkConfig.cpp"
"src/mods/ImGuiThemeHelpers.cpp"
"src/mods/LuaLoader.cpp"
"src/mods/PluginLoader.cpp"
"src/mods/UObjectHook.cpp"
"src/mods/VR.cpp"
Expand Down Expand Up @@ -787,6 +832,7 @@ target_link_libraries(uevr PUBLIC
DirectXTK12
sdkgenny
asmjit
luavrlib
)

target_link_libraries(uevr PUBLIC
Expand Down
23 changes: 17 additions & 6 deletions cmake.toml
Original file line number Diff line number Diff line change
Expand Up @@ -192,19 +192,29 @@ include-directories = ["dependencies/lua/src"]
type = "interface"
include-directories = ["dependencies/sol2/single/single/include"]

[target.LuaVR]
type = "shared"
[target.luavrlib]
type = "static"
compile-features = ["cxx_std_23"]
compile-options = ["/bigobj", "/EHa", "/MP"]
include-directories = ["include/"]
sources = ["lua-api/**.cpp", "lua-api/**.c"]
headers = ["lua-api/**.hpp", "lua-api/**.h"]
include-directories = ["include/", "lua-api/lib/include"]
sources = ["lua-api/lib/**.cpp", "lua-api/lib/**.c"]
headers = ["lua-api/lib/**.hpp", "lua-api/lib/**.h"]
link-libraries = [
"lua",
"sol2",
"kananlib"
]

[target.LuaVR]
type = "shared"
compile-features = ["cxx_std_23"]
compile-options = ["/bigobj", "/EHa", "/MP"]
include-directories = ["include/"]
sources = ["lua-api/Main.cpp"]
link-libraries = [
"luavrlib"
]

[target.LuaVR.properties]
RUNTIME_OUTPUT_DIRECTORY_RELEASE = "${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO = "${CMAKE_BINARY_DIR}/bin/${CMKR_TARGET}"
Expand Down Expand Up @@ -241,7 +251,8 @@ link-libraries = [
"DirectXTK",
"DirectXTK12",
"sdkgenny",
"asmjit"
"asmjit",
"luavrlib"
]

[template.ue4template.properties]
Expand Down
16 changes: 9 additions & 7 deletions lua-api/Main.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
// Lua API to expose UEVR functionality to Lua scripts via UE4SS

#include <windows.h>
#include "ScriptContext.hpp"
#include "lib/include/ScriptContext.hpp"

std::shared_ptr<uevr::ScriptContext> g_script_context{};

// Main exported function that takes in the lua_State*
extern "C" __declspec(dllexport) int luaopen_LuaVR(lua_State* L) {
luaL_checkversion(L);

ScriptContext::log("Initializing LuaVR...");
uevr::ScriptContext::log("Initializing LuaVR...");

auto script_context = ScriptContext::reinitialize(L);
g_script_context = uevr::ScriptContext::create(L);

if (!script_context->valid()) {
ScriptContext::log("LuaVR failed to initialize! Make sure to inject VR first!");
if (!g_script_context->valid()) {
uevr::ScriptContext::log("LuaVR failed to initialize! Make sure to inject VR first!");
return 0;
}

ScriptContext::log("LuaVR initialized!");
uevr::ScriptContext::log("LuaVR initialized!");

return script_context->setup_bindings();
return g_script_context->setup_bindings();
}

BOOL APIENTRY DllMain(HMODULE module, DWORD ul_reason_for_call, LPVOID reserved) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@

#include <vector>

class ScriptContext {
namespace uevr {
class ScriptContext : public std::enable_shared_from_this<ScriptContext> {
public:
static std::shared_ptr<ScriptContext> get();
static std::shared_ptr<ScriptContext> reinitialize(lua_State* l, UEVR_PluginInitializeParam* param = nullptr);
static std::shared_ptr<ScriptContext> create(lua_State* l, UEVR_PluginInitializeParam* param = nullptr) {
return std::make_shared<ScriptContext>(l, param);
}

ScriptContext(lua_State* l, UEVR_PluginInitializeParam* param = nullptr);

Expand Down Expand Up @@ -54,6 +56,34 @@ class ScriptContext {
}
}

auto& get_mutex() {
return m_mtx;
}

void script_reset() {
std::scoped_lock _{m_mtx};

for (auto& cb : m_on_script_reset_callbacks) {
handle_protected_result(cb());
}
}

void frame() {
std::scoped_lock _{m_mtx};

for (auto& cb : m_on_frame_callbacks) {
handle_protected_result(cb());
}
}

void draw_ui() {
std::scoped_lock _{m_mtx};

for (auto& cb : m_on_draw_ui_callbacks) {
handle_protected_result(cb());
}
}

private:
std::vector<void*> m_callbacks_to_remove{};

Expand All @@ -69,6 +99,11 @@ class ScriptContext {
std::vector<sol::protected_function> m_on_pre_viewport_client_draw_callbacks{};
std::vector<sol::protected_function> m_on_post_viewport_client_draw_callbacks{};

// Custom UEVR callbacks
std::vector<sol::protected_function> m_on_frame_callbacks{};
std::vector<sol::protected_function> m_on_draw_ui_callbacks{};
std::vector<sol::protected_function> m_on_script_reset_callbacks{};

static void on_pre_engine_tick(UEVR_UGameEngineHandle engine, float delta_seconds);
static void on_post_engine_tick(UEVR_UGameEngineHandle engine, float delta_seconds);
static void on_pre_slate_draw_window_render_thread(UEVR_FSlateRHIRendererHandle renderer, UEVR_FViewportInfoHandle viewport_info);
Expand All @@ -77,4 +112,8 @@ class ScriptContext {
static void on_post_calculate_stereo_view_offset(UEVR_StereoRenderingDeviceHandle device, int view_index, float world_to_meters, UEVR_Vector3f* position, UEVR_Rotatorf* rotation, bool is_double);
static void on_pre_viewport_client_draw(UEVR_UGameViewportClientHandle viewport_client, UEVR_FViewportHandle viewport, UEVR_FCanvasHandle canvas);
static void on_post_viewport_client_draw(UEVR_UGameViewportClientHandle viewport_client, UEVR_FViewportHandle viewport, UEVR_FCanvasHandle canvas);
};
static void on_frame();
static void on_draw_ui();
static void on_script_reset();
};
}
69 changes: 69 additions & 0 deletions lua-api/lib/include/ScriptState.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#pragma once

#include <chrono>
#include <iostream>
#include <memory>

#include <sol/sol.hpp>
#include <uevr/API.hpp>

#include <vector>

#include "ScriptContext.hpp"

namespace uevr {
class ScriptState {
public:
enum class GarbageCollectionHandler : uint32_t {
UEVR_MANAGED = 0,
LUA_MANAGED = 1,
LAST
};

enum class GarbageCollectionType : uint32_t {
STEP = 0,
FULL = 1,
LAST
};

enum class GarbageCollectionMode : uint32_t {
GENERATIONAL = 0,
INCREMENTAL = 1,
LAST
};

struct GarbageCollectionData {
GarbageCollectionHandler gc_handler{GarbageCollectionHandler::UEVR_MANAGED};
GarbageCollectionType gc_type{GarbageCollectionType::FULL};
GarbageCollectionMode gc_mode{GarbageCollectionMode::GENERATIONAL};
std::chrono::microseconds gc_budget{1000};

uint32_t gc_minor_multiplier{1};
uint32_t gc_major_multiplier{100};
};

ScriptState(const GarbageCollectionData& gc_data, UEVR_PluginInitializeParam* param, bool is_main_state);
~ScriptState();

void run_script(const std::string& p);
sol::protected_function_result handle_protected_result(sol::protected_function_result result); // because protected_functions don't throw

void gc_data_changed(GarbageCollectionData data);
void on_frame();
void on_draw_ui();
void on_script_reset();

auto& context() {
return m_context;
}

auto& lua() { return m_lua; }

private:
sol::state m_lua{};
std::shared_ptr<ScriptContext> m_context{nullptr};

GarbageCollectionData m_gc_data{};
bool m_is_main_state;
};
}
Loading

0 comments on commit a49082f

Please sign in to comment.