1 00:00:01,020 --> 00:00:04,670 For the gate logic, we're going to create a separate type entirely 2 00:00:04,670 --> 00:00:09,280 as a nested object in control tower just like runway and terminal. 3 00:00:09,280 --> 00:00:11,430 Here's what our code needs to do. 4 00:00:11,430 --> 00:00:12,880 We have a set of gates for 5 00:00:12,880 --> 00:00:17,830 each terminal that we need to query every time a plane requests a space. 6 00:00:17,830 --> 00:00:21,950 The information about terminals is encoded in the terminal type. 7 00:00:21,950 --> 00:00:26,770 So we could associate the terminal's gates with each enum member. 8 00:00:26,770 --> 00:00:30,300 Now one way we can do this is to use computed properties, so for 9 00:00:30,300 --> 00:00:34,800 example, we could have a computed property that returns the list of gates for 10 00:00:34,800 --> 00:00:37,820 terminal A, B, C, and so on. 11 00:00:37,820 --> 00:00:40,180 But unfortunately, that has its limits. 12 00:00:41,440 --> 00:00:46,460 A computed property has no storage in memory and either returns a static value 13 00:00:46,460 --> 00:00:51,320 every time or one that is computed from stored properties. 14 00:00:51,320 --> 00:00:57,580 We cannot use a computed property because we can't return the same gates every time. 15 00:00:57,580 --> 00:01:02,070 Let's say Terminal A had three gates, 1 through 3. 16 00:01:02,070 --> 00:01:06,070 An airline requests to park, and so we say go ahead and park at A1. 17 00:01:07,170 --> 00:01:09,822 If we use a computed property for the gates, 18 00:01:09,822 --> 00:01:14,080 we're going to return the gates 1 through 3 every time. 19 00:01:14,080 --> 00:01:17,170 Enums can't contain stored properties either. 20 00:01:17,170 --> 00:01:18,900 So, to get around this, 21 00:01:18,900 --> 00:01:22,440 we're going to encode the gate information in a different type altogether. 22 00:01:23,470 --> 00:01:27,200 There are other ways to do this, but because I want to show you certain 23 00:01:27,200 --> 00:01:31,470 things about protocols and enums, we'll go down this round. 24 00:01:31,470 --> 00:01:34,630 The nice thing though is the way we're about to implement gate logic, 25 00:01:34,630 --> 00:01:39,000 we're going to learn a few more things about Swift in the process. 26 00:01:39,000 --> 00:01:43,820 So, right after the terminal enum, let's add a new type, 27 00:01:43,820 --> 00:01:46,450 and we'll name this GateManager. 28 00:01:46,450 --> 00:01:47,561 And this is going to be a class. 29 00:01:51,859 --> 00:01:56,673 We're going to add four stored properties to this class to keep track of the status 30 00:01:56,673 --> 00:01:58,710 of various gates in the terminal. 31 00:01:59,730 --> 00:02:01,930 I'm going to copy paste this in, and 32 00:02:01,930 --> 00:02:06,690 as always, you can grab the code from the link in the teacher's notes as well. 33 00:02:06,690 --> 00:02:09,660 For these properties, we're using good old dictionaries and 34 00:02:09,660 --> 00:02:13,110 arrays to keep track of what gates are available. 35 00:02:13,110 --> 00:02:15,990 The first property, for example, gates for 36 00:02:15,990 --> 00:02:20,630 terminal A keeps track of the gates for terminal A obviously. 37 00:02:21,770 --> 00:02:28,840 The property contains a dictionary on the outside with two keys, occupied and empty. 38 00:02:30,300 --> 00:02:33,630 Using each key gets you an array of integers 39 00:02:33,630 --> 00:02:36,580 pertaining to the different gates available. 40 00:02:36,580 --> 00:02:41,510 Now there are ways we can improve this rather than using nested collection types, 41 00:02:41,510 --> 00:02:44,520 but I'm going to set that as an exercise for you. 42 00:02:44,520 --> 00:02:45,900 Get that brain of yours thinking. 43 00:02:47,300 --> 00:02:49,550 So the logic here is pretty simple. 44 00:02:49,550 --> 00:02:52,570 When Delta Airlines requests landing, 45 00:02:52,570 --> 00:02:56,580 we know it's Terminal A based on the logic we wrote earlier. 46 00:02:56,580 --> 00:02:59,640 So we queried the gatesForTerminalA property. 47 00:03:00,730 --> 00:03:06,450 Using the key empty, that's this one here, we check if there are any empty gates. 48 00:03:06,450 --> 00:03:08,540 If yes, we return the value. 49 00:03:08,540 --> 00:03:10,660 Otherwise, we return nil. 50 00:03:10,660 --> 00:03:12,720 When an empty gate is assigned to a flight, 51 00:03:12,720 --> 00:03:14,900 we need to update the stored property. 52 00:03:14,900 --> 00:03:19,438 So let's say we assign gate 9 for the flight to land at or park at. 53 00:03:19,438 --> 00:03:21,180 Well, now 9 isn't empty anymore, so 54 00:03:21,180 --> 00:03:24,840 we need to move 9 over into the occupied list. 55 00:03:24,840 --> 00:03:29,960 So to start, in this class, let's write two methods to get this work done. 56 00:03:29,960 --> 00:03:32,127 So first, we'll write a method to update the gate. 57 00:03:34,988 --> 00:03:37,630 So we'll say func update. 58 00:03:38,990 --> 00:03:43,670 This method is going to take a property that lists the gates. 59 00:03:43,670 --> 00:03:47,850 So now this type is this thing here, string, 60 00:03:47,850 --> 00:03:54,459 a dictionary with strings as keys and then array of integers as a value. 61 00:03:54,459 --> 00:03:57,350 And then it will also take a gate as an integer. 62 00:03:59,140 --> 00:04:05,580 Given a particular date, we want to switch it from the empty to the occupied array. 63 00:04:05,580 --> 00:04:07,800 So let's say we call this method update. 64 00:04:07,800 --> 00:04:11,830 And for gates, we pass in gates for terminal A, and 65 00:04:11,830 --> 00:04:14,570 the gate number as number 9. 66 00:04:14,570 --> 00:04:17,130 We want to remove the gate 9. 67 00:04:17,130 --> 00:04:20,650 We want to remove the value 9 from the empty array and 68 00:04:20,650 --> 00:04:23,150 add it to the occupied array. 69 00:04:23,150 --> 00:04:27,890 So the first thing we'll do in our method is get the list of occupied gates for 70 00:04:27,890 --> 00:04:29,050 a particular terminal. 71 00:04:29,050 --> 00:04:35,720 So we'll say if var occupiedGates = gates, 72 00:04:35,720 --> 00:04:40,643 and we'll use the key occupied. 73 00:04:44,408 --> 00:04:50,690 The gate's dictionary here represents the collection of gates for a terminal. 74 00:04:50,690 --> 00:04:54,790 And using the occupied key, we can get all the occupied gates. 75 00:04:54,790 --> 00:04:57,700 You'll notice that we're doing something we've never done before, and 76 00:04:57,700 --> 00:05:00,620 that's specifying if var instead of if let. 77 00:05:01,670 --> 00:05:04,740 if var creates a variable that can be modified, 78 00:05:04,740 --> 00:05:07,370 whereas let creates a constant value. 79 00:05:07,370 --> 00:05:11,270 The reason we want a variable is now that we have an array, 80 00:05:11,270 --> 00:05:13,969 we're going to append the gate value. 81 00:05:13,969 --> 00:05:19,519 So this occupied gates is now this list or this array of gates, 82 00:05:19,519 --> 00:05:24,300 and to that, we're going to append the new gate. 83 00:05:24,300 --> 00:05:27,120 That's this thing right here, saying append(gate). 84 00:05:28,250 --> 00:05:32,180 Now we've taken the gate and assigned it to the occupied list. 85 00:05:32,180 --> 00:05:37,170 You'll notice we didn't modify the array contained within the dictionary directly. 86 00:05:37,170 --> 00:05:41,130 We created a copy by assigning it to a local constant or 87 00:05:41,130 --> 00:05:44,860 local variable when we modify that variable. 88 00:05:44,860 --> 00:05:50,060 So now, now that we've modified it, we're going to use updateValue forKey 89 00:05:50,060 --> 00:05:54,005 on the gate's dictionary and reassign this array as a value. 90 00:05:54,005 --> 00:06:00,040 So we'll say gates.updateValue forKey. 91 00:06:00,040 --> 00:06:04,360 And for the value, we are going to pass in the occupiedGates, and for the key, 92 00:06:04,360 --> 00:06:05,600 we'll say occupied. 93 00:06:09,780 --> 00:06:14,350 This does not work however, and the reason for that is the gate's value. 94 00:06:14,350 --> 00:06:18,970 This right here is a function argument as you can see here. 95 00:06:18,970 --> 00:06:23,630 And function arguments are immutable within the body of a function. 96 00:06:23,630 --> 00:06:27,410 We can work around this by specifying var in front of the parameter, 97 00:06:27,410 --> 00:06:30,410 but this is a temporary solution. 98 00:06:30,410 --> 00:06:34,450 If you click on this, it says that var parameters are deprecated and 99 00:06:34,450 --> 00:06:36,820 will be removed in Swift three. 100 00:06:36,820 --> 00:06:37,570 So let's delete that. 101 00:06:40,520 --> 00:06:45,760 To future proof our code, what we can do is pass by reference. 102 00:06:45,760 --> 00:06:51,340 And we do this using the inout keyword in front of the parameter. 103 00:06:51,340 --> 00:06:56,430 Now, previously, before we added this, if we call this method, update, and 104 00:06:56,430 --> 00:07:02,020 passed in gatesForTerminalA, what we actually pass in is a copy of this value. 105 00:07:02,020 --> 00:07:06,270 Remember that Swift dictionaries are value types. 106 00:07:06,270 --> 00:07:09,490 By adding the inout keyword in front of our parameter, 107 00:07:09,490 --> 00:07:13,180 now when we call the method, we are actually passing by reference. 108 00:07:14,210 --> 00:07:19,250 So again, if we call this method and pass in gatesForTerminalA as the argument, 109 00:07:19,250 --> 00:07:23,540 by modifying gates inside the body of the method, we're modifying gates for 110 00:07:23,540 --> 00:07:25,090 Terminal A directly. 111 00:07:26,280 --> 00:07:28,550 Okay, so now this works. 112 00:07:28,550 --> 00:07:31,940 Now on the flip side, now that we've added the gate to the occupied list, 113 00:07:31,940 --> 00:07:34,280 we also need to remove it from the empty list. 114 00:07:34,280 --> 00:07:36,590 Now this code is pretty straightforward. 115 00:07:36,590 --> 00:07:41,220 First we get the list of empty gates using the empty key. 116 00:07:45,704 --> 00:07:49,120 Then we get the index of the value we're trying to remove. 117 00:07:49,120 --> 00:07:51,902 So we'll chain this and say, 118 00:07:51,902 --> 00:07:57,810 let index = emptyGates.indexOf and we'll pass in the gate. 119 00:07:59,890 --> 00:08:04,055 Now once we have these two values, we can easily remove the gate by saying, 120 00:08:04,055 --> 00:08:12,130 emptyGates.removeAtIndex, and pass in the index that we just obtained. 121 00:08:12,130 --> 00:08:16,640 Now our emptyGates actually reflects the updated status of the gates. 122 00:08:16,640 --> 00:08:21,720 So we can assign this back to the gates property by saying 123 00:08:21,720 --> 00:08:27,260 updateValue forKey and using the relevant key value pair. 124 00:08:30,510 --> 00:08:32,170 So far so good. 125 00:08:32,170 --> 00:08:35,700 While this method doesn't actually determine if a gate is empty, 126 00:08:35,700 --> 00:08:38,960 it ensures we're not assigning the same gate to two flights. 127 00:08:39,970 --> 00:08:43,690 In the next video, let's implement the actual gate sorting logic and 128 00:08:43,690 --> 00:08:45,050 finish off the gate manager.