home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Lighthouse Design Suite
/
LIGHTHOUSE.mdf
/
TaskMaster_1.8
/
Application
/
FilterServicer.service
/
tm2diagram
< prev
next >
Wrap
Text File
|
1993-09-02
|
20KB
|
788 lines
#
# tm2diagram
#
# This file when used as input to perl will take a TaskMaster file and
# generate a PERT diagram in Diagram!2 format.
#
# Copyright (C) 1993 Lighthouse Design Ltd.
#
# You may freely copy, distribute, and reuse the code in
# this example provided this copyright legend and disclaimer
# are preserved in all copies and derivative work.
#
# Lighthouse Design disclaims any warranty of any kind,
# expressed or implied, as to this code's fitness
# for any particular use.
#
#
# NOTE: tweak these to show/hide various parts of the PERT.
# Set to 0 if you don't want to see them, to 1 if you do.
#
$showResources = 1;
$showDates = 1;
$showCriticalPath = 1;
#
# variables
#
$taskWidth = 125;
$taskHeight = 54;
$taskTongueLength = 20;
$taskHorizOffset = 30 + 2 * $taskTongueLength;
$taskVertOffset = 50;
$groupTaskTopBorder = 43;
$groupTaskBottomBorder = ($showResources?27:20);
$groupTaskBorder = 20;
$resourceFieldHeight = 14;
$rootTaskX = 10;
$rootTaskY = 10;
$taskStroke = 1.00;
#$debug = "YES";
$a = 0; #hack to prevent compile warnings. used in &numerically
$b = 0;
@ARGV;
if($ARGV[0] eq "-t"){
require "writedg.pl";
shift(@ARGV);
foreach $file (@ARGV) {
if (! open(GPBFILE,"< $file/CoreText.tmdata")) {
printf(STDERR "$file/CoreText not readable. Skipping $file\n");
next;
}
$dirName = ".";
if ($file =~ /\//) {
$dirName = $file;
$dirName =~ s/\/[^\/]$//;
}
$diagramFilename = $file;
$diagramFilename =~ s/taskmaster/diagram2/;
&doFile();
#
# Cleanup
#
close(GPBFILE);
}
}else{
require "$ARGV[2]/writedg.pl";
$| = 1;
if (! open(GPBFILE,"< $ARGV[0]/CoreText.tmdata")) {
printf(STDERR "$ARGV[0] not readable.\n\n");
exit 0;
}
$diagramFilename = $ARGV[1];
# $silent = "YES";
&doFile();
close(GPBFILE);
}
sub doFile{
$inTask = 0;
$taskNum = 0;
$title = "";
$inDependency = 0;
$depFrom = 0;
$depTo = 0;
$inScenario = 0;
$hasSchedulingInfo = 0;
$inResource = 0;
$inAssignment = 0;
if($silent){
$printDebugMessages = "";
}else{
$printDebugMessages = $debug;
}
$taskNotified = 0;
$depNotified = 0;
$schedNotified = 0;
$resNotified = 0;
while (<GPBFILE>){
#
# TASK STUFF
#
$inTask == 0 && /^Task ([0-9]+)/ && do {
$inTask = 1;
print "Reading Tasks...\n\n" unless ($silent || $taskNotified);
$taskNotified = 1;
$taskNum = $1;
next;
};
$inTask == 1 && /Title \"(.*)\"$/ && do {
$title = $1;
next;
};
$inTask == 1 && /Parent (-?[0-9]+)/ && do {
if($1 <= 0){
$outlineNumber = "";
}else{
if(!$numKids{$1}){
$numKids{$1} = 1;
}else{
$numKids{$1}++;
}
if($outlineNumbers{$1}){
$outlineNumber = $outlineNumbers{$1}.".$numKids{$1}";
}else{
$outlineNumber = $numKids{$1};
}
if($children{$1}){
$children{$1} .= "$taskNum,";
}else{
$children{$1} = "$taskNum,";
}
}
$parent{$taskNum} = $1;
next;
};
$inTask && /^end/ && do {
$titles{$taskNum} = $title;
$title = "";
$outlineNumbers{$taskNum} = $outlineNumber;
$beginningXValue{$taskNum} = -1.0;
$endingXValue{$taskNum} = -1.0;
$beginningYValue{$taskNum} = -1.0;
$endingYValue{$taskNum} = -1.0;
if($printDebugMessages){
print "initialized $taskNum\n";
}
$inTask = 0;
};
#
# Scenario STUFF
#
$inScenario == 0 && /\# DefaultScenario/ && do {
$inScenario = 1;
print "Reading Scheduling Info...\n\n" unless ($silent || $schedNotified);
$schedNotified = 1;
$hasSchedulingInfo = 1;
};
$inScenario == 1 && /Task:([0-9]+)/ && do{
$taskNum = $1;
};
$inScenario == 1 && /Start: \^(.*)\^/ && do{
$taskStartDate{$taskNum} = $1;
};
$inScenario == 1 && /End: \^(.*)\^/ && do{
$taskEndDate{$taskNum} = $1;
};
$inScenario == 1 && /IsCritical:(YES|NO)/ && do{
if($1 =~ /YES/){
$critical{$taskNum} = 1;
}else{
$critical{$taskNum} = 0;
}
};
$inScenario == 1 && /^end/ && do{
$inScenario = 0;
};
#
# Dependency STUFF
#
$inDependency == 0 && /^Dependency ([0-9]+) DependsOn ([0-9]+)/ && do {
$inDependency = 1;
print "Reading Dependencies...\n\n" unless ($silent || $depNotified);
$depNotified = 1;
$depFrom = $2;
$depTo = $1;
next;
};
$inDependency && /^end/ && do {
push(@fromList,$depFrom);
push(@toList,$depTo);
if($predecessors{$depTo}){
$predecessors{$depTo} .= "$depFrom,";
}else{
$predecessors{$depTo} = "$depFrom,";
}
if($successors{$depFrom}){
$successors{$depFrom} .= "$depTo,";
}else{
$successors{$depFrom} = "$depTo,";
}
$inDependency = 0;
};
#
# Resource STUFF
#
$inResource == 0 && /^Resource ([0-9]+)/ && do {
$inResource = 1;
print "Reading Resources...\n\n" unless ($silent || $resNotified);
$resNotified = 1;
$resNum = $1;
next;
};
$inResource == 1 && /Name (.*)$/ && do {
$1 =~ /^\"(.*)\"$/;
$resourceName{$resNum} = $1;
next;
};
$inResource == 1 && /^end/ && do {
$inResource = 0;
next;
};
#
# Assignment STUFF
#
$inAssignment == 0 && /^ScheduledEvent (\d+) (\d+) (\d+)/ && do {
$inAssignment = 1;
print "Reading Assignments...\n\n" unless ($silent || $assignNotified);
$assignNotified = 1;
$currentAssignmentTask = $2;
next;
};
$inAssignment == 1 && /Assignment (\d+) (\d+)/ && do {
if($1 <= 3){
next;
}
if($taskAssignments{$currentAssignmentTask}){
$taskAssignments{$currentAssignmentTask} .= ", $resourceName{$1}";
}else{
$taskAssignments{$currentAssignmentTask} = "$resourceName{$1}";
}
next;
};
$inAssignment == 1 && /^end/ && do {
$inAssignment = 0;
next;
};
next;
}
#
# Calculate the tasks' X values
#
print "Calculating the X positions...\n\n" unless $silent;
&calcAllX(1);
#
# Calculate the tasks' Y values
#
print "Calculating the Y positions...\n\n" unless $silent;
&calcHeights(1);
&calcYs(1);
#
# Graphic Stuff
#
$numGroupLayers = &calcNumGroups(1);
$numLeafLayers = &calcNumLeaves(1);
$numLineLayers = &calcNumDependencies(1);
$numVertexLayers = 2*$numLineLayers;
$currentLeafLayer = 1;
$currentVertexLayer = $currentLeafLayer + $numLeafLayers;
$currentLineLayer = $currentVertexLayer + $numVertexLayers;
$currentGroupLayer = $currentLineLayer+$numLineLayers+$numGroupLayers;
#
# Calc pagesize
#
$numHorizPages = int(($endingXValue{1} / 756.0) + 1.0);
$numVertPages = int(($endingYValue{1} / 576.0) + 1.0);
if((1/$numHorizPages) < (1/$numVertPages)){
$zoom = (1/$numHorizPages);
}else{
$zoom = (1/$numVertPages);
}
#
# Setup file
&setDebugging(1) unless !$debug;
$theDocument = &newDocument();
&setDocumentButtons($theDocument, 1);
&setDocumentDefaultFont($theDocument, "Helvetica", 10.0);
&setDocumentCanvasSize($theDocument, $numHorizPages, $numVertPages);
&setDocumentZoom($theDocument, $zoom);
#
# create tasks
#
print "Drawing Tasks...\n\n" unless $silent;
&doAllFromRoot();
#
# create dependencies
#
print "Drawing Dependencies...\n\n" unless $silent;
foreach $ct (0 .. $#fromList){
$theLine = &newLine($theDocument, $fromPoint{$fromList[$ct]}, $toPoint{$toList[$ct]});
&setObjectLayer($theLine, $currentLineLayer++);
if($showCriticalPath && $critical{$fromList[$ct]} && $critical{$toList[$ct]}){
&setObjectFrameColor($theLine, 1, 0, 0);
}
}
print "Writing File...\n\n" unless $silent;
&writeDocument($theDocument, $diagramFilename);
print "Done.\n\n" unless $silent;
sleep 1;
}
#
# Graphic Setup subroutines
#
sub calcNumGroups {
$tempTask = $_[0];
local($totalNum, $theTask, $kid);
$theTask = $tempTask;
$totalNum = 0;
if($children{$theTask}){
foreach $kid (split(/,/ , $children{$theTask})){
$totalNum += &calcNumGroups($kid);
}
$totalNum++;
}
return($totalNum);
}
sub calcNumLeaves {
$tempTask = $_[0];
local($totalLeaves, $theTask, $kid);
$theTask = $tempTask;
$totalLeaves = 0;
if($children{$theTask}){
foreach $kid (split(/,/ , $children{$theTask})){
$totalLeaves += &calcNumLeaves($kid);
}
}else{
$totalLeaves = 1;
}
return($totalLeaves);
}
sub calcNumDependencies {
$tempTask = $_[0];
local($totalDependencies, $theTask, $kid, @deps);
$theTask = $tempTask;
if($predecessors{$theTask}){
@deps = (split(/,/ , $predecessors{$theTask}));
$totalDependencies = $#deps +1;
}else{
$totalDependencies = 0;
}
if($children{$theTask}){
foreach $kid (split(/,/ , $children{$theTask})){
$totalDependencies += &calcNumDependencies($kid);
}
}
return($totalDependencies);
}
#
# XValue subroutines
#
sub calcAllX {
$tempTask = $_[0];
local($theTask);
$theTask = $tempTask;
if($printDebugMessages){
print "\ncalcAllX $theTask\n";
}
&calcBeginningX($theTask);
&calcChildrenX($theTask);
&calcEndingX($theTask);
&checkBeginningX($theTask);
}
sub calcBeginningX {
$tempTask = $_[0];
local($theTask, $pred);
$theTask = $tempTask;
# root special case
if(($theTask) == 1){
&calcBegX($theTask);
return 1;
}
if($beginningXValue{$theTask} != -1.0){
return 1;
}
if($beginningXValue{$parent{$theTask}} == -1.0){
&calcBeginningX($parent{$theTask});
}
if($predecessors{$theTask}){
foreach $pred (split(/,/ , $predecessors{$theTask})){
if($endingXValue{$pred} < 0){
&calcAllX($pred);
}
}
}
&calcBegX($theTask);
}
sub calcChildrenX {
$tempTask = $_[0];
local($theTask, $kid);
$theTask = $tempTask;
if($children{$theTask}){
foreach $kid (split(/,/ , $children{$theTask})){
&calcAllX($kid);
}
}
}
sub calcEndingX {
&calcEndX($_[0]);
}
sub checkBeginningX {
$tempTask = $_[0];
local($theTask, $kid, $minChildX);
$theTask = $tempTask;
if($children{$theTask}){
$minChildX = $endingXValue{$theTask};
foreach $kid (split(/,/ , $children{$theTask})){
if($beginningXValue{$kid} < $minChildX){
$minChildX = $beginningXValue{$kid};
}
}
$beginningXValue{$theTask} = $minChildX - $groupTaskBorder;
}
}
sub calcBegX {
$tempTask = $_[0];
local($theTask, $maxX, $parentX, $pred, $x);
$theTask = $tempTask;
if($printDebugMessages){
print "calc'ed XBeginning of: $theTask\n";
}
if($theTask == 1){
$beginningXValue{$theTask} = $rootTaskX;
return 1;
}
$parentX = $beginningXValue{$parent{$theTask}};
$maxX = $parentX;
if($predecessors{$theTask}){
foreach $pred (split(/,/ , $predecessors{$theTask})){
$x = $endingXValue{$pred};
if ($x > $maxX){
$maxX = $x;
}
}
}
if($maxX == $parentX){
$beginningXValue{$theTask} = $maxX + $groupTaskBorder;
}else{
$beginningXValue{$theTask} = $maxX + $taskHorizOffset;
}
}
sub calcEndX {
$tempTask = $_[0];
local($theTask, $maxX, $kid, $x);
$theTask = $tempTask;
if($printDebugMessages){
print "calc'ed XEnding of: $theTask\n";
}
if($children{$theTask}){
$maxX = 0.0;
foreach $kid (split(/,/ , $children{$theTask})){
$x = $endingXValue{$kid};
if ($x > $maxX){
$maxX = $x;
}
}
$endingXValue{$theTask} = $maxX + $groupTaskBorder;
}else{
$endingXValue{$theTask} = $beginningXValue{$theTask} + $taskWidth;
}
}
#
# YValue subroutines
#
sub calcHeights {
$tempTask = $_[0];
local($theTask, $theOffset, @theChains, $temp);
$theTask = $tempTask;
if($printDebugMessages){
print "calcHeight: $outlineNumbers{$theTask}\n";
}
if($children{$theTask}){
foreach $kid (split(/,/ , $children{$theTask})){
if(&isChainBase($kid)){
push(@theChains, $kid);
}
}
$theOffset = $groupTaskTopBorder;
foreach $kid (sort sequentially @theChains){
$chainOffset{$kid} = $theOffset;
$temp = &calcChainHeights($kid, 0);
$theOffset += $temp + $taskVertOffset;
}
$theOffset += $groupTaskBottomBorder - $taskVertOffset;
$height{$theTask} = $theOffset;
}else{
$height{$theTask} = $taskHeight;
}
}
sub calcChainHeights {
$tempTask = $_[0];
$tempHeight = $_[1];
local($theTask, $succ, $siblings, $succsHeight, $myHeight, $currentHeight, @succs, $passHeight);
$theTask = $tempTask;
$currentHeight = $tempHeight;
if($printDebugMessages){
print "calcChainHeights:$outlineNumbers{$theTask} withHeight:$currentHeight\n";
}
$siblings = "";
foreach $sib (split(/,/, $children{$parent{$theTask}})){
$siblings .= "($outlineNumbers{$sib})";
}
if($height{$theTask}){
if($printDebugMessages){
print "Already calculated height for $outlineNumbers{$theTask}\n";
}
return 0;
}
$myHeight = &calcHeights($theTask);
foreach $succ (split(/,/ , $successors{$theTask})){
$checkString = "($outlineNumbers{$succ})";
if(index($siblings, $checkString)>=0){
push(@succs, $succ);
}
}
if ($#succs > 0){
$passHeight = 0;
}elsif($myHeight > $currentHeight){
$passHeight = $myHeight;
}else{
$passHeight = $currentHeight;
}
$succsHeight = 0.0;
foreach $succ (sort sequentially @succs){
if(!$height{$succ}){
$chainOffset{$succ} = $chainOffset{$theTask} + $succsHeight;
$succsHeight += &calcChainHeights($succ, $passHeight) + $taskVertOffset;
}
}
$succsHeight -= $taskVertOffset;
if($succsHeight > $currentHeight && $succsHeight > $myHeight){
$chainHeight{$theTask} = $succsHeight;
}elsif($currentHeight > $myHeight){
$chainHeight{$theTask} = $currentHeight;
}else{
$chainHeight{$theTask} = $myHeight;
}
}
sub calcYs {
$tempTask = $_[0];
local($theTask, $kid);
$theTask = $tempTask;
if($printDebugMessages){
print "calcYs: $outlineNumbers{$theTask}\n";
}
if($theTask == 1){
$beginningYValue{$theTask} = $rootTaskY;
}else{
$beginningYValue{$theTask} = $beginningYValue{$parent{$theTask}} + $chainOffset{$theTask} + ($chainHeight{$theTask}-$height{$theTask})/2;
}
if($printDebugMessages && $theTask != 1){
print "calcYs: $outlineNumbers{$theTask} -> $beginningYValue{$theTask} calc $beginningYValue{$parent{$theTask}} offset:$chainOffset{$theTask} chainHeight:$chainHeight{$theTask}\n";
}
$endingYValue{$theTask} = $beginningYValue{$theTask} + $height{$theTask};
if($children{$theTask}){
foreach $kid (split(/,/ , $children{$theTask})){
&calcYs($kid);
}
}
}
sub isChainBase {
$tempTask = $_[0];
local($theTask, $pred, $siblings);
$theTask = $tempTask;
$siblings = "";
foreach $sib (split(/,/, $children{$parent{$theTask}})){
$siblings .= "($outlineNumbers{$sib})";
}
foreach $pred (split(/,/ , $predecessors{$theTask})){
$checkString = "($outlineNumbers{$pred})";
if(index($siblings, $checkString) >= 0){
return 0;
}
}
if($printDebugMessages){
print "found chain base:$outlineNumbers{$theTask}\n";
}
return 1;
}
sub doAllFromRoot{
local($kid);
foreach $kid (split(/,/ , $children{1})){
&doTask($kid);
}
}
sub doTask {
$tempTask = $_[0];
local($theTask, $width, $height, $layer, $kid, $startField, $endField);
$theTask = $tempTask;
if($children{$theTask}){
$layer = $currentGroupLayer;
$currentGroupLayer--;
}else{
$layer = $currentLeafLayer;
$currentLeafLayer++;
}
$width = $endingXValue{$theTask}-$beginningXValue{$theTask};
$height = $endingYValue{$theTask}-$beginningYValue{$theTask};
$theTaskSymbol = &newSymbol($theDocument, "Rectangle", $beginningXValue{$theTask}, $beginningYValue{$theTask}, $width, $height);
&setObjectFramed($theTaskSymbol, 1);
if($showCriticalPath && $critical{$theTask}){
&setObjectFrameColor($theTaskSymbol, 1, 0, 0);
}
if($titles{$theTask}){
$taskString = "\{\\rtf0\\ansi\{\\fonttbl\\f0\\fswiss Helvetica;\}\\margl40\\margr40\\pard\\tx440\\tx1320\\tx1760\\tx2220\\tx2660\\tx3100\\tx3540\\tx4000\\tx4440\\f0\\b0\\i0\\ulnone\\fs20\\fc0\\cf0 Task $outlineNumbers{$theTask}\\\n\\b $titles{$theTask}\}";
}elsif($outlineNumbers{$theTask}){
$taskString = "\{\\rtf0\\ansi\{\\fonttbl\\f0\\fswiss Helvetica;\}\\margl40\\margr40\\pard\\tx440\\tx1320\\tx1760\\tx2220\\tx2660\\tx3100\\tx3540\\tx4000\\tx4440\\f0\\b0\\i0\\ulnone\\fs20\\fc0\\cf0 Task $outlineNumbers{$theTask}\}";
}
&setObjectRtfText($theTaskSymbol, $taskString);
&setObjectTextPlacement($theTaskSymbol, "top");
&setObjectFilled($theTaskSymbol, 1);
&setObjectLineWidth($theTaskSymbol, $taskStroke);
@groupList = ($theTaskSymbol);
#
# Start/End dates
#
if($showDates && $hasSchedulingInfo){
$startField = &newSymbol($theDocument, "Rectangle", $beginningXValue{$theTask} - 2.0, $beginningYValue{$theTask} - 12.0, $width, 14);
&setObjectFramed($startField, 0);
&setObjectText($startField, $taskStartDate{$theTask});
&setObjectTextPlacement($startField, "top");
$endField = &newSymbol($theDocument, "Rectangle", $beginningXValue{$theTask} - 2.0, $endingYValue{$theTask} - 2.0, $width, 14);
&setObjectFramed($endField, 0);
&setObjectText($endField, $taskEndDate{$theTask});
&setObjectTextPlacement($endField, "top");
push(@groupList, $startField, $endField);
}
#
# Resources
#
if($showResources && $taskAssignments{$theTask}){
$yLocation = $endingYValue{$theTask}+ ($showDates && $hasSchedulingInfo?10:-2);
$resourceField = &newSymbol($theDocument, "Rectangle", $beginningXValue{$theTask} - 2.0, $yLocation, $width, $resourceFieldHeight);
&setObjectFramed($resourceField, 0);
&setObjectRtfText($resourceField, "\{\\rtf0\\ansi\{\\fonttbl\\f0\\fswiss Helvetica;\}\\margl40\\margr40\\pard\\tx444\\tx889\\tx1334\\tx1779\\tx2223\\tx2668\\tx3113\\tx3558\\tx4003\\tx4447\\f0\\b0\\i\\ulnone\\fs20\\fc0\\cf0 $taskAssignments{$theTask}\}");
&setObjectTextPlacement($resourceField, "top");
push(@groupList, $resourceField);
}
#
# Tongues
#
if($successors{$theTask}){
$tongue = &newLine($theDocument, $theTaskSymbol, $theTaskSymbol);
@verts = &vertexesForLine($tongue);
$fromPoint{$theTask} = $verts[1];
&setObjectLocation($verts[1], $endingXValue{$theTask} + $taskTongueLength, $beginningYValue{$theTask} + $height/2.0);
&setLineTo($tongue, $verts[1]);
if($showCriticalPath && $critical{$theTask}){
&setObjectFrameColor($tongue, 1, 0, 0);
}
&setLineTailType($tongue, "circle");
push(@groupList, $tongue, @verts);
}
if($predecessors{$theTask}){
$tongue = &newLine($theDocument, $theTaskSymbol, $theTaskSymbol);
@verts = &vertexesForLine($tongue);
$toPoint{$theTask} = $verts[0];
&setObjectLocation($verts[0], $beginningXValue{$theTask} - $taskTongueLength, $beginningYValue{$theTask} + $height/2.0);
&setLineFrom($tongue, $verts[0]);
if($showCriticalPath && $critical{$theTask}){
&setObjectFrameColor($tongue, 1, 0, 0);
}
&setLineHeadType($tongue, "arrow");
push(@groupList, $tongue, @verts);
}
$theTaskGroup = &newGroup($theDocument, @groupList);
&setObjectLayer($theTaskGroup, $layer);
if($children{$theTask}){
&setObjectLocked($theTaskGroup, 1);
}
#
# now the kids
#
foreach $kid (split(/,/ , $children{$theTask})){
&doTask($kid, $layer-1);
}
}
sub sequentially {
local(@aThing, @bThing, $ct);
return 0 if !$a;
return 1 if !$b;
@aThing = split(/\./,$outlineNumbers{$a});
@bThing = split(/\./,$outlineNumbers{$b});
for($ct=0; $ct <= $#aThing; $ct++){
if(!$bThing[$ct]){
return 0;
}
if($aThing[$ct] < $bThing[$ct]){
return 0;
}
if($aThing[$ct] > $bThing[$ct]){
return 1;
}
}
return 1;
}
# Place Emacs into Perl-mode
# Local Variables:
# mode: perl
# End: