|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// Description:
// AnnotationMap contains the implementation of the map
// map between annotation id and attached annotations used by the service
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Annotations;
namespace MS.Internal.Annotations
{
/// <summary>
/// The AnnotationMap holds a map between the Id's of annotations and IAttachedAnnotations
/// </summary>
internal class AnnotationMap
{
/// <summary>
/// Add an IAttachedAnnotation to the annotation map.
/// </summary>
/// <param name="attachedAnnotation">the IAttachedAnnotation to be added to the map</param>
internal void AddAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
{
List<IAttachedAnnotation> list = null;
if (!_annotationIdToAttachedAnnotations.TryGetValue(attachedAnnotation.Annotation.Id, out list))
{
list = new List<IAttachedAnnotation>(1);
_annotationIdToAttachedAnnotations.Add(attachedAnnotation.Annotation.Id, list);
}
list.Add(attachedAnnotation);
}
/// <summary>
/// Remove an IAttachedAnnotation from the annotation map.
/// </summary>
/// <param name="attachedAnnotation"></param>
internal void RemoveAttachedAnnotation(IAttachedAnnotation attachedAnnotation)
{
List<IAttachedAnnotation> list = null;
if (_annotationIdToAttachedAnnotations.TryGetValue(attachedAnnotation.Annotation.Id, out list))
{
list.Remove(attachedAnnotation);
if (list.Count == 0)
{
_annotationIdToAttachedAnnotations.Remove(attachedAnnotation.Annotation.Id);
}
}
}
/// <summary>
/// Returns whether or not there are any annotations currently loaded. This can be
/// used to avoid costly walks of the tree.
/// </summary>
internal bool IsEmpty
{
get
{
return _annotationIdToAttachedAnnotations.Count == 0;
}
}
/// <summary>
/// Return a list of IAttachedAnnotations for a given annotation id
/// </summary>
/// <param name="annotationId"></param>
/// <returns>list of IAttachedAnnotations</returns>
internal List<IAttachedAnnotation> GetAttachedAnnotations(Guid annotationId)
{
List<IAttachedAnnotation> list = null;
if (!_annotationIdToAttachedAnnotations.TryGetValue(annotationId, out list))
{
// return empty list if annotation id not found
return _emptyList;
}
Debug.Assert(list != null, $"there should be an attached annotation list for the annotationId: {annotationId}");
return list;
}
/// <summary>
/// Return a list of all IAttachedAnnotations in the map
/// </summary>
/// <returns>list of IAttachedAnnotations</returns>
internal List<IAttachedAnnotation> GetAllAttachedAnnotations()
{
List<IAttachedAnnotation> result = new List<IAttachedAnnotation>(_annotationIdToAttachedAnnotations.Keys.Count);
foreach (Guid annId in _annotationIdToAttachedAnnotations.Keys)
{
List<IAttachedAnnotation> list = _annotationIdToAttachedAnnotations[annId];
result.AddRange(list);
}
if (result.Count == 0)
{
return _emptyList;
}
return result;
}
// hash table to hold annotation id to AttachedAnnotations list
private Dictionary<Guid, List<IAttachedAnnotation>> _annotationIdToAttachedAnnotations = new Dictionary<Guid, List<IAttachedAnnotation>>();
// a readonly empty list - cached for performance reasons
private static readonly List<IAttachedAnnotation> _emptyList = new List<IAttachedAnnotation>(0);
}
}
|