Beispiel #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);
        }