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!
}
void FPluginManager : : DiscoverAllPlugins ( )
{
struct Local
{
private :
/**
* Recursively searches for plugins and generates a list of plugin descriptors
*
* @ param PluginsDirectory Directory we ' re currently searching
* @ param LoadedFrom Where we ' re loading these plugins from ( game , engine , etc )
* @ param Plugins The array to be filled in with new plugins including descriptors
*/
2015-04-24 14:23:22 -04:00
static void FindPluginsRecursively ( const FString & PluginsDirectory , const EPluginLoadedFrom LoadedFrom , TArray < TSharedRef < FPlugin > > & Plugins )
2014-03-14 14:13:41 -04:00
{
// NOTE: The logic in this function generally matches that of the C# code for FindPluginsRecursively
// in UnrealBuildTool. These routines should be kept in sync.
// This directory scanning needs to be fast because it will happen every time at startup! We don't
// want to blindly recurse down every subdirectory, because plugin content and code directories could
// contain a lot of files in total!
// Each sub-directory is possibly a plugin. If we find that it contains a plugin, we won't recurse any
// further -- you can't have plugins within plugins. If we didn't find a plugin, we'll keep recursing.
TArray < FString > PossiblePluginDirectories ;
{
class FPluginDirectoryVisitor : public IPlatformFile : : FDirectoryVisitor
{
public :
FPluginDirectoryVisitor ( TArray < FString > & InitFoundDirectories )
: FoundDirectories ( InitFoundDirectories )
{
}
2014-06-13 06:14:46 -04:00
virtual bool Visit ( const TCHAR * FilenameOrDirectory , bool bIsDirectory ) override
2014-03-14 14:13:41 -04:00
{
if ( bIsDirectory )
{
FoundDirectories . Add ( FString ( FilenameOrDirectory ) ) ;
}
const bool bShouldContinue = true ;
return bShouldContinue ;
}
TArray < FString > & FoundDirectories ;
} ;
FPluginDirectoryVisitor PluginDirectoryVisitor ( PossiblePluginDirectories ) ;
FPlatformFileManager : : Get ( ) . GetPlatformFile ( ) . IterateDirectory ( * PluginsDirectory , PluginDirectoryVisitor ) ;
}
for ( auto PossiblePluginDirectoryIter ( PossiblePluginDirectories . CreateConstIterator ( ) ) ; PossiblePluginDirectoryIter ; + + PossiblePluginDirectoryIter )
{
const FString PossiblePluginDirectory = * PossiblePluginDirectoryIter ;
FString PluginDescriptorFilename ;
{
// Usually the plugin descriptor is named the same as the directory. It doesn't have to match the directory
// name but we'll check that first because its much faster than scanning!
const FString ProbablePluginDescriptorFilename = PossiblePluginDirectory / ( FPaths : : GetCleanFilename ( PossiblePluginDirectory ) + PluginSystemDefs : : PluginDescriptorFileExtension ) ;
if ( FPlatformFileManager : : Get ( ) . GetPlatformFile ( ) . FileExists ( * ProbablePluginDescriptorFilename ) )
{
PluginDescriptorFilename = ProbablePluginDescriptorFilename ;
}
else
{
// Scan the directory for a plugin descriptor.
TArray < FString > PluginDescriptorFilenames ;
{
class FPluginDescriptorFileVisitor : public IPlatformFile : : FDirectoryVisitor
{
public :
FPluginDescriptorFileVisitor ( const FWildcardString & InitSearchPattern , TArray < FString > & InitFoundPluginDescriptorFilenames )
: SearchPattern ( InitSearchPattern ) ,
FoundPluginDescriptorFilenames ( InitFoundPluginDescriptorFilenames )
{
}
2014-06-13 06:14:46 -04:00
virtual bool Visit ( const TCHAR * FilenameOrDirectory , bool bIsDirectory ) override
2014-03-14 14:13:41 -04:00
{
bool bShouldContinue = true ;
if ( ! bIsDirectory )
{
if ( SearchPattern . IsMatch ( FilenameOrDirectory ) )
{
FoundPluginDescriptorFilenames . Add ( FString ( FilenameOrDirectory ) ) ;
bShouldContinue = false ;
}
}
return bShouldContinue ;
}
const FWildcardString & SearchPattern ;
TArray < FString > & FoundPluginDescriptorFilenames ;
} ;
const FWildcardString PluginDescriptorSearchString = PossiblePluginDirectory / FString ( TEXT ( " * " ) ) + PluginSystemDefs : : PluginDescriptorFileExtension ;
FPluginDescriptorFileVisitor PluginDescriptorFileVisitor ( PluginDescriptorSearchString , PluginDescriptorFilenames ) ;
FPlatformFileManager : : Get ( ) . GetPlatformFile ( ) . IterateDirectory ( * PossiblePluginDirectory , PluginDescriptorFileVisitor ) ;
}
// Did we find any plugin descriptor files?
if ( PluginDescriptorFilenames . Num ( ) > 0 )
{
PluginDescriptorFilename = PluginDescriptorFilenames [ 0 ] ; ;
}
}
}
if ( ! PluginDescriptorFilename . IsEmpty ( ) )
{
// Found a plugin directory! No need to recurse any further.
2014-06-27 08:41:46 -04:00
FPluginDescriptor Descriptor ;
2014-03-14 14:13:41 -04:00
2014-06-27 08:41:46 -04:00
// Load the descriptor
2014-03-14 14:13:41 -04:00
FText FailureReason ;
2014-06-27 08:41:46 -04:00
if ( Descriptor . Load ( PluginDescriptorFilename , FailureReason ) )
2014-03-14 14:13:41 -04:00
{
2015-04-24 14:23:22 -04:00
TSharedRef < FPlugin > NewPlugin = MakeShareable ( new FPlugin ( PluginDescriptorFilename , Descriptor , LoadedFrom ) ) ;
2014-03-14 14:13:41 -04:00
if ( FPaths : : IsProjectFilePathSet ( ) )
{
FString GameProjectFolder = FPaths : : GetPath ( FPaths : : GetProjectFilePath ( ) ) ;
if ( PluginDescriptorFilename . StartsWith ( GameProjectFolder ) )
{
FString PluginBinariesFolder = FPaths : : Combine ( * FPaths : : GetPath ( PluginDescriptorFilename ) , TEXT ( " Binaries " ) , FPlatformProcess : : GetBinariesSubdirectory ( ) ) ;
2014-06-27 08:41:46 -04:00
FModuleManager : : Get ( ) . AddBinariesDirectory ( * PluginBinariesFolder , ( LoadedFrom = = EPluginLoadedFrom : : GameProject ) ) ;
2014-03-14 14:13:41 -04:00
}
}
Plugins . Add ( NewPlugin ) ;
}
else
{
// NOTE: Even though loading of this plugin failed, we'll keep processing other plugins
2014-09-11 11:59:05 -04:00
UE_LOG ( LogPluginManager , Error , TEXT ( " %s (%s) " ) , * FailureReason . ToString ( ) , * PluginDescriptorFilename ) ;
2014-03-14 14:13:41 -04:00
}
}
else
{
// Didn't find a plugin in this directory. Continue to look in subfolders.
FindPluginsRecursively ( PossiblePluginDirectory , LoadedFrom , Plugins ) ;
}
}
}
public :
/**
* Searches for plugins and generates a list of plugin descriptors
*
* @ param PluginsDirectory The base directory to search for plugins
* @ param LoadedFrom Where we ' re loading these plugins from ( game , engine , etc )
* @ param Plugins The array to be filled in with loaded plugin descriptors
*/
2015-04-24 14:23:22 -04:00
static void FindPluginsIn ( const FString & PluginsDirectory , const EPluginLoadedFrom LoadedFrom , TArray < TSharedRef < FPlugin > > & Plugins )
2014-03-14 14:13:41 -04:00
{
// Make sure the directory even exists
if ( FPlatformFileManager : : Get ( ) . GetPlatformFile ( ) . DirectoryExists ( * PluginsDirectory ) )
{
FindPluginsRecursively ( PluginsDirectory , LoadedFrom , Plugins ) ;
}
}
} ;
{
2015-04-24 14:23:22 -04:00
TArray < TSharedRef < FPlugin > > Plugins ;
2014-03-14 14:13:41 -04:00
# if (WITH_ENGINE && !IS_PROGRAM) || WITH_PLUGIN_SUPPORT
// Find "built-in" plugins. That is, plugins situated right within the Engine directory.
2014-06-27 08:41:46 -04:00
Local : : FindPluginsIn ( FPaths : : EnginePluginsDir ( ) , EPluginLoadedFrom : : Engine , Plugins ) ;
2014-03-14 14:13:41 -04:00
// Find plugins in the game project directory (<MyGameProject>/Plugins)
if ( FApp : : HasGameName ( ) )
{
2014-06-27 08:41:46 -04:00
Local : : FindPluginsIn ( FPaths : : GamePluginsDir ( ) , EPluginLoadedFrom : : GameProject , Plugins ) ;
2014-03-14 14:13:41 -04:00
}
# endif // (WITH_ENGINE && !IS_PROGRAM) || WITH_PLUGIN_SUPPORT
// Create plugin objects for all of the plugins that we found
ensure ( AllPlugins . Num ( ) = = 0 ) ; // Should not have already been initialized!
AllPlugins = Plugins ;
for ( auto PluginIt ( Plugins . CreateConstIterator ( ) ) ; PluginIt ; + + PluginIt )
{
2015-04-24 14:23:22 -04:00
const TSharedRef < FPlugin > & Plugin = * PluginIt ;
2014-03-14 14:13:41 -04:00
// Add the plugin binaries directory
2014-06-27 08:41:46 -04:00
const FString PluginBinariesPath = FPaths : : Combine ( * FPaths : : GetPath ( Plugin - > FileName ) , TEXT ( " Binaries " ) , FPlatformProcess : : GetBinariesSubdirectory ( ) ) ;
FModuleManager : : Get ( ) . AddBinariesDirectory ( * PluginBinariesPath , Plugin - > LoadedFrom = = EPluginLoadedFrom : : GameProject ) ;
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 )
{
for ( const FPluginReferenceDescriptor & Plugin : Project - > Plugins )
{
if ( Plugin . bEnabled & & ! FindPluginInstance ( Plugin . Name ) . IsValid ( ) )
{
FText Caption ( LOCTEXT ( " PluginMissingCaption " , " Plugin missing " ) ) ;
FString Description = ( Plugin . Description . Len ( ) > 0 ) ? FString : : Printf ( TEXT ( " \n \n %s " ) , * Plugin . Description ) : FString ( ) ;
FMessageDialog : : Open ( EAppMsgType : : Ok , FText : : Format ( LOCTEXT ( " PluginMissingError " , " This project requires the {0} plugin. {1} " ) , FText : : FromString ( Plugin . Name ) , FText : : FromString ( Description ) ) , & Caption ) ;
return false ;
}
}
}
// 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
{
2014-10-23 13:51:22 -04:00
// Build the list of content folders
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-04-26 22:19:39 -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 ;
2014-09-10 12:43:07 -04:00
if ( Plugin - > bEnabled & & ! FModuleDescriptor : : CheckModuleCompatbility ( 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