Revert "Revert "Replace legacy Evaluator with IntegerExpressions.""

This reverts commit 4f16b0d464.
This commit is contained in:
Matthias Mailänder
2023-05-20 20:26:15 +02:00
committed by Gustas
parent b18c2fe855
commit 94abd8a928
3 changed files with 16 additions and 123 deletions

View File

@@ -1,108 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System;
using System.Collections.Generic;
namespace OpenRA.Support
{
public static class Evaluator
{
public static int Evaluate(string expr)
{
return Evaluate(expr, new Dictionary<string, int>());
}
public static int Evaluate(string expr, Dictionary<string, int> syms)
{
var toks = Tokens(expr, "+-*/()");
var postfix = ToPostfix(toks, syms);
var s = new Stack<int>();
foreach (var t in postfix)
{
switch (t[0])
{
case '+': ApplyBinop(s, (x, y) => y + x); break;
case '-': ApplyBinop(s, (x, y) => y - x); break;
case '*': ApplyBinop(s, (x, y) => y * x); break;
case '/': ApplyBinop(s, (x, y) => y / x); break;
default: s.Push(Exts.ParseIntegerInvariant(t)); break;
}
}
return s.Pop();
}
static void ApplyBinop(Stack<int> s, Func<int, int, int> f)
{
var x = s.Pop();
var y = s.Pop();
s.Push(f(x, y));
}
static IEnumerable<string> ToPostfix(IEnumerable<string> toks, Dictionary<string, int> syms)
{
var s = new Stack<string>();
foreach (var t in toks)
{
if (t[0] == '(') s.Push(t);
else if (t[0] == ')')
{
var temp = "";
while ((temp = s.Pop()) != "(") yield return temp;
}
else if (char.IsNumber(t[0])) yield return t;
else if (char.IsLetter(t[0]))
{
if (!syms.ContainsKey(t))
throw new InvalidOperationException($"Substitution `{t}` undefined");
yield return syms[t].ToString();
}
else
{
while (s.Count > 0 && Prec[t] <= Prec[s.Peek()]) yield return s.Pop();
s.Push(t);
}
}
while (s.Count > 0) yield return s.Pop();
}
static readonly Dictionary<string, int> Prec
= new() { { "+", 0 }, { "-", 0 }, { "*", 1 }, { "/", 1 }, { "(", -1 } };
static IEnumerable<string> Tokens(string expr, string ops)
{
var s = "";
foreach (var c in expr)
{
if (char.IsWhiteSpace(c))
{
if (s != "") yield return s;
s = "";
}
else if (ops.Contains(c))
{
if (s != "") yield return s;
s = "";
yield return "" + c;
}
else
s += c;
}
if (s != "") yield return s;
}
}
}

View File

@@ -11,6 +11,7 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Network;
@@ -189,10 +190,10 @@ namespace OpenRA.Widgets
// Info defined in YAML
public string Id = null;
public string X = "0";
public string Y = "0";
public string Width = "0";
public string Height = "0";
public IntegerExpression X;
public IntegerExpression Y;
public IntegerExpression Width;
public IntegerExpression Height;
public string[] Logic = Array.Empty<string>();
public ChromeLogic[] LogicObjects { get; private set; }
public bool Visible = true;
@@ -272,16 +273,17 @@ namespace OpenRA.Widgets
substitutions.Add("PARENT_LEFT", parentBounds.Left);
substitutions.Add("PARENT_TOP", parentBounds.Top);
substitutions.Add("PARENT_BOTTOM", parentBounds.Height);
var width = Evaluator.Evaluate(Width, substitutions);
var height = Evaluator.Evaluate(Height, substitutions);
var readOnlySubstitutions = new ReadOnlyDictionary<string, int>(substitutions);
var width = Width != null ? Width.Evaluate(readOnlySubstitutions) : 0;
var height = Height != null ? Height.Evaluate(readOnlySubstitutions) : 0;
substitutions.Add("WIDTH", width);
substitutions.Add("HEIGHT", height);
Bounds = new Rectangle(Evaluator.Evaluate(X, substitutions),
Evaluator.Evaluate(Y, substitutions),
width,
height);
var x = X != null ? X.Evaluate(readOnlySubstitutions) : 0;
var y = Y != null ? Y.Evaluate(readOnlySubstitutions) : 0;
Bounds = new Rectangle(x, y, width, height);
}
public void PostInit(WidgetArgs args)

View File

@@ -15,7 +15,6 @@ using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Support;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic
@@ -511,8 +510,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{ "PARENT_BOTTOM", parentBounds.Height }
};
var width = Evaluator.Evaluate(w.Width, substitutions);
var height = Evaluator.Evaluate(w.Height, substitutions);
var width = w.Width.Evaluate(substitutions);
var height = w.Height.Evaluate(substitutions);
substitutions.Add("WIDTH", width);
substitutions.Add("HEIGHT", height);
@@ -521,8 +520,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
w.Bounds = new Rectangle(w.Bounds.X, w.Bounds.Y, width, w.Bounds.Height);
else
w.Bounds = new Rectangle(
Evaluator.Evaluate(w.X, substitutions),
Evaluator.Evaluate(w.Y, substitutions),
w.X.Evaluate(substitutions),
w.Y.Evaluate(substitutions),
width,
height);