If I have a TArray property that contains USTRUCTs:
USTRUCT(BlueprintType)
struct FMyStruct {
/*...*/
};
UCLASS()
class AMyActor : public AActor {
/*...*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
TArray<FMyStruct> MyStructs;
};
Is it safe to resize MyStructs (ie MyStructs.SetNum(N)) from a non-game thread (assuming I don’t simulatenously read or write to it from game thread) ?
Garbarge collection runs in the game thread, so could be running simulatenously to the resize - is that a problem?
Since TArray is not thread safe, I would assume that resizing it from non-game thread beyond array capacity (which mean reallocating array elements) is not safe.
std::vector is not thread safe, but you can safely resize it from one thread (reallocating array elements) provided simulatenous access is prevented from other threads during the operation (using for example std::mutex or other ways). TArray is clearly at least as unsafe as std::vector - however my question is about the garbage collector in the game thread. Is it going to access the TArray because its a property, scanning for UObject pointers - or is it going to figure out from reflection of the property and USTRUCT that it doesn’t have any.
Would the garbage collector consider the MyObject pointer property of an element of MyStructs a strong reference to the pointers target instance UMyObject, and hence prevent garbage collection of that target instance? (as it would if MyObject were a property of the actor and not the struct).
It sounds like you’re saying it wouldn’t ? (unless FMyStruct derived from FGCObject ?)
Now your structure holds a pointer to the UObject, which completely changes things.(in the first post you didn’t mention it)
I think so.
I have long believed that introducing GC to the C++ language raises more problems than good. This is one of those situations.
It’s probably safest not to mess with UWhatever in the other thread than game thread.