462 lines
9.3 KiB
C++
462 lines
9.3 KiB
C++
#ifndef __NmChannel_h__
|
|
#define __NmChannel_h__
|
|
|
|
#include "imsconf3.h"
|
|
|
|
class CNmConferenceObj;
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
class ATL_NO_VTABLE CNmChannel : public T
|
|
{
|
|
friend class CNmChannelDataObj;
|
|
friend class CNmChannelAudioObj;
|
|
friend class CNmChannelVideoObj;
|
|
friend class CNmChannelFtObj;
|
|
friend class CNmChannelAppShareObj;
|
|
|
|
public:
|
|
|
|
CNmChannel() : m_bActive(false), m_pConfObj(NULL) { ; }
|
|
|
|
~CNmChannel()
|
|
{
|
|
DBGENTRY(CNmChannel::~CNmChannel);
|
|
|
|
RemoveMembers();
|
|
|
|
DBGEXIT(CNmChannel::~CNmChannel);
|
|
}
|
|
|
|
|
|
// INmChannel methods
|
|
STDMETHOD(IsSameAs)(INmChannel *pChannel);
|
|
STDMETHOD(IsActive)(void);
|
|
STDMETHOD(SetActive)(BOOL fActive);
|
|
STDMETHOD(GetConference)(INmConference **ppConference);
|
|
STDMETHOD(GetInterface)(IID *_piid);
|
|
STDMETHOD(GetNmch)(ULONG *puCh);
|
|
STDMETHOD(EnumMember)(IEnumNmMember **ppEnum);
|
|
STDMETHOD(GetMemberCount)(ULONG * puCount);
|
|
|
|
// INmChannelNotify
|
|
STDMETHOD(NmUI)(CONFN uNotify);
|
|
STDMETHOD(MemberChanged)(NM_MEMBER_NOTIFY uNotify, INmMember *pInternalMember);
|
|
STDMETHOD(NotifySinksOfAllMembers)()
|
|
{
|
|
for(int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
|
|
{
|
|
Fire_MemberChanged(NM_MEMBER_ADDED, m_SDKMemberObjs[i]);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHOD(NotifySinksOfLocalMember)()
|
|
{
|
|
Fire_MemberChanged(NM_MEMBER_ADDED, GetConfObj()->GetLocalSDKMember());
|
|
return S_OK;
|
|
}
|
|
|
|
virtual bool IsChannelValid()
|
|
{
|
|
if(m_pConfObj)
|
|
{
|
|
NM_CONFERENCE_STATE state;
|
|
if(SUCCEEDED(m_pConfObj->GetState(&state)) && (NM_CONFERENCE_IDLE != state))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
virtual CNmConferenceObj* GetConfObj() { return m_pConfObj; }
|
|
virtual BOOL GetbActive() { return m_bActive; }
|
|
|
|
virtual void RemoveMembers()
|
|
{
|
|
|
|
// Free our conferencing objects
|
|
while(m_SDKMemberObjs.GetSize())
|
|
{
|
|
Fire_MemberChanged(NM_MEMBER_REMOVED, m_SDKMemberObjs[0]);
|
|
CComPtr<INmMember> sp = m_SDKMemberObjs[0];
|
|
m_SDKMemberObjs.RemoveAt(0);
|
|
sp.p->Release();
|
|
}
|
|
}
|
|
|
|
STDMETHOD(Activate)(BOOL bActive)
|
|
{
|
|
if(m_bActive != ((bActive) ? TRUE : FALSE))
|
|
{
|
|
m_bActive = ((bActive) ? TRUE : FALSE);
|
|
_OnActivate(bActive ? true : false);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHOD(SDKMemberAdded)(INmMember* pSDKMember)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
|
|
if(!_MemberInChannel(pSDKMember))
|
|
{
|
|
// Add the member
|
|
pSDKMember->AddRef();
|
|
m_SDKMemberObjs.Add(pSDKMember);
|
|
|
|
// Notify the sinks
|
|
Fire_MemberChanged(NM_MEMBER_ADDED, pSDKMember);
|
|
hr = S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHOD(SDKMemberRemoved)(INmMember* pSDKMember)
|
|
{
|
|
HRESULT hr = S_FALSE;
|
|
|
|
for(int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
|
|
{
|
|
CComPtr<INmMember> spMember = m_SDKMemberObjs[i];
|
|
|
|
if(spMember.IsEqualObject(pSDKMember))
|
|
{
|
|
m_SDKMemberObjs.RemoveAt(i);
|
|
|
|
Fire_MemberChanged(NM_MEMBER_REMOVED, spMember);
|
|
|
|
spMember.p->Release();
|
|
|
|
hr = S_OK;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
STDMETHOD(SDKMemberChanged)(INmMember* pSDKMember)
|
|
{
|
|
return Fire_MemberChanged(NM_MEMBER_UPDATED, pSDKMember);
|
|
}
|
|
|
|
void NotifySinkOfMembers(INmChannelNotify* pNotify)
|
|
{
|
|
for(int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
|
|
{
|
|
pNotify->MemberChanged(NM_MEMBER_ADDED, m_SDKMemberObjs[i]);
|
|
}
|
|
}
|
|
|
|
STDMETHOD(FireNotificationsToSyncState)()
|
|
{
|
|
for(int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
|
|
{
|
|
Fire_MemberChanged(NM_MEMBER_ADDED, m_SDKMemberObjs[i]);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
protected: // Helper Fns
|
|
INmMember* _GetSDKMemberFromInternalMember(INmMember* pInternalMember);
|
|
HRESULT _RemoveMember(INmMember* pInternalMember);
|
|
virtual bool _MemberInChannel(INmMember* pSDKMember);
|
|
|
|
private:
|
|
CSimpleArray<INmMember*> m_SDKMemberObjs;
|
|
CNmConferenceObj* m_pConfObj;
|
|
BOOL m_bActive;
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// INmChannel
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
STDMETHODIMP CNmChannel<T, piid, dwCh>::IsSameAs(INmChannel *pChannel)
|
|
{
|
|
DBGENTRY(CNmChannel::IsSameAs);
|
|
HRESULT hr = E_NOTIMPL;
|
|
CComPtr<IUnknown> pUnk(GetUnknown());
|
|
|
|
hr = pUnk.IsEqualObject(pChannel) ? S_OK : S_FALSE;
|
|
|
|
DBGEXIT_HR(CNmChannel::IsSameAs,hr);
|
|
return hr;
|
|
}
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
STDMETHODIMP CNmChannel<T, piid, dwCh>::IsActive(void)
|
|
{
|
|
DBGENTRY(CNmChannel::IsActive);
|
|
|
|
HRESULT hr = _IsActive();
|
|
|
|
DBGEXIT_HR(CNmChannel::IsActive,hr);
|
|
return hr;
|
|
}
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
STDMETHODIMP CNmChannel<T, piid, dwCh>::SetActive(BOOL fActive)
|
|
{
|
|
DBGENTRY(CNmChannel::SetActive);
|
|
|
|
HRESULT hr = _SetActive(fActive);
|
|
|
|
DBGEXIT_HR(CNmChannel::SetActive,hr);
|
|
return hr;
|
|
}
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
STDMETHODIMP CNmChannel<T, piid, dwCh>::GetConference(INmConference **ppConference)
|
|
{
|
|
DBGENTRY(CNmChannel::GetConference);
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_pConfObj)
|
|
{
|
|
IUnknown* pUnk = m_pConfObj->GetUnknown();
|
|
if(pUnk)
|
|
{
|
|
hr = pUnk->QueryInterface(IID_INmConference,reinterpret_cast<void**>(ppConference));
|
|
}
|
|
else
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
}
|
|
|
|
DBGEXIT_HR(CNmChannel::GetConference,hr);
|
|
return hr;
|
|
}
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
STDMETHODIMP CNmChannel<T, piid, dwCh>::GetInterface(IID *_piid)
|
|
{
|
|
DBGENTRY(CNmChannel::GetInterface);
|
|
HRESULT hr = S_OK;
|
|
|
|
if(piid)
|
|
{
|
|
*_piid = *piid;
|
|
}
|
|
else
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
|
|
DBGEXIT_HR(CNmChannel::GetInterface,hr);
|
|
return hr;
|
|
}
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
STDMETHODIMP CNmChannel<T, piid, dwCh>::GetNmch(ULONG *puCh)
|
|
{
|
|
DBGENTRY(CNmChannel::GetNmch);
|
|
HRESULT hr = S_OK;
|
|
|
|
if(puCh)
|
|
{
|
|
*puCh = dwCh;
|
|
}
|
|
else
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
|
|
DBGEXIT_HR(CNmChannel::GetNmch,hr);
|
|
return hr;
|
|
}
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
STDMETHODIMP CNmChannel<T, piid, dwCh>::EnumMember(IEnumNmMember **ppEnum)
|
|
{
|
|
DBGENTRY(CNmChannel::EnumMember);
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = CreateEnumFromSimpleAryOfInterface<IEnumNmMember, INmMember>(m_SDKMemberObjs, ppEnum);
|
|
|
|
DBGEXIT_HR(CNmChannel::EnumMember,hr);
|
|
return hr;
|
|
}
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
STDMETHODIMP CNmChannel<T, piid, dwCh>::GetMemberCount(ULONG * puCount)
|
|
{
|
|
DBGENTRY(CNmChannel::GetMemberCount);
|
|
HRESULT hr = S_OK;
|
|
|
|
if(puCount)
|
|
{
|
|
*puCount = m_SDKMemberObjs.GetSize();
|
|
}
|
|
else
|
|
{
|
|
hr = E_POINTER;
|
|
}
|
|
|
|
DBGEXIT_HR(CNmChannel::GetMemberCount,hr);
|
|
return hr;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// INmChannelNotify
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
STDMETHODIMP CNmChannel<T, piid, dwCh>::NmUI(CONFN uNotify)
|
|
{
|
|
DBGENTRY(CNmChannel::NmUI);
|
|
HRESULT hr = S_OK;
|
|
|
|
DBGEXIT_HR(CNmChannel::NmUI,hr);
|
|
return hr;
|
|
}
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
STDMETHODIMP CNmChannel<T, piid, dwCh>::MemberChanged(NM_MEMBER_NOTIFY uNotify, INmMember *pInternalMember)
|
|
{
|
|
DBGENTRY(CNmChannel::MemberChanged);
|
|
HRESULT hr = S_OK;
|
|
|
|
if(pInternalMember && m_pConfObj)
|
|
{
|
|
INmMember* pMember = NULL;
|
|
|
|
if(NM_MEMBER_ADDED == uNotify)
|
|
{
|
|
// Only add it if we haven't added it yet
|
|
if(!(pMember = _GetSDKMemberFromInternalMember(pInternalMember)))
|
|
{
|
|
pMember = m_pConfObj->GetSDKMemberFromInternalMember(pInternalMember);
|
|
ASSERT(pMember);
|
|
|
|
pMember->AddRef();
|
|
m_SDKMemberObjs.Add(pMember);
|
|
}
|
|
else
|
|
{
|
|
// We already have this member
|
|
goto end;
|
|
}
|
|
}
|
|
|
|
if(!pMember)
|
|
{
|
|
pMember = _GetSDKMemberFromInternalMember(pInternalMember);
|
|
}
|
|
|
|
// It is possable that the member has already been removed..
|
|
if(pMember)
|
|
{
|
|
if(NM_MEMBER_REMOVED == uNotify)
|
|
{
|
|
_RemoveMember(pInternalMember);
|
|
}
|
|
else
|
|
{
|
|
Fire_MemberChanged(uNotify, pMember);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("The member is not in the conference yet!!!"));
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
|
|
end:
|
|
|
|
DBGEXIT_HR(CNmChannel::MemberChanged,hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
INmMember* CNmChannel<T, piid, dwCh>::_GetSDKMemberFromInternalMember(INmMember* pInternalMember)
|
|
{
|
|
INmMember* pRet = NULL;
|
|
|
|
for( int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
|
|
{
|
|
CComQIPtr<IInternalMemberObj> spInternal = m_SDKMemberObjs[i];
|
|
ASSERT(spInternal);
|
|
|
|
CComPtr<INmMember> spMember;
|
|
if(SUCCEEDED(spInternal->GetInternalINmMember(&spMember)))
|
|
{
|
|
if(spMember.IsEqualObject(pInternalMember))
|
|
{
|
|
pRet = m_SDKMemberObjs[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pRet;
|
|
}
|
|
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
HRESULT CNmChannel<T, piid, dwCh>::_RemoveMember(INmMember* pInternalMember)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
for( int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
|
|
{
|
|
CComQIPtr<IInternalMemberObj> spSDKObj = m_SDKMemberObjs[i];
|
|
CComPtr<INmMember> spSDKMember = m_SDKMemberObjs[i];
|
|
ASSERT(spSDKObj);
|
|
|
|
CComPtr<INmMember> spMember;
|
|
if(SUCCEEDED(spSDKObj->GetInternalINmMember(&spMember)))
|
|
{
|
|
// Worst case we return S_FALSE to indicate that there is no such member
|
|
hr = S_FALSE;
|
|
|
|
if(spMember.IsEqualObject(pInternalMember))
|
|
{
|
|
m_SDKMemberObjs.RemoveAt(i);
|
|
|
|
Fire_MemberChanged(NM_MEMBER_REMOVED, spSDKMember);
|
|
|
|
spSDKMember.p->Release();
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
template<class T, const IID* piid, DWORD dwCh>
|
|
bool CNmChannel<T, piid, dwCh>::_MemberInChannel(INmMember* pSDKMember)
|
|
{
|
|
for( int i = 0; i < m_SDKMemberObjs.GetSize(); ++i)
|
|
{
|
|
|
|
CComPtr<INmMember> spMember = m_SDKMemberObjs[i];
|
|
if(spMember.IsEqualObject(pSDKMember))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
#endif // __NmChannel_h__
|