Whole Tomato Software Forums
Whole Tomato Software Forums
Main Site | Profile | Register | Active Topics | Members | Search | FAQ
User name:
Password:
Save Password
Forgot your password?

 All Forums
 Visual Assist
 Technical Support
 VA Find References is slow on generic names
 New Topic  Reply to Topic
 Printer Friendly
Next Page
Author Previous Topic Topic Next Topic
Page: of 2

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 10 2018 :  5:01:49 PM  Show Profile  Reply with Quote
I'm working in a massive project (UE4). If I Find References on functions named Update or Get, it starts returning functions of the same name but irrelevant contexts, not fitting the command's description: "The command ignores similarly named symbols of different contexts, and provides much more efficient access than Find in Files." It seems to return the function calls and definitions for auto and templates. This on its own is annoying, but what's even more annoying is how long it takes to finish when doing this. Finding references on a less generically named function takes less than 30 seconds for the entire project. Finding references for Update or Get takes at least 5 minutes every time. The VA output says something like "Creating instance of template" over and over.

I've basically always had these issues with VA.
  • Why is it so slow if its going to return basically every irrelevant result?
  • Why does it not only return the relevant results?
  • Does it do anything smart like return the most relevant results first and then start evaluating the templates?
  • Why doesn't it cache these results?

Basically there are some functions (and variables) I'd like to find references on but the tool is basically useless for them so I have to find all instances of the class and then look for where the function is called, which is not fun, or look through the results after they take forever to finish and if there's a lot of them try to figure out which results are relevant given the file name.

Currently on version 10.9.2270.0 in VS 2017. Disabled Intellisense.

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 10 2018 :  5:46:37 PM  Show Profile  Reply with Quote
When unwanted results are being returned, are these results in the UE4 project, or one of your projects?

Are you trying to run a find across several projects, or would limiting the scope to the current project be enough most of the time?

Depending on the above details, as a first step using the toolbar button "Display references from all projects"

in the Find References Results window may help. If you toggle this to only show results from the current project, VA will know it does not have to search beyond the current project, so fewer files will be parsed.

For caching the results, you can keep a current set of results open, in a separate window, by using the toolbar button "Clone Results". I am not sure if this is what you are looking for, but it may help.

zen is the art of being at one with the two'ness
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 10 2018 :  6:04:26 PM  Show Profile  Reply with Quote
I have just tried a very simple test here, using VS2015, VA 2270, and a small Unreal project. I have added the functions "Update()" and "Get()" to my class, and then triggered Find References on them. VA's scan is finishing nearly instantly when only scanning one project.

The scan is running for a while when I tell VA to scan across all projects, and I am getting quite a lot of references from inside Unreal it's self, so this is something I can look into.

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 11 2018 :  10:31:46 AM  Show Profile  Reply with Quote
I'm only searching the UE4 engine project. Not a game project.

If I find references on USignificanceManager::Get(), it returns 800 irrelevant results after 15 minutes.

If I find references on UObject::GetWorld(), it returns 2100 results after 5 minutes.

I guess my report is that finding references on something like Get or Update takes way too long and doesn't give me anything more useful than a string search of Get() which would return faster.

Thanks for looking into this.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 11 2018 :  3:50:44 PM  Show Profile  Reply with Quote
I am starting to see what is causing this problem. Doing a Find References on Get(), one of the results I am getting is to the file "AnimBlueprintGeneratedClass.cpp", where VA is picking up the code, and call:

if (const TWeakObjectPtr<UEdGraphNode>* pResult = localNodeToStateIndex.FindKey(StateIndex))
{
	return pResult->Get();
}


which gives me the function call "UEdGraphNode::Get()". So this is not something VA should be picking up, since I did a find on the Get member of my local test class. Except, that, according to this page:

http://api.unrealengine.com/INT/API/Runtime/Engine/EdGraph/UEdGraphNode/index.html

there is no function "UEdGraphNode::Get()", and the function "Get()" is not listed in any of the parent classes either. On a quick check, I cannot find this function in any of the base class declarations either. So it seems that VA is being tripped up by "invalid" code. I doubt this is actually invalid code, but it does look that way.

