using System; using System.Threading.Tasks; using UnityEngine; namespace MyInfoMate.Vr.Net { /// /// Le contenu d'un lieu, servi cache d'abord — item E4 du lot XR-4. /// /// Deux chemins, jamais mélangés : /// /// Au démarrage — le cache s'il existe, affiché tout de suite ; /// le réseau seulement s'il n'y a rien en cache. /// Ensuite — un rafraîchissement en tâche de fond, dont l'échec est /// silencieux : une borne hors ligne affiche son contenu de la veille, et /// ce n'est pas une erreur à montrer au visiteur. /// /// /// C'est aussi ce qui rendra la reprise après coupure gratuite : au redémarrage, le /// cache est déjà là. /// public class ContentService { readonly ApiClient _client; readonly string _configurationId; public ContentService(ApiClient client, string configurationId) { _client = client; _configurationId = configurationId; } public class Loaded { public ConfigurationExport Export; /// Vrai si le contenu vient du disque et non du serveur. public bool FromCache; /// Date du cache servi, pour l'afficher en mode dégradé. public DateTime? CachedAt; public string Error; public bool Ok => Error == null; } public async Task LoadAsync() { var cached = ContentCache.ReadExport(_configurationId); if (cached != null) { var parsed = ConfigurationExport.Parse(cached); if (parsed.Ok) return new Loaded { Export = parsed.Value, FromCache = true, CachedAt = ContentCache.ExportDate(_configurationId) }; // Un cache illisible est un cache mort : on ne le garde pas pour // rejouer le même échec au prochain démarrage. Debug.LogWarning("[Content] Cache illisible, il est écarté."); } return await FetchAsync(); } /// /// Rafraîchit le cache sans bloquer l'affichage. Renvoie le contenu neuf, ou null /// si rien n'a changé ou si le serveur n'a pas répondu — dans les deux cas /// l'appelant garde ce qu'il montre. /// public async Task RefreshAsync() { var before = ContentCache.ReadExport(_configurationId); var raw = await _client.GetRawAsync( $"/api/configuration/{_configurationId}/export"); if (!raw.Ok) { Debug.Log($"[Content] Rafraîchissement impossible ({raw.Error}) — " + "le contenu en cache reste affiché."); return null; } if (raw.Value == before) return null; var parsed = ConfigurationExport.Parse(raw.Value); if (!parsed.Ok) return null; ContentCache.WriteExport(_configurationId, raw.Value); return parsed.Value; } async Task FetchAsync() { var raw = await _client.GetRawAsync( $"/api/configuration/{_configurationId}/export"); if (!raw.Ok) return new Loaded { Error = raw.Error }; var parsed = ConfigurationExport.Parse(raw.Value); if (!parsed.Ok) return new Loaded { Error = parsed.Error }; ContentCache.WriteExport(_configurationId, raw.Value); return new Loaded { Export = parsed.Value }; } } }