Author |
Topic |
MichaelTraega
Senior Member
USA
25 Posts |
Posted - Aug 07 2018 : 11:23:32 AM
|
I am searching FStartFTestOnMap::Update and getting the following (ignoring autos, macros, and smart pointers):
// PlayerController.cpp ln 4063
for (TSortedMap<uint64, FDynamicForceFeedbackAction>::TIterator It(DynamicForceFeedbacks.CreateIterator()); It; ++It)
{
if (!It.Value().Update(DeltaTime, ForceFeedbackValues))
{
It.RemoveCurrent();
}
}
I haven't yet tested looked for the others specifically, but it seems at least TSortedMap isn't working. However, if I alt+g on the CreateIterator shown above, it lists SortedMap.h and va_stdafx.h, suggesting it is working to a degree? |
Edited by - MichaelTraega on Aug 07 2018 11:26:35 AM |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Aug 08 2018 : 4:19:52 PM
|
To fix TSortedMap, add the following to your va_stdafx.h file:
template<class KeyType, class ValueType, class _A, class _S>
class TSortedMap
{
public:
// iterator movement
typedef TIndexedContainerIterator<TTuple<KeyType, ValueType>, TTuple<KeyType, ValueType> > iterator;
iterator begin();
iterator end();
};
this is working here for me, so hopefully this will fix it for you as well. |
zen is the art of being at one with the two'ness |
|
|
MichaelTraega
Senior Member
USA
25 Posts |
Posted - Aug 09 2018 : 10:11:19 AM
|
Still getting the same issue. Also now when I alt+g this line, it shows me a whole bunch of Update functions that aren't related from all over the codebase, third party included. I think at least before when I alt+g it would actually only show TSortedMap results. |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Aug 09 2018 : 3:40:37 PM
|
Ah, here I am carefully trying to fix for loops with auto, but this problem is back to my "friend" CreateIterator(). Working on this now. |
zen is the art of being at one with the two'ness |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Aug 10 2018 : 1:34:16 PM
|
OK... there are two different iterators for TSortedMap, with slightly different members. In theory, and in my simple test case, replacing your current TSortedMap in the va_stdafx.h file with this version fixes the problem:
template<class KeyType, class ValueType, class _A, class _S>
class TSortedMap
{
public:
// required since the member TIterator class has a different pair API
// functions not exposed members, unlike the begin / end iterator
template<class KeyType, class ValueType>
class TIterator
{
KeyType Key();
ValueType Value();
void RemoveCurrent();
}
public:
// iterator movement
typedef TIndexedContainerIterator<TTuple<KeyType, ValueType>, TTuple<KeyType, ValueType> > iterator;
iterator begin();
iterator end();
}; but I am not sure this actually fixes the problem you are seeing here. So I am still looking at this, but you might want to try this version for now, and see if it helps.
I am also getting the feeling there are going to be quite a few of these "random" problems, but hopefully most of them can be fixed as they are found. |
zen is the art of being at one with the two'ness |
|
|
MichaelTraega
Senior Member
USA
25 Posts |
Posted - Aug 14 2018 : 5:13:39 PM
|
This seems to have fixed it. The only irrelevant updates I'm getting now are autos, smart pointers, and macros. I'm going to test Get again. |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Aug 15 2018 : 2:14:48 PM
|
Excellent news, thank you. I am working on fixing some of the other problems I have found along the way, so will hopefully have another update for you to test soon. |
zen is the art of being at one with the two'ness |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Aug 23 2018 : 12:53:26 PM
|
Here we go, this is my current set of fixes, which are all working well for me, testing with Unreal Engine 4.20.1
// helps ranged for loop iterate across TMap
template<class KeyType, class ValueType>
class TTuple
{
public:
KeyType Key;
ValueType Value;
};
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 access
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);
};
template<class ElementType, class _A>
class TArrayView
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
};
template<class ElementType, class _A>
class TChunkedArray
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
};
template <class ElementType>
class TDoubleLinkedList
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
};
template<typename ElementType, typename Allocator>
class TIndirectArray
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
public:
// data access
ElementType& operator[](int32 Index);
};
template<typename ElementType>
class TLinkedList
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
};
template<class KeyType, class ValueType, class _A, class _S>
class TMap
{
public:
// required since the member TIterator class has a different pair API
// uses functions not exposed members, unlike the STL style iterator below
template<class KeyType, class ValueType>
class TIterator
{
KeyType Key();
ValueType Value();
}
TMap::TIterator<KeyType, ValueType> CreateIterator();
TMap::TIterator<KeyType, ValueType> CreateConstIterator() const;
TMap::TIterator<KeyType, ValueType> CreateKeyIterator(KeyType InKey);
TMap::TIterator<KeyType, ValueType> CreateConstKeyIterator(KeyType InKey) const;
public:
// STL style iterator movement - ranged for loop
typedef TIndexedContainerIterator<TTuple<KeyType, ValueType>, TTuple<KeyType, ValueType> > iterator;
iterator begin();
iterator end();
};
template<typename ElementType, typename KeyFuncs, typename Allocator>
class TSet
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
};
template<class KeyType, class ValueType, class _A, class _S>
class TSortedMap
{
public:
// required since the member TIterator class has a different pair API
// uses functions not exposed members, unlike the STL style iterator below
template<class KeyType, class ValueType>
class TIterator
{
KeyType Key();
ValueType Value();
void RemoveCurrent();
}
TSortedMap::TIterator<KeyType, ValueType> CreateIterator();
TSortedMap::TIterator<KeyType, ValueType> CreateConstIterator() const;
TSortedMap::TIterator<KeyType, ValueType> CreateKeyIterator(KeyType InKey);
TSortedMap::TIterator<KeyType, ValueType> CreateConstKeyIterator(KeyType InKey) const;
public:
// STL style iterator movement - ranged for loop
typedef TIndexedContainerIterator<TTuple<KeyType, ValueType>, TTuple<KeyType, ValueType> > iterator;
iterator begin();
iterator end();
};
|
zen is the art of being at one with the two'ness |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Aug 25 2018 : 06:01:28 AM
|
Having found another case that is not yet fixed, adding the following block helps:
// so that for ranged-loop works correctly when TTuple key is a pointer
// the iterator is still returning the TTuple, not the pointer key
template<typename ContainerType, typename ElementType, typename IndexType>
class TIndexedContainerIterator
{
ElementType operator* () const;
};
|
zen is the art of being at one with the two'ness |
|
|
MichaelTraega
Senior Member
USA
25 Posts |
Posted - Nov 06 2018 : 2:51:26 PM
|
Any update on the fix for autos and smart pointers? I've been working with the va_stdafx for some time now and its working pretty well otherwise. |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Nov 07 2018 : 08:23:29 AM
|
Which version of VA are you currently using?
Can you tell me what problems you are seeing, and where you are seeing them?
The problem with pointers to smart pointers (case=117758) has been fixed, so if you have the latest version of VA this should not be causing any problems any more.
Since my Unreal va_stdafx.h file was being discussed in a few different places I started version numbering it, for ease I am currently at version 2.2, but there weren't many changes from the version above. Do you have a version with a version number at the top?
You may have found another edge case that I am not aware of yet, which still needs looking at. |
zen is the art of being at one with the two'ness |
|
|
MichaelTraega
Senior Member
USA
25 Posts |
Posted - Nov 07 2018 : 10:17:15 AM
|
Oh I thought you guys normally responded to a thread when a case was fixed. I will have to update and just work with it for a bit to see how it feels.
How would I get the latest va_stdfx.h? Does it just come with the next VA update and I need to remove the one I added next to my .sln? |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Nov 07 2018 : 2:24:12 PM
|
Normally the thread is updated, it looks like we missed this thread on this occasion.
If all goes well you will be able to delete your solution specific va_stdafx.h file with the next build of VA, but for now, the current version of the file that I have worked out is posted below. Can you please try this in combination with VA 2291.5, and let me know if this works correctly for you, or if you encounter any more odd results in Unreal?
// va_stdafx.h Feline Unreal Engine fixes
// Version 2.2
// fixed dot converted to -> on iterator over TMap of pointer type
// helps ranged for loop iterate across TMap
template<class KeyType, class ValueType>
class TTuple
{
public:
KeyType Key;
ValueType Value;
};
// so that for ranged-loop works correctly when TTuple key is a pointer
// the iterator is still returning the TTuple, not the pointer key
template<typename ContainerType, typename ElementType, typename IndexType>
class TIndexedContainerIterator
{
ElementType operator* () const;
};
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 access
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);
};
template<class ElementType, class _A>
class TArrayView
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
};
template<class ElementType, class _A>
class TChunkedArray
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
};
template <class ElementType>
class TDoubleLinkedList
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
};
template<typename ElementType, typename Allocator>
class TIndirectArray
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
public:
// data access
ElementType& operator[](int32 Index);
};
template<typename ElementType>
class TLinkedList
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
};
template<class KeyType, class ValueType, class _A, class _S>
class TMap
{
public:
// required since the member TIterator class has a different pair API
// uses functions not exposed members, unlike the STL style iterator below
// BUT also overloads -> to access Key and Value as members
template<class KeyType, class ValueType>
class TIterator
{
KeyType Key();
ValueType Value();
TTuple<KeyType, ValueType> operator->() const;
}
TMap::TIterator<KeyType, ValueType> CreateIterator();
TMap::TIterator<KeyType, ValueType> CreateConstIterator() const;
TMap::TIterator<KeyType, ValueType> CreateKeyIterator(KeyType InKey);
TMap::TIterator<KeyType, ValueType> CreateConstKeyIterator(KeyType InKey) const;
public:
// STL style iterator movement - ranged for loop
typedef TBaseIterator<TTuple<KeyType, ValueType> > iterator;
iterator begin();
iterator end();
};
template<typename ElementType, typename KeyFuncs, typename Allocator>
class TSet
{
public:
// iterator movement
typedef TIndexedContainerIterator<ElementType, ElementType> iterator;
iterator begin();
iterator end();
};
template<class KeyType, class ValueType, class _A, class _S>
class TSortedMap
{
public:
// required since the member TIterator class has a different pair API
// uses functions not exposed members, unlike the STL style iterator below
template<class KeyType, class ValueType>
class TIterator
{
KeyType Key();
ValueType Value();
void RemoveCurrent();
}
TSortedMap::TIterator<KeyType, ValueType> CreateIterator();
TSortedMap::TIterator<KeyType, ValueType> CreateConstIterator() const;
TSortedMap::TIterator<KeyType, ValueType> CreateKeyIterator(KeyType InKey);
TSortedMap::TIterator<KeyType, ValueType> CreateConstKeyIterator(KeyType InKey) const;
public:
// STL style iterator movement - ranged for loop
typedef TIndexedContainerIterator<TTuple<KeyType, ValueType>, TTuple<KeyType, ValueType> > iterator;
iterator begin();
iterator end();
};
|
zen is the art of being at one with the two'ness |
|
|
sean
Whole Tomato Software
USA
2817 Posts |
Posted - Dec 03 2018 : 6:37:15 PM
|
case=108835 and case=117768 are fixed in build 2301 |
Edited by - sean on Dec 03 2018 6:38:40 PM |
|
|
Zeblote
Tomato Guru
183 Posts |
Posted - Jan 02 2019 : 11:17:54 PM
|
Are you planning any more optimizations for this? For example, searching for references to UGameEngine::Init takes 5 minutes (!) and returns 11 results. Most of the time seems to be spent on "creating instance of template ..."
Maybe VA could cache template instances it has seen before to speed this up, if it isn't already? |
Edited by - Zeblote on Jan 02 2019 11:47:16 PM |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Jan 04 2019 : 10:51:37 AM
|
Are you always seeing a Find References run this slowly? Testing this in a small, default C++ Unreal project, the first time I run Find References on the code:
UGameEngine::Init();
the find takes nearly 10 minutes to finish. The second time I run the same Find References search the find is a LOT faster. So things are being cached, but not everything that is worked out is saved when you restart the IDE.
Is this similar to what you are seeing? Or are all of your finds this slow?
Are you aware you can tell VA to only run Find References across the current project, so the game engine code won't be searched, if you are only looking for references inside your own game code? This should also help to make the searches a lot faster. |
zen is the art of being at one with the two'ness |
|
|
MichaelTraega
Senior Member
USA
25 Posts |
Posted - Jan 04 2019 : 4:01:05 PM
|
Yes Find References tends to run slow the first time. All of my finds are not slow. Longer named finds seem faster.
Yes I'm aware I can run it on the current project. Typically though for generic functions like Init I tend to be looking at the engine and trying to understand or find where that gets called. |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Jan 07 2019 : 09:33:08 AM
|
Longer names being faster makes sense, if only because longer names tend to be more unique, so there is less chance of seeing something that has to be parsed in depth. Also less used in the deeper, template heavy parts of the engine code that take more parsing.
We are aware of the problem of VA spending a lot of time creating instances of templates when running a Find References. I have put a note onto the case about this to see if we can cache the results, at least for situations like Unreal Engine, where the template instances are inside stable code:
case=25958 |
zen is the art of being at one with the two'ness |
|
|
Topic |
|
|
|