On your machine, can you please right click in the Find References Results window, and in the context menu, turn Off "Display unknown/guess hits". How many unexpected results are you now left with?

What is happening here is that VA cannot work out which function this call to "Get" comes from, so it is listing it as a possible match for the "Get" function I am searching for. If it could work out its actual scope, it would know for sure if it should be included in the results list or not.

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 11 2018 :  4:00:59 PM  Show Profile  Reply with Quote
On first attempt that cleaned it up quite a bit. It is still taking much longer than other searches however, but this is much more useful than before. For something like Get though it seems like its still going to take 15+ minutes to finish searching, so I won't know until it finishes whether or not the results displayed are final.

I'm finding references on USoundEffectPreset::Update() now. This is a similar test case but should finish faster. Currently it has only returned the Updates from the owning h and cpp files. Seems like it will another 4 or 5 minutes to finish at this rate and I don't know yet whether or not an actual call to USoundEffectPreset::Update() will be found.

EDIT: Also I can't uncheck that (or check) that box while a search is in progress. Not a huge deal but makes it harder to check on this while its in progress.

EDIT2: Finding references has almost finished and it did find other calls to Update() that are actually relevant! I wish I had found this option sooner, seems like maybe it should be a button up at the top of the search or off by default. I am wondering if there's any way it could be sped up? But thank you still

Edited by - MichaelTraega on Jul 11 2018 4:06:14 PM
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 11 2018 :  4:11:15 PM  Show Profile  Reply with Quote
For your snippit above, the Get that's being called is on the smart pointer (TWeakObjectPtr). The FindKey is returning a raw pointer to the smart pointer, not to a UEdGraphNode object.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 13 2018 :  10:53:14 AM  Show Profile  Reply with Quote
For the Find References, normally, and in theory, there won't be any guessed results in the list. So the setting to show or hide them is not something we have put onto the toolbar. We try to identify all references fully, but clearly don't always manage it.

The Unreal Engine source is a large and complex code base, with a lot of macros and templates. We are working to improve our support and handling here, but I am not sure how much faster Find References will become. So long as you have allowed VA to use multiple threads, then Find References will use them, so running faster. We also start by searching the current file first, and then searching other files. But if you really do want and need to search across the entire solution, then this isn't going to help much.

Looking more closely at the code sample, ignoring the FindKey call for the moment, and just looking at the type, we have:

TWeakObjectPtr<UEdGraphNode>* pResult;

so what ever FindKey is returning, it has to match this type. The TWeakObjectPtr class has specified the operator -> function:

FORCEINLINE T * operator->() const
at line 156 of:
C:\Program Files\Epic Games\UE_4.18\Engine\Source\Runtime\Core\Public\UObject\WeakObjectPtrTemplates.h

So just looking at this function declaration, VA is correct in thinking that Get is being called on the template type, UEdGraphNode in this case. I need to dig a bit more into this, but so far what VA is doing makes sense, and the code its self does not make sense. I can see that TWeakObjectPtr is starting to do interesting things, but the operator -> prototype still seems clear enough.

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 13 2018 :  11:30:56 AM  Show Profile  Reply with Quote
I have a really powerful workstation that can compile the engine from scratch in less than 8 minutes, I guess that's why a 15 minute find references feels a bit unnecessarily long. It would seem it takes this long to search because its evaluating all the templates and autos to see if they're correct, but since it returns them all anyway it seems like its not doing a very good job of guessing. Like some of the results you can look at and instantly see what that auto evaluates too yet VAX is still thinking it could potentially be relevant. Still, though, I can't see why it would take longer than a full rebuild. At least one way I'd think to improve the search is to not try to evaluate all these templates and autos until after you've searched for all the blatantly relevant references first. Doesn't really speed it up but at least, I'd think, the most relevant results would return quicker.

