<commit_before>//
// vtTerrainScene - Container class for all of the terrains loaded
//
// Copyright (c) 2001 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "TerrainScene.h"
#include "Light.h"
#include "SkyDome.h"
#include "Terrain.h"
#include "TimeEngines.h"

///////////////////////////////////////////////////////////////////////
/**
 * A small engine that allows the SkyDome to stay around the Camera.
 */
class vtSkyTrackEngine : public vtEngine
{
public:
	vtSkyTrackEngine();
	virtual void Eval();
	vtCamera *m_pCamera;
};

vtSkyTrackEngine::vtSkyTrackEngine() : vtEngine()
{
	m_pCamera = NULL;
}

void vtSkyTrackEngine::Eval()
{
	// get the location of the camera and the target (skydome)
	vtTransform *pTarget = (vtTransform *) GetTarget();
	if (!pTarget || !m_pCamera)
		return;
	FPoint3 pos1 = m_pCamera->GetTrans();
	FPoint3 pos2 = pTarget->GetTrans();

	// move the target (skydome) to be centers in XZ on the camera
	pos2.x = pos1.x;
	pos2.z = pos1.z;
	pTarget->SetTrans(pos2);
}

///////////////////////////////////////////////////////////////////////
//
// vtTerrainScene class
//

vtTerrainScene::vtTerrainScene()
{
	horizon_color.Set(0.70f, 0.85f, 1.0f);
	azimuth_color.Set(0.12f, 0.32f, 0.70f);

	m_pSkyDome = NULL;
	m_pFirstTerrain = NULL;
	m_pCurrentTerrain = NULL;
	m_pTime = NULL;
	m_pSkyTrack = NULL;
	m_pSunLight = NULL;
}

vtTerrainScene::~vtTerrainScene()
{
	vtGetScene()->RemoveEngine(m_pTime);
	vtGetScene()->RemoveEngine(m_pSkyTrack);

	delete m_pTime;
	delete m_pSkyTrack;

	while (m_pFirstTerrain)
	{
		vtTerrain *del = m_pFirstTerrain;
		m_pFirstTerrain = m_pFirstTerrain->GetNext();
		delete del;
	}
	m_pFirstTerrain = NULL;
	m_pCurrentTerrain = NULL;
}

void vtTerrainScene::_CreateSkydome(const StringArray &datapath)
{
	if (m_pSkyDome != NULL)
		return;

	// 'bsc' is the Bright Star Catalog
	vtString bsc = FindFileOnPaths(datapath, "Sky/bsc.data");
	vtString sun = FindFileOnPaths(datapath, "Sky/glow2.png");
	vtString moon = FindFileOnPaths(datapath, "Sky/moon5_256.png");

	// create a day-night dome
	m_pSkyDome = new vtSkyDome();
	m_pSkyDome->SetDayColors(horizon_color, azimuth_color);
	m_pSkyDome->SetDawnTimes(5, 0, 7, 0);
	m_pSkyDome->SetDuskTimes(17, 0, 19, 0);

	m_pSkyDome->Create(bsc, 3, 1.0f,	// initially unit radius
		sun, moon);
	m_pSkyDome->SetName2("The Sky");
	m_pAtmosphereGroup->AddChild(m_pSkyDome);

	m_pSkyTrack = new vtSkyTrackEngine();
	m_pSkyTrack->SetName2("Sky-Camera-Following");
	m_pSkyTrack->m_pCamera = vtGetScene()->GetCamera();
	m_pSkyTrack->SetTarget(m_pSkyDome);
	vtGetScene()->AddEngine(m_pSkyTrack);
}

/**
 * Find a terrain whose name begins with a given string.
 */
vtTerrain *vtTerrainScene::FindTerrainByName(const char *name)
{
	int len = strlen(name);
	if (!len)
		return NULL;

	for (vtTerrain *pTerr = m_pFirstTerrain; pTerr; pTerr=pTerr->GetNext())
	{
		if (!strncmp(name, pTerr->GetName(), len))
			return pTerr;
	}
	return NULL;
}

void vtTerrainScene::_CreateEngines(bool bDoSound)
{
	// Set Time in motion
	m_pTime = new TimeEngine(this, 0);
	m_pTime->SetName2("Time");
	m_pTime->SetEnabled(false);
	vtGetScene()->AddEngine(m_pTime);
}

/**
 * Call this method once before adding any terrains, to initialize
 * the vtTerrainScene object.
 */
vtRoot *vtTerrainScene::BeginTerrainScene(bool bDoSound)
{
	_CreateEngines(bDoSound);

	m_pTop = new vtRoot();
	m_pTop->SetName2("All Terrain");

	// create the sun
	vtLight *pLight = new vtLight();
	pLight->SetName2("Main Light");
	m_pSunLight = new vtMovLight(pLight);

	// default location: over our right shoulder, pointing downward
	m_pSunLight->Translate1(FPoint3(1000.0f, 1000.0f, 1000.0f));
	m_pSunLight->RotateLocal(FPoint3(0,1,0), PIf/4.0f);
	m_pSunLight->RotateLocal(FPoint3(1,0,0), -PIf/4.0f);
	m_pSunLight->SetName2("SunLight");

	m_pTop->AddChild(m_pSunLight);

	// create sky group - this holds all celestial objects
	m_pAtmosphereGroup = new vtGroup();
	m_pAtmosphereGroup->SetName2("Atmosphere Group");
	m_pTop->AddChild(m_pAtmosphereGroup);

	return m_pTop;
}

/**
 * Adds a terrain to the scene.
 */
void vtTerrainScene::AppendTerrain(vtTerrain *pTerrain)
{
	// add to linked list
	pTerrain->SetNext(m_pFirstTerrain);
	m_pFirstTerrain = pTerrain;
}

/**
 * Call once after you have appended all of your terrains.
 */
void vtTerrainScene::Finish(const StringArray &datapath)
{
	_CreateSkydome(datapath);

	// start out with no scene active
	for (vtTerrain *t = m_pFirstTerrain; t != NULL; t=t->GetNext())
		t->ActivateEngines(false);
}

/**
 * Set the current Terrain for the scene.  There can only be one terrain
 * active a at time.  If you have more than one terrain, you can use this
 * method to switch between them.
 */
void vtTerrainScene::SetTerrain(vtTerrain *pTerrain)
{
	if (m_pCurrentTerrain != NULL)
	{
		// turn off the scene graph of the previous terrain
		m_pCurrentTerrain->Enable(false);

		// turn off the engines specific to the previous terrain
		m_pCurrentTerrain->ActivateEngines(false);
	}
	m_pCurrentTerrain = pTerrain;

	// if setting to no terrain nothing more to do
	if (!pTerrain)
	{
		if (m_pSkyDome != NULL)
			m_pSkyDome->SetEnabled(false);
		return;
	}

	// switch
	m_pTop->AddChild(m_pCurrentTerrain->GetTopGroup());
	m_pCurrentTerrain->Enable(true);

	TParams &param = m_pCurrentTerrain->GetParams();

	// switch to the projection of this terrain
	m_pCurrentTerrain->SetGlobalProjection();

	// move the sky to fit the new current terrain
	m_pSkyDome->SetEnabled(true);
	FRECT world_ext = pTerrain->GetHeightField()->m_WorldExtents;
	float radius = world_ext.Width() * 5.0;
	float max_radius = 450000;
	if (radius > max_radius)
		radius = max_radius;
	m_pSkyDome->SetRadius(radius);

	// Set background color to match the ocean
	vtGetScene()->SetBgColor(m_pCurrentTerrain->GetOceanColor());

	// turn on the engines specific to the new terrain
	m_pCurrentTerrain->ActivateEngines(true);

	// set the time to the time of the new terrain
	int time = param.m_iInitTime * 3600;
	SetTimeOfDay(time, true);

	// setup time engine
	m_pTime->SetTime(time);
	m_pTime->SetRealIncrement(param.m_fTimeSpeed);
	m_pTime->SetEnabled(param.m_bTimeOn);

	// handle the atmosphere
	m_pSkyDome->SetEnabled(param.m_bSky);
	if (param.m_bSky && param.m_strSkyTexture != "")
	{
		vtString filename = "Sky/";
		filename += param.m_strSkyTexture;
		vtString skytex = FindFileOnPaths(vtTerrain::m_DataPaths, filename);
		if (skytex != "")
			m_pSkyDome->SetTexture(skytex);
	}
	SetFog(param.m_bFog);
}

void vtTerrainScene::ToggleFog()
{
	SetFog(!m_bFog);
}

void vtTerrainScene::SetFog(bool fog)
{
	if (!m_pCurrentTerrain)
		return;
	m_bFog = fog;
	if (m_bFog)
	{
		TParams &param = m_pCurrentTerrain->GetParams();
		m_pCurrentTerrain->GetTopGroup()->SetFog(true, 0, param.m_iFogDistance * 1000);
		vtGetScene()->SetBgColor(horizon_color);
	}
	else
	{
		m_pCurrentTerrain->GetTopGroup()->SetFog(false);
		vtGetScene()->SetBgColor(m_pCurrentTerrain->GetOceanColor());
	}
}

void vtTerrainScene::SetTimeOfDay(unsigned int time, bool fFullRefresh)
{
	if (m_pSkyDome)
	{
		m_pSkyDome->SetSunLight(GetSunLight());
		m_pSkyDome->SetTimeOfDay(time, fFullRefresh);
//		m_pSkyDome->ApplyDayColors();
	}
	// TODO? Update the fog color to match the color of the horizon.
}
<commit_msg>added some debug logging<commit_after>//
// vtTerrainScene - Container class for all of the terrains loaded
//
// Copyright (c) 2001-2003 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "vtdata/vtLog.h"
#include "TerrainScene.h"
#include "Light.h"
#include "SkyDome.h"
#include "Terrain.h"
#include "TimeEngines.h"

///////////////////////////////////////////////////////////////////////
/**
 * A small engine that allows the SkyDome to stay around the Camera.
 */
class vtSkyTrackEngine : public vtEngine
{
public:
	vtSkyTrackEngine();
	virtual void Eval();
	vtCamera *m_pCamera;
};

vtSkyTrackEngine::vtSkyTrackEngine() : vtEngine()
{
	m_pCamera = NULL;
}

void vtSkyTrackEngine::Eval()
{
	// get the location of the camera and the target (skydome)
	vtTransform *pTarget = (vtTransform *) GetTarget();
	if (!pTarget || !m_pCamera)
		return;
	FPoint3 pos1 = m_pCamera->GetTrans();
	FPoint3 pos2 = pTarget->GetTrans();

	// move the target (skydome) to be centers in XZ on the camera
	pos2.x = pos1.x;
	pos2.z = pos1.z;
	pTarget->SetTrans(pos2);
}

///////////////////////////////////////////////////////////////////////
//
// vtTerrainScene class
//

vtTerrainScene::vtTerrainScene()
{
	horizon_color.Set(0.70f, 0.85f, 1.0f);
	azimuth_color.Set(0.12f, 0.32f, 0.70f);

	m_pSkyDome = NULL;
	m_pFirstTerrain = NULL;
	m_pCurrentTerrain = NULL;
	m_pTime = NULL;
	m_pSkyTrack = NULL;
	m_pSunLight = NULL;
}

vtTerrainScene::~vtTerrainScene()
{
	vtGetScene()->RemoveEngine(m_pTime);
	vtGetScene()->RemoveEngine(m_pSkyTrack);

	delete m_pTime;
	delete m_pSkyTrack;

	while (m_pFirstTerrain)
	{
		vtTerrain *del = m_pFirstTerrain;
		m_pFirstTerrain = m_pFirstTerrain->GetNext();
		delete del;
	}
	m_pFirstTerrain = NULL;
	m_pCurrentTerrain = NULL;
}

void vtTerrainScene::_CreateSkydome(const StringArray &datapath)
{
	if (m_pSkyDome != NULL)
		return;

	// 'bsc' is the Bright Star Catalog
	vtString bsc = FindFileOnPaths(datapath, "Sky/bsc.data");
	vtString sun = FindFileOnPaths(datapath, "Sky/glow2.png");
	vtString moon = FindFileOnPaths(datapath, "Sky/moon5_256.png");

	// create a day-night dome
	m_pSkyDome = new vtSkyDome();
	m_pSkyDome->SetDayColors(horizon_color, azimuth_color);
	m_pSkyDome->SetDawnTimes(5, 0, 7, 0);
	m_pSkyDome->SetDuskTimes(17, 0, 19, 0);

	m_pSkyDome->Create(bsc, 3, 1.0f,	// initially unit radius
		sun, moon);
	m_pSkyDome->SetName2("The Sky");
	m_pAtmosphereGroup->AddChild(m_pSkyDome);

	m_pSkyTrack = new vtSkyTrackEngine();
	m_pSkyTrack->SetName2("Sky-Camera-Following");
	m_pSkyTrack->m_pCamera = vtGetScene()->GetCamera();
	m_pSkyTrack->SetTarget(m_pSkyDome);
	vtGetScene()->AddEngine(m_pSkyTrack);
}

