using System; using System.Threading; using Cysharp.Threading.Tasks; using RebootKit.Engine.Foundation; using RebootKit.Engine.Services.Console; using RebootKit.Engine.Services.Game; using RebootKit.Engine.Services.Input; using RebootKit.Engine.Services.Simulation; using UnityEngine; using UnityEngine.SceneManagement; using Logger = RebootKit.Engine.Foundation.Logger; namespace RebootKit.Engine { public abstract class RAsset : ScriptableObject { } public class RR : IDisposable { public static RR Shared { get; set; } private static readonly Logger _logger = new Logger("RR"); private EngineConfigAsset _engineConfigAsset; private ConsoleService _consoleService; private InputService _inputService; private WorldService _worldService; private GameService _gameService; public void Dispose() { } public async UniTask Init(CancellationToken cancellationToken) { _logger.Info("Waking up"); _logger.Info("Loading engine config"); _engineConfigAsset = Resources.Load(RConsts.EngineConfigResourcesPath); if (_engineConfigAsset == null) { _logger.Error($"Couldn't load engine config from resources: {RConsts.EngineConfigResourcesPath}"); return; } _logger.Info("Loading engine found"); await CreateCoreServices(cancellationToken); await RegisterServiceAssetsFromConfig(cancellationToken); await RegisterServicesFromMainSceneAsync(cancellationToken); } public async UniTask Run(CancellationToken cancellationToken) { _logger.Info($"Starting initial game mode"); await _gameService.Start(_engineConfigAsset.StartingGameMode, cancellationToken); } private async UniTask CreateServiceAsync(ServiceAsset asset, CancellationToken cancellationToken = default) where TService : IService { TService service = asset.Create(); await ServicesLocator.Shared.RegisterAsync(service, cancellationToken); return service; } private async UniTask CreateCoreServices(CancellationToken cancellationToken) { _logger.Debug("Registering core services"); _consoleService = await CreateServiceAsync(_engineConfigAsset.ConsoleService, cancellationToken); _inputService = await CreateServiceAsync(_engineConfigAsset.InputService, cancellationToken); _worldService = await CreateServiceAsync(_engineConfigAsset.WorldService, cancellationToken); _gameService = await CreateServiceAsync(_engineConfigAsset.GameService, cancellationToken); } private async UniTask RegisterServiceAssetsFromConfig(CancellationToken cancellationToken = default) { if (_engineConfigAsset.Services.Length == 0) { return; } _logger.Info($"Registering {_engineConfigAsset.Services.Length} services"); foreach (ServiceAsset service in _engineConfigAsset.Services) { await ServicesLocator.Shared.RegisterAsync(service.Create(), cancellationToken); } } private async UniTask RegisterServicesFromMainSceneAsync(CancellationToken cancellationToken = default) { _logger.Info("Looking for services in mainscene"); int foundCount = 0; GameObject[] gameObjects = SceneManager.GetSceneByBuildIndex(RConsts.MainSceneBuildIndex).GetRootGameObjects(); if (gameObjects.Length == 0) { _logger.Info("No services found in main scene"); return; } foreach (GameObject root in gameObjects) { ServiceMonoBehaviour[] services = root.GetComponentsInChildren(); foreach (ServiceMonoBehaviour service in services) { await ServicesLocator.Shared.RegisterAsync(service, cancellationToken); foundCount += 1; } } _logger.Info($"Found and registered {foundCount} services from active scene"); } // // API // /// Services public static T Service() where T : IService { return ServicesLocator.Shared.Get(); } public static ConsoleService Console() => Shared._consoleService; public static InputService Input() => Shared._inputService; public static WorldService World() => Shared._worldService; public static GameService Game() => Shared._gameService; /// CVars public static CVar CVarIndex(string name, int defaultValue = -1) { CVar cvar = Console().GetCVar(name); if (cvar != null) { return cvar; } cvar = new CVar(name, defaultValue); Console().Replace(cvar); return cvar; } public static CVar CVarNumber(string name, double defaultValue = 0) { CVar cvar = Console().GetCVar(name); if (cvar != null) { return cvar; } cvar = new CVar(name, defaultValue); Console().Replace(cvar); return cvar; } public static CVar CVarString(string name, string defaultValue = "") { CVar cvar = Console().GetCVar(name); if (cvar != null) { return cvar; } cvar = new CVar(name, defaultValue); Console().Replace(cvar); return cvar; } } }