1 00:00:00,170 --> 00:00:04,220 We're updating our model but now we need to update our view as well, 2 00:00:04,220 --> 00:00:08,230 which can be a little bit tricky especially with Android. 3 00:00:08,230 --> 00:00:08,990 We'll need to wait for 4 00:00:08,990 --> 00:00:12,890 the activities on create method before we can create the view. 5 00:00:12,890 --> 00:00:16,940 So we aren't going to be able to initialize our view right from the get go. 6 00:00:16,940 --> 00:00:20,340 To remedy this let's create a property for our view and 7 00:00:20,340 --> 00:00:23,450 then once our view has been created, we'll call a function and 8 00:00:23,450 --> 00:00:26,920 our game presenter class to populate our view property. 9 00:00:26,920 --> 00:00:31,200 First let's make a property for our view and since we're going to be setting its 10 00:00:31,200 --> 00:00:35,990 value later with a function, we'll need to declare this property as mutable. 11 00:00:35,990 --> 00:00:41,850 At the the top of our class, let's type var view, give it a type of GameView. 12 00:00:44,810 --> 00:00:48,330 And then, since we don't have anything to set it to yet, and 13 00:00:48,330 --> 00:00:53,800 we have to set it to something, let's set it to null, which gives us an error, 14 00:00:53,800 --> 00:00:58,690 null cannot be a value of non null type GameView. 15 00:00:58,690 --> 00:01:00,618 Okay, so what does that mean? 16 00:01:00,618 --> 00:01:05,560 Well in Kotlin if you want an object to be able to equal null you need to add 17 00:01:05,560 --> 00:01:11,030 a question mark after the datatype, this is one of my favorite parts about Kotlin. 18 00:01:11,030 --> 00:01:15,200 It's not much but when you have to take the time to think about whether a property 19 00:01:15,200 --> 00:01:20,110 can be null or not I find that I end up writing better code. 20 00:01:20,110 --> 00:01:23,130 And definitely have a lot fewer null pointer exceptions. 21 00:01:23,130 --> 00:01:25,980 Anyway, now that we've got our view property let's create 22 00:01:25,980 --> 00:01:27,470 a function to populate it. 23 00:01:27,470 --> 00:01:29,935 And let's name it setGameView. 24 00:01:30,950 --> 00:01:35,770 Let's make it taken the gameview as a parameter and then 25 00:01:35,770 --> 00:01:40,860 inside this function let's set our view property equal to our gameView parameter. 26 00:01:42,510 --> 00:01:46,370 And now that we've got access to our view let's update it at the bottom of our 27 00:01:46,370 --> 00:01:51,360 onDeckTap function, view.update and 28 00:01:51,360 --> 00:01:54,608 pass in our GameModel. 29 00:01:54,608 --> 00:01:57,729 Nice, but what's this are all about? 30 00:01:57,729 --> 00:01:58,626 Only safe or 31 00:01:58,626 --> 00:02:04,203 non null asserted calls are allowed on a noble receiver of type game view. 32 00:02:04,203 --> 00:02:08,757 This is just another way that Kotlin makes sure we really know what we're doing 33 00:02:08,757 --> 00:02:10,277 when dealing with nulls. 34 00:02:10,277 --> 00:02:14,160 You see Kotlin knows our view property can be null. 35 00:02:15,600 --> 00:02:19,681 Kotlin also knows that it's possible that we're calling this 36 00:02:19,681 --> 00:02:24,980 update function on a null object, which makes Kotlin very unhappy. 37 00:02:24,980 --> 00:02:28,420 To solve this issue Kotlin gives us two options. 38 00:02:28,420 --> 00:02:31,170 We can add a question mark before the call, and 39 00:02:31,170 --> 00:02:35,590 now if our view is null, we won't call the update function and 40 00:02:35,590 --> 00:02:41,430 this whole line will just return null or on the other hand 41 00:02:41,430 --> 00:02:46,100 if our view is not null, then it will call the update function just like we want. 42 00:02:46,100 --> 00:02:50,470 The other way we can handle this is to use two exclamation points. 43 00:02:50,470 --> 00:02:53,510 When we precede a call with two exclamation points, 44 00:02:53,510 --> 00:02:57,970 we are promising Kotlin that whatever is before the exclamation points is not 45 00:02:57,970 --> 00:03:02,910 going to be null and if we promise that something isn't going to be null and 46 00:03:02,910 --> 00:03:06,660 then it is null we'll get a null pointer exception. 47 00:03:06,660 --> 00:03:10,410 So just to be on the safe side let's go back to using a safe call 48 00:03:10,410 --> 00:03:11,631 by adding in our question mark. 49 00:03:14,110 --> 00:03:15,300 Great work. 50 00:03:15,300 --> 00:03:17,770 Now that we're done with the onDeckTap function 51 00:03:17,770 --> 00:03:20,460 let's move on to our onWasteTap function. 52 00:03:20,460 --> 00:03:24,410 Let's declare the function fun onWasteTap. 53 00:03:25,480 --> 00:03:29,450 And then inside, let's update the model, 54 00:03:29,450 --> 00:03:34,076 GameModel.onWasteTap and then update the view. 55 00:03:34,076 --> 00:03:36,027 View? 56 00:03:36,027 --> 00:03:40,246 To make sure that we null for the whole statement if our view is null, 57 00:03:40,246 --> 00:03:42,550 .update and pass in our GameModel. 58 00:03:43,780 --> 00:03:44,650 And actually, 59 00:03:44,650 --> 00:03:49,360 wouldn't it be nice if we didn't have to pass in the GameModel each time? 60 00:03:49,360 --> 00:03:51,840 After all, it is a singleton. 61 00:03:51,840 --> 00:03:56,240 Let's head over to our GameView interface and see if we can't add our GameModel 62 00:03:56,240 --> 00:04:01,167 instance as a default value, = GameModel. 63 00:04:02,660 --> 00:04:08,310 Now back in our game presenter we can stop passing in our model as a parameter. 64 00:04:10,310 --> 00:04:14,890 Nice, getting back to our two remaining functions to give us a head start. 65 00:04:14,890 --> 00:04:17,069 Let's just copy them in from our game model class. 66 00:04:29,797 --> 00:04:37,392 Then let's delete the function bodies, And 67 00:04:37,392 --> 00:04:41,773 starting with onFoundationTap we need to first call 68 00:04:41,773 --> 00:04:47,758 GameModel.onFoundationTap, and pass along the foundationIndex. 69 00:04:50,062 --> 00:04:51,813 Then we need to update our view. 70 00:04:53,707 --> 00:05:00,115 Finally, for our on tableau tap function, we need to call GameModel.onTableauTap. 71 00:05:01,640 --> 00:05:07,650 Pass in our TableauIndex and our cardIndex and then update our view. 72 00:05:10,740 --> 00:05:13,880 All right, we've completely finished our game of solitaire. 73 00:05:13,880 --> 00:05:17,600 And while I know we won't be getting to the UI part until the next course, 74 00:05:17,600 --> 00:05:21,480 that doesn't mean we can't see some sweet solitaire action in this course. 75 00:05:21,480 --> 00:05:22,560 In the next stage, 76 00:05:22,560 --> 00:05:25,340 we'll look into creating a test to make sure that our game is working.