View mode: basic / threaded / horizontal-split · Log in · Help
September 10, 2005
Another event handling module
A few classes for multicast event handling have been previously released, 
and here's another. I think this one's unique in that it allows you to use 
both delegates and function pointers (although I may be wrong).

Read more or download it here:
http://www.paperocean.org/cirrus.core.events.html

If you find any bugs, please let me know.

BTW: I've added various ways of chaining together delegates/function 
(opAddAssign/opSubAssign, opCatAssign, add/remove method calls). This way 
you can use the one you prefer.

John.
September 11, 2005
Re: Another event handling module
John C wrote:
> A few classes for multicast event handling have been previously released, 
> and here's another. I think this one's unique in that it allows you to use 
> both delegates and function pointers (although I may be wrong).

dcouple at dsource has them too :-)

What do you do when a recipient gets deleted?

Bastiaan.
September 11, 2005
Re: Another event handling module
"Bastiaan Veelo" <Bastiaan.N.Veelo@ntnu.no> wrote in message 
news:dg1e0u$2ihm$1@digitaldaemon.com...
> John C wrote:
>> A few classes for multicast event handling have been previously released, 
>> and here's another. I think this one's unique in that it allows you to 
>> use both delegates and function pointers (although I may be wrong).
>
> dcouple at dsource has them too :-)
>
> What do you do when a recipient gets deleted?

Good question ... my test program crashes and there doesn't appear to be a 
way to check if the delegate still exists - testing for null doesn't work. 
Also, I was unable to catch any exceptions. Ideas?

As a workaround, you can call 'remove' to break the connection in the 
receiver's destructor. But I'm not sure how this can be done when a function 
literal is attached, though.

I've noticed that Ben Hinkle's MultiDelegate exhibits the same problem. I've 
not tested dcouple.

Shouldn't the compiler null out delegates that reference nonexistent 
methods?
September 11, 2005
Re: Another event handling module
In article <dg1r4v$2tcj$1@digitaldaemon.com>, John C says...
>
>"Bastiaan Veelo" <Bastiaan.N.Veelo@ntnu.no> wrote in message 
>news:dg1e0u$2ihm$1@digitaldaemon.com...
>> John C wrote:
>>> A few classes for multicast event handling have been previously released, 
>>> and here's another. I think this one's unique in that it allows you to 
>>> use both delegates and function pointers (although I may be wrong).
>>
>> dcouple at dsource has them too :-)
>>
>> What do you do when a recipient gets deleted?
>
>Good question ... my test program crashes and there doesn't appear to be a 
>way to check if the delegate still exists - testing for null doesn't work. 
>Also, I was unable to catch any exceptions. Ideas?

I'm not sure if this applies directly, but I use proxy classes for this purpose
in C++.  The basic idea is something like this:

# class Proxy(Dest) {
#     this() {}
#     this( Dest d ) { attach( d ); }
#     void attach( Dest d ) { m_dest = d; }
#     void detach() { m_dest = null; }
#     void opCall() { if( m_dest ) m_dest(); }
# private Dest m_dest;
# }
#
# class C {
#     ~this() {
#         foreach( Proxy!(C) p; m_proxies )
#             p.detach();
#     }
#     void doSomething() {
#         Proxy!(C) p = new Proxy!(C)( this );
#         // pass proxy to callback
#         m_proxies ~= p;
#    }
# private Proxy!(C)[] m_proxies;
# }

>As a workaround, you can call 'remove' to break the connection in the 
>receiver's destructor.

Sounds like you're doing something like the above.

>But I'm not sure how this can be done when a function 
>literal is attached, though.

A delegate you mean?  There's not much you can do aside from perhaps putting the
call in a try{}catch(Object){} block, as I think this will trap the access
violation if the referenced object has been destroyed.

>I've noticed that Ben Hinkle's MultiDelegate exhibits the same problem. I've 
>not tested dcouple.
>
>Shouldn't the compiler null out delegates that reference nonexistent 
>methods?

If so then it may as well do the same for references to objects that have been
cleaned up.  I think the issue is that this is simply too expensive to be
worthwhile in most cases.


Sean
September 11, 2005
Re: Another event handling module
"John C" <johnch_atms@hotmail.com> wrote in message 
news:dg1r4v$2tcj$1@digitaldaemon.com...
> "Bastiaan Veelo" <Bastiaan.N.Veelo@ntnu.no> wrote in message 
> news:dg1e0u$2ihm$1@digitaldaemon.com...
>> John C wrote:
>>> A few classes for multicast event handling have been previously 
>>> released, and here's another. I think this one's unique in that it 
>>> allows you to use both delegates and function pointers (although I may 
>>> be wrong).
>>
>> dcouple at dsource has them too :-)
>>
>> What do you do when a recipient gets deleted?
>
> Good question ... my test program crashes and there doesn't appear to be a 
> way to check if the delegate still exists - testing for null doesn't work. 
> Also, I was unable to catch any exceptions. Ideas?
>
> As a workaround, you can call 'remove' to break the connection in the 
> receiver's destructor. But I'm not sure how this can be done when a 
> function literal is attached, though.
>
> I've noticed that Ben Hinkle's MultiDelegate exhibits the same problem. 
> I've not tested dcouple.

Correct. When a programmer deletes an object by hand it is a promise that no 
other live references exist. Violating that promise results in crashes.

> Shouldn't the compiler null out delegates that reference nonexistent 
> methods?
September 11, 2005
Re: Another event handling module
"Ben Hinkle" <bhinkle@mathworks.com> wrote in message 
news:dg24mg$2r4$1@digitaldaemon.com...
>
> "John C" <johnch_atms@hotmail.com> wrote in message 
> news:dg1r4v$2tcj$1@digitaldaemon.com...
>> "Bastiaan Veelo" <Bastiaan.N.Veelo@ntnu.no> wrote in message 
>> news:dg1e0u$2ihm$1@digitaldaemon.com...
>>> John C wrote:
>>>> A few classes for multicast event handling have been previously 
>>>> released, and here's another. I think this one's unique in that it 
>>>> allows you to use both delegates and function pointers (although I may 
>>>> be wrong).
>>>
>>> dcouple at dsource has them too :-)
>>>
>>> What do you do when a recipient gets deleted?
>>
>> Good question ... my test program crashes and there doesn't appear to be 
>> a way to check if the delegate still exists - testing for null doesn't 
>> work. Also, I was unable to catch any exceptions. Ideas?
>>
>> As a workaround, you can call 'remove' to break the connection in the 
>> receiver's destructor. But I'm not sure how this can be done when a 
>> function literal is attached, though.
>>
>> I've noticed that Ben Hinkle's MultiDelegate exhibits the same problem. 
>> I've not tested dcouple.
>
> Correct. When a programmer deletes an object by hand it is a promise that 
> no other live references exist. Violating that promise results in crashes.

Sounds like a fair rule. After all, if you're explictly calling delete 
you'll probably want to ensure everything else is cleaned up too.

>
>> Shouldn't the compiler null out delegates that reference nonexistent 
>> methods?
>
>
September 12, 2005
Re: Another event handling module
John C wrote:

>>What do you do when a recipient gets deleted?
> 
> 
> Good question ... my test program crashes and there doesn't appear to be a 
> way to check if the delegate still exists - testing for null doesn't work. 
> Also, I was unable to catch any exceptions. Ideas?
> 
> As a workaround, you can call 'remove' to break the connection in the 
> receiver's destructor. But I'm not sure how this can be done when a function 
> literal is attached, though.
> 
> I've noticed that Ben Hinkle's MultiDelegate exhibits the same problem. I've 
> not tested dcouple.


Dcouple solves this with Slot objects and managing code. I am ioning out 
some segfaults in version 0.3, but 0.2 should work.


> Shouldn't the compiler null out delegates that reference nonexistent 
> methods? 


That would be nice, but how would the compiler know? There is a concept 
called weak references, that has been brought up a couple of times in 
this context. See the post "Resources" on the dcouple forum at dsource.


Bastiaan.
September 13, 2005
dcouple [was: Another event handling module]
Bastiaan Veelo wrote:

> Dcouple solves this with Slot objects and managing code.

Version 0.3 (currently in the svn trunk) works per today 
(http://svn.dsource.org/projects/dcouple/trunk/managed/dcouple/). The 
dcouple version of Ben's example from multidg.d is given below

#import dcouple.connect;
#import dcouple.release;
#import dcouple.signalslot;
#
#class Foo : SignalSlotManager
#{
#  mixin SignalSlotManagement;
#
#  Signal!(int) valueChanged;
#  Slot!(int) changeValue;
#
#  private int val;
#
#  this()
#  {
#    valueChanged = new Signal!(int)(this);
#    changeValue = new Slot!(int)(this, &value);
#  }
#
#  ~this()
#  {
#    deleteSignals();
#    deleteSlots();
#  }
#
#  int value()
#  {
#    return val;
#  }
#
#  void value(int v)
#  {
#    if (val != v) {
#      val = v;
#      valueChanged.emit(v);
#    }
#  }
#}
#
#import std.stdio;
#int main() {
#  writefln("Compiled with ", dcoupleVersion() );
#  Foo a = new Foo;
#  Foo b = new Foo;
#  connect(a.valueChanged, b.changeValue);
#  writefln(a.value," ",b.value);
#  b.value = 11;
#  writefln(a.value," ",b.value);
#  a.value = 79;
#  writefln(a.value," ",b.value);
#  delete b;                                      // Note delete!
#  a.value = 100;
#  writefln(a.value);
#  return 0;
#}

(also available here 
http://svn.dsource.org/projects/dcouple/trunk/managed/examples/delete_example.d)

output is

Compiled with dcouple version 0.3, copyright 2004, 2005 Bastiaan Veelo.
0 0
0 11
79 79
100


So dcouple lets you tie together objects, and handle them any way you 
like regardless what ties exist. If you delete an object, existing ties
clean themselves up.

Bastiaan.
September 13, 2005
Re: dcouple [was: Another event handling module]
> #  ~this()
> #  {
> #    deleteSignals();
> #    deleteSlots();
> #  }

Does deleteSignals and deleteSlots reference other GC-managed objects or 
arrays? If so then you'll get random seg-v's during a GC. Objects are 
collected in random order and so the other objects might be gone by the time 
~this runs. The details (as they are) are in 
http://www.digitalmars.com/d/class.html#destructors
September 14, 2005
Re: dcouple [was: Another event handling module]
Ben Hinkle wrote:
>>#  ~this()
>>#  {
>>#    deleteSignals();
>>#    deleteSlots();
>>#  }
> 
> 
> Does deleteSignals and deleteSlots reference other GC-managed objects or 
> arrays?

Yes, but only to objects (Signals and Slots) that know about each other 
and about their managers (the ones calling deleteSignals and/or 
deleteSlots). In their destructor they deregister themselves with these 
referencing objects. So at the time of destruction, only references 
exist to objects that have not been destructed yet. Therefore, the order 
of destruction does not matter.

Bastiaan.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home