/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation.
*
* This source code is subject to terms and conditions of the Apache License, Version 2.0. A
* copy of the license can be found in the License.html file at the root of this distribution. If
* you cannot locate the Apache License, Version 2.0, please send an email to
* vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
* by the terms of the Apache License, Version 2.0.
*
* You must not remove this notice, or any other, from this software.
*
* ***************************************************************************/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.OLE.Interop;
namespace Microsoft.VisualStudio.Project
{
///
/// Class used to identify a source of events of type SinkType.
///
[ComVisible(false)]
public interface IEventSource
where SinkType : class
{
void OnSinkAdded(SinkType sink);
void OnSinkRemoved(SinkType sink);
}
[ComVisible(true)]
public class ConnectionPointContainer : IConnectionPointContainer
{
private Dictionary connectionPoints;
public ConnectionPointContainer()
{
connectionPoints = new Dictionary();
}
public void AddEventSource(IEventSource source)
where SinkType : class
{
if (null == source)
{
throw new ArgumentNullException("source");
}
if (connectionPoints.ContainsKey(typeof(SinkType).GUID))
{
throw new ArgumentException("EventSource guid already added to the list of connection points", "source");
}
connectionPoints.Add(typeof(SinkType).GUID, new ConnectionPoint(this, source));
}
#region IConnectionPointContainer Members
void IConnectionPointContainer.EnumConnectionPoints(out IEnumConnectionPoints ppEnum)
{
throw new NotImplementedException(); ;
}
void IConnectionPointContainer.FindConnectionPoint(ref Guid riid, out IConnectionPoint ppCP)
{
ppCP = connectionPoints[riid];
}
#endregion
}
public class ConnectionPoint : IConnectionPoint
where SinkType : class
{
Dictionary sinks;
private uint nextCookie;
private ConnectionPointContainer container;
private IEventSource source;
public ConnectionPoint(ConnectionPointContainer container, IEventSource source)
{
if (null == container)
{
throw new ArgumentNullException("container");
}
if (null == source)
{
throw new ArgumentNullException("source");
}
this.container = container;
this.source = source;
sinks = new Dictionary();
nextCookie = 1;
}
#region IConnectionPoint Members
public void Advise(object pUnkSink, out uint pdwCookie)
{
SinkType sink = pUnkSink as SinkType;
if (null == sink)
{
Marshal.ThrowExceptionForHR(VSConstants.E_NOINTERFACE);
}
sinks.Add(nextCookie, sink);
pdwCookie = nextCookie;
source.OnSinkAdded(sink);
nextCookie += 1;
}
public void EnumConnections(out IEnumConnections ppEnum)
{
throw new NotImplementedException(); ;
}
public void GetConnectionInterface(out Guid pIID)
{
pIID = typeof(SinkType).GUID;
}
public void GetConnectionPointContainer(out IConnectionPointContainer ppCPC)
{
ppCPC = this.container;
}
public void Unadvise(uint dwCookie)
{
// This will throw if the cookie is not in the list.
SinkType sink = sinks[dwCookie];
sinks.Remove(dwCookie);
source.OnSinkRemoved(sink);
}
#endregion
}
}