So in the previous lecture when we did the memento pattern I mentioned that theoretically you could
use the memento pattern as a kind of undo and redo mechanism provided the State of the system whose
actual internals you are saving is particularly small.
Now here we're lucky because the bank account only has a single integer field.
We can certainly save the entire history of the bank account.
So in addition to yielding momentos out of any method we actually provide We can also save the internal
state.
We can save every single memento.
And this solves a lot of interesting problems like for example right now we have a bank account but
there is no way to actually restore it to the initial state to the state where the constructor was called.
And the reason for that is that the constructor isn't allowed to return and memento that kind of makes
sense because the constructor doesn't have a return value apart from the instance of that particular
object.
So what we can do is we can actually store every single memento ever generated inside the bank account
and then allow people to kind of navigate that forwards and backwards and that would be the implementation
of the undo and redo mechanics so let's actually implement this.
So let me get rid of all the demos here and I'm going to make a new bank accounts is going to be bank
account to bank account too.
OK.
So this is going to be a bit more complicated.
So we'll have the balance before starting at zero and we'll also have a vector of changes now because
we're both returning the change we're returning the memento and storing it internally.
I'll start using smart pointers here so I'll have a vector of shared PCR objects vector of shared from
the mento as code changes and I will also have an integer called Current.
Now this is kind of like a pointer to where in the overall timeline we actually are.
So if you undo a few times you want to be able to redo those times.
And so this integer is actually an index into the above changes vector.
So this tells us where we are in terms of the state of the bank account.
So let's make a constructor First of all we'll initialize the balance.
So let me make a constructor which initializes only the balance.
But in addition what we're going to do is we're going to save that Memento So we just change the balance
to an initial value what we'll do is we'll see changes that place back back and will make share a memento
with the current balance.
So we save that particular state and now we said current to zero.
So that is the point.
So right now we're pointing at the zeroth elements in the vector that's where we are at.
Now we're going to have a typical API like for example deposit function.
So here are the deposit function will return a share all from the mento because remember we want to
both store it internally and return at the same time.
So it's going to be called deposit and we'll have the amount here as always and what we're going to
do is we'll obviously increment the amount increment the balance by the amount.
I should say and then we'll make the momentos although he calls make shared the mento
with the balance that we currently have and then we'll add that momentum to the set of changes so changes
they'll push back.
Am will increment the pointer.
The changes point that we have.
And then we return the memento.
So this is how we're going to do it.
Let me just see what's going on here with the changes.
Underlining it there in red.
Oh okay.
So it's not changes it's current as the case may be.
And then we would turn the memento here.
All right so all is good here.
And we also want to have some sort of restore code.
We want to be able to restore the bank accounts with a particular memento So once again we'll have a
function called Restore which takes a concept shared Armento reference called am and what we're going
to do here is first of all we'll check these shared PVR is actually valid so we're going to say it because
it might be possible that you have a memento which is just a default initialized chokepoint or not you
probably want to well hold on.
Why are you going to have this kind of memento.
I'll I'll tell you why it's because sometimes you try to undo something and there is no undo functionality.
So if if you try to undo something you also want to return a memento of the result of that undo.
But if the UNDO didn't happen you were it's own the default construct shared pointer and that's what
we're going to take a look in just a moment so here provided that the momentum is actually valid.
We said the balance.
So we say balance equals imbalance.
And by the way yes for this you have to have a friend classful a bank account to as well that we go.
OK so you set the balance as before and then you also record this particular change so you record the
fact that somebody came in here and set the bank account using the momentos or you say changes don't
back home so you save the memento in the set of changes and then you move the current point.
So the current pointer is changes the size minus 1.
So that's how you actually get the current pointed to point to the very last element in the set of mementos
that we actually store.
OK.
So this is good and we can now implement undo and redo operations and you're going to see why the fourth
constructed chip pointers are a thing at least in this particular scenario.
So we're going to have a shared shared PVR memento returning undo function.
So of course in order to be able to undo something we have to be at least on the first step so the current
2.0 which is an index of where we are on the overall timeline has to be greater than zero.
So if current is greater than zero then we can in fact undo something so we can.
First of all decrements Currans we can get the change at that particular location.
So auto equals changes current.
So we get the previous momentos shall we say.
And then we set the balance from that Memento So we say balance equals and balance and we return that
memento.
So now you have another snapshot of what actually happened when somebody undid something.
So we essentially we just move the pointer one step back.
So the current pointer got moved we took the memento that was pointed to by that previous step and we
restore the balance to whatever was required.
Now if we don't have a possibility of undoing everything return just empty around brackets and this
the fault constructs this shit pithier without any object behind it.
And that's why here we have that statement because here we can return anti-flu constructed head here.
Now let's implement redo in much the same way.
So that's once again going to be a shared BPR and then so called redo.
By the way since I'm using smart pointers I might want to go into herder's and just comment to boost
for now because then I will have to do some big uate one and the other and it's just annoying.
So coming back here once again we have to make sure that we we got something to work with so if currents
are plus one is less than change his size then indeed we can move forward on the timeline in reading
something so we plus plus current we say auto Amakosa changes at current.
We set the balance and we return the memento.
Otherwise as always we return the full constructed shirt.
All right so we are done here and we can generate a stream output.
Operator And once again experiment with this approach.
So stream up with OPERATOR I'll just output the balance here.
I have to go back and delete those stream.
I hate when a line does this.
And now we can actually experiment with this kind of walking forwards and backwards so let's once again
make bank accounts.
So bank accounts to this time called B.A.A. with a bounce of 100.
I will deposit 50 and I'm not going to keep the momentos here.
Just trust me on this that if I do keep the momentum I can roll back to that momentum but we're going
to look mainly at undo and redo.
So I would do another deposit off 25 this time around.
So by this point we'll have 125 in the bank accounts.
I'll actually print out the bank account like so and then we're going to do a couple of operations so
I will undo once or undo I will undo again.
It's actually my copy this and paste it over but I do want some sort of diagnostic message so to undo
one like so.
And here I will add on to.
And here I will try to redo the redo and once you can put redo in here we do.
Let's align them both.
OK.
So essentially we've done this.
Well I guess I guess this is enough for now essentially.
So we do to undo.
So after 125 we should undo to 100 and then undo to well actually.
Hold on that's not 125.
That's one hundred seventy five.
That's what it should be.
OK so let's actually execute this and see what we get here.
All right.
So let's take a look at what we got and whether it's consistent with what we are expecting so we make
two deposits 15:25.
So the final balance is 175.
We undo ones.
So we go from one set of the five to 150.
And here it is we undo again so we go from 1 50 to 100 and then we redo so we go from 100 to 150.
So as you can see the takeaway from this is that theoretically you can use the mento pattern provided
that the state of the system is sufficiently small in terms of the memory footprint to actually record
every single change and as a result not only do you get the user to be able to restore the system to
any particular state just by using the momenta you also have this ability to walk forwards and backwards
in terms of the overall timeline the overall changes of the bank account in this case and you let the
user kind of undo and redo depending on their needs.