Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / VisualProxy.cs / 1305600 / VisualProxy.cs
//------------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description:
// Mapping between a visual and its handles on different channels.
//
//-----------------------------------------------------------------------------
namespace System.Windows.Media.Composition
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
///
/// Mapping between a visual and its handles on different channels.
///
internal struct VisualProxy
{
// -------------------------------------------------------------------
//
// Private Types
//
// -------------------------------------------------------------------
#region Private Types
///
/// Tuple binding a channel to a set of flags and a resource handle.
///
///
/// Note that DUCE.Channel is a reference type.
///
private struct Proxy
{
internal DUCE.Channel Channel;
internal VisualProxyFlags Flags;
internal DUCE.ResourceHandle Handle;
}
#endregion Private Types
// --------------------------------------------------------------------
//
// Internal Properties
//
// -------------------------------------------------------------------
#region Internal Properties
///
/// Returns the number of channels this resource is marshaled to.
///
internal int Count
{
get
{
if (_tail == null)
{
return _head.Channel == null ? 0 : 1;
}
else
{
//
// The logic here is simple: we keep at most one entry
// in the tail free. Heads has to be occupied and adds one.
//
int tailLength = _tail.Length;
bool lastTailIsEmpty =
_tail[tailLength - 1].Channel == null;
return 1 + tailLength - (lastTailIsEmpty ? 1 : 0);
}
}
}
///
/// Returns true if the parent resource is marshaled to at least
/// one channel.
///
internal bool IsOnAnyChannel
{
get
{
return Count != 0;
}
}
#endregion Internal Properties
// --------------------------------------------------------------------
//
// Internal Methods
//
// --------------------------------------------------------------------
#region Internal Methods
///
/// Returns true if the visual is marshaled to the
/// specified channel.
///
internal bool IsOnChannel(DUCE.Channel channel)
{
int index = Find(channel);
if (index == PROXY_NOT_FOUND)
{
return false;
}
else if (index == PROXY_STORED_INLINE)
{
return !_head.Handle.IsNull;
}
else
{
return !_tail[index].Handle.IsNull;
}
}
///
/// If the visual is on channel, its reference count is increased.
/// Otherwise, a new resource is created on that channel.
///
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;
}
///
/// If visual is on channel, its reference count is increased.
/// Otherwise, a new resource is created on that channel.
///
internal bool ReleaseOnChannel(DUCE.Channel channel)
{
int index = Find(channel);
bool proxyRemoved = false;
int count = Count;
if (index == PROXY_STORED_INLINE)
{
if (channel.ReleaseOnChannel(_head.Handle))
{
//
// Need to move the last of the non-empty tail to head
// or clear the head. Erase the head if that was the last
// proxy.
//
if (count == 1)
{
_head = new Proxy();
}
else
{
_head = _tail[count - 2];
}
proxyRemoved = true;
}
}
else if (index >= 0)
{
if (channel.ReleaseOnChannel(_tail[index].Handle))
{
//
// Need to move the last of the non-empty tail to the
// removed index. Avoid in-place copying.
//
if (index != count - 2)
{
_tail[index] = _tail[count - 2];
}
proxyRemoved = true;
}
}
else
{
Debug.Assert(index != PROXY_NOT_FOUND);
return false;
}
if (proxyRemoved)
{
if (_tail != null)
{
//
// Keep the tail short. We allow for one extra free element
// in tail to avoid constant allocations / reallocations.
//
if (count == 2)
{
// ------------------
// Before removal: [head] [tail c-1] [empty]
// Here and now: [head] [ deleted] [empty]
// After removal: [head]
//
_tail = null;
}
else if (count == _tail.Length)
{
// ---------------------------------------------------
// Before removal: [head] [tail 0] [tail 1] ... [tail c-3] [tail c-2] [empty]
// Here and now: [head] [tail 0] [tail 1] ... [tail c-3] [ deleted] [empty]
// After removal: [head] [tail 0] [tail 1] ... [tail c-3]
//
ResizeTail(-2);
}
else
{
// ------------------------------------------------------
// Before removal: [head] [tail 0] [tail 1] ... [tail c-4] [tail c-3] [tail c-2]
// Here and now: [head] [tail 0] [tail 1] ... [tail c-4] [tail c-3] [ deleted]
// After removal: [head] [tail 0] [tail 1] ... [tail c-4] [tail c-3] [ empty]
//
_tail[count - 2] = new Proxy();
}
}
}
return proxyRemoved;
}
///
/// Returns the channel that the n-th proxy connects to.
///
internal DUCE.Channel GetChannel(int index)
{
Debug.Assert(index >= 0 && index < Count);
if (index < Count)
{
if (index == 0)
{
return _head.Channel;
}
else if (index > 0)
{
return _tail[index - 1].Channel;
}
}
return null;
}
#endregion Internal Methods
// ---------------------------------------------------------------
//
// Internal Methods: resource handle getters
//
// ---------------------------------------------------------------
#region Internal Methods: resource handle getters
///
/// Returns the handle the visual has on a specific channel.
///
internal DUCE.ResourceHandle GetHandle(DUCE.Channel channel)
{
return GetHandle(Find(channel) + 1); // Find's results are -1 based, adjust by one.
}
///
/// Returns the handle the visual has on the n-th channel.
///
internal DUCE.ResourceHandle GetHandle(int index)
{
Debug.Assert(index >= 0 && index < Count);
if (index < Count)
{
if (index == 0)
{
return _head.Handle;
}
else if (index > 0)
{
return _tail[index - 1].Handle;
}
}
return DUCE.ResourceHandle.Null;
}
#endregion Internal Methods: resource handle getters
// ---------------------------------------------------------------
//
// Internal Methods: visual proxy flags
//
// ----------------------------------------------------------------
#region Internal Methods: visual proxy flags
///
/// Returns the flags the visual has on a specific channel.
///
internal VisualProxyFlags GetFlags(DUCE.Channel channel)
{
return GetFlags(Find(channel) + 1); // Find's results are -1 based, adjust by one.
}
///
/// Returns the handle the visual has on n-th channel.
///
internal VisualProxyFlags GetFlags(int index)
{
if (index < Count)
{
if (index == 0)
{
return _head.Flags;
}
else if (index > 0)
{
return _tail[index - 1].Flags;
}
}
return VisualProxyFlags.None;
}
///
/// Sets the flags the visual has on a specific channel.
///
internal void SetFlags(
DUCE.Channel channel,
bool value,
VisualProxyFlags flags)
{
SetFlags(Find(channel) + 1, value, flags); // Find's results are -1 based, adjust by one.
}
///
/// Sets the flags the visual has on the n-th channel.
///
internal void SetFlags(
int index,
bool value,
VisualProxyFlags flags)
{
Debug.Assert(index >= 0 && index < Count);
if (index < Count)
{
if (index == 0)
{
_head.Flags =
value ? (_head.Flags | flags) : (_head.Flags & ~flags);
}
else if (index > 0)
{
_tail[index - 1].Flags =
value ? (_tail[index - 1].Flags | flags) : (_tail[index - 1].Flags & ~flags);
}
}
}
///
/// Sets the flags on all channels the visual is marshaled to.
///
internal void SetFlagsOnAllChannels(
bool value,
VisualProxyFlags flags)
{
if (_head.Channel != null)
{
_head.Flags =
value ? (_head.Flags | flags) : (_head.Flags & ~flags);
for (int i = 0, limit = Count - 1; i < limit; i++)
{
_tail[i].Flags =
value ? (_tail[i].Flags | flags) : (_tail[i].Flags & ~flags);
}
}
}
///
/// Returns true if the given flags are set for every proxy or if
/// the visual is not being marshaled.
///
internal bool CheckFlagsOnAllChannels(
VisualProxyFlags conjunctionFlags)
{
if (_head.Channel != null)
{
if ((_head.Flags & conjunctionFlags) != conjunctionFlags)
return false;
for (int i = 0, limit = Count - 1; i < limit; i++)
{
if ((_tail[i].Flags & conjunctionFlags) != conjunctionFlags)
return false;
}
}
return true;
}
#endregion Internal Methods: visual proxy flags
// -------------------------------------------------------------------
//
// Private Methods
//
// --------------------------------------------------------------------
#region Private Methods
///
/// Looks for the given channel in the proxies list.
///
private int Find(DUCE.Channel channel)
{
if (_head.Channel == channel)
{
return PROXY_STORED_INLINE;
}
else if (_tail != null)
{
for (int i = 0, limit = Count - 1; i < limit; i++)
{
if (_tail[i].Channel == channel)
{
return i;
}
}
}
return PROXY_NOT_FOUND;
}
///
/// Grows or shrinks the tail by a given size.
///
private void ResizeTail(int delta)
{
int newLength = _tail.Length + delta;
Debug.Assert(delta % 2 == 0 && newLength >= 2);
Proxy[] reallocatedTail = new Proxy[newLength];
Array.Copy(_tail, reallocatedTail, Math.Min(_tail.Length, newLength));
_tail = reallocatedTail;
}
#endregion Private Methods
// --------------------------------------------------------------------
//
// Private Fields
//
// -------------------------------------------------------------------
#region Private Fields
///
/// Returned by the Find method to denote that a proxy for the given
/// channel has not been found.
///
private const int PROXY_NOT_FOUND = -2;
///
/// Returned by the Find method to denote that a proxy for the given
/// channel has been found in the inline storage.
///
private const int PROXY_STORED_INLINE = -1;
///
/// This data structure is optimized for single entry. _head is
/// the one entry that we inline into the struct for that purpose.
///
private Proxy _head;
///
/// All the other entries end up in this array.
///
private Proxy[] _tail;
#endregion Private Fields
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FtpRequestCacheValidator.cs
- SerializationSectionGroup.cs
- FileIOPermission.cs
- ProcessHostMapPath.cs
- Substitution.cs
- ColorAnimationBase.cs
- EntitySqlQueryCacheKey.cs
- HtmlInputHidden.cs
- XamlToRtfWriter.cs
- PerfCounterSection.cs
- DataSourceExpression.cs
- CodeCommentStatementCollection.cs
- RuntimeHandles.cs
- NamedElement.cs
- QilValidationVisitor.cs
- IntMinMaxAggregationOperator.cs
- IntSecurity.cs
- Clock.cs
- URIFormatException.cs
- TableItemPattern.cs
- PropertyGeneratedEventArgs.cs
- AssemblyFilter.cs
- CollectionBuilder.cs
- FastEncoder.cs
- ResourceContainer.cs
- TypedElement.cs
- VersionedStream.cs
- TaskFormBase.cs
- IgnoreFileBuildProvider.cs
- securitymgrsite.cs
- DbConnectionPoolGroupProviderInfo.cs
- PreviewPageInfo.cs
- SingleStorage.cs
- TextEndOfSegment.cs
- StorageTypeMapping.cs
- BitmapEffectInputConnector.cs
- EncryptedData.cs
- TranslateTransform.cs
- MetadataPropertyCollection.cs
- MobileControlsSection.cs
- OdbcConnection.cs
- VectorAnimation.cs
- Queue.cs
- Effect.cs
- ProviderIncompatibleException.cs
- XmlBinaryReader.cs
- SymbolType.cs
- EncryptedPackage.cs
- ReferenceConverter.cs
- XmlWellformedWriter.cs
- ExpressionTextBoxAutomationPeer.cs
- EncoderParameter.cs
- Delegate.cs
- PreloadedPackages.cs
- IResourceProvider.cs
- Hex.cs
- TimeSpanMinutesOrInfiniteConverter.cs
- TabRenderer.cs
- Rotation3DAnimationBase.cs
- RTLAwareMessageBox.cs
- ProtocolsConfigurationHandler.cs
- PropertyNames.cs
- FragmentQueryProcessor.cs
- DataGridSortingEventArgs.cs
- HtmlInputButton.cs
- ComponentSerializationService.cs
- MessageFormatterConverter.cs
- ConfigXmlReader.cs
- SectionVisual.cs
- DateTimeFormatInfo.cs
- Baml2006SchemaContext.cs
- configsystem.cs
- CompilerLocalReference.cs
- DataRowIndexBuffer.cs
- URI.cs
- EventPropertyMap.cs
- RegexRunnerFactory.cs
- InstanceDataCollectionCollection.cs
- XpsFixedDocumentSequenceReaderWriter.cs
- HierarchicalDataBoundControl.cs
- AssociativeAggregationOperator.cs
- ProjectionCamera.cs
- ControlPropertyNameConverter.cs
- IgnoreDataMemberAttribute.cs
- ClientRuntimeConfig.cs
- FieldTemplateFactory.cs
- ReplyChannel.cs
- COM2EnumConverter.cs
- Lease.cs
- ToolTip.cs
- AttachmentService.cs
- ExtentCqlBlock.cs
- GroupDescription.cs
- FormViewCommandEventArgs.cs
- PartManifestEntry.cs
- DispatcherOperation.cs
- SharedUtils.cs
- AppDomainManager.cs
- CapabilitiesSection.cs
- XPathLexer.cs