Also fix a memory leak when doing unversioned serialization of properties with destructors and default values: "loading as zero" doesn't call the destructor on the value being overwritten, and so isn't safe to use for properties that require destruction.
#rb Devin.Doucette, Robert.Manuszewski
[CL 26706988 by andrew scheidecker in ue5-main branch]
Like JS, JSON does not directly support FP specials in its numeric literal syntax. However, JS has Infinity and NaN global variables, and JSON does not have anything like that.
To work around the omission, this change makes the JSON formatter encode FP specials as a tagged string in the form:
"Number:+inf"
"Number:-inf"
"Number:-nan:0x123"
"Number:+nan:0xabc"
This change also gets rid of the special case that tried to print floats as integers as it invoked UB to cast an out-of-range float to an int.
#rb Francis.Hurteau
[CL 26704226 by andrew scheidecker in ue5-main branch]
- Allows callees of LoadPackageAsync to be notified when serialization is done so they can schedule the next load right from the async loading thread without having to pay for a round-trip to the game-thread
- Add UnattendedAsyncLoading test as a sample of how this feature can be used
- Add thread-safety tests for LoadPackageAsync
- Can be exercised using a cooked client build with the following command-line
-ExecCmds="Automation RunTest System.Engine.Loading.UnattendedAsyncLoadingTest+System.Engine.Loading.ThreadSafeAsyncLoadingTest;Quit"
#jira UE-188744
#rb Francis.Hurteau
[CL 26569151 by danny couture in ue5-main branch]
#rb Per.Larsson
### Problem
- The IoStore does not support bulkdata payloads being compressed at the package level, instead compression will be applied to the .ucas file when it is created, this means that we don't really use the SizeOnDisk value for cooked bulkdata as it should always be the same as the in memory size.
- Some code paths in the editor however might support compression in the workspace domain and so use the SizeOnDisk value, such as calling ::GetCopy.
- In this cause the size being passed to the IoDispatcher would be INDEX_NONE, which the system converts to "please load the entire .ubulk section of the package"
- The buffer returned to the user would eventually be trimmed to the correct in memory size so this bug would be hard to notice, the only downside is wasting time loading more data off disk than required.
### Fix
- AsyncLoading2 now sets the SizeOnDisk to be a valid value (the size of the payload in memory) if we are not using runtime only bulkdata (USE_RUNTIME_BULKDATA) so when GetSizeOnDisk is called, it returns the correct value and we only load the payload we want.
- An assert has been added to make sure that the payload is not compressed (in which case the size would be wrong and we could end up overrunning valid memory) even though the flag is removed when cooking and it should not be possible to get to that point.
[CL 26404304 by paul chipchase in ue5-main branch]
#rb Per.Larsson
#rnx
- Note that this should not change the outcome as ::TryLoadDataIntoMemory will return false if the length of the payload is zero s the previous behaviour was to allocate, fail to load, then delete. The new code path and the old code path both end up with the bulkdata containing no allocation.
[CL 26281649 by paul chipchase in ue5-main branch]
Previously small optionals worked, by accident rather than design, but large optionals didn't
#rb andew.scheidrecker,steve.robb
[CL 26281089 by johan torp in ue5-main branch]
Credit goes to Maxime.Mercier for a large part of the work on this.
#rb Maxime.Mercier, Robert.Manuszewski, Steve.Robb, Tim.Tillotson
[CL 26180447 by andrew scheidecker in ue5-main branch]
- Also prevents constructed objects from being assigned to the wrong package during highly recursive phase
#rnx
#rb Francis.Hurteau, PJ.Kack
[CL 26087239 by danny couture in ue5-main branch]
Only preload the current package instead of the whole hierarchy recursively
#rnx
#rb PJ.Kack, Francis.Hurteau
#preflight 64788f45947ff6973c0a1e7c
[CL 25788188 by danny couture in ue5-main branch]
I've reviewed all code using async requests and we had multiple places incorrectly handling the stat: some placed failed to decrease the counter, while others would decrease it when they shouldn't. The main cause was the fact that when we create an async request and pass nullptr as the target memory, the request allocates the memory itself and increases the STAT_AsyncFileMemory. However, when we call GetReadResults() on such requests, the responsibility is on the caller to balance the calls and decrease the stat, which is not very obvious and leads to the mentioned bugs. On top of that, when we call GetReadResults() we may not have the knowledge as to whether the returned memory was allocated by the request or not (which may affect whether we should touch the stat at all).
Resolved by adding IAsyncReadRequest::ReleaseMemoryOwnershipImpl member, which may be used by request implementations to do the proper clean up (balance the stat). This way requests take the full responsibility for their changes and users of the requests don't need to know their implementation details.
#preflight none
#rb Patrick.Laflamme
#jira UE-185064
[CL 25664733 by Wojciech Krywult in ue5-main branch]