Skip to content

Instantly share code, notes, and snippets.

@usagi
Last active May 1, 2016 08:55
Show Gist options
  • Save usagi/e64630658f4ac10565194f5fbcdc0e26 to your computer and use it in GitHub Desktop.
Save usagi/e64630658f4ac10565194f5fbcdc0e26 to your computer and use it in GitHub Desktop.
C++14 & boost::{coroutines|signals2} -> yieldable task system ref: http://qiita.com/usagi/items/6dad042e20ef1fe9f91c
#include <boost/coroutine/all.hpp>
#include <boost/signals2/signal.hpp>
#include <memory>
namespace usagi
{
class yieldable_task_system_type
{
boost::signals2::signal< auto () -> void > signal;
public:
template < typename COROUTINE_TYPE >
auto push( COROUTINE_TYPE&& coroutine ) -> void
{
push( boost::coroutines::coroutine< void >::pull_type( std::move( coroutine ) ) );
}
auto push( boost::coroutines::coroutine< void >::pull_type&& coroutine ) -> void
{
auto shared_coroutine = std::make_shared< boost::coroutines::coroutine< void >::pull_type >( std::move( coroutine ) );
auto shared_connection = std::make_shared< boost::signals2::connection >();
*shared_connection = signal.connect
( [ = ]
{
if ( not (*shared_coroutine)() )
shared_connection->disconnect();
}
);
}
auto consume_one() -> bool
{
signal();
return not signal.empty();
}
auto consume_all() -> void
{
while ( consume_one() );
}
auto operator()() -> void
{
consume_all();
}
};
}
#include "yieldable_task_system.hxx"
#include <chrono>
#include <iostream>
auto main() -> int
{
using namespace std::chrono;
usagi::yieldable_task_system_type yieldable_task_system;
yieldable_task_system.push
( [ t0 = high_resolution_clock::now() ]
( auto& yield )
{
std::cout << 'a' << std::flush;
yield();
do
{
std::cout << 'b' << std::flush;
yield();
}
while ( high_resolution_clock::now() - t0 < microseconds( 512 ) );
std::cout << 'c' << std::flush;
yield();
}
);
yieldable_task_system.push
( []
( auto& yield )
{
for ( const auto value : { 'X', 'Y', 'Z' } )
{
std::cout << value << std::flush;
yield();
}
}
);
yieldable_task_system.push
( []
( auto& yield )
{
std::cout << '1' << std::flush;
yield();
std::cout << '2' << std::flush;
yield();
}
);
yieldable_task_system();
}
aX1bY2bZbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment