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);
}
}
}
}