Skip to content

Commit

Permalink
reorganize xml parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
AnakinRaW committed Jun 22, 2024
1 parent dcce645 commit 64966e5
Show file tree
Hide file tree
Showing 16 changed files with 101 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using System;
using PG.StarWarsGame.Files.XML.Parsers;
using PG.StarWarsGame.Files.XML.Parsers;

namespace PG.StarWarsGame.Engine.Xml;

public interface IPetroglyphXmlFileParserFactory
{
IPetroglyphXmlFileParser<T> GetFileParser<T>();

IPetroglyphXmlFileParser GetFileParser(Type type);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace PG.StarWarsGame.Engine.Xml;

public sealed class ParserNotFoundException : Exception
{
public override string Message { get; }

public ParserNotFoundException(Type type)
{
Message = $"The parser for the type {type} was not found.";
}

public ParserNotFoundException(string tag)
{
Message = $"The parser for the tag {tag} was not found.";
}
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,44 @@
using System;
using System.Xml.Linq;
using Microsoft.Extensions.DependencyInjection;
using PG.Commons.Hashing;
using PG.StarWarsGame.Engine.DataTypes;
using PG.StarWarsGame.Files.XML;
using PG.StarWarsGame.Files.XML.Parsers;
using PG.StarWarsGame.Files.XML.Parsers.Primitives;

namespace PG.StarWarsGame.Engine.Xml.Parsers.Data;

public sealed class GameObjectParser(IServiceProvider serviceProvider) : XmlObjectParser<GameObject>(serviceProvider)
{
private readonly ICrc32HashingService _crc32Hashing = serviceProvider.GetRequiredService<ICrc32HashingService>();

protected override bool IsTagSupported(string tag)
{
throw new NotImplementedException();
}

public override GameObject Parse(XElement element)
protected override IPetroglyphXmlElementParser? GetParser(string tag)
{
throw new NotSupportedException();
switch (tag)
{
case "Land_Terrain_Model_Mapping":
return CommaSeparatedStringKeyValueListParser.Instance;
case "Galactic_Model_Name":
case "Destroyed_Galactic_Model_Name":
case "Land_Model_Name":
case "Space_Model_Name":
case "Model_Name":
case "Tactical_Model_Name":
case "Galactic_Fleet_Override_Model_Name":
case "GUI_Model_Name":
case "GUI_Model":
case "Land_Model_Anim_Override_Name":
case "xxxSpace_Model_Name":
case "Damaged_Smoke_Asset_Name":
return PetroglyphXmlStringParser.Instance;
default:
return null;
}
}

public override GameObject Parse(XElement element, IReadOnlyValueListDictionary<Crc32, GameObject> parsedElements, out Crc32 nameCrc)
{
var properties = ToKeyValuePairList(element);
var name = GetNameAttributeValue(element);
nameCrc = _crc32Hashing.GetCrc32Upper(name.AsSpan(), PGConstants.PGCrc32Encoding);
nameCrc = HashingService.GetCrc32Upper(name.AsSpan(), PGConstants.PGCrc32Encoding);
var type = GetTagName(element);
var objectType = EstimateType(type);
var gameObject = new GameObject(type, name, nameCrc, objectType, properties, XmlLocationInfo.FromElement(element));
Expand Down Expand Up @@ -83,8 +96,5 @@ private static GameObjectType EstimateType(string tagName)
};
}

public string GetTagName(XElement element)
{
return element.Name.LocalName;
}
public override GameObject Parse(XElement element) => throw new NotSupportedException();
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
using System;
using System.Xml.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PG.Commons.Hashing;
using PG.StarWarsGame.Engine.DataTypes;
using PG.StarWarsGame.Files.XML;
using PG.StarWarsGame.Files.XML.Parsers;

namespace PG.StarWarsGame.Engine.Xml.Parsers.Data;

public sealed class SfxEventParser(IServiceProvider serviceProvider) : XmlObjectParser<SfxEvent>(serviceProvider)
{
private readonly ICrc32HashingService _hashingService = serviceProvider.GetRequiredService<ICrc32HashingService>();

private readonly ILogger? _logger = serviceProvider.GetService<ILoggerFactory>()?.CreateLogger(typeof(SfxEventParser));
protected override IPetroglyphXmlElementParser? GetParser(string tag)
{
return null;
}

public override SfxEvent Parse(
XElement element,
IReadOnlyValueListDictionary<Crc32, SfxEvent> parsedElements,
out Crc32 nameCrc)
{
var name = GetNameAttributeValue(element);
nameCrc = _hashingService.GetCrc32Upper(name.AsSpan(), PGConstants.PGCrc32Encoding);
nameCrc = HashingService.GetCrc32Upper(name.AsSpan(), PGConstants.PGCrc32Encoding);

var valueList = new ValueListDictionary<string, object?>();

Expand All @@ -37,7 +37,7 @@ public override SfxEvent Parse(
if (tagName.Equals("Use_Preset"))
{
var presetName = parser.Parse(child) as string;
var presetNameCrc = _hashingService.GetCrc32Upper(presetName.AsSpan(), PGConstants.PGCrc32Encoding);
var presetNameCrc = HashingService.GetCrc32Upper(presetName.AsSpan(), PGConstants.PGCrc32Encoding);
if (presetNameCrc == default || !parsedElements.TryGetFirstValue(presetNameCrc, out var preset))
{
// Unable to find Preset
Expand All @@ -59,9 +59,4 @@ public override SfxEvent Parse(XElement element)
{
throw new NotSupportedException();
}

protected override bool IsTagSupported(string tag)
{
throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
using System;
using System.Xml.Linq;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PG.Commons.Hashing;
using PG.StarWarsGame.Engine.DataTypes;
using PG.StarWarsGame.Files.XML;
using PG.StarWarsGame.Files.XML.Parsers;

namespace PG.StarWarsGame.Engine.Xml.Parsers;

public abstract class XmlObjectParser<T>(IServiceProvider serviceProvider) : PetroglyphXmlElementParser<T> where T : XmlObject
public abstract class XmlObjectParser<T> : PetroglyphXmlElementParser<T> where T : XmlObject
{
protected IServiceProvider ServiceProvider { get; } = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
protected IServiceProvider ServiceProvider { get; }

protected abstract bool IsTagSupported(string tag);
protected ILogger? Logger { get; }

protected ICrc32HashingService HashingService { get; }

protected IPetroglyphXmlElementParser? GetParser(string tag)
protected XmlObjectParser(IServiceProvider serviceProvider)
{
if (!IsTagSupported(tag))
return null;

return null;
ServiceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
Logger = serviceProvider.GetService<ILoggerFactory>()?.CreateLogger(GetType());
HashingService = serviceProvider.GetRequiredService<ICrc32HashingService>();
}

protected abstract IPetroglyphXmlElementParser? GetParser(string tag);

protected ValueListDictionary<string, object> ToKeyValuePairList(XElement element)
{
var keyValuePairList = new ValueListDictionary<string, object>();
Expand All @@ -37,9 +43,4 @@ protected ValueListDictionary<string, object> ToKeyValuePairList(XElement elemen
}
return keyValuePairList;
}
}

internal interface IXmlParserFactory
{

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public IPetroglyphXmlFileParser<T> GetFileParser<T>()
return (IPetroglyphXmlFileParser<T>)GetFileParser(typeof(T));
}

public IPetroglyphXmlFileParser GetFileParser(Type type)
private IPetroglyphXmlFileParser GetFileParser(Type type)
{
if (type == typeof(XmlFileContainer))
return new XmlFileContainerParser(serviceProvider);
Expand All @@ -29,6 +29,6 @@ public IPetroglyphXmlFileParser GetFileParser(Type type)
if (type == typeof(SfxEvent))
return new SfxEventFileParser(serviceProvider);

throw new NotImplementedException($"The parser for the type {type} is not yet implemented.");
throw new ParserNotFoundException(type);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
using System.Xml.Linq;
using PG.Commons.Hashing;
namespace PG.StarWarsGame.Files.XML.Parsers;

namespace PG.StarWarsGame.Files.XML.Parsers;
public interface IPetroglyphXmlElementParser : IPetroglyphXmlParser;

public interface IPetroglyphXmlElementParser
{
public object Parse(XElement element);
}

public interface IPetroglyphXmlElementParser<T> : IPetroglyphXmlElementParser
{
public new T Parse(XElement element);

public T Parse(XElement element, IReadOnlyValueListDictionary<Crc32, T> parsedElements, out Crc32 nameCrc);
}
public interface IPetroglyphXmlElementParser<T> : IPetroglyphXmlElementParser, IPetroglyphXmlParser<T>;
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

namespace PG.StarWarsGame.Files.XML.Parsers;

public interface IPetroglyphXmlFileParser : IPetroglyphXmlElementParser
public interface IPetroglyphXmlFileParser : IPetroglyphXmlParser
{
public object? ParseFile(Stream stream);
}

public interface IPetroglyphXmlFileParser<T> : IPetroglyphXmlElementParser<T>, IPetroglyphXmlFileParser
public interface IPetroglyphXmlFileParser<T> : IPetroglyphXmlParser<T>, IPetroglyphXmlFileParser
{
public new T ParseFile(Stream stream);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Xml.Linq;

namespace PG.StarWarsGame.Files.XML.Parsers;

public interface IPetroglyphXmlParser
{
public object Parse(XElement element);
}

public interface IPetroglyphXmlParser<T> : IPetroglyphXmlParser
{
public new T Parse(XElement element);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
using System.Linq;
using System.Xml.Linq;
using PG.Commons.Hashing;

namespace PG.StarWarsGame.Files.XML.Parsers;

public abstract class PetroglyphXmlElementParser<T> : PetroglyphXmlParser<T>
{
protected string GetTagName(XElement element)
{
return element.Name.LocalName;
}

protected string GetNameAttributeValue(XElement element)
{
var nameAttribute = element.Attributes()
.FirstOrDefault(a => a.Name.LocalName == "Name");
return nameAttribute is null ? string.Empty : nameAttribute.Value;
}

public abstract T Parse(XElement element, IReadOnlyValueListDictionary<Crc32, T> parsedElements, out Crc32 nameCrc);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

namespace PG.StarWarsGame.Files.XML.Parsers;

public abstract class PetroglyphXmlFileParser<T>(IServiceProvider serviceProvider)
: PetroglyphXmlParser<T>, IPetroglyphXmlFileParser<T>
public abstract class PetroglyphXmlFileParser<T>(IServiceProvider serviceProvider) : PetroglyphXmlParser<T>, IPetroglyphXmlFileParser<T>
{
protected IServiceProvider ServiceProvider { get; } = serviceProvider;

Expand All @@ -27,11 +26,6 @@ public void ParseFile(Stream xmlStream, IValueListDictionary<Crc32, T> parsedEnt
Parse(root, parsedEntries);
}

public sealed override T Parse(XElement element, IReadOnlyValueListDictionary<Crc32, T> parsedElements, out Crc32 nameCrc)
{
throw new NotSupportedException();
}

protected abstract void Parse(XElement element, IValueListDictionary<Crc32, T> parsedElements);

private XElement? GetRootElement(Stream xmlStream)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
using System.Xml.Linq;
using PG.Commons.Hashing;

namespace PG.StarWarsGame.Files.XML.Parsers;

public abstract class PetroglyphXmlParser<T> : IPetroglyphXmlElementParser<T>
public abstract class PetroglyphXmlParser<T> : IPetroglyphXmlParser<T>
{
public abstract T Parse(XElement element, IReadOnlyValueListDictionary<Crc32, T> parsedElements, out Crc32 nameCrc);

public abstract T Parse(XElement element);

object IPetroglyphXmlElementParser.Parse(XElement element)
object IPetroglyphXmlParser.Parse(XElement element)
{
return Parse(element);

Check warning on line 11 in src/PetroglyphTools/PG.StarWarsGame.Files.XML/Parsers/PetroglyphXmlParser.cs

View workflow job for this annotation

GitHub Actions / Build & Test (windows-latest)

Possible null reference return.

Check warning on line 11 in src/PetroglyphTools/PG.StarWarsGame.Files.XML/Parsers/PetroglyphXmlParser.cs

View workflow job for this annotation

GitHub Actions / Build & Test (windows-latest)

Possible null reference return.

Check warning on line 11 in src/PetroglyphTools/PG.StarWarsGame.Files.XML/Parsers/PetroglyphXmlParser.cs

View workflow job for this annotation

GitHub Actions / Build & Test (ubuntu-latest)

Possible null reference return.
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace PG.StarWarsGame.Files.XML.Parsers;

public abstract class PetroglyphXmlPrimitiveElementParser<T> : PetroglyphXmlParser<T>, IPetroglyphXmlElementParser<T>;

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace PG.StarWarsGame.Files.XML.Parsers.Primitives;
// Used e.g, by <Land_Terrain_Model_Mapping>
// Format: Key, Value, Key, Value
// There might be arbitrary spaces, tabs and newlines
public sealed class CommaSeparatedStringKeyValueListParser : PetroglyphXmlPrimitiveParser<IList<(string key, string value)>>
public sealed class CommaSeparatedStringKeyValueListParser : PetroglyphXmlPrimitiveElementParser<IList<(string key, string value)>>
{
public static readonly CommaSeparatedStringKeyValueListParser Instance = new();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace PG.StarWarsGame.Files.XML.Parsers.Primitives;

public sealed class PetroglyphXmlStringParser : PetroglyphXmlPrimitiveParser<string>
public sealed class PetroglyphXmlStringParser : PetroglyphXmlPrimitiveElementParser<string>
{
public static readonly PetroglyphXmlStringParser Instance = new();

Expand Down

0 comments on commit 64966e5

Please sign in to comment.