ClassHandlersStore.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / ClassHandlersStore.cs / 1305600 / ClassHandlersStore.cs

                            using System; 
using System.Diagnostics;
using MS.Utility;

 
namespace System.Windows
{ 
    // Container for the class event handlers 
    // ClassHandlersStore constitues lists of
    // RoutedEventHandlerInfo keyed on the 
    // RoutedEvent
    internal class ClassHandlersStore
    {
        #region Construction 

        // Constructor for ClassHandlersStore 
        internal ClassHandlersStore(int size) 
        {
            _eventHandlersList = new ItemStructList(size); 
        }

        #endregion Construction
 
        #region Operations
 
        // Adds a routed event handler at the given index of the store 
        // Returns updated set of handlers
        // NOTE: index must be valid, i.e. not -1 
        internal RoutedEventHandlerInfoList AddToExistingHandlers(
            int index,
            Delegate handler,
            bool handledEventsToo) 
        {
            Debug.Assert(index != -1, "There should exist a set of handlers for the given routedEvent"); 
 
            // Create a new RoutedEventHandler
            RoutedEventHandlerInfo routedEventHandlerInfo = 
                new RoutedEventHandlerInfo(handler, handledEventsToo);

            // Check if we need to create a new node in the linked list
            RoutedEventHandlerInfoList handlers =  _eventHandlersList.List[index].Handlers; 
            if (handlers == null || _eventHandlersList.List[index].HasSelfHandlers == false)
            { 
                // Create a new node in the linked list of class 
                // handlers for this type and routed event.
                handlers = new RoutedEventHandlerInfoList(); 
                handlers.Handlers = new RoutedEventHandlerInfo[1];
                handlers.Handlers[0] = routedEventHandlerInfo;
                handlers.Next = _eventHandlersList.List[index].Handlers;
                _eventHandlersList.List[index].Handlers = handlers; 
                _eventHandlersList.List[index].HasSelfHandlers = true;
            } 
            else 
            {
                // Add this handler to the existing node in the linked list 
                // of class handlers for this type and routed event.
                int length = handlers.Handlers.Length;
                RoutedEventHandlerInfo[] mergedHandlers = new RoutedEventHandlerInfo[length + 1];
                Array.Copy(handlers.Handlers, 0, mergedHandlers,  0, length); 
                mergedHandlers[length] = routedEventHandlerInfo;
                handlers.Handlers = mergedHandlers; 
            } 

            return handlers; 
         }

        // Returns EventHandlers stored at the given index in the datastructure
        // NOTE: index must be valid, i.e. not -1 
        internal RoutedEventHandlerInfoList GetExistingHandlers(int index)
        { 
            Debug.Assert(index != -1, "There should exist a set of handlers for the given index"); 

            return _eventHandlersList.List[index].Handlers; 
        }

        // Creates reference to given handlers and RoutedEvent
        // Returns the index at which the new reference was added 
        // NOTE: There should not exist a set of handlers for the
        // given routedEvent 
        internal int CreateHandlersLink(RoutedEvent routedEvent, RoutedEventHandlerInfoList handlers) 
        {
            Debug.Assert(GetHandlersIndex(routedEvent) == -1, "There should not exist a set of handlers for the given routedEvent"); 

            ClassHandlers classHandlers = new ClassHandlers();
            classHandlers.RoutedEvent = routedEvent;
            classHandlers.Handlers = handlers; 
            classHandlers.HasSelfHandlers = false;
            _eventHandlersList.Add(classHandlers); 
 
            return _eventHandlersList.Count - 1;
        } 

