| @@ -7,9 +7,9 @@ namespace Discord | |||||
| { | { | ||||
| internal static class DynamicIL | internal static class DynamicIL | ||||
| { | { | ||||
| public static Action<T, T> CreateCloner<T>() | |||||
| public static Action<T, T> CreateCopyMethod<T>() | |||||
| { | { | ||||
| var method = new DynamicMethod("CopyFields", null, new[] { typeof(T), typeof(T) }, typeof(T), true); | |||||
| var method = new DynamicMethod("CopyTo", null, new[] { typeof(T), typeof(T) }, typeof(T), true); | |||||
| var generator = method.GetILGenerator(); | var generator = method.GetILGenerator(); | ||||
| var typeInfo = typeof(T).GetTypeInfo(); | var typeInfo = typeof(T).GetTypeInfo(); | ||||
| @@ -26,14 +26,24 @@ namespace Discord | |||||
| return method.CreateDelegate(typeof(Action<T, T>)) as Action<T, T>; | return method.CreateDelegate(typeof(Action<T, T>)) as Action<T, T>; | ||||
| } | } | ||||
| public static void ForEachField(this TypeInfo typeInfo, Action<FieldInfo> fieldProcessor) | |||||
| public static void ForEachField(this TypeInfo typeInfo, Action<FieldInfo> func) | |||||
| { | { | ||||
| var baseType = typeInfo.BaseType; | var baseType = typeInfo.BaseType; | ||||
| if (baseType != null) | if (baseType != null) | ||||
| ForEachField(baseType.GetTypeInfo(), fieldProcessor); | |||||
| baseType.GetTypeInfo().ForEachField(func); | |||||
| foreach (var field in typeInfo.DeclaredFields.Where(x => !x.IsStatic)) | foreach (var field in typeInfo.DeclaredFields.Where(x => !x.IsStatic)) | ||||
| fieldProcessor(field); | |||||
| func(field); | |||||
| } | |||||
| public static void ForEachProperty(this TypeInfo typeInfo, Action<PropertyInfo> func) | |||||
| { | |||||
| var baseType = typeInfo.BaseType; | |||||
| if (baseType != null) | |||||
| baseType.GetTypeInfo().ForEachProperty(func); | |||||
| foreach (var prop in typeInfo.DeclaredProperties.Where(x => | |||||
| (!x.CanRead || !x.GetMethod.IsStatic) && (!x.CanWrite || !x.SetMethod.IsStatic))) | |||||
| func(prop); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -14,7 +14,7 @@ namespace Discord | |||||
| { | { | ||||
| public class Channel : IMentionable | public class Channel : IMentionable | ||||
| { | { | ||||
| private readonly static Action<Channel, Channel> _cloner = DynamicIL.CreateCloner<Channel>(); | |||||
| private readonly static Action<Channel, Channel> _cloner = DynamicIL.CreateCopyMethod<Channel>(); | |||||
| private struct Member | private struct Member | ||||
| { | { | ||||
| @@ -4,7 +4,7 @@ namespace Discord | |||||
| { | { | ||||
| public class Color : IEquatable<Color> | public class Color : IEquatable<Color> | ||||
| { | { | ||||
| private readonly static Action<Color, Color> _cloner = DynamicIL.CreateCloner<Color>(); | |||||
| private readonly static Action<Color, Color> _cloner = DynamicIL.CreateCopyMethod<Color>(); | |||||
| public static readonly Color Default = PresetColor(0); | public static readonly Color Default = PresetColor(0); | ||||
| @@ -10,7 +10,7 @@ namespace Discord | |||||
| { | { | ||||
| public class Invite | public class Invite | ||||
| { | { | ||||
| private readonly static Action<Invite, Invite> _cloner = DynamicIL.CreateCloner<Invite>(); | |||||
| private readonly static Action<Invite, Invite> _cloner = DynamicIL.CreateCopyMethod<Invite>(); | |||||
| public class ServerInfo | public class ServerInfo | ||||
| { | { | ||||
| @@ -24,7 +24,7 @@ namespace Discord | |||||
| public class Message | public class Message | ||||
| { | { | ||||
| private readonly static Action<Message, Message> _cloner = DynamicIL.CreateCloner<Message>(); | |||||
| private readonly static Action<Message, Message> _cloner = DynamicIL.CreateCopyMethod<Message>(); | |||||
| private static readonly Regex _userRegex = new Regex(@"<@[0-9]+>"); | private static readonly Regex _userRegex = new Regex(@"<@[0-9]+>"); | ||||
| private static readonly Regex _channelRegex = new Regex(@"<#[0-9]+>"); | private static readonly Regex _channelRegex = new Regex(@"<#[0-9]+>"); | ||||
| @@ -33,7 +33,7 @@ namespace Discord | |||||
| public class ServerPermissions : Permissions | public class ServerPermissions : Permissions | ||||
| { | { | ||||
| private readonly static Action<ServerPermissions, ServerPermissions> _cloner = DynamicIL.CreateCloner<ServerPermissions>(); | |||||
| private readonly static Action<ServerPermissions, ServerPermissions> _cloner = DynamicIL.CreateCopyMethod<ServerPermissions>(); | |||||
| public static ServerPermissions None { get; } = new ServerPermissions(); | public static ServerPermissions None { get; } = new ServerPermissions(); | ||||
| public static ServerPermissions All { get; } = new ServerPermissions(Convert.ToUInt32("00000011111100111111110000111111", 2)); | public static ServerPermissions All { get; } = new ServerPermissions(Convert.ToUInt32("00000011111100111111110000111111", 2)); | ||||
| @@ -62,7 +62,7 @@ namespace Discord | |||||
| public class ChannelPermissions : Permissions | public class ChannelPermissions : Permissions | ||||
| { | { | ||||
| private readonly static Action<ChannelPermissions, ChannelPermissions> _cloner = DynamicIL.CreateCloner<ChannelPermissions>(); | |||||
| private readonly static Action<ChannelPermissions, ChannelPermissions> _cloner = DynamicIL.CreateCopyMethod<ChannelPermissions>(); | |||||
| public static ChannelPermissions None { get; } = new ChannelPermissions(); | public static ChannelPermissions None { get; } = new ChannelPermissions(); | ||||
| public static ChannelPermissions TextOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000000000000111111110000011001", 2)); | public static ChannelPermissions TextOnly { get; } = new ChannelPermissions(Convert.ToUInt32("00000000000000111111110000011001", 2)); | ||||
| @@ -169,7 +169,7 @@ namespace Discord | |||||
| public class DualChannelPermissions | public class DualChannelPermissions | ||||
| { | { | ||||
| private readonly static Action<DualChannelPermissions, DualChannelPermissions> _cloner = DynamicIL.CreateCloner<DualChannelPermissions>(); | |||||
| private readonly static Action<DualChannelPermissions, DualChannelPermissions> _cloner = DynamicIL.CreateCopyMethod<DualChannelPermissions>(); | |||||
| public ChannelPermissions Allow { get; } | public ChannelPermissions Allow { get; } | ||||
| public ChannelPermissions Deny { get; } | public ChannelPermissions Deny { get; } | ||||
| @@ -8,7 +8,7 @@ namespace Discord | |||||
| { | { | ||||
| public class Profile | public class Profile | ||||
| { | { | ||||
| private readonly static Action<Profile, Profile> _cloner = DynamicIL.CreateCloner<Profile>(); | |||||
| private readonly static Action<Profile, Profile> _cloner = DynamicIL.CreateCopyMethod<Profile>(); | |||||
| internal DiscordClient Client { get; } | internal DiscordClient Client { get; } | ||||
| @@ -11,7 +11,7 @@ namespace Discord | |||||
| { | { | ||||
| public class Role : IMentionable | public class Role : IMentionable | ||||
| { | { | ||||
| private readonly static Action<Role, Role> _cloner = DynamicIL.CreateCloner<Role>(); | |||||
| private readonly static Action<Role, Role> _cloner = DynamicIL.CreateCopyMethod<Role>(); | |||||
| internal DiscordClient Client => Server.Client; | internal DiscordClient Client => Server.Client; | ||||
| @@ -14,7 +14,7 @@ namespace Discord | |||||
| /// <summary> Represents a Discord server (also known as a guild). </summary> | /// <summary> Represents a Discord server (also known as a guild). </summary> | ||||
| public class Server | public class Server | ||||
| { | { | ||||
| private readonly static Action<Server, Server> _cloner = DynamicIL.CreateCloner<Server>(); | |||||
| private readonly static Action<Server, Server> _cloner = DynamicIL.CreateCopyMethod<Server>(); | |||||
| internal static string GetIconUrl(ulong serverId, string iconId) | internal static string GetIconUrl(ulong serverId, string iconId) | ||||
| => iconId != null ? $"{DiscordConfig.ClientAPIUrl}guilds/${serverId}/icons/${iconId}.jpg" : null; | => iconId != null ? $"{DiscordConfig.ClientAPIUrl}guilds/${serverId}/icons/${iconId}.jpg" : null; | ||||
| @@ -11,7 +11,7 @@ namespace Discord | |||||
| { | { | ||||
| public class User | public class User | ||||
| { | { | ||||
| private readonly static Action<User, User> _cloner = DynamicIL.CreateCloner<User>(); | |||||
| private readonly static Action<User, User> _cloner = DynamicIL.CreateCopyMethod<User>(); | |||||
| internal static string GetAvatarUrl(ulong userId, string avatarId) | internal static string GetAvatarUrl(ulong userId, string avatarId) | ||||
| => avatarId != null ? $"{DiscordConfig.ClientAPIUrl}users/{userId}/avatars/{avatarId}.jpg" : null; | => avatarId != null ? $"{DiscordConfig.ClientAPIUrl}users/{userId}/avatars/{avatarId}.jpg" : null; | ||||