Index: src/ch/FeedbackFileErrorDlg.cpp =================================================================== diff -u -r3921d82d9605d98b2281f3f42d9f9c8385b89a3e -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/ch/FeedbackFileErrorDlg.cpp (.../FeedbackFileErrorDlg.cpp) (revision 3921d82d9605d98b2281f3f42d9f9c8385b89a3e) +++ src/ch/FeedbackFileErrorDlg.cpp (.../FeedbackFileErrorDlg.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -25,6 +25,16 @@ { } +bool CFeedbackFileErrorDlg::IsApplyToAllItemsChecked() const +{ + return m_bAllItems; +} + +const chengine::FeedbackErrorRuleList& CFeedbackFileErrorDlg::GetRules() const +{ + return m_feedbackRules; +} + void CFeedbackFileErrorDlg::DoDataExchange(CDataExchange* pDX) { ictranslate::CLanguageDialog::DoDataExchange(pDX); Index: src/ch/FeedbackFileErrorDlg.h =================================================================== diff -u -r12ee49f6bf1f8921500ee2078e0a8c2d7b6d2a45 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/ch/FeedbackFileErrorDlg.h (.../FeedbackFileErrorDlg.h) (revision 12ee49f6bf1f8921500ee2078e0a8c2d7b6d2a45) +++ src/ch/FeedbackFileErrorDlg.h (.../FeedbackFileErrorDlg.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -19,6 +19,8 @@ #ifndef __FEEDBACKFILEERRORDLG_H__ #define __FEEDBACKFILEERRORDLG_H__ +#include "../libchengine/FeedbackErrorRuleList.h" + // CFeedbackFileErrorDlg dialog class CFeedbackFileErrorDlg : public ictranslate::CLanguageDialog { @@ -28,23 +30,30 @@ CFeedbackFileErrorDlg(const wchar_t* pszSrcPath, const wchar_t* pszDstPath, unsigned long ulSysError, CWnd* pParent = nullptr); // standard constructor virtual ~CFeedbackFileErrorDlg(); - afx_msg void OnBnClickedRetryButton(); - afx_msg void OnBnClickedSkipButton(); - afx_msg void OnBnClickedPauseButton(); - afx_msg void OnBnClickedCancel(); + bool IsApplyToAllItemsChecked() const; + const chengine::FeedbackErrorRuleList& GetRules() const; + protected: void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV support void OnCancel() override; + BOOL OnInitDialog() override; + afx_msg void OnBnClickedRetryButton(); + afx_msg void OnBnClickedSkipButton(); + afx_msg void OnBnClickedPauseButton(); + afx_msg void OnBnClickedCancel(); + DECLARE_MESSAGE_MAP() -public: - BOOL m_bAllItems; + +private: + BOOL m_bAllItems = FALSE; CStatic m_ctlErrorInfo; CString m_strSrcPath; CString m_strDstPath; - unsigned long m_ulSysError; - BOOL OnInitDialog() override; + unsigned long m_ulSysError = 0; + + chengine::FeedbackErrorRuleList m_feedbackRules; // feedback rules resulting from choices made in this dialog box }; #endif Index: src/ch/FeedbackHandler.cpp =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/ch/FeedbackHandler.cpp (.../FeedbackHandler.cpp) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/ch/FeedbackHandler.cpp (.../FeedbackHandler.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -30,78 +30,63 @@ using namespace chengine; using namespace string; -CFeedbackHandler::CFeedbackHandler() : - TFeedbackHandlerBase() +chengine::EFeedbackResult CFeedbackHandler::FileError(const TString& strSrcPath, const TString& strDstPath, EFileError /*eFileError*/, unsigned long ulError, FeedbackErrorRuleList& rNewRules) { -} - -CFeedbackHandler::~CFeedbackHandler() -{ -} - -TFeedbackResult CFeedbackHandler::FileError(const TString& strSrcPath, const TString& strDstPath, EFileError /*eFileError*/, unsigned long ulError) -{ - EFeedbackResult eResult = eResult_Unknown; - if(HasFileErrorPermanentResponse(eResult)) - return TFeedbackResult(eResult, true); - CFeedbackFileErrorDlg dlg(strSrcPath.c_str(), strDstPath.c_str(), ulError); - eResult = (EFeedbackResult)dlg.DoModal(); + EFeedbackResult eResult = (EFeedbackResult)dlg.DoModal(); - if (dlg.m_bAllItems) - SetFileErrorPermanentResponse(eResult); + if(!dlg.GetRules().IsEmpty()) + rNewRules = dlg.GetRules(); - return TFeedbackResult(eResult, false); + return eResult; } -TFeedbackResult CFeedbackHandler::FileAlreadyExists(const TFileInfo& spSrcFileInfo, const TFileInfo& spDstFileInfo) +chengine::EFeedbackResult CFeedbackHandler::FileAlreadyExists(const TFileInfo& spSrcFileInfo, const TFileInfo& spDstFileInfo, FeedbackAlreadyExistsRuleList& rNewRules) { - EFeedbackResult eResult = eResult_Unknown; - if(HasFileAlreadyExistsPermanentResponse(eResult)) - return TFeedbackResult(eResult, true); - CFeedbackReplaceDlg dlg(spSrcFileInfo, spDstFileInfo); - eResult = (EFeedbackResult)dlg.DoModal(); + EFeedbackResult eResult = (EFeedbackResult)dlg.DoModal(); - if(dlg.IsApplyToAllItemsChecked()) - SetFileAlreadyExistsPermanentResponse(eResult); + if(!dlg.GetRules().IsEmpty()) + rNewRules = dlg.GetRules(); - return TFeedbackResult(eResult, false); + return eResult; } -TFeedbackResult CFeedbackHandler::NotEnoughSpace(const TString& strSrcPath, const TString& strDstPath, unsigned long long ullRequiredSize) +chengine::EFeedbackResult CFeedbackHandler::NotEnoughSpace(const TString& strSrcPath, const TString& strDstPath, unsigned long long ullRequiredSize, FeedbackNotEnoughSpaceRuleList& rNewRules) { - EFeedbackResult eResult = eResult_Unknown; - if(HasNotEnoughSpacePermanentResponse(eResult)) - return TFeedbackResult(eResult, true); - CFeedbackNotEnoughSpaceDlg dlg(ullRequiredSize, strSrcPath.c_str(), strDstPath.c_str()); - eResult = (EFeedbackResult) dlg.DoModal(); + EFeedbackResult eResult = (EFeedbackResult) dlg.DoModal(); - if (dlg.m_bAllItems) - SetNotEnoughSpacePermanentResponse(eResult); + if(!dlg.GetRules().IsEmpty()) + rNewRules = dlg.GetRules(); - return TFeedbackResult(eResult, false); + return eResult; } -TFeedbackResult CFeedbackHandler::OperationFinished() +chengine::EFeedbackResult CFeedbackHandler::OperationEvent(EOperationEvent eEvent, FeedbackOperationEventRuleList&) { - if (GetPropValue(GetConfig())) + switch(eEvent) { - CString strPath = GetPropValue(GetConfig()); - PlaySound(GetApp().ExpandPath(strPath), nullptr, SND_FILENAME | SND_ASYNC); + case eOperationEvent_Finished: + { + if(GetPropValue(GetConfig())) + { + CString strPath = GetPropValue(GetConfig()); + PlaySound(GetApp().ExpandPath(strPath), nullptr, SND_FILENAME | SND_ASYNC); + } + break; } - - return TFeedbackResult(eResult_Unknown, true); -} - -TFeedbackResult CFeedbackHandler::OperationError() -{ - if (GetPropValue(GetConfig())) + case eOperationEvent_Error: { - CString strPath = GetPropValue(GetConfig()); - PlaySound(GetApp().ExpandPath(strPath), nullptr, SND_FILENAME | SND_ASYNC); + if(GetPropValue(GetConfig())) + { + CString strPath = GetPropValue(GetConfig()); + PlaySound(GetApp().ExpandPath(strPath), nullptr, SND_FILENAME | SND_ASYNC); + } + + break; } + } - return TFeedbackResult(eResult_Unknown, true); + return eResult_Unknown; } Index: src/ch/FeedbackHandler.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/ch/FeedbackHandler.h (.../FeedbackHandler.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/ch/FeedbackHandler.h (.../FeedbackHandler.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -19,25 +19,21 @@ #ifndef __FEEDBACKHANDLER_H__ #define __FEEDBACKHANDLER_H__ -#include "../libchengine/TFeedbackHandlerBase.h" +#include "../libchengine/IFeedbackHandler.h" namespace string { class TString; } -class CFeedbackHandler : public chengine::TFeedbackHandlerBase +class CFeedbackHandler : public chengine::IFeedbackHandler { public: - CFeedbackHandler(); - virtual ~CFeedbackHandler(); + chengine::EFeedbackResult FileError(const string::TString& strSrcPath, const string::TString& strDstPath, chengine::EFileError eFileError, unsigned long ulError, chengine::FeedbackErrorRuleList& rNewRules) override; + chengine::EFeedbackResult FileAlreadyExists(const chengine::TFileInfo& spSrcFileInfo, const chengine::TFileInfo& spDstFileInfo, chengine::FeedbackAlreadyExistsRuleList& rNewRules) override; + chengine::EFeedbackResult NotEnoughSpace(const string::TString& strSrcPath, const string::TString& strDstPath, unsigned long long ullRequiredSize, chengine::FeedbackNotEnoughSpaceRuleList& rNewRules) override; + chengine::EFeedbackResult OperationEvent(chengine::EOperationEvent eEvent, chengine::FeedbackOperationEventRuleList& rNewRules) override; - chengine::TFeedbackResult FileError(const string::TString& strSrcPath, const string::TString& strDstPath, chengine::EFileError eFileError, unsigned long ulError) override; - chengine::TFeedbackResult FileAlreadyExists(const chengine::TFileInfo& spSrcFileInfo, const chengine::TFileInfo& spDstFileInfo) override; - chengine::TFeedbackResult NotEnoughSpace(const string::TString& strSrcPath, const string::TString& strDstPath, unsigned long long ullRequiredSize) override; - chengine::TFeedbackResult OperationFinished() override; - chengine::TFeedbackResult OperationError() override; - protected: friend class CFeedbackHandlerFactory; }; Index: src/ch/FeedbackNotEnoughSpaceDlg.cpp =================================================================== diff -u -r3921d82d9605d98b2281f3f42d9f9c8385b89a3e -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/ch/FeedbackNotEnoughSpaceDlg.cpp (.../FeedbackNotEnoughSpaceDlg.cpp) (revision 3921d82d9605d98b2281f3f42d9f9c8385b89a3e) +++ src/ch/FeedbackNotEnoughSpaceDlg.cpp (.../FeedbackNotEnoughSpaceDlg.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -42,7 +42,16 @@ m_vstrFiles.push_back(pszSrcPath); } +bool CFeedbackNotEnoughSpaceDlg::IsApplyToAllItemsChecked() const +{ + return m_bAllItems; +} +const chengine::FeedbackNotEnoughSpaceRuleList& CFeedbackNotEnoughSpaceDlg::GetRules() const +{ + return m_feedbackRules; +} + void CFeedbackNotEnoughSpaceDlg::DoDataExchange(CDataExchange* pDX) { CLanguageDialog::DoDataExchange(pDX); Index: src/ch/FeedbackNotEnoughSpaceDlg.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/ch/FeedbackNotEnoughSpaceDlg.h (.../FeedbackNotEnoughSpaceDlg.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/ch/FeedbackNotEnoughSpaceDlg.h (.../FeedbackNotEnoughSpaceDlg.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -20,45 +20,45 @@ #define __FEEDBACKNOTENOUGHSPACEDLG_H__ #include "../libchengine/TLocalFilesystem.h" +#include "../libchengine/FeedbackNotEnoughSpaceRuleList.h" ///////////////////////////////////////////////////////////////////////////// // CFeedbackNotEnoughSpaceDlg dialog class CFeedbackNotEnoughSpaceDlg : public ictranslate::CLanguageDialog { -// Construction public: CFeedbackNotEnoughSpaceDlg(unsigned long long ullSizeRequired, const wchar_t* pszSrcPath, const wchar_t* pszDstPath); // standard constructor -// Overrides -protected: - void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV support + bool IsApplyToAllItemsChecked() const; -// Implementation -public: - CString m_strDisk; - unsigned long long m_ullRequired; - std::vector m_vstrFiles; - CListBox m_ctlFiles; + const chengine::FeedbackNotEnoughSpaceRuleList& GetRules() const; protected: + void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV support void UpdateDialog(); void OnLanguageChanged() override; void OnCancel() override; BOOL OnInitDialog() override; + afx_msg void OnTimer(UINT_PTR nIDEvent); afx_msg void OnRetryButton(); afx_msg void OnIgnoreButton(); afx_msg void OnBnClickedCancel(); DECLARE_MESSAGE_MAP() -public: - BOOL m_bAllItems; - private: + BOOL m_bAllItems = FALSE; + CString m_strDisk; + unsigned long long m_ullRequired = 0; + std::vector m_vstrFiles; + + CListBox m_ctlFiles; + chengine::TLocalFilesystem m_fsLocal; + chengine::FeedbackNotEnoughSpaceRuleList m_feedbackRules; // feedback rules resulting from choices made in this dialog box }; #endif Index: src/ch/FeedbackReplaceDlg.cpp =================================================================== diff -u -r5b4b933c78513d867ec02d33325907c2069c7bef -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/ch/FeedbackReplaceDlg.cpp (.../FeedbackReplaceDlg.cpp) (revision 5b4b933c78513d867ec02d33325907c2069c7bef) +++ src/ch/FeedbackReplaceDlg.cpp (.../FeedbackReplaceDlg.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -9,14 +9,14 @@ #include "resource.h" #include "../libchengine/TFileInfo.h" #include "StringHelpers.h" +#include "../libchengine/FeedbackPredefinedRules.h" -// CFeedbackReplaceDlg dialog +using namespace chengine; IMPLEMENT_DYNAMIC(CFeedbackReplaceDlg, ictranslate::CLanguageDialog) CFeedbackReplaceDlg::CFeedbackReplaceDlg(const chengine::TFileInfo& spSrcFile, const chengine::TFileInfo& spDstFile, CWnd* pParent /*=nullptr*/) : ictranslate::CLanguageDialog(IDD_FEEDBACK_REPLACE_DIALOG, pParent), - m_bAllItems(FALSE), m_rSrcFile(spSrcFile), m_rDstFile(spDstFile) { @@ -231,92 +231,80 @@ void CFeedbackReplaceDlg::OnBnMassReplace() { - CString str; switch (m_btnMassReplace.m_nMenuResult) { case ID_FEEDBACK_REPLACE_ALLEXISTINGFILES: - str = L"Replace all existing files"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_ApplyToAll, eResult_Overwrite); break; case ID_FEEDBACK_REPLACE_FILESWITHDIFFERENTDATESORSIZES: - str = L"Replace files with different dates or sizes"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenDifferentDateOrSize, eResult_Overwrite); break; case ID_FEEDBACK_REPLACE_OLDERFILESWITHNEWERVERSIONS: - str = L"Replace older files with newer ones"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenNewerThanDst, eResult_Overwrite); break; case ID_FEEDBACK_REPLACE_NEWERFILESWITHOLDERVERSIONS: - str = L"Replace newer files with older ones"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenOlderThanDst, eResult_Overwrite); break; - default: - str = L"Default"; - break; } - MessageBox(str); + + EndDialog(chengine::EFeedbackResult::eResult_Overwrite); } void CFeedbackReplaceDlg::OnBnMassRename() { - CString str; switch (m_btnMassRename.m_nMenuResult) { case ID_FEEDBACK_RENAME_WHENDESTIONATIONFILEEXISTS: - str = L"Rename when destination file exists"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_ApplyToAll, eResult_Rename); break; case ID_FEEDBACK_RENAME_WHENDATEORSIZEDIFFERS: - str = L"Rename when size or date differs"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenDifferentDateOrSize, eResult_Rename); break; case ID_FEEDBACK_RENAME_WHENDATEANDSZEARESAME: - str = L"Rename when date and size are same"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenSameDateAndSize, eResult_Rename); break; case ID_FEEDBACK_RENAME_WHENNEWERTHANDESTINATION: - str = L"Rename when newer than destination"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenNewerThanDst, eResult_Rename); break; case ID_FEEDBACK_RENAME_WHENOLDERTHANDESTINATION: - str = L"Rename when older than destination"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenOlderThanDst, eResult_Rename); break; - default: - str = L"Default"; - break; } - MessageBox(str); + + EndDialog(chengine::EFeedbackResult::eResult_Rename); } void CFeedbackReplaceDlg::OnBnMassResume() { - CString str; switch (m_btnMassResume.m_nMenuResult) { case ID_FEEDBACK_RESUME_WHENFILEBIGGERTHANDESTINATION: - str = L"Resume when file is bigger than destination"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenBiggerThanDst, eResult_CopyRest); break; - default: - str = L"Default"; - break; } - MessageBox(str); + + EndDialog(chengine::EFeedbackResult::eResult_CopyRest); } void CFeedbackReplaceDlg::OnBnMassSkip() { - CString str; switch (m_btnMassSkip.m_nMenuResult) { case ID_FEEDBACK_SKIP_ALLEXISTINGDESTINATIONFILES: - str = L"Skip all files already existing in destination dir"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_ApplyToAll, eResult_Skip); break; case ID_FEEDBACK_SKIP_ALLFILESWITHSAMEDATESANDSIZES: - str = L"Skip files with same date and size"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenSameDateAndSize, eResult_Skip); break; case ID_FEEDBACK_SKIP_FILESTHATAREOLDERTHANDESTINATION: - str = L"Skip files that are older than existing destination"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenOlderThanDst, eResult_Skip); break; case ID_FEEDBACK_SKIP_FILESTHATARENEWERTHANDESTINATION: - str = L"Skip files that are newer than destination"; + m_feedbackRules = FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition::eCondition_WhenNewerThanDst, eResult_Skip); break; - default: - str = L"Default"; - break; } - MessageBox(str); + + EndDialog(chengine::EFeedbackResult::eResult_Skip); } void CFeedbackReplaceDlg::OnCancel() @@ -325,9 +313,9 @@ EndDialog(chengine::EFeedbackResult::eResult_Cancel); } -bool CFeedbackReplaceDlg::IsApplyToAllItemsChecked() const +const chengine::FeedbackAlreadyExistsRuleList& CFeedbackReplaceDlg::GetRules() const { - return m_bAllItems != FALSE; + return m_feedbackRules; } void CFeedbackReplaceDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) Index: src/ch/FeedbackReplaceDlg.h =================================================================== diff -u -r5b4b933c78513d867ec02d33325907c2069c7bef -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/ch/FeedbackReplaceDlg.h (.../FeedbackReplaceDlg.h) (revision 5b4b933c78513d867ec02d33325907c2069c7bef) +++ src/ch/FeedbackReplaceDlg.h (.../FeedbackReplaceDlg.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -19,6 +19,8 @@ #ifndef __FEEDBACKREPLACEDLG_H__ #define __FEEDBACKREPLACEDLG_H__ +#include "../libchengine/FeedbackAlreadyExistsRuleList.h" + namespace chengine { class TFileInfo; @@ -34,7 +36,7 @@ BOOL OnInitDialog() override; - bool IsApplyToAllItemsChecked() const; + const chengine::FeedbackAlreadyExistsRuleList& GetRules() const; protected: void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV support @@ -43,6 +45,19 @@ void RefreshFilesInfo(); void RefreshImages(); + afx_msg void OnBnClickedReplaceButton(); + afx_msg void OnBnClickedCopyRestButton(); + afx_msg void OnBnClickedSkipButton(); + afx_msg void OnBnClickedPauseButton(); + afx_msg void OnBnClickedCancelButton(); + + afx_msg void OnBnMassReplace(); + afx_msg void OnBnMassRename(); + afx_msg void OnBnMassResume(); + afx_msg void OnBnMassSkip(); + + afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); + DECLARE_MESSAGE_MAP() private: @@ -76,27 +91,12 @@ CMFCMenuButton m_btnMassResume; CMFCMenuButton m_btnMassSkip; - BOOL m_bAllItems; - CRect m_rcInitial; -protected: const chengine::TFileInfo& m_rSrcFile; const chengine::TFileInfo& m_rDstFile; -public: - afx_msg void OnBnClickedReplaceButton(); - afx_msg void OnBnClickedCopyRestButton(); - afx_msg void OnBnClickedSkipButton(); - afx_msg void OnBnClickedPauseButton(); - afx_msg void OnBnClickedCancelButton(); - - afx_msg void OnBnMassReplace(); - afx_msg void OnBnMassRename(); - afx_msg void OnBnMassResume(); - afx_msg void OnBnMassSkip(); - - afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); + chengine::FeedbackAlreadyExistsRuleList m_feedbackRules; // feedback rules resulting from choices made in this dialog box }; #endif Index: src/libchengine/ECompareType.h =================================================================== diff -u -rf3c80778cfee0736195e00274c78040f7908ac5b -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/ECompareType.h (.../ECompareType.h) (revision f3c80778cfee0736195e00274c78040f7908ac5b) +++ src/libchengine/ECompareType.h (.../ECompareType.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -8,7 +8,8 @@ eCmp_LessOrEqual = 1, eCmp_Equal = 2, eCmp_GreaterOrEqual = 3, - eCmp_Greater = 4 + eCmp_Greater = 4, + eCmp_NotEqual = 5 }; template @@ -26,6 +27,8 @@ return value1 >= value2; case eCmp_Greater: return value1 > value2; + case eCmp_NotEqual: + return value1 != value2; } throw std::runtime_error("Invalid compare type"); Index: src/libchengine/EFeedbackResult.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/EFeedbackResult.h (.../EFeedbackResult.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/EFeedbackResult.h (.../EFeedbackResult.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -30,7 +30,8 @@ eResult_Cancel, eResult_Pause, eResult_Retry, - eResult_Ignore + eResult_Ignore, + eResult_Rename }; } Index: src/libchengine/EFileError.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/EFileError.h (.../EFileError.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/EFileError.h (.../EFileError.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -21,7 +21,7 @@ namespace chengine { - enum class EFileError + enum EFileError { eDeleteError, ///< Problem occurred when tried to delete the fs object eSeekError, ///< Problem occurred when tried to set file pointer Index: src/libchengine/EOperationEvent.h =================================================================== diff -u --- src/libchengine/EOperationEvent.h (revision 0) +++ src/libchengine/EOperationEvent.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,10 @@ +#pragma once + +namespace chengine +{ + enum EOperationEvent + { + eOperationEvent_Finished, + eOperationEvent_Error + }; +} Index: src/libchengine/FeedbackAlreadyExistsRule.cpp =================================================================== diff -u --- src/libchengine/FeedbackAlreadyExistsRule.cpp (revision 0) +++ src/libchengine/FeedbackAlreadyExistsRule.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,369 @@ +#include "stdafx.h" +#include "FeedbackAlreadyExistsRule.h" +#include "../libstring/TString.h" +#include "../libstring/TStringArray.h" + +using namespace serializer; +using namespace string; + +namespace chengine +{ + FeedbackAlreadyExistsRule::FeedbackAlreadyExistsRule() : + m_bUseMask(m_setModifications, false), + m_spaMask(m_setModifications), + m_bUseExcludeMask(m_setModifications, false), + m_spaExcludeMask(m_setModifications), + m_bUseDateCompare(m_setModifications, false), + m_cmpLastModified(m_setModifications, eCmp_Equal), + m_bUseSizeCompare(m_setModifications, false), + m_cmpSize(m_setModifications, eCmp_Equal), + m_eResult(m_setModifications, eResult_Unknown) + { + m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_Added] = true; + } + + + FeedbackAlreadyExistsRule::FeedbackAlreadyExistsRule(const FeedbackAlreadyExistsRule& rSrc) : + serializer::SerializableObject(rSrc), + m_bUseMask(rSrc.m_bUseMask, m_setModifications), + m_spaMask(rSrc.m_spaMask, m_setModifications), + m_bUseExcludeMask(rSrc.m_bUseExcludeMask, m_setModifications), + m_spaExcludeMask(rSrc.m_spaExcludeMask, m_setModifications), + m_bUseDateCompare(rSrc.m_bUseDateCompare, m_setModifications), + m_cmpLastModified(rSrc.m_cmpLastModified, m_setModifications), + m_bUseSizeCompare(rSrc.m_bUseSizeCompare, m_setModifications), + m_cmpSize(rSrc.m_cmpSize, m_setModifications), + m_eResult(rSrc.m_eResult, m_setModifications) + { + } + + FeedbackAlreadyExistsRule& FeedbackAlreadyExistsRule::operator=(const FeedbackAlreadyExistsRule& rSrc) + { + if(this == &rSrc) + return *this; + + __super::operator=(rSrc); + + SetData(rSrc); + + return *this; + } + + bool FeedbackAlreadyExistsRule::operator==(const FeedbackAlreadyExistsRule& rSrc) const + { + if(m_bUseMask != rSrc.m_bUseMask) + return false; + if(m_spaMask != rSrc.m_spaMask) + return false; + + if(m_bUseExcludeMask != rSrc.m_bUseExcludeMask) + return false; + + if(m_spaExcludeMask != rSrc.m_spaExcludeMask) + return false; + + if(m_bUseDateCompare != rSrc.m_bUseDateCompare) + return false; + if(m_cmpLastModified != rSrc.m_cmpLastModified) + return false; + + if(m_bUseSizeCompare != rSrc.m_bUseSizeCompare) + return false; + if(m_cmpSize != rSrc.m_cmpSize) + return false; + + if(m_eResult != rSrc.m_eResult) + return false; + + return true; + } + + bool FeedbackAlreadyExistsRule::operator!=(const FeedbackAlreadyExistsRule& rSrc) const + { + return !operator==(rSrc); + } + + void FeedbackAlreadyExistsRule::SetData(const FeedbackAlreadyExistsRule& rSrc) + { + if(this == &rSrc) + return; + + m_bUseMask = rSrc.m_bUseMask; + m_spaMask = rSrc.m_spaMask; + m_bUseExcludeMask = rSrc.m_bUseExcludeMask; + m_spaExcludeMask = rSrc.m_spaExcludeMask; + m_bUseDateCompare = rSrc.m_bUseDateCompare; + m_cmpLastModified = rSrc.m_cmpLastModified; + m_bUseSizeCompare = rSrc.m_bUseSizeCompare; + m_cmpSize = rSrc.m_cmpSize; + m_eResult = rSrc.m_eResult; + } + + bool FeedbackAlreadyExistsRule::Matches(const TFileInfo& rSrcFile, const TFileInfo& rDstFile, EFeedbackResult& eResult) const + { + eResult = eResult_Unknown; + + if(m_bUseMask) + { + if(!m_spaMask.Get().MatchesAny(rDstFile.GetFullFilePath().GetFileName().ToString())) + return false; + } + if(m_bUseExcludeMask) + { + if(m_spaExcludeMask.Get().MatchesAny(rDstFile.GetFullFilePath().GetFileName().ToString())) + return false; + } + if(m_bUseDateCompare) + { + if(!CompareByType(rSrcFile.GetLastWriteTime(), rDstFile.GetLastWriteTime(), m_cmpLastModified)) + return false; + } + + if(m_bUseSizeCompare) + { + if(!CompareByType(rSrcFile.GetLength64(), rDstFile.GetLength64(), m_cmpSize)) + return false; + } + + eResult = m_eResult; + return true; + } + + void FeedbackAlreadyExistsRule::InitColumns(serializer::IColumnsDefinition& rColumns) + { + rColumns.AddColumn(_T("id"), ColumnType::value); + rColumns.AddColumn(_T("use_mask"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("mask"), IColumnsDefinition::eType_string); + rColumns.AddColumn(_T("use_exclude_mask"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("exclude_mask"), IColumnsDefinition::eType_string); + rColumns.AddColumn(_T("use_date_compare"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("date_compare_type"), IColumnsDefinition::eType_int); + rColumns.AddColumn(_T("use_size_compare"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("size_compare_type"), IColumnsDefinition::eType_int); + rColumns.AddColumn(_T("result"), IColumnsDefinition::eType_int); + } + + void FeedbackAlreadyExistsRule::Store(const ISerializerContainerPtr& spContainer) const + { + bool bAdded = m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_Added]; + if(m_setModifications.any()) + { + ISerializerRowData& rRow = spContainer->GetRow(m_oidObjectID, bAdded); + + if(bAdded || m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_UseMask]) + rRow.SetValue(_T("use_mask"), m_bUseMask); + if(bAdded || m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_Mask]) + rRow.SetValue(_T("mask"), GetCombinedMask()); + + if(bAdded || m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_UseExcludeMask]) + rRow.SetValue(_T("use_exclude_mask"), m_bUseExcludeMask); + if(bAdded || m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_ExcludeMask]) + rRow.SetValue(_T("exclude_mask"), GetCombinedExcludeMask()); + + if(bAdded || m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_UseDateCompare]) + rRow.SetValue(_T("use_date_compare"), m_bUseDateCompare); + if(bAdded || m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_DateCompare]) + rRow.SetValue(_T("date_compare_type"), m_cmpLastModified); + + if(bAdded || m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_UseSizeCompare]) + rRow.SetValue(_T("use_size_compare"), m_bUseSizeCompare); + if(bAdded || m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_SizeCompare]) + rRow.SetValue(_T("size_compare_type"), m_cmpSize); + + if(bAdded || m_setModifications[FeedbackAlreadyExistsRuleEnum::eMod_Result]) + rRow.SetValue(_T("result"), m_eResult); + + m_setModifications.reset(); + } + } + + void FeedbackAlreadyExistsRule::Load(const ISerializerRowReaderPtr& spRowReader) + { + TString strMask; + + spRowReader->GetValue(_T("use_mask"), m_bUseMask.Modify()); + spRowReader->GetValue(_T("mask"), strMask); + SetCombinedMask(strMask); + + spRowReader->GetValue(_T("use_exclude_mask"), m_bUseExcludeMask.Modify()); + spRowReader->GetValue(_T("exclude_mask"), strMask); + SetCombinedExcludeMask(strMask); + + spRowReader->GetValue(_T("use_date_compare"), m_bUseDateCompare.Modify()); + spRowReader->GetValue(_T("date_compare_type"), *(int*)&m_cmpLastModified.Modify()); + + spRowReader->GetValue(_T("use_size_compare"), m_bUseSizeCompare.Modify()); + spRowReader->GetValue(_T("size_compare_type"), *(int*)&m_cmpSize.Modify()); + + spRowReader->GetValue(_T("result"), *(int*)&m_eResult.Modify()); + + m_setModifications.reset(); + } + + void FeedbackAlreadyExistsRule::StoreInConfig(TConfig& rConfig) const + { + SetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask.Get()); + SetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), m_spaMask.Get().ToSerializedStringArray()); + + SetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask.Get()); + SetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), m_spaExcludeMask.Get().ToSerializedStringArray()); + + SetConfigValue(rConfig, _T("DateCompare.Use"), m_bUseDateCompare.Get()); + SetConfigValue(rConfig, _T("DateCompare.CompareType"), m_cmpLastModified.Get()); + + SetConfigValue(rConfig, _T("SizeCompare.Use"), m_bUseDateCompare.Get()); + SetConfigValue(rConfig, _T("SizeCompare.CompareType"), m_cmpLastModified.Get()); + + SetConfigValue(rConfig, _T("Result"), m_eResult.Get()); + } + + void FeedbackAlreadyExistsRule::ReadFromConfig(const TConfig& rConfig) + { + if(!GetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask.Modify())) + m_bUseMask = false; + + TStringArray arrMask; + m_spaMask.Modify().Clear(); + GetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), arrMask); + m_spaMask.Modify().FromSerializedStringArray(arrMask); + + if(!GetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask.Modify())) + m_bUseExcludeMask = false; + + m_spaExcludeMask.Modify().Clear(); + GetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), arrMask); + m_spaExcludeMask.Modify().FromSerializedStringArray(arrMask); + + if(!GetConfigValue(rConfig, _T("DateCompare.Use"), m_bUseDateCompare.Modify())) + m_bUseDateCompare = false; + if(!GetConfigValue(rConfig, _T("DateCompare.CompareType"), *(int*)m_cmpLastModified.Modify())) + m_cmpLastModified = eCmp_Equal; + + if(!GetConfigValue(rConfig, _T("SizeCompare.Use"), m_bUseSizeCompare.Modify())) + m_bUseSizeCompare = false; + if(!GetConfigValue(rConfig, _T("SizeCompare.CompareType"), *(int*)m_cmpSize.Modify())) + m_cmpSize = eCmp_Equal; + + if(!GetConfigValue(rConfig, _T("Result"), *(int*)m_eResult.Modify())) + m_eResult = eResult_Unknown; + } + + bool FeedbackAlreadyExistsRule::HaveSameCondition(const FeedbackAlreadyExistsRule& rSrc) const + { + if(m_bUseMask != rSrc.m_bUseMask) + return false; + else if(m_bUseMask == true && m_spaMask != rSrc.m_spaMask) + return false; + + if(m_bUseExcludeMask != rSrc.m_bUseExcludeMask) + return false; + else if(m_bUseExcludeMask == true && m_spaExcludeMask != rSrc.m_spaExcludeMask) + return false; + + if(m_bUseDateCompare != rSrc.m_bUseDateCompare) + return false; + else if(m_bUseDateCompare == true && m_cmpLastModified != rSrc.m_cmpLastModified) + return false; + + if(m_bUseSizeCompare != rSrc.m_bUseSizeCompare) + return false; + else if(m_bUseSizeCompare == true && m_cmpSize != rSrc.m_cmpSize) + return false; + + return true; + } + + void FeedbackAlreadyExistsRule::SetUseMask(bool bUseMask) + { + m_bUseMask = bUseMask; + } + + bool FeedbackAlreadyExistsRule::GetUseMask() const + { + return m_bUseMask; + } + + bool FeedbackAlreadyExistsRule::GetUseExcludeMask() const + { + return m_bUseExcludeMask; + } + + void FeedbackAlreadyExistsRule::SetUseExcludeMask(bool bUseExcludeMask) + { + m_bUseExcludeMask = bUseExcludeMask; + } + + bool FeedbackAlreadyExistsRule::GetUseDateCompare() const + { + return m_bUseDateCompare; + } + + void FeedbackAlreadyExistsRule::SetUseDateCompare(bool bUseDateCompare) + { + m_bUseDateCompare = bUseDateCompare; + } + + ECompareType FeedbackAlreadyExistsRule::GetDateCompareType() const + { + return m_cmpLastModified; + } + + void FeedbackAlreadyExistsRule::SetDateCompareType(ECompareType eCmpType) + { + m_cmpLastModified = eCmpType; + } + + bool FeedbackAlreadyExistsRule::GetUseSizeCompare() const + { + return m_bUseSizeCompare; + } + + void FeedbackAlreadyExistsRule::SetUseSizeCompare(bool bUseSizeCompare) + { + m_bUseSizeCompare = bUseSizeCompare; + } + + ECompareType FeedbackAlreadyExistsRule::GetSizeCompareType() const + { + return m_cmpSize; + } + + void FeedbackAlreadyExistsRule::SetSizeCompareType(ECompareType eCmpType) + { + m_cmpSize = eCmpType; + } + + TString FeedbackAlreadyExistsRule::GetCombinedMask() const + { + return m_spaMask.Get().ToString(); + } + + void FeedbackAlreadyExistsRule::SetCombinedMask(const TString& strMask) + { + TStringPatternArray& rPatterns = m_spaMask.Modify(); + rPatterns.Clear(); + rPatterns.FromString(strMask); + } + + TString FeedbackAlreadyExistsRule::GetCombinedExcludeMask() const + { + return m_spaExcludeMask.Get().ToString(); + } + + void FeedbackAlreadyExistsRule::SetCombinedExcludeMask(const TString& strMask) + { + TStringPatternArray& rPatterns = m_spaExcludeMask.Modify(); + rPatterns.Clear(); + rPatterns.FromString(strMask); + } + + chengine::EFeedbackResult FeedbackAlreadyExistsRule::GetResult() const + { + return m_eResult; + } + + void FeedbackAlreadyExistsRule::SetResult(EFeedbackResult eResult) + { + m_eResult = eResult; + } +} Index: src/libchengine/FeedbackAlreadyExistsRule.h =================================================================== diff -u --- src/libchengine/FeedbackAlreadyExistsRule.h (revision 0) +++ src/libchengine/FeedbackAlreadyExistsRule.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,104 @@ +#pragma once + +#include "libchengine.h" +#include "../libserializer/SerializableObject.h" +#include "../libstring/TStringPatternArray.h" +#include "ECompareType.h" +#include "EFeedbackResult.h" +#include "../libserializer/SerializerDataTypes.h" +#include +#include "../libserializer/TSharedModificationTracker.h" +#include "TFileInfo.h" +#include "TConfig.h" + +namespace chengine +{ + namespace FeedbackAlreadyExistsRuleEnum + { + enum EModifications + { + eMod_Added, + eMod_UseMask, + eMod_Mask, + eMod_UseExcludeMask, + eMod_ExcludeMask, + eMod_UseSizeCompare, + eMod_SizeCompare, + eMod_UseDateCompare, + eMod_DateCompare, + eMod_Result, + + eMod_Last + }; + } + +#pragma warning(push) +#pragma warning(disable: 4251) + class LIBCHENGINE_API FeedbackAlreadyExistsRule : public serializer::SerializableObject + { + public: + FeedbackAlreadyExistsRule(); + FeedbackAlreadyExistsRule(const FeedbackAlreadyExistsRule& rSrc); + FeedbackAlreadyExistsRule& operator=(const FeedbackAlreadyExistsRule& rSrc); + + bool operator==(const FeedbackAlreadyExistsRule& rSrc) const; + bool operator!=(const FeedbackAlreadyExistsRule& rSrc) const; + + void SetData(const FeedbackAlreadyExistsRule& rSrc); + + bool Matches(const TFileInfo& rSrcFile, const TFileInfo& rDstFile, EFeedbackResult& eResult) const; + + void Store(const serializer::ISerializerContainerPtr& spContainer) const override; + void Load(const serializer::ISerializerRowReaderPtr& spRowReader) override; + static void InitColumns(serializer::IColumnsDefinition& rColumns); + + void StoreInConfig(TConfig& rConfig) const; + void ReadFromConfig(const TConfig& rConfig); + + // comparison + bool HaveSameCondition(const FeedbackAlreadyExistsRule& rSrc) const; + + // get/set + // atrributes access + bool GetUseMask() const; + void SetUseMask(bool bUseMask); + + string::TString GetCombinedMask() const; + void SetCombinedMask(const string::TString& strMask); + + bool GetUseExcludeMask() const; + void SetUseExcludeMask(bool bUseExcludeMask); + + string::TString GetCombinedExcludeMask() const; + void SetCombinedExcludeMask(const string::TString& strMask); + + bool GetUseDateCompare() const; + void SetUseDateCompare(bool bUseDateCompare); + + ECompareType GetDateCompareType() const; + void SetDateCompareType(ECompareType eCmpType); + + bool GetUseSizeCompare() const; + void SetUseSizeCompare(bool bUseSizeCompare); + + ECompareType GetSizeCompareType() const; + void SetSizeCompareType(ECompareType eCmpType); + + EFeedbackResult GetResult() const; + void SetResult(EFeedbackResult eResult); + + private: + serializer::TSharedModificationTracker m_bUseMask; + serializer::TSharedModificationTracker m_spaMask; + serializer::TSharedModificationTracker m_bUseExcludeMask; + serializer::TSharedModificationTracker m_spaExcludeMask; + + serializer::TSharedModificationTracker m_bUseDateCompare; + serializer::TSharedModificationTracker m_cmpLastModified; + serializer::TSharedModificationTracker m_bUseSizeCompare; + serializer::TSharedModificationTracker m_cmpSize; + + serializer::TSharedModificationTracker m_eResult; + }; +#pragma warning(pop) +} Index: src/libchengine/FeedbackAlreadyExistsRuleList.cpp =================================================================== diff -u --- src/libchengine/FeedbackAlreadyExistsRuleList.cpp (revision 0) +++ src/libchengine/FeedbackAlreadyExistsRuleList.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,90 @@ +#include "stdafx.h" +#include "FeedbackAlreadyExistsRuleList.h" +#include "TConfigArray.h" +#include "../libserializer/IColumnsDefinition.h" +#include "TFileFilter.h" + +using namespace string; +using namespace serializer; + +namespace chengine +{ + EFeedbackResult FeedbackAlreadyExistsRuleList::Matches(const TFileInfo& rSrcFile, const TFileInfo& rDstFile) const + { + if(m_vEntries.empty()) + return eResult_Unknown; + + for(const FeedbackAlreadyExistsRule& rRule : m_vEntries) + { + EFeedbackResult eResult = eResult_Unknown; + if(rRule.Matches(rSrcFile, rDstFile, eResult)) + return eResult; + } + + return eResult_Unknown; + } + + void FeedbackAlreadyExistsRuleList::Merge(const FeedbackAlreadyExistsRuleList& rSrc) + { + for(size_t stIndex = 0; stIndex < rSrc.GetCount(); ++stIndex) + { + InsertOrUpdateRule(rSrc.GetAt(stIndex)); + } + } + + void FeedbackAlreadyExistsRuleList::InsertOrUpdateRule(const FeedbackAlreadyExistsRule& rRule) + { + bool bFound = false; + for(size_t stIndex = 0; stIndex < GetCount(); ++stIndex) + { + FeedbackAlreadyExistsRule& rCurrent = GetAt(stIndex); + if(rCurrent.HaveSameCondition(rRule)) + { + bFound = true; + rCurrent.SetResult(rRule.GetResult()); + } + } + + if(!bFound) + InsertAt(0, rRule); + } + + void FeedbackAlreadyExistsRuleList::InitColumns(const serializer::ISerializerContainerPtr& spContainer) const + { + IColumnsDefinition& rColumns = spContainer->GetColumnsDefinition(); + if(rColumns.IsEmpty()) + TFileFilter::InitColumns(rColumns); + } + + void FeedbackAlreadyExistsRuleList::StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const + { + rConfig.DeleteNode(pszNodeName); + for(const FeedbackAlreadyExistsRule& rRule : m_vEntries) + { + TConfig cfgNode; + rRule.StoreInConfig(cfgNode); + + TString strNode = TString(pszNodeName) + _T(".RuleDefinition"); + rConfig.AddSubConfig(strNode.c_str(), cfgNode); + } + } + + bool FeedbackAlreadyExistsRuleList::ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName) + { + m_vEntries.clear(); + + TConfigArray vConfigs; + if(!rConfig.ExtractMultiSubConfigs(pszNodeName, vConfigs)) + return false; + + for(size_t stIndex = 0; stIndex < vConfigs.GetCount(); ++stIndex) + { + const TConfig& rCfg = vConfigs.GetAt(stIndex); + FeedbackAlreadyExistsRule rule; + rule.ReadFromConfig(rCfg); + + m_vEntries.push_back(rule); + } + return true; + } +} Index: src/libchengine/FeedbackAlreadyExistsRuleList.h =================================================================== diff -u --- src/libchengine/FeedbackAlreadyExistsRuleList.h (revision 0) +++ src/libchengine/FeedbackAlreadyExistsRuleList.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,31 @@ +#pragma once + +#include "libchengine.h" +#include "FeedbackAlreadyExistsRule.h" +#include "TConfig.h" +#include "../libserializer/SerializableContainer.h" + +namespace chengine +{ +#pragma warning(push) +#pragma warning(disable: 4251) + + class LIBCHENGINE_API FeedbackAlreadyExistsRuleList : public serializer::SerializableContainer + { + public: + EFeedbackResult Matches(const TFileInfo& rSrcFile, const TFileInfo& rDstFile) const; + + void Merge(const FeedbackAlreadyExistsRuleList& rSrc); + + void InitColumns(const serializer::ISerializerContainerPtr& spContainer) const override; + + void StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const; + bool ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName); + + private: + void InsertOrUpdateRule(const FeedbackAlreadyExistsRule& rRule); + }; +#pragma warning(pop) +} + +CONFIG_MEMBER_SERIALIZATION(FeedbackAlreadyExistsRuleList) Index: src/libchengine/FeedbackErrorRule.cpp =================================================================== diff -u --- src/libchengine/FeedbackErrorRule.cpp (revision 0) +++ src/libchengine/FeedbackErrorRule.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,372 @@ +#include "stdafx.h" +#include "FeedbackErrorRule.h" +#include "../libstring/TString.h" +#include "../libstring/TStringArray.h" +#include "../libchcore/TPath.h" + +using namespace serializer; +using namespace string; +using namespace chcore; + +namespace chengine +{ + FeedbackErrorRule::FeedbackErrorRule() : + m_bUseMask(m_setModifications, false), + m_spaMask(m_setModifications), + m_bUseExcludeMask(m_setModifications, false), + m_spaExcludeMask(m_setModifications), + m_bUseErrorType(m_setModifications, false), + m_eErrorType(m_setModifications, EFileError::eDeleteError), + m_bUseSystemErrorNo(m_setModifications, false), + m_ulSystemErrorNo(m_setModifications, 0), + m_eResult(m_setModifications, eResult_Unknown) + { + m_setModifications[FeedbackErrorRuleEnum::eMod_Added] = true; + } + + + FeedbackErrorRule::FeedbackErrorRule(const FeedbackErrorRule& rSrc) : + serializer::SerializableObject(rSrc), + m_bUseMask(rSrc.m_bUseMask, m_setModifications), + m_spaMask(rSrc.m_spaMask, m_setModifications), + m_bUseExcludeMask(rSrc.m_bUseExcludeMask, m_setModifications), + m_spaExcludeMask(rSrc.m_spaExcludeMask, m_setModifications), + m_bUseErrorType(rSrc.m_bUseErrorType, m_setModifications), + m_eErrorType(rSrc.m_eErrorType, m_setModifications), + m_bUseSystemErrorNo(rSrc.m_bUseSystemErrorNo, m_setModifications), + m_ulSystemErrorNo(rSrc.m_ulSystemErrorNo, m_setModifications), + m_eResult(rSrc.m_eResult, m_setModifications) + { + } + + FeedbackErrorRule& FeedbackErrorRule::operator=(const FeedbackErrorRule& rSrc) + { + if(this == &rSrc) + return *this; + + __super::operator=(rSrc); + + SetData(rSrc); + + return *this; + } + + bool FeedbackErrorRule::operator==(const FeedbackErrorRule& rSrc) const + { + if(m_bUseMask != rSrc.m_bUseMask) + return false; + if(m_spaMask != rSrc.m_spaMask) + return false; + + if(m_bUseExcludeMask != rSrc.m_bUseExcludeMask) + return false; + + if(m_spaExcludeMask != rSrc.m_spaExcludeMask) + return false; + + if(m_bUseErrorType != rSrc.m_bUseErrorType) + return false; + if(m_eErrorType != rSrc.m_eErrorType) + return false; + + if(m_bUseSystemErrorNo != rSrc.m_bUseSystemErrorNo) + return false; + if(m_ulSystemErrorNo != rSrc.m_ulSystemErrorNo) + return false; + + if(m_eResult != rSrc.m_eResult) + return false; + + return true; + } + + bool FeedbackErrorRule::operator!=(const FeedbackErrorRule& rSrc) const + { + return !operator==(rSrc); + } + + void FeedbackErrorRule::SetData(const FeedbackErrorRule& rSrc) + { + if(this == &rSrc) + return; + + m_bUseMask = rSrc.m_bUseMask; + m_spaMask = rSrc.m_spaMask; + m_bUseExcludeMask = rSrc.m_bUseExcludeMask; + m_spaExcludeMask = rSrc.m_spaExcludeMask; + m_bUseErrorType = rSrc.m_bUseErrorType; + m_eErrorType = rSrc.m_eErrorType; + m_bUseSystemErrorNo = rSrc.m_bUseSystemErrorNo; + m_ulSystemErrorNo = rSrc.m_ulSystemErrorNo; + m_eResult = rSrc.m_eResult; + } + + bool FeedbackErrorRule::Matches(const string::TString& strSrcPath, const string::TString& /*strDstPath*/, EFileError eErrorType, unsigned long ulError, EFeedbackResult& eResult) const + { + eResult = eResult_Unknown; + + TSmartPath path = PathFromWString(strSrcPath); + if(m_bUseMask) + { + if(!m_spaMask.Get().MatchesAny(path.GetFileName().ToString())) + return false; + } + if(m_bUseExcludeMask) + { + if(m_spaExcludeMask.Get().MatchesAny(path.GetFileName().ToString())) + return false; + } + if(m_bUseErrorType) + { + if(m_eErrorType != eErrorType) + return false; + } + + if(m_bUseSystemErrorNo) + { + if(m_ulSystemErrorNo != ulError) + return false; + } + + eResult = m_eResult; + return true; + } + + void FeedbackErrorRule::InitColumns(serializer::IColumnsDefinition& rColumns) + { + rColumns.AddColumn(_T("id"), ColumnType::value); + rColumns.AddColumn(_T("use_mask"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("mask"), IColumnsDefinition::eType_string); + rColumns.AddColumn(_T("use_exclude_mask"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("exclude_mask"), IColumnsDefinition::eType_string); + rColumns.AddColumn(_T("use_error_type"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("error_type"), IColumnsDefinition::eType_int); + rColumns.AddColumn(_T("use_system_error_no"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("system_error_no"), IColumnsDefinition::eType_ulong); + rColumns.AddColumn(_T("result"), IColumnsDefinition::eType_int); + } + + void FeedbackErrorRule::Store(const ISerializerContainerPtr& spContainer) const + { + bool bAdded = m_setModifications[FeedbackErrorRuleEnum::eMod_Added]; + if(m_setModifications.any()) + { + ISerializerRowData& rRow = spContainer->GetRow(m_oidObjectID, bAdded); + + if(bAdded || m_setModifications[FeedbackErrorRuleEnum::eMod_UseMask]) + rRow.SetValue(_T("use_mask"), m_bUseMask); + if(bAdded || m_setModifications[FeedbackErrorRuleEnum::eMod_Mask]) + rRow.SetValue(_T("mask"), GetCombinedMask()); + + if(bAdded || m_setModifications[FeedbackErrorRuleEnum::eMod_UseExcludeMask]) + rRow.SetValue(_T("use_exclude_mask"), m_bUseExcludeMask); + if(bAdded || m_setModifications[FeedbackErrorRuleEnum::eMod_ExcludeMask]) + rRow.SetValue(_T("exclude_mask"), GetCombinedExcludeMask()); + + if(bAdded || m_setModifications[FeedbackErrorRuleEnum::eMod_UseErrorType]) + rRow.SetValue(_T("use_error_type"), m_bUseErrorType); + if(bAdded || m_setModifications[FeedbackErrorRuleEnum::eMod_ErrorType]) + rRow.SetValue(_T("error_type"), m_eErrorType); + + if(bAdded || m_setModifications[FeedbackErrorRuleEnum::eMod_UseSystemErrorNo]) + rRow.SetValue(_T("use_system_error_no"), m_bUseSystemErrorNo); + if(bAdded || m_setModifications[FeedbackErrorRuleEnum::eMod_SystemErrorNo]) + rRow.SetValue(_T("system_error_no"), m_ulSystemErrorNo); + + if(bAdded || m_setModifications[FeedbackErrorRuleEnum::eMod_Result]) + rRow.SetValue(_T("result"), m_eResult); + + m_setModifications.reset(); + } + } + + void FeedbackErrorRule::Load(const ISerializerRowReaderPtr& spRowReader) + { + TString strMask; + + spRowReader->GetValue(_T("use_mask"), m_bUseMask.Modify()); + spRowReader->GetValue(_T("mask"), strMask); + SetCombinedMask(strMask); + + spRowReader->GetValue(_T("use_exclude_mask"), m_bUseExcludeMask.Modify()); + spRowReader->GetValue(_T("exclude_mask"), strMask); + SetCombinedExcludeMask(strMask); + + spRowReader->GetValue(_T("use_error_type"), m_bUseErrorType.Modify()); + spRowReader->GetValue(_T("error_type"), *(int*)&m_eErrorType.Modify()); + + spRowReader->GetValue(_T("use_system_error_no"), m_bUseSystemErrorNo.Modify()); + spRowReader->GetValue(_T("system_error_no"), m_ulSystemErrorNo.Modify()); + + spRowReader->GetValue(_T("result"), *(int*)&m_eResult.Modify()); + + m_setModifications.reset(); + } + + void FeedbackErrorRule::StoreInConfig(TConfig& rConfig) const + { + SetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask.Get()); + SetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), m_spaMask.Get().ToSerializedStringArray()); + + SetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask.Get()); + SetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), m_spaExcludeMask.Get().ToSerializedStringArray()); + + SetConfigValue(rConfig, _T("ErrorType.Use"), m_bUseErrorType.Get()); + SetConfigValue(rConfig, _T("ErrorType.Value"), m_eErrorType.Get()); + + SetConfigValue(rConfig, _T("SystemErrorNo.Use"), m_bUseSystemErrorNo.Get()); + SetConfigValue(rConfig, _T("SystemErrorNo.Value"), m_ulSystemErrorNo.Get()); + + SetConfigValue(rConfig, _T("Result"), m_eResult.Get()); + } + + void FeedbackErrorRule::ReadFromConfig(const TConfig& rConfig) + { + if(!GetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask.Modify())) + m_bUseMask = false; + + TStringArray arrMask; + m_spaMask.Modify().Clear(); + GetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), arrMask); + m_spaMask.Modify().FromSerializedStringArray(arrMask); + + if(!GetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask.Modify())) + m_bUseExcludeMask = false; + + m_spaExcludeMask.Modify().Clear(); + GetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), arrMask); + m_spaExcludeMask.Modify().FromSerializedStringArray(arrMask); + + if(!GetConfigValue(rConfig, _T("ErrorType.Use"), m_bUseErrorType.Modify())) + m_bUseErrorType = false; + if(!GetConfigValue(rConfig, _T("ErrorType.Value"), *(int*)m_eErrorType.Modify())) + m_eErrorType = EFileError::eDeleteError; + + if(!GetConfigValue(rConfig, _T("SystemErrorNo.Use"), m_bUseSystemErrorNo.Modify())) + m_bUseSystemErrorNo = false; + if(!GetConfigValue(rConfig, _T("SystemErrorNo.Value"), m_ulSystemErrorNo.Modify())) + m_ulSystemErrorNo = 0UL; + + if(!GetConfigValue(rConfig, _T("Result"), *(int*)m_eResult.Modify())) + m_eResult = eResult_Unknown; + } + + bool FeedbackErrorRule::HaveSameCondition(const FeedbackErrorRule& rSrc) const + { + if(m_bUseMask != rSrc.m_bUseMask) + return false; + else if(m_bUseMask == true && m_spaMask != rSrc.m_spaMask) + return false; + + if(m_bUseExcludeMask != rSrc.m_bUseExcludeMask) + return false; + else if(m_bUseExcludeMask == true && m_spaExcludeMask != rSrc.m_spaExcludeMask) + return false; + + if(m_bUseErrorType != rSrc.m_bUseErrorType) + return false; + else if(m_bUseErrorType == true && m_eErrorType != rSrc.m_eErrorType) + return false; + + if(m_bUseSystemErrorNo != rSrc.m_bUseSystemErrorNo) + return false; + else if(m_bUseSystemErrorNo == true && m_ulSystemErrorNo != rSrc.m_ulSystemErrorNo) + return false; + + return true; + } + + void FeedbackErrorRule::SetUseMask(bool bUseMask) + { + m_bUseMask = bUseMask; + } + + bool FeedbackErrorRule::GetUseMask() const + { + return m_bUseMask; + } + + bool FeedbackErrorRule::GetUseExcludeMask() const + { + return m_bUseExcludeMask; + } + + void FeedbackErrorRule::SetUseExcludeMask(bool bUseExcludeMask) + { + m_bUseExcludeMask = bUseExcludeMask; + } + + bool FeedbackErrorRule::GetUseErrorType() const + { + return m_bUseErrorType; + } + + void FeedbackErrorRule::SetUseErrorType(bool bUseErrorType) + { + m_bUseErrorType = bUseErrorType; + } + + EFileError FeedbackErrorRule::GetErrorType() const + { + return m_eErrorType; + } + + void FeedbackErrorRule::SetErrorType(EFileError eErrorType) + { + m_eErrorType = eErrorType; + } + + bool FeedbackErrorRule::GetUseSystemErrorNo() const + { + return m_bUseSystemErrorNo; + } + + void FeedbackErrorRule::SetUseSystemErrorNo(bool bUseSystemErrorNo) + { + m_bUseSystemErrorNo = bUseSystemErrorNo; + } + + unsigned int FeedbackErrorRule::GetSystemErrorNo() const + { + return m_ulSystemErrorNo; + } + + void FeedbackErrorRule::SetSystemErrorNo(unsigned int ulErrorNo) + { + m_ulSystemErrorNo = ulErrorNo; + } + + TString FeedbackErrorRule::GetCombinedMask() const + { + return m_spaMask.Get().ToString(); + } + + void FeedbackErrorRule::SetCombinedMask(const TString& strMask) + { + TStringPatternArray& rPatterns = m_spaMask.Modify(); + rPatterns.Clear(); + rPatterns.FromString(strMask); + } + + TString FeedbackErrorRule::GetCombinedExcludeMask() const + { + return m_spaExcludeMask.Get().ToString(); + } + + void FeedbackErrorRule::SetCombinedExcludeMask(const TString& strMask) + { + TStringPatternArray& rPatterns = m_spaExcludeMask.Modify(); + rPatterns.Clear(); + rPatterns.FromString(strMask); + } + + chengine::EFeedbackResult FeedbackErrorRule::GetResult() const + { + return m_eResult; + } + + void FeedbackErrorRule::SetResult(EFeedbackResult eResult) + { + m_eResult = eResult; + } +} Index: src/libchengine/FeedbackErrorRule.h =================================================================== diff -u --- src/libchengine/FeedbackErrorRule.h (revision 0) +++ src/libchengine/FeedbackErrorRule.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,103 @@ +#pragma once + +#include "libchengine.h" +#include "../libserializer/SerializableObject.h" +#include "../libstring/TStringPatternArray.h" +#include "ECompareType.h" +#include "EFeedbackResult.h" +#include "../libserializer/SerializerDataTypes.h" +#include +#include "../libserializer/TSharedModificationTracker.h" +#include "TFileInfo.h" +#include "TConfig.h" +#include "EFileError.h" + +namespace chengine +{ + namespace FeedbackErrorRuleEnum + { + enum EModifications + { + eMod_Added, + eMod_UseMask, + eMod_Mask, + eMod_UseExcludeMask, + eMod_ExcludeMask, + eMod_UseErrorType, + eMod_ErrorType, + eMod_UseSystemErrorNo, + eMod_SystemErrorNo, + eMod_Result, + + eMod_Last + }; + } + +#pragma warning(push) +#pragma warning(disable: 4251) + class LIBCHENGINE_API FeedbackErrorRule : public serializer::SerializableObject + { + public: + FeedbackErrorRule(); + FeedbackErrorRule(const FeedbackErrorRule& rSrc); + FeedbackErrorRule& operator=(const FeedbackErrorRule& rSrc); + + bool operator==(const FeedbackErrorRule& rSrc) const; + bool operator!=(const FeedbackErrorRule& rSrc) const; + + void SetData(const FeedbackErrorRule& rSrc); + + bool Matches(const string::TString& strSrcPath, const string::TString& strDstPath, EFileError eErrorType, unsigned long ulError, EFeedbackResult& eResult) const; + + void Store(const serializer::ISerializerContainerPtr& spContainer) const override; + void Load(const serializer::ISerializerRowReaderPtr& spRowReader) override; + static void InitColumns(serializer::IColumnsDefinition& rColumns); + + void StoreInConfig(TConfig& rConfig) const; + void ReadFromConfig(const TConfig& rConfig); + + // comparison + bool HaveSameCondition(const FeedbackErrorRule& rSrc) const; + + // get/set + // atrributes access + bool GetUseMask() const; + void SetUseMask(bool bUseMask); + + string::TString GetCombinedMask() const; + void SetCombinedMask(const string::TString& strMask); + + bool GetUseExcludeMask() const; + void SetUseExcludeMask(bool bUseExcludeMask); + + string::TString GetCombinedExcludeMask() const; + void SetCombinedExcludeMask(const string::TString& strMask); + + bool GetUseErrorType() const; + void SetUseErrorType(bool bUseErrorType); + EFileError GetErrorType() const; + void SetErrorType(EFileError eErrorType); + + bool GetUseSystemErrorNo() const; + void SetUseSystemErrorNo(bool bUseSystemErrorNo); + unsigned int GetSystemErrorNo() const; + void SetSystemErrorNo(unsigned int ulErrorNo); + + EFeedbackResult GetResult() const; + void SetResult(EFeedbackResult eResult); + + private: + serializer::TSharedModificationTracker m_bUseMask; + serializer::TSharedModificationTracker m_spaMask; + serializer::TSharedModificationTracker m_bUseExcludeMask; + serializer::TSharedModificationTracker m_spaExcludeMask; + + serializer::TSharedModificationTracker m_bUseErrorType; + serializer::TSharedModificationTracker m_eErrorType; + serializer::TSharedModificationTracker m_bUseSystemErrorNo; + serializer::TSharedModificationTracker m_ulSystemErrorNo; + + serializer::TSharedModificationTracker m_eResult; + }; +#pragma warning(pop) +} Index: src/libchengine/FeedbackErrorRuleList.cpp =================================================================== diff -u --- src/libchengine/FeedbackErrorRuleList.cpp (revision 0) +++ src/libchengine/FeedbackErrorRuleList.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,90 @@ +#include "stdafx.h" +#include "FeedbackErrorRuleList.h" +#include "TConfigArray.h" +#include "../libserializer/IColumnsDefinition.h" +#include "TFileFilter.h" + +using namespace string; +using namespace serializer; + +namespace chengine +{ + EFeedbackResult FeedbackErrorRuleList::Matches(const string::TString& strSrcPath, const string::TString& strDstPath, EFileError eErrorType, unsigned long ulError) const + { + if(m_vEntries.empty()) + return eResult_Unknown; + + for(const FeedbackErrorRule& rRule : m_vEntries) + { + EFeedbackResult eResult = eResult_Unknown; + if(rRule.Matches(strSrcPath, strDstPath, eErrorType, ulError, eResult)) + return eResult; + } + + return eResult_Unknown; + } + + void FeedbackErrorRuleList::Merge(const FeedbackErrorRuleList& rSrc) + { + for(size_t stIndex = 0; stIndex < rSrc.GetCount(); ++stIndex) + { + InsertOrUpdateRule(rSrc.GetAt(stIndex)); + } + } + + void FeedbackErrorRuleList::InsertOrUpdateRule(const FeedbackErrorRule& rRule) + { + bool bFound = false; + for(size_t stIndex = 0; stIndex < GetCount(); ++stIndex) + { + FeedbackErrorRule& rCurrent = GetAt(stIndex); + if(rCurrent.HaveSameCondition(rRule)) + { + bFound = true; + rCurrent.SetResult(rRule.GetResult()); + } + } + + if(!bFound) + InsertAt(0, rRule); + } + + void FeedbackErrorRuleList::InitColumns(const serializer::ISerializerContainerPtr& spContainer) const + { + IColumnsDefinition& rColumns = spContainer->GetColumnsDefinition(); + if(rColumns.IsEmpty()) + TFileFilter::InitColumns(rColumns); + } + + void FeedbackErrorRuleList::StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const + { + rConfig.DeleteNode(pszNodeName); + for(const FeedbackErrorRule& rRule : m_vEntries) + { + TConfig cfgNode; + rRule.StoreInConfig(cfgNode); + + TString strNode = TString(pszNodeName) + _T(".RuleDefinition"); + rConfig.AddSubConfig(strNode.c_str(), cfgNode); + } + } + + bool FeedbackErrorRuleList::ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName) + { + m_vEntries.clear(); + + TConfigArray vConfigs; + if(!rConfig.ExtractMultiSubConfigs(pszNodeName, vConfigs)) + return false; + + for(size_t stIndex = 0; stIndex < vConfigs.GetCount(); ++stIndex) + { + const TConfig& rCfg = vConfigs.GetAt(stIndex); + FeedbackErrorRule rule; + rule.ReadFromConfig(rCfg); + + m_vEntries.push_back(rule); + } + return true; + } +} Index: src/libchengine/FeedbackErrorRuleList.h =================================================================== diff -u --- src/libchengine/FeedbackErrorRuleList.h (revision 0) +++ src/libchengine/FeedbackErrorRuleList.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,31 @@ +#pragma once + +#include "libchengine.h" +#include "FeedbackErrorRule.h" +#include "TConfig.h" +#include "../libserializer/SerializableContainer.h" + +namespace chengine +{ +#pragma warning(push) +#pragma warning(disable: 4251) + + class LIBCHENGINE_API FeedbackErrorRuleList : public serializer::SerializableContainer + { + public: + EFeedbackResult Matches(const string::TString& strSrcPath, const string::TString& /*strDstPath*/, EFileError eErrorType, unsigned long ulError) const; + + void Merge(const FeedbackErrorRuleList& rSrc); + + void InitColumns(const serializer::ISerializerContainerPtr& spContainer) const override; + + void StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const; + bool ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName); + + private: + void InsertOrUpdateRule(const FeedbackErrorRule& rRule); + }; +#pragma warning(pop) +} + +CONFIG_MEMBER_SERIALIZATION(FeedbackErrorRuleList) Index: src/libchengine/FeedbackManager.cpp =================================================================== diff -u --- src/libchengine/FeedbackManager.cpp (revision 0) +++ src/libchengine/FeedbackManager.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,226 @@ +// ============================================================================ +// Copyright (C) 2001-2015 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. +// ============================================================================ +#include "stdafx.h" +#include "FeedbackManager.h" +#include +#include "../libserializer/ISerializerRowData.h" +#include "TScopedRunningTimeTrackerPause.h" +#include "../libchcore/TCoreException.h" +#include "../libchcore/ErrorCodes.h" + +using namespace serializer; +using namespace chcore; + +namespace chengine +{ + FeedbackManager::FeedbackManager(const IFeedbackHandlerPtr& spFeedbackHandler) : + m_spFeedbackHandler(spFeedbackHandler) + { + if(!spFeedbackHandler) + throw TCoreException(eErr_InvalidArgument, L"spFeedbackHandler", LOCATION); + } + + void FeedbackManager::SetRules(const FeedbackRules& rRules) + { + boost::unique_lock lock(m_lock); + m_feedbackRules = rRules; + } + + chengine::FeedbackRules FeedbackManager::GetRules() const + { + boost::shared_lock lock(m_lock); + chengine::FeedbackRules rules = m_feedbackRules; + return rules; + } + + chengine::TFeedbackResult FeedbackManager::FileError(const string::TString& strSrcPath, const string::TString& strDstPath, EFileError eFileError, unsigned long ulError) + { + bool bAutomatedResponse = true; + + EFeedbackResult eResult = eResult_Unknown; + + { + boost::shared_lock lock(m_lock); + eResult = m_feedbackRules.GetErrorRules().Matches(strSrcPath, strDstPath, eFileError, ulError); + } + + if(eResult == eResult_Unknown) + { + FeedbackErrorRuleList newRules; + { + TScopedRunningTimeTrackerPause scopedTimePause(m_pTimeTracker); + TScopedRunningTimeTrackerPause scopedSecondaryTimePause(m_pSecondaryTimeTracker); + eResult = m_spFeedbackHandler->FileError(strSrcPath, strDstPath, eFileError, ulError, newRules); + } + if(eResult != eResult_Unknown) + { + bAutomatedResponse = false; + if(!newRules.IsEmpty()) + { + boost::unique_lock lock(m_lock); + m_feedbackRules.GetErrorRules().Merge(newRules); + } + } + } + + return { eResult, bAutomatedResponse }; + } + + chengine::TFeedbackResult FeedbackManager::FileAlreadyExists(const TFileInfo& spSrcFileInfo, const TFileInfo& spDstFileInfo) + { + bool bAutomatedResponse = true; + EFeedbackResult eResult = eResult_Unknown; + + { + boost::shared_lock lock(m_lock); + eResult = m_feedbackRules.GetAlreadyExistsRules().Matches(spSrcFileInfo, spDstFileInfo); + } + if(eResult == eResult_Unknown) + { + FeedbackAlreadyExistsRuleList newRules; + { + TScopedRunningTimeTrackerPause scopedTimePause(m_pTimeTracker); + TScopedRunningTimeTrackerPause scopedSecondaryTimePause(m_pSecondaryTimeTracker); + eResult = m_spFeedbackHandler->FileAlreadyExists(spSrcFileInfo, spDstFileInfo, newRules); + } + if(eResult != eResult_Unknown) + { + bAutomatedResponse = false; + if(!newRules.IsEmpty()) + { + boost::unique_lock lock(m_lock); + m_feedbackRules.GetAlreadyExistsRules().Merge(newRules); + } + } + } + + return { eResult, bAutomatedResponse }; + } + + chengine::TFeedbackResult FeedbackManager::NotEnoughSpace(const string::TString& strSrcPath, const string::TString& strDstPath, unsigned long long ullRequiredSize) + { + bool bAutomatedResponse = true; + EFeedbackResult eResult = eResult_Unknown; + + { + boost::shared_lock lock(m_lock); + eResult = m_feedbackRules.GetNotEnoughSpaceRules().Matches(strSrcPath, strDstPath, ullRequiredSize); + } + if(eResult == eResult_Unknown) + { + FeedbackNotEnoughSpaceRuleList newRules; + { + TScopedRunningTimeTrackerPause scopedTimePause(m_pTimeTracker); + TScopedRunningTimeTrackerPause scopedSecondaryTimePause(m_pSecondaryTimeTracker); + eResult = m_spFeedbackHandler->NotEnoughSpace(strSrcPath, strDstPath, ullRequiredSize, newRules); + } + if(eResult != eResult_Unknown) + { + bAutomatedResponse = false; + if(!newRules.IsEmpty()) + { + boost::unique_lock lock(m_lock); + m_feedbackRules.GetNotEnoughSpaceRules().Merge(newRules); + } + } + } + + return { eResult, bAutomatedResponse }; + } + + chengine::TFeedbackResult FeedbackManager::OperationEvent(EOperationEvent eEvent) + { + bool bAutomatedResponse = true; + EFeedbackResult eResult = eResult_Unknown; + + { + boost::shared_lock lock(m_lock); + eResult = m_feedbackRules.GetOperationEventRules().Matches(eEvent); + } + if(eResult == eResult_Unknown) + { + FeedbackOperationEventRuleList newRules; + { + TScopedRunningTimeTrackerPause scopedTimePause(m_pTimeTracker); + TScopedRunningTimeTrackerPause scopedSecondaryTimePause(m_pSecondaryTimeTracker); + eResult = m_spFeedbackHandler->OperationEvent(eEvent, newRules); + } + if(eResult != eResult_Unknown) + { + bAutomatedResponse = false; + if(!newRules.IsEmpty()) + { + boost::unique_lock lock(m_lock); + m_feedbackRules.GetOperationEventRules().Merge(newRules); + } + } + } + + return { eResult, bAutomatedResponse }; + } + + void FeedbackManager::Store(const ISerializerPtr& spSerializer) const + { + boost::shared_lock lock(m_lock); + + ISerializerContainerPtr spContainer = spSerializer->GetContainer(L"feedback_error"); + m_feedbackRules.GetErrorRules().Store(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_already_exists"); + m_feedbackRules.GetAlreadyExistsRules().Store(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_not_enough_space"); + m_feedbackRules.GetNotEnoughSpaceRules().Store(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_operation_event"); + m_feedbackRules.GetOperationEventRules().Store(spContainer); + } + + void FeedbackManager::Load(const ISerializerPtr& spSerializer) + { + boost::unique_lock lock(m_lock); + + ISerializerContainerPtr spContainer = spSerializer->GetContainer(L"feedback_error"); + m_feedbackRules.GetErrorRules().Load(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_already_exists"); + m_feedbackRules.GetAlreadyExistsRules().Load(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_not_enough_space"); + m_feedbackRules.GetNotEnoughSpaceRules().Load(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_operation_event"); + m_feedbackRules.GetOperationEventRules().Load(spContainer); + } + + DWORD FeedbackManager::GetRetryInterval() const + { + return 100; + } + + void FeedbackManager::RestoreDefaults() + { + boost::unique_lock lock(m_lock); + + m_feedbackRules.GetErrorRules().Clear(); + m_feedbackRules.GetAlreadyExistsRules().Clear(); + m_feedbackRules.GetNotEnoughSpaceRules().Clear(); + m_feedbackRules.GetOperationEventRules().Clear(); + } +} Index: src/libchengine/FeedbackManager.h =================================================================== diff -u --- src/libchengine/FeedbackManager.h (revision 0) +++ src/libchengine/FeedbackManager.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,75 @@ +// ============================================================================ +// Copyright (C) 2001-2015 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. +// ============================================================================ +#ifndef __TFEEDBACKHANDLERBASE_H__ +#define __TFEEDBACKHANDLERBASE_H__ + +#include "IFeedbackHandler.h" +#include +#include "../libserializer/TSharedModificationTracker.h" +#include "../libserializer/ISerializer.h" +#include "TScopedRunningTimeTracker.h" +#include "FeedbackRules.h" + +namespace chengine +{ + class LIBCHENGINE_API FeedbackManager + { + public: + FeedbackManager(const IFeedbackHandlerPtr& spFeedbackHandler); + FeedbackManager(const FeedbackManager&) = delete; + + FeedbackManager& operator=(const FeedbackManager&) = delete; + + void SetRules(const FeedbackRules& rRules); + FeedbackRules GetRules() const; + + TFeedbackResult FileError(const string::TString& strSrcPath, const string::TString& strDstPath, EFileError eFileError, unsigned long ulError); + TFeedbackResult FileAlreadyExists(const TFileInfo& spSrcFileInfo, const TFileInfo& spDstFileInfo); + TFeedbackResult NotEnoughSpace(const string::TString& strSrcPath, const string::TString& strDstPath, unsigned long long ullRequiredSize); + TFeedbackResult OperationEvent(EOperationEvent eEvent); + + // resets the permanent status from all responses + void RestoreDefaults(); + + void SetTimeTracker(TScopedRunningTimeTracker* pTimeTracker) { m_pTimeTracker = pTimeTracker; } + void SetSecondaryTimeTracker(TScopedRunningTimeTracker* pTimeTracker) { m_pSecondaryTimeTracker = pTimeTracker; } + + // serialization + void Store(const serializer::ISerializerPtr& spSerializer) const; + void Load(const serializer::ISerializerPtr& spSerializer); + + DWORD GetRetryInterval() const; + + private: +#pragma warning(push) +#pragma warning(disable: 4251) + mutable boost::shared_mutex m_lock; + + IFeedbackHandlerPtr m_spFeedbackHandler; + TScopedRunningTimeTracker* m_pTimeTracker = nullptr; + TScopedRunningTimeTracker* m_pSecondaryTimeTracker = nullptr; +#pragma warning(pop) + + FeedbackRules m_feedbackRules; + }; + + using FeedbackManagerPtr = std::shared_ptr; +} + +#endif Index: src/libchengine/FeedbackNotEnoughSpaceRule.cpp =================================================================== diff -u --- src/libchengine/FeedbackNotEnoughSpaceRule.cpp (revision 0) +++ src/libchengine/FeedbackNotEnoughSpaceRule.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,253 @@ +#include "stdafx.h" +#include "FeedbackNotEnoughSpaceRule.h" +#include "../libstring/TString.h" +#include "../libstring/TStringArray.h" +#include "../libchcore/TPath.h" + +using namespace serializer; +using namespace string; +using namespace chcore; + +namespace chengine +{ + FeedbackNotEnoughSpaceRule::FeedbackNotEnoughSpaceRule() : + m_bUseMask(m_setModifications, false), + m_spaMask(m_setModifications), + m_bUseExcludeMask(m_setModifications, false), + m_spaExcludeMask(m_setModifications), + m_eResult(m_setModifications, eResult_Unknown) + { + m_setModifications[FeedbackNotEnoughSpaceRuleEnum::eMod_Added] = true; + } + + + FeedbackNotEnoughSpaceRule::FeedbackNotEnoughSpaceRule(const FeedbackNotEnoughSpaceRule& rSrc) : + serializer::SerializableObject(rSrc), + m_bUseMask(rSrc.m_bUseMask, m_setModifications), + m_spaMask(rSrc.m_spaMask, m_setModifications), + m_bUseExcludeMask(rSrc.m_bUseExcludeMask, m_setModifications), + m_spaExcludeMask(rSrc.m_spaExcludeMask, m_setModifications), + m_eResult(rSrc.m_eResult, m_setModifications) + { + } + + FeedbackNotEnoughSpaceRule& FeedbackNotEnoughSpaceRule::operator=(const FeedbackNotEnoughSpaceRule& rSrc) + { + if(this == &rSrc) + return *this; + + __super::operator=(rSrc); + + SetData(rSrc); + + return *this; + } + + bool FeedbackNotEnoughSpaceRule::operator==(const FeedbackNotEnoughSpaceRule& rSrc) const + { + if(m_bUseMask != rSrc.m_bUseMask) + return false; + if(m_spaMask != rSrc.m_spaMask) + return false; + + if(m_bUseExcludeMask != rSrc.m_bUseExcludeMask) + return false; + + if(m_spaExcludeMask != rSrc.m_spaExcludeMask) + return false; + + if(m_eResult != rSrc.m_eResult) + return false; + + return true; + } + + bool FeedbackNotEnoughSpaceRule::operator!=(const FeedbackNotEnoughSpaceRule& rSrc) const + { + return !operator==(rSrc); + } + + void FeedbackNotEnoughSpaceRule::SetData(const FeedbackNotEnoughSpaceRule& rSrc) + { + if(this == &rSrc) + return; + + m_bUseMask = rSrc.m_bUseMask; + m_spaMask = rSrc.m_spaMask; + m_bUseExcludeMask = rSrc.m_bUseExcludeMask; + m_spaExcludeMask = rSrc.m_spaExcludeMask; + m_eResult = rSrc.m_eResult; + } + + bool FeedbackNotEnoughSpaceRule::Matches(const string::TString& /*strSrcPath*/, const string::TString& strDstPath, unsigned long long /*ullRequiredSize*/, EFeedbackResult& eResult) const + { + eResult = eResult_Unknown; + + TSmartPath path = PathFromWString(strDstPath); + if(m_bUseMask) + { + if(!m_spaMask.Get().MatchesAny(path.GetFileName().ToString())) + return false; + } + if(m_bUseExcludeMask) + { + if(m_spaExcludeMask.Get().MatchesAny(path.GetFileName().ToString())) + return false; + } + + eResult = m_eResult; + return true; + } + + void FeedbackNotEnoughSpaceRule::InitColumns(serializer::IColumnsDefinition& rColumns) + { + rColumns.AddColumn(_T("id"), ColumnType::value); + rColumns.AddColumn(_T("use_mask"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("mask"), IColumnsDefinition::eType_string); + rColumns.AddColumn(_T("use_exclude_mask"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("exclude_mask"), IColumnsDefinition::eType_string); + rColumns.AddColumn(_T("result"), IColumnsDefinition::eType_int); + } + + void FeedbackNotEnoughSpaceRule::Store(const ISerializerContainerPtr& spContainer) const + { + bool bAdded = m_setModifications[FeedbackNotEnoughSpaceRuleEnum::eMod_Added]; + if(m_setModifications.any()) + { + ISerializerRowData& rRow = spContainer->GetRow(m_oidObjectID, bAdded); + + if(bAdded || m_setModifications[FeedbackNotEnoughSpaceRuleEnum::eMod_UseMask]) + rRow.SetValue(_T("use_mask"), m_bUseMask); + if(bAdded || m_setModifications[FeedbackNotEnoughSpaceRuleEnum::eMod_Mask]) + rRow.SetValue(_T("mask"), GetCombinedMask()); + + if(bAdded || m_setModifications[FeedbackNotEnoughSpaceRuleEnum::eMod_UseExcludeMask]) + rRow.SetValue(_T("use_exclude_mask"), m_bUseExcludeMask); + if(bAdded || m_setModifications[FeedbackNotEnoughSpaceRuleEnum::eMod_ExcludeMask]) + rRow.SetValue(_T("exclude_mask"), GetCombinedExcludeMask()); + + if(bAdded || m_setModifications[FeedbackNotEnoughSpaceRuleEnum::eMod_Result]) + rRow.SetValue(_T("result"), m_eResult); + + m_setModifications.reset(); + } + } + + void FeedbackNotEnoughSpaceRule::Load(const ISerializerRowReaderPtr& spRowReader) + { + TString strMask; + + spRowReader->GetValue(_T("use_mask"), m_bUseMask.Modify()); + spRowReader->GetValue(_T("mask"), strMask); + SetCombinedMask(strMask); + + spRowReader->GetValue(_T("use_exclude_mask"), m_bUseExcludeMask.Modify()); + spRowReader->GetValue(_T("exclude_mask"), strMask); + SetCombinedExcludeMask(strMask); + + spRowReader->GetValue(_T("result"), *(int*)&m_eResult.Modify()); + + m_setModifications.reset(); + } + + void FeedbackNotEnoughSpaceRule::StoreInConfig(TConfig& rConfig) const + { + SetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask.Get()); + SetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), m_spaMask.Get().ToSerializedStringArray()); + + SetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask.Get()); + SetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), m_spaExcludeMask.Get().ToSerializedStringArray()); + + SetConfigValue(rConfig, _T("Result"), m_eResult.Get()); + } + + void FeedbackNotEnoughSpaceRule::ReadFromConfig(const TConfig& rConfig) + { + if(!GetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask.Modify())) + m_bUseMask = false; + + TStringArray arrMask; + m_spaMask.Modify().Clear(); + GetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), arrMask); + m_spaMask.Modify().FromSerializedStringArray(arrMask); + + if(!GetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask.Modify())) + m_bUseExcludeMask = false; + + m_spaExcludeMask.Modify().Clear(); + GetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), arrMask); + m_spaExcludeMask.Modify().FromSerializedStringArray(arrMask); + + if(!GetConfigValue(rConfig, _T("Result"), *(int*)m_eResult.Modify())) + m_eResult = eResult_Unknown; + } + + bool FeedbackNotEnoughSpaceRule::HaveSameCondition(const FeedbackNotEnoughSpaceRule& rSrc) const + { + if(m_bUseMask != rSrc.m_bUseMask) + return false; + else if(m_bUseMask == true && m_spaMask != rSrc.m_spaMask) + return false; + + if(m_bUseExcludeMask != rSrc.m_bUseExcludeMask) + return false; + else if(m_bUseExcludeMask == true && m_spaExcludeMask != rSrc.m_spaExcludeMask) + return false; + + return true; + } + + void FeedbackNotEnoughSpaceRule::SetUseMask(bool bUseMask) + { + m_bUseMask = bUseMask; + } + + bool FeedbackNotEnoughSpaceRule::GetUseMask() const + { + return m_bUseMask; + } + + bool FeedbackNotEnoughSpaceRule::GetUseExcludeMask() const + { + return m_bUseExcludeMask; + } + + void FeedbackNotEnoughSpaceRule::SetUseExcludeMask(bool bUseExcludeMask) + { + m_bUseExcludeMask = bUseExcludeMask; + } + + TString FeedbackNotEnoughSpaceRule::GetCombinedMask() const + { + return m_spaMask.Get().ToString(); + } + + void FeedbackNotEnoughSpaceRule::SetCombinedMask(const TString& strMask) + { + TStringPatternArray& rPatterns = m_spaMask.Modify(); + rPatterns.Clear(); + rPatterns.FromString(strMask); + } + + TString FeedbackNotEnoughSpaceRule::GetCombinedExcludeMask() const + { + return m_spaExcludeMask.Get().ToString(); + } + + void FeedbackNotEnoughSpaceRule::SetCombinedExcludeMask(const TString& strMask) + { + TStringPatternArray& rPatterns = m_spaExcludeMask.Modify(); + rPatterns.Clear(); + rPatterns.FromString(strMask); + } + + chengine::EFeedbackResult FeedbackNotEnoughSpaceRule::GetResult() const + { + return m_eResult; + } + + void FeedbackNotEnoughSpaceRule::SetResult(EFeedbackResult eResult) + { + m_eResult = eResult; + } +} Index: src/libchengine/FeedbackNotEnoughSpaceRule.h =================================================================== diff -u --- src/libchengine/FeedbackNotEnoughSpaceRule.h (revision 0) +++ src/libchengine/FeedbackNotEnoughSpaceRule.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,88 @@ +#pragma once + +#include "libchengine.h" +#include "../libserializer/SerializableObject.h" +#include "../libstring/TStringPatternArray.h" +#include "ECompareType.h" +#include "EFeedbackResult.h" +#include "../libserializer/SerializerDataTypes.h" +#include +#include "../libserializer/TSharedModificationTracker.h" +#include "TFileInfo.h" +#include "TConfig.h" +#include "EFileError.h" + +namespace chengine +{ + namespace FeedbackNotEnoughSpaceRuleEnum + { + enum EModifications + { + eMod_Added, + eMod_UseMask, + eMod_Mask, + eMod_UseExcludeMask, + eMod_ExcludeMask, + eMod_UseErrorType, + eMod_ErrorType, + eMod_UseSystemErrorNo, + eMod_SystemErrorNo, + eMod_Result, + + eMod_Last + }; + } + +#pragma warning(push) +#pragma warning(disable: 4251) + class LIBCHENGINE_API FeedbackNotEnoughSpaceRule : public serializer::SerializableObject + { + public: + FeedbackNotEnoughSpaceRule(); + FeedbackNotEnoughSpaceRule(const FeedbackNotEnoughSpaceRule& rSrc); + FeedbackNotEnoughSpaceRule& operator=(const FeedbackNotEnoughSpaceRule& rSrc); + + bool operator==(const FeedbackNotEnoughSpaceRule& rSrc) const; + bool operator!=(const FeedbackNotEnoughSpaceRule& rSrc) const; + + void SetData(const FeedbackNotEnoughSpaceRule& rSrc); + + bool Matches(const string::TString& strSrcPath, const string::TString& strDstPath, unsigned long long ullRequiredSize, EFeedbackResult& eResult) const; + + void Store(const serializer::ISerializerContainerPtr& spContainer) const override; + void Load(const serializer::ISerializerRowReaderPtr& spRowReader) override; + static void InitColumns(serializer::IColumnsDefinition& rColumns); + + void StoreInConfig(TConfig& rConfig) const; + void ReadFromConfig(const TConfig& rConfig); + + // comparison + bool HaveSameCondition(const FeedbackNotEnoughSpaceRule& rSrc) const; + + // get/set + // atrributes access + bool GetUseMask() const; + void SetUseMask(bool bUseMask); + + string::TString GetCombinedMask() const; + void SetCombinedMask(const string::TString& strMask); + + bool GetUseExcludeMask() const; + void SetUseExcludeMask(bool bUseExcludeMask); + + string::TString GetCombinedExcludeMask() const; + void SetCombinedExcludeMask(const string::TString& strMask); + + EFeedbackResult GetResult() const; + void SetResult(EFeedbackResult eResult); + + private: + serializer::TSharedModificationTracker m_bUseMask; + serializer::TSharedModificationTracker m_spaMask; + serializer::TSharedModificationTracker m_bUseExcludeMask; + serializer::TSharedModificationTracker m_spaExcludeMask; + + serializer::TSharedModificationTracker m_eResult; + }; +#pragma warning(pop) +} Index: src/libchengine/FeedbackNotEnoughSpaceRuleList.cpp =================================================================== diff -u --- src/libchengine/FeedbackNotEnoughSpaceRuleList.cpp (revision 0) +++ src/libchengine/FeedbackNotEnoughSpaceRuleList.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,90 @@ +#include "stdafx.h" +#include "FeedbackNotEnoughSpaceRuleList.h" +#include "TConfigArray.h" +#include "../libserializer/IColumnsDefinition.h" +#include "TFileFilter.h" + +using namespace string; +using namespace serializer; + +namespace chengine +{ + EFeedbackResult FeedbackNotEnoughSpaceRuleList::Matches(const string::TString& strSrcPath, const string::TString& strDstPath, unsigned long long ullRequiredSize) const + { + if(m_vEntries.empty()) + return eResult_Unknown; + + for(const FeedbackNotEnoughSpaceRule& rRule : m_vEntries) + { + EFeedbackResult eResult = eResult_Unknown; + if(rRule.Matches(strSrcPath, strDstPath, ullRequiredSize, eResult)) + return eResult; + } + + return eResult_Unknown; + } + + void FeedbackNotEnoughSpaceRuleList::Merge(const FeedbackNotEnoughSpaceRuleList& rSrc) + { + for(size_t stIndex = 0; stIndex < rSrc.GetCount(); ++stIndex) + { + InsertOrUpdateRule(rSrc.GetAt(stIndex)); + } + } + + void FeedbackNotEnoughSpaceRuleList::InsertOrUpdateRule(const FeedbackNotEnoughSpaceRule& rRule) + { + bool bFound = false; + for(size_t stIndex = 0; stIndex < GetCount(); ++stIndex) + { + FeedbackNotEnoughSpaceRule& rCurrent = GetAt(stIndex); + if(rCurrent.HaveSameCondition(rRule)) + { + bFound = true; + rCurrent.SetResult(rRule.GetResult()); + } + } + + if(!bFound) + InsertAt(0, rRule); + } + + void FeedbackNotEnoughSpaceRuleList::InitColumns(const serializer::ISerializerContainerPtr& spContainer) const + { + IColumnsDefinition& rColumns = spContainer->GetColumnsDefinition(); + if(rColumns.IsEmpty()) + TFileFilter::InitColumns(rColumns); + } + + void FeedbackNotEnoughSpaceRuleList::StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const + { + rConfig.DeleteNode(pszNodeName); + for(const FeedbackNotEnoughSpaceRule& rRule : m_vEntries) + { + TConfig cfgNode; + rRule.StoreInConfig(cfgNode); + + TString strNode = TString(pszNodeName) + _T(".RuleDefinition"); + rConfig.AddSubConfig(strNode.c_str(), cfgNode); + } + } + + bool FeedbackNotEnoughSpaceRuleList::ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName) + { + m_vEntries.clear(); + + TConfigArray vConfigs; + if(!rConfig.ExtractMultiSubConfigs(pszNodeName, vConfigs)) + return false; + + for(size_t stIndex = 0; stIndex < vConfigs.GetCount(); ++stIndex) + { + const TConfig& rCfg = vConfigs.GetAt(stIndex); + FeedbackNotEnoughSpaceRule rule; + rule.ReadFromConfig(rCfg); + + m_vEntries.push_back(rule); + } + return true; + } +} Index: src/libchengine/FeedbackNotEnoughSpaceRuleList.h =================================================================== diff -u --- src/libchengine/FeedbackNotEnoughSpaceRuleList.h (revision 0) +++ src/libchengine/FeedbackNotEnoughSpaceRuleList.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,31 @@ +#pragma once + +#include "libchengine.h" +#include "FeedbackNotEnoughSpaceRule.h" +#include "TConfig.h" +#include "../libserializer/SerializableContainer.h" + +namespace chengine +{ +#pragma warning(push) +#pragma warning(disable: 4251) + + class LIBCHENGINE_API FeedbackNotEnoughSpaceRuleList : public serializer::SerializableContainer + { + public: + EFeedbackResult Matches(const string::TString& strSrcPath, const string::TString& strDstPath, unsigned long long ullRequiredSize) const; + + void Merge(const FeedbackNotEnoughSpaceRuleList& rSrc); + + void InitColumns(const serializer::ISerializerContainerPtr& spContainer) const override; + + void StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const; + bool ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName); + + private: + void InsertOrUpdateRule(const FeedbackNotEnoughSpaceRule& rRule); + }; +#pragma warning(pop) +} + +CONFIG_MEMBER_SERIALIZATION(FeedbackNotEnoughSpaceRuleList) Index: src/libchengine/FeedbackOperationEventRule.cpp =================================================================== diff -u --- src/libchengine/FeedbackOperationEventRule.cpp (revision 0) +++ src/libchengine/FeedbackOperationEventRule.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,180 @@ +#include "stdafx.h" +#include "FeedbackOperationEventRule.h" +#include "../libstring/TString.h" +#include "../libstring/TStringArray.h" +#include "../libchcore/TPath.h" + +using namespace serializer; +using namespace string; +using namespace chcore; + +namespace chengine +{ + FeedbackOperationEventRule::FeedbackOperationEventRule() : + m_bUseOperationEvent(m_setModifications, false), + m_eOperationEvent(m_setModifications, eOperationEvent_Finished), + m_eResult(m_setModifications, eResult_Unknown) + { + m_setModifications[FeedbackOperationEventRuleEnum::eMod_Added] = true; + } + + FeedbackOperationEventRule::FeedbackOperationEventRule(const FeedbackOperationEventRule& rSrc) : + serializer::SerializableObject(rSrc), + m_bUseOperationEvent(rSrc.m_bUseOperationEvent, m_setModifications), + m_eOperationEvent(rSrc.m_eOperationEvent, m_setModifications), + m_eResult(rSrc.m_eResult, m_setModifications) + { + } + + FeedbackOperationEventRule& FeedbackOperationEventRule::operator=(const FeedbackOperationEventRule& rSrc) + { + if(this == &rSrc) + return *this; + + __super::operator=(rSrc); + + SetData(rSrc); + + return *this; + } + + bool FeedbackOperationEventRule::operator==(const FeedbackOperationEventRule& rSrc) const + { + if(m_bUseOperationEvent != rSrc.m_bUseOperationEvent) + return false; + if(m_eOperationEvent != rSrc.m_eOperationEvent) + return false; + + if(m_eResult != rSrc.m_eResult) + return false; + + return true; + } + + bool FeedbackOperationEventRule::operator!=(const FeedbackOperationEventRule& rSrc) const + { + return !operator==(rSrc); + } + + void FeedbackOperationEventRule::SetData(const FeedbackOperationEventRule& rSrc) + { + if(this == &rSrc) + return; + + m_bUseOperationEvent = rSrc.m_bUseOperationEvent; + m_eOperationEvent = rSrc.m_eOperationEvent; + m_eResult = rSrc.m_eResult; + } + + bool FeedbackOperationEventRule::Matches(EOperationEvent eEvent, EFeedbackResult& eResult) const + { + eResult = eResult_Unknown; + + if(m_bUseOperationEvent) + { + if(m_eOperationEvent != eEvent) + return false; + } + + eResult = m_eResult; + return true; + } + + void FeedbackOperationEventRule::InitColumns(serializer::IColumnsDefinition& rColumns) + { + rColumns.AddColumn(_T("id"), ColumnType::value); + rColumns.AddColumn(_T("use_operation_event"), IColumnsDefinition::eType_bool); + rColumns.AddColumn(_T("operation_event"), IColumnsDefinition::eType_int); + rColumns.AddColumn(_T("result"), IColumnsDefinition::eType_int); + } + + void FeedbackOperationEventRule::Store(const ISerializerContainerPtr& spContainer) const + { + bool bAdded = m_setModifications[FeedbackOperationEventRuleEnum::eMod_Added]; + if(m_setModifications.any()) + { + ISerializerRowData& rRow = spContainer->GetRow(m_oidObjectID, bAdded); + + if(bAdded || m_setModifications[FeedbackOperationEventRuleEnum::eMod_UseOperationEvent]) + rRow.SetValue(_T("use_operation_event"), m_bUseOperationEvent); + if(bAdded || m_setModifications[FeedbackOperationEventRuleEnum::eMod_OperationEvent]) + rRow.SetValue(_T("operation_event"), m_eOperationEvent); + + if(bAdded || m_setModifications[FeedbackOperationEventRuleEnum::eMod_Result]) + rRow.SetValue(_T("result"), m_eResult); + + m_setModifications.reset(); + } + } + + void FeedbackOperationEventRule::Load(const ISerializerRowReaderPtr& spRowReader) + { + TString strMask; + + spRowReader->GetValue(_T("use_operation_event"), m_bUseOperationEvent.Modify()); + spRowReader->GetValue(_T("operation_event"), *(int*)&m_eOperationEvent.Modify()); + + spRowReader->GetValue(_T("result"), *(int*)&m_eResult.Modify()); + + m_setModifications.reset(); + } + + void FeedbackOperationEventRule::StoreInConfig(TConfig& rConfig) const + { + SetConfigValue(rConfig, _T("OperationEvent.Use"), m_bUseOperationEvent.Get()); + SetConfigValue(rConfig, _T("OperationEvent.Value"), m_eOperationEvent.Get()); + + SetConfigValue(rConfig, _T("Result"), m_eResult.Get()); + } + + void FeedbackOperationEventRule::ReadFromConfig(const TConfig& rConfig) + { + if(!GetConfigValue(rConfig, _T("OperationEvent.Use"), m_bUseOperationEvent.Modify())) + m_bUseOperationEvent = false; + if(!GetConfigValue(rConfig, _T("OperationEvent.Value"), *(int*)m_eOperationEvent.Modify())) + m_eOperationEvent = eOperationEvent_Finished; + + if(!GetConfigValue(rConfig, _T("Result"), *(int*)m_eResult.Modify())) + m_eResult = eResult_Unknown; + } + + bool FeedbackOperationEventRule::HaveSameCondition(const FeedbackOperationEventRule& rSrc) const + { + if(m_bUseOperationEvent != rSrc.m_bUseOperationEvent) + return false; + else if(m_bUseOperationEvent == true && m_eOperationEvent != rSrc.m_eOperationEvent) + return false; + + return true; + } + + bool FeedbackOperationEventRule::GetUseOperationEvent() const + { + return m_bUseOperationEvent; + } + + void FeedbackOperationEventRule::SetUseOperationEventType(bool bUseOperationEvent) + { + m_bUseOperationEvent = bUseOperationEvent; + } + + EOperationEvent FeedbackOperationEventRule::GetOperationEvent() const + { + return m_eOperationEvent; + } + + void FeedbackOperationEventRule::SetOperationEvent(EOperationEvent eOperationEvent) + { + m_eOperationEvent = eOperationEvent; + } + + chengine::EFeedbackResult FeedbackOperationEventRule::GetResult() const + { + return m_eResult; + } + + void FeedbackOperationEventRule::SetResult(EFeedbackResult eResult) + { + m_eResult = eResult; + } +} Index: src/libchengine/FeedbackOperationEventRule.h =================================================================== diff -u --- src/libchengine/FeedbackOperationEventRule.h (revision 0) +++ src/libchengine/FeedbackOperationEventRule.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,73 @@ +#pragma once + +#include "libchengine.h" +#include "../libserializer/SerializableObject.h" +#include "../libstring/TStringPatternArray.h" +#include "ECompareType.h" +#include "EFeedbackResult.h" +#include "../libserializer/SerializerDataTypes.h" +#include +#include "../libserializer/TSharedModificationTracker.h" +#include "TFileInfo.h" +#include "TConfig.h" +#include "EFileError.h" +#include "EOperationEvent.h" + +namespace chengine +{ + namespace FeedbackOperationEventRuleEnum + { + enum EModifications + { + eMod_Added, + eMod_UseOperationEvent, + eMod_OperationEvent, + eMod_Result, + + eMod_Last + }; + } + +#pragma warning(push) +#pragma warning(disable: 4251) + class LIBCHENGINE_API FeedbackOperationEventRule : public serializer::SerializableObject + { + public: + FeedbackOperationEventRule(); + FeedbackOperationEventRule(const FeedbackOperationEventRule& rSrc); + FeedbackOperationEventRule& operator=(const FeedbackOperationEventRule& rSrc); + + bool operator==(const FeedbackOperationEventRule& rSrc) const; + bool operator!=(const FeedbackOperationEventRule& rSrc) const; + + void SetData(const FeedbackOperationEventRule& rSrc); + + bool Matches(EOperationEvent eEvent, EFeedbackResult& eResult) const; + + void Store(const serializer::ISerializerContainerPtr& spContainer) const override; + void Load(const serializer::ISerializerRowReaderPtr& spRowReader) override; + static void InitColumns(serializer::IColumnsDefinition& rColumns); + + void StoreInConfig(TConfig& rConfig) const; + void ReadFromConfig(const TConfig& rConfig); + + // comparison + bool HaveSameCondition(const FeedbackOperationEventRule& rSrc) const; + + // attributes + bool GetUseOperationEvent() const; + void SetUseOperationEventType(bool bUseErrorType); + EOperationEvent GetOperationEvent() const; + void SetOperationEvent(EOperationEvent eErrorType); + + EFeedbackResult GetResult() const; + void SetResult(EFeedbackResult eResult); + + private: + serializer::TSharedModificationTracker m_bUseOperationEvent; + serializer::TSharedModificationTracker m_eOperationEvent; + + serializer::TSharedModificationTracker m_eResult; + }; +#pragma warning(pop) +} Index: src/libchengine/FeedbackOperationEventRuleList.cpp =================================================================== diff -u --- src/libchengine/FeedbackOperationEventRuleList.cpp (revision 0) +++ src/libchengine/FeedbackOperationEventRuleList.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,90 @@ +#include "stdafx.h" +#include "FeedbackOperationEventRuleList.h" +#include "TConfigArray.h" +#include "../libserializer/IColumnsDefinition.h" +#include "TFileFilter.h" + +using namespace string; +using namespace serializer; + +namespace chengine +{ + EFeedbackResult FeedbackOperationEventRuleList::Matches(EOperationEvent eEvent) const + { + if(m_vEntries.empty()) + return eResult_Unknown; + + for(const FeedbackOperationEventRule& rRule : m_vEntries) + { + EFeedbackResult eResult = eResult_Unknown; + if(rRule.Matches(eEvent, eResult)) + return eResult; + } + + return eResult_Unknown; + } + + void FeedbackOperationEventRuleList::Merge(const FeedbackOperationEventRuleList& rSrc) + { + for(size_t stIndex = 0; stIndex < rSrc.GetCount(); ++stIndex) + { + InsertOrUpdateRule(rSrc.GetAt(stIndex)); + } + } + + void FeedbackOperationEventRuleList::InsertOrUpdateRule(const FeedbackOperationEventRule& rRule) + { + bool bFound = false; + for(size_t stIndex = 0; stIndex < GetCount(); ++stIndex) + { + FeedbackOperationEventRule& rCurrent = GetAt(stIndex); + if(rCurrent.HaveSameCondition(rRule)) + { + bFound = true; + rCurrent.SetResult(rRule.GetResult()); + } + } + + if(!bFound) + InsertAt(0, rRule); + } + + void FeedbackOperationEventRuleList::InitColumns(const serializer::ISerializerContainerPtr& spContainer) const + { + IColumnsDefinition& rColumns = spContainer->GetColumnsDefinition(); + if(rColumns.IsEmpty()) + TFileFilter::InitColumns(rColumns); + } + + void FeedbackOperationEventRuleList::StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const + { + rConfig.DeleteNode(pszNodeName); + for(const FeedbackOperationEventRule& rRule : m_vEntries) + { + TConfig cfgNode; + rRule.StoreInConfig(cfgNode); + + TString strNode = TString(pszNodeName) + _T(".RuleDefinition"); + rConfig.AddSubConfig(strNode.c_str(), cfgNode); + } + } + + bool FeedbackOperationEventRuleList::ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName) + { + m_vEntries.clear(); + + TConfigArray vConfigs; + if(!rConfig.ExtractMultiSubConfigs(pszNodeName, vConfigs)) + return false; + + for(size_t stIndex = 0; stIndex < vConfigs.GetCount(); ++stIndex) + { + const TConfig& rCfg = vConfigs.GetAt(stIndex); + FeedbackOperationEventRule rule; + rule.ReadFromConfig(rCfg); + + m_vEntries.push_back(rule); + } + return true; + } +} Index: src/libchengine/FeedbackOperationEventRuleList.h =================================================================== diff -u --- src/libchengine/FeedbackOperationEventRuleList.h (revision 0) +++ src/libchengine/FeedbackOperationEventRuleList.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,31 @@ +#pragma once + +#include "libchengine.h" +#include "FeedbackOperationEventRule.h" +#include "TConfig.h" +#include "../libserializer/SerializableContainer.h" + +namespace chengine +{ +#pragma warning(push) +#pragma warning(disable: 4251) + + class LIBCHENGINE_API FeedbackOperationEventRuleList : public serializer::SerializableContainer + { + public: + EFeedbackResult Matches(EOperationEvent eEvent) const; + + void Merge(const FeedbackOperationEventRuleList& rSrc); + + void InitColumns(const serializer::ISerializerContainerPtr& spContainer) const override; + + void StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const; + bool ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName); + + private: + void InsertOrUpdateRule(const FeedbackOperationEventRule& rRule); + }; +#pragma warning(pop) +} + +CONFIG_MEMBER_SERIALIZATION(FeedbackOperationEventRuleList) Index: src/libchengine/FeedbackPredefinedRules.cpp =================================================================== diff -u --- src/libchengine/FeedbackPredefinedRules.cpp (revision 0) +++ src/libchengine/FeedbackPredefinedRules.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,89 @@ +#include "stdafx.h" +#include "FeedbackPredefinedRules.h" +#include "FeedbackAlreadyExistsRuleList.h" + +namespace chengine +{ + FeedbackAlreadyExistsRuleList FeedbackPredefinedRules::CreateAlreadyExistsRule(EPredefinedRuleCondition eCondition, EFeedbackResult eResult) + { + FeedbackAlreadyExistsRuleList ruleList; + + switch(eCondition) + { + case EPredefinedRuleCondition::eCondition_ApplyToAll: + { + FeedbackAlreadyExistsRule rule; + rule.SetResult(eResult); + ruleList.Add(rule); + break; + } + case EPredefinedRuleCondition::eCondition_WhenDifferentDateOrSize: + { + FeedbackAlreadyExistsRule rule; + rule.SetResult(eResult); + rule.SetUseDateCompare(true); + rule.SetDateCompareType(eCmp_NotEqual); + ruleList.Add(rule); + + FeedbackAlreadyExistsRule rule2; + rule2.SetResult(eResult); + rule2.SetUseSizeCompare(true); + rule2.SetSizeCompareType(eCmp_NotEqual); + ruleList.Add(rule2); + + break; + } + case EPredefinedRuleCondition::eCondition_WhenSameDateAndSize: + { + FeedbackAlreadyExistsRule rule; + rule.SetResult(eResult); + rule.SetUseDateCompare(true); + rule.SetDateCompareType(eCmp_Equal); + rule.SetUseSizeCompare(true); + rule.SetSizeCompareType(eCmp_Equal); + ruleList.Add(rule); + break; + } + case EPredefinedRuleCondition::eCondition_WhenNewerThanDst: + { + FeedbackAlreadyExistsRule rule; + rule.SetResult(eResult); + rule.SetUseDateCompare(true); + rule.SetDateCompareType(eCmp_Greater); + ruleList.Add(rule); + break; + } + case EPredefinedRuleCondition::eCondition_WhenOlderThanDst: + { + FeedbackAlreadyExistsRule rule; + rule.SetResult(eResult); + rule.SetUseDateCompare(true); + rule.SetDateCompareType(eCmp_Less); + ruleList.Add(rule); + break; + } + case EPredefinedRuleCondition::eCondition_WhenSmallerThanDst: + { + FeedbackAlreadyExistsRule rule; + rule.SetResult(eResult); + rule.SetUseSizeCompare(true); + rule.SetSizeCompareType(eCmp_Less); + ruleList.Add(rule); + break; + } + case EPredefinedRuleCondition::eCondition_WhenBiggerThanDst: + { + FeedbackAlreadyExistsRule rule; + rule.SetResult(eResult); + rule.SetUseSizeCompare(true); + rule.SetSizeCompareType(eCmp_Greater); + ruleList.Add(rule); + break; + } + default: + throw std::runtime_error("Unhandled predefined rule condition"); + } + + return ruleList; + } +} Index: src/libchengine/FeedbackPredefinedRules.h =================================================================== diff -u --- src/libchengine/FeedbackPredefinedRules.h (revision 0) +++ src/libchengine/FeedbackPredefinedRules.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,28 @@ +#pragma once + +#include "libchengine.h" +#include "EFeedbackResult.h" +#include "FeedbackAlreadyExistsRuleList.h" + +namespace chengine +{ + enum class EPredefinedRuleCondition + { + eCondition_ApplyToAll, + + eCondition_WhenDifferentDateOrSize, + eCondition_WhenSameDateAndSize, + + eCondition_WhenNewerThanDst, + eCondition_WhenOlderThanDst, + + eCondition_WhenSmallerThanDst, + eCondition_WhenBiggerThanDst + }; + + class LIBCHENGINE_API FeedbackPredefinedRules + { + public: + static FeedbackAlreadyExistsRuleList CreateAlreadyExistsRule(EPredefinedRuleCondition eCondition, EFeedbackResult eResult); + }; +} Fisheye: Tag 08717141ce5f6926116c298cbc9442094a45bb67 refers to a dead (removed) revision in file `src/libchengine/FeedbackRuleList.cpp'. Fisheye: No comparison available. Pass `N' to diff? Index: src/libchengine/FeedbackRules.cpp =================================================================== diff -u --- src/libchengine/FeedbackRules.cpp (revision 0) +++ src/libchengine/FeedbackRules.cpp (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,119 @@ +#include "stdafx.h" +#include "FeedbackRules.h" +#include "../libserializer/ISerializerContainer.h" + +using namespace serializer; + +void chengine::FeedbackRules::Store(const serializer::ISerializerPtr& spSerializer) const +{ + ISerializerContainerPtr spContainer = spSerializer->GetContainer(L"feedback_error"); + m_feedbackErrorRules.Store(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_already_exists"); + m_feedbackAlreadyExistsRules.Store(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_not_enough_space"); + m_feedbackNotEnoughSpaceRules.Store(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_operation_event"); + m_feedbackOperationEventRules.Store(spContainer); +} + +void chengine::FeedbackRules::Load(const serializer::ISerializerPtr& spSerializer) +{ + ISerializerContainerPtr spContainer = spSerializer->GetContainer(L"feedback_error"); + m_feedbackErrorRules.Load(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_already_exists"); + m_feedbackAlreadyExistsRules.Load(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_not_enough_space"); + m_feedbackNotEnoughSpaceRules.Load(spContainer); + + spContainer = spSerializer->GetContainer(L"feedback_operation_event"); + m_feedbackOperationEventRules.Load(spContainer); +} + +void chengine::FeedbackRules::StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const +{ + std::wstring strNode = pszNodeName; + std::wstring strNewNode = strNode + L".AlreadyExists"; + m_feedbackAlreadyExistsRules.StoreInConfig(rConfig, strNewNode.c_str()); + + strNewNode = strNewNode + L".Error"; + m_feedbackErrorRules.StoreInConfig(rConfig, strNewNode.c_str()); + + strNewNode = strNewNode + L".NotEnoughSpace"; + m_feedbackNotEnoughSpaceRules.StoreInConfig(rConfig, strNewNode.c_str()); + + strNewNode = strNewNode + L".OperationEvent"; + m_feedbackOperationEventRules.StoreInConfig(rConfig, strNewNode.c_str()); +} + +bool chengine::FeedbackRules::ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName) +{ + bool bResult = true; + + std::wstring strNode = pszNodeName; + std::wstring strNewNode = strNode + L".AlreadyExists"; + bResult &= m_feedbackAlreadyExistsRules.ReadFromConfig(rConfig, strNewNode.c_str()); + + strNewNode = strNewNode + L".Error"; + bResult &= m_feedbackErrorRules.ReadFromConfig(rConfig, strNewNode.c_str()); + + strNewNode = strNewNode + L".NotEnoughSpace"; + bResult &= m_feedbackNotEnoughSpaceRules.ReadFromConfig(rConfig, strNewNode.c_str()); + + strNewNode = strNewNode + L".OperationEvent"; + bResult &= m_feedbackOperationEventRules.ReadFromConfig(rConfig, strNewNode.c_str()); + + return bResult; +} + +void chengine::FeedbackRules::Clear() +{ + m_feedbackAlreadyExistsRules.Clear(); + m_feedbackErrorRules.Clear(); + m_feedbackNotEnoughSpaceRules.Clear(); + m_feedbackOperationEventRules.Clear(); +} + +const chengine::FeedbackAlreadyExistsRuleList& chengine::FeedbackRules::GetAlreadyExistsRules() const +{ + return m_feedbackAlreadyExistsRules; +} + +const chengine::FeedbackErrorRuleList& chengine::FeedbackRules::GetErrorRules() const +{ + return m_feedbackErrorRules; +} + +const chengine::FeedbackNotEnoughSpaceRuleList& chengine::FeedbackRules::GetNotEnoughSpaceRules() const +{ + return m_feedbackNotEnoughSpaceRules; +} + +const chengine::FeedbackOperationEventRuleList& chengine::FeedbackRules::GetOperationEventRules() const +{ + return m_feedbackOperationEventRules; +} + +chengine::FeedbackOperationEventRuleList& chengine::FeedbackRules::GetOperationEventRules() +{ + return m_feedbackOperationEventRules; +} + +chengine::FeedbackNotEnoughSpaceRuleList& chengine::FeedbackRules::GetNotEnoughSpaceRules() +{ + return m_feedbackNotEnoughSpaceRules; +} + +chengine::FeedbackErrorRuleList& chengine::FeedbackRules::GetErrorRules() +{ + return m_feedbackErrorRules; +} + +chengine::FeedbackAlreadyExistsRuleList& chengine::FeedbackRules::GetAlreadyExistsRules() +{ + return m_feedbackAlreadyExistsRules; +} Index: src/libchengine/FeedbackRules.h =================================================================== diff -u --- src/libchengine/FeedbackRules.h (revision 0) +++ src/libchengine/FeedbackRules.h (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -0,0 +1,45 @@ +#pragma once + +#include "libchengine.h" +#include "FeedbackAlreadyExistsRuleList.h" +#include "FeedbackErrorRuleList.h" +#include "FeedbackNotEnoughSpaceRuleList.h" +#include "FeedbackOperationEventRuleList.h" +#include "../libserializer/ISerializer.h" +#include "TConfig.h" + +namespace chengine +{ + class LIBCHENGINE_API FeedbackRules + { + public: + // serialization + void Store(const serializer::ISerializerPtr& spSerializer) const; + void Load(const serializer::ISerializerPtr& spSerializer); + + void StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const; + bool ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName); + + void Clear(); + + const FeedbackAlreadyExistsRuleList& GetAlreadyExistsRules() const; + FeedbackAlreadyExistsRuleList& GetAlreadyExistsRules(); + + const FeedbackErrorRuleList& GetErrorRules() const; + FeedbackErrorRuleList& GetErrorRules(); + + const FeedbackNotEnoughSpaceRuleList& GetNotEnoughSpaceRules() const; + FeedbackNotEnoughSpaceRuleList& GetNotEnoughSpaceRules(); + + const FeedbackOperationEventRuleList& GetOperationEventRules() const; + FeedbackOperationEventRuleList& GetOperationEventRules(); + + private: + FeedbackAlreadyExistsRuleList m_feedbackAlreadyExistsRules; + FeedbackErrorRuleList m_feedbackErrorRules; + FeedbackNotEnoughSpaceRuleList m_feedbackNotEnoughSpaceRules; + FeedbackOperationEventRuleList m_feedbackOperationEventRules; + }; +} + +CONFIG_MEMBER_SERIALIZATION(FeedbackRules) Index: src/libchengine/IFeedbackHandler.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/IFeedbackHandler.h (.../IFeedbackHandler.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/IFeedbackHandler.h (.../IFeedbackHandler.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -23,6 +23,11 @@ #include "TFeedbackResult.h" #include "../libstring/TString.h" #include "../libserializer/ISerializerContainer.h" +#include "EOperationEvent.h" +#include "FeedbackErrorRuleList.h" +#include "FeedbackAlreadyExistsRuleList.h" +#include "FeedbackNotEnoughSpaceRuleList.h" +#include "FeedbackOperationEventRuleList.h" namespace chengine { @@ -33,24 +38,10 @@ public: virtual ~IFeedbackHandler(); - // requests with some processing data - virtual TFeedbackResult FileError(const string::TString& strSrcPath, const string::TString& strDstPath, EFileError eFileError, unsigned long ulError) = 0; - virtual TFeedbackResult FileAlreadyExists(const TFileInfo& spSrcFileInfo, const TFileInfo& spDstFileInfo) = 0; - virtual TFeedbackResult NotEnoughSpace(const string::TString& strSrcPath, const string::TString& strDstPath, unsigned long long ullRequiredSize) = 0; - - // no-data requests - virtual TFeedbackResult OperationFinished() = 0; - virtual TFeedbackResult OperationError() = 0; - - // retry interval (in ms) - virtual DWORD GetRetryInterval() const = 0; - - // reset permanent states - virtual void RestoreDefaults() = 0; - - //serialization - virtual void Store(const serializer::ISerializerContainerPtr& spContainer) const = 0; - virtual void Load(const serializer::ISerializerContainerPtr& spContainer) = 0; + virtual EFeedbackResult FileError(const string::TString& strSrcPath, const string::TString& strDstPath, EFileError eFileError, unsigned long ulError, FeedbackErrorRuleList& rNewRules) = 0; + virtual EFeedbackResult FileAlreadyExists(const TFileInfo& spSrcFileInfo, const TFileInfo& spDstFileInfo, FeedbackAlreadyExistsRuleList& rNewRules) = 0; + virtual EFeedbackResult NotEnoughSpace(const string::TString& strSrcPath, const string::TString& strDstPath, unsigned long long ullRequiredSize, FeedbackNotEnoughSpaceRuleList& rNewRules) = 0; + virtual EFeedbackResult OperationEvent(EOperationEvent eEvent, FeedbackOperationEventRuleList& rNewRules) = 0; }; typedef std::shared_ptr IFeedbackHandlerPtr; Fisheye: Tag 08717141ce5f6926116c298cbc9442094a45bb67 refers to a dead (removed) revision in file `src/libchengine/TFeedbackHandlerBase.cpp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 08717141ce5f6926116c298cbc9442094a45bb67 refers to a dead (removed) revision in file `src/libchengine/TFeedbackHandlerBase.h'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 08717141ce5f6926116c298cbc9442094a45bb67 refers to a dead (removed) revision in file `src/libchengine/TFeedbackHandlerWrapper.cpp'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 08717141ce5f6926116c298cbc9442094a45bb67 refers to a dead (removed) revision in file `src/libchengine/TFeedbackHandlerWrapper.h'. Fisheye: No comparison available. Pass `N' to diff? Index: src/libchengine/TFilesystemFeedbackWrapper.cpp =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TFilesystemFeedbackWrapper.cpp (.../TFilesystemFeedbackWrapper.cpp) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TFilesystemFeedbackWrapper.cpp (.../TFilesystemFeedbackWrapper.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -28,8 +28,8 @@ namespace chengine { - TFilesystemFeedbackWrapper::TFilesystemFeedbackWrapper(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemPtr& spFilesystem, const logger::TLogFileDataPtr& spLogFileData, TWorkerThreadController& rThreadController) : - m_spFeedbackHandler(spFeedbackHandler), + TFilesystemFeedbackWrapper::TFilesystemFeedbackWrapper(const FeedbackManagerPtr& spFeedbackManager, const IFilesystemPtr& spFilesystem, const logger::TLogFileDataPtr& spLogFileData, TWorkerThreadController& rThreadController) : + m_spFeedbackManager(spFeedbackManager), m_spFilesystem(spFilesystem), m_spLog(logger::MakeLogger(spLogFileData, L"Filesystem")), m_rThreadController(rThreadController) @@ -64,7 +64,7 @@ strFormat.Replace(_T("%path"), pathDirectory.ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(pathDirectory.ToWString(), TString(), EFileError::eCreateError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(pathDirectory.ToWString(), TString(), EFileError::eCreateError, dwLastError); switch (frResult.GetResult()) { case eResult_Cancel: @@ -95,7 +95,7 @@ bool TFilesystemFeedbackWrapper::WasKillRequested(const TFeedbackResult& rFeedbackResult) const { - if(m_rThreadController.KillRequested(rFeedbackResult.IsAutomatedReply() ? m_spFeedbackHandler->GetRetryInterval() : 0)) + if(m_rThreadController.KillRequested(rFeedbackResult.IsAutomatedReply() ? m_spFeedbackManager->GetRetryInterval() : 0)) return true; return false; } @@ -133,7 +133,7 @@ strFormat.Replace(_T("%path"), pathDestination.ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - frResult = m_spFeedbackHandler->FileError(pathDestination.ToWString(), TString(), EFileError::eCheckForFreeSpace, dwLastError); + frResult = m_spFeedbackManager->FileError(pathDestination.ToWString(), TString(), EFileError::eCheckForFreeSpace, dwLastError); switch (frResult.GetResult()) { case eResult_Cancel: @@ -162,7 +162,7 @@ strFormat.Replace(_T("%availablesize"), boost::lexical_cast(ullAvailableSize).c_str()); LOG_WARNING(m_spLog) << strFormat.c_str(); - frResult = m_spFeedbackHandler->NotEnoughSpace(pathFirstSrc.ToWString(), pathDestination.ToWString(), ullNeededSize); + frResult = m_spFeedbackManager->NotEnoughSpace(pathFirstSrc.ToWString(), pathDestination.ToWString(), ullNeededSize); switch (frResult.GetResult()) { case eResult_Cancel: @@ -222,7 +222,7 @@ strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); switch (frResult.GetResult()) { case eResult_Cancel: @@ -281,7 +281,7 @@ strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); switch (frResult.GetResult()) { case eResult_Cancel: @@ -343,7 +343,7 @@ strFormat.Replace(_T("%dstpath"), pathDestination.ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(pathSrc.ToWString(), pathDestination.ToWString(), EFileError::eFastMoveError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(pathSrc.ToWString(), pathDestination.ToWString(), EFileError::eFastMoveError, dwLastError); switch (frResult.GetResult()) { case eResult_Cancel: @@ -389,7 +389,7 @@ dwLastError = e.GetNativeError(); } - TFeedbackResult frResult = m_spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), EFileError::eRetrieveFileInfo, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(pathCurrent.ToWString(), TString(), EFileError::eRetrieveFileInfo, dwLastError); switch (frResult.GetResult()) { case eResult_Cancel: @@ -436,7 +436,7 @@ dwLastError = e.GetNativeError(); } - TFeedbackResult frResult = m_spFeedbackHandler->FileError(pathFileDir.ToWString(), TString(), EFileError::eRetrieveFileInfo, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(pathFileDir.ToWString(), TString(), EFileError::eRetrieveFileInfo, dwLastError); switch(frResult.GetResult()) { case eResult_Cancel: Index: src/libchengine/TFilesystemFeedbackWrapper.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TFilesystemFeedbackWrapper.h (.../TFilesystemFeedbackWrapper.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TFilesystemFeedbackWrapper.h (.../TFilesystemFeedbackWrapper.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -22,6 +22,7 @@ #include "IFilesystem.h" #include "TSubTaskBase.h" #include "../liblogger/TLogger.h" +#include "FeedbackManager.h" namespace chcore { class TWorkerThreadController; @@ -32,7 +33,7 @@ class TFilesystemFeedbackWrapper { public: - TFilesystemFeedbackWrapper(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemPtr& spFilesystem, + TFilesystemFeedbackWrapper(const FeedbackManagerPtr& spFeedbackManager, const IFilesystemPtr& spFilesystem, const logger::TLogFileDataPtr& spLogFileData, chcore::TWorkerThreadController& rThreadController); TFilesystemFeedbackWrapper& operator=(const TFilesystemFeedbackWrapper&) = delete; @@ -56,7 +57,7 @@ bool WasKillRequested(const TFeedbackResult& rFeedbackResult) const; private: - IFeedbackHandlerPtr m_spFeedbackHandler; + FeedbackManagerPtr m_spFeedbackManager; IFilesystemPtr m_spFilesystem; logger::TLoggerPtr m_spLog; chcore::TWorkerThreadController& m_rThreadController; Index: src/libchengine/TFilesystemFileFeedbackWrapper.cpp =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TFilesystemFileFeedbackWrapper.cpp (.../TFilesystemFileFeedbackWrapper.cpp) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TFilesystemFileFeedbackWrapper.cpp (.../TFilesystemFileFeedbackWrapper.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -30,15 +30,15 @@ namespace chengine { TFilesystemFileFeedbackWrapper::TFilesystemFileFeedbackWrapper(const IFilesystemFilePtr& spFile, - const IFeedbackHandlerPtr& spFeedbackHandler, const logger::TLogFileDataPtr& spLogFileData, + const FeedbackManagerPtr& spFeedbackManager, const logger::TLogFileDataPtr& spLogFileData, TWorkerThreadController& rThreadController, const IFilesystemPtr& spFilesystem) : m_spFile(spFile), - m_spFeedbackHandler(spFeedbackHandler), + m_spFeedbackManager(spFeedbackManager), m_spFilesystem(spFilesystem), m_spLog(std::make_unique(spLogFileData, L"Filesystem-File")), m_rThreadController(rThreadController) { - if (!spFeedbackHandler) + if (!spFeedbackManager) throw TCoreException(eErr_InvalidArgument, L"spFeedbackHandler is NULL", LOCATION); if (!spFile) throw TCoreException(eErr_InvalidArgument, L"spFile is NULL", LOCATION); @@ -55,7 +55,7 @@ m_spFile->GetFileInfo(tDstFileInfo); // src and dst files are the same - TFeedbackResult frResult = m_spFeedbackHandler->FileAlreadyExists(*spSrcFileInfo, tDstFileInfo); + TFeedbackResult frResult = m_spFeedbackManager->FileAlreadyExists(*spSrcFileInfo, tDstFileInfo); switch(frResult.GetResult()) { case eResult_Overwrite: @@ -109,7 +109,7 @@ strFormat.Replace(_T("%path"), m_spFile->GetFilePath().ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eResizeError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eResizeError, dwLastError); switch (frResult.GetResult()) { case eResult_Cancel: @@ -161,7 +161,7 @@ strFormat.Replace(_T("%path"), m_spFile->GetFilePath().ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eReadError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eReadError, dwLastError); switch (frResult.GetResult()) { case eResult_Cancel: @@ -213,7 +213,7 @@ strFormat.Replace(_T("%path"), m_spFile->GetFilePath().ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eWriteError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eWriteError, dwLastError); switch (frResult.GetResult()) { case eResult_Cancel: @@ -264,7 +264,7 @@ strFormat.Replace(_T("%path"), m_spFile->GetFilePath().ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eFinalizeError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eFinalizeError, dwLastError); switch (frResult.GetResult()) { case eResult_Cancel: @@ -323,7 +323,7 @@ strFormat.Replace(_T("%path"), m_spFile->GetFilePath().ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eReadError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eReadError, dwLastError); switch(frResult.GetResult()) { case eResult_Cancel: @@ -355,7 +355,7 @@ strFormat.Replace(_T("%path"), m_spFile->GetFilePath().ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eWriteError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eWriteError, dwLastError); switch(frResult.GetResult()) { case eResult_Cancel: @@ -398,7 +398,7 @@ strFormat.Replace(_T("%path"), m_spFile->GetFilePath().ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError); switch(frResult.GetResult()) { case eResult_Cancel: @@ -457,7 +457,7 @@ if(bSilent) return TSubTaskBase::eSubResult_Error; - TFeedbackResult frResult = m_spFeedbackHandler->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eRetrieveFileInfo, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eRetrieveFileInfo, dwLastError); switch(frResult.GetResult()) { case eResult_Cancel: @@ -513,7 +513,7 @@ strFormat.Replace(_T("%path"), m_spFile->GetFilePath().ToString()); LOG_ERROR(m_spLog) << strFormat.c_str(); - TFeedbackResult frResult = m_spFeedbackHandler->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eRetrieveFileInfo, dwLastError); + TFeedbackResult frResult = m_spFeedbackManager->FileError(m_spFile->GetFilePath().ToWString(), TString(), EFileError::eRetrieveFileInfo, dwLastError); switch(frResult.GetResult()) { case eResult_Cancel: @@ -544,7 +544,7 @@ bool TFilesystemFileFeedbackWrapper::WasKillRequested(const TFeedbackResult& rFeedbackResult) const { - if(m_rThreadController.KillRequested(rFeedbackResult.IsAutomatedReply() ? m_spFeedbackHandler->GetRetryInterval() : 0)) + if(m_rThreadController.KillRequested(rFeedbackResult.IsAutomatedReply() ? m_spFeedbackManager->GetRetryInterval() : 0)) return true; return false; } Index: src/libchengine/TFilesystemFileFeedbackWrapper.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TFilesystemFileFeedbackWrapper.h (.../TFilesystemFileFeedbackWrapper.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TFilesystemFileFeedbackWrapper.h (.../TFilesystemFileFeedbackWrapper.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -21,9 +21,9 @@ #include "IFilesystemFile.h" #include "TSubTaskBase.h" -#include "IFeedbackHandler.h" #include "IFilesystem.h" #include "../liblogger/TLogger.h" +#include "FeedbackManager.h" namespace chcore { @@ -35,7 +35,7 @@ class TFilesystemFileFeedbackWrapper { public: - TFilesystemFileFeedbackWrapper(const IFilesystemFilePtr& spFile, const IFeedbackHandlerPtr& spFeedbackHandler, + TFilesystemFileFeedbackWrapper(const IFilesystemFilePtr& spFile, const FeedbackManagerPtr& spFeedbackManager, const logger::TLogFileDataPtr& spLogFileData, chcore::TWorkerThreadController& rThreadController, const IFilesystemPtr& spFilesystem); TFilesystemFileFeedbackWrapper& operator=(const TFilesystemFileFeedbackWrapper&) = delete; @@ -70,7 +70,7 @@ private: IFilesystemFilePtr m_spFile; - IFeedbackHandlerPtr m_spFeedbackHandler; + FeedbackManagerPtr m_spFeedbackManager; IFilesystemPtr m_spFilesystem; logger::TLoggerPtr m_spLog; chcore::TWorkerThreadController& m_rThreadController; Index: src/libchengine/TOverlappedReaderFB.cpp =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TOverlappedReaderFB.cpp (.../TOverlappedReaderFB.cpp) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TOverlappedReaderFB.cpp (.../TOverlappedReaderFB.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -27,7 +27,7 @@ namespace chengine { TOverlappedReaderFB::TOverlappedReaderFB(const IFilesystemPtr& spFilesystem, - const IFeedbackHandlerPtr& spFeedbackHandler, + const FeedbackManagerPtr& spFeedbackManager, TWorkerThreadController& rThreadController, const TSubTaskStatsInfoPtr& spStats, const TFileInfoPtr& spSrcFileInfo, @@ -50,7 +50,7 @@ m_rThreadController(rThreadController), m_spLog(logger::MakeLogger(spLogFileData, L"File-Reader")) { - if(!spFeedbackHandler) + if(!spFeedbackManager) throw TCoreException(eErr_InvalidArgument, L"spFeedbackHandler is NULL", LOCATION); if(!spFilesystem) throw TCoreException(eErr_InvalidArgument, L"spFilesystem is NULL", LOCATION); @@ -66,7 +66,7 @@ throw TCoreException(eErr_InvalidArgument, L"spDataRange is NULL", LOCATION); IFilesystemFilePtr fileSrc = m_spFilesystem->CreateFileObject(IFilesystemFile::eMode_Read, m_spSrcFileInfo->GetFullFilePath(), bNoBuffering, bProtectReadOnlyFiles); - m_spSrcFile = std::make_shared(fileSrc, spFeedbackHandler, spLogFileData, rThreadController, spFilesystem); + m_spSrcFile = std::make_shared(fileSrc, spFeedbackManager, spLogFileData, rThreadController, spFilesystem); } TOverlappedReaderFB::~TOverlappedReaderFB() Index: src/libchengine/TOverlappedReaderFB.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TOverlappedReaderFB.h (.../TOverlappedReaderFB.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TOverlappedReaderFB.h (.../TOverlappedReaderFB.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -32,7 +32,7 @@ { public: TOverlappedReaderFB(const IFilesystemPtr& spFilesystem, - const IFeedbackHandlerPtr& spFeedbackHandler, + const FeedbackManagerPtr& spFeedbackManager, chcore::TWorkerThreadController& rThreadController, const TSubTaskStatsInfoPtr& spStats, const TFileInfoPtr& spSrcFileInfo, Index: src/libchengine/TOverlappedReaderWriterFB.cpp =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TOverlappedReaderWriterFB.cpp (.../TOverlappedReaderWriterFB.cpp) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TOverlappedReaderWriterFB.cpp (.../TOverlappedReaderWriterFB.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -24,7 +24,7 @@ namespace chengine { TOverlappedReaderWriterFB::TOverlappedReaderWriterFB(const IFilesystemPtr& spFilesystem, - const IFeedbackHandlerPtr& spFeedbackHandler, + const FeedbackManagerPtr& spFeedbackManager, TWorkerThreadController& rThreadController, TOverlappedThreadPool& rThreadPool, const TFileInfoPtr& spSrcFileInfo, @@ -47,8 +47,8 @@ m_rThreadController(rThreadController), m_spRange(std::make_shared(ullResumePosition)), m_spMemoryPool(spMemoryPool), - m_spReader(std::make_shared(spFilesystem, spFeedbackHandler, rThreadController, spStats, spSrcFileInfo, spLogFileData, spMemoryPool ? spMemoryPool->GetBufferList() : TBufferListPtr(), m_spRange, dwChunkSize, uiMaxConcurrentReads, uiMaxReadAhead, bNoBuffering, bProtectReadOnlyFiles)), - m_spWriter(std::make_shared(spFilesystem, spFeedbackHandler, rThreadController, spStats, spSrcFileInfo, pathDst, spLogFileData, m_spReader->GetFinishedQueue(), m_spRange, spMemoryPool ? spMemoryPool->GetBufferList() : TBufferListPtr(), uiMaxConcurrentWrites, bOnlyCreate, bNoBuffering, bProtectReadOnlyFiles, bUpdateFileAttributesAndTimes)) + m_spReader(std::make_shared(spFilesystem, spFeedbackManager, rThreadController, spStats, spSrcFileInfo, spLogFileData, spMemoryPool ? spMemoryPool->GetBufferList() : TBufferListPtr(), m_spRange, dwChunkSize, uiMaxConcurrentReads, uiMaxReadAhead, bNoBuffering, bProtectReadOnlyFiles)), + m_spWriter(std::make_shared(spFilesystem, spFeedbackManager, rThreadController, spStats, spSrcFileInfo, pathDst, spLogFileData, m_spReader->GetFinishedQueue(), m_spRange, spMemoryPool ? spMemoryPool->GetBufferList() : TBufferListPtr(), uiMaxConcurrentWrites, bOnlyCreate, bNoBuffering, bProtectReadOnlyFiles, bUpdateFileAttributesAndTimes)) { } Index: src/libchengine/TOverlappedReaderWriterFB.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TOverlappedReaderWriterFB.h (.../TOverlappedReaderWriterFB.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TOverlappedReaderWriterFB.h (.../TOverlappedReaderWriterFB.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -24,6 +24,7 @@ #include "TOverlappedMemoryPool.h" #include "TOverlappedReaderFB.h" #include "TOverlappedWriterFB.h" +#include "FeedbackManager.h" namespace chengine { @@ -33,7 +34,7 @@ { public: explicit TOverlappedReaderWriterFB(const IFilesystemPtr& spFilesystem, - const IFeedbackHandlerPtr& spFeedbackHandler, + const FeedbackManagerPtr& spFeedbackManager, TWorkerThreadController& rThreadController, TOverlappedThreadPool& rThreadPool, const TFileInfoPtr& spSrcFileInfo, Index: src/libchengine/TOverlappedWriterFB.cpp =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TOverlappedWriterFB.cpp (.../TOverlappedWriterFB.cpp) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TOverlappedWriterFB.cpp (.../TOverlappedWriterFB.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -29,7 +29,7 @@ namespace chengine { TOverlappedWriterFB::TOverlappedWriterFB(const IFilesystemPtr& spFilesystem, - const IFeedbackHandlerPtr& spFeedbackHandler, + const FeedbackManagerPtr& spFeedbackManager, TWorkerThreadController& rThreadController, const TSubTaskStatsInfoPtr& spStats, const TFileInfoPtr& spSrcFileInfo, @@ -58,7 +58,7 @@ { if(!spFilesystem) throw TCoreException(eErr_InvalidArgument, L"spFilesystem is NULL", LOCATION); - if(!spFeedbackHandler) + if(!spFeedbackManager) throw TCoreException(eErr_InvalidArgument, L"spFeedbackHandler is NULL", LOCATION); if(!spStats) throw TCoreException(eErr_InvalidArgument, L"spStats is NULL", LOCATION); @@ -74,7 +74,7 @@ throw TCoreException(eErr_InvalidArgument, L"spBuffersToWrite is NULL", LOCATION); IFilesystemFilePtr fileDst = spFilesystem->CreateFileObject(IFilesystemFile::eMode_Write, pathDst, bNoBuffering, bProtectReadOnlyFiles); - m_spDstFile = std::make_shared(fileDst, spFeedbackHandler, spLogFileData, rThreadController, spFilesystem); + m_spDstFile = std::make_shared(fileDst, spFeedbackManager, spLogFileData, rThreadController, spFilesystem); } TOverlappedWriterFB::~TOverlappedWriterFB() Index: src/libchengine/TOverlappedWriterFB.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TOverlappedWriterFB.h (.../TOverlappedWriterFB.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TOverlappedWriterFB.h (.../TOverlappedWriterFB.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -33,7 +33,7 @@ { public: TOverlappedWriterFB(const IFilesystemPtr& spFilesystem, - const IFeedbackHandlerPtr& spFeedbackHandler, + const FeedbackManagerPtr& spFeedbackManager, TWorkerThreadController& rThreadController, const TSubTaskStatsInfoPtr& spStats, const TFileInfoPtr& spSrcFileInfo, Index: src/libchengine/TScopedRunningTimeTrackerPause.cpp =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TScopedRunningTimeTrackerPause.cpp (.../TScopedRunningTimeTrackerPause.cpp) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TScopedRunningTimeTrackerPause.cpp (.../TScopedRunningTimeTrackerPause.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -23,13 +23,21 @@ namespace chengine { TScopedRunningTimeTrackerPause::TScopedRunningTimeTrackerPause(TScopedRunningTimeTracker& rRunningTimeTracker) : - m_rRunningTimeTracker(rRunningTimeTracker) + m_pRunningTimeTracker(&rRunningTimeTracker) { - m_rRunningTimeTracker.PauseTimeTracking(); + m_pRunningTimeTracker->PauseTimeTracking(); } + TScopedRunningTimeTrackerPause::TScopedRunningTimeTrackerPause(TScopedRunningTimeTracker* pRunningTimeTracker) : + m_pRunningTimeTracker(pRunningTimeTracker) + { + if(m_pRunningTimeTracker) + m_pRunningTimeTracker->PauseTimeTracking(); + } + TScopedRunningTimeTrackerPause::~TScopedRunningTimeTrackerPause() { - m_rRunningTimeTracker.UnPauseTimeTracking(); + if(m_pRunningTimeTracker) + m_pRunningTimeTracker->UnPauseTimeTracking(); } } Index: src/libchengine/TScopedRunningTimeTrackerPause.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TScopedRunningTimeTrackerPause.h (.../TScopedRunningTimeTrackerPause.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TScopedRunningTimeTrackerPause.h (.../TScopedRunningTimeTrackerPause.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -27,13 +27,14 @@ { public: explicit TScopedRunningTimeTrackerPause(TScopedRunningTimeTracker& rRunningTimeTracker); + explicit TScopedRunningTimeTrackerPause(TScopedRunningTimeTracker* pRunningTimeTracker); ~TScopedRunningTimeTrackerPause(); TScopedRunningTimeTrackerPause(const TScopedRunningTimeTrackerPause&) = delete; TScopedRunningTimeTrackerPause& operator=(const TScopedRunningTimeTrackerPause&) = delete; private: - TScopedRunningTimeTracker& m_rRunningTimeTracker; + TScopedRunningTimeTracker* m_pRunningTimeTracker; }; } Index: src/libchengine/TSubTaskArray.cpp =================================================================== diff -u -r9ddf8fdd5f641491dd30c49eb90f8f740314b6af -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskArray.cpp (.../TSubTaskArray.cpp) (revision 9ddf8fdd5f641491dd30c49eb90f8f740314b6af) +++ src/libchengine/TSubTaskArray.cpp (.../TSubTaskArray.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -154,7 +154,7 @@ } } - TSubTaskBase::ESubOperationResult TSubTasksArray::Execute(const IFeedbackHandlerPtr& spFeedbackHandler, bool bRunOnlyEstimationSubTasks) + TSubTaskBase::ESubOperationResult TSubTasksArray::Execute(bool bRunOnlyEstimationSubTasks) { TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; @@ -175,7 +175,7 @@ break; } - eResult = spCurrentSubTask->Exec(spFeedbackHandler); + eResult = spCurrentSubTask->Exec(); if (eResult != TSubTaskBase::eSubResult_Continue) break; Index: src/libchengine/TSubTaskArray.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskArray.h (.../TSubTaskArray.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TSubTaskArray.h (.../TSubTaskArray.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -59,7 +59,7 @@ void Load(const serializer::ISerializerPtr& spSerializer); void InitBeforeExec(); - TSubTaskBase::ESubOperationResult Execute(const IFeedbackHandlerPtr& spFeedbackHandler, bool bRunOnlyEstimationSubTasks); + TSubTaskBase::ESubOperationResult Execute(bool bRunOnlyEstimationSubTasks); // checks if the fast move already marked all base paths as not be be further processed bool AreAllBasePathsProcessed() const; Index: src/libchengine/TSubTaskBase.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskBase.h (.../TSubTaskBase.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TSubTaskBase.h (.../TSubTaskBase.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -60,7 +60,7 @@ virtual void Reset() = 0; virtual void InitBeforeExec() = 0; - virtual ESubOperationResult Exec(const IFeedbackHandlerPtr& spFeedbackHandler) = 0; + virtual ESubOperationResult Exec() = 0; virtual ESubOperationType GetSubOperationType() const = 0; // serialization Index: src/libchengine/TSubTaskContext.cpp =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskContext.cpp (.../TSubTaskContext.cpp) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TSubTaskContext.cpp (.../TSubTaskContext.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -32,7 +32,7 @@ TSubTaskContext::TSubTaskContext(TConfig& rConfig, const TBasePathDataContainerPtr& spBasePaths, const TFileFiltersArray& rFilters, TTaskConfigTracker& rCfgTracker, const logger::TLogFileDataPtr& spLogFileData, - TWorkerThreadController& rThreadController, const IFilesystemPtr& spFilesystem) : + TWorkerThreadController& rThreadController, const IFilesystemPtr& spFilesystem, const FeedbackManagerPtr& spFeedbackManager) : m_rConfig(rConfig), m_eOperationType(eOperation_None), m_spBasePaths(spBasePaths), @@ -41,12 +41,15 @@ m_rCfgTracker(rCfgTracker), m_spFilesystem(spFilesystem), m_spLogFileData(spLogFileData), - m_rThreadController(rThreadController) + m_rThreadController(rThreadController), + m_spFeedbackManager(spFeedbackManager) { if (!spFilesystem) throw TCoreException(eErr_InvalidArgument, L"spFilesystem", LOCATION); - if (!spLogFileData) + if(!spLogFileData) throw TCoreException(eErr_InvalidArgument, L"spLogFileData", LOCATION); + if(!spFeedbackManager) + throw TCoreException(eErr_InvalidArgument, L"spFeedbackManager", LOCATION); } TSubTaskContext::~TSubTaskContext() Index: src/libchengine/TSubTaskContext.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskContext.h (.../TSubTaskContext.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TSubTaskContext.h (.../TSubTaskContext.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -28,6 +28,8 @@ #include "TFileInfoArray.h" #include "IFilesystem.h" #include "../liblogger/TLogFileData.h" +#include "FeedbackAlreadyExistsRuleList.h" +#include "FeedbackManager.h" namespace chcore { @@ -49,7 +51,8 @@ TSubTaskContext(TConfig& rConfig, const TBasePathDataContainerPtr& spBasePaths, const TFileFiltersArray& rFilters, TTaskConfigTracker& rCfgTracker, const logger::TLogFileDataPtr& spLogFileData, - chcore::TWorkerThreadController& rThreadController, const IFilesystemPtr& spFilesystem); + chcore::TWorkerThreadController& rThreadController, const IFilesystemPtr& spFilesystem, + const FeedbackManagerPtr& spFeedbackManager); TSubTaskContext(const TSubTaskContext& rSrc) = delete; ~TSubTaskContext(); @@ -64,6 +67,7 @@ TBasePathDataContainerPtr GetBasePaths() const; const TFileFiltersArray& GetFilters() const; + TFileInfoArray& GetFilesCache(); const TFileInfoArray& GetFilesCache() const; @@ -80,6 +84,9 @@ IFilesystemPtr GetLocalFilesystem() const; + FeedbackManagerPtr GetFeedbackManager() const { return m_spFeedbackManager; } + void SetFeedbackManager(const FeedbackManagerPtr& spFeedbackManager) { m_spFeedbackManager = spFeedbackManager; } + private: TConfig& m_rConfig; @@ -106,6 +113,8 @@ #pragma warning(disable: 4251) IFilesystemPtr m_spFilesystem; logger::TLogFileDataPtr m_spLogFileData; + + FeedbackManagerPtr m_spFeedbackManager; #pragma warning(pop) // thread control Index: src/libchengine/TSubTaskCopyMove.cpp =================================================================== diff -u -r301444777085263aae7aff911dd56722f302597e -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 301444777085263aae7aff911dd56722f302597e) +++ src/libchengine/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -33,7 +33,6 @@ #include "TFileInfo.h" #include "TFileInfoArray.h" #include "TScopedRunningTimeTracker.h" -#include "TFeedbackHandlerWrapper.h" #include "TOverlappedMemoryPool.h" #include "TTaskConfigBufferSizes.h" #include "TFilesystemFeedbackWrapper.h" @@ -42,6 +41,7 @@ #include "TThreadedQueueRunner.h" #include "TOverlappedThreadPool.h" #include "../libchcore/RoundingFunctions.h" +#include using namespace chcore; using namespace string; @@ -98,11 +98,16 @@ m_spSubTaskStats->SetCurrentPath(spFileInfo->GetFullFilePath().ToString()); } - TSubTaskBase::ESubOperationResult TSubTaskCopyMove::Exec(const IFeedbackHandlerPtr& spFeedback) + TSubTaskBase::ESubOperationResult TSubTaskCopyMove::Exec() { TScopedRunningTimeTracker guard(*m_spSubTaskStats); - TFeedbackHandlerWrapperPtr spFeedbackHandler(std::make_shared(spFeedback, guard)); + FeedbackManagerPtr spFeedbackManager = GetContext().GetFeedbackManager(); + spFeedbackManager->SetSecondaryTimeTracker(&guard); + BOOST_SCOPE_EXIT(&spFeedbackManager) { + spFeedbackManager->SetSecondaryTimeTracker(nullptr); + } BOOST_SCOPE_EXIT_END + TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); TTaskConfigTracker& rCfgTracker = GetContext().GetCfgTracker(); TWorkerThreadController& rThreadController = GetContext().GetThreadController(); @@ -111,7 +116,7 @@ IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); TBasePathDataContainerPtr spSrcPaths = GetContext().GetBasePaths(); - TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, GetContext().GetLogFileData(), rThreadController); + TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackManager, spFilesystem, GetContext().GetLogFileData(), rThreadController); // log LOG_INFO(m_spLog) << _T("Processing files/folders (ProcessFiles)"); @@ -230,7 +235,7 @@ ccp.spSrcFile = spFileInfo; // copy data - eResult = CustomCopyFileFB(spFeedbackHandler, threadPool, &ccp); + eResult = CustomCopyFileFB(spFeedbackManager, threadPool, &ccp); if (eResult == eSubResult_SkipFile) { spFileInfo->MarkAsProcessed(false); @@ -338,7 +343,7 @@ } } - TSubTaskBase::ESubOperationResult TSubTaskCopyMove::CustomCopyFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, + TSubTaskBase::ESubOperationResult TSubTaskCopyMove::CustomCopyFileFB(const FeedbackManagerPtr& spFeedbackManager, TOverlappedThreadPool& rThreadPool, CUSTOM_COPY_PARAMS* pData) { @@ -368,7 +373,7 @@ unsigned long long ullNextReadPos = m_spSubTaskStats->GetCurrentItemProcessedSize(); TOverlappedReaderWriterFB tReaderWriter(spFilesystem, - spFeedbackHandler, + spFeedbackManager, rThreadController, rThreadPool, pData->spSrcFile, Index: src/libchengine/TSubTaskCopyMove.h =================================================================== diff -u -r9ddf8fdd5f641491dd30c49eb90f8f740314b6af -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 9ddf8fdd5f641491dd30c49eb90f8f740314b6af) +++ src/libchengine/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -27,6 +27,7 @@ #include "TBufferSizes.h" #include "../liblogger/TLogger.h" #include "TOverlappedMemoryPool.h" +#include "FeedbackManager.h" namespace chengine { @@ -46,7 +47,7 @@ void Reset() override; void InitBeforeExec() override; - ESubOperationResult Exec(const IFeedbackHandlerPtr& spFeedbackHandler) override; + ESubOperationResult Exec() override; ESubOperationType GetSubOperationType() const override { return eSubOperation_Copying; } void Store(const serializer::ISerializerPtr& spSerializer) const override; @@ -60,7 +61,7 @@ TBufferSizes::EBufferType GetBufferIndex(const TBufferSizes& rBufferSizes, const TFileInfoPtr& spFileInfo); bool AdjustBufferIfNeeded(const TOverlappedMemoryPoolPtr& spBuffer, TBufferSizes& rBufferSizes, bool bForce = false); - ESubOperationResult CustomCopyFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, + ESubOperationResult CustomCopyFileFB(const FeedbackManagerPtr& spFeedbackManager, TOverlappedThreadPool& rThreadPool, CUSTOM_COPY_PARAMS* pData); Index: src/libchengine/TSubTaskDelete.cpp =================================================================== diff -u -r06dcc90de4fac6573a68b147ad9d62b770042582 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision 06dcc90de4fac6573a68b147ad9d62b770042582) +++ src/libchengine/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -31,9 +31,9 @@ #include "TFileInfo.h" #include "TTaskLocalStats.h" #include "TScopedRunningTimeTracker.h" -#include "TFeedbackHandlerWrapper.h" #include "TBufferSizes.h" #include "TFilesystemFeedbackWrapper.h" +#include using namespace chcore; using namespace string; @@ -75,17 +75,22 @@ m_tSubTaskStats.SetCurrentPath(spFileInfo->GetFullFilePath().ToString()); } - TSubTaskBase::ESubOperationResult TSubTaskDelete::Exec(const IFeedbackHandlerPtr& spFeedback) + TSubTaskBase::ESubOperationResult TSubTaskDelete::Exec() { TScopedRunningTimeTracker guard(m_tSubTaskStats); - TFeedbackHandlerWrapperPtr spFeedbackHandler(std::make_shared(spFeedback, guard)); + FeedbackManagerPtr spFeedbackManager = GetContext().GetFeedbackManager(); + spFeedbackManager->SetSecondaryTimeTracker(&guard); + BOOST_SCOPE_EXIT(&spFeedbackManager) { + spFeedbackManager->SetSecondaryTimeTracker(nullptr); + } BOOST_SCOPE_EXIT_END + // log TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); TWorkerThreadController& rThreadController = GetContext().GetThreadController(); IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); - TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, GetContext().GetLogFileData(), rThreadController); + TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackManager, spFilesystem, GetContext().GetLogFileData(), rThreadController); // log LOG_INFO(m_spLog) << _T("Deleting files (DeleteFiles)..."); Index: src/libchengine/TSubTaskDelete.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskDelete.h (.../TSubTaskDelete.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TSubTaskDelete.h (.../TSubTaskDelete.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -39,7 +39,7 @@ void Reset() override; void InitBeforeExec() override; - ESubOperationResult Exec(const IFeedbackHandlerPtr& spFeedbackHandler) override; + ESubOperationResult Exec() override; ESubOperationType GetSubOperationType() const override { return eSubOperation_Deleting; } void Store(const serializer::ISerializerPtr& spSerializer) const override; Index: src/libchengine/TSubTaskFastMove.cpp =================================================================== diff -u -r9ddf8fdd5f641491dd30c49eb90f8f740314b6af -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision 9ddf8fdd5f641491dd30c49eb90f8f740314b6af) +++ src/libchengine/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -31,10 +31,10 @@ #include "TFileInfo.h" #include #include "TScopedRunningTimeTracker.h" -#include "TFeedbackHandlerWrapper.h" #include "TBufferSizes.h" #include "TFilesystemFeedbackWrapper.h" #include "TDestinationPathProvider.h" +#include using namespace chcore; using namespace string; @@ -77,11 +77,17 @@ m_tSubTaskStats.SetCurrentPath(TString()); } - TSubTaskFastMove::ESubOperationResult TSubTaskFastMove::Exec(const IFeedbackHandlerPtr& spFeedback) + TSubTaskFastMove::ESubOperationResult TSubTaskFastMove::Exec() { TScopedRunningTimeTracker guard(m_tSubTaskStats); - TFeedbackHandlerWrapperPtr spFeedbackHandler(std::make_shared(spFeedback, guard)); + FeedbackManagerPtr spFeedbackManager = GetContext().GetFeedbackManager(); + spFeedbackManager->SetSecondaryTimeTracker(&guard); + BOOST_SCOPE_EXIT(&spFeedbackManager) { + spFeedbackManager->SetSecondaryTimeTracker(nullptr); + } BOOST_SCOPE_EXIT_END + + // log TWorkerThreadController& rThreadController = GetContext().GetThreadController(); TBasePathDataContainerPtr spBasePaths = GetContext().GetBasePaths(); @@ -90,7 +96,7 @@ const TFileFiltersArray& rafFilters = GetContext().GetFilters(); IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); - TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, GetContext().GetLogFileData(), rThreadController); + TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackManager, spFilesystem, GetContext().GetLogFileData(), rThreadController); LOG_INFO(m_spLog) << _T("Performing initial fast-move operation..."); Index: src/libchengine/TSubTaskFastMove.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskFastMove.h (.../TSubTaskFastMove.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TSubTaskFastMove.h (.../TSubTaskFastMove.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -42,7 +42,7 @@ void Reset() override; void InitBeforeExec() override; - ESubOperationResult Exec(const IFeedbackHandlerPtr& spFeedbackHandler) override; + ESubOperationResult Exec() override; ESubOperationType GetSubOperationType() const override { return eSubOperation_FastMove; } void Store(const serializer::ISerializerPtr& spSerializer) const override; Index: src/libchengine/TSubTaskScanDirectory.cpp =================================================================== diff -u -r85b07e753393f661f7d8f528e4238ebb6e9e1204 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision 85b07e753393f661f7d8f528e4238ebb6e9e1204) +++ src/libchengine/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -31,9 +31,9 @@ #include "TFileInfoArray.h" #include "TFileInfo.h" #include "TScopedRunningTimeTracker.h" -#include "TFeedbackHandlerWrapper.h" #include "TBufferSizes.h" #include "TFilesystemFeedbackWrapper.h" +#include using namespace chcore; using namespace string; @@ -78,11 +78,16 @@ m_tSubTaskStats.SetCurrentPath(TString()); } - TSubTaskScanDirectories::ESubOperationResult TSubTaskScanDirectories::Exec(const IFeedbackHandlerPtr& spFeedback) + TSubTaskScanDirectories::ESubOperationResult TSubTaskScanDirectories::Exec() { TScopedRunningTimeTracker guard(m_tSubTaskStats); - TFeedbackHandlerWrapperPtr spFeedbackHandler(std::make_shared(spFeedback, guard)); + FeedbackManagerPtr spFeedbackManager = GetContext().GetFeedbackManager(); + spFeedbackManager->SetSecondaryTimeTracker(&guard); + BOOST_SCOPE_EXIT(&spFeedbackManager) { + spFeedbackManager->SetSecondaryTimeTracker(nullptr); + } BOOST_SCOPE_EXIT_END + // log TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); TWorkerThreadController& rThreadController = GetContext().GetThreadController(); @@ -91,7 +96,7 @@ const TFileFiltersArray& rafFilters = GetContext().GetFilters(); IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); - TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackHandler, spFilesystem, GetContext().GetLogFileData(), rThreadController); + TFilesystemFeedbackWrapper tFilesystemFBWrapper(spFeedbackManager, spFilesystem, GetContext().GetLogFileData(), rThreadController); LOG_INFO(m_spLog) << _T("Searching for files..."); Index: src/libchengine/TSubTaskScanDirectory.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TSubTaskScanDirectory.h (.../TSubTaskScanDirectory.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TSubTaskScanDirectory.h (.../TSubTaskScanDirectory.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -43,7 +43,7 @@ void Reset() override; void InitBeforeExec() override; - ESubOperationResult Exec(const IFeedbackHandlerPtr& spFeedbackHandler) override; + ESubOperationResult Exec() override; ESubOperationType GetSubOperationType() const override { return eSubOperation_Scanning; } void Store(const serializer::ISerializerPtr& spSerializer) const override; Index: src/libchengine/TTask.cpp =================================================================== diff -u -rfa1b3554856407e4501db20d5093818e8d8c4068 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TTask.cpp (.../TTask.cpp) (revision fa1b3554856407e4501db20d5093818e8d8c4068) +++ src/libchengine/TTask.cpp (.../TTask.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -26,12 +26,12 @@ #include "TTaskStatsSnapshot.h" #include "TScopedRunningTimeTracker.h" #include "TScopedRunningTimeTrackerPause.h" -#include "TFeedbackHandlerWrapper.h" #include "TTaskConfigBufferSizes.h" #include #include "TLocalFilesystem.h" #include "TTaskConfigVerifier.h" #include "../liblogger/TAsyncMultiLogger.h" +#include using namespace chcore; using namespace string; @@ -45,13 +45,12 @@ TTask::TTask(const ISerializerPtr& spSerializer, const IFeedbackHandlerPtr& spFeedbackHandler, const TTaskDefinition& rTaskDefinition, const logger::TLogFileDataPtr& spLogFileData) : m_spSerializer(spSerializer), - m_spInternalFeedbackHandler(spFeedbackHandler), + m_spFeedbackManager(std::make_shared(spFeedbackHandler)), m_spLog(logger::MakeLogger(spLogFileData, L"Task")), m_spSrcPaths(new TBasePathDataContainer), + m_tSubTaskContext(m_tConfiguration, m_spSrcPaths, m_afFilters, m_cfgTracker, spLogFileData, m_workerThread, + std::make_shared(spLogFileData), m_spFeedbackManager), m_tSubTasksArray(m_tSubTaskContext), - m_tSubTaskContext(m_tConfiguration, m_spSrcPaths, m_afFilters, - m_cfgTracker, spLogFileData, m_workerThread, - std::make_shared(spLogFileData)), m_bForce(false), m_bContinue(false) { @@ -65,18 +64,15 @@ TTask::TTask(const ISerializerPtr& spSerializer, const IFeedbackHandlerPtr& spFeedbackHandler, const logger::TLogFileDataPtr& spLogFileData) : m_spSerializer(spSerializer), - m_spInternalFeedbackHandler(spFeedbackHandler), + m_spFeedbackManager(std::make_shared(spFeedbackHandler)), m_spLog(logger::MakeLogger(spLogFileData, L"Task")), m_spSrcPaths(new TBasePathDataContainer), + m_tSubTaskContext(m_tConfiguration, m_spSrcPaths, m_afFilters, m_cfgTracker, m_spLog->GetLogFileData(), m_workerThread, + std::make_shared(m_spLog->GetLogFileData()), m_spFeedbackManager), m_tSubTasksArray(m_tSubTaskContext), - m_tSubTaskContext(m_tConfiguration, m_spSrcPaths, m_afFilters, - m_cfgTracker, m_spLog->GetLogFileData(), m_workerThread, - std::make_shared(m_spLog->GetLogFileData())), m_bForce(false), m_bContinue(false) { - if(!spFeedbackHandler) - throw TCoreException(eErr_InvalidArgument, L"spFeedbackHandler", LOCATION); if(!spSerializer) throw TCoreException(eErr_InvalidArgument, L"spSerializer", LOCATION); } @@ -98,6 +94,7 @@ m_tConfiguration = rTaskDefinition.GetConfiguration(); *m_spSrcPaths = rTaskDefinition.GetSourcePaths(); m_afFilters = rTaskDefinition.GetFilters(); + m_spFeedbackManager->SetRules(rTaskDefinition.GetFeedbackRules()); m_tBaseData.SetTaskName(rTaskDefinition.GetTaskName()); m_tSubTasksArray.Init(rTaskDefinition.GetOperationPlan()); @@ -170,12 +167,11 @@ spContainer = m_spSerializer->GetContainer(_T("filters")); m_afFilters.Load(spContainer); + m_spFeedbackManager->Load(m_spSerializer); + spContainer = m_spSerializer->GetContainer(_T("local_stats")); m_tLocalStats.Load(spContainer); - spContainer = m_spSerializer->GetContainer(_T("feedback")); - m_spInternalFeedbackHandler->Load(spContainer); - // ensure copy-based context entries are properly updated after loading m_tSubTaskContext.SetDestinationPath(m_tBaseData.GetDestinationPath()); m_tSubTaskContext.SetOperationType(m_tSubTasksArray.GetOperationType()); @@ -274,12 +270,11 @@ spContainer = m_spSerializer->GetContainer(_T("filters")); m_afFilters.Store(spContainer); + m_spFeedbackManager->Store(m_spSerializer); + spContainer = m_spSerializer->GetContainer(_T("local_stats")); m_tLocalStats.Store(spContainer); - spContainer = m_spSerializer->GetContainer(_T("feedback")); - m_spInternalFeedbackHandler->Store(spContainer); - m_tSubTasksArray.Store(m_spSerializer); } @@ -349,7 +344,7 @@ SetTaskState(eTaskState_None); - m_spInternalFeedbackHandler->RestoreDefaults(); + m_spFeedbackManager->RestoreDefaults(); m_tSubTasksArray.ResetProgressAndStats(); m_tLocalStats.Clear(); m_spSrcPaths->ResetProcessingFlags(); @@ -362,7 +357,7 @@ void TTask::RestoreFeedbackDefaults() { - m_spInternalFeedbackHandler->RestoreDefaults(); + m_spFeedbackManager->RestoreDefaults(); } void TTask::PauseProcessing() @@ -402,6 +397,7 @@ spSnapshot->SetThreadPriority(GetTaskPropValue(m_tConfiguration)); spSnapshot->SetDestinationPath(m_tBaseData.GetDestinationPath().ToString()); spSnapshot->SetFilters(m_afFilters); + spSnapshot->SetFeedbackRules(m_spFeedbackManager->GetRules()); spSnapshot->SetTaskState(m_tBaseData.GetCurrentState()); spSnapshot->SetOperationType(m_tSubTasksArray.GetOperationType()); @@ -550,8 +546,14 @@ { // start tracking time for this thread TScopedRunningTimeTracker tProcessingGuard(m_tLocalStats); - TFeedbackHandlerWrapperPtr spFeedbackHandler(std::make_shared(m_spInternalFeedbackHandler, tProcessingGuard)); + // set time tracker and ensure it is unset on scope exit + m_spFeedbackManager->SetTimeTracker(&tProcessingGuard); + + BOOST_SCOPE_EXIT(&m_spFeedbackManager) { + m_spFeedbackManager->SetTimeTracker(nullptr); + } BOOST_SCOPE_EXIT_END + const size_t ExceptionBufferSize = 2048; std::unique_ptr upExceptionInfoBuffer(new wchar_t[ExceptionBufferSize]); try @@ -574,7 +576,7 @@ m_tSubTasksArray.InitBeforeExec(); // exec the estimation subtasks - TSubTaskBase::ESubOperationResult eResult = m_tSubTasksArray.Execute(spFeedbackHandler, true); + TSubTaskBase::ESubOperationResult eResult = m_tSubTasksArray.Execute(true); // go into wait state only in case the preprocessing did not finish the operation already // (only fast move can do that right now) @@ -585,7 +587,7 @@ eResult = CheckForWaitState(); // operation limiting } if (eResult == TSubTaskBase::eSubResult_Continue) - eResult = m_tSubTasksArray.Execute(spFeedbackHandler, false); + eResult = m_tSubTasksArray.Execute(false); // change status to finished if (eResult == TSubTaskBase::eSubResult_Continue) @@ -596,7 +598,7 @@ switch (eResult) { case TSubTaskBase::eSubResult_Error: - spFeedbackHandler->OperationError(); + m_spFeedbackManager->OperationEvent(eOperationEvent_Error); SetTaskState(eTaskState_Error); break; @@ -615,7 +617,7 @@ break; case TSubTaskBase::eSubResult_Continue: - spFeedbackHandler->OperationFinished(); + m_spFeedbackManager->OperationEvent(eOperationEvent_Finished); SetTaskState(eTaskState_Finished); break; @@ -664,7 +666,7 @@ LOG_ERROR(m_spLog) << strMsg.c_str(); // let others know some error happened - spFeedbackHandler->OperationError(); + m_spFeedbackManager->OperationEvent(eOperationEvent_Error); SetTaskState(eTaskState_Error); SetContinueFlag(false); Index: src/libchengine/TTask.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TTask.h (.../TTask.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TTask.h (.../TTask.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -19,7 +19,6 @@ #ifndef __TASK_H__ #define __TASK_H__ -#include "IFeedbackHandler.h" #include "TTaskDefinition.h" #include "TTaskConfigTracker.h" #include "TBasePathData.h" @@ -33,6 +32,7 @@ #include "IFilesystem.h" #include "../liblogger/TLogger.h" #include "../libchcore/TWorkerThreadController.h" +#include "FeedbackManager.h" namespace chengine { @@ -136,7 +136,8 @@ #pragma warning(disable: 4251) serializer::ISerializerPtr m_spSerializer; std::mutex m_mutexSerializer; - IFeedbackHandlerPtr m_spInternalFeedbackHandler; + + FeedbackManagerPtr m_spFeedbackManager; #pragma warning(pop) // base data @@ -151,10 +152,9 @@ // Global task settings TConfig m_tConfiguration; + TSubTaskContext m_tSubTaskContext; TSubTasksArray m_tSubTasksArray; - TSubTaskContext m_tSubTaskContext; - TTaskConfigTracker m_cfgTracker; // current task state (derivatives of the task initial information) Index: src/libchengine/TTaskDefinition.cpp =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TTaskDefinition.cpp (.../TTaskDefinition.cpp) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TTaskDefinition.cpp (.../TTaskDefinition.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -173,6 +173,7 @@ throw TCoreException(eErr_MissingXmlData, L"Missing TaskDefinition.SourcePaths.Path", LOCATION); GetConfigValue(rDataSrc, _T("TaskDefinition.Filters"), m_afFilters); + GetConfigValue(rDataSrc, _T("TaskDefinition.Feedback"), m_feedbackRules); // destination path if (!GetConfigValue(rDataSrc, _T("TaskDefinition.DestinationPath"), m_pathDestinationPath) || (!bAllowEmptyDstPath && m_pathDestinationPath.IsEmpty())) @@ -251,10 +252,11 @@ SetConfigValue(rConfig, _T("TaskDefinition.Version"), m_ullTaskVersion); + SetConfigValue(rConfig, _T("TaskDefinition.Feedback"), m_feedbackRules); + rConfig.PutSubConfig(_T("TaskDefinition.TaskSettings"), m_tConfiguration); } - const TFileFiltersArray& TTaskDefinition::GetFilters() const { return m_afFilters; @@ -269,4 +271,19 @@ { m_afFilters = rFilters; } + + const FeedbackRules& TTaskDefinition::GetFeedbackRules() const + { + return m_feedbackRules; + } + + FeedbackRules& TTaskDefinition::GetFeedbackRules() + { + return m_feedbackRules; + } + + void TTaskDefinition::SetFeedbackRules(const FeedbackRules& rFeedbackRules) + { + m_feedbackRules = rFeedbackRules; + } } Index: src/libchengine/TTaskDefinition.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TTaskDefinition.h (.../TTaskDefinition.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TTaskDefinition.h (.../TTaskDefinition.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -27,6 +27,8 @@ #include "TConfig.h" #include "TFileFiltersArray.h" #include "../libchcore/TPathContainer.h" +#include "FeedbackAlreadyExistsRuleList.h" +#include "FeedbackRules.h" namespace chengine { @@ -56,6 +58,11 @@ TFileFiltersArray& GetFilters(); void SetFilters(const TFileFiltersArray& rFilters); + // feedback rules + const FeedbackRules& GetFeedbackRules() const; + FeedbackRules& GetFeedbackRules(); + void SetFeedbackRules(const FeedbackRules& rFeedbackRules); + // Destination path void SetDestinationPath(const chcore::TSmartPath& pathDestination); chcore::TSmartPath GetDestinationPath() const; @@ -86,6 +93,7 @@ chcore::TPathContainer m_vSourcePaths; chcore::TSmartPath m_pathDestinationPath; TFileFiltersArray m_afFilters; + FeedbackRules m_feedbackRules; TOperationPlan m_tOperationPlan; ///< Describes the operation along with sub-operations to be performed on the task input data Index: src/libchengine/TTaskStatsSnapshot.cpp =================================================================== diff -u -r9ddf8fdd5f641491dd30c49eb90f8f740314b6af -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TTaskStatsSnapshot.cpp (.../TTaskStatsSnapshot.cpp) (revision 9ddf8fdd5f641491dd30c49eb90f8f740314b6af) +++ src/libchengine/TTaskStatsSnapshot.cpp (.../TTaskStatsSnapshot.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -41,6 +41,7 @@ m_iThreadPriority(0), m_strDestinationPath(), m_filters(), + m_feedbackRules(), m_eTaskState(eTaskState_None), m_strTaskID(), m_eOperationType(eOperation_None), @@ -67,6 +68,7 @@ m_iThreadPriority = 0; m_strDestinationPath.Clear(); m_filters.Clear(); + m_feedbackRules.Clear(); m_eTaskState = eTaskState_None; m_strTaskID.Clear(); m_eOperationType = eOperation_None; Index: src/libchengine/TTaskStatsSnapshot.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/TTaskStatsSnapshot.h (.../TTaskStatsSnapshot.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libchengine/TTaskStatsSnapshot.h (.../TTaskStatsSnapshot.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -29,6 +29,8 @@ #include "EOperationTypes.h" #include "ETaskCurrentState.h" #include "TaskID.h" +#include "FeedbackAlreadyExistsRuleList.h" +#include "FeedbackRules.h" namespace chengine { @@ -79,6 +81,9 @@ const TFileFiltersArray& GetFilters() const { return m_filters; } void SetFilters(const TFileFiltersArray& val) { m_filters = val; } + const FeedbackRules& GetFeedbackRules() const { return m_feedbackRules; } + void SetFeedbackRules(const FeedbackRules& val) { m_feedbackRules = val; } + ETaskCurrentState GetTaskState() const { return m_eTaskState; } void SetTaskState(ETaskCurrentState val) { m_eTaskState = val; } @@ -118,7 +123,11 @@ int m_iThreadPriority; string::TString m_strDestinationPath; + TFileFiltersArray m_filters; + + FeedbackRules m_feedbackRules; + ETaskCurrentState m_eTaskState; string::TString m_strTaskID; EOperationType m_eOperationType; Index: src/libchengine/libchengine.vcxproj =================================================================== diff -u -rf3c80778cfee0736195e00274c78040f7908ac5b -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/libchengine.vcxproj (.../libchengine.vcxproj) (revision f3c80778cfee0736195e00274c78040f7908ac5b) +++ src/libchengine/libchengine.vcxproj (.../libchengine.vcxproj) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -507,11 +507,20 @@ + - - + + + + + + + + + + @@ -530,8 +539,7 @@ - - + @@ -615,8 +623,16 @@ - - + + + + + + + + + + @@ -735,8 +751,7 @@ - - + Index: src/libchengine/libchengine.vcxproj.filters =================================================================== diff -u -rf3c80778cfee0736195e00274c78040f7908ac5b -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libchengine/libchengine.vcxproj.filters (.../libchengine.vcxproj.filters) (revision f3c80778cfee0736195e00274c78040f7908ac5b) +++ src/libchengine/libchengine.vcxproj.filters (.../libchengine.vcxproj.filters) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -96,6 +96,18 @@ {1412ea6d-b28c-4a96-b076-3094c476ce45} + + {675e75c1-b53c-4cfa-baf0-73fd29efd52e} + + + {3e00c6b6-92d8-4f97-8689-9df059db42f1} + + + {19f5e9c0-f34a-482a-9f3c-f3eb712da553} + + + {4a4f6b0e-39cc-4228-a3ae-566d54464f05} + @@ -212,9 +224,6 @@ Source Files\Task - - Source Files\Feedback - Source Files\Stats @@ -224,9 +233,6 @@ Source Files\Stats - - Source Files\Feedback - Source Files\Feedback @@ -239,9 +245,6 @@ Source Files\Task Config - - Source Files\Feedback - Source Files\Filesystems @@ -381,15 +384,48 @@ Source Files\Tools - + + Source Files\Tools + + Source Files\Feedback - + Source Files\Feedback - - Source Files\Tools + + Source Files\Feedback\AlreadyExists + + Source Files\Feedback\AlreadyExists + + + Source Files\Feedback\Error + + + Source Files\Feedback\Error + + + Source Files\Feedback\NotEnoughSpace + + + Source Files\Feedback\NotEnoughSpace + + + Source Files\Feedback\Error + + + Source Files\Feedback\OperationEvent + + + Source Files\Feedback\OperationEvent + + + Source Files\Feedback\OperationEvent + + + Source Files\Feedback + @@ -506,9 +542,6 @@ Tests - - Source Files\Feedback - Source Files\Stats @@ -518,9 +551,6 @@ Source Files\Stats - - Source Files\Feedback - Source Files\Task Config @@ -668,12 +698,39 @@ Source Files\Tools - + Source Files\Feedback - + Source Files\Feedback + + Source Files\Feedback\AlreadyExists + + + Source Files\Feedback\AlreadyExists + + + Source Files\Feedback\Error + + + Source Files\Feedback\Error + + + Source Files\Feedback\NotEnoughSpace + + + Source Files\Feedback\NotEnoughSpace + + + Source Files\Feedback\OperationEvent + + + Source Files\Feedback\OperationEvent + + + Source Files\Feedback + Index: src/libserializer/SerializableContainer.h =================================================================== diff -u -rf3c80778cfee0736195e00274c78040f7908ac5b -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libserializer/SerializableContainer.h (.../SerializableContainer.h) (revision f3c80778cfee0736195e00274c78040f7908ac5b) +++ src/libserializer/SerializableContainer.h (.../SerializableContainer.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -62,6 +62,18 @@ return false; } + bool InsertAt(size_t stIndex, const T& rNewEntry) + { + BOOST_ASSERT(stIndex <= m_vEntries.size()); + if(stIndex <= m_vEntries.size()) + { + m_vEntries.insert(m_vEntries.begin() + stIndex, rNewEntry); + return true; + } + + return false; + } + const T& GetAt(size_t stIndex) const { if(stIndex >= m_vEntries.size()) @@ -70,6 +82,14 @@ return m_vEntries.at(stIndex); } + T& GetAt(size_t stIndex) + { + if(stIndex >= m_vEntries.size()) + throw std::out_of_range("stIndex is out of range"); + + return m_vEntries.at(stIndex); + } + bool RemoveAt(size_t stIndex) { BOOST_ASSERT(stIndex < m_vEntries.size()); Index: src/libserializer/TSQLiteTaskSchema.cpp =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libserializer/TSQLiteTaskSchema.cpp (.../TSQLiteTaskSchema.cpp) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libserializer/TSQLiteTaskSchema.cpp (.../TSQLiteTaskSchema.cpp) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -62,6 +62,9 @@ if(tVersion.GetVersion() == 5) Migrate_005_006(spDatabase, tVersion); + + if(tVersion.GetVersion() == 6) + Migrate_006_007(spDatabase, tVersion); } tTransaction.Commit(); @@ -125,8 +128,15 @@ tStatement.Prepare(_T("CREATE TABLE feedback(id BIGINT UNIQUE, file_error INT NOT NULL, file_already_exists INT NOT NULL, not_enough_space INT NOT NULL, operation_finished INT NOT NULL, operation_error INT NOT NULL)")); tStatement.Step(); + tStatement.Prepare(_T("CREATE TABLE feedback_already_exists(id BIGINT UNIQUE, use_mask INT NOT NULL, mask varchar(32768) NOT NULL, ") + _T("use_exclude_mask INT NOT NULL, exclude_mask varchar(32768) NOT NULL, ") + _T("use_date_compare INT NOT NULL, date_compare_type INT NOT NULL, ") + _T("use_size_compare INT NOT NULL, size_compare_type INT NOT NULL, ") + _T("result INT NOT NULL)")); + tStatement.Step(); + // and finally set the database version to current one - tVersion.SetVersion(5); + tVersion.SetVersion(7); } void TSQLiteTaskSchema::Migrate_001_002(const sqlite::TSQLiteDatabasePtr& spDatabase, TSerializerVersion &tVersion) @@ -258,4 +268,23 @@ tVersion.SetVersion(6); } + + void TSQLiteTaskSchema::Migrate_006_007(const sqlite::TSQLiteDatabasePtr& spDatabase, TSerializerVersion& tVersion) + { + sqlite::TSQLiteStatement tStatement(spDatabase); + + // remove old feedback table (with no migration) +// tStatement.Prepare(_T("DROP TABLE feedback")); +// tStatement.Step(); + + // create new feedback tables + tStatement.Prepare(_T("CREATE TABLE feedback_already_exists(id BIGINT UNIQUE, use_mask INT NOT NULL, mask varchar(32768) NOT NULL, ") + _T("use_exclude_mask INT NOT NULL, exclude_mask varchar(32768) NOT NULL, ") + _T("use_date_compare INT NOT NULL, date_compare_type INT NOT NULL, ") + _T("use_size_compare INT NOT NULL, size_compare_type INT NOT NULL, ") + _T("result INT NOT NULL)")); + tStatement.Step(); + + tVersion.SetVersion(7); + } } Index: src/libserializer/TSQLiteTaskSchema.h =================================================================== diff -u -r0d5b67ee96b435d63f7bf075dc8e28603793b187 -r08717141ce5f6926116c298cbc9442094a45bb67 --- src/libserializer/TSQLiteTaskSchema.h (.../TSQLiteTaskSchema.h) (revision 0d5b67ee96b435d63f7bf075dc8e28603793b187) +++ src/libserializer/TSQLiteTaskSchema.h (.../TSQLiteTaskSchema.h) (revision 08717141ce5f6926116c298cbc9442094a45bb67) @@ -40,7 +40,8 @@ void Migrate_002_003(const sqlite::TSQLiteDatabasePtr& spDatabase, TSerializerVersion &tVersion); void Migrate_003_004(const sqlite::TSQLiteDatabasePtr& spDatabase, TSerializerVersion &tVersion); void Migrate_004_005(const sqlite::TSQLiteDatabasePtr& spDatabase, TSerializerVersion &tVersion); - void Migrate_005_006(const sqlite::TSQLiteDatabasePtr& spDatabase, TSerializerVersion &tVersion); + void Migrate_005_006(const sqlite::TSQLiteDatabasePtr& spDatabase, TSerializerVersion& tVersion); + void Migrate_006_007(const sqlite::TSQLiteDatabasePtr& spDatabase, TSerializerVersion& tVersion); }; typedef std::shared_ptr TSQLiteTaskSchemaPtr;