<commit_before>#include "VideodrommLiveCodingApp.h"

void VideodrommLiveCodingApp::prepare(Settings *settings)
{
	settings->setWindowSize(640, 480);
	//settings->setBorderless();
	settings->setWindowPos(0, 0);
}
void VideodrommLiveCodingApp::setup()
{
	// Settings
	mVDSettings = VDSettings::create();
	// Session
	mVDSession = VDSession::create(mVDSettings);

	mVDSession->getWindowsResolution();
	setWindowSize(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);

	mVDSettings->iResolution.x = mVDSettings->mRenderWidth;
	mVDSettings->iResolution.y = mVDSettings->mRenderHeight;
	// UI
	mVDUI = VDUI::create(mVDSettings, mVDSession);

	mouseGlobal = false;
	mFadeInDelay = true;
	// mouse cursor and UI
	setUIVisibility(mVDSettings->mCursorVisible);
	// windows
	mIsShutDown = false;
	isWindowReady = false;
	mMainWindow = getWindow();
	mMainWindow->getSignalDraw().connect(std::bind(&VideodrommLiveCodingApp::drawMain, this));
	mMainWindow->getSignalResize().connect(std::bind(&VideodrommLiveCodingApp::resizeWindow, this));
	if (mVDSettings->mStandalone) {
		createRenderWindow();
		setWindowSize(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);
		}
		else {

		}
	setFrameRate(mVDSession->getTargetFps());
	CI_LOG_V("setup");

}
void VideodrommLiveCodingApp::createRenderWindow()
{
	isWindowReady = false;
	mVDUI->resize();

	deleteRenderWindows();
	mVDSession->getWindowsResolution();

	mVDSettings->iResolution.x = mVDSettings->mRenderWidth;
	mVDSettings->iResolution.y = mVDSettings->mRenderHeight;

	CI_LOG_V("createRenderWindow, resolution:" + toString(mVDSettings->iResolution.x) + "x" + toString(mVDSettings->iResolution.y));

	string windowName = "render";
	mRenderWindow = createWindow(Window::Format().size(mVDSettings->iResolution.x, mVDSettings->iResolution.y));

	// create instance of the window and store in vector
	allRenderWindows.push_back(mRenderWindow);

	mRenderWindow->setBorderless();
	mRenderWindow->getSignalDraw().connect(std::bind(&VideodrommLiveCodingApp::drawRender, this));
	mVDSettings->mRenderPosXY = ivec2(mVDSettings->mRenderX, mVDSettings->mRenderY);//20141214 was 0
	mRenderWindow->setPos(50, 50);
	mRenderWindowTimer = 0.0f;
	timeline().apply(&mRenderWindowTimer, 1.0f, 2.0f).finishFn([&]{ positionRenderWindow(); });
}
void VideodrommLiveCodingApp::positionRenderWindow()
{
	mRenderWindow->setPos(mVDSettings->mRenderX, mVDSettings->mRenderY);
	isWindowReady = true;
}
void VideodrommLiveCodingApp::deleteRenderWindows()
{
#if defined( CINDER_MSW )
	for (auto wRef : allRenderWindows) DestroyWindow((HWND)mRenderWindow->getNative());
#endif
	allRenderWindows.clear();
}
void VideodrommLiveCodingApp::setUIVisibility(bool visible)
{
	if (visible)
	{
		showCursor();
	}
	else
	{
		hideCursor();
	}
}
void VideodrommLiveCodingApp::update()
{
	mVDSession->setControlValue(mVDSettings->IFPS, getAverageFps());
	mVDSession->update();
}
void VideodrommLiveCodingApp::cleanup()
{
	if (!mIsShutDown)
	{
		mIsShutDown = true;
		CI_LOG_V("shutdown");
		ui::disconnectWindow(getWindow());
		ui::Shutdown();
		// save settings
		mVDSettings->save();
		mVDSession->save();
		deleteRenderWindows();
		quit();
	}
}

void VideodrommLiveCodingApp::mouseMove(MouseEvent event)
{
	if (!mVDSession->handleMouseMove(event)) {
		// let your application perform its mouseMove handling here
	}
}

void VideodrommLiveCodingApp::mouseDown(MouseEvent event)
{
	if (!mVDSession->handleMouseDown(event)) {
		// let your application perform its mouseDown handling here
	}
}

void VideodrommLiveCodingApp::mouseDrag(MouseEvent event)
{
	if (!mVDSession->handleMouseDrag(event)) {
		// let your application perform its mouseDrag handling here
	}
}

void VideodrommLiveCodingApp::mouseUp(MouseEvent event)
{
	if (!mVDSession->handleMouseUp(event)) {
		// let your application perform its mouseUp handling here
	}
}
void VideodrommLiveCodingApp::keyDown(KeyEvent event)
{
#if defined( CINDER_COCOA )
	bool isModDown = event.isMetaDown();
#else // windows
	bool isModDown = event.isControlDown();
#endif
	if (isModDown) {
		switch (event.getCode()) {
		case KeyEvent::KEY_r:
			// quit the application
			createRenderWindow();
			break;
		case KeyEvent::KEY_d:
			// quit the application
			if (isModDown) deleteRenderWindows();
			break;
		}
	}
	else {
		if (!mVDSession->handleKeyDown(event)) {
			switch (event.getCode()) {
			case KeyEvent::KEY_ESCAPE:
				// quit the application
				quit();
				break;
			case KeyEvent::KEY_h:
				// mouse cursor and ui visibility
				mVDSettings->mCursorVisible = !mVDSettings->mCursorVisible;
				setUIVisibility(mVDSettings->mCursorVisible);
				break;
			}
		}
	}
}

void VideodrommLiveCodingApp::keyUp(KeyEvent event)
{
	if (!mVDSession->handleKeyUp(event)) {
	}
}
void VideodrommLiveCodingApp::resizeWindow()
{
	mVDUI->resize();
	//mVDSession->resize();
}
void VideodrommLiveCodingApp::fileDrop(FileDropEvent event)
{
	mVDSession->fileDrop(event);
}

void VideodrommLiveCodingApp::drawRender()
{
	gl::clear(Color::black());
	//gl::setMatricesWindow(toPixels(getWindowSize()));
	if (mFadeInDelay) {
		mVDSettings->iAlpha = 0.0f;
		if (getElapsedFrames() > mVDSession->getFadeInDelay()) {
			mFadeInDelay = false;
			// warps resize at the end
			mVDSession->resize();
			timeline().apply(&mVDSettings->iAlpha, 0.0f, 1.0f, 1.5f, EaseInCubic());
		}
	}
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	if (isWindowReady) 	gl::draw(mVDSession->getRenderTexture(), getWindowBounds());
}

void VideodrommLiveCodingApp::drawMain()
{
	mMainWindow->setTitle(mVDSettings->sFps + " fps Live Coding");

	gl::clear(Color::black());
	//	gl::setMatricesWindow(toPixels(getWindowSize()));
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	gl::draw(mVDSession->getRenderTexture(), getWindowBounds());
	//gl::draw(mVDSession->getStreamedTexture(), getWindowBounds());
	// imgui
	if (!mVDSettings->mCursorVisible) return;

	mVDUI->Run("UI", (int)getAverageFps());
	if (mVDUI->isReady()) {
	}

}

CINDER_APP(VideodrommLiveCodingApp, RendererGl, &VideodrommLiveCodingApp::prepare)

<commit_msg>Spout Output<commit_after>#include "VideodrommLiveCodingApp.h"

void VideodrommLiveCodingApp::prepare(Settings *settings)
{
	settings->setWindowSize(640, 480);
	//settings->setBorderless();
	settings->setWindowPos(0, 0);
}
void VideodrommLiveCodingApp::setup()
{
	// Settings
	mVDSettings = VDSettings::create();
	// Session
	mVDSession = VDSession::create(mVDSettings);

	mVDSession->getWindowsResolution();
	setWindowSize(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);

	mVDSettings->iResolution.x = mVDSettings->mRenderWidth;
	mVDSettings->iResolution.y = mVDSettings->mRenderHeight;
	// UI
	mVDUI = VDUI::create(mVDSettings, mVDSession);

	mouseGlobal = false;
	mFadeInDelay = true;
	// mouse cursor and UI
	setUIVisibility(mVDSettings->mCursorVisible);
	// windows
	mIsShutDown = false;
	isWindowReady = false;
	mMainWindow = getWindow();
	mMainWindow->getSignalDraw().connect(std::bind(&VideodrommLiveCodingApp::drawMain, this));
	mMainWindow->getSignalResize().connect(std::bind(&VideodrommLiveCodingApp::resizeWindow, this));
	if (mVDSettings->mStandalone) {
		createRenderWindow();
		setWindowSize(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);
		}
		else {

		}
	setFrameRate(mVDSession->getTargetFps());
	CI_LOG_V("setup");

}
void VideodrommLiveCodingApp::createRenderWindow()
{
	isWindowReady = false;
	mVDUI->resize();

	deleteRenderWindows();
	mVDSession->getWindowsResolution();

	mVDSettings->iResolution.x = mVDSettings->mRenderWidth;
	mVDSettings->iResolution.y = mVDSettings->mRenderHeight;

	CI_LOG_V("createRenderWindow, resolution:" + toString(mVDSettings->iResolution.x) + "x" + toString(mVDSettings->iResolution.y));

	string windowName = "render";
	mRenderWindow = createWindow(Window::Format().size(mVDSettings->iResolution.x, mVDSettings->iResolution.y));

	// create instance of the window and store in vector
	allRenderWindows.push_back(mRenderWindow);

	mRenderWindow->setBorderless();
	mRenderWindow->getSignalDraw().connect(std::bind(&VideodrommLiveCodingApp::drawRender, this));
	mVDSettings->mRenderPosXY = ivec2(mVDSettings->mRenderX, mVDSettings->mRenderY);//20141214 was 0
	mRenderWindow->setPos(50, 50);
	mRenderWindowTimer = 0.0f;
	timeline().apply(&mRenderWindowTimer, 1.0f, 2.0f).finishFn([&]{ positionRenderWindow(); });
}
void VideodrommLiveCodingApp::positionRenderWindow()
{
	mRenderWindow->setPos(mVDSettings->mRenderX, mVDSettings->mRenderY);
	isWindowReady = true;
}
void VideodrommLiveCodingApp::deleteRenderWindows()
{
#if defined( CINDER_MSW )
	for (auto wRef : allRenderWindows) DestroyWindow((HWND)mRenderWindow->getNative());
#endif
	allRenderWindows.clear();
}
void VideodrommLiveCodingApp::setUIVisibility(bool visible)
{
	if (visible)
	{
		showCursor();
	}
	else
	{
		hideCursor();
	}
}
void VideodrommLiveCodingApp::update()
{
	mVDSession->setControlValue(mVDSettings->IFPS, getAverageFps());
	mVDSession->update();
}
void VideodrommLiveCodingApp::cleanup()
{
	if (!mIsShutDown)
	{
		mIsShutDown = true;
		CI_LOG_V("shutdown");
		ui::disconnectWindow(getWindow());
		ui::Shutdown();
		// save settings
		mVDSettings->save();
		mVDSession->save();
		deleteRenderWindows();
		quit();
	}
}

void VideodrommLiveCodingApp::mouseMove(MouseEvent event)
{
	if (!mVDSession->handleMouseMove(event)) {
		// let your application perform its mouseMove handling here
	}
}

void VideodrommLiveCodingApp::mouseDown(MouseEvent event)
{
	if (!mVDSession->handleMouseDown(event)) {
		// let your application perform its mouseDown handling here
	}
}

void VideodrommLiveCodingApp::mouseDrag(MouseEvent event)
{
	if (!mVDSession->handleMouseDrag(event)) {
		// let your application perform its mouseDrag handling here
	}
}

void VideodrommLiveCodingApp::mouseUp(MouseEvent event)
{
	if (!mVDSession->handleMouseUp(event)) {
		// let your application perform its mouseUp handling here
	}
}
void VideodrommLiveCodingApp::keyDown(KeyEvent event)
{
#if defined( CINDER_COCOA )
	bool isModDown = event.isMetaDown();
#else // windows
	bool isModDown = event.isControlDown();
#endif
	if (isModDown) {
		switch (event.getCode()) {
		case KeyEvent::KEY_r:
			// quit the application
			createRenderWindow();
			break;
		case KeyEvent::KEY_d:
			// quit the application
			if (isModDown) deleteRenderWindows();
			break;
		}
	}
	else {
		if (!mVDSession->handleKeyDown(event)) {
			switch (event.getCode()) {
			case KeyEvent::KEY_ESCAPE:
				// quit the application
				quit();
				break;
			case KeyEvent::KEY_h:
				// mouse cursor and ui visibility
				mVDSettings->mCursorVisible = !mVDSettings->mCursorVisible;
				setUIVisibility(mVDSettings->mCursorVisible);
				break;
			}
		}
	}
}

void VideodrommLiveCodingApp::keyUp(KeyEvent event)
{
	if (!mVDSession->handleKeyUp(event)) {
	}
}
void VideodrommLiveCodingApp::resizeWindow()
{
	mVDUI->resize();
	//mVDSession->resize();
}
void VideodrommLiveCodingApp::fileDrop(FileDropEvent event)
{
	mVDSession->fileDrop(event);
}

void VideodrommLiveCodingApp::drawRender()
{
	gl::clear(Color::black());
	//gl::setMatricesWindow(toPixels(getWindowSize()));
	if (mFadeInDelay) {
		mVDSettings->iAlpha = 0.0f;
		if (getElapsedFrames() > mVDSession->getFadeInDelay()) {
			mFadeInDelay = false;
			// warps resize at the end
			mVDSession->resize();
			timeline().apply(&mVDSettings->iAlpha, 0.0f, 1.0f, 1.5f, EaseInCubic());
		}
	}
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	if (isWindowReady) 	gl::draw(mVDSession->getRenderTexture(), getWindowBounds());
}

