 Hey everybody, this is Brian. Welcome to the 123rd Qt Tutorial with C++ Inquity Programming. We're going to continue our journey down the Qt Concurrent, or as I like to call it, the Advanced Threading. Today we're going to be covering the map, or I should say blocking map specifically. And there's a difference between map and blocking map. Blocking map, well as the name implies, blocks until the map is complete where map will just begin mapping and immediately turn control over to your program. There's a slight difference, and you should be aware of that before we begin. Also, before we begin, I wanted to touch on a previous tutorial, the previous 122nd Qt Concurrent Run. I do try to keep up on comments, and there's one that I really wanted to point out. Danny77UK, which I think we've talked before, pretty knowledgeable guy, and he actually pointed out a few bugs that I had in there. And while I'm not going to read the whole thing, because it's quite lengthy, but you can go out and read it, and I highly recommend it. And he has some really good points that I'd like to summarize, which is you should create it in a static or a free function, and it should return something. I mean, that's the whole point of a Qt Future is to actually return something, right? Bind, run to the free function, et cetera, et cetera. Don't use member functions because you have raised conditions. So he has a lot of good points, and I highly recommend you go out there and read that. What it's really getting at, though, is that Qt Concurrent is not the catch-all solution for threading. You still have raised conditions, you still have deadlocks, and things of that nature you have to be aware of. I enjoy reading this kind of feedback, because it forces me to dive deeper into the subject and learn more. Alright, speaking of diving in, we're just going to create a new project. Very similar in style to the last one. We're going to call this... Oh, let's get creative and call it Randomizer. And we're going to select a Q dialog. And the premise of this application is your boss comes to you and says, hey, build me an app that generates 100 random numbers. Don't ask why, just do it. And you're like, okay, so we're just going to have a push button and a list widget. Now, you're thinking to yourself, well, random number, but he wants 100 of these things. So you're going to have to build 100 random numbers and then display the result to the end user. That is a little bit of a challenge if you think about the logistics of how to do that. Sure, you could make a for loop, et cetera, et cetera, but we want to get snazzy and we want to use threads. Because we know our boss and the next step is he'll want a thousand random numbers and then 100,000 and you get the point, right? It's going to take time. All right, so first thing we're adding concurrent into our includes. And then we're going to just open up the dialog H, maybe. There we go. That's a little better. Include QDebug. My notes here real quick. Okay. Sometimes after a long day, I just kind of lose track of what I'm actually working on here. I started this new video game called State of Decay. Oh my gosh, that game is just fun. I love it. I could see how it would get old because it's like a zombie game. All right, so we're going to make a static function. It's going to return an int and it's going to be called getNumber. And it's going to take an int. Reference to, we'll call it baseNumber. Not baseNamedNumber. And this is what's going to actually run in the thread, this guy right here. Now if you go back and read Danny's comments about run in static, the reason for that is if you call this, you're actually creating a new instance, et cetera, et cetera. And there's all sorts of other little inconsistencies that happen. So you want the static because remember static means there's one occurrence of this across all instances of your class. That's a mouthful. All right, so we're going to just jump right into the meat of this bad boy here. Actually, no, we're not. Sorry, backup. Like I said, I get a little ahead of myself. We're going to add this into our class. There we go. Very simple, very easy program. But when you think about the logistics of that, typically how would you do this? You need a hundred. So you'd say four I equal blah, blah, blah, blah. Well, we're going to do something similar. We're going to say let's actually flesh out our random code first. We're going to make the high. And we're going to say 100, make the low. We'll call it, let's call it one. And I'm sure there's a billion better ways of doing this, but this is how I do random. We're going to call the Qrand, which generates the random engine. And I'm going to say high plus one minus low and plus low. What that does is gives us a floor and a ceiling and generates a random number in between. Some spaces in there so we don't, some systems are kind of squirrely when it comes to white spaces even in C++. And we can say Qdebug. We're going to randomize the base number and is now going to be the random. And we're going to set that. So if you're paying attention, what we're doing here is we're actually passing this by reference instead of making a copy. And then we're setting it. And if you didn't pay attention during your C++ classes, that's why you would pretty much pass something by reference. So you're not making a copy and that you can implicitly, is that the right word? Implicitly. Anyways, you can basically change that value. If you just make a copy, you'll change the copy but not the actual value itself. Alright, so we've got our random generator there. Very simple, very easy. And just for giggles, I'm just going to add some spaces in there. And then we're going to make our Qlist. Qlisty, I like that. And we're going to give it an int type. We're just going to very explicitly here call it a list. And we're just going to add some garbage data to it. For int i equals zero, i is less than, why not, 100. And you could make another variable, a static variable that has the maximum. Just want to keep this example pretty simple here. And then we're just going to say list append. So all we're doing is we're just adding zero through 99 into that list. Let me actually write that in there. Now, this is what we're going to do. We're going to block until all have completed. Meaning we want to do all of these, 100 of them, at the same time. Pretty wild, huh? We're going to do concurrent. And you notice how you have like block filter, block map, blocking map, stuff like that. You also have the filter map. The difference, of course, is the blocking version will stop execution of your program and wait for all of them to complete. So we'll say blocking map. And we're going to hand it the list. And we're going to give it a reference to the dialogue. And we, of course, want the get number function. And notice how we're passing that by reference. I'm not sure if you actually need to pass that by reference or not. We can try it both ways. I know that this parameter right here is definitely by reference. So we can just look if we mouse over this thing. Yeah, it takes a map function. So it's looking for a member pointer under the hood. Okay. We'll leave it like it is for now. And then we're just going to say UI, list widget, clear. Because we're going to clear out any old results. And then we're just going to add them in here. Update the user interface. Kind of curious what everybody's doing for Christmas this year. I'm probably just going to hang out with the family and play some video games. You can usually find me out on Steam playing different video games. I've been horribly detected to state of decay. It's single player only. And multiplayer I've been playing Dota 2. I've actually bumped into people into Dota. They're like, hey, you know, I've actually seen some of your videos. And then I'm suddenly ashamed because they're much better at the game than I am. All right. So UI, list widget, add item. And then once again, I'm sure there's a more elegant way of doing this. But I just want to keep it very simple and very easy to understand. Queue string number. If anybody out there knows how to do like a queue list and put it directly into a list view. I'd be very interested in that. I actually was looking for that the other day and I just gave up because it was frustrating the hack out of me. I want to best be able to say something like, you know, list dot add list or whatever. You know what I mean. All right. So we're going to add the number and then we're going to do queue string. Hope if I could actually type number. And we're going to say list dot at I. All right. So give us a good build. Make sure this all works. It's always nerve wracking until you see that green line. Sometimes it goes around. I'm like, oh no. All right. So if we run this bad boy, click randomize. See we got a bunch of random numbers. Now sometimes the random engine isn't very random. Like you get a bunch of 14s. But if you click it, you see how it gets more random every time you use it. So for, you know, professional grade, you should call that a few times before you actually use it. But it was interesting to note that there are a lot of 14s because I believe it has something to do with time in memory or something that uses like the Unix time stamp under the hood. I could be like dead wrong about that. But every time you click it, it generates 100 random numbers. Now, let's say we want to check that up to 10,000. This may or may not blow up the application. I don't know. We'll find out. And you see how it's got that big swap. And that's because those are probably the first threads that kick off. So the Q random engines at the same time. But as you click it, you see it gets more and more and more random. It only did, you know, 99, but we can actually close this. Sure. Why not? Let's do that. You know, so it takes slightly longer because we're doing a much larger number, but we get them all in there. So let's discuss what this application is really doing under the hood here. I mean, it's great that we can generate random numbers and all, but you know, it just is random numbers. And like I said, there's probably a better way of doing this. This is just an example. What we're really focusing on is this blocking map. So what we're doing is we're creating what's called a sequence, which I believe just has to be like a Q list or a Q vector. And you fill it with some values. And these values could be integers. It could be strings. It could be, you know, your custom class, whatever. You're passing that it's automatic by reference based on the function call. And then you're passing the member function. I shouldn't say the member function, the function. And it's called the map function, the function you're mapping to. So you're mapping a function to the individual items in this list, meaning that function is going to get called for every single item in this list. In case you, you know, didn't get that through the example. So for zero through 99, it's going to call get number with that number. Let's run this again. And you can see how it's like randomizing that's going through. Now you should know how they're not in order. You notice that right off the bat, 85, 89, 67, dah, dah, dah, dah. And that's because it's kicking them off as the threads in the thread pool underneath are actually available. So you can't really guarantee in what order they're going to get done. But what you can guarantee is that it's random again because it's really bugging me. What you can guarantee is that this will block and it'll stop the execution of your program until it's complete. So you could actually just say que de bug, que de bomb, nice. Wow. Que de bug. There we go. Having one of those days finished. And let's just do the magic of copy and paste started. So it should say started print out a big block of numbers and then say finished. Maybe a better idea of what this is doing under the hood here. See, there's finished. And if we scroll all the way up to the top here where there's a lot of it started and then our random. So that's really what we're doing here. So that in a nutshell is the blocking mapped function. So they blocking map. And map works very similar except for it will not block, meaning you'll call this and execution will immediately jump down here. And we probably cover that in a future tutorial because you got to program a little bit differently for that. You have to use, I believe, a queue future or possibly a queue future watcher or both. I'm still learning a lot of this myself. So we will cover that. Thank you for watching. I hope you found this educational entertaining. Be sure to visit my YouTube channel for this and other tutorials. Also, voidrealms.com, my website where you can find the source code for this and all other tutorials. Just go languages cute. Also my petprojectpluginbot.net. And last but certainly not least we have a Voidrealms Facebook group out there. And we have as of right now 131 people. I just added Emily in there. So welcome aboard Emily. Thanks for watching.