/// <summary> /// Sets the watch on a node that is not our document node, but a node lower in the hierarchy. We watch both the Changed event and the TunneledEvent of this node. /// </summary> /// <param name="node">The node to watch.</param> protected virtual void SetWatchOnNode(IDocumentLeafNode node) { #if DOCNODEPROXY_CONCURRENTDEBUG int debugUsn = System.Threading.Interlocked.Increment(ref _debugUSN); _debug.Enqueue("START SetWatchOnNode " + debugUsn.ToString()); #endif if (null == node) { throw new ArgumentNullException(nameof(node)); } if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } node.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler <object, object, TunnelingEventArgs>(EhWatchedNode_TunneledEvent, handler => node.TunneledEvent -= handler)); node.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhWatchedNode_Changed, handler => node.Changed -= handler)); #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("Start watching node <<{0}>> of total path <<{1}>>", AbsoluteDocumentPath.GetAbsolutePath(node), _docNodePath); #endif #if DOCNODEPROXY_CONCURRENTDEBUG _debug.Enqueue("STOP SetWatchOnNode " + debugUsn.ToString() + (_docNodeRef == null).ToString()); #endif }
/// <summary> /// Sets the watch on a node that is not our document node, but a node lower in the hierarchy. We watch both the Changed event and the TunneledEvent of this node. /// </summary> /// <param name="node">The node to watch.</param> protected virtual void SetWatchOnNode(IDocumentLeafNode node) { if (null == node) { throw new ArgumentNullException(nameof(node)); } if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } node.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler <object, object, TunnelingEventArgs>(EhWatchedNode_TunneledEvent, handler => node.TunneledEvent -= handler)); node.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhWatchedNode_Changed, handler => node.Changed -= handler)); #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("Start watching node <<{0}>> of total path <<{1}>>", AbsoluteDocumentPath.GetAbsolutePath(node), _docNodePath); #endif }
/// <summary> /// Sets the document node that is held by this proxy. /// </summary> /// <param name="value">The document node. If <c>docNode</c> implements <see cref="Main.IDocumentLeafNode" />, /// the document path is stored for this object in addition to the object itself.</param> /// <param name="parentNode">The start point of the document path. Should be equal to the member _parent, but this might be not set now.</param> protected void InternalSetDocNode(Main.IDocumentLeafNode value, IDocumentLeafNode parentNode) { if (!IsValidDocument(value)) { throw new ArgumentException("This type of document is not allowed for the proxy of type " + GetType().ToString()); } if (null == parentNode) { throw new InvalidOperationException("Parent of this node must be set in order to set the docnode."); } var oldValue = InternalDocNode; if (object.ReferenceEquals(oldValue, value)) { return; // Nothing to do } if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } if (null != oldValue) { ClearDocNode(); } var newPath = RelativeDocumentPath.GetRelativePathFromTo(parentNode, value); if (null != newPath) { InternalDocumentPath = newPath; // especially in dispose situations, the new path can be null. In this case we leave the path as it was } _docNodeRef = new WeakReference(value); #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("RelDocNodeProxy.SetDocNode, path is <<{0}>>", _docNodePath); #endif value.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler <object, object, TunnelingEventArgs>(EhDocNode_TunneledEvent, handler => value.TunneledEvent -= handler)); if (null != _docNodePath && !_docNodePath.IsIdentity) // it does not make sense to watch the changed event of our target node is our parent because the parent can handle the Changed event itself { value.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhDocNode_Changed, handler => value.Changed -= handler)); } OnAfterSetDocNode(); EhSelfChanged(new Main.InstanceChangedEventArgs(oldValue, value)); }
/// <summary> /// Removes the event handlers for the watch /// </summary> protected void ClearWatch() { if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } }
/// <summary> /// Removes the event handlers for the watch /// </summary> protected void ClearWatch() { #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("DocNodeProxy.ClearWatch: path={0}", _docNodePath.ToString()); #endif if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } }
/// <summary> /// Disposing this instance is special - we must not dispose the reference this instance holds. /// Instead, we remove all references to the holded document node and also all event handlers- /// </summary> /// <param name="isDisposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> protected override void Dispose(bool isDisposing) { if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } _docNodeRef = null; #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("DocNodeProxy.Dispose, path was >>>{0}<<<", _docNodePath); #endif _docNodePath = null; base.Dispose(isDisposing); }
/// <summary> /// Sets the document node to null, but keeps the doc node path. /// </summary> protected void ClearDocNode() { if (_docNodeRef == null) { return; } OnBeforeClearDocNode(); if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } _docNodeRef = null; }
/// <summary> /// Sets the watch on a node that is not our document node, but a node lower in the hierarchy. We watch both the Changed event and the TunneledEvent of this node. /// </summary> /// <param name="node">The node to watch.</param> protected virtual void SetWatchOnNode(IDocumentLeafNode node) { #if DOCNODEPROXY_CONCURRENTDEBUG int debugUsn = System.Threading.Interlocked.Increment(ref _debugUSN); _debug.Enqueue("START SetWatchOnNode " + debugUsn.ToString()); #endif if (null == node) throw new ArgumentNullException(nameof(node)); if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } node.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler<object, object, TunnelingEventArgs>(EhWatchedNode_TunneledEvent, handler => node.TunneledEvent -= handler)); node.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhWatchedNode_Changed, handler => node.Changed -= handler)); #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("Start watching node <<{0}>> of total path <<{1}>>", AbsoluteDocumentPath.GetAbsolutePath(node), _docNodePath); #endif #if DOCNODEPROXY_CONCURRENTDEBUG _debug.Enqueue("STOP SetWatchOnNode " + debugUsn.ToString() + (_docNodeRef == null).ToString()); #endif }
/// <summary> /// Sets the document node that is held by this proxy. /// </summary> /// <param name="value">The document node. If <c>docNode</c> implements <see cref="Main.IDocumentLeafNode" />, /// the document path is stored for this object in addition to the object itself.</param> public void SetDocNode(IDocumentLeafNode value) { if (null == value) { throw new ArgumentNullException(nameof(value)); } var oldValue = InternalDocumentNode; if (object.ReferenceEquals(oldValue, value)) { return; } if (!IsValidDocument(value)) { throw new ArgumentException("This type of document is not allowed for the proxy of type " + GetType().ToString()); } #if DOCNODEPROXY_CONCURRENTDEBUG _debug.Enqueue("START SetDocNode"); #endif if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } #if DOCNODEPROXY_CONCURRENTDEBUG _debug.Enqueue("MIDDL SetDocNode EventHandlers removed"); #endif if (oldValue != null) { ClearDocNode(); } InternalDocumentPath = Main.AbsoluteDocumentPath.GetAbsolutePath(value); _docNodeRef = new WeakReference(value); #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("DocNodeProxy.SetDocNode, path is <<{0}>>", _docNodePath); #endif InternalCheckAbsolutePath(); value.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler <object, object, TunnelingEventArgs>(EhDocNode_TunneledEvent, handler => value.TunneledEvent -= handler)); value.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhDocNode_Changed, handler => value.Changed -= handler)); OnAfterSetDocNode(); EhSelfChanged(new Main.InstanceChangedEventArgs(oldValue, value)); #if DOCNODEPROXY_CONCURRENTDEBUG _debug.Enqueue("STOP SetDocNode"); #endif }
/// <summary> /// Sets the document node to null, but keeps the doc node path. /// </summary> protected void ClearDocNode() { if (_docNodeRef == null) return; OnBeforeClearDocNode(); if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } _docNodeRef = null; }
/// <summary> /// Sets the document node that is held by this proxy. /// </summary> /// <param name="value">The document node. If <c>docNode</c> implements <see cref="Main.IDocumentLeafNode" />, /// the document path is stored for this object in addition to the object itself.</param> public void SetDocNode(IDocumentLeafNode value) { if (null == value) throw new ArgumentNullException(nameof(value)); var oldValue = InternalDocumentNode; if (object.ReferenceEquals(oldValue, value)) return; if (!IsValidDocument(value)) throw new ArgumentException("This type of document is not allowed for the proxy of type " + this.GetType().ToString()); #if DOCNODEPROXY_CONCURRENTDEBUG _debug.Enqueue("START SetDocNode"); #endif if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } #if DOCNODEPROXY_CONCURRENTDEBUG _debug.Enqueue("MIDDL SetDocNode EventHandlers removed"); #endif if (oldValue != null) { ClearDocNode(); } InternalDocumentPath = Main.AbsoluteDocumentPath.GetAbsolutePath(value); _docNodeRef = new WeakReference(value); #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("DocNodeProxy.SetDocNode, path is <<{0}>>", _docNodePath); #endif InternalCheckAbsolutePath(); value.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler<object, object, TunnelingEventArgs>(EhDocNode_TunneledEvent, handler => value.TunneledEvent -= handler)); value.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhDocNode_Changed, handler => value.Changed -= handler)); OnAfterSetDocNode(); EhSelfChanged(new Main.InstanceChangedEventArgs(oldValue, value)); #if DOCNODEPROXY_CONCURRENTDEBUG _debug.Enqueue("STOP SetDocNode"); #endif }
/// <summary> /// Sets the watch on a node that is not our document node, but a node lower in the hierarchy. We watch both the Changed event and the TunneledEvent of this node. /// </summary> /// <param name="node">The node to watch.</param> protected virtual void SetWatchOnNode(IDocumentLeafNode node) { if (null == node) throw new ArgumentNullException(nameof(node)); if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } node.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler<object, object, TunnelingEventArgs>(EhWatchedNode_TunneledEvent, handler => node.TunneledEvent -= handler)); node.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhWatchedNode_Changed, handler => node.Changed -= handler)); #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("Start watching node <<{0}>> of total path <<{1}>>", AbsoluteDocumentPath.GetAbsolutePath(node), _docNodePath); #endif }
/// <summary> /// Sets the document node that is held by this proxy. /// </summary> /// <param name="value">The document node. If <c>docNode</c> implements <see cref="Main.IDocumentLeafNode" />, /// the document path is stored for this object in addition to the object itself.</param> /// <param name="parentNode">The start point of the document path. Should be equal to the member _parent, but this might be not set now.</param> protected void InternalSetDocNode(Main.IDocumentLeafNode value, IDocumentLeafNode parentNode) { if (!IsValidDocument(value)) throw new ArgumentException("This type of document is not allowed for the proxy of type " + this.GetType().ToString()); if (null == parentNode) throw new InvalidOperationException("Parent of this node must be set in order to set the docnode."); var oldValue = this.InternalDocNode; if (object.ReferenceEquals(oldValue, value)) return; // Nothing to do if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } if (null != oldValue) { ClearDocNode(); } var newPath = RelativeDocumentPath.GetRelativePathFromTo(parentNode, value); if (null != newPath) InternalDocumentPath = newPath; // especially in dispose situations, the new path can be null. In this case we leave the path as it was _docNodeRef = new WeakReference(value); #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("RelDocNodeProxy.SetDocNode, path is <<{0}>>", _docNodePath); #endif value.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler<object, object, TunnelingEventArgs>(EhDocNode_TunneledEvent, handler => value.TunneledEvent -= handler)); if (null != _docNodePath && !_docNodePath.IsIdentity) // it does not make sense to watch the changed event of our target node is our parent because the parent can handle the Changed event itself { value.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhDocNode_Changed, handler => value.Changed -= handler)); } OnAfterSetDocNode(); EhSelfChanged(new Main.InstanceChangedEventArgs(oldValue, value)); }