#ifndef _zloop_hpp_
#define _zloop_hpp_
#include <vector>
#include <list>
#include <atomic>
#include <mutex>
#include <assert.h>
#include <ev++.h>

struct zloop_base:ev::dynamic_loop
//struct zloop_base:ev::loop_ref
{
	std::atomic<bool>  m_stop_flag{false};
	ev::async m_async;

	int check_stop_flag()
	{
		if(!m_stop_flag.load())
			return 0;

		break_loop(ev::ALL);
		return 1;
	}

	virtual void on_async_0(){}

	void async_stop()
	{
		m_stop_flag.store(true);
		m_async.send();
	}

	zloop_base()
		:m_async(*this)
	{
		m_async.set<zloop_base,&zloop_base::on_async_0>(this);
		m_async.start();
	}

	virtual ~zloop_base()
	{
		m_async.stop();
	}
};

template<typename NT>
struct zloop:zloop_base
{
	std::mutex m_mutex;
	std::list<NT> m_async_list;

	virtual void on_async_0()
	{
		if(check_stop_flag()) 
			return;

		std::list<NT> async_list;
		{
			std::unique_lock<std::mutex> _lock(m_mutex);
			m_async_list.swap(async_list);
		}
		on_async(async_list);
	
	}

	virtual void on_async(const std::list<NT>&nt){}

	void async_request(NT tk)
	{
		{
			std::unique_lock<std::mutex> _lock(m_mutex);
			m_async_list.push_back(tk);
		}

		m_async.send();
	}

	zloop()
	{
	}

	~zloop()
	{
	}
};
#endif