OSDN Git Service

compiler-calculated maximum value for `m_SourceDefs` (#966)
[winmerge-jp/winmerge-jp.git] / Src / DiffThread.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /** 
3  * @file  DiffThread.h
4  *
5  * @brief Declaration file for CDiffThread
6  */
7 #pragma once
8
9 #include <memory>
10 #include <functional>
11 #define POCO_NO_UNWINDOWS 1
12 #include <Poco/Thread.h>
13 #include <Poco/BasicEvent.h>
14 #include <Poco/Delegate.h>
15 #include "DiffContext.h"
16
17 namespace Poco
18 {
19 class Semaphore;
20 }
21 class DiffThreadAbortable;
22
23 /**
24  * @brief Structure used in sending data to the threads.
25  * As thread functions have only one parameter we must pack all
26  * the data we need inside structure.
27  */
28 struct DiffFuncStruct
29 {
30         CDiffContext * context; /**< Compare context. */
31         Poco::BasicEvent<int> m_listeners; /**< Event listeners */
32         int nThreadState; /**< Thread state. */
33         DiffThreadAbortable * m_pAbortgate; /**< Interface for aborting compare. */
34         Poco::Semaphore *pSemaphore; /**< Semaphore for synchronizing threads. */
35         std::function<void (DiffFuncStruct*)> m_fncCollect;
36         std::function<void (DiffFuncStruct*)> m_fncCompare;
37
38         DiffFuncStruct()
39                 : context(nullptr)
40                 , nThreadState(0/*CDiffThread::THREAD_NOTSTARTED*/)
41                 , m_pAbortgate(nullptr)
42                 , pSemaphore(nullptr)
43                 {}
44 };
45
46 /**
47  * @brief Class for threaded folder compare.
48  * This class implements folder compare in two phases and in two threads:
49  * - first thread collects items to compare to compare-time list
50  *   (m_diffList).
51  * - second threads compares items in the list.
52  */
53 class CDiffThread
54 {
55 public:
56         /** @brief Thread's states. */
57         enum ThreadState
58         {
59                 THREAD_NOTSTARTED = 0, /**< Thread not started, idle. */
60                 THREAD_COMPARING, /**< Thread running (comparing). */
61                 THREAD_COMPLETED, /**< Thread has completed its task. */
62         };
63
64         enum ThreadEvent
65         {
66                 EVENT_COLLECT_COMPLETED = 2,
67                 EVENT_COMPARE_PROGRESSED = 1,
68                 EVENT_COMPARE_COMPLETED = 0,
69         };
70
71 // creation and use, called on main thread
72         CDiffThread();
73         ~CDiffThread();
74         void SetContext(CDiffContext * pCtx);
75         unsigned CompareDirectories();
76         template<class T>
77         void AddListener(T *pObj, void (T::*pMethod)(int& state)) {
78                 m_pDiffParm->m_listeners += Poco::delegate(pObj, pMethod);
79         }
80         template<class T>
81         void RemoveListener(T *pObj, void (T::*pMethod)(int& state)) {
82                 m_pDiffParm->m_listeners -= Poco::delegate(pObj, pMethod);
83         }
84         void SetCollectFunction(std::function<void(DiffFuncStruct*)> func) { m_pDiffParm->m_fncCollect = func; }
85         void SetCompareFunction(std::function<void(DiffFuncStruct*)> func) { m_pDiffParm->m_fncCompare = func; }
86
87 // runtime interface for main thread, called on main thread
88         unsigned GetThreadState() const;
89         void Abort() { m_bAborting = true; }
90         bool IsAborting() const { return m_bAborting; }
91         void Pause() { m_bPaused = true; }
92         void Continue() { m_bPaused = false; }
93         bool IsPaused() const { return m_bPaused; }
94
95 // runtime interface for child thread, called on child thread
96         bool ShouldAbort() const;
97
98 private:
99         CDiffContext * m_pDiffContext; /**< Compare context storing results. */
100         Poco::Thread m_threads[2]; /**< Compare threads. */
101         std::unique_ptr<DiffFuncStruct> m_pDiffParm; /**< Structure for sending data to threads. */
102         std::unique_ptr<DiffThreadAbortable> m_pAbortgate;
103         bool m_bAborting; /**< Is compare aborting? */
104         bool m_bPaused; /**< Is compare paused? */
105 };
106
107 /**
108  * @brief Sets context pointer forwarded to thread.
109  * @param [in] pCtx Pointer to compare context.
110  */
111 inline void CDiffThread::SetContext(CDiffContext * pCtx)
112 {
113         m_pDiffContext = pCtx;
114 }
115
116 /**
117  * @brief Returns thread's current state
118  */
119 inline unsigned CDiffThread::GetThreadState() const
120 {
121         return m_pDiffParm->nThreadState;
122 }