Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: fixed mistakes, removed [&] #859

Merged
merged 25 commits into from
Sep 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f8a3b08
Fixed typo's and added Callback Functions examples
Henonicks Aug 31, 2023
8e7ed3f
Added more explanation to Callback Functions example, removed unneces…
Henonicks Sep 1, 2023
b211d2a
Merge branch 'dev' into dev
Henonicks Sep 1, 2023
426d8bf
Merge branch 'dev' into dev
Henonicks Sep 1, 2023
e712670
Changed all // comments to /* comments */
Henonicks Sep 1, 2023
fdf4148
Fixed some real minor stuff so that the code follows the guide
Henonicks Sep 1, 2023
b316f8d
Fixed more stuff that didn't push
Henonicks Sep 1, 2023
c2439ad
Put the missing quote
Henonicks Sep 1, 2023
e3132d3
Put a missing comma in my example.
Henonicks Sep 1, 2023
4c85c17
In the action is now in action
Henonicks Sep 1, 2023
ef9eaca
callback.get<without a space>, extra line after else-if is gon
Henonicks Sep 1, 2023
93247c8
Merge branch 'brainboxdotcc:dev' into dev
Henonicks Sep 2, 2023
258e9e1
Merge branch 'brainboxdotcc:dev' into dev
Henonicks Sep 4, 2023
4de1dac
Added object editing example
Henonicks Sep 7, 2023
60047ae
Formatted the code that creates slashcommands, replaced std::string w…
Henonicks Sep 7, 2023
7aa248b
Fixing the most embarrasing mistake ever
Henonicks Sep 7, 2023
6497d1b
Renamed the page, changed reference representation
Henonicks Sep 7, 2023
55058ec
Fixed the code block issue that made it think that images are part of…
Henonicks Sep 7, 2023
f8f2608
Plural instead of Channel and Message, const where it can be const
Henonicks Sep 7, 2023
9ef6675
Added a note about bots' inability to edit messages sent by others
Henonicks Sep 7, 2023
defcf43
why didn't i google what plural means
Henonicks Sep 7, 2023
1f4c9c7
Merge branch 'brainboxdotcc:dev' into dev
Henonicks Sep 9, 2023
71305e2
Merge branch 'brainboxdotcc:dev' into dev
Henonicks Sep 16, 2023
27c737b
Removed the [&] in docs, fixed some mistakes
Henonicks Sep 16, 2023
cb2418b
Merge branch 'dev' into dev
Henonicks Sep 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docpages/advanced_reference/lambdas_and_locals.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

If you are reading this page, you have likely been sent here by someone helping you diagnose why your bot is crashing or why seemingly invalid values are being passed into lambdas within your program that uses D++.

It is important to remember that when you put a lambda callback onto a function in D++, that this lambda will execute at some point in the **future**. As with all things in the future and as 80s Sci-Fi movies will tell you, when you reach the future things may well have changed!
It is important to remember that when you put a lambda callback onto a function in D++, that this lambda will execute at some point in the **future**. As with all things in the future and as 80s Sci-Fi movies will tell you, when you reach the future, things may well have changed!

\image html delorean-time-travel.gif

To explain this situation and how it causes issues I'd like you to imagine the age old magic trick, where a magician sets a fine table full of cutlery, pots, pans and wine. He indicates to the audience that this is authentic, then with a whip of his wrist, he whips the tablecloth away, leaving the cutlery and other tableware in place (if he is any good as a magician!)
To explain this situation and how it causes issues, I'd like you to imagine the age-old magic trick, where a magician sets a fine table full of cutlery, pots, pans and wine. He indicates to the audience that this is authentic, then with a whip of his wrist, he whips the tablecloth away, leaving the cutlery and other tableware in place (if he is any good as a magician!)
Henonicks marked this conversation as resolved.
Show resolved Hide resolved

Now imagine the following code scenario. We will describe this code scenario as the magic trick above, in the steps below:

Expand All @@ -31,7 +31,7 @@ In this scenario, the outer event, `on_message_create` is your tablecloth. The l
* Best case scenario: you access invalid RAM no longer owned by your program by trying to write to `myvar`, and [your bot outright crashes horribly](https://www.youtube.com/watch?v=sm8qb2kP-fQ)!
* Worse case scenario: you silently corrupt ram and end up spending days trying to track down a bug that subtly breaks your bot...

The situation I am trying to describe here is one of object and variable ownership. When you call a lambda, **always assume that every non-global reference outside of that lambda will be invalid when the lambda is called**! For any non-global variable always take a **copy** of the variable (not reference, or pointer). Global variables or those declared directly in `main()` are safe to pass as references.
The situation I am trying to describe here is one of object and variable ownership. When you call a lambda, **always assume that every non-global reference outside of that lambda will be invalid when the lambda is called**! For any non-global variable, always take a **copy** of the variable (not reference, or pointer). Global variables or those declared directly in `main()` are safe to pass as references.

For example, if we were to fix the broken code above, we could rewrite it like this:

Expand All @@ -45,12 +45,12 @@ bot.on_message_create([&bot](const dpp::message_create_t & event) {
});
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Note, however that when you set `myvar` within the inner lambda, this does **not effect** the value of the var outside it. Lambdas should be considered self-contained silos, and as they execute in other threads should not be relied upon to set anything that exists **outside of that lambda**.
Note, however that when you set `myvar` within the inner lambda, this does **not affect** the value of the var outside it. Lambdas should be considered self-contained silos, and as they execute in other threads should not be relied upon to set anything that exists **outside of that lambda**.

\warning Always avoid just using `[&]` in a lambda to access all in the scope above. It is unlikely that half of this scope will still even be valid by the time you get a look at it!

Similarly, and important to note, your program **will not wait for bot.message_create to send its message and call its lambda** before continuing on to print `here`. It will instantly insert the request into its queue and bail straight back out (see the steps above) and immediately print the text.

If you do want to get variables out of your lambda, create a class, or call a separate function, and pass what you need into that function from the lambda **by value** or alternatively, you can use `std::bind` to bind a lambda directly to an object's method instead (this is great for modular bots).

If you are stuck, as this is a complex subject please do feel free to ask on the [official support server](https://discord.gg/dpp)!
If you are stuck, as this is a complex subject, please do feel free to ask on the [official support server](https://discord.gg/dpp)!
2 changes: 1 addition & 1 deletion docpages/example_code/cache_messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ int main() {
bot.on_log(dpp::utility::cout_logger());

/* Message handler */
bot.on_message_create([&](const dpp::message_create_t &event) {
bot.on_message_create([&message_cache](const dpp::message_create_t &event) {
/* Make a permanent pointer using new, for each message to be cached */
dpp::message* m = new dpp::message();

Expand Down
2 changes: 1 addition & 1 deletion docpages/example_code/context_menus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ int main()
bot.on_log(dpp::utility::cout_logger());

/* Use the on_user_context_menu event to look for user context menu actions */
bot.on_user_context_menu([&](const dpp::user_context_menu_t& event) {
bot.on_user_context_menu([](const dpp::user_context_menu_t& event) {

/* check if the context menu name is High Five */
if (event.command.get_command_name() == "high five") {
Expand Down
8 changes: 4 additions & 4 deletions docpages/example_code/modal_dialog_interactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ int main(int argc, char const *argv[])
});

/* This event handles form submission for the modal dialog we create above */
bot.on_form_submit([&](const dpp::form_submit_t & event) {
bot.on_form_submit([](const dpp::form_submit_t & event) {

/* For this simple example we know the first element of the first row ([0][0]) is value type string.
* In the real world it may not be safe to make such assumptions!
/* For this simple example, we know the first element of the first row ([0][0]) is value type string.
* In the real world, it may not be safe to make such assumptions!
*/
std::string v = std::get<std::string>(event.components[0].components[0].value);

Expand All @@ -59,7 +59,7 @@ int main(int argc, char const *argv[])
event.reply(m);
});

bot.on_ready([&](const dpp::ready_t & event) {
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a slash command and register it as a global command */
bot.global_command_create(dpp::slashcommand("dialog", "Make a modal dialog box", bot.me.id));
Expand Down
Loading