Skip to content

Commit

Permalink
fix: The majority of the lag in the live view tab is now gone
Browse files Browse the repository at this point in the history
  • Loading branch information
UE4SS authored and Buckminsterfullerene02 committed May 19, 2024
1 parent 34484ea commit e6e6ae5
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 63 deletions.
1 change: 0 additions & 1 deletion UE4SS/include/SettingsManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ namespace RC
bool DebugConsoleVisible{true};
float DebugGUIFontScaling{1.0};
GUI::GfxBackend GraphicsAPI{GUI::GfxBackend::GLFW3_OpenGL3};
int64_t LiveViewObjectsPerGroup{64 * 1024 / 2};
} Debug;

struct SectionCrashDump
Expand Down
106 changes: 52 additions & 54 deletions UE4SS/src/GUI/LiveView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ namespace RC::GUI
Filter::HasProperty,
Filter::HasPropertyType>{};

static int s_max_elements_per_chunk{};
static int s_chunk_id_start{};

static bool s_live_view_destructed = false;
static std::unordered_map<const UObject*, std::string> s_object_ptr_to_full_name{};

Expand Down Expand Up @@ -725,14 +722,6 @@ namespace RC::GUI
auto LiveView::initialize() -> void
{
s_need_to_filter_out_properties = Version::IsBelow(4, 25);
if (UE4SSProgram::settings_manager.Debug.LiveViewObjectsPerGroup > std::numeric_limits<int>::max())
{
Output::send<LogLevel::Warning>(STR("Debug.LiveViewObjectsPerGroup is too large, must be no larger than 4294967295.\n"));
Output::send<LogLevel::Warning>(STR("Using default value for Debug.LiveViewObjectsPerGroup.\n"));
UE4SSProgram::settings_manager.Debug.LiveViewObjectsPerGroup = 64 * 1024 / 2;
}
s_max_elements_per_chunk = static_cast<int>(UE4SSProgram::settings_manager.Debug.LiveViewObjectsPerGroup);
s_chunk_id_start = -s_max_elements_per_chunk;
m_is_initialized = true;
}

Expand Down Expand Up @@ -1523,13 +1512,18 @@ namespace RC::GUI
}
}

auto LiveView::guobjectarray_by_name_iterator([[maybe_unused]] int32_t int_data_1,
[[maybe_unused]] int32_t int_data_2,
const std::function<void(UObject*)>& callable) -> void
auto LiveView::guobjectarray_by_name_iterator(int32_t int_data_1, int32_t int_data_2, const std::function<void(UObject*)>& callable) -> void
{
for (const auto& object : s_name_search_results)
if (int_data_2 > s_name_search_results.size())
{
callable(object);
Output::send<LogLevel::Error>(STR("guobjectarray_by_name_iterator: asked to iterate beyond the size of the search result vector ({} > {})\n"),
int_data_2,
s_name_search_results.size());
return;
}
for (size_t i = int_data_1; i < int_data_2; i++)
{
callable(s_name_search_results[i]);
}
}

Expand All @@ -1544,18 +1538,6 @@ namespace RC::GUI
});
}

static auto collapse_all_except(int except_id) -> void
{
for (int i = 0; i < UObjectArray::GetNumChunks(); ++i)
{
if (i + s_chunk_id_start == except_id)
{
continue;
}
ImGui::GetStateStorage()->SetInt(ImGui_GetID(i + s_chunk_id_start), 0);
}
}

auto LiveView::collapse_all_except(void* except_id) -> void
{
// We don't need to do anything if we only have one node open.
Expand Down Expand Up @@ -1583,7 +1565,7 @@ namespace RC::GUI
if (are_listeners_allowed())
{
std::string search_buffer{m_search_by_name_buffer};
if (search_buffer.empty())
if (search_buffer.empty() || s_apply_search_filters_when_not_searching)
{
Output::send(STR("Search all chunks\n"));
s_name_to_search_by.clear();
Expand Down Expand Up @@ -2893,6 +2875,13 @@ namespace RC::GUI
static auto object_search_field_always_callback(ImGuiInputTextCallbackData* data) -> int
{
auto typed_this = static_cast<LiveView*>(data->UserData);
if (LiveView::s_apply_search_filters_when_not_searching)
{
static constexpr auto message = std::string_view{"Searching is disabled while 'Apply when not searching' is enabled.'"};
strncpy_s(data->Buf, message.size() + 1, message.data(), message.size() + 1);
data->BufTextLen = message.size();
data->BufDirty = true;
}
if (typed_this->was_search_field_clear_requested() && !typed_this->was_search_field_cleared())
{
strncpy_s(data->Buf, 1, "", 1);
Expand Down Expand Up @@ -3085,19 +3074,31 @@ namespace RC::GUI
{
ImGui::PushStyleColor(ImGuiCol_Text, g_imgui_text_inactive_color.Value);
}
auto apply_search_filters_when_not_searching = s_apply_search_filters_when_not_searching;
if (ImGui::InputText("##Search by name",
m_search_by_name_buffer,
m_search_buffer_capacity,
ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackAlways,
&object_search_field_always_callback,
this))
{
search();
if (!apply_search_filters_when_not_searching)
{
search();
}
}
if (ImGui::IsItemHovered())
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
{
ImGui::BeginTooltip();
ImGui::Text("Right-click to open search options.");
if (!apply_search_filters_when_not_searching)
{
ImGui::Text("Right-click to open search options.");
}
else
{
ImGui::Text("You can't search with 'Apply when not searching' enabled.");
ImGui::Text("Right click to bring up the menu and disable this option.");
}
ImGui::EndTooltip();
}
if (push_inactive_text_color)
Expand All @@ -3110,7 +3111,18 @@ namespace RC::GUI
{
ImGui::Text("Search options");
ImGui::SameLine();
// Making sure the user can't enable filters when not searching, if they are currently actually searching.
// Otherwise it uses the wrong iterator.
auto is_searching_by_name = m_is_searching_by_name;
if (is_searching_by_name)
{
ImGui::BeginDisabled();
}
ImGui::Checkbox("Apply when not searching", &s_apply_search_filters_when_not_searching);
if (is_searching_by_name)
{
ImGui::EndDisabled();
}
if (ImGui::BeginTable("search_options_table", 2))
{
bool instances_only_enabled = !(Filter::NonInstancesOnly::s_enabled || Filter::DefaultObjectsOnly::s_enabled);
Expand Down Expand Up @@ -3489,32 +3501,18 @@ namespace RC::GUI
};

ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, {0.0f, 0.0f});
if (m_is_searching_by_name)
if (!s_apply_search_filters_when_not_searching)
{
do_iteration();
ImGuiListClipper clipper{};
clipper.Begin(m_is_searching_by_name ? s_name_search_results.size() : UObjectArray::GetNumElements(), ImGui::GetTextLineHeightWithSpacing());
while (clipper.Step())
{
do_iteration(clipper.DisplayStart, clipper.DisplayEnd);
}
}
else
{
auto num_elements = UObjectArray::GetNumElements();

if (!s_apply_search_filters_when_not_searching)
{
int num_total_chunks = (num_elements / s_max_elements_per_chunk) + (num_elements % s_max_elements_per_chunk == 0 ? 0 : 1);
for (int i = 0; i < num_total_chunks; ++i)
{
if (ImGui_TreeNodeEx(std::format("Group #{}", i).c_str(), i + s_chunk_id_start, ImGuiTreeNodeFlags_CollapsingHeader))
{
::RC::GUI::collapse_all_except(i + s_chunk_id_start);
auto start = s_max_elements_per_chunk * i;
auto end = start + s_max_elements_per_chunk;
do_iteration(start, end);
}
}
}
else
{
do_iteration(0, UObjectArray::GetNumElements());
}
do_iteration(0, UObjectArray::GetNumElements());
}
ImGui::PopStyleVar();

Expand Down
1 change: 0 additions & 1 deletion UE4SS/src/SettingsManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ namespace RC
{
Debug.GraphicsAPI = GUI::GfxBackend::GLFW3_OpenGL3;
}
REGISTER_INT64_SETTING(Debug.LiveViewObjectsPerGroup, section_debug, LiveViewObjectsPerGroup);

constexpr static File::CharType section_crash_dump[] = STR("CrashDump");
REGISTER_BOOL_SETTING(CrashDump.EnableDumping, section_crash_dump, EnableDumping);
Expand Down
8 changes: 7 additions & 1 deletion assets/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ BREAKING: Changed `FTransform` constructor to be identical to unreal.
### General

### Live View
Fixed the majority of the lag ([UE4SS #512](https://github.com/UE4SS-RE/RE-UE4SS/pull/512))

Added support for watching ArrayProperty and StructProperty ([UE4SS #419](https://github.com/UE4SS-RE/RE-UE4SS/pull/419))

The search filter `ExcludeClassName` can now be found in the `IncludeClassNames` dropdown list. ([UE4SS #472](https://github.com/UE4SS-RE/RE-UE4SS/pull/472)) - Buckminsterfullerene
Expand Down Expand Up @@ -107,13 +109,17 @@ Fixes mods not loading when UE4SS initializes too late ([UE4SS #454](https://git
## Settings

### Added
```
```ini
[Hooks]
HookLoadMap = 1
HookAActorTick = 1
```

### Removed
```ini
[Debug]
LiveViewObjectsPerGroup = 32768
```


v3.0.1
Expand Down
6 changes: 0 additions & 6 deletions assets/UE4SS-settings.ini
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,6 @@ GuiConsoleFontScaling = 1
; Default: opengl
GraphicsAPI = opengl

; How many objects to put in each group in the live view.
; A lower number means more groups but less lag when a group is open.
; A higher number means less groups but more lag when a group is open.
; Default: 32768
LiveViewObjectsPerGroup = 32768

[Threads]
; The number of threads that the sig scanner will use (not real cpu threads, can be over your physical & hyperthreading max)
; If the game is modular then multi-threading will always be off regardless of the settings in this file
Expand Down

0 comments on commit e6e6ae5

Please sign in to comment.