As for that bit of engine code, that's what I was trying to say. VA is correctly assessing the code. And the code itself is correct as well. The -> operator here is on the first raw pointer (the pointer to a TWeakObjectPtr object), so it's calling TWeakObjectPtr::Get(), which returns the next raw pointer to UEdGraphNode object, which is what the function is supposed to return.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 13 2018 :  2:54:20 PM  Show Profile  Reply with Quote
For the speed comparison, remember that when compiling the pre-processor expands all macros, and also templates are turned into concrete code. These are steps that VA does not get to do, since this requires "rewriting" the code, so our parser has to do a different set of jobs, which can take longer. But if you are seeing specific places in the code where VA is having problems then I am more than happy to look at them, and put in bug reports, so we can try and improve VA's handling of the engine code.

We are actively working to improve our support for Unreal Engine, so any insight into where we struggle would be appreciated.

On your machine, looking at just this simple code sample, if you place the caret into the function call "Get()" what is shown in VA's context and definition fields? For me these are blank, since VA does not understand the context / scope of this function. When I go back a step and place the caret into "pResult" the context and definition fields show:

localUnrealFindNodeFromStateIndex.pResult
const TWeakObjectPtr<UEdGraphNode>* pResult = localNodeToStateIndex.FindKey(StateIndex)

so VA is not able to interpret this code correctly, which looks like a bug in our parser. I don't think I have ever seen a pointer to a smart pointer before, so I missed that on my first read-through the code. I have put in a bug report for this:

case=117758

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 13 2018 :  4:03:24 PM  Show Profile  Reply with Quote
Here's some examples of where I think VA should be able to tell right away this code is not relevant. This also overlaps with the issue you're seeing. I searched UAISense::Update.


// AnimationRecorder.cpp
void FAnimationRecorderManager::Tick(float DeltaTime)
{
	for (auto& Inst : RecorderInstances)
	{
		Inst.Update(DeltaTime); // ln 744
	}
}

RecorderInstances is a TArray<FAnimRecorderInstance>. A range-based for-loop on a TArray is always going to return a reference to the template type. So in this case, auto& Inst is always going to be an FAnimRecorderInstance, which means there's no way Inst could be of type UAISense and so Update should be excluded. I don't remember right now if VA struggles with autos elsewhere, but typically in this code base they'd only be used in for loops.



// AutomationTest.h - removed back slashes to fix newlines here
#define #define DEFINE_LATENT_AUTOMATION_COMMAND(CommandName)	
class CommandName : public IAutomationLatentCommand 
	{ 
	public: 
	virtual ~CommandName() 
		{} 
	virtual bool Update() override; 
}

I still don't know much about your parser, obviously, but another Update being returned as a guess is in this macro. I don't have to expand this macro to know class CommandName, whatever it may be, is not going to be UAISense because it inherits from IAutomationLatentCommand. So the Update() in here, again without having to expand all its uses, is definitely not the same Update found in UAISense.



// PlayerController.cpp
	for (const TPair<int32, FDynamicForceFeedbackDetails*>& DynamicEntry : LatentDynamicForceFeedbacks)
	{
		DynamicEntry.Value->Update(ForceFeedbackValues); // ln 4071
	}


Value in TPair will always return a reference of the second type in the template. Above this type is not at all related to UAISense, so why does VA not know what Value is going to be.


// PlayerController.cpp
	for (int32 Index = ActiveForceFeedbackEffects.Num() - 1; Index >= 0; --Index)
	{
		if (!ActiveForceFeedbackEffects[Index].Update(DeltaTime, ForceFeedbackValues)) // ln 4055
		{
			ActiveForceFeedbackEffects.RemoveAtSwap(Index); 
		}
	}

What's weird is further up in that same file, VA has no idea what line 4055's Update is. If I Alt+G on it, it return's several options, none of which are the actual Update function found in ForceFeedbackEffect.h line 74.

So there seems to be a pattern of not understanding template and auto functions in general, at least for unreal types. Maybe it's because of how complex they are, but if the parser can't, or doesn't want to, dive that deep, maybe assumptions could be made that are unreal specific.


