Commit e3c5d1b0 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Fixed model reload errors

parent 32c80b7d
......@@ -49,8 +49,9 @@ def parse_scene(scene):
composite = set(scene.composite_states.keys())
for each in scene.states:
if each.is_composite():
statename = unicode(each).split()[0].lower() # Ignore via clause
try:
composite.remove(unicode(each).lower())
composite.remove(statename)
sub_state = generate(each, composite=True, nextstate=False)
if sub_state:
sub_state.reverse()
......@@ -267,8 +268,8 @@ def _state(symbol, recursive=True, nextstate=True, composite=False, **kwargs):
else:
# Generate code for a nested state
result = Indent()
result.extend(['STATE {};'.format(unicode(symbol)),
'SUBSTRUCTURE'])
result.append('STATE {};'.format(unicode(symbol).split()[0]))
result.append('SUBSTRUCTURE')
Indent.indent += 1
entry_points, exit_points = [], []
for each in symbol.nested_scene.start:
......
......@@ -327,6 +327,7 @@ def _terminator(ast, scene, parent, states):
for each in chain(state_ast.inputs, state_ast.connects):
render(each, scene=scene, parent=symbol, states=states)
break
symbol.nested_scene = ast.composite or ogAST.CompositeState()
elif ast.kind == 'join':
symbol = sdlSymbols.Join(parent, ast)
elif ast.kind in ('return', 'stop'):
......
......@@ -455,6 +455,8 @@ class Terminator(object):
# There can be several if terminator follows a floating label
# Note, this field is updated by the Helper.flatten function
self.possible_states = []
# optional composite state content (type CompositeState)
self.composite = None
def trace(self):
''' Debug output for terminators '''
......
......@@ -1681,6 +1681,13 @@ def composite_state(root, parent=None, context=None):
errors.extend(err)
warnings.extend(warn)
comp.content.states.append(newstate)
# Post-processing: check that all NEXTSTATEs have a corresponding STATE
for ns in [t.inputString.lower() for t in comp.terminators
if t.kind == 'next_state']:
if not ns in [s.lower() for s in
comp.mapping.viewkeys()] + ['-']:
errors.append('In composite state "{}": missing definition '
'of substate "{}"'.format(comp.statename, ns.upper()))
return comp, errors, warnings
......@@ -2809,6 +2816,7 @@ def decision(root, parent, context):
def nextstate(root, context):
''' Parse a NEXTSTATE [VIA State_Entry_Point] '''
next_state_id, via, entrypoint = '', None, None
errors = []
for child in root.getChildren():
if child.type == lexer.ID:
next_state_id = child.text
......@@ -2824,25 +2832,24 @@ def nextstate(root, context):
if comp.statename.lower()
== next_state_id.lower())
except ValueError:
raise TypeError('State {} is not a composite state'
errors.append('State {} is not a composite state'
.format(next_state_id))
else:
if entrypoint.lower() not in composite.state_entrypoints:
raise TypeError('State {s} has no "{p}" entrypoint'
.format(s=next_state_id, p=entrypoint))
errors.append('State {s} has no "{p}" entrypoint'
.format(s=next_state_id, p=entrypoint))
for each in composite.content.named_start:
if each.inputString == entrypoint.lower() + '_START':
break
else:
raise TypeError('Entrypoint {p} in state {s} is '
'declared but not defined'.format
(s=next_state_id, p=entrypoint))
errors.append('Entrypoint {p} in state {s} is '
'declared but not defined'.format
(s=next_state_id, p=entrypoint))
else:
raise TypeError('"History" NEXTSTATE'
' cannot have a "via" clause')
errors.append('"History" NEXTSTATE cannot have a "via" clause')
else:
raise TypeError('NEXTSTATE undefined construct')
return next_state_id, via, entrypoint
errors.append('NEXTSTATE undefined construct')
return next_state_id, via, entrypoint, errors
def terminator_statement(root, parent, context):
......@@ -2864,15 +2871,21 @@ def terminator_statement(root, parent, context):
lab.terminators = [t]
elif term.type == lexer.NEXTSTATE:
t.kind = 'next_state'
try:
t.inputString, t.via, t.entrypoint = nextstate(term, context)
except TypeError as err:
errors.append(str(err))
t.inputString, t.via, t.entrypoint, err = nextstate(term, context)
if err:
errors.extend(err)
t.line = term.getChild(0).getLine()
t.charPositionInLine = term.getChild(0).getCharPositionInLine()
# Add next state infos at process level
# Used in rendering backends to merge a NEXTSTATE with a STATE
context.terminators.append(t)
# post-processing: if nextatate is nested, add link to the content
# (normally handled at state level, but if state is not defined
# standalone, the nextstate must hold the composite content)
if t.inputString != '-':
for each in context.composite_states:
if each.statename.lower() == t.inputString.lower():
t.composite = each
elif term.type == lexer.JOIN:
t.kind = 'join'
t.inputString = term.getChild(0).toString()
......
......@@ -377,7 +377,7 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
for each in self.states:
if each.is_composite() and \
each.nested_scene not in self._composite_states.viewvalues():
self._composite_states[unicode(each).lower()] = \
self._composite_states[unicode(each).split()[0].lower()] = \
each.nested_scene
return self._composite_states
......
......@@ -647,7 +647,7 @@ class State(VerticalSymbol):
def allow_nesting(self):
''' Redefinition - must be checked according to context '''
result = not any(elem in unicode(self).lower().strip()
for elem in ('-', ',', '*', ' '))
for elem in ('-', ',', '*'))
return result
@property
......@@ -658,7 +658,7 @@ class State(VerticalSymbol):
def double_click(self):
''' Catch a double click - Set nested scene '''
for each, value in self.scene().composite_states.viewitems():
if unicode(self).lower() == unicode(each):
if unicode(self).split()[0].lower() == unicode(each):
self.nested_scene = value
break
else:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment