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:
parent
7b5e1a5179
commit
81f75d4e95
3 changed files with 114 additions and 2 deletions
|
|
@ -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<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"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,4 +27,20 @@ public:
|
|||
|
||||
/** Implementation pure (sans verification), exposee pour les tests. */
|
||||
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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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<FString> Lines;
|
||||
for (const TPair<FString, TMap<FString, FString>>& Pair : Metadata)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue