Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
February 01, 2016 How would you implement this in D? (signals & slots) | ||||
---|---|---|---|---|
| ||||
module signals_and_slots; import std.algorithm: remove; struct Slots(DelegateType, ArgTypes...) { this() { } // How would you implement this? void call(ArgTypes args) { foreach (dg; delegates) dg(args); } void connect(DelegateType slot) { foreach (dg; delegates) { if (dg == slot) return; } delegates ~= slot; } void disconnect(DelegateType slot) { for (uint k=0; k < delegates.length; k++) { if (delegates[k] == slot) delegates = delegates.remove(k); } } private: DelegateType[] delegates; } ============================================================= How do you implement this template called like: void onColorChange(in Color) { // do something with color } auto slots = Slots!(void delegate(in Color), Color); slots.connect(&onColorChange); auto color = Color(0.0, 1.0, 1.0, 1.0); slots.call(color); ? Thank you! |
February 01, 2016 Re: How would you implement this in D? (signals & slots) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Enjoys Math | On Monday, 1 February 2016 at 21:40:45 UTC, Enjoys Math wrote: > module signals_and_slots; > > import std.algorithm: remove; > > [...] D's signals & slots: https://dlang.org/phobos/std_signals.html |
February 02, 2016 Re: How would you implement this in D? (signals & slots) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Enjoys Math | On Monday, 1 February 2016 at 21:44:28 UTC, Enjoys Math wrote:
> On Monday, 1 February 2016 at 21:40:45 UTC, Enjoys Math wrote:
>> module signals_and_slots;
>>
>> import std.algorithm: remove;
>>
>> [...]
>
>
> D's signals & slots:
>
> https://dlang.org/phobos/std_signals.html
I looked at that and perhaps I'm not reading the exampes correctly but I'm not sure how useful std.signals is in the real world. If you have a bunch of slots which take the same parameter types, not unusual in the GUI world, how would that work? The other thing that bugs me is lack of naming for slots and signals, again in the GUI world where you typically have dozens of these on an an individual widget differentiation is quite important.
For my GtkD app where I need my own events between components outside of the built-in GTK ones I've just been rolling my own by hand using delegates similar to your example. It's pretty trivial but admittingly there is a bunch of boilerplate I'd love to eliminate via templates if there is a way to address the weaknesses with std.signals.
|
February 02, 2016 Re: How would you implement this in D? (signals & slots) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gerald | On Tuesday, 2 February 2016 at 14:49:21 UTC, Gerald wrote: > On Monday, 1 February 2016 at 21:44:28 UTC, Enjoys Math wrote: >> On Monday, 1 February 2016 at 21:40:45 UTC, Enjoys Math wrote: >>> module signals_and_slots; >>> >>> import std.algorithm: remove; >>> >>> [...] >> >> >> D's signals & slots: >> >> https://dlang.org/phobos/std_signals.html > > I looked at that and perhaps I'm not reading the exampes correctly but I'm not sure how useful std.signals is in the real world. If you have a bunch of slots which take the same parameter types, not unusual in the GUI world, how would that work? Switch on the value inside the slot. Or use different types by wrapping, say, an int or a string with a struct: import std.stdio; import std.signals; struct String1 { string s; } struct String2 { string s; } class Observer { void watch1(String1) { writeln("watch1"); } void watch2(String2) { writeln("watch2"); } } class Signals { mixin Signal!String1; mixin Signal!String2; } void main() { auto o = new Observer; auto s = new Signals; s.connect(&o.watch1); s.connect(&o.watch2); s.emit(String1("foo")); s.emit(String2("bar")); } > The other thing that bugs me is lack of naming for slots and signals, again in the GUI world where you typically have dozens of these on an an individual widget differentiation is quite important. Slots are named: the methods are slots. Signals can be named if you use only one struct as the parameter, as above. The signals would be String1 and String2, the slots watch1 and watch2. Atila |
February 02, 2016 Re: How would you implement this in D? (signals & slots) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | http://dpaste.dzfl.pl/f888feb6f743 |
February 02, 2016 Re: How would you implement this in D? (signals & slots) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | On Tue, 02 Feb 2016 15:59:06 +0000, Atila Neves wrote: > struct String1 { string s; } > struct String2 { string s; } I've seen this sort of thing before. A blogger I used to follow, Jeremy Miller, implemented an event broker using this pattern. I don't like it. It requires a new type for each event, and you have to defensively use that pattern even if you only have one event at the moment. Every time I implemented an event system, I've gone with named events and no special type for their parameters. With std.signals, you could do this: struct Event(TArgs...) { mixin Signal!TArgs; } class Foo { Event!string usernameEntered; Event!string passwordEntered; Event!(long, string) someOtherEventHappened; void enterPassword(string s) { passwordEntered.emit(s); } void enterUsername(string s) { usernameEntered.emit(s); } } void main() { auto o = new Observer; auto f = new Foo; f.usernameEntered.connect(&o.watch); f.passwordEntered.connect(&o.watch); f.enterUsername("adelhurst"); f.enterPassword("********"); } |
February 02, 2016 Re: How would you implement this in D? (signals & slots) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Atila Neves | On Tuesday, 2 February 2016 at 15:59:06 UTC, Atila Neves wrote:
> Slots are named: the methods are slots. Signals can be named if you use only one struct as the parameter, as above. The signals would be String1 and String2, the slots watch1 and watch2.
What I meant is that the connect call didn't seem to tie you to a specific slot, it looked like it determined the slot based on the types which is potentially error prone. Kagamin showed an example of explicitly connecting to a named slot so I'm happy with that, I'm looking forward to re-writing my event handlers using this technique.
Always nice to learn something new.
|
February 02, 2016 Re: How would you implement this in D? (signals & slots) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Wright | On Tuesday, 2 February 2016 at 17:35:25 UTC, Chris Wright wrote:
> On Tue, 02 Feb 2016 15:59:06 +0000, Atila Neves wrote:
>> [...]
>
> I've seen this sort of thing before. A blogger I used to follow, Jeremy Miller, implemented an event broker using this pattern. I don't like it. It requires a new type for each event, and you have to defensively use that pattern even if you only have one event at the moment. Every time I implemented an event system, I've gone with named events and no special type for their parameters.
>
> [...]
Nice. I liked your example and Kagamin's better than mine.
Atila
|
February 03, 2016 Re: How would you implement this in D? (signals & slots) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Enjoys Math | On Monday, 1 February 2016 at 21:40:45 UTC, Enjoys Math wrote: > module signals_and_slots; > How do you implement this template called like: > void onColorChange(in Color) { > // do something with color > } > auto slots = Slots!(void delegate(in Color), Color); > slots.connect(&onColorChange); > auto color = Color(0.0, 1.0, 1.0, 1.0); > slots.call(color); Signals in DlangUI: https://github.com/buggins/dlangui/blob/master/src/dlangui/core/signals.d |
Copyright © 1999-2021 by the D Language Foundation