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("RR"); private EngineConfigAsset _engineConfigAsset; private ConsoleService _consoleService; private InputService _inputService; private WorldService _worldService; private GameService _gameService; private DIContext _diContext; 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"); _diContext = new DIContext(); _diContext.AddInjector(new CVarFieldInjector()); await CreateCoreServices(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(); _diContext.Bind(service); _diContext.Inject(service); await service.OnInit(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 RegisterServicesFromMainSceneAsync(CancellationToken cancellationToken = default) { GameObject[] gameObjects = SceneManager.GetSceneByBuildIndex(RConsts.MainSceneBuildIndex).GetRootGameObjects(); if (gameObjects.Length == 0) { return; } foreach (GameObject root in gameObjects) { SceneDI di = root.GetComponent(); if (di == null) { continue; } di.Install(_diContext); } await UniTask.Yield(); } // // API // /// Services 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; } } }