#include <iostream>
#include <thread>
#include <mutex>
#include <Windows.h>
// callback test
/////////////////////////////////////////////////////////////
// API part
typedef void(__stdcall *CallbackEvent)(const char* pStr, bool bOK, void * any);
/////////////////////////////////////////////////////////////
// API part
class API
{
public:
	API() = delete;
	API(CallbackEvent pCallBack, const char* pStr, bool bOK, void * any=nullptr)
		:
		mpStr	  (pStr	  )	  ,
		mbOK	  (bOK	  )	  ,
		mpCallBack(pCallBack) ,
		mAny	  (any)
	{
		mThread = std::make_unique<std::thread>(&API::run, this);
		mThread->detach();
	}
	~API(){};
	void run()
	{
		int i = 0;
		while (true)
		{
			Sleep(50);
			if (i % 10 == 0)
			{
				// start callback event
				//auto str = std::to_string(i);
				mpCallBack(mpStr, mbOK, mAny);
			}
			std::cout << "i = " << i << std::endl;
			++i;
			if (i == 200)
			{
				break;
			}
		}
	}
private:
	std::unique_ptr<std::thread> mThread    ;
	CallbackEvent	mpCallBack;
	// parameter of callback function.
	const char*		mpStr		;
	bool			mbOK		;
	void *			mAny		;
};
/////////////////////////////////////////////////////////////
typedef struct passToCallbackFun
{
	passToCallbackFun(int w, int h) 
		: 
		width (w),
		height(h)
	{}
	int width ;
	int height;
} ImgSize;
// user definition
void __stdcall onCallback(const char* pStr, bool ok,  void * any)
{
	std::cout << "doing: " << pStr << ", ok = " << ok << std::endl;
	if (any == nullptr) return;
	ImgSize* iSize = (ImgSize*)any;
	std::cout << "size: w=" << iSize->width << ", h= " << iSize->height << std::endl;
}
/////////////////////////////////////////////////////////////
int main()
{
	// register callback event
	std::string str("adc");
	ImgSize isize(10, 20);
	API api(onCallback, str.c_str(), true, &isize);
	// hold main thread
	int i = 0;
	while (true)
	{
		Sleep(50);
		if (i % 10 == 0)
		{
			// do something
		}
		//std::cout << "i = " << i << std::endl;
		++i;
		if (i == 200)
		{
			break;
		}
	}
	return 0;
}