/**
 * Find a terrain whose name begins with a given string.
 */
vtTerrain *vtTerrainScene::FindTerrainByName(const char *name)
{
	int len = strlen(name);
	if (!len)
		return NULL;

	for (vtTerrain *pTerr = m_pFirstTerrain; pTerr; pTerr=pTerr->GetNext())
	{
		if (!strncmp(name, pTerr->GetName(), len))
			return pTerr;
	}
	return NULL;
}

void vtTerrainScene::_CreateEngines(bool bDoSound)
{
	// Set Time in motion
	m_pTime = new TimeEngine(this, 0);
	m_pTime->SetName2("Time");
	m_pTime->SetEnabled(false);
	vtGetScene()->AddEngine(m_pTime);
}

/**
 * Call this method once before adding any terrains, to initialize
 * the vtTerrainScene object.
 */
vtRoot *vtTerrainScene::BeginTerrainScene(bool bDoSound)
{
	VTLOG("BeginTerrainScene:\n");
	_CreateEngines(bDoSound);

	m_pTop = new vtRoot();
	m_pTop->SetName2("All Terrain");

	// create the sun
	VTLOG("  creating Main Light\n");
	vtLight *pLight = new vtLight();
	pLight->SetName2("Main Light");
	m_pSunLight = new vtMovLight(pLight);

	// default location: over our right shoulder, pointing downward
	m_pSunLight->Translate1(FPoint3(1000.0f, 1000.0f, 1000.0f));
	m_pSunLight->RotateLocal(FPoint3(0,1,0), PIf/4.0f);
	m_pSunLight->RotateLocal(FPoint3(1,0,0), -PIf/4.0f);
	m_pSunLight->SetName2("SunLight");

	m_pTop->AddChild(m_pSunLight);

	// create sky group - this holds all celestial objects
	VTLOG("  creating Sky\n");
	m_pAtmosphereGroup = new vtGroup();
	m_pAtmosphereGroup->SetName2("Atmosphere Group");
	m_pTop->AddChild(m_pAtmosphereGroup);

	return m_pTop;
}

/**
 * Adds a terrain to the scene.
 */
void vtTerrainScene::AppendTerrain(vtTerrain *pTerrain)
{
	// add to linked list
	pTerrain->SetNext(m_pFirstTerrain);
	m_pFirstTerrain = pTerrain;
}

/**
 * Call once after you have appended all of your terrains.
 */
void vtTerrainScene::Finish(const StringArray &datapath)
{
	_CreateSkydome(datapath);

	// start out with no scene active
	for (vtTerrain *t = m_pFirstTerrain; t != NULL; t=t->GetNext())
		t->ActivateEngines(false);
}

/**
 * Set the current Terrain for the scene.  There can only be one terrain
 * active a at time.  If you have more than one terrain, you can use this
 * method to switch between them.
 */
void vtTerrainScene::SetTerrain(vtTerrain *pTerrain)
{
	if (m_pCurrentTerrain != NULL)
	{
		// turn off the scene graph of the previous terrain
		m_pCurrentTerrain->Enable(false);

		// turn off the engines specific to the previous terrain
		m_pCurrentTerrain->ActivateEngines(false);
	}
	m_pCurrentTerrain = pTerrain;

	// if setting to no terrain nothing more to do
	if (!pTerrain)
	{
		if (m_pSkyDome != NULL)
			m_pSkyDome->SetEnabled(false);
		return;
	}

	// switch
	m_pTop->AddChild(m_pCurrentTerrain->GetTopGroup());
	m_pCurrentTerrain->Enable(true);

	TParams &param = m_pCurrentTerrain->GetParams();

	// switch to the projection of this terrain
	m_pCurrentTerrain->SetGlobalProjection();

	// move the sky to fit the new current terrain
	m_pSkyDome->SetEnabled(true);
	FRECT world_ext = pTerrain->GetHeightField()->m_WorldExtents;
	float radius = world_ext.Width() * 5.0;
	float max_radius = 450000;
	if (radius > max_radius)
		radius = max_radius;
	m_pSkyDome->SetRadius(radius);

	// Set background color to match the ocean
	vtGetScene()->SetBgColor(m_pCurrentTerrain->GetOceanColor());

	// turn on the engines specific to the new terrain
	m_pCurrentTerrain->ActivateEngines(true);

	// set the time to the time of the new terrain
	int time = param.m_iInitTime * 3600;
	SetTimeOfDay(time, true);

	// setup time engine
	m_pTime->SetTime(time);
	m_pTime->SetRealIncrement(param.m_fTimeSpeed);
	m_pTime->SetEnabled(param.m_bTimeOn);

	// handle the atmosphere
	m_pSkyDome->SetEnabled(param.m_bSky);
	if (param.m_bSky && param.m_strSkyTexture != "")
	{
		vtString filename = "Sky/";
		filename += param.m_strSkyTexture;
		vtString skytex = FindFileOnPaths(vtTerrain::m_DataPaths, filename);
		if (skytex != "")
			m_pSkyDome->SetTexture(skytex);
	}
	SetFog(param.m_bFog);
}

void vtTerrainScene::ToggleFog()
{
	SetFog(!m_bFog);
}

void vtTerrainScene::SetFog(bool fog)
{
	if (!m_pCurrentTerrain)
		return;
	m_bFog = fog;
	if (m_bFog)
	{
		TParams &param = m_pCurrentTerrain->GetParams();
		m_pCurrentTerrain->GetTopGroup()->SetFog(true, 0, param.m_iFogDistance * 1000);
		vtGetScene()->SetBgColor(horizon_color);
	}
	else
	{
		m_pCurrentTerrain->GetTopGroup()->SetFog(false);
		vtGetScene()->SetBgColor(m_pCurrentTerrain->GetOceanColor());
	}
}

void vtTerrainScene::SetTimeOfDay(unsigned int time, bool fFullRefresh)
{
	if (m_pSkyDome)
	{
		m_pSkyDome->SetSunLight(GetSunLight());
		m_pSkyDome->SetTimeOfDay(time, fFullRefresh);
//		m_pSkyDome->ApplyDayColors();
	}
	// TODO? Update the fog color to match the color of the horizon.
}
<|endoftext|>


<commit_before>#include "platform.h"
#include <stdlib.h>
#include <boost/filesystem.hpp>
#include <iostream>
#include <sys/statvfs.h>
#include <sstream>
#include "Settings.h"

#include <fstream>

#ifdef WIN32
#include <codecvt>
#endif

std::string getHomePath()
{
	std::string homePath;

	// this should give you something like "/home/YOUR_USERNAME" on Linux and "C:\Users\YOUR_USERNAME\" on Windows
	const char * envHome = getenv("HOME");
	if(envHome != nullptr)
	{
		homePath = envHome;
	}

#ifdef WIN32
	// but does not seem to work for Windows XP or Vista, so try something else
	if (homePath.empty()) {
		const char * envDir = getenv("HOMEDRIVE");
		const char * envPath = getenv("HOMEPATH");
		if (envDir != nullptr && envPath != nullptr) {
			homePath = envDir;
			homePath += envPath;

			for(unsigned int i = 0; i < homePath.length(); i++)
				if(homePath[i] == '\\')
					homePath[i] = '/';
		}
	}
#endif

	// convert path to generic directory seperators
	boost::filesystem::path genericPath(homePath);
	return genericPath.generic_string();
}

int runShutdownCommand()
{
#ifdef WIN32 // windows
	return system("shutdown -s -t 0");
#else // osx / linux
	return system("poweroff");
#endif
}

int runRestartCommand()
{
#ifdef WIN32 // windows
	return system("shutdown -r -t 0");
#else // osx / linux
	return system("reboot");
#endif
}

int runSystemCommand(const std::string& cmd_utf8)
{
#ifdef WIN32
	// on Windows we use _wsystem to support non-ASCII paths
	// which requires converting from utf8 to a wstring
	typedef std::codecvt_utf8<wchar_t> convert_type;
	std::wstring_convert<convert_type, wchar_t> converter;
	std::wstring wchar_str = converter.from_bytes(cmd_utf8);
	return _wsystem(wchar_str.c_str());
#else
	return system(cmd_utf8.c_str());
#endif
}
<commit_msg>stdout: redirect launch stderr/stdout to files<commit_after>#include "platform.h"
#include <stdlib.h>
#include <boost/filesystem.hpp>
#include <iostream>
#include <sys/statvfs.h>
#include <sstream>
#include "Settings.h"

#include <fstream>

#ifdef WIN32
#include <codecvt>
#endif

std::string getHomePath()
{
	std::string homePath;

	// this should give you something like "/home/YOUR_USERNAME" on Linux and "C:\Users\YOUR_USERNAME\" on Windows
	const char * envHome = getenv("HOME");
	if(envHome != nullptr)
	{
		homePath = envHome;
	}

#ifdef WIN32
	// but does not seem to work for Windows XP or Vista, so try something else
	if (homePath.empty()) {
		const char * envDir = getenv("HOMEDRIVE");
		const char * envPath = getenv("HOMEPATH");
		if (envDir != nullptr && envPath != nullptr) {
			homePath = envDir;
			homePath += envPath;

			for(unsigned int i = 0; i < homePath.length(); i++)
				if(homePath[i] == '\\')
					homePath[i] = '/';
		}
	}
#endif

	// convert path to generic directory seperators
	boost::filesystem::path genericPath(homePath);
	return genericPath.generic_string();
}

int runShutdownCommand()
{
#ifdef WIN32 // windows
	return system("shutdown -s -t 0");
#else // osx / linux
	return system("poweroff");
#endif
}

int runRestartCommand()
{
#ifdef WIN32 // windows
	return system("shutdown -r -t 0");
#else // osx / linux
	return system("reboot");
#endif
}

int runSystemCommand(const std::string& cmd_utf8)
{
#ifdef WIN32
	// on Windows we use _wsystem to support non-ASCII paths
	// which requires converting from utf8 to a wstring
	typedef std::codecvt_utf8<wchar_t> convert_type;
	std::wstring_convert<convert_type, wchar_t> converter;
	std::wstring wchar_str = converter.from_bytes(cmd_utf8);
	return _wsystem(wchar_str.c_str());
#else
	return system((cmd_utf8 + " > /recalbox/share/system/logs/es_launch_stdout.log 2> /recalbox/share/system/logs/es_launch_stderr.log").c_str());
#endif
}
<|endoftext|>


<commit_before>// Time:  O(logn)
// Space: O(1)

class Solution {
public:
    /**
     * @param n: An integers.
     * @return: An integer which is the first bad version.
     */
    int findFirstBadVersion(int n) {
        int left = 1 - 1, right = n;

        VersionControl vc;

        // At the last, left is not target, right is target.
        while (right - left > 1) {
            int mid = left + (right - left) / 2;
            // Is target
            if (vc.isBadVersion(mid)) {
                right = mid;
            }
            else {
                left = mid;
            }
        }
        return right;
    }
};

class Solution2 {
public:
    /**
     * @param n: An integers.
     * @return: An integer which is the first bad version.
     */
    int findFirstBadVersion(int n) {
        int left = 1, right = n + 1;

        VersionControl vc;

        // At the last, left is not sure for target, right is target.
        while (left < right) {
            int mid = left + (right - left) / 2;
            // Is target
            if (vc.isBadVersion(mid)) {
                right = mid;
            }
            else {
                left = mid + 1;
            }
        }
        return left;
    }
};

class Solution3 {
public:
    /**
     * @param n: An integers.
     * @return: An integer which is the first bad version.
     */
    int findFirstBadVersion(int n) {
        int left = 1, right = n;

        VersionControl vc;

        // At the last, left is not sure for target, right is not sure for target.
        while (left <= right) {
            int mid = left + (right - left) / 2;
            // Is target
            if (vc.isBadVersion(mid)) {
                right = mid - 1;
            }
            else {
                left = mid + 1;
            }
        }
        return left;
    }
};
<commit_msg>3 types of binary search<commit_after>// Time:  O(logn)
// Space: O(1)

class Solution {
public:
    /**
     * @param n: An integers.
     * @return: An integer which is the first bad version.
     */
    int findFirstBadVersion(int n) {
        int left = 1 - 1, right = n + 1;

        VersionControl vc;

        // At the last, left is not target, right is target.
        while (right - left > 1) {
            int mid = left + (right - left) / 2;
            // Is target
            if (vc.isBadVersion(mid)) {
                right = mid;
            }
            else {
                left = mid;
            }
        }
        return right;
    }
};

