Skip to content

Commit

Permalink
Extract node matcher
Browse files Browse the repository at this point in the history
Will eventually be useful in modifying nodes too, but not without some
refactoring.  For now it is only used on root patches.
  • Loading branch information
blowfishpro committed Apr 12, 2018
1 parent cccdc85 commit 3698d7c
Show file tree
Hide file tree
Showing 8 changed files with 541 additions and 28 deletions.
1 change: 1 addition & 0 deletions ModuleManager/ModuleManager.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<Compile Include="ModuleManager.cs" />
<Compile Include="ModListGenerator.cs" />
<Compile Include="NeedsChecker.cs" />
<Compile Include="NodeMatcher.cs" />
<Compile Include="Operator.cs" />
<Compile Include="OperatorParser.cs" />
<Compile Include="Pass.cs" />
Expand Down
88 changes: 88 additions & 0 deletions ModuleManager/NodeMatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using ModuleManager.Extensions;

namespace ModuleManager
{
public interface INodeMatcher
{
bool IsMatch(ConfigNode node);
}

public class NodeMatcher : INodeMatcher
{
private static readonly char[] sep = { '[', ']' };

private string type;
private string[] namePatterns = null;
private string constraints = "";

public NodeMatcher(string nodeName)
{
if (nodeName == null) throw new ArgumentNullException(nameof(nodeName));
if (nodeName == "") throw new ArgumentException("can't be empty", nameof(nodeName));
if (!nodeName.IsBracketBalanced()) throw new FormatException("node name is not bracket balanced: " + nodeName);
string name = nodeName;

int indexOfHas = name.IndexOf(":HAS[", StringComparison.InvariantCultureIgnoreCase);

if (indexOfHas == 0)
{
throw new FormatException("node name cannot begin with :HAS : " + nodeName);
}
else if (indexOfHas > 0)
{
int closingBracketIndex = name.LastIndexOf(']', name.Length - 1, name.Length - indexOfHas - 1);
// Really shouldn't happen if we're bracket balanced but just in case
if (closingBracketIndex == -1) throw new FormatException("Malformed :HAS[] block detected: " + nodeName);

constraints = name.Substring(indexOfHas + 5, closingBracketIndex - indexOfHas - 5);
name = name.Substring(0, indexOfHas);
}

int bracketIndex = name.IndexOf('[');
if (bracketIndex == 0)
{
throw new FormatException("node name cannot begin with a bracket: " + nodeName);
}
else if (bracketIndex > 0)
{
int closingBracketIndex = name.LastIndexOf(']', name.Length - 1, name.Length - bracketIndex - 1);
// Really shouldn't happen if we're bracket balanced but just in case
if (closingBracketIndex == -1) throw new FormatException("Malformed brackets detected: " + nodeName);
string patterns = name.Substring(bracketIndex + 1, closingBracketIndex - bracketIndex - 1);
namePatterns = patterns.Split(',', '|');
type = name.Substring(0, bracketIndex);
}
else
{
type = name;
namePatterns = null;
}
}

public bool IsMatch(ConfigNode node)
{
if (node.name != type) return false;

if (namePatterns != null)
{
string name = node.GetValue("name");
if (name == null) return false;

bool match = false;
foreach (string pattern in namePatterns)
{
if (MMPatchLoader.WildcardMatch(name, pattern))
{
match = true;
break;
}
}

if (!match) return false;
}

return MMPatchLoader.CheckConstraints(node, constraints);
}
}
}
3 changes: 3 additions & 0 deletions ModuleManager/Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class Patch
public readonly UrlDir.UrlConfig urlConfig;
public readonly Command command;
public readonly ConfigNode node;
public readonly INodeMatcher nodeMatcher;

public Patch(UrlDir.UrlConfig urlConfig, Command command, ConfigNode node)
{
Expand All @@ -16,6 +17,8 @@ public Patch(UrlDir.UrlConfig urlConfig, Command command, ConfigNode node)
this.urlConfig = urlConfig ?? throw new ArgumentNullException(nameof(urlConfig));
this.command = command;
this.node = node ?? throw new ArgumentNullException(nameof(node));

nodeMatcher = new NodeMatcher(node.name);
}
}
}
32 changes: 4 additions & 28 deletions ModuleManager/PatchApplier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ private void ApplyPatches(IPass pass)
{
foreach (UrlDir.UrlConfig url in file.configs)
{
if (!IsMatch(url, type, patterns, condition)) continue;
if (!patch.nodeMatcher.IsMatch(url.config)) continue;
if (loop) logger.Info($"Looping on {patch.urlConfig.SafeUrl()} to {url.SafeUrl()}");

do
{
progress.ApplyingUpdate(url, patch.urlConfig);
url.config = MMPatchLoader.ModifyNode(new NodeStack(url.config), patch.node, context);
} while (loop && IsMatch(url, type, patterns, condition));
} while (loop && patch.nodeMatcher.IsMatch(url.config));

if (loop) url.config.RemoveNodes("MM_PATCH_LOOP");
}
Expand All @@ -102,7 +102,7 @@ private void ApplyPatches(IPass pass)
for (int i = 0; i < count; i++)
{
UrlDir.UrlConfig url = file.configs[i];
if (!IsMatch(url, type, patterns, condition)) continue;
if (!patch.nodeMatcher.IsMatch(url.config)) continue;

ConfigNode clone = MMPatchLoader.ModifyNode(new NodeStack(url.config), patch.node, context);
if (url.config.HasValue("name") && url.config.GetValue("name") == clone.GetValue("name"))
Expand All @@ -123,7 +123,7 @@ private void ApplyPatches(IPass pass)
{
UrlDir.UrlConfig url = file.configs[i];

if (IsMatch(url, type, patterns, condition))
if (patch.nodeMatcher.IsMatch(url.config))
{
progress.ApplyingDelete(url, patch.urlConfig);
file.configs.RemoveAt(i);
Expand Down Expand Up @@ -156,29 +156,5 @@ private void ApplyPatches(IPass pass)
}
}
}

private static bool IsMatch(UrlDir.UrlConfig url, string type, string[] namePatterns, string constraints)
{
if (url.type != type) return false;

if (namePatterns != null)
{
if (url.name == url.type) return false;

bool match = false;
foreach (string pattern in namePatterns)
{
if (MMPatchLoader.WildcardMatch(url.name, pattern))
{
match = true;
break;
}
}

if (!match) return false;
}

return MMPatchLoader.CheckConstraints(url.config, constraints);
}
}
}
1 change: 1 addition & 0 deletions ModuleManagerTests/ModuleManagerTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
<Compile Include="Logging\ExceptionMessageTest.cs" />
<Compile Include="Logging\NormalMessageTest.cs" />
<Compile Include="Logging\QueueLoggerTest.cs" />
<Compile Include="NodeMatcherTest.cs" />
<Compile Include="OperatorParserTest.cs" />
<Compile Include="PassTest.cs" />
<Compile Include="PatchApplierTest.cs" />
Expand Down
Loading

0 comments on commit 3698d7c

Please sign in to comment.