2016-01-07 08:17:16 -05:00
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
# include "CollectionManagerPrivatePCH.h"
2015-07-07 10:31:39 -04:00
# include "FileCache.h"
# include "Ticker.h"
2014-03-14 14:13:41 -04:00
# define LOCTEXT_NAMESPACE "CollectionManager"
2015-07-06 09:40:48 -04:00
FCollectionManagerCache : : FCollectionManagerCache ( FAvailableCollectionsMap & InAvailableCollections )
: AvailableCollections ( InAvailableCollections )
{
bIsCachedCollectionNamesFromGuidsDirty = true ;
bIsCachedObjectsDirty = true ;
bIsCachedHierarchyDirty = true ;
}
void FCollectionManagerCache : : HandleCollectionAdded ( )
{
bIsCachedCollectionNamesFromGuidsDirty = true ;
}
void FCollectionManagerCache : : HandleCollectionRemoved ( )
{
bIsCachedCollectionNamesFromGuidsDirty = true ;
bIsCachedObjectsDirty = true ;
bIsCachedHierarchyDirty = true ;
}
void FCollectionManagerCache : : HandleCollectionChanged ( )
{
bIsCachedObjectsDirty = true ;
bIsCachedHierarchyDirty = true ;
}
const FGuidToCollectionNamesMap & FCollectionManagerCache : : GetCachedCollectionNamesFromGuids ( ) const
{
if ( bIsCachedCollectionNamesFromGuidsDirty )
{
CachedCollectionNamesFromGuids_Internal . Reset ( ) ;
bIsCachedCollectionNamesFromGuidsDirty = false ;
const double CacheStartTime = FPlatformTime : : Seconds ( ) ;
for ( const auto & AvailableCollection : AvailableCollections )
{
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
const TSharedRef < FCollection > & Collection = AvailableCollection . Value ;
CachedCollectionNamesFromGuids_Internal . Add ( Collection - > GetCollectionGuid ( ) , CollectionKey ) ;
}
UE_LOG ( LogCollectionManager , Log , TEXT ( " Rebuilt the GUID cache for %d collections in %0.6f seconds " ) , AvailableCollections . Num ( ) , FPlatformTime : : Seconds ( ) - CacheStartTime ) ;
}
return CachedCollectionNamesFromGuids_Internal ;
}
const FCollectionObjectsMap & FCollectionManagerCache : : GetCachedObjects ( ) const
{
if ( bIsCachedObjectsDirty )
{
CachedObjects_Internal . Reset ( ) ;
bIsCachedObjectsDirty = false ;
const double CacheStartTime = FPlatformTime : : Seconds ( ) ;
for ( const auto & AvailableCollection : AvailableCollections )
{
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
const TSharedRef < FCollection > & Collection = AvailableCollection . Value ;
TArray < FName > ObjectsInCollection ;
Collection - > GetObjectsInCollection ( ObjectsInCollection ) ;
if ( ObjectsInCollection . Num ( ) > 0 )
{
auto RebuildCachedObjectsWorker = [ & ] ( 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 FName & ObjectPath : ObjectsInCollection )
{
auto & ObjectCollectionInfos = CachedObjects_Internal . FindOrAdd ( ObjectPath ) ;
FObjectCollectionInfo * ObjectInfoPtr = ObjectCollectionInfos . FindByPredicate ( [ & ] ( const 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 ( CollectionKey , ECollectionRecursionFlags : : All , RebuildCachedObjectsWorker ) ;
}
}
UE_LOG ( LogCollectionManager , Log , TEXT ( " Rebuilt the object cache for %d collections in %0.6f seconds (found %d objects) " ) , AvailableCollections . Num ( ) , FPlatformTime : : Seconds ( ) - CacheStartTime , CachedObjects_Internal . Num ( ) ) ;
}
return CachedObjects_Internal ;
}
const FCollectionHierarchyMap & FCollectionManagerCache : : GetCachedHierarchy ( ) const
{
if ( bIsCachedHierarchyDirty )
{
CachedHierarchy_Internal . Reset ( ) ;
bIsCachedHierarchyDirty = false ;
const FGuidToCollectionNamesMap & CachedCollectionNamesFromGuids = GetCachedCollectionNamesFromGuids ( ) ;
const double CacheStartTime = FPlatformTime : : Seconds ( ) ;
for ( const auto & AvailableCollection : AvailableCollections )
{
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 ) )
{
auto & CollectionChildren = CachedHierarchy_Internal . FindOrAdd ( ParentCollectionGuid ) ;
CollectionChildren . AddUnique ( Collection - > GetCollectionGuid ( ) ) ;
}
}
UE_LOG ( LogCollectionManager , Log , TEXT ( " Rebuilt the hierarchy cache for %d collections in %0.6f seconds " ) , AvailableCollections . Num ( ) , FPlatformTime : : Seconds ( ) - CacheStartTime ) ;
}
return CachedHierarchy_Internal ;
}
2015-10-28 19:18:20 -04:00
void FCollectionManagerCache : : RecursionHelper_DoWork ( const FCollectionNameType & InCollectionKey , const ECollectionRecursionFlags : : Flags InRecursionMode , FRecursiveWorkerFunc InWorkerFunc ) const
2015-07-06 09:40:48 -04:00
{
if ( ( InRecursionMode & ECollectionRecursionFlags : : Self ) & & InWorkerFunc ( InCollectionKey , ECollectionRecursionFlags : : Self ) = = ERecursiveWorkerFlowControl : : Stop )
{
return ;
}
if ( ( InRecursionMode & ECollectionRecursionFlags : : Parents ) & & RecursionHelper_DoWorkOnParents ( InCollectionKey , InWorkerFunc ) = = ERecursiveWorkerFlowControl : : Stop )
{
return ;
}
if ( ( InRecursionMode & ECollectionRecursionFlags : : Children ) & & RecursionHelper_DoWorkOnChildren ( InCollectionKey , InWorkerFunc ) = = ERecursiveWorkerFlowControl : : Stop )
{
return ;
}
}
2015-10-28 19:18:20 -04:00
FCollectionManagerCache : : ERecursiveWorkerFlowControl FCollectionManagerCache : : RecursionHelper_DoWorkOnParents ( const FCollectionNameType & InCollectionKey , FRecursiveWorkerFunc InWorkerFunc ) const
2015-07-06 09:40:48 -04:00
{
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( InCollectionKey ) ;
if ( CollectionRefPtr )
{
const FGuidToCollectionNamesMap & CachedCollectionNamesFromGuids = GetCachedCollectionNamesFromGuids ( ) ;
const FCollectionNameType * const ParentCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( ( * CollectionRefPtr ) - > GetParentCollectionGuid ( ) ) ;
if ( ParentCollectionKeyPtr )
{
if ( InWorkerFunc ( * ParentCollectionKeyPtr , ECollectionRecursionFlags : : Parents ) = = ERecursiveWorkerFlowControl : : Stop | | RecursionHelper_DoWorkOnParents ( * ParentCollectionKeyPtr , InWorkerFunc ) = = ERecursiveWorkerFlowControl : : Stop )
{
return ERecursiveWorkerFlowControl : : Stop ;
}
}
}
return ERecursiveWorkerFlowControl : : Continue ;
}
2015-10-28 19:18:20 -04:00
FCollectionManagerCache : : ERecursiveWorkerFlowControl FCollectionManagerCache : : RecursionHelper_DoWorkOnChildren ( const FCollectionNameType & InCollectionKey , FRecursiveWorkerFunc InWorkerFunc ) const
2015-07-06 09:40:48 -04:00
{
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( InCollectionKey ) ;
if ( CollectionRefPtr )
{
const FCollectionHierarchyMap & CachedHierarchy = GetCachedHierarchy ( ) ;
const TArray < FGuid > * const ChildCollectionGuids = CachedHierarchy . Find ( ( * CollectionRefPtr ) - > GetCollectionGuid ( ) ) ;
if ( ChildCollectionGuids )
{
for ( const FGuid & ChildCollectionGuid : * ChildCollectionGuids )
{
const FGuidToCollectionNamesMap & CachedCollectionNamesFromGuids = GetCachedCollectionNamesFromGuids ( ) ;
const FCollectionNameType * const ChildCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( ChildCollectionGuid ) ;
if ( ChildCollectionKeyPtr )
{
if ( InWorkerFunc ( * ChildCollectionKeyPtr , ECollectionRecursionFlags : : Children ) = = ERecursiveWorkerFlowControl : : Stop | | RecursionHelper_DoWorkOnChildren ( * ChildCollectionKeyPtr , InWorkerFunc ) = = ERecursiveWorkerFlowControl : : Stop )
{
return ERecursiveWorkerFlowControl : : Stop ;
}
}
}
}
}
return ERecursiveWorkerFlowControl : : Continue ;
}
2014-03-14 14:13:41 -04:00
FCollectionManager : : FCollectionManager ( )
2015-07-06 09:40:48 -04:00
: CollectionCache ( AvailableCollections )
2014-03-14 14:13:41 -04:00
{
LastError = LOCTEXT ( " Error_Unknown " , " None " ) ;
CollectionFolders [ ECollectionShareType : : CST_Local ] = FPaths : : GameSavedDir ( ) / TEXT ( " Collections " ) ;
CollectionFolders [ ECollectionShareType : : CST_Private ] = FPaths : : GameUserDeveloperDir ( ) / TEXT ( " Collections " ) ;
CollectionFolders [ ECollectionShareType : : CST_Shared ] = FPaths : : GameContentDir ( ) / TEXT ( " Collections " ) ;
CollectionExtension = TEXT ( " collection " ) ;
LoadCollections ( ) ;
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 ) ) ;
}
TickFileCacheDelegateHandle = FTicker : : GetCoreTicker ( ) . AddTicker ( FTickerDelegate : : CreateRaw ( this , & FCollectionManager : : TickFileCache ) , 1.0f ) ;
2014-03-14 14:13:41 -04:00
}
FCollectionManager : : ~ FCollectionManager ( )
{
2015-07-07 10:31:39 -04:00
FTicker : : GetCoreTicker ( ) . RemoveTicker ( TickFileCacheDelegateHandle ) ;
2014-03-14 14:13:41 -04:00
}
2015-05-29 13:15:23 -04:00
bool FCollectionManager : : HasCollections ( ) const
{
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
{
2015-07-06 09:40:48 -04:00
OutCollections . Reserve ( AvailableCollections . Num ( ) ) ;
for ( const auto & 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 ) ;
}
}
2014-03-14 14:13:41 -04:00
void FCollectionManager : : GetCollectionNames ( ECollectionShareType : : Type ShareType , TArray < FName > & CollectionNames ) const
{
2015-07-06 09:40:48 -04:00
for ( const auto & 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
{
2015-07-06 09:40:48 -04:00
const FGuidToCollectionNamesMap & CachedCollectionNamesFromGuids = CollectionCache . GetCachedCollectionNamesFromGuids ( ) ;
OutCollections . Reserve ( AvailableCollections . Num ( ) ) ;
for ( const auto & 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
{
2015-07-06 09:40:48 -04:00
const FGuidToCollectionNamesMap & CachedCollectionNamesFromGuids = CollectionCache . GetCachedCollectionNamesFromGuids ( ) ;
for ( const auto & 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
{
2015-07-06 09:40:48 -04:00
const FGuidToCollectionNamesMap & CachedCollectionNamesFromGuids = CollectionCache . GetCachedCollectionNamesFromGuids ( ) ;
const FCollectionHierarchyMap & CachedHierarchy = CollectionCache . GetCachedHierarchy ( ) ;
auto GetChildCollectionsInternal = [ & ] ( const FCollectionNameType & InCollectionKey )
2015-06-19 07:33:02 -04:00
{
2015-07-06 09:40:48 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( InCollectionKey ) ;
2015-06-19 07:33:02 -04:00
if ( CollectionRefPtr )
{
const auto * ChildCollectionGuids = CachedHierarchy . Find ( ( * CollectionRefPtr ) - > GetCollectionGuid ( ) ) ;
if ( ChildCollectionGuids )
{
for ( const FGuid & ChildCollectionGuid : * ChildCollectionGuids )
{
const FCollectionNameType * const ChildCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( ChildCollectionGuid ) ;
if ( ChildCollectionKeyPtr )
{
OutCollections . Add ( * ChildCollectionKeyPtr ) ;
}
}
}
}
} ;
if ( ShareType = = ECollectionShareType : : CST_All )
{
// Asked for all share types, find children in the specified collection name in any cache
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
{
GetChildCollectionsInternal ( FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) ) ;
}
}
else
{
GetChildCollectionsInternal ( FCollectionNameType ( CollectionName , ShareType ) ) ;
}
}
void FCollectionManager : : GetChildCollectionNames ( FName CollectionName , ECollectionShareType : : Type ShareType , ECollectionShareType : : Type ChildShareType , TArray < FName > & CollectionNames ) const
{
2015-07-06 09:40:48 -04:00
const FGuidToCollectionNamesMap & CachedCollectionNamesFromGuids = CollectionCache . GetCachedCollectionNamesFromGuids ( ) ;
const FCollectionHierarchyMap & CachedHierarchy = CollectionCache . GetCachedHierarchy ( ) ;
auto GetChildCollectionsInternal = [ & ] ( const FCollectionNameType & InCollectionKey )
2015-06-19 07:33:02 -04:00
{
2015-07-06 09:40:48 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( InCollectionKey ) ;
2015-06-19 07:33:02 -04:00
if ( CollectionRefPtr )
{
const auto * ChildCollectionGuids = CachedHierarchy . Find ( ( * CollectionRefPtr ) - > GetCollectionGuid ( ) ) ;
if ( ChildCollectionGuids )
{
for ( const FGuid & ChildCollectionGuid : * ChildCollectionGuids )
{
const FCollectionNameType * const ChildCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( ChildCollectionGuid ) ;
if ( ChildCollectionKeyPtr & & ( ChildShareType = = ECollectionShareType : : CST_All | | ChildShareType = = ChildCollectionKeyPtr - > Type ) )
{
CollectionNames . AddUnique ( ChildCollectionKeyPtr - > Name ) ;
}
}
}
}
} ;
if ( ShareType = = ECollectionShareType : : CST_All )
{
// Asked for all share types, find children in the specified collection name in any cache
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
{
GetChildCollectionsInternal ( FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) ) ;
}
}
else
{
GetChildCollectionsInternal ( FCollectionNameType ( CollectionName , ShareType ) ) ;
}
}
2015-07-01 11:36:19 -04:00
TOptional < FCollectionNameType > FCollectionManager : : GetParentCollection ( FName CollectionName , ECollectionShareType : : Type ShareType ) const
{
2015-07-06 09:40:48 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( FCollectionNameType ( CollectionName , ShareType ) ) ;
2015-07-01 11:36:19 -04:00
if ( CollectionRefPtr )
{
2015-07-06 09:40:48 -04:00
const FGuidToCollectionNamesMap & CachedCollectionNamesFromGuids = CollectionCache . GetCachedCollectionNamesFromGuids ( ) ;
2015-07-01 11:36:19 -04:00
const FCollectionNameType * const ParentCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( ( * CollectionRefPtr ) - > GetParentCollectionGuid ( ) ) ;
if ( ParentCollectionKeyPtr )
{
return * ParentCollectionKeyPtr ;
}
}
return TOptional < FCollectionNameType > ( ) ;
}
2014-03-14 14:13:41 -04:00
bool FCollectionManager : : CollectionExists ( FName CollectionName , ECollectionShareType : : Type ShareType ) const
{
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
}
}
2015-06-19 07:33:02 -04:00
bool FCollectionManager : : GetAssetsInCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , TArray < FName > & AssetsPaths , ECollectionRecursionFlags : : Flags RecursionMode ) const
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
bool bFoundAssets = false ;
2015-07-06 09:40:48 -04:00
auto GetAssetsInCollectionWorker = [ & ] ( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > FCollectionManagerCache : : ERecursiveWorkerFlowControl
2015-05-21 07:43:16 -04:00
{
2015-07-06 09:40:48 -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 )
{
2015-07-06 09:40:48 -04:00
CollectionCache . RecursionHelper_DoWork ( FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) , RecursionMode , GetAssetsInCollectionWorker ) ;
2014-03-14 14:13:41 -04:00
}
}
else
{
2015-07-06 09:40:48 -04:00
CollectionCache . RecursionHelper_DoWork ( 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
}
2015-06-19 07:33:02 -04:00
bool FCollectionManager : : GetClassesInCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , TArray < FName > & ClassPaths , ECollectionRecursionFlags : : Flags RecursionMode ) const
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
bool bFoundClasses = false ;
2015-07-06 09:40:48 -04:00
auto GetClassesInCollectionWorker = [ & ] ( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > FCollectionManagerCache : : ERecursiveWorkerFlowControl
2014-03-14 14:13:41 -04:00
{
2015-07-06 09:40:48 -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 )
{
2015-07-06 09:40:48 -04:00
CollectionCache . RecursionHelper_DoWork ( FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) , RecursionMode , GetClassesInCollectionWorker ) ;
2014-03-14 14:13:41 -04:00
}
}
else
{
2015-07-06 09:40:48 -04:00
CollectionCache . RecursionHelper_DoWork ( 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
}
2015-06-19 07:33:02 -04:00
bool FCollectionManager : : GetObjectsInCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , TArray < FName > & ObjectPaths , ECollectionRecursionFlags : : Flags RecursionMode ) const
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
bool bFoundObjects = false ;
2015-07-06 09:40:48 -04:00
auto GetObjectsInCollectionWorker = [ & ] ( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > FCollectionManagerCache : : ERecursiveWorkerFlowControl
2014-03-14 14:13:41 -04:00
{
2015-07-06 09:40:48 -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 )
{
2015-07-06 09:40:48 -04:00
CollectionCache . RecursionHelper_DoWork ( FCollectionNameType ( CollectionName , ECollectionShareType : : Type ( CacheIdx ) ) , RecursionMode , GetObjectsInCollectionWorker ) ;
2014-03-14 14:13:41 -04:00
}
}
else
{
2015-07-06 09:40:48 -04:00
CollectionCache . RecursionHelper_DoWork ( 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
}
2015-06-19 07:33:02 -04:00
void FCollectionManager : : GetCollectionsContainingObject ( FName ObjectPath , ECollectionShareType : : Type ShareType , TArray < FName > & OutCollectionNames , ECollectionRecursionFlags : : Flags RecursionMode ) const
2014-03-14 14:13:41 -04:00
{
2015-07-06 09:40:48 -04:00
const FCollectionObjectsMap & CachedObjects = CollectionCache . GetCachedObjects ( ) ;
2015-06-19 07:33:02 -04:00
const auto * ObjectCollectionInfosPtr = CachedObjects . Find ( ObjectPath ) ;
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
}
}
}
}
2015-06-19 07:33:02 -04:00
void FCollectionManager : : GetCollectionsContainingObject ( FName ObjectPath , TArray < FCollectionNameType > & OutCollections , ECollectionRecursionFlags : : Flags RecursionMode ) const
2015-05-29 13:15:23 -04:00
{
2015-07-06 09:40:48 -04:00
const FCollectionObjectsMap & CachedObjects = CollectionCache . GetCachedObjects ( ) ;
2015-06-19 07:33:02 -04:00
const auto * ObjectCollectionInfosPtr = CachedObjects . Find ( ObjectPath ) ;
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
}
}
2015-06-19 07:33:02 -04:00
void FCollectionManager : : GetCollectionsContainingObjects ( const TArray < FName > & ObjectPaths , TMap < FCollectionNameType , TArray < FName > > & OutCollectionsAndMatchedObjects , ECollectionRecursionFlags : : Flags RecursionMode ) const
2015-05-29 13:15:23 -04:00
{
2015-07-06 09:40:48 -04:00
const FCollectionObjectsMap & CachedObjects = CollectionCache . GetCachedObjects ( ) ;
2015-05-29 13:15:23 -04:00
for ( const FName & ObjectPath : ObjectPaths )
{
2015-06-19 07:33:02 -04:00
const auto * ObjectCollectionInfosPtr = CachedObjects . Find ( ObjectPath ) ;
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 )
{
TArray < FName > & MatchedObjects = OutCollectionsAndMatchedObjects . FindOrAdd ( ObjectCollectionInfo . CollectionKey ) ;
MatchedObjects . Add ( ObjectPath ) ;
}
2015-05-29 13:15:23 -04:00
}
2014-03-14 14:13:41 -04:00
}
}
}
2015-06-19 07:33:02 -04:00
FString FCollectionManager : : GetCollectionsStringForObject ( FName ObjectPath , ECollectionShareType : : Type ShareType , ECollectionRecursionFlags : : Flags RecursionMode ) const
2015-05-21 09:23:51 -04:00
{
2015-07-06 09:40:48 -04:00
const FCollectionObjectsMap & CachedObjects = CollectionCache . GetCachedObjects ( ) ;
2015-06-19 07:33:02 -04:00
const auto * ObjectCollectionInfosPtr = CachedObjects . Find ( ObjectPath ) ;
if ( ObjectCollectionInfosPtr )
2015-05-29 13:15:23 -04:00
{
TArray < FString > CollectionNameStrings ;
2015-05-21 09:23:51 -04:00
2015-07-01 10:25:19 -04:00
TArray < FString > CollectionPathStrings ;
2015-07-06 09:40:48 -04:00
auto GetCollectionsStringForObjectWorker = [ & ] ( 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
{
2015-07-01 10:25:19 -04:00
CollectionPathStrings . Reset ( ) ;
2015-07-06 09:40:48 -04:00
CollectionCache . RecursionHelper_DoWork ( ObjectCollectionInfo . CollectionKey , ECollectionRecursionFlags : : SelfAndParents , GetCollectionsStringForObjectWorker ) ;
2015-07-01 10:25:19 -04:00
CollectionNameStrings . Add ( FString : : Join ( CollectionPathStrings , TEXT ( " / " ) ) ) ;
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
{
2015-05-21 07:43:16 -04:00
if ( ! ensure ( ShareType ! = ECollectionShareType : : CST_All ) )
2014-03-14 14:13:41 -04:00
{
return ;
}
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 ) ;
}
2015-07-06 09:40:48 -04:00
CollectionAlreadyExists = AvailableCollections . Contains ( FCollectionNameType ( 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
}
2015-07-02 12:20:22 -04:00
bool FCollectionManager : : IsValidCollectionName ( const FString & CollectionName , ECollectionShareType : : Type ShareType ) const
{
// Make sure we are not creating an FName that is too large
if ( CollectionName . Len ( ) > NAME_SIZE )
{
LastError = LOCTEXT ( " Error_CollectionNameTooLong " , " This collection name is too long. Please choose a shorter name. " ) ;
return false ;
}
const FName CollectionNameFinal = * CollectionName ;
// Make sure the we actually have a new name set
if ( CollectionNameFinal . IsNone ( ) )
{
LastError = LOCTEXT ( " Error_CollectionNameEmptyOrNone " , " This collection name cannot be empty or 'None'. " ) ;
return false ;
}
// Make sure the new name only contains valid characters
if ( ! CollectionNameFinal . IsValidXName ( INVALID_OBJECTNAME_CHARACTERS INVALID_LONGPACKAGE_CHARACTERS , & LastError ) )
{
return false ;
}
// Make sure we're not duplicating an existing collection name
if ( CollectionExists ( CollectionNameFinal , ShareType ) )
{
LastError = FText : : Format ( LOCTEXT ( " Error_CollectionAlreadyExists " , " A collection already exists with the name '{0}'. " ) , FText : : FromName ( CollectionNameFinal ) ) ;
return false ;
}
return true ;
}
2015-07-09 09:59:51 -04:00
bool FCollectionManager : : CreateCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , ECollectionStorageMode : : Type StorageMode )
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
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
// Try to add the collection
2015-06-19 07:33:02 -04:00
const bool bUseSCC = ShouldUseSCC ( ShareType ) ;
const FString CollectionFilename = GetCollectionFilename ( CollectionName , ShareType ) ;
2014-03-14 14:13:41 -04:00
2015-07-09 09:59:51 -04:00
TSharedRef < FCollection > NewCollection = MakeShareable ( new FCollection ( CollectionFilename , bUseSCC , StorageMode ) ) ;
2015-05-21 07:43:16 -04:00
if ( ! AddCollection ( NewCollection , ShareType ) )
2014-03-14 14:13:41 -04:00
{
// Failed to add the collection, it already exists
LastError = LOCTEXT ( " Error_AlreadyExists " , " The collection already exists. " ) ;
return false ;
}
2015-05-21 07:43:16 -04:00
if ( NewCollection - > Save ( LastError ) )
2014-03-14 14:13:41 -04:00
{
2015-07-07 10:31:39 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreNewFile ( NewCollection - > GetSourceFilename ( ) ) ;
2014-03-14 14:13:41 -04:00
// Collection saved!
2015-05-21 07:43:16 -04:00
CollectionCreatedEvent . Broadcast ( FCollectionNameType ( CollectionName , ShareType ) ) ;
2014-03-14 14:13:41 -04:00
return true ;
}
else
{
// Collection failed to save, remove it from the cache
2015-05-21 07:43:16 -04:00
RemoveCollection ( NewCollection , ShareType ) ;
2014-03-14 14:13:41 -04:00
return false ;
}
}
2015-05-21 07:43:16 -04:00
bool FCollectionManager : : RenameCollection ( FName CurrentCollectionName , ECollectionShareType : : Type CurrentShareType , FName NewCollectionName , ECollectionShareType : : Type NewShareType )
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
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
2015-06-19 07:33:02 -04:00
const FCollectionNameType OriginalCollectionKey ( CurrentCollectionName , CurrentShareType ) ;
const FCollectionNameType NewCollectionKey ( NewCollectionName , NewShareType ) ;
2015-07-06 09:40:48 -04:00
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( OriginalCollectionKey ) ;
2015-06-19 07:33:02 -04:00
if ( ! CollectionRefPtr )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
// The collection doesn't exist
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
2014-03-14 14:13:41 -04:00
return false ;
}
2015-06-19 07:33:02 -04:00
// Add the new collection
TSharedPtr < FCollection > NewCollection ;
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
const bool bUseSCC = ShouldUseSCC ( NewShareType ) ;
const FString NewCollectionFilename = GetCollectionFilename ( NewCollectionName , NewShareType ) ;
2014-03-14 14:13:41 -04:00
2015-06-19 07:33:02 -04:00
// 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 ( NewCollection . ToSharedRef ( ) , NewShareType ) )
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
// Failed to add the collection, it already exists
LastError = LOCTEXT ( " Error_AlreadyExists " , " The collection already exists. " ) ;
return false ;
}
if ( ! NewCollection - > Save ( LastError ) )
{
// Collection failed to save, remove it from the cache
RemoveCollection ( NewCollection . ToSharedRef ( ) , NewShareType ) ;
2014-03-14 14:13:41 -04:00
return false ;
}
}
2015-06-19 07:33:02 -04:00
// Remove the old collection
2014-03-14 14:13:41 -04:00
{
2015-06-19 07:33:02 -04:00
if ( ( * CollectionRefPtr ) - > DeleteSourceFile ( LastError ) )
{
2015-07-07 10:31:39 -04:00
CollectionFileCaches [ CurrentShareType ] - > IgnoreDeletedFile ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
2015-06-19 07:33:02 -04:00
RemoveCollection ( * CollectionRefPtr , CurrentShareType ) ;
}
else
{
// Failed to remove the old collection, so remove the collection we created.
NewCollection - > DeleteSourceFile ( LastError ) ;
RemoveCollection ( NewCollection . ToSharedRef ( ) , NewShareType ) ;
return false ;
}
2014-03-14 14:13:41 -04:00
}
2015-07-07 10:31:39 -04:00
CollectionFileCaches [ NewShareType ] - > IgnoreNewFile ( NewCollection - > GetSourceFilename ( ) ) ;
2015-07-06 09:40:48 -04:00
CollectionCache . HandleCollectionChanged ( ) ;
2015-05-29 13:15:23 -04:00
2014-03-14 14:13:41 -04:00
// Success
2015-05-21 07:43:16 -04:00
CollectionRenamedEvent . Broadcast ( OriginalCollectionKey , NewCollectionKey ) ;
2014-03-14 14:13:41 -04:00
return true ;
}
2015-06-19 07:33:02 -04:00
bool FCollectionManager : : ReparentCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , FName ParentCollectionName , ECollectionShareType : : Type ParentShareType )
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) | | ( ! ParentCollectionName . IsNone ( ) & & ! ensure ( ParentShareType < ECollectionShareType : : CST_All ) ) )
{
// Bad share type
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2015-07-06 09:40:48 -04:00
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
2015-06-19 07:33:02 -04:00
if ( ! CollectionRefPtr )
{
// The collection doesn't exist
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
return false ;
}
const FGuid OldParentGuid = ( * CollectionRefPtr ) - > GetParentCollectionGuid ( ) ;
FGuid NewParentGuid ;
TOptional < FCollectionNameType > OldParentCollectionKey ;
TOptional < FCollectionNameType > NewParentCollectionKey ;
if ( ! ParentCollectionName . IsNone ( ) )
{
// Find and set the new parent GUID
NewParentCollectionKey = FCollectionNameType ( ParentCollectionName , ParentShareType ) ;
2015-07-06 09:40:48 -04:00
TSharedRef < FCollection > * const ParentCollectionRefPtr = AvailableCollections . Find ( NewParentCollectionKey . GetValue ( ) ) ;
2015-06-19 07:33:02 -04:00
if ( ! ParentCollectionRefPtr )
{
// The collection doesn't exist
LastError = 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 )
{
// Try and re-save the parent collection now
2015-07-07 10:31:39 -04:00
if ( ( * ParentCollectionRefPtr ) - > Save ( LastError ) )
{
CollectionFileCaches [ ParentShareType ] - > IgnoreFileModification ( ( * ParentCollectionRefPtr ) - > GetSourceFilename ( ) ) ;
}
else
2015-06-19 07:33:02 -04:00
{
return false ;
}
}
if ( ! IsValidParentCollection ( CollectionName , ShareType , ParentCollectionName , ParentShareType ) )
{
// IsValidParentCollection fills in LastError itself
return false ;
}
NewParentGuid = ( * ParentCollectionRefPtr ) - > GetCollectionGuid ( ) ;
}
// Anything changed?
if ( OldParentGuid = = NewParentGuid )
{
return true ;
}
( * CollectionRefPtr ) - > SetParentCollectionGuid ( NewParentGuid ) ;
// Try and save with the new parent GUID
2015-07-07 10:31:39 -04:00
if ( ( * CollectionRefPtr ) - > Save ( LastError ) )
{
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
}
else
2015-06-19 07:33:02 -04:00
{
// Failed to save... rollback the collection to use its old parent GUID
( * CollectionRefPtr ) - > SetParentCollectionGuid ( OldParentGuid ) ;
return false ;
}
2015-07-06 09:40:48 -04:00
CollectionCache . HandleCollectionChanged ( ) ;
2015-06-19 07:33:02 -04:00
// Find the old parent so we can notify about the change
{
2015-07-06 09:40:48 -04:00
const FGuidToCollectionNamesMap & CachedCollectionNamesFromGuids = CollectionCache . GetCachedCollectionNamesFromGuids ( ) ;
2015-06-19 07:33:02 -04:00
const FCollectionNameType * const OldParentCollectionKeyPtr = CachedCollectionNamesFromGuids . Find ( OldParentGuid ) ;
if ( OldParentCollectionKeyPtr )
{
OldParentCollectionKey = * OldParentCollectionKeyPtr ;
}
}
// Success
CollectionReparentedEvent . Broadcast ( CollectionKey , OldParentCollectionKey , NewParentCollectionKey ) ;
return true ;
}
2014-03-14 14:13:41 -04:00
bool FCollectionManager : : DestroyCollection ( FName CollectionName , ECollectionShareType : : Type ShareType )
{
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
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
2015-05-21 07:43:16 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2015-07-06 09:40:48 -04:00
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
{
// The collection doesn't exist
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
return false ;
}
2015-05-21 07:43:16 -04:00
if ( ( * CollectionRefPtr ) - > DeleteSourceFile ( LastError ) )
{
2015-07-07 10:31:39 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreDeletedFile ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
2015-05-21 07:43:16 -04:00
RemoveCollection ( * CollectionRefPtr , ShareType ) ;
CollectionDestroyedEvent . Broadcast ( CollectionKey ) ;
return true ;
}
else
{
// Failed to delete the source file
return false ;
}
2014-03-14 14:13:41 -04:00
}
2015-05-21 07:43:16 -04:00
bool FCollectionManager : : AddToCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , FName ObjectPath )
2014-03-14 14:13:41 -04:00
{
TArray < FName > Paths ;
Paths . Add ( ObjectPath ) ;
return AddToCollection ( CollectionName , ShareType , Paths ) ;
}
bool FCollectionManager : : AddToCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , const TArray < FName > & ObjectPaths , int32 * OutNumAdded )
{
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
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
2015-05-21 07:43:16 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2015-07-06 09:40:48 -04:00
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
{
// Collection doesn't exist
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
return false ;
}
2015-07-09 09:59:51 -04:00
if ( ( * CollectionRefPtr ) - > GetStorageMode ( ) ! = ECollectionStorageMode : : Static )
{
LastError = LOCTEXT ( " Error_AddNeedsStaticCollection " , " Objects can only be added to static collections. " ) ;
return false ;
}
2015-05-21 07:43:16 -04:00
int32 NumAdded = 0 ;
for ( const FName & ObjectPath : ObjectPaths )
2014-03-14 14:13:41 -04:00
{
2015-06-26 13:13:02 -04:00
if ( ( * CollectionRefPtr ) - > AddObjectToCollection ( ObjectPath ) )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
NumAdded + + ;
2014-03-14 14:13:41 -04:00
}
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 ( NumAdded > 0 )
{
if ( ( * CollectionRefPtr ) - > Save ( LastError ) )
2014-03-14 14:13:41 -04:00
{
2015-07-07 10:31:39 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
2015-05-21 07:43:16 -04:00
// Added and saved
if ( OutNumAdded )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
* OutNumAdded = NumAdded ;
}
2014-03-14 14:13:41 -04:00
2015-07-06 09:40:48 -04:00
CollectionCache . HandleCollectionChanged ( ) ;
2015-05-21 07:43:16 -04:00
AssetsAddedEvent . Broadcast ( CollectionKey , ObjectPaths ) ;
return true ;
2014-03-14 14:13:41 -04:00
}
else
{
2015-05-21 07:43:16 -04:00
// Added but not saved, revert the add
for ( const FName & ObjectPath : ObjectPaths )
{
2015-06-26 13:13:02 -04:00
( * CollectionRefPtr ) - > RemoveObjectFromCollection ( ObjectPath ) ;
2015-05-21 07:43:16 -04:00
}
2014-03-14 14:13:41 -04:00
return false ;
}
}
else
{
2015-05-21 07:43:16 -04:00
// Failed to add, all of the objects were already in the collection
LastError = LOCTEXT ( " Error_AlreadyInCollection " , " All of the assets were already in the collection. " ) ;
2014-03-14 14:13:41 -04:00
return false ;
}
}
bool FCollectionManager : : RemoveFromCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , FName ObjectPath )
{
TArray < FName > Paths ;
Paths . Add ( ObjectPath ) ;
return RemoveFromCollection ( CollectionName , ShareType , Paths ) ;
}
bool FCollectionManager : : RemoveFromCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , const TArray < FName > & ObjectPaths , int32 * OutNumRemoved )
{
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
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
2015-05-21 07:43:16 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2015-07-06 09:40:48 -04:00
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
{
// Collection not found
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
return false ;
}
2015-05-21 07:43:16 -04:00
2015-07-09 09:59:51 -04:00
if ( ( * CollectionRefPtr ) - > GetStorageMode ( ) ! = ECollectionStorageMode : : Static )
{
LastError = LOCTEXT ( " Error_RemoveNeedsStaticCollection " , " Objects can only be removed from static collections. " ) ;
return false ;
}
2015-05-21 07:43:16 -04:00
TArray < FName > RemovedAssets ;
for ( const FName & ObjectPath : ObjectPaths )
{
2015-06-26 13:13:02 -04:00
if ( ( * CollectionRefPtr ) - > RemoveObjectFromCollection ( ObjectPath ) )
2015-05-21 07:43:16 -04:00
{
RemovedAssets . Add ( ObjectPath ) ;
}
}
if ( RemovedAssets . Num ( ) = = 0 )
{
// Failed to remove, none of the objects were in the collection
LastError = LOCTEXT ( " Error_NotInCollection " , " None of the assets were in the collection. " ) ;
return false ;
}
if ( ( * CollectionRefPtr ) - > Save ( LastError ) )
{
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 ( ) ;
}
2015-07-06 09:40:48 -04:00
CollectionCache . HandleCollectionChanged ( ) ;
2015-05-21 07:43:16 -04:00
AssetsRemovedEvent . Broadcast ( CollectionKey , ObjectPaths ) ;
return true ;
}
else
{
// Removed but not saved, revert the remove
for ( const FName & RemovedAssetName : RemovedAssets )
{
2015-06-26 13:13:02 -04:00
( * CollectionRefPtr ) - > AddObjectToCollection ( RemovedAssetName ) ;
2015-05-21 07:43:16 -04:00
}
return false ;
}
2014-03-14 14:13:41 -04:00
}
2015-07-09 09:59:51 -04:00
bool FCollectionManager : : SetDynamicQueryText ( FName CollectionName , ECollectionShareType : : Type ShareType , const FString & InQueryText )
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
// Collection doesn't exist
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
return false ;
}
if ( ( * CollectionRefPtr ) - > GetStorageMode ( ) ! = ECollectionStorageMode : : Dynamic )
{
LastError = LOCTEXT ( " Error_SetNeedsDynamicCollection " , " Search queries can only be set on dynamic collections. " ) ;
return false ;
}
( * CollectionRefPtr ) - > SetDynamicQueryText ( InQueryText ) ;
if ( ( * CollectionRefPtr ) - > Save ( LastError ) )
{
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
CollectionCache . HandleCollectionChanged ( ) ;
CollectionUpdatedEvent . Broadcast ( CollectionKey ) ;
return true ;
}
return false ;
}
bool FCollectionManager : : GetDynamicQueryText ( FName CollectionName , ECollectionShareType : : Type ShareType , FString & OutQueryText ) const
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
// Collection doesn't exist
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
return false ;
}
if ( ( * CollectionRefPtr ) - > GetStorageMode ( ) ! = ECollectionStorageMode : : Dynamic )
{
LastError = LOCTEXT ( " Error_GetNeedsDynamicCollection " , " Search queries can only be got from dynamic collections. " ) ;
return false ;
}
OutQueryText = ( * CollectionRefPtr ) - > GetDynamicQueryText ( ) ;
return true ;
}
2015-07-09 14:24:02 -04:00
bool FCollectionManager : : TestDynamicQuery ( FName CollectionName , ECollectionShareType : : Type ShareType , const ITextFilterExpressionContext & InContext , bool & OutResult ) const
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
{
// Collection doesn't exist
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
return false ;
}
if ( ( * CollectionRefPtr ) - > GetStorageMode ( ) ! = ECollectionStorageMode : : Dynamic )
{
LastError = LOCTEXT ( " Error_TestNeedsDynamicCollection " , " Search queries can only be tested on dynamic collections. " ) ;
return false ;
}
OutResult = ( * CollectionRefPtr ) - > TestDynamicQuery ( InContext ) ;
return true ;
}
2014-03-14 14:13:41 -04:00
bool FCollectionManager : : EmptyCollection ( FName CollectionName , ECollectionShareType : : Type ShareType )
{
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
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
2015-07-09 14:24:02 -04:00
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( ! CollectionRefPtr )
2014-03-14 14:13:41 -04:00
{
2015-07-09 14:24:02 -04:00
// Collection doesn't exist
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
2014-03-14 14:13:41 -04:00
return false ;
}
2015-07-09 14:24:02 -04:00
if ( ( * CollectionRefPtr ) - > IsEmpty ( ) )
2014-03-14 14:13:41 -04:00
{
2015-07-09 14:24:02 -04:00
// Already empty - nothing to do
2014-03-14 14:13:41 -04:00
return true ;
}
2015-07-09 14:24:02 -04:00
( * CollectionRefPtr ) - > Empty ( ) ;
2014-03-14 14:13:41 -04:00
2015-07-09 14:24:02 -04:00
if ( ( * CollectionRefPtr ) - > Save ( LastError ) )
{
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
CollectionCache . HandleCollectionChanged ( ) ;
CollectionUpdatedEvent . Broadcast ( CollectionKey ) ;
return true ;
}
return false ;
2014-03-14 14:13:41 -04:00
}
2015-07-03 13:54:34 -04:00
bool FCollectionManager : : SaveCollection ( FName CollectionName , ECollectionShareType : : Type ShareType )
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2015-07-06 09:40:48 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
2015-07-03 13:54:34 -04:00
if ( CollectionRefPtr )
{
FCollectionStatusInfo StatusInfo = ( * CollectionRefPtr ) - > GetStatusInfo ( ) ;
const bool bNeedsSave = StatusInfo . bIsDirty | | ( StatusInfo . SCCState . IsValid ( ) & & StatusInfo . SCCState - > IsModified ( ) ) ;
if ( ! bNeedsSave )
{
// No changes - nothing to save
return true ;
}
if ( ( * CollectionRefPtr ) - > Save ( LastError ) )
{
2015-07-07 10:31:39 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
2015-07-06 09:40:48 -04:00
CollectionCache . HandleCollectionChanged ( ) ;
2015-07-03 13:54:34 -04:00
CollectionUpdatedEvent . Broadcast ( CollectionKey ) ;
return true ;
}
}
2015-07-09 09:59:51 -04:00
else
{
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
2015-07-03 13:54:34 -04:00
return false ;
}
bool FCollectionManager : : UpdateCollection ( FName CollectionName , ECollectionShareType : : Type ShareType )
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return false ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
2015-07-06 09:40:48 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
2015-07-03 13:54:34 -04:00
if ( CollectionRefPtr )
{
if ( ( * CollectionRefPtr ) - > Update ( LastError ) )
{
2015-07-07 10:31:39 -04:00
CollectionFileCaches [ ShareType ] - > IgnoreFileModification ( ( * CollectionRefPtr ) - > GetSourceFilename ( ) ) ;
2015-07-06 09:40:48 -04:00
CollectionCache . HandleCollectionChanged ( ) ;
2015-07-03 13:54:34 -04:00
CollectionUpdatedEvent . Broadcast ( CollectionKey ) ;
return true ;
}
}
2015-07-09 09:59:51 -04:00
else
{
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
2015-07-03 13:54:34 -04:00
return false ;
}
bool FCollectionManager : : GetCollectionStatusInfo ( FName CollectionName , ECollectionShareType : : Type ShareType , FCollectionStatusInfo & OutStatusInfo ) const
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
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return true ;
}
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
{
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
2014-03-14 14:13:41 -04:00
2015-07-09 09:59:51 -04:00
return false ;
}
bool FCollectionManager : : GetCollectionStorageMode ( FName CollectionName , ECollectionShareType : : Type ShareType , ECollectionStorageMode : : Type & OutStorageMode ) const
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return true ;
}
const FCollectionNameType CollectionKey ( CollectionName , ShareType ) ;
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( CollectionKey ) ;
if ( CollectionRefPtr )
{
OutStorageMode = ( * CollectionRefPtr ) - > GetStorageMode ( ) ;
return true ;
}
else
{
LastError = LOCTEXT ( " Error_DoesntExist " , " The collection doesn't exist. " ) ;
}
return false ;
2014-03-14 14:13:41 -04:00
}
2015-06-19 07:33:02 -04:00
bool FCollectionManager : : IsObjectInCollection ( FName ObjectPath , FName CollectionName , ECollectionShareType : : Type ShareType , ECollectionRecursionFlags : : Flags RecursionMode ) const
2015-05-29 13:15:23 -04:00
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) )
{
// Bad share type
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
return true ;
}
2015-06-19 07:33:02 -04:00
bool bFoundObject = false ;
2015-07-06 09:40:48 -04:00
auto IsObjectInCollectionWorker = [ & ] ( const FCollectionNameType & InCollectionKey , ECollectionRecursionFlags : : Flag InReason ) - > FCollectionManagerCache : : ERecursiveWorkerFlowControl
2015-05-29 13:15:23 -04:00
{
2015-07-06 09:40:48 -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
} ;
2015-07-06 09:40:48 -04:00
CollectionCache . RecursionHelper_DoWork ( FCollectionNameType ( CollectionName , ShareType ) , RecursionMode , IsObjectInCollectionWorker ) ;
2015-06-19 07:33:02 -04:00
return bFoundObject ;
}
bool FCollectionManager : : IsValidParentCollection ( FName CollectionName , ECollectionShareType : : Type ShareType , FName ParentCollectionName , ECollectionShareType : : Type ParentShareType ) const
{
if ( ! ensure ( ShareType < ECollectionShareType : : CST_All ) | | ( ! ParentCollectionName . IsNone ( ) & & ! ensure ( ParentShareType < ECollectionShareType : : CST_All ) ) )
{
// Bad share type
LastError = LOCTEXT ( " Error_Internal " , " There was an internal error. " ) ;
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 ;
2015-07-06 09:40:48 -04:00
auto IsValidParentCollectionWorker = [ & ] ( 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 ;
LastError = ( 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 ;
LastError = 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
}
2015-07-09 09:59:51 -04:00
const TSharedRef < FCollection > * const CollectionRefPtr = AvailableCollections . Find ( InCollectionKey ) ;
if ( CollectionRefPtr )
{
const ECollectionStorageMode : : Type StorageMode = ( * CollectionRefPtr ) - > GetStorageMode ( ) ;
if ( StorageMode = = ECollectionStorageMode : : Dynamic )
{
bValidParent = false ;
LastError = LOCTEXT ( " InvalidParent_InvalidParentStorageType " , " A dynamic collection cannot contain child collections " ) ;
return FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Stop ;
}
}
2015-07-06 09:40:48 -04:00
return FCollectionManagerCache : : ERecursiveWorkerFlowControl : : Continue ;
2015-06-19 07:33:02 -04:00
} ;
2015-07-06 09:40:48 -04:00
CollectionCache . RecursionHelper_DoWork ( 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 )
{
const double LoadStartTime = FPlatformTime : : Seconds ( ) ;
TArray < TPair < FName , FName > > ObjectsToRename ;
// Build up the list of redirected object into rename pairs
{
2015-07-06 09:40:48 -04:00
const FCollectionObjectsMap & CachedObjects = CollectionCache . GetCachedObjects ( ) ;
for ( const auto & CachedObjectInfo : CachedObjects )
2015-06-26 13:13:02 -04:00
{
2015-07-06 09:40:48 -04:00
FName NewObjectPath ;
if ( InRedirectorFollower . FixupObject ( CachedObjectInfo . Key , NewObjectPath ) )
{
ObjectsToRename . Add ( TPairInitializer < FName , FName > ( CachedObjectInfo . Key , NewObjectPath ) ) ;
}
2015-06-26 13:13:02 -04:00
}
}
2015-07-03 13:54:34 -04:00
TArray < FCollectionNameType > UpdatedCollections ;
TArray < FName > AddedObjects ;
AddedObjects . Reserve ( ObjectsToRename . Num ( ) ) ;
TArray < FName > RemovedObjects ;
RemovedObjects . Reserve ( ObjectsToRename . Num ( ) ) ;
// Handle the rename for each redirected object
2015-06-26 13:13:02 -04:00
for ( const auto & ObjectToRename : ObjectsToRename )
{
2015-07-03 13:54:34 -04:00
AddedObjects . Add ( ObjectToRename . Value ) ;
RemovedObjects . Add ( ObjectToRename . Key ) ;
ReplaceObjectInCollections ( ObjectToRename . Key , ObjectToRename . Value , UpdatedCollections ) ;
}
2015-07-06 09:40:48 -04:00
if ( UpdatedCollections . Num ( ) > 0 )
2015-07-03 13:54:34 -04:00
{
2015-07-06 09:40:48 -04:00
CollectionCache . HandleCollectionChanged ( ) ;
// Notify every collection that changed
for ( const FCollectionNameType & UpdatedCollection : UpdatedCollections )
{
AssetsRemovedEvent . Broadcast ( UpdatedCollection , RemovedObjects ) ;
AssetsAddedEvent . Broadcast ( UpdatedCollection , AddedObjects ) ;
}
2015-06-26 13:13:02 -04:00
}
2015-07-06 09:40:48 -04:00
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 ( ) ) ;
2015-06-26 13:13:02 -04:00
for ( const auto & ObjectToRename : ObjectsToRename )
{
UE_LOG ( LogCollectionManager , Verbose , TEXT ( " \t Redirected '%s' to '%s' " ) , * ObjectToRename . Key . ToString ( ) , * ObjectToRename . Value . ToString ( ) ) ;
}
}
bool FCollectionManager : : HandleRedirectorDeleted ( const FName & ObjectPath )
{
bool bSavedAllCollections = true ;
FTextBuilder AllErrors ;
2015-07-03 13:54:34 -04:00
TArray < FCollectionNameType > UpdatedCollections ;
2015-06-26 13:13:02 -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
2015-07-06 09:40:48 -04:00
for ( const auto & AvailableCollection : AvailableCollections )
2015-06-26 13:13:02 -04:00
{
2015-07-06 09:40:48 -04:00
const FCollectionNameType & CollectionKey = AvailableCollection . Key ;
const TSharedRef < FCollection > & Collection = AvailableCollection . Value ;
2015-06-26 13:13:02 -04:00
if ( Collection - > IsRedirectorInCollection ( ObjectPath ) )
{
FText SaveError ;
2015-07-03 13:54:34 -04:00
if ( Collection - > Save ( SaveError ) )
{
2015-07-07 10:31:39 -04:00
CollectionFileCaches [ CollectionKey . Type ] - > IgnoreFileModification ( Collection - > GetSourceFilename ( ) ) ;
2015-07-03 13:54:34 -04:00
UpdatedCollections . Add ( CollectionKey ) ;
}
else
2015-06-26 13:13:02 -04:00
{
AllErrors . AppendLine ( SaveError ) ;
bSavedAllCollections = false ;
}
}
}
2015-07-03 13:54:34 -04:00
TArray < FName > RemovedObjects ;
RemovedObjects . Add ( ObjectPath ) ;
// Notify every collection that changed
for ( const FCollectionNameType & UpdatedCollection : UpdatedCollections )
{
AssetsRemovedEvent . Broadcast ( UpdatedCollection , RemovedObjects ) ;
}
2015-06-26 13:13:02 -04:00
if ( ! bSavedAllCollections )
{
LastError = AllErrors . ToText ( ) ;
}
return bSavedAllCollections ;
}
void FCollectionManager : : HandleObjectRenamed ( const FName & OldObjectPath , const FName & NewObjectPath )
{
2015-07-03 13:54:34 -04:00
TArray < FCollectionNameType > UpdatedCollections ;
ReplaceObjectInCollections ( OldObjectPath , NewObjectPath , UpdatedCollections ) ;
2015-06-26 13:13:02 -04:00
2015-07-03 13:54:34 -04:00
TArray < FName > AddedObjects ;
AddedObjects . Add ( NewObjectPath ) ;
2015-06-26 13:13:02 -04:00
2015-07-03 13:54:34 -04:00
TArray < FName > RemovedObjects ;
RemovedObjects . Add ( OldObjectPath ) ;
2015-07-06 09:40:48 -04:00
if ( UpdatedCollections . Num ( ) > 0 )
2015-07-03 13:54:34 -04:00
{
2015-07-06 09:40:48 -04:00
CollectionCache . HandleCollectionChanged ( ) ;
// Notify every collection that changed
for ( const FCollectionNameType & UpdatedCollection : UpdatedCollections )
{
AssetsRemovedEvent . Broadcast ( UpdatedCollection , RemovedObjects ) ;
AssetsAddedEvent . Broadcast ( UpdatedCollection , AddedObjects ) ;
}
2015-06-26 13:13:02 -04:00
}
}
void FCollectionManager : : HandleObjectDeleted ( const FName & ObjectPath )
{
2015-07-03 13:54:34 -04:00
TArray < FCollectionNameType > UpdatedCollections ;
RemoveObjectFromCollections ( ObjectPath , UpdatedCollections ) ;
2015-06-26 13:13:02 -04:00
2015-07-03 13:54:34 -04:00
TArray < FName > RemovedObjects ;
RemovedObjects . Add ( ObjectPath ) ;
2015-07-06 09:40:48 -04:00
if ( UpdatedCollections . Num ( ) > 0 )
2015-06-26 13:13:02 -04:00
{
2015-07-06 09:40:48 -04:00
CollectionCache . HandleCollectionChanged ( ) ;
// Notify every collection that changed
for ( const FCollectionNameType & UpdatedCollection : UpdatedCollections )
{
AssetsRemovedEvent . Broadcast ( UpdatedCollection , RemovedObjects ) ;
}
2015-06-26 13:13:02 -04:00
}
}
2015-07-07 10:31:39 -04:00
bool FCollectionManager : : TickFileCache ( float InDeltaTime )
{
enum class ECollectionFileAction : uint8
{
None ,
AddCollection ,
MergeCollection ,
RemoveCollection ,
} ;
bool bDidChangeCollection = false ;
// Process changes that have happened outside of the collection manager
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
{
const ECollectionShareType : : Type ShareType = ECollectionShareType : : Type ( CacheIdx ) ;
auto & FileCache = CollectionFileCaches [ CacheIdx ] ;
if ( FileCache . IsValid ( ) )
{
FileCache - > Tick ( ) ;
const auto FileCacheChanges = FileCache - > GetOutstandingChanges ( ) ;
for ( const auto & FileCacheChange : FileCacheChanges )
{
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 ) )
{
if ( AddCollection ( NewCollection , ShareType ) )
{
bDidChangeCollection = true ;
CollectionCreatedEvent . Broadcast ( FCollectionNameType ( CollectionName , ShareType ) ) ;
}
}
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 ) )
{
bDidChangeCollection = true ;
CollectionUpdatedEvent . Broadcast ( FCollectionNameType ( CollectionName , ShareType ) ) ;
}
}
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
RemoveCollection ( * CollectionRefPtr , ShareType ) ;
CollectionDestroyedEvent . Broadcast ( FCollectionNameType ( CollectionName , ShareType ) ) ;
}
break ;
default :
break ;
}
}
}
}
if ( bDidChangeCollection )
{
CollectionCache . HandleCollectionChanged ( ) ;
}
return true ; // Tick again
}
2014-03-14 14:13:41 -04:00
void FCollectionManager : : LoadCollections ( )
{
const double LoadStartTime = FPlatformTime : : Seconds ( ) ;
2015-07-06 09:40:48 -04:00
const int32 PrevNumCollections = AvailableCollections . Num ( ) ;
2014-03-14 14:13:41 -04:00
for ( int32 CacheIdx = 0 ; CacheIdx < ECollectionShareType : : CST_All ; + + CacheIdx )
{
2015-07-07 10:31:39 -04:00
const ECollectionShareType : : Type ShareType = ECollectionShareType : : Type ( CacheIdx ) ;
2014-03-14 14:13:41 -04:00
const FString & CollectionFolder = CollectionFolders [ CacheIdx ] ;
const FString WildCard = FString : : Printf ( TEXT ( " %s/*.%s " ) , * CollectionFolder , * CollectionExtension ) ;
TArray < FString > Filenames ;
IFileManager : : Get ( ) . FindFiles ( Filenames , * WildCard , true , false ) ;
2015-05-21 07:43:16 -04:00
for ( const FString & BaseFilename : Filenames )
2014-03-14 14:13:41 -04:00
{
2015-05-21 07:43:16 -04:00
const FString Filename = CollectionFolder / BaseFilename ;
2015-07-07 10:31:39 -04:00
const bool bUseSCC = ShouldUseSCC ( ShareType ) ;
2015-06-19 07:33:02 -04:00
FText LoadErrorText ;
2015-07-09 09:59:51 -04:00
TSharedRef < FCollection > NewCollection = MakeShareable ( new FCollection ( Filename , bUseSCC , ECollectionStorageMode : : Static ) ) ;
2015-06-19 07:33:02 -04:00
if ( NewCollection - > Load ( LoadErrorText ) )
2014-03-14 14:13:41 -04:00
{
2015-07-07 10:31:39 -04:00
AddCollection ( NewCollection , ShareType ) ;
2014-03-14 14:13:41 -04:00
}
else
{
2015-06-19 07:33:02 -04:00
UE_LOG ( LogCollectionManager , Warning , TEXT ( " %s " ) , * LoadErrorText . ToString ( ) ) ;
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
CollectionCache . HandleCollectionChanged ( ) ;
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 ;
}
2015-05-21 07:43:16 -04:00
bool FCollectionManager : : AddCollection ( 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 ) ;
CollectionCache . HandleCollectionAdded ( ) ;
2015-05-21 07:43:16 -04:00
return true ;
}
bool FCollectionManager : : RemoveCollection ( const TSharedRef < FCollection > & CollectionRef , ECollectionShareType : : Type ShareType )
{
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 )
{
CollectionCache . HandleCollectionRemoved ( ) ;
return true ;
}
return false ;
2014-03-14 14:13:41 -04:00
}
2015-07-03 13:54:34 -04:00
void FCollectionManager : : RemoveObjectFromCollections ( const FName & ObjectPath , TArray < FCollectionNameType > & OutUpdatedCollections )
{
2015-07-06 09:40:48 -04:00
const FCollectionObjectsMap & CachedObjects = CollectionCache . GetCachedObjects ( ) ;
const auto * ObjectCollectionInfosPtr = CachedObjects . Find ( ObjectPath ) ;
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 ) ;
}
}
}
}
void FCollectionManager : : ReplaceObjectInCollections ( const FName & OldObjectPath , const FName & NewObjectPath , TArray < FCollectionNameType > & OutUpdatedCollections )
{
2015-07-06 09:40:48 -04:00
const FCollectionObjectsMap & CachedObjects = CollectionCache . GetCachedObjects ( ) ;
const auto * OldObjectCollectionInfosPtr = CachedObjects . Find ( OldObjectPath ) ;
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 ) ;
}
}
}
}
2014-03-14 14:13:41 -04:00
# undef LOCTEXT_NAMESPACE