E:\Devel\PlayniteDiagTool\PlayniteDiagTool\bin\Debug\temp\PlayniteSDK\Models\Emulator.cs e:\Devel\Playnite\source\PlayniteSDK\Models\Emulator.cs
.using Newtonsoft.Json; using Playnite.SDK.Data;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
   
namespace Playnite.SDK.Models namespace Playnite.SDK.Models
{ {
   /// <summary>    /// <summary>
.     /// Represents built-in region defition.
     /// </summary>
     public class EmulatedRegion : IEquatable<EmulatedRegion>
     {
         /// <summary>
         /// Gets region id.
         /// </summary>
         public string Id { get; set; }
         /// <summary>
         /// Gets region name.
         /// </summary>
         public string Name { get; set; }
         /// <summary>
         /// Gets value indicating whether the region should be imported into new libraries.
         /// </summary>
         public bool DefaultImport { get; set; }
         /// <summary>
         /// Gets ID of the region on IGDB database.
         /// </summary>
         public ulong IgdbId { get; set; }
         /// <summary>
         /// Gets region codes.
         /// </summary>
         public List<string> Codes { get; set; }
   
         /// <inheritdoc/>
         public override int GetHashCode()
         {
             return Id?.GetHashCode() ?? 0;
         }
   
         /// <inheritdoc/>
         public bool Equals(EmulatedRegion other)
         {
             return other.Id == Id;
         }
   
         /// <inheritdoc/>
         public override bool Equals(object obj)
         {
             if (obj is EmulatedRegion region)
             {
                 return Equals(region);
             }
             else
             {
                 return false;
             }
         }
   
         /// <inheritdoc/>
         public override string ToString()
         {
             return Name;
         }
     }
   
     /// <summary>
     /// Represents built-in platform definition.
     /// </summary>
     public class EmulatedPlatform : IEquatable<EmulatedPlatform>
     {
         /// <summary>
         /// Gets ID of the platform on IGDB database.
         /// </summary>
         public ulong IgdbId { get; set; }
         /// <summary>
         /// Gets platform name.
         /// </summary>
         public string Name { get; set; }
         /// <summary>
         /// Gets platform id.
         /// </summary>
         public string Id { get; set; }
         /// <summary>
         /// Gets list of platform ROM database ids.
         /// </summary>
         public List<string> Databases { get; set; }
         /// <summary>
         /// Gets liust of emulator IDs supporting this platform.
         /// </summary>
         public List<string> Emulators { get; set; }
   
         /// <inheritdoc/>
         public override int GetHashCode()
         {
             return Id?.GetHashCode() ?? 0;
         }
   
         /// <inheritdoc/>
         public bool Equals(EmulatedPlatform other)
         {
             return other.Id == Id;
         }
   
         /// <inheritdoc/>
         public override bool Equals(object obj)
         {
             if (obj is EmulatedPlatform platform)
             {
                 return Equals(platform);
             }
             else
             {
                 return false;
             }
         }
   
         /// <inheritdoc/>
         public override string ToString()
         {
             return Name;
         }
     }
   
     /// <summary>
     ///
     /// </summary>
     public abstract class EmulatorProfile : ObservableObject
     {
         private string id;
         /// <summary>
         /// Gets emulator profile ID.
         /// </summary>
         public string Id
         {
             get => id;
             set
             {
                 id = value;
                 OnPropertyChanged();
             }
         }
   
         private string name;
         /// <summary>
         /// Gets profile name.
         /// </summary>
         public string Name
         {
             get => name;
             set
             {
                 name = value;
                 OnPropertyChanged();
             }
         }
   
         private string preScript;
         /// <summary>
         /// Gets pre-execution script.
         /// </summary>
         public string PreScript
         {
             get => preScript;
             set
             {
                 preScript = value;
                 OnPropertyChanged();
             }
         }
   
         private string postScript;
         /// <summary>
         /// Gets post-execution script.
         /// </summary>
         public string PostScript
         {
             get => postScript;
             set
             {
                 postScript = value;
                 OnPropertyChanged();
             }
         }
   
         private string exitScript;
         /// <summary>
         /// Gets exit-execution script.
         /// </summary>
         public string ExitScript
         {
             get => exitScript;
             set
             {
                 exitScript = value;
                 OnPropertyChanged();
             }
         }
   
         /// <summary>
         /// Gets emulator profile object type.
         /// </summary>
         [DontSerialize]
         public Type Type => GetType();
   
         /// <inheritdoc/>
         public override string ToString()
         {
             return Name;
         }
     }
   
     /// <summary>
     /// Represents built-in emulator profile.
     /// </summary>
     public class BuiltInEmulatorProfile : EmulatorProfile, IEquatable<BuiltInEmulatorProfile>
     {
         internal static readonly string ProfilePrefix = "#builtin_";
   
         private string builtInProfileName;
         /// <summary>
         /// Gets name of built-in profile represented by this definition.
         /// </summary>
         public string BuiltInProfileName
         {
             get => builtInProfileName;
             set
             {
                 builtInProfileName = value;
                 OnPropertyChanged();
             }
         }
   
         /// <summary>
         /// Creates new instance of <see cref="BuiltInEmulatorProfile"/>.
         /// </summary>
         public BuiltInEmulatorProfile() : base()
         {
             Id = ProfilePrefix + Guid.NewGuid();
         }
   
         /// <inheritdoc/>
         public bool Equals(BuiltInEmulatorProfile other)
         {
             if (other is null)
             {
                 return false;
             }
   
             if (!string.Equals(BuiltInProfileName, other.BuiltInProfileName, StringComparison.Ordinal))
             {
                 return false;
             }
   
             if (!string.Equals(Name, other.Name, StringComparison.Ordinal))
             {
                 return false;
             }
   
             if (!string.Equals(ExitScript, other.ExitScript, StringComparison.Ordinal))
             {
                 return false;
             }
   
             if (!string.Equals(PostScript, other.PostScript, StringComparison.Ordinal))
             {
                 return false;
             }
   
             if (!string.Equals(PreScript, other.PreScript, StringComparison.Ordinal))
             {
                 return false;
             }
   
             return true;
         }
     }
   
     /// <summary>
   /// Represents emulator profile.    /// Represents emulator profile.
   /// </summary>    /// </summary>
.    public class EmulatorProfile : DatabaseObject, IEquatable<EmulatorProfile>    public class CustomEmulatorProfile : EmulatorProfile, IEquatable<CustomEmulatorProfile>
   {    {
.         internal static readonly string ProfilePrefix = "#custom_";
   
         private string startupScript;
         /// <summary>
         /// Gets startup script.
         /// </summary>
         public string StartupScript
         {
             get => startupScript;
             set
             {
                 startupScript = value;
                 OnPropertyChanged();
             }
         }
   
       private List<Guid> platforms;        private List<Guid> platforms;
       /// <summary>        /// <summary>
       /// Gets or sets platforms supported by profile.        /// Gets or sets platforms supported by profile.
       /// </summary>        /// </summary>
       public List<Guid> Platforms        public List<Guid> Platforms
       {        {
           get => platforms;            get => platforms;
           set            set
           {            {
               platforms = value;                platforms = value;
               OnPropertyChanged();                OnPropertyChanged();
           }            }
       }        }
   
       private List<string> imageExtensions;        private List<string> imageExtensions;
       /// <summary>        /// <summary>
       /// Gets or sets file extension supported by profile.        /// Gets or sets file extension supported by profile.
       /// </summary>        /// </summary>
       public List<string> ImageExtensions        public List<string> ImageExtensions
       {        {
           get => imageExtensions;            get => imageExtensions;
           set            set
           {            {
               imageExtensions = value;                imageExtensions = value;
               OnPropertyChanged();                OnPropertyChanged();
           }            }
       }        }
   
       private string executable;        private string executable;
       /// <summary>        /// <summary>
       /// Gets or sets executable path used to launch emulator.        /// Gets or sets executable path used to launch emulator.
       /// </summary>        /// </summary>
       public string Executable        public string Executable
       {        {
           get => executable;            get => executable;
           set            set
           {            {
               executable = value;                executable = value;
               OnPropertyChanged();                OnPropertyChanged();
           }            }
       }        }
   
       private string arguments;        private string arguments;
       /// <summary>        /// <summary>
       /// Gets or sets arguments for emulator executable.        /// Gets or sets arguments for emulator executable.
       /// </summary>        /// </summary>
       public string Arguments        public string Arguments
       {        {
           get => arguments;            get => arguments;
           set            set
           {            {
               arguments = value;                arguments = value;
               OnPropertyChanged();                OnPropertyChanged();
           }            }
       }        }
   
       private string workingDirectory;        private string workingDirectory;
       /// <summary>        /// <summary>
       /// Gets or sets working directory of emulator process.        /// Gets or sets working directory of emulator process.
       /// </summary>        /// </summary>
       public string WorkingDirectory        public string WorkingDirectory
       {        {
           get => workingDirectory;            get => workingDirectory;
           set            set
           {            {
               workingDirectory = value;                workingDirectory = value;
               OnPropertyChanged();                OnPropertyChanged();
           }            }
       }        }
   
       /// <summary>        /// <summary>
       ///        ///
       /// </summary>        /// </summary>
       /// <returns></returns>        /// <returns></returns>
       public override string ToString()        public override string ToString()
       {        {
           return Name;            return Name;
       }        }
   
       /// <summary>        /// <summary>
       /// Creates new instance of EmulatorProfile.        /// Creates new instance of EmulatorProfile.
       /// </summary>        /// </summary>
.        public EmulatorProfile() : base()        public CustomEmulatorProfile() : base()
       {        {
.             Id = ProfilePrefix + Guid.NewGuid();
       }        }
   
       /// <inheritdoc/>        /// <inheritdoc/>
.        public bool Equals(EmulatorProfile other)        public bool Equals(CustomEmulatorProfile other)
       {        {
           if (other is null)            if (other is null)
           {            {
               return false;                return false;
           }            }
   
.             if (!string.Equals(Id, other.Id, StringComparison.Ordinal))
             {
                 return false;
             }
   
             if (!string.Equals(Name, other.Name, StringComparison.Ordinal))
             {
                 return false;
             }
   
           if (!Platforms.IsListEqual(other.Platforms))            if (!Platforms.IsListEqual(other.Platforms))
           {            {
               return false;                return false;
           }            }
   
           if (!ImageExtensions.IsListEqual(other.ImageExtensions))            if (!ImageExtensions.IsListEqual(other.ImageExtensions))
           {            {
               return false;                return false;
           }            }
   
           if (!string.Equals(Executable, other.Executable, StringComparison.Ordinal))            if (!string.Equals(Executable, other.Executable, StringComparison.Ordinal))
           {            {
               return false;                return false;
           }            }
   
           if (!string.Equals(Arguments, other.Arguments, StringComparison.Ordinal))            if (!string.Equals(Arguments, other.Arguments, StringComparison.Ordinal))
           {            {
               return false;                return false;
           }            }
   
           if (!string.Equals(WorkingDirectory, other.WorkingDirectory, StringComparison.Ordinal))            if (!string.Equals(WorkingDirectory, other.WorkingDirectory, StringComparison.Ordinal))
           {            {
               return false;                return false;
           }            }
   
           if (!string.Equals(Name, other.Name, StringComparison.Ordinal))            if (!string.Equals(Name, other.Name, StringComparison.Ordinal))
           {            {
               return false;                return false;
           }            }
   
.             if (!string.Equals(ExitScript, other.ExitScript, StringComparison.Ordinal))
             {
                 return false;
             }
   
             if (!string.Equals(PostScript, other.PostScript, StringComparison.Ordinal))
             {
                 return false;
             }
   
             if (!string.Equals(PreScript, other.PreScript, StringComparison.Ordinal))
             {
                 return false;
             }
   
             if (!string.Equals(StartupScript, other.StartupScript, StringComparison.Ordinal))
             {
                 return false;
             }
   
           return true;            return true;
       }        }
   }    }
   
   /// <summary>    /// <summary>
   /// Represents system emulator.    /// Represents system emulator.
   /// </summary>    /// </summary>
   public class Emulator : DatabaseObject    public class Emulator : DatabaseObject
   {    {
.        private ObservableCollection<EmulatorProfile> profile;        private string builtInConfigId;
         /// <summary> 
         /// Gets id of built-in emulator profile. 
         /// </summary> 
         public string BuiltInConfigId 
         { 
             get => builtInConfigId; 
             set 
             { 
                 builtInConfigId = value; 
                 OnPropertyChanged(); 
             } 
         } 
   
         private string installDir; 
         /// <summary> 
         /// Gets emulator installation directory. 
         /// </summary> 
         public string InstallDir 
         { 
             get => installDir; 
             set 
             { 
                 installDir = value; 
                 OnPropertyChanged(); 
             } 
         } 
   
         private ObservableCollection<BuiltInEmulatorProfile> builtinProfiles; 
       /// <summary>        /// <summary>
       /// Gets or sets list of emulator profiles.        /// Gets or sets list of emulator profiles.
       /// </summary>        /// </summary>
.        public ObservableCollection<EmulatorProfile> Profiles        public ObservableCollection<BuiltInEmulatorProfile> BuiltinProfiles
       {        {
.            get => profile;            get => builtinProfiles;
           set            set
           {            {
.                profile = value;                 if (builtinProfiles != null) 
                 { 
                     builtinProfiles.CollectionChanged -= Profiles_CollectionChanged; 
                 } 
   
                 builtinProfiles = value; 
                 if (builtinProfiles != null) 
                 { 
                     builtinProfiles.CollectionChanged += Profiles_CollectionChanged; 
                 } 
   
               OnPropertyChanged();                OnPropertyChanged();
.                 OnPropertyChanged(nameof(AllProfiles));
                 OnPropertyChanged(nameof(SelectableProfiles));
             }
         }
   
         private ObservableCollection<CustomEmulatorProfile> customProfiles;
         /// <summary>
         /// Gets or sets list of emulator profiles.
         /// </summary>
         public ObservableCollection<CustomEmulatorProfile> CustomProfiles
         {
             get => customProfiles;
             set
             {
                 if (customProfiles != null)
                 {
                     customProfiles.CollectionChanged -= Profiles_CollectionChanged;
                 }
   
                 customProfiles = value;
                 if (customProfiles != null)
                 {
                     customProfiles.CollectionChanged += Profiles_CollectionChanged;
                 }
   
                 OnPropertyChanged();
                 OnPropertyChanged(nameof(AllProfiles));
                 OnPropertyChanged(nameof(SelectableProfiles));
             }
         }
   
         private void Profiles_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
         {
             OnPropertyChanged(nameof(AllProfiles));
             OnPropertyChanged(nameof(SelectableProfiles));
         }
   
         /// <summary>
         /// Gets list of all profiles including option for profile auto-select.
         /// </summary>
         [DontSerialize]
         public List<EmulatorProfile> SelectableProfiles
         {
             get
             {
                 var selProfiles = new List<EmulatorProfile>();
                 if (BuiltinProfiles.HasItems())
                 {
                     selProfiles.AddRange(BuiltinProfiles.OrderBy(a => a.Name));
                 }
   
                 if (CustomProfiles.HasItems())
                 {
                     selProfiles.AddRange(CustomProfiles.OrderBy(a => a.Name));
                 }
   
                 selProfiles.Insert(0, new CustomEmulatorProfile { Id = null, Name = ResourceProvider.GetString("LOCGameActionSelectOnStart") });
                 return selProfiles;
             }
         }
   
         /// <summary>
         /// Gets list of all profiles.
         /// </summary>
         [DontSerialize]
         public List<EmulatorProfile> AllProfiles
         {
             get
             {
                 var selProfiles = new List<EmulatorProfile>();
                 if (BuiltinProfiles.HasItems())
                 {
                     selProfiles.AddRange(BuiltinProfiles.OrderBy(a => a.Name));
                 }
   
                 if (CustomProfiles.HasItems())
                 {
                     selProfiles.AddRange(CustomProfiles.OrderBy(a => a.Name));
                 }
   
                 return selProfiles;
           }            }
       }        }
   
       /// <summary>        /// <summary>
       /// Creates new instance of Emulator.        /// Creates new instance of Emulator.
       /// </summary>        /// </summary>
       public Emulator() : base()        public Emulator() : base()
       {        {
       }        }
   
       /// <summary>        /// <summary>
       /// Creates new instance of Emulator with specific name.        /// Creates new instance of Emulator with specific name.
       /// </summary>        /// </summary>
       /// <param name="name">Emulator name.</param>        /// <param name="name">Emulator name.</param>
       public Emulator(string name) : this()        public Emulator(string name) : this()
       {        {
           Name = name;            Name = name;
       }        }
   
       /// <summary>        /// <summary>
       ///        ///
       /// </summary>        /// </summary>
       /// <returns></returns>        /// <returns></returns>
       public override string ToString()        public override string ToString()
       {        {
           return Name;            return Name;
       }        }
   
.         /// <summary>
         /// Gets profile by id.
         /// </summary>
         /// <param name="profileId"></param>
         /// <returns></returns>
         public EmulatorProfile GetProfile(string profileId)
         {
             var cus = CustomProfiles?.FirstOrDefault(a => a.Id == profileId);
             if (cus != null)
             {
                 return cus;
             }
   
             return BuiltinProfiles?.FirstOrDefault(a => a.Id == profileId);
         }
   
       /// <inheritdoc/>        /// <inheritdoc/>
       public override void CopyDiffTo(object target)        public override void CopyDiffTo(object target)
       {        {
           base.CopyDiffTo(target);            base.CopyDiffTo(target);
   
           if (target is Emulator tro)            if (target is Emulator tro)
           {            {
.                if (!Profiles.IsListEqualExact(tro.Profiles))                 if (!CustomProfiles.IsListEqualExact(tro.CustomProfiles)) 
                 { 
                     tro.CustomProfiles = CustomProfiles; 
                 } 
   
                 if (!BuiltinProfiles.IsListEqualExact(tro.BuiltinProfiles)) 
                 { 
                     tro.BuiltinProfiles = BuiltinProfiles; 
                 } 
   
                 if (!string.Equals(BuiltInConfigId, tro.BuiltInConfigId, StringComparison.Ordinal)) 
                 { 
                     tro.BuiltInConfigId = BuiltInConfigId; 
                 } 
   
                 if (!string.Equals(InstallDir, tro.InstallDir, StringComparison.Ordinal)) 
               {                {
.                    tro.Profiles = Profiles;                    tro.InstallDir = InstallDir;
               }                }
           }            }
           else            else
           {            {
               throw new ArgumentException($"Target object has to be of type {GetType().Name}");                throw new ArgumentException($"Target object has to be of type {GetType().Name}");
           }            }
       }        }
   }    }
} }