Fix #104305: Crash in node editor with large asset libraries
Various UI code would store the `AssetHandle` in a way that turns out to be unsafe. The file-data is part of the file browser caching system that releases file-data when a certain maximum of items is in the cache. So even while just iterating over the assets, earlier iterated asset handles may become invalid. Now asset handles are really treated as volatile, short lived objects. For the asset-view, the fix was more involved. There we need an RNA collection of asset-handles, because the UI list code requires that. So we create a dummy collection and get the asset handles as needed by index. This again meant that I had to keep the index of the collection and the asset-list in sync, so all filtering had to be moved to the UI list. I tried duplicating the file-data out of the cache instead, but that caused problems with managing the memory/ownership of the preview images. `AssetHandle` should be removed and replaced by `AssetRepresentation`, but this would be an even more disruptive change (breaking API compatibility too). Fixes #104305, #105535. Pull Request: #105773
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
@@ -17,8 +18,10 @@ namespace blender::nodes::geo_eval_log {
|
||||
struct GeometryAttributeInfo;
|
||||
}
|
||||
|
||||
struct PointerRNA;
|
||||
struct StructRNA;
|
||||
struct uiBlock;
|
||||
struct uiList;
|
||||
struct uiSearchItems;
|
||||
|
||||
namespace blender::ui {
|
||||
@@ -53,6 +56,60 @@ void attribute_search_add_items(StringRefNull str,
|
||||
|
||||
} // namespace blender::ui
|
||||
|
||||
enum eUIListFilterResult {
|
||||
/** Never show this item, even when filter results are inverted (#UILST_FLT_EXCLUDE). */
|
||||
UI_LIST_ITEM_NEVER_SHOW,
|
||||
/** Show this item, unless filter results are inverted (#UILST_FLT_EXCLUDE). */
|
||||
UI_LIST_ITEM_FILTER_MATCHES,
|
||||
/** Don't show this item, unless filter results are inverted (#UILST_FLT_EXCLUDE). */
|
||||
UI_LIST_ITEM_FILTER_MISMATCHES,
|
||||
};
|
||||
|
||||
/**
|
||||
* Function object for UI list item filtering that does the default name comparison with '*'
|
||||
* wildcards. Create an instance of this once and pass it to #UI_list_filter_and_sort_items(), do
|
||||
* NOT create an instance for every item, this would be costly.
|
||||
*/
|
||||
class uiListNameFilter {
|
||||
/* Storage with an inline buffer for smaller strings (small buffer optimization). */
|
||||
struct {
|
||||
char filter_buff[32];
|
||||
char *filter_dyn = nullptr;
|
||||
} storage_;
|
||||
char *filter_ = nullptr;
|
||||
|
||||
public:
|
||||
uiListNameFilter(uiList &list);
|
||||
~uiListNameFilter();
|
||||
|
||||
eUIListFilterResult operator()(const PointerRNA &itemptr,
|
||||
blender::StringRefNull name,
|
||||
int index);
|
||||
};
|
||||
|
||||
using uiListItemFilterFn = blender::FunctionRef<eUIListFilterResult(
|
||||
const PointerRNA &itemptr, blender::StringRefNull name, int index)>;
|
||||
using uiListItemGetNameFn =
|
||||
blender::FunctionRef<std::string(const PointerRNA &itemptr, int index)>;
|
||||
|
||||
/**
|
||||
* Filter list items using \a item_filter_fn and sort the result. This respects the normal UI list
|
||||
* filter settings like alphabetical sorting (#UILST_FLT_SORT_ALPHA), and result inverting
|
||||
* (#UILST_FLT_EXCLUDE).
|
||||
*
|
||||
* Call this from a #uiListType::filter_items callback with any #item_filter_fn. #uiListNameFilter
|
||||
* can be used to apply the default name based filtering.
|
||||
*
|
||||
* \param get_name_fn: In some cases the name cannot be retrieved via RNA. This function can be set
|
||||
* to provide the name still.
|
||||
*/
|
||||
void UI_list_filter_and_sort_items(uiList *ui_list,
|
||||
const struct bContext *C,
|
||||
uiListItemFilterFn item_filter_fn,
|
||||
PointerRNA *dataptr,
|
||||
const char *propname,
|
||||
uiListItemGetNameFn get_name_fn = nullptr);
|
||||
|
||||
/**
|
||||
* Override this for all available view types.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user