Legends-of-Azeroth-Pandaria-5.4.8

Форк
0
229 строк · 5.7 Кб
1
/*
2
* This file is part of the Pandaria 5.4.8 Project. See THANKS file for Copyright information
3
*
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the
6
* Free Software Foundation; either version 2 of the License, or (at your
7
* option) any later version.
8
*
9
* This program is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
* more details.
13
*
14
* You should have received a copy of the GNU General Public License along
15
* with this program. If not, see <http://www.gnu.org/licenses/>.
16
*/
17

18
#include "TaskScheduler.h"
19

20
TaskScheduler& TaskScheduler::ClearValidator()
21
{
22
    _predicate = EmptyValidator;
23
    return *this;
24
}
25

26
TaskScheduler& TaskScheduler::Update(success_t const& callback)
27
{
28
    _now = clock_t::now();
29
    Dispatch(callback);
30
    return *this;
31
}
32

33
TaskScheduler& TaskScheduler::Update(size_t const milliseconds, success_t const& callback)
34
{
35
    return Update(std::chrono::milliseconds(milliseconds), callback);
36
}
37

38
TaskScheduler& TaskScheduler::Async(std::function<void()> const& callable)
39
{
40
    _asyncHolder.push(callable);
41
    return *this;
42
}
43

44
TaskScheduler& TaskScheduler::CancelAll()
45
{
46
    /// Clear the task holder
47
    _task_holder.Clear();
48
    _asyncHolder = AsyncHolder();
49
    return *this;
50
}
51

52
TaskScheduler& TaskScheduler::CancelGroup(group_t const group)
53
{
54
    _task_holder.RemoveIf([group](TaskContainer const& task) -> bool
55
    {
56
        return task->IsInGroup(group);
57
    });
58
    return *this;
59
}
60

61
TaskScheduler& TaskScheduler::CancelGroupsOf(std::vector<group_t> const& groups)
62
{
63
    std::for_each(groups.begin(), groups.end(),
64
        std::bind(&TaskScheduler::CancelGroup, this, std::placeholders::_1));
65

66
    return *this;
67
}
68

69
TaskScheduler& TaskScheduler::InsertTask(TaskContainer task)
70
{
71
    _task_holder.Push(std::move(task));
72
    return *this;
73
}
74

75
void TaskScheduler::Dispatch(success_t const& callback)
76
{
77
    // If the validation failed abort the dispatching here.
78
    if (!_predicate())
79
        return;
80

81
    // Process all asyncs
82
    while (!_asyncHolder.empty())
83
    {
84
        _asyncHolder.front()();
85
        _asyncHolder.pop();
86

87
        // If the validation failed abort the dispatching here.
88
        if (!_predicate())
89
            return;
90
    }
91

92
    while (!_task_holder.IsEmpty())
93
    {
94
        if (_task_holder.First()->_end > _now)
95
            break;
96

97
        // Perfect forward the context to the handler
98
        // Use weak references to catch destruction before callbacks.
99
        TaskContext context(_task_holder.Pop(), std::weak_ptr<TaskScheduler>(self_reference));
100

101
        // Invoke the context
102
        context.Invoke();
103

104
        // If the validation failed abort the dispatching here.
105
        if (!_predicate())
106
            return;
107
    }
108

109
    // On finish call the final callback
110
    callback();
111
}
112

113
void TaskScheduler::TaskQueue::Push(TaskContainer&& task)
114
{
115
    container.insert(task);
116
}
117

118
auto TaskScheduler::TaskQueue::Pop() -> TaskContainer
119
{
120
    TaskContainer result = *container.begin();
121
    container.erase(container.begin());
122
    return result;
123
}
124

125
auto TaskScheduler::TaskQueue::First() const -> TaskContainer const&
126
{
127
    return *container.begin();
128
}
129

130
void TaskScheduler::TaskQueue::Clear()
131
{
132
    container.clear();
133
}
134

135
void TaskScheduler::TaskQueue::RemoveIf(std::function<bool(TaskContainer const&)> const& filter)
136
{
137
    for (auto itr = container.begin(); itr != container.end();)
138
        if (filter(*itr))
139
            itr = container.erase(itr);
140
        else
141
            ++itr;
142
}
143

144
void TaskScheduler::TaskQueue::ModifyIf(std::function<bool(TaskContainer const&)> const& filter)
145
{
146
    std::vector<TaskContainer> cache;
147
    for (auto itr = container.begin(); itr != container.end();)
148
        if (filter(*itr))
149
        {
150
            cache.push_back(*itr);
151
            itr = container.erase(itr);
152
        }
153
        else
154
            ++itr;
155

156
    container.insert(cache.begin(), cache.end());
157
}
158

159
bool TaskScheduler::TaskQueue::IsEmpty() const
160
{
161
    return container.empty();
162
}
163

164
TaskContext& TaskContext::Dispatch(std::function<TaskScheduler&(TaskScheduler&)> const& apply)
165
{
166
    if (auto const owner = _owner.lock())
167
        apply(*owner);
168

169
    return *this;
170
}
171

172
bool TaskContext::IsExpired() const
173
{
174
    return _owner.expired();
175
}
176

177
bool TaskContext::IsInGroup(TaskScheduler::group_t const group) const
178
{
179
    return _task->IsInGroup(group);
180
}
181

182
TaskContext& TaskContext::SetGroup(TaskScheduler::group_t const group)
183
{
184
    _task->_group = group;
185
    return *this;
186
}
187

188
TaskContext& TaskContext::ClearGroup()
189
{
190
    _task->_group = std::numeric_limits<uint32>::max();
191
    return *this;
192
}
193

194
TaskScheduler::repeated_t TaskContext::GetRepeatCounter() const
195
{
196
    return _task->_repeated;
197
}
198

199
TaskContext& TaskContext::Async(std::function<void()> const& callable)
200
{
201
    return Dispatch(std::bind(&TaskScheduler::Async, std::placeholders::_1, callable));
202
}
203

204
TaskContext& TaskContext::CancelAll()
205
{
206
    return Dispatch(std::mem_fn(&TaskScheduler::CancelAll));
207
}
208

209
TaskContext& TaskContext::CancelGroup(TaskScheduler::group_t const group)
210
{
211
    return Dispatch(std::bind(&TaskScheduler::CancelGroup, std::placeholders::_1, group));
212
}
213

214
TaskContext& TaskContext::CancelGroupsOf(std::vector<TaskScheduler::group_t> const& groups)
215
{
216
    return Dispatch(std::bind(&TaskScheduler::CancelGroupsOf, std::placeholders::_1, std::cref(groups)));
217
}
218

219
void TaskContext::AssertOnConsumed() const
220
{
221
    // This was adapted to TC to prevent static analysis tools from complaining.
222
    // If you encounter this assertion check if you repeat a TaskContext more then 1 time!
223
    ASSERT(!(*_consumed) && "Bad task logic, task context was consumed already!");
224
}
225

226
void TaskContext::Invoke()
227
{
228
    _task->_task(*this);
229
}
230

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.