using System; using System.Linq; using System.Collections; using System.Collections.Generic; using UnityEngine; using Sirenix.OdinInspector; using KairoEngine.Core; using KairoEngine.Core.ConfigOptions; using UniRx; namespace KairoEngine.Core.ModuleSystem { [CreateAssetMenu(fileName = "GameConfig", menuName = "KairoEngine/GameConfig"), HideMonoScript] public class GameConfig : ScriptableObject, ISerializationCallbackReceiver { [OnInspectorInit("GetApplicationName"), ReadOnly] public string applicationName; [OnInspectorInit("GetAppVersion"), ReadOnly] public string appVersion; [ListDrawerSettings(DraggableItems = true, HideRemoveButton = false, ShowPaging = false, ListElementLabelName = "@name", HideAddButton = true)] [ShowInInspector, NonSerialized, OnValueChanged("StartModule"), LabelText("Game Modules")] public List modules = new List(); [OnInspectorInit("GetModuleNames"), OnValueChanged("AddNewModule")] [ValueDropdown("possibleModules", IsUniqueList = false)] [LabelText("Add New Module")] [NonSerialized, PropertySpace(0, 8)] public GameModule newModule; [InlineProperty, HideLabel] public ConfigOptionsManager configOptions = new ConfigOptionsManager(); private void StartModule() { foreach (var module in modules) { if(module.isInitialized == false) { module.isInitialized = true; module.gameConfig = this; } } } private string GetApplicationName() => applicationName = Application.productName; private string GetAppVersion() => appVersion = Application.version; [NonSerialized] private IEnumerable possibleModules = new ValueDropdownList(); private void GetModuleNames() { possibleModules = ReflectiveEnumerator.GetEnumerableOfType(this) .Where(x => x.typeName != "GameModule") .Where(x => x.typeName != "GameModuleBase") .Select(x => new ValueDropdownItem(x.name, x)); } private void AddNewModule() { for (int i = 0; i < modules.Count; i++) { if(modules[i].name == newModule.name) { newModule = null; return; } } if(newModule != null) { modules.Add(newModule); newModule = null; } } [SerializeField, HideInInspector] private List serializedModules = new List(); [SerializeField, HideInInspector] private ObjectSerializer serializer = new ObjectSerializer(); public void OnBeforeSerialize() { if(modules == null) return; serializedModules = new List(); serializer.Clear(); for (int i = 0; i < modules.Count; i++) { modules[i].OnBeforeSerialize(serializer); string data = JsonUtility.ToJson(modules[i]); serializedModules.Add(data); } } public void OnAfterDeserialize() { if(serializedModules == null) return; if(modules == null) modules = new List(); if(modules.Count > 0) modules.Clear(); for (int i = 0; i < serializedModules.Count; i++) { GameModule module= null; try { module = JsonUtility.FromJson(serializedModules[i]); } catch (System.Exception e) { Debug.LogError($"Could not deserialize GameModule: \n{e}"); } if(module == null) continue; module = GameModule.InvokeStringMethod(module.className, module.typeName, serializedModules[i]); if(module == null) continue; module.gameConfig = this; module.OnBeforeDeserialize(serializer); modules.Add(module); } serializer.Clear(); serializedModules.Clear(); } } }