LifePlay-Revival/Docs/Migration/etat/sandbox/S4/S4-IMPL-H.md

151 lines
9.8 KiB
Markdown
Raw Normal View History

# 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`
```cpp
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.