using System.Collections.Generic; using Godot; public partial class GlobalManager : Node { private static readonly Logging.Logger logger = Logging.GetLogger("GlobalManager"); public static GlobalManager Instance { get; private set; } = null!; public static string ConfigPath { get; private set; } = "user://config.json"; private GlobalManager() { ConfigManager.SetFilePath(ProjectSettings.GlobalizePath(ConfigPath)); ConfigManager.SetDefault(_default_config); ConfigManager.LoadFromFile(); Mods = new GlobalModManager(ConfigManager.GetValue("mods_fpath")); Mods.SearchAllMods(); } public readonly GlobalModManager Mods = null!; public readonly IConfigManager ConfigManager = new JsonConfigManager(); private static readonly Dictionary _default_config = new() { {"font_size", 20}, {"server_addr", "wss://game.zzyxyz.com/"}, {"user_name", "undefined"}, {"mods_fpath", "user://mods"}, {"mods_allowed", false}, }; public string sessionId = ""; public Node CurrentScene { get; set; } = null!; public Theme GlobalTheme = null!; // readonly GodotConfigManager GlobalConfig = new("user://config.cfg"); // TODO will remove this public Dictionary GlobalData = new() { {"player_color", "red"}, }; // Called when the node enters the scene tree for the first time. public override void _Ready() { if (Instance == null) { Instance = this; } else { logger.Error("GlobalManager already exists"); QueueFree(); } if (OS.GetName() == "Android") { bool ret = OS.RequestPermissions(); logger.Warning($"RequestPermissions ret is {ret}"); } Viewport root = GetTree().Root; CurrentScene = root.GetChild(root.GetChildCount() - 1); SetProcess(false); } public void GlobalThemeConfigFlush() { int font_size = ConfigManager.GetValue("font_size"); GlobalTheme.DefaultFontSize = font_size; // GlobalTheme?.SetFontSize("font_size", "Label", font_size); // GlobalTheme?.SetFontSize("font_size", "Button", font_size); // GlobalTheme?.SetFontSize("font_size", "TextEdit", font_size); // GlobalTheme?.SetFontSize("font_size", "LineEdit", font_size); // CurrentScene.GetWindow().AddThemeFontSizeOverride("Control", (int)GlobalConfigDict["font_size"]); } private void OnGotoScene() { GlobalThemeConfigFlush(); } public void SaveConfig() { ConfigManager.SaveToFile(); // GlobalConfig.SaveConfig("Global", _conf_dict); } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) { // RPClient.PollEx(delta); } public override void _Notification(int what) { if (what == NotificationWMCloseRequest) { // SaveConfig(); // RPClient.Close(); GetTree().Quit(); // default behavior } } public delegate void ChangeSceneCallback(Node newSence); private static ChangeSceneCallback? changeSceneCallback = null; public void GotoScene(string path, ChangeSceneCallback? callback = null) { // This function will usually be called from a signal callback, // or some other function from the current scene. // Deleting the current scene at this point is // a bad idea, because it may still be executing code. // This will result in a crash or unexpected behavior. // The solution is to defer the load to a later time, when // we can be sure that no code from the current scene is running: if (callback != null) { changeSceneCallback = callback; } Callable callbackWrapper = new(null, nameof(changeSceneCallback)); CallDeferred(MethodName.DeferredGotoScene, path, callbackWrapper); changeSceneCallback = null; } public void DeferredGotoScene(string path, Callable onLoaded) { // It is now safe to remove the current scene. CurrentScene.Free(); // Load a new scene. var nextScene = GD.Load(path); // Instance the new scene. CurrentScene = nextScene.Instantiate(); if (changeSceneCallback != null) { onLoaded.Call(CurrentScene); } // Add it to the active scene, as child of root. GetTree().Root.AddChild(CurrentScene); // Optionally, to make it compatible with the SceneTree.change_scene_to_file() API. GetTree().CurrentScene = CurrentScene; OnGotoScene(); } }