Why bother with the event system, and so on from the very beginning, when you can just start printing a triangle on the screen with glfw and glad and gradually add functionality? It will be more interesting to the viewer and they will get more practical knowledge than to clutter their heads with non-priority things like a event system. All I see in this series is just a trash-talking for the half of a video. But, in any case, unsubbed. Best regards
@@joebravo4224 It needs to be done at some point no matter what. From experience I prefer having most of the side components done, so when the writing of the actual engine starts, I don't have to stop to write something else that's required to continue. You clearly have no ambition to make anything, other than copy-pasting stuff. The point of this series is to actually teach stuff, not just sit here and write some code and be done. "clutter their heads with non-priority things like a event system" - I hate to break it to you, but the engine will just be a lifeless piece of shit without an event system, it wont function in any meaningful way whatsoever. I don't think you've any idea of how any of this works, I suggest you watch the videos so that you can prevent making a fool of yourself in the future.
TheChernoProject Didnt get to watch the video yet, but I wanted to tell you that you missed a perfect opportunity for your video. You could have added 3 red exclamation marks above your head like in Metal Gear Solid when the enemy sees you as the thumbnail image :D
Hello TheCherno, could you please explain to me why do we need a class for EventDispatcher, even though it is just one function essentially? Thank you very much if you answer.
For anyone struggling like me, *(T*)&m_Event casts the m_Event reference from an Event to T. The order of operations is & then (T*) then *. First, &m_Event gets the memory address of of m_Event (now it's type Event*). Second, this Event* gets casted to a T* using (T*) (now it's type T*). Last, this T* gets dereferenced into a T with *(object from second step). Hope this helps.
thx, if anyone's confused as to why we are casting the memory address of the event to a T*, I think its because we want to get the child event of the event , m_Event is an object of type Event but we want to get the child event such as WindowResize
Say you have two unrelated classes: class Mouse { //... }; class Airplane { //... }; Of course it doesn't make sense to turn a Mouse into an Airplane. So casting a Mouse into an Airplane won't work: Mouse m{}; auto a1 = static_cast(m); // won't compile It also won't work for pointers: auto a2 = static_cast(&m); // won't compile This is a feature, not a bug. Casting a type into an unrelated type is undefined behaviour. If it were allowed, it would probably crash the program but it might also keep running with garbage data. That makes for an interesting debugging experience. Doing things like this is typically a bug and the compiler tries to protect you from doing that. Casting a Mouse into an Airpland might be possible in your situation. If so, you can add a converting constructor: class Airplane { public: Airplane (Mouse m) {//....} }; Now the conversion will work: mouse m; auto a = static_cast(m); // compiles now But he goes one step further: he does it in a template. He tries to convert an Event into some type T. The compiler has no way of telling what T is. It might be something that can be created out of an Event. But it might just as well be something like unsigned char. So the compiler won't allow it. But he still wants to do it, because _he_ knows that he will use the template only with types that can be created out of an Event Of course, if by accident he uses the template with a type T that can't be created out of an Event, he's in trouble and it's undefined behaviour. So he uses a dirty hack. In fact, it's two dirty hacks. The first one is that he knows that pointers to any type are essentially the same thing: it's essentially an int filled with a memory address. But the C++ type system still won't let you cast a pointer into a pointer of an unrelated type. So he uses the second dirty hack: C does allow that. The C-cast goes roughshod over the type system and just reinterprrets a pointer to Event into a pointer to T. It can do that, because it knows that both pointers have the same size and layout. So he takes a pointer to Event, uses C to cast that pointer into a pointer to T and then dereferences that pointer into a T. Effectively he has turned an Event into a T. What he could have done: 1- use a concept to restrict T to only those types that are acceptable and create conversions for all those types. Or use a concept that only allows types that are constructable out of an Event (slightly different way of doing it, but boils down to the same behaviour).This will work and it is safe: any "wrong" type wil be caught by the concept and will not compile. But concepts is a C++20 feature and this video was made before 2020. 2- use OO. Make Event the superclass and all eventtypes derived classes. Now use polymorphism to create the correct eventtype. This will work and it is type-safe. Drawbacks are that polymorphism works through pointer indirection (in fact his hack is kind of what polymorphism does under the hood) and it's a runtime mechanism. That implies a runtime performance hit at a very performance-critical bit of code. 3- use a union. Make Event a union of eventtypes. Communicate (through an enum) which eventtype is the present one. Now the user can pick the right eventtype. This is how SFML does it. Drawback: it's not type-safe. If the user takes (by mistake) the wrong union member, it's undefined behaviour. 3- use a variant. std::variant is a fancy union that adds type-safety. If the user takes the wrong variant alternative, it's not undefined behaviour as with a union, but it will throw an exception. But variant is a C++17 feature and I think he uses C++14 for this project.
In this situation, I think the variant approach is by far the best one. It has no runtime cost and it's typesafe. So (this is a simplified example) in a keyboard event you want to communicate the keycode, in a mouse event the button used and the mouse coordinates and in a window resize event the new windowsize. struct Keyboard_event { int keycode; } struct Mouse_event { enum class Button { None, Left, Middle, Right }; Button button; int x; int y; } struct Resize_event { int new_width; int new_height; } struct Event { enum class Type { Keyboard, Mouse, Resize }; using Data = std::variant; // there will be more in real code Type type; Data data; } Now, the type var of Event tells you which event you have, the data var holds the data. Ypu can simply switch on the type. void process_event (Event& ev) { switch (ev.type) { case Event::Type::Keyboard: { // extra block to localise data variable, it has a different type in each branch auto data = std::get(ev.data); // do stuff } break; case Event::Type::Mouse: { auto data = std::get(ev.data); // do stuff; } break; case Event::Type::Resize: { auto data = std::get(ev.data); // do stuff; } break; } } This is type-safe: if for some reason (a bug) the event does not contain a Keyboard_event when type == Event::Type::Keyboard, or if you try to extract another event type than there really is, you will get a bad_variant_access exception. This is easy to spot and debug. There is no undefined behaviour, there is no chance of the program running on with garbage data. I would advice against using this type-punning thing. In modern C++ there is almost always a better way to do it. Most of the time this will be std::variant. I say "almost" because the words "always" and "never" are dangerous: there will probably be some obscure situation that's different.
I prefer the old format, it's much more difficult to follow along this way. Also it's helpful to see you make mistakes because it's likely that many of your viewers will make the same mistake. For example, you changed the premake file but didn't mention this until the end, so either you can't build the project until the end of the video or you have to fix it yourself and possibly diverge from how you did it which could potentially cause problems later down the line from having discrepancies that you forget about.
To be honest I liked previous format much more. In my opinion real-time decision making is something "you want to watch", code reading on the other hand is something that not really require a "host".
totally agree - when you see the reasoning behind some architectual decision you learn it deeper than just when you see it as a final result which you forget within a minute
This is allot harder to follow. I liked the way how your old way was so hans on. I felt like i was there when you wrote the code, and therefore i understood alot more.
At some point you have to force yourself to write using your own noggin, just so you dont have to follow along verbose. Like i slaved over my first REAL program that you type in a std::string - which has an algorithm to sort it and add * signs when you preform multiplication without a sign - remove white spaces - find ')' work back to '(' - etc - etc.. it frucked my head for a long time while i was still learning, and im very glad i forced myself to write it myself. because my brain is now A LOT better and more comfortable with writing triple nested for loops with switch cases that call different functions and move pointers around, in a way i wouldnt be comfortable with if i just followed along.
Nah the new method is slapping. It sqves a lot of time and he gets to explain everything a lot clearer. In the older videos many of the things he did were not even being mentioned.
When I have a stable income (maybe after graduating), I will definitely join your Patreon. What you are doing is simply amazing. Thank so much for everything!
I totally understand the reason why you can't continue with the old format when so many lines of code are needed but by including the live coding segment it helps us to understand better the different decisions you took and not just the final result. There are some nuances that you might not realize are important to mention given your vastly experience as a c++ developer but a for a newcomer might create a lot of struggle. Just as an example, I didn't realize until late that you used a scoped enum only for EventType but an old fashion enum for EventCategory. Trying to use scoped enums as flags in c++ was not as easy for me as in c# where I just need to add a decorator to the enum. Overloading bitwise operators for each enum used as flag didn't seem right to me and had to look for a macro (which also I don't completely like). Anyway, thanks a lot for the series. I'm really learning a lot by following it.
Thanks for the tutorial its really great. However, i prefer watching a 5hour video you typing the code than what you just did. I still appreciate keep up the good job.
For anyone following along. IF you get a warning saying the class needs to have dll interface. Just add the following code to the file where you set your log output text. #pragma warning(push) #pragma warning(disable:4251) ^^^This at the top with the other pragma that is there then below the last share_ptr still within the brackets add #pragma warning(pop) This doesn't fix it, but it makes it so you don't see it in the console while building.
I enjoy the behind scene planning videos as much as the coding ones. That's what make the whole series stand out from most took for granted tutorials. Keep the great work, thank you~
This! Thank you kind sir. This can be fixed by doing HZ_TRACE(e.ToString()) as well instead of HZ_TRACE(e), not sure which one is better (I would say yours though)
@@brichearnaud5314 yup, using e.ToString() would work too, but the whole point of that inline function was to make sure whenever 'e' is logged, it should be treated as 'e.ToString()'.
Would it be possible to just record when you write code (no comment needed) and just upload those as "coding the HAZEL" as its own playlist? Then you can have these explanatory videos where you have these comments. I really like to follow along and code side by side with videos, It takes out the big project feeling that is overwhelming. Otherwise, keep up the good work.
I personally like this format, for the people who say it's hard to follow I definitely see it being harder to follow than him typing out the code. However, I personally believe that this is a better learning format, because it forces you to go back to the material. I watched the episode first, then decided to code everything you showed based solely on what I remembered from the first run and it ended up being a surprisingly good learning experience. There were moments where I got stuck, some I managed to pull through, others I had to go back to the video to refresh my memory.
The new format definitely helps to outline the ideas and implementation more succinctly and efficiently at a high level. I feel, however, this is harder to understand the lower levels, as the learner. When you explain something in this fashion a key piece of information can get missed by the viewer who does not have the concept, or code intricacies, fully mapped in their brain yet (.. me ..). I always find I realize things as I write them and you are describing an idea. This is often in a "Oh, ok. I get why that is like that and it makes sense now" fashion. I think I can still get that from this method, but it's far more cumbersome for the viewer/learner, in my personal opinion. I will probably have to watch this video multiple times to fully get it and copy it. That said, I understand you wanting to keep your sanity and so I am happy to follow however you proceed. If it's more time for me but it benefits the series as a whole the juice may be worth the squeeze. This is amazing work.
I'd prefer the older videos, this seems weird to follow the thought process, had to watch some parts several times due to Speed and scrolling. Just my thoughts, really liked the old style
If you're following along in linux or using a different compiler than the one in Visual Studio, remove the concatenation of the first line of the EVENT_CLASS_TYPE. Instead of return EventType::##type; it's return EventType::type;
I'd definitely enjoy longer episodes! That being said, the new format is SIGNIFICANTLY better then the old format. Your ability to explain the systems you've written are so much more concise, and more thorough. My only two remarks are the following: 1) Potentially putting some sort of class separator in between each class when putting them in the same file (a simple //---------------------------// would be fine) to help the readability a bit more. 2) Writing and demonstrating a more detailed driver. It would have perfected the video to have seen a proper demonstration of your event system and the event dispatcher (even if it was hardcoding the events and such).
I like it more if you type the code in the video because you can learn a lot better how to write a game Engine than if you have typed it offscreen. I think at some point you will have finished the game Engine but still be showing the code you have written years ago
I hope the series will switch back to live coding soon, it's way more difficult (and not fun) to follow in this fashion. I very much prefer to follow while you code and explain. I'll try to follow along with this method, but I'm afraid I will drop out as I don't enjoy this format :(
Unfortunately, this is where the series lost me - I am just not experienced enough and simply keying in great blocks of code doesn't help me much. Cherno's videos are awesome but probably need to go back to something more basic with more step-by-step explanation...
I really liked that coding part because everyone sees what you thought in that moment and which order you chose. Hopping from top to bottom can be really confusing. But I saw that you found a way in between to show some code and still provide some live coding. Thats a good compromise I think.
Thanks, fully understand why you chose this format. As for me I find the commit on github for this video and retype it all myself because when I type things myself I learn it better and I see what I do not fully understand then watch the video with the explanation. This way I get to learn it. I understand why a lot of people prefer the old format, it's basically a lazy way to learn it especially when you are not super comfortable with C/C++ (basically being lazy and I am also lazy but eager to learn).
Great video, a moot point (lost in time) but watching you type the code is better for my own reference. But regardless, these video are pure-gold! Thank you for providing them.
Hey all! If you run into this error: Severity Code Description Project File Line Suppression State Error C2338 don't know how to format the type, include fmt/ostream.h if it provides an operator
This format is much better for people already familiar with programming and c++. If they're not, then they should be watching one of the other series first.
Bro. If I know how to program in C++ I would never touched or watch this game engine series in the first place. Since following along his tutorial is just same as not creating my engine and just become the spectator in this series. And this format is better for anyone that already have enough knowledge in C++ but just want to plagiarism but doesn't have the gut or creativity to create their own engine. Or to lazy to read the book about game engine architecture. But because I have no clue about programming and refer to every line of code that Cherno code to his C++ series, I am able to understand better what software engineer of game engine is and how they make them and subsequently C++ knowledge. So this format is pretty much hindered the progress of small scope of the viewers that have no clue but have motivation to learn C++ through this series.
@@tomatoturtule technically it aint plagarism because its more of a course, you obviously can get inspired by the code, no diff then searching through stack overflow
To explain some bigger process as a overview then this style of explaining is we wanted. We can quickly grasp the architecture and flow of that concept.u saved my time a lot.thanks buddy.keep post something about windows event log apis like eventsubscribe events and how to consume or render events stuffs like that.thankyou
BTW: Diff should be done in the beginning, so people can add those files, make changes without having to just dump the whole commit. I'd like to state the obvious as others have stated from what I can see in the comments. Videos up until now where not about just typing code and taking time, I think most of us don't care how long the videos are anyways. They were about typing code, and seeing what that code does, add some more, and see the outcome. Make a mistake, learn from it. You've taken all of that with this new approach of just explaining written, working code. Up until this video I felt like I learned tons, and felt connected to the project. I understand all this four classes would have taken a long time to write. Don't get me wrong, I still enjoy this video, it just feels way different.
please if you got time, how would you explain it in layman terms to a total beginner? and if you can recommend a book on the similar coding architecture which cherno is ( coding in / following for the hazel project) will really appreciate that.
@@GohersWay Well, to explain it, if you were going to store the event flags as integers such as event 1, event 2, event 3 and so on, each number would be represented as 0000000000000001, 0000000000000010, 0000000000000011, and so on, so if you wanted to say, hey, we have events 1, 2, and 5 this frame, you would have to send three separate integers to the event handler class (or whatever) The way the Cherno did it, you can send it as 0000000000010011 and the event handler will see that there is a 1 in the 0 bit, the 1 bit, and the 4 bit, so it knows that events 0, 1, and 4 are active, (or 1, 2, and 5 if you add 1) With that said, this series is definitely not for beginners. I would recommend either looking at the Cherno's C++ series to start learning some of the basics, or check other places on the internet. I would not really recommend buying a book on it, because you can find a lot of free learning resources on the web. This example is actually very low-level though, (or in other words, slightly more advanced) so typically you don't want to start with topics such as bit fields and flags. If you are not a beginner, but you want to make a game engine and still want a book on it, I'm sorry but you know about as much as I do. I started this series and was following along, but I ended up quitting because the topics covered are very specific and I am planning on going in a different direction as a software engineer.
@@shreksthongg thanks i get the idea now but still dont understand the working of this code any way, i feel like someone should start a tutorial series calling ( following cherno hazel ) the unfamiliarity of coding style is so aparent that its painful. I know, to understand this i have to write smaller examples myself but even though if somehow i able to write some broken code myself it wont be even closer to cherno style of coding, and to adopt this coding style i have to follow a book or some kind of a similar source which go in depth of large project (and coding style/coding patterns )but in a beginner friendly way. Note : I have done engineering in software and trust me, having a degree is useless, just get the cheepest degree from whatever means, literally ( i will let your imagination go wild here , virual online etc ) and also just start working on your final or any big project that you think you will submit / present in the final smester universities are useless unless you find a teacher / friend who is actually genius and can help you with a project like this. So at the end its all about socializing. Sorry for blabbing too much. Thanks again.
@@GohersWay Yeah I've been getting that vibe too. Depending on where you want to work, having a degree might be important, but networking and getting to know people in the industry and doing projects on the side seems to be what's most important. I am in university right now and a lot of what I am learning is very basic and not going to land me a job most likely, which is why I'm trying to focus on side projects, networking, and internships as well as my studies.
I was absolutely loving doing this alongside building a "game" in Unreal for Android. Very insightful for why Unreal does this or that. However I reached this video and stopped. Maybe lost steam from the format change, but honestly I think the size of this undertaking was finally sinking in lol. Still what an amazing series, I hope I can chug along!
repeatCount should definitely be there. Using it, someone can easily delay the repeat from happening or, on your example, gradually increase how fast you're scrolling through the menu
While following this tutorial loosely (using Rust and architecting the engine quite differently), I actually managed to get something pretty generic working. In essence, reflection via Rust's std::any is used to implement an EventManager type (to decouple it from the main application) which has a map of event types to a set of dynamically typed handlers that is queried whenever an event is dispatched. It seems like a fairly elegant model for the event system, only requiring 1 HashMap lookup to get the set of events to loop over, 1 to insert a new event type, 1 to remove an event, 2 to add an event handler, and 2 to remove said handler.
I really liked the old format, but I also like this. Maybe you could record you typing out the code and then make a time lapse of it while you are explaining it.
Here's a thought, record your "offline" coding sessions and, occasionally, stub in a speeded up section of coding with a summary voice-over. It could clarify some sections of code when necessary.
Not a fan of the new format. I'm all for hour-long videos or splitting it into parts, but this took me two hours or so to get down because I was constantly pausing when you had certain classes etc. on screen and copying it down before/after you explain it. It feels to me like it shortens the time/effort it takes to make the video/series, at the expense of the viewer's time, which is a shame because I had been looking forward to this series because your thought process of explaining code as you go is hard to come by and is the reason I subscribed to this channel in the first place.
Best way to follow along is to first watch the video to know what is happening then go to the github repo and open the code for the specific episode and then gloss over the code yourself and try to code it. i dont like this style but this is easier for cherno + much more can be covered this way. dont give hate for this he is giving these tutorials for free
Very nice format, it saves time, and lets us do the typing when pausing :) If I may, an opinion: I don't like too much the fact that the event system seems to have alot of repeating code. Why couldn't we just make function pointers or some sort of delegates like in C# where the client can hook up to any event he/she wants exposed by the app ? Thanks, keep up the good work
New format is better in my opinion. It takes a bit to get used to it but once you do, there is no problem to get the relevant changes from the repo. Then the video itself can focus more on the explanation flow instead of getting stuck at the actual coding.
I would prefer to see you writing the code. The reason is that it's overwhelming when I see all the new code at once. Also seeing the order you wrote the code matters to me. You could just fast forward the physical writing of the code and explain what it does in the same time.
Hey The Cherno, I know I'm a year late to this series but I want to give my feedback here. Videos up to this point were very helpful as a beginner. It was somewhat difficult to switch to this style at first but it actually *forced me to learn* more about git (btw not complaining about learning git, it is so helpful) so that I could go back to the state you had for this episode and learn what you were coding at that time. I do need to learn about diffs still and how to use them effectively. But I still got a similar effect as the early videos by simply typing it all out from your repository then watching the explanation a couple times, checking errors and such. I'm attempting to make a big career change and following this series is helping me learn so much about C++.
Both formats have their ups and downs. The new format is nice in that it takes away the normal mistakes and course corrections of development, letting you just discuss the finished solution. Though it also denies viewers the chance to learn from those course corrections or compile errors.
Actually I'd like you typing all that out much more, however I understand that this would cost you much more time At least the style you present the code should change a bit, maybe border it by darkening the rest surrounding the specific code block or something like that? I find it much harder to follow this way, because your mouse movement is much to quick
this new format pretty much means that we are supposed to copy paste from your github and then just sit here and listen as you talk through it.. idk for me i preferred the old way better but we are at your mercy Cherno and cheers, trying to leave constructive feedback not hating
I'm ok with this new format, but i feel it would be easier to understand if you pasted the code as you speak, that way the episodes would still be short and it would be easier to follow the whole process.
so i guess this could be used for all sorts of communications between different parts of the engine, right? Also for interactions between different objects, such as collisions. Because this seems a little too complicated just for handling input...
Another video down. I keep hoping it will get easier for me, it hasn't. I'm grateful the Cherno makes is good at explaining things like this for people like me. I'm still in this. The Cherno's new way of doing his videos caught me by surprise. I really liked it when he was typing the code as he did the video; typing the code myself as I watched, I can tell it is a burden while typing, teaching and planning at the same time. Besides, he's generous enough to share his knowledge with us, so I shouldn't complain. In another note, the fact that I can keep up means that anyone can do it too, or maybe I don't give myself enough credit. But the more videos I finish and code up, the more confident I become. Don't give up, we've made it this far. I'll see you on the next video's comment section.
Personally I think you should have split this up into two or more videos. The first video would just cover the core of the event system in the old format with just one event. The others would be quick incremental videos introducing extensions and new concepts. I know you don't want this to take ten years but event systems can be quite foreign to some so starting simple and mutating slowly through multiple videos would really help people out. Ideally if broken up the videos might only be 5-15 minutes long but there would just be more of them.
The new format is AMAZING. Please continue to do this. You are able to get through a larger amount of material in a shorter time. This is a great thing.
constexpr is not always Compiletime where as #define runs before the Compiler does anything else replacing all occurrences with the expression. There is no guarantee that constexpr will be performed at Compile time. In this case it almost surely will but you can never really know unless you do some funky stuff with constexpr to trigger a compile error if its not run at compile time.
This format is good for me -- I'm more concerned with the "why's," more with the architecture and its rationale than the specifics. Not everyone may agree, but there are already tons of series on the specifics of rendering and other engine sub-systems.
Hey Jared hope you are well, and if you don't mind may i ask what coding pattern is cherno using and can you recommend a book as well a tutorial which can help me understand this event system, I am having hard time grasping where he started his code and how he gradually updated his code to this event system to make it better why is writing this code like that. I am newbie, I understand the theory behind from his previous video but i don't get the code. Cherno lost me on the bit shift even though I understand the bit shift itself ( obviously i youtube it :D ) but i don't get this even system at all.
I wasn't convinced when you announced it on Twitter, but finally, I am okay with this new format of videos. It can be greater than watching you, tapping code for 1h, explaining every single line you might be righting
Really late to the party, but learning and enjoying a lot anyway. Thank you for this. In Event.h, this static method: #define EVENT_CLASS_TYPE(type) \ static EventType GetStaticType() { return EventType::type; } \ ... could be a public static const instead? const static EventType classEventType = EventType::type; \ A public static const does not violate encapsulation. It's not a bad practice and also avoids a function call. What do you think?
I'm following along and at around 31:00, trying UG_TRACE(e) throws an error: Severity Code Description Project File Line Suppression State Details Error C2079 '_' uses undefined struct 'fmt::v10::detail::type_is_unformattable_for' Umgebung C:\dev\Umgebung\Umgebung\vendor\spdlog\include\spdlog\fmt\bundled\core.h 2593 I'm unsure as to why it worked for Cherno. I was able to get it working by doing UG_TRACE(e.ToString());
Please, we need you to make a video about the events system separately but we want you to make your explanation more simply because it isn't easy to understand.
For EVENT_CLASS_TYPE , i always get the error "identifier "category" undefined". How can I fix the problem and why doesn't Cherno's code have that problem?
It was a good format, but you jumped around a lot when you where explaining the code, stick 1 one file, explain that file, and then move onto the next one
I know the video format was to get more into the episode and to make it easier for you, but it was a lot harder to follow along. At the end of the video i have 3494 errors.
I really prefer this format much more, because I can just listen about the idea and why something is made in a certain way and then I can just look at the code in peace.
Im late to the party by about 2.5 years. I just want to say that something another programming youtuber does (Fireship IO) is he has the full working version, then he deletes things in reverse order (so the last section first first section last) then he ctrl+z the sections back. allows us to see the snippets of code while not waiting for you to type/mistype and can easily explain sections at a time. maybe for future videos this could be an option. I prefer the old video first cause i could follow along and see what was going on as you explained sections. now everytime you scroll i gotta stop the page, copy everything and then wait for you to talk about it so i dont miss out unless i wanna check out the github page.
same thing here, I can complie it but it doesn't show up like in the video and Intellisense also doesn't recognise any of the EventType enums. Are you using VS2019?
Why EventType is "enum class" while EventCategory is "enum" only ? I guess there's a functional difference as if it were a personal preference , both would be same type.
32:55 in terms of clarity, isn't it better practice to prefer MyEnumType::MyEnumValue rather than just MyEnumValue? (line 20 - e.IsInCategory(EventCategoryApplication))
I may be in the minority here, but I liked the new diff review video format. I also hope this new format allows you to remove some bottlenecks in producing the videos so that the engine gets put together more quickly!
Thanks for watching guys, hope you enjoyed the video! Next episode is already available for Patrons on www.patreon.com/posts/23069412 ❤️
Why bother with the event system, and so on from the very beginning, when you can just start printing a triangle on the screen with glfw and glad and gradually add functionality? It will be more interesting to the viewer and they will get more practical knowledge than to clutter their heads with non-priority things like a event system.
All I see in this series is just a trash-talking for the half of a video.
But, in any case, unsubbed.
Best regards
@@joebravo4224 It needs to be done at some point no matter what. From experience I prefer having most of the side components done, so when the writing of the actual engine starts, I don't have to stop to write something else that's required to continue.
You clearly have no ambition to make anything, other than copy-pasting stuff. The point of this series is to actually teach stuff, not just sit here and write some code and be done.
"clutter their heads with non-priority things like a event system" - I hate to break it to you, but the engine will just be a lifeless piece of shit without an event system, it wont function in any meaningful way whatsoever. I don't think you've any idea of how any of this works, I suggest you watch the videos so that you can prevent making a fool of yourself in the future.
TheChernoProject Didnt get to watch the video yet, but I wanted to tell you that you missed a perfect opportunity for your video.
You could have added 3 red exclamation marks above your head like in Metal Gear Solid when the enemy sees you as the thumbnail image :D
This format is nice!
Hello TheCherno, could you please explain to me why do we need a class for EventDispatcher, even though it is just one function essentially? Thank you very much if you answer.
For anyone struggling like me, *(T*)&m_Event casts the m_Event reference from an Event to T.
The order of operations is & then (T*) then *.
First, &m_Event gets the memory address of of m_Event (now it's type Event*).
Second, this Event* gets casted to a T* using (T*) (now it's type T*).
Last, this T* gets dereferenced into a T with *(object from second step).
Hope this helps.
thx, if anyone's confused as to why we are casting the memory address of the event to a T*, I think its because we want to get the child event of the event , m_Event is an object of type Event but we want to get the child event such as WindowResize
Any reason he doesn't use `static_cast(m_Event)` instead of this monstrosity?
Say you have two unrelated classes:
class Mouse
{
//...
};
class Airplane
{
//...
};
Of course it doesn't make sense to turn a Mouse into an Airplane. So casting a Mouse into an Airplane won't work:
Mouse m{};
auto a1 = static_cast(m); // won't compile
It also won't work for pointers:
auto a2 = static_cast(&m); // won't compile
This is a feature, not a bug. Casting a type into an unrelated type is undefined behaviour. If it were allowed, it would probably crash the program but it might also keep running with garbage data. That makes for an interesting debugging experience. Doing things like this is typically a bug and the compiler tries to protect you from doing that.
Casting a Mouse into an Airpland might be possible in your situation. If so, you can add a converting constructor:
class Airplane
{
public:
Airplane (Mouse m) {//....}
};
Now the conversion will work:
mouse m;
auto a = static_cast(m); // compiles now
But he goes one step further: he does it in a template. He tries to convert an Event into some type T. The compiler has no way of telling what T is. It might be something that can be created out of an Event. But it might just as well be something like unsigned char. So the compiler won't allow it.
But he still wants to do it, because _he_ knows that he will use the template only with types that can be created out of an Event Of course, if by accident he uses the template with a type T that can't be created out of an Event, he's in trouble and it's undefined behaviour. So he uses a dirty hack. In fact, it's two dirty hacks. The first one is that he knows that pointers to any type are essentially the same thing: it's essentially an int filled with a memory address. But the C++ type system still won't let you cast a pointer into a pointer of an unrelated type. So he uses the second dirty hack: C does allow that. The C-cast goes roughshod over the type system and just reinterprrets a pointer to Event into a pointer to T. It can do that, because it knows that both pointers have the same size and layout. So he takes a pointer to Event, uses C to cast that pointer into a pointer to T and then dereferences that pointer into a T. Effectively he has turned an Event into a T.
What he could have done:
1- use a concept to restrict T to only those types that are acceptable and create conversions for all those types. Or use a concept that only allows types that are constructable out of an Event (slightly different way of doing it, but boils down to the same behaviour).This will work and it is safe: any "wrong" type wil be caught by the concept and will not compile. But concepts is a C++20 feature and this video was made before 2020.
2- use OO. Make Event the superclass and all eventtypes derived classes. Now use polymorphism to create the correct eventtype. This will work and it is type-safe. Drawbacks are that polymorphism works through pointer indirection (in fact his hack is kind of what polymorphism does under the hood) and it's a runtime mechanism. That implies a runtime performance hit at a very performance-critical bit of code.
3- use a union. Make Event a union of eventtypes. Communicate (through an enum) which eventtype is the present one. Now the user can pick the right eventtype. This is how SFML does it. Drawback: it's not type-safe. If the user takes (by mistake) the wrong union member, it's undefined behaviour.
3- use a variant. std::variant is a fancy union that adds type-safety. If the user takes the wrong variant alternative, it's not undefined behaviour as with a union, but it will throw an exception. But variant is a C++17 feature and I think he uses C++14 for this project.
omg thanks so much!
In this situation, I think the variant approach is by far the best one. It has no runtime cost and it's typesafe. So (this is a simplified example) in a keyboard event you want to communicate the keycode, in a mouse event the button used and the mouse coordinates and in a window resize event the new windowsize.
struct Keyboard_event
{
int keycode;
}
struct Mouse_event
{
enum class Button { None, Left, Middle, Right };
Button button;
int x;
int y;
}
struct Resize_event
{
int new_width;
int new_height;
}
struct Event
{
enum class Type { Keyboard, Mouse, Resize };
using Data = std::variant; // there will be more in real code
Type type;
Data data;
}
Now, the type var of Event tells you which event you have, the data var holds the data. Ypu can simply switch on the type.
void process_event (Event& ev)
{
switch (ev.type)
{
case Event::Type::Keyboard:
{ // extra block to localise data variable, it has a different type in each branch
auto data = std::get(ev.data);
// do stuff
}
break;
case Event::Type::Mouse:
{
auto data = std::get(ev.data);
// do stuff;
}
break;
case Event::Type::Resize:
{
auto data = std::get(ev.data);
// do stuff;
}
break;
}
}
This is type-safe: if for some reason (a bug) the event does not contain a Keyboard_event when type == Event::Type::Keyboard, or if you try to extract another event type than there really is, you will get a bad_variant_access exception. This is easy to spot and debug. There is no undefined behaviour, there is no chance of the program running on with garbage data.
I would advice against using this type-punning thing. In modern C++ there is almost always a better way to do it. Most of the time this will be std::variant. I say "almost" because the words "always" and "never" are dangerous: there will probably be some obscure situation that's different.
I prefer the old format, it's much more difficult to follow along this way. Also it's helpful to see you make mistakes because it's likely that many of your viewers will make the same mistake. For example, you changed the premake file but didn't mention this until the end, so either you can't build the project until the end of the video or you have to fix it yourself and possibly diverge from how you did it which could potentially cause problems later down the line from having discrepancies that you forget about.
To be honest I liked previous format much more. In my opinion real-time decision making is something "you want to watch", code reading on the other hand is something that not really require a "host".
Agreed
i disagree a host for code reading can be quite helpful for walkthrough, thought i do agree the old format is quite a bit more thorough
I'd rather watch longer episodes, even if they hit 1-2 hour marks. you could split them
Watch at .25 speed. You're welcome.
totally agree - when you see the reasoning behind some architectual decision you learn it deeper than just when you see it as a final result which you forget within a minute
This is allot harder to follow. I liked the way how your old way was so hans on. I felt like i was there when you wrote the code, and therefore i understood alot more.
At some point you have to force yourself to write using your own noggin, just so you dont have to follow along verbose.
Like i slaved over my first REAL program that you type in a std::string - which has an algorithm to sort it and add * signs when you preform multiplication without a sign - remove white spaces - find ')' work back to '(' - etc - etc..
it frucked my head for a long time while i was still learning, and im very glad i forced myself to write it myself. because my brain is now A LOT better and more comfortable with writing triple nested for loops with switch cases that call different functions and move pointers around, in a way i wouldnt be comfortable with if i just followed along.
I agree, it was much easier to follow along and learn the old way.. to hear the thought process and actually follow along
Nah the new method is slapping. It sqves a lot of time and he gets to explain everything a lot clearer. In the older videos many of the things he did were not even being mentioned.
@@krupt5995 Hi, a lot has changed in the 3 years i wrote this comment. I am glad his current style suits you and your learning style.
@@sarex33 Did he changed it back to the old one?
I personally prefer watching you write the code - but I don't mind this format!
When I have a stable income (maybe after graduating), I will definitely join your Patreon. What you are doing is simply amazing. Thank so much for everything!
I totally understand the reason why you can't continue with the old format when so many lines of code are needed but by including the live coding segment it helps us to understand better the different decisions you took and not just the final result.
There are some nuances that you might not realize are important to mention given your vastly experience as a c++ developer but a for a newcomer might create a lot of struggle. Just as an example, I didn't realize until late that you used a scoped enum only for EventType but an old fashion enum for EventCategory. Trying to use scoped enums as flags in c++ was not as easy for me as in c# where I just need to add a decorator to the enum. Overloading bitwise operators for each enum used as flag didn't seem right to me and had to look for a macro (which also I don't completely like).
Anyway, thanks a lot for the series. I'm really learning a lot by following it.
Thanks for the tutorial its really great. However, i prefer watching a 5hour video you typing the code than what you just did. I still appreciate keep up the good job.
fact lol
For anyone following along. IF you get a warning saying the class needs to have dll interface. Just add the following code to the file where you set your log output text.
#pragma warning(push)
#pragma warning(disable:4251)
^^^This at the top with the other pragma that is there then below the last share_ptr still within the brackets add
#pragma warning(pop)
This doesn't fix it, but it makes it so you don't see it in the console while building.
I enjoy the behind scene planning videos as much as the coding ones. That's what make the whole series stand out from most took for granted tutorials. Keep the great work, thank you~
This doesn't work for me:
inline std::ostream& operator
This! Thank you kind sir.
This can be fixed by doing HZ_TRACE(e.ToString()) as well instead of HZ_TRACE(e), not sure which one is better (I would say yours though)
@@brichearnaud5314 yup, using e.ToString() would work too, but the whole point of that inline function was to make sure whenever 'e' is logged, it should be treated as 'e.ToString()'.
broo tysm, was actually getting mad at chatGPT for not being able to help me lmao
Thank you so much for this fix, but could you pls explain how this works
thanks
Would it be possible to just record when you write code (no comment needed) and just upload those as "coding the HAZEL" as its own playlist?
Then you can have these explanatory videos where you have these comments.
I really like to follow along and code side by side with videos, It takes out the big project feeling that is overwhelming.
Otherwise, keep up the good work.
this
Did he return to actually coding the engine with us? Im only this far into the series
Best idea here.
@@pxolqopt3597
@@darthvader8469
I personally like this format, for the people who say it's hard to follow I definitely see it being harder to follow than him typing out the code. However, I personally believe that this is a better learning format, because it forces you to go back to the material. I watched the episode first, then decided to code everything you showed based solely on what I remembered from the first run and it ended up being a surprisingly good learning experience. There were moments where I got stuck, some I managed to pull through, others I had to go back to the video to refresh my memory.
I don't mind the new format, it's kinda appealing! It's more streamline, clean, concise-"already tested", but either way love your work!
The new format definitely helps to outline the ideas and implementation more succinctly and efficiently at a high level. I feel, however, this is harder to understand the lower levels, as the learner. When you explain something in this fashion a key piece of information can get missed by the viewer who does not have the concept, or code intricacies, fully mapped in their brain yet (.. me ..). I always find I realize things as I write them and you are describing an idea. This is often in a "Oh, ok. I get why that is like that and it makes sense now" fashion. I think I can still get that from this method, but it's far more cumbersome for the viewer/learner, in my personal opinion. I will probably have to watch this video multiple times to fully get it and copy it. That said, I understand you wanting to keep your sanity and so I am happy to follow however you proceed. If it's more time for me but it benefits the series as a whole the juice may be worth the squeeze. This is amazing work.
I'd prefer the older videos, this seems weird to follow the thought process, had to watch some parts several times due to Speed and scrolling. Just my thoughts, really liked the old style
If you're following along in linux or using a different compiler than the one in Visual Studio, remove the concatenation of the first line of the EVENT_CLASS_TYPE.
Instead of return EventType::##type; it's return EventType::type;
Great, thanks! :)
Yes indeed GCC will understand 2 tokens intead of 3 ;)
Thanks!
Thanks!
@@jovanmaksimovic1191 Thanks! This indeed solved my issue on macOS/M1 using CLion with clang and Intel's icpc.
I'd definitely enjoy longer episodes! That being said, the new format is SIGNIFICANTLY better then the old format. Your ability to explain the systems you've written are so much more concise, and more thorough.
My only two remarks are the following:
1) Potentially putting some sort of class separator in between each class when putting them in the same file (a simple //---------------------------// would be fine) to help the readability a bit more.
2) Writing and demonstrating a more detailed driver. It would have perfected the video to have seen a proper demonstration of your event system and the event dispatcher (even if it was hardcoding the events and such).
I like it more if you type the code in the video because you can learn a lot better how to write a game Engine than if you have typed it offscreen. I think at some point you will have finished the game Engine but still be showing the code you have written years ago
I hope the series will switch back to live coding soon, it's way more difficult (and not fun) to follow in this fashion. I very much prefer to follow while you code and explain. I'll try to follow along with this method, but I'm afraid I will drop out as I don't enjoy this format :(
Unfortunately, this is where the series lost me - I am just not experienced enough and simply keying in great blocks of code doesn't help me much. Cherno's videos are awesome but probably need to go back to something more basic with more step-by-step explanation...
I really liked that coding part because everyone sees what you thought in that moment and which order you chose. Hopping from top to bottom can be really confusing. But I saw that you found a way in between to show some code and still provide some live coding. Thats a good compromise I think.
Thanks, fully understand why you chose this format. As for me I find the commit on github for this video and retype it all myself because when I type things myself I learn it better and I see what I do not fully understand then watch the video with the explanation. This way I get to learn it. I understand why a lot of people prefer the old format, it's basically a lazy way to learn it especially when you are not super comfortable with C/C++ (basically being lazy and I am also lazy but eager to learn).
Great video, a moot point (lost in time) but watching you type the code is better for my own reference. But regardless, these video are pure-gold! Thank you for providing them.
Hey all! If you run into this error:
Severity Code Description Project File Line Suppression State
Error C2338 don't know how to format the type, include fmt/ostream.h if it provides an operator
Dear sir, you saved me hours of painstaking headscratchers. Thank you very much!
I did all this but I still have the error why?
@@CKVR_Incorporated Any chance you worked it out?
This format is much better for people already familiar with programming and c++. If they're not, then they should be watching one of the other series first.
Bro. If I know how to program in C++ I would never touched or watch this game engine series in the first place. Since following along his tutorial is just same as not creating my engine and just become the spectator in this series. And this format is better for anyone that already have enough knowledge in C++ but just want to plagiarism but doesn't have the gut or creativity to create their own engine. Or to lazy to read the book about game engine architecture.
But because I have no clue about programming and refer to every line of code that Cherno code to his C++ series, I am able to understand better what software engineer of game engine is and how they make them and subsequently C++ knowledge. So this format is pretty much hindered the progress of small scope of the viewers that have no clue but have motivation to learn C++ through this series.
@@tomatoturtule nobodys gonna read 1000 pages of a book for this lol
@@mazazaza11 You are. First sentence is enough to get the attention.
@@tomatoturtule technically it aint plagarism because its more of a course, you obviously can get inspired by the code, no diff then searching through stack overflow
To explain some bigger process as a overview then this style of explaining is we wanted. We can quickly grasp the architecture and flow of that concept.u saved my time a lot.thanks buddy.keep post something about windows event log apis like eventsubscribe events and how to consume or render events stuffs like that.thankyou
last time I was this early, GTX 20 series were actually a promising upgrade!
BTW: Diff should be done in the beginning, so people can add those files, make changes without having to just dump the whole commit.
I'd like to state the obvious as others have stated from what I can see in the comments. Videos up until now where not about just typing code and taking time, I think most of us don't care how long the videos are anyways. They were about typing code, and seeing what that code does, add some more, and see the outcome. Make a mistake, learn from it. You've taken all of that with this new approach of just explaining written, working code. Up until this video I felt like I learned tons, and felt connected to the project. I understand all this four classes would have taken a long time to write.
Don't get me wrong, I still enjoy this video, it just feels way different.
that bit field thing is genius. I wouldn't have thought of doing it that way
please if you got time, how would you explain it in layman terms to a total beginner? and if you can recommend a book on the similar coding architecture which cherno is ( coding in / following for the hazel project) will really appreciate that.
@@GohersWay Well, to explain it, if you were going to store the event flags as integers such as event 1, event 2, event 3 and so on, each number would be represented as 0000000000000001, 0000000000000010, 0000000000000011, and so on, so if you wanted to say, hey, we have events 1, 2, and 5 this frame, you would have to send three separate integers to the event handler class (or whatever) The way the Cherno did it, you can send it as 0000000000010011 and the event handler will see that there is a 1 in the 0 bit, the 1 bit, and the 4 bit, so it knows that events 0, 1, and 4 are active, (or 1, 2, and 5 if you add 1)
With that said, this series is definitely not for beginners. I would recommend either looking at the Cherno's C++ series to start learning some of the basics, or check other places on the internet. I would not really recommend buying a book on it, because you can find a lot of free learning resources on the web. This example is actually very low-level though, (or in other words, slightly more advanced) so typically you don't want to start with topics such as bit fields and flags.
If you are not a beginner, but you want to make a game engine and still want a book on it, I'm sorry but you know about as much as I do. I started this series and was following along, but I ended up quitting because the topics covered are very specific and I am planning on going in a different direction as a software engineer.
@@shreksthongg thanks i get the idea now but still dont understand the working of this code any way, i feel like someone should start a tutorial series calling ( following cherno hazel ) the unfamiliarity of coding style is so aparent that its painful. I know, to understand this i have to write smaller examples myself but even though if somehow i able to write some broken code myself it wont be even closer to cherno style of coding, and to adopt this coding style i have to follow a book or some kind of a similar source which go in depth of large project (and coding style/coding patterns )but in a beginner friendly way. Note : I have done engineering in software and trust me, having a degree is useless, just get the cheepest degree from whatever means, literally ( i will let your imagination go wild here , virual online etc ) and also just start working on your final or any big project that you think you will submit / present in the final smester universities are useless unless you find a teacher / friend who is actually genius and can help you with a project like this. So at the end its all about socializing. Sorry for blabbing too much. Thanks again.
@@GohersWay Yeah I've been getting that vibe too. Depending on where you want to work, having a degree might be important, but networking and getting to know people in the industry and doing projects on the side seems to be what's most important.
I am in university right now and a lot of what I am learning is very basic and not going to land me a job most likely, which is why I'm trying to focus on side projects, networking, and internships as well as my studies.
I was absolutely loving doing this alongside building a "game" in Unreal for Android.
Very insightful for why Unreal does this or that.
However I reached this video and stopped.
Maybe lost steam from the format change, but honestly I think the size of this undertaking was finally sinking in lol.
Still what an amazing series, I hope I can chug along!
repeatCount should definitely be there. Using it, someone can easily delay the repeat from happening or, on your example, gradually increase how fast you're scrolling through the menu
Love the new format mate, this series is the bomb
Cherno - Turning aspirations into professions!
I really like this format! Since I’m a few years behind I’ll be interesting to see which format prevailed lol
While following this tutorial loosely (using Rust and architecting the engine quite differently), I actually managed to get something pretty generic working. In essence, reflection via Rust's std::any is used to implement an EventManager type (to decouple it from the main application) which has a map of event types to a set of dynamically typed handlers that is queried whenever an event is dispatched. It seems like a fairly elegant model for the event system, only requiring 1 HashMap lookup to get the set of events to loop over, 1 to insert a new event type, 1 to remove an event, 2 to add an event handler, and 2 to remove said handler.
I really liked the old format, but I also like this. Maybe you could record you typing out the code and then make a time lapse of it while you are explaining it.
Watching you write the code is much better.
Here's a thought, record your "offline" coding sessions and, occasionally, stub in a speeded up section of coding with a summary voice-over. It could clarify some sections of code when necessary.
That would be amazing if he could do that! But I'm concerned that may be asking too much. I can't imagine anything more ideal for the student though.
Great, keep the videos coming :)
Maybe it’s time to make that emun class video in the c++ series
Not a fan of the new format. I'm all for hour-long videos or splitting it into parts, but this took me two hours or so to get down because I was constantly pausing when you had certain classes etc. on screen and copying it down before/after you explain it. It feels to me like it shortens the time/effort it takes to make the video/series, at the expense of the viewer's time, which is a shame because I had been looking forward to this series because your thought process of explaining code as you go is hard to come by and is the reason I subscribed to this channel in the first place.
You should use the GitHub repository for that.
@@lisandroCT That's only really useful for troubleshooting - and that's when he remembers to update it when the video comes out.
Best way to follow along is to first watch the video to know what is happening then go to the github repo and open the code for the specific episode and then gloss over the code yourself and try to code it. i dont like this style but this is easier for cherno + much more can be covered this way. dont give hate for this he is giving these tutorials for free
This format that you explain things is ok.
Very nice format, it saves time, and lets us do the typing when pausing :) If I may, an opinion: I don't like too much the fact that the event system seems to have alot of repeating code. Why couldn't we just make function pointers or some sort of delegates like in C# where the client can hook up to any event he/she wants exposed by the app ? Thanks, keep up the good work
New format is better in my opinion.
It takes a bit to get used to it but once you do, there is no problem to get the relevant changes from the repo. Then the video itself can focus more on the explanation flow instead of getting stuck at the actual coding.
just got to watch this series, (a bit too late i know)), absolutely love this format, it's a shame many people in the comments don't
I would prefer to see you writing the code. The reason is that it's overwhelming when I see all the new code at once. Also seeing the order you wrote the code matters to me. You could just fast forward the physical writing of the code and explain what it does in the same time.
Also liked the format as it was before.
You spoiling us with all these uploads
Can't complain pls don't stop
Hey The Cherno, I know I'm a year late to this series but I want to give my feedback here. Videos up to this point were very helpful as a beginner. It was somewhat difficult to switch to this style at first but it actually *forced me to learn* more about git (btw not complaining about learning git, it is so helpful) so that I could go back to the state you had for this episode and learn what you were coding at that time. I do need to learn about diffs still and how to use them effectively. But I still got a similar effect as the early videos by simply typing it all out from your repository then watching the explanation a couple times, checking errors and such. I'm attempting to make a big career change and following this series is helping me learn so much about C++.
Both formats have their ups and downs. The new format is nice in that it takes away the normal mistakes and course corrections of development, letting you just discuss the finished solution. Though it also denies viewers the chance to learn from those course corrections or compile errors.
This format is better than the previous one. Good job!
MouseOver event should be added as well
Actually I'd like you typing all that out much more, however I understand that this would cost you much more time
At least the style you present the code should change a bit, maybe border it by darkening the rest surrounding the specific code block or something like that? I find it much harder to follow this way, because your mouse movement is much to quick
I am getting addicted to your videos.. :)
I really wish you would like in the description to the "previous video" if you are going to say that.
Old format was waaaay better imo. But I still like it and it seems like you enjoy it so there's no problem.
this new format pretty much means that we are supposed to copy paste from your github and then just sit here and listen as you talk through it.. idk for me i preferred the old way better but we are at your mercy Cherno and cheers, trying to leave constructive feedback not hating
I'm ok with this new format, but i feel it would be easier to understand if you pasted the code as you speak, that way the episodes would still be short and it would be easier to follow the whole process.
New video format is great! Much more concise without all the typing and compiling errors if you were to type and explain at the same time.
so i guess this could be used for all sorts of communications between different parts of the engine, right? Also for interactions between different objects, such as collisions. Because this seems a little too complicated just for handling input...
Another video down. I keep hoping it will get easier for me, it hasn't. I'm grateful the Cherno makes is good at explaining things like this for people like me. I'm still in this. The Cherno's new way of doing his videos caught me by surprise. I really liked it when he was typing the code as he did the video; typing the code myself as I watched, I can tell it is a burden while typing, teaching and planning at the same time. Besides, he's generous enough to share his knowledge with us, so I shouldn't complain. In another note, the fact that I can keep up means that anyone can do it too, or maybe I don't give myself enough credit. But the more videos I finish and code up, the more confident I become. Don't give up, we've made it this far. I'll see you on the next video's comment section.
The new way of explaining this makes more sense and is also easier to understand than the old way.
Thanks Cherno.
Personally I think you should have split this up into two or more videos. The first video would just cover the core of the event system in the old format with just one event. The others would be quick incremental videos introducing extensions and new concepts. I know you don't want this to take ten years but event systems can be quite foreign to some so starting simple and mutating slowly through multiple videos would really help people out. Ideally if broken up the videos might only be 5-15 minutes long but there would just be more of them.
I prefer the old style of these videos.
People who agree
👇
The new format is AMAZING. Please continue to do this. You are able to get through a larger amount of material in a shorter time. This is a great thing.
What i really like about your event system is the undefined behaviour when calling delete on a KeyEvent or Event pointer.
Maybe if I watch this a second time I'll understand something lol
would not have done this series up to here if i knew this style chage was going to happen
I don't quite understand the
using EventFn = std::function;
Why is using there and what does the function pointer used for?
Took me a while to figure that out also, look up "Alias Template"
in other words:
"EventFn func" becomes std::function func
I like the new format!
who'd be brave enough to make a game with the trackpad
I'd prefer you type in front of us although I understand the other way is better for explaining things and saves time. :)
Are there any benefits of using #define BIT(x) (1
constexpr is more C++y, also inline is advisable for function declarations, but not in this context ;)
constexpr is not always Compiletime where as #define runs before the Compiler does anything else replacing all occurrences with the expression. There is no guarantee that constexpr will be performed at Compile time. In this case it almost surely will but you can never really know unless you do some funky stuff with constexpr to trigger a compile error if its not run at compile time.
my favourite part is when he says ahem :^)
This format is good for me -- I'm more concerned with the "why's," more with the architecture and its rationale than the specifics. Not everyone may agree, but there are already tons of series on the specifics of rendering and other engine sub-systems.
Hey Jared hope you are well, and if you don't mind may i ask what coding pattern is cherno using and can you recommend a book as well a tutorial which can help me understand this event system, I am having hard time grasping where he started his code and how he gradually updated his code to this event system to make it better why is writing this code like that. I am newbie, I understand the theory behind from his previous video but i don't get the code. Cherno lost me on the bit shift even though I understand the bit shift itself ( obviously i youtube it :D ) but i don't get this even system at all.
Previous format was best. It took 8 hrs for me to implement this whole vdo.
I wasn't convinced when you announced it on Twitter, but finally, I am okay with this new format of videos. It can be greater than watching you, tapping code for 1h, explaining every single line you might be righting
This might get harder to follow but I prefer the new format anyway. It is much more efficient.
Really late to the party, but learning and enjoying a lot anyway. Thank you for this.
In Event.h, this static method:
#define EVENT_CLASS_TYPE(type) \
static EventType GetStaticType() { return EventType::type; } \
... could be a public static const instead?
const static EventType classEventType = EventType::type; \
A public static const does not violate encapsulation. It's not a bad practice and also avoids a function call. What do you think?
I'm following along and at around 31:00, trying UG_TRACE(e) throws an error:
Severity Code Description Project File Line Suppression State Details
Error C2079 '_' uses undefined struct 'fmt::v10::detail::type_is_unformattable_for' Umgebung C:\dev\Umgebung\Umgebung\vendor\spdlog\include\spdlog\fmt\bundled\core.h 2593
I'm unsure as to why it worked for Cherno. I was able to get it working by doing UG_TRACE(e.ToString());
Please, we need you to make a video about the events system separately but we want you to make your explanation more simply because it isn't easy to understand.
i find it very dirty to throw bunch of classes in the same file - i'd prefer 1 file per class/struct so that the object naming matches the file system
that will make the files very cluttery. U have 26 files just for events. U have to also include them.
For EVENT_CLASS_TYPE , i always get the error "identifier "category" undefined". How can I fix the problem and why doesn't Cherno's code have that problem?
It was a good format, but you jumped around a lot when you where explaining the code, stick 1 one file, explain that file, and then move onto the next one
I know the video format was to get more into the episode and to make it easier for you, but it was a lot harder to follow along. At the end of the video i have 3494 errors.
I really prefer this format much more, because I can just listen about the idea and why something is made in a certain way and then I can just look at the code in peace.
I like the new format! ;)
Im late to the party by about 2.5 years. I just want to say that something another programming youtuber does (Fireship IO) is he has the full working version, then he deletes things in reverse order (so the last section first first section last) then he ctrl+z the sections back. allows us to see the snippets of code while not waiting for you to type/mistype and can easily explain sections at a time. maybe for future videos this could be an option.
I prefer the old video first cause i could follow along and see what was going on as you explained sections. now everytime you scroll i gotta stop the page, copy everything and then wait for you to talk about it so i dont miss out unless i wanna check out the github page.
thanks
Changes format to reduce video length, still makes a 35 minute video. Never change haha
The EVENT_CLASS_TYPE(type) doesn't work for me, it says the enum class is undefined, I don't really undersand why this happens
same thing here, I can complie it but it doesn't show up like in the video and Intellisense also doesn't recognise any of the EventType enums.
Are you using VS2019?
Why EventType is "enum class" while EventCategory is "enum" only ? I guess there's a functional difference as if it were a personal preference , both would be same type.
so early that the video is still in 360p :(
32:55 in terms of clarity, isn't it better practice to prefer MyEnumType::MyEnumValue rather than just MyEnumValue? (line 20 - e.IsInCategory(EventCategoryApplication))
I don't like to admit it, but I actually liked this format better
I may be in the minority here, but I liked the new diff review video format. I also hope this new format allows you to remove some bottlenecks in producing the videos so that the engine gets put together more quickly!
More difficult than before. Maybe it is due to my poor English.