Skip to content

Instantly share code, notes, and snippets.

@Steve132
Created October 19, 2023 06:04
Show Gist options
  • Save Steve132/d6569dd99912e932011d2cb9d11092d9 to your computer and use it in GitHub Desktop.
Save Steve132/d6569dd99912e932011d2cb9d11092d9 to your computer and use it in GitHub Desktop.
Eventy.hpp
#pragma once
#include<vector>
#include<cstdint>
#include<cstdlib>
#include<algorithm>
namespace eventy{
//An event returns either true or false...for what it gets turned into (alive (looping) or dead 0)
//another option is to have it return an unsigned int for priority (probably better for a little bit of scope). Also just we really really need my vector thing here.
using priority=uint32_t;
static constexpr priority DIE=0;
static constexpr priority STAY_ALIVE=1;
struct abstract_queue{
virtual size_t tick(size_t MAX=0xFFFFFF)=0;
virtual size_t size() const=0;
};
abstract_queue& get_global_queue();
template<class EventFunction>
static inline void later(EventFunction&& a);
namespace impl{
struct metaqueue: public abstract_queue{
protected:
std::vector<abstract_queue*> all_queues;
size_t qi=0;
void register_queue(abstract_queue* nb){
if(std::find(all_queues.cbegin(),all_queues.cend(),nb) == all_queues.cend()){
all_queues.push_back(nb);
}
}
friend struct normal_queue_base;
friend abstract_queue& get_global_queue();
public:
static metaqueue& global_instance(){
static metaqueue inst;
return inst;
}
virtual size_t tick(size_t MAX=0xFFFFFF){
size_t i=0;
bool get_to_end=false;
size_t zeros_count=0;
while(zeros_count < all_queues.size()){
auto& qptr=all_queues[qi];
if(qptr->size() == 0){
zeros_count++;
qi++;
if(all_queues.size()){
qi%=all_queues.size();
}
continue;
}
zeros_count=0;
i+=qptr->tick(MAX-i);
if(i >= MAX) {
break;
};
}
return i;
}
virtual size_t size() const{
size_t sm = 0;
for (const auto& q : all_queues) {
sm += q->size();
}
return sm;
}
};
struct normal_queue_base: public abstract_queue{
normal_queue_base(){
metaqueue::global_instance().register_queue(this);
}
};
template<class EventType>
struct event_queue: public impl::normal_queue_base{
private:
std::vector<EventType> pool;
size_t qi=0;
void enqueue(EventType&& a){
pool.emplace_back(std::forward<EventType>(a));
}
static event_queue& instance(){
static event_queue inst;
return inst;
}
friend void later<EventType>(EventType&&);
public:
virtual size_t size() const{
return pool.size();
}
/*warning: single threaded.*/
virtual size_t tick(size_t MAX=0xFFFFFF){
size_t i=0;
if(MAX == 0) return 0;
while(i < MAX && pool.size() > 0){
auto& evt=pool[qi];
auto ret=evt();
if(int(ret) == DIE){
pool[qi]=std::move(pool.back());
pool.erase(pool.end()-1);
}
qi++;
if(pool.size()) {qi%=pool.size();};
i++;
}
return i;
}
};
}
template<class EventFunction>
static inline void later(EventFunction&& a){
impl::event_queue<EventFunction>::instance().enqueue(std::forward<EventFunction>(a));
}
abstract_queue& get_global_queue(){
return impl::metaqueue::global_instance();
}
size_t tick(size_t MAX=0xFFFFFF){
return get_global_queue().tick(MAX);
}
}
#include "eventy.hpp"
#include<iostream>
int main(int argc,char**){
eventy::later([](){ std::cout << "Hello, world"; return false; });
eventy::tick();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment