Browse Source

支持generator,完成相关范例

tags/v2.9.7
tearshark 4 years ago
parent
commit
8d580dcda4

+ 1
- 1
librf/src/def.h View File

@@ -67,7 +67,7 @@ namespace resumef
template<typename _PromiseT = void>
using coroutine_handle = std::experimental::coroutine_handle<_PromiseT>;
template <typename _Ty, typename _Alloc = std::allocator<char>>
template <typename _Ty = std::nullptr_t, typename _Alloc = std::allocator<char>>
using generator_t = std::experimental::generator<_Ty, _Alloc>;
enum struct error_code

+ 9
- 2
librf/src/generator.h View File

@@ -166,13 +166,13 @@ namespace experimental {
void *operator new(size_t _Size)
{
_Alloc_of_char_type _Al;
_Alloc_char _Al;
return _Al.allocate(_Size);
}
void operator delete(void *_Ptr, size_t _Size)
{
_Alloc_of_char_type _Al;
_Alloc_char _Al;
return _Al.deallocate(static_cast<char *>(_Ptr), _Size);
}
};
@@ -228,6 +228,13 @@ namespace experimental {
}
}
coroutine_handle<promise_type> detach()
{
auto t = _Coro;
_Coro = nullptr;
return t;
}
private:
coroutine_handle<promise_type> _Coro = nullptr;
};

+ 31
- 18
librf/src/rf_task.h View File

@@ -13,8 +13,13 @@ namespace resumef
RF_API task_base_t();
RF_API virtual ~task_base_t();
virtual state_base_t * get_state() const = 0;
state_base_t* get_state() const
{
return _state.get();
}
protected:
counted_ptr<state_base_t> _state;
public:
task_base_t* _next_node;
task_base_t* _prev_node;
};
@@ -31,17 +36,34 @@ namespace resumef
using future_type = future_t<value_type>;
using state_type = state_t<value_type>;
counted_ptr<state_type> _state;
task_t() = default;
task_t(future_type && f)
: _state(std::move(f._state))
{
initialize(std::forward<future_type>(f));
}
protected:
void initialize(future_type&& f)
{
_state = f._state.get();
}
};
virtual state_base_t * get_state() const
template<class _Ty>
struct task_t<generator_t<_Ty>> : public task_base_t
{
using value_type = _Ty;
using future_type = generator_t<value_type>;
using state_type = state_generator_t;
task_t() = default;
task_t(future_type&& f)
{
return _state.get();
initialize(std::forward<future_type>(f));
}
protected:
void initialize(future_type&& f)
{
_state = new state_type(f.detach());
}
};
@@ -51,25 +73,16 @@ namespace resumef
//这个'函数对象'被调用后,返回generator<_Ty>/future_t<_Ty>类型
//然后'函数对象'作为异步执行的上下文状态保存起来
template<class _Ctx>
struct ctx_task_t : public task_base_t
struct ctx_task_t : public task_t<typename std::remove_cvref<decltype(std::declval<_Ctx>()())>::type>
{
using context_type = _Ctx;
using future_type = typename std::remove_cvref<decltype(std::declval<_Ctx>()())>::type;
using value_type = typename future_type::value_type;
using state_type = state_t<value_type>;
context_type _context;
counted_ptr<state_type> _state;
ctx_task_t(context_type ctx)
: _context(std::move(ctx))
{
_state = _context()._state;
}
virtual state_base_t* get_state() const
{
return _state.get();
this->initialize(_context());
}
};
}

+ 4
- 4
librf/src/scheduler.h View File

@@ -40,13 +40,13 @@ namespace resumef
RF_API void run();
//RF_API void break_all();
template<class _Ty, typename = std::enable_if_t<std::is_callable_v<_Ty> || is_future_v<_Ty>>>
template<class _Ty, typename = std::enable_if_t<std::is_callable_v<_Ty> || is_future_v<_Ty> || is_generator_v<_Ty> >>
inline void operator + (_Ty && t_)
{
if constexpr(is_future_v<_Ty>)
new_task(new task_t<_Ty>(std::forward<_Ty>(t_)));
else
if constexpr(std::is_callable_v<_Ty>)
new_task(new ctx_task_t<_Ty>(std::forward<_Ty>(t_)));
else
new_task(new task_t<_Ty>(std::forward<_Ty>(t_)));
}
inline bool empty() const

+ 5
- 0
librf/src/state.cpp View File

@@ -15,9 +15,14 @@ namespace resumef
{
_coro.resume();
if (_coro.done())
{
_coro = nullptr;
_scheduler->del_final(this);
}
else
{
_scheduler->add_generator(this);
}
}
}

+ 8
- 2
librf/src/state.h View File

@@ -20,8 +20,8 @@ namespace resumef
coroutine_handle<> _coro;
public:
virtual void resume() = 0;
virtual bool is_ready() const = 0;
virtual bool has_handler() const = 0;
virtual bool is_ready() const = 0;
void set_scheduler(scheduler_t* sch)
{
@@ -35,9 +35,15 @@ namespace resumef
struct state_generator_t : public state_base_t
{
public:
state_generator_t(coroutine_handle<> handler)
{
_coro = handler;
}
virtual void resume() override;
virtual bool is_ready() const override;
virtual bool has_handler() const override;
virtual bool is_ready() const override;
};
struct state_future_t : public state_base_t

+ 1
- 1
tutorial/test_async_resumable.cpp View File

@@ -46,7 +46,7 @@ void resumable_switch(intptr_t coro, size_t idx)
{
for (intptr_t i = 0; i < N / coro; ++i)
co_yield i;
return N / coro;
co_return N / coro;
};
}
auto middle = std::chrono::steady_clock::now();

+ 2
- 3
tutorial/test_async_yield_return.cpp View File

@@ -9,8 +9,7 @@
using namespace resumef;
//std::experimental::generator<int>
auto test_yield_int() -> std::experimental::generator<int>
auto test_yield_int() -> generator_t<int>
{
std::cout << "1 will yield return" << std::endl;
co_yield 1;
@@ -43,7 +42,7 @@ auto test_yield_void()
}
*/
auto test_yield_void() -> std::experimental::generator<std::nullptr_t>
auto test_yield_void() -> generator_t<>
{
std::cout << "block 1 will yield return" << std::endl;
co_yield_void;

+ 3
- 4
vs_proj/librf.cpp View File

@@ -30,11 +30,12 @@ int main(int argc, const char* argv[])
{
//resumable_main_cb();
//resumable_main_suspend_always();
resumable_main_routine();
//resumable_main_yield_return();
resumable_main_resumable();
//resumable_main_routine();
//resumable_main_exception();
/*
resumable_main_resumable();
resumable_main_benchmark_mem();
if (argc > 1)
resumable_main_benchmark_asio_client(atoi(argv[1]));
@@ -43,10 +44,8 @@ int main(int argc, const char* argv[])
resumable_main_when_all();
resumable_main_multi_thread();
resumable_main_yield_return();
resumable_main_timer();
resumable_main_sleep();
resumable_main_resumable();
resumable_main_mutex();
resumable_main_event();
resumable_main_event_timeout();

+ 1
- 4
vs_proj/librf.vcxproj View File

@@ -243,10 +243,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_resumable.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_resumable.cpp" />
<ClCompile Include="..\tutorial\test_async_routine.cpp" />
<ClCompile Include="..\tutorial\test_async_sleep.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>

Loading…
Cancel
Save