
#include "MainLoop.h"

// Live++ API
#include "LivePP/API/x64/LPP_API_x64_CPP.h"


static lpp::LppSynchronizedAgent g_lppAgent = {};

extern "C" __declspec(dllexport) void __cdecl NativeModuleStartup(void)
{
	// create a synchronized Live++ agent
	g_lppAgent = lpp::LppCreateSynchronizedAgent(nullptr, L"../../../LivePP");
	g_lppAgent.EnableModule(lpp::LppGetCurrentModulePath(), lpp::LPP_MODULES_OPTION_NONE, nullptr, nullptr);

	// init the example
	MainLoop::Init("Example 13: Arbitrary target");
	MainLoop::Announce(g_lppAgent, "../../readme/README_ArbitraryTarget.txt");
}


extern "C" __declspec(dllexport) void __cdecl NativeModuleShutdown(void)
{
	MainLoop::Exit();

	lpp::LppDestroySynchronizedAgent(&g_lppAgent);
}


extern "C" __declspec(dllexport) bool __cdecl NativeModuleFrame(void)
{
	const bool shouldRun = MainLoop::PollInput(g_lppAgent);
	if (!shouldRun)
	{
		return false;
	}
	
	// listen to hot-reload and hot-restart requests
	if (g_lppAgent.WantsReload(lpp::LPP_RELOAD_OPTION_SYNCHRONIZE_WITH_RELOAD))
	{
		// Live++: client code can do whatever it wants here, e.g. synchronize across several threads, the network, etc.
		g_lppAgent.Reload(lpp::LPP_RELOAD_BEHAVIOUR_WAIT_UNTIL_CHANGES_ARE_APPLIED);
	}

	if (g_lppAgent.WantsRestart())
	{
		// Live++: client code can do whatever it wants here, e.g. finish logging, abandon threads, etc.
		g_lppAgent.Restart(lpp::LPP_RESTART_BEHAVIOUR_INSTANT_TERMINATION, 0u, nullptr);
	}

	// run the main loop
	MainLoop::Update();
	MainLoop::Render();
	MainLoop::Present();

	return true;
}
