Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Corrected lack of XML.ElementInfo text and element child mixing #161

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

Spartan322
Copy link
Collaborator

ElementInfo:
Added XmlNodeType Type
Added IsText for validating ElementInfo as text element
Added default ctor that sets Type to Element
Added argument ctor to streamline construction
Added TryContentAs methods for bool validation of content
Added GetContentAs methods for default failed conversions of content
Added TryAttributeAs methods
Added GetAttributeAs methods
Added AttributeAs methods for throwing exceptions
Added TryAddChild for bool validation of add
Added TrySetParent for bool validation of parent setting
Added TrySetAttribute for bool validation attribute setting
Added TryGetAttribute for bool validation and out of attribute string
Added SetParent, and SetAttribute for method chaining
Added GetAttribute for attribute string retrieval with default
WriteToXML will write text elements with WriteString(Content)
Added FromText for generating a text element from a string input
Created ElementInfoStringExtensions for string handling
Created ElementInfoListExtensions to take the place of ListExtensions
ListExtensions is obsolete
Created ElementInfoDictionaryExtensions for conversion for the attribute dictionary
EventExecutor implements element and text mixing

ElementInfo:
	Added XmlNodeType Type
	Added IsText for validating ElementInfo as text element
	Added default ctor that sets Type to Element
	Added argument ctor to streamline construction
	Added TryContentAs methods for bool validation of content
	Added GetContentAs methods for default failed conversions of content
	Added TryAttributeAs methods
	Added GetAttributeAs methods
	Added AttributeAs methods for throwing exceptions
	Added TryAddChild for bool validation of add
	Added TrySetParent for bool validation of parent setting
	Added TrySetAttribute for bool validation attribute setting
	Added TryGetAttribute for bool validation and out of attribute string
	Added SetParent, and SetAttribute for method chaining
	Added GetAttribute for attribute string retrieval with default
	WriteToXML will write text elements with WriteString(Content)
	Added FromText for generating a text element from a string input
Created ElementInfoStringExtensions for string handling
Created ElementInfoListExtensions to take the place of ListExtensions
ListExtensions is obsolete
Created ElementInfoDictionaryExtensions for conversion for the attribute dictionary
EventExecutor implements element and text mixing
@Fayti1703
Copy link
Contributor

Fayti1703 commented Apr 25, 2022

I'd personally change the names and architecture a little -- specifically, I'd split ElementInfo into NodeInfo and ElementInfo : NodeInfo -- some operations that make sense on elements (e.g. anything related to attributes, having other NodeInfos as children) don't make sense on text nodes.

@Spartan322
Copy link
Collaborator Author

Spartan322 commented Apr 27, 2022

I'd personally change the names and architecture a little -- specifically, I'd split ElementInfo into NodeInfo and ElementInfo : NodeInfo -- some operations that make sense on elements (e.g. anything related to attributes, having other NodeInfos as children) don't make sense on text nodes.

I'm pretty sure that's a breaking change, can be considered for major version change, but I'm fairly sure that would violate semver to do otherwise and it actually could have capability to cause problems for mod devs if they used 5.1.0 and this is what anything other then 6.0.0 had in it.

@Fayti1703
Copy link
Contributor

I'd personally change the names and architecture a little -- specifically, I'd split ElementInfo into NodeInfo and ElementInfo : NodeInfo -- some operations that make sense on elements (e.g. anything related to attributes, having other NodeInfos as children) don't make sense on text nodes.

I'm pretty sure that's a breaking change,

Changing the class architecture (i.e. adding NodeInfo) itself shouldn't be, but you're right that changing the method signatures / collection types would be.

I guess for that we could go for something DOMian here -- Children that only contains child elements, ChildNodes that contains all nodes, including text nodes.

@Fayti1703
Copy link
Contributor

Something else: The As%Type% methods for attributes specify the name as literally attribute[key], resulting in FormatExceptions with text like Value of 'attribute[key]' is not true or false

@Spartan322
Copy link
Collaborator Author

Spartan322 commented Apr 27, 2022

Something else: The As%Type% methods for attributes specify the name as literally attribute[key], resulting in FormatExceptions with text like Value of 'attribute[key]' is not true or false

This is kind of an intended output, perhaps it should say something like Value of 'attribute[key]' is 'not a boolean value' but is not true or false instead.

@Fayti1703
Copy link
Contributor

You sure we don't want, say, 'attribute[foobar]' in there?

AsBoolean, AsFloat, and AsInt FormatExceptions describe both the content value and the key's value for dictionaries
=> ElementInfoListExtensions.TryGetElement(list, elementName, out info);
}

public static class ElementInfoDictionaryExtensions
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these not the same extension methods that already exist in PathfinderAPI.Utils.DictionaryExtensions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either I forgot or it was done before we had those, this stuff was around for a long time before I committed it.

: throw new FormatException($"Value of '{valName}' is '{content}' which is not a float, e.g.: 1.0");
}

public static class ElementInfoListExtensions
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is being done here? These methods are not extension methods in this class, yet the ones in the obsolete class got their API changed (it was changed from List to IEnumerable)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a screwup, I'll fix it, would've been a breaking change if I don't.

: throw new FormatException($"Value of '{Name}' is not a float, e.g.: 1.0");
=> Content.AsFloat(nameof(Content));

public bool TryAttributeAsBoolean(string attribName, out bool result)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This naming scheme seems confusing, the behavior difference between GetAttributeAsX/AttributeAsX/TryAttributeAsX are not clear and I believe they would be prone to incorrect usage

Copy link
Collaborator Author

@Spartan322 Spartan322 May 1, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I probably should remove AttributeAs methods and instead add required and default behavior to GetAttributeAs like GetAttributeAsInt(string name, bool required = false, int def = default) (or could do GetAttributeAsInt(string name, int? def = null))

return Children.Last() == info;
}

public bool TrySetParent(ElementInfo info)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this makes sense to be here, an element doesn't doesn't care about its parent, so why would you set it through the child element

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose, was doing it for convenience but I suppose a child doesn't need to be aware of its parent's add success

@@ -16,6 +19,20 @@ public class ElementInfo
public Dictionary<string, string> Attributes { get; set; } = new Dictionary<string, string>();
public List<ElementInfo> Children { get; set; } = new List<ElementInfo>();
public ulong NodeID { get; } = freeId++;
public XmlNodeType Type { get; set; }
public bool IsText => Type == XmlNodeType.Text;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This entire structure is confusing, why can a text element have attributes and children if they will never be serialized? This also makes adding text to an element two operations for a developer, since I have to both create a child element and also append to Content myself to keep everything up to date. These being out of sync really shouldn't be allowed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backwards compatibility, this was addressed with here. It obviously doesn't make sense but without a refactor which would introduce breaking changes, which is addressed with #163, there is no safe way for mods to rely on the API's semver being true.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants