taskjuggler 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +280 -0
- data/README +31 -0
- data/Rakefile +20 -0
- data/benchmarks/UTF-8-Strings.rb +58 -0
- data/benchmarks/allocate.tjp +30 -0
- data/benchmarks/booking.tjp +62 -0
- data/benchmarks/depends.tjp +112 -0
- data/benchmarks/htmltaskreport.tjp +45 -0
- data/benchmarks/runbench.rb +24 -0
- data/bin/tj3 +3 -0
- data/bin/tj3man +3 -0
- data/doc/classes/AppConfig.html +808 -0
- data/doc/classes/Arguments.html +226 -0
- data/doc/classes/String.html +395 -0
- data/doc/classes/TaskJuggler.html +1358 -0
- data/doc/classes/TaskJuggler/Account.html +257 -0
- data/doc/classes/TaskJuggler/AccountScenario.html +218 -0
- data/doc/classes/TaskJuggler/Allocation.html +419 -0
- data/doc/classes/TaskJuggler/AllocationAttribute.html +291 -0
- data/doc/classes/TaskJuggler/AttributeBase.html +608 -0
- data/doc/classes/TaskJuggler/AttributeDefinition.html +259 -0
- data/doc/classes/TaskJuggler/Booking.html +307 -0
- data/doc/classes/TaskJuggler/BookingListAttribute.html +263 -0
- data/doc/classes/TaskJuggler/BooleanAttribute.html +261 -0
- data/doc/classes/TaskJuggler/CSVFile.html +325 -0
- data/doc/classes/TaskJuggler/Charge.html +279 -0
- data/doc/classes/TaskJuggler/ChargeListAttribute.html +229 -0
- data/doc/classes/TaskJuggler/ChargeSet.html +440 -0
- data/doc/classes/TaskJuggler/ChargeSetListAttribute.html +276 -0
- data/doc/classes/TaskJuggler/ColumnTable.html +260 -0
- data/doc/classes/TaskJuggler/DateAttribute.html +194 -0
- data/doc/classes/TaskJuggler/DependencyListAttribute.html +267 -0
- data/doc/classes/TaskJuggler/DurationAttribute.html +229 -0
- data/doc/classes/TaskJuggler/FixnumAttribute.html +194 -0
- data/doc/classes/TaskJuggler/FlagListAttribute.html +263 -0
- data/doc/classes/TaskJuggler/FloatAttribute.html +229 -0
- data/doc/classes/TaskJuggler/GanttChart.html +667 -0
- data/doc/classes/TaskJuggler/GanttContainer.html +441 -0
- data/doc/classes/TaskJuggler/GanttHeader.html +280 -0
- data/doc/classes/TaskJuggler/GanttHeaderScaleItem.html +245 -0
- data/doc/classes/TaskJuggler/GanttLine.html +398 -0
- data/doc/classes/TaskJuggler/GanttLoadStack.html +327 -0
- data/doc/classes/TaskJuggler/GanttMilestone.html +415 -0
- data/doc/classes/TaskJuggler/GanttRouter.html +425 -0
- data/doc/classes/TaskJuggler/GanttTaskBar.html +429 -0
- data/doc/classes/TaskJuggler/HTMLDocument.html +240 -0
- data/doc/classes/TaskJuggler/HTMLGraphics.html +231 -0
- data/doc/classes/TaskJuggler/Interval.html +552 -0
- data/doc/classes/TaskJuggler/IntervalListAttribute.html +267 -0
- data/doc/classes/TaskJuggler/KeywordDocumentation.html +796 -0
- data/doc/classes/TaskJuggler/Limits.html +416 -0
- data/doc/classes/TaskJuggler/Limits/Limit.html +381 -0
- data/doc/classes/TaskJuggler/LimitsAttribute.html +261 -0
- data/doc/classes/TaskJuggler/Log.html +613 -0
- data/doc/classes/TaskJuggler/LogicalAttribute.html +226 -0
- data/doc/classes/TaskJuggler/LogicalExpression.html +251 -0
- data/doc/classes/TaskJuggler/LogicalFlag.html +229 -0
- data/doc/classes/TaskJuggler/LogicalFunction.html +324 -0
- data/doc/classes/TaskJuggler/LogicalOperation.html +299 -0
- data/doc/classes/TaskJuggler/Macro.html +194 -0
- data/doc/classes/TaskJuggler/MacroParser.html +360 -0
- data/doc/classes/TaskJuggler/MacroTable.html +366 -0
- data/doc/classes/TaskJuggler/Message.html +281 -0
- data/doc/classes/TaskJuggler/MessageHandler.html +215 -0
- data/doc/classes/TaskJuggler/Project.html +1606 -0
- data/doc/classes/TaskJuggler/ProjectFileParser.html +412 -0
- data/doc/classes/TaskJuggler/PropertyList.html +597 -0
- data/doc/classes/TaskJuggler/PropertySet.html +1200 -0
- data/doc/classes/TaskJuggler/PropertyTreeNode.html +1449 -0
- data/doc/classes/TaskJuggler/Query.html +600 -0
- data/doc/classes/TaskJuggler/RealFormat.html +252 -0
- data/doc/classes/TaskJuggler/ReferenceAttribute.html +194 -0
- data/doc/classes/TaskJuggler/Report.html +528 -0
- data/doc/classes/TaskJuggler/ReportElement.html +1070 -0
- data/doc/classes/TaskJuggler/ReportTable.html +497 -0
- data/doc/classes/TaskJuggler/ReportTableCell.html +518 -0
- data/doc/classes/TaskJuggler/ReportTableColumn.html +364 -0
- data/doc/classes/TaskJuggler/ReportTableElement.html +644 -0
- data/doc/classes/TaskJuggler/ReportTableLegend.html +343 -0
- data/doc/classes/TaskJuggler/ReportTableLine.html +431 -0
- data/doc/classes/TaskJuggler/Resource.html +211 -0
- data/doc/classes/TaskJuggler/ResourceListAttribute.html +267 -0
- data/doc/classes/TaskJuggler/ResourceListRE.html +249 -0
- data/doc/classes/TaskJuggler/ResourceScenario.html +1137 -0
- data/doc/classes/TaskJuggler/RichText.html +537 -0
- data/doc/classes/TaskJuggler/RichTextAttribute.html +229 -0
- data/doc/classes/TaskJuggler/RichTextDocument.html +418 -0
- data/doc/classes/TaskJuggler/RichTextElement.html +829 -0
- data/doc/classes/TaskJuggler/RichTextException.html +212 -0
- data/doc/classes/TaskJuggler/RichTextParser.html +317 -0
- data/doc/classes/TaskJuggler/RichTextProtocolExample.html +303 -0
- data/doc/classes/TaskJuggler/RichTextProtocolHandler.html +194 -0
- data/doc/classes/TaskJuggler/RichTextScanner.html +561 -0
- data/doc/classes/TaskJuggler/RichTextSnip.html +364 -0
- data/doc/classes/TaskJuggler/RichTextSyntaxRules.html +883 -0
- data/doc/classes/TaskJuggler/Scenario.html +163 -0
- data/doc/classes/TaskJuggler/ScenarioData.html +354 -0
- data/doc/classes/TaskJuggler/Scoreboard.html +638 -0
- data/doc/classes/TaskJuggler/Shift.html +255 -0
- data/doc/classes/TaskJuggler/ShiftAssignment.html +488 -0
- data/doc/classes/TaskJuggler/ShiftAssignments.html +715 -0
- data/doc/classes/TaskJuggler/ShiftAssignmentsAttribute.html +261 -0
- data/doc/classes/TaskJuggler/ShiftScenario.html +282 -0
- data/doc/classes/TaskJuggler/SourceFileInfo.html +247 -0
- data/doc/classes/TaskJuggler/StringAttribute.html +229 -0
- data/doc/classes/TaskJuggler/SymbolAttribute.html +194 -0
- data/doc/classes/TaskJuggler/SyntaxReference.html +516 -0
- data/doc/classes/TaskJuggler/TOCEntry.html +242 -0
- data/doc/classes/TaskJuggler/TableColumnDefinition.html +273 -0
- data/doc/classes/TaskJuggler/TableOfContents.html +256 -0
- data/doc/classes/TaskJuggler/Task.html +203 -0
- data/doc/classes/TaskJuggler/TaskDependency.html +251 -0
- data/doc/classes/TaskJuggler/TaskListAttribute.html +267 -0
- data/doc/classes/TaskJuggler/TaskListRE.html +250 -0
- data/doc/classes/TaskJuggler/TaskScenario.html +2206 -0
- data/doc/classes/TaskJuggler/TextParser.html +670 -0
- data/doc/classes/TaskJuggler/TextParser/Pattern.html +923 -0
- data/doc/classes/TaskJuggler/TextParser/Rule.html +779 -0
- data/doc/classes/TaskJuggler/TextParser/StackElement.html +267 -0
- data/doc/classes/TaskJuggler/TextParser/TextParserResultArray.html +212 -0
- data/doc/classes/TaskJuggler/TextParser/TokenDoc.html +221 -0
- data/doc/classes/TaskJuggler/TextScanner.html +708 -0
- data/doc/classes/TaskJuggler/TextScanner/BufferStreamHandle.html +355 -0
- data/doc/classes/TaskJuggler/TextScanner/FileStreamHandle.html +341 -0
- data/doc/classes/TaskJuggler/TextScanner/StreamHandle.html +260 -0
- data/doc/classes/TaskJuggler/TjException.html +185 -0
- data/doc/classes/TaskJuggler/TjTime.html +1845 -0
- data/doc/classes/TaskJuggler/TjpExample.html +310 -0
- data/doc/classes/TaskJuggler/TjpExportRE.html +329 -0
- data/doc/classes/TaskJuggler/TjpSyntaxRules.html +8928 -0
- data/doc/classes/TaskJuggler/UserManual.html +606 -0
- data/doc/classes/TaskJuggler/WorkingHours.html +582 -0
- data/doc/classes/TaskJuggler/WorkingHoursAttribute.html +284 -0
- data/doc/classes/TaskJuggler/XMLBlob.html +207 -0
- data/doc/classes/TaskJuggler/XMLComment.html +206 -0
- data/doc/classes/TaskJuggler/XMLDocument.html +293 -0
- data/doc/classes/TaskJuggler/XMLElement.html +341 -0
- data/doc/classes/TaskJuggler/XMLNamedText.html +174 -0
- data/doc/classes/TaskJuggler/XMLText.html +221 -0
- data/doc/files/COPYING.html +448 -0
- data/doc/files/README.html +134 -0
- data/doc/files/lib/AccountScenario_rb.html +116 -0
- data/doc/files/lib/Account_rb.html +118 -0
- data/doc/files/lib/Allocation_rb.html +118 -0
- data/doc/files/lib/AppConfig_rb.html +116 -0
- data/doc/files/lib/AttributeBase_rb.html +106 -0
- data/doc/files/lib/AttributeDefinition_rb.html +106 -0
- data/doc/files/lib/Attributes_rb.html +130 -0
- data/doc/files/lib/Booking_rb.html +106 -0
- data/doc/files/lib/ChargeSet_rb.html +116 -0
- data/doc/files/lib/Charge_rb.html +116 -0
- data/doc/files/lib/HTMLDocument_rb.html +116 -0
- data/doc/files/lib/Interval_rb.html +116 -0
- data/doc/files/lib/KeywordDocumentation_rb.html +122 -0
- data/doc/files/lib/Limits_rb.html +116 -0
- data/doc/files/lib/Log_rb.html +116 -0
- data/doc/files/lib/LogicalExpression_rb.html +122 -0
- data/doc/files/lib/LogicalFlag_rb.html +116 -0
- data/doc/files/lib/LogicalFunction_rb.html +116 -0
- data/doc/files/lib/LogicalOperation_rb.html +116 -0
- data/doc/files/lib/MacroParser_rb.html +118 -0
- data/doc/files/lib/MacroTable_rb.html +122 -0
- data/doc/files/lib/MessageHandler_rb.html +106 -0
- data/doc/files/lib/Message_rb.html +116 -0
- data/doc/files/lib/ProjectFileParser_rb.html +122 -0
- data/doc/files/lib/Project_rb.html +148 -0
- data/doc/files/lib/PropertyList_rb.html +106 -0
- data/doc/files/lib/PropertySet_rb.html +118 -0
- data/doc/files/lib/PropertyTreeNode_rb.html +106 -0
- data/doc/files/lib/Query_rb.html +116 -0
- data/doc/files/lib/RealFormat_rb.html +106 -0
- data/doc/files/lib/ResourceScenario_rb.html +116 -0
- data/doc/files/lib/Resource_rb.html +118 -0
- data/doc/files/lib/RichTextDocument_rb.html +120 -0
- data/doc/files/lib/RichTextElement_rb.html +120 -0
- data/doc/files/lib/RichTextParser_rb.html +120 -0
- data/doc/files/lib/RichTextProtocolExample_rb.html +120 -0
- data/doc/files/lib/RichTextProtocolHandler_rb.html +106 -0
- data/doc/files/lib/RichTextScanner_rb.html +116 -0
- data/doc/files/lib/RichTextSnip_rb.html +118 -0
- data/doc/files/lib/RichTextSyntaxRules_rb.html +106 -0
- data/doc/files/lib/RichText_rb.html +118 -0
- data/doc/files/lib/ScenarioData_rb.html +118 -0
- data/doc/files/lib/Scenario_rb.html +116 -0
- data/doc/files/lib/Scoreboard_rb.html +106 -0
- data/doc/files/lib/ShiftAssignments_rb.html +116 -0
- data/doc/files/lib/ShiftScenario_rb.html +116 -0
- data/doc/files/lib/Shift_rb.html +118 -0
- data/doc/files/lib/SourceFileInfo_rb.html +106 -0
- data/doc/files/lib/SyntaxReference_rb.html +122 -0
- data/doc/files/lib/TOCEntry_rb.html +118 -0
- data/doc/files/lib/TableColumnDefinition_rb.html +106 -0
- data/doc/files/lib/TableOfContents_rb.html +118 -0
- data/doc/files/lib/TaskDependency_rb.html +106 -0
- data/doc/files/lib/TaskJuggler_rb.html +120 -0
- data/doc/files/lib/TaskScenario_rb.html +116 -0
- data/doc/files/lib/Task_rb.html +118 -0
- data/doc/files/lib/TextParser/Pattern_rb.html +116 -0
- data/doc/files/lib/TextParser/Rule_rb.html +106 -0
- data/doc/files/lib/TextParser/StackElement_rb.html +106 -0
- data/doc/files/lib/TextParser/TokenDoc_rb.html +106 -0
- data/doc/files/lib/TextParser_rb.html +124 -0
- data/doc/files/lib/TextScanner_rb.html +128 -0
- data/doc/files/lib/Tj3Config_rb.html +118 -0
- data/doc/files/lib/TjException_rb.html +106 -0
- data/doc/files/lib/TjTime_rb.html +118 -0
- data/doc/files/lib/TjpExample_rb.html +116 -0
- data/doc/files/lib/TjpSyntaxRules_rb.html +106 -0
- data/doc/files/lib/UTF8String_rb.html +132 -0
- data/doc/files/lib/UserManual_rb.html +124 -0
- data/doc/files/lib/WorkingHours_rb.html +116 -0
- data/doc/files/lib/XMLDocument_rb.html +116 -0
- data/doc/files/lib/XMLElement_rb.html +116 -0
- data/doc/files/lib/reports/CSVFile_rb.html +116 -0
- data/doc/files/lib/reports/ColumnTable_rb.html +116 -0
- data/doc/files/lib/reports/GanttChart_rb.html +122 -0
- data/doc/files/lib/reports/GanttContainer_rb.html +116 -0
- data/doc/files/lib/reports/GanttHeaderScaleItem_rb.html +106 -0
- data/doc/files/lib/reports/GanttHeader_rb.html +116 -0
- data/doc/files/lib/reports/GanttLine_rb.html +126 -0
- data/doc/files/lib/reports/GanttLoadStack_rb.html +116 -0
- data/doc/files/lib/reports/GanttMilestone_rb.html +116 -0
- data/doc/files/lib/reports/GanttRouter_rb.html +106 -0
- data/doc/files/lib/reports/GanttTaskBar_rb.html +116 -0
- data/doc/files/lib/reports/HTMLGraphics_rb.html +106 -0
- data/doc/files/lib/reports/ReportElement_rb.html +118 -0
- data/doc/files/lib/reports/ReportTableCell_rb.html +106 -0
- data/doc/files/lib/reports/ReportTableColumn_rb.html +106 -0
- data/doc/files/lib/reports/ReportTableElement_rb.html +122 -0
- data/doc/files/lib/reports/ReportTableLegend_rb.html +106 -0
- data/doc/files/lib/reports/ReportTableLine_rb.html +116 -0
- data/doc/files/lib/reports/ReportTable_rb.html +118 -0
- data/doc/files/lib/reports/Report_rb.html +126 -0
- data/doc/files/lib/reports/ResourceListRE_rb.html +122 -0
- data/doc/files/lib/reports/TaskListRE_rb.html +122 -0
- data/doc/files/lib/reports/TjpExportRE_rb.html +116 -0
- data/doc/files/lib/taskjuggler3_rb.html +276 -0
- data/doc/files/lib/tj3man_rb.html +189 -0
- data/doc/fr_class_index.html +285 -0
- data/doc/fr_file_index.html +223 -0
- data/doc/fr_method_index.html +1953 -0
- data/doc/index.html +21 -0
- data/doc/rdoc-style.css +299 -0
- data/examples/tutorial.tjp +361 -0
- data/gem_spec.rb +30 -0
- data/lib/Account.rb +50 -0
- data/lib/AccountScenario.rb +39 -0
- data/lib/Allocation.rb +102 -0
- data/lib/AppConfig.rb +134 -0
- data/lib/AttributeBase.rb +131 -0
- data/lib/AttributeDefinition.rb +47 -0
- data/lib/Attributes.rb +478 -0
- data/lib/BatchProcessor.rb +209 -0
- data/lib/Booking.rb +59 -0
- data/lib/Charge.rb +71 -0
- data/lib/ChargeSet.rb +126 -0
- data/lib/HTMLDocument.rb +59 -0
- data/lib/Interval.rb +127 -0
- data/lib/KeywordDocumentation.rb +560 -0
- data/lib/Limits.rb +219 -0
- data/lib/Log.rb +160 -0
- data/lib/LogicalExpression.rb +71 -0
- data/lib/LogicalFlag.rb +34 -0
- data/lib/LogicalFunction.rb +102 -0
- data/lib/LogicalOperation.rb +118 -0
- data/lib/MacroParser.rb +77 -0
- data/lib/MacroTable.rb +84 -0
- data/lib/Message.rb +56 -0
- data/lib/MessageHandler.rb +34 -0
- data/lib/Project.rb +662 -0
- data/lib/ProjectFileParser.rb +333 -0
- data/lib/PropertyList.rb +181 -0
- data/lib/PropertySet.rb +304 -0
- data/lib/PropertyTreeNode.rb +461 -0
- data/lib/Query.rb +227 -0
- data/lib/RealFormat.rb +73 -0
- data/lib/Resource.rb +42 -0
- data/lib/ResourceScenario.rb +511 -0
- data/lib/RichText.rb +147 -0
- data/lib/RichTextDocument.rb +139 -0
- data/lib/RichTextElement.rb +391 -0
- data/lib/RichTextParser.rb +66 -0
- data/lib/RichTextProtocolExample.rb +65 -0
- data/lib/RichTextProtocolHandler.rb +35 -0
- data/lib/RichTextScanner.rb +390 -0
- data/lib/RichTextSnip.rb +104 -0
- data/lib/RichTextSyntaxRules.rb +265 -0
- data/lib/Scenario.rb +27 -0
- data/lib/ScenarioData.rb +65 -0
- data/lib/Scoreboard.rb +141 -0
- data/lib/Shift.rb +48 -0
- data/lib/ShiftAssignments.rb +291 -0
- data/lib/ShiftScenario.rb +46 -0
- data/lib/SourceFileInfo.rb +37 -0
- data/lib/SyntaxReference.rb +284 -0
- data/lib/TOCEntry.rb +76 -0
- data/lib/TableColumnDefinition.rb +54 -0
- data/lib/TableOfContents.rb +46 -0
- data/lib/Task.rb +37 -0
- data/lib/TaskDependency.rb +39 -0
- data/lib/TaskJuggler.rb +84 -0
- data/lib/TaskScenario.rb +1622 -0
- data/lib/TextParser.rb +416 -0
- data/lib/TextParser/Pattern.rb +263 -0
- data/lib/TextParser/Rule.rb +171 -0
- data/lib/TextParser/StackElement.rb +45 -0
- data/lib/TextParser/TokenDoc.rb +38 -0
- data/lib/TextScanner.rb +682 -0
- data/lib/Tj3Config.rb +27 -0
- data/lib/TjException.rb +27 -0
- data/lib/TjTime.rb +395 -0
- data/lib/TjpExample.rb +119 -0
- data/lib/TjpSyntaxRules.rb +4022 -0
- data/lib/UTF8String.rb +100 -0
- data/lib/UserManual.rb +282 -0
- data/lib/WorkingHours.rb +323 -0
- data/lib/XMLDocument.rb +54 -0
- data/lib/XMLElement.rb +175 -0
- data/lib/reports/CSVFile.rb +146 -0
- data/lib/reports/ColumnTable.rb +66 -0
- data/lib/reports/GanttChart.rb +308 -0
- data/lib/reports/GanttContainer.rb +107 -0
- data/lib/reports/GanttHeader.rb +141 -0
- data/lib/reports/GanttHeaderScaleItem.rb +42 -0
- data/lib/reports/GanttLine.rb +329 -0
- data/lib/reports/GanttLoadStack.rb +113 -0
- data/lib/reports/GanttMilestone.rb +80 -0
- data/lib/reports/GanttRouter.rb +375 -0
- data/lib/reports/GanttTaskBar.rb +95 -0
- data/lib/reports/HTMLGraphics.rb +65 -0
- data/lib/reports/Report.rb +344 -0
- data/lib/reports/ReportElement.rb +427 -0
- data/lib/reports/ReportTable.rb +144 -0
- data/lib/reports/ReportTableCell.rb +142 -0
- data/lib/reports/ReportTableColumn.rb +82 -0
- data/lib/reports/ReportTableElement.rb +852 -0
- data/lib/reports/ReportTableLegend.rb +167 -0
- data/lib/reports/ReportTableLine.rb +87 -0
- data/lib/reports/ResourceListRE.rb +72 -0
- data/lib/reports/TaskListRE.rb +73 -0
- data/lib/reports/TjpExportRE.rb +394 -0
- data/lib/taskjuggler3.rb +106 -0
- data/lib/tj3man.rb +88 -0
- data/manual/Day_To_Day_Juggling +168 -0
- data/manual/Getting_Started +61 -0
- data/manual/How_To_Contribute +185 -0
- data/manual/Installation +68 -0
- data/manual/Intro +102 -0
- data/manual/Reporting_Bugs +26 -0
- data/manual/Rich_Text_Attributes +90 -0
- data/manual/TaskJuggler_2x_Migration +40 -0
- data/manual/Tutorial +579 -0
- data/manual/fdl +450 -0
- data/prj_cfg.rb +43 -0
- data/setup.rb +1585 -0
- data/tasks/csts.rake +72 -0
- data/tasks/gem.rake +14 -0
- data/tasks/manual.rake +10 -0
- data/tasks/missing.rake +21 -0
- data/tasks/rcov.rake +14 -0
- data/tasks/rdoc.rake +17 -0
- data/tasks/rexml_fix.rb +16 -0
- data/tasks/rexml_fix_19.rb +49 -0
- data/tasks/show.rake +21 -0
- data/tasks/stats.rake +25 -0
- data/tasks/test.rake +11 -0
- data/test/MessageChecker.rb +53 -0
- data/test/TestSuite/CSV-Reports/celltext-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/celltext.tjp +7 -0
- data/test/TestSuite/CSV-Reports/genrefs +6 -0
- data/test/TestSuite/CSV-Reports/project-1.tji +57 -0
- data/test/TestSuite/CSV-Reports/resourcereport-Reference.csv +4 -0
- data/test/TestSuite/CSV-Reports/resourcereport.tjp +10 -0
- data/test/TestSuite/CSV-Reports/resourcereport_with_tasks-Reference.csv +22 -0
- data/test/TestSuite/CSV-Reports/resourcereport_with_tasks.tjp +11 -0
- data/test/TestSuite/CSV-Reports/sortByTree-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/sortByTree.tjp +8 -0
- data/test/TestSuite/CSV-Reports/sortBy_duration.down-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/sortBy_duration.down.tjp +10 -0
- data/test/TestSuite/CSV-Reports/sortBy_effort.up-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/sortBy_effort.up.tjp +10 -0
- data/test/TestSuite/CSV-Reports/sortBy_plan.start.down-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/sortBy_plan.start.down.tjp +10 -0
- data/test/TestSuite/CSV-Reports/taskreport-Reference.csv +14 -0
- data/test/TestSuite/CSV-Reports/taskreport.tjp +10 -0
- data/test/TestSuite/CSV-Reports/taskreport_with_resources-Reference.csv +24 -0
- data/test/TestSuite/CSV-Reports/taskreport_with_resources.tjp +11 -0
- data/test/TestSuite/Scheduler/Correct/Allocate.tjp +86 -0
- data/test/TestSuite/Scheduler/Correct/AutomaticMilestones.tjp +63 -0
- data/test/TestSuite/Scheduler/Correct/Booking.tjp +161 -0
- data/test/TestSuite/Scheduler/Correct/Depends.tjp +50 -0
- data/test/TestSuite/Scheduler/Correct/Duration.tjp +34 -0
- data/test/TestSuite/Scheduler/Correct/InheritStartEnd.tjp +129 -0
- data/test/TestSuite/Scheduler/Correct/Limits.tjp +81 -0
- data/test/TestSuite/Scheduler/Correct/MultipleMandatories.tjp +43 -0
- data/test/TestSuite/Scheduler/Correct/Optimize-1.tjp +28 -0
- data/test/TestSuite/Scheduler/Correct/Optimize-2.tjp +33 -0
- data/test/TestSuite/Scheduler/Correct/Optimize-3.tjp +33 -0
- data/test/TestSuite/Scheduler/Correct/Optimize-4.tjp +34 -0
- data/test/TestSuite/Scheduler/Correct/Optimize-5.tjp +62 -0
- data/test/TestSuite/Scheduler/Correct/Precedes.tjp +50 -0
- data/test/TestSuite/Scheduler/Correct/Shift.tjp +102 -0
- data/test/TestSuite/Scheduler/Errors/account_no_leaf.tjp +13 -0
- data/test/TestSuite/Scheduler/Errors/booking_conflict.tjp +10 -0
- data/test/TestSuite/Scheduler/Errors/booking_no_duty.tjp +9 -0
- data/test/TestSuite/Scheduler/Errors/booking_on_vacation.tjp +9 -0
- data/test/TestSuite/Scheduler/Errors/container_booking.tjp +14 -0
- data/test/TestSuite/Scheduler/Errors/container_duration.tjp +11 -0
- data/test/TestSuite/Scheduler/Errors/effort_no_allocations.tjp +7 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_1.tjp +19 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_10.tjp +36 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_11.tjp +27 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_12.tjp +20 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_13.tjp +27 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_14.tjp +26 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_2.tjp +24 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_3.tjp +18 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_4.tjp +36 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_5.tjp +37 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_6.tjp +35 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_7.tjp +46 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_8.tjp +51 -0
- data/test/TestSuite/Scheduler/Errors/loop_detected_9.tjp +20 -0
- data/test/TestSuite/Scheduler/Errors/maxend.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/maxstart.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/milestone_booking.tjp +10 -0
- data/test/TestSuite/Scheduler/Errors/milestone_duration.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/milestone_start_end.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/minend.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/minstart.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/multiple_durations.tjp +11 -0
- data/test/TestSuite/Scheduler/Errors/no_tasks.tjp +6 -0
- data/test/TestSuite/Scheduler/Errors/not_scheduled.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/task_depend_child.tjp +10 -0
- data/test/TestSuite/Scheduler/Errors/task_depend_multi.tjp +13 -0
- data/test/TestSuite/Scheduler/Errors/task_depend_parent.tjp +11 -0
- data/test/TestSuite/Scheduler/Errors/task_depend_self.tjp +10 -0
- data/test/TestSuite/Scheduler/Errors/task_depend_unknown.tjp +10 -0
- data/test/TestSuite/Scheduler/Errors/task_overspecified_1.tjp +9 -0
- data/test/TestSuite/Scheduler/Errors/task_overspecified_2.tjp +14 -0
- data/test/TestSuite/Scheduler/Errors/task_overspecified_3.tjp +14 -0
- data/test/TestSuite/Scheduler/Errors/task_underspecified_1.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/task_underspecified_2.tjp +8 -0
- data/test/TestSuite/Scheduler/Errors/task_underspecified_3.tjp +9 -0
- data/test/TestSuite/Syntax/Correct/Account.tjp +53 -0
- data/test/TestSuite/Syntax/Correct/Allocate-1.tjp +24 -0
- data/test/TestSuite/Syntax/Correct/Alternative.tjp +13 -0
- data/test/TestSuite/Syntax/Correct/AutoMacros.tjp +14 -0
- data/test/TestSuite/Syntax/Correct/Booking.tjp +26 -0
- data/test/TestSuite/Syntax/Correct/Caption.tjp +33 -0
- data/test/TestSuite/Syntax/Correct/Celltext.tjp +28 -0
- data/test/TestSuite/Syntax/Correct/Comments.tjp +29 -0
- data/test/TestSuite/Syntax/Correct/Complete.tjp +16 -0
- data/test/TestSuite/Syntax/Correct/CompletedWork.tji +20 -0
- data/test/TestSuite/Syntax/Correct/CriticalPath.tjp +31 -0
- data/test/TestSuite/Syntax/Correct/Currencyformat.tjp +12 -0
- data/test/TestSuite/Syntax/Correct/CustomAttributes.tjp +14 -0
- data/test/TestSuite/Syntax/Correct/Depends1.tjp +22 -0
- data/test/TestSuite/Syntax/Correct/Durations.tjp +29 -0
- data/test/TestSuite/Syntax/Correct/Efficiency.tjp +19 -0
- data/test/TestSuite/Syntax/Correct/Export.tjp +40 -0
- data/test/TestSuite/Syntax/Correct/Flags.tjp +32 -0
- data/test/TestSuite/Syntax/Correct/Freeze.tjp +28 -0
- data/test/TestSuite/Syntax/Correct/Gap.tjp +15 -0
- data/test/TestSuite/Syntax/Correct/HtmlTaskReport.tjp +33 -0
- data/test/TestSuite/Syntax/Correct/Limits-1.tjp +71 -0
- data/test/TestSuite/Syntax/Correct/LoadUnits.tjp +31 -0
- data/test/TestSuite/Syntax/Correct/Macro-1.tjp +19 -0
- data/test/TestSuite/Syntax/Correct/Mandatory.tjp +17 -0
- data/test/TestSuite/Syntax/Correct/Milestone.tjp +12 -0
- data/test/TestSuite/Syntax/Correct/MinMax.tjp +17 -0
- data/test/TestSuite/Syntax/Correct/Numberformat.tjp +12 -0
- data/test/TestSuite/Syntax/Correct/Period.tjp +16 -0
- data/test/TestSuite/Syntax/Correct/Persistent.tjp +11 -0
- data/test/TestSuite/Syntax/Correct/Precedes1.tjp +17 -0
- data/test/TestSuite/Syntax/Correct/Priority.tjp +30 -0
- data/test/TestSuite/Syntax/Correct/Project.tjp +21 -0
- data/test/TestSuite/Syntax/Correct/ProjectIDs.tjp +23 -0
- data/test/TestSuite/Syntax/Correct/RawHTML.tjp +29 -0
- data/test/TestSuite/Syntax/Correct/Reports.tjp +54 -0
- data/test/TestSuite/Syntax/Correct/Resource.tjp +20 -0
- data/test/TestSuite/Syntax/Correct/Responsible.tjp +16 -0
- data/test/TestSuite/Syntax/Correct/Scenario.tjp +15 -0
- data/test/TestSuite/Syntax/Correct/Scheduling.tjp +26 -0
- data/test/TestSuite/Syntax/Correct/Select.tjp +27 -0
- data/test/TestSuite/Syntax/Correct/Shift.tjp +55 -0
- data/test/TestSuite/Syntax/Correct/Simple.tjp +25 -0
- data/test/TestSuite/Syntax/Correct/String.tjp +12 -0
- data/test/TestSuite/Syntax/Correct/Supplement.tjp +24 -0
- data/test/TestSuite/Syntax/Correct/TaskRoot.tjp +34 -0
- data/test/TestSuite/Syntax/Correct/TimeFrame.tjp +19 -0
- data/test/TestSuite/Syntax/Correct/Timezone.tjp +8 -0
- data/test/TestSuite/Syntax/Correct/Vacation.tjp +33 -0
- data/test/TestSuite/Syntax/Correct/csvtest +16 -0
- data/test/TestSuite/Syntax/Correct/manual2example.rb +24 -0
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +485 -0
- data/test/TestSuite/Syntax/Errors/bad_include.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/booking_group.tjp +14 -0
- data/test/TestSuite/Syntax/Errors/booking_milestone.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/booking_no_leaf.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/chargeset.tjp +14 -0
- data/test/TestSuite/Syntax/Errors/chargeset_master.tjp +15 -0
- data/test/TestSuite/Syntax/Errors/container_attribute.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/cost_acct_no_top.tjp +24 -0
- data/test/TestSuite/Syntax/Errors/cost_rev_same.tjp +24 -0
- data/test/TestSuite/Syntax/Errors/date_in_range.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/effort_zero.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/empty.tjp +1 -0
- data/test/TestSuite/Syntax/Errors/export_bad_extn.tjp +9 -0
- data/test/TestSuite/Syntax/Errors/extend_id_cap.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/interval_end_in_range.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/interval_start_in_range.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/leaf_resource_id_expected.tjp +12 -0
- data/test/TestSuite/Syntax/Errors/misaligned_date.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/no_csv_suffix.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/no_html_suffix.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/operand_attribute.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/operand_unkn_flag.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/operand_unkn_scen.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/overtime_range.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/purge_no_list.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/purge_unknown_id.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/report_end.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/report_redifinition.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/report_start.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/resource_exists.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/resource_id_expected.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/rev_acct_no_top.tjp +24 -0
- data/test/TestSuite/Syntax/Errors/scenario_exists.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/shift_assignment_overlap.tjp +15 -0
- data/test/TestSuite/Syntax/Errors/shift_exists.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/shift_id_expected.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/sloppy_range.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/sort_direction.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/sort_unknown_scen.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/sorting_crit_exptd1.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/sorting_crit_exptd2.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/sorting_wbs.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/start_before_end1.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/start_before_end2.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/task_complete.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/task_exists.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/task_priority.tjp +8 -0
- data/test/TestSuite/Syntax/Errors/task_without_chargeset.tjp +9 -0
- data/test/TestSuite/Syntax/Errors/time_interval.tjp +12 -0
- data/test/TestSuite/Syntax/Errors/too_many_bangs.tjp +10 -0
- data/test/TestSuite/Syntax/Errors/undecl_flag.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/unknown_projectid.tjp +7 -0
- data/test/TestSuite/Syntax/Errors/unknown_scenario_id.tjp +6 -0
- data/test/TestSuite/Syntax/Errors/unknown_scenario_idx.tjp +11 -0
- data/test/TestSuite/Syntax/Errors/unknown_task.tjp +10 -0
- data/test/all.rb +31 -0
- data/test/test_BatchProcessor.rb +54 -0
- data/test/test_CSV-Reports.rb +101 -0
- data/test/test_Limits.rb +104 -0
- data/test/test_LogicalExpression.rb +110 -0
- data/test/test_MacroTable.rb +51 -0
- data/test/test_Project.rb +57 -0
- data/test/test_PropertySet.rb +71 -0
- data/test/test_Query.rb +83 -0
- data/test/test_RealFormat.rb +83 -0
- data/test/test_RichText.rb +869 -0
- data/test/test_Scheduler.rb +42 -0
- data/test/test_ShiftAssignments.rb +77 -0
- data/test/test_Syntax.rb +41 -0
- data/test/test_TextScanner.rb +95 -0
- data/test/test_TjTime.rb +114 -0
- data/test/test_TjpExample.rb +169 -0
- data/test/test_UTF8String.rb +84 -0
- data/test/test_WorkingHours.rb +56 -0
- metadata +649 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = MessageHandler.rb -- The TaskJuggler III Project Management Software
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
|
|
7
|
+
#
|
|
8
|
+
# This program is free software; you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of version 2 of the GNU General Public License as
|
|
10
|
+
# published by the Free Software Foundation.
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
class TaskJuggler
|
|
14
|
+
|
|
15
|
+
class MessageHandler
|
|
16
|
+
|
|
17
|
+
attr_reader :messages
|
|
18
|
+
|
|
19
|
+
def initialize(console = false)
|
|
20
|
+
@messages = []
|
|
21
|
+
@console = console
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def send(message)
|
|
25
|
+
@messages << message
|
|
26
|
+
if @console
|
|
27
|
+
$stderr.puts message
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
|
data/lib/Project.rb
ADDED
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = Project.rb -- The TaskJuggler III Project Management Software
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009 by Chris Schlaeger <cs@kde.org>
|
|
7
|
+
#
|
|
8
|
+
# This program is free software; you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of version 2 of the GNU General Public License as
|
|
10
|
+
# published by the Free Software Foundation.
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
require 'TjTime'
|
|
14
|
+
require 'Booking'
|
|
15
|
+
require 'PropertySet'
|
|
16
|
+
require 'Attributes'
|
|
17
|
+
require 'RealFormat'
|
|
18
|
+
require 'PropertyList'
|
|
19
|
+
require 'TaskDependency'
|
|
20
|
+
require 'Scenario'
|
|
21
|
+
require 'Shift'
|
|
22
|
+
require 'Account'
|
|
23
|
+
require 'Task'
|
|
24
|
+
require 'Resource'
|
|
25
|
+
require 'reports/Report'
|
|
26
|
+
require 'ShiftAssignments'
|
|
27
|
+
require 'WorkingHours'
|
|
28
|
+
require 'ProjectFileParser'
|
|
29
|
+
require 'BatchProcessor'
|
|
30
|
+
|
|
31
|
+
class TaskJuggler
|
|
32
|
+
|
|
33
|
+
# This class implements objects that hold all project properties. Project
|
|
34
|
+
# generally consist of resources, tasks and a number of other optional
|
|
35
|
+
# properties. Tasks, Resources, Accounts and Shifts are all build on the
|
|
36
|
+
# same underlying storage class PropertyTreeNode. Properties of the same
|
|
37
|
+
# kind are kept in PropertySet objects. There is only one PropertySet for
|
|
38
|
+
# each type of property. Additionally, each property may belong to various
|
|
39
|
+
# PropertyList objects. In contrast to PropertySet objects, PropertyList
|
|
40
|
+
# object have well defined sorting order and no information about the
|
|
41
|
+
# attributes of each type of property. The PropertySet holds the blueprints
|
|
42
|
+
# for the data construction inside the PropertyTreeNode objects. It contains
|
|
43
|
+
# the list of known Attributes.
|
|
44
|
+
class Project
|
|
45
|
+
|
|
46
|
+
attr_reader :accounts, :shifts, :tasks, :resources, :scenarios,
|
|
47
|
+
:reports, :messageHandler
|
|
48
|
+
|
|
49
|
+
# Create a project with the specified +id+, +name+ and +version+.
|
|
50
|
+
# +messageHandler+ is a MessageHandler reference that is used to handle
|
|
51
|
+
# all error and warning messages that might occur during processing. The
|
|
52
|
+
# constructor will set default values for all project attributes.
|
|
53
|
+
def initialize(id, name, version, messageHandler)
|
|
54
|
+
@messageHandler = messageHandler
|
|
55
|
+
@attributes = {
|
|
56
|
+
'projectid' => id,
|
|
57
|
+
'projectids' => [ id ],
|
|
58
|
+
'name' => name,
|
|
59
|
+
'version' => version,
|
|
60
|
+
'costAccount' => nil,
|
|
61
|
+
'copyright' => nil,
|
|
62
|
+
'currency' => "EUR",
|
|
63
|
+
'currencyformat' => RealFormat.new([ '-', '', '', ',', 2 ]),
|
|
64
|
+
'dailyworkinghours' => 8.0,
|
|
65
|
+
'end' => nil,
|
|
66
|
+
'flags' => [],
|
|
67
|
+
'limits' => nil,
|
|
68
|
+
'loadunit' => :shortauto,
|
|
69
|
+
'now' => TjTime.now.align(3600),
|
|
70
|
+
'numberformat' => RealFormat.new([ '-', '', '', '.', 1]),
|
|
71
|
+
'priority' => 500,
|
|
72
|
+
'rate' => 0.0,
|
|
73
|
+
'revenueAccount' => nil,
|
|
74
|
+
'scheduleGranularity' => 3600,
|
|
75
|
+
'shorttimeformat' => "%H:%M",
|
|
76
|
+
'start' => nil,
|
|
77
|
+
'timeformat' => "%Y-%m-%d",
|
|
78
|
+
'timezone' => nil,
|
|
79
|
+
'vacations' => [],
|
|
80
|
+
'weekstartsmonday' => true,
|
|
81
|
+
'workinghours' => WorkingHours.new,
|
|
82
|
+
'yearlyworkingdays' => 260.714
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Before we can add any properties to this project, we need to define the
|
|
86
|
+
# attributes that each of the property types will be using. In TaskJuggler
|
|
87
|
+
# lingo, properties of a project are resources, tasks, accounts, shifts
|
|
88
|
+
# and scenarios. Each of these properties can have lots of further
|
|
89
|
+
# information attached to it. These bits of information are called
|
|
90
|
+
# attributes. An attribute is defined by the AttributeDefinition class.
|
|
91
|
+
# The PropertySet objects need to be fed with a list of such attribute
|
|
92
|
+
# definitions to register the attributes with the properties.
|
|
93
|
+
@scenarios = PropertySet.new(self, true)
|
|
94
|
+
attrs = [
|
|
95
|
+
# ID Name Type Inh. Scen. Default
|
|
96
|
+
[ 'enabled', 'Enabled', BooleanAttribute, true, false, true ],
|
|
97
|
+
[ 'minslackrate', 'Min. Slack Rate', FloatAttribute, true, false, 0.0 ],
|
|
98
|
+
[ 'projection', 'Projection Mode', BooleanAttribute, true, false, false ],
|
|
99
|
+
[ 'strict', 'Strict Bookings', BooleanAttribute, true, false, false ]
|
|
100
|
+
]
|
|
101
|
+
attrs.each { |a| @scenarios.addAttributeType(AttributeDefinition.new(*a)) }
|
|
102
|
+
|
|
103
|
+
@shifts = PropertySet.new(self, true)
|
|
104
|
+
attrs = [
|
|
105
|
+
# ID Name Type Inher. Scen. Default
|
|
106
|
+
[ 'index', 'Index', FixnumAttribute, false, false, -1 ],
|
|
107
|
+
[ 'replace', 'Replace', BooleanAttribute, true, true, false ],
|
|
108
|
+
[ 'timezone', 'Time Zone', StringAttribute, true, true, nil ],
|
|
109
|
+
[ 'tree', 'Tree Index', StringAttribute, false, false, "" ],
|
|
110
|
+
[ 'vacations', 'Vacations', IntervalListAttribute, true, true, [] ],
|
|
111
|
+
[ 'wbs', 'WBS', StringAttribute, false, false, "" ],
|
|
112
|
+
[ 'workinghours', 'Working Hours', WorkingHoursAttribute, true, true,
|
|
113
|
+
nil ]
|
|
114
|
+
]
|
|
115
|
+
attrs.each { |a| @shifts.addAttributeType(AttributeDefinition.new(*a)) }
|
|
116
|
+
|
|
117
|
+
@accounts = PropertySet.new(self, true)
|
|
118
|
+
attrs = [
|
|
119
|
+
# ID Name Type Inher. Scen. Default
|
|
120
|
+
[ 'index', 'Index', FixnumAttribute, false, false, -1 ],
|
|
121
|
+
[ 'tree', 'Tree Index', StringAttribute, false, false, "" ],
|
|
122
|
+
[ 'wbs', 'WBS', StringAttribute, false, false, "" ]
|
|
123
|
+
]
|
|
124
|
+
attrs.each { |a| @accounts.addAttributeType(AttributeDefinition.new(*a)) }
|
|
125
|
+
|
|
126
|
+
@resources = PropertySet.new(self, true)
|
|
127
|
+
attrs = [
|
|
128
|
+
# ID Name Type Inher. Scen. Default
|
|
129
|
+
[ 'alloctdeffort', 'Alloctd. Effort', FloatAttribute, false, true, 0.0 ],
|
|
130
|
+
[ 'criticalness', 'Criticalness', FloatAttribute, false, true, 0.0 ],
|
|
131
|
+
[ 'duties', 'Duties', TaskListAttribute, false, true, [] ],
|
|
132
|
+
[ 'efficiency','Efficiency', FloatAttribute, true, true, 1.0 ],
|
|
133
|
+
[ 'effort', 'Total Effort', FixnumAttribute, false, true, 0 ],
|
|
134
|
+
[ 'email', 'Email', StringAttribute, true, false, nil ],
|
|
135
|
+
[ 'flags', 'Flags', FlagListAttribute, true, true, [] ],
|
|
136
|
+
[ 'fte', 'FTE', FloatAttribute, false, true, 1.0 ],
|
|
137
|
+
[ 'headcount', 'Headcount', FixnumAttribute, false, true, 1 ],
|
|
138
|
+
[ 'index', 'Index', FixnumAttribute, false, false, -1 ],
|
|
139
|
+
[ 'limits', 'Limits', LimitsAttribute, true, true, nil ],
|
|
140
|
+
[ 'rate', 'Rate', FloatAttribute, true, true, 0.0 ],
|
|
141
|
+
[ 'shifts', 'Shifts', ShiftAssignmentsAttribute, true, true,
|
|
142
|
+
nil ],
|
|
143
|
+
[ 'timezone', 'Time Zone', StringAttribute, true, true, nil ],
|
|
144
|
+
[ 'tree', 'Tree Index', StringAttribute, false, false, "" ],
|
|
145
|
+
[ 'vacations', 'Vacations', IntervalListAttribute, true, true, [] ],
|
|
146
|
+
[ 'wbs', 'WBS', StringAttribute, false, false, "" ],
|
|
147
|
+
[ 'workinghours', 'Working Hours', WorkingHoursAttribute, true, true,
|
|
148
|
+
nil ]
|
|
149
|
+
]
|
|
150
|
+
attrs.each { |a| @resources.addAttributeType(AttributeDefinition.new(*a)) }
|
|
151
|
+
|
|
152
|
+
@tasks = PropertySet.new(self, false)
|
|
153
|
+
attrs = [
|
|
154
|
+
# ID Name Type Inher. Scen. Default
|
|
155
|
+
[ 'allocate', 'Allocations', AllocationAttribute, true, true, [] ],
|
|
156
|
+
[ 'assignedresources', 'Assigned Resources', ResourceListAttribute, false, true, [] ],
|
|
157
|
+
[ 'booking', 'Bookings', BookingListAttribute, false, true, [] ],
|
|
158
|
+
[ 'charge', 'Charges', ChargeListAttribute, false, true, [] ],
|
|
159
|
+
[ 'chargeset', 'Charge Sets', ChargeSetListAttribute, true, true, [] ],
|
|
160
|
+
[ 'complete', 'Completion', FloatAttribute, false, true, nil ],
|
|
161
|
+
[ 'criticalness', 'Criticalness', FloatAttribute, false, true, 0.0 ],
|
|
162
|
+
[ 'depends', '-', DependencyListAttribute, true, true, [] ],
|
|
163
|
+
[ 'duration', 'Duration', DurationAttribute, false, true, 0 ],
|
|
164
|
+
[ 'effort', 'Effort', DurationAttribute, false, true, 0 ],
|
|
165
|
+
[ 'end', 'End', DateAttribute, true, true, nil ],
|
|
166
|
+
[ 'endpreds', 'End Preds.', TaskListAttribute, false, true, [] ],
|
|
167
|
+
[ 'endsuccs', 'End Succs.', TaskListAttribute, false, true, [] ],
|
|
168
|
+
[ 'flags', 'Flags', FlagListAttribute, true, true, [] ],
|
|
169
|
+
[ 'forward', 'Scheduling', BooleanAttribute, true, true, true ],
|
|
170
|
+
[ 'index', 'Index', FixnumAttribute, false, false, -1 ],
|
|
171
|
+
[ 'length', 'Length', DurationAttribute, false, true, 0 ],
|
|
172
|
+
[ 'limits', 'Limits', LimitsAttribute, false, true, nil ],
|
|
173
|
+
[ 'maxend', 'Max. End', DateAttribute, true, true, nil ],
|
|
174
|
+
[ 'maxstart', 'Max. Start', DateAttribute, true, true, nil ],
|
|
175
|
+
[ 'milestone', 'Milestone', BooleanAttribute, false, true, false ],
|
|
176
|
+
[ 'minend', 'Min. End', DateAttribute, true, true, nil ],
|
|
177
|
+
[ 'minstart', 'Min. Start', DateAttribute, true, true, nil ],
|
|
178
|
+
[ 'note', 'Note', RichTextAttribute, false, false, nil ],
|
|
179
|
+
[ 'pathcriticalness', 'Path Criticalness', FloatAttribute, false, true, 0.0 ],
|
|
180
|
+
[ 'precedes', '-', DependencyListAttribute, true, true, [] ],
|
|
181
|
+
[ 'priority', 'Priority', FixnumAttribute, true, true, 500 ],
|
|
182
|
+
[ 'projectid', 'Project ID', SymbolAttribute, true, true, nil ],
|
|
183
|
+
[ 'responsible', 'Responsible', ResourceListAttribute, true, true, [] ],
|
|
184
|
+
[ 'scheduled', 'Scheduled', BooleanAttribute, true, true, false ],
|
|
185
|
+
[ 'shifts', 'Shifts', ShiftAssignmentsAttribute, true, true,
|
|
186
|
+
nil ],
|
|
187
|
+
[ 'start', 'Start', DateAttribute, true, true, nil ],
|
|
188
|
+
[ 'startpreds', 'Start Preds.', TaskListAttribute, false, true, [] ],
|
|
189
|
+
[ 'startsuccs', 'Start Succs.', TaskListAttribute, false, true, [] ],
|
|
190
|
+
[ 'tree', 'Tree Index', StringAttribute, false, false, "" ],
|
|
191
|
+
[ 'wbs', 'WBS', StringAttribute, false, false, "" ]
|
|
192
|
+
]
|
|
193
|
+
attrs.each { |a| @tasks.addAttributeType(AttributeDefinition.new(*a)) }
|
|
194
|
+
|
|
195
|
+
Scenario.new(self, 'plan', 'Plan Scenario', nil)
|
|
196
|
+
|
|
197
|
+
@reports = { }
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Pass a message (error or warning) to the message handler. _message_ is a
|
|
201
|
+
# String that contains the message.
|
|
202
|
+
def sendMessage(message)
|
|
203
|
+
@messageHandler.send(message)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Query the value of a Project attribute. _name_ is the ID of the attribute.
|
|
207
|
+
def [](name)
|
|
208
|
+
if !@attributes.has_key?(name)
|
|
209
|
+
raise "Unknown project attribute #{name}"
|
|
210
|
+
end
|
|
211
|
+
@attributes[name]
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Set the Project attribute with ID _name_ to _value_.
|
|
215
|
+
def []=(name, value)
|
|
216
|
+
if !@attributes.has_key?(name)
|
|
217
|
+
raise "Unknown project attribute #{name}"
|
|
218
|
+
end
|
|
219
|
+
@attributes[name] = value
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Return the number of defined scenarios for the project.
|
|
223
|
+
def scenarioCount
|
|
224
|
+
@scenarios.items
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Return the average number of working hours per day. This defaults to 8 but
|
|
228
|
+
# can be set to other values by the user.
|
|
229
|
+
def dailyWorkingHours
|
|
230
|
+
@attributes['dailyworkinghours'].to_f
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Return the average number of working days per week.
|
|
234
|
+
def weeklyWorkingDays
|
|
235
|
+
@attributes['yearlyworkingdays'] / 52.1429
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Return the average number of working days per month.
|
|
239
|
+
def monthlyWorkingDays
|
|
240
|
+
@attributes['yearlyworkingdays'] / 12.0
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Return the average number of working days per year.
|
|
244
|
+
def yearlyWorkingDays
|
|
245
|
+
@attributes['yearlyworkingdays'].to_f
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# call-seq:
|
|
249
|
+
# scenario(index) -> Scenario
|
|
250
|
+
# scenario(id) -> Scenario
|
|
251
|
+
#
|
|
252
|
+
# Return the Scenario with the given _id_ or _index_.
|
|
253
|
+
def scenario(arg)
|
|
254
|
+
if arg.is_a?(Fixnum)
|
|
255
|
+
if $DEBUG && (arg < 0 || arg >= @scenarios.items)
|
|
256
|
+
raise "Scenario index out of range: #{arg}"
|
|
257
|
+
end
|
|
258
|
+
@scenarios.each do |sc|
|
|
259
|
+
return sc if sc.sequenceNo - 1 == arg
|
|
260
|
+
end
|
|
261
|
+
raise "No scenario with index #{arg}"
|
|
262
|
+
else
|
|
263
|
+
if $DEBUG && @scenarios[arg].nil?
|
|
264
|
+
raise "No scenario with id '#{arg}'"
|
|
265
|
+
end
|
|
266
|
+
@scenarios[arg]
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# call-seq:
|
|
271
|
+
# scenarioIdx(scenario)
|
|
272
|
+
# scenarioIdx(id)
|
|
273
|
+
#
|
|
274
|
+
# Return the index of the given Scenario specified by _scenario_ or _id_.
|
|
275
|
+
def scenarioIdx(sc)
|
|
276
|
+
if sc.is_a?(Scenario)
|
|
277
|
+
return sc.sequenceNo - 1
|
|
278
|
+
elsif @scenarios[sc].nil?
|
|
279
|
+
return nil
|
|
280
|
+
else
|
|
281
|
+
return @scenarios[sc].sequenceNo - 1
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# Return the Shift with the ID _id_ or return nil if it does not exist.
|
|
286
|
+
def shift(id)
|
|
287
|
+
@shifts[id]
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Return the Account with the ID _id_ or return nil if it does not exist.
|
|
291
|
+
def account(id)
|
|
292
|
+
@accounts[id]
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Return the Task with the ID _id_ or return nil if it does not exist.
|
|
296
|
+
def task(id)
|
|
297
|
+
@tasks[id]
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# Return the Resource with the ID _id_ or return nil if it does not exist.
|
|
301
|
+
def resource(id)
|
|
302
|
+
@resources[id]
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# This function must be called after the Project data structures have been
|
|
306
|
+
# filled with data. It schedules all scenario and stores the result in the
|
|
307
|
+
# data structures again.
|
|
308
|
+
def schedule
|
|
309
|
+
[ @shifts, @resources, @tasks ].each do |p|
|
|
310
|
+
p.inheritAttributesFromScenario
|
|
311
|
+
# Set all index counters to their proper values.
|
|
312
|
+
p.index
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
if @tasks.empty?
|
|
316
|
+
message = Message.new('no_tasks', 'error', "No tasks defined")
|
|
317
|
+
sendMessage(message)
|
|
318
|
+
return false
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
begin
|
|
322
|
+
@scenarios.each do |sc|
|
|
323
|
+
# Skip disabled scenarios
|
|
324
|
+
next unless sc.get('enabled')
|
|
325
|
+
|
|
326
|
+
scIdx = scenarioIdx(sc)
|
|
327
|
+
|
|
328
|
+
# All user provided values are set now. The next step is to
|
|
329
|
+
# propagate inherited values. These values must be marked as
|
|
330
|
+
# inherited by setting the mode to 1. As we always call
|
|
331
|
+
# PropertyTreeNode#inherit this is just a safeguard.
|
|
332
|
+
AttributeBase.setMode(1)
|
|
333
|
+
prepareScenario(scIdx)
|
|
334
|
+
|
|
335
|
+
# Now change to mode 2 so all values that are modified are marked
|
|
336
|
+
# as computed.
|
|
337
|
+
AttributeBase.setMode(2)
|
|
338
|
+
# Schedule the scenario.
|
|
339
|
+
scheduleScenario(scIdx)
|
|
340
|
+
|
|
341
|
+
# Complete the data sets, and check the result.
|
|
342
|
+
finishScenario(scIdx)
|
|
343
|
+
end
|
|
344
|
+
rescue TjException
|
|
345
|
+
return false
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
true
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# Call this function to generate the reports based on the scheduling result.
|
|
352
|
+
# This function may only be called after Project#schedule has been called.
|
|
353
|
+
def generateReports(maxCpuCores)
|
|
354
|
+
begin
|
|
355
|
+
if maxCpuCores == 1
|
|
356
|
+
@reports.each_value do |report|
|
|
357
|
+
Log.startProgressMeter("Report #{report.name}")
|
|
358
|
+
report.generate
|
|
359
|
+
Log.stopProgressMeter
|
|
360
|
+
end
|
|
361
|
+
else
|
|
362
|
+
bp = BatchProcessor.new(maxCpuCores)
|
|
363
|
+
@reports.each_value { |report| bp.queue(report) { report.generate } }
|
|
364
|
+
bp.wait do |report|
|
|
365
|
+
$stdout.print(report.stdout)
|
|
366
|
+
$stderr.print(report.stderr)
|
|
367
|
+
Log.startProgressMeter("Report #{report.tag.name}")
|
|
368
|
+
Log.stopProgressMeter
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
rescue TjException
|
|
372
|
+
$stderr.puts "Report Generation Error: #{$!}"
|
|
373
|
+
return false
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
true
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
####################################################################
|
|
380
|
+
# The following functions are not intended to be called from outside
|
|
381
|
+
# the TaskJuggler library. There is no guarantee that these
|
|
382
|
+
# functions will be usable or present in future releases.
|
|
383
|
+
####################################################################
|
|
384
|
+
|
|
385
|
+
def addScenario(scenario) # :nodoc:
|
|
386
|
+
@scenarios.addProperty(scenario)
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def addShift(shift) # :nodoc:
|
|
390
|
+
@shifts.addProperty(shift)
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
def addAccount(account) # :nodoc:
|
|
394
|
+
@accounts.addProperty(account)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def addTask(task) # :nodoc:
|
|
398
|
+
@tasks.addProperty(task)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def addResource(resource) # :nodoc:
|
|
402
|
+
@resources.addProperty(resource)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
def addReport(report) # :nodoc:
|
|
406
|
+
@reports[report.name] = report
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# call-seq:
|
|
410
|
+
# isWorkingTime(slot) -> true or false
|
|
411
|
+
# isWorkingTime(startTime, endTime) -> true or false
|
|
412
|
+
# isWorkingTime(interval) -> true or false
|
|
413
|
+
#
|
|
414
|
+
# Return true if the _slot_ (TjTime) is withing globally defined working
|
|
415
|
+
# time or false if not. If the argument is an Interval, all slots of the
|
|
416
|
+
# interval must be working time to return true as result. Global work time
|
|
417
|
+
# means, no vacation defined and the slot lies within a defined working time
|
|
418
|
+
# period.
|
|
419
|
+
def isWorkingTime(*args)
|
|
420
|
+
# Normalize argument(s) to Interval
|
|
421
|
+
if args.length == 1
|
|
422
|
+
if args[0].is_a?(Interval)
|
|
423
|
+
iv = args[0]
|
|
424
|
+
else
|
|
425
|
+
iv = Interval.new(args[0], args[0] +
|
|
426
|
+
@attributes['scheduleGranularity'])
|
|
427
|
+
end
|
|
428
|
+
else
|
|
429
|
+
iv = Interval.new(args[0], args[1])
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
# Check if the interval has overlap with any of the global vacations.
|
|
433
|
+
@attributes['vacations'].each do |vacation|
|
|
434
|
+
return false if vacation.overlaps?(iv)
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
return false if @attributes['workinghours'].timeOff?(iv)
|
|
438
|
+
|
|
439
|
+
true
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
# Convert working _seconds_ to working days. The result depends on the
|
|
443
|
+
# setting of the global 'dailyworkinghours' attribute.
|
|
444
|
+
def convertToDailyLoad(seconds)
|
|
445
|
+
seconds / (@attributes['dailyworkinghours'] * 3600.0)
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
# Many internal data structures use Scoreboard objects to keep track of
|
|
449
|
+
# scheduling data. These have one entry for every schedulable time slot in
|
|
450
|
+
# the project time frame. This functions returns the number of entries in
|
|
451
|
+
# the scoreboards.
|
|
452
|
+
def scoreboardSize
|
|
453
|
+
((@attributes['end'] - @attributes['start']) /
|
|
454
|
+
@attributes['scheduleGranularity']).to_i
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
# Convert a Scoreboard index to the equivalent date. _idx_ is the index and
|
|
458
|
+
# it must be within the range of the Scoreboard objects. If not, an
|
|
459
|
+
# exception is raised.
|
|
460
|
+
def idxToDate(idx)
|
|
461
|
+
if $DEBUG && (idx < 0 || idx > scoreboardSize)
|
|
462
|
+
raise "Scoreboard index out of range"
|
|
463
|
+
end
|
|
464
|
+
@attributes['start'] + idx * @attributes['scheduleGranularity']
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
# Convert a _date_ (TjTime) to the equivalent Scoreboard index. If
|
|
468
|
+
# _forceIntoProject_ is true, the date will be pushed into the project time
|
|
469
|
+
# frame.
|
|
470
|
+
def dateToIdx(date, forceIntoProject = false)
|
|
471
|
+
if (date < @attributes['start'] || date > @attributes['end'])
|
|
472
|
+
# Date is out of range.
|
|
473
|
+
if forceIntoProject
|
|
474
|
+
return 0 if date < @attributes['start']
|
|
475
|
+
return scoreboardSize - 1 if date > @attributes['end']
|
|
476
|
+
else
|
|
477
|
+
raise "Date #{date} is out of project time range " +
|
|
478
|
+
"(#{@attributes['start']} - #{@attributes['end']})"
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
# Calculate the corresponding index.
|
|
482
|
+
((date - @attributes['start']) / @attributes['scheduleGranularity']).to_i
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
# Print the attribute values. It's used for debugging only.
|
|
486
|
+
def to_s
|
|
487
|
+
@attributes.each do |attribute, value|
|
|
488
|
+
if value
|
|
489
|
+
puts "#{attribute}: " +
|
|
490
|
+
"#{value.is_a?(PropertyTreeNode) ? value.fullId : value}"
|
|
491
|
+
end
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
protected
|
|
496
|
+
|
|
497
|
+
def prepareScenario(scIdx)
|
|
498
|
+
Log.startProgressMeter("Preparing scenario #{scenario(scIdx).get('name')}")
|
|
499
|
+
resources = PropertyList.new(@resources)
|
|
500
|
+
tasks = PropertyList.new(@tasks)
|
|
501
|
+
|
|
502
|
+
# Compile a list of leaf resources that are actually used in this
|
|
503
|
+
# project.
|
|
504
|
+
usedResources = []
|
|
505
|
+
tasks.each do |task|
|
|
506
|
+
task.candidates(scIdx).each do |resource|
|
|
507
|
+
usedResources << resource unless usedResources.include?(resource)
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
total = usedResources.length
|
|
511
|
+
i = 0
|
|
512
|
+
usedResources.each do |resource|
|
|
513
|
+
resource.prepareScheduling(scIdx)
|
|
514
|
+
i += 1
|
|
515
|
+
Log.progress((i.to_f / total) * 0.8)
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
tasks.each { |task| task.prepareScheduling(scIdx) }
|
|
519
|
+
|
|
520
|
+
tasks.each { |task| task.Xref(scIdx) }
|
|
521
|
+
tasks.each { |task| task.propagateInitialValues(scIdx) }
|
|
522
|
+
tasks.each { |task| task.preScheduleCheck(scIdx) }
|
|
523
|
+
|
|
524
|
+
# Check for dependency loops in the task graph.
|
|
525
|
+
tasks.each { |task| task.resetLoopFlags(scIdx) }
|
|
526
|
+
tasks.each do |task|
|
|
527
|
+
task.checkForLoops(scIdx, [], false, true) if task.parent.nil?
|
|
528
|
+
end
|
|
529
|
+
Log.progress(0.85)
|
|
530
|
+
tasks.each { |task| task.resetLoopFlags(scIdx) }
|
|
531
|
+
tasks.each do |task|
|
|
532
|
+
task.checkForLoops(scIdx, [], true, true) if task.parent.nil?
|
|
533
|
+
end
|
|
534
|
+
Log.progress(0.87)
|
|
535
|
+
|
|
536
|
+
# Compute the criticalness of the tasks and their pathes.
|
|
537
|
+
tasks.each { |task| task.countResourceAllocations(scIdx) }
|
|
538
|
+
Log.progress(0.88)
|
|
539
|
+
resources.each { |resource| resource.calcCriticalness(scIdx) }
|
|
540
|
+
Log.progress(0.9)
|
|
541
|
+
tasks.each { |task| task.calcCriticalness(scIdx) }
|
|
542
|
+
Log.progress(0.95)
|
|
543
|
+
tasks.each { |task| task.calcPathCriticalness(scIdx) }
|
|
544
|
+
Log.progress(1.0)
|
|
545
|
+
|
|
546
|
+
Log.stopProgressMeter
|
|
547
|
+
# This is used for debugging only
|
|
548
|
+
if false
|
|
549
|
+
resources.each do |resource|
|
|
550
|
+
puts resource
|
|
551
|
+
end
|
|
552
|
+
tasks.each do |task|
|
|
553
|
+
puts task
|
|
554
|
+
end
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
def finishScenario(scIdx)
|
|
559
|
+
Log.startProgressMeter("Checking scenario #{scenario(scIdx).get('name')}")
|
|
560
|
+
total = @tasks.items
|
|
561
|
+
i = 0
|
|
562
|
+
@tasks.each do |task|
|
|
563
|
+
task.finishScheduling(scIdx)
|
|
564
|
+
i += 1
|
|
565
|
+
Log.progress((i.to_f / total) * 0.5)
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
i = 0
|
|
569
|
+
@tasks.each do |task|
|
|
570
|
+
task.postScheduleCheck(scIdx) if task.parent.nil?
|
|
571
|
+
i += 1
|
|
572
|
+
Log.progress(0.5 + (i.to_f / total) * 0.5)
|
|
573
|
+
end
|
|
574
|
+
Log.stopProgressMeter
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
# Schedule all tasks for the given Scenario with index +scIdx+.
|
|
578
|
+
def scheduleScenario(scIdx)
|
|
579
|
+
tasks = PropertyList.new(@tasks)
|
|
580
|
+
tasks.delete_if { |task| !task.leaf? }
|
|
581
|
+
|
|
582
|
+
Log.enter('scheduleScenario', "#{tasks.length} leaf tasks")
|
|
583
|
+
# The sorting of the work item list determines which tasks will get their
|
|
584
|
+
# resources first. The first sorting criterium is the user specified task
|
|
585
|
+
# priority. The second criterium is the scheduler determined priority
|
|
586
|
+
# stored in the pathcriticalness attribute. That way, the user can always
|
|
587
|
+
# override the scheduler determined priority. To always have a defined
|
|
588
|
+
# order, the third criterium is the sequence number.
|
|
589
|
+
tasks.setSorting([ [ 'priority', false, scIdx ],
|
|
590
|
+
[ 'pathcriticalness', false, scIdx ],
|
|
591
|
+
[ 'seqno', true, -1 ] ])
|
|
592
|
+
tasks.sort!
|
|
593
|
+
totalTasks = tasks.length
|
|
594
|
+
|
|
595
|
+
# Enter the main scheduling loop. This loop is only terminated when all
|
|
596
|
+
# tasks have been scheduled or another thread has set the breakFlag to
|
|
597
|
+
# true.
|
|
598
|
+
Log.startProgressMeter("Scheduling scenario " +
|
|
599
|
+
"#{scenario(scIdx).get('name')}")
|
|
600
|
+
loop do
|
|
601
|
+
# The main scheduler loop only needs to look at the first task that is
|
|
602
|
+
# ready to be scheduled.
|
|
603
|
+
workItems = Array.new(tasks)
|
|
604
|
+
|
|
605
|
+
# Count the already completed tasks.
|
|
606
|
+
completedTasks = 0
|
|
607
|
+
workItems.each do |task|
|
|
608
|
+
completedTasks += 1 if task['scheduled', scIdx]
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
Log.progress(completedTasks.to_f / totalTasks)
|
|
612
|
+
# Remove all tasks that are not ready for scheduling yet.
|
|
613
|
+
workItems.delete_if { |task| !task.readyForScheduling?(scIdx) }
|
|
614
|
+
|
|
615
|
+
# Check if we are done.
|
|
616
|
+
break if workItems.empty?
|
|
617
|
+
|
|
618
|
+
# The first task in the list is the one with the highes priority and
|
|
619
|
+
# the largest path criticalness that is ready to be scheduled.
|
|
620
|
+
task = workItems[0]
|
|
621
|
+
# Schedule it.
|
|
622
|
+
if task.schedule(scIdx)
|
|
623
|
+
Log << "Task #{task.fullId}: #{task['start', scIdx]} -> " +
|
|
624
|
+
"#{task['end', scIdx]}"
|
|
625
|
+
end
|
|
626
|
+
end
|
|
627
|
+
unscheduledTasks = []
|
|
628
|
+
tasks.each { |t| unscheduledTasks << t unless t['scheduled', scIdx] }
|
|
629
|
+
|
|
630
|
+
# Check for unscheduled tasks and report the first 10 of them as
|
|
631
|
+
# warnings.
|
|
632
|
+
unless unscheduledTasks.empty?
|
|
633
|
+
message = Message.new('unscheduled_tasks', 'warning',
|
|
634
|
+
"#{unscheduledTasks.length} tasks could not be " +
|
|
635
|
+
"scheduled")
|
|
636
|
+
sendMessage(message)
|
|
637
|
+
i = 0
|
|
638
|
+
unscheduledTasks.each do |t|
|
|
639
|
+
message = Message.new(
|
|
640
|
+
'unscheduled_task', 'warning',
|
|
641
|
+
"Task #{t.fullId}: " +
|
|
642
|
+
"#{t['start', scIdx] ? t['start', scIdx] : '<?>'} -> " +
|
|
643
|
+
"#{t['end', scIdx] ? t['end', scIdx] : '<?>'}", t,
|
|
644
|
+
scenario(scIdx))
|
|
645
|
+
sendMessage(message)
|
|
646
|
+
|
|
647
|
+
i += 1
|
|
648
|
+
break if i >= 10
|
|
649
|
+
end
|
|
650
|
+
Log.stopProgressMeter
|
|
651
|
+
return false
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
Log.stopProgressMeter
|
|
655
|
+
Log.exit('scheduleScenario', "Scheduling of scenario #{scIdx} finished")
|
|
656
|
+
true
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
end
|
|
662
|
+
|