Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions ovos_workshop/skills/common_play.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,14 +392,15 @@ def play_media(self, media, disambiguation=None, playlist=None):

# @killable_event("ovos.common_play.stop", react_to_stop=True)
def __handle_ocp_play(self, message):
self.activate()
self._playing.set()
self._paused.clear()
if self.__playback_handler:
params = signature(self.__playback_handler).parameters
kwargs = {"message": message} if "message" in params else {}
self.__playback_handler(**kwargs)
self.bus.emit(Message("ovos.common_play.player.state",
{"state": PlayerState.PLAYING}))
self._playing.set()
self._paused.clear()
else:
LOG.error(f"Playback requested but {self.skill_id} handler not "
"implemented")
Expand All @@ -417,6 +418,7 @@ def __handle_ocp_pause(self, message):
"implemented")

def __handle_ocp_resume(self, message):
self.activate()
self._paused.clear()
if self.__resume_handler:
params = signature(self.__playback_handler).parameters
Expand Down
47 changes: 32 additions & 15 deletions ovos_workshop/skills/game_skill.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,14 @@ def stop(self) -> bool:
return True
return False

def calc_intent(self, utterance: str, lang: str) -> Optional[Dict[str, str]]:
def calc_intent(self, utterance: str, lang: str, timeout=1.0) -> Optional[Dict[str, str]]:
"""helper to check what intent would be selected by ovos-core"""
# let's see what intent ovos-core will assign to the utterance
# NOTE: converse, common_query and fallbacks are not included in this check
response = self.bus.wait_for_response(Message("intent.service.intent.get",
{"utterance": utterance, "lang": lang}),
"intent.service.intent.reply",
timeout=1.0)
timeout=timeout)
if not response:
return None
return response.data["intent"]
Expand Down Expand Up @@ -183,7 +183,6 @@ def on_game_command(self, utterance: str, lang: str):
don't forget to self.speak the game output too!
"""

@abc.abstractmethod
def on_abandon_game(self):
"""user abandoned game mid interaction

Expand All @@ -193,7 +192,7 @@ def on_abandon_game(self):
on_game_stop will be called after this handler"""

# converse
def skill_will_trigger(self, utterance: str, lang: str, skill_id: Optional[str] = None) -> bool:
def skill_will_trigger(self, utterance: str, lang: str, skill_id: Optional[str] = None, timeout=0.8) -> bool:
"""helper to check if this skill would be selected by ovos-core with the given utterance

useful in converse method
Expand All @@ -205,7 +204,7 @@ def skill_will_trigger(self, utterance: str, lang: str, skill_id: Optional[str]
# determine if an intent from this skill
# will be selected by ovos-core
id_to_check = skill_id or self.skill_id
intent = self.calc_intent(utterance, lang)
intent = self.calc_intent(utterance, lang, timeout=timeout)
skill_id = intent["skill_id"] if intent else ""
return skill_id == id_to_check

Expand All @@ -221,26 +220,44 @@ def _autosave(self):
if self.settings.get("auto_save", False) and self.save_is_implemented:
self.on_save_game()

def converse(self, message: Message):
def _async_cmd(self, message: Message):
utterance = message.data["utterances"][0]
lang = get_message_lang(message)
self.log.debug(f"Piping utterance to game: {utterance}")
self.on_game_command(utterance, lang)

def converse(self, message: Message) -> bool:
try:
utterance = message.data["utterances"][0]
lang = get_message_lang(message)
# let the user implemented intents do the job if they can handle the utterance
# otherwise pipe utterance to the game handler
if self.skill_will_trigger(utterance, lang):
self.log.debug("Skill intent will trigger, don't pipe utterance to game")
return False

if self.is_paused:
self.log.debug("game is paused")
# let ocp_pipeline unpause as appropriate
return False

self._autosave()
utterance = message.data["utterances"][0]
lang = get_message_lang(message)
# let the user implemented intents do the job if they can handle the utterance
if self.is_playing and not self.skill_will_trigger(utterance, lang):
# otherwise pipe utterance to the game handler
self.on_game_command(utterance, lang)
try:
self._autosave()
except Exception as e:
self.log.error(f"Autosave failed: {e}")

if self.is_playing:
# do this async so converse executes faster
self.bus.once(f"{self.skill_id}.game_cmd", self._async_cmd)
self.bus.emit(message.forward(f"{self.skill_id}.game_cmd", message.data))
return True

return False
except (KeyError, IndexError) as e:
self.log.error(f"Error processing converse message: {e}")
self.log.error(f"Error processing game converse message: {e}")
return False
except Exception as e:
self.log.exception(f"Unexpected error in converse: {e}")
self.log.exception(f"Unexpected error in game converse: {e}")
return False

def handle_deactivate(self, message: Message):
Expand Down