Defining event handlers for function, method, or shared method
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Jan 26 11:57:11 PST 2016
On 01/26/2016 11:42 AM, tcak wrote:
>> struct S {
>> void memberFunction() {
>> }
>> }
>> auto s = S();
>>
>> auto memberClosure(ref S s) {
>> return () => s.memberFunction();
>> }
>>
>> events ~= new ConcreteEvent!(() => memberClosure(s),
>> () => writeln("stop"),
>> bar);
>>
>> events.each!(e => e.stop);
>> }
>>
>> Ali
> Hmm. Your example works fine for functions, but I can't pass a method
> instead of function as alias.
That's why I used a closure in the example.
> Check my example:
>
>
> import std.socket;
>
> class EventClass{
> public void eventHandlerMethod(){
> writeln("Barking from method");
> }
> }
>
> class Generator(alias eventHandler){
> public void bark(){
> eventHandler();
> }
> }
>
> public void eventHandlerFunc(){
> writeln("Barking from function");
> }
>
> void main(){
> auto events = new EventClass;
>
> auto gen1 = new Generator!( eventHandlerFunc )();
> auto gen2 = new Generator!( events.eventHandlerMethod )();
As far as I know, just the member function name cannot be used that way.
The problem boils down to how to create a type (or an alias) that will
call a specific member function of a given object.
One way is to have a dedicated type that always call foo():
import std.stdio;
class C {
void foo() {
writeln("foo called");
}
}
class FooCaller {
C c;
this (C c) {
this.c = c;
}
void call() {
c.foo(); // hard-coded to call foo()
}
}
void main() {
auto f = new FooCaller(new C());
f.call();
}
The following one creates a lambda (closure in this case?) that allows
the user to pick which member function to call. Admittedly,
CallableCaller() is not really needed in this example but it
demonstrates how "a member function call on a specific object" can be
passed as an alias template parameter:
import std.stdio;
class C {
void foo() {
writeln("foo called");
}
}
class CallableCaller(alias closure) {
void call() {
closure();
}
}
void main() {
auto c = new C();
auto f = new CallableCaller!(() => c.foo());
f.call();
}
Ali
More information about the Digitalmars-d-learn
mailing list