#include "RuntimeShaderBridge.h"

#include <chrono>

RuntimeShaderBridge::~RuntimeShaderBridge()
{
	Stop();
}

void RuntimeShaderBridge::Start(const std::string& shaderId, ArtifactCallback onArtifactReady, ErrorCallback onError)
{
	Stop();
	if (shaderId.empty())
		return;

	mOnArtifactReady = std::move(onArtifactReady);
	mOnError = std::move(onError);
	mStopping.store(false, std::memory_order_release);
	mCompiler.StartShaderBuild(shaderId);
	mThread = std::thread([this]() { ThreadMain(); });
}

void RuntimeShaderBridge::Stop()
{
	mStopping.store(true, std::memory_order_release);
	if (mThread.joinable())
		mThread.join();
	mCompiler.Stop();
	mOnArtifactReady = ArtifactCallback();
	mOnError = ErrorCallback();
}

void RuntimeShaderBridge::ThreadMain()
{
	while (!mStopping.load(std::memory_order_acquire))
	{
		RuntimeSlangShaderBuild build;
		if (mCompiler.TryConsume(build))
		{
			if (build.succeeded)
			{
				if (mOnArtifactReady)
					mOnArtifactReady(build.artifact);
			}
			else if (mOnError)
			{
				mOnError(build.message);
			}
			return;
		}
		std::this_thread::sleep_for(std::chrono::milliseconds(5));
	}
}