void VideodrommLiveCodingApp::drawMain()
{
	mMainWindow->setTitle(mVDSettings->sFps + " fps videodromm");

	gl::clear(Color::black());
	//	gl::setMatricesWindow(toPixels(getWindowSize()));
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	gl::draw(mVDSession->getRenderTexture(), getWindowBounds());
	//gl::draw(mVDSession->getStreamedTexture(), getWindowBounds());
	// imgui
	if (!mVDSettings->mCursorVisible) return;

	mVDUI->Run("UI", (int)getAverageFps());
	if (mVDUI->isReady()) {
	}

}

CINDER_APP(VideodrommLiveCodingApp, RendererGl, &VideodrommLiveCodingApp::prepare)

<|endoftext|>


<commit_before>#include "VideodrommLiveCodingApp.h"

void VideodrommLiveCodingApp::prepare(Settings *settings)
{
	settings->setWindowSize(640, 480);
	//settings->setBorderless();
	settings->setWindowPos(0, 0);
}
void VideodrommLiveCodingApp::setup()
{
	// Settings
	mVDSettings = VDSettings::create();
	// Session
	mVDSession = VDSession::create(mVDSettings);

	mVDSession->getWindowsResolution();
	setWindowSize(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);

	// UI
	mVDUI = VDUI::create(mVDSettings, mVDSession);

	mouseGlobal = false;
	mFadeInDelay = true;
	// mouse cursor and UI
	setUIVisibility(mVDSettings->mCursorVisible);
	// windows
	mIsShutDown = false;
	isWindowReady = false;
	mMainWindow = getWindow();
	mMainWindow->getSignalDraw().connect(std::bind(&VideodrommLiveCodingApp::drawMain, this));
	mMainWindow->getSignalResize().connect(std::bind(&VideodrommLiveCodingApp::resizeWindow, this));
	if (mVDSettings->mStandalone) {
		createRenderWindow();
		setWindowSize(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);
	}
	else {

	}
	setFrameRate(mVDSession->getTargetFps());
	CI_LOG_V("setup");

}
void VideodrommLiveCodingApp::createRenderWindow()
{
	isWindowReady = false;
	mVDUI->resize();

	deleteRenderWindows();
	mVDSession->getWindowsResolution();

	CI_LOG_V("createRenderWindow, resolution:" + toString(mVDSettings->mRenderWidth) + "x" + toString(mVDSettings->mRenderHeight));

	string windowName = "render";
	mRenderWindow = createWindow(Window::Format().size(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight));

	// create instance of the window and store in vector
	allRenderWindows.push_back(mRenderWindow);

	mRenderWindow->setBorderless();
	mRenderWindow->getSignalDraw().connect(std::bind(&VideodrommLiveCodingApp::drawRender, this));
	mVDSettings->mRenderPosXY = ivec2(mVDSettings->mRenderX, mVDSettings->mRenderY);
	mRenderWindow->setPos(50, 50);
	mRenderWindowTimer = 0.0f;
	timeline().apply(&mRenderWindowTimer, 1.0f, 2.0f).finishFn([&] { positionRenderWindow(); });
}
void VideodrommLiveCodingApp::positionRenderWindow()
{
	mRenderWindow->setPos(mVDSettings->mRenderX, mVDSettings->mRenderY);
	isWindowReady = true;
}
void VideodrommLiveCodingApp::deleteRenderWindows()
{
#if defined( CINDER_MSW )
	for (auto wRef : allRenderWindows) DestroyWindow((HWND)mRenderWindow->getNative());
#endif
	allRenderWindows.clear();
}
void VideodrommLiveCodingApp::setUIVisibility(bool visible)
{
	if (visible)
	{
		showCursor();
	}
	else
	{
		hideCursor();
	}
}
void VideodrommLiveCodingApp::update()
{
	switch (mVDSession->getCmd()) {
	case 0:
		createRenderWindow();
		break;
	case 1:
		deleteRenderWindows();
		break;
	}
	mVDSession->setControlValue(mVDSettings->IFPS, getAverageFps());
	mVDSession->update();
}
void VideodrommLiveCodingApp::cleanup()
{
	if (!mIsShutDown)
	{
		mIsShutDown = true;
		CI_LOG_V("shutdown");
		ui::disconnectWindow(getWindow());
		ui::Shutdown();
		// save settings
		mVDSettings->save();
		mVDSession->save();
		deleteRenderWindows();
		quit();
	}
}

void VideodrommLiveCodingApp::mouseMove(MouseEvent event)
{
	if (!mVDSession->handleMouseMove(event)) {
		// let your application perform its mouseMove handling here
	}
}

void VideodrommLiveCodingApp::mouseDown(MouseEvent event)
{
	if (!mVDSession->handleMouseDown(event)) {
		// let your application perform its mouseDown handling here
	}
}

void VideodrommLiveCodingApp::mouseDrag(MouseEvent event)
{
	if (!mVDSession->handleMouseDrag(event)) {
		// let your application perform its mouseDrag handling here
	}
}

void VideodrommLiveCodingApp::mouseUp(MouseEvent event)
{
	if (!mVDSession->handleMouseUp(event)) {
		// let your application perform its mouseUp handling here
	}
}
void VideodrommLiveCodingApp::keyDown(KeyEvent event)
{
	if (!mVDSession->handleKeyDown(event)) {
		switch (event.getCode()) {
		case KeyEvent::KEY_KP_PLUS:
			createRenderWindow();
			break;
		case KeyEvent::KEY_KP_MINUS:
			deleteRenderWindows();
			break;
		case KeyEvent::KEY_ESCAPE:
			// quit the application
			quit();
			break;
		case KeyEvent::KEY_h:
			// mouse cursor and ui visibility
			mVDSettings->mCursorVisible = !mVDSettings->mCursorVisible;
			setUIVisibility(mVDSettings->mCursorVisible);
			break;
		}
	}
}
void VideodrommLiveCodingApp::keyUp(KeyEvent event)
{
	if (!mVDSession->handleKeyUp(event)) {
	}
}
void VideodrommLiveCodingApp::resizeWindow()
{
	mVDUI->resize();
	//mVDSession->resize();
}
void VideodrommLiveCodingApp::fileDrop(FileDropEvent event)
{
	mVDSession->fileDrop(event);
}

void VideodrommLiveCodingApp::drawRender()
{
	gl::clear(Color::black());
	//gl::setMatricesWindow(toPixels(getWindowSize()));
	if (mFadeInDelay) {
		mVDSettings->iAlpha = 0.0f;
		if (getElapsedFrames() > mVDSession->getFadeInDelay()) {
			mFadeInDelay = false;
			// warps resize at the end
			mVDSession->resize();
			timeline().apply(&mVDSettings->iAlpha, 0.0f, 1.0f, 1.5f, EaseInCubic());
		}
	}
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	if (isWindowReady) 	gl::draw(mVDSession->getRenderTexture(), getWindowBounds());
}

void VideodrommLiveCodingApp::drawMain()
{
	mMainWindow->setTitle(mVDSettings->sFps + " fps videodromm");

	gl::clear(Color::black());
	//	gl::setMatricesWindow(toPixels(getWindowSize()));
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	gl::draw(mVDSession->getRenderTexture(), getWindowBounds());
	//gl::draw(mVDSession->getStreamedTexture(), getWindowBounds());
	// imgui
	if (!mVDSettings->mCursorVisible) return;

	mVDUI->Run("UI", (int)getAverageFps());
	if (mVDUI->isReady()) {
	}

}

CINDER_APP(VideodrommLiveCodingApp, RendererGl, &VideodrommLiveCodingApp::prepare)

<commit_msg>direct triangle<commit_after>#include "VideodrommLiveCodingApp.h"

void VideodrommLiveCodingApp::prepare(Settings *settings)
{
	settings->setWindowSize(640, 480);
	//settings->setBorderless();
	settings->setWindowPos(0, 0);
}
void VideodrommLiveCodingApp::setup()
{
	// Settings
	mVDSettings = VDSettings::create();
	// Session
	mVDSession = VDSession::create(mVDSettings);

	mVDSession->getWindowsResolution();
	setWindowSize(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);

	// UI
	mVDUI = VDUI::create(mVDSettings, mVDSession);

	mouseGlobal = false;
	mFadeInDelay = true;
	// mouse cursor and UI
	setUIVisibility(mVDSettings->mCursorVisible);
	// windows
	mIsShutDown = false;
	isWindowReady = false;
	mMainWindow = getWindow();
	mMainWindow->getSignalDraw().connect(std::bind(&VideodrommLiveCodingApp::drawMain, this));
	mMainWindow->getSignalResize().connect(std::bind(&VideodrommLiveCodingApp::resizeWindow, this));
	if (mVDSettings->mStandalone) {
		createRenderWindow();
		setWindowSize(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight);
	}
	else {

	}
	setFrameRate(mVDSession->getTargetFps());
	CI_LOG_V("setup");

}
void VideodrommLiveCodingApp::createRenderWindow()
{
	isWindowReady = false;
	mVDUI->resize();

	deleteRenderWindows();
	mVDSession->getWindowsResolution();

	CI_LOG_V("createRenderWindow, resolution:" + toString(mVDSettings->mRenderWidth) + "x" + toString(mVDSettings->mRenderHeight));

	string windowName = "render";
	mRenderWindow = createWindow(Window::Format().size(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight));

	// create instance of the window and store in vector
	allRenderWindows.push_back(mRenderWindow);

	mRenderWindow->setBorderless();
	mRenderWindow->getSignalDraw().connect(std::bind(&VideodrommLiveCodingApp::drawRender, this));
	mVDSettings->mRenderPosXY = ivec2(mVDSettings->mRenderX, mVDSettings->mRenderY);
	mRenderWindow->setPos(50, 50);
	mRenderWindowTimer = 0.0f;
	timeline().apply(&mRenderWindowTimer, 1.0f, 2.0f).finishFn([&] { positionRenderWindow(); });
}
void VideodrommLiveCodingApp::positionRenderWindow()
{
	mRenderWindow->setPos(mVDSettings->mRenderX, mVDSettings->mRenderY);
	isWindowReady = true;
}
void VideodrommLiveCodingApp::deleteRenderWindows()
{
#if defined( CINDER_MSW )
	for (auto wRef : allRenderWindows) DestroyWindow((HWND)mRenderWindow->getNative());
#endif
	allRenderWindows.clear();
}
void VideodrommLiveCodingApp::setUIVisibility(bool visible)
{
	if (visible)
	{
		showCursor();
	}
	else
	{
		hideCursor();
	}
}
void VideodrommLiveCodingApp::update()
{
	switch (mVDSession->getCmd()) {
	case 0:
		createRenderWindow();
		break;
	case 1:
		deleteRenderWindows();
		break;
	}
	mVDSession->setControlValue(mVDSettings->IFPS, getAverageFps());
	mVDSession->update();
}
void VideodrommLiveCodingApp::cleanup()
{
	if (!mIsShutDown)
	{
		mIsShutDown = true;
		CI_LOG_V("shutdown");
		ui::disconnectWindow(getWindow());
		ui::Shutdown();
		// save settings
		mVDSettings->save();
		mVDSession->save();
		deleteRenderWindows();
		quit();
	}
}

void VideodrommLiveCodingApp::mouseMove(MouseEvent event)
{
	if (!mVDSession->handleMouseMove(event)) {
		// let your application perform its mouseMove handling here
	}
}

void VideodrommLiveCodingApp::mouseDown(MouseEvent event)
{
	if (!mVDSession->handleMouseDown(event)) {
		// let your application perform its mouseDown handling here
	}
}

void VideodrommLiveCodingApp::mouseDrag(MouseEvent event)
{
	if (!mVDSession->handleMouseDrag(event)) {
		// let your application perform its mouseDrag handling here
	}
}

void VideodrommLiveCodingApp::mouseUp(MouseEvent event)
{
	if (!mVDSession->handleMouseUp(event)) {
		// let your application perform its mouseUp handling here
	}
}
void VideodrommLiveCodingApp::keyDown(KeyEvent event)
{
	if (!mVDSession->handleKeyDown(event)) {
		switch (event.getCode()) {
		case KeyEvent::KEY_KP_PLUS:
			createRenderWindow();
			break;
		case KeyEvent::KEY_KP_MINUS:
			deleteRenderWindows();
			break;
		case KeyEvent::KEY_ESCAPE:
			// quit the application
			quit();
			break;
		case KeyEvent::KEY_h:
			// mouse cursor and ui visibility
			mVDSettings->mCursorVisible = !mVDSettings->mCursorVisible;
			setUIVisibility(mVDSettings->mCursorVisible);
			break;
		}
	}
}
void VideodrommLiveCodingApp::keyUp(KeyEvent event)
{
	if (!mVDSession->handleKeyUp(event)) {
	}
}
void VideodrommLiveCodingApp::resizeWindow()
{
	mVDUI->resize();
	//mVDSession->resize();
}
void VideodrommLiveCodingApp::fileDrop(FileDropEvent event)
{
	mVDSession->fileDrop(event);
}

void VideodrommLiveCodingApp::drawRender()
{
	gl::clear(Color::black());
	//gl::setMatricesWindow(toPixels(getWindowSize()));
	if (mFadeInDelay) {
		mVDSettings->iAlpha = 0.0f;
		if (getElapsedFrames() > mVDSession->getFadeInDelay()) {
			mFadeInDelay = false;
			// warps resize at the end
			mVDSession->resize();
			timeline().apply(&mVDSettings->iAlpha, 0.0f, 1.0f, 1.5f, EaseInCubic());
		}
	}
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	if (isWindowReady) 	gl::draw(mVDSession->getRenderTexture(), getWindowBounds());
}

void VideodrommLiveCodingApp::drawMain()
{
	mMainWindow->setTitle(mVDSettings->sFps + " fps videodromm");

	gl::clear(Color::black());
	//	gl::setMatricesWindow(toPixels(getWindowSize()));
	gl::setMatricesWindow(mVDSettings->mRenderWidth, mVDSettings->mRenderHeight, false);
	for (int w = 0; w < mVDSession->getTriangleCount(); w++) {
		gl::draw(mVDSession->getTriangleTexture(w), getWindowBounds());
	}
	// 20170106 gl::draw(mVDSession->getRenderTexture(), getWindowBounds());
	// imgui
	if (!mVDSettings->mCursorVisible) return;

	mVDUI->Run("UI", (int)getAverageFps());
	if (mVDUI->isReady()) {
	}

}