        // Update Sub Class Handlers with the given base class listeners
        // NOTE : Do not wastefully try to update subclass listeners when
        // base class listeners are null 
        internal void UpdateSubClassHandlers(
            RoutedEvent routedEvent, 
            RoutedEventHandlerInfoList baseClassListeners) 
        {
            Debug.Assert(baseClassListeners != null, "Update only when there are base class listeners to be updated"); 

            // Get the handlers index corresponding to the given RoutedEvent
            int index = GetHandlersIndex(routedEvent);
            if (index != -1) 
            {
                bool hasSelfHandlers = _eventHandlersList.List[index].HasSelfHandlers; 
 
                // Fetch the handlers for your baseType that the current node knows of
 
                RoutedEventHandlerInfoList handlers = hasSelfHandlers ?
                    _eventHandlersList.List[index].Handlers.Next :
                    _eventHandlersList.List[index].Handlers;
 
                bool needToChange = false;
 
                // If the current node has baseType handlers check if the baseClassListeners 
                // provided is for a super type of that baseType. If it is then you will
                // replace the baseType handlers for the current node with the provided 
                // baseClassListeners. If the given baseClassListeners is for a sub type
                // of the current nodes's baseType then we do not need to update the current node.
                //
                // Example: Consider the following class hierarchy A -> B -> C. 
                //
                // Now imagine that we register class handlers in the following order. 
                // 1. Register class handler for A. 
                // - A's linked list will be A -> NULL.
                // - B's linked list will be NULL. 
                // - C's linked list will be NULL.
                // 2. Register class handler for C.
                // - A's linked list will be A -> NULL.
                // - B's linkedList will be NULL. 
                // - C's linked list will be C -> A -> NULL.
                // 3. Register class handler for B. 
                // - A's linked list will be A -> NULL. 
                // - B's linkedList will be B -> A -> NULL.
                // - While updating C's linked list we are given B's linked list for the baseClassListers. 
                //   Now we want to check if B is a super type of A which is the current baseType that C
                //   knows of. The contains check below determines this. Since it is we now replace C.Next
                //   to be B. Thus we get C -> B -> A -> NULL.
                // 
                // Now imagine that we register class handlers in the following order.
                // 1. Register class handler for C. 
                // - A's linked list will be NULL. 
                // - B's linked list will be NULL.
                // - C's linked list will be C -> NULL. 
                // 2. Register class handler for B.
                // - A's linked list will be NULL.
                // - B's linkedList will be B -> NULL.
                // - While updating C's linked list we are given B's linked list for the baseClassListeners. 
                //   Since C does not know of any baseType listeners already it takes the given
                //   baseClassListeners as is. Thus it has C -> B -> NULL 
                // 3. Register class handler for A. 
                // - A's linked list will be A -> NULL.
                // - B's linkedList will be B -> A -> NULL. 
                // - While updating C's linked list we are given A's linked list for the baseClassListers.
                //   Now we want to check if A is a super type of B which is the current baseType that C
                //   knows of. The contains check below determines this. Since it isn't we do not need to
                //   change the linked list for C. Since B's linked list has already been updated we get 
                //   C -> B - > A -> NULL.
 
                if (handlers != null) 
                {
                    if (baseClassListeners.Next != null && baseClassListeners.Next.Contains(handlers)) 
                    {
                        needToChange = true;
                    }
                } 

                // If the current node does not have any baseType handlers then if will 
                // simply use the given baseClassListeners. 

                else 
                {
                    needToChange = true;
                }
 
                if (needToChange)
                { 
                    // If current node has self handlers then its next pointer 
                    // needs update if not the current node needs update.
 
                    if (hasSelfHandlers)
                    {
                        _eventHandlersList.List[index].Handlers.Next = baseClassListeners;
                    } 
                    else
                    { 
                        _eventHandlersList.List[index].Handlers = baseClassListeners; 
                    }
                } 
            }
        }

        // Returns EventHandlers Index for the given RoutedEvent 
        internal int GetHandlersIndex(RoutedEvent routedEvent)
        { 
            // Linear Search 
            for (int i=0; i<_eventHandlersList.Count; i++)
            { 
                if (_eventHandlersList.List[i].RoutedEvent == routedEvent)
                {
                    return i;
                } 
            }
 
            return -1; 
        }
 
        #endregion Operations

        #region Data
 
        // Stores list of ClassHandlers keyed on RoutedEvent
        private ItemStructList _eventHandlersList; 
 
        #endregion Data
    } 

    // Stores ClassHandlers for the given RoutedEvent
    internal struct ClassHandlers
    { 
        #region Operations
 
        ///  
        ///     Is the given object equals the current
        ///  
        public override bool Equals(object o)
        {
            return Equals((ClassHandlers)o);
        } 

        ///  
        ///     Is the given ClassHandlers struct equals the current 
        /// 
        public bool Equals(ClassHandlers classHandlers) 
        {
            return (
                classHandlers.RoutedEvent == this.RoutedEvent &&
                classHandlers.Handlers == this.Handlers); 
        }
 
        ///  
        ///     Serves as a hash function for a particular type, suitable for use in
        ///     hashing algorithms and data structures like a hash table 
        /// 
        public override int GetHashCode()
        {
            return base.GetHashCode(); 
        }
 
        ///  
        ///     Equals operator overload
        ///  
        public static bool operator== (ClassHandlers classHandlers1, ClassHandlers classHandlers2)
        {
            return classHandlers1.Equals(classHandlers2);
        } 

        ///  
        ///     NotEquals operator overload 
        /// 
        public static bool operator!= (ClassHandlers classHandlers1, ClassHandlers classHandlers2) 
        {
            return !classHandlers1.Equals(classHandlers2);
        }
 
        #endregion Operations
 
        #region Data 

        internal RoutedEvent RoutedEvent; 
        internal RoutedEventHandlerInfoList Handlers;
        internal bool HasSelfHandlers;

        #endregion Data 
    }
 
    ///  
    ///     This data-structure represents a linked list of all
    ///     the Class Handlers for a type and its base types. 
    /// 
    internal class RoutedEventHandlerInfoList
    {
        internal RoutedEventHandlerInfo[] Handlers; 
        internal RoutedEventHandlerInfoList Next;
 
        internal bool Contains(RoutedEventHandlerInfoList handlers) 
        {
            RoutedEventHandlerInfoList tempHandlers = this; 
            while (tempHandlers != null)
            {
                if (tempHandlers == handlers)
                { 
                    return true;
                } 
 
                tempHandlers = tempHandlers.Next;
            } 

            return false;
        }
    } 
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK