We are now going to take a look at a much more sophisticated implementation of the chain of responsibility
design pattern and what we're going to be building is effectively an event the broker and the vendor
broker is actually a combination of several different patterns so it's suddenly changing responsibility.
But we're also going to be using the observer design pattern and specifically we'll be using the boost
signals to library and we're also going to be using command queery separation which is a separate idea
of splitting the system into commands and queries and this affects the command that design pattern which
you should also take a look at.
But this is kind of a combination demo so it's in the middle of the course but we're going to be putting
lots of things together and hopefully I will go slowly enough for you to understand what is going on.
So first of all let me show you my set of headers the header that we're interested in here is boost
signal still this is a library for implementing events basically So we're going to be sending notifications
of different events to classes.
Now the question is Well why was this relevant to the chain of responsibility what we're going to see
it in just a moment.
But first of all let's actually recreate some of the some of the structures that we've had previously
So let's suppose that we still have this idea of a creature in a game but this time round things are
going to be slightly different because in addition to having a creature We're also going to have every
single creature refer to the game that they are in.
So we're going to have a structure called game and inside the structure Well we'll have something in
here but centrally the game object which is added to every creature as a reference.
Here is a reference to the game.
This is a mediator really.
So this is how we're also covering the mediator design pattern as it happens to be.
Now the one thing the game gives us or the one thing that we're interested in is queries.
We're going to set up a situation where in order to figure out a creature's attack or defense value
you query it and every single other object in the game has a chance to modify the result of that query.
So what we're going to do here is we'll define a signal and a signal is a way of defining an event that
people can subscribe to.
And we're going to have a signal which is going to be a void function which takes at queery reference.
OK so I know it might seem cryptic.
That the queries here.
So what exactly is a query.
Now a query is quite simply an object a query is quite simply a class and it's a class where you get
to request some information about the creature.
So if you want to find out something about the creature you have to provide the creature name you also
have to specify which statistic of the creature you want to find out.
And remember the creature is going to have a heart attack and defense values.
So in attack and defense as well.
And also the name.
So let me actually just generate a constructor for all of this.
Now we go so we're going to have a constructor which initializes basically everything.
So when you query a you need to specify which value you want do you want the attack value or the defense
value.
So I'm going to have a name here called arguments.
Notice I'm using an I'm not an economic class because it's inside the structure already.
So you can query an attack value or a defense value and I'm going to call this argument.
So notice I'm both defining the name and giving it's a member variable name at the same time.
And then of course there's the result of the query.
So some of the query is a creatures attack a name and get one and the one would be written into this
value here.
So once again what are we going to do is we're going to generate a constructor for the query as well
taking the argument the result.
And something seems to be missing here.
Yeah the creature name has to be in here as well.
That's funny that the generator hasn't added it.
But we're going to do it ourselves.
So it is going to be Kohn's Konst string creature name.
And then the other stuff.
So I mean just try to lay it out nicely.
So here we go.
Creature name creature name.
There we go let's do a bit of indentation here just so it looks better.
So this is.
Oh I see what the problem is.
It should be a string.
That's why it wasn't part of the generator.
OK.
So we have this setup now and what we can do is we can actually support this idea of queering.
So here's the idea.
Essentially when you want to query something from the game you take the signal.
The signal here and you give it a query and you invoke it and the query goes through every single subscriber
on that signal.
And every single subscriber can actually do something with a query like for example they can perform
a modification.
So the creature modify that we built in the previous lecture is the one that you would apply to change
the result.
And we're going to see how this is done in a moment but it doesn't lead to certain complications one
of the complications is you'll notice the attack and defense values are private.
They are baseline values but when you want an actual attack you with all the modifiers applied you would
have to have a getter you would have to have some sort of get attack.
And here is where you would actually perform the query.
So how do you perform the query.
Well let's suppose we want to find the exact value of the ticket.
Krishna what we do is make a query called.
And here we specify the name of the creature we want to query.
We specify the argument that we actually won so we can for example specify query arguments attack because
we're interested in the attack of value and we can also specify the initial value which might be modified
later on.
So the initial value happens to be the attack value before any kind of modifiers are applied to it.
So this is how you would set up the original process and then what you would do is you would take the
signal that we have in our mediator which is the game.
So here we have queries and you would invoke the signal.
So you would essentially say game Daut queries game queries and you would invoke it with the current
query.
So this is how it goes.
And after you're done you have the query result and you return that result to whoever's interested.
OK so this might seem particularly complicated let's actually generate a two string implementation as
well.
So I'm going to get that string output operator.
Obviously we don't need the game.
I don't think so.
First of all yeah let's do this again.
So stream output.
Operator we don't need the game we just need to attack the fence and name and remember that the attack
is actually only acquired through a get attack.
So we're going to have to get attack in here and I'm actually going to ignore the defense value just
because well it's too much for us and I don't want to go into them and get the while it's fairly obvious
how to implement this anyway.
So now that we've got this set up we can start thinking about creature modifies again.
So a creature modifier is also something that references our mediator which is our event broke the game
object and it provides sudden functionality specifically what the modified does is it subscribes to
the queries because it wants to modify a creature whenever the creature is affected somehow.
So here we go.
Here is how it's going to look like.
So Clauss creature modifier and we have a reference to the game and we also have a reference to the
creature that we're actually modifying.
Now we go.
So what are we going to have in the public section.
Well we're going to have a constructor
where we're going to have both game and creature We're going to require all inheritors to have this
constructor and that's pretty much it.
We can have a virtual destructor for example.
That's a good thing.
It's just the default implementation here.
But that's pretty much all that we want.
So now through one let's say you will want to double the creature's attack using this event Broecker
approach.
So what we would do is we would make a double attack modifier which would be a creature modifier.
And here we would do the following.
So we're going to have a constructor which takes both the game and the creature in fact where we have
to have such a constructor.
So I'm going to implement functions.
Well actually interesting enough it's not a function let's do it like this.
Create the constructor which matches the base class constructor.
I mean do a line break in here.
OK so this is our constructor but inside the constructor what we want to do is we want to actually start
using the gain queries so that we can handle the situation whenever somebody asks for the attack value.
So what I'm going to do is I'm going to say game queries.
So that is our signal and we're going to connect to the signal and I'm going to provide a lambda function
which takes a query and notice it's not a query because we're going to modify its result.
So what we want to do is we want to check whether or not we need to apply the doubling of the attack
in this particular case.
So to do this we first of all need to check that the name of the query the name of the creature in the
query actually matches the name of the creature we are attached to.
So we say if you dog the creature creature in the game is equal to creature dog name.
So that's one requirement.
Another requirement is we need to make sure that somebody is queering the attack value and not the defense
value for example so we say Kuder argument is equal to query argument attack.
And if both of these conditions hold them we can double the attack value we can say.
You don't result multiply equals 2.
So we take the intermediate value inside the query and we double it.
And that's pretty much it.
So any time when this happens we actually want to perform the modification.
Now this connection to the signal is something that we can save we can save it to a variable and the
type of the variable is connection and the upside of this is that we can now make a destructor and we
can unsubscribe in the destructor.
So here I can make a destructor
and here what I can do is I can take that connection and say disconnect though again.
OK so this implementation of the double attack by her allows us to apply the modify it temporarily so
we can see how this works so I'm going to make a game obviously and I'm going to make a creature once
again it's going to be a goblin.
And this time round I need to provide a reference to the game and I'm going to call this a strong Goblin
and we'll have a two hour attack into the fans kind of creature.
OK so now that we have this and I'm kind of surprised it's underlining in red here.
Let me just verify that the goblin constructor is.
Oh yeah.
Yeah the name went as the last argument.
Bizarrely enough so let's stick that the last argument.
OK so strong Goldbloom there we go.
So you want to do is we want to first of all print the goblin
and then I want to temporarily apply the double attack modifier so I'll pull the curly braces here I
will apply the double attack modifier.
I will printout the goblin again and now print the goblin after we exit the scope because it's interesting
to see the destructor actually unsubscribed from the event and thereby no longer affect the modifications.
So let's run all of this and see what we get.
All right so you can see we're getting the correct results here so we have a strong bloom with a baseline
to 2 and then we apply the double attack modifier so it becomes a 4:2.
And then we Exod. the scope and it goes back to being a two again.