1 //
2 // Copyright (c) 2010-2014 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 Antmicro.Renode.Peripherals;
9 using System.Collections.Generic;
10 using System.Linq;
11 using Antmicro.Renode.Exceptions;
12 
13 namespace Antmicro.Renode.Core.Structure
14 {
15     public abstract class NullRegistrationPointPeripheralContainer<TPeripheral> :
16         IPeripheralContainer<TPeripheral, NullRegistrationPoint>,
17         IPeripheral
18         where TPeripheral : class, IPeripheral
19     {
Reset()20         public abstract void Reset();
21 
NullRegistrationPointPeripheralContainer(IMachine machine)22         protected NullRegistrationPointPeripheralContainer(IMachine machine)
23         {
24             Machine = machine;
25             container = new NullRegistrationPointContainerHelper<TPeripheral>(machine, this);
26         }
27 
Register(TPeripheral peripheral, NullRegistrationPoint registrationPoint)28         public virtual void Register(TPeripheral peripheral, NullRegistrationPoint registrationPoint)
29         {
30             container.Register(peripheral, registrationPoint);
31         }
32 
Unregister(TPeripheral peripheral)33         public virtual void Unregister(TPeripheral peripheral)
34         {
35             container.Unregister(peripheral);
36         }
37 
GetRegistrationPoints(TPeripheral peripheral)38         public IEnumerable<NullRegistrationPoint> GetRegistrationPoints(TPeripheral peripheral)
39         {
40             return container.GetRegistrationPoints(peripheral);
41         }
42 
43         public IEnumerable<IRegistered<TPeripheral, NullRegistrationPoint>> Children => container.Children;
44 
45         protected TPeripheral RegisteredPeripheral => container.RegisteredPeripheral;
46 
47         protected readonly IMachine Machine;
48 
49         private readonly NullRegistrationPointContainerHelper<TPeripheral> container;
50     }
51 
52     public class NullRegistrationPointContainerHelper<TPeripheral> : IPeripheralContainer<TPeripheral, NullRegistrationPoint>
53         where TPeripheral : class, IPeripheral
54     {
NullRegistrationPointContainerHelper(IMachine machine, IPeripheral owner)55         public NullRegistrationPointContainerHelper(IMachine machine, IPeripheral owner)
56         {
57             this.machine = machine;
58             this.owner = owner;
59         }
60 
Register(TPeripheral peripheral, NullRegistrationPoint registrationPoint)61         public void Register(TPeripheral peripheral, NullRegistrationPoint registrationPoint)
62         {
63             if(RegisteredPeripheral != null)
64             {
65                 throw new RegistrationException("Cannot register more than one peripheral.");
66             }
67             machine.RegisterAsAChildOf(owner, peripheral, registrationPoint);
68             RegisteredPeripheral = peripheral;
69         }
70 
Unregister(TPeripheral peripheral)71         public void Unregister(TPeripheral peripheral)
72         {
73             if(RegisteredPeripheral == null || RegisteredPeripheral != peripheral)
74             {
75                 throw new RegistrationException("The specified peripheral was never registered.");
76             }
77             machine.UnregisterAsAChildOf(owner, peripheral);
78             RegisteredPeripheral = null;
79         }
80 
GetRegistrationPoints(TPeripheral peripheral)81         public IEnumerable<NullRegistrationPoint> GetRegistrationPoints(TPeripheral peripheral)
82         {
83             return RegisteredPeripheral != null ?
84                 new [] { NullRegistrationPoint.Instance } :
85                 Enumerable.Empty<NullRegistrationPoint>();
86         }
87 
88         public IEnumerable<IRegistered<TPeripheral, NullRegistrationPoint>> Children
89         {
90             get
91             {
92                 return RegisteredPeripheral != null ?
93                     new [] { Registered.Create(RegisteredPeripheral, NullRegistrationPoint.Instance) } :
94                     Enumerable.Empty<IRegistered<TPeripheral, NullRegistrationPoint>>();
95             }
96         }
97 
98         public TPeripheral RegisteredPeripheral { get; private set; }
99 
100         private readonly IMachine machine;
101         private readonly IPeripheral owner;
102     }
103 }
104