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 { [Title("Game Modules", "List of game system modules in load order")] [ListDrawerSettings(DraggableItems = false, HideRemoveButton = true, ShowPaging = false)] [ShowInInspector, NonSerialized, OnValueChanged("StartModule")] public List modules = new List(); [OnInspectorInit("GetModuleNames"), OnValueChanged("AddNewModule")] [ValueDropdown("possibleModules", IsUniqueList = false)] [LabelText("Add New Module")] [NonSerialized] public GameModule newModule; [Title("Startup Configurations", "List of configurations to be set up when the game starts")] [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; } } } [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(); } } }