feature: add a way to remove type readers from the interaction/command service. (#2210)

* Add remove methods

* add inline docs

Co-authored-by: Cenngo <cenk.ergen1@gmail.com>
This commit is contained in:
Quin Lynch
2022-03-26 16:21:26 -03:00
committed by GitHub
parent 91d8fabb70
commit 73399459ea
3 changed files with 99 additions and 0 deletions

View File

@@ -403,6 +403,41 @@ namespace Discord.Commands
AddNullableTypeReader(type, reader); AddNullableTypeReader(type, reader);
} }
} }
/// <summary>
/// Removes a type reader from the list of type readers.
/// </summary>
/// <remarks>
/// Removing a <see cref="TypeReader"/> from the <see cref="CommandService"/> will not dereference the <see cref="TypeReader"/> from the loaded module/command instances.
/// You need to reload the modules for the changes to take effect.
/// </remarks>
/// <param name="type">The type to remove the readers from.</param>
/// <param name="isDefaultTypeReader"><see langword="true"/> if the default readers for <paramref name="type"/> should be removed; otherwise <see langword="false"/>.</param>
/// <param name="readers">The removed collection of type readers.</param>
/// <returns><see langword="true"/> if the remove operation was successful; otherwise <see langword="false"/>.</returns>
public bool TryRemoveTypeReader(Type type, bool isDefaultTypeReader, out IDictionary<Type, TypeReader> readers)
{
readers = new Dictionary<Type, TypeReader>();
if (isDefaultTypeReader)
{
var isSuccess = _defaultTypeReaders.TryRemove(type, out var result);
if (isSuccess)
readers.Add(result?.GetType(), result);
return isSuccess;
}
else
{
var isSuccess = _typeReaders.TryRemove(type, out var result);
if (isSuccess)
readers = result;
return isSuccess;
}
}
internal bool HasDefaultTypeReader(Type type) internal bool HasDefaultTypeReader(Type type)
{ {
if (_defaultTypeReaders.ContainsKey(type)) if (_defaultTypeReaders.ContainsKey(type))

View File

@@ -905,9 +905,61 @@ namespace Discord.Interactions
public void AddGenericTypeReader(Type targetType, Type readerType) => public void AddGenericTypeReader(Type targetType, Type readerType) =>
_typeReaderMap.AddGeneric(targetType, readerType); _typeReaderMap.AddGeneric(targetType, readerType);
/// <summary>
/// Removes a type reader for the type <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">The type to remove the readers from.</typeparam>
/// <param name="reader">The reader if the resulting remove operation was successful.</param>
/// <returns><see langword="true"/> if the remove operation was successful; otherwise <see langword="false"/>.</returns>
public bool TryRemoveTypeReader<T>(out TypeReader reader)
=> TryRemoveTypeReader(typeof(T), out reader);
/// <summary>
/// Removes a type reader for the given type.
/// </summary>
/// <remarks>
/// Removing a <see cref="TypeReader"/> from the <see cref="CommandService"/> will not dereference the <see cref="TypeReader"/> from the loaded module/command instances.
/// You need to reload the modules for the changes to take effect.
/// </remarks>
/// <param name="type">The type to remove the reader from.</param>
/// <param name="reader">The reader if the resulting remove operation was successful.</param>
/// <returns><see langword="true"/> if the remove operation was successful; otherwise <see langword="false"/>.</returns>
public bool TryRemoveTypeReader(Type type, out TypeReader reader)
=> _typeReaderMap.TryRemoveConcrete(type, out reader);
/// <summary>
/// Removes a generic type reader from the type <typeparamref name="T"/>.
/// </summary>
/// <remarks>
/// Removing a <see cref="TypeReader"/> from the <see cref="CommandService"/> will not dereference the <see cref="TypeReader"/> from the loaded module/command instances.
/// You need to reload the modules for the changes to take effect.
/// </remarks>
/// <typeparam name="T">The type to remove the readers from.</typeparam>
/// <param name="readerType">The removed readers type.</param>
/// <returns><see langword="true"/> if the remove operation was successful; otherwise <see langword="false"/>.</returns>
public bool TryRemoveGenericTypeReader<T>(out Type readerType)
=> TryRemoveGenericTypeReader(typeof(T), out readerType);
/// <summary>
/// Removes a generic type reader from the given type.
/// </summary>
/// <remarks>
/// Removing a <see cref="TypeReader"/> from the <see cref="CommandService"/> will not dereference the <see cref="TypeReader"/> from the loaded module/command instances.
/// You need to reload the modules for the changes to take effect.
/// </remarks>
/// <param name="type">The type to remove the reader from.</param>
/// <param name="readerType">The readers type if the remove operation was successful.</param>
/// <returns><see langword="true"/> if the remove operation was successful; otherwise <see langword="false"/>.</returns>
public bool TryRemoveGenericTypeReader(Type type, out Type readerType)
=> _typeReaderMap.TryRemoveGeneric(type, out readerType);
/// <summary> /// <summary>
/// Serialize an object using a <see cref="TypeReader"/> into a <see cref="string"/> to be placed in a Component CustomId. /// Serialize an object using a <see cref="TypeReader"/> into a <see cref="string"/> to be placed in a Component CustomId.
/// </summary> /// </summary>
/// <remarks>
/// Removing a <see cref="TypeReader"/> from the <see cref="CommandService"/> will not dereference the <see cref="TypeReader"/> from the loaded module/command instances.
/// You need to reload the modules for the changes to take effect.
/// </remarks>
/// <typeparam name="T">Type of the object to be serialized.</typeparam> /// <typeparam name="T">Type of the object to be serialized.</typeparam>
/// <param name="obj">Object to be serialized.</param> /// <param name="obj">Object to be serialized.</param>
/// <param name="services">Services that will be passed on to the <see cref="TypeReader"/>.</param> /// <param name="services">Services that will be passed on to the <see cref="TypeReader"/>.</param>

View File

@@ -74,6 +74,18 @@ namespace Discord.Interactions
_generics[targetType] = converterType; _generics[targetType] = converterType;
} }
public bool TryRemoveConcrete<TTarget>(out TConverter converter)
=> TryRemoveConcrete(typeof(TTarget), out converter);
public bool TryRemoveConcrete(Type type, out TConverter converter)
=> _concretes.TryRemove(type, out converter);
public bool TryRemoveGeneric<TTarget>(out Type converterType)
=> TryRemoveGeneric(typeof(TTarget), out converterType);
public bool TryRemoveGeneric(Type targetType, out Type converterType)
=> _generics.TryRemove(targetType, out converterType);
private Type GetMostSpecific(Type type) private Type GetMostSpecific(Type type)
{ {
if (_generics.TryGetValue(type, out var matching)) if (_generics.TryGetValue(type, out var matching))