summaryrefslogtreecommitdiff
path: root/src/model/BaseJob.cpp
blob: 1a358fbc70a2ed904c3b80acfcaeeb4a87c592b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
 * Copyright 2017 Samsung Electronics Co., Ltd
 *
 * Licensed under the Flora License, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://floralicense.org/license/
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "BaseJob.h"

#include <Ecore.h>

#include "common.h"

namespace gallery {

	BaseJob::BaseJob(const NotiHandler &onComplete,
			const bool isCancelable) :
		m_onComplete(onComplete),
		m_isCancelable(isCancelable),
		m_result(RES_ILLEGAL_STATE),
		m_selfPtr(new BaseJob *(this)),
		m_isCancelled(0)
	{
	}

	BaseJob::~BaseJob()
	{
		finish();
	}

	Result BaseJob::prepare()
	{
		if (!m_thread.start(
			[this]()
			{
				m_result = execute();
				notifyCompleteAsync();
			}
			)) {
			LOG_RETURN(RES_FAIL, "m_thread->start() failed!");
		}
		return RES_OK;
	}

	Result BaseJob::getResult() const
	{
		if (!m_thread.wasJoinded()) {
			LOG_RETURN(RES_ILLEGAL_STATE, "Job is not complete!");
		}
		return m_result;
	}

	bool BaseJob::isCancelable() const
	{
		return m_isCancelable;
	}

	Result BaseJob::cancel()
	{
		if (!m_isCancelable) {
			LOG_RETURN(RES_NOT_SUPPORTED, "Not cancelable!");
		}
		if (isCancelled()) {
			return RES_FALSE;
		}
		m_isCancelled.store(true);
		return RES_OK;
	}

	bool BaseJob::isCancelled() const
	{
		return m_isCancelled.load();
	}

	void BaseJob::notifyCompleteAsync()
	{
		ecore_main_loop_thread_safe_call_async(
			[](void *data)
			{
				const auto selfPtr = static_cast<BaseJob **>(data);
				const auto self = *selfPtr;
				delete selfPtr;
				if (self) {
					self->m_selfPtr = nullptr;
					self->finish();
				}
			},
			m_selfPtr);
	}

	void BaseJob::finish()
	{
		if (!m_thread.wasJoinded()) {
			m_thread.join();
			if (m_selfPtr) {
				*m_selfPtr = nullptr;
			}
			if (m_onComplete) {
				m_onComplete();
			}
		}
	}
}