|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public class CompositeKey : Key, IEquatable<CompositeKey> { |
|
|
|
readonly object componentKey1; |
|
|
|
readonly object componentKey2; |
|
|
|
|
|
|
|
public CompositeKey(object componentKey1, object componentKey2) { |
|
|
|
this.componentKey1 = componentKey1; |
|
|
|
this.componentKey2 = componentKey2; |
|
|
|
} |
|
|
|
|
|
|
|
public bool Equals(CompositeKey other) { |
|
|
|
if (ReferenceEquals(null, other)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (ReferenceEquals(this, other)) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
return ReferenceEquals(this.componentKey1, other.componentKey1) && |
|
|
|
ReferenceEquals(this.componentKey2, other.componentKey2); |
|
|
|
} |
|
|
|
|
|
|
|
public override bool Equals(object obj) { |
|
|
|
if (ReferenceEquals(null, obj)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (ReferenceEquals(this, obj)) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
if (obj.GetType() != this.GetType()) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return this.Equals((CompositeKey) obj); |
|
|
|
} |
|
|
|
|
|
|
|
public override int GetHashCode() { |
|
|
|
return (this.componentKey1 != null ? this.componentKey1.GetHashCode() : 0) ^ |
|
|
|
(this.componentKey2 != null ? this.componentKey2.GetHashCode() : 0); |
|
|
|
} |
|
|
|
|
|
|
|
public static bool operator ==(CompositeKey left, CompositeKey right) { |
|
|
|
return Equals(left, right); |
|
|
|
} |
|
|
|
|
|
|
|
public static bool operator !=(CompositeKey left, CompositeKey right) { |
|
|
|
return !Equals(left, right); |
|
|
|
} |
|
|
|
|
|
|
|
public override string ToString() { |
|
|
|
return this.GetType() + $"({this.componentKey1},{this.componentKey2})"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public abstract class GlobalKey : Key { |
|
|
|
protected GlobalKey() { |
|
|
|
} |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
static readonly Dictionary<GlobalKey, Element> _registry = |
|
|
|
new Dictionary<GlobalKey, Element>(); |
|
|
|
static readonly Dictionary<CompositeKey, Element> _registry = |
|
|
|
new Dictionary<CompositeKey, Element>(); |
|
|
|
static readonly HashSet<GlobalKey> _removedKeys = new HashSet<GlobalKey>(); |
|
|
|
static readonly HashSet<CompositeKey> _removedKeys = new HashSet<CompositeKey>(); |
|
|
|
static readonly Dictionary<GlobalKey, Element> _debugReservations = |
|
|
|
new Dictionary<GlobalKey, Element>(); |
|
|
|
static readonly Dictionary<CompositeKey, Element> _debugReservations = |
|
|
|
new Dictionary<CompositeKey, Element>(); |
|
|
|
CompositeKey compKey = new CompositeKey(Window.instance, this); |
|
|
|
if (_registry.ContainsKey(this)) { |
|
|
|
if (_registry.ContainsKey(compKey)) { |
|
|
|
D.assert(_registry[this].widget != null); |
|
|
|
D.assert(element.widget.GetType() != _registry[this].widget.GetType()); |
|
|
|
_debugIllFatedElements.Add(_registry[this]); |
|
|
|
D.assert(_registry[compKey].widget != null); |
|
|
|
D.assert(element.widget.GetType() != _registry[compKey].widget.GetType()); |
|
|
|
_debugIllFatedElements.Add(_registry[compKey]); |
|
|
|
_registry[this] = element; |
|
|
|
_registry[compKey] = element; |
|
|
|
CompositeKey compKey = new CompositeKey(Window.instance, this); |
|
|
|
if (_registry.ContainsKey(this) && _registry[this] != element) { |
|
|
|
if (_registry.ContainsKey(compKey) && _registry[compKey] != element) { |
|
|
|
D.assert(_registry[this].widget != null); |
|
|
|
D.assert(element.widget.GetType() != _registry[this].widget.GetType()); |
|
|
|
D.assert(_registry[compKey].widget != null); |
|
|
|
D.assert(element.widget.GetType() != _registry[compKey].widget.GetType()); |
|
|
|
if (_registry[this] == element) { |
|
|
|
_registry.Remove(this); |
|
|
|
_removedKeys.Add(this); |
|
|
|
if (_registry.getOrDefault(compKey) == element) { |
|
|
|
_registry.Remove(compKey); |
|
|
|
_removedKeys.Add(compKey); |
|
|
|
CompositeKey compKey = new CompositeKey(Window.instance, this); |
|
|
|
if (_debugReservations.ContainsKey(this) && _debugReservations[this] != parent) { |
|
|
|
string older = _debugReservations[this].ToString(); |
|
|
|
if (_debugReservations.ContainsKey(compKey) && _debugReservations[compKey] != parent) { |
|
|
|
string older = _debugReservations[compKey].ToString(); |
|
|
|
string newer = parent.ToString(); |
|
|
|
if (older != newer) { |
|
|
|
throw new UIWidgetsError( |
|
|
|
|
|
|
"A GlobalKey can only be specified on one widget at a time in the widget tree."); |
|
|
|
} |
|
|
|
|
|
|
|
_debugReservations[this] = parent; |
|
|
|
_debugReservations[compKey] = parent; |
|
|
|
return true; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
D.assert(element.widget != null); |
|
|
|
D.assert(element.widget.key != null); |
|
|
|
GlobalKey key = (GlobalKey) element.widget.key; |
|
|
|
D.assert(_registry.ContainsKey(key)); |
|
|
|
CompositeKey compKey = new CompositeKey(Window.instance, key); |
|
|
|
|
|
|
|
D.assert(_registry.ContainsKey(compKey)); |
|
|
|
elements.Add(_registry[key]); |
|
|
|
elements.Add(_registry[compKey]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
internal Element _currentElement { |
|
|
|
get { |
|
|
|
Element result; |
|
|
|
_registry.TryGetValue(this, out result); |
|
|
|
CompositeKey compKey = new CompositeKey(Window.instance, this); |
|
|
|
_registry.TryGetValue(compKey, out result); |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
if (fn != null) { |
|
|
|
fn(); |
|
|
|
} |
|
|
|
|
|
|
|
this._element.markNeedsBuild(); |
|
|
|
} |
|
|
|
|
|
|
|