2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
# include "ProjectsPrivatePCH.h"
DEFINE_LOG_CATEGORY_STATIC ( LogPluginManager , Log , All ) ;
# define LOCTEXT_NAMESPACE "PluginManager"
namespace PluginSystemDefs
{
/** File extension of plugin descriptor files.
NOTE : This constant exists in UnrealBuildTool code as well . */
static const TCHAR PluginDescriptorFileExtension [ ] = TEXT ( " .uplugin " ) ;
}
2015-04-24 14:23:22 -04:00
FPlugin : : FPlugin ( const FString & InFileName , const FPluginDescriptor & InDescriptor , EPluginLoadedFrom InLoadedFrom )
2014-06-27 08:41:46 -04:00
: Name ( FPaths : : GetBaseFilename ( InFileName ) )
, FileName ( InFileName )
, Descriptor ( InDescriptor )
, LoadedFrom ( InLoadedFrom )
, bEnabled ( false )
{
}
2015-04-24 17:05:49 -04:00
FPlugin : : ~ FPlugin ( )
{
}
2015-04-24 14:23:22 -04:00
FString FPlugin : : GetName ( ) const
{
return Name ;
}
2014-06-27 08:41:46 -04:00
2015-04-26 09:18:08 -04:00
FString FPlugin : : GetDescriptorFileName ( ) const
{
return FileName ;
}
2015-04-24 14:23:22 -04:00
FString FPlugin : : GetBaseDir ( ) const
{
return FPaths : : GetPath ( FileName ) ;
}
FString FPlugin : : GetContentDir ( ) const
{
return FPaths : : GetPath ( FileName ) / TEXT ( " Content " ) ;
}
FString FPlugin : : GetMountedAssetPath ( ) const
{
return FString : : Printf ( TEXT ( " /%s/ " ) , * Name ) ;
}
bool FPlugin : : IsEnabled ( ) const
{
return bEnabled ;
}
bool FPlugin : : CanContainContent ( ) const
{
return Descriptor . bCanContainContent ;
}
2014-06-27 08:41:46 -04:00
2015-04-26 09:18:08 -04:00
EPluginLoadedFrom FPlugin : : GetLoadedFrom ( ) const
{
return LoadedFrom ;
}
const FPluginDescriptor & FPlugin : : GetDescriptor ( ) const
{
return Descriptor ;
}
bool FPlugin : : UpdateDescriptor ( const FPluginDescriptor & NewDescriptor , FText & OutFailReason )
{
if ( ! NewDescriptor . Save ( FileName , OutFailReason ) )
{
return false ;
}
Descriptor = NewDescriptor ;
return true ;
}
2014-06-27 08:41:46 -04:00
2014-03-14 14:13:41 -04:00
FPluginManager : : FPluginManager ( )
2014-07-10 14:20:43 -04:00
: bHaveConfiguredEnabledPlugins ( false )
2014-07-30 13:16:05 -04:00
, bHaveAllRequiredPlugins ( false )
2014-03-14 14:13:41 -04:00
{
DiscoverAllPlugins ( ) ;
}
FPluginManager : : ~ FPluginManager ( )
{
// NOTE: All plugins and modules should be cleaned up or abandoned by this point
// @todo plugin: Really, we should "reboot" module manager's unloading code so that it remembers at which startup phase
// modules were loaded in, so that we can shut groups of modules down (in reverse-load order) at the various counterpart
// shutdown phases. This will fix issues where modules that are loaded after game modules are shutdown AFTER many engine
// systems are already killed (like GConfig.) Currently the only workaround is to listen to global exit events, or to
// explicitly unload your module somewhere. We should be able to handle most cases automatically though!
}
2015-05-10 15:38:43 -04:00
void FPluginManager : : RefreshPluginsList ( )
{
// Read a new list of all plugins
TArray < TSharedRef < FPlugin > > NewPlugins ;
ReadAllPlugins ( NewPlugins ) ;
// Build a list of filenames for plugins which are enabled, and remove the rest
TArray < FString > EnabledPluginFileNames ;
for ( int32 Idx = 0 ; Idx < AllPlugins . Num ( ) ; Idx + + )
{
const TSharedRef < FPlugin > & Plugin = AllPlugins [ Idx ] ;
if ( Plugin - > bEnabled )
{
EnabledPluginFileNames . Add ( Plugin - > FileName ) ;
}
else
{
AllPlugins . RemoveAt ( Idx - - ) ;
}
}
// Add all the plugins which aren't already enabled
for ( TSharedRef < FPlugin > & NewPlugin : NewPlugins )
{
if ( ! EnabledPluginFileNames . Contains ( NewPlugin - > FileName ) )
{
AllPlugins . Add ( NewPlugin ) ;
}
}
}
2014-03-14 14:13:41 -04:00
void FPluginManager : : DiscoverAllPlugins ( )
{
2015-05-10 15:38:43 -04:00
ensure ( AllPlugins . Num ( ) = = 0 ) ; // Should not have already been initialized!
ReadAllPlugins ( AllPlugins ) ;
}
2014-03-14 14:13:41 -04:00
2015-05-10 15:38:43 -04:00
void FPluginManager : : ReadAllPlugins ( TArray < TSharedRef < FPlugin > > & Plugins )
{
# if (WITH_ENGINE && !IS_PROGRAM) || WITH_PLUGIN_SUPPORT
// Find "built-in" plugins. That is, plugins situated right within the Engine directory.
ReadPluginsInDirectory ( FPaths : : EnginePluginsDir ( ) , EPluginLoadedFrom : : Engine , Plugins ) ;
// Find plugins in the game project directory (<MyGameProject>/Plugins)
if ( FApp : : HasGameName ( ) )
{
ReadPluginsInDirectory ( FPaths : : GamePluginsDir ( ) , EPluginLoadedFrom : : GameProject , Plugins ) ;
}
# endif
}
void FPluginManager : : ReadPluginsInDirectory ( const FString & PluginsDirectory , const EPluginLoadedFrom LoadedFrom , TArray < TSharedRef < FPlugin > > & Plugins )
{
// Make sure the directory even exists
if ( FPlatformFileManager : : Get ( ) . GetPlatformFile ( ) . DirectoryExists ( * PluginsDirectory ) )
{
TArray < FString > FileNames ;
FindPluginsInDirectory ( PluginsDirectory , FileNames ) ;
for ( const FString & FileName : FileNames )
2014-03-14 14:13:41 -04:00
{
2015-05-10 15:38:43 -04:00
FPluginDescriptor Descriptor ;
FText FailureReason ;
if ( Descriptor . Load ( FileName , FailureReason ) )
2014-03-14 14:13:41 -04:00
{
2015-05-10 15:38:43 -04:00
Plugins . Add ( MakeShareable ( new FPlugin ( FileName , Descriptor , LoadedFrom ) ) ) ;
2014-03-14 14:13:41 -04:00
}
2015-05-10 15:38:43 -04:00
else
2014-03-14 14:13:41 -04:00
{
2015-05-10 15:38:43 -04:00
// NOTE: Even though loading of this plugin failed, we'll keep processing other plugins
2015-07-20 06:52:56 -04:00
FString FullPath = FPaths : : ConvertRelativePathToFull ( FileName ) ;
FText FailureMessage = FText : : Format ( LOCTEXT ( " FailureFormat " , " {0} ({1}) " ) , FailureReason , FText : : FromString ( FullPath ) ) ;
FText DialogTitle = LOCTEXT ( " PluginFailureTitle " , " Failed to load Plugin " ) ;
UE_LOG ( LogPluginManager , Error , TEXT ( " %s " ) , * FailureMessage . ToString ( ) ) ;
FMessageDialog : : Open ( EAppMsgType : : Ok , FailureMessage , & DialogTitle ) ;
2014-03-14 14:13:41 -04:00
}
}
2015-05-10 15:38:43 -04:00
}
}
2014-03-14 14:13:41 -04:00
2015-05-10 15:38:43 -04:00
void FPluginManager : : FindPluginsInDirectory ( const FString & PluginsDirectory , TArray < FString > & FileNames )
{
// Class to enumerate the contents of a directory, and find all sub-directories and plugin descriptors within it
struct FPluginDirectoryVisitor : public IPlatformFile : : FDirectoryVisitor
{
TArray < FString > SubDirectories ;
TArray < FString > PluginDescriptors ;
2014-03-14 14:13:41 -04:00
2015-05-10 15:38:43 -04:00
virtual bool Visit ( const TCHAR * FilenameOrDirectory , bool bIsDirectory ) override
2014-03-14 14:13:41 -04:00
{
2015-05-10 15:38:43 -04:00
FString FilenameOrDirectoryStr = FilenameOrDirectory ;
if ( bIsDirectory )
2014-03-14 14:13:41 -04:00
{
2015-05-10 15:38:43 -04:00
SubDirectories . Add ( FilenameOrDirectoryStr ) ;
2014-03-14 14:13:41 -04:00
}
2015-05-10 15:38:43 -04:00
else if ( FilenameOrDirectoryStr . EndsWith ( TEXT ( " .uplugin " ) ) )
{
PluginDescriptors . Add ( FilenameOrDirectoryStr ) ;
}
return true ;
2014-03-14 14:13:41 -04:00
}
} ;
2015-05-10 15:38:43 -04:00
// Enumerate the contents of the current directory
FPluginDirectoryVisitor Visitor ;
FPlatformFileManager : : Get ( ) . GetPlatformFile ( ) . IterateDirectory ( * PluginsDirectory , Visitor ) ;
2014-03-14 14:13:41 -04:00
2015-05-10 15:38:43 -04:00
// If there's no plugins in this directory, recurse through all the child directories
if ( Visitor . PluginDescriptors . Num ( ) = = 0 )
2014-03-14 14:13:41 -04:00
{
2015-05-10 15:38:43 -04:00
for ( const FString & SubDirectory : Visitor . SubDirectories )
2014-03-14 14:13:41 -04:00
{
2015-05-10 15:38:43 -04:00
FindPluginsInDirectory ( SubDirectory , FileNames ) ;
2014-03-14 14:13:41 -04:00
}
2015-05-10 15:38:43 -04:00
}
else
{
for ( const FString & PluginDescriptor : Visitor . PluginDescriptors )
2014-03-14 14:13:41 -04:00
{
2015-05-10 15:38:43 -04:00
FileNames . Add ( PluginDescriptor ) ;
2014-03-14 14:13:41 -04:00
}
}
}
2014-11-10 15:59:44 -05:00
// Helper class to find all pak files.
class FPakFileSearchVisitor : public IPlatformFile : : FDirectoryVisitor
{
TArray < FString > & FoundFiles ;
public :
FPakFileSearchVisitor ( TArray < FString > & InFoundFiles )
: FoundFiles ( InFoundFiles )
{ }
virtual bool Visit ( const TCHAR * FilenameOrDirectory , bool bIsDirectory )
{
if ( bIsDirectory = = false )
{
FString Filename ( FilenameOrDirectory ) ;
if ( Filename . MatchesWildcard ( TEXT ( " *.pak " ) ) )
{
FoundFiles . Add ( Filename ) ;
}
}
return true ;
}
} ;
2014-07-30 13:16:05 -04:00
bool FPluginManager : : ConfigureEnabledPlugins ( )
2014-03-14 14:13:41 -04:00
{
2014-07-10 14:20:43 -04:00
if ( ! bHaveConfiguredEnabledPlugins )
2014-03-14 14:13:41 -04:00
{
2014-07-30 13:16:05 -04:00
// Don't need to run this again
bHaveConfiguredEnabledPlugins = true ;
// If a current project is set, check that we know about any plugin that's explicitly enabled
const FProjectDescriptor * Project = IProjectManager : : Get ( ) . GetCurrentProject ( ) ;
if ( Project ! = nullptr )
{
2015-06-29 05:14:20 -04:00
// Take a copy of the Project's plugins as we may remove some
TArray < FPluginReferenceDescriptor > PluginsCopy = Project - > Plugins ;
for ( const FPluginReferenceDescriptor & Plugin : PluginsCopy )
2014-07-30 13:16:05 -04:00
{
if ( Plugin . bEnabled & & ! FindPluginInstance ( Plugin . Name ) . IsValid ( ) )
{
FText Caption ( LOCTEXT ( " PluginMissingCaption " , " Plugin missing " ) ) ;
2015-05-08 18:24:48 -04:00
if ( Plugin . MarketplaceURL . Len ( ) > 0 )
{
if ( FMessageDialog : : Open ( EAppMsgType : : YesNo , FText : : Format ( LOCTEXT ( " PluginMissingError " , " This project requires the {0} plugin. \n \n Would you like to download it from the the Marketplace? " ) , FText : : FromString ( Plugin . Name ) ) , & Caption ) = = EAppReturnType : : Yes )
{
FString Error ;
FPlatformProcess : : LaunchURL ( * Plugin . MarketplaceURL , nullptr , & Error ) ;
if ( Error . Len ( ) > 0 ) FMessageDialog : : Open ( EAppMsgType : : Ok , FText : : FromString ( Error ) ) ;
2015-05-27 12:56:05 -04:00
return false ;
2015-05-08 18:24:48 -04:00
}
}
else
{
2015-06-16 10:27:07 -04:00
FString Description = ( Plugin . Description . Len ( ) > 0 ) ? FString : : Printf ( TEXT ( " \n \n %s " ) , * Plugin . Description ) : FString ( ) ;
2015-05-08 18:24:48 -04:00
FMessageDialog : : Open ( EAppMsgType : : Ok , FText : : Format ( LOCTEXT ( " PluginMissingError " , " This project requires the {0} plugin. {1} " ) , FText : : FromString ( Plugin . Name ) , FText : : FromString ( Description ) ) , & Caption ) ;
2015-06-16 10:27:07 -04:00
if ( FMessageDialog : : Open ( EAppMsgType : : YesNo , FText : : Format ( LOCTEXT ( " PluginMissingDisable " , " Would you like to disable {0}? You will no longer be able to open any assets created using it. " ) , FText : : FromString ( Plugin . Name ) ) , & Caption ) = = EAppReturnType : : No )
{
return false ;
}
2015-05-27 12:56:05 -04:00
2015-06-29 05:14:20 -04:00
FText FailReason ;
if ( ! IProjectManager : : Get ( ) . SetPluginEnabled ( * Plugin . Name , false , FailReason ) )
{
FMessageDialog : : Open ( EAppMsgType : : Ok , FailReason ) ;
}
}
}
2014-07-30 13:16:05 -04:00
}
}
// If we made it here, we have all the required plugins
bHaveAllRequiredPlugins = true ;
// Get all the enabled plugin names
2014-07-10 14:20:43 -04:00
TArray < FString > EnabledPluginNames ;
# if IS_PROGRAM
GConfig - > GetArray ( TEXT ( " Plugins " ) , TEXT ( " ProgramEnabledPlugins " ) , EnabledPluginNames , GEngineIni ) ;
# else
FProjectManager : : Get ( ) . GetEnabledPlugins ( EnabledPluginNames ) ;
# endif
2014-03-14 14:13:41 -04:00
2014-07-10 14:20:43 -04:00
// Build a set from the array
TSet < FString > AllEnabledPlugins ;
AllEnabledPlugins . Append ( MoveTemp ( EnabledPluginNames ) ) ;
2014-07-02 13:18:43 -04:00
2014-07-10 14:20:43 -04:00
// Enable all the plugins by name
2015-04-24 14:23:22 -04:00
for ( const TSharedRef < FPlugin > Plugin : AllPlugins )
2014-07-02 13:18:43 -04:00
{
2014-07-10 14:20:43 -04:00
if ( AllEnabledPlugins . Contains ( Plugin - > Name ) )
{
Plugin - > bEnabled = true ;
}
2014-03-14 14:13:41 -04:00
}
2014-07-10 14:20:43 -04:00
2015-04-24 14:23:22 -04:00
for ( const TSharedRef < FPlugin > & Plugin : AllPlugins )
2014-07-10 14:20:43 -04:00
{
2014-10-23 13:51:22 -04:00
if ( Plugin - > bEnabled )
2014-07-10 14:20:43 -04:00
{
2015-08-20 15:34:43 -04:00
// Add the plugin binaries directory
const FString PluginBinariesPath = FPaths : : Combine ( * FPaths : : GetPath ( Plugin - > FileName ) , TEXT ( " Binaries " ) , FPlatformProcess : : GetBinariesSubdirectory ( ) ) ;
FModuleManager : : Get ( ) . AddBinariesDirectory ( * PluginBinariesPath , Plugin - > LoadedFrom = = EPluginLoadedFrom : : GameProject ) ;
2015-08-27 13:58:18 -04:00
# if !IS_MONOLITHIC
// Only check this when in a non-monolithic build where modules could be in separate binaries
if ( Project ! = NULL & & Project - > Modules . Num ( ) = = 0 )
{
// Content only project - check whether any plugins are incompatible and offer to disable instead of trying to build them later
TArray < FString > IncompatibleFiles ;
if ( ! FModuleDescriptor : : CheckModuleCompatibility ( Plugin - > Descriptor . Modules , Plugin - > LoadedFrom = = EPluginLoadedFrom : : GameProject , IncompatibleFiles ) )
{
// Ask whether to disable plugin if incompatible
FText Caption ( LOCTEXT ( " IncompatiblePluginCaption " , " Plugin missing or incompatible " ) ) ;
if ( FMessageDialog : : Open ( EAppMsgType : : YesNo , FText : : Format ( LOCTEXT ( " IncompatiblePluginText " , " Missing or incompatible modules in {0} plugin - would you like to disable it? You will no longer be able to open any assets created using it. " ) , FText : : FromString ( Plugin - > Name ) ) , & Caption ) = = EAppReturnType : : No )
{
return false ;
}
FText FailReason ;
if ( ! IProjectManager : : Get ( ) . SetPluginEnabled ( * Plugin - > Name , false , FailReason ) )
{
FMessageDialog : : Open ( EAppMsgType : : Ok , FailReason ) ;
}
}
}
# endif //!IS_MONOLITHIC
// Build the list of content folders
2014-10-23 13:51:22 -04:00
if ( Plugin - > Descriptor . bCanContainContent )
2014-09-15 03:24:02 -04:00
{
2014-10-23 13:51:22 -04:00
if ( auto EngineConfigFile = GConfig - > Find ( GEngineIni , false ) )
2014-09-15 03:24:02 -04:00
{
2014-10-23 13:51:22 -04:00
if ( auto CoreSystemSection = EngineConfigFile - > Find ( TEXT ( " Core.System " ) ) )
{
2015-04-24 16:37:21 -04:00
CoreSystemSection - > AddUnique ( " Paths " , Plugin - > GetContentDir ( ) ) ;
2014-10-23 13:51:22 -04:00
}
2014-09-15 03:24:02 -04:00
}
}
2014-10-23 13:51:22 -04:00
// Load Default<PluginName>.ini config file if it exists
FString PluginConfigDir = FPaths : : GetPath ( Plugin - > FileName ) / TEXT ( " Config/ " ) ;
FConfigFile PluginConfig ;
FConfigCacheIni : : LoadExternalIniFile ( PluginConfig , * Plugin - > Name , * FPaths : : EngineConfigDir ( ) , * PluginConfigDir , true ) ;
if ( PluginConfig . Num ( ) > 0 )
{
FString PlaformName = FPlatformProperties : : PlatformName ( ) ;
FString PluginConfigFilename = FString : : Printf ( TEXT ( " %s%s/%s.ini " ) , * FPaths : : GeneratedConfigDir ( ) , * PlaformName , * Plugin - > Name ) ;
FConfigFile & NewConfigFile = GConfig - > Add ( PluginConfigFilename , FConfigFile ( ) ) ;
NewConfigFile . AddMissingProperties ( PluginConfig ) ;
NewConfigFile . Write ( PluginConfigFilename ) ;
}
2014-07-10 14:20:43 -04:00
}
}
2014-11-10 15:59:44 -05:00
// Mount all the plugin content folders and pak files
TArray < FString > FoundPaks ;
FPakFileSearchVisitor PakVisitor ( FoundPaks ) ;
IPlatformFile & PlatformFile = FPlatformFileManager : : Get ( ) . GetPlatformFile ( ) ;
2015-04-26 22:19:39 -04:00
for ( TSharedRef < IPlugin > Plugin : GetEnabledPlugins ( ) )
2014-07-10 14:20:43 -04:00
{
2015-08-20 15:34:43 -04:00
if ( Plugin - > CanContainContent ( ) & & ensure ( RegisterMountPointDelegate . IsBound ( ) ) )
2014-07-10 14:20:43 -04:00
{
2015-04-26 22:19:39 -04:00
FString ContentDir = Plugin - > GetContentDir ( ) ;
RegisterMountPointDelegate . Execute ( Plugin - > GetMountedAssetPath ( ) , ContentDir ) ;
2015-04-24 16:37:21 -04:00
2015-04-26 22:19:39 -04:00
// Pak files are loaded from <PluginName>/Content/Paks/<PlatformName>
if ( FPlatformProperties : : RequiresCookedData ( ) )
{
FoundPaks . Reset ( ) ;
PlatformFile . IterateDirectoryRecursively ( * ( ContentDir / TEXT ( " Paks " ) / FPlatformProperties : : PlatformName ( ) ) , PakVisitor ) ;
for ( const auto & PakPath : FoundPaks )
2014-11-10 15:59:44 -05:00
{
2015-04-26 22:19:39 -04:00
if ( FCoreDelegates : : OnMountPak . IsBound ( ) )
2014-11-10 15:59:44 -05:00
{
2015-04-26 22:19:39 -04:00
FCoreDelegates : : OnMountPak . Execute ( PakPath , 0 ) ;
2014-11-10 15:59:44 -05:00
}
}
}
2014-07-10 14:20:43 -04:00
}
}
2014-03-14 14:13:41 -04:00
}
2014-07-30 13:16:05 -04:00
return bHaveAllRequiredPlugins ;
2014-03-14 14:13:41 -04:00
}
2015-04-24 14:23:22 -04:00
TSharedPtr < FPlugin > FPluginManager : : FindPluginInstance ( const FString & Name )
2014-07-30 13:16:05 -04:00
{
2015-04-24 14:23:22 -04:00
TSharedPtr < FPlugin > Result ;
for ( const TSharedRef < FPlugin > & Instance : AllPlugins )
2014-07-30 13:16:05 -04:00
{
if ( Instance - > Name = = Name )
{
Result = Instance ;
break ;
}
}
return Result ;
}
bool FPluginManager : : LoadModulesForEnabledPlugins ( const ELoadingPhase : : Type LoadingPhase )
2014-03-14 14:13:41 -04:00
{
2014-07-10 14:20:43 -04:00
// Figure out which plugins are enabled
2014-07-30 13:16:05 -04:00
if ( ! ConfigureEnabledPlugins ( ) )
{
return false ;
}
2014-03-14 14:13:41 -04:00
2014-12-17 02:15:23 -05:00
FScopedSlowTask SlowTask ( AllPlugins . Num ( ) ) ;
2014-03-14 14:13:41 -04:00
// Load plugins!
2015-04-24 14:23:22 -04:00
for ( const TSharedRef < FPlugin > Plugin : AllPlugins )
2014-03-14 14:13:41 -04:00
{
2014-12-17 02:15:23 -05:00
SlowTask . EnterProgressFrame ( 1 ) ;
2014-06-27 08:41:46 -04:00
if ( Plugin - > bEnabled )
2014-03-14 14:13:41 -04:00
{
2014-06-18 19:23:34 -04:00
TMap < FName , EModuleLoadResult > ModuleLoadFailures ;
2014-06-27 08:41:46 -04:00
FModuleDescriptor : : LoadModulesForPhase ( LoadingPhase , Plugin - > Descriptor . Modules , ModuleLoadFailures ) ;
2014-03-14 14:13:41 -04:00
FText FailureMessage ;
for ( auto FailureIt ( ModuleLoadFailures . CreateConstIterator ( ) ) ; FailureIt ; + + FailureIt )
{
const auto ModuleNameThatFailedToLoad = FailureIt . Key ( ) ;
const auto FailureReason = FailureIt . Value ( ) ;
2014-06-18 19:23:34 -04:00
if ( FailureReason ! = EModuleLoadResult : : Success )
2014-03-14 14:13:41 -04:00
{
2014-06-27 08:41:46 -04:00
const FText PluginNameText = FText : : FromString ( Plugin - > Name ) ;
2014-03-14 14:13:41 -04:00
const FText TextModuleName = FText : : FromName ( FailureIt . Key ( ) ) ;
2014-06-18 19:23:34 -04:00
if ( FailureReason = = EModuleLoadResult : : FileNotFound )
2014-03-14 14:13:41 -04:00
{
2014-07-30 13:16:05 -04:00
FailureMessage = FText : : Format ( LOCTEXT ( " PluginModuleNotFound " , " Plugin '{0}' failed to load because module '{1}' could not be found. Please ensure the plugin is properly installed, otherwise consider disabling the plugin for this project. " ) , PluginNameText , TextModuleName ) ;
2014-03-14 14:13:41 -04:00
}
2014-06-18 19:23:34 -04:00
else if ( FailureReason = = EModuleLoadResult : : FileIncompatible )
2014-03-14 14:13:41 -04:00
{
2014-07-30 13:16:05 -04:00
FailureMessage = FText : : Format ( LOCTEXT ( " PluginModuleIncompatible " , " Plugin '{0}' failed to load because module '{1}' does not appear to be compatible with the current version of the engine. The plugin may need to be recompiled. " ) , PluginNameText , TextModuleName ) ;
2014-03-14 14:13:41 -04:00
}
2014-06-18 19:23:34 -04:00
else if ( FailureReason = = EModuleLoadResult : : CouldNotBeLoadedByOS )
2014-03-14 14:13:41 -04:00
{
2014-07-30 13:16:05 -04:00
FailureMessage = FText : : Format ( LOCTEXT ( " PluginModuleCouldntBeLoaded " , " Plugin '{0}' failed to load because module '{1}' could not be loaded. There may be an operating system error or the module may not be properly set up. " ) , PluginNameText , TextModuleName ) ;
2014-03-14 14:13:41 -04:00
}
2014-06-18 19:23:34 -04:00
else if ( FailureReason = = EModuleLoadResult : : FailedToInitialize )
2014-03-14 14:13:41 -04:00
{
2014-07-30 13:16:05 -04:00
FailureMessage = FText : : Format ( LOCTEXT ( " PluginModuleFailedToInitialize " , " Plugin '{0}' failed to load because module '{1}' could be initialized successfully after it was loaded. " ) , PluginNameText , TextModuleName ) ;
2014-03-14 14:13:41 -04:00
}
else
{
ensure ( 0 ) ; // If this goes off, the error handling code should be updated for the new enum values!
FailureMessage = FText : : Format ( LOCTEXT ( " PluginGenericLoadFailure " , " Plugin '{0}' failed to load because module '{1}' could not be loaded for an unspecified reason. This plugin's functionality will not be available. Please report this error. " ) , PluginNameText , TextModuleName ) ;
}
// Don't need to display more than one module load error per plugin that failed to load
break ;
}
}
if ( ! FailureMessage . IsEmpty ( ) )
{
FMessageDialog : : Open ( EAppMsgType : : Ok , FailureMessage ) ;
2014-07-30 13:16:05 -04:00
return false ;
2014-03-14 14:13:41 -04:00
}
}
}
2014-07-30 13:16:05 -04:00
return true ;
2014-03-14 14:13:41 -04:00
}
void FPluginManager : : SetRegisterMountPointDelegate ( const FRegisterMountPointDelegate & Delegate )
{
RegisterMountPointDelegate = Delegate ;
}
2014-07-30 13:16:05 -04:00
bool FPluginManager : : AreRequiredPluginsAvailable ( )
{
return ConfigureEnabledPlugins ( ) ;
}
2014-09-10 12:43:07 -04:00
bool FPluginManager : : CheckModuleCompatibility ( TArray < FString > & OutIncompatibleModules )
2014-04-30 10:48:13 -04:00
{
2014-07-30 13:16:05 -04:00
if ( ! ConfigureEnabledPlugins ( ) )
{
return false ;
}
2014-04-30 10:48:13 -04:00
2014-09-10 12:43:07 -04:00
bool bResult = true ;
2015-04-24 14:23:22 -04:00
for ( TArray < TSharedRef < FPlugin > > : : TConstIterator Iter ( AllPlugins ) ; Iter ; + + Iter )
2014-04-30 10:48:13 -04:00
{
2015-04-24 14:23:22 -04:00
const TSharedRef < FPlugin > & Plugin = * Iter ;
2015-07-01 11:29:29 -04:00
if ( Plugin - > bEnabled & & ! FModuleDescriptor : : CheckModuleCompatibility ( Plugin - > Descriptor . Modules , Plugin - > LoadedFrom = = EPluginLoadedFrom : : GameProject , OutIncompatibleModules ) )
2014-04-30 10:48:13 -04:00
{
2014-09-10 12:43:07 -04:00
bResult = false ;
2014-04-30 10:48:13 -04:00
}
}
2014-09-10 12:43:07 -04:00
return bResult ;
2014-04-30 10:48:13 -04:00
}
2014-03-14 14:13:41 -04:00
IPluginManager & IPluginManager : : Get ( )
{
// Single instance of manager, allocated on demand and destroyed on program exit.
static FPluginManager * PluginManager = NULL ;
if ( PluginManager = = NULL )
{
PluginManager = new FPluginManager ( ) ;
}
return * PluginManager ;
}
2015-04-26 10:47:22 -04:00
TSharedPtr < IPlugin > FPluginManager : : FindPlugin ( const FString & Name )
2015-04-24 14:23:22 -04:00
{
2015-04-26 10:47:22 -04:00
TSharedPtr < IPlugin > Plugin ;
2015-04-24 14:23:22 -04:00
for ( TSharedRef < FPlugin > & PossiblePlugin : AllPlugins )
{
if ( PossiblePlugin - > Name = = Name )
{
2015-04-26 10:47:22 -04:00
Plugin = PossiblePlugin ;
2015-04-24 14:23:22 -04:00
break ;
}
}
return Plugin ;
}
2015-04-26 10:47:22 -04:00
TArray < TSharedRef < IPlugin > > FPluginManager : : GetEnabledPlugins ( )
2015-04-24 14:58:39 -04:00
{
2015-04-26 10:47:22 -04:00
TArray < TSharedRef < IPlugin > > Plugins ;
2015-04-24 14:58:39 -04:00
for ( TSharedRef < FPlugin > & PossiblePlugin : AllPlugins )
{
if ( PossiblePlugin - > bEnabled )
{
2015-04-26 10:47:22 -04:00
Plugins . Add ( PossiblePlugin ) ;
2015-04-24 14:58:39 -04:00
}
}
return Plugins ;
}
2015-04-26 10:47:22 -04:00
TArray < TSharedRef < IPlugin > > FPluginManager : : GetDiscoveredPlugins ( )
2015-04-26 09:18:08 -04:00
{
2015-04-26 10:47:22 -04:00
TArray < TSharedRef < IPlugin > > Plugins ;
2015-04-26 09:18:08 -04:00
for ( TSharedRef < FPlugin > & Plugin : AllPlugins )
{
2015-04-26 10:47:22 -04:00
Plugins . Add ( Plugin ) ;
2015-04-26 09:18:08 -04:00
}
return Plugins ;
}
2014-03-14 14:13:41 -04:00
TArray < FPluginStatus > FPluginManager : : QueryStatusForAllPlugins ( ) const
{
TArray < FPluginStatus > PluginStatuses ;
for ( auto PluginIt ( AllPlugins . CreateConstIterator ( ) ) ; PluginIt ; + + PluginIt )
{
2015-04-24 14:23:22 -04:00
const TSharedRef < FPlugin > & Plugin = * PluginIt ;
2014-03-14 14:13:41 -04:00
FPluginStatus PluginStatus ;
2014-06-27 08:41:46 -04:00
PluginStatus . Name = Plugin - > Name ;
2014-07-02 07:33:17 -04:00
PluginStatus . PluginDirectory = FPaths : : GetPath ( Plugin - > FileName ) ;
2014-06-27 08:41:46 -04:00
PluginStatus . bIsEnabled = Plugin - > bEnabled ;
2015-04-22 16:41:13 -04:00
PluginStatus . Descriptor = Plugin - > Descriptor ;
PluginStatus . LoadedFrom = Plugin - > LoadedFrom ;
2014-03-14 14:13:41 -04:00
PluginStatuses . Add ( PluginStatus ) ;
}
return PluginStatuses ;
}
2014-07-30 23:46:52 -04:00
# undef LOCTEXT_NAMESPACE