digitalmars.D.learn - Copying a variable state in a delegate literal definition
- Andrej Mitrovic (44/44) Sep 02 2011 So I have this code right here (semi-pseudocode) inside a "MenuBar" widg...
- David Nadlinger (8/10) Sep 02 2011 You can try introducing a new frame using a immediately executed
- Steven Schveighoffer (10/55) Sep 02 2011 Am I missing something, or is it this simple?
- Andrej Mitrovic (4/12) Sep 02 2011 Actually It *is* that simple. Which is odd because I swear I've tried
- Daniel Murphy (7/22) Sep 02 2011 It won't work when loops are involved. In that case I usually use:
So I have this code right here (semi-pseudocode) inside a "MenuBar" widget: void showMenu(index menuIndex) { } void appendMenuButton() { static size_t menuIndex; // create menu button, and then: button.connect!(Signal.MouseClick) = { this.showMenu(menuIndex); }; menuIndex++; } button is a newly constructed widget object, Signal is just an enum. Inside of my Widget class I have this: void delegate()[] clickHandlers; property void connect(Signal signal)(void delegate() dg) { static if (signal == Signal.MouseClick) clickHandlers ~= dg; else // ... } void onClicked() { foreach (handler; clickHandlers) { handler(); } } So far so good. This works except for the following quirk: button.connect!(Signal.MouseClick) = { this.showMenu(menuIndex); }; Inside this lambda menuIndex is accessed through that frame pointer when the lambda is called. But I actually want a *copy* of menuIndex at the definition site. Because as I call appendMenuButton() numerous times, menuIndex is increased, so if I do this: menu.appendMenuButton(); menu.appendMenuButton(); { this.showMenu(menuIndex); }; becomes: { this.showMenu(2); }; when it is called. I can't use a function literal instead of a delegate literal because I want to have access to "this.showMenu", but I want a copy of menuIndex. I've tried this: { size_t index = menuIndex; writeln(index); } However that doesn't copy the state either, it initializes index with the menuIndex in the frame pointer when the literal is called. So how can I selectively copy the state of some variables at the site of the definition of a delegate literal?
Sep 02 2011
On 9/2/11 8:29 PM, Andrej Mitrovic wrote:So how can I selectively copy the state of some variables at the site of the definition of a delegate literal?You can try introducing a new frame using a immediately executed delegate literal: button.connect!(Signal.MouseClick) = { auto index = menuIndex; return { this.showMenu(index); }; }(); David
Sep 02 2011
On Fri, 02 Sep 2011 14:29:18 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:So I have this code right here (semi-pseudocode) inside a "MenuBar" widget: void showMenu(index menuIndex) { } void appendMenuButton() { static size_t menuIndex; // create menu button, and then: button.connect!(Signal.MouseClick) = { this.showMenu(menuIndex); }; menuIndex++; } button is a newly constructed widget object, Signal is just an enum. Inside of my Widget class I have this: void delegate()[] clickHandlers; property void connect(Signal signal)(void delegate() dg) { static if (signal == Signal.MouseClick) clickHandlers ~= dg; else // ... } void onClicked() { foreach (handler; clickHandlers) { handler(); } } So far so good. This works except for the following quirk: button.connect!(Signal.MouseClick) = { this.showMenu(menuIndex); }; Inside this lambda menuIndex is accessed through that frame pointer when the lambda is called. But I actually want a *copy* of menuIndex at the definition site. Because as I call appendMenuButton() numerous times, menuIndex is increased, so if I do this: menu.appendMenuButton(); menu.appendMenuButton(); { this.showMenu(menuIndex); }; becomes: { this.showMenu(2); }; when it is called. I can't use a function literal instead of a delegate literal because I want to have access to "this.showMenu", but I want a copy of menuIndex. I've tried this: { size_t index = menuIndex; writeln(index); } However that doesn't copy the state either, it initializes index with the menuIndex in the frame pointer when the literal is called. So how can I selectively copy the state of some variables at the site of the definition of a delegate literal?Am I missing something, or is it this simple? void appendMenuButton() { static size_t menuIndex; auto frameIndex = menuIndex++; button.connect!(Signal.MouseClick) = { this.showMenu(frameIndex); }; } -Steve
Sep 02 2011
On 9/2/11, Steven Schveighoffer <schveiguy yahoo.com> wrote:Am I missing something, or is it this simple? void appendMenuButton() { static size_t menuIndex; auto frameIndex = menuIndex++; button.connect!(Signal.MouseClick) = { this.showMenu(frameIndex); }; } -SteveActually It *is* that simple. Which is odd because I swear I've tried it once but it didn't work, and now it works again. Something has to be messing with the compiler or my brain!
Sep 02 2011
"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message news:mailman.2651.1315000369.14074.digitalmars-d-learn puremagic.com...On 9/2/11, Steven Schveighoffer <schveiguy yahoo.com> wrote:It won't work when loops are involved. In that case I usually use: foreach(i; ...) (int i){ something = { delegate that uses i like a constant }; }(i);Am I missing something, or is it this simple? void appendMenuButton() { static size_t menuIndex; auto frameIndex = menuIndex++; button.connect!(Signal.MouseClick) = { this.showMenu(frameIndex); }; } -SteveActually It *is* that simple. Which is odd because I swear I've tried it once but it didn't work, and now it works again. Something has to be messing with the compiler or my brain!
Sep 02 2011