Added callbacks to TagReader class to permit user-handled parsing
This commit is contained in:
parent
778d15f44b
commit
a3e5ce5f5a
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace SharpNBT
|
||||
{
|
||||
/// <summary>
|
||||
/// Arguments supplied with tag-related events.
|
||||
/// </summary>
|
||||
public class TagEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a constant describing the basic NBT type of the tag.
|
||||
/// </summary>
|
||||
public TagType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parsed <see cref="Tag"/> instance.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public Tag Tag { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="TagEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="type">A constant describing the basic NBT type of the tag.</param>
|
||||
/// <param name="tag">The parsed <see cref="Tag"/> instance.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="tag"/> is <see langword="null"/>.</exception>
|
||||
public TagEventArgs(TagType type, [NotNull] Tag tag)
|
||||
{
|
||||
Type = type;
|
||||
Tag = tag ?? throw new ArgumentNullException(nameof(tag));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace SharpNBT
|
||||
{
|
||||
/// <summary>
|
||||
/// Arguments supplied when an event that can be handled by an event subscriber.
|
||||
/// </summary>
|
||||
public class TagHandledEventArgs : HandledEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a constant describing the basic NBT type of the tag.
|
||||
/// </summary>
|
||||
public TagType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets flag indicating if this tag is named, only <see langowrd="false"/> when a tag is a direct child of a <see cref="ListTag"/>.
|
||||
/// </summary>
|
||||
public bool IsNamed { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the stream being read from, positioned at the beginning of the tag payload.
|
||||
/// <para/>
|
||||
/// When handling this event, the stream position must be moved to the end of the payload, ready for the next tag to be parsed.
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public Stream Stream { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the resulting tag from this event being handled.
|
||||
/// </summary>
|
||||
/// <remarks>This property <b>must</b> set to a non-null value when <see cref="HandledEventArgs.Handled"/> is <see langword="true"/>.</remarks>
|
||||
[CanBeNull]
|
||||
public Tag Result { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="TagHandledEventArgs"/> class.
|
||||
/// </summary>
|
||||
/// <param name="type">A constant describing the basic NBT type of the tag.</param>
|
||||
/// <param name="isNamed">Flag indicating if this tag is named, only <see langowrd="false"/> when a tag is a direct child of a <see cref="ListTag"/>.</param>
|
||||
/// <param name="stream">The stream being read from, positioned at the beginning of the tag payload.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="stream"/> is <see langword="null"/>.</exception>
|
||||
public TagHandledEventArgs(TagType type, bool isNamed, [NotNull] Stream stream)
|
||||
{
|
||||
Type = type;
|
||||
IsNamed = isNamed;
|
||||
Stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace SharpNBT
|
||||
{
|
||||
/// <summary>
|
||||
/// Handler for events used with the <see cref="TagReader"/> class.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">A type derived from <see cref="EventArgs"/>.</typeparam>
|
||||
/// <param name="reader">The <see cref="TagReader"/> instance invoking the event.</param>
|
||||
/// <param name="args">Any relevant args to be supplied with the callback,</param>
|
||||
public delegate void TagReaderCallback<in T>(TagReader reader, T args) where T : EventArgs;
|
||||
}
|
|
@ -7,12 +7,7 @@ using JetBrains.Annotations;
|
|||
|
||||
namespace SharpNBT
|
||||
{
|
||||
/// <summary>
|
||||
/// Delegate type for tag-related events that can occur within the <see cref="TagReader"/> class.
|
||||
/// </summary>
|
||||
/// <seealso cref="TagReader.TagRead"/>
|
||||
public delegate void TagReadCallback(TagReader reader, TagType type, Tag tag);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Provides methods for reading NBT data from a stream.
|
||||
/// </summary>
|
||||
|
@ -22,7 +17,9 @@ namespace SharpNBT
|
|||
/// <summary>
|
||||
/// Occurs when a tag has been fully deserialized from the stream.
|
||||
/// </summary>
|
||||
public event TagReadCallback TagRead;
|
||||
public event TagReaderCallback<TagEventArgs> TagRead;
|
||||
|
||||
public event TagReaderCallback<TagHandledEventArgs> TagEncountered;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying stream this <see cref="TagReader"/> is operating on.
|
||||
|
@ -351,6 +348,13 @@ namespace SharpNBT
|
|||
[NotNull]
|
||||
private Tag ReadTag(TagType type, bool named)
|
||||
{
|
||||
var result = OnTagEncountered(type, named);
|
||||
if (result != null)
|
||||
{
|
||||
OnTagRead(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Tag tag = type switch
|
||||
{
|
||||
TagType.End => new EndTag(),
|
||||
|
@ -447,7 +451,19 @@ namespace SharpNBT
|
|||
/// Invokes the <see cref="TagRead"/> event when a tag has been fully deserialized from the <see cref="BaseStream"/>.
|
||||
/// </summary>
|
||||
/// <param name="tag">The deserialized <see cref="Tag"/> instance.</param>
|
||||
protected virtual void OnTagRead(Tag tag) => TagRead?.Invoke(this, tag.Type, tag);
|
||||
protected virtual void OnTagRead(Tag tag) => TagRead?.Invoke(this, new TagEventArgs(tag.Type, tag));
|
||||
|
||||
[CanBeNull]
|
||||
protected virtual Tag OnTagEncountered(TagType type, bool named)
|
||||
{
|
||||
// Early out if no subscribers.
|
||||
if (TagEncountered is null)
|
||||
return null;
|
||||
|
||||
var args = new TagHandledEventArgs(type, named, BaseStream);
|
||||
TagEncountered.Invoke(this, args);
|
||||
return args.Handled ? args.Result : null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue