Skip to content

Instantly share code, notes, and snippets.

@chrhlnd
Last active December 23, 2023 16:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrhlnd/6a7680d26121b8dbc2347ff44d9a8d40 to your computer and use it in GitHub Desktop.
Save chrhlnd/6a7680d26121b8dbc2347ff44d9a8d40 to your computer and use it in GitHub Desktop.
Hmm Async?
#include <iostream>
#include <functional>
#include <vector>
#include <random>
static std::mt19937_64 gen{ std::random_device()() };
static std::uniform_real_distribution<double> dis{ 0.0, 1.0 };
using namespace std;
class AsyncTask
{
public:
enum class Res
{
Done,
More,
Error
};
using fnItem = function<Res()>;
private:
vector<fnItem> m_items;
bool m_running = false;
public:
template <typename ...Args>
void Do(Args&& ...fns){
auto insertAt = m_running ? m_items.begin() + 1 : m_items.end();
for (auto&& item : initializer_list<fnItem>{ fns... })
{
insertAt = m_items.insert(insertAt, item);
++insertAt;
}
}
bool Step()
{
if (m_items.empty())
return false;
m_running = true;
auto res = m_items[0]();
m_running = false;
switch (res)
{
case Res::Done:
m_items.erase(m_items.begin());
break;
case Res::More:
break;
case Res::Error:
return false;
}
return true;
}
};
namespace
{
double nextRandom()
{
return dis(gen);
}
AsyncTask::Res printHi()
{
std::cout << "Hi\n";
if (nextRandom() < .5)
return AsyncTask::Res::More;
return AsyncTask::Res::Done;
}
AsyncTask::Res printBye()
{
std::cout << "Bye\n";
if (nextRandom() < .5)
return AsyncTask::Res::More;
return AsyncTask::Res::Done;
}
AsyncTask::Res printFun()
{
std::cout << "Fun\n";
return AsyncTask::Res::Done;
}
AsyncTask::Res printStuff()
{
std::cout << "Stuff\n";
return AsyncTask::Res::Done;
}
struct print
{
string m_msg;
int m_count;
print(const string& msg, int count = 1)
: m_msg(msg)
, m_count(count)
{}
AsyncTask::Res operator()()
{
if (m_count--)
std::cout << m_msg;
return m_count ? AsyncTask::Res::More : AsyncTask::Res::Done;
}
};
struct doMore
{
AsyncTask& m_task;
doMore(AsyncTask& task)
: m_task(task)
{}
AsyncTask::Res operator()()
{
m_task.Do(
print("DoMore - Starting\n", 3),
printStuff,
printFun,
printStuff,
print("DoMore - Finishing\n", 3)
);
return AsyncTask::Res::Done;
}
};
}
int main()
{
auto task = AsyncTask();
task.Do(
printHi,
printBye,
doMore(task),
print("AllDone\n", 2)
);
while (task.Step()) {}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment