Presenter reference
There is one instance of each presenter for the whole app. Inject the interface into a view registered by your scene scope.
| Presenter | Namespace (SilverTiger.ProjectV.Unity.Presentation.*) | Used by |
|---|---|---|
IProjectVStartupPresenter | .Startup | Login: admission, session restore, hydration |
IProjectVAuthenticationPresenter | .Authentication | Login: Guest, password, Google, Apple |
IProjectVAccountPresenter | .Account | Account popup: logout, account deletion |
IProjectVLobbyPresenter | .Lobby | Lobby profile |
IProjectVHeaderPresenter | .Header | Top bar: currencies, stamina countdown |
IProjectVCharacterPresenter | .Character | Characters, skills, equipment, skins, items |
IProjectVAlliancePresenter | .Alliance | Ally selection |
IProjectVCampaignPresenter | .Campaign | Mission list, stars, entry |
IProjectVShopPresenter | .Shop | Offers and purchases |
IProjectVGameplayDataPresenter | .Gameplay | Mission scene: start data and settlement |
Types shared by several presenters (recovery state, transaction confirmation, errors, typed IDs, UI-binding helpers) are on Shared types.
Prefer the screen contract
Lobby, Character, Alliance, Campaign and Shop also have a
screen contract (IProjectVLobbyScreen and so on). A page
observes one view and calls commands. Use the presenter only for what the
contract does not cover yet.
The common shape​
Every screen presenter follows the same pattern:
ProjectVXxxSnapshot Current { get; } // latest snapshot, never null
Task<IDisposable> SubscribeAsync(Action<ProjectVXxxSnapshot> listener); // current value, then every change
Task<ProjectVXxxCommandResult> RefreshAsync(CancellationToken token); // where the screen has data
Task<ProjectVXxxCommandResult> SomeCommandAsync(..., CancellationToken token);
- A snapshot carries a
Statusenum, the screen data (ornullbefore it loads), anError(ornull) and, on data screens, aProjectVScreenRecoveryStateRecovery. - A command result carries
SnapshotandIsSuccess. Always render the snapshot, even on failure; the previous usable data is kept. - A presenter listener may run off the Unity main thread. Switch to the main
thread before touching Unity objects (for example with UniTask's
await UniTask.SwitchToMainThread()). Screen contracts do this for you. - Exceptions mean a programming or lifecycle error (bad argument, wrong
scene). Expected backend failures are values in
Error.
Errors by presenter​
| Presenter | Error type | Show the player |
|---|---|---|
| Startup, Authentication, Account, Lobby | ProjectV*Error | LocalizationKey (for example projectv.startup.network) through your localization |
| Character, Alliance, Campaign, Shop | ProjectV*Error | SafeMessage (already safe for players) |
| Gameplay data | ProjectVGameplayDataResult | SafeMessage; keep ErrorCode for logs |
All error types expose Category (ProjectVBackendErrorCategory), Code
and, where the server returned one, RequestId for support.