Commit 78970185 authored by Maxime Perrotin's avatar Maxime Perrotin

Add procedure call display in MSC

parent d3a0f87e
......@@ -82,6 +82,11 @@ class AddToMsc(QUndoCommand):
y=handler.next_y,
label=message)
self.increase_factor = 40
elif direction == 'procedure_call':
# Local procedure call: an arrow from and to the same instance
self.item = handler.msc_scene.addProcedure(handler.taste_instance,
y=handler.next_y,
label=message)
#self.item.hide()
# This is how to add a comment on the graph:
# comment = handler.msc_scene.addComment(msg)
......
......@@ -21,6 +21,7 @@ from mscgraphics import MscGraphBasicMSCScene
from mscgraphics import MscGraphMessage
from mscgraphics import MscGraphCondition
from mscgraphics import MscGraphTimer
from mscgraphics import MscGraphProcedure
from collections import deque
from msccore import mscregexp
......@@ -41,10 +42,12 @@ class MscStreamingScene(MscGraphBasicMSCScene):
self.max_items = 30
self.globalDiff = 0
@Slot(int)
def setLimit(self, limit):
self.max_items = limit
#**************************************************************************
# Add Items Functions
#**************************************************************************
......@@ -69,6 +72,7 @@ class MscStreamingScene(MscGraphBasicMSCScene):
self.streamingControl(rst)
return rst
@Slot(MscGraphInstance, float, str)
def addCondition(self, instance, y=None, label=''):
''' Add new "condition" in streaming mode '''
......@@ -77,6 +81,7 @@ class MscStreamingScene(MscGraphBasicMSCScene):
self.streamingControl(rst)
return rst
def addTimer(self, instance, y, label=''):
''' Add timer (set, reset, timeout) '''
y = y - self.globalDiff
......@@ -85,24 +90,37 @@ class MscStreamingScene(MscGraphBasicMSCScene):
self.streamingControl(rst)
return rst
@Slot(MscGraphInstance, float, str)
def addSetTimer(self, instance, y=None, label=''):
''' Add a new SET TIMER symbol in streaming mode '''
self.setItemType(MscTimer.StartTimer)
return self.addTimer(instance, y, label)
@Slot(MscGraphInstance, float, str)
def addTimeout(self, instance, y=None, label=''):
''' Add a new TIMEOUT symbol in streaming mode '''
self.setItemType(MscTimer.TimeOut)
return self.addTimer(instance, y, label)
@Slot(MscGraphInstance, float, str)
def addResetTimer(self, instance, y=None, label=''):
''' Add a new RESET TIMER symbol in streaming mode '''
self.setItemType(MscTimer.StopTimer)
return self.addTimer(instance, y, label)
@Slot(MscGraphInstance, float, str)
def addProcedure(self, instance, y=None, label=''):
''' Add new "procedure call" in streaming mode '''
y = y - self.globalDiff
rst = super(MscStreamingScene, self).addProcedure(instance, y, label)
self.streamingControl(rst)
return rst
def removeGenericItem(self, item):
''' Call the remove function depending on the type of the item '''
if isinstance(item, MscGraphMessage):
......@@ -111,6 +129,8 @@ class MscStreamingScene(MscGraphBasicMSCScene):
self.removeCondition(item)
elif isinstance(item, MscGraphTimer):
self.removeTimer(item)
elif isinstance(item, MscGraphProcedure):
self.removeProcedure(item)
else:
pass
......
......@@ -650,6 +650,7 @@ class sdlHandler(QObject):
as_bytes.contents[idx] = \
ASN1.DV.byte_SWIG_PTR_getitem(swig_ptr, idx)
self.add_to_msc('procedure_call', '{}'.format(name))
# At the end, delete allocated buffers
for _, asn1_instance in interface['in']:
del(asn1_instance)
......
This short document explains how to extend the MSC streaming interface.
The MSC (Message Sequence Charts) are produced on the fly during simulation or
execution of a TASTE system, thanks to the streaming API of the MSC Editor.
The client application is for example the SDL handler (sdlHandler.py). It can
emit Qt signals (see "self.msc.emit(direction, msg, undo_stack)") that are
eventually sent to the MSC Handler (mscHandler.py), class AddToMsc.
In this class, there is a test of the "direction" argument, which ends up
adding the corresponding symbol to the MSC sceme.
For example:
if direction == 'set':
self.item = handler.msc_scene.addSetTimer(handler.taste_instance,
handler.next_y,
message)
If you want to add a symbol to the MSC scene to support a wider range of the
MSC standard, that is the place to start - add a branch, then we will implement
step by step the code that will effectively add the symbol on the diagram.
Let's add the symbol of a procedure call, which is an arrow starting
from an MSC instance and ending to the same instance:
elif direction == 'procedure_call':
self.item = handler.msc_scene.addProcedure(handler.taste_instance,
y=handler.next_y,
label=message)
Now we have to implement this "addProcedure" function in the msc_scene.
This is defined in file mscStreamingScene.py, in class MscStreamingScene.
Add a slot here (below the other addXXXX functions) - mimick the existing ones
@Slot(MscGraphInstance, float, str)
def addProcedure(self, instance, y=None, label=''):
''' Add new "procedure call" in streaming mode '''
y = y - self.globalDiff
rst = super(MscStreamingScene, self).addProcedure(instance, y, label)
self.streamingControl(rst)
return rst
There is also a function called "removeGenericItem", that you must extend
(this is needed for the Undo function):
def removeGenericItem(self, item):
''' Call the remove function depending on the type of the item '''
if isinstance(item, MscGraphMessage):
....
elif isinstance(item, MscGraphProcedure): # Add these two lines
self.removeProcedure(item)
else:
pass
At this point we have introduced three new elements that need to be defined:
MscGraphProcedure, addProcedure and removeProcedure. The last two are to be
defined at the parent class.
Import MscGraphProcedure it at the top of the file:
from mscgraphics import MscGraphProcedure
There are no other additions to be made on this file. We must now extend
the MscGraphBasicMscScene to implement the the two new functions.
This class is defined in the pymsc Python module (in TASTE repos)
More precisely in pymsc/mscgraphics/basicmscgraph/mscGraphBasicMSCScene.py
Add an import:
from mscGraphProcedure import MscGraphProcedure
And add a section to handle the new symbol creation and deletion:
#--------------- Local Procedure Call
def addProcedure(self, instance, y=None, label=''):
u"""
Add new "Procedure call " to the scene and position it in y pos if any
"""
procedure = MscGraphProcedure(label=label, y=y,
parent=self.bmsc(), instance=instance)
instance.addEvent(procedure)
if y is not None:
procedure.setY(instance.mapFromScene(0, y).y())
procedure.itemSelected.connect(self.itemSelected)
self.itemInserted.emit(procedure)
return condition
def removeProcedure(self, procedure):
procedure.delete()
if procedure.scene():
self.removeItem(procedure)
Now we have to define the MscGraphProcedure class.
In the same directory, create a new file "mscGraphProcedure.py" (copy the
one of an existing symbol and edit it - differences are usually minor).
At the begining of the file you must import a class (to be implemented):
from msccore import MscProcedure # replace Procedure with your symbol name
Then if you copied the class from another symbol, don't forget to rename it:
class MscGraphProcedure(MscGraphItem):
...
(In general it may be good to make a global search and replace of the old
class name: %s,MscGraphCondition,MscGraphProcedure,g in vim)
Then the main change to do in this function is to implement the "createPath"
function, which defines the graphical shape of your symbol:
def createPath(self):
u"""
Create the path of the Procedure Call symbol
"""
self.path = QPainterPath()
self.path.moveTo(0, 0)
self.path.lineTo(self.DefaultWidth, 0)
self.path.lineTo(self.DefaultWidth, self.DefaultHeight)
self.path.lineTo(0, self.DefaultHeight)
self.path.moveTo(5, self.DefaultHeight - 5)
self.path.lineTo(0, self.DefaultHeight)
self.path.lineTo(5, self.DefaultHeight + 5)
self.updateBounding()
You can browse through the other parts of this class and check if anything
has to be tuned for your symbol but usually that's not the case.
Last we need to create the MscProcedure class, which has to be placed in:
pymsc/msccore
As before copy an existing class (e.g. msccondition.py) and edit it. By default
just renaming the name of the symbol you copied is sufficient.
Finally you must update two __init__.py files to reflect the class you created:
pymsc/mscgraphics/basicmscgraph/__init__.py and add the import of your new
component:
from mscGraphProcedure import MscGraphProcedure
and same in pymsc/msccore/__init__.py:
from mscprocedure import MscProcedure
That's it! Next you may want to support the saving and parsing of the newly
created symbol. You can check how it is done for other symbols and copy the
structure.
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