2019-12-26 15:32:37 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3209340 on 2016/11/23 by Ben.Marsh
Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h.
Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms.
* Every header now includes everything it needs to compile.
* There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first.
* There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h.
* Every .cpp file includes its matching .h file first.
* This helps validate that each header is including everything it needs to compile.
* No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more.
* You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there.
* There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible.
* No engine code explicitly includes a precompiled header any more.
* We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies.
* PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files.
Tool used to generate this transform is at Engine\Source\Programs\IncludeTool.
[CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
# include "CollectionManager.h"
2024-04-19 18:17:59 -04:00
# include "Algo/Sort.h"
# include "Algo/Unique.h"
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340)
#lockdown Nick.Penwarden
#rb none
==========================
MAJOR FEATURES + CHANGES
==========================
Change 3209340 on 2016/11/23 by Ben.Marsh
Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h.
Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms.
* Every header now includes everything it needs to compile.
* There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first.
* There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h.
* Every .cpp file includes its matching .h file first.
* This helps validate that each header is including everything it needs to compile.
* No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more.
* You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there.
* There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible.
* No engine code explicitly includes a precompiled header any more.
* We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies.
* PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files.
Tool used to generate this transform is at Engine\Source\Programs\IncludeTool.
[CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
# include "HAL/FileManager.h"
# include "Misc/Paths.h"
# include "Containers/Ticker.h"
# include "CollectionManagerLog.h"
2023-05-01 17:00:52 -04:00
# include "CollectionManagerModule.h"
2015-07-07 10:31:39 -04:00
# include "FileCache.h"
Copying //UE4/Dev-Editor to //UE4/Dev-Main (Source: //UE4/Dev-Editor @ 3621452)
#lockdown Nick.Penwarden
#rb none
============================
MAJOR FEATURES & CHANGES
============================
Change 3567301 by Arciel.Rekman
Linux: fix for importing failure when clicking shortcuts (UE-47932).
- Slate dialog would return incorrect relative paths (not matching CWD) if Engine or Project shortcuts were used.
#jira UE-47932
Change 3567687 by Arciel.Rekman
Minor fixes to gdb pretty printers by icculus.
Change 3568024 by Arciel.Rekman
Made SDL_SetWindowInputFocus() wait until window is viewable (UE-33369).
- Pull request #2608 contributed by Ereski.
- Updated x86_64 lib only (anticipating more changes to SDL).
#coderview Cengiz.Terzibas, Ryan.Gordon
Change 3568173 by Max.Chen
Movie Scene Capture: Delay on shot boundaries by setting the sequencer play rate to 0.
This allows particles, TAA, and other effects to settle on the shot cuts.
#jira UE-44598
Change 3568174 by Max.Chen
Sequencer: Added option to rerun construction scripts on bound actors in the sequence every frame.
#jira UE-31193
Change 3568331 by Matt.Kuhlenschmidt
PR #3850: Add extensible source navigation service (Contributed by mhutch)
Change 3568350 by Matt.Kuhlenschmidt
PR #3851: Add argument to pass params to standalone play session (Contributed by mhutch)
Change 3568387 by Matt.Kuhlenschmidt
PR #3852: Add FEditorDelegates::BeginLocalPlay event (Contributed by mhutch)
Change 3568541 by Arciel.Rekman
Merged Icculus' patch for copy-paste (UE-40071).
- Alas does not seem to fix inability to copy/paste between Output log and kate.
- Updated x86_64 lib only (anticipating more changes).
Change 3568547 by Arciel.Rekman
Fix OpenGL queries reused after deletion.
Change 3568790 by Matt.Kuhlenschmidt
PR #3857: Loading screen widgets not scaled correctly (Contributed by projectgheist)
Change 3568900 by Alexis.Matte
Fix the fbx re-import factory handler to say failed in case there was no geometry to import.
#jira UE-47506
Change 3568902 by Alexis.Matte
Reduce memory footprint when importing large FBX scene PR #3834
#jira UE-47833
Change 3569061 by Arciel.Rekman
Linux: remove unnecessary symbols for MSVC visualizers.
- Reported by ASan as collision because they exist in each DSO.
Change 3569782 by Cody.Albert
Updated ImportAssets Commandlet help text to properly reflect supported features.
Change 3569843 by Arciel.Rekman
SDL: add logic to select headless EGL device.
- SDL will try to guess which device is GPU using CUDA device id (can also be hinted explicitly).
- Also fixes the problem of engine not starting on some drivers that don't support the necessary EGL extensions.
Change 3570234 by Max.Chen
Sequencer: Import FBX settings. Added settings to toggle force front x axis and whether to create cameras that don't already exist in the level.
#jira UE-46754
Change 3570578 by Arciel.Rekman
Linux: make FAnsiMalloc compatible with malloc()/free().
- Prerequisite for ASan. Also helps fringe cases when we have to use FAnsiMalloc.
Change 3571015 by Alexis.Matte
Issue warning when we found zero normal, tangent or binormal
#jira UE-46419
Change 3571376 by Jamie.Dale
Force a unique package localization ID when loading packages for diffing
Change 3571412 by Jamie.Dale
Removed unused setting
Change 3571487 by Alexis.Matte
fix speed tree import cancel workflow
#jira UE-47482
Change 3571614 by Jamie.Dale
Games now use the native culture of any of the game targets as the fallback (rather than always using English)
This replaces the previously removed redundant setting from CL# 3571412
Change 3572649 by Jamie.Dale
SavePackageHelper now always honors KeepObjectFlags
Change 3572730 by Matt.Kuhlenschmidt
Guard against crash in the details panel when there is a message in the queue and something scrolls into view when the list has been invalidated
#jira UE-48037
Change 3572773 by Matt.Kuhlenschmidt
Guard against high res screenshot crashing if the requested image size doesnt match the image data size
#jira UE-47765
Change 3572813 by Michael.Trepka
Workaround for a mysterious issue in Xcode 9 beta 3 and 4 which makes it generate -Wnullability-inferred-on-nested-type warnings/errors in MetalDebugCommandEncoder.h even though we tell Clang to ignore them in MacPlatformCompilerPreSetup.h
Change 3573043 by Arciel.Rekman
FAnsiMalloc: fix compile issue (UE-48066).
#jira UE-48066
Change 3573236 by Arciel.Rekman
Linux: add UnrealLightmass to the installed build.
- Was also requested by a licensee on UDN.
Change 3573705 by Arciel.Rekman
SDL: update UE4 fork to the latest trunk (UETOOL-1242).
- Revision 11184 form 2017-08-04: http://hg.libsdl.org/SDL/rev/04063928c4a8
- Change by icculus (Ryan Gordon).
- Rebuilt x86_64 library only for now.
Change 3573741 by Arciel.Rekman
Fix crash when capturing a movie (UE-48093).
#jira UE-48093
Change 3574389 by Max.Chen
Sequencer: Array bounds check.
#jira UE-48095
Change 3574399 by Max.Chen
Sequencer: Fix crash in removing delegate
#jira UE-47461
Change 3574415 by Max.Chen
Sequencer: Put level visibility tracks in the SpawnObjects evaluation group to ensure levels are streamed before any possessable bindings are resolved
Change 3574416 by Max.Chen
Prevent slow task feedback from performing slow operations (flushing rendering commands, checking if shaders are initialized) when there are no modal dialogs open
Change 3574726 by Matt.Kuhlenschmidt
Focus the details view when actor selection changes if it is not focused
Change 3574922 by Michael.Trepka
Copy of CL 3574653 by Richard.Wallis
XCode Beta 4 Compile fixes. "Inferring '_Nonnull' for pointer type within array is deprecated "
Change 3576525 by Nick.Darnell
Editor - Data table rows names sort correctly in the property customization.
Blueprint - Fixing some crashes due to holding onto raw pointers instead of TWeakObjectPtrs.
UMG - SetWidgetClass now reinstances the widget if you change it at runtime.
Editor - Deleting actors that are still referenced now at least logs to the console what still references it.
Change 3576714 by Nick.Darnell
Editor - Build fix.
Change 3576770 by Jamie.Dale
Removed some dead code
It seems to be left over from the first attempt at stable localization keys
Change 3578433 by Matt.Kuhlenschmidt
Fix content browser settings being per project and having created a "Global" category for one setting
Change 3578556 by Max.Chen
Editor: Fix toolbar shared ref which was keeping the viewport toolbar around when switching between default and cinematic viewports.
#jira UE-48125
Change 3578561 by Matt.Kuhlenschmidt
Fix USD importing not respecting DestinationPath for automated import
Change 3580124 by Matt.Kuhlenschmidt
Fix bogus warning message when a property has an editcondition that is not marked edit aynwhere. This has always been supported and is the correct way to make an editcondition
Change 3581936 by Jamie.Dale
Restoring defaults for UContentBrowserSettings
Change 3582039 by Matt.Kuhlenschmidt
High DPI mode changes
- Editor viewport screen percentage is now adjusted automatically to account for DPI scaling. By default the scene will be rendered at a lower resolution based on screen percentage calculated based on 100/DPIScale. Users can override this automatic calcuation in the performance options if desired.
- DPI awareness is only set on windows in the editor now (still disabled by default)
- Fixed hit proxy calculation not working properly with screen percentage
- Developers can now register a delegate with SlateApplication to tell when a window's DPI changes
Change 3582049 by Matt.Kuhlenschmidt
Fix color picker not properly converting FColor properties back to gamma space
Change 3582054 by Matt.Kuhlenschmidt
Fix mac menus updating during unsafe times such as modal windows and slow tasks
#jira UE-47874
Change 3582084 by Jamie.Dale
Make sure to update the rendering resources for the active world if reloading its map build data
This prevents a crash in the renderer due to it holding onto stale data
Change 3582257 by Matt.Kuhlenschmidt
Fix widget component spawning widgets on cook
#jira UE-48201
Change 3582655 by Matt.Kuhlenschmidt
Fix DPI scale not being accounted for when entering immersive.
Change 3582706 by Matt.Kuhlenschmidt
Fix automation tests
Change 3582728 by Matt.Kuhlenschmidt
Turn on high dpi by default for windows editor
Change 3582732 by Matt.Kuhlenschmidt
Turn on high DPI by default for mac editor
Change 3583112 by Max.Chen
Sequencer: Add OnPlayReverse() event for when playback is in reverse
Change 3584130 by Matt.Kuhlenschmidt
PR #3897: Git plugin: fix action icon in history window (Contributed by SRombauts)
Change 3584237 by Matt.Kuhlenschmidt
Added the beginnings of a way to extend the usd importer with a custom resolver class that optionally handles prim identification and mesh and actor spawning.
Added a test resolver that handles prims based on usd "kind" metadata.
Change 3584535 by Matt.Kuhlenschmidt
Fix LOD identification in USD files
Change 3587703 by Matt.Kuhlenschmidt
Fix tooltip
Change 3587901 by Matt.Kuhlenschmidt
Fixed USD importing not finding and importing LODs properly
Change 3588380 by Matt.Kuhlenschmidt
Fix ctrl+w not duplicating on mac
#jira UE-46573
Change 3590435 by Jamie.Dale
Added support for in-editor previews of localized game text
This is configured by the "Preview Game Culture" setting, and will automatically be active when PIE is running (the preview language is also passed to any standalone games that are launched via the editor). This preview can also be used in the UMG editor to preview widgets in different languages.
While a preview is running, all editable FText fields are locked-down (read-only) to prevent accidentally clobbering source data with translation data. You can also use this new lock-down feature to prevent any localization changes in your project (set "LockLocalization" to "True" under the "Internationalization" section of either your DefaultGame or DefaultEngine INI).
In order to allow the game translations to be used in the editor, we now map the translation to any package localization ID variants when the LocRes data is loaded (or when looking up a specific piece of text). This is needed as the LocRes files only ever contain the "clean" versions of the IDs (without the package localization ID the editor uses), and also means that we no longer need to gather the "editor-only" variants of the text within assets.
Change 3592131 by Matt.Kuhlenschmidt
Log for newly converted actors being pending kill
#jira UE-47464
Change 3592200 by Matt.Kuhlenschmidt
Made the class viewer menu function properly on mac. Since it as a nomad tab it wasnt properly inserting itself into the top level menu on mac nor should it since it could be docked anywhere. The filters menu is now consistent with other filters menus
Change 3592227 by Matt.Kuhlenschmidt
Fix drag drop of actors being offset with high dpi monitors.
Change 3592719 by Bradut.Palas
#jira UE-45632 - dual key bindings feature
My approach was transforming the ActiveChord and DefaultChord into arrays and accessing them through an enum class called EMultipleKeyBindingIndex. A lot of connecting code, function prototypes, and data structures had to be changed to accomodate this. Most menus and tooltip texts are generated using the first valid active shortcut.
Change 3592793 by Bradut.Palas
Fix compile warnings for InputBindingManager (there were actually hidden bugs among them)
Change 3593128 by Matt.Kuhlenschmidt
Force low quality mode for background blurs by default on android
Change 3593579 by Michael.Dupuis
#jira UE-47223 :
If we have no world simply return null when GetLandscapeInfo is called
Handle the cases in PostEditChange to handle null returned from GetLandscapeInfo
Change 3593580 by Michael.Dupuis
Added missing shaders while generating thumbnails
Change 3593582 by Michael.Dupuis
#jira UE-47492 : Make sure LayerInfo is valid before accessing data
Change 3593584 by Michael.Dupuis
#jira UE-47253: Do not recreate the scene info in simulation mode
Change 3593585 by Michael.Dupuis
#jira UE-48484: no longer mark the package dirty while generating the GrassMap if they were not existing
Change 3593586 by Michael.Dupuis
#jira UE-48483 : hide the Rendering property group so user can't by mistake change the actor visibility
Change 3593593 by Michael.Dupuis
#jira UE-48327: Added guard to prevent crash when using CVarFoliageDiscardDataOnLoad and having invalid foliage in your map
Change 3593597 by Michael.Dupuis
#jira UE-48309: Do not build the tree if the static mesh is not even loaded yet
#jira UE-48340: Properly support the Random stream and partial buffer update
#jira UE-48228: Instance from blueprint are now visible in standalone game
#jira UE-45854: Crash probably linked to post load called on not loaded static mesh
#jira UE-48035: Properly init the per instance render data when creating a new component
Only update instance in non archetype or CDO.
Change 3594060 by Matt.Kuhlenschmidt
Fix high DPI mode being set for non-editor. Also prevent possible crashes due to dll handle for high DPI method being freed before called
Change 3594355 by Matt.Kuhlenschmidt
Change API help link to point to a website since offline CHM based docs are no longer used
#jira UE-48230
Change 3595358 by Matt.Kuhlenschmidt
Fixed bad initial window position and sizes for editor windows
By default SWindow.ClientSize will assume unscaled window size and will scale it based on DPI as needed. AdjustInitialSizeAndPositionForDPIScale argument can be used to disable this if needed
Fixed a dock tabs and the main frame not taking into account dpi scale when saving their layout. Now we always save window size at 1.0 scale and auto scale it based on DPI of the monitor it opens on.
#jira UE-48446
Change 3595590 by Matt.Kuhlenschmidt
Fix missing includes
Change 3595792 by Matt.Kuhlenschmidt
Fix style warnings
Change 3596418 by Bradut.Palas
fixing initial issue with dual keybinds (removed ensure macro to speedup first use of alternate key)
Change 3598679 by Max.Chen
PR #3872: Fix small typo in ImagePlate Plugin (Contributed by TheCodez)
#jira UE-48141
Change 3598720 by Max.Chen
Cine Camera: Add toggle to disable constraining the roll when look at tracking is enabled. This allows the user to animate the roll while tracking an object.
#jira UE-48316
Change 3600236 by Alexis.Matte
Create a LOD Custom Mode in the meshes editor UI. This allow user to compare details values between LODs
#jira UE-46822
Change 3600260 by Alexis.Matte
Make sure temporary rename do not create redirector
#jira UE-48364
Change 3600671 by Lauren.Ridge
PR #3913: Fixed 3D preview issue in the material editor (Contributed by YuchenMei)
#jira UE-48539
#jira UE-48180
#jira UE-48182
Change 3600812 by Jamie.Dale
We now defer the registration of IME contexts until an editable text first gains focus
Certain IMEs can have very high per-context costs, so this avoids that cost until we know that we definitely need to use the context
#jira UE-48100
Change 3601839 by Matt.Kuhlenschmidt
Fix USD import crash with "facevarying" normals
Change 3602434 by Jamie.Dale
Removing dead code
These flags were never being tested or used in any meaningul way
Change 3602611 by Jamie.Dale
Ensure PackageToReload is non-null
#jira UE-46655
Change 3602648 by Jamie.Dale
Fixed custom columns with the same name as fixed columns causing infinite duplications in the content browser
#jira UE-47392
Change 3602651 by Lauren.Ridge
Fix for parameter tooltips not being found
#jira UE-47417
Change 3604172 by Bradut.Palas
#jira UE-48449
#jira UE-48380
#jira UE-48381
#jira UE-48423
I moved the IsFilenameValidForSaving() function from FEditorFileUtils to FFileHelper so that it is accessible from CollectionManager.cpp in order to validate collection names as file names and no longer trigger any of the bugs.
Change 3604210 by Bradut.Palas
#jira UE-48718
Regression issue appeared from fixing a crash when using console command "open"
Reworked by only refusing to open local URLs in case of client mode and multiprocess being active simultaneously.
Change 3604258 by Jamie.Dale
IME contexts can now flag themselves as dead to avoid latent IME callbacks trying to access a deleted widget
#jira UE-46815
#jira UE-47295
Change 3604312 by Matt.Kuhlenschmidt
PR #3931: Fixing a few obvious copy & paste errors. (Contributed by DaveC79)
Change 3604352 by Matt.Kuhlenschmidt
Fix crash accessing potentially invalid parent layout from a detail category
#jira UE-48729
Change 3604402 by Lauren.Ridge
Epic Friday - array drag and drop
Change 3605228 by Cody.Albert
TSets and TMaps should now properly rehash if a key is modified in the details panel.
Change 3605275 by Alexis.Matte
Merge actor do not keep the material slot name
#jira UE-43246
Change 3605715 by Max.Chen
Sequencer: Fix cinematic mode getting activated on BeginPlay() instead of OnStartedPlaying().
#jira UE-48770
Change 3606411 by Max.Chen
Sequencer: Fix a few player state issues. When paused, calling stop now tears down properly (spawnables are removed, etc). When a level sequence is deleted, tears down properly as well.
#jira UE-42008
Change 3606440 by Max.Chen
Sequencer: Update spawanble name when the spawnable actor name is changed.
#jira UE-47815
Change 3606899 by Lauren.Ridge
Disabling enum-based arrays from reordering
Change 3606958 by Lauren.Ridge
Visual polish on array handles
Change 3607733 by Max.Chen
Sequencer: Check null in camera cut
Change 3607849 by Max.Chen
Sequencer: Clip transport controls.
#jira UE-48812
Change 3608181 by Max.Chen
#jira UE-48813 Correctly set GPlayInEditorID when initializing the PIE gameinstance, which does the initial tick. This fixes autoplay sequences
Copy from Dev-Framework
Change 3608361 by christopher.biancard
QAGame: Submitting test content for Array Element Reorder testing
Change 3608512 by Alexis.Matte
Add fbx exporter option dialog, support export all and cancel all functionality when doing bulk export.
#jira UE-48058
Change 3608629 by Max.Chen
Camera Rig: Fix crane and rail not being packaged properly.
#jira UE-48829
Change 3609217 by Matt.Kuhlenschmidt
Added a lock around access to slate active timers to protect it against race conditions when accessed on the slate movie thread and the game thread
Change 3609722 by Alexis.Matte
Make sure a warning is log when we cannot export an animation sequence.
#jira UE-48390
Change 3609774 by Alexis.Matte
Fix the merge actor build LOD scale again, a previous merge erase the fix
#jira UE-48156
Change 3609891 by christopher.biancard
QAGame: Minor additions for test coverage on Array Element Reorder
Change 3610171 by Lauren.Ridge
Fixes for reordering metadata, creating actual swap function out of three element functions
#jira UE-48823
Change 3610407 by Lauren.Ridge
Fixing highlighting and behavior to place dragged row in the spot you release (not below)
Change 3610472 by Lauren.Ridge
Moving final location logic
Change 3610797 by Lauren.Ridge
Disabling dragging handles during PIE
Change 3611089 by Lauren.Ridge
Disabling handles when overall tree is disabled
Change 3612479 by Lauren.Ridge
Fix for asset contex menu warning
#jira UE-46667
Change 3612791 by Michael.Dupuis
#jira UE-48914 : Add the possibility to specify if we need CPU access to the instance buffer depending on the usage.
Grass should always have CPU access.
Change 3612802 by Michael.Dupuis
missing file from checkin 3612791
Change 3612805 by Max.Chen
Sequencer: Fix crash with null GEditor
Copy from Release-4.17
#jira UE-48443
Change 3612806 by Max.Chen
Sequencer: Fix crash when capturing a movie with options enabling separate process and close editor.
Copy from Release-4.17
#jira UE-48487
Change 3612807 by Max.Chen
Sequencer: Fix crash upgrading the time range of a null track.
Copy from Release-4.17
#jira UE-48490
Change 3612808 by Max.Chen
Sequencer: Fixed dragging skeletal animations causing them to revert back to t-pose
Copy from Release-4.17
#jira UE-48367
Change 3612849 by Arciel.Rekman
Fix tesselation in packaged Linux projects (UE-24301).
- Change by Cengiz.Terzibas.
#jira UE-24301
Change 3613022 by Nick.Darnell
Editor - Fixing a crash on load with a null CoordIndex json node.
Change 3613030 by Matt.Kuhlenschmidt
PR #3932: UE-48693: if instead of while statement (Contributed by projectgheist)
#jira UE-48747
Change 3613047 by Matt.Kuhlenschmidt
PR #3933: Git plugin: add "branch source" in history window (Contributed by SRombauts)
Change 3613050 by Matt.Kuhlenschmidt
PR #3942: Sort Data Table Structures Alphabetically (Contributed by Nick-Pearson)
Change 3613062 by Matt.Kuhlenschmidt
PR #3939: Fix a typo in RecordQualityLevelsAnalytics(). (Contributed by samhocevar)
Change 3613241 by Nick.Darnell
Editor - Fixing the content browser's view settings to be project agnostic, and they will start saving again.
Change 3613329 by Lauren.Ridge
Moving favorite levels to a standard submenu so they also work on Mac
Change 3613344 by Nick.Darnell
Editor - Fixing the achorgrid show up as white in HDPI mode, seems because we were upsampling the image, the blend was between dark and a transparent white, so that caused everything to turn white in HDPI mode.
#jira UE-48921
Change 3613380 by Matt.Kuhlenschmidt
Fix FBX window being off the screen in high DPI
#jira UE-48872
Change 3614598 by Matt.Kuhlenschmidt
Fixed Sequencer Keyframes appearing out of place on High DPI Monitors
#jira UE-48915
Change 3614625 by Matt.Kuhlenschmidt
Fixed not being able to click on BSP correctly in high dpi
#jira UE-48947
Change 3614672 by Matt.Kuhlenschmidt
Fix combo box windows being larger than necessary on high dpi monitors
#jira UE-48908
Change 3614699 by Matt.Kuhlenschmidt
Fix typo
#jira UE-48941
Change 3615011 by Matt.Kuhlenschmidt
Fix color picker calculation appearing offscreen for high dpi
Change 3615013 by Michael.Dupuis
#jira UE-48897: Properly rebuild the tree when reapplying instance to the component
Change 3615014 by Colin.Benoit
Sequencer Recorder test content
Change 3615048 by Colin.Benoit
Sequencer Recorder: more test content
Change 3615118 by Lauren.Ridge
Updating realtime state of viewports to also change when settings toggled
#jira UE-48884
Change 3615127 by Lauren.Ridge
Remove delegate binding on viewport destruction
Change 3615180 by Bradut.Palas
#jira UE-48167 profiler crash
Don't duplicate the graph data when rebuilding because that completely voids the OneToOneMapping mechanism, resulting in the crash. Looking up objects in the mapping would always return null because the mapping contains the old addresses, before the rebuild.
One option would have been to completely rebuild the mapping according to the duplicate graph, which would be dubious because the duplicate method isn't specifically designed so that the result would replace the source.
But it looks like duplicating the data is not needed, it's safe to rebuild in-place, RebuildForFilter() doesn't do anything illegal with the objects. This is also the only purpose and the only reference of the function.
Change 3615232 by Lauren.Ridge
Adding input handling to the material editor viewport client
#jira UE-48909
Change 3615703 by Jamie.Dale
Fixed crash when fixing up references after a package rename failed
#jira UE-48856
Change 3615752 by Matt.Kuhlenschmidt
More generic fix for color picker and other windows that use CalculatePopupWindowPostion not accounting for DPI scale
Change 3615907 by Jamie.Dale
Fixed some crashes caused by CL# 3600812
Change 3616031 by Matt.Kuhlenschmidt
Added guard against invalid blueprints (ones without a generated class) being trying to be opened in the property matrix and failing
#jira UE-48986
Change 3616151 by Arciel.Rekman
Fixing adding array elements in config.
- "+Blah=Foo" will do Blah.AddUnique(Foo)
- ".Blah=Foo" will do Blah.Add(Foo)
- See JoshA re: why (also see: https://udn.unrealengine.com/questions/388157/incorrect-behavior-in-configcacheinicpp.html?childToView=389307)
Change 3616439 by Andrew.Porter
QAGame: Updating level visibility content in sequencer smoke map
Change 3616441 by Matt.Kuhlenschmidt
Fix more sequencer track offsetting with DPI scale
#jira UE-48981
Change 3617263 by Max.Chen
Sequencer: Fix crash in level visibility teardown. Null playback context.
#jira UE-49012
Change 3617316 by Max.Chen
Sequencer: Fixed a regression where the frame rate isn't getting initialized for a movie scene.
Change 3617648 by Matt.Kuhlenschmidt
Adding some windows specific logging around setting or failing to set process dpi awareness
Change 3617665 by Matt.Kuhlenschmidt
Guard against layers module not being loaded in keybinding automation test
Change 3617731 by Arciel.Rekman
Fix crashes on AMD Mesa drivers (UE-48374).
- Do not expose unnecessary symbols from libelf.a to avoid symbol collision with system library used by drivers.
Change 3617923 by Bradut.Palas
#jira UE-47072
Editor was crashing because deleted actor was not cleaned properly from asset editors. Changed IAssetEditorInstance to offer a function for deleting an object from the editor.
Change 3618088 by Matt.Kuhlenschmidt
Guard against crash with potentially invalid worlds in preview scenes
#jira UE-48997
Change 3618373 by Matt.Kuhlenschmidt
Force worldsettings to be hidden in editor so that it is not considered for selection
#jira UE-48996
Change 3618464 by Max.Chen
Sequencer: Fix regression where spawnables don't play because they're defined as temporary editor actors.
#jira UE-48923
Change 3619789 by Matt.Kuhlenschmidt
Fix DPI scale warnings in any kind of headless editor mode
Change 3619802 by Jamie.Dale
Fixed deprecation warning in malloc profiler
Change 3619841 by Matt.Kuhlenschmidt
Fix missing icons in the package project menu
#jira UE-48674
Change 3619991 by Lauren.Ridge
Fix typo in transaction message
#jira UE-48993
Change 3620086 by Lauren.Ridge
Moving realtime viewport logic to refresh instead of construct so it is always triggered upon opening a new material editor
#jira UE-48884
Change 3620616 by Matt.Kuhlenschmidt
Fix up file
Change 3621002 by Matt.Kuhlenschmidt
Back out change to apply scaling rules in loading screens since blueprint based DPI scaling rule classes will not have been created yet
#jira UE-49125
Change 3621049 by Arciel.Rekman
Fix a build error.
- Also make sure that we don't print confusing message when no messagebox can be shown
(this code changed during the merge).
Change 3621064 by Arciel.Rekman
Deleted too much in the previous changelist.
Change 3621369 by Matt.Kuhlenschmidt
Fix keybindings automation test failing due to multiple entries in the active choords array pointing to the same thing
#jira UE-49131
[CL 3621569 by Matt Kuhlenschmidt in Main branch]
2017-08-31 21:51:42 -04:00
# include "Misc/FileHelper.h"
2020-04-28 06:20:33 -04:00
# include "Misc/ScopeRWLock.h"
# include "Async/ParallelFor.h"
2021-11-30 14:20:47 -05:00
# include "Misc/CommandLine.h"
2022-02-10 10:05:44 -05:00
# include "SourceControlPreferences.h"
2024-04-19 18:17:59 -04:00
# include "Tasks/Task.h"
2014-03-14 14:13:41 -04:00
# define LOCTEXT_NAMESPACE "CollectionManager"
2024-04-19 18:17:59 -04:00
// Base class for lock hierarchy. When used as a function parameter it means the called must hold at least a read lock
class FCollectionLock
{
protected :
UE_NODISCARD_CTOR explicit FCollectionLock ( FRWLock & InLockObject , bool InWriteLock )
: LockObject ( InLockObject )
, bWriteLock ( InWriteLock )
{
if ( InWriteLock )
{
LockObject . WriteLock ( ) ;
}
else
{
LockObject . ReadLock ( ) ;
}
}
// Promoted the lock from read to write, possibly being interrupted by another writer in between
void PromoteInterruptible ( )
{
if ( ! bWriteLock )
{
LockObject . ReadUnlock ( ) ;
LockObject . WriteLock ( ) ;
bWriteLock = true ;
}
}
~ FCollectionLock ( )
{
if ( bWriteLock )
{
LockObject . WriteUnlock ( ) ;
}
else
{
LockObject . ReadUnlock ( ) ;
}
}
// Used for assertions to confirm that the correct kind of lock has been taken
bool IsWriteLock ( )
{
return bWriteLock ;
}
private :
UE_NONCOPYABLE ( FCollectionLock ) ;
FRWLock & LockObject ;
bool bWriteLock = false ;
} ;
// Scoped lock type used to hold lock and to tag methods which should at least hold a read lock
class FCollectionLock_Read : public FCollectionLock
{
public :
UE_NODISCARD_CTOR explicit FCollectionLock_Read ( FRWLock & InLockObject )
: FCollectionLock ( InLockObject , false )
{
}
} ;
// A lock on the collection manager which begins in a read only state and can be promoted into a write lock with potential interruption in between
class FCollectionLock_RW : public FCollectionLock
{
public :
UE_NODISCARD_CTOR explicit FCollectionLock_RW ( FRWLock & InLockObject , bool bWrite = false )
: FCollectionLock ( InLockObject , bWrite )
{
}
// Promoted the lock from read to write, possibly being interrupted by another writer in between
using FCollectionLock : : PromoteInterruptible ;
// Used for assertions to confirm that the correct kind of lock has been taken
using FCollectionLock : : IsWriteLock ;
} ;
// Write lock on the collection manager
class FCollectionLock_Write : public FCollectionLock_RW
{
public :
UE_NODISCARD_CTOR explicit FCollectionLock_Write ( FRWLock & InLockObject )
: FCollectionLock_RW ( InLockObject , true )
{
}
} ;
/** Wraps up the lazy caching of the collection manager */
class FCollectionManagerCache
{
public :
FCollectionManagerCache ( TMap < FCollectionNameType , TSharedRef < FCollection > > * InAvailableCollections ) ;
/**
* Dirty the parts of the cache that need to change when a collection is added to our collection manager .
* The collection manager must be locked .
*/
void HandleCollectionAdded ( FCollectionLock_Write & ) ;
/**
* Dirty the parts of the cache that need to change when a collection is removed from our collection manager
* The collection manager must be locked .
*/
void HandleCollectionRemoved ( FCollectionLock_Write & ) ;
/**
* Dirty the parts of the cache that need to change when a collection is modified
* The collcetion manager must be lockedl
*/
void HandleCollectionChanged ( FCollectionLock_Write & ) ;
/**
* Update the given dirty parts of the cache based on which parts will be accessed while the given lock is held .
* A read / write lock will be promoted to a write lock if the cache must be updated .
* A write lock may also be passed as it extends the read / write lock .
* The calling thread may be interrupted by another write operation during the promotion operation .
* Therefore , caches should be updated as early as possible in order to prevent invalidation of state .
*
* This function is used rather than updating the caches in the Get * functions to prevent issues with pre - emption
* on the lock upgrade deep into a method .
*/
void UpdateCaches ( FCollectionLock_RW & InGuard , ECollectionCacheFlags Flags ) ;
/**
* Access the CachedCollectionNamesFromGuids map , asserting that it is up - to - date .
* The collection manager must be read - locked .
*/
const TMap < FGuid , FCollectionNameType > & GetCachedCollectionNamesFromGuids ( FCollectionLock & ) const ;
/**
* Access the CachedObjects map , asserting that it is up - to - date .
* The collection manager must be read - locked .
*/
const TMap < FSoftObjectPath , TArray < FObjectCollectionInfo > > & GetCachedObjects ( FCollectionLock & ) const ;
/**
* Access the CachedHierarchy map , asserting that it is up - to - date .
* The collection manager must be read - locked .
*/
const TMap < FGuid , TArray < FGuid > > & GetCachedHierarchy ( FCollectionLock & ) const ;
/**
* Access the CachedColors array , asserting that it is up - to - date
* The collection manager must be read - locked .
*/
const TArray < FLinearColor > & GetCachedColors ( FCollectionLock & ) const ;
enum class ERecursiveWorkerFlowControl : uint8
{
Stop ,
Continue ,
} ;
typedef TFunctionRef < ERecursiveWorkerFlowControl ( const FCollectionNameType & , ECollectionRecursionFlags : : Flag ) > FRecursiveWorkerFunc ;
/**
* Perform a recursive operation on the given collection and optionally its parents and children .
* The collection manager must be read - locked and UpdateCaches must be called for names and hierarchy .
*/
void RecursionHelper_DoWork ( FCollectionLock & , const FCollectionNameType & InCollectionKey , const ECollectionRecursionFlags : : Flags InRecursionMode , FRecursiveWorkerFunc InWorkerFunc ) const ;
private :
/** Reference to the collections that are currently available in our owner collection manager */
TMap < FCollectionNameType , TSharedRef < FCollection > > * AvailableCollections ;
/** A map of collection GUIDs to their associated collection names */
TMap < FGuid , FCollectionNameType > CachedCollectionNamesFromGuids_Internal ;
/** A map of object paths to their associated collection info - only objects that are in collections will appear in here */
TMap < FSoftObjectPath , TArray < FObjectCollectionInfo > > CachedObjects_Internal ;
/** A map of parent collection GUIDs to their child collection GUIDs - only collections that have children will appear in here */
TMap < FGuid , TArray < FGuid > > CachedHierarchy_Internal ;
/** An array of all unique colors currently used by collections */
TArray < FLinearColor > CachedColors_Internal ;
/** Which parts of the cache are dirty */
ECollectionCacheFlags DirtyFlags = ECollectionCacheFlags : : All ;
ERecursiveWorkerFlowControl RecursionHelper_DoWorkOnParents ( FCollectionLock & , const FCollectionNameType & InCollectionKey , FRecursiveWorkerFunc InWorkerFunc ) const ;
ERecursiveWorkerFlowControl RecursionHelper_DoWorkOnChildren ( FCollectionLock & , const FCollectionNameType & InCollectionKey , FRecursiveWorkerFunc InWorkerFunc ) const ;
} ;
FCollectionManagerCache : : FCollectionManagerCache ( TMap < FCollectionNameType , TSharedRef < FCollection > > * InAvailableCollections )
2015-07-06 09:40:48 -04:00
: AvailableCollections ( InAvailableCollections )
{
}
2024-04-19 18:17:59 -04:00
void FCollectionManagerCache : : HandleCollectionAdded ( FCollectionLock_Write & )
2015-07-06 09:40:48 -04:00
{
2024-04-19 18:17:59 -04:00
DirtyFlags | = ECollectionCacheFlags : : Names ;
2015-07-06 09:40:48 -04:00
}
2024-04-19 18:17:59 -04:00
void FCollectionManagerCache : : HandleCollectionRemoved ( FCollectionLock_Write & )
2015-07-06 09:40:48 -04:00
{
2024-04-19 18:17:59 -04:00
DirtyFlags | = ECollectionCacheFlags : : All ;
2015-07-06 09:40:48 -04:00
}
2024-04-19 18:17:59 -04:00
void FCollectionManagerCache : : HandleCollectionChanged ( FCollectionLock_Write & )
2015-07-06 09:40:48 -04:00
{
2024-04-19 18:17:59 -04:00
DirtyFlags | = ECollectionCacheFlags : : Objects | ECollectionCacheFlags : : Hierarchy | ECollectionCacheFlags : : Colors ;
2015-07-06 09:40:48 -04:00
}
2024-04-19 18:17:59 -04:00
void FCollectionManagerCache : : UpdateCaches ( FCollectionLock_RW & InGuard , ECollectionCacheFlags ToUpdate )
2015-07-06 09:40:48 -04:00
{
2024-04-19 18:17:59 -04:00
// Updating objects or hierarchy requires name mapping
if ( EnumHasAnyFlags ( ToUpdate , ECollectionCacheFlags : : Hierarchy | ECollectionCacheFlags : : Objects ) )
{
ToUpdate | = ECollectionCacheFlags : : Names ;
}
// Updating objects requires hierarchy
if ( EnumHasAnyFlags ( ToUpdate , ECollectionCacheFlags : : Objects ) )
{
ToUpdate | = ECollectionCacheFlags : : Hierarchy ;
}
if ( EnumHasAnyFlags ( DirtyFlags , ToUpdate ) )
{
InGuard . PromoteInterruptible ( ) ;
}
if ( ! EnumHasAnyFlags ( DirtyFlags , ToUpdate ) )
{
// Caches we care about were updated while we switched locks
return ;
}
// Limit updates to what's dirty
ToUpdate = ToUpdate & DirtyFlags ;
const double CacheStartTime = FPlatformTime : : Seconds ( ) ;
if ( EnumHasAllFlags ( ToUpdate , ECollectionCacheFlags : : Names ) )
2015-07-06 09:40:48 -04:00
{
CachedCollectionNamesFromGuids_Internal . Reset ( ) ;
2024-04-19 18:17:59 -04:00
EnumRemoveFlags ( DirtyFlags , ECollectionCacheFlags : : Names ) ;
for ( const TPair < FCollectionNameType , TSharedRef < FCollection > > & AvailableCollection : * AvailableCollections )
2015-07-06 09:40:48 -04:00
{
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
const TSharedRef < FCollection > & Collection = AvailableCollection . Value ;
CachedCollectionNamesFromGuids_Internal . Add ( Collection - > GetCollectionGuid ( ) , CollectionKey ) ;
}
}
2024-04-19 18:17:59 -04:00
if ( EnumHasAllFlags ( ToUpdate , ECollectionCacheFlags : : Hierarchy ) )
2015-07-06 09:40:48 -04:00
{
CachedHierarchy_Internal . Reset ( ) ;
2024-04-19 18:17:59 -04:00
EnumRemoveFlags ( DirtyFlags , ECollectionCacheFlags : : Hierarchy ) ;
const TMap < FGuid , FCollectionNameType > & CachedCollectionNamesFromGuids = GetCachedCollectionNamesFromGuids ( InGuard ) ;
2015-07-06 09:40:48 -04:00
2024-04-19 18:17:59 -04:00
for ( const TPair < FCollectionNameType , TSharedRef < FCollection > > & AvailableCollection : * AvailableCollections )
2015-07-06 09:40:48 -04:00
{
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
const TSharedRef < FCollection > & Collection = AvailableCollection . Value ;
// Make sure this is a known parent GUID before adding it to the map
const FGuid & ParentCollectionGuid = Collection - > GetParentCollectionGuid ( ) ;
if ( CachedCollectionNamesFromGuids . Contains ( ParentCollectionGuid ) )
{
2024-04-19 18:17:59 -04:00
TArray < FGuid > & CollectionChildren = CachedHierarchy_Internal . FindOrAdd ( ParentCollectionGuid ) ;
2015-07-06 09:40:48 -04:00
CollectionChildren . AddUnique ( Collection - > GetCollectionGuid ( ) ) ;
}
}
}
2024-04-19 18:17:59 -04:00
if ( EnumHasAllFlags ( ToUpdate , ECollectionCacheFlags : : Objects ) )
{
CachedObjects_Internal . Reset ( ) ;
EnumRemoveFlags ( DirtyFlags , ECollectionCacheFlags : : Objects ) ;
2015-07-06 09:40:48 -04:00
2024-04-19 18:17:59 -04:00
for ( const TPair < FCollectionNameType , TSharedRef < FCollection > > & AvailableCollection : * AvailableCollections )
{
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
const TSharedRef < FCollection > & Collection = AvailableCollection . Value ;
const TSet < FSoftObjectPath > & ObjectsInCollection = Collection - > GetObjectSet ( ) ;
if ( ObjectsInCollection . Num ( ) = = 0 )
{
continue ;
}
auto RebuildCachedObjectsWorker = [ CachedObjects_Internal = & CachedObjects_Internal , & ObjectsInCollection ]
( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > ERecursiveWorkerFlowControl
{
// The worker reason will tell us why this collection is being processed (eg, because it is a parent of the collection we told it to DoWork on),
// however, the reason this object exists in that parent collection is because a child collection contains it, and this is the reason we need
// to put into the FObjectCollectionInfo, since that's what we'll test against later when we do the "do my children contain this object"? test
// That's why we flip the reason logic here...
ECollectionRecursionFlags : : Flag ReasonObjectInCollection = InReason ;
switch ( InReason )
{
case ECollectionRecursionFlags : : Parents :
ReasonObjectInCollection = ECollectionRecursionFlags : : Children ;
break ;
case ECollectionRecursionFlags : : Children :
ReasonObjectInCollection = ECollectionRecursionFlags : : Parents ;
break ;
default :
break ;
}
for ( const FSoftObjectPath & ObjectPath : ObjectsInCollection )
{
TArray < FObjectCollectionInfo > & ObjectCollectionInfos = CachedObjects_Internal - > FindOrAdd ( ObjectPath ) ;
FObjectCollectionInfo * ObjectInfoPtr = ObjectCollectionInfos . FindByPredicate ( [ InCollectionKey ] ( FObjectCollectionInfo & InCollectionInfo ) { return InCollectionInfo . CollectionKey = = InCollectionKey ; } ) ;
if ( ObjectInfoPtr )
{
ObjectInfoPtr - > Reason | = ReasonObjectInCollection ;
}
else
{
ObjectCollectionInfos . Add ( FObjectCollectionInfo ( InCollectionKey , ReasonObjectInCollection ) ) ;
}
}
return ERecursiveWorkerFlowControl : : Continue ;
} ;
// Recursively process all collections so that they know they contain these objects (and why!)
RecursionHelper_DoWork ( InGuard , CollectionKey , ECollectionRecursionFlags : : All , RebuildCachedObjectsWorker ) ;
}
}
if ( EnumHasAllFlags ( ToUpdate , ECollectionCacheFlags : : Colors ) )
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
{
CachedColors_Internal . Reset ( ) ;
2024-04-19 18:17:59 -04:00
EnumRemoveFlags ( DirtyFlags , ECollectionCacheFlags : : Colors ) ;
for ( const TPair < FCollectionNameType , TSharedRef < FCollection > > & AvailableCollection : * AvailableCollections )
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
{
const TSharedRef < FCollection > & Collection = AvailableCollection . Value ;
if ( const TOptional < FLinearColor > CollectionColor = Collection - > GetCollectionColor ( ) )
{
2024-04-19 18:17:59 -04:00
CachedColors_Internal . Add ( CollectionColor . GetValue ( ) ) ;
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
}
2024-04-19 18:17:59 -04:00
// Deduplicate
Algo : : SortBy ( CachedColors_Internal , [ ] ( FLinearColor Color ) { return GetTypeHash ( Color ) ; } ) ;
CachedColors_Internal . SetNum ( Algo : : Unique ( CachedColors_Internal ) ) ;
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
}
}
2024-04-19 18:17:59 -04:00
UE_LOG ( LogCollectionManager , Verbose , TEXT ( " Rebuilt caches for %d collections in in %0.6f seconds " ) , AvailableCollections - > Num ( ) , FPlatformTime : : Seconds ( ) - CacheStartTime ) ;
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
}
2024-04-19 18:17:59 -04:00
void FCollectionManagerCache : : RecursionHelper_DoWork ( FCollectionLock & Guard ,
const FCollectionNameType & InCollectionKey ,
const ECollectionRecursionFlags : : Flags InRecursionMode ,
FRecursiveWorkerFunc InWorkerFunc ) const
2015-07-06 09:40:48 -04:00
{
2024-04-19 18:17:59 -04:00
checkf ( ! EnumHasAnyFlags ( DirtyFlags , ECollectionCacheFlags : : RecursionWorker ) , TEXT ( " Collection cache must be updated with RecursionWorker flags before recursing through hierarchy. " ) ) ;
2015-07-06 09:40:48 -04:00
if ( ( InRecursionMode & ECollectionRecursionFlags : : Self ) & & InWorkerFunc ( InCollectionKey , ECollectionRecursionFlags : : Self ) = = ERecursiveWorkerFlowControl : : Stop )
{
return ;
}
2024-04-19 18:17:59 -04:00
if ( ( InRecursionMode & ECollectionRecursionFlags : : Parents ) & & RecursionHelper_DoWorkOnParents ( Guard , InCollectionKey , InWorkerFunc ) = = ERecursiveWorkerFlowControl : : Stop )
2015-07-06 09:40:48 -04:00
{
return ;
}
2024-04-19 18:17:59 -04:00
if ( ( InRecursionMode & ECollectionRecursionFlags : : Children ) & & RecursionHelper_DoWorkOnChildren ( Guard , InCollectionKey , InWorkerFunc ) = = ERecursiveWorkerFlowControl : : Stop )
2015-07-06 09:40:48 -04:00
{
return ;
}
}
2024-04-19 18:17:59 -04:00
FCollectionManagerCache : : ERecursiveWorkerFlowControl FCollectionManagerCache : : RecursionHelper_DoWorkOnParents (
FCollectionLock & Guard , const FCollectionNameType & InCollectionKey , FRecursiveWorkerFunc InWorkerFunc ) const
2015-07-06 09:40:48 -04:00
{
2024-04-19 18:17:59 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections - > Find ( InCollectionKey ) ;
2015-07-06 09:40:48 -04:00
if ( CollectionRefPtr )
{
2024-04-19 18:17:59 -04:00
const TMap < FGuid , FCollectionNameType > & CachedCollectionNamesFromGuids = GetCachedCollectionNamesFromGuids ( Guard ) ;
2015-07-06 09:40:48 -04:00
const FCollectionNameType * const ParentCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( ( * CollectionRefPtr ) - > GetParentCollectionGuid ( ) ) ;
if ( ParentCollectionKeyPtr )
{
2024-04-19 18:17:59 -04:00
if ( InWorkerFunc ( * ParentCollectionKeyPtr , ECollectionRecursionFlags : : Parents ) = = ERecursiveWorkerFlowControl : : Stop | | RecursionHelper_DoWorkOnParents ( Guard , * ParentCollectionKeyPtr , InWorkerFunc ) = = ERecursiveWorkerFlowControl : : Stop )
2015-07-06 09:40:48 -04:00
{
return ERecursiveWorkerFlowControl : : Stop ;
}
}
}
return ERecursiveWorkerFlowControl : : Continue ;
}
2024-04-19 18:17:59 -04:00
FCollectionManagerCache : : ERecursiveWorkerFlowControl FCollectionManagerCache : : RecursionHelper_DoWorkOnChildren (
FCollectionLock & Guard , const FCollectionNameType & InCollectionKey , FRecursiveWorkerFunc InWorkerFunc ) const
2015-07-06 09:40:48 -04:00
{
2024-04-19 18:17:59 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections - > Find ( InCollectionKey ) ;
2015-07-06 09:40:48 -04:00
if ( CollectionRefPtr )
{
2024-04-19 18:17:59 -04:00
const TMap < FGuid , TArray < FGuid > > & CachedHierarchy = GetCachedHierarchy ( Guard ) ;
2015-07-06 09:40:48 -04:00
const TArray < FGuid > * const ChildCollectionGuids = CachedHierarchy . Find ( ( * CollectionRefPtr ) - > GetCollectionGuid ( ) ) ;
if ( ChildCollectionGuids )
{
for ( const FGuid & ChildCollectionGuid : * ChildCollectionGuids )
{
2024-04-19 18:17:59 -04:00
const TMap < FGuid , FCollectionNameType > & CachedCollectionNamesFromGuids = GetCachedCollectionNamesFromGuids ( Guard ) ;
2015-07-06 09:40:48 -04:00
const FCollectionNameType * const ChildCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( ChildCollectionGuid ) ;
if ( ChildCollectionKeyPtr )
{
2024-04-19 18:17:59 -04:00
if ( InWorkerFunc ( * ChildCollectionKeyPtr , ECollectionRecursionFlags : : Children ) = = ERecursiveWorkerFlowControl : : Stop | | RecursionHelper_DoWorkOnChildren ( Guard , * ChildCollectionKeyPtr , InWorkerFunc ) = = ERecursiveWorkerFlowControl : : Stop )
2015-07-06 09:40:48 -04:00
{
return ERecursiveWorkerFlowControl : : Stop ;
}
}
}
}
}
return ERecursiveWorkerFlowControl : : Continue ;
}
2024-04-19 18:17:59 -04:00
const TMap < FGuid , FCollectionNameType > & FCollectionManagerCache : : GetCachedCollectionNamesFromGuids ( FCollectionLock & ) const
2024-04-16 12:54:49 -04:00
{
2024-04-19 18:17:59 -04:00
checkf ( ! EnumHasAnyFlags ( DirtyFlags , ECollectionCacheFlags : : Names ) , TEXT ( " Accessed guid->name map without updating cache " ) ) ;
return CachedCollectionNamesFromGuids_Internal ;
}
2024-04-17 02:10:31 -04:00
2024-04-19 18:17:59 -04:00
const TMap < FSoftObjectPath , TArray < FObjectCollectionInfo > > & FCollectionManagerCache : : GetCachedObjects ( FCollectionLock & ) const
{
checkf ( ! EnumHasAnyFlags ( DirtyFlags , ECollectionCacheFlags : : Objects ) , TEXT ( " Accessd object->collection map without updating cache " ) ) ;
return CachedObjects_Internal ;
}
const TMap < FGuid , TArray < FGuid > > & FCollectionManagerCache : : GetCachedHierarchy ( FCollectionLock & ) const
{
checkf ( ! EnumHasAnyFlags ( DirtyFlags , ECollectionCacheFlags : : Hierarchy ) , TEXT ( " Accessed collection hierarchy map without updating cache " ) ) ;
return CachedHierarchy_Internal ;
}
const TArray < FLinearColor > & FCollectionManagerCache : : GetCachedColors ( FCollectionLock & ) const
{
checkf ( ! EnumHasAnyFlags ( DirtyFlags , ECollectionCacheFlags : : Colors ) , TEXT ( " Accessed collection colors without updating cache " ) ) ;
return CachedColors_Internal ;
}
FStringView FCollectionManager : : CollectionExtension = TEXTVIEW ( " collection " ) ;
FCollectionManager : : FCollectionManager ( )
: CollectionCache ( MakePimpl < FCollectionManagerCache > ( & AvailableCollections ) )
{
Copying //UE4/Dev-Core to //UE4/Dev-Main (Source: //UE4/Dev-Core @ 3548365)
#lockdown Nick.Penwarden
============================
MAJOR FEATURES & CHANGES
============================
Change 3494741 by Steve.Robb
Generated code size savings.
#jira UE-43048
Change 3495484 by Steve.Robb
Fix for generated indices of static arrays when saving configs.
Change 3497926 by Robert.Manuszewski
Removed FPackageFileSummary's CompressedChunks array as it was no longer being used by anything.
Change 3498077 by Robert.Manuszewski
Only use the recursion guard in async loading code when the event driven loader is enabled.
Change 3498112 by Ben.Marsh
UBT: Respect the option to not create debug info in the Android toolchain. This option is already being respected by the compiler, but the linker adds debug info of its own.
Change 3500239 by Robert.Manuszewski
Made sure the Super Class token stream is also locked when assembling Class token stream with async loading thread enabled. This to to prevent race conditions when loading BP classes.
Change 3500395 by Steve.Robb
Extra codegen savings when not in hot reload.
Change 3501004 by Steve.Robb
EObjectFlags now have constexpr operators.
Change 3502079 by Ben.Marsh
UBT: Pad multi-line error messages so that they align under the prefix for the first line, and include the timestamp if necessary.
Change 3502527 by Steve.Robb
Fix for zero-sized array compile error in generated code when all functions are editor-only.
Change 3502542 by Ben.Marsh
UAT: Remove the custom source parameter from log functions, and add support for a customizable indent instead.
Change 3502868 by Steve.Robb
Workaround for inefficient generated code with stateless lambdas on Clang.
Change 3503550 by Steve.Robb
Another generated code lambda optimization.
Change 3503582 by Ben.Marsh
BuildGraph: Add support for nullable parameter types.
Change 3504424 by Steve.Robb
New AllOf, AnyOf and NoneOf algorithms.
Change 3504712 by Ben.Marsh
UAT: Less spammy log and error output from UAT.
* Callstacks for AutomationExceptions are suppressed by default but still included in the log (the path to the log is noted in console output with the message from the exception).
* Add a mechanism for any exceptions to be caught and rethrown with additional lines of context (CommandUtils.AddContext()) that will be appended to the error output by UAT. Avoids decaying the exception type or masking the inner exception message while still adding additional information.
* AggregateExceptions resulting from exceptions on child threads are automatically unwrapped (full details are still appended to the log)
* Name of the calling function is not included in console output by default, but still included in the log.
Change 3504808 by Ben.Marsh
UAT: Suppress P4 output when running a recursive instance of UAT.
Change 3505044 by Steve.Robb
Code generation improved for TCppClassType code.
Change 3505485 by Ben.Marsh
Fix deterministic cooking issue; always use a pseudo-random number stream when compiling a module.
Change 3505699 by Ben.Marsh
Plugins: Store the bEnabledByDefault flag exactly as it was read from disk rather than collapsing it to an absolute value based on the default for the location it was read from. This allows loading/saving plugin descriptors without any knowledge of whether they are game or engine plugins.
Change 3506055 by Ben.Marsh
UAT: Add a class to apply a log indent for the lifetime of an object (ScopedLogIndent), and use it to apply an indent to MegaXGE/ParallelExecutor output.
Change 3507745 by Robert.Manuszewski
Moved FSimpleObjectReferenceCollectorArchive and FSimpleObjectReferenceCollectorArchive to be internal archives used only by FReferenceCollector so that they are constructed only once per GC task instead of potentially multiple times per GC (as was the case with UDataTables and BlueprintGeneratedClasses).
Change 3507911 by Ben.Marsh
Plugins: Minor changes to plugin descriptors.
* Add a distinct setting for an unspecified EnabledByDefault setting in plugin descriptors.
* Add a function to IPlugin to determine the effective EnabledByDefault setting, based on where the plugin was loaded from.
Change 3508669 by Ben.Marsh
EC: Parse multi-line messages from UBT and UAT.
Change 3508691 by Ben.Marsh
Fix double-spacing of cook stats.
Change 3509245 by Steve.Robb
UHT makefiles removed.
Flag audit removed.
Change 3509275 by Steve.Robb
Fix for mismatched stat categories in AudioMixer.
#jira UE-46129
Change 3509289 by Robert.Manuszewski
Custom Version Container will no longer be always constructed in FArchive constructor. This reduces the number of the Custom Version Container allocations considerably.
Change 3509294 by Robert.Manuszewski
UDataTable::AddReferencedObjects will no longer try to iterate over the RowMap if there's no UObject references in it.
Change 3509312 by Steve.Robb
GitHub# 3679: Add TArray constructor that takes a raw pointer and a count
Check improved for Append() to allow nullptr in empty ranges, and added to new constructor too.
#jira UE-46136
Change 3509396 by Steve.Robb
GitHub# 3676: Fix TUnion operator<< compile error
#jira UE-46099
Change 3509633 by Steve.Robb
Fix for line numbers on multiline macros.
Change 3509938 by Gil.Gribb
UE4 - Fix rare assert involving cancelled precache requests and non-pak-file loading.
Change 3510593 by Daniel.Lamb
Fixed up unsoilicited files getting populated with files which aren't finished being created yet.
#test None
Change 3510594 by Daniel.Lamb
Fixed up temp files directory for patching.
Thanks David Yerkess @ Milestone
#review@Ben.Marsh
Change 3511628 by Ben.Marsh
PR #3707: Fixed UBT stack size (Contributed by gildor2)
Change 3511808 by Ben.Marsh
Optimize checks for whether the game project contains source code. Now stops as soon as the first file is found and ignores directories beginning with a '.' character (eg. .git)
#jira UE-46540
Change 3512017 by Ben.Marsh
Plugins: Deprecate the QueryStatusForAllPlugins() function; the same functionality is available via the IPlugin interface.
Change 3513935 by Steve.Robb
Reverted array iteration in FPropertyNode::PropagatePropertyChange as this is now covered in TProperty::InitializeValueInternal() as of CL# 3293477.
Change 3514142 by Steve.Robb
MemoryProfiler2 added to generated solution.
Change 3516463 by Ben.Marsh
Plugins: Create a manifest for each PAK file containing all the plugin descriptors in one place. Eliminates need to recurse through directories and read separate multiple files in serial at startup, and allows reading all plugin descriptors with one read. The "Mods" directory is excluded from the manifest, since these are intended to be installed separately by the user.
Change 3517860 by Ben.Marsh
PR #3727: FString Dereference Fixes (Contributed by jovisgCL)
Change 3517967 by Ben.Marsh
Suppress additional system error dialogs when loading DLLs if -unnattended is on the command line.
Change 3518070 by Steve.Robb
Disable Binned2 stats in shipping non-editor builds.
Change 3520079 by Steve.Robb
Fixed bad codegen TAssetPtrs being passed into BlueprintImplementableEvent functions.
#jira UE-24034
Change 3520080 by Robert.Manuszewski
Made max package summary size to be configurable with ini setting
Change 3520083 by Steve.Robb
Force a GC after hot reload to clean up reinstanced objects which may still tick.
#jira UE-40421
Change 3520480 by Robert.Manuszewski
Improved assert message when the initial package read request was too small.
Change 3520590 by Graeme.Thornton
SignedArchiveReader optimizations
- Loads more stats
- Stop chunk cache worker from waking up continuously to poll for work. Only wake up when triggered by the archive reader
- Signed archive reader just yields when waiting for buffers to finish loading, rather than sleeping for some arbitrary amount of time
- Track the number of pending read requests in an atomic counter, to save having to lock the request queue to check for new entries
Change 3521023 by Graeme.Thornton
Remove spin from signed archive reader. Main thread waits on an event triggered by the chunk worker to indicate that new chunks are ready for processing
Change 3521787 by Ben.Marsh
PR #3736: Small static code analysis fixes (Contributed by jovisgCL)
Change 3521789 by Ben.Marsh
PR #3735: Fix case sensitivity issue in FWindowsPlatformProcess::IsApplicationRunning. (Contributed by samhocevar)
Change 3524721 by Ben.Marsh
Move Linux SDL initialization into FLinuxPlatformApplicationMisc. Attempting to move functionality related to interactive applications (graphics, input, etc...) into a separate place, so it can ultimately be moved out of Core.
Change 3524741 by Ben.Marsh
Move PumpMessages() into FPlatformApplicationMisc.
Change 3525399 by Ben.Marsh
UGS: Use the default Perforce server port when opening P4V if there is not one set in the environment.
Change 3525743 by Ben.Marsh
UAT: Add a parameter to allow updating version files without updating Version.h, to allow faster link times on incremental builds.
Change 3525746 by Ben.Marsh
EC: Include the clobber option on new workspaces, to allow overriding version files when syncing.
Change 3526453 by Ben.Marsh
UGS: Do not generate project files when syncing precompiled binaries.
Change 3527045 by Ben.Marsh
Fix hot reload generating import libraries without DLLs. Now that they are produced by separate actions by default, it was removing DLLs from the action graph due to the bSkipLinkingWhenNothingToCompile setting.
Change 3527420 by Ben.Marsh
UGS: Add additional search paths for UGS config files, and fix a few cosmetic issues (inability to display ampersands in tools menu, showing changelist -1 when running a tool without syncing).
Config files are now read from:
Engine/Programs/UnrealGameSync/UnrealGameSync.ini
Engine/Programs/UnrealGameSync/NotForLicensees/UnrealGameSync.ini
If a project is selected:
<ProjectDir>/Build/UnrealGameSync.ini
<ProjectDir>/Build/NotForLicensees/UnrealGameSync.ini
If the .uprojectdirs file is selected:
Engine/Programs/UnrealGameSync/DefaultProject.ini
Engine/Programs/UnrealGameSync/NotForLicensees/DefaultProject.ini
Change 3528063 by Ben.Marsh
Fix non-thread safe construction of FPluginManager singleton. Length of time spent in the constructor resulted in multiple instances being constructed at startup, making the time to enumerate plugins on slow media significantly worse.
Change 3528415 by Ben.Marsh
UAT: Remove \r characters from the end of multiline log messages.
Change 3528427 by Ben.Marsh
EC: Fix spaces being converted to tabs at start of line in failure emails (by Gmail), and wrap following lines at the same indent.
Change 3528485 by Ben.Marsh
EC: Remove zero-width word break characters from slashes in notification emails; can cause really hard to debug problems when copy pasted into other places.
Change 3528505 by Steve.Robb
PR #3755: MallocProfiler - Remove subfolder from profiling save directory (Contributed by Josef-CL)
#jira UE-46819
Change 3528772 by Robert.Manuszewski
Enabling actor and blueprint clustering in ShooterGame
Change 3528786 by Robert.Manuszewski
PR #3760: Fix typo (Contributed by jesseyeh)
Change 3528792 by Steve.Robb
PR #3764: MallocProfiler - Refactoring Scopelock (Contributed by Josef-CL)
#jira UE-46962
Change 3528941 by Robert.Manuszewski
Fixed lazy object pointers not being updated for streaming sub-levels in PIE. Fixed lazy pointers returning object that is still being loaded which could lead to undefined behavior when client code started modifying the returned object.
#jira UE-44996
Change 3530241 by Ben.Marsh
UAT: Only pass -submit or -nosubmit to child instances of UAT if they were specified on the original command line. BuildCookRun uses this flag to determine whether to submit, rather than just whether to allow submitting, so we shouldn't pass an inferred value.
Change 3531377 by Ben.Marsh
Plugins: Allow plugins to specify a list of supported target platforms, which is propagated to any .uproject file that enables it.
This has several advantages over the per-module platform whitelist/blacklist:
* Platform-specific .uplugin files can now be excluded when staging other platforms. Previously, it was only possible to determine which platforms a plugin supports by reading the plugin descriptor itself. Now that information is copied into the .uproject file, so the runtime knows which plugins to ignore.
* References to dependent plugins from platform-specific plugins can now be eliminated.
* Plugins containing content can now be unambiguously disabled on a per-platform basis (having no modules for a platform does not confer that a plugin doesn't support that platform; now it is possible to specify supported platforms explicitly).
* The editor can load any plugins without having to whitelist supported editor host platforms.
UE4 targets which support loading plugins for target platforms can set TargetRules.bIncludePluginsForTargetPlatforms (true for the editor by default, false for any other target types). This defines the LOAD_PLUGINS_FOR_TARGET_PLATFORMS macro at runtime, which allows the plugin system to filter which plugins to look for at runtime.
Any .uproject file will be updated at startup to contain the list of supported platforms for each referenced plugin if necessary.
Change 3531502 by Jin.Zhang
Add support for GPUCrash #rb
Change 3531664 by Ben.Marsh
UBT: Change output format from C# JSON writer to match output by the engine.
Change 3531848 by Ben.Marsh
UAT: Add script to resaving all project descriptors under a folder, embedding information for any supported platforms for the plugins they enable.
Change 3531869 by Ben.Marsh
UAT: Add parameter to the ResaveProjectDescriptors command to update the engine association field.
Change 3532474 by Ben.Marsh
UBT: Use the same mechanism as UAT for logging exceptions.
Change 3532734 by Graeme.Thornton
Initial VSCode Support
- Tasks generated for building all game/engine/program targets
- Debugging support for targets on Win64
Change 3532789 by Steve.Robb
FScriptSet::Add and TScriptMap::Add now replace the element, matching the behavior of TSet and TMap.
Set_Add and Map_Add no longer have a return value.
FScriptSet::Find and FScriptMap::Find functions are now FindIndex.
FScriptSetHelper::FindElementFromHash is now FindElementIndexFromHash.
Change 3532845 by Steve.Robb
Obsolete UHT settings deleted.
Change 3532875 by Graeme.Thornton
VSCode
- Add debug targets for different target configurations
- Choose between VS debugger (windows) and GDB (mac/linux)
Change 3532906 by Graeme.Thornton
VSCode
- Point all builds directly at UBT rather than the batch files
- Adjust mac build tasks to run through mono
Change 3532924 by Ben.Marsh
UAT: Set the UAT working directory immediately on startup. This ensures that any command line arguments containing paths are resolved consistently to the branch root.
Change 3535234 by Graeme.Thornton
VSCode - Pass intellisense system a list of paths to use for header resolution
Change 3535247 by Graeme.Thornton
UBT - Add a ToString to ProjectFile.Source file to help with debugger watch presentation
Change 3535376 by Graeme.Thornton
VSCode
- Added build jobs for C# projects
- Linked launch tasks to relevant build task
Change 3537083 by Ben.Marsh
EC: Change P4 swarm links to start at the changelist for a build.
Change 3537368 by Graeme.Thornton
Fix for crash in FSignedArchiveReader when multithreading is disabled
Change 3537550 by Graeme.Thornton
Fixed a crash in the taskgraph when running single threaded
Change 3537922 by Steve.Robb
Missing PF_ATC_RGBA_I added to FOREACH_ENUM_EPIXELFORMAT.
Change 3539691 by Graeme.Thornton
VSCode - Various updates to get PC and Mac C++ projects building and debugging.
- Some other changes to C# setup to allow compilation. Debugging doesn't work.
Change 3539775 by Ben.Marsh
Plugins: Various fixes to settings for enabling plugins.
* Fix crash on startup when trying to disable a missing plugin (was keeping pointers to elements in the project's plugin reference array, which may be modified if a plugin is disabled).
* Revert fix to set PluginDescriptor.bRequiresBuildPlatform = true by default. This was the originally intended behavior, but it was accidentally defaulted to false during serialization unless specified in the .uplugin file. Many plugins may rely on this behavior (they may not declare asset classes otherwise, for example, which could result in loss of data), so change the default value to false instead. Also fixes popups to disable platform-specific plugins if platform SDKs are not installed.
* Fix plugins which are referenced but do not exist not showing the appropriate prompt to disable them.
Change 3540788 by Ben.Marsh
UBT: Add support for declaring custom pre-build steps and post-build steps from .target.cs files. Similarly to the custom build steps configurable from .uproject and .uplugin files, these specify commands which will be executed by the host platform's shell before or after a build. The following variables are expanded within the list of commands before execution: $(EngineDir), $(ProjectDir), $(TargetName), $(TargetPlatform), $(TargetConfiguration), $(TargetType), $(ProjectFile).
Example usage:
public class UnrealPakTarget : TargetRules
{
public UnrealPakTarget(TargetInfo Target) : base(Target)
{
Type = TargetType.Program;
LinkType = TargetLinkType.Monolithic;
LaunchModuleName = "UnrealPak";
if(HostPlatform == UnrealTargetPlatform.Win64)
{
PreBuildSteps.Add("echo Before building:");
PreBuildSteps.Add("echo This is $(TargetName) $(TargetConfiguration) $(TargetPlatform)");
PostBuildSteps.Add("echo After building!");
PostBuildSteps.Add("echo This is $(TargetName) $(TargetConfiguration) $(TargetPlatform)");
}
}
}
Change 3541664 by Graeme.Thornton
VSCode - Add problemMatcher tag to cpp build targets
Change 3541732 by Graeme.Thornton
VSCode - Change UBT command line switch to "-vscode" for simplicity
Change 3541967 by Graeme.Thornton
VSCode - Fixes for Mac/Linux build steps
Change 3541968 by Ben.Marsh
CRP: Pass through the EnabledPlugins element in crash context XML files.
#jira UE-46912
Change 3542519 by Ben.Marsh
UBT: Add chain of references to error messages when configuring plugins.
Change 3542523 by Ben.Marsh
UBT: Add more useful error message when attempt to parse a JSON object fails.
Change 3542658 by Ben.Marsh
UBT: Include a chain of references when reporting errors instantiating modules.
Change 3543432 by Ben.Marsh
Plugins: Fix plugins which are enabled by default not being enabled unless a project file is set.
Change 3543436 by Ben.Marsh
UBT: Prevent recursing through the same module more than once when building out the referenced modules. Produces much shorter reference chains when something fails.
Change 3543536 by Ben.Marsh
UBT: Downgrade message about redundant plugin references to a warning.
Change 3543871 by Gil.Gribb
UE4 - Fixed a critical crash bug with non-EDL loading from pak files.
Change 3543924 by Robert.Manuszewski
Fixed a crash on UnrealFrontend startup caused by re-assembling GC token stream for one of the classes.
+Small optimization to token stream generation code.
Change 3544469 by Jin.Zhang
Crashes page displays the list of plugins from the crash context #rb
Change 3544608 by Steve.Robb
Fix for nativized generated code.
#jira UE-47452
Change 3544612 by Ben.Marsh
Add callback into FMacPlatformMisc::PumpMessages() from FMacPlatformApplicationMisc::PumpMessages().
#jira UE-47449
Change 3545954 by Gil.Gribb
Fixed a critical crash bug relating to a race condition in async package summary reading.
Change 3545968 by Ben.Marsh
UAT: Fix incorrect username in BuildGraph <Submit> task. Should use the username from the Perforce environment, not assume the logged in user name is the same.
#jira UE-47419
Change 3545976 by Ben.Marsh
EC: Delete the AutoSDK client if the directory doesn't exist. When we format build machines, we need to force everything to be resynced from scratch.
Change 3546185 by Ben.Marsh
Hacky fix for deployment on IOS/TVOS. Since deployment directly references the NonUFS manifest files that are written out, merge all the SystemNonUFS files back into the NonUFS list after the regular NonUFS files have been remapped.
Change 3547084 by Gil.Gribb
Fixed a critical race condition in the new async loader. This was only reproducible on IOS, but may affect other platforms.
Change 3547968 by Gil.Gribb
Fixed critical race which potentially could cause a crash in the pak precacher.
Change 3504722 by Ben.Marsh
BuildGraph: Improved tracing for error messages. All errors are now propagated as exceptions, and are tagged with additional context information about the task currently being run.
For example, throwing new AutomationException("Unable to write foo.txt") from SetVersionTask.Execute is now displayed in the log as:
ERROR: Unable to write to foo.txt
while executing <SetVersion Change="0" CompatibleChange="0" Branch="Unknown" Promoted="True" />
at Engine\Build\InstalledEngineBuild.xml(91)
(see D:\P4 UE4\Engine\Programs\AutomationTool\Saved\Logs\UAT_Log.txt for full exception trace)
Change 3512255 by Ben.Marsh
Rename FPaths functions with a "Game" prefix (GameDir(), GameContentDir(), etc...) to have a "Project" prefix (ProjectDir(), ProjectContentDir(), etc...) for clarity with non-game uses of UE4. Old functions still exist but are deprecated.
Change 3512332 by Ben.Marsh
Rename "Game" functions in FApp to be "Project" functions (FApp::GetGameName() -> FApp::GetProjectName(), etc...) for clarity with non-game uses of UE4.
Change 3512393 by Ben.Marsh
Rename FPaths::GameLogDir() to FPaths::ProjectLogDir().
Change 3513452 by Ben.Marsh
Plugins: Rename EPluginLoadedFrom::GameProject to EPluginLoadedFrom::Project.
Change 3516262 by Ben.Marsh
Add support for a "Mods" folder distinct from the project's "Plugins" folder, instead of using the bIsMod flag on the plugin descriptor.
* Mods are enumerated similarly to regular plugins, but IPlugin::GetType() will return EPluginType::Mod.
* The DLCName parameter to BuildCookRun and the cooker now correctly finds any plugin in the Plugins or Mods directory (or any subfolders).
Change 3517565 by Ben.Marsh
Remove fixed engine version numbers from OSS plugins.
Change 3518005 by Ben.Marsh
UAT: Remove the bUFSFile parameter from DeployLowerCaseFilenames(). Every platform returns false if the argument is false.
Change 3518054 by Ben.Marsh
UAT: Use an enum to direct whether all directories should be searched when finding files to stage, rather than a bool. Having so many optional boolean arguments makes code unreadable and refactoring hard.
Change 3524496 by Ben.Marsh
Start moving GUI application code into a separate static platform class, hopefully ultimately removing it from Core.
Change 3524641 by Ben.Marsh
Move more functionality related to windowed/graphical applications into FPlatformApplicationMisc.
Change 3528723 by Steve.Robb
MoveTemp now static asserts if passed a const reference or rvalue.
MoveTempIfPossible still follows the old (std::move) rule, which is useful for templates where the nature of the argument is not obvious.
Fixes to violations of these new rules.
Change 3528876 by Ben.Marsh
Move FPlatformMisc::ClipboardCopy and FPlatformMisc::ClipboardPaste to FPlatformApplicationMisc::ClipboardCopy and FPlatformApplicationMisc::ClipboardPaste.
Change 3529073 by Ben.Marsh
Add script to package ShooterGame for any platforms.
Change 3531493 by Ben.Marsh
Update platform-specific plugins to declare the target platforms they support.
Change 3531611 by Ben.Marsh
UAT: Add a ResavePluginDescriptors command, which resaves all plugin descriptors under a given folder, removing any outdated fields and rewrites them in a consistent style. Many plugins in the wild contain redundant or no-longer used fields due to using our plugins as templates.
Change 3531868 by Ben.Marsh
Resaving project descriptors to remove invalid fields.
Change 3531983 by Ben.Marsh
UAT: Simplify logic for staging code, and add validation against shipping files in restricted folders.
* Added a new SystemNonUFS type for staged files, which excludes files from being remapped or renamed by the platform layer.
* Replaced the DeplyomentContext.StageFiles() function with simpler overloads for particular use cases (options for remapping are replaced with the SystemNonUFS file type)
* Config entries in the [Staging] category in DefaultGame.ini file allow remapping one directory to another, so restricted content can be made public in packaged builds (Example syntax: +RemapDirectory=(From="Foo/NoRedist", To="Foo"))
* An error is output if any restricted folder names other than the output platform are in the staged output.
Change 3540315 by Ben.Marsh
UAT: Moving StreamCopyDescription command into a NotForLicensees folder, since it's only meant to be used by engine developers.
Change 3542410 by Ben.Marsh
UBT: Deprecate accessing properties through BuildConfiguration.* or UEBuildConfiguration.* from .target.cs files. These have been aliases to the current TargetRules instance for several releases already.
Change 3543018 by Ben.Marsh
UBT: Deprecate the BuildConfiguration and UEBuildConfiguration aliases from the ModuleRules class. These have been implemented as an alias ot the ReadOnlyTargetRules instance passed to the constructor for several engine versions.
Change 3544371 by Steve.Robb
Fixes to TSet_Add and TMap_Add BPs.
#jira UE-47441
[CL 3548391 by Ben Marsh in Main branch]
2017-07-21 12:42:36 -04:00
CollectionFolders [ ECollectionShareType : : CST_Local ] = FPaths : : ProjectSavedDir ( ) / TEXT ( " Collections " ) ;
2014-03-14 14:13:41 -04:00
CollectionFolders [ ECollectionShareType : : CST_Private ] = FPaths : : GameUserDeveloperDir ( ) / TEXT ( " Collections " ) ;
Copying //UE4/Dev-Core to //UE4/Dev-Main (Source: //UE4/Dev-Core @ 3548365)
#lockdown Nick.Penwarden
============================
MAJOR FEATURES & CHANGES
============================
Change 3494741 by Steve.Robb
Generated code size savings.
#jira UE-43048
Change 3495484 by Steve.Robb
Fix for generated indices of static arrays when saving configs.
Change 3497926 by Robert.Manuszewski
Removed FPackageFileSummary's CompressedChunks array as it was no longer being used by anything.
Change 3498077 by Robert.Manuszewski
Only use the recursion guard in async loading code when the event driven loader is enabled.
Change 3498112 by Ben.Marsh
UBT: Respect the option to not create debug info in the Android toolchain. This option is already being respected by the compiler, but the linker adds debug info of its own.
Change 3500239 by Robert.Manuszewski
Made sure the Super Class token stream is also locked when assembling Class token stream with async loading thread enabled. This to to prevent race conditions when loading BP classes.
Change 3500395 by Steve.Robb
Extra codegen savings when not in hot reload.
Change 3501004 by Steve.Robb
EObjectFlags now have constexpr operators.
Change 3502079 by Ben.Marsh
UBT: Pad multi-line error messages so that they align under the prefix for the first line, and include the timestamp if necessary.
Change 3502527 by Steve.Robb
Fix for zero-sized array compile error in generated code when all functions are editor-only.
Change 3502542 by Ben.Marsh
UAT: Remove the custom source parameter from log functions, and add support for a customizable indent instead.
Change 3502868 by Steve.Robb
Workaround for inefficient generated code with stateless lambdas on Clang.
Change 3503550 by Steve.Robb
Another generated code lambda optimization.
Change 3503582 by Ben.Marsh
BuildGraph: Add support for nullable parameter types.
Change 3504424 by Steve.Robb
New AllOf, AnyOf and NoneOf algorithms.
Change 3504712 by Ben.Marsh
UAT: Less spammy log and error output from UAT.
* Callstacks for AutomationExceptions are suppressed by default but still included in the log (the path to the log is noted in console output with the message from the exception).
* Add a mechanism for any exceptions to be caught and rethrown with additional lines of context (CommandUtils.AddContext()) that will be appended to the error output by UAT. Avoids decaying the exception type or masking the inner exception message while still adding additional information.
* AggregateExceptions resulting from exceptions on child threads are automatically unwrapped (full details are still appended to the log)
* Name of the calling function is not included in console output by default, but still included in the log.
Change 3504808 by Ben.Marsh
UAT: Suppress P4 output when running a recursive instance of UAT.
Change 3505044 by Steve.Robb
Code generation improved for TCppClassType code.
Change 3505485 by Ben.Marsh
Fix deterministic cooking issue; always use a pseudo-random number stream when compiling a module.
Change 3505699 by Ben.Marsh
Plugins: Store the bEnabledByDefault flag exactly as it was read from disk rather than collapsing it to an absolute value based on the default for the location it was read from. This allows loading/saving plugin descriptors without any knowledge of whether they are game or engine plugins.
Change 3506055 by Ben.Marsh
UAT: Add a class to apply a log indent for the lifetime of an object (ScopedLogIndent), and use it to apply an indent to MegaXGE/ParallelExecutor output.
Change 3507745 by Robert.Manuszewski
Moved FSimpleObjectReferenceCollectorArchive and FSimpleObjectReferenceCollectorArchive to be internal archives used only by FReferenceCollector so that they are constructed only once per GC task instead of potentially multiple times per GC (as was the case with UDataTables and BlueprintGeneratedClasses).
Change 3507911 by Ben.Marsh
Plugins: Minor changes to plugin descriptors.
* Add a distinct setting for an unspecified EnabledByDefault setting in plugin descriptors.
* Add a function to IPlugin to determine the effective EnabledByDefault setting, based on where the plugin was loaded from.
Change 3508669 by Ben.Marsh
EC: Parse multi-line messages from UBT and UAT.
Change 3508691 by Ben.Marsh
Fix double-spacing of cook stats.
Change 3509245 by Steve.Robb
UHT makefiles removed.
Flag audit removed.
Change 3509275 by Steve.Robb
Fix for mismatched stat categories in AudioMixer.
#jira UE-46129
Change 3509289 by Robert.Manuszewski
Custom Version Container will no longer be always constructed in FArchive constructor. This reduces the number of the Custom Version Container allocations considerably.
Change 3509294 by Robert.Manuszewski
UDataTable::AddReferencedObjects will no longer try to iterate over the RowMap if there's no UObject references in it.
Change 3509312 by Steve.Robb
GitHub# 3679: Add TArray constructor that takes a raw pointer and a count
Check improved for Append() to allow nullptr in empty ranges, and added to new constructor too.
#jira UE-46136
Change 3509396 by Steve.Robb
GitHub# 3676: Fix TUnion operator<< compile error
#jira UE-46099
Change 3509633 by Steve.Robb
Fix for line numbers on multiline macros.
Change 3509938 by Gil.Gribb
UE4 - Fix rare assert involving cancelled precache requests and non-pak-file loading.
Change 3510593 by Daniel.Lamb
Fixed up unsoilicited files getting populated with files which aren't finished being created yet.
#test None
Change 3510594 by Daniel.Lamb
Fixed up temp files directory for patching.
Thanks David Yerkess @ Milestone
#review@Ben.Marsh
Change 3511628 by Ben.Marsh
PR #3707: Fixed UBT stack size (Contributed by gildor2)
Change 3511808 by Ben.Marsh
Optimize checks for whether the game project contains source code. Now stops as soon as the first file is found and ignores directories beginning with a '.' character (eg. .git)
#jira UE-46540
Change 3512017 by Ben.Marsh
Plugins: Deprecate the QueryStatusForAllPlugins() function; the same functionality is available via the IPlugin interface.
Change 3513935 by Steve.Robb
Reverted array iteration in FPropertyNode::PropagatePropertyChange as this is now covered in TProperty::InitializeValueInternal() as of CL# 3293477.
Change 3514142 by Steve.Robb
MemoryProfiler2 added to generated solution.
Change 3516463 by Ben.Marsh
Plugins: Create a manifest for each PAK file containing all the plugin descriptors in one place. Eliminates need to recurse through directories and read separate multiple files in serial at startup, and allows reading all plugin descriptors with one read. The "Mods" directory is excluded from the manifest, since these are intended to be installed separately by the user.
Change 3517860 by Ben.Marsh
PR #3727: FString Dereference Fixes (Contributed by jovisgCL)
Change 3517967 by Ben.Marsh
Suppress additional system error dialogs when loading DLLs if -unnattended is on the command line.
Change 3518070 by Steve.Robb
Disable Binned2 stats in shipping non-editor builds.
Change 3520079 by Steve.Robb
Fixed bad codegen TAssetPtrs being passed into BlueprintImplementableEvent functions.
#jira UE-24034
Change 3520080 by Robert.Manuszewski
Made max package summary size to be configurable with ini setting
Change 3520083 by Steve.Robb
Force a GC after hot reload to clean up reinstanced objects which may still tick.
#jira UE-40421
Change 3520480 by Robert.Manuszewski
Improved assert message when the initial package read request was too small.
Change 3520590 by Graeme.Thornton
SignedArchiveReader optimizations
- Loads more stats
- Stop chunk cache worker from waking up continuously to poll for work. Only wake up when triggered by the archive reader
- Signed archive reader just yields when waiting for buffers to finish loading, rather than sleeping for some arbitrary amount of time
- Track the number of pending read requests in an atomic counter, to save having to lock the request queue to check for new entries
Change 3521023 by Graeme.Thornton
Remove spin from signed archive reader. Main thread waits on an event triggered by the chunk worker to indicate that new chunks are ready for processing
Change 3521787 by Ben.Marsh
PR #3736: Small static code analysis fixes (Contributed by jovisgCL)
Change 3521789 by Ben.Marsh
PR #3735: Fix case sensitivity issue in FWindowsPlatformProcess::IsApplicationRunning. (Contributed by samhocevar)
Change 3524721 by Ben.Marsh
Move Linux SDL initialization into FLinuxPlatformApplicationMisc. Attempting to move functionality related to interactive applications (graphics, input, etc...) into a separate place, so it can ultimately be moved out of Core.
Change 3524741 by Ben.Marsh
Move PumpMessages() into FPlatformApplicationMisc.
Change 3525399 by Ben.Marsh
UGS: Use the default Perforce server port when opening P4V if there is not one set in the environment.
Change 3525743 by Ben.Marsh
UAT: Add a parameter to allow updating version files without updating Version.h, to allow faster link times on incremental builds.
Change 3525746 by Ben.Marsh
EC: Include the clobber option on new workspaces, to allow overriding version files when syncing.
Change 3526453 by Ben.Marsh
UGS: Do not generate project files when syncing precompiled binaries.
Change 3527045 by Ben.Marsh
Fix hot reload generating import libraries without DLLs. Now that they are produced by separate actions by default, it was removing DLLs from the action graph due to the bSkipLinkingWhenNothingToCompile setting.
Change 3527420 by Ben.Marsh
UGS: Add additional search paths for UGS config files, and fix a few cosmetic issues (inability to display ampersands in tools menu, showing changelist -1 when running a tool without syncing).
Config files are now read from:
Engine/Programs/UnrealGameSync/UnrealGameSync.ini
Engine/Programs/UnrealGameSync/NotForLicensees/UnrealGameSync.ini
If a project is selected:
<ProjectDir>/Build/UnrealGameSync.ini
<ProjectDir>/Build/NotForLicensees/UnrealGameSync.ini
If the .uprojectdirs file is selected:
Engine/Programs/UnrealGameSync/DefaultProject.ini
Engine/Programs/UnrealGameSync/NotForLicensees/DefaultProject.ini
Change 3528063 by Ben.Marsh
Fix non-thread safe construction of FPluginManager singleton. Length of time spent in the constructor resulted in multiple instances being constructed at startup, making the time to enumerate plugins on slow media significantly worse.
Change 3528415 by Ben.Marsh
UAT: Remove \r characters from the end of multiline log messages.
Change 3528427 by Ben.Marsh
EC: Fix spaces being converted to tabs at start of line in failure emails (by Gmail), and wrap following lines at the same indent.
Change 3528485 by Ben.Marsh
EC: Remove zero-width word break characters from slashes in notification emails; can cause really hard to debug problems when copy pasted into other places.
Change 3528505 by Steve.Robb
PR #3755: MallocProfiler - Remove subfolder from profiling save directory (Contributed by Josef-CL)
#jira UE-46819
Change 3528772 by Robert.Manuszewski
Enabling actor and blueprint clustering in ShooterGame
Change 3528786 by Robert.Manuszewski
PR #3760: Fix typo (Contributed by jesseyeh)
Change 3528792 by Steve.Robb
PR #3764: MallocProfiler - Refactoring Scopelock (Contributed by Josef-CL)
#jira UE-46962
Change 3528941 by Robert.Manuszewski
Fixed lazy object pointers not being updated for streaming sub-levels in PIE. Fixed lazy pointers returning object that is still being loaded which could lead to undefined behavior when client code started modifying the returned object.
#jira UE-44996
Change 3530241 by Ben.Marsh
UAT: Only pass -submit or -nosubmit to child instances of UAT if they were specified on the original command line. BuildCookRun uses this flag to determine whether to submit, rather than just whether to allow submitting, so we shouldn't pass an inferred value.
Change 3531377 by Ben.Marsh
Plugins: Allow plugins to specify a list of supported target platforms, which is propagated to any .uproject file that enables it.
This has several advantages over the per-module platform whitelist/blacklist:
* Platform-specific .uplugin files can now be excluded when staging other platforms. Previously, it was only possible to determine which platforms a plugin supports by reading the plugin descriptor itself. Now that information is copied into the .uproject file, so the runtime knows which plugins to ignore.
* References to dependent plugins from platform-specific plugins can now be eliminated.
* Plugins containing content can now be unambiguously disabled on a per-platform basis (having no modules for a platform does not confer that a plugin doesn't support that platform; now it is possible to specify supported platforms explicitly).
* The editor can load any plugins without having to whitelist supported editor host platforms.
UE4 targets which support loading plugins for target platforms can set TargetRules.bIncludePluginsForTargetPlatforms (true for the editor by default, false for any other target types). This defines the LOAD_PLUGINS_FOR_TARGET_PLATFORMS macro at runtime, which allows the plugin system to filter which plugins to look for at runtime.
Any .uproject file will be updated at startup to contain the list of supported platforms for each referenced plugin if necessary.
Change 3531502 by Jin.Zhang
Add support for GPUCrash #rb
Change 3531664 by Ben.Marsh
UBT: Change output format from C# JSON writer to match output by the engine.
Change 3531848 by Ben.Marsh
UAT: Add script to resaving all project descriptors under a folder, embedding information for any supported platforms for the plugins they enable.
Change 3531869 by Ben.Marsh
UAT: Add parameter to the ResaveProjectDescriptors command to update the engine association field.
Change 3532474 by Ben.Marsh
UBT: Use the same mechanism as UAT for logging exceptions.
Change 3532734 by Graeme.Thornton
Initial VSCode Support
- Tasks generated for building all game/engine/program targets
- Debugging support for targets on Win64
Change 3532789 by Steve.Robb
FScriptSet::Add and TScriptMap::Add now replace the element, matching the behavior of TSet and TMap.
Set_Add and Map_Add no longer have a return value.
FScriptSet::Find and FScriptMap::Find functions are now FindIndex.
FScriptSetHelper::FindElementFromHash is now FindElementIndexFromHash.
Change 3532845 by Steve.Robb
Obsolete UHT settings deleted.
Change 3532875 by Graeme.Thornton
VSCode
- Add debug targets for different target configurations
- Choose between VS debugger (windows) and GDB (mac/linux)
Change 3532906 by Graeme.Thornton
VSCode
- Point all builds directly at UBT rather than the batch files
- Adjust mac build tasks to run through mono
Change 3532924 by Ben.Marsh
UAT: Set the UAT working directory immediately on startup. This ensures that any command line arguments containing paths are resolved consistently to the branch root.
Change 3535234 by Graeme.Thornton
VSCode - Pass intellisense system a list of paths to use for header resolution
Change 3535247 by Graeme.Thornton
UBT - Add a ToString to ProjectFile.Source file to help with debugger watch presentation
Change 3535376 by Graeme.Thornton
VSCode
- Added build jobs for C# projects
- Linked launch tasks to relevant build task
Change 3537083 by Ben.Marsh
EC: Change P4 swarm links to start at the changelist for a build.
Change 3537368 by Graeme.Thornton
Fix for crash in FSignedArchiveReader when multithreading is disabled
Change 3537550 by Graeme.Thornton
Fixed a crash in the taskgraph when running single threaded
Change 3537922 by Steve.Robb
Missing PF_ATC_RGBA_I added to FOREACH_ENUM_EPIXELFORMAT.
Change 3539691 by Graeme.Thornton
VSCode - Various updates to get PC and Mac C++ projects building and debugging.
- Some other changes to C# setup to allow compilation. Debugging doesn't work.
Change 3539775 by Ben.Marsh
Plugins: Various fixes to settings for enabling plugins.
* Fix crash on startup when trying to disable a missing plugin (was keeping pointers to elements in the project's plugin reference array, which may be modified if a plugin is disabled).
* Revert fix to set PluginDescriptor.bRequiresBuildPlatform = true by default. This was the originally intended behavior, but it was accidentally defaulted to false during serialization unless specified in the .uplugin file. Many plugins may rely on this behavior (they may not declare asset classes otherwise, for example, which could result in loss of data), so change the default value to false instead. Also fixes popups to disable platform-specific plugins if platform SDKs are not installed.
* Fix plugins which are referenced but do not exist not showing the appropriate prompt to disable them.
Change 3540788 by Ben.Marsh
UBT: Add support for declaring custom pre-build steps and post-build steps from .target.cs files. Similarly to the custom build steps configurable from .uproject and .uplugin files, these specify commands which will be executed by the host platform's shell before or after a build. The following variables are expanded within the list of commands before execution: $(EngineDir), $(ProjectDir), $(TargetName), $(TargetPlatform), $(TargetConfiguration), $(TargetType), $(ProjectFile).
Example usage:
public class UnrealPakTarget : TargetRules
{
public UnrealPakTarget(TargetInfo Target) : base(Target)
{
Type = TargetType.Program;
LinkType = TargetLinkType.Monolithic;
LaunchModuleName = "UnrealPak";
if(HostPlatform == UnrealTargetPlatform.Win64)
{
PreBuildSteps.Add("echo Before building:");
PreBuildSteps.Add("echo This is $(TargetName) $(TargetConfiguration) $(TargetPlatform)");
PostBuildSteps.Add("echo After building!");
PostBuildSteps.Add("echo This is $(TargetName) $(TargetConfiguration) $(TargetPlatform)");
}
}
}
Change 3541664 by Graeme.Thornton
VSCode - Add problemMatcher tag to cpp build targets
Change 3541732 by Graeme.Thornton
VSCode - Change UBT command line switch to "-vscode" for simplicity
Change 3541967 by Graeme.Thornton
VSCode - Fixes for Mac/Linux build steps
Change 3541968 by Ben.Marsh
CRP: Pass through the EnabledPlugins element in crash context XML files.
#jira UE-46912
Change 3542519 by Ben.Marsh
UBT: Add chain of references to error messages when configuring plugins.
Change 3542523 by Ben.Marsh
UBT: Add more useful error message when attempt to parse a JSON object fails.
Change 3542658 by Ben.Marsh
UBT: Include a chain of references when reporting errors instantiating modules.
Change 3543432 by Ben.Marsh
Plugins: Fix plugins which are enabled by default not being enabled unless a project file is set.
Change 3543436 by Ben.Marsh
UBT: Prevent recursing through the same module more than once when building out the referenced modules. Produces much shorter reference chains when something fails.
Change 3543536 by Ben.Marsh
UBT: Downgrade message about redundant plugin references to a warning.
Change 3543871 by Gil.Gribb
UE4 - Fixed a critical crash bug with non-EDL loading from pak files.
Change 3543924 by Robert.Manuszewski
Fixed a crash on UnrealFrontend startup caused by re-assembling GC token stream for one of the classes.
+Small optimization to token stream generation code.
Change 3544469 by Jin.Zhang
Crashes page displays the list of plugins from the crash context #rb
Change 3544608 by Steve.Robb
Fix for nativized generated code.
#jira UE-47452
Change 3544612 by Ben.Marsh
Add callback into FMacPlatformMisc::PumpMessages() from FMacPlatformApplicationMisc::PumpMessages().
#jira UE-47449
Change 3545954 by Gil.Gribb
Fixed a critical crash bug relating to a race condition in async package summary reading.
Change 3545968 by Ben.Marsh
UAT: Fix incorrect username in BuildGraph <Submit> task. Should use the username from the Perforce environment, not assume the logged in user name is the same.
#jira UE-47419
Change 3545976 by Ben.Marsh
EC: Delete the AutoSDK client if the directory doesn't exist. When we format build machines, we need to force everything to be resynced from scratch.
Change 3546185 by Ben.Marsh
Hacky fix for deployment on IOS/TVOS. Since deployment directly references the NonUFS manifest files that are written out, merge all the SystemNonUFS files back into the NonUFS list after the regular NonUFS files have been remapped.
Change 3547084 by Gil.Gribb
Fixed a critical race condition in the new async loader. This was only reproducible on IOS, but may affect other platforms.
Change 3547968 by Gil.Gribb
Fixed critical race which potentially could cause a crash in the pak precacher.
Change 3504722 by Ben.Marsh
BuildGraph: Improved tracing for error messages. All errors are now propagated as exceptions, and are tagged with additional context information about the task currently being run.
For example, throwing new AutomationException("Unable to write foo.txt") from SetVersionTask.Execute is now displayed in the log as:
ERROR: Unable to write to foo.txt
while executing <SetVersion Change="0" CompatibleChange="0" Branch="Unknown" Promoted="True" />
at Engine\Build\InstalledEngineBuild.xml(91)
(see D:\P4 UE4\Engine\Programs\AutomationTool\Saved\Logs\UAT_Log.txt for full exception trace)
Change 3512255 by Ben.Marsh
Rename FPaths functions with a "Game" prefix (GameDir(), GameContentDir(), etc...) to have a "Project" prefix (ProjectDir(), ProjectContentDir(), etc...) for clarity with non-game uses of UE4. Old functions still exist but are deprecated.
Change 3512332 by Ben.Marsh
Rename "Game" functions in FApp to be "Project" functions (FApp::GetGameName() -> FApp::GetProjectName(), etc...) for clarity with non-game uses of UE4.
Change 3512393 by Ben.Marsh
Rename FPaths::GameLogDir() to FPaths::ProjectLogDir().
Change 3513452 by Ben.Marsh
Plugins: Rename EPluginLoadedFrom::GameProject to EPluginLoadedFrom::Project.
Change 3516262 by Ben.Marsh
Add support for a "Mods" folder distinct from the project's "Plugins" folder, instead of using the bIsMod flag on the plugin descriptor.
* Mods are enumerated similarly to regular plugins, but IPlugin::GetType() will return EPluginType::Mod.
* The DLCName parameter to BuildCookRun and the cooker now correctly finds any plugin in the Plugins or Mods directory (or any subfolders).
Change 3517565 by Ben.Marsh
Remove fixed engine version numbers from OSS plugins.
Change 3518005 by Ben.Marsh
UAT: Remove the bUFSFile parameter from DeployLowerCaseFilenames(). Every platform returns false if the argument is false.
Change 3518054 by Ben.Marsh
UAT: Use an enum to direct whether all directories should be searched when finding files to stage, rather than a bool. Having so many optional boolean arguments makes code unreadable and refactoring hard.
Change 3524496 by Ben.Marsh
Start moving GUI application code into a separate static platform class, hopefully ultimately removing it from Core.
Change 3524641 by Ben.Marsh
Move more functionality related to windowed/graphical applications into FPlatformApplicationMisc.
Change 3528723 by Steve.Robb
MoveTemp now static asserts if passed a const reference or rvalue.
MoveTempIfPossible still follows the old (std::move) rule, which is useful for templates where the nature of the argument is not obvious.
Fixes to violations of these new rules.
Change 3528876 by Ben.Marsh
Move FPlatformMisc::ClipboardCopy and FPlatformMisc::ClipboardPaste to FPlatformApplicationMisc::ClipboardCopy and FPlatformApplicationMisc::ClipboardPaste.
Change 3529073 by Ben.Marsh
Add script to package ShooterGame for any platforms.
Change 3531493 by Ben.Marsh
Update platform-specific plugins to declare the target platforms they support.
Change 3531611 by Ben.Marsh
UAT: Add a ResavePluginDescriptors command, which resaves all plugin descriptors under a given folder, removing any outdated fields and rewrites them in a consistent style. Many plugins in the wild contain redundant or no-longer used fields due to using our plugins as templates.
Change 3531868 by Ben.Marsh
Resaving project descriptors to remove invalid fields.
Change 3531983 by Ben.Marsh
UAT: Simplify logic for staging code, and add validation against shipping files in restricted folders.
* Added a new SystemNonUFS type for staged files, which excludes files from being remapped or renamed by the platform layer.
* Replaced the DeplyomentContext.StageFiles() function with simpler overloads for particular use cases (options for remapping are replaced with the SystemNonUFS file type)
* Config entries in the [Staging] category in DefaultGame.ini file allow remapping one directory to another, so restricted content can be made public in packaged builds (Example syntax: +RemapDirectory=(From="Foo/NoRedist", To="Foo"))
* An error is output if any restricted folder names other than the output platform are in the staged output.
Change 3540315 by Ben.Marsh
UAT: Moving StreamCopyDescription command into a NotForLicensees folder, since it's only meant to be used by engine developers.
Change 3542410 by Ben.Marsh
UBT: Deprecate accessing properties through BuildConfiguration.* or UEBuildConfiguration.* from .target.cs files. These have been aliases to the current TargetRules instance for several releases already.
Change 3543018 by Ben.Marsh
UBT: Deprecate the BuildConfiguration and UEBuildConfiguration aliases from the ModuleRules class. These have been implemented as an alias ot the ReadOnlyTargetRules instance passed to the constructor for several engine versions.
Change 3544371 by Steve.Robb
Fixes to TSet_Add and TMap_Add BPs.
#jira UE-47441
[CL 3548391 by Ben Marsh in Main branch]
2017-07-21 12:42:36 -04:00
CollectionFolders [ ECollectionShareType : : CST_Shared ] = FPaths : : ProjectContentDir ( ) / TEXT ( " Collections " ) ;
2014-03-14 14:13:41 -04:00
2021-11-30 14:20:47 -05:00
bNoFixupRedirectors = FParse : : Param ( FCommandLine : : Get ( ) , TEXT ( " NoFixupRedirectorsInCollections " ) ) ;
2014-03-14 14:13:41 -04:00
LoadCollections ( ) ;
2015-07-07 10:31:39 -04:00
2024-04-19 18:17:59 -04:00
// Perform initial caching of collection information ready for user to interact with anything
UE : : Tasks : : Launch ( UE_SOURCE_LOCATION , [ this ] ( ) {
FCollectionLock_Write Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : All ) ;
} ) ;
2015-07-07 10:31:39 -04:00
// Watch for changes that may happen outside of the collection manager
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
{
const FString & CollectionFolder = CollectionFolders [ CacheIdx ] ;
2015-07-21 12:47:33 -04:00
if ( CollectionFolder . IsEmpty ( ) )
{
continue ;
}
// Make sure the folder we want to watch exists on disk
2015-10-28 19:18:20 -04:00
if ( ! IFileManager : : Get ( ) . MakeDirectory ( * CollectionFolder , true ) )
{
continue ;
}
2015-07-21 12:47:33 -04:00
2015-07-07 10:31:39 -04:00
DirectoryWatcher : : FFileCacheConfig FileCacheConfig ( FPaths : : ConvertRelativePathToFull ( CollectionFolder ) , FString ( ) ) ;
FileCacheConfig . DetectMoves ( false ) ;
FileCacheConfig . RequireFileHashes ( false ) ;
CollectionFileCaches [ CacheIdx ] = MakeShareable ( new DirectoryWatcher : : FFileCache ( FileCacheConfig ) ) ;
}
2021-08-16 11:09:22 -04:00
TickFileCacheDelegateHandle = FTSTicker : : GetCoreTicker ( ) . AddTicker ( FTickerDelegate : : CreateRaw ( this , & FCollectionManager : : TickFileCache ) , 1.0f ) ;
2014-03-14 14:13:41 -04:00
}
FCollectionManager : : ~ FCollectionManager ( )
{
2024-04-19 18:17:59 -04:00
FWriteScopeLock Guard ( Lock ) ;
2021-08-16 11:09:22 -04:00
FTSTicker : : GetCoreTicker ( ) . RemoveTicker ( TickFileCacheDelegateHandle ) ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
2014-03-14 14:13:41 -04:00
2015-05-29 13:15:23 -04:00
bool FCollectionManager : : HasCollections ( ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Read Guard ( Lock ) ;
2015-07-06 09:40:48 -04:00
return AvailableCollections . Num ( ) > 0 ;
2015-05-29 13:15:23 -04:00
}
2015-06-19 07:33:02 -04:00
void FCollectionManager : : GetCollections ( TArray < FCollectionNameType > & OutCollections ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Read Guard ( Lock ) ;
2015-07-06 09:40:48 -04:00
OutCollections . Reserve ( AvailableCollections . Num ( ) ) ;
2024-04-19 18:17:59 -04:00
for ( const TPair < FCollectionNameType , TSharedRef < FCollection > > & AvailableCollection : AvailableCollections )
2015-06-19 07:33:02 -04:00
{
2015-07-06 09:40:48 -04:00
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
2015-06-19 07:33:02 -04:00
OutCollections . Add ( CollectionKey ) ;
}
}
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
void FCollectionManager : : GetCollections ( FName CollectionName , TArray < FCollectionNameType > & OutCollections ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Read Guard ( Lock ) ;
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
{
if ( AvailableCollections . Contains ( FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) ) )
{
OutCollections . Add ( FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) ) ;
}
}
}
2014-03-14 14:13:41 -04:00
void FCollectionManager : : GetCollectionNames ( ECollectionShareType : : Type ShareType , TArray < FName > & CollectionNames ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Read Guard ( Lock ) ;
for ( const TPair < FCollectionNameType , TSharedRef < FCollection > > & AvailableCollection : AvailableCollections )
2014-03-14 14:13:41 -04:00
{
2015-07-06 09:40:48 -04:00
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
2015-05-21 07:43:16 -04:00
if ( ShareType = = ECollectionShareType : : CST_All | | ShareType = = CollectionKey . Type )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
CollectionNames . AddUnique ( CollectionKey . Name ) ;
2014-03-14 14:13:41 -04:00
}
}
}
2015-06-19 07:33:02 -04:00
void FCollectionManager : : GetRootCollections ( TArray < FCollectionNameType > & OutCollections ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Names ) ;
const TMap < FGuid , FCollectionNameType > & CachedCollectionNamesFromGuids = CollectionCache - > GetCachedCollectionNamesFromGuids ( Guard ) ;
2015-07-06 09:40:48 -04:00
OutCollections . Reserve ( AvailableCollections . Num ( ) ) ;
2024-04-19 18:17:59 -04:00
for ( const TPair < FCollectionNameType , TSharedRef < FCollection > > & AvailableCollection : AvailableCollections )
2015-06-19 07:33:02 -04:00
{
2015-07-06 09:40:48 -04:00
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
const TSharedRef < FCollection > & Collection = AvailableCollection . Value ;
2015-06-19 07:33:02 -04:00
// A root collection either has no parent GUID, or a parent GUID that cannot currently be found - the check below handles both
if ( ! CachedCollectionNamesFromGuids . Contains ( Collection - > GetParentCollectionGuid ( ) ) )
{
OutCollections . Add ( CollectionKey ) ;
}
}
}
void FCollectionManager : : GetRootCollectionNames ( ECollectionShareType : : Type ShareType , TArray < FName > & CollectionNames ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Names ) ;
const TMap < FGuid , FCollectionNameType > & CachedCollectionNamesFromGuids = CollectionCache - > GetCachedCollectionNamesFromGuids ( Guard ) ;
2015-07-06 09:40:48 -04:00
2024-04-19 18:17:59 -04:00
for ( const TPair < FCollectionNameType , TSharedRef < FCollection > > & AvailableCollection : AvailableCollections )
2015-06-19 07:33:02 -04:00
{
2015-07-06 09:40:48 -04:00
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
const TSharedRef < FCollection > & Collection = AvailableCollection . Value ;
2015-06-19 07:33:02 -04:00
if ( ShareType = = ECollectionShareType : : CST_All | | ShareType = = CollectionKey . Type )
{
// A root collection either has no parent GUID, or a parent GUID that cannot currently be found - the check below handles both
if ( ! CachedCollectionNamesFromGuids . Contains ( Collection - > GetParentCollectionGuid ( ) ) )
{
CollectionNames . AddUnique ( CollectionKey . Name ) ;
}
}
}
}
void FCollectionManager : : GetChildCollections ( FName CollectionName , ECollectionShareType : : Type ShareType , TArray < FCollectionNameType > & OutCollections ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Names | ECollectionCacheFlags : : Hierarchy ) ;
2015-07-06 09:40:48 -04:00
2024-04-19 18:17:59 -04:00
const TMap < FGuid , FCollectionNameType > & CachedCollectionNamesFromGuids = CollectionCache - > GetCachedCollectionNamesFromGuids ( Guard ) ;
const TMap < FGuid , TArray < FGuid > > & CachedHierarchy = CollectionCache - > GetCachedHierarchy ( Guard ) ;
const int32 Start = ShareType = = ECollectionShareType : : CST_All ? 0 : int32 ( ShareType ) ;
const int32 End = ShareType = = ECollectionShareType : : CST_All ? int32 ( ECollectionShareType : : CST_All ) : int32 ( ShareType ) + 1 ;
for ( int32 CacheIdx = Start ; CacheIdx < End ; + + CacheIdx )
2015-06-19 07:33:02 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionNameType CollectionKey { CollectionName , ECollectionShareType : : Type ( CacheIdx ) } ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
2015-06-19 07:33:02 -04:00
{
2024-04-19 18:17:59 -04:00
continue ;
}
const TArray < FGuid > * ChildCollectionGuids = CachedHierarchy . Find ( ( * CollectionRefPtr ) - > GetCollectionGuid ( ) ) ;
if ( ! ChildCollectionGuids )
{
continue ;
}
for ( const FGuid & ChildCollectionGuid : * ChildCollectionGuids )
{
const FCollectionNameType * const ChildCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( ChildCollectionGuid ) ;
if ( ChildCollectionKeyPtr )
2015-06-19 07:33:02 -04:00
{
2024-04-19 18:17:59 -04:00
OutCollections . Add ( * ChildCollectionKeyPtr ) ;
2015-06-19 07:33:02 -04:00
}
}
} ;
}
void FCollectionManager : : GetChildCollectionNames ( FName CollectionName , ECollectionShareType : : Type ShareType , ECollectionShareType : : Type ChildShareType , TArray < FName > & CollectionNames ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Names | ECollectionCacheFlags : : Hierarchy ) ;
const TMap < FGuid , FCollectionNameType > & CachedCollectionNamesFromGuids = CollectionCache - > GetCachedCollectionNamesFromGuids ( Guard ) ;
const TMap < FGuid , TArray < FGuid > > & CachedHierarchy = CollectionCache - > GetCachedHierarchy ( Guard ) ;
2015-07-06 09:40:48 -04:00
2024-04-19 18:17:59 -04:00
const int32 Start = ShareType = = ECollectionShareType : : CST_All ? 0 : int32 ( ShareType ) ;
const int32 End = ShareType = = ECollectionShareType : : CST_All ? int32 ( ECollectionShareType : : CST_All ) : int32 ( ShareType ) + 1 ;
for ( int32 CacheIdx = Start ; CacheIdx < End ; + + CacheIdx )
2015-06-19 07:33:02 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionNameType CollectionKey { CollectionName , ECollectionShareType : : Type ( CacheIdx ) } ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
2015-06-19 07:33:02 -04:00
{
2024-04-19 18:17:59 -04:00
continue ;
}
const TArray < FGuid > * ChildCollectionGuids = CachedHierarchy . Find ( ( * CollectionRefPtr ) - > GetCollectionGuid ( ) ) ;
if ( ! ChildCollectionGuids )
{
continue ;
}
for ( const FGuid & ChildCollectionGuid : * ChildCollectionGuids )
{
const FCollectionNameType * const ChildCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( ChildCollectionGuid ) ;
if ( ChildCollectionKeyPtr & & ( ChildShareType = = ECollectionShareType : : CST_All | | ChildShareType = = ChildCollectionKeyPtr - > Type ) )
2015-06-19 07:33:02 -04:00
{
2024-04-19 18:17:59 -04:00
CollectionNames . AddUnique ( ChildCollectionKeyPtr - > Name ) ;
2015-06-19 07:33:02 -04:00
}
}
} ;
}
2015-07-01 11:36:19 -04:00
TOptional < FCollectionNameType > FCollectionManager : : GetParentCollection ( FName CollectionName , ECollectionShareType : : Type ShareType ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
2015-07-06 09:40:48 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( FCollectionNameType ( CollectionName , ShareType ) ) ;
2024-04-19 18:17:59 -04:00
if ( ! CollectionRefPtr )
2015-07-01 11:36:19 -04:00
{
2024-04-19 18:17:59 -04:00
return TOptional < FCollectionNameType > ( ) ;
2015-07-01 11:36:19 -04:00
}
2024-04-19 18:17:59 -04:00
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Names ) ;
const TMap < FGuid , FCollectionNameType > & CachedCollectionNamesFromGuids = CollectionCache - > GetCachedCollectionNamesFromGuids ( Guard ) ;
const FCollectionNameType * const ParentCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( ( * CollectionRefPtr ) - > GetParentCollectionGuid ( ) ) ;
if ( ParentCollectionKeyPtr )
{
return * ParentCollectionKeyPtr ;
}
2015-07-01 11:36:19 -04:00
return TOptional < FCollectionNameType > ( ) ;
}
2014-03-14 14:13:41 -04:00
bool FCollectionManager : : CollectionExists ( FName CollectionName , ECollectionShareType : : Type ShareType ) const
2024-04-19 18:17:59 -04:00
{
FCollectionLock_Read Guard ( Lock ) ;
return CollectionExists_Locked ( Guard , CollectionName , ShareType ) ;
}
bool FCollectionManager : : CollectionExists_Locked ( FCollectionLock & , FName CollectionName , ECollectionShareType : : Type ShareType ) const
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
if ( ShareType = = ECollectionShareType : : CST_All )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
// Asked to check all share types...
2014-03-14 14:13:41 -04:00
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
{
2015-07-06 09:40:48 -04:00
if ( AvailableCollections . Contains ( FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) ) )
2014-03-14 14:13:41 -04:00
{
// Collection exists in at least one cache
return true ;
}
}
// Collection not found in any cache
return false ;
}
else
{
2015-07-06 09:40:48 -04:00
return AvailableCollections . Contains ( FCollectionNameType ( CollectionName , ShareType ) ) ;
2014-03-14 14:13:41 -04:00
}
}
2022-09-16 20:57:34 -04:00
bool FCollectionManager : : GetAssetsInCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , TArray < FSoftObjectPath > & AssetsPaths , ECollectionRecursionFlags : : Flags RecursionMode ) const
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : RecursionWorker ) ;
2015-06-19 07:33:02 -04:00
bool bFoundAssets = false ;
2024-04-19 18:17:59 -04:00
auto GetAssetsInCollectionWorker = [ AvailableCollections = & AvailableCollections , & AssetsPaths , & bFoundAssets ] ( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > FCollectionManagerCache : : ERecursiveWorkerFlowControl
2015-05-21 07:43:16 -04:00
{
2024-04-19 18:17:59 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections - > Find ( InCollectionKey ) ;
2015-05-21 07:43:16 -04:00
if ( CollectionRefPtr )
{
( * CollectionRefPtr ) - > GetAssetsInCollection ( AssetsPaths ) ;
2015-06-19 07:33:02 -04:00
bFoundAssets = true ;
2015-05-21 07:43:16 -04:00
}
2015-07-06 09:40:48 -04:00
return FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Continue ;
2015-05-21 07:43:16 -04:00
} ;
if ( ShareType = = ECollectionShareType : : CST_All )
2014-03-14 14:13:41 -04:00
{
// Asked for all share types, find assets in the specified collection name in any cache
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
{
2024-04-19 18:17:59 -04:00
CollectionCache - > RecursionHelper_DoWork ( Guard , FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) , RecursionMode , GetAssetsInCollectionWorker ) ;
2014-03-14 14:13:41 -04:00
}
}
else
{
2024-04-19 18:17:59 -04:00
CollectionCache - > RecursionHelper_DoWork ( Guard , FCollectionNameType ( CollectionName , ShareType ) , RecursionMode , GetAssetsInCollectionWorker ) ;
2014-03-14 14:13:41 -04:00
}
2015-06-19 07:33:02 -04:00
return bFoundAssets ;
2014-03-14 14:13:41 -04:00
}
2022-09-16 20:57:34 -04:00
bool FCollectionManager : : GetClassesInCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , TArray < FTopLevelAssetPath > & ClassPaths , ECollectionRecursionFlags : : Flags RecursionMode ) const
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : RecursionWorker ) ;
2015-06-19 07:33:02 -04:00
bool bFoundClasses = false ;
2024-04-19 18:17:59 -04:00
auto GetClassesInCollectionWorker = [ AvailableCollections = & AvailableCollections , & ClassPaths , & bFoundClasses ] ( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > FCollectionManagerCache : : ERecursiveWorkerFlowControl
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections - > Find ( InCollectionKey ) ;
2015-05-21 07:43:16 -04:00
if ( CollectionRefPtr )
{
( * CollectionRefPtr ) - > GetClassesInCollection ( ClassPaths ) ;
2015-06-19 07:33:02 -04:00
bFoundClasses = true ;
2015-05-21 07:43:16 -04:00
}
2015-07-06 09:40:48 -04:00
return FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Continue ;
2015-05-21 07:43:16 -04:00
} ;
2014-03-14 14:13:41 -04:00
2015-05-21 07:43:16 -04:00
if ( ShareType = = ECollectionShareType : : CST_All )
{
// Asked for all share types, find classes in the specified collection name in any cache
2014-03-14 14:13:41 -04:00
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
{
2024-04-19 18:17:59 -04:00
CollectionCache - > RecursionHelper_DoWork ( Guard , FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) , RecursionMode , GetClassesInCollectionWorker ) ;
2014-03-14 14:13:41 -04:00
}
}
else
{
2024-04-19 18:17:59 -04:00
CollectionCache - > RecursionHelper_DoWork ( Guard , FCollectionNameType ( CollectionName , ShareType ) , RecursionMode , GetClassesInCollectionWorker ) ;
2014-03-14 14:13:41 -04:00
}
2015-06-19 07:33:02 -04:00
return bFoundClasses ;
2014-03-14 14:13:41 -04:00
}
2022-09-16 20:57:34 -04:00
bool FCollectionManager : : GetObjectsInCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , TArray < FSoftObjectPath > & ObjectPaths , ECollectionRecursionFlags : : Flags RecursionMode ) const
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : RecursionWorker ) ;
2015-06-19 07:33:02 -04:00
bool bFoundObjects = false ;
2024-04-19 18:17:59 -04:00
auto GetObjectsInCollectionWorker = [ AvailableCollections = & AvailableCollections , & ObjectPaths , & bFoundObjects ] ( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > FCollectionManagerCache : : ERecursiveWorkerFlowControl
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections - > Find ( InCollectionKey ) ;
2015-05-21 07:43:16 -04:00
if ( CollectionRefPtr )
{
( * CollectionRefPtr ) - > GetObjectsInCollection ( ObjectPaths ) ;
2015-06-19 07:33:02 -04:00
bFoundObjects = true ;
2015-05-21 07:43:16 -04:00
}
2015-07-06 09:40:48 -04:00
return FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Continue ;
2015-05-21 07:43:16 -04:00
} ;
2014-03-14 14:13:41 -04:00
2015-05-21 07:43:16 -04:00
if ( ShareType = = ECollectionShareType : : CST_All )
{
2015-06-19 07:33:02 -04:00
// Asked for all share types, find classes in the specified collection name in any cache
2014-03-14 14:13:41 -04:00
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
{
2024-04-19 18:17:59 -04:00
CollectionCache - > RecursionHelper_DoWork ( Guard , FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) , RecursionMode , GetObjectsInCollectionWorker ) ;
2014-03-14 14:13:41 -04:00
}
}
else
{
2024-04-19 18:17:59 -04:00
CollectionCache - > RecursionHelper_DoWork ( Guard , FCollectionNameType ( CollectionName , ShareType ) , RecursionMode , GetObjectsInCollectionWorker ) ;
2014-03-14 14:13:41 -04:00
}
2015-06-19 07:33:02 -04:00
return bFoundObjects ;
2014-03-14 14:13:41 -04:00
}
2022-09-16 20:57:34 -04:00
void FCollectionManager : : GetCollectionsContainingObject ( const FSoftObjectPath & ObjectPath , ECollectionShareType : : Type ShareType , TArray < FName > & OutCollectionNames , ECollectionRecursionFlags : : Flags RecursionMode ) const
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Objects ) ;
const TMap < FSoftObjectPath , TArray < FObjectCollectionInfo > > & CachedObjects = CollectionCache - > GetCachedObjects ( Guard ) ;
2015-07-06 09:40:48 -04:00
2024-04-19 18:17:59 -04:00
const TArray < FObjectCollectionInfo > * ObjectCollectionInfosPtr = CachedObjects . Find ( ObjectPath ) ;
2015-06-19 07:33:02 -04:00
if ( ObjectCollectionInfosPtr )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
for ( const FObjectCollectionInfo & ObjectCollectionInfo : * ObjectCollectionInfosPtr )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
if ( ( ShareType = = ECollectionShareType : : CST_All | | ShareType = = ObjectCollectionInfo . CollectionKey . Type ) & & ( RecursionMode & ObjectCollectionInfo . Reason ) ! = 0 )
2015-05-29 13:15:23 -04:00
{
2015-06-19 07:33:02 -04:00
OutCollectionNames . Add ( ObjectCollectionInfo . CollectionKey . Name ) ;
2015-05-29 13:15:23 -04:00
}
}
}
}
2022-09-16 20:57:34 -04:00
void FCollectionManager : : GetCollectionsContainingObject ( const FSoftObjectPath & ObjectPath , TArray < FCollectionNameType > & OutCollections , ECollectionRecursionFlags : : Flags RecursionMode ) const
2015-05-29 13:15:23 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Objects ) ;
const TMap < FSoftObjectPath , TArray < FObjectCollectionInfo > > & CachedObjects = CollectionCache - > GetCachedObjects ( Guard ) ;
2015-07-06 09:40:48 -04:00
2024-04-19 18:17:59 -04:00
const TArray < FObjectCollectionInfo > * ObjectCollectionInfosPtr = CachedObjects . Find ( ObjectPath ) ;
2015-06-19 07:33:02 -04:00
if ( ObjectCollectionInfosPtr )
2015-05-29 13:15:23 -04:00
{
2015-06-19 07:33:02 -04:00
OutCollections . Reserve ( OutCollections . Num ( ) + ObjectCollectionInfosPtr - > Num ( ) ) ;
for ( const FObjectCollectionInfo & ObjectCollectionInfo : * ObjectCollectionInfosPtr )
{
if ( ( RecursionMode & ObjectCollectionInfo . Reason ) ! = 0 )
{
OutCollections . Add ( ObjectCollectionInfo . CollectionKey ) ;
}
}
2015-05-29 13:15:23 -04:00
}
}
2022-09-16 20:57:34 -04:00
void FCollectionManager : : GetCollectionsContainingObjects ( const TArray < FSoftObjectPath > & ObjectPaths , TMap < FCollectionNameType , TArray < FSoftObjectPath > > & OutCollectionsAndMatchedObjects , ECollectionRecursionFlags : : Flags RecursionMode ) const
2015-05-29 13:15:23 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Objects ) ;
const TMap < FSoftObjectPath , TArray < FObjectCollectionInfo > > & CachedObjects = CollectionCache - > GetCachedObjects ( Guard ) ;
2015-07-06 09:40:48 -04:00
2022-09-16 20:57:34 -04:00
for ( const FSoftObjectPath & ObjectPath : ObjectPaths )
2015-05-29 13:15:23 -04:00
{
2024-04-19 18:17:59 -04:00
const TArray < FObjectCollectionInfo > * ObjectCollectionInfosPtr = CachedObjects . Find ( ObjectPath ) ;
2015-06-19 07:33:02 -04:00
if ( ObjectCollectionInfosPtr )
2015-05-29 13:15:23 -04:00
{
2015-06-19 07:33:02 -04:00
for ( const FObjectCollectionInfo & ObjectCollectionInfo : * ObjectCollectionInfosPtr )
2015-05-29 13:15:23 -04:00
{
2015-06-19 07:33:02 -04:00
if ( ( RecursionMode & ObjectCollectionInfo . Reason ) ! = 0 )
{
2022-09-16 20:57:34 -04:00
TArray < FSoftObjectPath > & MatchedObjects = OutCollectionsAndMatchedObjects . FindOrAdd ( ObjectCollectionInfo . CollectionKey ) ;
2015-06-19 07:33:02 -04:00
MatchedObjects . Add ( ObjectPath ) ;
}
2015-05-29 13:15:23 -04:00
}
2014-03-14 14:13:41 -04:00
}
}
}
2022-09-16 20:57:34 -04:00
FString FCollectionManager : : GetCollectionsStringForObject ( const FSoftObjectPath & ObjectPath , ECollectionShareType : : Type ShareType , ECollectionRecursionFlags : : Flags RecursionMode , bool bFullPaths ) const
2015-05-21 09:23:51 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Objects | ECollectionCacheFlags : : RecursionWorker ) ;
const TMap < FSoftObjectPath , TArray < FObjectCollectionInfo > > & CachedObjects = CollectionCache - > GetCachedObjects ( Guard ) ;
2015-07-06 09:40:48 -04:00
2024-04-19 18:17:59 -04:00
const TArray < FObjectCollectionInfo > * ObjectCollectionInfosPtr = CachedObjects . Find ( ObjectPath ) ;
2015-06-19 07:33:02 -04:00
if ( ObjectCollectionInfosPtr )
2015-05-29 13:15:23 -04:00
{
TArray < FString > CollectionNameStrings ;
2015-07-01 10:25:19 -04:00
TArray < FString > CollectionPathStrings ;
2024-04-19 18:17:59 -04:00
auto GetCollectionsStringForObjectWorker = [ & CollectionPathStrings ] ( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > FCollectionManagerCache : : ERecursiveWorkerFlowControl
2015-07-01 10:25:19 -04:00
{
CollectionPathStrings . Insert ( InCollectionKey . Name . ToString ( ) , 0 ) ;
2015-07-06 09:40:48 -04:00
return FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Continue ;
2015-07-01 10:25:19 -04:00
} ;
2015-06-19 07:33:02 -04:00
for ( const FObjectCollectionInfo & ObjectCollectionInfo : * ObjectCollectionInfosPtr )
2015-05-21 09:23:51 -04:00
{
2015-06-19 07:33:02 -04:00
if ( ( ShareType = = ECollectionShareType : : CST_All | | ShareType = = ObjectCollectionInfo . CollectionKey . Type ) & & ( RecursionMode & ObjectCollectionInfo . Reason ) ! = 0 )
2015-05-29 13:15:23 -04:00
{
2018-10-24 17:22:01 -04:00
if ( bFullPaths )
{
CollectionPathStrings . Reset ( ) ;
2024-04-19 18:17:59 -04:00
CollectionCache - > RecursionHelper_DoWork ( Guard , ObjectCollectionInfo . CollectionKey , ECollectionRecursionFlags : : SelfAndParents , GetCollectionsStringForObjectWorker ) ;
2018-10-24 17:22:01 -04:00
CollectionNameStrings . Add ( FString : : Join ( CollectionPathStrings , TEXT ( " / " ) ) ) ;
}
else
{
CollectionNameStrings . Add ( ObjectCollectionInfo . CollectionKey . Name . ToString ( ) ) ;
}
2015-05-29 13:15:23 -04:00
}
}
if ( CollectionNameStrings . Num ( ) > 0 )
{
CollectionNameStrings . Sort ( ) ;
return FString : : Join ( CollectionNameStrings , TEXT ( " , " ) ) ;
2015-05-21 09:23:51 -04:00
}
}
return FString ( ) ;
}
2014-03-14 14:13:41 -04:00
void FCollectionManager : : CreateUniqueCollectionName ( const FName & BaseName , ECollectionShareType : : Type ShareType , FName & OutCollectionName ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Read Guard ( Lock ) ;
2014-03-14 14:13:41 -04:00
int32 IntSuffix = 1 ;
bool CollectionAlreadyExists = false ;
do
{
2015-05-21 07:43:16 -04:00
if ( IntSuffix < = 1 )
2014-03-14 14:13:41 -04:00
{
OutCollectionName = BaseName ;
}
else
{
OutCollectionName = * FString : : Printf ( TEXT ( " %s%d " ) , * BaseName . ToString ( ) , IntSuffix ) ;
}
2024-04-19 18:17:59 -04:00
CollectionAlreadyExists = CollectionExists_Locked ( Guard , OutCollectionName , ShareType ) ;
2014-03-14 14:13:41 -04:00
+ + IntSuffix ;
}
2015-05-21 07:43:16 -04:00
while ( CollectionAlreadyExists ) ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : IsValidCollectionName ( const FString & CollectionName , ECollectionShareType : : Type ShareType , FText * OutError ) const
2015-07-02 12:20:22 -04:00
{
// Make sure we are not creating an FName that is too large
2021-04-08 14:32:07 -04:00
if ( CollectionName . Len ( ) > = NAME_SIZE )
2015-07-02 12:20:22 -04:00
{
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = FText : : Format ( LOCTEXT ( " Error_CollectionNameTooLong " , " This collection name is too long ({0} characters), the maximum is {1}. Please choose a shorter name. Collection name: {2} " ) ,
FText : : AsNumber ( CollectionName . Len ( ) ) , FText : : AsNumber ( NAME_SIZE ) , FText : : FromString ( CollectionName ) ) ;
}
2015-07-02 12:20:22 -04:00
return false ;
}
const FName CollectionNameFinal = * CollectionName ;
// Make sure the we actually have a new name set
if ( CollectionNameFinal . IsNone ( ) )
{
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_CollectionNameEmptyOrNone " , " This collection name cannot be empty or 'None'. " ) ;
}
2015-07-02 12:20:22 -04:00
return false ;
}
// Make sure the new name only contains valid characters
2024-04-19 18:17:59 -04:00
if ( ! CollectionNameFinal . IsValidXName ( INVALID_OBJECTNAME_CHARACTERS INVALID_LONGPACKAGE_CHARACTERS , OutError ) )
2015-07-02 12:20:22 -04:00
{
return false ;
}
// Make sure we're not duplicating an existing collection name
2024-04-19 18:17:59 -04:00
// NB: Ok to call public function here because we don't need acquire a lock for the previous checks
2015-07-02 12:20:22 -04:00
if ( CollectionExists ( CollectionNameFinal , ShareType ) )
{
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = FText : : Format ( LOCTEXT ( " Error_CollectionAlreadyExists " , " A collection already exists with the name '{0}'. " ) , FText : : FromName ( CollectionNameFinal ) ) ;
}
2015-07-02 12:20:22 -04:00
return false ;
}
return true ;
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : CreateCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , ECollectionStorageMode : : Type StorageMode , FText * OutError )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
2014-03-14 14:13:41 -04:00
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2014-03-14 14:13:41 -04:00
return false ;
}
2024-04-19 18:17:59 -04:00
if ( ! IsValidCollectionName ( CollectionName . ToString ( ) , ShareType , OutError ) )
Copying //UE4/Dev-Editor to //UE4/Dev-Main (Source: //UE4/Dev-Editor @ 3621452)
#lockdown Nick.Penwarden
#rb none
============================
MAJOR FEATURES & CHANGES
============================
Change 3567301 by Arciel.Rekman
Linux: fix for importing failure when clicking shortcuts (UE-47932).
- Slate dialog would return incorrect relative paths (not matching CWD) if Engine or Project shortcuts were used.
#jira UE-47932
Change 3567687 by Arciel.Rekman
Minor fixes to gdb pretty printers by icculus.
Change 3568024 by Arciel.Rekman
Made SDL_SetWindowInputFocus() wait until window is viewable (UE-33369).
- Pull request #2608 contributed by Ereski.
- Updated x86_64 lib only (anticipating more changes to SDL).
#coderview Cengiz.Terzibas, Ryan.Gordon
Change 3568173 by Max.Chen
Movie Scene Capture: Delay on shot boundaries by setting the sequencer play rate to 0.
This allows particles, TAA, and other effects to settle on the shot cuts.
#jira UE-44598
Change 3568174 by Max.Chen
Sequencer: Added option to rerun construction scripts on bound actors in the sequence every frame.
#jira UE-31193
Change 3568331 by Matt.Kuhlenschmidt
PR #3850: Add extensible source navigation service (Contributed by mhutch)
Change 3568350 by Matt.Kuhlenschmidt
PR #3851: Add argument to pass params to standalone play session (Contributed by mhutch)
Change 3568387 by Matt.Kuhlenschmidt
PR #3852: Add FEditorDelegates::BeginLocalPlay event (Contributed by mhutch)
Change 3568541 by Arciel.Rekman
Merged Icculus' patch for copy-paste (UE-40071).
- Alas does not seem to fix inability to copy/paste between Output log and kate.
- Updated x86_64 lib only (anticipating more changes).
Change 3568547 by Arciel.Rekman
Fix OpenGL queries reused after deletion.
Change 3568790 by Matt.Kuhlenschmidt
PR #3857: Loading screen widgets not scaled correctly (Contributed by projectgheist)
Change 3568900 by Alexis.Matte
Fix the fbx re-import factory handler to say failed in case there was no geometry to import.
#jira UE-47506
Change 3568902 by Alexis.Matte
Reduce memory footprint when importing large FBX scene PR #3834
#jira UE-47833
Change 3569061 by Arciel.Rekman
Linux: remove unnecessary symbols for MSVC visualizers.
- Reported by ASan as collision because they exist in each DSO.
Change 3569782 by Cody.Albert
Updated ImportAssets Commandlet help text to properly reflect supported features.
Change 3569843 by Arciel.Rekman
SDL: add logic to select headless EGL device.
- SDL will try to guess which device is GPU using CUDA device id (can also be hinted explicitly).
- Also fixes the problem of engine not starting on some drivers that don't support the necessary EGL extensions.
Change 3570234 by Max.Chen
Sequencer: Import FBX settings. Added settings to toggle force front x axis and whether to create cameras that don't already exist in the level.
#jira UE-46754
Change 3570578 by Arciel.Rekman
Linux: make FAnsiMalloc compatible with malloc()/free().
- Prerequisite for ASan. Also helps fringe cases when we have to use FAnsiMalloc.
Change 3571015 by Alexis.Matte
Issue warning when we found zero normal, tangent or binormal
#jira UE-46419
Change 3571376 by Jamie.Dale
Force a unique package localization ID when loading packages for diffing
Change 3571412 by Jamie.Dale
Removed unused setting
Change 3571487 by Alexis.Matte
fix speed tree import cancel workflow
#jira UE-47482
Change 3571614 by Jamie.Dale
Games now use the native culture of any of the game targets as the fallback (rather than always using English)
This replaces the previously removed redundant setting from CL# 3571412
Change 3572649 by Jamie.Dale
SavePackageHelper now always honors KeepObjectFlags
Change 3572730 by Matt.Kuhlenschmidt
Guard against crash in the details panel when there is a message in the queue and something scrolls into view when the list has been invalidated
#jira UE-48037
Change 3572773 by Matt.Kuhlenschmidt
Guard against high res screenshot crashing if the requested image size doesnt match the image data size
#jira UE-47765
Change 3572813 by Michael.Trepka
Workaround for a mysterious issue in Xcode 9 beta 3 and 4 which makes it generate -Wnullability-inferred-on-nested-type warnings/errors in MetalDebugCommandEncoder.h even though we tell Clang to ignore them in MacPlatformCompilerPreSetup.h
Change 3573043 by Arciel.Rekman
FAnsiMalloc: fix compile issue (UE-48066).
#jira UE-48066
Change 3573236 by Arciel.Rekman
Linux: add UnrealLightmass to the installed build.
- Was also requested by a licensee on UDN.
Change 3573705 by Arciel.Rekman
SDL: update UE4 fork to the latest trunk (UETOOL-1242).
- Revision 11184 form 2017-08-04: http://hg.libsdl.org/SDL/rev/04063928c4a8
- Change by icculus (Ryan Gordon).
- Rebuilt x86_64 library only for now.
Change 3573741 by Arciel.Rekman
Fix crash when capturing a movie (UE-48093).
#jira UE-48093
Change 3574389 by Max.Chen
Sequencer: Array bounds check.
#jira UE-48095
Change 3574399 by Max.Chen
Sequencer: Fix crash in removing delegate
#jira UE-47461
Change 3574415 by Max.Chen
Sequencer: Put level visibility tracks in the SpawnObjects evaluation group to ensure levels are streamed before any possessable bindings are resolved
Change 3574416 by Max.Chen
Prevent slow task feedback from performing slow operations (flushing rendering commands, checking if shaders are initialized) when there are no modal dialogs open
Change 3574726 by Matt.Kuhlenschmidt
Focus the details view when actor selection changes if it is not focused
Change 3574922 by Michael.Trepka
Copy of CL 3574653 by Richard.Wallis
XCode Beta 4 Compile fixes. "Inferring '_Nonnull' for pointer type within array is deprecated "
Change 3576525 by Nick.Darnell
Editor - Data table rows names sort correctly in the property customization.
Blueprint - Fixing some crashes due to holding onto raw pointers instead of TWeakObjectPtrs.
UMG - SetWidgetClass now reinstances the widget if you change it at runtime.
Editor - Deleting actors that are still referenced now at least logs to the console what still references it.
Change 3576714 by Nick.Darnell
Editor - Build fix.
Change 3576770 by Jamie.Dale
Removed some dead code
It seems to be left over from the first attempt at stable localization keys
Change 3578433 by Matt.Kuhlenschmidt
Fix content browser settings being per project and having created a "Global" category for one setting
Change 3578556 by Max.Chen
Editor: Fix toolbar shared ref which was keeping the viewport toolbar around when switching between default and cinematic viewports.
#jira UE-48125
Change 3578561 by Matt.Kuhlenschmidt
Fix USD importing not respecting DestinationPath for automated import
Change 3580124 by Matt.Kuhlenschmidt
Fix bogus warning message when a property has an editcondition that is not marked edit aynwhere. This has always been supported and is the correct way to make an editcondition
Change 3581936 by Jamie.Dale
Restoring defaults for UContentBrowserSettings
Change 3582039 by Matt.Kuhlenschmidt
High DPI mode changes
- Editor viewport screen percentage is now adjusted automatically to account for DPI scaling. By default the scene will be rendered at a lower resolution based on screen percentage calculated based on 100/DPIScale. Users can override this automatic calcuation in the performance options if desired.
- DPI awareness is only set on windows in the editor now (still disabled by default)
- Fixed hit proxy calculation not working properly with screen percentage
- Developers can now register a delegate with SlateApplication to tell when a window's DPI changes
Change 3582049 by Matt.Kuhlenschmidt
Fix color picker not properly converting FColor properties back to gamma space
Change 3582054 by Matt.Kuhlenschmidt
Fix mac menus updating during unsafe times such as modal windows and slow tasks
#jira UE-47874
Change 3582084 by Jamie.Dale
Make sure to update the rendering resources for the active world if reloading its map build data
This prevents a crash in the renderer due to it holding onto stale data
Change 3582257 by Matt.Kuhlenschmidt
Fix widget component spawning widgets on cook
#jira UE-48201
Change 3582655 by Matt.Kuhlenschmidt
Fix DPI scale not being accounted for when entering immersive.
Change 3582706 by Matt.Kuhlenschmidt
Fix automation tests
Change 3582728 by Matt.Kuhlenschmidt
Turn on high dpi by default for windows editor
Change 3582732 by Matt.Kuhlenschmidt
Turn on high DPI by default for mac editor
Change 3583112 by Max.Chen
Sequencer: Add OnPlayReverse() event for when playback is in reverse
Change 3584130 by Matt.Kuhlenschmidt
PR #3897: Git plugin: fix action icon in history window (Contributed by SRombauts)
Change 3584237 by Matt.Kuhlenschmidt
Added the beginnings of a way to extend the usd importer with a custom resolver class that optionally handles prim identification and mesh and actor spawning.
Added a test resolver that handles prims based on usd "kind" metadata.
Change 3584535 by Matt.Kuhlenschmidt
Fix LOD identification in USD files
Change 3587703 by Matt.Kuhlenschmidt
Fix tooltip
Change 3587901 by Matt.Kuhlenschmidt
Fixed USD importing not finding and importing LODs properly
Change 3588380 by Matt.Kuhlenschmidt
Fix ctrl+w not duplicating on mac
#jira UE-46573
Change 3590435 by Jamie.Dale
Added support for in-editor previews of localized game text
This is configured by the "Preview Game Culture" setting, and will automatically be active when PIE is running (the preview language is also passed to any standalone games that are launched via the editor). This preview can also be used in the UMG editor to preview widgets in different languages.
While a preview is running, all editable FText fields are locked-down (read-only) to prevent accidentally clobbering source data with translation data. You can also use this new lock-down feature to prevent any localization changes in your project (set "LockLocalization" to "True" under the "Internationalization" section of either your DefaultGame or DefaultEngine INI).
In order to allow the game translations to be used in the editor, we now map the translation to any package localization ID variants when the LocRes data is loaded (or when looking up a specific piece of text). This is needed as the LocRes files only ever contain the "clean" versions of the IDs (without the package localization ID the editor uses), and also means that we no longer need to gather the "editor-only" variants of the text within assets.
Change 3592131 by Matt.Kuhlenschmidt
Log for newly converted actors being pending kill
#jira UE-47464
Change 3592200 by Matt.Kuhlenschmidt
Made the class viewer menu function properly on mac. Since it as a nomad tab it wasnt properly inserting itself into the top level menu on mac nor should it since it could be docked anywhere. The filters menu is now consistent with other filters menus
Change 3592227 by Matt.Kuhlenschmidt
Fix drag drop of actors being offset with high dpi monitors.
Change 3592719 by Bradut.Palas
#jira UE-45632 - dual key bindings feature
My approach was transforming the ActiveChord and DefaultChord into arrays and accessing them through an enum class called EMultipleKeyBindingIndex. A lot of connecting code, function prototypes, and data structures had to be changed to accomodate this. Most menus and tooltip texts are generated using the first valid active shortcut.
Change 3592793 by Bradut.Palas
Fix compile warnings for InputBindingManager (there were actually hidden bugs among them)
Change 3593128 by Matt.Kuhlenschmidt
Force low quality mode for background blurs by default on android
Change 3593579 by Michael.Dupuis
#jira UE-47223 :
If we have no world simply return null when GetLandscapeInfo is called
Handle the cases in PostEditChange to handle null returned from GetLandscapeInfo
Change 3593580 by Michael.Dupuis
Added missing shaders while generating thumbnails
Change 3593582 by Michael.Dupuis
#jira UE-47492 : Make sure LayerInfo is valid before accessing data
Change 3593584 by Michael.Dupuis
#jira UE-47253: Do not recreate the scene info in simulation mode
Change 3593585 by Michael.Dupuis
#jira UE-48484: no longer mark the package dirty while generating the GrassMap if they were not existing
Change 3593586 by Michael.Dupuis
#jira UE-48483 : hide the Rendering property group so user can't by mistake change the actor visibility
Change 3593593 by Michael.Dupuis
#jira UE-48327: Added guard to prevent crash when using CVarFoliageDiscardDataOnLoad and having invalid foliage in your map
Change 3593597 by Michael.Dupuis
#jira UE-48309: Do not build the tree if the static mesh is not even loaded yet
#jira UE-48340: Properly support the Random stream and partial buffer update
#jira UE-48228: Instance from blueprint are now visible in standalone game
#jira UE-45854: Crash probably linked to post load called on not loaded static mesh
#jira UE-48035: Properly init the per instance render data when creating a new component
Only update instance in non archetype or CDO.
Change 3594060 by Matt.Kuhlenschmidt
Fix high DPI mode being set for non-editor. Also prevent possible crashes due to dll handle for high DPI method being freed before called
Change 3594355 by Matt.Kuhlenschmidt
Change API help link to point to a website since offline CHM based docs are no longer used
#jira UE-48230
Change 3595358 by Matt.Kuhlenschmidt
Fixed bad initial window position and sizes for editor windows
By default SWindow.ClientSize will assume unscaled window size and will scale it based on DPI as needed. AdjustInitialSizeAndPositionForDPIScale argument can be used to disable this if needed
Fixed a dock tabs and the main frame not taking into account dpi scale when saving their layout. Now we always save window size at 1.0 scale and auto scale it based on DPI of the monitor it opens on.
#jira UE-48446
Change 3595590 by Matt.Kuhlenschmidt
Fix missing includes
Change 3595792 by Matt.Kuhlenschmidt
Fix style warnings
Change 3596418 by Bradut.Palas
fixing initial issue with dual keybinds (removed ensure macro to speedup first use of alternate key)
Change 3598679 by Max.Chen
PR #3872: Fix small typo in ImagePlate Plugin (Contributed by TheCodez)
#jira UE-48141
Change 3598720 by Max.Chen
Cine Camera: Add toggle to disable constraining the roll when look at tracking is enabled. This allows the user to animate the roll while tracking an object.
#jira UE-48316
Change 3600236 by Alexis.Matte
Create a LOD Custom Mode in the meshes editor UI. This allow user to compare details values between LODs
#jira UE-46822
Change 3600260 by Alexis.Matte
Make sure temporary rename do not create redirector
#jira UE-48364
Change 3600671 by Lauren.Ridge
PR #3913: Fixed 3D preview issue in the material editor (Contributed by YuchenMei)
#jira UE-48539
#jira UE-48180
#jira UE-48182
Change 3600812 by Jamie.Dale
We now defer the registration of IME contexts until an editable text first gains focus
Certain IMEs can have very high per-context costs, so this avoids that cost until we know that we definitely need to use the context
#jira UE-48100
Change 3601839 by Matt.Kuhlenschmidt
Fix USD import crash with "facevarying" normals
Change 3602434 by Jamie.Dale
Removing dead code
These flags were never being tested or used in any meaningul way
Change 3602611 by Jamie.Dale
Ensure PackageToReload is non-null
#jira UE-46655
Change 3602648 by Jamie.Dale
Fixed custom columns with the same name as fixed columns causing infinite duplications in the content browser
#jira UE-47392
Change 3602651 by Lauren.Ridge
Fix for parameter tooltips not being found
#jira UE-47417
Change 3604172 by Bradut.Palas
#jira UE-48449
#jira UE-48380
#jira UE-48381
#jira UE-48423
I moved the IsFilenameValidForSaving() function from FEditorFileUtils to FFileHelper so that it is accessible from CollectionManager.cpp in order to validate collection names as file names and no longer trigger any of the bugs.
Change 3604210 by Bradut.Palas
#jira UE-48718
Regression issue appeared from fixing a crash when using console command "open"
Reworked by only refusing to open local URLs in case of client mode and multiprocess being active simultaneously.
Change 3604258 by Jamie.Dale
IME contexts can now flag themselves as dead to avoid latent IME callbacks trying to access a deleted widget
#jira UE-46815
#jira UE-47295
Change 3604312 by Matt.Kuhlenschmidt
PR #3931: Fixing a few obvious copy & paste errors. (Contributed by DaveC79)
Change 3604352 by Matt.Kuhlenschmidt
Fix crash accessing potentially invalid parent layout from a detail category
#jira UE-48729
Change 3604402 by Lauren.Ridge
Epic Friday - array drag and drop
Change 3605228 by Cody.Albert
TSets and TMaps should now properly rehash if a key is modified in the details panel.
Change 3605275 by Alexis.Matte
Merge actor do not keep the material slot name
#jira UE-43246
Change 3605715 by Max.Chen
Sequencer: Fix cinematic mode getting activated on BeginPlay() instead of OnStartedPlaying().
#jira UE-48770
Change 3606411 by Max.Chen
Sequencer: Fix a few player state issues. When paused, calling stop now tears down properly (spawnables are removed, etc). When a level sequence is deleted, tears down properly as well.
#jira UE-42008
Change 3606440 by Max.Chen
Sequencer: Update spawanble name when the spawnable actor name is changed.
#jira UE-47815
Change 3606899 by Lauren.Ridge
Disabling enum-based arrays from reordering
Change 3606958 by Lauren.Ridge
Visual polish on array handles
Change 3607733 by Max.Chen
Sequencer: Check null in camera cut
Change 3607849 by Max.Chen
Sequencer: Clip transport controls.
#jira UE-48812
Change 3608181 by Max.Chen
#jira UE-48813 Correctly set GPlayInEditorID when initializing the PIE gameinstance, which does the initial tick. This fixes autoplay sequences
Copy from Dev-Framework
Change 3608361 by christopher.biancard
QAGame: Submitting test content for Array Element Reorder testing
Change 3608512 by Alexis.Matte
Add fbx exporter option dialog, support export all and cancel all functionality when doing bulk export.
#jira UE-48058
Change 3608629 by Max.Chen
Camera Rig: Fix crane and rail not being packaged properly.
#jira UE-48829
Change 3609217 by Matt.Kuhlenschmidt
Added a lock around access to slate active timers to protect it against race conditions when accessed on the slate movie thread and the game thread
Change 3609722 by Alexis.Matte
Make sure a warning is log when we cannot export an animation sequence.
#jira UE-48390
Change 3609774 by Alexis.Matte
Fix the merge actor build LOD scale again, a previous merge erase the fix
#jira UE-48156
Change 3609891 by christopher.biancard
QAGame: Minor additions for test coverage on Array Element Reorder
Change 3610171 by Lauren.Ridge
Fixes for reordering metadata, creating actual swap function out of three element functions
#jira UE-48823
Change 3610407 by Lauren.Ridge
Fixing highlighting and behavior to place dragged row in the spot you release (not below)
Change 3610472 by Lauren.Ridge
Moving final location logic
Change 3610797 by Lauren.Ridge
Disabling dragging handles during PIE
Change 3611089 by Lauren.Ridge
Disabling handles when overall tree is disabled
Change 3612479 by Lauren.Ridge
Fix for asset contex menu warning
#jira UE-46667
Change 3612791 by Michael.Dupuis
#jira UE-48914 : Add the possibility to specify if we need CPU access to the instance buffer depending on the usage.
Grass should always have CPU access.
Change 3612802 by Michael.Dupuis
missing file from checkin 3612791
Change 3612805 by Max.Chen
Sequencer: Fix crash with null GEditor
Copy from Release-4.17
#jira UE-48443
Change 3612806 by Max.Chen
Sequencer: Fix crash when capturing a movie with options enabling separate process and close editor.
Copy from Release-4.17
#jira UE-48487
Change 3612807 by Max.Chen
Sequencer: Fix crash upgrading the time range of a null track.
Copy from Release-4.17
#jira UE-48490
Change 3612808 by Max.Chen
Sequencer: Fixed dragging skeletal animations causing them to revert back to t-pose
Copy from Release-4.17
#jira UE-48367
Change 3612849 by Arciel.Rekman
Fix tesselation in packaged Linux projects (UE-24301).
- Change by Cengiz.Terzibas.
#jira UE-24301
Change 3613022 by Nick.Darnell
Editor - Fixing a crash on load with a null CoordIndex json node.
Change 3613030 by Matt.Kuhlenschmidt
PR #3932: UE-48693: if instead of while statement (Contributed by projectgheist)
#jira UE-48747
Change 3613047 by Matt.Kuhlenschmidt
PR #3933: Git plugin: add "branch source" in history window (Contributed by SRombauts)
Change 3613050 by Matt.Kuhlenschmidt
PR #3942: Sort Data Table Structures Alphabetically (Contributed by Nick-Pearson)
Change 3613062 by Matt.Kuhlenschmidt
PR #3939: Fix a typo in RecordQualityLevelsAnalytics(). (Contributed by samhocevar)
Change 3613241 by Nick.Darnell
Editor - Fixing the content browser's view settings to be project agnostic, and they will start saving again.
Change 3613329 by Lauren.Ridge
Moving favorite levels to a standard submenu so they also work on Mac
Change 3613344 by Nick.Darnell
Editor - Fixing the achorgrid show up as white in HDPI mode, seems because we were upsampling the image, the blend was between dark and a transparent white, so that caused everything to turn white in HDPI mode.
#jira UE-48921
Change 3613380 by Matt.Kuhlenschmidt
Fix FBX window being off the screen in high DPI
#jira UE-48872
Change 3614598 by Matt.Kuhlenschmidt
Fixed Sequencer Keyframes appearing out of place on High DPI Monitors
#jira UE-48915
Change 3614625 by Matt.Kuhlenschmidt
Fixed not being able to click on BSP correctly in high dpi
#jira UE-48947
Change 3614672 by Matt.Kuhlenschmidt
Fix combo box windows being larger than necessary on high dpi monitors
#jira UE-48908
Change 3614699 by Matt.Kuhlenschmidt
Fix typo
#jira UE-48941
Change 3615011 by Matt.Kuhlenschmidt
Fix color picker calculation appearing offscreen for high dpi
Change 3615013 by Michael.Dupuis
#jira UE-48897: Properly rebuild the tree when reapplying instance to the component
Change 3615014 by Colin.Benoit
Sequencer Recorder test content
Change 3615048 by Colin.Benoit
Sequencer Recorder: more test content
Change 3615118 by Lauren.Ridge
Updating realtime state of viewports to also change when settings toggled
#jira UE-48884
Change 3615127 by Lauren.Ridge
Remove delegate binding on viewport destruction
Change 3615180 by Bradut.Palas
#jira UE-48167 profiler crash
Don't duplicate the graph data when rebuilding because that completely voids the OneToOneMapping mechanism, resulting in the crash. Looking up objects in the mapping would always return null because the mapping contains the old addresses, before the rebuild.
One option would have been to completely rebuild the mapping according to the duplicate graph, which would be dubious because the duplicate method isn't specifically designed so that the result would replace the source.
But it looks like duplicating the data is not needed, it's safe to rebuild in-place, RebuildForFilter() doesn't do anything illegal with the objects. This is also the only purpose and the only reference of the function.
Change 3615232 by Lauren.Ridge
Adding input handling to the material editor viewport client
#jira UE-48909
Change 3615703 by Jamie.Dale
Fixed crash when fixing up references after a package rename failed
#jira UE-48856
Change 3615752 by Matt.Kuhlenschmidt
More generic fix for color picker and other windows that use CalculatePopupWindowPostion not accounting for DPI scale
Change 3615907 by Jamie.Dale
Fixed some crashes caused by CL# 3600812
Change 3616031 by Matt.Kuhlenschmidt
Added guard against invalid blueprints (ones without a generated class) being trying to be opened in the property matrix and failing
#jira UE-48986
Change 3616151 by Arciel.Rekman
Fixing adding array elements in config.
- "+Blah=Foo" will do Blah.AddUnique(Foo)
- ".Blah=Foo" will do Blah.Add(Foo)
- See JoshA re: why (also see: https://udn.unrealengine.com/questions/388157/incorrect-behavior-in-configcacheinicpp.html?childToView=389307)
Change 3616439 by Andrew.Porter
QAGame: Updating level visibility content in sequencer smoke map
Change 3616441 by Matt.Kuhlenschmidt
Fix more sequencer track offsetting with DPI scale
#jira UE-48981
Change 3617263 by Max.Chen
Sequencer: Fix crash in level visibility teardown. Null playback context.
#jira UE-49012
Change 3617316 by Max.Chen
Sequencer: Fixed a regression where the frame rate isn't getting initialized for a movie scene.
Change 3617648 by Matt.Kuhlenschmidt
Adding some windows specific logging around setting or failing to set process dpi awareness
Change 3617665 by Matt.Kuhlenschmidt
Guard against layers module not being loaded in keybinding automation test
Change 3617731 by Arciel.Rekman
Fix crashes on AMD Mesa drivers (UE-48374).
- Do not expose unnecessary symbols from libelf.a to avoid symbol collision with system library used by drivers.
Change 3617923 by Bradut.Palas
#jira UE-47072
Editor was crashing because deleted actor was not cleaned properly from asset editors. Changed IAssetEditorInstance to offer a function for deleting an object from the editor.
Change 3618088 by Matt.Kuhlenschmidt
Guard against crash with potentially invalid worlds in preview scenes
#jira UE-48997
Change 3618373 by Matt.Kuhlenschmidt
Force worldsettings to be hidden in editor so that it is not considered for selection
#jira UE-48996
Change 3618464 by Max.Chen
Sequencer: Fix regression where spawnables don't play because they're defined as temporary editor actors.
#jira UE-48923
Change 3619789 by Matt.Kuhlenschmidt
Fix DPI scale warnings in any kind of headless editor mode
Change 3619802 by Jamie.Dale
Fixed deprecation warning in malloc profiler
Change 3619841 by Matt.Kuhlenschmidt
Fix missing icons in the package project menu
#jira UE-48674
Change 3619991 by Lauren.Ridge
Fix typo in transaction message
#jira UE-48993
Change 3620086 by Lauren.Ridge
Moving realtime viewport logic to refresh instead of construct so it is always triggered upon opening a new material editor
#jira UE-48884
Change 3620616 by Matt.Kuhlenschmidt
Fix up file
Change 3621002 by Matt.Kuhlenschmidt
Back out change to apply scaling rules in loading screens since blueprint based DPI scaling rule classes will not have been created yet
#jira UE-49125
Change 3621049 by Arciel.Rekman
Fix a build error.
- Also make sure that we don't print confusing message when no messagebox can be shown
(this code changed during the merge).
Change 3621064 by Arciel.Rekman
Deleted too much in the previous changelist.
Change 3621369 by Matt.Kuhlenschmidt
Fix keybindings automation test failing due to multiple entries in the active choords array pointing to the same thing
#jira UE-49131
[CL 3621569 by Matt Kuhlenschmidt in Main branch]
2017-08-31 21:51:42 -04:00
{
return false ;
}
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Write Guard ( Lock ) ;
// Try to add the collection
const bool bUseSCC = ShouldUseSCC ( ShareType ) ;
const FString CollectionFilename = GetCollectionFilename ( CollectionName , ShareType ) ;
// Validate collection name as file name
FText UnusedError ;
bool bFilenameValid = FFileHelper : : IsFilenameValidForSaving ( CollectionName . ToString ( ) , OutError ? * OutError : UnusedError ) ;
if ( ! bFilenameValid )
{
return false ;
}
TSharedRef < FCollection > NewCollection = MakeShareable ( new FCollection ( CollectionFilename , bUseSCC , StorageMode ) ) ;
if ( ! AddCollection ( Guard , NewCollection , ShareType ) )
{
// Failed to add the collection, it already exists
if ( OutError )
{
* OutError = LOCTEXT ( " Error_AlreadyExists " , " The collection already exists. " ) ;
}
return false ;
}
constexpr bool bForceCommitToRevisionControl = true ;
if ( ! InternalSaveCollection ( Guard , NewCollection , OutError , bForceCommitToRevisionControl ) )
{
// Collection failed to save, remove it from the cache
RemoveCollection ( Guard , NewCollection , ShareType ) ;
return false ;
}
2014-03-14 14:13:41 -04:00
2015-07-07 10:31:39 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreNewFile ( NewCollection - > GetSourceFilename ( ) ) ;
2024-04-19 18:17:59 -04:00
}
2015-07-07 10:31:39 -04:00
2024-04-19 18:17:59 -04:00
// Collection saved!
// Broadcast events outside of lock
CollectionCreatedEvent . Broadcast ( FCollectionNameType ( CollectionName , ShareType ) ) ;
return true ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : RenameCollection ( FName CurrentCollectionName , ECollectionShareType : : Type CurrentShareType , FName NewCollectionName , ECollectionShareType : : Type NewShareType , FText * OutError )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
if ( ! ensure ( CurrentShareType < ECollectionShareType : : CST_All ) | | ! ensure ( NewShareType < ECollectionShareType : : CST_All ) )
2014-03-14 14:13:41 -04:00
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2014-03-14 14:13:41 -04:00
return false ;
}
2015-06-19 07:33:02 -04:00
const FCollectionNameType OriginalCollectionKey ( CurrentCollectionName , CurrentShareType ) ;
const FCollectionNameType NewCollectionKey ( NewCollectionName , NewShareType ) ;
2024-04-17 02:10:31 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Write Guard ( Lock ) ;
2024-04-17 02:10:31 -04:00
2024-04-19 18:17:59 -04:00
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( OriginalCollectionKey ) ;
if ( ! CollectionRefPtr )
2024-04-16 12:54:49 -04:00
{
// The collection doesn't exist
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
2024-04-16 12:54:49 -04:00
return false ;
}
2024-04-19 18:17:59 -04:00
// Add the new collection
TSharedPtr < FCollection > NewCollection ;
2024-04-16 12:54:49 -04:00
{
2024-04-19 18:17:59 -04:00
const bool bUseSCC = ShouldUseSCC ( NewShareType ) ;
const FString NewCollectionFilename = GetCollectionFilename ( NewCollectionName , NewShareType ) ;
// Create an exact copy of the collection using its new path - this will preserve its GUID and avoid losing hierarchy data
NewCollection = ( * CollectionRefPtr ) - > Clone ( NewCollectionFilename , bUseSCC , ECollectionCloneMode : : Exact ) ;
if ( ! AddCollection ( Guard , NewCollection . ToSharedRef ( ) , NewShareType ) )
2024-04-16 12:54:49 -04:00
{
2024-04-19 18:17:59 -04:00
// Failed to add the collection, it already exists
if ( OutError )
{
* OutError = LOCTEXT ( " Error_AlreadyExists " , " The collection already exists. " ) ;
}
return false ;
2024-04-16 12:54:49 -04:00
}
2024-04-19 18:17:59 -04:00
bool bForceCommitToRevisionControl = true ;
if ( ! InternalSaveCollection ( Guard , NewCollection . ToSharedRef ( ) , OutError , bForceCommitToRevisionControl ) )
2024-04-16 12:54:49 -04:00
{
2024-04-19 18:17:59 -04:00
// Collection failed to save, remove it from the cache
RemoveCollection ( Guard , NewCollection . ToSharedRef ( ) , NewShareType ) ;
2024-04-16 12:54:49 -04:00
return false ;
}
}
2024-04-19 18:17:59 -04:00
// Remove the old collection
2024-04-16 12:54:49 -04:00
{
2024-04-19 18:17:59 -04:00
FText UnusedError ;
if ( ( * CollectionRefPtr ) - > DeleteSourceFile ( OutError ? * OutError : UnusedError ) )
{
CollectionFileCaches [ CurrentShareType ] - > IgnoreDeletedFile ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
RemoveCollection ( Guard , * CollectionRefPtr , CurrentShareType ) ;
}
else
{
// Failed to remove the old collection, so remove the collection we created.
NewCollection - > DeleteSourceFile ( OutError ? * OutError : UnusedError ) ;
RemoveCollection ( Guard , NewCollection . ToSharedRef ( ) , NewShareType ) ;
return false ;
}
2024-04-16 12:54:49 -04:00
}
2024-04-19 18:17:59 -04:00
CollectionFileCaches [ NewShareType ] - > IgnoreNewFile ( NewCollection - > GetSourceFilename ( ) ) ;
CollectionCache - > HandleCollectionChanged ( Guard ) ;
2024-04-17 02:10:31 -04:00
}
2024-04-16 12:54:49 -04:00
2024-04-19 18:17:59 -04:00
// Success, broadcast events outside of lock
CollectionRenamedEvent . Broadcast ( OriginalCollectionKey , NewCollectionKey ) ;
2024-04-16 12:54:49 -04:00
return true ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : ReparentCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , FName ParentCollectionName , ECollectionShareType : : Type ParentShareType , FText * OutError )
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) | | ( ! ParentCollectionName . IsNone ( ) & & ! ensure ( ParentShareType < ECollectionShareType : : CST_All ) ) )
2024-04-16 12:54:49 -04:00
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2024-04-16 12:54:49 -04:00
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2024-04-19 18:17:59 -04:00
TOptional < FCollectionNameType > OldParentCollectionKey ;
TOptional < FCollectionNameType > NewParentCollectionKey ;
2024-04-16 12:54:49 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Write Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : RecursionWorker ) ;
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
// The collection doesn't exist
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
}
const FGuid OldParentGuid = ( * CollectionRefPtr ) - > GetParentCollectionGuid ( ) ;
FGuid NewParentGuid ;
if ( ! ParentCollectionName . IsNone ( ) )
{
// Find and set the new parent GUID
NewParentCollectionKey = FCollectionNameType ( ParentCollectionName , ParentShareType ) ;
TSharedRef < FCollection > * const ParentCollectionRefPtr = AvailableCollections . Find ( NewParentCollectionKey . GetValue ( ) ) ;
if ( ! ParentCollectionRefPtr )
{
// The collection doesn't exist
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
}
// Does the parent collection need saving in order to have a stable GUID?
if ( ( * ParentCollectionRefPtr ) - > GetCollectionVersion ( ) < ECollectionVersion : : AddedCollectionGuid )
{
bool bForceCommitToRevisionControl = false ;
// Try and re-save the parent collection now
if ( InternalSaveCollection ( Guard , * ParentCollectionRefPtr , OutError , bForceCommitToRevisionControl ) )
{
CollectionFileCaches [ ParentShareType ] - > IgnoreFileModification ( ( * ParentCollectionRefPtr ) - > GetSourceFilename ( ) ) ;
}
else
{
return false ;
}
}
if ( ! IsValidParentCollection_Locked ( Guard , CollectionName , ShareType , ParentCollectionName , ParentShareType , OutError ) )
{
return false ;
}
NewParentGuid = ( * ParentCollectionRefPtr ) - > GetCollectionGuid ( ) ;
}
// Anything changed?
if ( OldParentGuid = = NewParentGuid )
{
return true ;
}
( * CollectionRefPtr ) - > SetParentCollectionGuid ( NewParentGuid ) ;
// Try and save with the new parent GUID
bool bForceCommitToRevisionControl = false ;
if ( InternalSaveCollection ( Guard , * CollectionRefPtr , OutError , bForceCommitToRevisionControl ) )
{
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
}
else
{
// Failed to save... rollback the collection to use its old parent GUID
( * CollectionRefPtr ) - > SetParentCollectionGuid ( OldParentGuid ) ;
return false ;
}
CollectionCache - > HandleCollectionChanged ( Guard ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Names ) ;
// Find the old parent so we can notify about the change
{
const TMap < FGuid , FCollectionNameType > & CachedCollectionNamesFromGuids = CollectionCache - > GetCachedCollectionNamesFromGuids ( Guard ) ;
const FCollectionNameType * const OldParentCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( OldParentGuid ) ;
if ( OldParentCollectionKeyPtr )
{
OldParentCollectionKey = * OldParentCollectionKeyPtr ;
}
}
2024-04-16 12:54:49 -04:00
}
2024-04-19 18:17:59 -04:00
// Success, broadcast event outside of lock
CollectionReparentedEvent . Broadcast ( CollectionKey , OldParentCollectionKey , NewParentCollectionKey ) ;
return true ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : DestroyCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , FText * OutError )
2024-04-16 12:54:49 -04:00
{
2024-04-19 18:17:59 -04:00
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
{
FCollectionLock_Write Guard ( Lock ) ;
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
// The collection doesn't exist
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
}
FText UnusedError ;
if ( ( * CollectionRefPtr ) - > DeleteSourceFile ( OutError ? * OutError : UnusedError ) )
{
CollectionFileCaches [ ShareType ] - > IgnoreDeletedFile ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
RemoveCollection ( Guard , * CollectionRefPtr , ShareType ) ;
}
else
{
// Failed to delete the source file
return false ;
}
}
// Broadcast event outside of lock
CollectionDestroyedEvent . Broadcast ( CollectionKey ) ;
return true ;
2024-04-16 12:54:49 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : AddToCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , const FSoftObjectPath & ObjectPath , FText * OutError )
{
return AddToCollection ( CollectionName , ShareType , MakeArrayView ( & ObjectPath , 1 ) ) ;
}
bool FCollectionManager : : AddToCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , TConstArrayView < FSoftObjectPath > ObjectPaths , int32 * OutNumAdded , FText * OutError )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
if ( OutNumAdded )
2014-03-14 14:13:41 -04:00
{
* OutNumAdded = 0 ;
}
2015-05-21 07:43:16 -04:00
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
2014-03-14 14:13:41 -04:00
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2014-03-14 14:13:41 -04:00
return false ;
}
2015-05-21 07:43:16 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2024-04-19 18:17:59 -04:00
{
FCollectionLock_Write Guard ( Lock ) ;
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
// Collection doesn't exist
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
if ( ( * CollectionRefPtr ) - > GetStorageMode ( ) ! = ECollectionStorageMode : : Static )
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
if ( OutError )
2024-04-16 12:54:49 -04:00
{
2024-04-19 18:17:59 -04:00
* OutError = LOCTEXT ( " Error_AddNeedsStaticCollection " , " Objects can only be added to static collections. " ) ;
2024-04-16 12:54:49 -04:00
}
2024-04-19 18:17:59 -04:00
return false ;
}
int32 NumAdded = 0 ;
for ( const FSoftObjectPath & ObjectPath : ObjectPaths )
{
if ( ( * CollectionRefPtr ) - > AddObjectToCollection ( ObjectPath ) )
2024-04-16 12:54:49 -04:00
{
2024-04-19 18:17:59 -04:00
NumAdded + + ;
}
}
if ( NumAdded > 0 )
{
constexpr bool bForceCommitToRevisionControl = false ;
if ( InternalSaveCollection ( Guard , * CollectionRefPtr , OutError , bForceCommitToRevisionControl ) )
{
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
// Added and saved
if ( OutNumAdded )
{
* OutNumAdded = NumAdded ;
}
CollectionCache - > HandleCollectionChanged ( Guard ) ;
// Fall out of scope to return
}
else
{
// Added but not saved, revert the add
for ( const FSoftObjectPath & ObjectPath : ObjectPaths )
{
( * CollectionRefPtr ) - > RemoveObjectFromCollection ( ObjectPath ) ;
}
return false ;
2022-09-16 20:57:34 -04:00
}
2014-03-14 14:13:41 -04:00
}
else
{
2024-04-19 18:17:59 -04:00
// Failed to add, all of the objects were already in the collection
if ( OutError )
2015-05-21 07:43:16 -04:00
{
2024-04-19 18:17:59 -04:00
* OutError = LOCTEXT ( " Error_AlreadyInCollection " , " All of the assets were already in the collection. " ) ;
2015-05-21 07:43:16 -04:00
}
2014-03-14 14:13:41 -04:00
return false ;
}
}
2024-04-19 18:17:59 -04:00
// Broadast event out of lock
AssetsAddedToCollectionDelegate . Broadcast ( CollectionKey , ObjectPaths ) ;
return true ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : RemoveFromCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , const FSoftObjectPath & ObjectPath , FText * OutError )
2014-03-14 14:13:41 -04:00
{
2024-04-19 18:17:59 -04:00
return RemoveFromCollection ( CollectionName , ShareType , MakeArrayView ( & ObjectPath , 1 ) , nullptr , OutError ) ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : RemoveFromCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , TConstArrayView < FSoftObjectPath > ObjectPaths , int32 * OutNumRemoved , FText * OutError )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
if ( OutNumRemoved )
2014-03-14 14:13:41 -04:00
{
* OutNumRemoved = 0 ;
}
2015-05-21 07:43:16 -04:00
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
2014-03-14 14:13:41 -04:00
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2014-03-14 14:13:41 -04:00
return false ;
}
2015-05-21 07:43:16 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2024-04-19 18:17:59 -04:00
{
FCollectionLock_Write Guard ( Lock ) ;
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
2024-04-16 12:54:49 -04:00
{
2024-04-19 18:17:59 -04:00
// Collection not found
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
}
if ( ( * CollectionRefPtr ) - > GetStorageMode ( ) ! = ECollectionStorageMode : : Static )
{
if ( OutError )
{
* OutError = LOCTEXT ( " Error_RemoveNeedsStaticCollection " , " Objects can only be removed from static collections. " ) ;
}
return false ;
}
TArray < FSoftObjectPath > RemovedAssets ;
for ( const FSoftObjectPath & ObjectPath : ObjectPaths )
{
if ( ( * CollectionRefPtr ) - > RemoveObjectFromCollection ( ObjectPath ) )
{
RemovedAssets . Add ( ObjectPath ) ;
}
}
if ( RemovedAssets . Num ( ) = = 0 )
{
// Failed to remove, none of the objects were in the collection
if ( OutError )
{
* OutError = LOCTEXT ( " Error_NotInCollection " , " None of the assets were in the collection. " ) ;
}
return false ;
}
constexpr bool bForceCommitToRevisionControl = false ;
if ( ! InternalSaveCollection ( Guard , * CollectionRefPtr , OutError , bForceCommitToRevisionControl ) )
{
// Removed but not saved, revert the remove
for ( const FSoftObjectPath & RemovedAssetName : RemovedAssets )
{
( * CollectionRefPtr ) - > AddObjectToCollection ( RemovedAssetName ) ;
}
return false ;
2015-05-21 07:43:16 -04:00
}
2015-07-07 10:31:39 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
2015-05-21 07:43:16 -04:00
// Removed and saved
if ( OutNumRemoved )
{
* OutNumRemoved = RemovedAssets . Num ( ) ;
}
2024-04-19 18:17:59 -04:00
CollectionCache - > HandleCollectionChanged ( Guard ) ;
2015-05-21 07:43:16 -04:00
}
2024-04-19 18:17:59 -04:00
// Broadcast event out of lock
AssetsRemovedFromCollectionDelegate . Broadcast ( CollectionKey , ObjectPaths ) ;
return true ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : SetDynamicQueryText ( FName CollectionName , ECollectionShareType : : Type ShareType , const FString & InQueryText , FText * OutError )
2015-07-09 09:59:51 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2015-07-09 09:59:51 -04:00
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2024-04-19 18:17:59 -04:00
{
FCollectionLock_Write Guard ( Lock ) ;
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
// Collection doesn't exist
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
}
2015-07-09 09:59:51 -04:00
2024-04-19 18:17:59 -04:00
if ( ( * CollectionRefPtr ) - > GetStorageMode ( ) ! = ECollectionStorageMode : : Dynamic )
{
if ( OutError )
{
* OutError = LOCTEXT ( " Error_SetNeedsDynamicCollection " , " Search queries can only be set on dynamic collections. " ) ;
}
return false ;
}
2024-04-17 02:10:31 -04:00
2024-04-19 18:17:59 -04:00
( * CollectionRefPtr ) - > SetDynamicQueryText ( InQueryText ) ;
constexpr bool bForceCommitToRevisionControl = true ;
if ( ! InternalSaveCollection ( Guard , * CollectionRefPtr , OutError , bForceCommitToRevisionControl ) )
{
return false ;
}
2024-04-17 02:10:31 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
2024-04-19 18:17:59 -04:00
CollectionCache - > HandleCollectionChanged ( Guard ) ;
2024-04-17 02:10:31 -04:00
}
2024-04-19 18:17:59 -04:00
// Broadcast event outside of lock
CollectionUpdatedEvent . Broadcast ( CollectionKey ) ;
return true ;
2024-04-17 02:10:31 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : GetDynamicQueryText ( FName CollectionName , ECollectionShareType : : Type ShareType , FString & OutQueryText , FText * OutError ) const
2024-04-17 02:10:31 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2024-04-17 02:10:31 -04:00
return false ;
}
2024-04-19 18:17:59 -04:00
FCollectionLock_Read Guard ( Lock ) ;
2024-04-17 02:10:31 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
// Collection doesn't exist
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
2024-04-17 02:10:31 -04:00
return false ;
}
if ( ( * CollectionRefPtr ) - > GetStorageMode ( ) ! = ECollectionStorageMode : : Dynamic )
{
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_GetNeedsDynamicCollection " , " Search queries can only be got from dynamic collections. " ) ;
}
2015-07-09 09:59:51 -04:00
return false ;
}
OutQueryText = ( * CollectionRefPtr ) - > GetDynamicQueryText ( ) ;
return true ;
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : TestDynamicQuery ( FName CollectionName , ECollectionShareType : : Type ShareType , const ITextFilterExpressionContext & InContext , bool & OutResult , FText * OutError ) const
2015-07-09 14:24:02 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2015-07-09 14:24:02 -04:00
return false ;
}
2024-04-19 18:17:59 -04:00
FCollectionLock_Read Guard ( Lock ) ;
2015-07-09 14:24:02 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
// Collection doesn't exist
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
2015-07-09 14:24:02 -04:00
return false ;
}
if ( ( * CollectionRefPtr ) - > GetStorageMode ( ) ! = ECollectionStorageMode : : Dynamic )
{
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_TestNeedsDynamicCollection " , " Search queries can only be tested on dynamic collections. " ) ;
}
2015-07-09 14:24:02 -04:00
return false ;
}
2024-04-19 18:17:59 -04:00
( * CollectionRefPtr ) - > PrepareDynamicQuery ( ) ;
2015-07-09 14:24:02 -04:00
OutResult = ( * CollectionRefPtr ) - > TestDynamicQuery ( InContext ) ;
return true ;
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : EmptyCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , FText * OutError )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
2014-03-14 14:13:41 -04:00
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2014-03-14 14:13:41 -04:00
return false ;
}
2015-07-09 14:24:02 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2024-04-19 18:17:59 -04:00
{
FCollectionLock_Write Guard ( Lock ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
// Collection doesn't exist
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
}
2015-07-09 14:24:02 -04:00
2024-04-19 18:17:59 -04:00
if ( ( * CollectionRefPtr ) - > IsEmpty ( ) )
{
// Already empty - nothing to do
return true ;
}
2015-07-09 14:24:02 -04:00
2024-04-19 18:17:59 -04:00
( * CollectionRefPtr ) - > Empty ( ) ;
constexpr bool bForceCommitToRevisionControl = true ;
if ( InternalSaveCollection ( Guard , * CollectionRefPtr , OutError , bForceCommitToRevisionControl ) )
{
return false ;
}
2015-07-09 14:24:02 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
2024-04-19 18:17:59 -04:00
CollectionCache - > HandleCollectionChanged ( Guard ) ;
2015-07-09 14:24:02 -04:00
}
2024-04-19 18:17:59 -04:00
// Broadcast event outside of lock
CollectionUpdatedEvent . Broadcast ( CollectionKey ) ;
return true ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : SaveCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , FText * OutError )
2015-07-03 13:54:34 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2015-07-03 13:54:34 -04:00
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2024-04-19 18:17:59 -04:00
{
FCollectionLock_Write Guard ( Lock ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
}
2015-07-03 13:54:34 -04:00
FCollectionStatusInfo StatusInfo = ( * CollectionRefPtr ) - > GetStatusInfo ( ) ;
const bool bNeedsSave = StatusInfo . bIsDirty | | ( StatusInfo . SCCState . IsValid ( ) & & StatusInfo . SCCState - > IsModified ( ) ) ;
if ( ! bNeedsSave )
{
// No changes - nothing to save
return true ;
}
2024-02-28 18:50:54 -05:00
constexpr bool bForceCommitToRevisionControl = true ;
2024-04-19 18:17:59 -04:00
if ( ! InternalSaveCollection ( Guard , * CollectionRefPtr , OutError , bForceCommitToRevisionControl ) )
2015-07-03 13:54:34 -04:00
{
2024-04-19 18:17:59 -04:00
return false ;
2015-07-03 13:54:34 -04:00
}
2024-04-17 02:10:31 -04:00
2024-04-19 18:17:59 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
CollectionCache - > HandleCollectionChanged ( Guard ) ;
}
// Broadcast event out of lock
CollectionUpdatedEvent . Broadcast ( CollectionKey ) ;
return true ;
2015-07-03 13:54:34 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : UpdateCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , FText * OutError )
2015-07-03 13:54:34 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2015-07-03 13:54:34 -04:00
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2024-04-19 18:17:59 -04:00
{
FCollectionLock_Write Guard ( Lock ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
2015-07-03 13:54:34 -04:00
{
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
2024-04-16 12:54:49 -04:00
}
2024-04-19 18:17:59 -04:00
FText UnusedError ;
if ( ! ( * CollectionRefPtr ) - > Update ( OutError ? * OutError : UnusedError ) )
{
return false ;
}
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
CollectionCache - > HandleCollectionChanged ( Guard ) ;
2015-07-09 09:59:51 -04:00
}
2015-07-03 13:54:34 -04:00
2024-04-19 18:17:59 -04:00
// Broadcast event outside of lock
CollectionUpdatedEvent . Broadcast ( CollectionKey ) ;
return true ;
2015-07-03 13:54:34 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : GetCollectionStatusInfo ( FName CollectionName , ECollectionShareType : : Type ShareType , FCollectionStatusInfo & OutStatusInfo , FText * OutError ) const
2014-03-14 14:13:41 -04:00
{
2022-10-13 11:24:42 -04:00
TRACE_CPUPROFILER_EVENT_SCOPE ( FCollectionManager : : GetCollectionStatusInfo ) ;
2015-05-21 07:43:16 -04:00
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
2014-03-14 14:13:41 -04:00
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2014-03-14 14:13:41 -04:00
return true ;
}
2024-04-19 18:17:59 -04:00
FCollectionLock_Read Guard ( Lock ) ;
2015-05-21 07:43:16 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2015-07-06 09:40:48 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
2015-05-21 07:43:16 -04:00
if ( CollectionRefPtr )
2014-03-14 14:13:41 -04:00
{
2015-07-03 13:54:34 -04:00
OutStatusInfo = ( * CollectionRefPtr ) - > GetStatusInfo ( ) ;
return true ;
2014-03-14 14:13:41 -04:00
}
2015-07-09 09:59:51 -04:00
else
{
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
2015-07-09 09:59:51 -04:00
}
2014-03-14 14:13:41 -04:00
2015-07-09 09:59:51 -04:00
return false ;
}
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
bool FCollectionManager : : HasCollectionColors ( TArray < FLinearColor > * OutColors ) const
{
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Colors ) ;
const TArray < FLinearColor > & CollectionColors = CollectionCache - > GetCachedColors ( Guard ) ;
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
if ( OutColors )
{
* OutColors = CollectionColors ;
}
return CollectionColors . Num ( ) > 0 ;
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : GetCollectionColor ( FName CollectionName , ECollectionShareType : : Type ShareType , TOptional < FLinearColor > & OutColor , FText * OutError ) const
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
return true ;
}
2024-04-19 18:17:59 -04:00
FCollectionLock_Read Guard ( Lock ) ;
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( CollectionRefPtr )
{
OutColor = ( * CollectionRefPtr ) - > GetCollectionColor ( ) ;
return true ;
}
else
{
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
}
return false ;
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : SetCollectionColor ( FName CollectionName , ECollectionShareType : : Type ShareType , const TOptional < FLinearColor > & NewColor , FText * OutError )
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
return true ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2024-04-19 18:17:59 -04:00
{
FCollectionLock_Write Guard ( Lock ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
}
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
( * CollectionRefPtr ) - > SetCollectionColor ( NewColor ) ;
2024-02-28 18:50:54 -05:00
constexpr bool bForceCommitToRevisionControl = false ;
2024-04-19 18:17:59 -04:00
if ( ! InternalSaveCollection ( Guard , * CollectionRefPtr , OutError , bForceCommitToRevisionControl ) )
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
{
2024-04-19 18:17:59 -04:00
return false ;
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
}
2024-04-19 18:17:59 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
CollectionCache - > HandleCollectionChanged ( Guard ) ;
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
}
2024-04-19 18:17:59 -04:00
// Broadcast event outside of lock
CollectionUpdatedEvent . Broadcast ( CollectionKey ) ;
return true ;
Collection UX improvements
Revamped collection UI:
- Uses a more modern design.
- Adds the asset count to the collection view.
- Adds the collections more prominently in asset tooltips.
Revamped sources panel UI:
- Added a unified search for all aspects of the sources panel (paths, favorites, and collections).
- Added a switcher for the paths and collections views, which auto-switches as you browse to paths or collections.
- Collections are now visible by default, rather than hidden behind a View Option.
Improved Content Browser auto-complete:
- Now lists collection and meta-data tag names, as well as the old class names.
- Tokenizes the search terms to allow auto-complete on partial statements.
- Note: Involves some breaking API changes to SAssetSearchBox to allow more complex filtering and auto-complete rules.
Added scripting API support:
- Collections can now be created, destroyed, and manipulated via Python or Editor Utilities (editor-only, see the AssetTagsSubsystem API).
- Collections can be queried both in-editor and at runtime (if cooked).
Added support for optionally "cooking" collections for use at runtime:
- This only works for static collections, and adds their information to the asset registry meta-data.
- See the AssetRegistry settings in BaseEngine.ini (bTagAllCollections, CollectionsToIncludeAsTags, and CollectionsToExcludeAsTags).
- No collections are cooked by default.
#rb Chris.Gagnon
[CL 8847950 by Jamie Dale in Dev-Editor branch]
2019-09-18 16:53:27 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : GetCollectionStorageMode ( FName CollectionName , ECollectionShareType : : Type ShareType , ECollectionStorageMode : : Type & OutStorageMode , FText * OutError ) const
2015-07-09 09:59:51 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2015-07-09 09:59:51 -04:00
return true ;
}
2024-04-19 18:17:59 -04:00
FCollectionLock_Read Guard ( Lock ) ;
2015-07-09 09:59:51 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( CollectionRefPtr )
{
OutStorageMode = ( * CollectionRefPtr ) - > GetStorageMode ( ) ;
return true ;
}
else
{
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
2015-07-09 09:59:51 -04:00
}
return false ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : IsObjectInCollection ( const FSoftObjectPath & ObjectPath , FName CollectionName , ECollectionShareType : : Type ShareType , ECollectionRecursionFlags : : Flags RecursionMode , FText * OutError ) const
2015-05-29 13:15:23 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2015-05-29 13:15:23 -04:00
return true ;
}
2024-04-19 18:17:59 -04:00
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : RecursionWorker ) ;
2015-06-19 07:33:02 -04:00
bool bFoundObject = false ;
2024-04-19 18:17:59 -04:00
auto IsObjectInCollectionWorker = [ AvailableCollections = & AvailableCollections , ObjectPath , & bFoundObject ] ( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > FCollectionManagerCache : : ERecursiveWorkerFlowControl
2015-05-29 13:15:23 -04:00
{
2024-04-19 18:17:59 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections - > Find ( InCollectionKey ) ;
2015-06-19 07:33:02 -04:00
if ( CollectionRefPtr )
{
bFoundObject = ( * CollectionRefPtr ) - > IsObjectInCollection ( ObjectPath ) ;
}
2015-07-06 09:40:48 -04:00
return ( bFoundObject ) ? FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Stop : FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Continue ;
2015-06-19 07:33:02 -04:00
} ;
2024-04-19 18:17:59 -04:00
CollectionCache - > RecursionHelper_DoWork ( Guard , FCollectionNameType ( CollectionName , ShareType ) , RecursionMode , IsObjectInCollectionWorker ) ;
2015-06-19 07:33:02 -04:00
return bFoundObject ;
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : IsValidParentCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , FName ParentCollectionName , ECollectionShareType : : Type ParentShareType , FText * OutError ) const
{
FCollectionLock_RW Guard ( Lock ) ;
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : RecursionWorker ) ;
return IsValidParentCollection_Locked ( Guard , CollectionName , ShareType , ParentCollectionName , ParentShareType , OutError ) ;
}
bool FCollectionManager : : IsValidParentCollection_Locked ( FCollectionLock & InGuard , FName CollectionName , ECollectionShareType : : Type ShareType , FName ParentCollectionName , ECollectionShareType : : Type ParentShareType , FText * OutError ) const
2015-06-19 07:33:02 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) | | ( ! ParentCollectionName . IsNone ( ) & & ! ensure ( ParentShareType < ECollectionShareType : : CST_All ) ) )
{
// Bad share type
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
}
2015-06-19 07:33:02 -04:00
return true ;
2015-05-29 13:15:23 -04:00
}
2015-06-19 07:33:02 -04:00
if ( ParentCollectionName . IsNone ( ) )
{
// Clearing the parent is always valid
return true ;
}
bool bValidParent = true ;
2024-04-19 18:17:59 -04:00
auto IsValidParentCollectionWorker = [ OutError , CollectionName , ShareType , & bValidParent , AvailableCollections = & AvailableCollections ]
( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > FCollectionManagerCache : : ERecursiveWorkerFlowControl
2015-06-19 07:33:02 -04:00
{
const bool bMatchesCollectionBeingReparented = ( CollectionName = = InCollectionKey . Name & & ShareType = = InCollectionKey . Type ) ;
if ( bMatchesCollectionBeingReparented )
{
bValidParent = false ;
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = ( InReason = = ECollectionRecursionFlags : : Self )
? LOCTEXT ( " InvalidParent_CannotParentToSelf " , " A collection cannot be parented to itself " )
: LOCTEXT ( " InvalidParent_CannotParentToChildren " , " A collection cannot be parented to its children " ) ;
}
2015-07-06 09:40:48 -04:00
return FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Stop ;
2015-06-19 07:33:02 -04:00
}
2015-07-01 12:12:44 -04:00
const bool bIsValidChildType = ECollectionShareType : : IsValidChildType ( InCollectionKey . Type , ShareType ) ;
if ( ! bIsValidChildType )
{
bValidParent = false ;
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = FText : : Format ( LOCTEXT ( " InvalidParent_InvalidChildType " , " A {0} collection cannot contain a {1} collection " ) , ECollectionShareType : : ToText ( InCollectionKey . Type ) , ECollectionShareType : : ToText ( ShareType ) ) ;
}
2015-07-06 09:40:48 -04:00
return FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Stop ;
2015-07-01 12:12:44 -04:00
}
2024-04-19 18:17:59 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections - > Find ( InCollectionKey ) ;
2015-07-09 09:59:51 -04:00
if ( CollectionRefPtr )
{
const ECollectionStorageMode : : Type StorageMode = ( * CollectionRefPtr ) - > GetStorageMode ( ) ;
if ( StorageMode = = ECollectionStorageMode : : Dynamic )
{
bValidParent = false ;
2024-04-19 18:17:59 -04:00
if ( OutError )
{
* OutError = LOCTEXT ( " InvalidParent_InvalidParentStorageType " , " A dynamic collection cannot contain child collections " ) ;
}
2015-07-09 09:59:51 -04:00
return FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Stop ;
}
}
2015-07-06 09:40:48 -04:00
return FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Continue ;
2015-06-19 07:33:02 -04:00
} ;
2024-04-19 18:17:59 -04:00
CollectionCache - > RecursionHelper_DoWork ( InGuard , FCollectionNameType ( ParentCollectionName , ParentShareType ) , ECollectionRecursionFlags : : SelfAndParents , IsValidParentCollectionWorker ) ;
2015-06-19 07:33:02 -04:00
return bValidParent ;
2015-05-29 13:15:23 -04:00
}
2015-06-26 13:13:02 -04:00
void FCollectionManager : : HandleFixupRedirectors ( ICollectionRedirectorFollower & InRedirectorFollower )
{
2021-11-30 14:20:47 -05:00
if ( bNoFixupRedirectors )
{
return ;
}
2024-04-17 02:10:31 -04:00
TArray < FCollectionNameType > UpdatedCollections ;
TArray < FSoftObjectPath > AddedObjects ;
TArray < FSoftObjectPath > RemovedObjects ;
2015-06-26 13:13:02 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Write Guard ( Lock ) ;
2024-04-17 02:10:31 -04:00
2024-04-19 18:17:59 -04:00
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Objects ) ;
2024-04-17 02:10:31 -04:00
2024-04-19 18:17:59 -04:00
const double LoadStartTime = FPlatformTime : : Seconds ( ) ;
2024-04-17 02:10:31 -04:00
2024-04-19 18:17:59 -04:00
TArray < TPair < FSoftObjectPath , FSoftObjectPath > > ObjectsToRename ;
// Build up the list of redirected object into rename pairs
2024-04-17 02:10:31 -04:00
{
2024-04-19 18:17:59 -04:00
const TMap < FSoftObjectPath , TArray < FObjectCollectionInfo > > & CachedObjects = CollectionCache - > GetCachedObjects ( Guard ) ;
for ( const TPair < FSoftObjectPath , TArray < FObjectCollectionInfo > > & CachedObjectInfo : CachedObjects )
2024-04-17 02:10:31 -04:00
{
2024-04-19 18:17:59 -04:00
FSoftObjectPath NewObjectPath ;
if ( InRedirectorFollower . FixupObject ( CachedObjectInfo . Key , NewObjectPath ) )
{
ObjectsToRename . Emplace ( CachedObjectInfo . Key , NewObjectPath ) ;
}
2024-04-17 02:10:31 -04:00
}
}
2024-04-19 18:17:59 -04:00
AddedObjects . Reserve ( ObjectsToRename . Num ( ) ) ;
RemovedObjects . Reserve ( ObjectsToRename . Num ( ) ) ;
// Handle the rename for each redirected object
for ( const TPair < FSoftObjectPath , FSoftObjectPath > & ObjectToRename : ObjectsToRename )
{
AddedObjects . Add ( ObjectToRename . Value ) ;
RemovedObjects . Add ( ObjectToRename . Key ) ;
ReplaceObjectInCollections ( Guard , ObjectToRename . Key , ObjectToRename . Value , UpdatedCollections ) ;
}
UE_LOG ( LogCollectionManager , Log , TEXT ( " Fixed up redirectors for %d collections in %0.6f seconds (updated %d objects) " ) , AvailableCollections . Num ( ) , FPlatformTime : : Seconds ( ) - LoadStartTime , ObjectsToRename . Num ( ) ) ;
for ( const TPair < FSoftObjectPath , FSoftObjectPath > & ObjectToRename : ObjectsToRename )
{
UE_LOG ( LogCollectionManager , Verbose , TEXT ( " \t Redirected '%s' to '%s' " ) , * ObjectToRename . Key . ToString ( ) , * ObjectToRename . Value . ToString ( ) ) ;
}
if ( UpdatedCollections . Num ( ) > 0 )
{
CollectionCache - > HandleCollectionChanged ( Guard ) ;
}
2024-04-17 02:10:31 -04:00
}
2024-04-19 18:17:59 -04:00
// Notify every collection that changed, outside of the lock
for ( const FCollectionNameType & UpdatedCollection : UpdatedCollections )
2024-04-17 02:10:31 -04:00
{
2024-04-19 18:17:59 -04:00
AssetsRemovedFromCollectionDelegate . Broadcast ( UpdatedCollection , RemovedObjects ) ;
AssetsAddedToCollectionDelegate . Broadcast ( UpdatedCollection , AddedObjects ) ;
2015-06-26 13:13:02 -04:00
}
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : HandleRedirectorsDeleted ( TConstArrayView < FSoftObjectPath > ObjectPaths , FText * OutError )
2015-06-26 13:13:02 -04:00
{
bool bSavedAllCollections = true ;
2015-07-03 13:54:34 -04:00
TArray < FCollectionNameType > UpdatedCollections ;
2024-04-19 18:17:59 -04:00
{
FCollectionLock_Write Guard ( Lock ) ;
TSet < FCollectionNameType > CollectionsToSave ;
FTextBuilder ErrorBuilder ;
2015-07-03 13:54:34 -04:00
2024-04-19 18:17:59 -04:00
for ( const FSoftObjectPath & ObjectPath : ObjectPaths )
2015-06-26 13:13:02 -04:00
{
2024-04-19 18:17:59 -04:00
// We don't have a cache for on-disk objects, so we have to do this the slower way and query each collection in turn
for ( const TPair < FCollectionNameType , TSharedRef < FCollection > > & AvailableCollection : AvailableCollections )
2024-01-26 11:33:21 -05:00
{
2024-04-19 18:17:59 -04:00
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
const TSharedRef < FCollection > & Collection = AvailableCollection . Value ;
if ( Collection - > IsRedirectorInCollection ( ObjectPath ) )
{
CollectionsToSave . Add ( CollectionKey ) ;
}
2024-01-26 11:33:21 -05:00
}
}
2024-04-19 18:17:59 -04:00
for ( const FCollectionNameType & CollectionKey : CollectionsToSave )
{
if ( TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) )
{
const TSharedRef < FCollection > & Collection = * CollectionRefPtr ;
FText SaveError ;
2024-09-12 13:16:46 -04:00
constexpr bool bForceCommitToRevisionControl = false ;
2024-04-19 18:17:59 -04:00
if ( InternalSaveCollection ( Guard , Collection , & SaveError , bForceCommitToRevisionControl ) )
{
CollectionFileCaches [ CollectionKey . Type ] - > IgnoreFileModification ( Collection - > GetSourceFilename ( ) ) ;
UpdatedCollections . Add ( CollectionKey ) ;
}
else
{
UE_LOG ( LogCollectionManager , Error , TEXT ( " Error saving collection on redirector deletion: %s " ) , * SaveError . ToString ( ) ) ;
ErrorBuilder . AppendLine ( SaveError ) ;
bSavedAllCollections = false ;
}
}
}
if ( OutError )
{
* OutError = ErrorBuilder . ToText ( ) ;
}
2024-01-26 11:33:21 -05:00
}
2024-04-19 18:17:59 -04:00
// Notify every collection that changed, outside of the lock
2015-07-03 13:54:34 -04:00
for ( const FCollectionNameType & UpdatedCollection : UpdatedCollections )
{
2024-01-26 11:33:21 -05:00
AssetsRemovedFromCollectionDelegate . Broadcast ( UpdatedCollection , ObjectPaths ) ;
2015-07-03 13:54:34 -04:00
}
2015-06-26 13:13:02 -04:00
return bSavedAllCollections ;
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : HandleRedirectorDeleted ( const FSoftObjectPath & ObjectPath , FText * Error )
2024-01-26 11:33:21 -05:00
{
2024-04-19 18:17:59 -04:00
return HandleRedirectorsDeleted ( MakeArrayView ( & ObjectPath , 1 ) , Error ) ;
2024-01-26 11:33:21 -05:00
}
2022-09-16 20:57:34 -04:00
void FCollectionManager : : HandleObjectRenamed ( const FSoftObjectPath & OldObjectPath , const FSoftObjectPath & NewObjectPath )
2015-06-26 13:13:02 -04:00
{
2024-04-19 18:17:59 -04:00
TArray < FCollectionNameType > UpdatedCollections ;
2022-09-16 20:57:34 -04:00
TArray < FSoftObjectPath > AddedObjects ;
TArray < FSoftObjectPath > RemovedObjects ;
2015-07-03 13:54:34 -04:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Write Guard ( Lock ) ;
2024-04-16 12:54:49 -04:00
2024-04-19 18:17:59 -04:00
ReplaceObjectInCollections ( Guard , OldObjectPath , NewObjectPath , UpdatedCollections ) ;
AddedObjects . Add ( NewObjectPath ) ;
RemovedObjects . Add ( OldObjectPath ) ;
if ( UpdatedCollections . Num ( ) > 0 )
2024-04-17 02:10:31 -04:00
{
2024-04-19 18:17:59 -04:00
CollectionCache - > HandleCollectionChanged ( Guard ) ;
2024-04-17 02:10:31 -04:00
}
2024-04-19 18:17:59 -04:00
}
// Notify every collection that changed, outside the lock
for ( const FCollectionNameType & UpdatedCollection : UpdatedCollections )
{
AssetsRemovedFromCollectionDelegate . Broadcast ( UpdatedCollection , RemovedObjects ) ;
AssetsAddedToCollectionDelegate . Broadcast ( UpdatedCollection , AddedObjects ) ;
2015-06-26 13:13:02 -04:00
}
}
2024-01-26 11:33:21 -05:00
void FCollectionManager : : HandleObjectsDeleted ( TConstArrayView < FSoftObjectPath > ObjectPaths )
2015-06-26 13:13:02 -04:00
{
2015-07-03 13:54:34 -04:00
TArray < FCollectionNameType > UpdatedCollections ;
2024-01-26 11:33:21 -05:00
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Write Guard ( Lock ) ;
2024-10-01 19:26:41 -04:00
if ( SuppressObjectDeletionRefCount . load ( ) > 0 )
{
DeferredDeletedObjects . Append ( ObjectPaths ) ;
return ;
}
2024-04-19 18:17:59 -04:00
CollectionCache - > UpdateCaches ( Guard , ECollectionCacheFlags : : Objects ) ;
for ( const FSoftObjectPath & ObjectPath : ObjectPaths )
{
RemoveObjectFromCollections ( Guard , ObjectPath , UpdatedCollections ) ;
}
if ( UpdatedCollections . Num ( ) > 0 )
{
CollectionCache - > HandleCollectionChanged ( Guard ) ;
}
2024-01-26 11:33:21 -05:00
}
2015-07-03 13:54:34 -04:00
2024-04-19 18:17:59 -04:00
// Notify every collection that changed, outside the lock
for ( const FCollectionNameType & UpdatedCollection : UpdatedCollections )
2015-06-26 13:13:02 -04:00
{
2024-04-19 18:17:59 -04:00
AssetsRemovedFromCollectionDelegate . Broadcast ( UpdatedCollection , ObjectPaths ) ;
2015-06-26 13:13:02 -04:00
}
}
2024-01-26 11:33:21 -05:00
void FCollectionManager : : HandleObjectDeleted ( const FSoftObjectPath & ObjectPath )
{
HandleObjectsDeleted ( MakeArrayView ( & ObjectPath , 1 ) ) ;
}
2024-10-01 19:26:41 -04:00
void FCollectionManager : : SuppressObjectDeletionHandling ( )
{
check ( IsInGameThread ( ) ) ;
SuppressObjectDeletionRefCount . fetch_add ( 1 ) ;
}
void FCollectionManager : : ResumeObjectDeletionHandling ( )
{
check ( IsInGameThread ( ) ) ;
int32 PrevRefCount = SuppressObjectDeletionRefCount . fetch_sub ( 1 ) ;
ensure ( PrevRefCount > = 1 ) ;
if ( PrevRefCount = = 1 )
{
if ( ! DeferredDeletedObjects . IsEmpty ( ) )
{
HandleObjectsDeleted ( DeferredDeletedObjects ) ;
DeferredDeletedObjects . Empty ( ) ;
}
}
}
2015-07-07 10:31:39 -04:00
bool FCollectionManager : : TickFileCache ( float InDeltaTime )
{
2018-05-23 21:04:31 -04:00
QUICK_SCOPE_CYCLE_COUNTER ( STAT_FCollectionManager_TickFileCache ) ;
2015-07-07 10:31:39 -04:00
enum class ECollectionFileAction : uint8
{
None ,
AddCollection ,
MergeCollection ,
RemoveCollection ,
} ;
2024-04-19 18:17:59 -04:00
// Cached events to fire when we release the lock
TArray < TTuple < ECollectionFileAction , FCollectionNameType > > Events ;
2015-07-07 10:31:39 -04:00
{
2024-04-19 18:17:59 -04:00
// Acquire write lock immediately so we don't need to deal with state change during promotion
FCollectionLock_Write Guard ( Lock ) ;
2015-07-07 10:31:39 -04:00
2024-04-19 18:17:59 -04:00
// Process changes that have happened outside of the collection manager
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
2015-07-07 10:31:39 -04:00
{
2024-04-19 18:17:59 -04:00
const ECollectionShareType : : Type ShareType = ECollectionShareType : : Type ( CacheIdx ) ;
TSharedPtr < DirectoryWatcher : : FFileCache > & FileCache = CollectionFileCaches [ CacheIdx ] ;
if ( ! FileCache . IsValid ( ) )
{
continue ;
}
2015-07-07 10:31:39 -04:00
FileCache - > Tick ( ) ;
2024-04-19 18:17:59 -04:00
const TArray < DirectoryWatcher : : FUpdateCacheTransaction > FileCacheChanges = FileCache - > GetOutstandingChanges ( ) ;
for ( const DirectoryWatcher : : FUpdateCacheTransaction & FileCacheChange : FileCacheChanges )
2015-07-07 10:31:39 -04:00
{
2015-07-21 12:47:33 -04:00
const FString CollectionFilename = FileCacheChange . Filename . Get ( ) ;
if ( FPaths : : GetExtension ( CollectionFilename ) ! = CollectionExtension )
{
continue ;
}
const FName CollectionName = * FPaths : : GetBaseFilename ( CollectionFilename ) ;
2015-07-07 10:31:39 -04:00
ECollectionFileAction CollectionFileAction = ECollectionFileAction : : None ;
switch ( FileCacheChange . Action )
{
case DirectoryWatcher : : EFileAction : : Added :
case DirectoryWatcher : : EFileAction : : Modified :
// File was added or modified, but does this collection already exist?
CollectionFileAction = ( AvailableCollections . Contains ( FCollectionNameType ( CollectionName , ShareType ) ) )
? ECollectionFileAction : : MergeCollection
: ECollectionFileAction : : AddCollection ;
break ;
case DirectoryWatcher : : EFileAction : : Removed :
// File was removed, but does this collection actually exist?
CollectionFileAction = ( AvailableCollections . Contains ( FCollectionNameType ( CollectionName , ShareType ) ) )
? ECollectionFileAction : : RemoveCollection
: ECollectionFileAction : : None ;
break ;
default :
break ;
}
switch ( CollectionFileAction )
{
case ECollectionFileAction : : AddCollection :
{
const bool bUseSCC = ShouldUseSCC ( ShareType ) ;
FText LoadErrorText ;
2015-07-09 09:59:51 -04:00
TSharedRef < FCollection > NewCollection = MakeShareable ( new FCollection ( GetCollectionFilename ( CollectionName , ShareType ) , bUseSCC , ECollectionStorageMode : : Static ) ) ;
2015-07-07 10:31:39 -04:00
if ( NewCollection - > Load ( LoadErrorText ) )
{
2024-04-19 18:17:59 -04:00
if ( AddCollection ( Guard , NewCollection , ShareType ) )
2015-07-07 10:31:39 -04:00
{
2024-04-19 18:17:59 -04:00
Events . Emplace ( CollectionFileAction , FCollectionNameType ( CollectionName , ShareType ) ) ;
2015-07-07 10:31:39 -04:00
}
}
else
{
UE_LOG ( LogCollectionManager , Warning , TEXT ( " %s " ) , * LoadErrorText . ToString ( ) ) ;
}
}
break ;
case ECollectionFileAction : : MergeCollection :
{
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( FCollectionNameType ( CollectionName , ShareType ) ) ;
check ( CollectionRefPtr ) ; // We tested AvailableCollections.Contains(...) above, so this shouldn't fail
FText LoadErrorText ;
2015-07-09 09:59:51 -04:00
FCollection TempCollection ( GetCollectionFilename ( CollectionName , ShareType ) , /*bUseSCC*/ false , ECollectionStorageMode : : Static ) ;
2015-07-07 10:31:39 -04:00
if ( TempCollection . Load ( LoadErrorText ) )
{
if ( ( * CollectionRefPtr ) - > Merge ( TempCollection ) )
{
2024-04-19 18:17:59 -04:00
Events . Emplace ( CollectionFileAction , FCollectionNameType ( CollectionName , ShareType ) ) ;
2015-07-07 10:31:39 -04:00
}
}
else
{
UE_LOG ( LogCollectionManager , Warning , TEXT ( " %s " ) , * LoadErrorText . ToString ( ) ) ;
}
}
break ;
case ECollectionFileAction : : RemoveCollection :
{
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( FCollectionNameType ( CollectionName , ShareType ) ) ;
check ( CollectionRefPtr ) ; // We tested AvailableCollections.Contains(...) above, so this shouldn't fail
2024-04-19 18:17:59 -04:00
RemoveCollection ( Guard , * CollectionRefPtr , ShareType ) ;
Events . Emplace ( CollectionFileAction , FCollectionNameType ( CollectionName , ShareType ) ) ;
2015-07-07 10:31:39 -04:00
}
break ;
default :
break ;
}
}
}
2024-04-19 18:17:59 -04:00
if ( Events . Num ( ) > 0 )
{
CollectionCache - > HandleCollectionChanged ( Guard ) ;
}
2015-07-07 10:31:39 -04:00
}
2024-04-19 18:17:59 -04:00
// Broadcast events outside the lock
for ( const TTuple < ECollectionFileAction , FCollectionNameType > & Event : Events )
2015-07-07 10:31:39 -04:00
{
2024-04-19 18:17:59 -04:00
switch ( Event . Key )
{
case ECollectionFileAction : : AddCollection :
CollectionCreatedEvent . Broadcast ( Event . Value ) ;
break ;
case ECollectionFileAction : : MergeCollection :
CollectionUpdatedEvent . Broadcast ( Event . Value ) ;
break ;
case ECollectionFileAction : : RemoveCollection :
CollectionDestroyedEvent . Broadcast ( Event . Value ) ;
break ;
}
2015-07-07 10:31:39 -04:00
}
return true ; // Tick again
}
2014-03-14 14:13:41 -04:00
void FCollectionManager : : LoadCollections ( )
{
2020-04-28 06:20:33 -04:00
TRACE_CPUPROFILER_EVENT_SCOPE ( FCollectionManager : : LoadCollections )
2014-03-14 14:13:41 -04:00
const double LoadStartTime = FPlatformTime : : Seconds ( ) ;
2015-07-06 09:40:48 -04:00
const int32 PrevNumCollections = AvailableCollections . Num ( ) ;
2022-02-09 21:53:31 -05:00
LLM_SCOPE_BYNAME ( TEXT ( " CollectionManager " ) ) ;
2014-03-14 14:13:41 -04:00
2024-04-19 18:17:59 -04:00
// This function should only be called during construction, don't acquire a lock here, acquire it for each individual add operation
2020-04-28 06:20:33 -04:00
ParallelFor (
2022-02-23 19:25:03 -05:00
TEXT ( " LoadCollections.PF " ) ,
ECollectionShareType : : CST_All , 1 ,
2024-04-19 18:17:59 -04:00
[ this ] ( int32 CacheIdx )
2014-03-14 14:13:41 -04:00
{
2020-04-28 06:20:33 -04:00
const ECollectionShareType : : Type ShareType = ECollectionShareType : : Type ( CacheIdx ) ;
2015-07-07 10:31:39 -04:00
const bool bUseSCC = ShouldUseSCC ( ShareType ) ;
2020-04-28 06:20:33 -04:00
const FString & CollectionFolder = CollectionFolders [ CacheIdx ] ;
2024-04-19 18:17:59 -04:00
const TStringBuilder < 256 > WildCard { InPlace , CollectionFolder , TEXTVIEW ( " /*. " ) , CollectionExtension } ;
2015-06-19 07:33:02 -04:00
2020-04-28 06:20:33 -04:00
TArray < FString > Filenames ;
IFileManager : : Get ( ) . FindFiles ( Filenames , * WildCard , true , false ) ;
ParallelFor (
2022-02-23 19:25:03 -05:00
TEXT ( " LoadCollections.PF " ) ,
Filenames . Num ( ) , 1 ,
2024-04-19 18:17:59 -04:00
[ this , & Filenames , & CollectionFolder , bUseSCC , ShareType ] ( int32 FilenameIdx )
2020-04-28 06:20:33 -04:00
{
const FString & BaseFilename = Filenames [ FilenameIdx ] ;
const FString Filename = CollectionFolder / BaseFilename ;
FText LoadErrorText ;
TSharedRef < FCollection > NewCollection = MakeShareable ( new FCollection ( Filename , bUseSCC , ECollectionStorageMode : : Static ) ) ;
if ( NewCollection - > Load ( LoadErrorText ) )
{
2024-04-19 18:17:59 -04:00
FCollectionLock_Write Guard ( Lock ) ;
AddCollection ( Guard , NewCollection , ShareType ) ;
2020-04-28 06:20:33 -04:00
}
else
{
UE_LOG ( LogCollectionManager , Warning , TEXT ( " %s " ) , * LoadErrorText . ToString ( ) ) ;
}
} ,
EParallelForFlags : : Unbalanced
) ;
} ,
EParallelForFlags : : Unbalanced
) ;
2014-03-14 14:13:41 -04:00
2015-07-06 09:40:48 -04:00
// AddCollection is assumed to be adding an empty collection, so also notify that collection cache that the collection has "changed" since loaded collections may not always be empty
2024-04-19 18:17:59 -04:00
FCollectionLock_Write Guard ( Lock ) ;
CollectionCache - > HandleCollectionChanged ( Guard ) ;
2015-05-29 13:15:23 -04:00
2015-07-06 09:40:48 -04:00
UE_LOG ( LogCollectionManager , Log , TEXT ( " Loaded %d collections in %0.6f seconds " ) , AvailableCollections . Num ( ) - PrevNumCollections , FPlatformTime : : Seconds ( ) - LoadStartTime ) ;
2014-03-14 14:13:41 -04:00
}
bool FCollectionManager : : ShouldUseSCC ( ECollectionShareType : : Type ShareType ) const
{
return ShareType ! = ECollectionShareType : : CST_Local & & ShareType ! = ECollectionShareType : : CST_System ;
}
2015-06-19 07:33:02 -04:00
FString FCollectionManager : : GetCollectionFilename ( const FName & InCollectionName , const ECollectionShareType : : Type InCollectionShareType ) const
{
FString CollectionFilename = CollectionFolders [ InCollectionShareType ] / InCollectionName . ToString ( ) + TEXT ( " . " ) + CollectionExtension ;
FPaths : : NormalizeFilename ( CollectionFilename ) ;
return CollectionFilename ;
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : AddCollection ( FCollectionLock_Write & Guard , const TSharedRef < FCollection > & CollectionRef , ECollectionShareType : : Type ShareType )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
2014-03-14 14:13:41 -04:00
{
// Bad share type
return false ;
}
2015-05-21 07:43:16 -04:00
const FCollectionNameType CollectionKey ( CollectionRef - > GetCollectionName ( ) , ShareType ) ;
2015-07-06 09:40:48 -04:00
if ( AvailableCollections . Contains ( CollectionKey ) )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
UE_LOG ( LogCollectionManager , Warning , TEXT ( " Failed to add collection '%s' because it already exists. " ) , * CollectionRef - > GetCollectionName ( ) . ToString ( ) ) ;
return false ;
2014-03-14 14:13:41 -04:00
}
2015-07-06 09:40:48 -04:00
AvailableCollections . Add ( CollectionKey , CollectionRef ) ;
2024-04-19 18:17:59 -04:00
CollectionCache - > HandleCollectionAdded ( Guard ) ;
2015-05-21 07:43:16 -04:00
return true ;
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : RemoveCollection ( FCollectionLock_Write & Guard , const TSharedRef < FCollection > & CollectionRef , ECollectionShareType : : Type ShareType )
2015-05-21 07:43:16 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
return false ;
}
const FCollectionNameType CollectionKey ( CollectionRef - > GetCollectionName ( ) , ShareType ) ;
2015-07-06 09:40:48 -04:00
if ( AvailableCollections . Remove ( CollectionKey ) > 0 )
{
2024-04-19 18:17:59 -04:00
CollectionCache - > HandleCollectionRemoved ( Guard ) ;
2015-07-06 09:40:48 -04:00
return true ;
}
return false ;
2014-03-14 14:13:41 -04:00
}
2024-04-19 18:17:59 -04:00
void FCollectionManager : : RemoveObjectFromCollections ( FCollectionLock_Write & Guard , const FSoftObjectPath & ObjectPath , TArray < FCollectionNameType > & OutUpdatedCollections )
2015-07-03 13:54:34 -04:00
{
2024-04-19 18:17:59 -04:00
const TMap < FSoftObjectPath , TArray < FObjectCollectionInfo > > & CachedObjects = CollectionCache - > GetCachedObjects ( Guard ) ;
2015-07-06 09:40:48 -04:00
2024-04-19 18:17:59 -04:00
const TArray < FObjectCollectionInfo > * ObjectCollectionInfosPtr = CachedObjects . Find ( ObjectPath ) ;
2015-07-06 09:40:48 -04:00
if ( ! ObjectCollectionInfosPtr )
2015-07-03 13:54:34 -04:00
{
return ;
}
// Remove this object reference from all collections that use it
2015-07-06 09:40:48 -04:00
for ( const FObjectCollectionInfo & ObjectCollectionInfo : * ObjectCollectionInfosPtr )
2015-07-03 13:54:34 -04:00
{
if ( ( ObjectCollectionInfo . Reason & ECollectionRecursionFlags : : Self ) ! = 0 )
{
// The object is contained directly within this collection (rather than coming from a parent or child collection), so remove the object reference
2015-07-06 09:40:48 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( ObjectCollectionInfo . CollectionKey ) ;
2015-07-03 13:54:34 -04:00
if ( CollectionRefPtr )
{
OutUpdatedCollections . AddUnique ( ObjectCollectionInfo . CollectionKey ) ;
( * CollectionRefPtr ) - > RemoveObjectFromCollection ( ObjectPath ) ;
}
}
}
}
2024-04-19 18:17:59 -04:00
void FCollectionManager : : ReplaceObjectInCollections ( FCollectionLock_Write & InGuard , const FSoftObjectPath & OldObjectPath , const FSoftObjectPath & NewObjectPath , TArray < FCollectionNameType > & OutUpdatedCollections )
2015-07-03 13:54:34 -04:00
{
2024-04-19 18:17:59 -04:00
CollectionCache - > UpdateCaches ( InGuard , ECollectionCacheFlags : : Objects ) ;
const TMap < FSoftObjectPath , TArray < FObjectCollectionInfo > > & CachedObjects = CollectionCache - > GetCachedObjects ( InGuard ) ;
2015-07-06 09:40:48 -04:00
2024-04-19 18:17:59 -04:00
const TArray < FObjectCollectionInfo > * OldObjectCollectionInfosPtr = CachedObjects . Find ( OldObjectPath ) ;
2015-07-06 09:40:48 -04:00
if ( ! OldObjectCollectionInfosPtr )
2015-07-03 13:54:34 -04:00
{
return ;
}
2015-07-06 09:40:48 -04:00
// Replace this object reference in all collections that use it
for ( const FObjectCollectionInfo & OldObjectCollectionInfo : * OldObjectCollectionInfosPtr )
2015-07-03 13:54:34 -04:00
{
if ( ( OldObjectCollectionInfo . Reason & ECollectionRecursionFlags : : Self ) ! = 0 )
{
// The old object is contained directly within this collection (rather than coming from a parent or child collection), so update the object reference
2015-07-06 09:40:48 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( OldObjectCollectionInfo . CollectionKey ) ;
2015-07-03 13:54:34 -04:00
if ( CollectionRefPtr )
{
OutUpdatedCollections . AddUnique ( OldObjectCollectionInfo . CollectionKey ) ;
( * CollectionRefPtr ) - > RemoveObjectFromCollection ( OldObjectPath ) ;
( * CollectionRefPtr ) - > AddObjectToCollection ( NewObjectPath ) ;
}
}
}
}
2024-04-19 18:17:59 -04:00
bool FCollectionManager : : InternalSaveCollection ( FCollectionLock_Write & InGuard , const TSharedRef < FCollection > & CollectionRef , FText * OutError , bool bForceCommitToRevisionControl )
2018-09-25 10:11:35 -04:00
{
TArray < FText > AdditionalChangelistText ;
2022-02-10 10:05:44 -05:00
2024-04-19 18:17:59 -04:00
// Give game specific editors a chance to add lines - do this under the lock because we don't expect re-entrancy
2018-09-25 10:11:35 -04:00
AddToCollectionCheckinDescriptionEvent . Broadcast ( CollectionRef - > GetCollectionName ( ) , AdditionalChangelistText ) ;
2022-02-10 10:05:44 -05:00
// Give settings a chance to add lines
TArray < FString > SettingsLines ;
const USourceControlPreferences * Settings = GetDefault < USourceControlPreferences > ( ) ;
if ( const FString * SpecificMatch = Settings - > SpecificCollectionChangelistTags . Find ( CollectionRef - > GetCollectionName ( ) ) )
{
// Parse input buffer into an array of lines
SpecificMatch - > ParseIntoArrayLines ( SettingsLines , /*bCullEmpty=*/ false ) ;
}
SettingsLines . Append ( Settings - > CollectionChangelistTags ) ;
for ( const FString & OneSettingLine : SettingsLines )
{
AdditionalChangelistText . Add ( FText : : FromString ( * OneSettingLine ) ) ;
}
// Save the collection
2024-04-19 18:17:59 -04:00
FText UnusedError ;
return CollectionRef - > Save ( AdditionalChangelistText , OutError ? * OutError : UnusedError , bForceCommitToRevisionControl ) ;
2018-09-25 10:11:35 -04:00
}
2014-03-14 14:13:41 -04:00
# undef LOCTEXT_NAMESPACE