LifePlay-Revival/Docs/Migration/etat/sandbox/S4/S4-IMPL-H.md
edujiro5972 04b053554f Sandbox addon : brancher le jeu sur LifePlay-Sandbox (plugin LPSandbox).
Charge le plugin via AdditionalPluginDirectories, conserve ShowCouple et les commandlets anim côté jeu, et documente les lots S0–S8 (CHG-212 à CHG-220).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-06 21:10:53 +02:00

9.8 KiB

S4-IMPL-H — Découpe de LPPairSandbox.cpp (fiche S4-T2)

  • Date : 2026-10-06
  • Fiche : S4-T2 | Agent : A-IMPL-H | Rôle : Implémentation
  • Modèle prévu : claude-opus-5-thinking-high (M3)
  • Amont : S4/S4-CART.md (S4-T1, lecture seule)
  • Statut : compilé — LPSandboxEditor et LPSandbox Win64 Development, 0 erreur / 0 avertissement
  • Commit addon : 32ad09c — S4-T2: decoupe de LPPairSandbox.cpp en 7 unites de traduction

Le repo jeu n'est pas modifié par cette fiche, hors ce document. Tout le code vit dans D:\Game\LifePlay-Sandbox\Plugins\LPSandbox\Source\LPSandbox\. LPInteractionSandbox.* (legacy, 441 LOC) n'est pas touché : sa suppression est le lot S4-T3.


1. Résultat : LOC par fichier

Avant : LPPairSandbox.cpp = 4274 lignes, LPPairSandbox.h = 322.

Fichier LOC Contenu
LPPairSandbox.h 332 UCLASS inchangées + 3 déclarations privées + 4 déclarations anticipées
LPPairSandboxMenu.h 73 FPairSandboxMenu, PairSandboxMenu::FindChoice / MakeCombo
LPSandboxActionVM.h 55 PairSandbox::FAction / FPerson, extern des globales, 4 prototypes
LPSandboxRoomBuilder.cpp 316 .lpworld (Token, FProp, LoadWorldFile), Stage::Build (mobilier, murs, éclairage)
LPCoupleSim.cpp 477 PlayIdle, ConfigureCapsule, Weld, Apply, Toggle*, PlayPair, MoveCouple, FitCoupleBox, LoadQuaternius, SelectBody, ApplyBody, RefreshPose, PlayWalk
LPSandboxActionVM.cpp 647 Tokenize, FWhoEval, WhoAllows, WhereHas, LoadActions, ReadInteractKey, CollectActions
LPSandboxInteraction.cpp 493 LoadChat, BeginInteraction, ApplyFilters, ApplyInteractionView, ShowChat / HideChat, pastille de touche, BuildFilterPanel
LPSandboxMeasure.cpp 837 EndMeasure, BeginMeasure, ReplayMeasure, ShowBestModel, caméras fixes et libre, DrawMeasureFigures, ScoreMeasureViews, BuildMeasurePanel
LPSandboxMeasureTour.cpp 743 PairSandboxAuto, Toggle{Raw,Formula,T}, SetAutoRun, TickAuto, PairSandboxTour, clips et navigation, StartTour / TickTour, vignettes, planches, TickMeasureInput
LPPairSandbox.cpp 807 constructeurs, Possess, SetStage, EndPlay, ResetView, Select*, ShowAnimMenu, Tick, GameMode
  • Plus gros fichier : 837 LOC (LPSandboxMeasure.cpp), sous l'objectif de ~900.
  • Trois fichiers dépassent le seuil souple de 800 (837, 807) ; les ramener sous 800 imposerait de couper BeginMeasure (374 lignes) et ShowAnimMenu (277 lignes après extraction) au-delà du découpage « pragmatique » demandé.
  • Total du module : 4274 → 4320 lignes de code déplacé + 240 lignes d'en-têtes et d'includes répétés.

2. Écart assumé avec la fiche : 7 unités au lieu de 5 (+1)

La fiche demandait 5 unités, avec autorisation de scinder Mesure en deux si elle dépassait 900. Deux scissions ont été nécessaires, pour une raison arithmétique :

Unité telle que définie par la fiche LOC si non scindée
Mesure (BeginMeasure … draw + panneau + touches) ~1570 → scindée en 837 + 743 (prévu par la fiche)
Interaction (VM lpaction + catalogue + chat + mode + filtres) ~1140 → scindée en 647 (ActionVM) + 493 (Interaction)

La scission d'Interaction suit le fichier que la fiche nommait elle-même comme en-tête optionnel (LPSandboxActionVM.h) : l'en-tête a été créé et son .cpp, parce que le corps de l'évaluateur (Tokenize + FWhoEval + filtrage du catalogue, 592 lignes) n'a aucune raison d'être inline. La frontière est nette : LPSandboxActionVM.* ne connaît ni UE Slate, ni les classes de la sandbox — c'est du code libre, testable isolément.

Les 5 noms de fichiers demandés existent tous et portent le contenu demandé.

3. Ce qui n'a pas bougé

  • Aucune UCLASS déplacée. Les 3 classes restent déclarées dans LPPairSandbox.h, donc UHT ne voit aucun changement de réflexion (Reflection code generated : 1 fichier, comme avant).
  • Aucun corps de fonction réécrit. Le découpage a été fait par extraction de plages de lignes : un diff ligne à ligne entre l'original et l'union des nouveaux fichiers ne remonte que 13 lignes retirées et 33 ajoutées, toutes listées au §4.
  • LPSandbox.Build.cs est inchangé : UBT ramasse les nouveaux .cpp du dossier plat.
  • LPInteractionSandbox.* (doublon connu de LoadChat / ShowChat / HideChat) est intact : lot S4-T3.

