Attached is a draft of the solution for event handlers.  I wanted to
put it up for others to get one last chance to comment on before I
commit it.

I wasn't sure what the most appropriate place to put
RegisterWeakListener.  I've put it in include/csutil/event.h for now
unless there is a better place someone can point out.

The three files are:
* weak-listener.patch - the core code,
* weak-listener-engine-example.patch
   - an example of using RegisterWeakListener in "plugins/engine/3d/engine.h",
* weak-listener-graph2d-example.patch
   - an example of using RegisterWeakListener in
"include/csplugincommon/canvas/graph2d.h".

Michael D. Adams
[EMAIL PROTECTED]

On 8/4/06, Jorrit Tyberghein <[EMAIL PROTECTED]> wrote:
None of these solutions really sound very attractive I must say. I
wonder if we perhaps should concentrate our solution only on the most
common type of callback (event handler) and then just use embedded
interfaces (or separate classes as is also commonly done) for the
others.

Unless someone can still come up with a workable solution.

Greetings,

On 8/4/06, Michael D. Adams <[EMAIL PROTECTED]> wrote:
> I like your idea of generalizing this solution to enable weak
> callbacks in general, but am unable to think of a satisfactory way to
> do that.  In pricipal it is easy, but the limitations of C++ would
> require writting redirection functions for every function in the
> interface.  I can't think of a clean way to to that automaticly.
>
> Let me brainstorm here for a bit.  None of the following ideas
> actually work (well some would work but are probably distatefull), but
> maybe they will stimulate an idea in someone.
>
> Idea 1:
> Add some wrapper layer to C++ that would allow the following:
> template<typename T>
> class csWeakCallback : T
> {
>   T *imp;
> public:
>   csWeakCallback (T *imp) : imp(imp) { }
> <%for $func in functions_of(T)%>
>   $func () { imp->$func(); }
> <%end for%>
> };
>
> Idea 1.5:
> The same as Idea 1, but use the preprocessor to do that.  (Still
> probably not possible b/c the preprocessor would need to be able to
> figure out what functions a particular interface had.)
>
> Idea 2:
> Find some way to take a pointer to a call back interface (e.g.
> iEventHandler*) and produce another pointer to that interface with the
> same vtable except for the entries for IncRef and DecRef which would
> get assigned to no-op functions.
>
> Idea 3:
> Establish some way to "poison" the csRefs that are used internally by
> what ever the callback is registered with.
>
> Idea 3a: Establish some kind of weak-object system so csRef could tell
> that the pointer it is holding is to an object that should always be
> held only weakly.
>
> Idea 3b: Make a "poisoned" csRef that would poison any csRef that it
> gets assigned to (poisioned = hold the object only weakly).  Then when
> registering the callback use a csRef instead of a pointer which we
> will pre-poison.
>
> On 8/4/06, Jorrit Tyberghein <[EMAIL PROTECTED]> wrote:
> > I just considered something. I think this solution is focusing too
> > much on event handlers but event handlers are not the only type of
> > callback where this problem occurs. I can't give examples right now
> > but I'm sure there are many other types of callbacks where similar
> > problem occurs right now which is also solved with embedding
> > interface. So perhaps we should find a way to generalize this so that
> > it can work for a general callback type system?
> > Perhaps using a template?
> >
> > Greetings,
> >
> > On 8/3/06, Michael D. Adams <[EMAIL PROTECTED]> wrote:
> > > 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]

Attachment: weak-listener.patch
Description: Binary data

Attachment: weak-listener-engine-example.patch
Description: Binary data

Attachment: weak-listener-graph2d-example.patch
Description: Binary data

-------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/crystal-main
Unsubscribe: mailto:[EMAIL PROTECTED]

Reply via email to