From ebf0d1ebadd5623edc7b8c5c03d7ad0260170dc2 Mon Sep 17 00:00:00 2001 From: Ruben van de Ven Date: Sun, 28 Apr 2019 11:34:30 +0200 Subject: [PATCH] Prevent diversions after chapter has been played --- hugvey/central_command.py | 1 - hugvey/story.py | 19 +++++++++++++++++++ www/js/hugvey_console.js | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/hugvey/central_command.py b/hugvey/central_command.py index 770d094..cdb20ca 100644 --- a/hugvey/central_command.py +++ b/hugvey/central_command.py @@ -633,7 +633,6 @@ class HugveyState(object): self.isConfigured = None self.setStatus(self.STATE_GONE) - def shutdown(self, definitive = False): self.logger.info(f"Start shutdown sequence {definitive}") self.eventLogger.critical(f"error: shutting down") diff --git a/hugvey/story.py b/hugvey/story.py index 3f19c32..dd63e3c 100644 --- a/hugvey/story.py +++ b/hugvey/story.py @@ -14,6 +14,7 @@ from zmq.asyncio import Context import zmq import wave from pythonosc import udp_client +from builtins import isinstance mainLogger = logging.getLogger("hugvey") logger = mainLogger.getChild("narrative") @@ -521,6 +522,16 @@ class Diversion(object): Validate if condition is met for the current story state Returns True when diverging """ + + # For all diversion except repeat (which simply doesn't have the variable) + if 'notAfterMsgId' in self.params and self.params['notAfterMsgId']: + msg = story.get(self.params['notAfterMsgId']) + if msg is None: + story.logger.warn(f"Invalid message selected for diversion: {self.params['notAfterMsgId']} for {self.id}") + elif story.logHasMsg(msg): +# story.logger.warn(f"Block diversion {self.id} because of hit message {self.params['notAfterMsgId']}") + return False + r = await self.method(story, msgFrom, msgTo) if r: self.hasHit = True @@ -784,6 +795,7 @@ class Story(object): self.events = [] # queue of received events self.commands = [] # queue of commands to send self.log = [] # all nodes/elements that are triggered + self.msgLog = [] # hit messages self.logger = mainLogger.getChild(f"{self.hugvey.id}").getChild("story") self.currentMessage = None self.currentDiversion = None @@ -902,6 +914,7 @@ class Story(object): self.events = [] # queue of received events self.commands = [] # queue of commands to send self.log = [] # all nodes/elements that are triggered + self.msgLog = [] self.currentReply = None self.stats = { @@ -1087,6 +1100,9 @@ class Story(object): def addToLog(self, node): self.log.append((node, self.timer.getElapsed())) + if isinstance(node, Message): + self.msgLog.append(node) + if self.hugvey.recorder: if isinstance(node, Message): self.hugvey.recorder.log('hugvey', node.text, node.id) @@ -1094,6 +1110,9 @@ class Story(object): self.hugvey.recorder.log('diversion',node.id) if isinstance(node, Condition): self.hugvey.recorder.log('condition',node.logInfo, node.id) + + def logHasMsg(self, node): + return node in self.msgLog async def _renderer(self): """ diff --git a/www/js/hugvey_console.js b/www/js/hugvey_console.js index 46c8f3d..ae09262 100644 --- a/www/js/hugvey_console.js +++ b/www/js/hugvey_console.js @@ -382,6 +382,10 @@ class Graph { alert('invalid type for diversion'); } + if(type != 'repeat') { + div['params']['notAfterMsgId'] = ""; + } + this.data.push( div ); this.updateFromData(); this.build(); @@ -401,6 +405,27 @@ class Graph { let divsNoResponse =[], divsRepeat = [], divsReplyContains = [], divsTimeouts = []; for(let div of this.diversions) { + + let notAfterMsgIdEl = ""; + if(div['type'] != 'repeat') { + let notMsgOptions = [crel('option',"")]; + let chapterMsgs = this.messages.filter( m => m.hasOwnProperty('chapterStart') && m['chapterStart'] == true); + for(let startMsg of chapterMsgs) { + let optionParams = { + 'value': startMsg['@id'] + }; + if(div['params']['notAfterMsgId'] == startMsg['@id']) { + optionParams['selected'] = 'selected'; + } + notMsgOptions.push(crel('option', optionParams , `${startMsg['text']} (${startMsg['@id']})`)); + } + notAfterMsgIdEl = crel('label', 'Not when chapter has hit:', + crel('select', {'on': { + 'change': (e) => div['params']['notAfterMsgId'] = e.target.value + }}, ...notMsgOptions) + ); + } + if(div['type'] == 'no_response') { let returnAttrs = { 'type': 'checkbox', @@ -468,7 +493,8 @@ class Graph { crel('select', {'on': { 'change': (e) => div['params']['msgId'] = e.target.value }}, ...msgOptions) - ) + ), + notAfterMsgIdEl )); } if(div['type'] == 'reply_contains') { @@ -544,7 +570,8 @@ class Graph { crel('select', {'on': { 'change': (e) => div['params']['msgId'] = e.target.value }}, ...msgOptions) - ) + ), + notAfterMsgIdEl )); } if(div['type'] == 'timeout') { @@ -638,7 +665,8 @@ class Graph { crel('select', {'on': { 'change': (e) => div['params']['msgId'] = e.target.value }}, ...msgOptions) - ) + ), + notAfterMsgIdEl )); } if(div['type'] == 'repeat'){