4. Les seules modifications de code (liste exhaustive)

4.1. Trois méthodes privées ajoutées à LPPairSandbox.h

TSharedRef<SWidget> BuildMeasurePanel(TSharedPtr<SVerticalBox>& OutHolder);
TSharedRef<SWidget> BuildFilterPanel(TSharedPtr<SBox>& OutHolder);
void TickMeasureInput(APlayerController* PC, ALPPairSandboxStage* Room, float DeltaSeconds, float DX, float DY);

Elles sortent trois blocs contigus de ShowAnimMenu (576 lignes) et de Tick (301 lignes), qui à eux seuls auraient laissé LPPairSandbox.cpp à ~1220 LOC. Elles restent membres : le panneau des filtres construit des cases à cocher sur des pointeurs sur membres privés (&ALPPairSandboxCharacter::bWho1Married), ce qu'une fonction libre ne peut pas faire (risque n° 3 de la cartographie). Déclarations anticipées ajoutées : APlayerController, SBox, SVerticalBox.

Les corps appelants gardent la forme d'origine :

Avant (ligne d'origine) Après
SAssignNew(MeasureHolder, SVerticalBox) … (3706-3822) BuildMeasurePanel(MeasureHolder)
SAssignNew(FilterHolder, SBox) … (3845-3878) BuildFilterPanel(FilterHolder)
if (bMeasure && Room) { … } (4125-4211) if (bMeasure && Room) { TickMeasureInput(PC, Room, DeltaSeconds, DX, DY); }

Les holders restent des variables locales de ShowAnimMenu, recopiées ensuite dans Menu->MeasureRow / Menu->FilterRow comme avant : l'ordre d'évaluation de l'arbre Slate est identique.

4.2. Deux lambdas locales devenues fonctions libres

FindChoice et MakeCombo (lignes 3512-3545) servaient à 9 listes déroulantes, dont 7 partent dans BuildFilterPanel. Elles deviennent PairSandboxMenu::FindChoice / MakeCombo dans LPPairSandboxMenu.h, corps inchangé. MakeCombo capturait Self sans l'utiliser : la capture inutile disparaît. Les 9 appels sont simplement qualifiés.

4.3. Globales du catalogue

PairSandbox::Catalog, PlaceChoices, WhenChoices restent définies une seule fois (LPSandboxActionVM.cpp) et sont déclarées extern dans LPSandboxActionVM.h (risque n° 2 de la cartographie). ShowAnimMenu les lit toujours directement.

4.4. Namespaces de constantes

PairSandboxAuto et PairSandboxTour n'ont pas eu besoin d'un en-tête partagé (risque n° 1 de la cartographie) : après ce découpage, leurs quatre consommateurs (TickAuto, StartTour, TickTour, SaveVignette / WritePlanche) vivent tous dans LPSandboxMeasureTour.cpp. C'est ce qui a dicté la frontière Mesure / MesureTour : LPSandboxMeasure.cpp ne référence aucune des deux. Le static bool bPoseWritten de ShowFormulaDefault reste unique, dans le même fichier (risque n° 4).

5. Compilation

Cible Mode d'unité Résultat
LPSandboxEditor Win64 Development non-unity (7 .cpp exclus du blob, car dans le working set git) succès, 0 avertissement
LPSandbox Win64 Development (Game) non-unity succès, Binaries/Win64/LPSandbox.exe
LPSandboxEditor Win64 Development unity (-Rebuild après commit) succès, 0 avertissement

Les deux modes ont été vérifiés (risque n° 5 de la cartographie) : la première compilation, faite avant le commit, a traité chaque nouveau .cpp isolément, ce qui prouve que les blocs #include de chaque unité se suffisent à eux-mêmes ; le -Rebuild après commit valide le chemin unity. Aucun include n'a dû être corrigé : la compilation est passée du premier coup.

6. Vérification « zéro changement de comportement »

Contrôle automatisé : comparaison du multiensemble des lignes de code (hors #include, commentaires, accolades et crochets seuls) entre l'original et l'union des 9 fichiers produits.

  • 13 lignes de l'original absentes : les 2 déclarations de lambdas FindChoice / MakeCombo, les 9 lignes d'appel à ces lambdas (requalifiées), les 2 SAssignNew(…Holder, …) (devenus SAssignNew(OutHolder, …)).
  • 33 lignes nouvelles : les 9 appels requalifiés, 2 TWeakObjectPtr Self(this), les 3 signatures des méthodes extraites et leurs 3 appels, 2 #pragma once, 2 ouvertures de namespace, et les 12 lignes de déclaration de LPSandboxActionVM.h / LPPairSandboxMenu.h.

Tout le reste du fichier d'origine — y compris l'ordre des blocs de Tick (souris, déplacement, interaction, Échap, mesure, libellés), qui était le risque n° 7 — est recopié à l'octet près.

7. Reste à faire

  • S4-T3 : supprimer LPInteractionSandbox.* (441 LOC), doublon de LoadChat / ShowChat / HideChat désormais isolés dans LPSandboxInteraction.cpp. Penser au GameMode /Script/LPSandbox.LPInteractionGameMode référencé par Tools/debug/LifePlay_interaction_sandbox.bat.
  • Validation d'exécution (S4-VAL) : non faite ici. Lancer les 3 modes (Pair, Interaction, Mesure) et comparer Saved/Measurement/tour.csv et une vignette avant / après, comme le recommande S4-CART.md §6.7.
  • Si le seuil souple de 800 LOC devient contraignant : découper BeginMeasure (RunMeasureClip, SpawnMeasureCameras) et ShowAnimMenu, ce qui ferait passer Mesure et l'orchestrateur sous 700.