/// <summary> /// Calling this will make sure that the render request /// is registered with the MediaContext. /// </summary> private void RegisterForAsyncRenderForCyclicBrush() { DUCE.IResource resource = this as DUCE.IResource; if (resource != null) { if ((Dispatcher != null) && !_isAsyncRenderRegistered) { MediaContext mediaContext = MediaContext.From(Dispatcher); // // Only register for a deferred render if this visual brush // is actually on the channel. // if (!resource.GetHandle(mediaContext.Channel).IsNull) { // Add this handler to this event means that the handler will be // called on the next UIThread render for this Dispatcher. ICyclicBrush cyclicBrush = this as ICyclicBrush; mediaContext.ResourcesUpdated += new MediaContext.ResourcesUpdatedHandler(cyclicBrush.RenderForCyclicBrush); _isAsyncRenderRegistered = true; } } } }
public bool EnterTreeWalk(ICyclicBrush brush) { if (this._cyclicBrushes.ContainsKey(brush)) { return(false); } this._cyclicBrushes.Add(brush, EmptyStruct.Default); return(true); }
/// <summary> /// Override this function in derived classes to release unmanaged resources /// during Dispose and during removal of a subtree. /// </summary> internal virtual void ReleaseOnChannelForCyclicBrush( ICyclicBrush cyclicBrush, DUCE.Channel channel) { // Update the number of times this visual brush uses this visual across all channels. Dictionary<ICyclicBrush, int> cyclicBrushToChannelsMap = CyclicBrushToChannelsMapField.GetValue(this); Debug.Assert(cyclicBrushToChannelsMap != null); Debug.Assert(cyclicBrushToChannelsMap.ContainsKey(cyclicBrush)); Debug.Assert(cyclicBrushToChannelsMap[cyclicBrush] > 0); if (cyclicBrushToChannelsMap[cyclicBrush] == 1) { // // If the ICyclicBrush no longer uses this Visual across all channels, then // we can remove it from the map. // cyclicBrushToChannelsMap.Remove(cyclicBrush); } else { // Decrease the number os times this ICyclicBrush uses this Visual across all channels cyclicBrushToChannelsMap[cyclicBrush] = cyclicBrushToChannelsMap[cyclicBrush] - 1; } // Decrease the number of ICyclicBrush using the visual as root on this channel Dictionary<DUCE.Channel, int> channelsToCyclicBrushMap = ChannelsToCyclicBrushMapField.GetValue(this); Debug.Assert(channelsToCyclicBrushMap != null); Debug.Assert(channelsToCyclicBrushMap.ContainsKey(channel)); Debug.Assert(channelsToCyclicBrushMap[channel] > 0); channelsToCyclicBrushMap[channel] = channelsToCyclicBrushMap[channel] - 1; // // If on this channel, there are no more ICyclicBrushes using this visual as // a root then we need to remove the flag saying that the visual is a visual // brush root and make sure that the dependant resources are released in // case we are no longer connected to the visual tree. // if (channelsToCyclicBrushMap[channel] == 0) { channelsToCyclicBrushMap.Remove(channel); SetFlags(false, VisualFlags.NodeIsCyclicBrushRoot); PropagateFlags( this, VisualFlags.None, VisualProxyFlags.IsSubtreeDirtyForRender); // // If we do not have a parent or we have already disconnected from // the parent and we are also not the root then we need to clear out // the tree. // if ( (_parent == null || !CheckFlagsAnd(channel, VisualProxyFlags.IsConnectedToParent)) && !IsRootElement) { ((DUCE.IResource)this).ReleaseOnChannel(channel); } } }
internal virtual void AddRefOnChannelForCyclicBrush( ICyclicBrush cyclicBrush, DUCE.Channel channel) { // // Since the ICyclicBrush to visual relationship is being created on this channel, // we need to update the number of cyclic brushes using this visual on this channel. // Dictionary<DUCE.Channel, int> channelsToCyclicBrushMap = ChannelsToCyclicBrushMapField.GetValue(this); if (channelsToCyclicBrushMap == null) { channelsToCyclicBrushMap = new Dictionary<DUCE.Channel, int>(); ChannelsToCyclicBrushMapField.SetValue(this, channelsToCyclicBrushMap); } if (!channelsToCyclicBrushMap.ContainsKey(channel)) { // If on this channel we were not previously using this Visual as the root // node of a VisualBrush, set the flag indicating that it is the root now. // Also set the number of uses on this channel to 1. SetFlags(true, VisualFlags.NodeIsCyclicBrushRoot); channelsToCyclicBrushMap[channel] = 1; } else { Debug.Assert(channelsToCyclicBrushMap[channel] > 0); channelsToCyclicBrushMap[channel] += 1; } // // Since the ICyclicBrush to visual relationship is being created on this channel, // we need to update the number of times this cyclic brush is used across all // channels. // Dictionary<ICyclicBrush, int> cyclicBrushToChannelsMap = CyclicBrushToChannelsMapField.GetValue(this); if (cyclicBrushToChannelsMap == null) { cyclicBrushToChannelsMap = new Dictionary<ICyclicBrush, int>(); CyclicBrushToChannelsMapField.SetValue(this, cyclicBrushToChannelsMap); } if (!cyclicBrushToChannelsMap.ContainsKey(cyclicBrush)) { cyclicBrushToChannelsMap[cyclicBrush] = 1; } else { Debug.Assert(cyclicBrushToChannelsMap[cyclicBrush] > 0); cyclicBrushToChannelsMap[cyclicBrush] += 1; } // // Render the brush's visual. // cyclicBrush.RenderForCyclicBrush(channel, false); }
public bool IsTreeWalkInProgress(ICyclicBrush brush) { return(this._cyclicBrushes.ContainsKey(brush)); }
public void ExitTreeWalk(ICyclicBrush brush) { this._cyclicBrushes.Remove(brush); }