digitalmars.D.learn - Passing a function as an argument to another function : what is this
- Derix (40/40) May 25 2014 Hello everyone,
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (10/35) May 25 2014 I have some documentation here:
- Rikki Cattermole (13/53) May 25 2014 In this case &onDraw is a pointer to a member function aka delegate.
- Gary Willoughby (73/112) May 25 2014 It's basically passing an existing function via a pointer. Notice
Hello everyone, So I'm "Getting Started With Gtkd" [1] and the tuto includes this piece of code : ... DrawingArea da = new DrawingArea(590, 200); da.addOnDraw(&onDraw); layout.put(da, 5, 30); add(layout); // Add the layout to our main window showAll(); } bool onDraw(Context c, Widget w) { //draw things return true; } } and I'm a bit puzzled by the line da.addOnDraw(&onDraw); I'm pretty sure I've met this construct before along with relevant explainations, but I find myself a bit forgetful and in need of a refresher. Hence questions : 1) What is the generic name for this kind construct ? 2) Any hint to some reading about the supporting theory or rationale ? 3) When the onDraw function is actually called, whence does it takes its arguments from ? What is that Context ? Does it float around as some sort of implicit global object ? When was it instanciated ? 4) Is &onDraw a predefined event belonging to the class DrawingArea ? Is the name of the onDraw function thus constrained ? 5) What is the chain of events leading to the "onDraw" event occuring ? I'd guess it's the 'showAll()' line, but by the way where does this 'showAll()' come from ? In the documentation [2], I don't see it as a method belonging to the class DrawingArea. Is it inherited from a superclass ? Thank you for the enlightment ! ------------------------------------------------------------------------------------------------ [1] http://britseyeview.com/software/articles/gsgtkd102.html [2] http://api.gtkd.org/src/gtk/DrawingArea.html
May 25 2014
On 05/25/2014 02:37 AM, Derix wrote:DrawingArea da = new DrawingArea(590, 200); da.addOnDraw(&onDraw); layout.put(da, 5, 30); add(layout); // Add the layout to our main window showAll(); } bool onDraw(Context c, Widget w) { //draw things return true; } } and I'm a bit puzzled by the line da.addOnDraw(&onDraw); I'm pretty sure I've met this construct before along with relevant explainations, but I find myself a bit forgetful and in need of a refresher. Hence questions : 1) What is the generic name for this kind construct ?Function pointer. What you are showing is a "callback function" usage.2) Any hint to some reading about the supporting theory or rationale ?I have some documentation here: http://ddili.org/ders/d.en/lambda.html3) When the onDraw function is actually called, whence does it takes its arguments from ?da.addOnDraw() simply stores the function pointer (onDraw in this case) for later use. Later, it satisfies the call parameters by passing necessary Context and Widget objects that are known at that later time.What is that Context ? Does it float around as some sort of implicit global object ? When was it instanciated ?The library manages those objects. Ali
May 25 2014
On 25/05/2014 9:37 p.m., Derix wrote:Hello everyone, So I'm "Getting Started With Gtkd" [1] and the tuto includes this piece of code : ... DrawingArea da = new DrawingArea(590, 200); da.addOnDraw(&onDraw); layout.put(da, 5, 30); add(layout); // Add the layout to our main window showAll(); } bool onDraw(Context c, Widget w) { //draw things return true; } } and I'm a bit puzzled by the line da.addOnDraw(&onDraw); I'm pretty sure I've met this construct before along with relevant explainations, but I find myself a bit forgetful and in need of a refresher. Hence questions : 1) What is the generic name for this kind construct ?In this case &onDraw is a pointer to a member function aka delegate. There is two types of pointers for code sections, function and delegates. A function is a raw pointer (essentially) and a delegate is a pointer to function + "this" pointer.2) Any hint to some reading about the supporting theory or rationale ? 3) When the onDraw function is actually called, whence does it takes its arguments from ? What is that Context ? Does it float around as some sort of implicit global object ? When was it instanciated ?As I said above, for a delegate, it includes a context pointer. So you can assume the arguments defined by the method, are required to call it. Method decl: bool onDraw(Context c, Widget w) Callable: bool delegate(Context, Widget) myEventFunc = ... bool res = myEventFunc(myContext, myWidget);4) Is &onDraw a predefined event belonging to the class DrawingArea ? Is the name of the onDraw function thus constrained ? 5) What is the chain of events leading to the "onDraw" event occuring ? I'd guess it's the 'showAll()' line, but by the way where does this 'showAll()' come from ? In the documentation [2], I don't see it as a method belonging to the class DrawingArea. Is it inherited from a superclass ? Thank you for the enlightment ! ------------------------------------------------------------------------------------------------ [1] http://britseyeview.com/software/articles/gsgtkd102.html [2] http://api.gtkd.org/src/gtk/DrawingArea.html
May 25 2014
On Sunday, 25 May 2014 at 09:37:46 UTC, Derix wrote:Hello everyone, So I'm "Getting Started With Gtkd" [1] and the tuto includes this piece of code : ... DrawingArea da = new DrawingArea(590, 200); da.addOnDraw(&onDraw); layout.put(da, 5, 30); add(layout); // Add the layout to our main window showAll(); } bool onDraw(Context c, Widget w) { //draw things return true; } } and I'm a bit puzzled by the line da.addOnDraw(&onDraw); I'm pretty sure I've met this construct before along with relevant explainations, but I find myself a bit forgetful and in need of a refresher. Hence questions : 1) What is the generic name for this kind construct ? 2) Any hint to some reading about the supporting theory or rationale ?It's basically passing an existing function via a pointer. Notice the ampersand (&)? That gets the underlying memory location (i.e. pointer). Normal procedural type functions can be passed like this as can methods of classes (if you have access to them). When passing a class method like this it can be referred to as passing a delegate. Delegates internally store another pointer to it's surrounding context. For example, a function can be passed like this: void foo() { // Do something. } bar.addFoo(&foo); Then in the addFoo method foo can be called as if it was a normal function. You can also write the above like this: bar.addFoo(function(){ // Do something. }); As function literals are passed via a pointer by default so no ampersand needed. The problem is that normal functions can not refer to anything outside of their scope. For this you need a delegate which contains a context pointer (which is a reference to it's surroundings). Here is an example if using a class method. class Foo { public void bar() { // Do something. } public void baz() { // Refers to bar outside of this method's scope. this.bar(); } } auto foo = new Foo(); // baz can refer to the instance of Foo (it's context) // so it can call bar. qux.addBaz(&foo.baz); You can also use the literal notation too: qux.addBaz(delegate(){ // I can now use things outside this scope. }); Like function literals, delegates are also passed by their pointer by default.3) When the onDraw function is actually called, whence does it takes its arguments from ? What is that Context ? Does it float around as some sort of implicit global object ? When was it instanciated ?When passing functions or methods like this they need to be typed just like anything else you would pass as an argument. Like this: alias void delegate(string) MyCallback; Here we define the signature of a delegate using an alias. Once a method is defined taking this alias as a type then it will only accept a delegate with this signature. class Foo { // Only accept 'void delegate(string)' void bar(MyCallback baz) { // call conforming to the MyCallback signature. baz("hello world"); <-- } } auto foo = new Foo(); // Passed delegate conforms to the MyCallback signature. foo.bar(delegate(string x){ writeln(x); }); Functions are typed the same way: alias void function(string) MyCallback;4) Is &onDraw a predefined event belonging to the class DrawingArea ? Is the name of the onDraw function thus constrained ?onDraw will just be a method that accepts a delegate (or standard function).5) What is the chain of events leading to the "onDraw" event occuring ? I'd guess it's the 'showAll()' line, but by the way where does this 'showAll()' come from ? In the documentationI've no idea you'll have to read the source to find that out.I don't see it as a method belonging to the class DrawingArea. Is it inherited from a superclass ?Probably.
May 25 2014