[kplato] Some code for KPTProject::getDuration()
John D Lamb
kplato@kde.org
Sat, 25 Aug 2001 22:09:24 +0100
Thomas Zander wrote:
>
> Hmm, I think you should know that I am not really a c++ programmer,
> I know c and java. And learned some c++ tricks over the time ;)
>
Actually that makes a lot of sense. I mainly use C++. Java is a very
moralistic language. And one of my motivations for learning it was to
improve the quality of my C++. Java doesn't let you do things like
operator overloading and multiple inheritance that are usually a bad
idea. My guess is that you'll be much better than me at handling
concurrency and GUIs. :-)
STL (standard template library) is a newish part of the C++ standard
library that uses templates (I'm told java has templates but they're not
switched on) and operator overloading to allow generic programming. It
implements specifications for concepts such as containers, iterators and
algorithms so that they can be intantiated as template classes with
guaranteed efficiency. It is only really suitable for a few of the
algorithms in PERT/CPM.
>
> I don't mind making the core QT free, its just that I can't do it. I don't
> have _any_ experience with STL, I never use the class string for example.
> If you can provide the STL implementation of KPTDuration and friends,
> i'm fine with it.
I looked at QList and QListIterator. I can't extend these to STL
containers and iterators or create a container or iterator to emulate
them. So I think it's best to leave them as they are in QTNode. Most of
what is needed for PERT/CPM can be generated as needed within KPTNode as
it is.
I'm not yet sure what the purpose of KPTRelation is. This may be
ignorance on my part. What is clear is that it encapsulates the idea
that (say) Node A comes before Node B in a Project. My instinct would be
to encapsulate this by listing B as a time-dependent child of A and A as
a parent of B. I think any other information can be calculated
efficiently or encapsulated by a node ... of course if I've got this
wrong, its much easier to work with a KPTRelation than without it. ;-)
I've thought of a sensible way to prevent unnecessary recalculations of
durations, floats, earliest starts, etc. Give each node a flag called
recalculate. Define in KPTNode a function
void setRecalculate(){
recalculate = true;
for_each( child )
setRecalculate();
}
Similarly, since only a Project can sensibly have no parent, the Project
can easily be recovered
KPTProject* KPTNode::getProject() const {
if( m_parent == NULL )
return dynamic_cast<KPTProject*>( this ); // hope that cast's right
:-)
else
return m_parent->getProject();
}
Thus, from any node, we can at will reset the recalculate flags for the
entire project efficiently through
getProject()->setRecalculate();
Then each call to getDuration() or similar would set the recalculate
flag to false.
I'm volunteering to implement this! :-)
> If it is to hard for you to do, then why not ignore the problem and pospone
> it until someone wants to use the core classes.
>
> I don't see the need for this, as its for a possible future new-gui. Then
> I say, lets fix the thing in that possible future.
>
> Again, if you want to do this in STL, I must warn you I have little experience
> in that, but I will support that decision. I'll also try my best to master
> the structures STL provides. (I'll borrow a book from a collegue or whatever ;)
>
> Your call.
> My comment was from a data structure POV, if the user signals task A has
> ended, we update the data structure to reflect that, in this case by
> setting the endtime to that specific data.
>
> The PERT analytical will then tell us that B will start at the same time as
> A ended (we know that exact time) and allow C to start at that time
> as well.
>
> The user can then tell KPlato to start, which will set the starttime of node
> C to that exact time, again changing the of the PERT.
>
> Will that do?
How about a flags userStarted and userFinished on each Node to say that
whether the user has specified a start or finish time? with a check on
dependent parent nodes before allowing the user to set something. Then
the start time, end time and duration are either user fixed or estimated
by PERT/CPM. If the user has specified anything, that gives an earliest
starttime that PERT/CPM can use. Otherwise, use 0?
I suggest we add (in a struct?) earliest_start, latest_finish as
QDateTimes. I thinks that would be enough. Also, rather than having
separate functions for expected, random, optimistic, etc. times, why not
create another KPTNode enumerated type (or even a set of empty classes
if you want to be smug and gain efficiency by getting all the actual
functions resolved at compile time) something like
enum calcType { expected, random, optimistic };
Then define (say)
... getDuration( KPTNode::calcType CalcType = KPTNode::expected );
and get the functions themselves to work out what to do. This is likely
to be especially useful at say Project level:
getDuration(KPTNode::calcType CalcType = KPTNode::expected ){
...
for_each( child )
child->getDuration( CalcType );
...
}
Will that cause more problems than it solves?
Any thoughts?
JDL