Estrutura principal de front-end estilo Lyra portada para C++ proprio do ZMMO (sem CommonGame), seguindo o padrao C++ Abstract -> WBP concreto: - EZMMOFrontEndState / EZMMOLobbyPage e GameplayTags UI.Layer.* nativos - UUIActivatableScreen_Base: base de tela (input config, hook de tema, voltar) espelhando o padrao de UUIButton_Base - UUIPrimaryGameLayout_Base: switch principal (4 stacks CommonUI/camada) - UUIManagerSubsystem (LocalPlayer): dono do root layout, idempotente - UUIFrontEndFlowSubsystem (GameInstance): maquina de estados + driver de rede (Boot->Connecting->Login->ServerSelect->Lobby->EnteringWorld ->InWorld); Lobby e o hub logado, paginas internas = EZMMOLobbyPage - UUIFrontEndScreenSet (DataAsset): mapa estado->tela, forge-ready - AZMMOFrontEndGameMode + AZMMOFrontEndPlayerController - GameInstance: bAutoConnectOnStart=false (conexao dirigida pelo fluxo) - Build.cs: +GameplayTags; ARQUITETURA.md PR-first (s2.1/2.2/3.3/4.8/5) - Assets: L_FrontEnd (GameMode via World Settings), WBP_PrimaryGameLayout, DA_FrontEndScreenSet; Config wiring WBPs de pagina (Boot/Login/...) virao do Zeus UMG Forge depois (s4.8). Smoke test PIE OK: root layout no viewport, fluxo Boot->Connecting, no-op+log para telas nao configuradas, sem crash. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
110 lines
3.5 KiB
C++
110 lines
3.5 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Subsystems/GameInstanceSubsystem.h"
|
|
#include "UI/FrontEndTypes.h"
|
|
#include "UIFrontEndFlowSubsystem.generated.h"
|
|
|
|
class UUIFrontEndScreenSet;
|
|
class UUIManagerSubsystem;
|
|
class UZeusNetworkSubsystem;
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnZMMOFrontEndStateChanged, EZMMOFrontEndState, NewState);
|
|
|
|
/**
|
|
* Orquestrador do fluxo de front-end. UGameInstanceSubsystem porque o
|
|
* GameInstance persiste o travel boot→mundo (a máquina de estados não pode
|
|
* morrer no OpenLevel).
|
|
*
|
|
* Responsável por: (a) dirigir a conexão via UZeusNetworkSubsystem;
|
|
* (b) manter EZMMOFrontEndState; (c) resolver estado→tela pelo
|
|
* DA_FrontEndScreenSet e pedir ao UUIManagerSubsystem para empurrar na
|
|
* camada certa; (d) detectar a chegada ao mundo.
|
|
*
|
|
* As telas (WBP) ainda não existem — virão do Zeus UMG Forge (§4.8).
|
|
* Enquanto não registradas no DA, cada transição faz no-op + log.
|
|
*/
|
|
UCLASS(Config = Game)
|
|
class ZMMO_API UUIFrontEndFlowSubsystem : public UGameInstanceSubsystem
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
// USubsystem
|
|
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
|
virtual void Deinitialize() override;
|
|
|
|
/**
|
|
* Ponto de entrada chamado pelo AZMMOFrontEndPlayerController::BeginPlay
|
|
* (garante que os subsistemas já existem — ver aviso no header do
|
|
* ZeusNetworkSubsystem sobre GameInstance::Init). Cria o root layout,
|
|
* liga os delegates de rede e dispara Boot→Connecting.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category = "FrontEnd")
|
|
void StartFrontEnd();
|
|
|
|
UFUNCTION(BlueprintCallable, Category = "FrontEnd")
|
|
void SetState(EZMMOFrontEndState NewState);
|
|
|
|
UFUNCTION(BlueprintPure, Category = "FrontEnd")
|
|
EZMMOFrontEndState GetCurrentState() const { return CurrentState; }
|
|
|
|
/** Mostra uma página interna do Lobby ("switch principal"). */
|
|
UFUNCTION(BlueprintCallable, Category = "FrontEnd")
|
|
void ShowLobbyPage(EZMMOLobbyPage Page);
|
|
|
|
/** "Voltar". Retorna true se o fluxo consumiu (tela base encaminha aqui). */
|
|
UFUNCTION(BlueprintCallable, Category = "FrontEnd")
|
|
bool RequestBack();
|
|
|
|
UPROPERTY(BlueprintAssignable, Category = "FrontEnd")
|
|
FOnZMMOFrontEndStateChanged OnStateChanged;
|
|
|
|
protected:
|
|
/** DA com o mapa estado→tela. Config em DefaultGame.ini. */
|
|
UPROPERTY(Config, EditDefaultsOnly, Category = "FrontEnd")
|
|
TSoftObjectPtr<UUIFrontEndScreenSet> ScreenSetAsset;
|
|
|
|
private:
|
|
void BindNetwork();
|
|
void UnbindNetwork();
|
|
UZeusNetworkSubsystem* GetZeusNetwork() const;
|
|
UUIManagerSubsystem* GetUIManager() const;
|
|
UUIFrontEndScreenSet* GetScreenSet();
|
|
|
|
/** Resolve a soft class do estado e empurra na camada Menu (no-op+log se vazio). */
|
|
void ResolveAndPushScreen(EZMMOFrontEndState State);
|
|
|
|
UFUNCTION()
|
|
void HandleConnected();
|
|
|
|
UFUNCTION()
|
|
void HandleConnectionFailed(FString Reason);
|
|
|
|
UFUNCTION()
|
|
void HandleDisconnected();
|
|
|
|
UFUNCTION()
|
|
void HandleServerTravelRequested(const FString& MapName, const FString& MapPath);
|
|
|
|
void HandlePostLoadMap(UWorld* LoadedWorld);
|
|
|
|
/**
|
|
* Dívida técnica (D5): ServerHello traz ThemeId, mas o UZeusNetworkSubsystem
|
|
* ainda não expõe um delegate/getter dedicado. Quando expuser, ligar aqui
|
|
* → UZMMOThemeSubsystem::ApplyServerTheme. Sem isto, o tema resolve por
|
|
* calendário/Default (ARQUITETURA.md §1.10).
|
|
*/
|
|
void HandleServerHelloTheme(FName ThemeId);
|
|
|
|
UPROPERTY(Transient)
|
|
EZMMOFrontEndState CurrentState = EZMMOFrontEndState::None;
|
|
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UUIFrontEndScreenSet> ScreenSet;
|
|
|
|
bool bNetBound = false;
|
|
bool bTravelingToWorld = false;
|
|
FDelegateHandle PostLoadMapHandle;
|
|
};
|