G6b : PreloadCityPackages au démarrage (LPDataCompat, LPModInfoSubsystem ; rattrape FindCenterOfPolygon et le renommage ModInfoCheckInterval)

Phase G6b (CHG-116).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
edujiro5972 2026-10-07 15:49:05 +02:00
parent 7b5e1a5179
commit 81f75d4e95
3 changed files with 114 additions and 2 deletions

View file

@ -2,6 +2,7 @@
#include "LPDataCompat.h" #include "LPDataCompat.h"
#include "Engine/StreamableManager.h"
#include "Kismet/KismetStringLibrary.h" #include "Kismet/KismetStringLibrary.h"
#include "LifePlay.h" #include "LifePlay.h"
#include "LPStringCompat.h" #include "LPStringCompat.h"
@ -185,3 +186,94 @@ void ULPDataCompat::WhatWhereToArray(UObject* Target, const FString& Line, TArra
It->DestroyValue_InContainer(Params); It->DestroyValue_InContainer(Params);
} }
} }
namespace
{
FMapProperty* FindAreasMap(const UObject* GI)
{
if (!GI)
{
return nullptr;
}
for (TFieldIterator<FMapProperty> It(GI->GetClass()); It; ++It)
{
if (It->GetAuthoredName() == TEXT("Areas"))
{
return *It;
}
}
return nullptr;
}
}
void ULPDataCompat::FindCenterOfPolygon(UObject* Target, const TArray<FVector2D>& BuildingPoints, FVector2D& Center, double& Area)
{
// Le graphe copie X et Y dans des tableaux de float (MinOfFloatArray), puis calcule en double.
float MinX = 0.f, MaxX = 0.f, MinY = 0.f, MaxY = 0.f;
if (BuildingPoints.Num() > 0)
{
MinX = MaxX = static_cast<float>(BuildingPoints[0].X);
MinY = MaxY = static_cast<float>(BuildingPoints[0].Y);
for (const FVector2D& Point : BuildingPoints)
{
const float X = static_cast<float>(Point.X);
const float Y = static_cast<float>(Point.Y);
MinX = FMath::Min(MinX, X);
MaxX = FMath::Max(MaxX, X);
MinY = FMath::Min(MinY, Y);
MaxY = FMath::Max(MaxY, Y);
}
}
Center.X = (static_cast<double>(MinX) + static_cast<double>(MaxX)) / 2.0;
Center.Y = (static_cast<double>(MinY) + static_cast<double>(MaxY)) / 2.0;
Area = FMath::Abs(static_cast<double>(MaxX) - static_cast<double>(MinX))
* FMath::Abs(static_cast<double>(MaxY) - static_cast<double>(MinY))
/ 1000.0;
FMapProperty* Areas = FindAreasMap(Target);
if (!Areas)
{
UE_LOG(LogLifePlay, Error, TEXT("FindCenterOfPolygon : GI.Areas introuvable sur %s"), *GetNameSafe(Target));
return;
}
const FStructProperty* KeyStruct = CastField<FStructProperty>(Areas->KeyProp);
if (!KeyStruct || KeyStruct->Struct != TBaseStructure<FVector2D>::Get())
{
UE_LOG(LogLifePlay, Error, TEXT("FindCenterOfPolygon : GI.Areas n'est pas indexe par Vector2D"));
return;
}
FScriptMapHelper Helper(Areas, Areas->ContainerPtrToValuePtr<void>(Target));
if (const FDoubleProperty* AsDouble = CastField<FDoubleProperty>(Areas->ValueProp))
{
(void)AsDouble;
Helper.AddPair(&Center, &Area);
}
else if (CastField<FFloatProperty>(Areas->ValueProp))
{
const float AreaFloat = static_cast<float>(Area);
Helper.AddPair(&Center, &AreaFloat);
}
else
{
UE_LOG(LogLifePlay, Error, TEXT("FindCenterOfPolygon : valeur de GI.Areas ni float ni double"));
}
}
void ULPDataCompat::PreloadCityPackages()
{
// Le handle doit vivre : sinon le fluxable libere le paquet avant le clic Continuer.
static FStreamableManager Manager;
static TSharedPtr<FStreamableHandle> Handle;
if (Handle.IsValid())
{
return;
}
const TArray<FSoftObjectPath> Paths = {
FSoftObjectPath(TEXT("/Game/Heavy/StreetMap/Static/CentralLondon.CentralLondon")),
FSoftObjectPath(TEXT("/Game/Heavy/StreetMap/CentralLondon.CentralLondon")),
};
Handle = Manager.RequestAsyncLoad(Paths, FStreamableDelegate(), FStreamableManager::AsyncLoadHighPriority);
UE_LOG(LogLifePlay, Display, TEXT("Preload ville : %s"), Handle.IsValid() ? TEXT("demande envoyee") : TEXT("echec"));
}

