blob: b3ca73a6387a84f3935add8fa636f69888b2b213 [file] [log] [blame]
//
// Copyright (c) 2010-2023 Antmicro
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//
using System;
using System.Collections.Generic;
using System.Linq;
using Antmicro.Renode.Core;
using Antmicro.Renode.Peripherals;
namespace Antmicro.Renode.RobotFramework
{
internal abstract class TestersProvider<TTester, TPeripheral>
where TPeripheral: class, IEmulationElement
where TTester: class
{
public TestersProvider()
{
testers = new Dictionary<int, TTester>();
peripheralsWithTesters = new List<TPeripheral>();
EmulationManager.Instance.EmulationChanged += () =>
{
lock(testers)
{
testers.Clear();
peripheralsWithTesters.Clear();
}
};
}
public int CreateNewTester(Func<TPeripheral, TTester> creator, string peripheralName, string machine = null)
{
lock(testers)
{
IMachine machineObject;
if(machine == null)
{
if(!EmulationManager.Instance.CurrentEmulation.Machines.Any())
{
throw new KeywordException("There is no machine in the emulation. Could not create tester for peripheral: {0}", peripheralName);
}
machineObject = EmulationManager.Instance.CurrentEmulation.Machines.Count() == 1
? EmulationManager.Instance.CurrentEmulation.Machines.First()
: null;
if(machineObject == null)
{
throw new KeywordException("No machine name provided. Don't know which one to choose. Available machines: [{0}]",
string.Join(", ", EmulationManager.Instance.CurrentEmulation.Machines.Select(x => EmulationManager.Instance.CurrentEmulation[x])));
}
}
else if(!EmulationManager.Instance.CurrentEmulation.TryGetMachineByName(machine, out machineObject))
{
throw new KeywordException("Machine with name {0} not found. Available machines: [{1}]", machine,
string.Join(", ", EmulationManager.Instance.CurrentEmulation.Machines.Select(x => EmulationManager.Instance.CurrentEmulation[x])));
}
if(!machineObject.TryGetByName(peripheralName, out IPeripheral typeLessPeripheral))
{
throw new KeywordException("Peripheral for machine '{0}' not found or of wrong type: '{1}'. Available peripherals: [{2}]", machine, peripheralName,
string.Join(", ", machineObject.GetAllNames()));
}
var peripheral = typeLessPeripheral as TPeripheral;
if(peripheral == null)
{
throw new KeywordException("Peripheral for machine '{0}' not found or of wrong type: '{1}'. Available peripherals: [{2}]", machine, peripheralName,
string.Join(", ", machineObject.GetAllNames()));
}
var testerId = peripheralsWithTesters.IndexOf(peripheral);
if(testerId != -1)
{
return testerId;
}
var tester = creator(peripheral);
peripheralsWithTesters.Add(peripheral);
testers.Add(peripheralsWithTesters.Count - 1, tester);
return peripheralsWithTesters.Count - 1;
}
}
public void SetDefaultTesterId(int? id)
{
lock(testers)
{
if(id.HasValue)
{
if(!testers.TryGetValue(id.Value, out var tester))
{
throw new KeywordException($"Tester #{id.Value} was not found. Create a tester before setting it as default");
}
defaultTester = tester;
}
else
{
defaultTester = null;
}
}
}
protected TTester GetTesterOrThrowException(int? testerId)
{
lock(testers)
{
if(testerId == null)
{
if(defaultTester != null)
{
return defaultTester;
}
if(testers.Count != 1)
{
throw new KeywordException(testers.Count == 0
? "There are no testers available."
: "There is more than one tester available - please specify ID of the desired tester.");
}
return testers.Single().Value;
}
if(!testers.TryGetValue(testerId.Value, out var tester))
{
throw new KeywordException("Tester for given ID={0} was not found. Did you forget to create the tester?", testerId);
}
return tester;
}
}
private TTester defaultTester;
private readonly Dictionary<int, TTester> testers;
private readonly List<TPeripheral> peripheralsWithTesters;
}
}