Programación
Utilizar un almacén de progreso propio
Implementa IProgressStore, instálalo antes de la inicialización, respeta su contrato de validación y gestiona los resultados de las operaciones.
Implementar cuatro operaciones de clave exacta
IProgressStore define TryRead, Write, Delete y Flush. El Manager proporciona claves completas y opacas. El adaptador no debe interpretarlas, cambiarles el prefijo, enumerarlas ni mezclarlas con las ranuras del sistema de partida.
Una clave ausente devuelve false y un string vacío. Un valor vacío guardado devuelve true. Las claves null producen ArgumentNullException; vacías o con espacios, ArgumentException; Write también rechaza un valor null.
Instalar el proveedor antes del bloqueo
Llama a TrySetProgressStore antes de leer, escribir, restaurar, borrar, confirmar o iniciar la progresión. Success sustituye el proveedor sin copiar ni modificar datos. Un valor null devuelve StoreUnavailable; una llamada tardía, ManagerAlreadyInitialized.
Un proveedor del Inspector debe ser un MonoBehaviour que implemente la interfaz. Si no se asigna se utiliza PlayerPrefs. V1 llama desde el hilo principal y no exige seguridad multihilo.
No ocultar fallos del almacenamiento
- Write crea o sustituye sin llamar a Flush.
- Delete indica si existía y tampoco confirma automáticamente.
- Flush confirma lo pendiente, pero no captura nuevo progreso.
- Las excepciones se convierten en StoreError.
- Un esquema más nuevo devuelve UnsupportedSchema.
Si el proveedor real es asíncrono, acumula operaciones limitadas y define una frontera de confirmación compatible, o conserva esa persistencia fuera de este adaptador. No bloquees el hilo principal con red sin límite.
Pruebas del proveedor
- 1Distingue clave ausente y valor vacío.
- 2Escribe dos veces y comprueba que sustituye.
- 3Elimina una clave existente y otra ausente: true y false.
- 4Comprueba que Write/Delete no llaman a Flush y una sola llamada confirma el conjunto.
- 5Provoca fallos de cada operación y exige StoreError.
- 6Ejecuta la prueba de restauración y confirma que no se repiten eventos históricos.
Confirmar el progreso en un punto de guardado
- Dónde colocarlo
- Añade este método al coordinador de guardado o al controlador de puntos de control del proyecto.
- Cuándo llamarlo
- Llama a FlushAtSavePoint después de cambios de progreso aceptados o antes de una salida controlada.
- Comportamiento
- FlushProgress solo confirma el almacén de progresión configurado; no serializa escenas, inventarios ni GameObjects arbitrarios.
using System;
using System.Collections;
using System.Collections.Generic;
using OverFuture.ChapterObjectiveSystem.Chapters;
using OverFuture.ChapterObjectiveSystem.Events;
using OverFuture.ChapterObjectiveSystem.Objectives;
using OverFuture.ChapterObjectiveSystem.Persistence;
using OverFuture.ChapterObjectiveSystem.Progression;
using UnityEngine;
public sealed class FlushProgressExample : MonoBehaviour
{
public ProgressOperationResult FlushAtSavePoint()
{
ChapterManager manager = ChapterManager.Instance;
return manager != null
? manager.FlushProgress()
: ProgressOperationResult.StoreUnavailable;
}
}
Implementar un IProgressStore personalizado
- Dónde colocarlo
- Coloca el almacén en el ensamblado de guardado del proyecto y pasa una instancia a TrySetProgressStore antes de que la inicialización bloquee la configuración.
- Cuándo llamarlo
- El Manager llama a las operaciones de clave exacta desde el hilo principal de Unity; Flush solo se invoca en puntos explícitos.
- Comportamiento
- El ejemplo en memoria demuestra el contrato, pero no conserva datos entre sesiones. Sustituye el almacenamiento y Flush por tu sistema sin interpretar ni reescribir las claves opacas.
using System;
using System.Collections;
using System.Collections.Generic;
using OverFuture.ChapterObjectiveSystem.Chapters;
using OverFuture.ChapterObjectiveSystem.Events;
using OverFuture.ChapterObjectiveSystem.Objectives;
using OverFuture.ChapterObjectiveSystem.Persistence;
using OverFuture.ChapterObjectiveSystem.Progression;
using UnityEngine;
public sealed class MemoryProgressStore : IProgressStore
{
private readonly Dictionary<string, string> values =
new Dictionary<string, string>(StringComparer.Ordinal);
public bool TryRead(string key, out string value)
{
ValidateKey(key);
if (values.TryGetValue(key, out value))
{
return true;
}
value = string.Empty;
return false;
}
public void Write(string key, string value)
{
ValidateKey(key);
values[key] = value ?? throw new ArgumentNullException(nameof(value));
}
public bool Delete(string key)
{
ValidateKey(key);
return values.Remove(key);
}
public void Flush()
{
// Persist pending data in the project-specific backend here.
}
private static void ValidateKey(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("A progress key cannot be empty.", nameof(key));
}
}
}