-
Notifications
You must be signed in to change notification settings - Fork 6k
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
Refactor and migrate FlutterUndoManagerPlugin to ARC #52234
Conversation
3e1d857
to
231e00e
Compare
shell/platform/darwin/ios/framework/Source/FlutterUndoManagerDelegate.h
Outdated
Show resolved
Hide resolved
shell/platform/darwin/ios/framework/Source/FlutterUndoManagerDelegate.h
Outdated
Show resolved
Hide resolved
id<FlutterUndoManagerDelegate> _undoManagerDelegate; | ||
} | ||
@interface FlutterUndoManagerPlugin () | ||
@property(nonatomic, weak, readonly) id<FlutterUndoManagerDelegate> undoManagerDelegate; |
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.
From below:
// `_undoManagerDelegate` is a weak reference because it should retain FlutterUndoManagerPlugin.
: FlutterUndoRedoDirectionRedo; | ||
[target registerUndoWithDirection:newDirection]; | ||
// Invoke method on delegate. | ||
[target.undoManagerDelegate flutterUndoManagerPlugin:target |
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.
Changed _undoManagerDelegate
to target.undoManagerDelegate
and passed target
into flutterUndoManagerPlugin
so self
isn't retained in this block.
shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPluginTest.mm
Outdated
Show resolved
Hide resolved
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.
Nice! Some minor comments, but LGTM.
@@ -19,8 +21,14 @@ typedef NS_ENUM(NSInteger, FlutterUndoRedoDirection) { | |||
@class FlutterUndoManagerPlugin; | |||
|
|||
@protocol FlutterUndoManagerDelegate <NSObject> | |||
|
|||
@property(nonatomic, weak) UIResponder* viewController; |
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.
Could you add declaration comments to these explaining their role in the delegation? (Per style guide, all declarations should be commented. I know the engine is awful about this, but it would be good to break the cycle in new code.)
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.
Documenting how this delegate works led me to rewrite it.
-
The
-flutterUndoManagerPlugin:handleUndoWithDirection:
engine implementation doesn't use theundoManagerPlugin
, so there's no need to pass it back through. -
I realized we were exposing the view controller just to get the undo manager, and exposing the text input plugin just to get the active text input view, which was a message chain code smell. I changed the delegate to just require the objects the undo manager plugin actually needs, and updated
FlutterEngine
's implementation of this protocol. This also allowed me to reduce the mocking in the tests.
id<FlutterUndoManagerDelegate> _undoManagerDelegate; | ||
} | ||
@interface FlutterUndoManagerPlugin () | ||
@property(nonatomic, weak, readonly) id<FlutterUndoManagerDelegate> undoManagerDelegate; |
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.
This should also have a declaration comment (maybe a short summary of what kinds of things are delegated).
@@ -34,7 +31,6 @@ - (instancetype)initWithDelegate:(id<FlutterUndoManagerDelegate>)undoManagerDele | |||
|
|||
- (void)dealloc { | |||
[self resetUndoManager]; |
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.
Optional since it's pre-existing: it would be good to inline the chain of calls (which is still only one line) to use _undoManagerDelegate
directly instead of calling a self
method in dealloc
in violation of style guide/best practices.
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.
Done, and my refactor of the delegate reduced the chaining. It still calls self
since that's what being passed into -removeAllActionsWithTarget
but at least it isn't calling its own properties.
[_undoManagerDelegate.undoManager removeAllActionsWithTarget:self];
handleUndoWithDirection:direction]; | ||
}]; | ||
[[self undoManager] endUndoGrouping]; | ||
NSUndoManager* undoManager = [self undoManager]; |
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.
Optional nit: self.undoManager
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.
Right now it's a method, but I can add the readonly property. I was trying to limit the number of changes to this file, but I've touched everything at this point.
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.
Scratch that. I since removed the -undoManager
method and changed the callsites to self.undoManagerDelegate.undoManager
.
shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPlugin.mm
Outdated
Show resolved
Hide resolved
shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPlugin.mm
Outdated
Show resolved
Hide resolved
@@ -99,16 +97,15 @@ - (void)setUndoState:(NSDictionary*)dictionary API_AVAILABLE(ios(9.0)) { | |||
if (canRedo) { | |||
[self registerRedo]; | |||
} | |||
|
|||
if (_viewController.engine.textInputPlugin.textInputView != nil) { | |||
UIView<UITextInput>* textInputView = [self.undoManagerDelegate.textInputPlugin textInputView]; |
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.
Is textInputView
not declared as a property?
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.
No:
- (UIView<UITextInput>*)textInputView; |
At the moment I don't want to tackle changing that in a public header.
shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPluginTest.mm
Outdated
Show resolved
Hide resolved
@@ -1189,12 +1187,19 @@ - (void)flutterTextInputView:(FlutterTextInputView*)textInputView | |||
|
|||
#pragma mark - Undo Manager Delegate | |||
|
|||
- (void)flutterUndoManagerPlugin:(FlutterUndoManagerPlugin*)undoManagerPlugin | |||
handleUndoWithDirection:(FlutterUndoRedoDirection)direction { | |||
- (void)handleUndoWithDirection:(FlutterUndoRedoDirection)direction { |
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.
undoManagerPlugin
was unused.
- (UIView<UITextInput>*)activeTextInputView { | ||
return [[self textInputPlugin] textInputView]; | ||
} | ||
|
||
- (NSUndoManager*)undoManager { | ||
return self.viewController.undoManager; | ||
} |
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.
Two new properties to conform to the delegate, to reduce how much the plugin needs to understand this ownership model.
|
||
- (void)tearDown { | ||
[self.undoManager removeAllActionsWithTarget:self.undoManagerPlugin]; |
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.
This was only class mocked, I don't think this would do anything.
@@ -74,18 +97,6 @@ - (void)testSetUndoState { | |||
.andDo(^(NSInvocation* invocation) { | |||
removeAllActionsCount++; | |||
}); | |||
__block int delegateUndoCount = 0; |
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.
This is now tracked in the FakeFlutterUndoManagerDelegate
test object, which is not mocked anywhere.
handleUndoWithDirection:direction]; | ||
}]; | ||
[[self undoManager] endUndoGrouping]; | ||
NSUndoManager* undoManager = [self undoManager]; |
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.
Scratch that. I since removed the -undoManager
method and changed the callsites to self.undoManagerDelegate.undoManager
.
return _viewController.undoManager; | ||
} | ||
|
||
- (void)resetUndoManager API_AVAILABLE(ios(9.0)) { |
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.
Removed API_AVAILABLE(ios(9.0))
since the min is iOS 12. Must have missed that in a cleanup.
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.
Nice!
…147190) flutter/engine@a4b71f0...33c828f 2024-04-22 skia-flutter-autoroll@skia.org Roll Skia from eb29b46236e6 to 3b32e3280b67 (1 revision) (flutter/engine#52298) 2024-04-22 magder@google.com Break dependency cycle of FlutterViewController <-> FlutterPlatformView (flutter/engine#52271) 2024-04-22 chris@bracken.jp [et] Lookup output filesystem path, not label (flutter/engine#52248) 2024-04-22 skia-flutter-autoroll@skia.org Roll Skia from 975859a96f8f to eb29b46236e6 (9 revisions) (flutter/engine#52297) 2024-04-22 1961493+harryterkelsen@users.noreply.github.com [canvaskit] Add configuration for maximum canvases (flutter/engine#51735) 2024-04-22 120297255+PurplePolyhedron@users.noreply.github.com Fix link in BlendMode.saturation (flutter/engine#52156) 2024-04-22 magder@google.com Refactor and migrate FlutterUndoManagerPlugin to ARC (flutter/engine#52234) 2024-04-22 skia-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from Rr9lFiKCPhMXDGa89... to L533ubzhjWwW7jxbc... (flutter/engine#52293) 2024-04-22 skia-flutter-autoroll@skia.org Roll Dart SDK from 0a83dd7e61b1 to 0ed66a4d77cb (1 revision) (flutter/engine#52294) Also rolling transitive DEPS: fuchsia/sdk/core/linux-amd64 from Rr9lFiKCPhMX to L533ubzhjWwW If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC jsimmons@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Smart pointers support ARC as of #47612, and the unit tests were migrated in #48162.
Migrate
FlutterUndoManagerPlugin
from MRC to ARC.FlutterViewController
orFlutterEngine
(its delegate). This decouples the plugin, and means it doesn't depend on any MRC classes.Part of flutter/flutter#137801.