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 } }