Skip to content

Commit

Permalink
Merge 7867897 into 4fc8691
Browse files Browse the repository at this point in the history
  • Loading branch information
UE4SS authored Dec 19, 2024
2 parents 4fc8691 + 7867897 commit 40d1262
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 70 deletions.
99 changes: 96 additions & 3 deletions UE4SS/include/LuaType/LuaUObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,99 @@ namespace RC::LuaType

// Whether to create a new Lua item (example: table) or use an existing one on the top of the stack
bool create_new_if_get_non_trivial_local{true};

auto get_operation() const -> const char*
{
switch (operation)
{
case Operation::Get:
return "Get";
case Operation::GetNonTrivialLocal:
return "GetNonTrivialLocal";
case Operation::Set:
return "Set";
case Operation::GetParam:
return "GetParam";
}
return "UnknownOperation";
}

// https://stackoverflow.com/questions/59091462/from-c-how-can-i-print-the-contents-of-the-lua-stack/59097940#59097940
auto get_stack_dump(const char* message = "") const -> std::string
{
auto lua_state = lua.get_lua_state();
auto out_message = fmt::format("\n\nLUA Stack dump -> START------------------------------\n{}\n", message);
int top = lua_gettop(lua_state);
for (int i = 1; i <= top; i++)
{
out_message.append(fmt::format("{}\t{}\t", i, luaL_typename(lua_state, i)));
switch (lua_type(lua_state, i))
{
case LUA_TNUMBER:
out_message.append(fmt::format("{}", lua_tonumber(lua_state, i)));
break;
case LUA_TSTRING:
out_message.append(fmt::format("{}", lua_tostring(lua_state, i)));
break;
case LUA_TBOOLEAN:
out_message.append(fmt::format("{}", (lua_toboolean(lua_state, i) ? "true" : "false")));
break;
case LUA_TNIL:
out_message.append("nil");
break;
case LUA_TFUNCTION:
out_message.append("function");
break;
default:
out_message.append(fmt::format("{}", lua_topointer(lua_state, i)));
break;
}
out_message.append("\n");
}
out_message.append("\nLUA Stack dump -> END----------------------------\n\n");
return out_message;
}

auto throw_error_internal_append_args(std::string&) const -> void
{
}
template <typename K1, typename V1>
auto throw_error_internal_append_args(std::string& error_message, K1&& key, V1&& value) const -> void
{
error_message.append(fmt::format(" {}: {}\n", key, value));
}
template <typename K1, typename V1, typename... Remaining>
auto throw_error_internal_append_args(std::string& error_message, K1&& key, V1&& value, Remaining&&... remaining) const -> void
{
error_message.append(fmt::format(" {}: {}\n", key, value));
throw_error_internal_append_args(error_message, remaining...);
}
// Helper to throw nicely formatted error messages in property pushers.
// You can supply extra data by passing two extra args per data.
// The first arg is the name of the data, it must be a string.
// The second arg is anything that fmt::format can format.
// Example: throw_error("push_objectproperty", "Value must be UObject or nil", "extra_data", 1234)
// Output:
// [push_objectproperty] Error:
// Value must be UObject or nil
// Property: ObjectProperty Children./Script/Engine.Actor:Children
// extra_data: 1234
template <typename... Args>
auto throw_error(std::string_view handler_name, std::string_view format, Args&&... args) const -> void
{
std::string error_message{};
error_message.append(fmt::format("[{}] Error:\n", handler_name));
error_message.append(fmt::format(" {}\n", format));
error_message.append(fmt::format(" Operation: {}\n", get_operation()));
error_message.append(fmt::format(" Base: {}\n", static_cast<void*>(base)));
error_message.append(fmt::format(" Data: {}\n", data));
error_message.append(fmt::format(" Property ({}): {}\n", static_cast<void*>(property), property ? to_string(property->GetFullName()) : "null"));
error_message.append(fmt::format(" StoredAtIndex: {}\n", stored_at_index));
error_message.append(fmt::format(" CreateNewIfGetNonTrivialLocal: {}\n", create_new_if_get_non_trivial_local));
throw_error_internal_append_args(error_message, args...);
error_message.append(get_stack_dump());
lua.throw_error(error_message);
}
};

struct RC_UE4SS_API FunctionPusherParams
Expand Down Expand Up @@ -821,7 +914,7 @@ No overload found for function 'UObject.ProcessConsoleExec'.
IntegerType* integer_ptr = static_cast<IntegerType*>(params.data);
if (!integer_ptr)
{
params.lua.throw_error("[push_integer] data pointer is nullptr");
params.throw_error("push_integer", "data pointer is nullptr");
}

switch (params.operation)
Expand All @@ -837,10 +930,10 @@ No overload found for function 'UObject.ProcessConsoleExec'.
RemoteUnrealParam::construct(params.lua, integer_ptr, params.base, params.property);
return;
default:
params.lua.throw_error("[push_integer] Unhandled Operation");
params.throw_error("push_integer", "Unhandled Operation");
break;
}

params.lua.throw_error(fmt::format("[push_integer] Unknown Operation ({}) not supported", static_cast<int32_t>(params.operation)));
params.throw_error("push_integer", "Operation not supported");
}
} // namespace RC::LuaType
8 changes: 7 additions & 1 deletion UE4SS/src/GUI/ConsoleOutputDevice.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <chrono>
#include <locale>
#include <sstream>

#include <GUI/ConsoleOutputDevice.hpp>
#include <UE4SSProgram.hpp>
Expand Down Expand Up @@ -27,7 +28,12 @@ namespace RC::Output
fmt_copy.pop_back();
}
auto color = static_cast<Color::Color>(optional_arg);
UE4SSProgram::get_program().get_debugging_ui().get_console().add_line(m_formatter(fmt_copy), color);
auto formatted_message = m_formatter(fmt_copy);
std::wstringstream stream{formatted_message};
for (File::StringType line; std::getline(stream, line);)
{
UE4SSProgram::get_program().get_debugging_ui().get_console().add_line(line, color);
}
#endif
}
} // namespace RC::Output
Loading

0 comments on commit 40d1262

Please sign in to comment.