On Thursday, 5 January 2023 at 11:55:33 UTC, thebluepandabear
wrote:
I am using CSFML D bindings and I have created my own sort of
UI library for drawing elements onto the screen.
One of the classes I've created is a `Button` class, which
contains a delegate called `onButtonClick` which is called when
the button is clicked on by the user.
Up until now, everything has worked fine.
I want to add a couple of buttons side by side to represent an
element of a list and assign them each a unique lambda
expression for that particular element in the list, this is the
current code I have:
```D
foreach (BoardSize boardSize; arr) {
Button button = new Button();
button.text = format("%sx%s", boardSize[0], boardSize[1]);
button.onButtonClick = {
eventHandler.settingsWindow_onBoardSizeButtonClick(boardSize);
};
button.onButtonClick();
_boardSizeRow.addChild(button);
}
```
Running this code, I had expected that everything would work
fine. Unfortunately upon running the code, tapping each of the
buttons returned only the largest `boardSize` value, the one
which is gets iterated last.
Note that I am still not totally sure why this is the case. At
first, I was confused, but then I suspected that after the
variable gets sent as a parameter to the
`settingsWindow_onBoardSizeButtonClick` function, it gets
changed again in the next iteration creating a sort of chain
effect -- I may be wrong, but this is my suspicion.
Some of the things I tried was creating a new object each time,
although it didn't work. I might have not done this properly as
I am a beginner to D language. I saw someone else ask a similar
question as to why this is happening but that was for C#, not
D, so it wasn't that much of a use to me.
Help would be appreciated!
Ah, I think you ran into that delegate bug
# 🥲
Try this code in it's place:
```d
foreach (BoardSize boardSize; arr) (){ // notice the brackets
Button button = new Button();
button.text = format("%sx%s", boardSize[0], boardSize[1]);
button.onButtonClick = {
eventHandler.settingsWindow_onBoardSizeButtonClick(boardSize);
};
button.onButtonClick();
_boardSizeRow.addChild(button);
}() // notice the brackets
```
This is not your fault, it's an "optimization" that's being
performed by dmd so that "the user doesn't get surprised" when
they realize that capturing every single variable emitted in a
`foreach` will allocate a new heap closure
Have fun reading this :
https://issues.dlang.org/show_bug.cgi?id=21929