On 7/29/06, Jorrit Tyberghein <[EMAIL PROTECTED]> wrote:
> >   *token = new csWeakEventHandler(listener);
>
> This is invalid code. You can't use a weak ref like that. Keep in mind
> that if the only thing that holds a reference to something is a weak
> reference then the object will be removed. You'll have to rework the
> code a bit so that after allocation you have a real reference for a
> while and then you release that reference as soon as you register to
> the event registry.
>
> I do understand the basic idea of your solution though and it seems
> like a possibility.

Below is a redraft of the code.  I changed two things.  But I'm not
sure whether I am using csHandlerID correctly for the second change.

First, I fixed my use of csRef as Jorrit noted should be done.

The second change is to make the csWeakEventListener completely
invisible to the client code.  Now the csHandlerID that is handed back
(by RegisterListener via RegisterWeakListener) is used to lookup the
iEventHandler (really a csWeakEventListener) that should be passed on
to RemoveListener by RemoveWeakListener.  (As a side benefit, this
eliminates the need for an output parameter in RemoveWeakListener to
hand back the "csRef<csWeakEventListener>*".)

As far as I can tell, there are two kinds of csHandlerID, generic and
instance.  The csHandlerID returned by RegisterListener is an instance
csHandlerID.  What I'm not 100% sure on is that "instance" in this
context means "per object instance".  If it doesn't, then this code
probably wont work and I should go back to handing back a
"csRef<csWeakEventListener>*".  So can anyone confirm that
understanding of "instance csHandlerID"?

Michael D. Adams
[EMAIL PROTECTED]

// The indirection class.  Hidden from client code
class csWeakEventHandler :
  scfImplementation1<csWeakEventHandler, iEventHandler>
{
private:
  csWeakRef<iEventHandler> parent;
public:
  csWeakEventHandler (iEventHandler *parent) :
    scfImplementationType (this), parent(parent) { }
  bool HandleEvent (iEvent& e) { parent->HandleEvent(e); }
  /* Similar code to HandleEvent for all the other methods of iEventHandler */
};

// Helper function used by client code
// May be unnecessary.  The client code can just call the code on its own.
csHandlerID RegisterWeakListener (iEventQueue *q, iEventHandler * listener)
{
  csRef<csWeakEventHandler> handler;
  handler.AttachNew (new csWeakEventHandler (listener));
  return q->RegisterListener (handler);
}

// Helper function used by client code.
// May be unnecessary.  The client code can just call the code on its own.
void RemoveWeakListener (iEventQueue *q, iObjectRegistry *r, csHandlerId id)
{
  q->RemoveListener(csEventHandlerRegistry::Handler(r, id));
}

// Example client code
class csFoo : scfImplementation2<csFoo, iComponent, iEventHandler>
{
private:
  csHandlerID id;
public:
  csFoo() : id(CS_HANDLER_INVALID) { /* ... */ }
  ~csFoo();
  bool Initialize (iObjectRegistry *object_reg);
  bool HandleEvent (iEvent& e) { /* ... */ }
};

bool csFoo::Initialize (iObjectRegistry *object_reg)
{
  /* ... */
  csRef<iEventQueue> q (CS_QUERY_REGISTRY (object_reg, iEventQueue));
  if (q != 0)
  {
    id = RegisterWeakListener(q, this);
  }
  /* ... */
  return true;
}

csFoo::~csFoo ()
{
  /* ... */
  if (id != CS_HANDLER_INVALID)
  {
    RemoveWeakListener(q, object_reg, id);
  }
  /* ... */
}

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Crystal-main mailing list
Crystal-main@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/crystal-main
Unsubscribe: mailto:[EMAIL PROTECTED]

Reply via email to