@@ -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; | ||||