diff --git a/source/sayAllHandler.py b/source/sayAllHandler.py index ff4b5884b7e..ae49cfccc22 100644 --- a/source/sayAllHandler.py +++ b/source/sayAllHandler.py @@ -3,6 +3,7 @@ # This file may be used under the terms of the GNU General Public License, version 2 or later. # For more details see: https://www.gnu.org/licenses/gpl-2.0.html +from typing import Optional import weakref import garbageHandler import speech @@ -17,9 +18,6 @@ from speech.commands import CallbackCommand, EndUtteranceCommand -speakWithoutPauses = speech.SpeechWithoutPauses(speakFunc=speech.speak).speakWithoutPauses - - CURSOR_CARET = 0 CURSOR_REVIEW = 1 @@ -28,6 +26,18 @@ #: This is a weakref because the manager should be allowed to die once say all is complete. _activeSayAll = lambda: None # Return None when called like a dead weakref. + +def getSpeechWithoutPauses() -> "speech.SpeechWithoutPauses": + """Returns an instance of `speech.SpeechWithoutPauses` which should be used for say all + creating it if necessary.""" + if getSpeechWithoutPauses.speechWithoutPausesInstance is None: + getSpeechWithoutPauses.speechWithoutPausesInstance = speech.SpeechWithoutPauses(speakFunc=speech.speak) + return getSpeechWithoutPauses.speechWithoutPausesInstance + + +getSpeechWithoutPauses.speechWithoutPausesInstance: Optional["speech.SpeechWithoutPauses"] = None + + def stop(): active = _activeSayAll() if active: @@ -154,7 +164,7 @@ def nextLine(self): if isinstance(self.reader.obj, textInfos.DocumentWithPageTurns): # Once the last line finishes reading, try turning the page. cb = CallbackCommand(self.turnPage, name="say-all:turnPage") - speakWithoutPauses([cb, EndUtteranceCommand()]) + getSpeechWithoutPauses().speakWithoutPauses([cb, EndUtteranceCommand()]) else: self.finish() return @@ -186,7 +196,7 @@ def _onLineReached(obj=self.reader.obj, state=state): seq = list(speech._flattenNestedSequences(speechGen)) seq.insert(0, cb) # Speak the speech sequence. - spoke = speakWithoutPauses(seq) + spoke = getSpeechWithoutPauses().speakWithoutPauses(seq) # Update the textInfo state ready for when speaking the next line. self.speakTextInfoState = state.copy() @@ -208,7 +218,7 @@ def _onLineReached(obj=self.reader.obj, state=state): else: # We don't want to buffer too much. # Force speech. lineReached will resume things when speech catches up. - speakWithoutPauses(None) + getSpeechWithoutPauses().speakWithoutPauses(None) # The first buffered line has now started speaking. self.numBufferedLines -= 1 @@ -245,7 +255,7 @@ def finish(self): # we might switch synths too early and truncate the final speech. # We do this by putting a CallbackCommand at the start of a new utterance. cb = CallbackCommand(self.stop, name="say-all:stop") - speakWithoutPauses([ + getSpeechWithoutPauses().speakWithoutPauses([ EndUtteranceCommand(), cb, EndUtteranceCommand() diff --git a/source/speech/__init__.py b/source/speech/__init__.py index befd122ebfe..cefdd72e2fe 100755 --- a/source/speech/__init__.py +++ b/source/speech/__init__.py @@ -117,7 +117,7 @@ def cancelSpeech(): # Import only for this function to avoid circular import. import sayAllHandler sayAllHandler.stop() - _speakWithoutPauses.reset() + sayAllHandler.getSpeechWithoutPauses().reset() if beenCanceled: return elif speechMode==speechMode_off: @@ -2534,9 +2534,6 @@ def _getSpeech( return finalSpeechSequence -_speakWithoutPauses = SpeechWithoutPauses(speakFunc=speak) - - #: The singleton _SpeechManager instance used for speech functions. #: @type: L{manager.SpeechManager} _manager = manager.SpeechManager()