Change the write side into a series of short running operations rather than a single operation looping while listening.
This commit is contained in:
parent
c61b9c0729
commit
b732007d68
|
@ -68,8 +68,8 @@ class GSConnection : ObservableObject {
|
||||||
private let writeQueue = OperationQueue()
|
private let writeQueue = OperationQueue()
|
||||||
private var mainQueue = OperationQueue.main
|
private var mainQueue = OperationQueue.main
|
||||||
|
|
||||||
private var condition = NSCondition()
|
|
||||||
private var canSend = true
|
private var canSend = true
|
||||||
|
private var lastSent = ""
|
||||||
|
|
||||||
private func changeState(newState : GSConnectionState)
|
private func changeState(newState : GSConnectionState)
|
||||||
{
|
{
|
||||||
|
@ -154,10 +154,10 @@ class GSConnection : ObservableObject {
|
||||||
do {
|
do {
|
||||||
let unpacked = try unpack("<h", data)
|
let unpacked = try unpack("<h", data)
|
||||||
if (unpacked[0] as? Int == GSConnection.LISTEN_SEND_MORE) {
|
if (unpacked[0] as? Int == GSConnection.LISTEN_SEND_MORE) {
|
||||||
condition.lock()
|
mainQueue.addOperation {
|
||||||
canSend = true
|
self.canSend = true
|
||||||
condition.broadcast()
|
self.trySend()
|
||||||
condition.unlock()
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("Unexpected message on socket from \(self.destination)")
|
logger.error("Unexpected message on socket from \(self.destination)")
|
||||||
errorOccurred(title: "Protocol Error", message: "Unexpected message from the GS")
|
errorOccurred(title: "Protocol Error", message: "Unexpected message from the GS")
|
||||||
|
@ -193,13 +193,10 @@ class GSConnection : ObservableObject {
|
||||||
stopListening()
|
stopListening()
|
||||||
}
|
}
|
||||||
|
|
||||||
condition.lock()
|
|
||||||
if (client != nil) {
|
if (client != nil) {
|
||||||
client!.close()
|
client!.close()
|
||||||
self.client = nil
|
self.client = nil
|
||||||
}
|
}
|
||||||
condition.broadcast()
|
|
||||||
condition.unlock()
|
|
||||||
|
|
||||||
waitForWriteQueue()
|
waitForWriteQueue()
|
||||||
waitForReadQueue()
|
waitForReadQueue()
|
||||||
|
@ -212,12 +209,11 @@ class GSConnection : ObservableObject {
|
||||||
speechForwarder.stopListening()
|
speechForwarder.stopListening()
|
||||||
self.speechForwarder = nil
|
self.speechForwarder = nil
|
||||||
}
|
}
|
||||||
condition.lock()
|
|
||||||
if (state == .listening) {
|
if (state == .listening) {
|
||||||
changeState(newState: .stoplistening)
|
changeState(newState: .stoplistening)
|
||||||
condition.broadcast()
|
trySend()
|
||||||
}
|
}
|
||||||
condition.unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func sendListenMsg(isListening: Bool) -> Bool {
|
private func sendListenMsg(isListening: Bool) -> Bool {
|
||||||
|
@ -236,6 +232,7 @@ class GSConnection : ObservableObject {
|
||||||
|
|
||||||
func listen(speechForwarder: SpeechForwarderProtocol) {
|
func listen(speechForwarder: SpeechForwarderProtocol) {
|
||||||
textHeard = ""
|
textHeard = ""
|
||||||
|
lastSent = ""
|
||||||
writeQueue.addOperation {
|
writeQueue.addOperation {
|
||||||
if (!self.sendListenMsg(isListening: true)) {
|
if (!self.sendListenMsg(isListening: true)) {
|
||||||
self.errorOccurred(title: "Write Error", message: "Unable to send data to the GS")
|
self.errorOccurred(title: "Write Error", message: "Unable to send data to the GS")
|
||||||
|
@ -252,57 +249,39 @@ class GSConnection : ObservableObject {
|
||||||
}
|
}
|
||||||
self.speechForwarder = speechForwarder
|
self.speechForwarder = speechForwarder
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.send()
|
}
|
||||||
|
|
||||||
_ = self.sendListenMsg(isListening: false)
|
private func trySend() {
|
||||||
|
if (textHeard == lastSent) {
|
||||||
self.mainQueue.addOperation {
|
if (state == .stoplistening) {
|
||||||
if (self.state == .stoplistening) {
|
writeQueue.addOperation {
|
||||||
self.changeState(newState: .connected)
|
_ = self.sendListenMsg(isListening: false)
|
||||||
|
}
|
||||||
|
changeState(newState: .connected)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!canSend) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
canSend = false
|
||||||
|
let stringToSend = textHeard
|
||||||
|
writeQueue.addOperation {
|
||||||
|
if self.send(latestText: stringToSend, lastSent: self.lastSent) {
|
||||||
|
self.mainQueue.addOperation {
|
||||||
|
self.lastSent = stringToSend
|
||||||
|
self.trySend()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func set(text:String)
|
func set(text:String) {
|
||||||
{
|
|
||||||
condition.lock()
|
|
||||||
textHeard = text
|
textHeard = text
|
||||||
condition.broadcast()
|
trySend()
|
||||||
condition.unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func send() {
|
|
||||||
var stringLastSent = ""
|
|
||||||
var stringToSend = ""
|
|
||||||
|
|
||||||
while true {
|
|
||||||
condition.lock()
|
|
||||||
guard client != nil else {
|
|
||||||
condition.unlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ((stringLastSent == textHeard) && (state == .stoplistening)) {
|
|
||||||
condition.unlock()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ((!canSend) ||
|
|
||||||
(stringLastSent == textHeard)) {
|
|
||||||
condition.wait()
|
|
||||||
condition.unlock()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
stringToSend = textHeard
|
|
||||||
condition.unlock()
|
|
||||||
|
|
||||||
if send(latestText: stringToSend, lastSent: stringLastSent) {
|
|
||||||
stringLastSent = stringToSend
|
|
||||||
condition.lock()
|
|
||||||
canSend = false
|
|
||||||
condition.unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func send(latestText : String, lastSent: String) -> Bool {
|
private func send(latestText : String, lastSent: String) -> Bool {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.0</string>
|
<string>1.0</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>598</string>
|
<string>619</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.utilities</string>
|
<string>public.app-category.utilities</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
|
|
@ -80,7 +80,6 @@ struct Webview: UIViewRepresentable {
|
||||||
decisionHandler(WKNavigationActionPolicy.cancel)
|
decisionHandler(WKNavigationActionPolicy.cancel)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
print("no link")
|
|
||||||
decisionHandler(WKNavigationActionPolicy.allow)
|
decisionHandler(WKNavigationActionPolicy.allow)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,9 +103,10 @@ class ListenerGSTests: XCTestCase {
|
||||||
XCTAssertEqual(connection.textHeard, "Hello, everyone!")
|
XCTAssertEqual(connection.textHeard, "Hello, everyone!")
|
||||||
|
|
||||||
XCTAssert(server.sendMore())
|
XCTAssert(server.sendMore())
|
||||||
|
connection.waitForMain()
|
||||||
|
connection.waitForWriteQueue()
|
||||||
XCTAssertEqual(server.getText(), "\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}everyone!")
|
XCTAssertEqual(server.getText(), "\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}everyone!")
|
||||||
|
|
||||||
connection.waitForWriteQueue()
|
|
||||||
connection.waitForMain()
|
connection.waitForMain()
|
||||||
XCTAssert(server.getListenState(isListening: false))
|
XCTAssert(server.getListenState(isListening: false))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue