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.Any(md => md.Name == name); } public MemoryDomainList(IList domains) : base(domains) { } public MemoryDomain this[string name] => this.FirstOrDefault(x => x.Name == name); public MemoryDomain MainMemory { get => _mainMemory ?? this.First(); set => _mainMemory = value; } public bool HasSystemBus => _systemBus != null || this.Any(x => x.Name == "System Bus"); public MemoryDomain SystemBus { get { if (_systemBus != null) { return _systemBus; } return this.FirstOrDefault(x => x.Name == "System Bus") ?? 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) { if (domains.TryGetValue(src.Name, out var 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 { if (dest is T d1 && src is T s1) { func(d1, s1); } } } }