digitalmars.D.learn - automatic function call after closing block
- Saaa (6/6) Sep 20 2008 I'd like the following:
- Denis Koroskin (7/13) Sep 20 2008 Yep!
- Saaa (20/26) Sep 20 2008 Ah, that's at least nicer, but I meant that I somehow change texture.bin...
- Sergey Gromov (17/19) Sep 20 2008 You can do something very similar:
- Jarrett Billingsley (25/53) Sep 20 2008 How about a horrible/wonderful misuse of the 'in' operator? (credited
- Saaa (5/29) Sep 20 2008 :D
- Jarrett Billingsley (17/22) Sep 20 2008 No more than any other method that uses delegates; it's just a bit of
- Jarrett Billingsley (7/30) Sep 20 2008 I suppose I should also mention that if you're using D2, delegates
- Sergey Gromov (12/45) Sep 20 2008 As to how it works. The t.bindBlock() in {...} can be rewritten using
- Michel Fortin (19/27) Sep 20 2008 You could create a scope class, bind in the constructor and unbind in
- Saaa (2/29) Sep 20 2008
- Frank Benoit (9/21) Sep 20 2008 void bind( Texture t, void delegate() dg ){
- Saaa (2/2) Sep 20 2008 Delegate it is then.
- Saaa (2/2) Sep 20 2008 These performance questions of mine are more questions in how the mechan...
- Christopher Wright (4/6) Sep 20 2008 Delegate performance should be no worse than virtual method invocation.
- Saaa (1/1) Sep 21 2008 Thanks all!
I'd like the following: texture.bind() //class texture, method bind. { .. } //here texture.unbind would automatically be run. Is this possible?
Sep 20 2008
On Sat, 20 Sep 2008 20:15:17 +0400, Saaa <empty needmail.com> wrote:I'd like the following: texture.bind() //class texture, method bind. { .. } //here texture.unbind would automatically be run. Is this possible?Yep! texture.bind() { scope(exit) texture.unbind() ... }
Sep 20 2008
Ah, that's at least nicer, but I meant that I somehow change texture.bind() to include texture.unbind() class texture { public void bind() { .. underlying scope(exit) texture.unbind() } private void unbind() { .. } } .. texture.bind() { .. } ..Yep! texture.bind() { scope(exit) texture.unbind() ... }
Sep 20 2008
Saaa <empty needmail.com> wrote:Ah, that's at least nicer, but I meant that I somehow change texture.bind() to include texture.unbind()You can do something very similar: class Texture { public void bind(void delegate() body) { // bind a texture here body(); unbind(); } private void unbind() { // unbind the texture here } } texture.bind( { // use the bound texture here } );
Sep 20 2008
On Sat, Sep 20, 2008 at 12:24 PM, Saaa <empty needmail.com> wrote:Ah, that's at least nicer, but I meant that I somehow change texture.bind() to include texture.unbind() class texture { public void bind() { .. underlying scope(exit) texture.unbind() } private void unbind() { .. } } .. texture.bind() { .. } ..How about a horrible/wonderful misuse of the 'in' operator? (credited to Tom S): class Texture { ... struct BindBlock { Texture self; void opIn(void delegate() dg) { self.bind(); scope(exit) self.unbind(); dg(); } } BindBlock bindBlock() { return BindBlock(this); } ... } auto t = new Texture("foo.png"); t.bindBlock() in { // some rendering code! }; It has a nice functional-sounding flair to it, with the 'in' there ;)Yep! texture.bind() { scope(exit) texture.unbind() ... }
Sep 20 2008
:D Looks cool! No way I could have come up with that. Same question (as I have no clue how this internally works): Is there a performance penalty?How about a horrible/wonderful misuse of the 'in' operator? (credited to Tom S): class Texture { ... struct BindBlock { Texture self; void opIn(void delegate() dg) { self.bind(); scope(exit) self.unbind(); dg(); } } BindBlock bindBlock() { return BindBlock(this); } ... } auto t = new Texture("foo.png"); t.bindBlock() in { // some rendering code! }; It has a nice functional-sounding flair to it, with the 'in' there ;)
Sep 20 2008
On Sat, Sep 20, 2008 at 1:48 PM, Saaa <empty needmail.com> wrote::D Looks cool! No way I could have come up with that. Same question (as I have no clue how this internally works): Is there a performance penalty?No more than any other method that uses delegates; it's just a bit of syntax abuse to call a function. Delegates work by passing an implicit context pointer to the nested function as a parameter. Nested functions use a pointer to the stack frame of the enclosing function as the context pointer, so they can access the local variables of the enclosing function. There is a performance penalty for calling delegates just as there is for calling functions through function pointers: it may cause a processor pipeline stall. However with the preponderance of object-oriented programming in which calling virtual methods involves calling functions through pointers, many modern processors have been so heavily optimized for it that the performance difference from hard-coding the function address into the code is negligible. Not nonexistent, but definitely better than it used to be. And besides -- you're calling that delegate once, so it'll be just a constant time overhead.
Sep 20 2008
On Sat, Sep 20, 2008 at 2:40 PM, Jarrett Billingsley <jarrett.billingsley gmail.com> wrote:On Sat, Sep 20, 2008 at 1:48 PM, Saaa <empty needmail.com> wrote:I suppose I should also mention that if you're using D2, delegates will secretly allocate outer functions' local variables on the heap if nested functions access them. There is currently no way in D2 to achieve the efficient D1 behavior of always keeping the stack frame on the stack.:D Looks cool! No way I could have come up with that. Same question (as I have no clue how this internally works): Is there a performance penalty?No more than any other method that uses delegates; it's just a bit of syntax abuse to call a function. Delegates work by passing an implicit context pointer to the nested function as a parameter. Nested functions use a pointer to the stack frame of the enclosing function as the context pointer, so they can access the local variables of the enclosing function. There is a performance penalty for calling delegates just as there is for calling functions through function pointers: it may cause a processor pipeline stall. However with the preponderance of object-oriented programming in which calling virtual methods involves calling functions through pointers, many modern processors have been so heavily optimized for it that the performance difference from hard-coding the function address into the code is negligible. Not nonexistent, but definitely better than it used to be. And besides -- you're calling that delegate once, so it'll be just a constant time overhead.
Sep 20 2008
As to how it works. The t.bindBlock() in {...} can be rewritten using C++-like syntax: void worker() { // some rendering code! } BindBlock bb = t.bindBlock(); bb.opIn(&worker); The code below simply writes all this in one line using a temporary BindBlock structure, an overloaded operator 'in', and an inline anonymous delegate syntax. Saaa <empty needmail.com> wrote::D Looks cool! No way I could have come up with that. Same question (as I have no clue how this internally works): Is there a performance penalty?How about a horrible/wonderful misuse of the 'in' operator? (credited to Tom S): class Texture { ... struct BindBlock { Texture self; void opIn(void delegate() dg) { self.bind(); scope(exit) self.unbind(); dg(); } } BindBlock bindBlock() { return BindBlock(this); } ... } auto t = new Texture("foo.png"); t.bindBlock() in { // some rendering code! };
Sep 20 2008
On 2008-09-20 12:15:17 -0400, "Saaa" <empty needmail.com> said:I'd like the following: texture.bind() //class texture, method bind. { .. } //here texture.unbind would automatically be run. Is this possible?You could create a scope class, bind in the constructor and unbind in the destructor. Something like this: scope class Binding { Texture t; this(Texture t) { this.t = t; t.bind() }; ~this() { t.unbind(); } } then use it like this: { scope b = new Binding(texture); ... // automatic destruction of b; } Perhaps it could be made more elegant in D2 with struct destructors. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Sep 20 2008
Never used/heart of a scope class, thanks! But I'll try the delegate thing first ;)I'd like the following: texture.bind() //class texture, method bind. { .. } //here texture.unbind would automatically be run. Is this possible?You could create a scope class, bind in the constructor and unbind in the destructor. Something like this: scope class Binding { Texture t; this(Texture t) { this.t = t; t.bind() }; ~this() { t.unbind(); } } then use it like this: { scope b = new Binding(texture); ... // automatic destruction of b; } Perhaps it could be made more elegant in D2 with struct destructors. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Sep 20 2008
Saaa schrieb:I'd like the following: texture.bind() //class texture, method bind. { .. } //here texture.unbind would automatically be run. Is this possible?void bind( Texture t, void delegate() dg ){ t.bind(); dg(); t.unbind(); } bind( texture, { ... });
Sep 20 2008
Delegate it is then. Is there any performance penalty when using delegates?
Sep 20 2008
These performance questions of mine are more questions in how the mechanism works than that I worry about the speed.
Sep 20 2008
Saaa wrote:These performance questions of mine are more questions in how the mechanism works than that I worry about the speed.Delegate performance should be no worse than virtual method invocation. You're passing a pointer to a function, whereas virtual method invocation is effectively passing a pointer to a pointer to a function.
Sep 20 2008