Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:04,230 --> 00:00:07,540
So let's take a look at this rather complicated looking diagram.
2
00:00:07,560 --> 00:00:08,730
It's not that complicated.
3
00:00:08,760 --> 00:00:10,360
Trust me, I'm sorry, it's a little bit blurry.
4
00:00:10,380 --> 00:00:14,790
This is taken from Wikipedia, where somebody has already done the work of putting this together for
5
00:00:14,790 --> 00:00:20,640
me, and I think it's useful to evaluate some of the stuff from Wikipedia because the kind of diagrams
6
00:00:20,640 --> 00:00:22,470
you're going to come across quite often.
7
00:00:22,470 --> 00:00:25,470
So if you Google for state pattern, this is the kind of diagram that comes up.
8
00:00:25,500 --> 00:00:26,730
So what is it saying?
9
00:00:26,730 --> 00:00:32,950
Well, we have the idea of a context, which is we're coming from a finite state machine.
10
00:00:32,950 --> 00:00:35,520
This is basically our finite state machine in here.
11
00:00:35,640 --> 00:00:42,570
And then you have the state, except now the state is turned in instead of being an enum.
12
00:00:43,110 --> 00:00:52,590
It is a an interface, is a class eight allows us to say this is an operation you can call this operation
13
00:00:52,590 --> 00:00:53,280
on me.
14
00:00:54,090 --> 00:01:00,540
And what will happen is that in this context, in the finite state machine, something happens and we
15
00:01:00,540 --> 00:01:06,360
trigger, for example, the jump operation or the jump transition on the state.
16
00:01:07,440 --> 00:01:11,210
And we don't actually know which concrete state we are in.
17
00:01:11,220 --> 00:01:15,870
So you can have different states for the different states that inherit from the interface.
18
00:01:15,870 --> 00:01:23,190
So state one, state two or jumping in air and ground, it could be three different subclasses and each
19
00:01:23,190 --> 00:01:26,340
of them would implement their own version of Jump.
20
00:01:27,060 --> 00:01:32,190
And then what happens is this is the little sequence diagram over here on the right.
21
00:01:32,200 --> 00:01:35,730
So the context says, Hey, this operation.
22
00:01:36,660 --> 00:01:42,810
So it could be saying, Hey, jump now state one could be ground.
23
00:01:42,810 --> 00:01:44,550
It will say, OK, well set.
24
00:01:44,550 --> 00:01:51,420
The state basically goes back and calls on the context again and says, Hey, go and set the state to
25
00:01:51,450 --> 00:01:52,230
state to.
26
00:01:52,230 --> 00:01:55,080
In this case, it's going to be to the jumping state.
27
00:01:55,830 --> 00:01:58,620
And then the next song Operation comes in jump, for example.
28
00:01:58,920 --> 00:02:05,100
Well, State two, which is maybe a jumping state, would ignore it and set or in this case, setting
29
00:02:05,100 --> 00:02:06,750
it back to state one.
30
00:02:07,590 --> 00:02:11,100
So that's a little bit elaborate from this pattern hierarchy.
31
00:02:11,430 --> 00:02:15,420
Don't worry if you didn't get it from that, I just wanted to draw your attention to it.
32
00:02:15,420 --> 00:02:21,150
And if you come back to this after we've had a look at some code, it might be a little bit clearer.
33
00:02:21,330 --> 00:02:25,620
So here is an outline of what I've just been explaining.
34
00:02:25,620 --> 00:02:32,970
We've got ourselves this locomotion state, which is an interface, as I said, and to implement this
35
00:02:32,970 --> 00:02:38,550
interface, you need to implement the jump for all land and crouch transitions.
36
00:02:38,550 --> 00:02:43,200
We're going to call the transitions to keep in line with our finite state machine that we saw in the
37
00:02:43,200 --> 00:02:44,040
previous video.
38
00:02:44,670 --> 00:02:47,700
You'll notice that they pass in this locomotion context.
39
00:02:47,700 --> 00:02:49,620
We'll get to this in just a second.
40
00:02:50,280 --> 00:02:51,660
But don't worry about it just yet.
41
00:02:51,900 --> 00:02:55,320
It's essentially a state machine itself.
42
00:02:56,400 --> 00:02:59,230
So then what does the state machine itself do?
43
00:02:59,250 --> 00:03:04,890
Well, instead of keeping track of the enum, as I said, it's going to keep track of a locomotion state
44
00:03:04,890 --> 00:03:06,990
that's referencing this interface here.
45
00:03:07,860 --> 00:03:14,430
And whenever we get a crouch, full jump or land, it's just going to call Crouch full jump or land
46
00:03:14,880 --> 00:03:19,020
on that current state, whatever that state currently is.
47
00:03:19,770 --> 00:03:23,320
Now one problem here is that I haven't initialized that current state.
48
00:03:23,340 --> 00:03:30,120
We do need to initialize it to something so we could set it equal to the new instance of and what states
49
00:03:30,120 --> 00:03:30,960
do we actually have?
50
00:03:30,990 --> 00:03:36,630
Well, you got a grounded state in our state and crashing state that override locomotion.
51
00:03:36,630 --> 00:03:37,830
State interface.
52
00:03:38,580 --> 00:03:39,270
Don't override.
53
00:03:39,270 --> 00:03:39,630
Sorry.
54
00:03:39,660 --> 00:03:41,870
That's the wrong word for interfaces.
55
00:03:41,910 --> 00:03:48,870
They implement that interface so we can instantiate an instance of the Granite State.
56
00:03:49,020 --> 00:03:57,900
So now at first blush, if we get a crouch events, we pass it on to the grounded state and we crouch
57
00:03:57,900 --> 00:03:59,190
from within the Granite State.
58
00:03:59,200 --> 00:04:00,590
So now let's go and have a look.
59
00:04:00,600 --> 00:04:03,390
What happens if I crouch from within the Granite State?
60
00:04:03,630 --> 00:04:04,080
Aha.
61
00:04:04,350 --> 00:04:06,930
This is where that locomotion context comes in.
62
00:04:07,560 --> 00:04:14,550
Essentially, what's going on is, we are saying, set the state on our finite state machine to be a
63
00:04:14,550 --> 00:04:15,450
crouching state.
64
00:04:15,450 --> 00:04:16,950
So new crouching state.
65
00:04:17,550 --> 00:04:19,459
So that's what's going on here.
66
00:04:19,470 --> 00:04:22,320
And ultimately, I find this so much easier to read.
67
00:04:22,320 --> 00:04:25,950
If we're in the ground state and we crouch, we go to the crashing state.
68
00:04:25,950 --> 00:04:29,150
If we're in the ground state and we fall, we go to the interstate.
69
00:04:29,620 --> 00:04:31,290
We in the Granite State and we jump.
70
00:04:31,290 --> 00:04:32,970
We go to the interstate.
71
00:04:32,970 --> 00:04:35,640
If we land in the Granite State, well, nothing happens.
72
00:04:35,640 --> 00:04:40,590
That kind of keeps us honest and make sure we don't forget about any of the transitions, because if
73
00:04:40,590 --> 00:04:47,940
we had a new transition to the locomotion state to that interface, we have to implement it in each
74
00:04:47,940 --> 00:04:53,250
of the states, even if it needs to do nothing, which is a nice mechanism for keeping us honest.
75
00:04:53,400 --> 00:04:57,600
Now, I promised I'd circle back to this locomotion context interface.
76
00:04:58,200 --> 00:04:59,610
So what have I done here?
77
00:05:00,240 --> 00:05:03,240
There is another interface, and all it does is.
78
00:05:03,630 --> 00:05:05,670
Have this set state function?
79
00:05:06,490 --> 00:05:12,090
Why have I done that and why have I passed that in instead of the locomotion state pattern?
80
00:05:12,300 --> 00:05:13,770
Well, two reasons, really.
81
00:05:14,040 --> 00:05:21,510
The first one is I don't like circular references, so I didn't like the idea that we would have the
82
00:05:21,780 --> 00:05:29,820
locomotion state pattern depending upon something like the grounded state and or the locomotion state
83
00:05:29,820 --> 00:05:34,380
and then the locomotion state itself, depending back on the locomotion state pattern.
84
00:05:34,920 --> 00:05:37,770
I don't like it when there is those circular references like that.
85
00:05:38,280 --> 00:05:42,450
So there's generally it's not a good idea to have circular references.
86
00:05:42,450 --> 00:05:44,470
It means things are very, very tightly coupled together.
87
00:05:44,520 --> 00:05:49,200
So adding the locomotion context in here inverts those dependencies a little bit.
88
00:05:49,200 --> 00:05:56,250
So locomotion state pattern depends on the context, and the state locomotion context depends only on
89
00:05:56,250 --> 00:06:00,810
the state, and the state depends on the context of those two interfaces are linked to each other.
90
00:06:01,170 --> 00:06:03,780
But that's all right when we're talking about interfaces.
91
00:06:04,920 --> 00:06:11,790
So then the other reason for this is if I were to expose this locomotion state pattern to the wider
92
00:06:11,790 --> 00:06:20,250
world and I want them to be able to call Crouch full jump land on here in order to manipulate this state,
93
00:06:20,250 --> 00:06:23,550
perhaps in this finite state machine's internal state.
94
00:06:23,910 --> 00:06:29,400
What I don't want is another public function here called set state, which would allow them to directly
95
00:06:29,520 --> 00:06:33,180
manipulate the state of this nonno behavior.
96
00:06:33,480 --> 00:06:44,310
So instead, by exposing it through an interface, we are saying you can only use this function if you
97
00:06:44,310 --> 00:06:46,650
are using it via this interface.
98
00:06:46,920 --> 00:06:50,400
So it just allows us to have a bit of interface segregation.
99
00:06:50,400 --> 00:06:57,990
It makes it easier to not make the mistake of setting the state by accident directly and instead having
100
00:06:57,990 --> 00:07:01,050
to use these transition functions instead.
101
00:07:01,260 --> 00:07:07,230
Now we do have two more classes down here the interstate state and the crashing state, which you can
102
00:07:07,230 --> 00:07:09,450
see haven't yet been implemented.
103
00:07:09,450 --> 00:07:12,330
And you probably guessed it, that's going to be your challenge.
104
00:07:12,600 --> 00:07:14,710
So here is the state machine again.
105
00:07:14,730 --> 00:07:19,560
For reference, I've crossed out the Granite State and the transitions away from the ground state because
106
00:07:19,560 --> 00:07:21,120
those have already been implemented.
107
00:07:21,630 --> 00:07:27,450
So using those as a reference, go in, poke around with the code, get familiar with it and implement
108
00:07:27,450 --> 00:07:30,120
the in-air and crashing states as well.
109
00:07:30,150 --> 00:07:31,500
Post video and have a go.
110
00:07:34,320 --> 00:07:35,500
OK, welcome back.
111
00:07:35,520 --> 00:07:40,680
So hopefully this will be a bit easier because this is a more logical way of thinking about it.
112
00:07:40,680 --> 00:07:44,670
So if we're in the inner state and we crouch, nothing's going to happen.
113
00:07:44,670 --> 00:07:47,460
If we fall, nothing's going to transition, if we jump.
114
00:07:47,880 --> 00:07:48,870
Nothing's going to happen.
115
00:07:48,870 --> 00:07:55,350
So the only case where this actually does anything is in the land transition for the interstate state.
116
00:07:55,770 --> 00:08:04,500
So that case, we're going to go to the context and set the state to be a new grounded state instance.
117
00:08:04,500 --> 00:08:11,250
Like so now we go into our crouching state and we hit Crouch where we do want to do something and here
118
00:08:11,340 --> 00:08:17,730
we want to take the context and set the state to a new grounded state instance.
119
00:08:17,730 --> 00:08:24,360
Again, because we are going from crouching to grounded and ground and crashing and so on like that,
120
00:08:24,750 --> 00:08:26,910
then we've got our fall.
121
00:08:27,270 --> 00:08:29,820
What happens if we fall while we are crouching?
122
00:08:30,150 --> 00:08:37,140
We're going to set the context set state to in and so new in our state.
123
00:08:39,240 --> 00:08:44,610
If we jump, that is another state where we're just going to transition to ground, it's going to you
124
00:08:44,970 --> 00:08:46,230
put that transition in there.
125
00:08:46,740 --> 00:08:48,660
And if we land well, it does nothing.
126
00:08:48,690 --> 00:08:49,720
We're already crouching.
127
00:08:49,740 --> 00:08:50,740
We should be on the ground.
128
00:08:50,760 --> 00:08:52,950
So landing shouldn't affect us.
129
00:08:53,280 --> 00:08:57,090
So hopefully you can see how the state pattern makes it far easier to write this sort of code.
130
00:08:57,090 --> 00:09:00,390
It also allows us to add in code.
131
00:09:00,390 --> 00:09:06,300
Perhaps we could have update functions here within an individual state so that there's update functions
132
00:09:06,300 --> 00:09:11,340
that are only running when you're crouching or update functions that are only running when you're in
133
00:09:11,340 --> 00:09:15,600
the interstate allows us to segregate that code between the states much more easily.
134
00:09:16,080 --> 00:09:19,850
In this example, I've put them all under one file.
135
00:09:19,860 --> 00:09:25,800
Obviously, in reality, you would probably split each one of these, including the interfaces, into
136
00:09:25,800 --> 00:09:27,030
their separate files.
137
00:09:27,510 --> 00:09:33,060
But this gives you an idea of how you could use the state pattern for, in this case, locomotion.
138
00:09:33,060 --> 00:09:39,390
You could use it for Ally like I was talking about, and you can implement all sorts of behaviors and
139
00:09:39,390 --> 00:09:41,610
expand upon this immensely.
140
00:09:41,820 --> 00:09:47,280
So if you do end up using the state pattern in your own code or you have already used the state patch
141
00:09:47,280 --> 00:09:50,190
in your own code, please go and share in the discussions.
142
00:09:50,460 --> 00:09:52,260
And let us know how you used it.
143
00:09:52,470 --> 00:09:57,720
It would be really interesting to see this put to use in the wild by our students.
14606
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.