diff -r 000000000000 -r dfb7c4ff071f commsfwtools/commstools/svg/collaboration.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/commsfwtools/commstools/svg/collaboration.pl Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,634 @@ +# Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# + +#!/usr/bin/perl + + +use strict; + +my %objectCoordinates = # pretty dumb. could smarten this up a lot. +( + "CSocket", [200,100], + "CSubConn", [400,100], + "CConn", [600,100], + "CCommsMgr", [800,100], + "CSelectionRequest", [1000,110], # NOT Tier Manager's sub-session hence offset + + "CFlowFactCtr", [100,150], + "CSubConnFactCtr", [300,150], + "CConnFactCtr", [500,150], + "CMetaConnFactCtr", [700,150], + "CTierMgrFactCtr", [900,150], + + + "CIPDefaultSCPrFact", [300,200], + "CIPCPrFact", [500,200], + "CNetMCPrFact", [700,200], + "CNetTierMgrFact", [900,200], + + "CIPDefaultSCPr", [400,250], + "CIPCPr", [600,250], + "CNetMCPr", [800,250], + "CNetTierMgr", [1000,250], + + + "CIPProtoSCPrFact", [300,300], + "CIPProtoCPrFact", [500,300], + "CIPProtoMCPrFact", [700,300], + "CIPProtoTierMgrFact", [900,300], + + "CIPProtoDefaultSCPr", [400,350], + "CIPProtoCPr", [600,350], + "CIPProtoMCPr", [800,350], + "CIPProtoTierMgr", [1000,350], + + + "CIPProtoDefaultSCPr-1", [400,400], + "CIPProtoCPr-1", [600,400], + + + "CPPPSCPrFact", [300,500], + "CPPPCPrFact", [500,500], + "CPPPMCPrFact", [700,500], + "CPPPTierMgrFact", [900,500], + + "CPPPSCPr", [400,550], + "CPPPCPr", [600,550], + "CPPPMCPr", [800,550], + "CPPPTierMgr", [1000,550], + +); + +# +# constants +# +my $incrementY = 20; +my $topMargin = 20; +my $arrowWidth = 10; +my $textArrowSpacing = 1; +my $messageSpacingAboveLine = 1; +my $objectVerticalLineSpacing = 2; +my $objectUnderlineToLifelineGap = 2; + +my $objectsPerRow = 4; +my $objectSpacesToSkipBeforeAutoSpacing = 4 * $objectsPerRow - 1; # start on 5th line +my $xSpacing = 200; +my $ySpacing = 100; + +my $objectName = 0; +my $objectX = 1; +my $objectY = 2; +my $objectMsgCount = 3; +my $objectCreationPointKnown = 4; + +my $sequenceAction = 0; +my $sequenceObjRef = 1; # if action == "t" || "oc" +my $sequenceMsgRef = 1; # if action != "t" +my $sequenceX = 2; +my $sequenceY = 3; + +my $anims = 1; +my $time = 0; +my $timeDelta = 500; +my $timeDur = $timeDelta * 0.9; + +my $colouredBoxes = 1; + +my $animKeys = '1234567890qwertyuiopasdfghjklzxcvbnm'; +#$animKeys = ''; # uncomment this line to enable animKeys +my $animMessagesPerKey = 5; +my $animKeyCounter = 0; +my $animKeysFirstElement=1; + +my @sequences; +my @messages; +my @objects; + +if(@ARGV && $ARGV[0] eq '-auto') +{ +shift; +$animKeys=''; +} + +# +# Data Structures: +# +# "objects" is array of arrays: +# [ ] +# +# "sequences" is an array of arrays: +# [ "t" \objects[] "text" ] +# [ "[p|r]" \messages[n] \objects[], \objects[] ] +# [ "oc" \objects[] ] + + +# Input file format: +# +# ... +# +# specifically: +# +# [P|R] +# T +# OC +# +# actions: +# +# P Post +# R Receive +# T Text +# OC Object Create +# +# All fields are space separated text. For example: +# +# P StartFlow SCPR Flow +# + +while (<>) { + die unless s/^(\w+)\s+//; + my $action = $1; + if ($action eq "t") + { + # Text + # t + my $pos; + if (s/^([\w\d-]+)\s+//) { $pos = $1; } + my $objRef = addObject($pos); + chomp; + my $text = $_; + push @sequences, [$action, $objRef, $text]; + } + elsif ($action eq "oc") + { + # Object Create + # oc + my $objName; + if (s/^([\w\d-]+)\s+//) { $objName = $1; } + my $objRef = addObject($objName); + ${$objRef}->[$objectCreationPointKnown] = 1; + chomp; + push @sequences, [$action, $objRef]; + } + else + { + # Post/Receive + # [P|R] + split; + my $msgRef = addMessage(shift @_); + my $srcRef = addObject(shift @_); + my $destRef = addObject(shift @_); + ${$srcRef}->[$objectMsgCount]++; + ${$destRef}->[$objectMsgCount]++; + push @sequences, [$action, $msgRef, $srcRef, $destRef]; + } + } + + +my ($screenWidth,$screenHeight) = calculateObjectPositions(); + +#my $screenWidth = $objects[$#objects]->[$objectX] + $rightMargin; +#my $screenHeight = scalar(@sequences) * ($incrementY + 2) + $topMargin; +#my $screenWidth = 500; +#my $screenHeight = 500; + +outputDocHeader($screenWidth, $screenHeight); + +drawObjectsAtTop(); + + +drawCollaborations(); + +outputDocFooter(); + +#################### +# Message routines +#################### + + +sub drawObjectsAtTop() + { + my $i; + foreach $i (@objects) + { + if ($i->[$objectCreationPointKnown] == 1) + { + next; + } + outputText($i->[$objectX], $i->[$objectName], $i->[$objectY], "middle", "underline","freeze",'',0); + } + print "\n"; + } + + +sub addMessage() + { + my $obj = $_[0]; + my $i; + for ($i = 0 ; $i < scalar(@messages) ; ++$i) { + if ($messages[$i] eq $obj) { + return \$messages[$i]; + } + } + $messages[$i] = $obj; + return \$messages[$i]; + } + +sub printMessages() + { + print "Messages (", scalar(@messages), ") : "; + foreach my $msg (@messages) { + print $msg, " "; + } + print "\n"; + } + +################### +# Object routines +################### + +sub addObject() + { + my $objName = $_[0]; + my $i; + for ($i = 0 ; $i < scalar(@objects) ; ++$i) { + if ($objects[$i]->[$objectName] eq $objName) { + return \$objects[$i]; + } + } + $objects[$i] = [ $objName, 0, 0, 0, 0 ]; + return \$objects[$i]; + } + +sub printObjects() + { + print "Objects (", scalar(@objects), "): "; + foreach my $obj (@objects) { + print $obj->[0], "(", $obj->[1], ") "; + } + print "\n"; + } + +sub calculateObjectPositions() + { + my ($maxX, $maxY) = (0,0); + + my $xSpacing = 200; + my $ySpacing = 100; + + my $objctr = $objectSpacesToSkipBeforeAutoSpacing; + my $i; + for ($i = 0 ; $i < scalar(@objects) ; ++$i) + { + my $coords = $objectCoordinates{$objects[$i][$objectName]}; + if(defined $coords) + { + ($objects[$i][$objectX],$objects[$i][$objectY]) = + ($coords->[0], $coords->[1]); + } + else + { + $objctr++; +# for($objctr = 0 ; $objctr < 50 ; $objctr++) +# { + my $x = (1+($objctr % $objectsPerRow)) * $xSpacing; + my $y = (1+int($objctr / $objectsPerRow)) * $ySpacing; + # print STDERR ("X $x Y $y\n"); + # } + # exit; +#my ($x,$y); + ($objects[$i][$objectX],$objects[$i][$objectY]) = + ($x, $y); + } + + if($objects[$i][$objectX] > $maxX) { $maxX = $objects[$i][$objectX];} + if($objects[$i][$objectY] > $maxY) { $maxY = $objects[$i][$objectY];} + + $objects[$i][$objectX] -= $xSpacing/2; + $objects[$i][$objectY] -= $ySpacing/2; + + print STDERR ("$i $objects[$i][$objectName] $objects[$i][$objectX] $objects[$i][$objectY]\n") + } +# die("$maxX $maxY"); + return ($maxX,$maxY); + } + +sub trimSilentObjects() + { + # get rid of objects that didn't end up with any messages sent to/from them + my $i; + for ($i = 0 ; $i < scalar(@objects) ; ) { + if ($objects[$i][$objectMsgCount] == 0) + { + my $j; + for ($j = 0 ; $j < scalar(@sequences) ; ) + { + my $action = $sequences[$j][$sequenceAction]; + if ( (($action eq "t") || ($action eq "oc")) && + ($sequences[$j][$sequenceObjRef] == \$objects[$i]) ) + { + splice @sequences, $j, 1; +#print "delete sequence $j\n"; +#++$j; + } + else + { + ++$j; + } + } + splice @objects, $i, 1; +#print "delete object $i $objects[$i][$objectName]\n"; +#++$i; + } + else + { + ++$i; + } + } + } + +sub drawObject($$$) + { + my ($x,$y,$name) = @_; + outputText($x, $name, $y, "middle", "underline","freeze",qq{opacity="0.9"},0); +# outputVerticalLine($x, $y + $objectUnderlineToLifelineGap, $screenHeight - $topOffset); + } + + + +sub drawCollaborations() + { + foreach my $ref (@sequences) { + my $action = $ref->[$sequenceAction]; + if ($action eq "t") + { + my $objX = ${$ref->[$sequenceObjRef]}->[$objectX]; + my $objY = ${$ref->[$sequenceObjRef]}->[$objectY] + $incrementY; + my $text = $ref->[2]; +print STDERR ("DRAWING $text $objX $objY\n"); + outputText($objX, $text, $objY, "middle", "", "freeze",qq{opacity="0.9"},0); + $time += $timeDelta/2; + } + elsif ($action eq "oc") + { +# if ($objectsDisplayedAtCreationPoint == 1) + { + my $objX = ${$ref->[$sequenceObjRef]}->[$objectX]; + my $objY = ${$ref->[$sequenceObjRef]}->[$objectY]; + my $objName = ${$ref->[$sequenceObjRef]}->[$objectName]; + drawObject($objX, $objY, $objName); + } + } + else + { + my $msg = ${$ref->[$sequenceObjRef]}; + my $srcX = ${$ref->[$sequenceX]}->[$objectX]; + my $srcY = ${$ref->[$sequenceX]}->[$objectY]; + my $destX = ${$ref->[$sequenceY]}->[$objectX]; + my $destY = ${$ref->[$sequenceY]}->[$objectY]; + my $align; + if ($action eq "p") { + $align = "tail"; + } + elsif ($action eq "r") { + $align = "head"; + } + outputLabelledLine($srcX, $srcY, $destX, $destY, $msg, $align); + + $time += $timeDelta; + + if($animKeys) + { + $animKeyCounter++; + if($animKeyCounter % $animMessagesPerKey == 0) + { + $time = 0; + $animKeysFirstElement=1; + } + } + + } + print "\n"; + } + } + + +####################### +# SVG output routines +####################### + +sub outputDocHeader() + { + my ($width,$height) = @_; + print '',"\n"; + print '',"\n"; + print "\n"; + outputDefs(); + } + +sub outputDefs() + { + print "\n"; + print qq{\n}; + print qq{\t\n}; + print "\n"; + print "\n"; + } + +sub outputDocFooter() + { + print "\n"; + } + +sub shortenLine($$$$$) +{ + my($x1,$y1,$x2,$y2,$amount) = @_; + + my $xdiff = $x1-$x2; + my $ydiff = $y1-$y2; + my $linelen = sqrt(($xdiff*$xdiff) + ($ydiff*$ydiff)); + my $factor = 1 - ($amount / ($linelen+1)); + + if($x2>$x1) + { + $amount = (1-$factor) * ($x2-$x1); + $x1 += $amount; + $x2 -= $amount; + } + else + { + $amount = (1-$factor) * ($x1-$x2); + $x1 -= $amount; + $x2 += $amount; + } + + if($y2>$y1) + { + $amount = (1-$factor) * ($y2-$y1); + $y1 += $amount; + $y2 -= $amount; + } + else + { + $amount = (1-$factor) * ($y1-$y2); + $y1 -= $amount; + $y2 += $amount; + } + + return ($x1,$y1,$x2,$y2); +} + +sub outputLabelledLine() + { + my ($x1,$y1,$x2,$y2,$text,$alignment) = @_; + +# my $scale = 0.9; + ($x1,$y1,$x2,$y2) = shortenLine($x1,$y1,$x2,$y2,15); + outputLine($x1,$y1,$x2,$y2); + + my ($textx,$texty); + my $anchor; +# if (!$alignment || $alignment eq "mid") { + $textx = (($x1 + $x2) / 2); + $texty = (($y1 + $y2) / 2); + $anchor = "middle"; +# } +# else { +# if ($alignment eq "head") { +# if ($x1 < $x2) { +# $anchor = "end"; +# $textx = $x2 - $arrowWidth - $textArrowSpacing; +# $texty = $y2 - $arrowWidth - $textArrowSpacing; +# } +# else { +# $anchor = "start"; +# $textx = $x2 + $arrowWidth + $textArrowSpacing; +# $texty = $y2 + $arrowWidth + $textArrowSpacing; +# } +# } else { # "tail" +# $textx = $x1; +# $texty = $y1; +# if ($x1 < $x2) { +# $anchor = "start"; +# } else { +# $anchor = "end"; +# } +# } +# } + + my $rectangleColour = "black"; + + if($colouredBoxes) + { + if($alignment eq "head") + { + $rectangleColour='pink'; + } + else + { + $rectangleColour='lightgreen'; + } + } + + outputText($textx,$text,$texty, $anchor, "", "remove", "", $rectangleColour); + } + +sub getAnimStr +{ + my ($animFill) = @_; + + my $beginStr = ''; + my $idStr = ''; + if($animKeys) + { + my $char = substr ($animKeys, int($animKeyCounter/$animMessagesPerKey) , 1); + if($animKeysFirstElement) # if first in sequence + { + $animKeysFirstElement=0; + $beginStr.=qq{accessKey($char)}; + $idStr = qq{ id="anim_$char" }; + } + else + { + $beginStr = qq{anim_$char.begin}; + if($time) {$beginStr .= qq{ + $time}.'ms'} + } + } + else + { + $beginStr = $time; + $beginStr .= 'ms'; + } + + my $anim = qq{}; + return $anim; +} + +sub outputText() + { + my ($x,$text,$y,$anchor,$decoration,$animFill,$otherAttrs,$rectangleColour) = @_; + +#$rectangleUnder=1; + my $attrs = qq{ x="$x" y="$y" $otherAttrs}; + + if ($decoration) + { + $attrs .= qq{ text-decoration="$decoration" }; + } + + my $anim=''; + + if ($anims) + { + $attrs .= qq{ visibility="hidden" }; + $anim = getAnimStr($animFill); + } + + if ($anchor) + { + $attrs .= qq { text-anchor="$anchor" }; + } + + if($rectangleColour) + { + my $w = 8*length($text); # guessing + my $h = 18; # guessing + my $rx = $x - $w/2; + my $ry = $y - $h/2 - 4; + print qq{$anim\n}; + } + print "$text$anim\n"; + } + +sub outputLine() + { + my ($x1,$y1,$x2,$y2) = @_; + my $animTag=''; + my $animAttr=''; + if($anims) + { + $animAttr=qq{visibility="hidden"}; + $animTag= getAnimStr('remove'); + } + print qq{$animTag\n}; + } + +sub outputVerticalLine() + { + my ($x,$y1,$y2) = @_; + print qq{\n}; + } + + +