【UE4】 Notes d'étude sur le principe du fichier de configuration du moteur

Je viens de rencontrer une optimisation du chargement ini. Profitez de cette occasion pour enregistrer et en savoir plus sur la hiérarchie des fichiers de configuration et le processus de lecture du moteur UE

deux questions

Lorsque vous regardez la structure du répertoire du projet, vous posez-vous une question :
pourquoi y a-t-il une configuration sous le répertoire enregistré au même niveau, et il y a une autre configuration dans enregistré : enregistré/config ? Quelle est la différence entre eux?
insérez la description de l'image ici

Regardez le code source du fichier de configuration de lecture fantôme : il s'avère qu'il utilise une LoadExternalIniFilefonction pour lire le fichier de configuration. Mais cette fonction effectue une opération d'écriture en plus d'une opération de lecture . Pourquoi dois-je écrire le fichier après avoir chargé le fichier de configuration dans Unreal ?
insérez la description de l'image ici

structure hiérarchique

En fait, la stratégie de lecture du fichier de configuration config adoptée par l'UE se présente sous la forme de couches, qui peuvent être divisées en quatre niveaux :

  1. Moteur/Configuration
  2. Moteur/Enregistré/Config
  3. [Nom du projet]/Config
  4. [Nom du projet]/Enregistré/Config

Lors du chargement d'un fichier de configuration nommé "ConfigFileName", UE parcourra ces répertoires à tour de rôle. Ceux lus plus tard couvrent les précédents, c'est-à-dire que leurs priorités augmentent séquentiellement.

Ce concept de hiérarchie est très intéressant. C'est un peu comme la duplication de sous-classe : si le répertoire dans le projet a l'ini ConofigFileName, utilisez l'ini dans le projet. Sinon, le fichier ConofigFileName.ini de son répertoire de moteur parent est utilisé.

Il est garanti que la modification de l'ini d'un projet n'affectera pas les autres projets, et la partie non modifiée utilise toujours les paramètres généraux.

Le répertoire du fichier de configuration que UE lira est enregistré dans GConfigLayers de ConfigCacheIni.cpp :

// ConfigCacheIni.cpp
GConfigLayers[] =
{
    
    
	/**************************************************
	**** CRITICAL NOTES
	**** If you change this array, you need to also change EnumerateConfigFileLocations() in ConfigHierarchy.cs!!!
	**** And maybe UObject::GetDefaultConfigFilename(), UObject::GetGlobalUserConfigFilename()
	**************************************************/

	// Engine/Base.ini
	{
    
     TEXT("AbsoluteBase"),				TEXT("{ENGINE}/Config/Base.ini"), EConfigLayerFlags::Required | EConfigLayerFlags::NoExpand},
	
	// Engine/Base*.ini
	{
    
     TEXT("Base"),						TEXT("{ENGINE}/Config/Base{TYPE}.ini") },
	// Engine/Platform/BasePlatform*.ini
	{
    
     TEXT("BasePlatform"),				TEXT("{ENGINE}/Config/{PLATFORM}/Base{PLATFORM}{TYPE}.ini")  },
	// Project/Default*.ini
	{
    
     TEXT("ProjectDefault"),			TEXT("{PROJECT}/Config/Default{TYPE}.ini"), EConfigLayerFlags::AllowCommandLineOverride | EConfigLayerFlags::GenerateCacheKey },
	// Project/Generated*.ini Reserved for files generated by build process and should never be checked in 
	{
    
     TEXT("ProjectGenerated"),			TEXT("{PROJECT}/Config/Generated{TYPE}.ini"), EConfigLayerFlags::GenerateCacheKey },
	// Engine/Platform/Platform*.ini
	{
    
     TEXT("EnginePlatform"),			TEXT("{ENGINE}/Config/{PLATFORM}/{PLATFORM}{TYPE}.ini") },
	// Project/Platform/Platform*.ini
	{
    
     TEXT("ProjectPlatform"),			TEXT("{PROJECT}/Config/{PLATFORM}/{PLATFORM}{TYPE}.ini") },
	// Project/Generated*.ini Reserved for files generated by build process and should never be checked in 
	{
    
     TEXT("ProjectPlatformGenerated"),	TEXT("{PROJECT}/Config/{PLATFORM}/Generated{PLATFORM}{TYPE}.ini") },
	// UserSettings/.../User*.ini
	{
    
     TEXT("UserSettingsDir"),			TEXT("{USERSETTINGS}Unreal Engine/Engine/Config/User{TYPE}.ini"), EConfigLayerFlags::NoExpand },
	// UserDir/.../User*.ini
	{
    
     TEXT("UserDir"),					TEXT("{USER}Unreal Engine/Engine/Config/User{TYPE}.ini"), EConfigLayerFlags::NoExpand },
	// Project/User*.ini
	{
    
     TEXT("GameDirUser"),				TEXT("{PROJECT}/Config/User{TYPE}.ini"), EConfigLayerFlags::GenerateCacheKey | EConfigLayerFlags::NoExpand },
};

