Index: src/ch/TSubTaskProgressInfo.cpp =================================================================== diff -u --- src/ch/TSubTaskProgressInfo.cpp (revision 0) +++ src/ch/TSubTaskProgressInfo.cpp (revision ae09c8430aad5eaa8225df84878b7d9050bdccd6) @@ -0,0 +1,252 @@ +// ============================================================================ +// Copyright (C) 2001-2010 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// 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 Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +/// @file TSubTaskProgressInfo.cpp +/// @date 2010/09/19 +/// @brief Contains implementation of class handling progress information for subtasks. +// ============================================================================ +#include "stdafx.h" +#include "TSubTaskProgressInfo.h" + +/////////////////////////////////////////////////////////////////////////// +// TSubTaskProgressInfo +TSubTaskProgressInfo::TSubTaskProgressInfo() : + m_stProcessedCount(0), + m_stTotalCount(0), + m_ullProcessedSize(0), + m_ullTotalSize(0), + m_timeElapsed(0), + m_timeLast(-1) +{ +} + +TSubTaskProgressInfo::~TSubTaskProgressInfo() +{ +} + +void TSubTaskProgressInfo::GetSnapshot(TSubTaskProgressInfo& rDst) const +{ + boost::unique_lock dst_lock(rDst.m_lock); + boost::shared_lock lock(m_lock); + + rDst.m_stProcessedCount = m_stProcessedCount; + rDst.m_stTotalCount = m_stTotalCount; + + rDst.m_ullProcessedSize = m_ullProcessedSize; + rDst.m_ullTotalSize = m_ullTotalSize; + + if(m_timeLast != -1) + rDst.m_timeElapsed = m_timeElapsed + time(NULL) - m_timeLast; // not storing current time to avoid writing to this object + else + rDst.m_timeElapsed = m_timeElapsed; + + rDst.m_timeLast = -1; +} + +void TSubTaskProgressInfo::Clear() +{ + m_stProcessedCount = 0; + m_stTotalCount = 0; + m_ullProcessedSize = 0; + m_ullTotalSize = 0; + m_timeElapsed = 0; + m_timeLast = -1; +} + +// count-based progress +void TSubTaskProgressInfo::IncreaseProcessedCount(size_t stAdd) +{ + boost::unique_lock lock(m_lock); + m_stProcessedCount += stAdd; +} + +void TSubTaskProgressInfo::DecreaseProcessedCount(size_t stSub) +{ + boost::unique_lock lock(m_lock); + m_stProcessedCount -= stSub; +} + +void TSubTaskProgressInfo::SetProcessedCount(size_t stSet) +{ + boost::unique_lock lock(m_lock); + m_stProcessedCount = stSet; +} + +size_t TSubTaskProgressInfo::GetProcessedCount() const +{ + boost::shared_lock lock(m_lock); + return m_stProcessedCount; +} + +size_t TSubTaskProgressInfo::GetUnProcessedCount() const +{ + boost::shared_lock lock(m_lock); + return m_stTotalCount - m_stProcessedCount; +} + +void TSubTaskProgressInfo::IncreaseTotalCount(size_t stAdd) +{ + boost::unique_lock lock(m_lock); + m_stTotalCount += stAdd; +} + +void TSubTaskProgressInfo::DecreaseTotalCount(size_t stSub) +{ + boost::unique_lock lock(m_lock); + m_stTotalCount -= stSub; +} + +void TSubTaskProgressInfo::SetTotalCount(size_t stSet) +{ + boost::unique_lock lock(m_lock); + m_stTotalCount = stSet; +} + +size_t TSubTaskProgressInfo::GetTotalCount() const +{ + boost::shared_lock lock(m_lock); + return m_stTotalCount; +} + +double TSubTaskProgressInfo::GetCountProgressInPercent() const +{ + boost::shared_lock lock(m_lock); + + long double dPercent = 0; + + if(m_stTotalCount != 0) + dPercent = (long double)m_stProcessedCount / (long double)m_stTotalCount; + + return (double)dPercent; +} + +// size-based progress +void TSubTaskProgressInfo::IncreaseProcessedSize(unsigned long long ullAdd) +{ + boost::unique_lock lock(m_lock); + m_ullProcessedSize += ullAdd; +} + +void TSubTaskProgressInfo::DecreaseProcessedSize(unsigned long long ullSub) +{ + boost::unique_lock lock(m_lock); + m_ullProcessedSize -= ullSub; +} + +void TSubTaskProgressInfo::SetProcessedSize(unsigned long long ullSet) +{ + boost::unique_lock lock(m_lock); + m_ullProcessedSize = ullSet; +} + +unsigned long long TSubTaskProgressInfo::GetProcessedSize() const +{ + boost::shared_lock lock(m_lock); + return m_ullProcessedSize; +} + +unsigned long long TSubTaskProgressInfo::GetUnProcessedSize() const +{ + boost::shared_lock lock(m_lock); + return m_ullTotalSize - m_ullProcessedSize; +} + +void TSubTaskProgressInfo::IncreaseTotalSize(unsigned long long ullAdd) +{ + boost::unique_lock lock(m_lock); + m_ullTotalSize += ullAdd; +} + +void TSubTaskProgressInfo::DecreaseTotalSize(unsigned long long ullSub) +{ + boost::unique_lock lock(m_lock); + m_ullTotalSize -= ullSub; +} + +void TSubTaskProgressInfo::SetTotalSize(unsigned long long ullSet) +{ + boost::unique_lock lock(m_lock); + m_ullTotalSize = ullSet; +} + +unsigned long long TSubTaskProgressInfo::GetTotalSize() const +{ + boost::shared_lock lock(m_lock); + return m_ullTotalSize; +} + +double TSubTaskProgressInfo::GetSizeProgressInPercent() const +{ + boost::shared_lock lock(m_lock); + + long double dPercent = 0; + + if(m_ullTotalSize != 0) + dPercent = (long double)m_ullProcessedSize / (long double)m_ullTotalSize; + + return (double)dPercent; +} + +void TSubTaskProgressInfo::SetTimeElapsed(time_t timeElapsed) +{ + boost::unique_lock lock(m_lock); + m_timeElapsed = timeElapsed; +} + +time_t TSubTaskProgressInfo::GetTimeElapsed() +{ + UpdateTime(); + + boost::shared_lock lock(m_lock); + return m_timeElapsed; +} + +void TSubTaskProgressInfo::EnableTimeTracking() +{ + boost::upgrade_lock lock(m_lock); + if(m_timeLast == -1) + { + boost::upgrade_to_unique_lock lock_upgraded(lock); + m_timeLast = time(NULL); + } +} + +void TSubTaskProgressInfo::DisableTimeTracking() +{ + UpdateTime(); + + boost::upgrade_lock lock(m_lock); + if(m_timeLast != -1) + { + boost::upgrade_to_unique_lock lock_upgraded(lock); + m_timeLast = -1; + } +} + +void TSubTaskProgressInfo::UpdateTime() +{ + boost::upgrade_lock lock(m_lock); + if(m_timeLast != -1) + { + time_t timeCurrent = time(NULL); + + boost::upgrade_to_unique_lock lock_upgraded(lock); + m_timeElapsed += timeCurrent - m_timeLast; + m_timeLast = timeCurrent; + } +} Index: src/ch/TSubTaskProgressInfo.h =================================================================== diff -u --- src/ch/TSubTaskProgressInfo.h (revision 0) +++ src/ch/TSubTaskProgressInfo.h (revision ae09c8430aad5eaa8225df84878b7d9050bdccd6) @@ -0,0 +1,97 @@ +// ============================================================================ +// Copyright (C) 2001-2010 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// 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 Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +/// @file TSubTaskProgressInfo.h +/// @date 2010/09/19 +/// @brief Contains declaration of class handling progress information for subtasks. +// ============================================================================ +#ifndef __TSUBTASKPROGRESSINFO_H__ +#define __TSUBTASKPROGRESSINFO_H__ + + +/////////////////////////////////////////////////////////////////////////// +// TSubTaskProgressInfo + +class TSubTaskProgressInfo +{ +public: + TSubTaskProgressInfo(); + ~TSubTaskProgressInfo(); + + void GetSnapshot(TSubTaskProgressInfo& rDst) const; + + void Clear(); + + // count of data + void IncreaseProcessedCount(size_t stAdd); + void DecreaseProcessedCount(size_t stSub); + void SetProcessedCount(size_t stSet); + size_t GetProcessedCount() const; + + size_t GetUnProcessedCount() const; + + void IncreaseTotalCount(size_t stAdd); + void DecreaseTotalCount(size_t stSub); + void SetTotalCount(size_t stSet); + size_t GetTotalCount() const; + + double GetCountProgressInPercent() const; + + // size of data + void IncreaseProcessedSize(unsigned long long ullAdd); + void DecreaseProcessedSize(unsigned long long ullSub); + void SetProcessedSize(unsigned long long ullSet); + unsigned long long GetProcessedSize() const; + + unsigned long long GetUnProcessedSize() const; + + void IncreaseTotalSize(unsigned long long ullAdd); + void DecreaseTotalSize(unsigned long long ullSub); + void SetTotalSize(unsigned long long ullSet); + unsigned long long GetTotalSize() const; + + // calculated values + double GetSizeProgressInPercent() const; + + // time tracking + void SetTimeElapsed(time_t timeElapsed); + time_t GetTimeElapsed(); + + void EnableTimeTracking(); + void DisableTimeTracking(); + void UpdateTime(); + +private: + // count of data + volatile size_t m_stProcessedCount; + volatile size_t m_stTotalCount; + + // size of data + volatile unsigned long long m_ullProcessedSize; + volatile unsigned long long m_ullTotalSize; + + // time + volatile time_t m_timeElapsed; ///< How much time has elapsed from the start + volatile time_t m_timeLast; ///< Last time the time elapsed has been updated + + mutable boost::shared_mutex m_lock; +}; + +typedef boost::shared_ptr TSubTaskProgressInfoPtr; + +#endif // __TSUBTASKPROGRESSINFO_H__ \ No newline at end of file Index: src/ch/TTaskOperationPlan.cpp =================================================================== diff -u --- src/ch/TTaskOperationPlan.cpp (revision 0) +++ src/ch/TTaskOperationPlan.cpp (revision ae09c8430aad5eaa8225df84878b7d9050bdccd6) @@ -0,0 +1,102 @@ +// ============================================================================ +// Copyright (C) 2001-2009 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// 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 Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +/// @file TSubTasks.cpp +/// @date 2010/09/18 +/// @brief Contains implementation of classes for subtasks management. +// ============================================================================ +#include "stdafx.h" +#include "TTaskOperationPlan.h" + +//////////////////////////////////////////////////////////////////////////// +// class TOperationPlan + +TOperationPlan::TOperationPlan() : + m_eOperation(eOperation_None) +{ +} + +TOperationPlan::~TOperationPlan() +{ +} + +void TOperationPlan::SetOperationType(EOperationType eOperation) +{ + switch(eOperation) + { + case eOperation_None: + THROW(_T("Cannot set operation type 'none'"), 0, 0, 0); + break; + + case eOperation_Copy: + { + boost::unique_lock lock(m_lock); + m_vSubOperations.clear(); + m_vSubOperations.push_back(std::make_pair(eSubOperation_Scanning, 0.05)); + m_vSubOperations.push_back(std::make_pair(eSubOperation_Copying, 0.95)); + break; + } + + case eOperation_Move: + { + boost::unique_lock lock(m_lock); + m_vSubOperations.clear(); + m_vSubOperations.push_back(std::make_pair(eSubOperation_Scanning, 0.05)); + m_vSubOperations.push_back(std::make_pair(eSubOperation_Copying, 0.90)); + m_vSubOperations.push_back(std::make_pair(eSubOperation_Deleting, 0.05)); + break; + } + + BOOST_STATIC_ASSERT(eOperation_Move == eOperation_Max - 1); + + default: + THROW(_T("Unhandled case"), 0, 0, 0); + } + + m_eOperation = eOperation; +} + +EOperationType TOperationPlan::GetOperationType() const +{ + boost::shared_lock lock(m_lock); + return m_eOperation; +} + +size_t TOperationPlan::GetSubOperationsCount() const +{ + boost::shared_lock lock(m_lock); + return m_vSubOperations.size(); +} + +ESubOperationType TOperationPlan::GetSubOperationAt(size_t stIndex) const +{ + boost::shared_lock lock(m_lock); + if(stIndex >= m_vSubOperations.size()) + THROW(_T("Index out of bounds"), 0, 0, 0); + else + return m_vSubOperations[stIndex].first; +} + +double TOperationPlan::GetEstimatedTimeAt(size_t stIndex) const +{ + boost::shared_lock lock(m_lock); + if(stIndex >= m_vSubOperations.size()) + THROW(_T("Index out of bounds"), 0, 0, 0); + else + return m_vSubOperations[stIndex].second; +} Index: src/ch/TTaskOperationPlan.h =================================================================== diff -u --- src/ch/TTaskOperationPlan.h (revision 0) +++ src/ch/TTaskOperationPlan.h (revision ae09c8430aad5eaa8225df84878b7d9050bdccd6) @@ -0,0 +1,94 @@ +// ============================================================================ +// Copyright (C) 2001-2009 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// 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 Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +/// @file TSubTasks.cpp +/// @date 2010/09/18 +/// @brief File contains classes for handling subtasks. +// ============================================================================ +#ifndef __TSUBTASKS_H__ +#define __TSUBTASKS_H__ + +// enum represents type of the operation handled by the task +enum EOperationType +{ + eOperation_None, + eOperation_Copy, + eOperation_Move, + + // add new operation types before this enum value + eOperation_Max +}; + +enum ESubOperationType +{ + eSubOperation_None, + eSubOperation_Scanning, + eSubOperation_Copying, + eSubOperation_Deleting, + + // add new operation types before this one + eSubOperation_Max +}; + +/////////////////////////////////////////////////////////////////////////// +// TOperationPlan + +// class describes the sub-operations to be performed +class TOperationPlan +{ +public: + TOperationPlan(); + ~TOperationPlan(); + + void SetOperationType(EOperationType eOperation); + EOperationType GetOperationType() const; + + size_t GetSubOperationsCount() const; + ESubOperationType GetSubOperationAt(size_t stIndex) const; + double GetEstimatedTimeAt(size_t stIndex) const; + + template + void load(Archive& ar, unsigned int /*uiVersion*/); + + template + void save(Archive& ar, unsigned int /*uiVersion*/) const; + + BOOST_SERIALIZATION_SPLIT_MEMBER(); + +private: + EOperationType m_eOperation; + std::vector > m_vSubOperations; ///< Vector of sub-task type and estimated part in the entire task time + + mutable boost::shared_mutex m_lock; +}; + +template +void TOperationPlan::load(Archive& ar, unsigned int /*uiVersion*/) +{ + EOperationType eOperation = eOperation_None; + ar >> eOperation; + SetOperationType(eOperation); +} + +template +void TOperationPlan::save(Archive& ar, unsigned int /*uiVersion*/) const +{ + ar << m_eOperation; +} + +#endif Index: src/ch/TTaskProgressInfo.cpp =================================================================== diff -u --- src/ch/TTaskProgressInfo.cpp (revision 0) +++ src/ch/TTaskProgressInfo.cpp (revision ae09c8430aad5eaa8225df84878b7d9050bdccd6) @@ -0,0 +1,125 @@ +// ============================================================================ +// Copyright (C) 2001-2009 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// 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 Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +/// @file TTaskProgressInfo.cpp +/// @date 2010/09/19 +/// @brief Contains implementation of classes related to task progress reporting. +// ============================================================================ +#include "stdafx.h" +#include "TTaskProgressInfo.h" + +/////////////////////////////////////////////////////////////////////////// +// TProgressSnapshot + +TProgressSnapshot::TProgressSnapshot() : + m_stCurrentOperation(0), + m_dCountTotalProgress(0.0), + m_dSizeTotalProgress(0.0) +{ +} + +TProgressSnapshot::~TProgressSnapshot() +{ +} + +/////////////////////////////////////////////////////////////////////////// +// TTaskProgressInfo + +TTaskProgressInfo::TTaskProgressInfo() : + m_stSubOperationIndex(0) +{ +} + +TTaskProgressInfo::~TTaskProgressInfo() +{ +} + +void TTaskProgressInfo::CreateFromOperationPlan(const TOperationPlan& rOperationPlan) +{ + m_stSubOperationIndex = 0; + m_vProgressInfo.clear(); + + BOOST_ASSERT(rOperationPlan.GetSubOperationsCount() != 0); + if(rOperationPlan.GetSubOperationsCount() == 0) + return; + + for(size_t stIndex = 0; stIndex < rOperationPlan.GetSubOperationsCount(); ++stIndex) + { + TSubTaskProgressInfoPtr spProgressInfo(boost::make_shared()); + m_vProgressInfo.push_back(boost::make_tuple(rOperationPlan.GetSubOperationAt(stIndex), rOperationPlan.GetEstimatedTimeAt(stIndex), spProgressInfo)); + } +} + +void TTaskProgressInfo::GetProgressSnapshot(TProgressSnapshot& rSnapshot) const +{ + boost::shared_lock lock(m_lock); + + // current operation index + rSnapshot.m_stCurrentOperation = m_stSubOperationIndex; + + // reset other stats + rSnapshot.m_tCurrentSubTaskProgress.Clear(); + + // whole progress + rSnapshot.m_dCountTotalProgress = 0.0; + rSnapshot.m_dSizeTotalProgress = 0.0; + + for(size_t stIndex = 0; stIndex < m_vProgressInfo.size(); ++stIndex) + { + const boost::tuple& rProgressInfo = m_vProgressInfo.at(stIndex); + if(stIndex < m_stSubOperationIndex) + { + // this operation is already finished, so assuming 100% + rSnapshot.m_dCountTotalProgress += boost::get<1>(rProgressInfo); + rSnapshot.m_dSizeTotalProgress += boost::get<1>(rProgressInfo); + } + else if(stIndex == m_stSubOperationIndex) + { + // this operation is in progress, so calculate percentages and store snapshot of current subtask progress info + const TSubTaskProgressInfoPtr& spInfo = boost::get<2>(rProgressInfo); + if(!spInfo) + THROW(_T("Invalid pointer"), 0, 0, 0); + + rSnapshot.m_tCurrentSubTaskProgress.GetSnapshot(*spInfo); + + rSnapshot.m_dCountTotalProgress += spInfo->GetCountProgressInPercent() * boost::get<1>(rProgressInfo); + rSnapshot.m_dSizeTotalProgress += spInfo->GetSizeProgressInPercent() * boost::get<1>(rProgressInfo); + } + else + break; + } +} + +void TTaskProgressInfo::SetSubOperationIndex(size_t stSubOperationIndex) +{ + boost::unique_lock lock(m_lock); + m_stSubOperationIndex = stSubOperationIndex; +} + +size_t TTaskProgressInfo::GetSubOperationIndex() const +{ + boost::shared_lock lock(m_lock); + return m_stSubOperationIndex; +} + +void TTaskProgressInfo::IncreaseSubOperationIndex() +{ + boost::unique_lock lock(m_lock); + ++m_stSubOperationIndex; +} + Index: src/ch/TTaskProgressInfo.h =================================================================== diff -u --- src/ch/TTaskProgressInfo.h (revision 0) +++ src/ch/TTaskProgressInfo.h (revision ae09c8430aad5eaa8225df84878b7d9050bdccd6) @@ -0,0 +1,124 @@ +// ============================================================================ +// Copyright (C) 2001-2009 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// 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 Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +/// @file TTaskProgressInfo.h +/// @date 2010/09/19 +/// @brief File contains declarations of classes related to task progress reporting. +// ============================================================================ +#ifndef __TTASKPROGRESSINFO_H__ +#define __TTASKPROGRESSINFO_H__ + +#include "TTaskOperationPlan.h" +#include "TSubTaskProgressInfo.h" + +/////////////////////////////////////////////////////////////////////////// +// TProgressSnapshot + +class TProgressSnapshot +{ +public: + TProgressSnapshot(); + ~TProgressSnapshot(); + + // total progress (percentage) of the whole task + double GetTaskCountProgress() const { return m_dCountTotalProgress; } + double GetTaskSizeProgress() const { return m_dSizeTotalProgress; } + + // progress of current subtask + const TSubTaskProgressInfo& GetCurrentSubTaskProgress() const { return m_tCurrentSubTaskProgress; } + + // index of current subtask in the operation plan + size_t GetCurrentSubTaskIndex() const; + +private: + // percentage progress based on count and size of items + double m_dCountTotalProgress; + double m_dSizeTotalProgress; + + // copy of progress of current subtask + TSubTaskProgressInfo m_tCurrentSubTaskProgress; + + // states which subtask is active at the moment + size_t m_stCurrentOperation; + + friend class TTaskProgressInfo; +}; + +/////////////////////////////////////////////////////////////////////////// +// TTaskProgressInfo + +class TTaskProgressInfo +{ +public: + TTaskProgressInfo(); + ~TTaskProgressInfo(); + + // initializes the progress info + void CreateFromOperationPlan(const TOperationPlan& rOperationPlan); + + // progress operations + void GetProgressSnapshot(TProgressSnapshot& rSnapshot) const; + + void SetSubOperationIndex(size_t stSubOperationIndex); + void IncreaseSubOperationIndex(); + size_t GetSubOperationIndex() const; + + // retrieve reference to the subtask progress info to pass it to the subtask itself + TSubTaskProgressInfo& GetProgressInfo(size_t stSubTaskIndex); + + // serialization + template + void load(Archive& ar, unsigned int /*uiVersion*/); + + template + void save(Archive& ar, unsigned int /*uiVersion*/) const; + + BOOST_SERIALIZATION_SPLIT_MEMBER(); + +private: + volatile size_t m_stSubOperationIndex; // index of sub-operation from TOperationDescription + + std::vector > m_vProgressInfo; + + mutable boost::shared_mutex m_lock; +}; + +template +void TTaskProgressInfo::load(Archive& ar, unsigned int /*uiVersion*/) +{ + boost::unique_lock lock(m_lock); + + ar >> m_vProgressInfo; + ar >> m_stSubOperationIndex; + + // note that m_stSubOperationIndex could be equal to m_vProgressInfo.size() + // in case all subtasks has already finished + if(m_stSubOperationIndex > m_vProgressInfo.size()) + THROW(_T("Corrupted progress data"), 0, 0, 0); +} + +template +void TTaskProgressInfo::save(Archive& ar, unsigned int /*uiVersion*/) const +{ + boost::shared_lock lock(m_lock); + + ar << m_vProgressInfo; + ar << m_stSubOperationIndex; +} + +#endif // __TTASKPROGRESSINFO_H__ \ No newline at end of file