private void ComposeSystems() { foreach (var sharperSystem in Systems) { var sysType = sharperSystem.GetType(); var method = sysType.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic) .FirstOrDefault(x => x.GetCustomAttribute <SharperInjectAttribute>() != null); if (method == null) { continue; } var parameters = method.GetParameters(); if (parameters.Any(x => !typeof(BaseSharperSystem <>).IsSubclassOfRawGeneric(x.ParameterType))) { throw new NotSupportedException($"One or more parameters in type {sharperSystem.GetType().Name} are not BaseSharperSystems. This is not supported. Please pass in any dependencies that aren't systems via the constructor."); } var systems = new List <object>(); foreach (var parameterInfo in parameters) { systems.Add(Systems.First(x => x.GetType() == parameterInfo.ParameterType)); } method.Invoke(sharperSystem, systems.ToArray()); } }
/// <summary> /// Launches the Game. This task runs for as long as the game is running. /// </summary> /// <returns>A <see cref="Task"/> represnting the asynchronous game loop.</returns> public async Task RunGameAsync() { ComposeSystems(); Task <(string CommandName, List <string> Args, IUniverseCommandSource CommandSource)> inputTask = Task.Run(() => IOHandler.GetInputAsync()); Func <string, Task> outputDel = IOHandler.SendOutputAsync; var inputSystem = (SharperInputSystem)Systems.First(x => x is SharperInputSystem); while (true) { if (inputTask.IsCompleted) { if (CommandBindings.ContainsKey(inputTask.Result.CommandName)) { var commandModel = (IUniverseCommandInfo)Activator.CreateInstance(CommandBindings[inputTask.Result.CommandName]); await commandModel.ProcessArgsAsync(inputTask.Result.Args); await inputSystem.AssignNewCommandAsync(commandModel, inputTask.Result.CommandSource); } inputTask = Task.Run(() => IOHandler.GetInputAsync()); } else if (inputTask.IsFaulted) { var exception = inputTask.Exception ?? new Exception("REEEEEEEEEEEEEEEEEEE WTF DID YOU DO TO MY POOR ENGINE???"); throw exception; } foreach (var sharperSystem in Systems) { await sharperSystem.CycleUpdateAsync(outputDel); var entitiesToDestroy = Entities.Where(x => x.ShouldDestroy).ToList(); for (var i = entitiesToDestroy.Count - 1; i > -1; i--) { var entity = entitiesToDestroy[i]; await sharperSystem.UnregisterAllComponentsByEntityAsync(entity); } } await inputSystem.CycleCommandFlushAsync(); await Task.Delay(DeltaMs); } }
/// <summary> /// Launches the Game. This task runs for as long as the game is running. /// </summary> /// <returns>A <see cref="Task"/> representing the asynchronous game loop.</returns> public async Task RunGameAsync() { var inputSystem = (SharperInputSystem)Systems.First(x => x is SharperInputSystem); Server.NewConnectionMade += inputSystem.OnNewInputConnectionAsync; ServerLog.LogInfo("Server launch successful."); while (!_cancellationTokenSource.IsCancellationRequested) { foreach (var sharperSystem in Systems) { await sharperSystem.CycleUpdateAsync(DeltaMs); var entitiesToDestroy = Entities.Where(x => x.ShouldDestroy).ToList(); for (var i = entitiesToDestroy.Count - 1; i > -1; i--) { var entity = entitiesToDestroy[i]; await sharperSystem.UnregisterAllComponentsByEntityAsync(entity); } } await inputSystem.CycleCommandFlushAsync(); await Task.Delay(DeltaMs); } }