#include "testobj.h"
#include "testevent.h"
#include <QCoreApplication>
#include <QTextStream>
#include <QThread>
static const int testCounts = 10000;
static const int fillStrLen = 1024;
TestObj::TestObj(QObject *parent)
	: QObject{parent}
{

}

void TestObj::customEvent(QEvent * evt)
{
	if (evt->type()==TestMsg::type())
	{
		clock_t curr_clk = clock();
		if (m_nFirstClkEvt==-1)
			m_nFirstClkEvt = curr_clk;
		TestMsg * e = dynamic_cast<TestMsg *>(evt);
		if (e)
		{
			e->fillStr(fillStrLen);
			++m_nCount_Evts;
		}
		if (m_nCount_Evts==testCounts)
		{
			QTextStream strm(stdout);
			strm << objectName()<< QString().asprintf(" (%llX) run %d Events, total costs %.2lf ms, AVG cost %.2lf us /test.\n"
									   ,(unsigned long long)this
									   ,(int)(m_nCount_Evts)
									   ,1e3 * (curr_clk - m_nFirstClkEvt) / CLOCKS_PER_SEC
									   ,1e6 * (curr_clk - m_nFirstClkEvt) / testCounts / CLOCKS_PER_SEC
									   );
			strm.flush();
			emit evt_finished();
		}
	}
	else if (evt->type()==TestMsg::startEvt() && m_buddy)
	{
		m_buddy->m_nCount_Evts = 0;
		m_buddy->m_nFirstClkEvt = -1;
		run_event();
	}
	else if (evt->type()==TestMsg::startSig() &&m_buddy)
	{
		m_buddy->m_nCount_Sigs = 0;
		m_buddy->m_nFirstClkSig = -1;
		run_signal();
	}
	else if (evt->type()==TestMsg::quitEvt())
	{
		thread()->quit();
	}
}

void TestObj::test_slot16(QEvent * evt)
{

	clock_t curr_clk = clock();
	if (m_nFirstClkSig==-1)
		m_nFirstClkSig = curr_clk;

	TestMsg * e = dynamic_cast<TestMsg *>(evt);
	if (e)
	{
		++m_nCount_Sigs;
		e->fillStr(fillStrLen);
		if (m_nCount_Sigs==testCounts)
		{
			QTextStream strm(stdout);
			strm << objectName()<< QString().asprintf(" (%llX) run %d Signals, total costs %.2lf ms, AVG cost %.2lf us / test.\n"
									   ,(unsigned long long)this
									   ,(int)(m_nCount_Sigs)
									   ,1e3 * (curr_clk - m_nFirstClkSig) / CLOCKS_PER_SEC
									   ,1e6 * (curr_clk - m_nFirstClkSig) / CLOCKS_PER_SEC / testCounts
									   );
			strm.flush();
			emit sig_finished();
		}
		delete e;

	}
}

void TestObj::run_signal()
{
	for (int i=0;i<testCounts;++i)
		emit test_sig16(new TestMsg(clock()));
}
void TestObj::run_event()
{
	if (!m_buddy)
		return;
	for (int i=0;i<testCounts;++i)
		QCoreApplication::postEvent(m_buddy,new TestMsg(clock()));
}
void TestObj::runDirectCall()
{
	m_nCount_Dir = 0;
	m_nFirstClkDir = -1;
	printf("Test Direct Call...\n");
	for (int i=0;i<testCounts;++i)
	{
		direct_call(new TestMsg(clock()));
	}
}
void TestObj::direct_call(QEvent * evt)
{
	clock_t curr_clk = clock();
	if (m_nFirstClkDir==-1)
		m_nFirstClkDir = curr_clk;

	TestMsg * e = dynamic_cast<TestMsg *>(evt);
	if (e)
	{
		++m_nCount_Dir;
		e->fillStr(fillStrLen);
		if (m_nCount_Dir==testCounts)
		{
			QTextStream strm(stdout);
			strm << objectName()<< QString().asprintf(" (%llX) run %d Direct Calls, total costs %.2lf ms, AVG cost %.2lf us / test.\n"
													   ,(unsigned long long)this
													   ,(int)(m_nCount_Dir)
													   ,1e3 * (curr_clk - m_nFirstClkDir) / CLOCKS_PER_SEC
													   ,1e6 * (curr_clk - m_nFirstClkDir) / CLOCKS_PER_SEC / testCounts
													   );
			strm.flush();
		}
		delete e;
	}

}
