Hey look guys my name is China welcome
back to my game engine series so last
time we took a look at setting up remake
for up on a build system our project
generation system make sure you check
out that video if you haven't already
and today we're gonna have a good old
fashioned kind of planning session in
which we plan what we're going to do
next which is going to be to kind of
create an event system for our engine so
that we can deal with window events that
we will have to receive questions you
know the window being closed the window
being resized input events such as Mouse
events of keyboard events whenever stuff
like that happens in our engine we want
our application to kind of become aware
of it and have a chance to handle it and
just basically have hazal be aware that
things are happening to it so that's
what today is going to kind of be about
first of all I just want to thank all
the patrons that make this series
possible if you guys aren't supporting
the series you can go to
patreon.com/scishow the Cherno you'll
get these videos one week early as well
as access to a private development broth
brunch in which everything we're going
to talk about today and many episodes in
the future is already written and
obviously it just helps the board the
series and that's why these videos are
here for everyone else so huge thank you
to everyone as always okay so event
systems let's talk about this this is
one of my favorite things to write just
because it's it's quite the way it links
together is quite satisfying and it's
just it's just something that does need
to be done sometime like in the past I
used to maybe write like a whole Windows
system first and then deal with events
but it's just there's no point in doing
that you might as well get the event
system done so that when you get get to
the point of actually writing your
window you can already kind of dispatch
all your events and everything will just
work and everything is gonna be great
because kind of you can write it with no
system an entire renderer without even
dealing with events at all but then as
soon as you start saying that I want a
camera that I can move around using the
mouse and keyboard or whatever you start
being like oh well you know to do this
properly I have to spend like a while
now writing a whole event system so
we're gonna get all that out of the way
kind of immediately so that would then
when we actually do build up a window we
can deal with everything really easily
so I'm gonna go to the drawing board and
see exactly how all this is going to
together okay so at the moment we have
something it's called an application
this is that kind of application class
which is kind of like our central really
class for a lot of things I mean
primarily this is kind of a
representation of our actual hazal
application like in terms of important
things it contains I mean the run loop
is probably one of the biggest things
which means that essentially it contains
the loop that keeps everything running
and keeps updating kind of our game all
the time but also this being the central
kind of hub for things it also needs to
be able to receive events so that
dispatch them eventually to something
called a layer two all the layers in our
games now layers are something that
we'll talk about in the future so I
won't mention them too much because
we'll have a separate video on that and
also they're not really a hundred
percent required by this cope of what
we're gonna be implementing in terms of
this event system so they're just
summing for the future but just know
that kind of the application will
eventually propagate events to layers so
that they can kind of deal with that
sort in terms of our application there
we have an application this needs to be
able to receive events so how does all
of that work well since both since we're
specifically talking about window events
let's kind of draw a little window klass
that we might have here and then see how
that communication is going to work so
our window class is a representation of
our actual window that kind of makes up
our application so this is literally
like you know windows kind of window
with a Kotaro bar and like you know we
might have like the triangle rendering
and all that stuff over here and every
time we receive events in this window
whether it be kind of the fact that a
resize has taken place someone's hit the
close button we have kind of mouse move
events or whatever and all that stuff
whenever that stuff happens and you know
keyboard events whatever all that when
all that stuff happens our kind of
windowing library or just the win32 API
or whatever we're using will receive an
event and then once that event happens
inside that window class we need a way
of communicating that back to
application but guess what we don't
actually want to tie our application
to the window class so the winter class
should not be aware of our application
class at all the application class kind
of creates a winter right so it's
clearly kind of aware of that right but
I don't want the winter class actually
having any knowledge of application
that's not really a link that should
exist so what we need to do actually is
create some kind of method for kind of
messaging back all of these events to
the application to the application can
kind of deal with them and because the
application creates a window it has the
ability obviously to kind of set up all
of that kind of messaging system so long
story short this is what happens when an
event occurs inside our actual window
this window class will receive an event
callback right and then what it has to
do is construct essentially a hazal
event and then somehow propagated back
to application okay
so let's talk about the details of that
so first of all hazel event right what
do we need well we need some kind of
event class right an event system really
which contains all the details required
by an event that has occurred so a mouse
click right I've just moved my mouse and
I've clicked it over here what kind of
information do we need well we
definitely need kind of the X&Y position
of that click as well as which button
was pressed right and then what we can
do with that information is create
something called a mouse button pressed
event which I'm definitely going to
write out but we create a mouse button
pressed event right which is essentially
just a struct which contains this
position and this button and once we've
created that which is kind of our own
custom data type we need a way to
actually send that data over to
application so that so we kind of
everything kind of ties back to that
link and how it works well we don't want
window to actually hold like an
application point or something like that
but instead what we want to do is
essentially give the opportunity for
this application to provide window with
a callback now this could be something
as simple as just a function pointer in
fact we kind of deal with that first to
begin with and then we can
more abstract ways of deftly dealing
with this but essentially what happens
is when we create a window from our
application class we're also going to
create we're also going to set a
callback to that window class an event
callback so that every time this window
gets an event it can check to see if the
callback is present rights of the
callback isn't null and if the callback
isn't null is going to call the callback
with this event data okay and then since
basically application will have a
function called on event which might you
know take in something like an event
reference right it's going to call this
function from window okay so window
doesn't actually know about application
but if we set a callback window does
know about this function and so window
will call this function with this kind
of data in a suddenly application which
has a non event function and own event
method on itself right this will get
cold
with all the event data now this is kind
of something known as like a blocking
event so the reason that kind of is the
case is because you know when we do
receive that Mouse event that mouse
button pressed event we construct it
probably on the stack right there and
then we immediately call this function
so it's not it kind of you know pauses
all the other events while we deal with
this event and so that's why it's kind
of called a blocking event now in the
future you could create something like a
buffered event system which basically
says that it kind of you know grabs this
information queues it stores the data
elsewhere
proceeds to other events and then maybe
once per frame we kind of go through
that queue of events like an event here
and we just kind of dispatch and handle
all of them there instead of doing it
immediately upon receiving the event but
I find it as something that doesn't
necessarily need to be implemented
straight away in an engine we can kind
of just deal with this and this is a lot
simpler so if we do kind of that that is
maybe something to explore in the future
when things get a little bit more
complicated and we want a
little bit more control about I'm kind
of you know how our our engine flows and
do not just block the whole edge and
every time in event occurs until it's
been fully handled by everything in our
application so like a Buffett event you
may end up being a better idea in the
future but for now this is totally fine
okay so now if it's received that it can
kind of dispatch the event to anything
that requires it so for example you know
we talked about the layer stack that we
had earlier it can kind of propagate
that event down the layer stack so that
all the layers have a chance to kind of
receive that mouse button press event
and handle it and maybe block further
layers from receiving that event if the
need if if need be but that's kind of it
you know our application is now about
aware of an event that's occurred from
our window just by kind of that function
pointer now instead of having like a
function pointer or like an you know STD
function or something like that that we
set on window you could essentially
create like an event listener interface
called like eye event listener or
something and maybe window could have
like an array or some kind of like you
know container of eye event listeners
and then every time an event occurs it
simply goes through that kind of
collection of eye event listeners and
then the calls on event right so
application itself could end up kind of
being you know an eye event listener
because it listens to events as would
you know all the layers and so because
it kind of needs to implement that
interface
it would then implement on event and
then set itself kind of as an event
listener to window which might have you
know event
listen you know just like an array of
them or whatever and then this would
kind of go through all the event
listeners and actually call their own
event function so you could do something
like that it's a little bit more
abstract a little bit more kind of
high-level I guess and just having like
sed function or like a raw function
point or something like that but that
kind of gets the job done
it doesn't matter those are kind of all
implementation details so in terms of
what we actually have to do right now
then what we need to do before this kind
of window even exists is we probably
need to make something called
I event listener we need to make this
whole kind of event system so we
actually need to create all the data we
need for events so every type of event
you know we'll have like a base event
type and then every type of event of
event will kind of you know stem stem
down from there essentially so we'll
have all about window events like a
resize and close will have all of our
input advanced mouse button pressed
mouse moved key pressed key released
that kind of stuff and then we could
also have actual application events if
we wanted to so for example application
and these originate from applications so
stuff like run loca vents right so on
update on tick on render all of those
kind of events instead of being just
propagated immediately from the kind of
application class they could actually be
kind of dispatched as events and then
layers could for example listen to on
update or whatever or just just listen
to app update uptick events whatever and
then if they chose them to they could
kind of handle it there so that's this
kind of event system will allow for that
as well but basically what I'm saying is
we need to construct all of the kind of
event classes that we have and then we
also want to have you know certain debug
data as well so for example it may be
like event names and stuff like that we
also want you know event categories so
there's a few different things that we
need to do this kind of becomes a little
bit more complicated we also want
something called an event dispatcher
which basically on this on event class
on this kind of on event function which
contains this kind of event reference we
want to be able to kind of dispatch that
event to maybe a different function
based on its type so we might end up
having something like an on mouse you
know moved function which takes
specifically like a mouse move event or
something like that and then turn right
fast and then kind of what happens is if
this event type ends up being a mouse
move event then we want to automatically
kind of dispatch it to this function
automatically like without having to do
any kind of really heavy code or
whatever right there in the on event
function to find out what the tire pairs
and all that so that can be achieved
fairly simply by just creating kind of
an event dispatcher little class which
is just wraps an event and then just
figures out its type and dispatches it
to a given function pointer if it
matches the right type so things like
that right that's what we need to write
basically
right away and that's what we'll do next
episode now and then from there we'll be
stuck writing our winter class and then
you know who hooked that up with the
event system
and being able to kind of call back to
the application class and then provide
all the event details that we actually
need so that's the plan I think it
sounds pretty good those are kind of our
next steps for hazel okay so that's
pretty much it that's our whole kind of
event system that we have to actually
write along with kind of how we're going
to communicate all those events bash
application and propagate them to our
kind of layer stack yeah I love kind of
writing this stuff should be a little
fun hopefully we can actually squeeze in
all these event types as well as the
application and event lists and stuff
all in one episode we'll see next
episode might end up being quite long
but yeah I hope you guys kind of enjoy
these planning videos it's something
that is the 1% necessary and I think
just kind of talking about what we're
actually going to do instead of just
kind of doing it is really important
because remember this series is kind of
here for you guys to learn not
necessarily to just kind of watch me
write an engine without really saying
much and just you know kind of not
talking about because what I like to
talk about in this series is why I make
the decisions that I do make and kind of
how all this fits together so that you
guys can understand the actual
architecture of an engine and all that
stuff anyway leave your thoughts below
as to what I've kind of described here
in my design keep in mind that you know
none of this is set in stone if someone
says hey you should do it this way you
know we can talk about that we can
discuss that you know you can submit
like a pull request or something for
example maybe too early to do that
nowadays because the repository is quiet
you know bland isn't quite a kind of
bear right now but in the future you
know you can always submit a pull
request and we always discussed that
there's actually been a few already that
we've discussed on the github repository
Luke will be in the different blur um
but yeah we don't always talk about this
stuff and especially in these design
sessions it's a good idea you know in a
real kind of software team what happens
is someone will basically give a little
presentation like I've just done and
then we can
sit around in a group and be like you
know trying to poke holes in it and try
a bit like yeah but what happens in this
scenario what happens in that scenario
you know maybe a better way of doing it
would be this way or have you thought
about being a performance or like client
kind of API requirements or just there's
all this stuff to consider so that's why
these whole design sessions are really
really important anyway hope you guys
enjoy this video if you did you can hit
the like button you can also help spoil
the stories by going to patronymic on
for size the Cherno you'll get the next
video already if you're watching this
live on youtube it's public the next
video is actually already out so you can
already see me implementing all this
stuff right now if you just go on over
to patreon convoy slash the Cherno and
also you'll I mean for the patrons as
well in my private development branch
this whole event system everything I've
described here has been around for like
weeks so you can definitely check that
out if you're interested to kind of
surge ahead in the series and see what's
coming as well as just kind of get all
the code to play around with before it
even kind of gets explained or goes live
I hope to see you guys in that in the
next video we're actually gonna start
implementing the stuffs gonna be really
exciting until then goodbye
[Music]
you
[Music]