CodePorting.Translator Cs2Cpp
CodePorting.Translator.Cs2Cpp.Framework
async.h
1
3#pragma once
4
5#include <functional>
6#include <system/object_ext.h>
7#include <system/action.h>
8#include <system/threading/tasks/result_task.h>
9#include <system/threading/tasks/task_status.h>
10#include <system/details/dereference.h>
11
12namespace System { namespace Details {
13
17struct ASPOSECPP_SHARED_CLASS AsyncContextBase
18{
21 void Step(int32_t s) {stage = s;}
23 ASPOSECPP_SHARED_API void Continue();
31 template<typename T>
32 bool Await(const T& awaitee, int32_t step)
33 {
34 return AwaitImpl(awaitee, step, [](const auto& awaiter) { awaiter.GetResult(); });
35 }
45 template <typename T, typename V>
46 bool Await(const T& awaitee, V& value, int32_t step)
47 {
48 return AwaitImpl(awaitee, step, [&value](const auto& awaiter) { value = ExplicitCast<V>(awaiter.GetResult()); });
49 }
50
52 ASPOSECPP_SHARED_API void operator()();
53
55 int32_t stage = 0;
56
57protected:
59 using Continuer = std::function<void()>;
60
62 virtual Threading::Tasks::Task* get_Task() const = 0;
64 virtual void Execute() = 0;
73 template <typename AwaiteeT, typename ContinuerT>
74 bool AwaitImpl(const AwaiteeT& awaitee, int32_t step, const ContinuerT& continuer)
75 {
76 stage = step;
77
78 // Getting awaiter instance
79 auto awaiter = Dereference(awaitee).GetAwaiter();
80
81 // Trying to avoid sleeping if awaiter completed already
82 if (awaiter.get_IsCompleted())
83 {
84 continuer(awaiter);
85 return false;
86 }
87
88 // Going to suspend
89 Suspend([awaiter, continuer]() { continuer(awaiter); });
90
91 // Setting up resume context (we need to get it here because resuming should be executed in other context)
92 auto continuationContext = GetResumeScheduler(awaiter.continueOnCapturedContext);
93
94 // Setting up resume action
95 awaiter.OnCompleted(Action<>([this, continuationContext] { Resume(continuationContext); }));
96
97 return true;
98 }
100 ASPOSECPP_SHARED_API void Suspend(Continuer&& continuer);
102 ASPOSECPP_SHARED_API Threading::Tasks::TaskScheduler* GetResumeScheduler(bool continueOnCapturedContext) const;
104 ASPOSECPP_SHARED_API void Resume(Threading::Tasks::TaskScheduler* context);
105
107 Continuer m_continuer;
109 bool m_executing = false;
111 Threading::Tasks::TaskScheduler* m_activator = nullptr;
112};
113
116using AsyncFunction = std::function<void(struct AsyncContext&)>;
117
120struct AsyncContext : AsyncContextBase
121{
124 AsyncContext(Threading::Tasks::Task* task, const AsyncFunction& fnc) : m_task(task), m_function(fnc)
125 {}
126
128 ASPOSECPP_SHARED_API void Return();
129
130protected:
132 Threading::Tasks::Task* get_Task() const override {return m_task;}
134 void Execute() override {m_function(*this);}
135
137 Threading::Tasks::Task* m_task;
139 AsyncFunction m_function;
140};
141
142template<typename T>
143struct ResultAsyncContext;
144
149template <typename T>
150using ResultAsyncFunction = std::function<void(ResultAsyncContext<T>&)>;
151
155template<typename T>
156struct ResultAsyncContext : AsyncContextBase
157{
160 ResultAsyncContext(Threading::Tasks::ResultTask<T>* task, const ResultAsyncFunction<T>& fnc) : m_result_task(task), m_function(fnc)
161 {}
162
167 void Return(const T& result)
168 {
169 m_result_task->set_Result(result);
170 m_result_task->set_Status(Threading::Tasks::TaskStatus::RanToCompletion);
171 }
172
173protected:
175 Threading::Tasks::Task* get_Task() const override {return m_result_task;}
177 void Execute() override {m_function(*this);}
178
180 Threading::Tasks::ResultTask<T>* m_result_task;
182 ResultAsyncFunction<T> m_function;
183};
184
185} // namespace Details
186
187ASPOSECPP_SHARED_API TaskPtr MakeAsync(const Details::AsyncFunction& fnc);
188
189template<typename T>
190RTaskPtr<T> MakeAsync(const Details::ResultAsyncFunction<T>& fnc)
191{
192 auto result = System::MakeObject<Threading::Tasks::ResultTask<T>>();
193 result->set_Function(Details::ResultAsyncContext<T>(result.GetPointer(), fnc));
194 result->RunSynchronously();
195 return result;
196}
197
198} // namespace System
void set_Function(const FunctionT &fnc)
Sets the internal function to execute.
Definition: task.h:125
@ Suspend
Suspension of a logical operation.
@ Resume
Resumption of a logical operation.
@ Continue
The 'Continue' status code that equals to HTTP status 100.
Definition: db_command.h:9
TaskPtr MakeAsync(const Details::AsyncFunction &fnc)