CINDER_APP(VideodrommLiveCodingApp, RendererGl, &VideodrommLiveCodingApp::prepare)

<|endoftext|>


<commit_before>// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "VkGetProcAddress.h"

#include <unordered_map>

namespace vk
{
#define MAKE_VULKAN_ENTRY(aFunction) { #aFunction, reinterpret_cast<PFN_vkVoidFunction>(aFunction) }
	static const std::unordered_map <std::string, PFN_vkVoidFunction> func_ptrs =
	{
		MAKE_VULKAN_ENTRY(vkCreateInstance),
		MAKE_VULKAN_ENTRY(vkDestroyInstance),
		MAKE_VULKAN_ENTRY(vkEnumeratePhysicalDevices),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFeatures),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFormatProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceImageFormatProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceQueueFamilyProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceMemoryProperties),
		MAKE_VULKAN_ENTRY(vkGetInstanceProcAddr),
		MAKE_VULKAN_ENTRY(vkGetDeviceProcAddr),
		MAKE_VULKAN_ENTRY(vkCreateDevice),
		MAKE_VULKAN_ENTRY(vkDestroyDevice),
		MAKE_VULKAN_ENTRY(vkEnumerateInstanceExtensionProperties),
		MAKE_VULKAN_ENTRY(vkEnumerateDeviceExtensionProperties),
		MAKE_VULKAN_ENTRY(vkEnumerateInstanceLayerProperties),
		MAKE_VULKAN_ENTRY(vkEnumerateDeviceLayerProperties),
		MAKE_VULKAN_ENTRY(vkGetDeviceQueue),
		MAKE_VULKAN_ENTRY(vkQueueSubmit),
		MAKE_VULKAN_ENTRY(vkQueueWaitIdle),
		MAKE_VULKAN_ENTRY(vkDeviceWaitIdle),
		MAKE_VULKAN_ENTRY(vkAllocateMemory),
		MAKE_VULKAN_ENTRY(vkFreeMemory),
		MAKE_VULKAN_ENTRY(vkMapMemory),
		MAKE_VULKAN_ENTRY(vkUnmapMemory),
		MAKE_VULKAN_ENTRY(vkFlushMappedMemoryRanges),
		MAKE_VULKAN_ENTRY(vkInvalidateMappedMemoryRanges),
		MAKE_VULKAN_ENTRY(vkGetDeviceMemoryCommitment),
		MAKE_VULKAN_ENTRY(vkBindBufferMemory),
		MAKE_VULKAN_ENTRY(vkBindImageMemory),
		MAKE_VULKAN_ENTRY(vkGetBufferMemoryRequirements),
		MAKE_VULKAN_ENTRY(vkGetImageMemoryRequirements),
		MAKE_VULKAN_ENTRY(vkGetImageSparseMemoryRequirements),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceSparseImageFormatProperties),
		MAKE_VULKAN_ENTRY(vkQueueBindSparse),
		MAKE_VULKAN_ENTRY(vkCreateFence),
		MAKE_VULKAN_ENTRY(vkDestroyFence),
		MAKE_VULKAN_ENTRY(vkResetFences),
		MAKE_VULKAN_ENTRY(vkGetFenceStatus),
		MAKE_VULKAN_ENTRY(vkWaitForFences),
		MAKE_VULKAN_ENTRY(vkCreateSemaphore),
		MAKE_VULKAN_ENTRY(vkDestroySemaphore),
		MAKE_VULKAN_ENTRY(vkCreateEvent),
		MAKE_VULKAN_ENTRY(vkDestroyEvent),
		MAKE_VULKAN_ENTRY(vkGetEventStatus),
		MAKE_VULKAN_ENTRY(vkSetEvent),
		MAKE_VULKAN_ENTRY(vkResetEvent),
		MAKE_VULKAN_ENTRY(vkCreateQueryPool),
		MAKE_VULKAN_ENTRY(vkDestroyQueryPool),
		MAKE_VULKAN_ENTRY(vkGetQueryPoolResults),
		MAKE_VULKAN_ENTRY(vkCreateBuffer),
		MAKE_VULKAN_ENTRY(vkDestroyBuffer),
		MAKE_VULKAN_ENTRY(vkCreateBufferView),
		MAKE_VULKAN_ENTRY(vkDestroyBufferView),
		MAKE_VULKAN_ENTRY(vkCreateImage),
		MAKE_VULKAN_ENTRY(vkDestroyImage),
		MAKE_VULKAN_ENTRY(vkGetImageSubresourceLayout),
		MAKE_VULKAN_ENTRY(vkCreateImageView),
		MAKE_VULKAN_ENTRY(vkDestroyImageView),
		MAKE_VULKAN_ENTRY(vkCreateShaderModule),
		MAKE_VULKAN_ENTRY(vkDestroyShaderModule),
		MAKE_VULKAN_ENTRY(vkCreatePipelineCache),
		MAKE_VULKAN_ENTRY(vkDestroyPipelineCache),
		MAKE_VULKAN_ENTRY(vkGetPipelineCacheData),
		MAKE_VULKAN_ENTRY(vkMergePipelineCaches),
		MAKE_VULKAN_ENTRY(vkCreateGraphicsPipelines),
		MAKE_VULKAN_ENTRY(vkCreateComputePipelines),
		MAKE_VULKAN_ENTRY(vkDestroyPipeline),
		MAKE_VULKAN_ENTRY(vkCreatePipelineLayout),
		MAKE_VULKAN_ENTRY(vkDestroyPipelineLayout),
		MAKE_VULKAN_ENTRY(vkCreateSampler),
		MAKE_VULKAN_ENTRY(vkDestroySampler),
		MAKE_VULKAN_ENTRY(vkCreateDescriptorSetLayout),
		MAKE_VULKAN_ENTRY(vkDestroyDescriptorSetLayout),
		MAKE_VULKAN_ENTRY(vkCreateDescriptorPool),
		MAKE_VULKAN_ENTRY(vkDestroyDescriptorPool),
		MAKE_VULKAN_ENTRY(vkResetDescriptorPool),
		MAKE_VULKAN_ENTRY(vkAllocateDescriptorSets),
		MAKE_VULKAN_ENTRY(vkFreeDescriptorSets),
		MAKE_VULKAN_ENTRY(vkUpdateDescriptorSets),
		MAKE_VULKAN_ENTRY(vkCreateFramebuffer),
		MAKE_VULKAN_ENTRY(vkDestroyFramebuffer),
		MAKE_VULKAN_ENTRY(vkCreateRenderPass),
		MAKE_VULKAN_ENTRY(vkDestroyRenderPass),
		MAKE_VULKAN_ENTRY(vkGetRenderAreaGranularity),
		MAKE_VULKAN_ENTRY(vkCreateCommandPool),
		MAKE_VULKAN_ENTRY(vkDestroyCommandPool),
		MAKE_VULKAN_ENTRY(vkResetCommandPool),
		MAKE_VULKAN_ENTRY(vkAllocateCommandBuffers),
		MAKE_VULKAN_ENTRY(vkFreeCommandBuffers),
		MAKE_VULKAN_ENTRY(vkBeginCommandBuffer),
		MAKE_VULKAN_ENTRY(vkEndCommandBuffer),
		MAKE_VULKAN_ENTRY(vkResetCommandBuffer),
		MAKE_VULKAN_ENTRY(vkCmdBindPipeline),
		MAKE_VULKAN_ENTRY(vkCmdSetViewport),
		MAKE_VULKAN_ENTRY(vkCmdSetScissor),
		MAKE_VULKAN_ENTRY(vkCmdSetLineWidth),
		MAKE_VULKAN_ENTRY(vkCmdSetDepthBias),
		MAKE_VULKAN_ENTRY(vkCmdSetBlendConstants),
		MAKE_VULKAN_ENTRY(vkCmdSetDepthBounds),
		MAKE_VULKAN_ENTRY(vkCmdSetStencilCompareMask),
		MAKE_VULKAN_ENTRY(vkCmdSetStencilWriteMask),
		MAKE_VULKAN_ENTRY(vkCmdSetStencilReference),
		MAKE_VULKAN_ENTRY(vkCmdBindDescriptorSets),
		MAKE_VULKAN_ENTRY(vkCmdBindIndexBuffer),
		MAKE_VULKAN_ENTRY(vkCmdBindVertexBuffers),
		MAKE_VULKAN_ENTRY(vkCmdDraw),
		MAKE_VULKAN_ENTRY(vkCmdDrawIndexed),
		MAKE_VULKAN_ENTRY(vkCmdDrawIndirect),
		MAKE_VULKAN_ENTRY(vkCmdDrawIndexedIndirect),
		MAKE_VULKAN_ENTRY(vkCmdDispatch),
		MAKE_VULKAN_ENTRY(vkCmdDispatchIndirect),
		MAKE_VULKAN_ENTRY(vkCmdCopyBuffer),
		MAKE_VULKAN_ENTRY(vkCmdCopyImage),
		MAKE_VULKAN_ENTRY(vkCmdBlitImage),
		MAKE_VULKAN_ENTRY(vkCmdCopyBufferToImage),
		MAKE_VULKAN_ENTRY(vkCmdCopyImageToBuffer),
		MAKE_VULKAN_ENTRY(vkCmdUpdateBuffer),
		MAKE_VULKAN_ENTRY(vkCmdFillBuffer),
		MAKE_VULKAN_ENTRY(vkCmdClearColorImage),
		MAKE_VULKAN_ENTRY(vkCmdClearDepthStencilImage),
		MAKE_VULKAN_ENTRY(vkCmdClearAttachments),
		MAKE_VULKAN_ENTRY(vkCmdResolveImage),
		MAKE_VULKAN_ENTRY(vkCmdSetEvent),
		MAKE_VULKAN_ENTRY(vkCmdResetEvent),
		MAKE_VULKAN_ENTRY(vkCmdWaitEvents),
		MAKE_VULKAN_ENTRY(vkCmdPipelineBarrier),
		MAKE_VULKAN_ENTRY(vkCmdBeginQuery),
		MAKE_VULKAN_ENTRY(vkCmdEndQuery),
		MAKE_VULKAN_ENTRY(vkCmdResetQueryPool),
		MAKE_VULKAN_ENTRY(vkCmdWriteTimestamp),
		MAKE_VULKAN_ENTRY(vkCmdCopyQueryPoolResults),
		MAKE_VULKAN_ENTRY(vkCmdPushConstants),
		MAKE_VULKAN_ENTRY(vkCmdBeginRenderPass),
		MAKE_VULKAN_ENTRY(vkCmdNextSubpass),
		MAKE_VULKAN_ENTRY(vkCmdEndRenderPass),
		MAKE_VULKAN_ENTRY(vkCmdExecuteCommands),
		MAKE_VULKAN_ENTRY(vkEnumerateInstanceVersion),
		MAKE_VULKAN_ENTRY(vkBindBufferMemory2),
		MAKE_VULKAN_ENTRY(vkBindImageMemory2),
		MAKE_VULKAN_ENTRY(vkGetDeviceGroupPeerMemoryFeatures),
		MAKE_VULKAN_ENTRY(vkCmdSetDeviceMask),
		MAKE_VULKAN_ENTRY(vkCmdDispatchBase),
		MAKE_VULKAN_ENTRY(vkEnumeratePhysicalDeviceGroups),
		MAKE_VULKAN_ENTRY(vkGetImageMemoryRequirements2),
		MAKE_VULKAN_ENTRY(vkGetBufferMemoryRequirements2),
		MAKE_VULKAN_ENTRY(vkGetImageSparseMemoryRequirements2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFeatures2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceProperties2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFormatProperties2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceImageFormatProperties2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceQueueFamilyProperties2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceMemoryProperties2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceSparseImageFormatProperties2),
		MAKE_VULKAN_ENTRY(vkTrimCommandPool),
		MAKE_VULKAN_ENTRY(vkGetDeviceQueue2),
		MAKE_VULKAN_ENTRY(vkCreateSamplerYcbcrConversion),
		MAKE_VULKAN_ENTRY(vkDestroySamplerYcbcrConversion),
		MAKE_VULKAN_ENTRY(vkCreateDescriptorUpdateTemplate),
		MAKE_VULKAN_ENTRY(vkDestroyDescriptorUpdateTemplate),
		MAKE_VULKAN_ENTRY(vkUpdateDescriptorSetWithTemplate),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalBufferProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalFenceProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalSemaphoreProperties),
		MAKE_VULKAN_ENTRY(vkGetDescriptorSetLayoutSupport),
		// VK_KHR_bind_memory2
		MAKE_VULKAN_ENTRY(vkBindBufferMemory2KHR),
		MAKE_VULKAN_ENTRY(vkBindImageMemory2KHR),
		// VK_KHR_descriptor_update_template
		MAKE_VULKAN_ENTRY(vkCreateDescriptorUpdateTemplateKHR),
		MAKE_VULKAN_ENTRY(vkDestroyDescriptorUpdateTemplateKHR),
		MAKE_VULKAN_ENTRY(vkUpdateDescriptorSetWithTemplateKHR),
		// VK_KHR_device_group
		MAKE_VULKAN_ENTRY(vkGetDeviceGroupPeerMemoryFeaturesKHR),
		MAKE_VULKAN_ENTRY(vkCmdSetDeviceMaskKHR),
		MAKE_VULKAN_ENTRY(vkCmdDispatchBaseKHR),
		// VK_KHR_device_group_creation
		MAKE_VULKAN_ENTRY(vkEnumeratePhysicalDeviceGroupsKHR),
		// VK_KHR_external_fence_capabilities
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalFencePropertiesKHR),
		// VK_KHR_external_memory_capabilities
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalBufferPropertiesKHR),
		// VK_KHR_external_semaphore_capabilities
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalSemaphorePropertiesKHR),
		// VK_KHR_get_memory_requirements2
		MAKE_VULKAN_ENTRY(vkGetImageMemoryRequirements2KHR),
		MAKE_VULKAN_ENTRY(vkGetBufferMemoryRequirements2KHR),
		MAKE_VULKAN_ENTRY(vkGetImageSparseMemoryRequirements2KHR),
		// VK_KHR_get_physical_device_properties2
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFeatures2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceProperties2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFormatProperties2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceImageFormatProperties2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceQueueFamilyProperties2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceMemoryProperties2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceSparseImageFormatProperties2KHR),
		// VK_KHR_maintenance1
		MAKE_VULKAN_ENTRY(vkTrimCommandPoolKHR),
		// VK_KHR_maintenance3
		MAKE_VULKAN_ENTRY(vkGetDescriptorSetLayoutSupportKHR),
		// VK_KHR_sampler_ycbcr_conversion
		MAKE_VULKAN_ENTRY(vkCreateSamplerYcbcrConversionKHR),
		MAKE_VULKAN_ENTRY(vkDestroySamplerYcbcrConversionKHR),
	};
#undef MAKE_VULKAN_ENTRY

	PFN_vkVoidFunction GetProcAddr(const char* pName)
	{
		auto pFunc = func_ptrs.find(std::string(pName));
		return (pFunc == func_ptrs.end()) ? nullptr : pFunc->second;
	}
}
<commit_msg>Include <string> for fixing undefined template on Mac.<commit_after>// Copyright 2018 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "VkGetProcAddress.h"

#include <unordered_map>
#include <string>

namespace vk
{
#define MAKE_VULKAN_ENTRY(aFunction) { #aFunction, reinterpret_cast<PFN_vkVoidFunction>(aFunction) }
	static const std::unordered_map <std::string, PFN_vkVoidFunction> func_ptrs =
	{
		MAKE_VULKAN_ENTRY(vkCreateInstance),
		MAKE_VULKAN_ENTRY(vkDestroyInstance),
		MAKE_VULKAN_ENTRY(vkEnumeratePhysicalDevices),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFeatures),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFormatProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceImageFormatProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceQueueFamilyProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceMemoryProperties),
		MAKE_VULKAN_ENTRY(vkGetInstanceProcAddr),
		MAKE_VULKAN_ENTRY(vkGetDeviceProcAddr),
		MAKE_VULKAN_ENTRY(vkCreateDevice),
		MAKE_VULKAN_ENTRY(vkDestroyDevice),
		MAKE_VULKAN_ENTRY(vkEnumerateInstanceExtensionProperties),
		MAKE_VULKAN_ENTRY(vkEnumerateDeviceExtensionProperties),
		MAKE_VULKAN_ENTRY(vkEnumerateInstanceLayerProperties),
		MAKE_VULKAN_ENTRY(vkEnumerateDeviceLayerProperties),
		MAKE_VULKAN_ENTRY(vkGetDeviceQueue),
		MAKE_VULKAN_ENTRY(vkQueueSubmit),
		MAKE_VULKAN_ENTRY(vkQueueWaitIdle),
		MAKE_VULKAN_ENTRY(vkDeviceWaitIdle),
		MAKE_VULKAN_ENTRY(vkAllocateMemory),
		MAKE_VULKAN_ENTRY(vkFreeMemory),
		MAKE_VULKAN_ENTRY(vkMapMemory),
		MAKE_VULKAN_ENTRY(vkUnmapMemory),
		MAKE_VULKAN_ENTRY(vkFlushMappedMemoryRanges),
		MAKE_VULKAN_ENTRY(vkInvalidateMappedMemoryRanges),
		MAKE_VULKAN_ENTRY(vkGetDeviceMemoryCommitment),
		MAKE_VULKAN_ENTRY(vkBindBufferMemory),
		MAKE_VULKAN_ENTRY(vkBindImageMemory),
		MAKE_VULKAN_ENTRY(vkGetBufferMemoryRequirements),
		MAKE_VULKAN_ENTRY(vkGetImageMemoryRequirements),
		MAKE_VULKAN_ENTRY(vkGetImageSparseMemoryRequirements),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceSparseImageFormatProperties),
		MAKE_VULKAN_ENTRY(vkQueueBindSparse),
		MAKE_VULKAN_ENTRY(vkCreateFence),
		MAKE_VULKAN_ENTRY(vkDestroyFence),
		MAKE_VULKAN_ENTRY(vkResetFences),
		MAKE_VULKAN_ENTRY(vkGetFenceStatus),
		MAKE_VULKAN_ENTRY(vkWaitForFences),
		MAKE_VULKAN_ENTRY(vkCreateSemaphore),
		MAKE_VULKAN_ENTRY(vkDestroySemaphore),
		MAKE_VULKAN_ENTRY(vkCreateEvent),
		MAKE_VULKAN_ENTRY(vkDestroyEvent),
		MAKE_VULKAN_ENTRY(vkGetEventStatus),
		MAKE_VULKAN_ENTRY(vkSetEvent),
		MAKE_VULKAN_ENTRY(vkResetEvent),
		MAKE_VULKAN_ENTRY(vkCreateQueryPool),
		MAKE_VULKAN_ENTRY(vkDestroyQueryPool),
		MAKE_VULKAN_ENTRY(vkGetQueryPoolResults),
		MAKE_VULKAN_ENTRY(vkCreateBuffer),
		MAKE_VULKAN_ENTRY(vkDestroyBuffer),
		MAKE_VULKAN_ENTRY(vkCreateBufferView),
		MAKE_VULKAN_ENTRY(vkDestroyBufferView),
		MAKE_VULKAN_ENTRY(vkCreateImage),
		MAKE_VULKAN_ENTRY(vkDestroyImage),
		MAKE_VULKAN_ENTRY(vkGetImageSubresourceLayout),
		MAKE_VULKAN_ENTRY(vkCreateImageView),
		MAKE_VULKAN_ENTRY(vkDestroyImageView),
		MAKE_VULKAN_ENTRY(vkCreateShaderModule),
		MAKE_VULKAN_ENTRY(vkDestroyShaderModule),
		MAKE_VULKAN_ENTRY(vkCreatePipelineCache),
		MAKE_VULKAN_ENTRY(vkDestroyPipelineCache),
		MAKE_VULKAN_ENTRY(vkGetPipelineCacheData),
		MAKE_VULKAN_ENTRY(vkMergePipelineCaches),
		MAKE_VULKAN_ENTRY(vkCreateGraphicsPipelines),
		MAKE_VULKAN_ENTRY(vkCreateComputePipelines),
		MAKE_VULKAN_ENTRY(vkDestroyPipeline),
		MAKE_VULKAN_ENTRY(vkCreatePipelineLayout),
		MAKE_VULKAN_ENTRY(vkDestroyPipelineLayout),
		MAKE_VULKAN_ENTRY(vkCreateSampler),
		MAKE_VULKAN_ENTRY(vkDestroySampler),
		MAKE_VULKAN_ENTRY(vkCreateDescriptorSetLayout),
		MAKE_VULKAN_ENTRY(vkDestroyDescriptorSetLayout),
		MAKE_VULKAN_ENTRY(vkCreateDescriptorPool),
		MAKE_VULKAN_ENTRY(vkDestroyDescriptorPool),
		MAKE_VULKAN_ENTRY(vkResetDescriptorPool),
		MAKE_VULKAN_ENTRY(vkAllocateDescriptorSets),
		MAKE_VULKAN_ENTRY(vkFreeDescriptorSets),
		MAKE_VULKAN_ENTRY(vkUpdateDescriptorSets),
		MAKE_VULKAN_ENTRY(vkCreateFramebuffer),
		MAKE_VULKAN_ENTRY(vkDestroyFramebuffer),
		MAKE_VULKAN_ENTRY(vkCreateRenderPass),
		MAKE_VULKAN_ENTRY(vkDestroyRenderPass),
		MAKE_VULKAN_ENTRY(vkGetRenderAreaGranularity),
		MAKE_VULKAN_ENTRY(vkCreateCommandPool),
		MAKE_VULKAN_ENTRY(vkDestroyCommandPool),
		MAKE_VULKAN_ENTRY(vkResetCommandPool),
		MAKE_VULKAN_ENTRY(vkAllocateCommandBuffers),
		MAKE_VULKAN_ENTRY(vkFreeCommandBuffers),
		MAKE_VULKAN_ENTRY(vkBeginCommandBuffer),
		MAKE_VULKAN_ENTRY(vkEndCommandBuffer),
		MAKE_VULKAN_ENTRY(vkResetCommandBuffer),
		MAKE_VULKAN_ENTRY(vkCmdBindPipeline),
		MAKE_VULKAN_ENTRY(vkCmdSetViewport),
		MAKE_VULKAN_ENTRY(vkCmdSetScissor),
		MAKE_VULKAN_ENTRY(vkCmdSetLineWidth),
		MAKE_VULKAN_ENTRY(vkCmdSetDepthBias),
		MAKE_VULKAN_ENTRY(vkCmdSetBlendConstants),
		MAKE_VULKAN_ENTRY(vkCmdSetDepthBounds),
		MAKE_VULKAN_ENTRY(vkCmdSetStencilCompareMask),
		MAKE_VULKAN_ENTRY(vkCmdSetStencilWriteMask),
		MAKE_VULKAN_ENTRY(vkCmdSetStencilReference),
		MAKE_VULKAN_ENTRY(vkCmdBindDescriptorSets),
		MAKE_VULKAN_ENTRY(vkCmdBindIndexBuffer),
		MAKE_VULKAN_ENTRY(vkCmdBindVertexBuffers),
		MAKE_VULKAN_ENTRY(vkCmdDraw),
		MAKE_VULKAN_ENTRY(vkCmdDrawIndexed),
		MAKE_VULKAN_ENTRY(vkCmdDrawIndirect),
		MAKE_VULKAN_ENTRY(vkCmdDrawIndexedIndirect),
		MAKE_VULKAN_ENTRY(vkCmdDispatch),
		MAKE_VULKAN_ENTRY(vkCmdDispatchIndirect),
		MAKE_VULKAN_ENTRY(vkCmdCopyBuffer),
		MAKE_VULKAN_ENTRY(vkCmdCopyImage),
		MAKE_VULKAN_ENTRY(vkCmdBlitImage),
		MAKE_VULKAN_ENTRY(vkCmdCopyBufferToImage),
		MAKE_VULKAN_ENTRY(vkCmdCopyImageToBuffer),
		MAKE_VULKAN_ENTRY(vkCmdUpdateBuffer),
		MAKE_VULKAN_ENTRY(vkCmdFillBuffer),
		MAKE_VULKAN_ENTRY(vkCmdClearColorImage),
		MAKE_VULKAN_ENTRY(vkCmdClearDepthStencilImage),
		MAKE_VULKAN_ENTRY(vkCmdClearAttachments),
		MAKE_VULKAN_ENTRY(vkCmdResolveImage),
		MAKE_VULKAN_ENTRY(vkCmdSetEvent),
		MAKE_VULKAN_ENTRY(vkCmdResetEvent),
		MAKE_VULKAN_ENTRY(vkCmdWaitEvents),
		MAKE_VULKAN_ENTRY(vkCmdPipelineBarrier),
		MAKE_VULKAN_ENTRY(vkCmdBeginQuery),
		MAKE_VULKAN_ENTRY(vkCmdEndQuery),
		MAKE_VULKAN_ENTRY(vkCmdResetQueryPool),
		MAKE_VULKAN_ENTRY(vkCmdWriteTimestamp),
		MAKE_VULKAN_ENTRY(vkCmdCopyQueryPoolResults),
		MAKE_VULKAN_ENTRY(vkCmdPushConstants),
		MAKE_VULKAN_ENTRY(vkCmdBeginRenderPass),
		MAKE_VULKAN_ENTRY(vkCmdNextSubpass),
		MAKE_VULKAN_ENTRY(vkCmdEndRenderPass),
		MAKE_VULKAN_ENTRY(vkCmdExecuteCommands),
		MAKE_VULKAN_ENTRY(vkEnumerateInstanceVersion),
		MAKE_VULKAN_ENTRY(vkBindBufferMemory2),
		MAKE_VULKAN_ENTRY(vkBindImageMemory2),
		MAKE_VULKAN_ENTRY(vkGetDeviceGroupPeerMemoryFeatures),
		MAKE_VULKAN_ENTRY(vkCmdSetDeviceMask),
		MAKE_VULKAN_ENTRY(vkCmdDispatchBase),
		MAKE_VULKAN_ENTRY(vkEnumeratePhysicalDeviceGroups),
		MAKE_VULKAN_ENTRY(vkGetImageMemoryRequirements2),
		MAKE_VULKAN_ENTRY(vkGetBufferMemoryRequirements2),
		MAKE_VULKAN_ENTRY(vkGetImageSparseMemoryRequirements2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFeatures2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceProperties2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFormatProperties2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceImageFormatProperties2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceQueueFamilyProperties2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceMemoryProperties2),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceSparseImageFormatProperties2),
		MAKE_VULKAN_ENTRY(vkTrimCommandPool),
		MAKE_VULKAN_ENTRY(vkGetDeviceQueue2),
		MAKE_VULKAN_ENTRY(vkCreateSamplerYcbcrConversion),
		MAKE_VULKAN_ENTRY(vkDestroySamplerYcbcrConversion),
		MAKE_VULKAN_ENTRY(vkCreateDescriptorUpdateTemplate),
		MAKE_VULKAN_ENTRY(vkDestroyDescriptorUpdateTemplate),
		MAKE_VULKAN_ENTRY(vkUpdateDescriptorSetWithTemplate),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalBufferProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalFenceProperties),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalSemaphoreProperties),
		MAKE_VULKAN_ENTRY(vkGetDescriptorSetLayoutSupport),
		// VK_KHR_bind_memory2
		MAKE_VULKAN_ENTRY(vkBindBufferMemory2KHR),
		MAKE_VULKAN_ENTRY(vkBindImageMemory2KHR),
		// VK_KHR_descriptor_update_template
		MAKE_VULKAN_ENTRY(vkCreateDescriptorUpdateTemplateKHR),
		MAKE_VULKAN_ENTRY(vkDestroyDescriptorUpdateTemplateKHR),
		MAKE_VULKAN_ENTRY(vkUpdateDescriptorSetWithTemplateKHR),
		// VK_KHR_device_group
		MAKE_VULKAN_ENTRY(vkGetDeviceGroupPeerMemoryFeaturesKHR),
		MAKE_VULKAN_ENTRY(vkCmdSetDeviceMaskKHR),
		MAKE_VULKAN_ENTRY(vkCmdDispatchBaseKHR),
		// VK_KHR_device_group_creation
		MAKE_VULKAN_ENTRY(vkEnumeratePhysicalDeviceGroupsKHR),
		// VK_KHR_external_fence_capabilities
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalFencePropertiesKHR),
		// VK_KHR_external_memory_capabilities
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalBufferPropertiesKHR),
		// VK_KHR_external_semaphore_capabilities
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceExternalSemaphorePropertiesKHR),
		// VK_KHR_get_memory_requirements2
		MAKE_VULKAN_ENTRY(vkGetImageMemoryRequirements2KHR),
		MAKE_VULKAN_ENTRY(vkGetBufferMemoryRequirements2KHR),
		MAKE_VULKAN_ENTRY(vkGetImageSparseMemoryRequirements2KHR),
		// VK_KHR_get_physical_device_properties2
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFeatures2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceProperties2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceFormatProperties2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceImageFormatProperties2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceQueueFamilyProperties2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceMemoryProperties2KHR),
		MAKE_VULKAN_ENTRY(vkGetPhysicalDeviceSparseImageFormatProperties2KHR),
		// VK_KHR_maintenance1
		MAKE_VULKAN_ENTRY(vkTrimCommandPoolKHR),
		// VK_KHR_maintenance3
		MAKE_VULKAN_ENTRY(vkGetDescriptorSetLayoutSupportKHR),
		// VK_KHR_sampler_ycbcr_conversion
		MAKE_VULKAN_ENTRY(vkCreateSamplerYcbcrConversionKHR),
		MAKE_VULKAN_ENTRY(vkDestroySamplerYcbcrConversionKHR),
	};
#undef MAKE_VULKAN_ENTRY

	PFN_vkVoidFunction GetProcAddr(const char* pName)
	{
		auto pFunc = func_ptrs.find(std::string(pName));
		return (pFunc == func_ptrs.end()) ? nullptr : pFunc->second;
	}
}
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads

// <mutex>

// class recursive_timed_mutex;

// void lock();

#include <mutex>
#include <thread>
#include <cstdlib>
#include <cassert>

#include <iostream>

std::recursive_timed_mutex m;

typedef std::chrono::system_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef std::chrono::milliseconds ms;
typedef std::chrono::nanoseconds ns;

void f()
{
    time_point t0 = Clock::now();
    m.lock();
    time_point t1 = Clock::now();
    m.lock();
    m.unlock();
    m.unlock();
    ns d = t1 - t0 - ms(250);
    assert(d < ms(50));  // within 50ms
}

int main()
{
    m.lock();
    std::thread t(f);
    std::this_thread::sleep_for(ms(250));
    m.unlock();
    t.join();
}
<commit_msg>Mark another test as flaky<commit_after>//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads

// FLAKY_TEST.

// <mutex>

// class recursive_timed_mutex;

// void lock();

#include <mutex>
#include <thread>
#include <cstdlib>
#include <cassert>

#include <iostream>

std::recursive_timed_mutex m;

typedef std::chrono::system_clock Clock;
typedef Clock::time_point time_point;
typedef Clock::duration duration;
typedef std::chrono::milliseconds ms;
typedef std::chrono::nanoseconds ns;

void f()
{
    time_point t0 = Clock::now();
    m.lock();
    time_point t1 = Clock::now();
    m.lock();
    m.unlock();
    m.unlock();
    ns d = t1 - t0 - ms(250);
    assert(d < ms(50));  // within 50ms
}

int main()
{
    m.lock();
    std::thread t(f);
    std::this_thread::sleep_for(ms(250));
    m.unlock();
    t.join();
}
<|endoftext|>


<commit_before>#include "../promise.h"
#include <gtest/gtest.h>
#include <thread>

using namespace promise;

struct MoveOnly {
  int value_;
  explicit MoveOnly(int value) : value_(value) {}

  PROMISE_DISALLOW_COPY(MoveOnly);

  MoveOnly(MoveOnly&& other) : value_(other.value_) {}
  MoveOnly& operator=(MoveOnly&& other) {
    value_ = other.value_;
    return *this;
  }
};

template <typename F, typename... V>
void resolve(F&& f, V&&... v) {
  try {
    f.fulfill(std::forward<V>(v)...);
  }
  catch (...) {
  }
}

template <typename F, typename V>
void reject(F&& f, V&& v) {
  try {
    f.reject(std::forward<V>(v));
  }
  catch (...) {
  }
}

// When fulfilled, a promise: must not transition to any other state.
TEST(PromiseAPlusTest, Test_2_1_2_1) {
  // trying to fulfill then immediately reject
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_fulfilled_called = false;

    auto new_promise =
        promise.then([&on_fulfilled_called]() { on_fulfilled_called = true; },
                     [&on_fulfilled_called](std::exception_ptr) {
          EXPECT_EQ(false, on_fulfilled_called);
        });

    resolve(fulfiller);
    reject(fulfiller, std::make_exception_ptr(std::runtime_error{""}));
  }

  // trying to fulfill then reject, delayed
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_fulfilled_called = false;

    auto new_promise =
        promise.then([&on_fulfilled_called]() { on_fulfilled_called = true; },
                     [&on_fulfilled_called](std::exception_ptr) {
          EXPECT_EQ(false, on_fulfilled_called);
        });

    std::thread{[&fulfiller]() {
                  resolve(fulfiller);
                  reject(fulfiller,
                         std::make_exception_ptr(std::runtime_error{""}));
                }}.join();
  }

  // trying to fulfill immediately then reject delayed
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_fulfilled_called = false;

    auto new_promise =
        promise.then([&on_fulfilled_called]() { on_fulfilled_called = true; },
                     [&on_fulfilled_called](std::exception_ptr) {
          EXPECT_EQ(false, on_fulfilled_called);
        });

    resolve(fulfiller);
    std::thread{[&fulfiller]() {
                  reject(fulfiller,
                         std::make_exception_ptr(std::runtime_error{""}));
                }}.join();
  }
}

// When rejected, a promise: must not transition to any other state.
TEST(PromiseAPlusTest, Test_2_1_3_1) {
  // trying to reject then immediately fulfill
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_rejected_called = false;

    auto new_promise = promise.then(
      [&on_rejected_called]() {
        EXPECT_EQ(false, on_rejected_called);
      },
      [&on_rejected_called](std::exception_ptr) {
        on_rejected_called = true;
      });

    reject(fulfiller, std::make_exception_ptr(std::runtime_error{""}));
    resolve(fulfiller);
  }

  // trying to reject then fulfill, delayed
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_rejected_called = false;

    auto new_promise = promise.then(
      [&on_rejected_called]() {
        EXPECT_EQ(false, on_rejected_called);
      },
      [&on_rejected_called](std::exception_ptr) {
        on_rejected_called = true;
      });

    std::thread{[&fulfiller]() {
                  reject(fulfiller,
                         std::make_exception_ptr(std::runtime_error{""}));
                  resolve(fulfiller);
                }}.join();
  }

  // trying to reject immediately then fulfill delayed
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_rejected_called = false;

    auto new_promise = promise.then(
      [&on_rejected_called]() {
        EXPECT_EQ(false, on_rejected_called);
      },
      [&on_rejected_called](std::exception_ptr) {
        on_rejected_called = true;
      });

    reject(fulfiller, std::make_exception_ptr(std::runtime_error{ "" }));
    std::thread{[&fulfiller]() { resolve(fulfiller); }}.join();
  }
}<commit_msg>pass Promise/A+ 2.2.1 test<commit_after>#include "../promise.h"
#include <gtest/gtest.h>
#include <thread>

using namespace promise;

struct MoveOnly {
  int value_;
  explicit MoveOnly(int value) : value_(value) {}

  PROMISE_DISALLOW_COPY(MoveOnly);

  MoveOnly(MoveOnly&& other) : value_(other.value_) {}
  MoveOnly& operator=(MoveOnly&& other) {
    value_ = other.value_;
    return *this;
  }
};

template <typename F, typename... V>
void resolve(F&& f, V&&... v) {
  try {
    f.fulfill(std::forward<V>(v)...);
  }
  catch (...) {
  }
}

template <typename F, typename V>
void reject(F&& f, V&& v) {
  try {
    f.reject(std::forward<V>(v));
  }
  catch (...) {
  }
}

template <typename T>
Promise<T> rejected() {
  return makePromise<T>(std::make_exception_ptr(std::runtime_error{ "" }));
}

// When fulfilled, a promise: must not transition to any other state.
TEST(PromiseAPlusTest, Test_2_1_2_1) {
  // trying to fulfill then immediately reject
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_fulfilled_called = false;

    auto new_promise =
        promise.then([&on_fulfilled_called]() { on_fulfilled_called = true; },
                     [&on_fulfilled_called](std::exception_ptr) {
          EXPECT_EQ(false, on_fulfilled_called);
        });

    resolve(fulfiller);
    reject(fulfiller, std::make_exception_ptr(std::runtime_error{""}));
  }

  // trying to fulfill then reject, delayed
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_fulfilled_called = false;

    auto new_promise =
        promise.then([&on_fulfilled_called]() { on_fulfilled_called = true; },
                     [&on_fulfilled_called](std::exception_ptr) {
          EXPECT_EQ(false, on_fulfilled_called);
        });

    std::thread{[&fulfiller]() {
                  resolve(fulfiller);
                  reject(fulfiller,
                         std::make_exception_ptr(std::runtime_error{""}));
                }}.join();
  }

  // trying to fulfill immediately then reject delayed
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_fulfilled_called = false;

    auto new_promise =
        promise.then([&on_fulfilled_called]() { on_fulfilled_called = true; },
                     [&on_fulfilled_called](std::exception_ptr) {
          EXPECT_EQ(false, on_fulfilled_called);
        });

    resolve(fulfiller);
    std::thread{[&fulfiller]() {
                  reject(fulfiller,
                         std::make_exception_ptr(std::runtime_error{""}));
                }}.join();
  }
}

// When rejected, a promise: must not transition to any other state.
TEST(PromiseAPlusTest, Test_2_1_3_1) {
  // trying to reject then immediately fulfill
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_rejected_called = false;

    auto new_promise = promise.then(
      [&on_rejected_called]() {
        EXPECT_EQ(false, on_rejected_called);
      },
      [&on_rejected_called](std::exception_ptr) {
        on_rejected_called = true;
      });

    reject(fulfiller, std::make_exception_ptr(std::runtime_error{""}));
    resolve(fulfiller);
  }

  // trying to reject then fulfill, delayed
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_rejected_called = false;

    auto new_promise = promise.then(
      [&on_rejected_called]() {
        EXPECT_EQ(false, on_rejected_called);
      },
      [&on_rejected_called](std::exception_ptr) {
        on_rejected_called = true;
      });

    std::thread{[&fulfiller]() {
                  reject(fulfiller,
                         std::make_exception_ptr(std::runtime_error{""}));
                  resolve(fulfiller);
                }}.join();
  }

  // trying to reject immediately then fulfill delayed
  {
    auto promise = Promise<void>{};
    auto fulfiller = promise.getFulfiller();
    bool on_rejected_called = false;

    auto new_promise = promise.then(
      [&on_rejected_called]() {
        EXPECT_EQ(false, on_rejected_called);
      },
      [&on_rejected_called](std::exception_ptr) {
        on_rejected_called = true;
      });

    reject(fulfiller, std::make_exception_ptr(std::runtime_error{ "" }));
    std::thread{[&fulfiller]() { resolve(fulfiller); }}.join();
  }
}

// Both "onFulfilled" and "onRejected" are optional arguments

// If "onFulfilled" is a nullptr, it must be ignored
TEST(PromiseAPlusTest, Test_2_2_1_1) {
  ::testing::StaticAssertTypeEq<default_on_fulfilled_t, std::nullptr_t>();

  // applied to a directly-rejected promise
  {
    bool on_rejected_called = false;
    auto promise = rejected<void>().then(
        nullptr, [&on_rejected_called](std::exception_ptr) {
          on_rejected_called = true;
        });

    EXPECT_EQ(true, on_rejected_called);
  }

  // applied to a promise rejected and then chained off of
  {
    bool on_rejected_called = false;
    auto promise = rejected<void>().then([]() {}).then(
        nullptr, [&on_rejected_called](std::exception_ptr) {
          on_rejected_called = true;
        });

    EXPECT_EQ(true, on_rejected_called);
  }
}

// If "onRejected" is a nullptr, it must be ignored
TEST(PromiseAPlusTest, Test_2_2_1_2) {
  ::testing::StaticAssertTypeEq<default_on_rejected_t, std::nullptr_t>();

  // applied to a directly-fulfilled promise
  {
    bool on_fulfilled_called = false;
    auto promise = makePromise<MoveOnly>(MoveOnly{42})
                       .then([&on_fulfilled_called](MoveOnly mo) {
                               EXPECT_EQ(42, mo.value_);
                               on_fulfilled_called = true;
                             },
                             nullptr);

    EXPECT_EQ(true, on_fulfilled_called);
  }

  // applied to a promise fulfilled and then chained off of
  {
    bool on_fulfilled_called = false;
    auto promise =
        makePromise<MoveOnly>(MoveOnly{42})
            .then(nullptr, [](std::exception_ptr) { return MoveOnly{0}; })
            .then([&on_fulfilled_called](MoveOnly mo) {
                    EXPECT_EQ(42, mo.value_);
                    on_fulfilled_called = true;
                  },
                  nullptr);

    EXPECT_EQ(true, on_fulfilled_called);
  }
}<|endoftext|>


<commit_before>/*
* Copyright (c) 2003-2015 Rony Shapiro <ronys@users.sourceforge.net>.
* All rights reserved. Use of the code is allowed under the
* Artistic License 2.0 terms, as specified in the LICENSE file
* distributed with this code, or available from
* http://www.opensource.org/licenses/artistic-license-2.0.php
*/

/**
 * \file Windows-specific implementation of registry.h
 *
 * Actually contains two implementations:
 * One for Windows/MFC, and one for wxWidgets
 */

#include "../typedefs.h"
#include "../registry.h"
#include "../debug.h"

#ifndef __WX__

static HKEY hSubTreeKey;      // not re-entrant, but who cares?
static bool bSubTreeKeyValid; // not me!

bool pws_os::RegCheckExists(const TCHAR *stree)
{
  if (stree == NULL)
    stree = ::AfxGetApp()->m_pszRegistryKey;

  const stringT csSubkey = _T("Software\\") + stringT(stree);
  HKEY hSubkey;
  bool bExists = ::RegOpenKeyEx(HKEY_CURRENT_USER, csSubkey.c_str(), 0L,
                                KEY_READ, &hSubkey) == ERROR_SUCCESS;
  if (bExists)
    ::RegCloseKey(hSubkey);
  return bExists;
}

bool pws_os::RegWriteValue(const TCHAR *section, const TCHAR *entry, int value)
{
  return ::AfxGetApp()->WriteProfileInt(section, entry, value) == TRUE;
}

bool pws_os::RegWriteValue(const TCHAR *section, const TCHAR *entry,
                           const TCHAR *value)
{
  return ::AfxGetApp()->WriteProfileString(section, entry, value) == TRUE;
}

bool pws_os::RegDeleteEntry(const TCHAR *name)
{
  HKEY hSubkey;
  DWORD dwResult, dwType;
  bool bRetVal;

  // Keys in registry are in:
  // "HKEY_CURRENT_USER\Software\Password Safe\Password Safe\"
  const stringT csSubkey = _T("Software\\") +
    stringT(::AfxGetApp()->m_pszRegistryKey)
    + _T("\\") +
    stringT(::AfxGetApp()->m_pszRegistryKey);

  dwResult = RegOpenKeyEx(HKEY_CURRENT_USER,
                          csSubkey.c_str(),
                          NULL,
                          KEY_ALL_ACCESS,
                          &hSubkey);

  if (dwResult != ERROR_SUCCESS)
    return false; // may have been called due to OldPrefs

  dwResult = RegQueryValueEx(hSubkey, name, NULL, &dwType, NULL, NULL);
  if (dwResult == ERROR_SUCCESS) {
    // Was there - now delete it
    dwResult = RegDeleteValue(hSubkey, name);
    ASSERT(dwResult == ERROR_SUCCESS);
    bRetVal = (dwResult == ERROR_SUCCESS);
  } else
    bRetVal = true;

  dwResult = RegCloseKey(hSubkey);
  ASSERT(dwResult == ERROR_SUCCESS);
  return bRetVal;
}

int pws_os::RegReadValue(const TCHAR *section, const TCHAR *entry, const int value)
{
  return ::AfxGetApp()->GetProfileInt(section, entry, value);
}

const stringT pws_os::RegReadValue(const TCHAR *section, const TCHAR *entry,
                                   const TCHAR *value)
{
  return (const TCHAR*)::AfxGetApp()->GetProfileString(section, entry, value);
}

void pws_os::RegDeleteSubtree(const TCHAR *stree)
{
  HKEY hSubkey;
  LONG dw = ::RegOpenKeyEx(HKEY_CURRENT_USER,
                           _T("Software"),
                           NULL,
                           KEY_ALL_ACCESS,
                           &hSubkey);
  if (dw != ERROR_SUCCESS) {
    pws_os::Trace0(_T("pws_os::RegDeleteSubtree: RegOpenKeyEx failed\n"));
    return;
  }

  dw = ::AfxGetApp()->DelRegTree(hSubkey, stree);
  if (dw != ERROR_SUCCESS) {
    pws_os::Trace0(_T("pws_os::RegDeleteSubtree: DelRegTree failed\n"));
  }
  dw = ::RegCloseKey(hSubkey);
  if (dw != ERROR_SUCCESS) {
    pws_os::Trace0(_T("pws_os::RegDeleteSubtree: RegCloseKey failed\n"));
  }
}

// Start of registry Subtree functions
// Use static variable hSubTreeKey to hold registry key handle between calls.
bool pws_os::RegOpenSubtree(const TCHAR *stree)
{
  const stringT streeT(stree);
  stringT OldAppKey(_T("Software\\"));
  OldAppKey += streeT; OldAppKey += _T("\\Password Safe");
  LONG dw = ::RegOpenKeyEx(HKEY_CURRENT_USER,
                           OldAppKey.c_str(),
                           NULL,
                           KEY_ALL_ACCESS,
                           &hSubTreeKey);
  bSubTreeKeyValid = (dw == ERROR_SUCCESS);
  return bSubTreeKeyValid;
}

bool pws_os::RegReadSTValue(const TCHAR *name, bool &value)
{
  if (!bSubTreeKeyValid)
    return bSubTreeKeyValid;

  int v;
  bool retval = RegReadSTValue(name, v);
  if (retval)
    value = (v != 0);
  return retval;
}

bool pws_os::RegReadSTValue(const TCHAR *name, int &value)
{
  if (!bSubTreeKeyValid)
    return bSubTreeKeyValid;

  bool retval = false;
  LONG rv;
  DWORD dwType, vData, DataLen(sizeof(vData));
  rv = ::RegQueryValueEx(hSubTreeKey,
                         name,
                         NULL,
                         &dwType,
                         LPBYTE(&vData),
                         &DataLen);
  if (rv == ERROR_SUCCESS && dwType == REG_DWORD) {
    value = vData;
    retval = true;
  }
  return retval;
}

bool pws_os::RegReadSTValue(const TCHAR *name, stringT &value)
{
  if (!bSubTreeKeyValid)
    return bSubTreeKeyValid;

  bool retval = false;
  LONG rv;
  DWORD dwType, DataLen;
  rv = ::RegQueryValueEx(hSubTreeKey,
                         name,
                         NULL,
                         &dwType,
                         NULL,
                         &DataLen);
  if (rv == ERROR_SUCCESS && dwType == REG_SZ) {
    DataLen++;
    TCHAR *pData = new TCHAR[DataLen];
    ::memset(pData, 0, DataLen);
    rv = ::RegQueryValueEx(hSubTreeKey,
                            name,
                            NULL,
                            &dwType,
                            LPBYTE(pData),
                            &DataLen);

    if (rv == ERROR_SUCCESS) {
      value = pData;
      retval = true;
    }
    delete[] pData;
  }
  return retval;
}

bool pws_os::RegCloseSubtree()
{
  if (!bSubTreeKeyValid)
    return bSubTreeKeyValid;

  bool retval = (::RegCloseKey(hSubTreeKey) == ERROR_SUCCESS);
  bSubTreeKeyValid = false;
  return retval;
}

// End of registry Subtree functions

bool pws_os::DeleteRegistryEntries()
{
  HKEY hSubkey;
  const stringT csSubkey = _T("Software\\");
  bool retval = true;

  LONG dw = RegOpenKeyEx(HKEY_CURRENT_USER,
                         csSubkey.c_str(),
                         NULL,
                         KEY_ALL_ACCESS,
                         &hSubkey);
  if (dw != ERROR_SUCCESS) {
    return false; // may have been called due to OldPrefs
  }

  dw = ::AfxGetApp()->DelRegTree(hSubkey, ::AfxGetApp()->m_pszAppName);
  if (dw != ERROR_SUCCESS) {
    pws_os::Trace0(_T("pws_os::DeleteRegistryEntries: DelRegTree() failed\n"));
    retval = false;
  }

  dw = RegCloseKey(hSubkey);
  if (dw != ERROR_SUCCESS) {
    pws_os::Trace0(_T("pws_os::DeleteRegistryEntries: RegCloseKey() failed\n"));
  }
  return retval;
}

#else /* __WX__ */

// XXX All TBD...

bool pws_os::RegCheckExists(const TCHAR *)
{
  return false;
}

bool pws_os::RegWriteValue(const TCHAR *, const TCHAR *, int)
{
  return false;
}

bool pws_os::RegWriteValue(const TCHAR *, const TCHAR *, const TCHAR *)
{
  return false;
}
bool pws_os::RegDeleteEntry(const TCHAR *)
{
  return false;
}

int pws_os::RegReadValue(const TCHAR *, const TCHAR *, int value)
{
  return value;
}

const stringT pws_os::RegReadValue(const TCHAR *, const TCHAR *, const TCHAR *value)
{
  return stringT(value);
}

void pws_os::RegDeleteSubtree(const TCHAR *)
{
}

bool pws_os::RegOpenSubtree(const TCHAR *)
{
  return false;
}

bool pws_os::RegReadSTValue(const TCHAR *, bool &)
{
  return false;
}

bool pws_os::RegReadSTValue(const TCHAR *, int &)
{
  return false;
}

bool pws_os::RegReadSTValue(const TCHAR *, stringT &)
{
  return false;
}

bool pws_os::RegCloseSubtree()
{
  return false;
}

bool pws_os::DeleteRegistryEntries()
{
  return false;
}

#endif /* __WX__ */
<commit_msg>PWSprefs::GetInstance() won't crash under Windows coretest<commit_after>/*
* Copyright (c) 2003-2015 Rony Shapiro <ronys@users.sourceforge.net>.
* All rights reserved. Use of the code is allowed under the
* Artistic License 2.0 terms, as specified in the LICENSE file
* distributed with this code, or available from
* http://www.opensource.org/licenses/artistic-license-2.0.php
*/

/**
 * \file Windows-specific implementation of registry.h
 *
 * Actually contains two implementations:
 * One for Windows/MFC, and one for wxWidgets
 */

#include "../typedefs.h"
#include "../registry.h"
#include "../debug.h"

#ifndef __WX__

static HKEY hSubTreeKey;      // not re-entrant, but who cares?
static bool bSubTreeKeyValid; // not me!

bool pws_os::RegCheckExists(const TCHAR *stree)
{
  if (stree == NULL) {
    CWinApp *app = ::AfxGetApp();
    if (app == NULL) // can happen in unit test framework
      return false;
    stree = app->m_pszRegistryKey;
  }

  const stringT csSubkey = _T("Software\\") + stringT(stree);
  HKEY hSubkey;
  bool bExists = ::RegOpenKeyEx(HKEY_CURRENT_USER, csSubkey.c_str(), 0L,
                                KEY_READ, &hSubkey) == ERROR_SUCCESS;
  if (bExists)
    ::RegCloseKey(hSubkey);
  return bExists;
}

bool pws_os::RegWriteValue(const TCHAR *section, const TCHAR *entry, int value)
{
  return ::AfxGetApp()->WriteProfileInt(section, entry, value) == TRUE;
}

bool pws_os::RegWriteValue(const TCHAR *section, const TCHAR *entry,
                           const TCHAR *value)
{
  return ::AfxGetApp()->WriteProfileString(section, entry, value) == TRUE;
}

bool pws_os::RegDeleteEntry(const TCHAR *name)
{
  HKEY hSubkey;
  DWORD dwResult, dwType;
  bool bRetVal;

  // Keys in registry are in:
  // "HKEY_CURRENT_USER\Software\Password Safe\Password Safe\"
  const stringT csSubkey = _T("Software\\") +
    stringT(::AfxGetApp()->m_pszRegistryKey)
    + _T("\\") +
    stringT(::AfxGetApp()->m_pszRegistryKey);

  dwResult = RegOpenKeyEx(HKEY_CURRENT_USER,
                          csSubkey.c_str(),
                          NULL,
                          KEY_ALL_ACCESS,
                          &hSubkey);

  if (dwResult != ERROR_SUCCESS)
    return false; // may have been called due to OldPrefs

  dwResult = RegQueryValueEx(hSubkey, name, NULL, &dwType, NULL, NULL);
  if (dwResult == ERROR_SUCCESS) {
    // Was there - now delete it
    dwResult = RegDeleteValue(hSubkey, name);
    ASSERT(dwResult == ERROR_SUCCESS);
    bRetVal = (dwResult == ERROR_SUCCESS);
  } else
    bRetVal = true;

  dwResult = RegCloseKey(hSubkey);
  ASSERT(dwResult == ERROR_SUCCESS);
  return bRetVal;
}

int pws_os::RegReadValue(const TCHAR *section, const TCHAR *entry, const int value)
{
  return ::AfxGetApp()->GetProfileInt(section, entry, value);
}

const stringT pws_os::RegReadValue(const TCHAR *section, const TCHAR *entry,
                                   const TCHAR *value)
{
  return (const TCHAR*)::AfxGetApp()->GetProfileString(section, entry, value);
}

void pws_os::RegDeleteSubtree(const TCHAR *stree)
{
  HKEY hSubkey;
  LONG dw = ::RegOpenKeyEx(HKEY_CURRENT_USER,
                           _T("Software"),
                           NULL,
                           KEY_ALL_ACCESS,
                           &hSubkey);
  if (dw != ERROR_SUCCESS) {
    pws_os::Trace0(_T("pws_os::RegDeleteSubtree: RegOpenKeyEx failed\n"));
    return;
  }

  dw = ::AfxGetApp()->DelRegTree(hSubkey, stree);
  if (dw != ERROR_SUCCESS) {
    pws_os::Trace0(_T("pws_os::RegDeleteSubtree: DelRegTree failed\n"));
  }
  dw = ::RegCloseKey(hSubkey);
  if (dw != ERROR_SUCCESS) {
    pws_os::Trace0(_T("pws_os::RegDeleteSubtree: RegCloseKey failed\n"));
  }
}