Processus de lecture de fichier

processus d'initialisation

Les fichiers de configuration ini lus sont mis en cache dans la variable globale GConfig.
insérez la description de l'image ici

Processus de lecture de fichier

insérez la description de l'image ici
Le principal consommateur de temps est les deux positions de configuration de lecture et de configuration d'écriture.

écriture de fichier

Une fois que l'UE a effectué la traversée hiérarchique mentionnée ci-dessus, il obtient un fichier de configuration qui prend effet en dernier. Il écrit le contenu de ce fichier dans le répertoire Saved.

Lire uniquement depuis Engine/Config, le sous-niveau n'a pas de fichiers écrasés et écrire dans Engine/Saved/Config. Sinon, écrivez dans [ProjectName]/Saved/Config. Notez que l'écriture ici n'écrit que la différence.

Pour l'écriture d'une propriété, si la valeur de cette propriété est la même que le CDO de sa classe, il n'est pas nécessaire de stocker plusieurs copies, et le fichier de configuration ne sera pas écrit.

Pour s'assurer que plusieurs copies des mêmes informations ne sont pas stockées dans les parcours, les opérations d'écriture impliquent plusieurs forparcours imbriqués. Si le fichier ini est très volumineux, ConfigFile.Writecette opération peut prendre beaucoup de temps.

Notre premier problème est donc résolu : le fichier dans le chemin avec Saved est écrit au moment de l'exécution, et le fichier sans Save est la configuration d'origine pour la lecture.

  1. Moteur/Configuration【Configuration d'origine】
  2. Engine/Saved/Config [écrire après que le moteur tourne]
  3. [Nom du projet]/Config【Configuration d'origine】
  4. [ProjectName]/Saved/Config [Écrire après l'exécution du projet]

Voici une question : Pourquoi avez-vous besoin d'écrire dans save lors de l'initialisation et du chargement du fichier ini ? Bien que l'UE ait effectué une comparaison dans l'opération d'écriture, s'il n'y a pas de différence avec le contenu de son propre niveau parent, il ne sera pas écrit dans le répertoire enregistré. Mais théoriquement, le contenu qui vient d'être chargé dans GConfig ne sera pas modifié lors du chargement initial

Contenu du fichier de configuration et structure GConfig

Ouvrez un fichier de configuration pour voir sa structure : la
insérez la description de l'image ici
structure de fichier d'un ConfigFile est résumée comme suit :
insérez la description de l'image ici
GConfig est également entièrement construit selon cette structure :
insérez la description de l'image ici
GConfig est un nom de fichier en tant que valeur de cléTMap<FString,FConfigFile> ; FConfigFile est un nom de section en tant que clé TMap<FString,FConfigSection>et FConfigSection est une paire clé-valeur sous chaque section.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_44559752/article/details/128242897
conseillé
Classement