Talk:RDF:Delegates

From MozillaWiki
Jump to: navigation, search
Dual ownership 
The delegate object presents two XPCOM objects, the first (inner) object exposes the interfaces nsISupports and nsIInterfaceRequestor to the corresponding RDF resource object. The GetInterface method on the inner XPCOM object returns a distinct nsISupports implementation (outer) on the delegate object (and calls QueryInterface on it). This may forward the reference counting to the RDF resource object to the resource object alive as long as there are external references to outer. The Release implementation on outer *does not delete* the delegate object under any circumstances, this is the sole responsibility of Release implementation on the inner nsISupports interface, which will be called upon deletion of the resurce object.

Alternative wrapper model

/* the actual delegate should extend this class */
class nsRDFDelegateBase : nsISupports
{
  public:
    NS_IMETHOD_(nsrefcnt) AddRef(void);
    NS_IMETHOD_(nsrefcnt) Release(void);
    nsRDFDelegateBase(nsIRDFResource* aResource) : mResource(aResource) {};
  protected:
    nsIRDFResource *mResource;
}
NS_IMETHOD_(nsrefcnt) nsRDFDelegateBase::AddRef(void)
{
  NS_LOG_ADDREF(this, count, #_class, sizeof(*this));
  NS_PRECONDITION(mResource, "No resource!");
  return mResource->AddRef();
}
NS_IMETHOD_(nsrefcnt) nsRDFDelegateBase::AddRef(void)
{
  NS_LOG_ADDREF(this, count, #_class, sizeof(*this));
  NS_PRECONDITION(mResource, "No resource!");
  return mResource->Release();
}
/* this is because I can't be bothered to template AddRef/Release */
class nsRDFBaseWrapper : public nsIInterfaceRequestor
{
  public:
    NS_DECL_ISUPPORTS
}
NS_IMPL_ISUPPORTS1(nsRDFBaseWrapper, nsIInterfaceRequestor);
/* this is the object actually created by the delegate factory */
template<class T>
class nsRDFDelegateWrapper : public nsRDFBaseWrapper
{
  public:
    NS_DECL_NSIINTERFACEREQUESTOR
  private:
    T mDelegate;
}
template<class T>
NS_IMETHODIMP nsRDFDelegateWrapper<T>::GetInterface(REFNSIID aIID, void **aResult)
{
  return mDelegate->QueryInterface(aIID, aResult);
}