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 "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-10-02 12:43:46 -04:00
/**
* Parsing the command line and loads any foreign plugins that were
* specified using the - PLUGIN = command .
*
* @ param CommandLine The commandline used to launch the editor .
* @ param SearchPathsOut
* @ return The number of plugins that were specified using the - PLUGIN param .
*/
static int32 GetAdditionalPluginPaths ( TSet < FString > & PluginPathsOut )
{
const TCHAR * SwitchStr = TEXT ( " PLUGIN= " ) ;
const int32 SwitchLen = FCString : : Strlen ( SwitchStr ) ;
int32 PluginCount = 0 ;
const TCHAR * SearchStr = FCommandLine : : Get ( ) ;
do
{
FString PluginPath ;
SearchStr = FCString : : Strfind ( SearchStr , SwitchStr ) ;
if ( FParse : : Value ( SearchStr , SwitchStr , PluginPath ) )
{
FString PluginDir = FPaths : : GetPath ( PluginPath ) ;
PluginPathsOut . Add ( PluginDir ) ;
+ + PluginCount ;
SearchStr + = SwitchLen + PluginPath . Len ( ) ;
}
else
{
break ;
}
} while ( SearchStr ! = nullptr ) ;
Copying //UE4/Dev-Core to //UE4/Main
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2799478 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added Dev Stream custom versions.
- Each stream now has its own custom version
- Developers working in a stream should only modify their respective version
Change 2789867 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
UnrealHeaderTool plugins no longer need to be a separate plugin and don't require UnrealHeaderTool source code changes to work.
- Merged ScriptGeneratorPlugin with ScriptPlugin
- Introduced the concept of UHT plugin support for plugins so that UHT's source files don't need to be modified to make it work with external plugins
- Added RuntimeNoProgram module type (module that can be used at runtime but not by program targets).
- Fixed logic with project file path setting in the engine. It will no longer try to crate a full path from an already rooted path.
Change 2796114 on 2015/12/09 by Steve.Robb@Dev-Core
TEnumRange - enabled ranged-based for iteration over enum values.
Change 2789843 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
More thorough way of verifying GC cluster assumptions.
Change 2794221 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Don't merge GC clusters by default
Change 2797824 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added the option to load all symbols for stack walking in non-monolithic builds.
Change 2790539 on 2015/12/04 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Stats/Profiler - Better handling for live connection, using the same path as file profiles, added FStatsLoadedState to separate runtime stats state from the loaded one
Change 2794183 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Always reset events when returning them to pool.
Change 2794406 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Fixing -unversioned flag being completely ignored when cooking
Change 2794563 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Making sure string referenced assets don't get cooked if referenced by editor-only properties.
Change 2795124 on 2015/12/08 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Fixed bad data in min/max/avg inclusive times, added min/max/avg num calls, fixed event graph tooltip not displaying correct values
Change 2796208 on 2015/12/09 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Remove support for multiple instances in the profiler (game thread is always visible, a few crash fixes, cleaned code a bit)
Change 2797658 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Allocation verification helpers. Helps with tracking down memory stomps, freeing the same pointers multiple times.
Change 2797699 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fix incorrect asset loading in Cooked game data (by bozaro)
PR #1844
Change 2798173 on 2015/12/10 by Steve.Robb@Dev-Core
Migration of Fortnite to use engine's TEnumRange.
Change 2798217 on 2015/12/10 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
PR #1331
[Core] Added a stomp allocator that allows finding memory overruns, underruns, and read/write after free. (Contributed by Pablo Zurita)
Change 2799605 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fixing a crash when cancelling async loading caused by detaching linker from objects that had RF_NeedLoad flag set.
Change 2799849 on 2015/12/11 by Steve.Robb@Dev-Core
Migration of Ocean to use engine's TEnumRange.
Change 2803144 on 2015/12/15 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Changed export tagging archive to also serialize class default objects using the normal Serialize path so that it can collect all custom versions used by exports.
Change 2803206 on 2015/12/15 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
#jira UE-24177
Audit ôshippingö defines in engine
Change 2804868 on 2015/12/16 by Steve.Robb@Dev-Core
Removal of stats from MallocBinned2, to be readded later.
#lockdown Nick.Penwarden
[CL 2805158 by Robert Manuszewski in Main branch]
2015-12-16 11:52:36 -05:00
# if IS_PROGRAM
// For programs that have the project dir set, look for plugins under the project directory
const FProjectDescriptor * Project = IProjectManager : : Get ( ) . GetCurrentProject ( ) ;
if ( Project ! = nullptr )
{
PluginPathsOut . Add ( FPaths : : GetPath ( FPaths : : GetProjectFilePath ( ) ) / TEXT ( " Plugins " ) ) ;
}
# endif
2015-10-02 12:43:46 -04:00
return PluginCount ;
}
2014-03-14 14:13:41 -04:00
}
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 ;
2015-10-02 12:43:46 -04:00
ReadAllPlugins ( NewPlugins , PluginDiscoveryPaths ) ;
2015-05-10 15:38:43 -04:00
// 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!
2015-10-02 12:43:46 -04:00
PluginSystemDefs : : GetAdditionalPluginPaths ( PluginDiscoveryPaths ) ;
ReadAllPlugins ( AllPlugins , PluginDiscoveryPaths ) ;
2015-05-10 15:38:43 -04:00
}
2014-03-14 14:13:41 -04:00
2015-10-02 12:43:46 -04:00
void FPluginManager : : ReadAllPlugins ( TArray < TSharedRef < FPlugin > > & Plugins , const TSet < FString > & ExtraSearchPaths )
2015-05-10 15:38:43 -04:00
{
# 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 ) ;
}
2015-10-02 12:43:46 -04:00
for ( const FString & ExtraSearchPath : ExtraSearchPaths )
{
ReadPluginsInDirectory ( ExtraSearchPath , EPluginLoadedFrom : : GameProject , Plugins ) ;
}
2015-05-10 15:38:43 -04:00
# 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 ;
}
} ;
Copying //UE4/Dev-Core to //UE4/Main
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2799478 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added Dev Stream custom versions.
- Each stream now has its own custom version
- Developers working in a stream should only modify their respective version
Change 2789867 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
UnrealHeaderTool plugins no longer need to be a separate plugin and don't require UnrealHeaderTool source code changes to work.
- Merged ScriptGeneratorPlugin with ScriptPlugin
- Introduced the concept of UHT plugin support for plugins so that UHT's source files don't need to be modified to make it work with external plugins
- Added RuntimeNoProgram module type (module that can be used at runtime but not by program targets).
- Fixed logic with project file path setting in the engine. It will no longer try to crate a full path from an already rooted path.
Change 2796114 on 2015/12/09 by Steve.Robb@Dev-Core
TEnumRange - enabled ranged-based for iteration over enum values.
Change 2789843 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
More thorough way of verifying GC cluster assumptions.
Change 2794221 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Don't merge GC clusters by default
Change 2797824 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added the option to load all symbols for stack walking in non-monolithic builds.
Change 2790539 on 2015/12/04 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Stats/Profiler - Better handling for live connection, using the same path as file profiles, added FStatsLoadedState to separate runtime stats state from the loaded one
Change 2794183 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Always reset events when returning them to pool.
Change 2794406 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Fixing -unversioned flag being completely ignored when cooking
Change 2794563 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Making sure string referenced assets don't get cooked if referenced by editor-only properties.
Change 2795124 on 2015/12/08 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Fixed bad data in min/max/avg inclusive times, added min/max/avg num calls, fixed event graph tooltip not displaying correct values
Change 2796208 on 2015/12/09 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Remove support for multiple instances in the profiler (game thread is always visible, a few crash fixes, cleaned code a bit)
Change 2797658 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Allocation verification helpers. Helps with tracking down memory stomps, freeing the same pointers multiple times.
Change 2797699 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fix incorrect asset loading in Cooked game data (by bozaro)
PR #1844
Change 2798173 on 2015/12/10 by Steve.Robb@Dev-Core
Migration of Fortnite to use engine's TEnumRange.
Change 2798217 on 2015/12/10 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
PR #1331
[Core] Added a stomp allocator that allows finding memory overruns, underruns, and read/write after free. (Contributed by Pablo Zurita)
Change 2799605 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fixing a crash when cancelling async loading caused by detaching linker from objects that had RF_NeedLoad flag set.
Change 2799849 on 2015/12/11 by Steve.Robb@Dev-Core
Migration of Ocean to use engine's TEnumRange.
Change 2803144 on 2015/12/15 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Changed export tagging archive to also serialize class default objects using the normal Serialize path so that it can collect all custom versions used by exports.
Change 2803206 on 2015/12/15 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
#jira UE-24177
Audit ôshippingö defines in engine
Change 2804868 on 2015/12/16 by Steve.Robb@Dev-Core
Removal of stats from MallocBinned2, to be readded later.
#lockdown Nick.Penwarden
[CL 2805158 by Robert Manuszewski in Main branch]
2015-12-16 11:52:36 -05:00
bool FPluginManager : : IsPluginSupportedByCurrentTarget ( TSharedRef < FPlugin > Plugin ) const
{
bool bSupported = false ;
if ( Plugin - > GetDescriptor ( ) . Modules . Num ( ) )
{
for ( const FModuleDescriptor & Module : Plugin - > GetDescriptor ( ) . Modules )
{
// Programs support only program type plugins
// Non-program targets don't support from plugins
# if IS_PROGRAM
if ( Module . Type = = EHostType : : Program )
{
bSupported = true ;
}
# else
if ( Module . Type ! = EHostType : : Program )
{
bSupported = true ;
}
# endif
}
}
else
{
bSupported = true ;
}
return bSupported ;
}
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-12-10 16:56:55 -05:00
FMessageDialog : : Open ( EAppMsgType : : Ok , FText : : Format ( LOCTEXT ( " PluginRequiredError " , " 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 ;
Copying //UE4/Dev-Core to //UE4/Main
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2799478 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added Dev Stream custom versions.
- Each stream now has its own custom version
- Developers working in a stream should only modify their respective version
Change 2789867 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
UnrealHeaderTool plugins no longer need to be a separate plugin and don't require UnrealHeaderTool source code changes to work.
- Merged ScriptGeneratorPlugin with ScriptPlugin
- Introduced the concept of UHT plugin support for plugins so that UHT's source files don't need to be modified to make it work with external plugins
- Added RuntimeNoProgram module type (module that can be used at runtime but not by program targets).
- Fixed logic with project file path setting in the engine. It will no longer try to crate a full path from an already rooted path.
Change 2796114 on 2015/12/09 by Steve.Robb@Dev-Core
TEnumRange - enabled ranged-based for iteration over enum values.
Change 2789843 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
More thorough way of verifying GC cluster assumptions.
Change 2794221 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Don't merge GC clusters by default
Change 2797824 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added the option to load all symbols for stack walking in non-monolithic builds.
Change 2790539 on 2015/12/04 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Stats/Profiler - Better handling for live connection, using the same path as file profiles, added FStatsLoadedState to separate runtime stats state from the loaded one
Change 2794183 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Always reset events when returning them to pool.
Change 2794406 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Fixing -unversioned flag being completely ignored when cooking
Change 2794563 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Making sure string referenced assets don't get cooked if referenced by editor-only properties.
Change 2795124 on 2015/12/08 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Fixed bad data in min/max/avg inclusive times, added min/max/avg num calls, fixed event graph tooltip not displaying correct values
Change 2796208 on 2015/12/09 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Remove support for multiple instances in the profiler (game thread is always visible, a few crash fixes, cleaned code a bit)
Change 2797658 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Allocation verification helpers. Helps with tracking down memory stomps, freeing the same pointers multiple times.
Change 2797699 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fix incorrect asset loading in Cooked game data (by bozaro)
PR #1844
Change 2798173 on 2015/12/10 by Steve.Robb@Dev-Core
Migration of Fortnite to use engine's TEnumRange.
Change 2798217 on 2015/12/10 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
PR #1331
[Core] Added a stomp allocator that allows finding memory overruns, underruns, and read/write after free. (Contributed by Pablo Zurita)
Change 2799605 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fixing a crash when cancelling async loading caused by detaching linker from objects that had RF_NeedLoad flag set.
Change 2799849 on 2015/12/11 by Steve.Robb@Dev-Core
Migration of Ocean to use engine's TEnumRange.
Change 2803144 on 2015/12/15 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Changed export tagging archive to also serialize class default objects using the normal Serialize path so that it can collect all custom versions used by exports.
Change 2803206 on 2015/12/15 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
#jira UE-24177
Audit ôshippingö defines in engine
Change 2804868 on 2015/12/16 by Steve.Robb@Dev-Core
Removal of stats from MallocBinned2, to be readded later.
#lockdown Nick.Penwarden
[CL 2805158 by Robert Manuszewski in Main branch]
2015-12-16 11:52:36 -05:00
const bool bHasProjectFile = IProjectManager : : Get ( ) . GetCurrentProject ( ) ! = nullptr ;
2014-07-30 13:16:05 -04:00
// Get all the enabled plugin names
2014-07-10 14:20:43 -04:00
TArray < FString > EnabledPluginNames ;
Copying //UE4/Dev-Core to //UE4/Main
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2799478 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added Dev Stream custom versions.
- Each stream now has its own custom version
- Developers working in a stream should only modify their respective version
Change 2789867 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
UnrealHeaderTool plugins no longer need to be a separate plugin and don't require UnrealHeaderTool source code changes to work.
- Merged ScriptGeneratorPlugin with ScriptPlugin
- Introduced the concept of UHT plugin support for plugins so that UHT's source files don't need to be modified to make it work with external plugins
- Added RuntimeNoProgram module type (module that can be used at runtime but not by program targets).
- Fixed logic with project file path setting in the engine. It will no longer try to crate a full path from an already rooted path.
Change 2796114 on 2015/12/09 by Steve.Robb@Dev-Core
TEnumRange - enabled ranged-based for iteration over enum values.
Change 2789843 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
More thorough way of verifying GC cluster assumptions.
Change 2794221 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Don't merge GC clusters by default
Change 2797824 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added the option to load all symbols for stack walking in non-monolithic builds.
Change 2790539 on 2015/12/04 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Stats/Profiler - Better handling for live connection, using the same path as file profiles, added FStatsLoadedState to separate runtime stats state from the loaded one
Change 2794183 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Always reset events when returning them to pool.
Change 2794406 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Fixing -unversioned flag being completely ignored when cooking
Change 2794563 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Making sure string referenced assets don't get cooked if referenced by editor-only properties.
Change 2795124 on 2015/12/08 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Fixed bad data in min/max/avg inclusive times, added min/max/avg num calls, fixed event graph tooltip not displaying correct values
Change 2796208 on 2015/12/09 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Remove support for multiple instances in the profiler (game thread is always visible, a few crash fixes, cleaned code a bit)
Change 2797658 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Allocation verification helpers. Helps with tracking down memory stomps, freeing the same pointers multiple times.
Change 2797699 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fix incorrect asset loading in Cooked game data (by bozaro)
PR #1844
Change 2798173 on 2015/12/10 by Steve.Robb@Dev-Core
Migration of Fortnite to use engine's TEnumRange.
Change 2798217 on 2015/12/10 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
PR #1331
[Core] Added a stomp allocator that allows finding memory overruns, underruns, and read/write after free. (Contributed by Pablo Zurita)
Change 2799605 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fixing a crash when cancelling async loading caused by detaching linker from objects that had RF_NeedLoad flag set.
Change 2799849 on 2015/12/11 by Steve.Robb@Dev-Core
Migration of Ocean to use engine's TEnumRange.
Change 2803144 on 2015/12/15 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Changed export tagging archive to also serialize class default objects using the normal Serialize path so that it can collect all custom versions used by exports.
Change 2803206 on 2015/12/15 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
#jira UE-24177
Audit ôshippingö defines in engine
Change 2804868 on 2015/12/16 by Steve.Robb@Dev-Core
Removal of stats from MallocBinned2, to be readded later.
#lockdown Nick.Penwarden
[CL 2805158 by Robert Manuszewski in Main branch]
2015-12-16 11:52:36 -05:00
# if IS_PROGRAM
// Programs with a project file specified take the list of enabled plugins from the project file
if ( bHasProjectFile )
{
2014-07-10 14:20:43 -04:00
FProjectManager : : Get ( ) . GetEnabledPlugins ( EnabledPluginNames ) ;
Copying //UE4/Dev-Core to //UE4/Main
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2799478 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added Dev Stream custom versions.
- Each stream now has its own custom version
- Developers working in a stream should only modify their respective version
Change 2789867 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
UnrealHeaderTool plugins no longer need to be a separate plugin and don't require UnrealHeaderTool source code changes to work.
- Merged ScriptGeneratorPlugin with ScriptPlugin
- Introduced the concept of UHT plugin support for plugins so that UHT's source files don't need to be modified to make it work with external plugins
- Added RuntimeNoProgram module type (module that can be used at runtime but not by program targets).
- Fixed logic with project file path setting in the engine. It will no longer try to crate a full path from an already rooted path.
Change 2796114 on 2015/12/09 by Steve.Robb@Dev-Core
TEnumRange - enabled ranged-based for iteration over enum values.
Change 2789843 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
More thorough way of verifying GC cluster assumptions.
Change 2794221 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Don't merge GC clusters by default
Change 2797824 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added the option to load all symbols for stack walking in non-monolithic builds.
Change 2790539 on 2015/12/04 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Stats/Profiler - Better handling for live connection, using the same path as file profiles, added FStatsLoadedState to separate runtime stats state from the loaded one
Change 2794183 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Always reset events when returning them to pool.
Change 2794406 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Fixing -unversioned flag being completely ignored when cooking
Change 2794563 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Making sure string referenced assets don't get cooked if referenced by editor-only properties.
Change 2795124 on 2015/12/08 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Fixed bad data in min/max/avg inclusive times, added min/max/avg num calls, fixed event graph tooltip not displaying correct values
Change 2796208 on 2015/12/09 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Remove support for multiple instances in the profiler (game thread is always visible, a few crash fixes, cleaned code a bit)
Change 2797658 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Allocation verification helpers. Helps with tracking down memory stomps, freeing the same pointers multiple times.
Change 2797699 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fix incorrect asset loading in Cooked game data (by bozaro)
PR #1844
Change 2798173 on 2015/12/10 by Steve.Robb@Dev-Core
Migration of Fortnite to use engine's TEnumRange.
Change 2798217 on 2015/12/10 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
PR #1331
[Core] Added a stomp allocator that allows finding memory overruns, underruns, and read/write after free. (Contributed by Pablo Zurita)
Change 2799605 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fixing a crash when cancelling async loading caused by detaching linker from objects that had RF_NeedLoad flag set.
Change 2799849 on 2015/12/11 by Steve.Robb@Dev-Core
Migration of Ocean to use engine's TEnumRange.
Change 2803144 on 2015/12/15 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Changed export tagging archive to also serialize class default objects using the normal Serialize path so that it can collect all custom versions used by exports.
Change 2803206 on 2015/12/15 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
#jira UE-24177
Audit ôshippingö defines in engine
Change 2804868 on 2015/12/16 by Steve.Robb@Dev-Core
Removal of stats from MallocBinned2, to be readded later.
#lockdown Nick.Penwarden
[CL 2805158 by Robert Manuszewski in Main branch]
2015-12-16 11:52:36 -05:00
}
else
{
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 ) )
Copying //UE4/Dev-Core to //UE4/Main
==========================
MAJOR FEATURES + CHANGES
==========================
Change 2799478 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added Dev Stream custom versions.
- Each stream now has its own custom version
- Developers working in a stream should only modify their respective version
Change 2789867 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
UnrealHeaderTool plugins no longer need to be a separate plugin and don't require UnrealHeaderTool source code changes to work.
- Merged ScriptGeneratorPlugin with ScriptPlugin
- Introduced the concept of UHT plugin support for plugins so that UHT's source files don't need to be modified to make it work with external plugins
- Added RuntimeNoProgram module type (module that can be used at runtime but not by program targets).
- Fixed logic with project file path setting in the engine. It will no longer try to crate a full path from an already rooted path.
Change 2796114 on 2015/12/09 by Steve.Robb@Dev-Core
TEnumRange - enabled ranged-based for iteration over enum values.
Change 2789843 on 2015/12/04 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
More thorough way of verifying GC cluster assumptions.
Change 2794221 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Don't merge GC clusters by default
Change 2797824 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Added the option to load all symbols for stack walking in non-monolithic builds.
Change 2790539 on 2015/12/04 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Stats/Profiler - Better handling for live connection, using the same path as file profiles, added FStatsLoadedState to separate runtime stats state from the loaded one
Change 2794183 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Always reset events when returning them to pool.
Change 2794406 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Fixing -unversioned flag being completely ignored when cooking
Change 2794563 on 2015/12/08 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream2
Making sure string referenced assets don't get cooked if referenced by editor-only properties.
Change 2795124 on 2015/12/08 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Fixed bad data in min/max/avg inclusive times, added min/max/avg num calls, fixed event graph tooltip not displaying correct values
Change 2796208 on 2015/12/09 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
Profiler - Remove support for multiple instances in the profiler (game thread is always visible, a few crash fixes, cleaned code a bit)
Change 2797658 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Allocation verification helpers. Helps with tracking down memory stomps, freeing the same pointers multiple times.
Change 2797699 on 2015/12/10 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fix incorrect asset loading in Cooked game data (by bozaro)
PR #1844
Change 2798173 on 2015/12/10 by Steve.Robb@Dev-Core
Migration of Fortnite to use engine's TEnumRange.
Change 2798217 on 2015/12/10 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
PR #1331
[Core] Added a stomp allocator that allows finding memory overruns, underruns, and read/write after free. (Contributed by Pablo Zurita)
Change 2799605 on 2015/12/11 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Fixing a crash when cancelling async loading caused by detaching linker from objects that had RF_NeedLoad flag set.
Change 2799849 on 2015/12/11 by Steve.Robb@Dev-Core
Migration of Ocean to use engine's TEnumRange.
Change 2803144 on 2015/12/15 by Robert.Manuszewski@Robert.Manuszewski_NCL_Stream1
Changed export tagging archive to also serialize class default objects using the normal Serialize path so that it can collect all custom versions used by exports.
Change 2803206 on 2015/12/15 by Jaroslaw.Surowiec@Stream.1.JarekSurowiec
#jira UE-24177
Audit ôshippingö defines in engine
Change 2804868 on 2015/12/16 by Steve.Robb@Dev-Core
Removal of stats from MallocBinned2, to be readded later.
#lockdown Nick.Penwarden
[CL 2805158 by Robert Manuszewski in Main branch]
2015-12-16 11:52:36 -05:00
{
Plugin - > bEnabled = ( ! IS_PROGRAM | | ! bHasProjectFile ) | | IsPluginSupportedByCurrentTarget ( Plugin ) ;
2014-07-10 14:20:43 -04:00
}
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 ;
}
2015-10-02 12:43:46 -04:00
void FPluginManager : : AddPluginSearchPath ( const FString & ExtraDiscoveryPath , bool bRefresh )
{
PluginDiscoveryPaths . Add ( ExtraDiscoveryPath ) ;
if ( bRefresh )
{
RefreshPluginsList ( ) ;
}
}
2014-07-30 23:46:52 -04:00
# undef LOCTEXT_NAMESPACE