30:35 ,the usage of words "move " and "undo " was confusing for me, but I translated in my mind as (and that is the output that I would rather see) : "move by x and y" and instead of undo : " move by -x and -y ".
The below would be okay, because we know exactly how much memory to allocate for 'Move'. For 'Command' it's an abstract class, at the top of the error messages, the compiler warns us it does not know how to create a vector of an abstract type. Move m; std::vector test; test.push_back(m);
I've been slowly combing through your C++ playlists, and I've been learning so much! I like your teaching style a lot. Thanks for the great content! Excited to see the channel grow :-)
After rewatching it and as an advice for anyone starting on the topic I would recommend to think about using a range for loop for running the commands, and even though smart pointers are mentioned I think considering type aliases together with the semantics of unique_ptr could be something to take into consideration. (using Commads = unique_ptr --->std::vector instead of std::vector ) great vid once again overall
hardly anybody bothers to give book references. I feel sad when i watch any good video. Its so important to acknowledge the sources of information. Thanks Mike!!
Hey Mike, I really like your videos and the way you explain the general concepts of the different patterns, before taking a deep dive in code examples. Most video covering these kind of topics lack a conceptual overview and rely solely in "explanation by example". I also would be interested to see some approaches how to combine different pattern, because they're often used in combination. Maybe, you would be interested in making a video about this topic some day? :)
So by handing the Character as an argument, you essentially need different command classes for different signatures. If you'd want to have a command queue that could handle different sorts of commands, you'd have to use variadic functions in the Command class, right? Or storing arguments in the command I guess (like with functors) and hand them to the Move class instead of the execute function. Thats probably easier.
Using a variant or indeed using a union with 'commands' would also be another strategy. The polymorphism here has the advantage of type-safety, and restricts us (which may be good) to using just 'execute' and 'undo' -- or otherwise as you have suggested, sending in as a parameter to 'execute' a functor() or std::function to otherwise change behavior further.
Thanks for this serie Mike. Just starting it. Ambition is to code your examples in vlang. Is it correct to say that this pattern is what’s implemented in an event loop, in SDL for instance?
I really enjoy watching your videos. For this pattern, I was curious about parameters. In your Move example, the x and y positions are randomly generated in the execute method, but what if you wanted these values to be specified in the main function? Would they be pass into a Move constructor, or is there a better way to do this?
Correct, the move object itself could have a constructor to populate these values. In this way, you try to keep your classes simple, in that they are again just implementations of 'Command' interface, and you just have to construct the command and push it into the queue :)
Most folks learn the language and build some software first, and then in order to write very efficient/fast software, it is good/necessary to know hardware.
Hi, thanks, great video and nice link for the book. I didn't understood why you couldn't push "Command"'s into the vector but "Command*" was OK but maybe that is another story?
Taking advantage of polymorphic behavior by using 'Command*'. Meaning that anything that 'is-a' 'type of' Command in the inheritance hierarchy, during run-time the correct member functions are called for whatever type of Command* is called.
I have the same question here, why does compiler not allow us to push Command object into the vector, but ok to a Command pointer. Maybe because Command is a pure virtual Class? Also, I got "invalid new-expression of abstract class type ‘Command’" error which is different from "static assertion" in the tutorial when I'm trying it. ( I have no clue of the reason behind it)
@@MikeShah Having command as the base class with everything virtual is to support polymorphism. I may create, say, Teleport, inherited from Command. So at run-time, Command.execute() can be Move.execute() or Teleport.execute(), depending on the run-time context. Please correct me if I am wrong.
Correct, it's not a bad idea to queue up the commands and then execute them. 'Event Queue' or 'polling' are probably the search terms to find out more in other libraries related.
Finally a video that breaks this step by step explaining every little detail, great video
Cheers, you are most welcome!
Enjoyed this, do more! If you had 500+ people in a room listening to you teach you'd feel the power. Views are no different.
Thank you for the kind words! More on the way :)
30:35 ,the usage of words "move " and "undo " was confusing for me, but I translated in my mind as (and that is the output that I would rather see) : "move by x and y" and instead of undo : " move by -x and -y ".
Since the value of the move that is being written is not what is being output(i.e. c.x and c.y), x and y still need to be negated.
I just found your channel and I must say the content is great! Everything really well explained. Thanks for sharing.
Cheers, thank you for the kind words!
Mike, why compiler complained about move being created over stack and pushed over vector? Why is breaking here? 23:07
The below would be okay, because we know exactly how much memory to allocate for 'Move'. For 'Command' it's an abstract class, at the top of the error messages, the compiler warns us it does not know how to create a vector of an abstract type.
Move m;
std::vector test;
test.push_back(m);
I've been slowly combing through your C++ playlists, and I've been learning so much! I like your teaching style a lot. Thanks for the great content! Excited to see the channel grow :-)
Cheers, thank you for the kind words! More to come!
Awesome session sir
Cheers!
After rewatching it and as an advice for anyone starting on the topic I would recommend to think about using a range for loop for running the commands, and even though smart pointers are mentioned I think considering type aliases together with the semantics of unique_ptr could be something to take into consideration. (using Commads = unique_ptr --->std::vector instead of std::vector ) great vid once again overall
hardly anybody bothers to give book references. I feel sad when i watch any good video. Its so important to acknowledge the sources of information. Thanks Mike!!
Cheers! Thank you for the kind words
Another great C++ tutorial video! Thanks for sharing it.
Cheers!
Hey Mike,
I really like your videos and the way you explain the general concepts of the different patterns, before taking a deep dive in code examples. Most video covering these kind of topics lack a conceptual overview and rely solely in "explanation by example". I also would be interested to see some approaches how to combine different pattern, because they're often used in combination. Maybe, you would be interested in making a video about this topic some day? :)
Thank you for the kind words! Noted the request!
What other books are a good reference material book for C++ design patterns such as these to read more about?
You can seek Klaus Uglberger's software design book.
So by handing the Character as an argument, you essentially need different command classes for different signatures.
If you'd want to have a command queue that could handle different sorts of commands, you'd have to use variadic functions in the Command class, right?
Or storing arguments in the command I guess (like with functors) and hand them to the Move class instead of the execute function. Thats probably easier.
Using a variant or indeed using a union with 'commands' would also be another strategy.
The polymorphism here has the advantage of type-safety, and restricts us (which may be good) to using just 'execute' and 'undo' -- or otherwise as you have suggested, sending in as a parameter to 'execute' a functor() or std::function to otherwise change behavior further.
I noticed you didnt do many patterns, just to say this was helpful to me, theres a lot of videos but not loads in c++, particularly in their title
More on the way :) The factory method is next up!
@@MikeShah sometimes you gotta get a load of videos up and the exposure comes later. put the word gaming in your titles lol. or game making.
@@AlbertRyanstein More C++ videos on the way! :) Thanks again for your support!
Thanks for this serie Mike. Just starting it. Ambition is to code your examples in vlang. Is it correct to say that this pattern is what’s implemented in an event loop, in SDL for instance?
Cheers, very cool! SDL probably just uses a union of structs for events, but same idea indeed of pushing events to some queue 🙂
I really enjoy watching your videos. For this pattern, I was curious about parameters. In your Move example, the x and y positions are randomly generated in the execute method, but what if you wanted these values to be specified in the main function? Would they be pass into a Move constructor, or is there a better way to do this?
Correct, the move object itself could have a constructor to populate these values. In this way, you try to keep your classes simple, in that they are again just implementations of 'Command' interface, and you just have to construct the command and push it into the queue :)
Amazing explanation! Thank you
Cheers, thank you for the kind words!
I have a question:Is good to learn first about cpu,ram,hdd,ssd basics and then move to C++?
Most folks learn the language and build some software first, and then in order to write very efficient/fast software, it is good/necessary to know hardware.
@@MikeShah but is a good choice with learnning C++?
@@jeffsad8391 Yes, because C++ is a systems language, it goes well with learning hardware :)
@@MikeShah i m intersted like with software of operating system and AI
@@jeffsad8391 Great, you're in the right place!
Fascinating! Thanks yet again!
Cheers!
Hi, thanks, great video and nice link for the book. I didn't understood why you couldn't push "Command"'s into the vector but "Command*" was OK but maybe that is another story?
Taking advantage of polymorphic behavior by using 'Command*'. Meaning that anything that 'is-a' 'type of' Command in the inheritance hierarchy, during run-time the correct member functions are called for whatever type of Command* is called.
I have the same question here, why does compiler not allow us to push Command object into the vector, but ok to a Command pointer. Maybe because Command is a pure virtual Class?
Also, I got "invalid new-expression of abstract class type ‘Command’" error which is different from "static assertion" in the tutorial when I'm trying it. ( I have no clue of the reason behind it)
It turns out different g++ version result in error difference, thx for the informative lesson
@@MikeShah Having command as the base class with everything virtual is to support polymorphism. I may create, say, Teleport, inherited from Command. So at run-time, Command.execute() can be Move.execute() or Teleport.execute(), depending on the run-time context. Please correct me if I am wrong.
That's the idea!@@_w62_
Robert Nystrom's book is really great
I read it online, then I bought a copy as it truly deserved a place on the bookshelf.
@@MikeShah Has a place on my bookshelf, too ;)
So the Action design pattern would be like a message queue in a way?
Correct, it's not a bad idea to queue up the commands and then execute them. 'Event Queue' or 'polling' are probably the search terms to find out more in other libraries related.
awesome playlist
Cheers! Enjoy!
seem you computer have a little lagging :)