First Checked In.

This commit is contained in:
scc%netscape.com 1999-08-03 03:41:27 +00:00
parent d540ac2701
commit fbc8779752
5 changed files with 369 additions and 0 deletions

View File

@ -0,0 +1,39 @@
// nsIWeakReference.idl
#include "nsISupports.idl"
[scriptable, uuid(9188bc85-f92e-11d2-81ef-0060083a0bcf)]
interface nsIWeakReference : nsISupports
{
void QueryReference( in nsIIDRef uuid, [iid_is(uuid), retval] out nsQIResult result );
};
[scriptable, uuid(9188bc86-f92e-11d2-81ef-0060083a0bcf)]
interface nsISupportsWeakReference : nsISupports
{
void GetWeakReference( [retval] out nsIWeakReference result );
};
%{C++
#ifndef nsCOMPtr_h___
#include "nsCOMPtr.h"
#endif
typedef nsCOMPtr<nsIWeakReference> nsWeakPtr;
nsIWeakReference* NS_GetWeakReference( nsISupports* );
// ...convenience. Get a weak reference (if possible) without doing the query yourself
template <class T>
inline
nsresult
CallQueryReference( nsIWeakReference* aSource, T** aDestination )
{
NS_PRECONDITION(aSource, "null parameter");
NS_PRECONDITION(aDestination, "null parameter");
return aSource->QueryReference(nsCOMTypeInfo<T>::GetIID(), (void**)aDestination);
}
%}

View File

@ -0,0 +1,83 @@
// nsWeakReference.cpp
#include "nsWeakReference.h"
nsIWeakReference*
NS_GetWeakReference( nsISupports* aInstance, nsresult* aResult )
{
nsIWeakReference* result = 0;
nsCOMPtr<nsISupportsWeakReference> factory = do_QueryInterface(aInstance, aResult);
nsIWeakReference* w
if ( factory )
result = factory->GetWeakReference();
return result;
}
nsresult
nsSupportsWeakReference::GetWeakReference( nsIWeakReference** aInstancePtr )
{
if ( !aInstancePtr )
return NS_ERROR_NULL_POINTER;
if ( !mProxy )
mProxy = new nsWeakReference(this);
*aInstancePtr = mProxy;
nsresult status;
if ( !*aInstancePtr )
status = NS_NOINTERFACE;
else
{
NS_ADDREF(*aInstancePtr);
status = NS_OK;
}
return status;
}
nsrefcnt
nsWeakReference::AddRef()
{
return ++mRefCount
}
nsrefcnt
nsWeakReference::Release()
{
nsrefcnt temp = --mRefCount;
if ( !mRefCount )
delete this;
return temp;
}
nsresult
nsWeakReference::QueryInterface( const nsIID& aIID, void** aInstancePtr )
{
if ( !aInstancePtr )
return NS_ERROR_NULL_POINTER;
if ( aIID.Equals(nsCOMTypeInfo<nsIWeakReference>::GetIID()) )
*aInstancePtr = NS_STATIC_CAST(nsIWeakReference*, this);
else if ( aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID()) )
*aInstancePtr = NS_STATIC_CAST(nsISupports*, this);
else
*aInstancePtr = 0;
nsresult status;
if ( !*aInstancePtr )
status = NS_NOINTERFACE;
else
{
NS_ADDREF( NS_REINTERPRET_CAST(nsISupports*, *aInstancePtr) );
status = NS_OK;
}
return status;
}
nsresult
nsWeakReference::QueryReference( const nsIID& aIID, void** aInstancePtr )
{
return mReferent ? mReferent->QueryInterface(aIID, aInstancePtr) : NS_ERROR_NULL_PTR;
}

View File

@ -0,0 +1,82 @@
#ifndef nsWeakReference_h__
#define nsWeakReference_h__
// nsWeakReference.h
#include "nsIWeakReference.h"
class nsSupportsWeakReference : public nsISupportsWeakReference
{
public:
nsSupportsWeakReference()
: mProxy(0)
{
// nothing else to do here
}
inline ~nsSupportsWeakReference();
virtual nsresult GetWeakReference( nsIWeakReference** );
private:
friend class nsWeakReference;
void
NoticeProxyDestruction()
// ...called (only) by an |nsWeakReference| from _its_ dtor.
{
mProxy = 0;
}
nsWeakReference* mProxy;
};
class nsWeakReference : public nsIWeakReference
{
public:
// nsISupports...
virtual nsrefcnt AddRef();
virtual nsrefcnt Release();
virtual nsresult QueryInterface( const nsIID&, void** );
// nsIWeakReference...
virtual nsresult QueryReference( const nsIID&, void** );
private:
friend class nsSupportsWeakReference;
nsWeakReference( nsSupportsWeakReference* referent )
: mRefCount(0),
mReferent(referent)
// ...I can only be constructed by an |nsSupportsWeakReference|
{
// nothing else to do here
}
~nsWeakReference()
// ...I will only be destroyed by calling |delete| myself.
{
if ( mReferent )
mReferent->NoticeProxyDestruction();
}
void
NoticeReferentDestruction()
// ...called (only) by an |nsSupportsWeakReference| from _its_ dtor.
{
mReferent = 0;
}
nsrefcnt mRefCount;
nsSupportsWeakReference* mReferent;
};
inline
nsSupportsWeakReference::~nsSupportsWeakReference()
{
if ( mProxy )
mProxy->NoticeReferentDestruction();
}
#endif