class Solution2 {
public:
    /**
     * @param n: An integers.
     * @return: An integer which is the first bad version.
     */
    int findFirstBadVersion(int n) {
        int left = 1, right = n + 1;

        VersionControl vc;

        // At the last, left is not sure for target, right is target.
        while (left < right) {
            int mid = left + (right - left) / 2;
            // Is target
            if (vc.isBadVersion(mid)) {
                right = mid;
            }
            else {
                left = mid + 1;
            }
        }
        return left;
    }
};

class Solution3 {
public:
    /**
     * @param n: An integers.
     * @return: An integer which is the first bad version.
     */
    int findFirstBadVersion(int n) {
        int left = 1, right = n;

        VersionControl vc;

        // At the last, left is not sure for target, right is not sure for target.
        while (left <= right) {
            int mid = left + (right - left) / 2;
            // Is target
            if (vc.isBadVersion(mid)) {
                right = mid - 1;
            }
            else {
                left = mid + 1;
            }
        }
        return left;
    }
};
<|endoftext|>


<commit_before>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2020 Michael Fink
//
/// \file ConnectCameraDlg.cpp Camera connect dialog
//

// includes
#include "StdAfx.h"
#include "resource.h"
#include "ConnectCameraDlg.hpp"
#include "CameraInfoDlg.hpp"
#include "CameraErrorDlg.hpp"
#include "Icons.hpp"
#include "Instance.hpp"
#include "CameraException.hpp"
#include "SourceInfo.hpp"
#include "UsbDriverSwitcherDlg.hpp"

ConnectCameraDlg::ConnectCameraDlg()
:m_iSelectedSourceDeviceIndex(-1),
 m_instance(Instance::Get())
{
}

std::shared_ptr<SourceDevice> ConnectCameraDlg::GetSourceDevice() const
{
   ATLASSERT(m_iSelectedSourceDeviceIndex != -1);

   try
   {
      std::vector<std::shared_ptr<SourceInfo>> vecSourceDevices;
      m_instance.EnumerateDevices(vecSourceDevices);

      if (!vecSourceDevices.empty())
      {
         std::shared_ptr<SourceInfo> spSourceInfo = vecSourceDevices[static_cast<size_t>(m_iSelectedSourceDeviceIndex)];
         return spSourceInfo->Open();
      }
   }
   catch (const CameraException& ex)
   {
      CameraErrorDlg dlg(_T("Couldn't open camera device"), ex);
      dlg.DoModal(m_hWnd);
   }

   return std::shared_ptr<SourceDevice>();
}

LRESULT ConnectCameraDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
   DoDataExchange(DDX_LOAD);

   CenterWindow(GetParent());

   DlgResize_Init(false, false);

   // load image lists
   {
      m_ilIcons.Create(16,15, ILC_MASK | ILC_COLOR32, 0, 0);
      CBitmap bmpIcons;
      bmpIcons.LoadBitmap(IDB_ICONS);
      m_ilIcons.Add(bmpIcons, RGB(255, 0, 255));
   }

   // set up cameras list
   {
      m_lcCameras.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
      m_lcCameras.SetImageList(m_ilIcons, LVSIL_SMALL);

      CRect rcCamera;
      m_lcCameras.GetClientRect(&rcCamera);

      m_lcCameras.InsertColumn(0, _T("Camera"), LVCFMT_LEFT, rcCamera.Width());

      RefreshCameraList();
   }

   if (m_lcCameras.GetItemCount() > 0)
      m_lcCameras.SelectItem(0);

   m_instance.AsyncWaitForCamera(std::bind(&ConnectCameraDlg::OnCameraAdded, this));

   return TRUE;
}

LRESULT ConnectCameraDlg::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   if (wID == IDOK)
   {
      // get device index of selected device
      int iItem = m_lcCameras.GetSelectedIndex();
      m_iSelectedSourceDeviceIndex = m_lcCameras.GetItemData(iItem);
      ATLASSERT(m_iSelectedSourceDeviceIndex != -1);
   }

   // unregister handler
   m_instance.AsyncWaitForCamera();

   EndDialog(wID);
   return 0;
}

LRESULT ConnectCameraDlg::OnBtnRefresh(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   int iItemCountBeforeRefresh = m_lcCameras.GetItemCount();

   RefreshCameraList();

   int iItemCount = m_lcCameras.GetItemCount();

   // select first item when list has updated
   if (iItemCount > 0 &&
       iItemCountBeforeRefresh != iItemCount &&
       m_lcCameras.GetSelectedIndex() == -1)
      m_lcCameras.SelectItem(0);

   return 0;
}

LRESULT ConnectCameraDlg::OnBtnInfo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   // unregister handler
   m_instance.AsyncWaitForCamera();

   // get device index of selected device
   int iItem = m_lcCameras.GetSelectedIndex();
   m_iSelectedSourceDeviceIndex = static_cast<int>(m_lcCameras.GetItemData(iItem));
   ATLASSERT(m_iSelectedSourceDeviceIndex != -1);

   // now that currently selected device is stored in m_iSelectedSourceDeviceIndex, we can call GetSourceDevice()
   try
   {
      std::shared_ptr<SourceDevice> spSourceDevice = GetSourceDevice();

      if (spSourceDevice != nullptr)
      {
         CameraInfoDlg dlg(*spSourceDevice);
         dlg.DoModal(m_hWnd);
      }
   }
   catch (const CameraException& ex)
   {
      CameraErrorDlg dlg(_T("Couldn't get camera info"), ex);
      dlg.DoModal(m_hWnd);
   }

   // re-register handler
   m_instance.AsyncWaitForCamera(std::bind(&ConnectCameraDlg::OnCameraAdded, this));

   return 0;
}

LRESULT ConnectCameraDlg::OnButtonConfigUsb(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   UsbDriverSwitcherDlg dlg;
   dlg.DoModal();

   return 0;
}

LRESULT ConnectCameraDlg::OnListCameraItemChanged(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
   NMLISTVIEW* pnmv = (LPNMLISTVIEW)pnmh;

   int iItem = pnmv->iItem;

   if ((pnmv->uNewState & LVIS_SELECTED) == 0)
   {
      // selection was removed; check if an item is still selected
      int iSelectedItem = m_lcCameras.GetSelectedIndex();
      if (iSelectedItem == -1)
         iItem = -1;
      else
         return 0;
   }

   bool bEnableBtns = iItem != -1;

   if (iItem != -1)
      m_iSelectedSourceDeviceIndex = m_lcCameras.GetItemData(iItem);
   else
      m_iSelectedSourceDeviceIndex = -1;

   GetDlgItem(IDC_BUTTON_INFO).EnableWindow(bEnableBtns ? TRUE : FALSE);
   GetDlgItem(IDOK).EnableWindow(bEnableBtns ? TRUE : FALSE);

   return 0;
}

void ConnectCameraDlg::OnCameraAdded()
{
   // note: this is called from another thread, so just send a refresh button press message
   PostMessage(WM_COMMAND,
      MAKEWPARAM(IDC_BUTTON_REFRESH, BN_CLICKED),
      reinterpret_cast<LPARAM>(GetDlgItem(IDC_BUTTON_REFRESH).m_hWnd));
}

void ConnectCameraDlg::RefreshCameraList()
{
   m_lcCameras.SetRedraw(FALSE);
   m_lcCameras.DeleteAllItems();

   int iLastSelectedItem = m_lcCameras.GetSelectedIndex();
   CString cszLastSelectedCamera;
   m_lcCameras.GetItemText(iLastSelectedItem, 0, cszLastSelectedCamera);

   int iNextSelectedItem = -1;
   try
   {
      std::vector<std::shared_ptr<SourceInfo>> vecSourceDevices;
      m_instance.EnumerateDevices(vecSourceDevices);

      for (size_t i=0, iMax=vecSourceDevices.size(); i<iMax; i++)
      {
         std::shared_ptr<SourceInfo> spSourceInfo = vecSourceDevices[i];

         int iItem = m_lcCameras.InsertItem(m_lcCameras.GetItemCount(), spSourceInfo->Name(), iconSmallCamera);
         m_lcCameras.SetItemData(iItem, i);

         if (cszLastSelectedCamera == spSourceInfo->Name())
            iNextSelectedItem = iItem;
      }

      if (vecSourceDevices.empty())
      {
         GetDlgItem(IDC_BUTTON_INFO).EnableWindow(FALSE);
         GetDlgItem(IDOK).EnableWindow(FALSE);
      }
   }
   catch (const CameraException& ex)
   {
      CameraErrorDlg dlg(_T("Couldn't refresh camera list"), ex);
      dlg.DoModal(m_hWnd);
   }

   if (iNextSelectedItem != -1)
      m_lcCameras.SelectItem(iNextSelectedItem);

   m_lcCameras.SetRedraw(TRUE);
}
<commit_msg>added checking for source devices index<commit_after>//
// RemotePhotoTool - remote camera control software
// Copyright (C) 2008-2020 Michael Fink
//
/// \file ConnectCameraDlg.cpp Camera connect dialog
//

// includes
#include "StdAfx.h"
#include "resource.h"
#include "ConnectCameraDlg.hpp"
#include "CameraInfoDlg.hpp"
#include "CameraErrorDlg.hpp"
#include "Icons.hpp"
#include "Instance.hpp"
#include "CameraException.hpp"
#include "SourceInfo.hpp"
#include "UsbDriverSwitcherDlg.hpp"

ConnectCameraDlg::ConnectCameraDlg()
:m_iSelectedSourceDeviceIndex(-1),
 m_instance(Instance::Get())
{
}

std::shared_ptr<SourceDevice> ConnectCameraDlg::GetSourceDevice() const
{
   ATLASSERT(m_iSelectedSourceDeviceIndex != -1);

   size_t sourceDeviceIndex = static_cast<size_t>(m_iSelectedSourceDeviceIndex);

   try
   {
      std::vector<std::shared_ptr<SourceInfo>> vecSourceDevices;
      m_instance.EnumerateDevices(vecSourceDevices);

      if (!vecSourceDevices.empty() &&
         sourceDeviceIndex < vecSourceDevices.size())
      {
         std::shared_ptr<SourceInfo> spSourceInfo = vecSourceDevices[sourceDeviceIndex];
         return spSourceInfo->Open();
      }
   }
   catch (const CameraException& ex)
   {
      CameraErrorDlg dlg(_T("Couldn't open camera device"), ex);
      dlg.DoModal(m_hWnd);
   }

   return std::shared_ptr<SourceDevice>();
}

LRESULT ConnectCameraDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
   DoDataExchange(DDX_LOAD);

   CenterWindow(GetParent());

   DlgResize_Init(false, false);

   // load image lists
   {
      m_ilIcons.Create(16,15, ILC_MASK | ILC_COLOR32, 0, 0);
      CBitmap bmpIcons;
      bmpIcons.LoadBitmap(IDB_ICONS);
      m_ilIcons.Add(bmpIcons, RGB(255, 0, 255));
   }

   // set up cameras list
   {
      m_lcCameras.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
      m_lcCameras.SetImageList(m_ilIcons, LVSIL_SMALL);

      CRect rcCamera;
      m_lcCameras.GetClientRect(&rcCamera);

      m_lcCameras.InsertColumn(0, _T("Camera"), LVCFMT_LEFT, rcCamera.Width());

      RefreshCameraList();
   }

   if (m_lcCameras.GetItemCount() > 0)
      m_lcCameras.SelectItem(0);

   m_instance.AsyncWaitForCamera(std::bind(&ConnectCameraDlg::OnCameraAdded, this));

   return TRUE;
}

LRESULT ConnectCameraDlg::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   if (wID == IDOK)
   {
      // get device index of selected device
      int iItem = m_lcCameras.GetSelectedIndex();
      m_iSelectedSourceDeviceIndex = m_lcCameras.GetItemData(iItem);
      ATLASSERT(m_iSelectedSourceDeviceIndex != -1);
   }

   // unregister handler
   m_instance.AsyncWaitForCamera();

   EndDialog(wID);
   return 0;
}

LRESULT ConnectCameraDlg::OnBtnRefresh(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   int iItemCountBeforeRefresh = m_lcCameras.GetItemCount();

   RefreshCameraList();

   int iItemCount = m_lcCameras.GetItemCount();

   // select first item when list has updated
   if (iItemCount > 0 &&
       iItemCountBeforeRefresh != iItemCount &&
       m_lcCameras.GetSelectedIndex() == -1)
      m_lcCameras.SelectItem(0);

   return 0;
}

LRESULT ConnectCameraDlg::OnBtnInfo(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   // unregister handler
   m_instance.AsyncWaitForCamera();

   // get device index of selected device
   int iItem = m_lcCameras.GetSelectedIndex();
   m_iSelectedSourceDeviceIndex = static_cast<int>(m_lcCameras.GetItemData(iItem));
   ATLASSERT(m_iSelectedSourceDeviceIndex != -1);

   // now that currently selected device is stored in m_iSelectedSourceDeviceIndex, we can call GetSourceDevice()
   try
   {
      std::shared_ptr<SourceDevice> spSourceDevice = GetSourceDevice();

      if (spSourceDevice != nullptr)
      {
         CameraInfoDlg dlg(*spSourceDevice);
         dlg.DoModal(m_hWnd);
      }
   }
   catch (const CameraException& ex)
   {
      CameraErrorDlg dlg(_T("Couldn't get camera info"), ex);
      dlg.DoModal(m_hWnd);
   }

   // re-register handler
   m_instance.AsyncWaitForCamera(std::bind(&ConnectCameraDlg::OnCameraAdded, this));

   return 0;
}

LRESULT ConnectCameraDlg::OnButtonConfigUsb(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
   UsbDriverSwitcherDlg dlg;
   dlg.DoModal();

   return 0;
}

LRESULT ConnectCameraDlg::OnListCameraItemChanged(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
{
   NMLISTVIEW* pnmv = (LPNMLISTVIEW)pnmh;

   int iItem = pnmv->iItem;

   if ((pnmv->uNewState & LVIS_SELECTED) == 0)
   {
      // selection was removed; check if an item is still selected
      int iSelectedItem = m_lcCameras.GetSelectedIndex();
      if (iSelectedItem == -1)
         iItem = -1;
      else
         return 0;
   }

   bool bEnableBtns = iItem != -1;

   if (iItem != -1)
      m_iSelectedSourceDeviceIndex = m_lcCameras.GetItemData(iItem);
   else
      m_iSelectedSourceDeviceIndex = -1;

   GetDlgItem(IDC_BUTTON_INFO).EnableWindow(bEnableBtns ? TRUE : FALSE);
   GetDlgItem(IDOK).EnableWindow(bEnableBtns ? TRUE : FALSE);

   return 0;
}

void ConnectCameraDlg::OnCameraAdded()
{
   // note: this is called from another thread, so just send a refresh button press message
   PostMessage(WM_COMMAND,
      MAKEWPARAM(IDC_BUTTON_REFRESH, BN_CLICKED),
      reinterpret_cast<LPARAM>(GetDlgItem(IDC_BUTTON_REFRESH).m_hWnd));
}

void ConnectCameraDlg::RefreshCameraList()
{
   m_lcCameras.SetRedraw(FALSE);
   m_lcCameras.DeleteAllItems();

   int iLastSelectedItem = m_lcCameras.GetSelectedIndex();
   CString cszLastSelectedCamera;
   m_lcCameras.GetItemText(iLastSelectedItem, 0, cszLastSelectedCamera);

   int iNextSelectedItem = -1;
   try
   {
      std::vector<std::shared_ptr<SourceInfo>> vecSourceDevices;
      m_instance.EnumerateDevices(vecSourceDevices);

      for (size_t i=0, iMax=vecSourceDevices.size(); i<iMax; i++)
      {
         std::shared_ptr<SourceInfo> spSourceInfo = vecSourceDevices[i];

         int iItem = m_lcCameras.InsertItem(m_lcCameras.GetItemCount(), spSourceInfo->Name(), iconSmallCamera);
         m_lcCameras.SetItemData(iItem, i);

         if (cszLastSelectedCamera == spSourceInfo->Name())
            iNextSelectedItem = iItem;
      }

      if (vecSourceDevices.empty())
      {
         GetDlgItem(IDC_BUTTON_INFO).EnableWindow(FALSE);
         GetDlgItem(IDOK).EnableWindow(FALSE);
      }
   }
   catch (const CameraException& ex)
   {
      CameraErrorDlg dlg(_T("Couldn't refresh camera list"), ex);
      dlg.DoModal(m_hWnd);
   }

   if (iNextSelectedItem != -1)
      m_lcCameras.SelectItem(iNextSelectedItem);

   m_lcCameras.SetRedraw(TRUE);
}
<|endoftext|>


<commit_before>// Base header file.  Must be first.
#include <Include/PlatformDefinitions.hpp>

#include <iostream>
#include <strstream>
#include <fstream>

#include <util/PlatformUtils.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>

#include <XPath/XObjectFactoryDefault.hpp>
#include <XPath/XPathSupportDefault.hpp>
#include <XPath/XPathFactoryDefault.hpp>

#include <XSLT/StylesheetConstructionContextDefault.hpp>
#include <XSLT/StylesheetExecutionContextDefault.hpp>
#include <XSLT/XSLTEngineImpl.hpp>
#include <XSLT/XSLTInit.hpp>
#include <XSLT/XSLTInputSource.hpp>
#include <XSLT/XSLTProcessorEnvSupportDefault.hpp>
#include <XSLT/XSLTResultTarget.hpp>

#include <XercesParserLiaison/XercesDOMSupport.hpp>
#include <XercesParserLiaison/XercesParserLiaison.hpp>

int
main(
			int				argc,
			const char*		/* argv */[])
{
#if !defined(XALAN_NO_NAMESPACES)
	using std::cerr;
	using std::cout;
	using std::endl;
	using std::istrstream;
	using std::ofstream;
	using std::ostrstream;
#endif

	if (argc != 1)
	{
		cerr << "Usage: StreamTransform"
			 << endl
			 << endl;
	}
	else
	{
		try
		{
			// Call the static initializer for Xerces...
			XMLPlatformUtils::Initialize();

			{
				// Initialize the Xalan XSLT subsystem...
				XSLTInit						theInit;

				// Create the support objects that are necessary for running the processor...
				XercesDOMSupport				theDOMSupport;
				XercesParserLiaison				theParserLiaison(theDOMSupport);
				XPathSupportDefault				theXPathSupport(theDOMSupport);
				XSLTProcessorEnvSupportDefault	theXSLTProcessorEnvSupport;
				XObjectFactoryDefault			theXObjectFactory;
				XPathFactoryDefault				theXPathFactory;

				// Create a processor...
				XSLTEngineImpl	theProcessor(
						theParserLiaison,
						theXPathSupport,
						theXSLTProcessorEnvSupport,
						theDOMSupport,
						theXObjectFactory,
						theXPathFactory);

				// Connect the processor to the support object...
				theXSLTProcessorEnvSupport.setProcessor(&theProcessor);

				// Create a stylesheet construction context, and a stylesheet
				// execution context...
				StylesheetConstructionContextDefault	theConstructionContext(
							theProcessor,
							theXSLTProcessorEnvSupport,
							theXPathFactory);

				StylesheetExecutionContextDefault		theExecutionContext(
							theProcessor,
							theXSLTProcessorEnvSupport,
							theXPathSupport,
							theXObjectFactory);

				// A simple input document...
				const char* const  theInputDocument = "<?xml version='1.0'?><doc>Hello world!</doc>";

				// A "hello world" stylesheet.  Note that the encoding for the output is US-ASCII,
				// since we're writing to a string.  It could be any encoding, but "binary" encodings,
				// or encodings that could produce multi-byte characters would require transcoding on
				// some platforms.
				const char* const  theStylesheet =
"<?xml version='1.0'?>\
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>\
<xsl:output encoding='US-ASCII'/>\
<xsl:template match='doc'>\
<out><xsl:value-of select='.'/></out>\
</xsl:template>\
</xsl:stylesheet>";

				// Our input streams...
				istrstream	theInputDocumentStream(theInputDocument, strlen(theInputDocument));
				istrstream	theStylesheetStream(theStylesheet, strlen(theStylesheet));

				// Our input sources...
				XSLTInputSource		theInputSource(&theInputDocumentStream);
				XSLTInputSource		theStylesheetSource(&theStylesheetStream);

				// Our output target.  By default, we'll use an ostrstream that will allocate
				// memory dynamically, although we could also use a static buffer since we
				// know the size of the output.
#if defined(SIMPLE_STREAM_USE_STATIC_BUFFER)
				char				theData[100];

				ostrstream			theOutputStream(theData, sizeof(theData));
#else
				ostrstream			theOutputStream;
#endif

				XSLTResultTarget	theResultTarget(&theOutputStream);

				theProcessor.process(
							theInputSource,
							theStylesheetSource,
							theResultTarget,
							theConstructionContext,
							theExecutionContext);

				// OK, we'll now write the data from the string buffer to cout.

				// Null-terminate the data first, to make things easier...
				theOutputStream << '\0';

#if !defined(SIMPLE_STREAM_USE_STATIC_BUFFER)
				// Get a pointer to the string...
				const char* const	theData = theOutputStream.str();

				// Unfreeze the stream, so the memory is automatically
				// delete when the stream goes out of scope...
				theOutputStream.freeze(false);
#endif

				cout << theData;
			}

			// Call the static terminator for Xerces...
			XMLPlatformUtils::Terminate();
		}
		catch(...)
		{
			cerr << "Exception caught!!!"
				 << endl
				 << endl;
		}
	}

	return 0;
}
<commit_msg>Set system ID on the input sources.<commit_after>// Base header file.  Must be first.
#include <Include/PlatformDefinitions.hpp>

#include <iostream>
#include <strstream>
#include <fstream>

#include <util/PlatformUtils.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>

#include <XPath/XObjectFactoryDefault.hpp>
#include <XPath/XPathSupportDefault.hpp>
#include <XPath/XPathFactoryDefault.hpp>

#include <XSLT/StylesheetConstructionContextDefault.hpp>
#include <XSLT/StylesheetExecutionContextDefault.hpp>
#include <XSLT/XSLTEngineImpl.hpp>
#include <XSLT/XSLTInit.hpp>
#include <XSLT/XSLTInputSource.hpp>
#include <XSLT/XSLTProcessorEnvSupportDefault.hpp>
#include <XSLT/XSLTResultTarget.hpp>

#include <XercesParserLiaison/XercesDOMSupport.hpp>
#include <XercesParserLiaison/XercesParserLiaison.hpp>

int
main(
			int				argc,
			const char*		/* argv */[])
{
#if !defined(XALAN_NO_NAMESPACES)
	using std::cerr;
	using std::cout;
	using std::endl;
	using std::istrstream;
	using std::ofstream;
	using std::ostrstream;
#endif

	if (argc != 1)
	{
		cerr << "Usage: StreamTransform"
			 << endl
			 << endl;
	}
	else
	{
		try
		{
			// Call the static initializer for Xerces...
			XMLPlatformUtils::Initialize();

			{
				// Initialize the Xalan XSLT subsystem...
				XSLTInit						theInit;

				// Create the support objects that are necessary for running the processor...
				XercesDOMSupport				theDOMSupport;
				XercesParserLiaison				theParserLiaison(theDOMSupport);
				XPathSupportDefault				theXPathSupport(theDOMSupport);
				XSLTProcessorEnvSupportDefault	theXSLTProcessorEnvSupport;
				XObjectFactoryDefault			theXObjectFactory;
				XPathFactoryDefault				theXPathFactory;

				// Create a processor...
				XSLTEngineImpl	theProcessor(
						theParserLiaison,
						theXPathSupport,
						theXSLTProcessorEnvSupport,
						theDOMSupport,
						theXObjectFactory,
						theXPathFactory);

				// Connect the processor to the support object...
				theXSLTProcessorEnvSupport.setProcessor(&theProcessor);

				// Create a stylesheet construction context, and a stylesheet
				// execution context...
				StylesheetConstructionContextDefault	theConstructionContext(
							theProcessor,
							theXSLTProcessorEnvSupport,
							theXPathFactory);

				StylesheetExecutionContextDefault		theExecutionContext(
							theProcessor,
							theXSLTProcessorEnvSupport,
							theXPathSupport,
							theXObjectFactory);

				// A simple input document...
				const char* const  theInputDocument = "<?xml version='1.0'?><doc>Hello world!</doc>";

				// A "hello world" stylesheet.  Note that the encoding for the output is US-ASCII,
				// since we're writing to a string.  It could be any encoding, but "binary" encodings,
				// or encodings that could produce multi-byte characters would require transcoding on
				// some platforms.
				const char* const  theStylesheet =
"<?xml version='1.0'?>\
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>\
<xsl:output encoding='US-ASCII'/>\
<xsl:template match='doc'>\
<out><xsl:value-of select='.'/></out>\
</xsl:template>\
</xsl:stylesheet>";

				// Our input streams...
				istrstream	theInputDocumentStream(theInputDocument, strlen(theInputDocument));
				istrstream	theStylesheetStream(theStylesheet, strlen(theStylesheet));

				// Our input sources...
				XSLTInputSource		theInputSource(&theInputDocumentStream);
				XSLTInputSource		theStylesheetSource(&theStylesheetStream);

				// A fake system ID for the input sources...
				const XalanDOMString	theSystemID("Memory buffer");

				// Set the system IDs...
				theInputSource.setSystemId(c_wstr(theSystemID));
				theStylesheetSource.setSystemId(c_wstr(theSystemID));

				// Our output target.  By default, we'll use an ostrstream that will allocate
				// memory dynamically, although we could also use a static buffer since we
				// know the size of the output.
#if defined(SIMPLE_STREAM_USE_STATIC_BUFFER)
				char				theData[100];

				ostrstream			theOutputStream(theData, sizeof(theData));
#else
				ostrstream			theOutputStream;
#endif

				XSLTResultTarget	theResultTarget(&theOutputStream);

				theProcessor.process(
							theInputSource,
							theStylesheetSource,
							theResultTarget,
							theConstructionContext,
							theExecutionContext);

				// OK, we'll now write the data from the string buffer to cout.

				// Null-terminate the data first, to make things easier...
				theOutputStream << '\0';

#if !defined(SIMPLE_STREAM_USE_STATIC_BUFFER)
				// Get a pointer to the string...
				const char* const	theData = theOutputStream.str();

				// Unfreeze the stream, so the memory is automatically
				// delete when the stream goes out of scope...
				theOutputStream.freeze(false);
#endif

				cout << theData;
			}

			// Call the static terminator for Xerces...
			XMLPlatformUtils::Terminate();
		}
		catch(...)
		{
			cerr << "Exception caught!!!"
				 << endl
				 << endl;
		}
	}

	return 0;
}
<|endoftext|>


<commit_before>
// Qt includes
#include <QDebug>

// QtPropertyBrowser includes
#include <QtVariantPropertyManager>

// Visomics includes
#include "voDataObject.h"
#include "voHierarchicalClustering.h"
#include "voTableDataObject.h"
#include "voUtils.h"
#include "vtkExtendedTable.h"

// VTK includes
#include <vtkDataSetAttributes.h>
#include <vtkArrayData.h>
#include <vtkDenseArray.h>
#include <vtkDoubleArray.h>
#include <vtkIntArray.h>
#include <vtkMutableDirectedGraph.h>
#include <vtkNew.h>
#include <vtkRCalculatorFilter.h>
#include <vtkSmartPointer.h>
#include <vtkStringArray.h>
#include <vtkTable.h>
#include <vtkTree.h>
#include <vtkAdjacentVertexIterator.h>
#include <vtkTreeDFSIterator.h>

// --------------------------------------------------------------------------
// voHierarchicalClustering methods

// --------------------------------------------------------------------------
voHierarchicalClustering::voHierarchicalClustering():
    Superclass()
{
}

// --------------------------------------------------------------------------
voHierarchicalClustering::~voHierarchicalClustering()
{
}

// --------------------------------------------------------------------------
void voHierarchicalClustering::setInputInformation()
{
  this->addInputType("input", "vtkExtendedTable");
}

// --------------------------------------------------------------------------
void voHierarchicalClustering::setOutputInformation()
{
  this->addOutputType("clusterTree", "vtkTree",
                      "voTreeGraphView", "clusterTree");

  this->addOutputType("cluster", "vtkTable",
                      "voHeatMapView", "HeatMap");
}

// --------------------------------------------------------------------------
void voHierarchicalClustering::setParameterInformation()
{
  QList<QtProperty*> hclust_parameters;

  // HClust / Method
  QStringList hclust_methods;
  hclust_methods << "complete" << "average" << "mcquitty" << "median" << "centroid";
  hclust_parameters << this->addEnumParameter("method", tr("Method"), hclust_methods, "average");

  this->addParameterGroup("HClust parameters", hclust_parameters);
}

// --------------------------------------------------------------------------
bool voHierarchicalClustering::execute()
{
  // Import data table
  vtkExtendedTable* extendedTable =  vtkExtendedTable::SafeDownCast(this->input()->data());
  if (!extendedTable)
    {
    qWarning() << "Input is Null";
    return false;
    }

  vtkSmartPointer<vtkTable> inputDataTable = extendedTable->GetData();

  vtkSmartPointer<vtkStringArray> columnNames = extendedTable->GetColumnMetaDataOfInterestAsString();

  // Parameters
  QString hclust_method = this->enumParameter("method");

  // R input
  vtkSmartPointer<vtkArray> RInputArray;
  voUtils::tableToArray(inputDataTable.GetPointer(), RInputArray);

  vtkNew<vtkArrayData> RInputArrayData;
  RInputArrayData->AddArray(RInputArray.GetPointer());

  // Run R
  vtkNew <vtkRCalculatorFilter> RCalc;
  RCalc->SetRoutput(0);
  RCalc->SetInputConnection(RInputArrayData->GetProducerPort());
  RCalc->PutArray("0", "metabData");
  RCalc->GetArray("height","height");
//  RCalc->GetArray("order","order");
  RCalc->GetArray("merge","merge");
  RCalc->SetRscript(QString(
                     "dEuc<-dist(t(metabData))\n"
                     "cluster<-hclust(dEuc,method=\"%1\")\n"
                     "height<-cluster$height\n"
//                     "order<-cluster$order\n"
                     "merge<-cluster$merge\n"
                     ).arg(hclust_method).toLatin1());
  RCalc->Update();

  /*
   * hclust class in R has the following attributes
   *
   * labels: labels for each of the objects being clustered.
   *
   * merge: an n-1 by 2 matrix.  Row i of merge describes the
   *       merging of clusters at step i of the clustering.  If an
   *       element j in the row is negative, then observation -j was
   *       merged at this stage.  If j is positive then the merge was
   *      with the cluster formed at the (earlier) stage j of the
   *      algorithm.  Thus negative entries in merge indicate
   *       agglomerations of singletons, and positive entries indicate
   *       agglomerations of non-singletons.
   *
   *
   * height: a set of n-1 non-decreasing real values.  The clustering
   *       _height_: that is, the value of the criterion associated with
   *       the clustering method for the particular agglomeration.
   *
   * order: a vector giving the permutation of the original observations
   *       suitable for plotting, in the sense that a cluster plot using
   *       this ordering and matrix merge will not have crossings
   *       of the branches.
   *
   *
   * labels : labels for each of the objects being clustered.
   *
   */

  // Get R output
  vtkSmartPointer<vtkArrayData> outputArrayData = vtkArrayData::SafeDownCast(RCalc->GetOutput());

  vtkSmartPointer< vtkDenseArray<double> > heightArray;
  heightArray = vtkDenseArray<double>::SafeDownCast(outputArrayData->GetArrayByName("height"));

  vtkSmartPointer< vtkDenseArray<double> > mergeArray;
  mergeArray = vtkDenseArray<double>::SafeDownCast(outputArrayData->GetArrayByName("merge"));

  // Analysis outputs
  vtkNew<vtkMutableDirectedGraph> graph;

  vtkNew<vtkStringArray> clusterLabelArray; // Array to label the vertices
  clusterLabelArray->SetName("id");

  vtkNew<vtkDoubleArray> distanceArray; // Array to store the vertices height
  distanceArray->SetName("Height");

  // Build graph
  vtkNew<vtkIntArray> clusterMap; // [clusterIndex] -> clusterVertexID
  clusterMap->SetNumberOfValues(mergeArray->GetExtent(0).GetSize());

  for(int clusterIndex = 0; clusterIndex < mergeArray->GetExtent(0).GetSize(); ++clusterIndex)
    {
    // R cluster index starts from 1; when firstCluster/secondCluster is used, its value must be taken as: abs(cluster) - 1
    int firstCluster  =  mergeArray->GetValue(clusterIndex, 0);
    int secondCluster =  mergeArray->GetValue(clusterIndex, 1);

    double heightParent =  heightArray->GetValue(clusterIndex);
    double heightChildren = heightParent - 0.1;// arbitrary

    vtkIdType parentID = graph->AddVertex();
    clusterLabelArray->InsertNextValue ("");
    distanceArray->InsertNextValue(heightParent);

    clusterMap->SetValue(clusterIndex, parentID);

    vtkIdType child1ID;
    if ( firstCluster < 0 )
      {
      child1ID = graph->AddVertex();
      clusterLabelArray->InsertNextValue(columnNames->GetValue(abs(firstCluster) - 1));
      distanceArray->InsertNextValue(heightChildren);
      }
    else // ( firstCluster > 0 )
      {
      child1ID = clusterMap->GetValue(firstCluster - 1);
      }

    vtkIdType child2ID;
    if (secondCluster < 0)
      {
      child2ID = graph->AddVertex();
      clusterLabelArray->InsertNextValue(columnNames->GetValue(abs(secondCluster) - 1));
      distanceArray->InsertNextValue(heightChildren);
      }
    else // ( secondCluster > 0 )
      {
      child2ID = clusterMap->GetValue(secondCluster - 1);
      }

    graph->AddEdge( parentID, child1ID );
    graph->AddEdge( parentID, child2ID );
    }

  vtkNew<vtkTree> tree;
  tree->ShallowCopy(graph.GetPointer());

  //Add vertex attributes
  tree->GetVertexData()->AddArray(clusterLabelArray.GetPointer());
  tree->GetVertexData()->AddArray(distanceArray.GetPointer());

  this->setOutput("clusterTree", new voDataObject("clusterTree", tree.GetPointer()));

  vtkIdType level;
  vtkIdType root = tree->GetRoot();

  vtkStringArray* labels = vtkStringArray::SafeDownCast(tree->GetVertexData()->GetAbstractArray("id"));

  vtkNew<vtkTreeDFSIterator> dfs;
  dfs->SetStartVertex(root);
  dfs->SetTree(tree.GetPointer());

  vtkIdType maxLevel = 0;

  while (dfs->HasNext())
    {
    vtkIdType vertex = dfs->Next();

    maxLevel = qMax(tree->GetLevel(vertex), maxLevel);
    }

  vtkNew<vtkTable> clusterTable;
  clusterTable->AddColumn(extendedTable->GetRowMetaDataOfInterestAsString());

  for( int i=maxLevel; i >= 0; i-- )
    {
    vtkNew<vtkTreeDFSIterator> dfs;

    dfs->SetStartVertex(root);
    dfs->SetTree(tree.GetPointer());

    while (dfs->HasNext())
      {
      vtkIdType vertex = dfs->Next();

      level = tree->GetLevel(vertex);
      if ( level == i )
        {
        if ( labels->GetValue(vertex) != "")
          {
          vtkAbstractArray* col = inputDataTable->GetColumnByName(labels->GetValue(vertex));
          col->SetName(col->GetName());
          clusterTable->AddColumn(col);
          }
        }
      }
    }

  this->setOutput("cluster", new voTableDataObject("cluster", clusterTable.GetPointer()));

  return true;
}
<commit_msg>Refactor voHierarchicalClustering; heat map algorithm<commit_after>
// Qt includes
#include <QDebug>

// QtPropertyBrowser includes
#include <QtVariantPropertyManager>

// Visomics includes
#include "voDataObject.h"
#include "voHierarchicalClustering.h"
#include "voTableDataObject.h"
#include "voUtils.h"
#include "vtkExtendedTable.h"

// VTK includes
#include <vtkDataSetAttributes.h>
#include <vtkArrayData.h>
#include <vtkDenseArray.h>
#include <vtkDoubleArray.h>
#include <vtkIntArray.h>
#include <vtkMutableDirectedGraph.h>
#include <vtkNew.h>
#include <vtkRCalculatorFilter.h>
#include <vtkSmartPointer.h>
#include <vtkStringArray.h>
#include <vtkTable.h>
#include <vtkTree.h>
#include <vtkAdjacentVertexIterator.h>
#include <vtkTreeDFSIterator.h>
#include <vtkTreeBFSIterator.h>

// --------------------------------------------------------------------------
// voHierarchicalClustering methods

// --------------------------------------------------------------------------
voHierarchicalClustering::voHierarchicalClustering():
    Superclass()
{
}

// --------------------------------------------------------------------------
voHierarchicalClustering::~voHierarchicalClustering()
{
}

// --------------------------------------------------------------------------
void voHierarchicalClustering::setInputInformation()
{
  this->addInputType("input", "vtkExtendedTable");
}

// --------------------------------------------------------------------------
void voHierarchicalClustering::setOutputInformation()
{
  this->addOutputType("clusterTree", "vtkTree",
                      "voTreeGraphView", "clusterTree");

  this->addOutputType("cluster", "vtkTable",
                      "voHeatMapView", "HeatMap");
}

// --------------------------------------------------------------------------
void voHierarchicalClustering::setParameterInformation()
{
  QList<QtProperty*> hclust_parameters;

  // HClust / Method
  QStringList hclust_methods;
  hclust_methods << "complete" << "average" << "mcquitty" << "median" << "centroid";
  hclust_parameters << this->addEnumParameter("method", tr("Method"), hclust_methods, "average");

  this->addParameterGroup("HClust parameters", hclust_parameters);
}

// --------------------------------------------------------------------------
bool voHierarchicalClustering::execute()
{
  // Import data table
  vtkExtendedTable* extendedTable =  vtkExtendedTable::SafeDownCast(this->input()->data());
  if (!extendedTable)
    {
    qWarning() << "Input is Null";
    return false;
    }

  vtkSmartPointer<vtkTable> inputDataTable = extendedTable->GetData();

  vtkSmartPointer<vtkStringArray> columnNames = extendedTable->GetColumnMetaDataOfInterestAsString();

  // Parameters
  QString hclust_method = this->enumParameter("method");

  // R input
  vtkSmartPointer<vtkArray> RInputArray;
  voUtils::tableToArray(inputDataTable.GetPointer(), RInputArray);

  vtkNew<vtkArrayData> RInputArrayData;
  RInputArrayData->AddArray(RInputArray.GetPointer());

  // Run R
  vtkNew <vtkRCalculatorFilter> RCalc;
  RCalc->SetRoutput(0);
  RCalc->SetInputConnection(RInputArrayData->GetProducerPort());
  RCalc->PutArray("0", "metabData");
  RCalc->GetArray("height","height");
//  RCalc->GetArray("order","order");
  RCalc->GetArray("merge","merge");
  RCalc->SetRscript(QString(
                     "dEuc<-dist(t(metabData))\n"
                     "cluster<-hclust(dEuc,method=\"%1\")\n"
                     "height<-cluster$height\n"
//                     "order<-cluster$order\n"
                     "merge<-cluster$merge\n"
                     ).arg(hclust_method).toLatin1());
  RCalc->Update();

  /*
   * hclust class in R has the following attributes
   *
   * labels: labels for each of the objects being clustered.
   *
   * merge: an n-1 by 2 matrix.  Row i of merge describes the
   *       merging of clusters at step i of the clustering.  If an
   *       element j in the row is negative, then observation -j was
   *       merged at this stage.  If j is positive then the merge was
   *      with the cluster formed at the (earlier) stage j of the
   *      algorithm.  Thus negative entries in merge indicate
   *       agglomerations of singletons, and positive entries indicate
   *       agglomerations of non-singletons.
   *
   *
   * height: a set of n-1 non-decreasing real values.  The clustering
   *       _height_: that is, the value of the criterion associated with
   *       the clustering method for the particular agglomeration.
   *
   * order: a vector giving the permutation of the original observations
   *       suitable for plotting, in the sense that a cluster plot using
   *       this ordering and matrix merge will not have crossings
   *       of the branches.
   *
   *
   * labels : labels for each of the objects being clustered.
   *
   */

  // Get R output
  vtkSmartPointer<vtkArrayData> outputArrayData = vtkArrayData::SafeDownCast(RCalc->GetOutput());

  vtkSmartPointer< vtkDenseArray<double> > heightArray;
  heightArray = vtkDenseArray<double>::SafeDownCast(outputArrayData->GetArrayByName("height"));

  vtkSmartPointer< vtkDenseArray<double> > mergeArray;
  mergeArray = vtkDenseArray<double>::SafeDownCast(outputArrayData->GetArrayByName("merge"));

  // Analysis outputs
  vtkNew<vtkMutableDirectedGraph> graph;

  vtkNew<vtkStringArray> clusterLabelArray; // Array to label the vertices
  clusterLabelArray->SetName("id");

  vtkNew<vtkDoubleArray> distanceArray; // Array to store the vertices height
  distanceArray->SetName("Height");

  // Build graph
  vtkNew<vtkIntArray> clusterMap; // [clusterIndex] -> clusterVertexID
  clusterMap->SetNumberOfValues(mergeArray->GetExtent(0).GetSize());

  for(int clusterIndex = 0; clusterIndex < mergeArray->GetExtent(0).GetSize(); ++clusterIndex)
    {
    // R cluster index starts from 1; when firstCluster/secondCluster is used, its value must be taken as: abs(cluster) - 1
    int firstCluster  =  mergeArray->GetValue(clusterIndex, 0);
    int secondCluster =  mergeArray->GetValue(clusterIndex, 1);

    double heightParent =  heightArray->GetValue(clusterIndex);
    double heightChildren = heightParent - 0.1;// arbitrary

    vtkIdType parentID = graph->AddVertex();
    clusterLabelArray->InsertNextValue ("");
    distanceArray->InsertNextValue(heightParent);

    clusterMap->SetValue(clusterIndex, parentID);

    vtkIdType child1ID;
    if ( firstCluster < 0 )
      {
      child1ID = graph->AddVertex();
      clusterLabelArray->InsertNextValue(columnNames->GetValue(abs(firstCluster) - 1));
      distanceArray->InsertNextValue(heightChildren);
      }
    else // ( firstCluster > 0 )
      {
      child1ID = clusterMap->GetValue(firstCluster - 1);
      }

    vtkIdType child2ID;
    if (secondCluster < 0)
      {
      child2ID = graph->AddVertex();
      clusterLabelArray->InsertNextValue(columnNames->GetValue(abs(secondCluster) - 1));
      distanceArray->InsertNextValue(heightChildren);
      }
    else // ( secondCluster > 0 )
      {
      child2ID = clusterMap->GetValue(secondCluster - 1);
      }

    graph->AddEdge( parentID, child1ID );
    graph->AddEdge( parentID, child2ID );
    }

  vtkNew<vtkTree> tree;
  tree->ShallowCopy(graph.GetPointer());

  //Add vertex attributes
  tree->GetVertexData()->AddArray(clusterLabelArray.GetPointer());
  tree->GetVertexData()->AddArray(distanceArray.GetPointer());

  this->setOutput("clusterTree", new voDataObject("clusterTree", tree.GetPointer()));

  QStringList reverseBFSLabels;
    {
    vtkNew<vtkTreeBFSIterator> bfs;
    bfs->SetTree(tree.GetPointer());
    int prevTreeLevel = 0;
    QStringList levelLabels;
    vtkStringArray* treeLabels = vtkStringArray::SafeDownCast(tree->GetVertexData()->GetAbstractArray("id"));
    while (bfs->HasNext())
      {
      vtkIdType curVertex = bfs->Next();
      vtkIdType curLevel = tree->GetLevel(curVertex);
      if (prevTreeLevel != curLevel)
        {
        reverseBFSLabels = levelLabels + reverseBFSLabels; // Prepend level list to master list
        levelLabels.clear();
        prevTreeLevel = curLevel;
        }
      if (treeLabels->GetValue(curVertex) != "")
        {
        levelLabels << QString(treeLabels->GetValue(curVertex));
        }
      }
    reverseBFSLabels = levelLabels + reverseBFSLabels;
    }

  vtkNew<vtkTable> clusterTable;
  clusterTable->AddColumn(extendedTable->GetRowMetaDataOfInterestAsString());
  foreach(QString colLabel, reverseBFSLabels)
    {
    clusterTable->AddColumn(inputDataTable->GetColumnByName(colLabel.toLatin1()));
    }

  this->setOutput("cluster", new voTableDataObject("cluster", clusterTable.GetPointer()));

  return true;
}
<|endoftext|>


<commit_before>// Time:  O(n)
// Space: O(1)

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        // Xor all the elements to get x ^ y.
        const auto x_xor_y = accumulate(nums.cbegin(), nums.cend(), 0, bit_xor<int>());

        // Get the last bit where 1 occurs by "x & ~(x - 1)"
        // Becease -(x - 1) = ~(x - 1) + 1 <=> -x = ~(x - 1)
        // So we can also get the last bit where 1 occurs by "x & -x"
        const auto bit = x_xor_y & -x_xor_y;

        // Get the subset of A where the number has the bit.
        // The subset only contains one of the two integers, call it x.
        // Xor all the elements in the subset to get x.
        vector<int> result(2, 0);
        for (const auto& i : nums) {
            result[static_cast<bool>(i & bit)] ^= i;
        }
        return result;
    }
};

class Solution2 {
public:
    vector<int> singleNumber(vector<int>& nums) {
        // Xor all the elements to get x ^ y.
        int x_xor_y = 0;
        for (const auto& i : nums) {
            x_xor_y ^= i;
        }

        // Get the last bit where 1 occurs.
        const auto bit = x_xor_y & ~(x_xor_y - 1);

        // Get the subset of A where the number has the bit.
        // The subset only contains one of the two integers, call it x.
        // Xor all the elements in the subset to get x.
        int x = 0;
        for (const auto& i : nums) {
            if (i & bit) {
                x ^= i;
            }
        }

        return {x, x_xor_y ^ x};
    }
};
<commit_msg>Update single-number-iii.cpp<commit_after>// Time:  O(n)
// Space: O(1)

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        // Xor all the elements to get x ^ y.
        const auto x_xor_y = accumulate(nums.cbegin(), nums.cend(), 0, bit_xor<int>());

        // Get the last bit where 1 occurs by "x & ~(x - 1)"
        // Because -(x - 1) = ~(x - 1) + 1 <=> -x = ~(x - 1)
        // So we can also get the last bit where 1 occurs by "x & -x"
        const auto bit = x_xor_y & -x_xor_y;

        // Get the subset of A where the number has the bit.
        // The subset only contains one of the two integers, call it x.
        // Xor all the elements in the subset to get x.
        vector<int> result(2, 0);
        for (const auto& i : nums) {
            result[static_cast<bool>(i & bit)] ^= i;
        }
        return result;
    }
};

class Solution2 {
public:
    vector<int> singleNumber(vector<int>& nums) {
        // Xor all the elements to get x ^ y.
        int x_xor_y = 0;
        for (const auto& i : nums) {
            x_xor_y ^= i;
        }

        // Get the last bit where 1 occurs.
        const auto bit = x_xor_y & ~(x_xor_y - 1);

        // Get the subset of A where the number has the bit.
        // The subset only contains one of the two integers, call it x.
        // Xor all the elements in the subset to get x.
        int x = 0;
        for (const auto& i : nums) {
            if (i & bit) {
                x ^= i;
            }
        }

        return {x, x_xor_y ^ x};
    }
};
<|endoftext|>


<commit_before>#include <dlfcn.h>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <map>
#include <cstdio>
using namespace std;
typedef void (*Mp)(vector<int> &);
typedef const char *(*Self)();
const char *ALGS = "sort";
const char *NAME = "self";

void load_handle(vector<void *> &handle, int num, char *so[]) {
    void *lib_handle = NULL;
    for (int i = 0; i < num; i++) {
        if ((lib_handle = dlopen(so[i], RTLD_NOW)) == NULL) {
            printf("Open Error %s\n", dlerror());
            continue;
        }
        handle.push_back(lib_handle);
    }
}

void load_algs(vector<void *> &handle, vector<pair<Self, Mp> > &algs) {
    Mp method = NULL;
    Self self = NULL;

    for (int i = 0; i < handle.size(); i++) {
        if ((self = (Self)dlsym(handle[i], NAME)) == NULL) {
            printf("Open Error %s\n", dlerror());
            continue;
        }

        if ((method = (Mp)dlsym(handle[i], ALGS)) == NULL) {
            printf("Open Error %s\n", dlerror());
            continue;
        }
        algs.push_back(make_pair(self, method));
    }
}

void destruct_handle(vector<void *> &handle) {
    for (int i = 0; i < handle.size(); i++)
        dlclose(handle[i]);
    handle.clear();
}

bool is_correct(vector<int> &array) {
    for (int i = 1; i < array.size(); i++)
        if (array[i - 1] > array[i])
            return false;
    return true;
}

vector<int> random(int num) {
    vector<int> random_variable;

    srand(time(NULL));
    while (num--)
        random_variable.push_back(rand());

    return random_variable;
}

int main(int argc, char *argv[]) {
    if (argc < 3) return 0;

    vector<pair<Self, Mp> > algs;
    vector<void *> handle;

    load_handle(handle, argc - 1, argv + 1);
    load_algs(handle, algs);

    for (int num = 1; num < 10; num += 2) {
        multimap<double, const char *> res;
        vector<int> origin = random(num * 1000);
        printf("\nFor %d integers\n", num * 1000);

        for (int i = 0; i < algs.size(); i++) {
            vector<int> data = origin;

            clock_t start = clock();
            //printf("%s\n", (*algs[i].first)());
            (*algs[i].second)(data);
            clock_t finish = clock();

            if (is_correct(data))
                res.insert(make_pair((double)(finish - start) / CLOCKS_PER_SEC,
                            (*algs[i].first)()));
            /*
            for (int i = 0; i < data.size(); i++)
                printf("%d ", data[i]);
            */
        }

        typedef multimap<double, const char *>::iterator multip;
        for (multip p = res.begin(); p != res.end();) {
            multip last = p++;
            if (p == res.end()) break;
            printf("    %s is %.2f times faster than %s\n",
                    last->second, p->first / last->first, p->second);
        }
    }

    destruct_handle(handle);
    return 0;
}
<commit_msg>add check sum<commit_after>#include <dlfcn.h>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <map>
#include <cstdio>
using namespace std;
typedef void (*Mp)(vector<int> &);
typedef const char *(*Self)();
const char *ALGS = "sort";
const char *NAME = "self";

