1 //
2 // Copyright (c) 2010-2018 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using System.Collections.Generic;
10 using Antmicro.Renode.Exceptions;
11 using Antmicro.Renode.Utilities.Collections;
12 using System.Linq;
13 using Microsoft.CSharp.RuntimeBinder;
14 
15 namespace Antmicro.Renode.Core
16 {
17     public class Connector
18     {
Connector()19         public Connector()
20         {
21             connections = new WeakMultiTable<IConnectable, IEmulationElement>();
22         }
23 
Connect(IEmulationElement connectee, IConnectable connector)24         public void Connect(IEmulationElement connectee, IConnectable connector)
25         {
26             try
27             {
28                 ((dynamic)connector).AttachTo((dynamic)connectee);
29                 connections.Add(connector, connectee);
30             }
31             catch (RuntimeBinderException)
32             {
33                 ThrowConnectionException(connectee.GetType(), connector.GetType());
34             }
35         }
36 
Disconnect(IEmulationElement connectee, IConnectable connector)37         public void Disconnect(IEmulationElement connectee, IConnectable connector)
38         {
39             Disconnect(connector, connectee);
40         }
41 
Disconnect(IConnectable connector, IEmulationElement connectee)42         public void Disconnect(IConnectable connector, IEmulationElement connectee)
43         {
44             try
45             {
46                 ((dynamic)connector).DetachFrom((dynamic)connectee);
47                 connections.RemovePair(connector, connectee);
48             }
49             catch(RuntimeBinderException)
50             {
51                 ThrowConnectionException(connectee.GetType(), connector.GetType(), true);
52             }
53         }
54 
DisconnectFromAll(IEmulationElement element)55         public void DisconnectFromAll(IEmulationElement element)
56         {
57             var interestingKeys = connections.GetAllForRight(element);
58             foreach(var external in interestingKeys)
59             {
60                 Disconnect(external, element);
61             }
62         }
63 
GetConnectionsFor(IEmulationElement obj)64         public IEnumerable<IConnectable<IEmulationElement>> GetConnectionsFor(IEmulationElement obj)
65         {
66             return connections.GetAllForRight(obj).Cast<IConnectable<IEmulationElement>>();
67         }
68 
GetObjectsConnectedTo(IConnectable obj)69         public IEnumerable<IEmulationElement> GetObjectsConnectedTo(IConnectable obj)
70         {
71             return connections.GetAllForLeft(obj).ToList();
72         }
73 
ThrowConnectionException(Type tone, Type ttwo, bool disconnection = false)74         private static void ThrowConnectionException(Type tone, Type ttwo, bool disconnection = false)
75         {
76             throw new RecoverableException(String.Format("Could not find a way to {2}connect {0} {3} {1}", tone.Name, ttwo.Name, disconnection ? "dis" : string.Empty, disconnection ? "from" : "to"));
77         }
78 
79         private readonly WeakMultiTable<IConnectable, IEmulationElement> connections;
80     }
81 }
82