View File

@ -0,0 +1,83 @@
// nsWeakReference.cpp
#include "nsWeakReference.h"
nsIWeakReference*
NS_GetWeakReference( nsISupports* aInstance, nsresult* aResult )
{
nsIWeakReference* result = 0;
nsCOMPtr<nsISupportsWeakReference> factory = do_QueryInterface(aInstance, aResult);
nsIWeakReference* w
if ( factory )
result = factory->GetWeakReference();
return result;
}
nsresult
nsSupportsWeakReference::GetWeakReference( nsIWeakReference** aInstancePtr )
{
if ( !aInstancePtr )
return NS_ERROR_NULL_POINTER;
if ( !mProxy )
mProxy = new nsWeakReference(this);
*aInstancePtr = mProxy;
nsresult status;
if ( !*aInstancePtr )
status = NS_NOINTERFACE;
else
{
NS_ADDREF(*aInstancePtr);
status = NS_OK;
}
return status;
}
nsrefcnt
nsWeakReference::AddRef()
{
return ++mRefCount
}
nsrefcnt
nsWeakReference::Release()
{
nsrefcnt temp = --mRefCount;
if ( !mRefCount )
delete this;
return temp;
}
nsresult
nsWeakReference::QueryInterface( const nsIID& aIID, void** aInstancePtr )
{
if ( !aInstancePtr )
return NS_ERROR_NULL_POINTER;
if ( aIID.Equals(nsCOMTypeInfo<nsIWeakReference>::GetIID()) )
*aInstancePtr = NS_STATIC_CAST(nsIWeakReference*, this);
else if ( aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID()) )
*aInstancePtr = NS_STATIC_CAST(nsISupports*, this);
else
*aInstancePtr = 0;
nsresult status;
if ( !*aInstancePtr )
status = NS_NOINTERFACE;
else
{
NS_ADDREF( NS_REINTERPRET_CAST(nsISupports*, *aInstancePtr) );
status = NS_OK;
}
return status;
}
nsresult
nsWeakReference::QueryReference( const nsIID& aIID, void** aInstancePtr )
{
return mReferent ? mReferent->QueryInterface(aIID, aInstancePtr) : NS_ERROR_NULL_PTR;
}

View File

@ -0,0 +1,82 @@
#ifndef nsWeakReference_h__
#define nsWeakReference_h__
// nsWeakReference.h
#include "nsIWeakReference.h"
class nsSupportsWeakReference : public nsISupportsWeakReference
{
public:
nsSupportsWeakReference()
: mProxy(0)
{
// nothing else to do here
}
inline ~nsSupportsWeakReference();
virtual nsresult GetWeakReference( nsIWeakReference** );
private:
friend class nsWeakReference;
void
NoticeProxyDestruction()
// ...called (only) by an |nsWeakReference| from _its_ dtor.
{
mProxy = 0;
}
nsWeakReference* mProxy;
};
class nsWeakReference : public nsIWeakReference
{
public:
// nsISupports...
virtual nsrefcnt AddRef();
virtual nsrefcnt Release();
virtual nsresult QueryInterface( const nsIID&, void** );
// nsIWeakReference...
virtual nsresult QueryReference( const nsIID&, void** );
private:
friend class nsSupportsWeakReference;
nsWeakReference( nsSupportsWeakReference* referent )
: mRefCount(0),
mReferent(referent)
// ...I can only be constructed by an |nsSupportsWeakReference|
{
// nothing else to do here
}
~nsWeakReference()
// ...I will only be destroyed by calling |delete| myself.
{
if ( mReferent )
mReferent->NoticeProxyDestruction();
}
void
NoticeReferentDestruction()
// ...called (only) by an |nsSupportsWeakReference| from _its_ dtor.
{
mReferent = 0;
}
nsrefcnt mRefCount;
nsSupportsWeakReference* mReferent;
};
inline
nsSupportsWeakReference::~nsSupportsWeakReference()
{
if ( mProxy )
mProxy->NoticeReferentDestruction();
}
#endif