And yeah, a pointer to a smart pointer is confusing. I think it's just because there is no FindKeyRef like there is a Find[Value]Ref. But I'd guess that's because FindKey kind of defeats the purpose of a hash map and shouldn't be used too often. Where are you wanting the caret inserted? I don't use this operator with Unreal. I don't believe it works with Unreal pointers. I don't know what change you made to have VA understand Get() in that context.

Edited by - MichaelTraega on Jul 13 2018 4:08:22 PM
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 14 2018 :  11:39:23 AM  Show Profile  Reply with Quote
Thank you for the clear examples. For your first example, our parser is currently having some problems with TArray, including working out the type when doing a for loop scan across the array:

case=108835

which is what is going wrong here. Without the type being used inside the loop, VA won't understand the function call inside the loop.


The second example, with the macro, this is actually a reasonable gray area for our parser. When you compile code with macros the first step, during the pre-processor, is to expand all of the macros, so the rest of the compiler never actually see's or has to deal with the macros. Unfortunately this isn't something we can do, so macros are a hard problem for VA. If we treated this as code, rather than a macro, then its clear that this Update does not apply. But since it is a macro, it's not that clear.

Also you have to assume that no further macro is about to happen to this code, to change it further.

The flip side is that this should be a piece of code that VA does not spend much time thinking about, so it should not be slowing down the Find References by any noticeable amount. Templates get expanded, as you will see from the status bar messages, but I would expect this to be simply parsed once and moved over.


The third example, I have some different code to you. I am checking in an Unreal Engine 4.18.1 project, in case that is important. I have the code:

for (const TPair<int32, FDynamicForceFeedbackDetails>& DynamicEntry : DynamicForceFeedbacks)
{
	DynamicEntry.Value.Update(ForceFeedbackValues);
}

but I don't think the differences are that important for the problem. If you place the caret into "Value", or use Alt-g on "Value" on this line, what happens? VA does not understand what Value is here, for me. Blank context and definition fields, and several guesses in the Alt-g menu. I will look into this one more deeply next.


Your forth example, I don't have that exact code block, but I do have something similar, where the for loop is scanning a TArray. So it looks like VA is having problems with the [] operator on a TArray, at least in this case. I will have a look at this as well.


We are making some Unreal specific assumptions and simplifications, this is an ongoing job. Here though, I confirmed that a pointer to a smart pointer is something our parser does not understand in simple pure C++. I tested it with the most basic smart pointer class I could make, and I still got the bug. So this is something that probably needs to be fixed at the parser level, any work arounds I suggest are likely to break more things than they fix.

zen is the art of being at one with the two'ness
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 14 2018 :  12:26:01 PM  Show Profile  Reply with Quote
I have found where Value and Key are defined for the TPair, its a template specialisation buried a few layers down. Do you have a "va_stdafx.h" file in the same directory as your SLN file? If you do, then can you please open this file up and add the following class to the end of the file, making sure that the file still ends with a blank line:

template<class KeyType, class ValueType>
class TTuple
{
public:
	KeyType Key;
	ValueType Value;
};

you will now need to trigger a VA Symbol database rebuild for this to take effect, so press the button:

VA Options -> Performance -> Rebuild symbol databases

and close and reload your IDE.

This should fix this TPair problem. But as you can see, I have told VA that TTuple with more than 2 parameters also have these functions, which is wrong, but hopefully won't cause to many problems.

I have also put in a bug report for VA not knowing about these two members of TPair

case=117768

zen is the art of being at one with the two'ness

Edited by - feline on Jul 14 2018 12:41:47 PM
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 14 2018 :  2:48:04 PM  Show Profile  Reply with Quote
I have put in a bug report for the array item problem with TArray:

case=117770

and I have also got a work around. Again using your va_stdafx.h file, add the code:

template<class ElementType, class _A>
class TArray
{
public:
	ElementType& operator[](int32 Index)
};


again making sure the file still ends with a blank line. If you don't already have a va_stdafx.h file, this page explains what it is:

https://support.wholetomato.com/default.asp?W302

simply put, it is a helper file that our parser searches for and parses before anything in your solution is parsed, and it is used to help our parser with code that is confusing it. The file should not be added to your solution, and VA automatically looks for it in the same directory as your SLN or VCXPROJ files.

