root/trunk/RBFoundation/RBFoundation/TaskProgress.py

Revision 457, 5.8 kB (checked in by sholloway, 6 years ago)

*** empty log message ***

Line 
1 #!/usr/bin/env python
2 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 ##~ License
4 ##~
5 ##- The RuneBlade Foundation library is intended to ease some
6 ##- aspects of writing intricate Jabber, XML, and User Interface (wxPython, etc.)
7 ##- applications, while providing the flexibility to modularly change the
8 ##- architecture. Enjoy.
9 ##~
10 ##~ Copyright (C) 2002  TechGame Networks, LLC.
11 ##~
12 ##~ This library is free software; you can redistribute it and/or
13 ##~ modify it under the terms of the BSD style License as found in the
14 ##~ LICENSE file included with this distribution.
15 ##~
16 ##~ TechGame Networks, LLC can be reached at:
17 ##~ 3578 E. Hartsel Drive #211
18 ##~ Colorado Springs, Colorado, USA, 80920
19 ##~
20 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 #~ Imports
24 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25
26 from SubObs.Basic import Subject
27
28 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
29 #~ Definitions
30 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31
32 def SimpleSubtaskSum(self, Task):
33     """Just an oversimplifed way to Rollup subtask progress."""
34     result = 0.
35     for subtask in Task.Subtasks:
36         result += subtask.Percentage
37     Task.Progress = result
38
39 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40
41 class TaskProgress(object):
42     """Class to encapsulate recursive subtasks in a reasonable way for overal progress updates."""
43
44     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45     #~ Constants / Variables / Etc.
46     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47
48     SubjectFactory = Subject
49     SubtaskFactory = None
50     RollupStrategy = SimpleSubtaskSum
51
52     ProgressStart = 0
53     ProgressEnd = 1
54     ProgressUpdateSteps = 0
55     ProgressUpdateThreshold = 0
56     _Progress = 0
57
58     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59     #~ Definitions
60     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
61
62     def __init__(self, name, *args, **kw):
63         self.Name = name
64         self.OnProgress = self.SubjectFactory()
65         self.OnAddSubtask = self.SubjectFactory()
66         if args or kw:
67             self.SetProgressRange(*args, **kw)
68
69     def __iadd__(self, DeltaProgress):
70         self.Progress += DeltaProgress
71         return self
72     def __isub__(self, DeltaProgress):
73         self.Progress -= DeltaProgress
74         return self
75
76     def NewSubtask(self, Name, Start=0., Stop=1., UpdateSteps=None):
77         subtask = self.SubtaskFactory(Name, Start, Stop, UpdateSteps or self.ProgressUpdateSteps)
78         return self.AddSubtask(subtask)
79
80     def AddSubtask(self, subtask):
81         try:
82             self.Subtasks.append(subtask)
83         except AttributeError:
84             self.Subtasks = [subtask]
85         subtask.OnProgress.Add(self._OnSubtaskUpdate)
86         self.OnAddSubtask.Update(self, subtask)
87         self._OnSubtaskUpdate(subtask, subtask.Progress)
88         return subtask
89
90     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
91     #~ Properties
92     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
93
94     def SetProgressRange(self, Start, Stop, UpdateSteps=10, bSetProgress=1):
95         self.ProgressUpdateSteps = UpdateSteps
96         self.ProgressUpdateThreshold = Start
97         self.ProgressStart = Start
98         self.ProgressEnd = Stop
99         if bSetProgress:
100             self.Progress = Start
101         else:
102             self.OnProgress.Update(self, self.Progress)
103
104     def ResetProgress(self):
105         self.ProgressUpdateThreshold = self.ProgressStart
106         self.Progress = self.ProgressStart
107
108     def _getProgress(self):
109         return self._Progress
110     def _setProgress(self, Progress):
111         self._Progress = Progress
112         if Progress >= self.ProgressUpdateThreshold:
113             self.OnProgress.Update(self, Progress)
114             self.ProgressUpdateThreshold += float(self.ProgressEnd - self.ProgressStart) / self.ProgressUpdateSteps
115         elif Progress >= self.ProgressEnd:
116             self.OnProgress.Update(self, Progress)
117     def _delProgress(self):
118         del self._Progress
119     Progress = property(_getProgress, _setProgress, _delProgress, doc="The tasks progress in real numbers.")
120
121     def _getPercent(self):
122         result = (self._Progress - self.ProgressStart) / float(self.ProgressEnd - self.ProgressStart)
123         return max(0., min(1., result))
124     def _setPercent(self, percent):
125         self.Progress = self.ProgressStart + percent*(self.ProgressEnd-self.ProgressStart)
126     Percentage = Percent = property(_getPercent, _setPercent, _delProgress, doc="The task's percent [0.,1.] complete.  Linear mapping of Progress to the progress range.")
127
128     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
129     #~ Protected Methods
130     #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
131
132     def _OnSubtaskUpdate(self, subtask, Progress):
133         self.RollupStrategy(self)
134
135 TaskProgress.SubtaskFactory = TaskProgress
136
137 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
138 #~ Testing
139 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
140
141 if __name__=='__main__':
142     print "Testing..."
143
144     task = TaskProgress('Test task', 0, 10000, 15)
145
146     task += 10
147     print task.Progress, task.ProgressStart, task.ProgressEnd, task.ProgressUpdateSteps
148
149     def PrintProgress(task, progress):
150         print '%-20s [%5.1f%%]' % (task.Name, task.Percentage * 100)
151
152     task.OnProgress.Add(PrintProgress)
153
154     print
155     print "==", "Task progress", "="*20
156     for p in range(task.ProgressStart, task.ProgressEnd, (task.ProgressEnd - task.ProgressStart)/task.ProgressUpdateSteps * .4):
157         task.Progress = p
158     task.Progress = task.ProgressEnd
159
160     print
161     print "==", "Subtasks", "="*20
162     task.SetProgressRange(0.,1.,5)
163     for each in xrange(5):
164         subtask = task.NewSubtask('   Subtask %s' % each, 0., 1., 4)
165         subtask.OnProgress.Add(PrintProgress)
166
167     while task.Percent < 1.:
168         for subtask in task.Subtasks:
169             subtask += 0.01
170
171     print "Test complete."
172
173
Note: See TracBrowser for help on using the browser.