Last active
December 23, 2023 16:48
-
-
Save chrhlnd/6a7680d26121b8dbc2347ff44d9a8d40 to your computer and use it in GitHub Desktop.
Hmm Async?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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