void load_handle(vector<void *> &handle, int num, char *so[]) {
    void *lib_handle = NULL;
    for (int i = 0; i < num; i++) {
        if ((lib_handle = dlopen(so[i], RTLD_NOW)) == NULL) {
            printf("Open Error %s\n", dlerror());
            continue;
        }
        handle.push_back(lib_handle);
    }
}

void load_algs(vector<void *> &handle, vector<pair<Self, Mp> > &algs) {
    Mp method = NULL;
    Self self = NULL;

    for (int i = 0; i < handle.size(); i++) {
        if ((self = (Self)dlsym(handle[i], NAME)) == NULL) {
            printf("Open Error %s\n", dlerror());
            continue;
        }

        if ((method = (Mp)dlsym(handle[i], ALGS)) == NULL) {
            printf("Open Error %s\n", dlerror());
            continue;
        }
        algs.push_back(make_pair(self, method));
    }
}

void destruct_handle(vector<void *> &handle) {
    for (int i = 0; i < handle.size(); i++)
        dlclose(handle[i]);
    handle.clear();
}

bool is_correct(vector<int> &array, long long check_sum) {
    for (int i = 1; i < array.size(); i++)
        if (array[i - 1] > array[i])
            return false;

	long long sum = 0;
	for (int i = 0; i < array.size(); i++)
		sum += array[i];

	return sum == check_sum? true: false;
}

vector<int> random(int num) {
    vector<int> random_variable;

    srand(time(NULL));
    while (num--)
        random_variable.push_back(rand());

    return random_variable;
}

int main(int argc, char *argv[]) {
    if (argc < 3) return 0;

    vector<pair<Self, Mp> > algs;
    vector<void *> handle;

    load_handle(handle, argc - 1, argv + 1);
    load_algs(handle, algs);

    for (int num = 1; num < 10; num += 2) {
        multimap<double, const char *> res;
        vector<int> origin = random(num * 10000);

		long long check_sum = 0;
		for (int i = 0; i < origin.size(); i++)
			check_sum += origin[i];
        printf("\nFor %d integers\n", num * 10000);

        for (int i = 0; i < algs.size(); i++) {
            vector<int> data = origin;

            clock_t start = clock();
            //printf("%s\n", (*algs[i].first)());
            (*algs[i].second)(data);
            clock_t finish = clock();

            if (is_correct(data, check_sum))
                res.insert(make_pair((double)(finish - start) / CLOCKS_PER_SEC,
                            (*algs[i].first)()));
            /*
            for (int i = 0; i < data.size(); i++)
                printf("%d ", data[i]);
            */
        }

        typedef multimap<double, const char *>::iterator multip;
        for (multip p = res.begin(); p != res.end();) {
            multip last = p++;
            if (p == res.end()) break;
            printf("    %s is %.2f times faster than %s\n",
                    last->second, p->first / last->first, p->second);
        }
    }

    destruct_handle(handle);
    return 0;
}
<|endoftext|>


<commit_before>// Hand.cpp
// Created by Evan Almonte
//
#include "Hand.hpp"
#include "Card.hpp"
#include <iostream>

using std::cout;

Hand::Hand ( ) : LinkedList<Card*> ( ) {}

int Hand::evaluate( ) {
	Node* foundGroup = findGroup ( );
	if(size > 3 && foundGroup != nullptr) {
		removeGroup (foundGroup);
		return 1 + evaluate ( );
	}
	return 0;
}

void Hand::removeGroup(Node* node) {
	if (node == nullptr) { return; }
	Node* previous = nullptr;
	Node* current = head;
	while(current != node) {
		previous = current;
		current = current->next;
	}
	Node* afterDelete = nullptr;
	for (int i = 0; i < 4; i++) {
		afterDelete = current->next;
		delete current;
		--size;
		current = afterDelete;
	}
	if(previous == nullptr) {
		head = afterDelete;
	} else if (previous == head) {
		head->next = afterDelete;
	}
	if(afterDelete == nullptr) {
		tail = previous;
	}
}

LinkedList<Card*>::Node* Hand::findGroup( ) const {
	if (head == nullptr) { return nullptr; }
	Node* current = head;
	Node* startOfGroup = head;
	int groupCount = 1;
	while(current->next != nullptr)
	{
		if (startOfGroup->data->compareByRank(*current->next->data) == 0) {
			groupCount++;
			if (groupCount == 4) { return startOfGroup; }
		} else {
			startOfGroup = current->next;
			groupCount = 1;
		}
		current = current->next;
	}
	return nullptr;
}

std::ostream& operator<<(std::ostream& output, const Hand& aHand) {
	Hand::Node* current = aHand.head;
	while(current != nullptr) {
		cout << *current->data;
		if(current->next != nullptr) {
			cout << " | ";
		}
		current = current->next;
	}
	return output;
}
<commit_msg>Modifies operator<< to print out 10 cards per line<commit_after>// Hand.cpp
// Created by Evan Almonte
//
#include "Hand.hpp"
#include "Card.hpp"
#include <iostream>

using std::cout;

Hand::Hand ( ) : LinkedList<Card*> ( ) {}

int Hand::evaluate( ) {
	Node* foundGroup = findGroup ( );
	if(size > 3 && foundGroup != nullptr) {
		removeGroup (foundGroup);
		return 1 + evaluate ( );
	}
	return 0;
}

void Hand::removeGroup(Node* node) {
	if (node == nullptr) { return; }
	Node* previous = nullptr;
	Node* current = head;
	while(current != node) {
		previous = current;
		current = current->next;
	}
	Node* afterDelete = nullptr;
	for (int i = 0; i < 4; i++) {
		afterDelete = current->next;
		delete current;
		--size;
		current = afterDelete;
	}
	if(previous == nullptr) {
		head = afterDelete;
	} else if (previous == head) {
		head->next = afterDelete;
	}
	if(afterDelete == nullptr) {
		tail = previous;
	}
}

LinkedList<Card*>::Node* Hand::findGroup( ) const {
	if (head == nullptr) { return nullptr; }
	Node* current = head;
	Node* startOfGroup = head;
	int groupCount = 1;
	while(current->next != nullptr)
	{
		if (startOfGroup->data->compareByRank(*current->next->data) == 0) {
			groupCount++;
			if (groupCount == 4) { return startOfGroup; }
		} else {
			startOfGroup = current->next;
			groupCount = 1;
		}
		current = current->next;
	}
	return nullptr;
}

std::ostream& operator<<(std::ostream& output, const Hand& aHand) {
	Hand::Node* current = aHand.head;
	int numPrinted = 0;
	while(current != nullptr) {
		cout << *current->data;
		if(current->next != nullptr) {
			cout << " | ";
			if ((numPrinted + 1) % 10 == 0) {
				cout << "\n";
			}
			numPrinted++;
		}
		current = current->next;
	}
	return output;
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <iostream>
#include <Context.h>
#include <Filter.h>
#include <text.h>
#include <util.h>
#include <i18n.h>
#include <main.h>
#include <CmdDenotate.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
CmdDenotate::CmdDenotate ()
{
  _keyword     = "denotate";
  _usage       = "task <filter> denotate <pattern>";
  _description = STRING_CMD_DENO_USAGE;
  _read_only   = false;
  _displays_id = false;
}

////////////////////////////////////////////////////////////////////////////////
int CmdDenotate::execute (std::string& output)
{
  int rc = 0;
  int count = 0;
  bool sensitive = context.config.getBoolean ("search.case.sensitive");

  // Apply filter.
  Filter filter;
  std::vector <Task> filtered;
  filter.subset (filtered);
  if (filtered.size () == 0)
  {
    context.footnote (STRING_FEEDBACK_NO_TASKS_SP);
    return 1;
  }

  // Extract all the ORIGINAL MODIFICATION args as simple text patterns.
  std::string pattern = "";
  for (auto& a : context.cli._args)
  {
    if (a.hasTag ("ORIGINAL") &&
        a.hasTag ("MODIFICATION"))
    {
      if (pattern != "")
        pattern += ' ';

      pattern += a.attribute ("raw");
    }
  }

  // Accumulated project change notifications.
  std::map <std::string, std::string> projectChanges;

  for (auto& task : filtered)
  {
    Task before (task);

    std::map <std::string, std::string> annotations;
    task.getAnnotations (annotations);

    if (annotations.size () == 0)
      throw std::string (STRING_CMD_DENO_NONE);

    std::string anno;
    bool match = false;
    for (auto i = annotations.begin (); i != annotations.end (); ++i)
    {
      if (i->second == pattern)
      {
        match = true;
        anno = i->second;
        annotations.erase (i);
        task.setAnnotations (annotations);
        break;
      }
    }

    if (! match)
    {
      for (auto i = annotations.begin (); i != annotations.end (); ++i)
      {
        auto loc = find (i->second, pattern, sensitive);
        if (loc != std::string::npos)
        {
          anno = i->second;
          annotations.erase (i);
          task.setAnnotations (annotations);
          break;
        }
      }
    }

    if (taskDiff (before, task))
    {
      std::string question = format (STRING_CMD_DENO_CONFIRM,
                                     task.id,
                                     task.get ("description"));

      if (permission (task, taskDifferences (before, task) + question, filtered.size ()))
      {
        ++count;
        context.tdb2.modify (task);
        feedback_affected (format (STRING_CMD_DENO_FOUND, anno));
        if (context.verbose ("project"))
          projectChanges[task.get ("project")] = onProjectChange (task, false);
      }
      else
      {
        std::cout << STRING_CMD_DENO_NO << "\n";
        rc = 1;
        if (_permission_quit)
          break;
      }
    }
    else
    {
      std::cout << format (STRING_CMD_DENO_NOMATCH, pattern) << "\n";
      rc = 1;
    }
  }

  // Now list the project changes.
  for (auto& change : projectChanges)
    if (change.first != "")
      context.footnote (change.second);

  feedback_affected (count == 1 ? STRING_CMD_DENO_1 : STRING_CMD_DENO_N, count);
  return rc;
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>CmdDenotate: Converted from CLI to CLI2<commit_after>////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////

#include <cmake.h>
#include <iostream>
#include <Context.h>
#include <Filter.h>
#include <text.h>
#include <util.h>
#include <i18n.h>
#include <main.h>
#include <CmdDenotate.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
CmdDenotate::CmdDenotate ()
{
  _keyword     = "denotate";
  _usage       = "task <filter> denotate <pattern>";
  _description = STRING_CMD_DENO_USAGE;
  _read_only   = false;
  _displays_id = false;
}

////////////////////////////////////////////////////////////////////////////////
int CmdDenotate::execute (std::string& output)
{
  int rc = 0;
  int count = 0;
  bool sensitive = context.config.getBoolean ("search.case.sensitive");

  // Apply filter.
  Filter filter;
  std::vector <Task> filtered;
  filter.subset (filtered);
  if (filtered.size () == 0)
  {
    context.footnote (STRING_FEEDBACK_NO_TASKS_SP);
    return 1;
  }

  // Extract all the ORIGINAL MODIFICATION args as simple text patterns.
  std::string pattern = "";
  for (auto& a : context.cli2._args)
  {
    if (a.hasTag ("MODIFICATION"))
    {
      if (pattern != "")
        pattern += ' ';

      pattern += a.attribute ("raw");
    }
  }

  // Accumulated project change notifications.
  std::map <std::string, std::string> projectChanges;

  for (auto& task : filtered)
  {
    Task before (task);

    std::map <std::string, std::string> annotations;
    task.getAnnotations (annotations);

    if (annotations.size () == 0)
      throw std::string (STRING_CMD_DENO_NONE);

    std::string anno;
    bool match = false;
    for (auto i = annotations.begin (); i != annotations.end (); ++i)
    {
      if (i->second == pattern)
      {
        match = true;
        anno = i->second;
        annotations.erase (i);
        task.setAnnotations (annotations);
        break;
      }
    }

    if (! match)
    {
      for (auto i = annotations.begin (); i != annotations.end (); ++i)
      {
        auto loc = find (i->second, pattern, sensitive);
        if (loc != std::string::npos)
        {
          anno = i->second;
          annotations.erase (i);
          task.setAnnotations (annotations);
          break;
        }
      }
    }

    if (taskDiff (before, task))
    {
      std::string question = format (STRING_CMD_DENO_CONFIRM,
                                     task.id,
                                     task.get ("description"));

      if (permission (task, taskDifferences (before, task) + question, filtered.size ()))
      {
        ++count;
        context.tdb2.modify (task);
        feedback_affected (format (STRING_CMD_DENO_FOUND, anno));
        if (context.verbose ("project"))
          projectChanges[task.get ("project")] = onProjectChange (task, false);
      }
      else
      {
        std::cout << STRING_CMD_DENO_NO << "\n";
        rc = 1;
        if (_permission_quit)
          break;
      }
    }
    else
    {
      std::cout << format (STRING_CMD_DENO_NOMATCH, pattern) << "\n";
      rc = 1;
    }
  }

  // Now list the project changes.
  for (auto& change : projectChanges)
    if (change.first != "")
      context.footnote (change.second);

  feedback_affected (count == 1 ? STRING_CMD_DENO_1 : STRING_CMD_DENO_N, count);
  return rc;
}

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>#include "SettingsMenu.hpp"

namespace swift
{
	SettingsMenu::SettingsMenu(sf::RenderWindow& win, AssetManager& am, Settings& s)
		:	State(win, am),
			settings(s)
	{
		returnType = State::Type::SettingsMenu;
	}

	SettingsMenu::~SettingsMenu()
	{
	}

	void SettingsMenu::setup()
	{
		activeScripts.push_back(&assets.getScript("./data/scripts/settingsMenu.lua"));

		for(auto& s : activeScripts)
		{
			s->start();
		}

		setupButtons();
	}

	void SettingsMenu::handleEvent(sf::Event &event)
	{
		gui.update(event);
		keyboard(event);
		mouse(event);
	}

	void SettingsMenu::update(sf::Time /*dt*/)
	{
		updateScripts();

		bool vsyncState = gui.getWidget(1).getState();
		settings.set("vsync", vsyncState);
	}

	void SettingsMenu::draw(float /*e*/)
	{
		window.draw(gui);
	}

	bool SettingsMenu::switchFrom()
	{
		return returnType != State::Type::SettingsMenu;
	}

	State::Type SettingsMenu::finish()
	{
		return returnType;
	}

	void SettingsMenu::setupButtons()
	{
		// return to mainMenu button
		struct
		{
			int x = 0;
			int y = 0;
			int w = 0;
			int h = 0;
			std::string str = "";
		} mainMenuReturnData;

		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("mainMenuReturnW", mainMenuReturnData.w);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("mainMenuReturnH", mainMenuReturnData.h);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("mainMenuReturnX", mainMenuReturnData.x);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("mainMenuReturnY", mainMenuReturnData.y);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("mainMenuReturnStr", mainMenuReturnData.str);

		cstr::Button& mainMenuButton = gui.addButton({mainMenuReturnData.x, mainMenuReturnData.y, mainMenuReturnData.w, mainMenuReturnData.h}, assets.getTexture("./data/textures/button.png"), [&]()
		{
			returnType = State::Type::MainMenu;
		});

		mainMenuButton.setText(mainMenuReturnData.str);
		mainMenuButton.setFont(assets.getFont("./data/fonts/DroidSansMono.ttf"));

		// v-sync toggle
		struct
		{
			int x = 0;
			int y = 0;
			int w = 0;
			int h = 0;
			std::string str = "";
		} vsyncToggleData;

		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("vsyncW", vsyncToggleData.w);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("vsyncH", vsyncToggleData.h);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("vsyncX", vsyncToggleData.x);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("vsyncY", vsyncToggleData.y);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("vsyncStr", vsyncToggleData.str);

		bool vsyncState;
		settings.get("vsync", vsyncState);

		cstr::Toggle& vsyncToggle = gui.addToggle(	{vsyncToggleData.x, vsyncToggleData.y, vsyncToggleData.w, vsyncToggleData.h},
													assets.getTexture("./data/textures/toggleOff.png"),
													assets.getTexture("./data/textures/toggleOn.png"),
													vsyncState);

		cstr::Label& vsyncLabel = gui.addLabel({static_cast<float>(vsyncToggleData.x),
												static_cast<float>(vsyncToggleData.y - 40)},
												vsyncToggleData.str,
												assets.getFont("./data/fonts/DroidSansMono.ttf"));

	}
}
<commit_msg>Fixed formatting<commit_after>#include "SettingsMenu.hpp"

namespace swift
{
	SettingsMenu::SettingsMenu(sf::RenderWindow& win, AssetManager& am, Settings& s)
		:	State(win, am),
			settings(s)
	{
		returnType = State::Type::SettingsMenu;
	}

	SettingsMenu::~SettingsMenu()
	{
	}

	void SettingsMenu::setup()
	{
		activeScripts.push_back(&assets.getScript("./data/scripts/settingsMenu.lua"));

		for(auto& s : activeScripts)
		{
			s->start();
		}

		setupButtons();
	}

	void SettingsMenu::handleEvent(sf::Event &event)
	{
		gui.update(event);
		keyboard(event);
		mouse(event);
	}

	void SettingsMenu::update(sf::Time /*dt*/)
	{
		updateScripts();

		bool vsyncState = gui.getWidget(1).getState();
		settings.set("vsync", vsyncState);
	}

	void SettingsMenu::draw(float /*e*/)
	{
		window.draw(gui);
	}

	bool SettingsMenu::switchFrom()
	{
		return returnType != State::Type::SettingsMenu;
	}

	State::Type SettingsMenu::finish()
	{
		return returnType;
	}

	void SettingsMenu::setupButtons()
	{
		// return to mainMenu button
		struct
		{
			int x = 0;
			int y = 0;
			int w = 0;
			int h = 0;
			std::string str = "";
		} mainMenuReturnData;

		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("mainMenuReturnW", mainMenuReturnData.w);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("mainMenuReturnH", mainMenuReturnData.h);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("mainMenuReturnX", mainMenuReturnData.x);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("mainMenuReturnY", mainMenuReturnData.y);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("mainMenuReturnStr", mainMenuReturnData.str);

		cstr::Button& mainMenuButton = gui.addButton({mainMenuReturnData.x, mainMenuReturnData.y, mainMenuReturnData.w, mainMenuReturnData.h}, assets.getTexture("./data/textures/button.png"), [&]()
		{
			returnType = State::Type::MainMenu;
		});

		mainMenuButton.setText(mainMenuReturnData.str);
		mainMenuButton.setFont(assets.getFont("./data/fonts/DroidSansMono.ttf"));

		// v-sync toggle
		struct
		{
			int x = 0;
			int y = 0;
			int w = 0;
			int h = 0;
			std::string str = "";
		} vsyncToggleData;

		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("vsyncW", vsyncToggleData.w);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("vsyncH", vsyncToggleData.h);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("vsyncX", vsyncToggleData.x);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("vsyncY", vsyncToggleData.y);
		assets.getScript("./data/scripts/settingsMenu.lua").getVariable("vsyncStr", vsyncToggleData.str);

		bool vsyncState;
		settings.get("vsync", vsyncState);

		cstr::Toggle& vsyncToggle = gui.addToggle(	{vsyncToggleData.x, vsyncToggleData.y, vsyncToggleData.w, vsyncToggleData.h},
													assets.getTexture("./data/textures/toggleOff.png"),
													assets.getTexture("./data/textures/toggleOn.png"),
													vsyncState);

		cstr::Label& vsyncLabel = gui.addLabel({static_cast<float>(vsyncToggleData.x),
												static_cast<float>(vsyncToggleData.y - 40)},
												vsyncToggleData.str,
												assets.getFont("./data/fonts/DroidSansMono.ttf"));
	}
}
<|endoftext|>


<commit_before>#include "update-dialog.h"
#include "ui_update-dialog.h"
#include <QMessageBox>
#include <QProcess>
#include "functions.h"
#if !defined Q_OS_WIN || defined NIGHTLY
	#include <QDesktopServices>
#endif

UpdateDialog::UpdateDialog(bool *shouldQuit, QWidget *parent)
	: QDialog(Q_NULLPTR), ui(new Ui::UpdateDialog), m_shouldQuit(shouldQuit), m_parent(parent)
{
	ui->setupUi(this);

	ui->scrollArea->setVisible(ui->checkShowChangelog->isChecked());
	ui->progressDownload->hide();
	resize(300, 0);

	connect(&m_updater, &ProgramUpdater::finished, this, &UpdateDialog::checkForUpdatesDone);
}

UpdateDialog::~UpdateDialog()
{
	delete ui;
}

void UpdateDialog::resizeToFit()
{
	ui->scrollArea->setVisible(ui->checkShowChangelog->isChecked());
	int width = ui->labelUpdateAvailable->size().width();

	ui->labelUpdateAvailable->setMinimumWidth(width);
	adjustSize();
	ui->labelUpdateAvailable->setMinimumWidth(0);
}

void UpdateDialog::checkForUpdates()
{
	m_updater.checkForUpdates();
}

void UpdateDialog::checkForUpdatesDone(QString newVersion, bool available, QString changelog)
{
	if (!available)
	{
		emit noUpdateAvailable();
		return;
	}

	bool hasChangelog = !changelog.isEmpty();
	if (hasChangelog)
	{
		ui->labelChangelog->setTextFormat(Qt::RichText);
		ui->labelChangelog->setText(parseMarkdown(changelog));
	}
	ui->checkShowChangelog->setVisible(hasChangelog);
	ui->scrollArea->setVisible(hasChangelog);
	ui->labelVersion->setText(tr("Version %1").arg(newVersion));

	show();
	activateWindow();
}

void UpdateDialog::accept()
{
	#if defined Q_OS_WIN && !defined NIGHTLY
		downloadUpdate();
	#else
		QDesktopServices::openUrl(m_updater.latestUrl());
		close();
	#endif
}

void UpdateDialog::downloadUpdate()
{
	ui->progressDownload->show();

	m_updater.downloadUpdate();
	connect(&m_updater, &ProgramUpdater::downloadProgress, this, &UpdateDialog::downloadProgress);
	connect(&m_updater, &ProgramUpdater::downloadFinished, this, &UpdateDialog::downloadFinished);
}

void UpdateDialog::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
	ui->progressDownload->setMaximum(bytesTotal);
	ui->progressDownload->setValue(bytesReceived);
}

void UpdateDialog::downloadFinished(QString path)
{
	ui->progressDownload->setValue(ui->progressDownload->maximum());

	QProcess::startDetached(path);

	if (m_parent != Q_NULLPTR)
	{ m_parent->close(); }

	*m_shouldQuit = true;
	qApp->exit();
}
<commit_msg>Fix changelog opened small by default (fix #1126)<commit_after>#include "update-dialog.h"
#include "ui_update-dialog.h"
#include <QMessageBox>
#include <QProcess>
#include "functions.h"
#if !defined Q_OS_WIN || defined NIGHTLY
	#include <QDesktopServices>
#endif

UpdateDialog::UpdateDialog(bool *shouldQuit, QWidget *parent)
	: QDialog(Q_NULLPTR), ui(new Ui::UpdateDialog), m_shouldQuit(shouldQuit), m_parent(parent)
{
	ui->setupUi(this);

	ui->checkShowChangelog->hide();
	ui->scrollArea->hide();
	ui->progressDownload->hide();
	resize(300, 0);

	connect(&m_updater, &ProgramUpdater::finished, this, &UpdateDialog::checkForUpdatesDone);
}

UpdateDialog::~UpdateDialog()
{
	delete ui;
}

void UpdateDialog::resizeToFit()
{
	ui->scrollArea->setVisible(ui->checkShowChangelog->isChecked());
	int width = ui->labelUpdateAvailable->size().width();

	ui->labelUpdateAvailable->setMinimumWidth(width);
	adjustSize();
	ui->labelUpdateAvailable->setMinimumWidth(0);
}

void UpdateDialog::checkForUpdates()
{
	m_updater.checkForUpdates();
}

void UpdateDialog::checkForUpdatesDone(QString newVersion, bool available, QString changelog)
{
	if (!available)
	{
		emit noUpdateAvailable();
		return;
	}

	bool hasChangelog = !changelog.isEmpty();
	if (hasChangelog)
	{
		ui->labelChangelog->setTextFormat(Qt::RichText);
		ui->labelChangelog->setText(parseMarkdown(changelog));
	}
	ui->checkShowChangelog->setVisible(hasChangelog);
	ui->scrollArea->setVisible(hasChangelog && ui->checkShowChangelog->isChecked());
	ui->labelVersion->setText(tr("Version %1").arg(newVersion));

	show();
	activateWindow();
}

void UpdateDialog::accept()
{
	#if defined Q_OS_WIN && !defined NIGHTLY
		downloadUpdate();
	#else
		QDesktopServices::openUrl(m_updater.latestUrl());
		close();
	#endif
}

void UpdateDialog::downloadUpdate()
{
	ui->progressDownload->show();

	m_updater.downloadUpdate();
	connect(&m_updater, &ProgramUpdater::downloadProgress, this, &UpdateDialog::downloadProgress);
	connect(&m_updater, &ProgramUpdater::downloadFinished, this, &UpdateDialog::downloadFinished);
}

void UpdateDialog::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
	ui->progressDownload->setMaximum(bytesTotal);
	ui->progressDownload->setValue(bytesReceived);
}

void UpdateDialog::downloadFinished(QString path)
{
	ui->progressDownload->setValue(ui->progressDownload->maximum());

	QProcess::startDetached(path);

	if (m_parent != Q_NULLPTR)
	{ m_parent->close(); }

	*m_shouldQuit = true;
	qApp->exit();
}
<|endoftext|>