1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
/**************************************************************************
* *
* Regina - A Normal Surface Theory Calculator *
* Computational Engine *
* *
* Copyright (c) 1999-2009, Ben Burton *
* For further details contact Ben Burton (bab@debian.org). *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
**************************************************************************/
/* end stub */
/*! \file nprogressmanager.h
* \brief Facilitates sharing NProgress objects between an
* operation thread and an external interface.
*/
#ifndef __NPROGRESSMANAGER_H
#ifndef __DOXYGEN
#define __NPROGRESSMANAGER_H
#endif
#include "progress/nprogress.h"
namespace regina {
/**
* \weakgroup progress
* @{
*/
/**
* Manages the sharing of an NProgress object between reading and
* writing threads.
*
* The life cycle of an NProgressManager and the corresponding NProgress
* is as follows. Note that the <i>reading thread</i> is the interface
* thread that is querying the state of progress, and the <i>writing
* thread</i> is the thread in which the operation is actually being
* performed.
*
* - Before the operation begins, an NProgressManager is created and
* both the reading and writing threads have access to it. This can
* be achieved for instance by having the reading thread create an
* NProgressManager and pass it to the writing thread as a parameter
* of the actual operation function call.
* - The writing thread:
* - creates a new NProgress and stores it in the NProgressManager
* using setProgress();
* - updates the NProgress throughout the operation;
* - finally calls NProgress::setFinished() when the operation is
* complete;
* - <b>does not touch</b> either the NProgress or the NProgressManager
* again.
* - The reading thread:
* - repeatedly calls isStarted() and waits until this returns \c true;
* - now knows the NProgress has been created and begins querying it
* using getProgress() and displaying progress reports;
* - whilst querying, repeatedly calls isFinished() to test if the
* operation is complete;
* - once isFinished() returns \c true, displays the final progress
* message to the user and destroys the NProgressManager.
* - Note that the NProgressManager destructor will automatically destroy the
* NProgress. It is imperative that the writing thread does not touch
* either the NProgress or the NProgressManager after calling
* NProgress::setFinished(), since once isFinished()
* returns \c true the reading
* thread might destroy the NProgressManager and thus the NProgress at
* any time. The writing thread cannot destroy these objects because
* it has no guarantee that the reading thread is not still reading
* progress reports from them.
*/
class NProgressManager : public ShareableObject {
private:
NProgress* progress;
/**< The progress report object that we are managing. */
public:
/**
* Creates a new progress manager with no NProgress to manage.
*/
NProgressManager();
/**
* Destroys this manager as well as the corresponding NProgress.
*
* \pre There is an NProgress assigned to this manager; that is,
* isStarted() returns \c true.
* \pre The NProgress that we are managing has finished, that is,
* isFinished() returns \c true.
*/
~NProgressManager();
/**
* Determines if an NProgress has been assigned to this
* manager yet.
*
* Once this routine returns \c true, it will always return \c
* true; thus there will be no need to call it again.
*
* @return \c true if and only if an NProgress has been assigned
* to this manager.
*/
bool isStarted() const;
/**
* Determines if the NProgress that we are managing has finished.
* That is, this routine determines if NProgress::isFinished()
* returns \c true.
*
* Once this routine returns \c true, it will always return \c
* true; thus there will be no need to call it again.
*
* \pre There is an NProgress assigned to this manager; that is,
* isStarted() returns \c true.
*
* @return \c true if and only if the NProgress that we are
* managing has finished.
*/
bool isFinished() const;
/**
* Returns the NProgress that this manager is managing.
* If isStarted() returns \c true, you are guaranteed that
* this routine will not return zero.
*
* @return the NProgress that this manager is managing, or 0 if
* an NProgress has not yet been assigned to this manager.
*/
const NProgress* getProgress() const;
/**
* Assigns the given NProgress to this manager to manage.
*
* \pre setProgress() has not already been called.
*
* \ifacespython Not present; this routine should only be called
* from within calculation engine routines whose progress is
* being watched.
*
* @param newProgress the NProgress that this manager will manage.
*/
void setProgress(NProgress* newProgress);
void writeTextShort(std::ostream& out) const;
};
/*@}*/
// Inline functions for NProgressManager
inline NProgressManager::NProgressManager() : progress(0) {
}
inline NProgressManager::~NProgressManager() {
if (progress)
delete progress;
}
inline bool NProgressManager::isStarted() const {
return (progress != 0);
}
inline bool NProgressManager::isFinished() const {
return progress->isFinished();
}
inline const NProgress* NProgressManager::getProgress() const {
return progress;
}
inline void NProgressManager::setProgress(NProgress* newProgress) {
progress = newProgress;
}
inline void NProgressManager::writeTextShort(std::ostream& out) const {
out << "[Progress Manager]";
}
} // namespace regina
#endif
|