// Speech history helpers. // Provides a reusable speak_with_history wrapper and key navigation. string[] speechHistory; int speechHistoryMaxEntries = 10; int speechHistoryCurrentIndex = -1; bool speechHistoryDeduplicate = true; funcdef string speech_history_message_transform_callback(const string& in message); speech_history_message_transform_callback @speechHistoryMessageTransform = null; void speech_history_set_message_transform_callback(speech_history_message_transform_callback @callback) { @speechHistoryMessageTransform = @callback; } string speech_history_transform_message(const string& in message) { if (@speechHistoryMessageTransform is null) return message; return speechHistoryMessageTransform(message); } void speech_history_set_max_entries(int maxEntries) { if (maxEntries < 1) { maxEntries = 1; } speechHistoryMaxEntries = maxEntries; while (speechHistory.length() > uint(speechHistoryMaxEntries)) { speechHistory.remove_at(0); } if (speechHistory.length() == 0) { speechHistoryCurrentIndex = -1; } else if (speechHistoryCurrentIndex >= int(speechHistory.length())) { speechHistoryCurrentIndex = speechHistory.length() - 1; } } void speech_history_clear() { speechHistory.resize(0); speechHistoryCurrentIndex = -1; } void speech_history_set_deduplicate(bool deduplicate) { speechHistoryDeduplicate = deduplicate; } void speech_history_add(const string& in message) { if (message == "") { return; } if (speechHistoryDeduplicate) { for (uint messageIndex = 0; messageIndex < speechHistory.length(); messageIndex++) { if (speechHistory[messageIndex] == message) { speechHistoryCurrentIndex = messageIndex; return; } } } speechHistory.insert_last(message); while (speechHistory.length() > uint(speechHistoryMaxEntries)) { speechHistory.remove_at(0); } speechHistoryCurrentIndex = speechHistory.length() - 1; } void speak_with_history(const string& in message, bool interrupt) { string transformedMessage = speech_history_transform_message(message); speech_history_add(transformedMessage); screen_reader_speak(transformedMessage, interrupt); } void check_speech_history_keys() { // Comma: older. if (key_pressed(KEY_COMMA)) { if (speechHistory.length() == 0) { screen_reader_speak(speech_history_transform_message("No speech history."), true); return; } speechHistoryCurrentIndex--; if (speechHistoryCurrentIndex < 0) { speechHistoryCurrentIndex = 0; screen_reader_speak( speech_history_transform_message("Oldest message. " + speechHistory[speechHistoryCurrentIndex]), true); return; } int position = speechHistoryCurrentIndex + 1; screen_reader_speak(speech_history_transform_message(speechHistory[speechHistoryCurrentIndex] + " " + position + " of " + speechHistory.length()), true); return; } // Period: newer. if (key_pressed(KEY_PERIOD)) { if (speechHistory.length() == 0) { screen_reader_speak(speech_history_transform_message("No speech history."), true); return; } speechHistoryCurrentIndex++; if (speechHistoryCurrentIndex >= int(speechHistory.length())) { speechHistoryCurrentIndex = speechHistory.length() - 1; screen_reader_speak( speech_history_transform_message("Newest message. " + speechHistory[speechHistoryCurrentIndex]), true); return; } int position = speechHistoryCurrentIndex + 1; screen_reader_speak(speech_history_transform_message(speechHistory[speechHistoryCurrentIndex] + " " + position + " of " + speechHistory.length()), true); } } string speech_history_latest() { if (speechHistory.length() == 0) { return ""; } return speechHistory[speechHistory.length() - 1]; }