#ifndef DEBUG
#undef markcu
#endif
#ifdef markcu
#endif
#if defined (SHOW_SPONSOR_INFO)
#include<typeinfo.h>
#endif
#ifdef SHOW_SPONSOR_INFO
class CDebugClass {
public:
CSimpleArray<CComBSTR> bstrSponsors;
CSimpleArray<CComBSTR> bstrLimbs;
~CDebugClass()
{
USES_CONVERSION;
int s = bstrSponsors.GetSize();
int l = bstrLimbs.GetSize();
if (s > 0)
{
printf("Sponsors left over:\n");
for(int i = 0; i < s; ++i)
{
printf("%s\n", OLE2A(bstrSponsors[i]));
}
}
if (l > 0)
{
printf("Limbs left over:\n");
for(int i = 0; i < l; ++i)
{
printf("%s\n", OLE2A(bstrLimbs[i]));
}
}
if (s > 0 || l > 0)
DebugBreak();
}
};
extern CDebugClass DebugClass;
#endif
class CBaseSponsor
{
public:
virtual void DetachLimb() = 0;
};
#ifdef SHOW_SPONSOR_INFO
extern int cSponsor;
extern int cLimb;
#endif
template <class CAdminLimbObj> class CAdminSponsor : public CBaseSponsor
{
public:
CAdminSponsor()
{
#ifdef SHOW_SPONSOR_INFO
cSponsor++;
printf (" Spon %i %s\n", cSponsor, typeid(*this).name());
DebugClass.bstrSponsors.Add(CComBSTR(typeid(*this).name()));
#endif
m_pCAdminLimbObj = NULL;
m_iidInterface = NULL;
}
virtual ~CAdminSponsor()
{
if (m_pCAdminLimbObj)
{
m_pCAdminLimbObj->_ForceDestruction();
}
#ifdef SHOW_SPONSOR_INFO
int i = DebugClass.bstrSponsors.Find(CComBSTR(typeid(*this).name()));
if (i == -1) printf("Name not found in array for:\n");
else DebugClass.bstrSponsors.RemoveAt(i);
cSponsor--;
printf ("~Spon %i %s\n", cSponsor, typeid(*this).name());
#endif
}
HRESULT Make(const IID& iidInterface, void **ppInterface)
{
HRESULT hr = S_OK;
if (m_iidInterface == NULL)
{
assert(m_pCAdminLimbObj == NULL);
RETURN_FAILED(m_pCAdminLimbObj->CreateInstance(&m_pCAdminLimbObj));
m_pCAdminLimbObj->SetBaseSponsor(this);
}
assert(m_pCAdminLimbObj);
hr = m_pCAdminLimbObj->QueryInterface(iidInterface, &m_iidInterface);
*ppInterface = m_iidInterface;
return hr;
}
virtual void DetachLimb()
{
m_pCAdminLimbObj = NULL;
m_iidInterface = NULL;
}
CAdminLimbObj* GetLimb() { return m_pCAdminLimbObj; }
private:
CComObject<CAdminLimbObj>* m_pCAdminLimbObj;
void * m_iidInterface;
};
template <class CDerivedClass, class TInferfaceClass> class CAdminLimb {
public:
CAdminLimb()
{
#ifdef SHOW_SPONSOR_INFO
cLimb++;
printf (" Limb %i %s\n", cLimb, typeid(*this).name());
DebugClass.bstrLimbs.Add(CComBSTR(typeid(*this).name()));
#endif
m_pCBaseSponsor = NULL;
}
virtual ~CAdminLimb()
{
DetachFromSponsor();
#ifdef SHOW_SPONSOR_INFO
int i = DebugClass.bstrLimbs.Find(CComBSTR(typeid(*this).name()));
if (i == -1) printf("Name not found in array for:\n");
else DebugClass.bstrLimbs.RemoveAt(i);
cLimb--;
printf ("~Limb %i %s\n", cLimb, typeid(*this).name());
#endif
}
void _ForceDestruction()
{
DetachFromSponsor();
static_cast<CDerivedClass*>(this)->AddRef();
CoDisconnectObject(static_cast<TInferfaceClass*>((static_cast<CDerivedClass*>(this))), 0);
static_cast<CDerivedClass*>(this)->Release();
}
void SetBaseSponsor(CBaseSponsor *pCBaseSponsor) {m_pCBaseSponsor = pCBaseSponsor;}
private:
void DetachFromSponsor()
{
if (m_pCBaseSponsor)
{
m_pCBaseSponsor->DetachLimb();
m_pCBaseSponsor = NULL;
}
}
CBaseSponsor *m_pCBaseSponsor;
};