// Start of registry Subtree functions
// Use static variable hSubTreeKey to hold registry key handle between calls.
bool pws_os::RegOpenSubtree(const TCHAR *stree)
{
  const stringT streeT(stree);
  stringT OldAppKey(_T("Software\\"));
  OldAppKey += streeT; OldAppKey += _T("\\Password Safe");
  LONG dw = ::RegOpenKeyEx(HKEY_CURRENT_USER,
                           OldAppKey.c_str(),
                           NULL,
                           KEY_ALL_ACCESS,
                           &hSubTreeKey);
  bSubTreeKeyValid = (dw == ERROR_SUCCESS);
  return bSubTreeKeyValid;
}

bool pws_os::RegReadSTValue(const TCHAR *name, bool &value)
{
  if (!bSubTreeKeyValid)
    return bSubTreeKeyValid;

  int v;
  bool retval = RegReadSTValue(name, v);
  if (retval)
    value = (v != 0);
  return retval;
}

bool pws_os::RegReadSTValue(const TCHAR *name, int &value)
{
  if (!bSubTreeKeyValid)
    return bSubTreeKeyValid;

  bool retval = false;
  LONG rv;
  DWORD dwType, vData, DataLen(sizeof(vData));
  rv = ::RegQueryValueEx(hSubTreeKey,
                         name,
                         NULL,
                         &dwType,
                         LPBYTE(&vData),
                         &DataLen);
  if (rv == ERROR_SUCCESS && dwType == REG_DWORD) {
    value = vData;
    retval = true;
  }
  return retval;
}

bool pws_os::RegReadSTValue(const TCHAR *name, stringT &value)
{
  if (!bSubTreeKeyValid)
    return bSubTreeKeyValid;

  bool retval = false;
  LONG rv;
  DWORD dwType, DataLen;
  rv = ::RegQueryValueEx(hSubTreeKey,
                         name,
                         NULL,
                         &dwType,
                         NULL,
                         &DataLen);
  if (rv == ERROR_SUCCESS && dwType == REG_SZ) {
    DataLen++;
    TCHAR *pData = new TCHAR[DataLen];
    ::memset(pData, 0, DataLen);
    rv = ::RegQueryValueEx(hSubTreeKey,
                            name,
                            NULL,
                            &dwType,
                            LPBYTE(pData),
                            &DataLen);

    if (rv == ERROR_SUCCESS) {
      value = pData;
      retval = true;
    }
    delete[] pData;
  }
  return retval;
}

bool pws_os::RegCloseSubtree()
{
  if (!bSubTreeKeyValid)
    return bSubTreeKeyValid;

  bool retval = (::RegCloseKey(hSubTreeKey) == ERROR_SUCCESS);
  bSubTreeKeyValid = false;
  return retval;
}

// End of registry Subtree functions

bool pws_os::DeleteRegistryEntries()
{
  HKEY hSubkey;
  const stringT csSubkey = _T("Software\\");
  bool retval = true;

  LONG dw = RegOpenKeyEx(HKEY_CURRENT_USER,
                         csSubkey.c_str(),
                         NULL,
                         KEY_ALL_ACCESS,
                         &hSubkey);
  if (dw != ERROR_SUCCESS) {
    return false; // may have been called due to OldPrefs
  }

  dw = ::AfxGetApp()->DelRegTree(hSubkey, ::AfxGetApp()->m_pszAppName);
  if (dw != ERROR_SUCCESS) {
    pws_os::Trace0(_T("pws_os::DeleteRegistryEntries: DelRegTree() failed\n"));
    retval = false;
  }

  dw = RegCloseKey(hSubkey);
  if (dw != ERROR_SUCCESS) {
    pws_os::Trace0(_T("pws_os::DeleteRegistryEntries: RegCloseKey() failed\n"));
  }
  return retval;
}

#else /* __WX__ */

// XXX All TBD...

bool pws_os::RegCheckExists(const TCHAR *)
{
  return false;
}

bool pws_os::RegWriteValue(const TCHAR *, const TCHAR *, int)
{
  return false;
}

bool pws_os::RegWriteValue(const TCHAR *, const TCHAR *, const TCHAR *)
{
  return false;
}
bool pws_os::RegDeleteEntry(const TCHAR *)
{
  return false;
}

int pws_os::RegReadValue(const TCHAR *, const TCHAR *, int value)
{
  return value;
}

const stringT pws_os::RegReadValue(const TCHAR *, const TCHAR *, const TCHAR *value)
{
  return stringT(value);
}

void pws_os::RegDeleteSubtree(const TCHAR *)
{
}

bool pws_os::RegOpenSubtree(const TCHAR *)
{
  return false;
}

bool pws_os::RegReadSTValue(const TCHAR *, bool &)
{
  return false;
}

bool pws_os::RegReadSTValue(const TCHAR *, int &)
{
  return false;
}

bool pws_os::RegReadSTValue(const TCHAR *, stringT &)
{
  return false;
}

bool pws_os::RegCloseSubtree()
{
  return false;
}

bool pws_os::DeleteRegistryEntries()
{
  return false;
}

#endif /* __WX__ */
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osg/DisplaySettings>
#include <osg/ArgumentParser>
#include <osg/ApplicationUsage>
#include <osg/ref_ptr>

#include <algorithm>

using namespace osg;
using namespace std;

DisplaySettings* DisplaySettings::instance()
{
    static ref_ptr<DisplaySettings> s_displaySettings = new DisplaySettings;
    return s_displaySettings.get();
}

DisplaySettings::DisplaySettings(const DisplaySettings& vs):Referenced()
{
    setDisplaySettings(vs);
}

DisplaySettings::~DisplaySettings()
{
}

 DisplaySettings& DisplaySettings::operator = (const DisplaySettings& vs)
{
    if (this==&vs) return *this;
    setDisplaySettings(vs);
    return *this;
}

void DisplaySettings::setDisplaySettings(const DisplaySettings& vs)
{
    _displayType = vs._displayType;
    _stereoMode = vs._stereoMode;
    _eyeSeparation = vs._eyeSeparation;
    _screenWidth = vs._screenWidth;
    _screenHeight = vs._screenHeight;
    _screenDistance = vs._screenDistance;

    _splitStereoHorizontalEyeMapping = vs._splitStereoHorizontalEyeMapping;
    _splitStereoHorizontalSeparation = vs._splitStereoHorizontalSeparation;

    _splitStereoVerticalEyeMapping = vs._splitStereoVerticalEyeMapping;
    _splitStereoVerticalSeparation = vs._splitStereoVerticalSeparation;

    _splitStereoAutoAdjustAspectRatio = vs._splitStereoAutoAdjustAspectRatio;

    _doubleBuffer = vs._doubleBuffer;
    _RGB = vs._RGB;
    _depthBuffer = vs._depthBuffer;
    _minimumNumberAlphaBits = vs._minimumNumberAlphaBits;
    _minimumNumberStencilBits = vs._minimumNumberStencilBits;

    _maxNumOfGraphicsContexts = vs._maxNumOfGraphicsContexts;
}

void DisplaySettings::merge(const DisplaySettings& vs)
{
    if (_stereo       || vs._stereo)        _stereo = true;

    // need to think what to do about merging the stereo mode.

    if (_doubleBuffer || vs._doubleBuffer)  _doubleBuffer = true;
    if (_RGB          || vs._RGB)           _RGB = true;
    if (_depthBuffer  || vs._depthBuffer)   _depthBuffer = true;

    if (vs._minimumNumberAlphaBits>_minimumNumberAlphaBits) _minimumNumberAlphaBits = vs._minimumNumberAlphaBits;
    if (vs._minimumNumberStencilBits>_minimumNumberStencilBits) _minimumNumberStencilBits = vs._minimumNumberStencilBits;
}

void DisplaySettings::setDefaults()
{
    _displayType = MONITOR;

    _stereo = false;
    _stereoMode = ANAGLYPHIC;
    _eyeSeparation = 0.05f;
    _screenWidth = 0.325f;
    _screenHeight = 0.26f;
    _screenDistance = 0.5f;

    _splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT;
    _splitStereoHorizontalSeparation = 0;

    _splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT;
    _splitStereoVerticalSeparation = 0;

    _splitStereoAutoAdjustAspectRatio = true;

    _doubleBuffer = true;
    _RGB = true;
    _depthBuffer = true;
    _minimumNumberAlphaBits = 0;
    _minimumNumberStencilBits = 0;

    _maxNumOfGraphicsContexts = 3;
}

static ApplicationUsageProxy DisplaySetting_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_DISPLAY_TYPE <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
static ApplicationUsageProxy DisplaySetting_e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO_MODE <mode>","QUAD_BUFFER | ANAGLYPHIC | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE");
static ApplicationUsageProxy DisplaySetting_e2(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO <mode>","OFF | ON");
static ApplicationUsageProxy DisplaySetting_e3(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EYE_SEPARATION <float>","physical distance between eyes");
static ApplicationUsageProxy DisplaySetting_e4(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_DISTANCE <float>","physical distance between eyes and screen");
static ApplicationUsageProxy DisplaySetting_e5(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_HEIGHT <float>","physical screen height");
static ApplicationUsageProxy DisplaySetting_e6(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_WIDTH <float>","physical screen width");
static ApplicationUsageProxy DisplaySetting_e7(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING <mode>","LEFT_EYE_LEFT_VIEWPORT | LEFT_EYE_RIGHT_VIEWPORT");
static ApplicationUsageProxy DisplaySetting_e8(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION <float>","number of pixels between viewports");
static ApplicationUsageProxy DisplaySetting_e9(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING <mode>","LEFT_EYE_TOP_VIEWPORT | LEFT_EYE_BOTTOM_VIEWPORT");
static ApplicationUsageProxy DisplaySetting_e10(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO <mode>","OFF | ON  Default to ON to compenstate for the compression of the aspect ratio when viewing in split screen stereo.  Note, if you are setting fovx and fovy explicityly OFF should be used.");
static ApplicationUsageProxy DisplaySetting_e11(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_SEPARATION <float>","number of pixels between viewports");
static ApplicationUsageProxy DisplaySetting_e12(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS <int>","maximum number of graphics contexts to be used with applications.");

void DisplaySettings::readEnvironmentalVariables()
{
    char *ptr;

    if ((ptr = getenv("OSG_DISPLAY_TYPE")) != 0)
    {
        if (strcmp(ptr,"MONITOR")==0)
        {
            _displayType = MONITOR;
        }
        else
        if (strcmp(ptr,"POWERWALL")==0)
        {
            _displayType = POWERWALL;
        }
        else
        if (strcmp(ptr,"REALITY_CENTER")==0)
        {
            _displayType = REALITY_CENTER;
        }
        else
        if (strcmp(ptr,"HEAD_MOUNTED_DISPLAY")==0)
        {
            _displayType = HEAD_MOUNTED_DISPLAY;
        }
    }

    if( (ptr = getenv("OSG_STEREO_MODE")) != 0)
    {
        if (strcmp(ptr,"QUAD_BUFFER")==0)
        {
            _stereoMode = QUAD_BUFFER;
        }
        else
        if (strcmp(ptr,"ANAGLYPHIC")==0)
        {
            _stereoMode = ANAGLYPHIC;
        }
        else
        if (strcmp(ptr,"HORIZONTAL_SPLIT")==0)
        {
            _stereoMode = HORIZONTAL_SPLIT;
        }
        else
        if (strcmp(ptr,"VERTICAL_SPLIT")==0)
        {
            _stereoMode = VERTICAL_SPLIT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE")==0)
        {
            _stereoMode = LEFT_EYE;
        }
        else
        if (strcmp(ptr,"RIGHT_EYE")==0)
        {
            _stereoMode = RIGHT_EYE;
        }
    }

    if( (ptr = getenv("OSG_STEREO")) != 0)
    {
        if (strcmp(ptr,"OFF")==0)
        {
            _stereo = false;
        }
        else
        if (strcmp(ptr,"ON")==0)
        {
            _stereo = true;
        }
    }

    if( (ptr = getenv("OSG_EYE_SEPARATION")) != 0)
    {
        _eyeSeparation = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_WIDTH")) != 0)
    {
        _screenWidth = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_HEIGHT")) != 0)
    {
        _screenHeight = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_DISTANCE")) != 0)
    {
        _screenDistance = atof(ptr);
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING")) != 0)
    {
        if (strcmp(ptr,"LEFT_EYE_LEFT_VIEWPORT")==0)
        {
            _splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE_RIGHT_VIEWPORT")==0)
        {
            _splitStereoHorizontalEyeMapping = LEFT_EYE_RIGHT_VIEWPORT;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION")) != 0)
    {
        _splitStereoHorizontalSeparation = atoi(ptr);
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING")) != 0)
    {
        if (strcmp(ptr,"LEFT_EYE_TOP_VIEWPORT")==0)
        {
            _splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE_BOTTOM_VIEWPORT")==0)
        {
            _splitStereoVerticalEyeMapping = LEFT_EYE_BOTTOM_VIEWPORT;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO")) != 0)
    {
        if (strcmp(ptr,"OFF")==0)
        {
            _splitStereoAutoAdjustAspectRatio = false;
        }
        else
        if (strcmp(ptr,"ON")==0)
        {
            _splitStereoAutoAdjustAspectRatio = true;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_SEPARATION")) != 0)
    {
        _splitStereoVerticalSeparation = atoi(ptr);
    }

    if( (ptr = getenv("OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS")) != 0)
    {
        _maxNumOfGraphicsContexts = atoi(ptr);
    }
}

void DisplaySettings::readCommandLine(ArgumentParser& arguments)
{

    // report the usage options.
    if (arguments.getApplicationUsage())
    {
        arguments.getApplicationUsage()->addCommandLineOption("--display <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
        arguments.getApplicationUsage()->addCommandLineOption("--stereo","Use default stereo mode which is ANAGLYPHIC if not overriden by environmental variable");
        arguments.getApplicationUsage()->addCommandLineOption("--stereo <mode>","ANAGLYPHIC | QUAD_BUFFER | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE | ON | OFF ");
        arguments.getApplicationUsage()->addCommandLineOption("--rgba","Request a RGBA color buffer visual");
        arguments.getApplicationUsage()->addCommandLineOption("--stencil","Request a stencil buffer visual");
    }

    std::string str;
    while(arguments.read("--display",str))
    {
        if (str=="MONITOR") _displayType = MONITOR;
        else if (str=="POWERWALL") _displayType = POWERWALL;
        else if (str=="REALITY_CENTER") _displayType = REALITY_CENTER;
        else if (str=="HEAD_MOUNTED_DISPLAY") _displayType = HEAD_MOUNTED_DISPLAY;
    }

    int pos;
    while ((pos=arguments.find("--stereo"))!=0)
    {
        if (arguments.match(pos+1,"ANAGLYPHIC"))            { arguments.remove(pos,2); _stereo = true;_stereoMode = ANAGLYPHIC; }
        else if (arguments.match(pos+1,"QUAD_BUFFER"))      { arguments.remove(pos,2); _stereo = true;_stereoMode = QUAD_BUFFER; }
        else if (arguments.match(pos+1,"HORIZONTAL_SPLIT")) { arguments.remove(pos,2); _stereo = true;_stereoMode = HORIZONTAL_SPLIT; }
        else if (arguments.match(pos+1,"VERTICAL_SPLIT"))   { arguments.remove(pos,2); _stereo = true;_stereoMode = VERTICAL_SPLIT; }
        else if (arguments.match(pos+1,"LEFT_EYE"))         { arguments.remove(pos,2); _stereo = true;_stereoMode = LEFT_EYE; }
        else if (arguments.match(pos+1,"RIGHT_EYE"))        { arguments.remove(pos,2); _stereo = true;_stereoMode = RIGHT_EYE; }
        else if (arguments.match(pos+1,"ON"))               { arguments.remove(pos,2); _stereo = true; }
        else if (arguments.match(pos+1,"OFF"))              { arguments.remove(pos,2); _stereo = false; }
        else                                                { arguments.remove(pos); _stereo = true; }
    }

    while (arguments.read("--rgba"))
    {
        _RGB = true;
        _minimumNumberAlphaBits = 1;
    }

    while (arguments.read("--stencil"))
    {
        _minimumNumberStencilBits = 1;
    }
}
<commit_msg>Added missing copy of _stereo<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/
#include <osg/DisplaySettings>
#include <osg/ArgumentParser>
#include <osg/ApplicationUsage>
#include <osg/ref_ptr>

#include <algorithm>

using namespace osg;
using namespace std;

DisplaySettings* DisplaySettings::instance()
{
    static ref_ptr<DisplaySettings> s_displaySettings = new DisplaySettings;
    return s_displaySettings.get();
}

DisplaySettings::DisplaySettings(const DisplaySettings& vs):Referenced()
{
    setDisplaySettings(vs);
}

DisplaySettings::~DisplaySettings()
{
}

 DisplaySettings& DisplaySettings::operator = (const DisplaySettings& vs)
{
    if (this==&vs) return *this;
    setDisplaySettings(vs);
    return *this;
}

void DisplaySettings::setDisplaySettings(const DisplaySettings& vs)
{
    _displayType = vs._displayType;
    _stereo = vs._stereo;
    _stereoMode = vs._stereoMode;
    _eyeSeparation = vs._eyeSeparation;
    _screenWidth = vs._screenWidth;
    _screenHeight = vs._screenHeight;
    _screenDistance = vs._screenDistance;

    _splitStereoHorizontalEyeMapping = vs._splitStereoHorizontalEyeMapping;
    _splitStereoHorizontalSeparation = vs._splitStereoHorizontalSeparation;

    _splitStereoVerticalEyeMapping = vs._splitStereoVerticalEyeMapping;
    _splitStereoVerticalSeparation = vs._splitStereoVerticalSeparation;

    _splitStereoAutoAdjustAspectRatio = vs._splitStereoAutoAdjustAspectRatio;

    _doubleBuffer = vs._doubleBuffer;
    _RGB = vs._RGB;
    _depthBuffer = vs._depthBuffer;
    _minimumNumberAlphaBits = vs._minimumNumberAlphaBits;
    _minimumNumberStencilBits = vs._minimumNumberStencilBits;

    _maxNumOfGraphicsContexts = vs._maxNumOfGraphicsContexts;
}

void DisplaySettings::merge(const DisplaySettings& vs)
{
    if (_stereo       || vs._stereo)        _stereo = true;

    // need to think what to do about merging the stereo mode.

    if (_doubleBuffer || vs._doubleBuffer)  _doubleBuffer = true;
    if (_RGB          || vs._RGB)           _RGB = true;
    if (_depthBuffer  || vs._depthBuffer)   _depthBuffer = true;

    if (vs._minimumNumberAlphaBits>_minimumNumberAlphaBits) _minimumNumberAlphaBits = vs._minimumNumberAlphaBits;
    if (vs._minimumNumberStencilBits>_minimumNumberStencilBits) _minimumNumberStencilBits = vs._minimumNumberStencilBits;
}

void DisplaySettings::setDefaults()
{
    _displayType = MONITOR;

    _stereo = false;
    _stereoMode = ANAGLYPHIC;
    _eyeSeparation = 0.05f;
    _screenWidth = 0.325f;
    _screenHeight = 0.26f;
    _screenDistance = 0.5f;

    _splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT;
    _splitStereoHorizontalSeparation = 0;

    _splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT;
    _splitStereoVerticalSeparation = 0;

    _splitStereoAutoAdjustAspectRatio = true;

    _doubleBuffer = true;
    _RGB = true;
    _depthBuffer = true;
    _minimumNumberAlphaBits = 0;
    _minimumNumberStencilBits = 0;

    _maxNumOfGraphicsContexts = 3;
}

static ApplicationUsageProxy DisplaySetting_e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_DISPLAY_TYPE <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
static ApplicationUsageProxy DisplaySetting_e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO_MODE <mode>","QUAD_BUFFER | ANAGLYPHIC | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE");
static ApplicationUsageProxy DisplaySetting_e2(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO <mode>","OFF | ON");
static ApplicationUsageProxy DisplaySetting_e3(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EYE_SEPARATION <float>","physical distance between eyes");
static ApplicationUsageProxy DisplaySetting_e4(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_DISTANCE <float>","physical distance between eyes and screen");
static ApplicationUsageProxy DisplaySetting_e5(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_HEIGHT <float>","physical screen height");
static ApplicationUsageProxy DisplaySetting_e6(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_WIDTH <float>","physical screen width");
static ApplicationUsageProxy DisplaySetting_e7(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING <mode>","LEFT_EYE_LEFT_VIEWPORT | LEFT_EYE_RIGHT_VIEWPORT");
static ApplicationUsageProxy DisplaySetting_e8(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION <float>","number of pixels between viewports");
static ApplicationUsageProxy DisplaySetting_e9(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING <mode>","LEFT_EYE_TOP_VIEWPORT | LEFT_EYE_BOTTOM_VIEWPORT");
static ApplicationUsageProxy DisplaySetting_e10(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO <mode>","OFF | ON  Default to ON to compenstate for the compression of the aspect ratio when viewing in split screen stereo.  Note, if you are setting fovx and fovy explicityly OFF should be used.");
static ApplicationUsageProxy DisplaySetting_e11(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_SEPARATION <float>","number of pixels between viewports");
static ApplicationUsageProxy DisplaySetting_e12(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS <int>","maximum number of graphics contexts to be used with applications.");

void DisplaySettings::readEnvironmentalVariables()
{
    char *ptr;

    if ((ptr = getenv("OSG_DISPLAY_TYPE")) != 0)
    {
        if (strcmp(ptr,"MONITOR")==0)
        {
            _displayType = MONITOR;
        }
        else
        if (strcmp(ptr,"POWERWALL")==0)
        {
            _displayType = POWERWALL;
        }
        else
        if (strcmp(ptr,"REALITY_CENTER")==0)
        {
            _displayType = REALITY_CENTER;
        }
        else
        if (strcmp(ptr,"HEAD_MOUNTED_DISPLAY")==0)
        {
            _displayType = HEAD_MOUNTED_DISPLAY;
        }
    }

    if( (ptr = getenv("OSG_STEREO_MODE")) != 0)
    {
        if (strcmp(ptr,"QUAD_BUFFER")==0)
        {
            _stereoMode = QUAD_BUFFER;
        }
        else
        if (strcmp(ptr,"ANAGLYPHIC")==0)
        {
            _stereoMode = ANAGLYPHIC;
        }
        else
        if (strcmp(ptr,"HORIZONTAL_SPLIT")==0)
        {
            _stereoMode = HORIZONTAL_SPLIT;
        }
        else
        if (strcmp(ptr,"VERTICAL_SPLIT")==0)
        {
            _stereoMode = VERTICAL_SPLIT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE")==0)
        {
            _stereoMode = LEFT_EYE;
        }
        else
        if (strcmp(ptr,"RIGHT_EYE")==0)
        {
            _stereoMode = RIGHT_EYE;
        }
    }

    if( (ptr = getenv("OSG_STEREO")) != 0)
    {
        if (strcmp(ptr,"OFF")==0)
        {
            _stereo = false;
        }
        else
        if (strcmp(ptr,"ON")==0)
        {
            _stereo = true;
        }
    }

    if( (ptr = getenv("OSG_EYE_SEPARATION")) != 0)
    {
        _eyeSeparation = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_WIDTH")) != 0)
    {
        _screenWidth = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_HEIGHT")) != 0)
    {
        _screenHeight = atof(ptr);
    }

    if( (ptr = getenv("OSG_SCREEN_DISTANCE")) != 0)
    {
        _screenDistance = atof(ptr);
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING")) != 0)
    {
        if (strcmp(ptr,"LEFT_EYE_LEFT_VIEWPORT")==0)
        {
            _splitStereoHorizontalEyeMapping = LEFT_EYE_LEFT_VIEWPORT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE_RIGHT_VIEWPORT")==0)
        {
            _splitStereoHorizontalEyeMapping = LEFT_EYE_RIGHT_VIEWPORT;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION")) != 0)
    {
        _splitStereoHorizontalSeparation = atoi(ptr);
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING")) != 0)
    {
        if (strcmp(ptr,"LEFT_EYE_TOP_VIEWPORT")==0)
        {
            _splitStereoVerticalEyeMapping = LEFT_EYE_TOP_VIEWPORT;
        }
        else
        if (strcmp(ptr,"LEFT_EYE_BOTTOM_VIEWPORT")==0)
        {
            _splitStereoVerticalEyeMapping = LEFT_EYE_BOTTOM_VIEWPORT;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_AUTO_ADJUST_ASPECT_RATIO")) != 0)
    {
        if (strcmp(ptr,"OFF")==0)
        {
            _splitStereoAutoAdjustAspectRatio = false;
        }
        else
        if (strcmp(ptr,"ON")==0)
        {
            _splitStereoAutoAdjustAspectRatio = true;
        }
    }

    if( (ptr = getenv("OSG_SPLIT_STEREO_VERTICAL_SEPARATION")) != 0)
    {
        _splitStereoVerticalSeparation = atoi(ptr);
    }

    if( (ptr = getenv("OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS")) != 0)
    {
        _maxNumOfGraphicsContexts = atoi(ptr);
    }
}

void DisplaySettings::readCommandLine(ArgumentParser& arguments)
{

    // report the usage options.
    if (arguments.getApplicationUsage())
    {
        arguments.getApplicationUsage()->addCommandLineOption("--display <type>","MONITOR | POWERWALL | REALITY_CENTER | HEAD_MOUNTED_DISPLAY");
        arguments.getApplicationUsage()->addCommandLineOption("--stereo","Use default stereo mode which is ANAGLYPHIC if not overriden by environmental variable");
        arguments.getApplicationUsage()->addCommandLineOption("--stereo <mode>","ANAGLYPHIC | QUAD_BUFFER | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE | ON | OFF ");
        arguments.getApplicationUsage()->addCommandLineOption("--rgba","Request a RGBA color buffer visual");
        arguments.getApplicationUsage()->addCommandLineOption("--stencil","Request a stencil buffer visual");
    }

    std::string str;
    while(arguments.read("--display",str))
    {
        if (str=="MONITOR") _displayType = MONITOR;
        else if (str=="POWERWALL") _displayType = POWERWALL;
        else if (str=="REALITY_CENTER") _displayType = REALITY_CENTER;
        else if (str=="HEAD_MOUNTED_DISPLAY") _displayType = HEAD_MOUNTED_DISPLAY;
    }

    int pos;
    while ((pos=arguments.find("--stereo"))!=0)
    {
        if (arguments.match(pos+1,"ANAGLYPHIC"))            { arguments.remove(pos,2); _stereo = true;_stereoMode = ANAGLYPHIC; }
        else if (arguments.match(pos+1,"QUAD_BUFFER"))      { arguments.remove(pos,2); _stereo = true;_stereoMode = QUAD_BUFFER; }
        else if (arguments.match(pos+1,"HORIZONTAL_SPLIT")) { arguments.remove(pos,2); _stereo = true;_stereoMode = HORIZONTAL_SPLIT; }
        else if (arguments.match(pos+1,"VERTICAL_SPLIT"))   { arguments.remove(pos,2); _stereo = true;_stereoMode = VERTICAL_SPLIT; }
        else if (arguments.match(pos+1,"LEFT_EYE"))         { arguments.remove(pos,2); _stereo = true;_stereoMode = LEFT_EYE; }
        else if (arguments.match(pos+1,"RIGHT_EYE"))        { arguments.remove(pos,2); _stereo = true;_stereoMode = RIGHT_EYE; }
        else if (arguments.match(pos+1,"ON"))               { arguments.remove(pos,2); _stereo = true; }
        else if (arguments.match(pos+1,"OFF"))              { arguments.remove(pos,2); _stereo = false; }
        else                                                { arguments.remove(pos); _stereo = true; }
    }

    while (arguments.read("--rgba"))
    {
        _RGB = true;
        _minimumNumberAlphaBits = 1;
    }

    while (arguments.read("--stencil"))
    {
        _minimumNumberStencilBits = 1;
    }
}
<|endoftext|>