After changing your va_stdafx.h file you need to press the button:

VA Options -> Performance -> Rebuild symbol databases

and restart your IDE, for the changes to take effect.

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 16 2018 :  11:29:06 AM  Show Profile  Reply with Quote
I'm in 4.20 preview 5.

Still working on testing the va_stdafx.h. I think I've set it up correct. Right now it's just parsing.
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 16 2018 :  2:30:24 PM  Show Profile  Reply with Quote
Okay that seems to have improved the find. There are still bad results.

0. For starters, in OnlinePresenceInterfaceSteam.cpp, FOnlinePresenceSteam::QueryPresence and UpdatePresenceForUser both use a pointer to a TSharedRef, FoundEntry, and call an irrelevant Update. I assume this might be resolved by your fixing of the core parsing behavior pointers to smart pointers.


1. More strangely, SAnimCompositePanel::Update() is also being included in the results for some reason (SAnimCompositePanel.h ln 49). Not sure why, might be because of the slate macros above? This was probably here before I updated the stdafx.


2. Also, this line in PlayerController is an issue. I didn't mention it before but it was there before as well:

for (TSortedMap<uint64, FDynamicForceFeedbackAction>::TIterator It(DynamicForceFeedbacks.CreateIterator()); It; ++It)
{
	if (!It.Value().Update(DeltaTime, ForceFeedbackValues))
	{
		It.RemoveCurrent(); // ln 4065 (unreal 4.20)
	}
}


3. Then in AnimationRecorder.cpp, the Inst.Update calls in both FAnimationRecorderManager::Ticks being included. These are auto& in a range-based for-loop of a TArray.

4. MaterialStats.cpp, FMaterialStats::Update has a auto + loop as well that's being included. But the container is a TMap instead of TArray.

for (const auto Entry : ShaderPlatformStatsDB)
{
	auto PlatformStats = Entry.Value;
	bInfoChanged |= PlatformStats->Update();
}


5. Finally, DisplayClusterInputManager.cpp FDisplayClusterInputManager::Update()'s internal Update is also included in the find results. This one looks like it's a bit of a doozy because it's a nested for loop with autos.

UE_LOG(LogDisplayClusterInput, Verbose, TEXT("Input update..."));
for (auto classIt = Devices.CreateIterator(); classIt; ++classIt)
{
	for (auto devIt = classIt->Value.CreateConstIterator(); devIt; ++devIt)
	{
		devIt->Value->Update();
	}
}



Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 17 2018 :  07:12:54 AM  Show Profile  Reply with Quote
There will be a small delay on moving to a new version of the Unreal Engine, I have just been told the video card on the test machine (VMware virtual machine) I am using is not up to the job. So I will install Unreal on a different machine, and check these code examples as well as I can with 4.18.3

zen is the art of being at one with the two'ness

Edited by - feline on Jul 17 2018 07:25:17 AM
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 17 2018 :  1:32:23 PM  Show Profile  Reply with Quote
Point 0, so far no sign of any file called "OnlinePresenceInterfaceSteam.cpp", but if it looks like a pointer to a smart pointer then yes, it should be fixed by the same code change in our parser.

Point 1 - I am not seeing this reference returned by Find References in my Unreal Engine 4.18 test project. I do have the file "SAnimCompositePanel.h" and the call to Update in my solution, so it looks like the changes to va_stdafx.h should have fixed this reference turning up. If you keep on getting this reference come up then can you please go to this reference, place the caret into the "Update()" call and see what VA is showing in its context and definition fields? Also what happens when you use Alt-G on this function call? For me alt-g takes me to the matching cpp file, and the function body for "Update()".

Point 2 - I am not finding this piece of code in the file "PlayerController.cpp" in Unreal 4.18 or 4.19. I will get the preview downloading soon, and re-check then. At a guess, some of the problems we are having with TArray may also apply to TMap and TSortedMap, but I want to confirm this to be sure.

Point 3 - this is due to our parser having problems with an auto for loop scanning across TArray, and is covered by:

case=108835

