Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-16 09:17:55

0001 // Created on: 2002-02-20
0002 // Created by: Andrey BETENEV
0003 // Copyright (c) 2002-2014 OPEN CASCADE SAS
0004 //
0005 // This file is part of Open CASCADE Technology software library.
0006 //
0007 // This library is free software; you can redistribute it and/or modify it under
0008 // the terms of the GNU Lesser General Public License version 2.1 as published
0009 // by the Free Software Foundation, with special exception defined in the file
0010 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0011 // distribution for complete text of the license and disclaimer of any warranty.
0012 //
0013 // Alternatively, this file may be used under the terms of Open CASCADE
0014 // commercial license or contractual agreement.
0015 
0016 #ifndef _Message_ProgressIndicator_HeaderFile
0017 #define _Message_ProgressIndicator_HeaderFile
0018 
0019 #include <Standard_Handle.hxx>
0020 #include <Standard_Transient.hxx>
0021 #include <Standard_Type.hxx>
0022 
0023 #include <mutex>
0024 
0025 class Message_ProgressRange;
0026 class Message_ProgressScope;
0027 
0028 //! Defines abstract interface from program to the user.
0029 //! This includes progress indication and user break mechanisms.
0030 //!
0031 //! The progress indicator controls the progress scale with range from 0 to 1.
0032 //!
0033 //! Method Start() should be called once, at the top level of the call stack,
0034 //! to reset progress indicator and get access to the root range:
0035 //!
0036 //! @code{.cpp}
0037 //! occ::handle<Message_ProgressIndicator> aProgress = ...;
0038 //! anAlgorithm.Perform (aProgress->Start());
0039 //! @endcode
0040 //!
0041 //! To advance the progress indicator in the algorithm,
0042 //! use the class Message_ProgressScope that provides iterator-like
0043 //! interface for incrementing progress; see documentation of that
0044 //! class for details.
0045 //! The object of class Message_ProgressRange will automatically advance
0046 //! the indicator if it is not passed to any Message_ProgressScope.
0047 //!
0048 //! The progress indicator supports concurrent processing and
0049 //! can be used in multithreaded applications.
0050 //!
0051 //! The derived class should be created to connect this interface to
0052 //! actual implementation of progress indicator, to take care of visualization
0053 //! of the progress (e.g. show total position at the graphical bar,
0054 //! print scopes in text mode, or else), and for implementation
0055 //! of user break mechanism (if necessary).
0056 //!
0057 //! See details in documentation of methods Show() and UserBreak().
0058 
0059 class Message_ProgressIndicator : public Standard_Transient
0060 {
0061   DEFINE_STANDARD_RTTIEXT(Message_ProgressIndicator, Standard_Transient)
0062 public:
0063   //!@name Initialization of progress indication
0064 
0065   //! Resets the indicator to zero, calls Reset(), and returns the range.
0066   //! This range refers to the scope that has no name and is initialized
0067   //! with max value 1 and step 1.
0068   //! Use this method to get the top level range for progress indication.
0069   Standard_EXPORT Message_ProgressRange Start();
0070 
0071   //! If argument is non-null handle, returns theProgress->Start().
0072   //! Otherwise, returns dummy range that can be safely used in the algorithms
0073   //! but not bound to progress indicator.
0074   Standard_EXPORT static Message_ProgressRange Start(
0075     const occ::handle<Message_ProgressIndicator>& theProgress);
0076 
0077 protected:
0078   //!@name Virtual methods to be defined by descendant.
0079 
0080   //! Should return True if user has sent a break signal.
0081   //!
0082   //! This method can be called concurrently, thus implementation should
0083   //! be thread-safe. It should not call Show() or Position() to
0084   //! avoid possible data races. The method should return as soon
0085   //! as possible to avoid delaying the calling algorithm.
0086   //!
0087   //! Default implementation returns False.
0088   virtual bool UserBreak() { return false; }
0089 
0090   //! Virtual method to be defined by descendant.
0091   //! Should update presentation of the progress indicator.
0092   //!
0093   //! It is called whenever progress position is changed.
0094   //! Calls to this method from progress indicator are protected by mutex so that
0095   //! it is never called concurrently for the same progress indicator instance.
0096   //! Show() should return as soon as possible to reduce thread contention
0097   //! in multithreaded algorithms.
0098   //!
0099   //! It is recommended to update (redraw, output etc.) only if progress is
0100   //! advanced by at least 1% from previous update.
0101   //!
0102   //! Flag isForce is intended for forcing update in case if it is required
0103   //! at particular step of the algorithm; all calls to it from inside the core
0104   //! mechanism (Message_Progress... classes) are done with this flag equal to False.
0105   //!
0106   //! The parameter theScope is the current scope being advanced;
0107   //! it can be used to show the names and ranges of the on-going scope and
0108   //! its parents, providing more visibility of the current stage of the process.
0109   virtual void Show(const Message_ProgressScope& theScope, const bool isForce) = 0;
0110 
0111   //! Call-back method called by Start(), can be redefined by descendants
0112   //! if some actions are needed when the indicator is restarted.
0113   virtual void Reset() {}
0114 
0115 public:
0116   //!@name Auxiliary methods
0117 
0118   //! Returns total progress position ranged from 0 to 1.
0119   //! Should not be called concurrently while the progress is advancing,
0120   //! except from implementation of method Show().
0121   double GetPosition() const { return myPosition; }
0122 
0123   //! Destructor
0124   Standard_EXPORT ~Message_ProgressIndicator() override;
0125 
0126 protected:
0127   //! Constructor
0128   Standard_EXPORT Message_ProgressIndicator();
0129 
0130 private:
0131   //! Increment the progress value by the specified step,
0132   //! then calls Show() to update presentation.
0133   //! The parameter theScope is reference to the caller object;
0134   //! it is passed to Show() where can be used to track context of the process.
0135   void Increment(const double theStep, const Message_ProgressScope& theScope);
0136 
0137 private:
0138   double                 myPosition;  //!< Total progress position ranged from 0 to 1
0139   std::mutex             myMutex;     //!< Protection of myPosition from concurrent increment
0140   Message_ProgressScope* myRootScope; //!< The root progress scope
0141 
0142 private:
0143   friend class Message_ProgressScope; //!< Friend: can call Increment()
0144   friend class Message_ProgressRange; //!< Friend: can call Increment()
0145 };
0146 
0147 #include <Message_ProgressScope.hxx>
0148 
0149 //=================================================================================================
0150 
0151 inline void Message_ProgressIndicator::Increment(const double                 theStep,
0152                                                  const Message_ProgressScope& theScope)
0153 {
0154   // protect incrementation by mutex to avoid problems in multithreaded scenarios
0155   std::lock_guard<std::mutex> aLock(myMutex);
0156 
0157   myPosition = (std::min)(myPosition + theStep, 1.);
0158 
0159   // show progress indicator; note that this call is protected by
0160   // the same mutex to avoid concurrency and ensure that this call
0161   // to Show() will see the position exactly as it was just set above
0162   Show(theScope, false);
0163 }
0164 
0165 #endif // _Message_ProgressIndicator_HeaderFile