예제 #1
0
        /// <summary> 
        /// If the visual is on channel, its reference count is increased.
        /// Otherwise, a new resource is created on that channel. 
        /// </summary>
        internal bool CreateOrAddRefOnChannel(
            object instance,
            DUCE.Channel channel, 
            DUCE.ResourceType resourceType)
        { 
            int index = Find(channel); 
            int count = Count;
 
            if (index == PROXY_NOT_FOUND)
            {
                //
                // This is the case where we have to create a new resource. 
                //
 
                if (_head.Channel == null) 
                {
                    // 
                    // We're adding the first proxy.
                    //
                    // Before:        [empty]
                    // After insert:  [ head] 
                    //
 
                    Debug.Assert(count == 0); 

                    _head.Channel = channel; 
                    _head.Flags = VisualProxyFlags.None;

                    channel.CreateOrAddRefOnChannel(
                        instance, 
                        ref _head.Handle,
                        resourceType); 
                } 
                else
                { 
                    if (_tail == null)
                    {
                        //
                        // We're adding the second proxy. 
                        //
                        // Before:        [head] 
                        // After resize:  [head] [ empty] [empty] 
                        // After insert:  [head] [tail 0] [empty]
                        //                       ---------------- 

                        Debug.Assert(count == 1);

                        _tail = new Proxy[2]; 
                    }
                    else if (count > _tail.Length) 
                    { 
                        //
                        // Increase the tail size by 2. 
                        //
                        // Before:        [head] [tail 0] ... [tail c-2]
                        // After resize:  [head] [tail 0] ... [tail c-2] [   empty] [empty]
                        // After insert:  [head] [tail 0] ... [tail c-3] [tail c-2] [empty] 
                        //                       ------------------------------------------
                        // 
 
                        ResizeTail(2);
                    } 

                    //
                    // Now that we have a tail, fill in the first free element.
                    // 

                    Proxy proxy; 
 
                    proxy.Channel = channel;
                    proxy.Flags = VisualProxyFlags.None; 
                    proxy.Handle = DUCE.ResourceHandle.Null;

                    channel.CreateOrAddRefOnChannel(
                        instance, 
                        ref proxy.Handle,
                        resourceType); 
 
                    _tail[count - 1] = proxy;
                } 

                return /* created */ true;
            }
            else if (index == PROXY_STORED_INLINE) 
            {
                // 
                // We simply need to increase the reference count on head... 
                //
 
                channel.CreateOrAddRefOnChannel(
                    instance,
                    ref _head.Handle,
                    resourceType); 
            }
            else 
            { 
                //
                // Increase the reference count on one of the tail proxies... 
                //

                channel.CreateOrAddRefOnChannel(
                    instance, 
                    ref _tail[index].Handle,
                    resourceType); 
            } 

            return /* not created */ false; 
        }