This repository has been archived on 2022-08-04. You can view files and clone it, but cannot push or open issues or pull requests.
LyokoCMD/src/LyokoCMD.Sim/Supercomputer.cs

94 lines
3.9 KiB
C#

using System;
using System.Linq;
using LyokoCMD.Sim.EnergyProviders;
using LyokoCMD.Sim.Extensions;
using LyokoCMD.Sim.Tasks;
using LyokoCMD.Sim.Workers;
namespace LyokoCMD.Sim
{
/// <summary>
/// Décrit un supercalculateur de Code Lyoko.
/// </summary>
public class Supercomputer
{
private bool _Running = false, _Cooling = true;
public bool Running => _Running;
public bool Cooling => _Cooling;
private const double BaseTemperature = 90.0;
public ObjectsRegistry<EnergyProvider> EnergyProviders = new ObjectsRegistry<EnergyProvider>();
public ObjectsRegistry<SCWorker> Workers = new ObjectsRegistry<SCWorker>();
public ObjectsRegistry<SCTask> Tasks = new ObjectsRegistry<SCTask>();
public double Temperature => Math.Round((Running ? BaseTemperature : 20.0) + (Cooling ? -70 : 0) + (UsedEnergy / 100), 1);
public double TotalEnergy => EnergyProviders.All().Sum(e => e.AvailableEnergy);
public double UsedEnergy => Workers.All().Where(w => w.Running).Sum(w => w.RequiredEnergy);
public double AvailableEnergy => TotalEnergy - UsedEnergy;
public void Start() => _Running = true;
public void Stop()
{
Console.WriteLine("Arrêt des services...");
Workers.All().Where(w => w.Running).ForEach(w => w.Stop());
_Running = false;
}
public void StartCooling() => _Cooling = true;
public void StopCooling() => _Cooling = false;
public SCTask GetTask(String name)
{
if (Tasks.All().All(t => t.Name.ToLower() != name.ToLower())) throw new ArgumentException("Tâche introuvable");
return Tasks.All().First(t => t.Name.ToLower() == name.ToLower());
}
public void RunTask(string name) => RunTask(name, new string[] { });
public void RunTask(String name, string[] args)
{
if (!Running) throw new InvalidOperationException("Impossible d'exécuter une tâche sur un supercalculateur éteint");
if (Tasks.All().All(t => t.Name.ToLower() != name.ToLower())) throw new ArgumentException("Tâche introuvable");
SCTask task = GetTask(name);
if (task.RequiredEnergy > AvailableEnergy) throw new InvalidOperationException("Pas assez d'énergie pour exécuter la tâche");
task.Run(args);
}
public SCWorker GetWorker(String name)
{
if (Workers.All().All(w => w.Name.ToLower() != name.ToLower())) throw new ArgumentException("Service introuvable");
return Workers.All().First(w => w.Name.ToLower() == name.ToLower());
}
public void StartWorker(String name)
{
if (!Running) throw new InvalidOperationException("Impossible de démarrer un service sur un supercalculateur éteint");
SCWorker worker = GetWorker(name);
if (worker.RequiredEnergy > AvailableEnergy) throw new InvalidOperationException("Pas assez d'énergie pour démarrer le service");
worker.Start();
}
public void SuspendWorker(String name)
{
if (!Running) throw new InvalidOperationException("Impossible de suspendre un service sur un supercalculateur éteint");
SCWorker worker = GetWorker(name);
if (worker.Status != SCWorkerStatus.Running) throw new InvalidOperationException("Ce service n'est pas en cours d'exécution.");
worker.Suspend();
}
public void StopWorker(String name)
{
if (!Running) throw new InvalidOperationException("Impossible d'arrêter un service sur un supercalculateur éteint");
SCWorker worker = GetWorker(name);
if (worker.Running)
worker.Stop();
else throw new InvalidOperationException("Ce service n'est pas en cours d'exécution.");
}
}
}