Difference between revisions of "Intermediate C++ Game Programming Tutorial 25"
(→Tutorial 25 - Bonus) |
(→Tutorial 25 - Bonus) |
||
Line 191: | Line 191: | ||
</div> | </div> | ||
* Defining <code>std::function</code> to hold a pointer to a member function [https://youtu.be/4EZVTNHmojc?t=3m30s 3:30] | * Defining <code>std::function</code> to hold a pointer to a member function [https://youtu.be/4EZVTNHmojc?t=3m30s 3:30] | ||
+ | <div class="mw-collapsible-content"> | ||
:* When you wrap a member function in <code>std::function</code>, the instance becomes the first parameter of the function | :* When you wrap a member function in <code>std::function</code>, the instance becomes the first parameter of the function | ||
:* The syntax: <code>std::function<int(Foo,int)> func = &Foo::SomeMemberFunction;</code> | :* The syntax: <code>std::function<int(Foo,int)> func = &Foo::SomeMemberFunction;</code> | ||
::- (Note, you could also take a Foo object by reference <code>std::function<int(Foo&,int)>...</code> | ::- (Note, you could also take a Foo object by reference <code>std::function<int(Foo&,int)>...</code> | ||
:* And to call: <code>func(foo,2);</code> | :* And to call: <code>func(foo,2);</code> | ||
+ | </div> | ||
* <code>std::bind</code> from the Utilities library adapts function signatures <functional>[https://youtu.be/4EZVTNHmojc?t=5m57s 5:57] | * <code>std::bind</code> from the Utilities library adapts function signatures <functional>[https://youtu.be/4EZVTNHmojc?t=5m57s 5:57] | ||
+ | <div class="mw-collapsible-content"> | ||
:* Works as a sort of adaptor for functions; it allows you to bind values to input parameters | :* Works as a sort of adaptor for functions; it allows you to bind values to input parameters | ||
:* For instance say you have some free functino <code>int Foo(int x)</code> | :* For instance say you have some free functino <code>int Foo(int x)</code> | ||
Line 218: | Line 221: | ||
::- the placeholder ensures that the first parameter of f is forwarded to the first parameter of Thing | ::- the placeholder ensures that the first parameter of f is forwarded to the first parameter of Thing | ||
::- we have "bound", or "adapted" Thing into the function pointer object | ::- we have "bound", or "adapted" Thing into the function pointer object | ||
+ | </div> | ||
* Reference wrappers <code>std::reference_wrapper</code> [https://youtu.be/4EZVTNHmojc?t=10m20s 10:20] | * Reference wrappers <code>std::reference_wrapper</code> [https://youtu.be/4EZVTNHmojc?t=10m20s 10:20] | ||
+ | <div class="mw-collapsible-content"> | ||
:* Note that if you include a variable in the <code>std::bind</code> statement and you want it passed by reference, you need to use <code>std::bind( SomeFunc,std::ref(x) );</code> | :* Note that if you include a variable in the <code>std::bind</code> statement and you want it passed by reference, you need to use <code>std::bind( SomeFunc,std::ref(x) );</code> | ||
+ | </div> | ||
* <code>mem_fn</code> creates a function object out of a pointer to a member [https://youtu.be/4EZVTNHmojc?t=12m12s 12:12] | * <code>mem_fn</code> creates a function object out of a pointer to a member [https://youtu.be/4EZVTNHmojc?t=12m12s 12:12] | ||
+ | <div class="mw-collapsible-content"> | ||
:* Convenience function, lets you rewrite something like: | :* Convenience function, lets you rewrite something like: | ||
::<syntaxhighlight lang="cpp" line> | ::<syntaxhighlight lang="cpp" line> | ||
Line 229: | Line 236: | ||
auto f = std::mem_fn( &Foo::DoublePlus ); | auto f = std::mem_fn( &Foo::DoublePlus ); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | </div> | ||
* Lambda functions can bind much more elegantly [https://youtu.be/4EZVTNHmojc?t=12m36s 12:36] | * Lambda functions can bind much more elegantly [https://youtu.be/4EZVTNHmojc?t=12m36s 12:36] | ||
+ | <div class="mw-collapsible-content"> | ||
:* Binding <code>Thing</code> in the example 2 code boxes above with a lambda: | :* Binding <code>Thing</code> in the example 2 code boxes above with a lambda: | ||
::<syntaxhighlight lang="cpp" line> | ::<syntaxhighlight lang="cpp" line> | ||
Line 235: | Line 244: | ||
g(10); // returns 25 | g(10); // returns 25 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | </div> | |
+ | * WORK-IN-PROGRESS | ||
</div> | </div> | ||
Revision as of 22:30, 16 February 2020
Function pointers allow you to store and change what function is to be called dynamically at runtime. Combine that with containers to have collections of actions/behaviors that can be selected from, and then jam in the power std::function
to allow you to wrap up pretty much any kind of callable thing and bring them together in one container. Groovy.
Contents
[hide]Topics Covered
- Function pointers
- Functionoids
-
std::function
Bonus Video
- Pointers to member functions
- std::bind
- std::mem_fn
- std::reference_wrapper (a little)
- Pointer to static member function (it's the same as for normal funcy bois)
- You can use normal func pointers for lambdas if they do not capture anything
Video Timestamp Index
Tutorial 25
- How to switch on a string? (execute some code based on the string passed to the switch): using Functionoids 0:15
- Introducing Function Pointers 5:13
- Using Function Pointers with a map 7:27
- Alternative route: use
std::function<>
in order to map to lambda functions 9:33
- Example: making a single string switch class 13:01
- Homework assignment: time to face the music 20:06
Tutorial 25 - Bonus
- Pointers to a member function of a class/struct 0:07
- Defining
std::function
to hold a pointer to a member function 3:30
-
std::bind
from the Utilities library adapts function signatures <functional>5:57
- Reference wrappers
std::reference_wrapper
10:20
-
mem_fn
creates a function object out of a pointer to a member 12:12
- Lambda functions can bind much more elegantly 12:36
- WORK-IN-PROGRESS
Tutorial 25 - Solution
Homework Assignment
This homework might wreck your butthole a little, but hopefully not too badly. Anyways, you get the code from the repo, you try and get it to build. The project requires Box2D, but the repo doesn't have it included so you're gonna need to wrangle it yourself. The easiest way to accomplish this is to pull in dependencies into your system with vcpkg. Some of you are probably going to run into some speed bumps at this point getting vcpkg to work on your system, but I recommend powering through and not giving the fuck up, because vcpkg is immensely useful for adding amazing libraries to your projects easily. If you search YouTube, you'll find a video of me showing how to install vcpkg and use it to grab SFML, so that might be a good starting point.
After you get that shit working, the party has just started. Then you need to figure out how the codebase actually works. Use all the tools at your disposal (debugger, Google, Box2D documentation, etc.), and don't get bogged down in unimportant distractions (you don't need to know how the triangle rendering pipeline works to understand the general simulation system, for example).
The actual tasks are, as laid out in the video:
- Implement destruction of boxes when two boxes with the same color trait hit each other
- Implement a box splitting mechanic
- Implement a pattern matching collision event manager based on std::unordered_map (this is the main task that ties into Intermediate 25)
- Use the pattern matching system together with box splitting and other effects to define simulation with various action that occur based on what colors of boxes collide with each other.
Chili will hook you up with a solution video that A) explains the starting codebase in some detail and B) goes over the process of implementing all the the above.
The repo: GitHub