Skip to content

Commit 364196b

Browse files
authored
Merge pull request #1090 from UE4SS-RE/live-view-faster-constant-filtering
perf(LiveView): 'Apply filters when not searching' is much faster now
2 parents 065b207 + de53758 commit 364196b

File tree

4 files changed

+206
-116
lines changed

4 files changed

+206
-116
lines changed

UE4SS/include/GUI/LiveView.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ namespace RC::GUI
187187

188188
private:
189189
auto collapse_all_except(void* except_id) -> void;
190-
auto search() -> void;
191-
auto search_by_name() -> void;
190+
auto search(bool apply_filters_when_not_searching = false) -> void;
191+
auto make_filtered_set(bool ignore_name = false) -> void;
192192
auto select_object(size_t index, const FUObjectItem* object_item, UObject* object, AffectsHistory = AffectsHistory::Yes) -> void;
193193
auto select_property(size_t index, FProperty* property, AffectsHistory affects_history) -> void;
194194
auto get_selected_object_or_property() -> const ObjectOrProperty&;

UE4SS/include/GUI/LiveView/Filter/SearchFilter.hpp

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@
1616
// 5. In the same file, find the 'LiveView::render' function and find the 'if (ImGui::BeginPopupContextItem("##search-options"))' if-statement.
1717
// 6. Add a checkbox (or whatever) to control your search filter inside the if-statement.
1818

19+
// Whether to track the reason why objects get filtered out.
20+
#ifndef RC_LIVE_VIEW_DEBUG_FILTER_RESULTS
21+
#define RC_LIVE_VIEW_DEBUG_FILTER_RESULTS 0
22+
#endif
23+
24+
#ifndef RC_LIVE_VIEW_MAKE_FILTER_RETURN_VALUE
25+
#if RC_LIVE_VIEW_DEBUG_FILTER_RESULTS
26+
#define RC_LIVE_VIEW_MAKE_FILTER_RETURN_VALUE(FilteredOut, Reason) {Reason, FilteredOut}
27+
#else
28+
#define RC_LIVE_VIEW_MAKE_FILTER_RETURN_VALUE(FilteredOut, ...) FilteredOut
29+
#endif
30+
#endif
31+
32+
#ifndef RC_LIVE_VIEW_WAS_FILTERED
33+
#if RC_LIVE_VIEW_DEBUG_FILTER_RESULTS
34+
#define RC_LIVE_VIEW_WAS_FILTERED(Result) Result.was_filtered
35+
#else
36+
#define RC_LIVE_VIEW_WAS_FILTERED(Result) Result
37+
#endif
38+
#endif
39+
1940
namespace RC::GUI::Filter
2041
{
2142
using namespace Unreal;
@@ -36,6 +57,16 @@ namespace RC::GUI::Filter
3657
s_highlighted_properties.emplace(property);
3758
}
3859

60+
#if RC_LIVE_VIEW_DEBUG_FILTER_RESULTS
61+
struct FilterResult
62+
{
63+
StringType reason{};
64+
bool was_filtered{true};
65+
};
66+
#else
67+
using FilterResult = bool;
68+
#endif
69+
3970
template <typename...>
4071
struct Types
4172
{
@@ -52,20 +83,20 @@ namespace RC::GUI::Filter
5283
};
5384

5485
template <typename T>
55-
auto eval_pre_search_filters(T&, UObject* object) -> bool
86+
auto eval_pre_search_filters(T&, UObject* object) -> FilterResult
5687
{
5788
if constexpr (CanPreEval<T>)
5889
{
5990
return T::pre_eval(object);
6091
}
6192
else
6293
{
63-
return false;
94+
return RC_LIVE_VIEW_MAKE_FILTER_RETURN_VALUE(false, {});
6495
}
6596
}
6697

6798
template <typename T, typename... Ts>
68-
auto eval_pre_search_filters(Types<T, Ts...>&, UObject* object) -> bool
99+
auto eval_pre_search_filters(Types<T, Ts...>&, UObject* object) -> FilterResult
69100
{
70101
auto eval_next_filters = [&] {
71102
Types<Ts...> next_filters{};
@@ -76,7 +107,7 @@ namespace RC::GUI::Filter
76107
{
77108
if (T::pre_eval(object))
78109
{
79-
return true;
110+
return RC_LIVE_VIEW_MAKE_FILTER_RETURN_VALUE(true, fmt::format(STR("{}"), T::s_debug_name));
80111
}
81112
else
82113
{
@@ -90,20 +121,20 @@ namespace RC::GUI::Filter
90121
}
91122

92123
template <typename T>
93-
auto eval_post_search_filters(T&, UObject* object) -> bool
124+
auto eval_post_search_filters(T&, UObject* object) -> FilterResult
94125
{
95126
if constexpr (CanPostEval<T>)
96127
{
97128
return T::post_eval(object);
98129
}
99130
else
100131
{
101-
return false;
132+
return RC_LIVE_VIEW_MAKE_FILTER_RETURN_VALUE(false, {});
102133
}
103134
}
104135

105136
template <typename T, typename... Ts>
106-
auto eval_post_search_filters(Types<T, Ts...>&, UObject* object) -> bool
137+
auto eval_post_search_filters(Types<T, Ts...>&, UObject* object) -> FilterResult
107138
{
108139
auto eval_next_filters = [&] {
109140
Types<Ts...> next_filters{};
@@ -114,7 +145,7 @@ namespace RC::GUI::Filter
114145
{
115146
if (T::post_eval(object))
116147
{
117-
return true;
148+
return RC_LIVE_VIEW_MAKE_FILTER_RETURN_VALUE(true, fmt::format(STR("{}"), T::s_debug_name));
118149
}
119150
else
120151
{
@@ -127,18 +158,6 @@ namespace RC::GUI::Filter
127158
}
128159
}
129160

130-
#define APPLY_PRE_SEARCH_FILTERS(Filters) \
131-
if (eval_pre_search_filters(Filters, object)) \
132-
{ \
133-
return true; \
134-
}
135-
136-
#define APPLY_POST_SEARCH_FILTERS(Filters) \
137-
if (eval_post_search_filters(Filters, object)) \
138-
{ \
139-
return true; \
140-
}
141-
142161
static auto is_instance(UObject* object, bool care_about_cdo = true) -> bool
143162
{
144163
const auto cdo = care_about_cdo ? !object->HasAnyFlags(static_cast<EObjectFlags>(RF_ClassDefaultObject | RF_ArchetypeObject)) : true;

0 commit comments

Comments
 (0)