Merge branch 'mkirk/input-bar-async'

pull/1/head
Michael Kirk 7 years ago
commit f9ff1b22cc

@ -13,6 +13,7 @@
#import "UIView+OWS.h"
#import "ViewControllerUtils.h"
#import <SignalMessaging/OWSFormat.h>
#import <SignalMessaging/SignalMessaging-Swift.h>
#import <SignalServiceKit/NSTimer+OWS.h>
#import <SignalServiceKit/TSQuotedMessage.h>
@ -221,11 +222,17 @@ const CGFloat kMaxTextViewHeight = 98;
// Momentarily switch to a non-default keyboard, else reloadInputViews
// will not affect the displayed keyboard. In practice this isn't perceptable to the user.
// The alternative would be to dismiss-and-pop the keyboard, but that can cause a more pronounced animation.
self.inputTextView.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
[self.inputTextView reloadInputViews];
self.inputTextView.keyboardType = UIKeyboardTypeDefault;
[self.inputTextView reloadInputViews];
//
// This is surprisingly expensive (~5ms), so we do it async, *after* the message is rendered.
dispatch_async(dispatch_get_main_queue(), ^{
[BenchManager benchWithTitle:@"toggleDefaultKeyboard" block:^{
self.inputTextView.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
[self.inputTextView reloadInputViews];
self.inputTextView.keyboardType = UIKeyboardTypeDefault;
[self.inputTextView reloadInputViews];
}];
});
}
- (void)setQuotedReply:(nullable OWSQuotedReplyModel *)quotedReply

@ -3834,6 +3834,7 @@ typedef enum : NSUInteger {
- (void)sendButtonPressed
{
[BenchManager startEventWithTitle:@"Send message" eventId:@"message-send"];
[self tryToSendTextMessage:self.inputToolbar.messageText updateKeyboardState:YES];
}
@ -4539,6 +4540,7 @@ typedef enum : NSUInteger {
if (scrollToBottom) {
[self scrollToBottomAnimated:NO];
}
[BenchManager completeEventWithEventId:@"message-send"];
}];
}
} @catch (NSException *exception) {

@ -28,3 +28,69 @@ public func Bench(title: String, block: () -> Void) {
finish()
}
}
/// When it's not convenient to retain the event completion handler, e.g. when the measured event
/// crosses multiple classes, you can use the BenchEvent tools
///
/// // in one class
/// let message = getMessage()
/// BenchEventStart(title: "message sending", eventId: message.id)
///
/// ...
///
/// // in another class
/// BenchEventComplete(title: "message sending", eventId: message.id)
///
/// Or in objc
///
/// [BenchManager startEventWithTitle:"message sending" eventId:message.id]
/// ...
/// [BenchManager startEventWithTitle:"message sending" eventId:message.id]
public func BenchEventStart(title: String, eventId: BenchmarkEventId) {
BenchAsync(title: title) { finish in
runningEvents[eventId] = Event(title: title, eventId: eventId, completion: finish)
}
}
public func BenchEventComplete(eventId: BenchmarkEventId) {
guard let event = runningEvents.removeValue(forKey: eventId) else {
Logger.debug("no active event with id: \(eventId)")
return
}
event.completion()
}
public typealias BenchmarkEventId = String
private struct Event {
let title: String
let eventId: BenchmarkEventId
let completion: () -> Void
}
private var runningEvents: [BenchmarkEventId: Event] = [:]
@objc
public class BenchManager: NSObject {
@objc
public class func startEvent(title: String, eventId: BenchmarkEventId) {
BenchEventStart(title: title, eventId: eventId)
}
@objc
public class func completeEvent(eventId: BenchmarkEventId) {
BenchEventComplete(eventId: eventId)
}
@objc
public class func benchAsync(title: String, block: (@escaping () -> Void) -> Void) {
BenchAsync(title: title, block: block)
}
@objc
public class func bench(title: String, block: () -> Void) {
Bench(title: title, block: block)
}
}

Loading…
Cancel
Save