I am concerned however that when the number of items becomes really large (couple thousand items) the performance of it will be quite poor (as is commonly the case with for loops)
How could I optimize it? Every method I’ve been able to think of somehow just returns me to using a for loop;
Is there a way I could multithread this? maybe do something like 8 for loops processing different chunks of the available items?
Or is there a way to do this without using the for loop all together? (I’m not particularly attached to doing it exactly this way, I ultimately just need to find items that ‘contain’ the search string and display those while hiding ones that do not contain it.
If your childs are being generated(via bp), you could make an array of Name which would contain an id of each of these child.
So when a child is created, add an id to the array. But the id will have to contain a unique name that you know you can search.
This way you can use a simple Find Text like this:
I don’t think that would work for me, find requires an exact match right? but I’m using search which needs to support vague matches (hence the ‘contains’ node is used)
And because of that I also need to get multiple matches at once, for instance if I type ot into search, i’d want to get “foot” and “root” and “other” and so on shown.
Your problem seems to relate to fulltext search in a non indexed data set. Without indexation, you have no other possibility than to scan for each object.
The (very) hard solution would be to have a dedicated and precomputed “search-oriented” data structure. Basically you build once all the possible substrings patterns of your Tooltip Text variable in all the objects you have, and have a map associating each pattern to a list of objects that match. The search is then just to look for various patterns in the map.
The “Asset Search” plugin works a little bit like that, enable it, and go to “Search” functionality in the tool menu to get the idea of how it works (this is implemented in C++). You’ll see that there is an “indexation” process running in background, and once complete, the search is instantaneous.
For a more pragmatic solution, still using a “for” but not risking to block the game thread,
I’d create a new latent node that would perform the search computation in an asynchronous way. This also have to be done in C++ though, and not particularly trivial to implement (but feasible with some work IMHO).
There is a few example of latent nodes doing tasks in background, such as “Async Load Asset” for example, that load an asset asynchronously in the background without blocking anything, and once complete, may continue in the blueprint event graph.
Something that you must do is cache the GetAllChildren result to a temporary variable and loop through that variable
Otherwise your for loop will call GetAllChildren in every loop which will add a lot to the overall cost
Also if you feel confident with C++, loops are many times faster in C++, especially as the number of iterations increases
It’s the get all widgets of class thingy that i really hate about how I did it. Ideally I’d want to just use something like get parent and cast but that wouldn’t work. (Maybe I can somehow feed the parent into it on spawn? )
However, I tested it with like a good 6000 widgets and i no longer noticed any delay, this is a really good way of doing it, thanks!
Also doing it this way means i no longer have to use the tooltip text hack (it was the only string I seemed to be able to easily access from the parent without a hard reference)
I can just create a customized searchable string for each widget internally instead, this is really nice.
yeah i’d just have the parent widget construct the children widget and pass through a Ref, or if they’re all on a common widget (like a vertical box) they should be able to Ref each other.