I haven't found a work around for this one yet, it might require a change to our parser to handle this correctly.

Point 4 - Looks like another example of TMap having the same type of problem as TArray, I am going to run some more tests on this.

Point 5 - no sign of the file "DisplayClusterInputManager.cpp" yet, so it looks like this is also specific to the preview, so I will check on this once I have the preview installed and available.

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 17 2018 :  2:23:56 PM  Show Profile  Reply with Quote
Point 0: I guess I was pointing this one out because it's a TSharedRef, so I don't know if it needs to be interpreted differently.

Point 1: Alt+G takes me to the correct definition. So I just ran find references again, and this time it was not included. I guess this hadn't yet been parsed or something during the search?


Thanks so much for looking into this so thoroughly. It always kinda bothered me, and I finally had time to investigate it.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 18 2018 :  4:07:02 PM  Show Profile  Reply with Quote
Got Unreal Engine 4.20 release now. Have you created a project with this version of Unreal yet? I have made a default project, to get a solution to open in the IDE. What is odd is that when trying to open VS2017 from the Unreal Editor the IDE does not finish loading. I get the IDE window, but the title bar is updated with "not responding". Waiting does not make any difference.

Just wondering if this is a one off oddity, or if you have seen this as well. Opening VS2017 directly is fine, and I had no problems opening the IDE with my UE 4.18 project.

Point 0, TSharedRef looks and behaves like a smart pointer, so the same parser change should fix this. I have put a note onto the case about TSharedRef.

Point 1, yes, it looks like something did not get re-parsed correctly here the first time. We are seeing the same results and behaviour here, that is important.

Point 5, I have the code now, but this looks a little different. This is an explicit iterator for loop, rather than a for range loop, so I need to look at this a bit before commenting. Something is confusing us, but what and where?

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 20 2018 :  11:12:48 AM  Show Profile  Reply with Quote
I rarely open visual studios from the editor, but I just tested it and it worked fine.

Point 5, the code looks the same after I updated to the release version of the engine. What I pasted above wasn't a range-based loop to begin with.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 23 2018 :  12:18:28 PM  Show Profile  Reply with Quote
Apologies, I did not explain my thinking at all clearly here. For point 5, I wanted to wait until I had the code in front of me before thinking about it to much, since sometimes its more about the types that are being used than it is about the loop structure.

It turns out that this is one of those cases. For some very strange reason VA is struggling with the line:

auto autoDeviceIterator = Devices.CreateIterator();

but is perfectly happy with the line:

TIterator directDeviceIterator = Devices.CreateIterator();

so we are failing at the type of the iterator in the outer loop...

URG and now I know why, but not what to do about this, or how Unreal avoids running into problems with doing this.

If I asked you what a TIterator was, what would you say?

In the file "UnrealString.h" I have a TIterator CreateIterator() function, and the typedef:
typedef TArray<TCHAR>::TIterator TIterator;

while in the file "" I also have a TIterator CreateIterator() function, and this time I am finding the class:
class TIterator : public TBaseIterator<false>

Hopefully all iterators have a base class, but what is the data type that is being returned when you ask for the iterator content? Urg.

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 23 2018 :  1:17:37 PM  Show Profile  Reply with Quote
Just alt+g'ing through these and I don't think all of these share the same base class.

Array.h has TIndexedContainerIterator which is typedef'd to TIterator in only 3 places (Array, IndirectArray, and FPreviewAssetAttachComponent). All of these are typedef'd.

Most others seem to be of type TBaseIterator. These are not typdef'd. They're nested classes.
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 23 2018 :  1:23:37 PM  Show Profile  Reply with Quote
So I guess a workaround is that if the iterator is being created for a TArray or TIndirectArray, you assume its of type TIndexedContainerArray. Otherwise you assume it's definition is in whatever class its nested in, but it will always inherit from TBaseIterator
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 23 2018 :  3:17:29 PM  Show Profile  Reply with Quote
I am currently searching through the Engine 4.18 code, looking for all calls to "CreateIterator()". The initial results are mixed. Sometimes the iterator is a clear type. Sometimes its a typedef inside the class scope. Sometimes its a typedef at file / global scope.

