-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChangeMonitor.cs
92 lines (81 loc) · 1.99 KB
/
ChangeMonitor.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
80
81
82
83
84
85
86
87
88
89
90
91
92
using System.Collections.Generic;
using System;
public class ChangeMonitor {
public delegate T Query<T>();
public delegate bool Evaluator<T>(T currentValue, T previousValue);
private interface IProperty {
bool Evaluate();
}
private class Property<T>: IProperty {
public Query<T> query;
public Evaluator<T> evaluator;
public T lastObservedValue;
#region IProperty implementation
public bool Evaluate ()
{
var newValue = query();
var evaluatesAsTrue = evaluator(newValue, lastObservedValue);
lastObservedValue = newValue;
return evaluatesAsTrue;
}
#endregion
}
private readonly ICollection<IProperty> properties;
private readonly bool evaluateAsTrueOnFirstPass;
private bool firstPassPending;
public ChangeMonitor(bool evaluateAsTrueOnFirstPass = true)
{
properties = new HashSet<IProperty>();
this.evaluateAsTrueOnFirstPass = evaluateAsTrueOnFirstPass;
firstPassPending = true;
}
public void Add<T>(Query<T> query) {
var property = new Property<T> {
query = query,
evaluator = (alfa, bravo) => alfa == null ? bravo != null : !alfa.Equals(bravo),
lastObservedValue = query()
};
properties.Add(property);
}
public void Add<T>(Query<T> query, Evaluator<T> evaluator) {
var property = new Property<T> {
query = query,
evaluator = evaluator,
lastObservedValue = query()
};
properties.Add(property);
}
public bool Evaluate() {
var result = firstPassPending && evaluateAsTrueOnFirstPass;
foreach(var property in properties)
{
result |= property.Evaluate();
}
firstPassPending = false;
return result;
}
public static bool ArrayEvaluator<T>(T[] alfa, T[] bravo)
{
if(alfa != bravo)
{
return true;
}
else if(alfa.Length != bravo.Length)
{
return true;
}
else if(alfa.Length > 0) {
var result = false;
for(int i = 0; i < alfa.Length && !result; i++)
{
var a = alfa[i];
var b = bravo[i];
result |= a == null ? b != null : !a.Equals(b);
}
return result;
}
else {
return false;
}
}
}