CodePorting.Translator Cs2Cpp
CodePorting.Translator.Cs2Cpp.Framework
async.h
1
3#pragma once
4
5#include <functional>
6#include <system/object.h>
7#include <system/action.h>
8#include <system/threading/tasks/task.h>
9#include <system/threading/tasks/task_status.h>
10#include <system/threading/tasks/task_scheduler.h>
11#include <system/details/dereference.h>
12
13namespace System { namespace Details {
14
18struct ASPOSECPP_SHARED_CLASS AsyncContext
19{
22 AsyncContext(Threading::Tasks::Task* task) : m_task(task) {}
23
26 void Step(int32_t s) {stage = s;}
28 ASPOSECPP_SHARED_API void Return();
30 ASPOSECPP_SHARED_API void Continue();
38 template<typename T>
39 bool Await(const T& awaitee, int32_t step)
40 {
41 return AwaitImpl(awaitee, step, [](const auto& awaiter) { awaiter.GetResult(); });
42 }
52 template <typename T, typename V>
53 bool Await(const T& awaitee, V& value, int32_t step)
54 {
55 return AwaitImpl(awaitee, step, [&value](const auto& awaiter) { value = awaiter.GetResult(); });
56 }
57
59 int32_t stage = 0;
60
61protected:
70 template <typename AwaiteeT, typename ContinuerT>
71 bool AwaitImpl(const AwaiteeT& awaitee, int32_t step, const ContinuerT& continuer)
72 {
73 stage = step;
74
75 auto awaiter = Dereference(awaitee).GetAwaiter();
76 if (awaiter.get_IsCompleted())
77 {
78 continuer(awaiter);
79 return false;
80 }
81
83
84 auto continuationContext =
85 awaiter.continueOnCapturedContext
87 : nullptr;
88
89 awaiter.OnCompleted(Action<>([this, awaiter, continuer, continuationContext]
90 {
91 m_continuer = [awaiter, continuer](){continuer(awaiter);};
93 m_task->Activate(continuationContext);
94 }));
95
96 return true;
97 }
98
100 Threading::Tasks::Task* m_task;
102 std::function<void()> m_continuer;
103};
104
107using AsyncFunction = std::function<void(AsyncContext&)>;
108
112template<typename T>
113struct ResultAsyncContext : AsyncContext
114{
117 ResultAsyncContext(Threading::Tasks::ResultTask<T>* task) : AsyncContext(task), m_result_task(task) {}
118
123 void Return(const T& result)
124 {
125 m_result_task->set_Result(result);
126
127 AsyncContext::Return();
128 }
129
130protected:
132 Threading::Tasks::ResultTask<T>* m_result_task;
133};
134
139template<typename T>
140using ResultAsyncFunction = std::function<void(ResultAsyncContext<T>&)>;
141
142} // namespace Details
143
144ASPOSECPP_SHARED_API TaskPtr MakeAsync(const Details::AsyncFunction& fnc);
145
146template<typename T>
147RTaskPtr<T> MakeAsync(const Details::ResultAsyncFunction<T>& fnc)
148{
149 auto result = System::MakeObject<Threading::Tasks::ResultTask<T>>();
150 Details::ResultAsyncContext<T> context(result.GetPointer());
151 result->set_Function([fnc, context]() mutable { fnc(context); });
152 result->RunSynchronously();
153 return result;
154}
155
156} // namespace System
static SharedPtr< TaskScheduler > FromCurrentSynchronizationContext()
Creates a TaskScheduler associated with the current thread.
@ Continue
The 'Continue' status code that equals to HTTP status 100.
Definition: db_command.h:9
TaskPtr MakeAsync(const Details::AsyncFunction &fnc)