Have you ever seen any sign that Unreal Engine uses namespaces to separate out blocks of code? I am not seeing any signs yet, so suspect the answer is no.

Thank you for your answer, hopefully this will all make a bit more sense when I have finished listing these examples and checking them out.

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 23 2018 :  3:29:29 PM  Show Profile  Reply with Quote
Namespaces are mostly used for oldschool typed enums. But doing a quick find text search, I found there are places in engine where they're used for encapsulating blocks of code. I use them as well. But they are never really used at a project scale unless it's a third party, like Box2D or physx.

Couple of examples:
MacTargetSettingsDetailsConstants.cpp
ConvexHull2d.h
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Jul 23 2018 :  3:41:42 PM  Show Profile  Reply with Quote
Instead of trying to learn Unreal, I will just learn the bit's I need to solve the problems that come up... Just wondering how long before this plan turns into learning Unreal

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Jul 23 2018 :  3:52:21 PM  Show Profile  Reply with Quote
I've been working in unreal for over 5 years now and I'm wondering when I'm going to learn it. It's so massive you're never going to cover every edge case. I'm just happy to see VAX handling it better. I was first introduced to VAX and Unreal (3) at the same time. Still learning what VAX can do as well.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Aug 04 2018 :  10:44:34 AM  Show Profile  Reply with Quote
I have made some useful progress, on the "CreateIterator()" functions that several of the Unreal Engine container classes use. VA handles some of these functions, but not others. Adding this to your va_stdafx.h file fixes this for these classes:

template<typename InElementType, typename KeyFuncs = DefaultKeyFuncs<InElementType>, typename Allocator = FDefaultSetAllocator>
class TSet
{
	typedef TIndexedContainerIterator<TSet, InElementType, int32> TIterator;
	TIndexedContainerIterator<TSet, InElementType> CreateIterator();
};

template <typename KeyType, typename ValueType, typename ArrayAllocator, typename SortPredicate>
class TSortedMap
{
	TIndexedContainerIterator<TSortedMap, ValueType> CreateIterator();
};

template<typename InElementType, typename Allocator>
class TSparseArray
{
	TIndexedContainerIterator<TSparseArray, InElementType> CreateIterator();
};

now to see if I can generalise this to help with more of the iterator problems.

zen is the art of being at one with the two'ness
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
17013 Posts

Posted - Aug 06 2018 :  5:41:12 PM  Show Profile  Reply with Quote
I have TArray fixed, at least in the simple test cases that I have checked so far. Can you please add the following to your va_stdafx.h file, and if you already have an entry for TArray, replace it with this new entry:

template<class ElementType, class _A>
class TArray
{
public:
	// iterator movement
	typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
	typedef TIndexedContainerIterator<ElementType, ElementType> const_iterator;
	typedef TIndexedContainerIterator<ElementType, ElementType> reverse_iterator;
	typedef TIndexedContainerIterator<ElementType, ElementType> const_reverse_iterator;
  
	iterator begin();
	iterator end();
	const_iterator cbegin() const;
	const_iterator cend() const;
	reverse_iterator rbegin();
	reverse_iterator rend();
	const_reverse_iterator crbegin() const;
	const_reverse_iterator crend() const;
  
public:
	// data access
	ElementType& operator[](int32 Index)
};


as before, you will need to press:

VA Options -> Performance -> Rebuild symbol databases

and restart your IDE for this to take effect. Hopefully this will work well for you. My next step is to see if I can see similar problems with other Unreal Engine collection types, and see if the same form of fix will work for them as well.

zen is the art of being at one with the two'ness
Go to Top of Page

MichaelTraega
Senior Member

USA
25 Posts

Posted - Aug 06 2018 :  5:51:38 PM  Show Profile  Reply with Quote
Alright everything is reparsing right now. Will try to test this tomorrow.
Go to Top of Page
Page: of 2 Previous Topic Topic Next Topic  
Next Page
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
© 2019 Whole Tomato Software, LLC Go To Top Of Page
Snitz Forums 2000