using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ShiroginSDK.Runtime.Modules.Data.Scripts;
using ShiroginSDK.Runtime.Services.Base;
using ShiroginSDK.Runtime.Services.Interfaces;
using UnityEditor;
using UnityEngine;
namespace ShiroginSDK.Runtime.Services.Implementations.Data
{
///
/// Centralized data manager for ShiroginSDK.
/// Loads, caches, and manages all BaseData-derived classes.
///
public class DataService : ServiceBase, IDataService
{
private readonly Dictionary _dataCache = new();
// ----------------------------------------------------
// Accessors
// ----------------------------------------------------
public T Get() where T : BaseData
{
if (_dataCache.TryGetValue(typeof(T), out var data))
return data as T;
Debug.LogWarning($"[DataService] โ ๏ธ No data found for {typeof(T).Name}. Creating new instance...");
var newData = Activator.CreateInstance();
newData.Load();
_dataCache[typeof(T)] = newData;
return newData;
}
public void SaveAll()
{
foreach (var kvp in _dataCache)
kvp.Value.Save();
Debug.Log("[DataService] ๐พ All data saved.");
}
public void DeleteAll()
{
foreach (var kvp in _dataCache)
kvp.Value.Delete();
_dataCache.Clear();
Debug.Log("[DataService] ๐งน All data deleted.");
InitializeAllData();
}
public bool Exists() where T : BaseData
{
return Get()?.Exists() ?? false;
}
public string ToJson(bool pretty = true) where T : BaseData
{
var data = Get();
return data != null ? data.ToJson(pretty) : "{}";
}
// ----------------------------------------------------
// Initialization
// ----------------------------------------------------
protected override void OnInitialize()
{
InitializeAllData();
}
protected override void OnDispose()
{
_dataCache.Clear();
}
private void InitializeAllData()
{
var baseType = typeof(BaseData);
var derivedTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a =>
{
try
{
return a.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
return e.Types.Where(t => t != null);
}
})
.Where(t => t.IsClass && !t.IsAbstract && baseType.IsAssignableFrom(t));
var loaded = 0;
foreach (var type in derivedTypes)
try
{
if (_dataCache.ContainsKey(type))
continue;
var instance = Activator.CreateInstance(type) as BaseData;
instance?.Load();
_dataCache[type] = instance;
loaded++;
}
catch (Exception ex)
{
Debug.LogError($"[DataService] โ Failed to load {type.Name}: {ex.Message}");
}
Debug.Log($"[DataService] โ
Initialization complete โ {loaded} data classes loaded.");
}
#if UNITY_EDITOR
// ----------------------------------------------------
// Unity Editor Tools
// ----------------------------------------------------
[ContextMenu("๐ Copy Game Save (JSON)")]
private void CopyGameSaveToClipboard()
{
try
{
var gameData = Get();
if (gameData == null)
{
Debug.LogWarning("[DataService] No GameData found to copy.");
return;
}
gameData.Player = Get();
gameData.Economy = Get();
gameData.Store = Get();
gameData.Settings = Get();
gameData.Theme = Get();
gameData.Rewards = Get();
gameData.Device = Get();
gameData.Progression = Get();
gameData.Inventory = Get();
gameData.UpdateMeta();
var json = gameData.ToJson();
EditorGUIUtility.systemCopyBuffer = json;
Debug.Log($"[DataService] โ
GameData JSON copied ({json.Length} chars)");
}
catch (Exception ex)
{
Debug.LogError($"[DataService] CopyGameSaveToClipboard failed: {ex.Message}");
}
}
#endif
}
}