View file

@ -27,4 +27,20 @@ public:
/** Implementation pure (sans verification), exposee pour les tests. */ /** Implementation pure (sans verification), exposee pour les tests. */
static TArray<FString> ComputeWhatWhere(const UObject* GI, const FString& Line); static TArray<FString> ComputeWhatWhere(const UObject* GI, const FString& Line);
/**
* Equivalent C++ de GI::FindCenterOfPolygon (centre de la boite englobante, pas le centroide).
* Appelee une fois par batiment au chargement de la ville (49 425 fois, 0,74 s inclus dans la trace
* Development du 2026-10-04). Meme resultat que le graphe : coordonnees ramenees en float avant
* min/max, centre = milieu de la boite, aire = |dx| * |dy| / 1000, puis GI.Areas[centre] = aire.
*/
UFUNCTION(BlueprintCallable, Category = "LifePlay|Compat", meta = (DefaultToSelf = "Target", HidePin = "Target"))
static void FindCenterOfPolygon(UObject* Target, const TArray<FVector2D>& BuildingPoints, FVector2D& Center, double& Area);
/**
* Demarre la lecture des paquets de la ville (maillage statique et donnees StreetMap) avant le
* clic Continuer. Separer du correctif FindCenterOfPolygon : la trace I6 attribuait ~164 Mo a
* l'image de plusieurs secondes ; ces deux paquets sont ceux que le canal loadtime nomme.
*/
static void PreloadCityPackages();
}; };

View file

@ -9,6 +9,7 @@
#include "HAL/FileManager.h" #include "HAL/FileManager.h"
#include "HAL/PlatformTime.h" #include "HAL/PlatformTime.h"
#include "LifePlay.h" #include "LifePlay.h"
#include "LPDataCompat.h"
#include "Misc/FileHelper.h" #include "Misc/FileHelper.h"
#include "Misc/Paths.h" #include "Misc/Paths.h"
#include "Styling/CoreStyle.h" #include "Styling/CoreStyle.h"
@ -22,7 +23,7 @@
namespace namespace
{ {
constexpr double CheckInterval = 2.0; constexpr double ModInfoCheckInterval = 2.0;
FString FieldText(const UStruct* Struct, const void* Data, const TCHAR* AuthoredName) FString FieldText(const UStruct* Struct, const void* Data, const TCHAR* AuthoredName)
{ {
@ -70,6 +71,9 @@ void ULPModInfoSubsystem::Initialize(FSubsystemCollectionBase& Collection)
WithGameVersion += Keys.Contains(TEXT("MODULE_GAME_VERSION")) ? 1 : 0; WithGameVersion += Keys.Contains(TEXT("MODULE_GAME_VERSION")) ? 1 : 0;
} }
UE_LOG(LogLifePlay, Display, TEXT("Modules : %d .lpmod lu(s), %d avec MODULE_GAME_VERSION (jeu %s)"), Metadata.Num(), WithGameVersion, *GameVersion); UE_LOG(LogLifePlay, Display, TEXT("Modules : %d .lpmod lu(s), %d avec MODULE_GAME_VERSION (jeu %s)"), Metadata.Num(), WithGameVersion, *GameVersion);
// Lot separe du correctif FindCenterOfPolygon : lancer la lecture des ~164 Mo de la ville
// des l'instance de jeu, pas dans l'image du clic Continuer.
ULPDataCompat::PreloadCityPackages();
if (WithGameVersion > 0) if (WithGameVersion > 0)
{ {
TickHandle = FTSTicker::GetCoreTicker().AddTicker(FTickerDelegate::CreateUObject(this, &ULPModInfoSubsystem::Tick)); TickHandle = FTSTicker::GetCoreTicker().AddTicker(FTickerDelegate::CreateUObject(this, &ULPModInfoSubsystem::Tick));
@ -124,7 +128,7 @@ bool ULPModInfoSubsystem::Tick(float DeltaTime)
{ {
return true; return true;
} }
NextCheck = Now + CheckInterval; NextCheck = Now + ModInfoCheckInterval;
TArray<FString> Lines; TArray<FString> Lines;
for (const TPair<FString, TMap<FString, FString>>& Pair : Metadata) for (const TPair<FString, TMap<FString, FString>>& Pair : Metadata)
{ {