forked from MUnique/OpenMU
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AttributeRelationshipElement.cs
79 lines (68 loc) · 2.79 KB
/
AttributeRelationshipElement.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// <copyright file="AttributeRelationshipElement.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.AttributeSystem;
/// <summary>
/// An attribute relationship element which takes several input elements which are summed up and multiplied.
/// Calculated values are cached for a better performance.
/// </summary>
public class AttributeRelationshipElement : SimpleElement
{
private float? _cachedValue;
/// <summary>
/// Initializes a new instance of the <see cref="AttributeRelationshipElement" /> class.
/// </summary>
/// <param name="inputElements">The input elements which are summed up.</param>
/// <param name="inputOperand">The operand which is applied to the summed up input elements.</param>
/// <param name="inputOperator">The input operator.</param>
public AttributeRelationshipElement(IEnumerable<IElement> inputElements, IElement inputOperand, InputOperator inputOperator)
{
this.InputElements = inputElements;
this.InputOperand = inputOperand;
this.InputOperator = inputOperator;
foreach (var element in this.InputElements)
{
element.ValueChanged += this.ElementChanged;
}
inputOperand.ValueChanged += this.ElementChanged;
// TODO: Is Dispose required?
}
/// <summary>
/// Gets the input elements.
/// </summary>
public IEnumerable<IElement> InputElements { get; }
/// <summary>
/// Gets or sets the multiplier with which the sum of all input element values are multiplied.
/// </summary>
public IElement InputOperand { get; set; }
/// <summary>
/// Gets or sets the input operator.
/// </summary>
public InputOperator InputOperator { get; set; }
/// <summary>
/// Gets the calculated value.
/// </summary>
public override float Value => this._cachedValue ?? this.GetAndCacheValue();
private void ElementChanged(object? sender, EventArgs eventArgs)
{
this._cachedValue = null;
this.RaiseValueChanged();
}
private float GetAndCacheValue()
{
this._cachedValue = this.CalculateValue();
return this._cachedValue.Value;
}
private float CalculateValue()
{
return this.InputOperator switch
{
InputOperator.Multiply => this.InputElements.Sum(a => a.Value) * this.InputOperand.Value,
InputOperator.Add => this.InputElements.Sum(a => a.Value) + this.InputOperand.Value,
InputOperator.Exponentiate => (float)Math.Pow(
this.InputElements.Sum(a => a.Value),
this.InputOperand.Value),
_ => throw new InvalidOperationException($"Input operator {this.InputOperator} unknown")
};
}
}