From 81f75d4e956b2018ceb4878b6be46ee414a3cfd7 Mon Sep 17 00:00:00 2001 From: edujiro5972 <336072401+edujiro5972@users.noreply.github.com> Date: Wed, 7 Oct 2026 15:49:05 +0200 Subject: [PATCH] =?UTF-8?q?G6b=20:=20PreloadCityPackages=20au=20d=C3=A9mar?= =?UTF-8?q?rage=20(LPDataCompat,=20LPModInfoSubsystem=20;=20rattrape=20Fin?= =?UTF-8?q?dCenterOfPolygon=20et=20le=20renommage=20ModInfoCheckInterval)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase G6b (CHG-116). Co-Authored-By: Claude Opus 5.5 --- Source/LifePlay/LPDataCompat.cpp | 92 ++++++++++++++++++++++++++ Source/LifePlay/LPDataCompat.h | 16 +++++ Source/LifePlay/LPModInfoSubsystem.cpp | 8 ++- 3 files changed, 114 insertions(+), 2 deletions(-) diff --git a/Source/LifePlay/LPDataCompat.cpp b/Source/LifePlay/LPDataCompat.cpp index b7a10c5..32ed2d3 100644 --- a/Source/LifePlay/LPDataCompat.cpp +++ b/Source/LifePlay/LPDataCompat.cpp @@ -2,6 +2,7 @@ #include "LPDataCompat.h" +#include "Engine/StreamableManager.h" #include "Kismet/KismetStringLibrary.h" #include "LifePlay.h" #include "LPStringCompat.h" @@ -185,3 +186,94 @@ void ULPDataCompat::WhatWhereToArray(UObject* Target, const FString& Line, TArra It->DestroyValue_InContainer(Params); } } + +namespace +{ + FMapProperty* FindAreasMap(const UObject* GI) + { + if (!GI) + { + return nullptr; + } + for (TFieldIterator It(GI->GetClass()); It; ++It) + { + if (It->GetAuthoredName() == TEXT("Areas")) + { + return *It; + } + } + return nullptr; + } +} + +void ULPDataCompat::FindCenterOfPolygon(UObject* Target, const TArray& 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(BuildingPoints[0].X); + MinY = MaxY = static_cast(BuildingPoints[0].Y); + for (const FVector2D& Point : BuildingPoints) + { + const float X = static_cast(Point.X); + const float Y = static_cast(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(MinX) + static_cast(MaxX)) / 2.0; + Center.Y = (static_cast(MinY) + static_cast(MaxY)) / 2.0; + Area = FMath::Abs(static_cast(MaxX) - static_cast(MinX)) + * FMath::Abs(static_cast(MaxY) - static_cast(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(Areas->KeyProp); + if (!KeyStruct || KeyStruct->Struct != TBaseStructure::Get()) + { + UE_LOG(LogLifePlay, Error, TEXT("FindCenterOfPolygon : GI.Areas n'est pas indexe par Vector2D")); + return; + } + + FScriptMapHelper Helper(Areas, Areas->ContainerPtrToValuePtr(Target)); + if (const FDoubleProperty* AsDouble = CastField(Areas->ValueProp)) + { + (void)AsDouble; + Helper.AddPair(&Center, &Area); + } + else if (CastField(Areas->ValueProp)) + { + const float AreaFloat = static_cast(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 Handle; + if (Handle.IsValid()) + { + return; + } + const TArray 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")); +} diff --git a/Source/LifePlay/LPDataCompat.h b/Source/LifePlay/LPDataCompat.h index ccc33cb..a6f4dea 100644 --- a/Source/LifePlay/LPDataCompat.h +++ b/Source/LifePlay/LPDataCompat.h @@ -27,4 +27,20 @@ public: /** Implementation pure (sans verification), exposee pour les tests. */ static TArray 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& 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(); }; diff --git a/Source/LifePlay/LPModInfoSubsystem.cpp b/Source/LifePlay/LPModInfoSubsystem.cpp index 4c2e267..b856010 100644 --- a/Source/LifePlay/LPModInfoSubsystem.cpp +++ b/Source/LifePlay/LPModInfoSubsystem.cpp @@ -9,6 +9,7 @@ #include "HAL/FileManager.h" #include "HAL/PlatformTime.h" #include "LifePlay.h" +#include "LPDataCompat.h" #include "Misc/FileHelper.h" #include "Misc/Paths.h" #include "Styling/CoreStyle.h" @@ -22,7 +23,7 @@ namespace { - constexpr double CheckInterval = 2.0; + constexpr double ModInfoCheckInterval = 2.0; 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; } 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) { TickHandle = FTSTicker::GetCoreTicker().AddTicker(FTickerDelegate::CreateUObject(this, &ULPModInfoSubsystem::Tick)); @@ -124,7 +128,7 @@ bool ULPModInfoSubsystem::Tick(float DeltaTime) { return true; } - NextCheck = Now + CheckInterval; + NextCheck = Now + ModInfoCheckInterval; TArray Lines; for (const TPair>& Pair : Metadata) {