-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auto diffing section controller #494
Conversation
@rnystrom updated the pull request - view changes |
I think it is a good name. It describes what it does pretty well without being too verbose 👌 To get a better feeling for how it would be to use this, it would be awesome with a description on how to test it (in an example project) 💯 |
How about |
Yeah, |
@jessesquires @heumn we had some convo in #449 with other ideas:
I like IGListAutoDiffSectionController too! |
Will rebase off of #525 to lighten the load here. |
Anyone got any ideas on what we could demo as an example? Something that isn't crazy complicated, but would show off cells updating automatically. |
Summary: Batch updates are complicated b/c its unknown when the update block will actually execute. When executing the block, we want to collect inserts/deletes/reloads/moves (item and section). Allow mutations to happen synchronously outside of the update block. Tracking state will also help with the auto-diff where we need to allow re-entrant updates. Peeling off a chunk from #494 Issue fixed: #288 - [x] All tests pass. Demo project builds and runs. - [x] I added tests, an experiment, or detailed why my change isn't tested. - [x] I added an entry to the `CHANGELOG.md` for any breaking changes, enhancements, or bug fixes. Closes #525 Reviewed By: jessesquires Differential Revision: D4656463 Pulled By: rnystrom fbshipit-source-id: 8f4d3dc21b03d595e02ee9ee9664277e8ead0531
@rnystrom - can we defer this to |
@jessesquires no breaking changes, we could kick this from 3.0 but I think I'll have this working + example this weekend. |
@rnystrom updated the pull request - view changes |
@rnystrom updated the pull request - view changes |
Ok, I'm getting super excited about this. Check out the demo (gif below). I'm about ready to move this from WIP to review. Should be ready tomorrow. cc @jessesquires @zhubofei @heumn @Sherlouk @PhilCai1993 for feedback |
Initial reaction to this is that you've just saved me hundreds of lines of code and a hack 😂 Looks great I also postponed "Call mom" until the 25th, and rather "Started cycling" the 20th. No flashing reloading of the sections and things updated just as I wanted 👌 💯 Maybe it could be an idea to add something like this to extend on how powerful this is? I also keep thinking how you could make it extra clear that the section models has to follow this principle? No ideas apart from the obvious documentation that is needed :) If not later today then tomorrow I will have more time to start refactoring on my current project and get more hands on experience with this
|
Btw, I forgot to that big f***ing thank you for the awesome work you are putting in @rnystrom 🙌 |
@heumn great idea! I'm going to add an assert inside And nice extension! Maybe we can add that as a follow up? |
Perfect 🎉
👌 |
Importing for internal review! |
@rnystrom has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
that calendar view though 😚 👌 |
Early morning review before a run is probably the best kind of review right? |
@amonshiz forget to hit "Submit Review"? 🤔 |
|
||
#pragma mark - Public API | ||
|
||
- (void)updateAnimated:(BOOL)animated completion:(void (^)())completion { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this completion block is getting used. And I may have missed it but I don't think it's use is being tested either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good eye! Means I need to add a test for this too.
@rnystrom yup! reviewing and trying to comment on github at 6:15am right after waking up is clearly not what i'm best at. |
Generated by 🚫 Danger |
Waddup @iglistkit-bot catching my own mistakes. I'm in love w/ this tool. |
I'm still going back and forth on naming. Now I'm starting to lean towards
The emphasis of this API should be on the model -> view model -> binding parts, not that it diffs. What do you all think? @jessesquires @heumn @PhilCai1993 @amonshiz |
sure? i'm bad at naming. |
i'll defer to @amonshiz for naming strategies. |
@rnystrom has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
Good reasoning 👌 👍 |
It's excited! I wish I could download this commits but how? 😅 |
It was merged into master, so you can just point you podfile to the master branch :) |
@PhilCai1993 check out installation guide |
May I have a question here? If in a collectionview with various "Month", since |
@PhilCai1993 covering that in #621 I think |
Started work on the plane to get this moving since #418 is up and ready to land. We'll likely need to spend some time fleshing out the API of this, and I think I'll split it up into a couple different PRs once ready for review. Putting this up now to get early feedback.
What is this?
This adds an auto-diffing section controller as outlined in #38. There are several key parts:
IGListAutoSectionController
(naming wip)IGListBindable
so that we can control when the cell is updated w/ the view model.UICollectionView
TODO
reloadObjects:
didSelectItemAtIndex:
supportIGListAdapterUpdater
changesCreate PR for re-entrant updatese.g. callingdoing this hereperformBatchAnimated:updates:completion:
within an in-progress update block should execute immediatelyIGListAdapter
I had to make some changes to
IGListAdapterUpdater
in order for this to work. The biggest challenge is when the section controller receives a new object, it has to split it up into view models and then apply changes.However,
didUpdateToObject:
will be called insideperformBatchUpdates:
, so we need to diff and fire off the changes on the collection view immediately. A few issues:-[IGListCollectionContext performBatchAnimated:updates:completion:]
insidedidUpdateToObject:
and have it update immediately (async updates)didUpdateToObject:
gets called, so we can't just insert/delete/moveDiffing top-level models
One super important piece to getting this right is having top-level (the ones given to
IGListAdapter
and handed to the SC indidUpdateToObject:
always equal itself, even if its values change. I solved this in the unit tests w/ an object that implements diffing like:If you use a traditional
isEqualToDiffableObject:
(where you check all props/values) you'll end up reloading the section, avoiding all the nice cell animations.I started making a stock object that does this, something like
IGListAutoObject
, but its so simple that it's kind of annoying. It's essentially a model box that will probably end up more confusing than having to learn how to diff w/ the auto SC.Would love thoughts here.
Selection
didSelectItemAtIndex:
is totally broken. Options are:We've discussed splitting off
didSelectItemAtIndex:
into aselectionDelegate
(like the display/scroll/etc delegate) in #184 and elsewhere. That might help, though the view models array is private, so we'd have to expose that or create another delegate API.How can I help?
Since this is super early, please hold on nit picks, formatting, etc. I'll work on that as we go along. But there are some big things I'd love your thoughts on:
IGListAutoSectionController
. Anything better out there? I thoughtIGListDiffableSectionController
but idkIGListSingleSectionController
). I thought the API was kind of gross though, and you have to subclass the SC anyways.IGListBindable
is great, but you can't just use the view model to config the cell. For instance, how do you make the SC the cell delegate? That's why I'm leaving the method to still return a cell, but we will call bind before returning it. Is this ok?