using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; namespace BizHawk.Emulation.Common { /// /// A generic implementation of IMemoryDomain that can be used by any core /// /// public class MemoryDomainList : ReadOnlyCollection, IMemoryDomains { private MemoryDomain _mainMemory; private MemoryDomain _systemBus; public bool Has(string name) { return this.FirstOrDefault((md) => md.Name == name) != null; } public MemoryDomainList(IList domains) : base(domains) { } public MemoryDomain this[string name] { get { return this.FirstOrDefault(x => x.Name == name); } } public MemoryDomain MainMemory { get { if (_mainMemory != null) { return _mainMemory; } return this.First(); } set { _mainMemory = value; } } public bool HasSystemBus { get { if (_systemBus != null) { return true; } return this.Any(x => x.Name == "System Bus"); } } public MemoryDomain SystemBus { get { if (_systemBus != null) { return _systemBus; } var bus = this.FirstOrDefault(x => x.Name == "System Bus"); if (bus != null) { return bus; } return MainMemory; } set { _systemBus = value; } } /// /// for core use only /// public void MergeList(MemoryDomainList other) { var domains = this.ToDictionary(m => m.Name); foreach (var src in other) { MemoryDomain dst; if (domains.TryGetValue(src.Name, out dst)) { TryMerge(dst, src, (d, s) => d.Data = s.Data); TryMerge(dst, src, (d, s) => d.Data = s.Data); TryMerge(dst, src, (d, s) => d.Data = s.Data); TryMerge(dst, src, (d, s) => { d.Peek = s.Peek; d.Poke = s.Poke; }); } } } /// /// big hacks /// /// The memory domain type to merge private static void TryMerge(MemoryDomain dest, MemoryDomain src, Action func) where T : MemoryDomain { var d1 = dest as T; var s1 = src as T; if (d1 != null && s1 != null) { func(d1, s1); } } } }