On 7/29/06, Jorrit Tyberghein <[EMAIL PROTECTED]> wrote:
> > I just thought of another solution as I'm typing this.  We could make
> > a generic class ("csWeakEventHandler"?) to act as an indirector and
> > write a helper function ("RegisterWeakListener"?) that does the usual
> > subscription but indirected through "csWeakEventHandler".  The use of
> > the "csWeakEventHandler" would be invisible to the user.  This way
> > classes wouldn't be pseudo-embedding (both redundant work and looking
> > confusingly like true embedding), but it wouldn't have to change the
> > internals of the event system.  I can provide code excepts if this
> > description isn't clear enough.
>
> Ok, code samples would be nice.

I'm writing this up without testing compilation so there may be typos
in it, but it should give you an idea of what I'm talking about.  (I'm
also not clear on when to use a csRef and when to use a regular
pointer in the interface to a function call.)

Also, after writing the code out what I ended up with is slightly
different than what I started with in mind.  It ends up being a very
minor change from the current way of pseudo-embedding.  But I think it
makes it clearer to someone reading the code that this is *not* true
embedding.  It also eliminates all the existing repetitions of
scfiEventHandler code by abstracting it out into one class that can be
reused.

// The indirection class.  Not directly used by 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> *token)
{
  *token = new csWeakEventHandler(listener);
  return q->RegisterListener(*token);
}

// Helper function used by client code.
// May be unnecessary.  The client code can just call the code on its own.
void RemoveWeakListener (iEventQueue *q, csWeakEventHandler* token)
{
  q->RemoveListener(token);
}

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

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

csFoo::~csFoo ()
{
  if (weakEventHandler)
  {
    RemoveWeakListener(q, weakEventHandler);
  }
}

-------------------------------------------------------------------------
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