<commit_before>/*
 Copyright (c) 2012, Paul Houx
 All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and
	the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
	the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
*/

/*
	This sample will show how to use the CameraStereo class to setup and render stereoscopic images.
	The camera contains different matrices for the left and right eye of the viewer. By rendering the scene
	twice, once for each eye, we can view the scene in 3D on monitors or televisions that support 3D.

	Here, we divide the window into a left and right half and render the scene to each half. This is called
	side-by-side stereoscopic and is supported by most 3D televisions. Simply connect your computer to
	such a television, run the sample in full screen and enable the TV's 3D mode.

	When creating your own stereoscopic application, be careful how you choose your focal length.
	An excellent article can be found here:
	http://paulbourke.net/miscellaneous/stereographics/stereorender/

	The CameraStereo class is based on the Off-Axis method described in this article.
*/

#include "cinder/app/AppBasic.h"

#include "cinder/gl/gl.h"
#include "cinder/gl/CameraStereoAutoFocuser.h"
#include "cinder/gl/GlslProg.h"
#include "cinder/gl/Vbo.h"

#include "cinder/Camera.h"
#include "cinder/ImageIo.h"
#include "cinder/MayaCamUI.h"
#include "cinder/Rand.h"
#include "cinder/TriMesh.h"
#include "cinder/ObjLoader.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class StereoscopicRenderingApp : public AppBasic {
public:
	typedef enum { SET_FOCAL_LENGTH, SET_FOCUS, AUTO_FOCUS_SIMPLE, AUTO_FOCUS_DEPTH } AutoFocusMethod;
public:
	void prepareSettings( Settings *settings );

	void setup();
	void update();
	void draw();

	void mouseDown( MouseEvent event );
	void mouseDrag( MouseEvent event );

	void keyDown( KeyEvent event );

	void resize( ResizeEvent event );
private:
	bool			mIsStereo;

	AutoFocusMethod	mFocusMethod;

	MayaCamUI		mMayaCam;
	CameraStereo	mCamera;

	gl::CameraStereoAutoFocuser	mAF;

	gl::GlslProg	mShader;

	gl::VboMesh		mMesh;
	gl::VboMesh		mNote;

	void render();
};

void StereoscopicRenderingApp::prepareSettings( Settings *settings )
{
	// create a 16:9 window
	settings->setWindowSize(960, 540);
	settings->setTitle("Stereoscopic Rendering");

	// allow high frame rates to test performance
	settings->setFrameRate( 300.0f );
}

void StereoscopicRenderingApp::setup()
{
	// enable stereoscopic rendering (press S to toggle)
	mIsStereo = true;

	// enable auto-focussing
	mFocusMethod = AUTO_FOCUS_DEPTH;

	// setup the camera
	mCamera.setEyePoint( Vec3f(0.2f, 1.3f, -11.5f) );
	mCamera.setCenterOfInterestPoint( Vec3f(0.5f, 1.5f, -0.1f) );
	mCamera.setFov( 60.0f );

	mMayaCam.setCurrentCam( mCamera );

	try {
		// load shader(s)
		mShader = gl::GlslProg( loadAsset("shaders/phong_vert.glsl"), loadAsset("shaders/phong_frag.glsl") );

		// load model(s)
		TriMesh		mesh;

		mesh.read( loadAsset("models/trombone.msh") );
		mMesh = gl::VboMesh( mesh );

		mesh.read( loadAsset("models/note.msh") );
		mNote = gl::VboMesh( mesh );
	}
	catch( const std::exception &e ) {
		// something went wrong, display error and quit
		console() << e.what() << std::endl;
		quit();
	}
}

void StereoscopicRenderingApp::update()
{
	float d, f;

	switch( mFocusMethod )
	{
	case SET_FOCAL_LENGTH:
		// auto-focus by calculating distance to center of interest
		d = (mCamera.getCenterOfInterestPoint() - mCamera.getEyePoint()).length();
		f = math<float>::min( 5.0f, d * 0.5f );

		// The setFocalLength() method will not change the eye separation distance,
		// which may cause the parallax effect to become uncomfortably big.
		mCamera.setFocalLength( f );
		mCamera.setEyeSeparation( 0.05f );
		break;
	case SET_FOCUS:
		// auto-focus by calculating distance to center of interest
		d = (mCamera.getCenterOfInterestPoint() - mCamera.getEyePoint()).length();
		f = math<float>::min( 5.0f, d * 0.5f );

		// The setFocus() method will automatically calculate a fitting value eye separation distance.
		// There is still no guarantee that the parallax effect stays within comfortable levels,
		// because there may be objects very near to the camera compared to the point we are looking at.
		mCamera.setFocus( f );
		break;
	case AUTO_FOCUS_SIMPLE:
		// Here, we use the gl::CameraStereoAutoFocuser class to determine the best focal length,
		// based on the distance to the center of interest. This is very similar to the SET_FOCUS
		// method. Use the UP and DOWN keys to adjust the intensity of the parallax effect.
		mAF.autoFocus( mCamera, false );
		break;
	case AUTO_FOCUS_DEPTH:
		// Here, we use the gl::CameraStereoAutoFocuser class to determine the best focal length,
		// based on the contents of the current depth buffer. This is by far the best method of
		// the four, because it guarantees the parallax effect will never be out of bounds.
		// Use the UP and DOWN keys to adjust the intensity of the parallax effect.
		mAF.autoFocus( mCamera, true );
		break;
	}
}

void StereoscopicRenderingApp::draw()
{
	// gray background
	gl::clear( Color(0.8f, 0.8f, 0.8f) );

	// enable 3D rendering
	gl::enableDepthRead();
	gl::enableDepthWrite();
	gl::pushMatrices();

	// stereoscopic rendering
	if( mIsStereo ) {
		// find dimensions of each viewport (side by side)
		int w = getWindowWidth();
		int h = getWindowHeight();

		// store current viewport
		glPushAttrib( GL_VIEWPORT_BIT );

		// draw to left half of window only
		gl::setViewport( Area(0, 0, w / 2, h) );

		// activate left camera
		mCamera.enableStereoLeft();
		gl::setMatrices( mCamera );

		// render scene
		render();

		// draw to right half of window only
		gl::setViewport( Area(w / 2, 0, w, h) );

		// activate right camera
		mCamera.enableStereoRight();
		gl::setMatrices( mCamera );

		// render scene
		render();

		// restore viewport
		glPopAttrib();
	}
	else {
		// activate mono camera
		mCamera.disableStereo();
		gl::setMatrices( mCamera );

		// render scene
		render();
	}

	// restore 2D
	gl::popMatrices();
	gl::disableDepthWrite();
	gl::disableDepthRead();
}

void StereoscopicRenderingApp::mouseDown( MouseEvent event )
{
	// handle camera
	mMayaCam.mouseDown( event.getPos() );
}

void StereoscopicRenderingApp::mouseDrag( MouseEvent event )
{
	// handle camera
	mMayaCam.mouseDrag( event.getPos(), event.isLeftDown(), event.isMiddleDown(), event.isRightDown() );

	// update stereoscopic camera
	mCamera.setEyePoint( mMayaCam.getCamera().getEyePoint() );
	mCamera.setCenterOfInterestPoint( mMayaCam.getCamera().getCenterOfInterestPoint() );
}

void StereoscopicRenderingApp::keyDown( KeyEvent event )
{
	switch( event.getCode() )
	{
	case KeyEvent::KEY_ESCAPE:
		quit();
		break;
	case KeyEvent::KEY_f:
		// toggle full screen
		setFullScreen( ! isFullScreen() );
		break;
	case KeyEvent::KEY_s:
		// toggle stereoscopic rendering
		mIsStereo = !mIsStereo;
		break;
	case KeyEvent::KEY_v:
		// toggle vertical sync
		gl::enableVerticalSync( !gl::isVerticalSyncEnabled() );
		break;
	case KeyEvent::KEY_1:
		mFocusMethod = SET_FOCAL_LENGTH;
		break;
	case KeyEvent::KEY_2:
		mFocusMethod = SET_FOCUS;
		break;
	case KeyEvent::KEY_3:
		mFocusMethod = AUTO_FOCUS_SIMPLE;
		break;
	case KeyEvent::KEY_4:
		mFocusMethod = AUTO_FOCUS_DEPTH;
		break;
	case KeyEvent::KEY_UP:
		// increase the parallax effect (towards negative parallax)
		if(mFocusMethod >= AUTO_FOCUS_SIMPLE)
			mAF.setAutoFocusDepth( mAF.getAutoFocusDepth() + 0.05f );
		break;
	case KeyEvent::KEY_DOWN:
		// decrease the parallax effect (towards positive parallax)
		if(mFocusMethod >= AUTO_FOCUS_SIMPLE)
			mAF.setAutoFocusDepth( mAF.getAutoFocusDepth() - 0.05f );
		break;
	case KeyEvent::KEY_SPACE:
		// reset the parallax effect to 'no parallax for the nearest object'
		mAF.setAutoFocusDepth( 1.0f );
		break;
	}
}

void StereoscopicRenderingApp::resize( ResizeEvent event )
{
	// make sure the camera's aspect ratio remains correct
	mCamera.setAspectRatio( event.getAspectRatio() );
	mMayaCam.setCurrentCam( mCamera );
}

void StereoscopicRenderingApp::render()
{
	float seconds = (float) getElapsedSeconds();

	if( mShader && mMesh && mNote ) {
		// enable phong shading
		mShader.bind();

		// draw trombone
		gl::pushModelView();
		{
			gl::color( Color(0.7f, 0.6f, 0.0f) );
			gl::rotate( Vec3f::yAxis() * 10.0f * seconds );
			gl::draw( mMesh );

			// reflection
			gl::scale( 1.0f, -1.0f, 1.0f );
			gl::draw( mMesh );
		}
		gl::popModelView();

		// draw animated notes
		Rand rnd;
		for(int i=-100; i<=100; ++i) {
			rnd.seed(i);

			float t = rnd.nextFloat() * 200.0f + 2.0f * seconds;
			float r = rnd.nextFloat() * 360.0f + 60.0f * seconds;
			float z = fmodf( 5.0f * t, 200.0f ) - 100.0f;

			gl::pushModelView();
			{
				gl::color( Color( CM_HSV, rnd.nextFloat(), 1.0f, 1.0f ) );

				gl::pushModelView();
				gl::translate( i * 0.5f, 0.15f + 1.0f * math<float>::abs( sinf(3.0f * t) ), -z );
				gl::rotate( Vec3f::yAxis() * r );
				gl::draw( mNote );
				gl::popModelView();

				// reflection
				gl::pushModelView();
				gl::scale( 1.0f, -1.0f, 1.0f );
				gl::translate( i * 0.5f, 0.15f + 1.0f * math<float>::abs( sinf(3.0f * t) ), -z );
				gl::rotate( Vec3f::yAxis() * r );
				gl::draw( mNote );
				gl::popModelView();
			}
			gl::popModelView();
		}

		mShader.unbind();
	}

	// draw grid
	gl::color( Color(0.8f, 0.8f, 0.8f) );
	for(int i=-100; i<=100; ++i) {
		gl::drawLine( Vec3f((float) i, 0, -100), Vec3f((float) i, 0, 100) );
		gl::drawLine( Vec3f(-100, 0, (float) i), Vec3f(100, 0, (float) i) );
	}

	// draw floor
	gl::enableAlphaBlending();
	gl::color( ColorA(1,1,1,0.75f) );
	gl::drawCube( Vec3f(0.0f, -0.5f, 0.0f), Vec3f(200.0f, 1.0f, 200.0f) );
	gl::disableAlphaBlending();
}

CINDER_APP_BASIC( StereoscopicRenderingApp, RendererGl )<commit_msg>Tweaks to the StereoscopicRendering sample.<commit_after>/*
 Copyright (c) 2012, Paul Houx
 All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and
	the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
	the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
*/

/*
	This sample will show how to use the CameraStereo class to setup and render stereoscopic images.
	The camera contains different matrices for the left and right eye of the viewer. By rendering the scene
	twice, once for each eye, we can view the scene in 3D on monitors or televisions that support 3D.

	Here, we divide the window into a left and right half and render the scene to each half. This is called
	side-by-side stereoscopic and is supported by most 3D televisions. Simply connect your computer to
	such a television, run the sample in full screen and enable the TV's 3D mode.

	When creating your own stereoscopic application, be careful how you choose your focal length.
	An excellent article can be found here:
	http://paulbourke.net/miscellaneous/stereographics/stereorender/

	The CameraStereo class is based on the Off-Axis method described in this article.
*/

#include "cinder/app/AppBasic.h"

#include "cinder/gl/gl.h"
#include "cinder/gl/CameraStereoAutoFocuser.h"
#include "cinder/gl/GlslProg.h"
#include "cinder/gl/Vbo.h"

#include "cinder/Camera.h"
#include "cinder/Font.h"
#include "cinder/ImageIo.h"
#include "cinder/MayaCamUI.h"
#include "cinder/Rand.h"
#include "cinder/TriMesh.h"
#include "cinder/ObjLoader.h"

#include <boost/format.hpp>

using namespace ci;
using namespace ci::app;
using namespace std;

class StereoscopicRenderingApp : public AppBasic {
public:
	typedef enum { SET_FOCAL_LENGTH, SET_FOCUS, AUTO_FOCUS_SIMPLE, AUTO_FOCUS_DEPTH } AutoFocusMethod;
public:
	void prepareSettings( Settings *settings );

	void setup();
	void update();
	void draw();

	void mouseDown( MouseEvent event );
	void mouseDrag( MouseEvent event );

	void keyDown( KeyEvent event );

	void resize( ResizeEvent event );
private:
	bool			mIsStereo;

	AutoFocusMethod	mFocusMethod;

	MayaCamUI		mMayaCam;
	CameraStereo	mCamera;

	gl::CameraStereoAutoFocuser	mAF;

	gl::GlslProg	mShader;

	gl::VboMesh		mMesh;
	gl::VboMesh		mNote;

	Font			mFont;

	void render();
	void renderUI();
};

void StereoscopicRenderingApp::prepareSettings( Settings *settings )
{
	// create a 16:9 window
	settings->setWindowSize(960, 540);
	settings->setTitle("Stereoscopic Rendering");

	// allow high frame rates to test performance
	settings->setFrameRate( 300.0f );
}

void StereoscopicRenderingApp::setup()
{
	// enable stereoscopic rendering (press S to toggle)
	mIsStereo = true;

	// enable auto-focussing
	mFocusMethod = AUTO_FOCUS_DEPTH;

	// setup the camera
	mCamera.setEyePoint( Vec3f(0.2f, 1.3f, -11.5f) );
	mCamera.setCenterOfInterestPoint( Vec3f(0.5f, 1.5f, -0.1f) );
	mCamera.setFov( 60.0f );

	mMayaCam.setCurrentCam( mCamera );

	try {
		// load shader(s)
		mShader = gl::GlslProg( loadAsset("shaders/phong_vert.glsl"), loadAsset("shaders/phong_frag.glsl") );

		// load model(s)
		TriMesh		mesh;

		mesh.read( loadAsset("models/trombone.msh") );
		mMesh = gl::VboMesh( mesh );

		mesh.read( loadAsset("models/note.msh") );
		mNote = gl::VboMesh( mesh );
	}
	catch( const std::exception &e ) {
		// something went wrong, display error and quit
		console() << e.what() << std::endl;
		quit();
	}

	mFont = Font("Verdana", 36.0f);
}

void StereoscopicRenderingApp::update()
{
	float d, f;

	switch( mFocusMethod )
	{
	case SET_FOCAL_LENGTH:
		// auto-focus by calculating distance to center of interest
		d = (mCamera.getCenterOfInterestPoint() - mCamera.getEyePoint()).length();
		f = math<float>::min( 5.0f, d * 0.5f );

		// The setFocalLength() method will not change the eye separation distance,
		// which may cause the parallax effect to become uncomfortably big.
		mCamera.setFocalLength( f );
		mCamera.setEyeSeparation( 0.05f );
		break;
	case SET_FOCUS:
		// auto-focus by calculating distance to center of interest
		d = (mCamera.getCenterOfInterestPoint() - mCamera.getEyePoint()).length();
		f = math<float>::min( 5.0f, d * 0.5f );

		// The setFocus() method will automatically calculate a fitting value eye separation distance.
		// There is still no guarantee that the parallax effect stays within comfortable levels,
		// because there may be objects very near to the camera compared to the point we are looking at.
		mCamera.setFocus( f );
		break;
	case AUTO_FOCUS_SIMPLE:
		// Here, we use the gl::CameraStereoAutoFocuser class to determine the best focal length,
		// based on the distance to the center of interest. This is very similar to the SET_FOCUS
		// method. Use the UP and DOWN keys to adjust the intensity of the parallax effect.
		mAF.autoFocus( mCamera, false );
		break;
	case AUTO_FOCUS_DEPTH:
		// Here, we use the gl::CameraStereoAutoFocuser class to determine the best focal length,
		// based on the contents of the current depth buffer. This is by far the best method of
		// the four, because it guarantees the parallax effect will never be out of bounds.
		// Use the UP and DOWN keys to adjust the intensity of the parallax effect.
		mAF.autoFocus( mCamera, true );
		break;
	}
}

void StereoscopicRenderingApp::draw()
{
	// find dimensions of each viewport
	int w = getWindowWidth();
	int h = getWindowHeight();

	// gray background
	gl::clear( Color(0.8f, 0.8f, 0.8f) );

	// enable 3D rendering
	gl::enableDepthRead();
	gl::enableDepthWrite();
	gl::pushMatrices();

	// stereoscopic rendering
	if( mIsStereo ) {
		// store current viewport
		glPushAttrib( GL_VIEWPORT_BIT );

		// draw to left half of window only
		gl::setViewport( Area(0, 0, w / 2, h) );

		// activate left camera
		mCamera.enableStereoLeft();
		gl::setMatrices( mCamera );

		// render scene
		render();

		// draw to right half of window only
		gl::setViewport( Area(w / 2, 0, w, h) );

		// activate right camera
		mCamera.enableStereoRight();
		gl::setMatrices( mCamera );

		// render scene
		render();

		// restore viewport
		glPopAttrib();
	}
	else {
		// activate mono camera
		mCamera.disableStereo();
		gl::setMatrices( mCamera );

		// render scene
		render();
	}

	// restore 2D
	gl::popMatrices();
	gl::disableDepthWrite();
	gl::disableDepthRead();

	// render 2D user interface
	if( mIsStereo )
	{
		// store current viewport
		glPushAttrib( GL_VIEWPORT_BIT );

		// draw to left half of window only
		gl::setViewport( Area(0, 0, w / 2, h) );
		renderUI();

		// draw to right half of window only
		gl::setViewport( Area(w / 2, 0, w, h) );
		renderUI();

		// restore viewport
		glPopAttrib();
	}
	else
		renderUI();
}

void StereoscopicRenderingApp::mouseDown( MouseEvent event )
{
	// handle camera
	mMayaCam.mouseDown( event.getPos() );
}

void StereoscopicRenderingApp::mouseDrag( MouseEvent event )
{
	// handle camera
	mMayaCam.mouseDrag( event.getPos(), event.isLeftDown(), event.isMiddleDown(), event.isRightDown() );

	// update stereoscopic camera
	mCamera.setEyePoint( mMayaCam.getCamera().getEyePoint() );
	mCamera.setCenterOfInterestPoint( mMayaCam.getCamera().getCenterOfInterestPoint() );
}

void StereoscopicRenderingApp::keyDown( KeyEvent event )
{
	switch( event.getCode() )
	{
	case KeyEvent::KEY_ESCAPE:
		quit();
		break;
	case KeyEvent::KEY_f:
		// toggle full screen
		setFullScreen( ! isFullScreen() );
		break;
	case KeyEvent::KEY_s:
		// toggle stereoscopic rendering
		mIsStereo = !mIsStereo;
		break;
	case KeyEvent::KEY_v:
		// toggle vertical sync
		gl::enableVerticalSync( !gl::isVerticalSyncEnabled() );
		break;
	case KeyEvent::KEY_1:
		mFocusMethod = SET_FOCAL_LENGTH;
		break;
	case KeyEvent::KEY_2:
		mFocusMethod = SET_FOCUS;
		break;
	case KeyEvent::KEY_3:
		mFocusMethod = AUTO_FOCUS_SIMPLE;
		break;
	case KeyEvent::KEY_4:
		mFocusMethod = AUTO_FOCUS_DEPTH;
		break;
	case KeyEvent::KEY_UP:
		// increase the parallax effect (towards negative parallax)
		if(mFocusMethod >= AUTO_FOCUS_SIMPLE)
			mAF.setAutoFocusDepth( mAF.getAutoFocusDepth() + 0.05f );
		break;
	case KeyEvent::KEY_DOWN:
		// decrease the parallax effect (towards positive parallax)
		if(mFocusMethod >= AUTO_FOCUS_SIMPLE)
			mAF.setAutoFocusDepth( mAF.getAutoFocusDepth() - 0.05f );
		break;
	case KeyEvent::KEY_SPACE:
		// reset the parallax effect to 'no parallax for the nearest object'
		mAF.setAutoFocusDepth( 1.0f );
		break;
	case KeyEvent::KEY_LEFT:
		// reduce the auto focus speed
		mAF.setAutoFocusSpeed( mAF.getAutoFocusSpeed() - 0.01f );
		break;
	case KeyEvent::KEY_RIGHT:
		// increase the auto focus speed
		mAF.setAutoFocusSpeed( mAF.getAutoFocusSpeed() + 0.01f );
		break;
	}
}

void StereoscopicRenderingApp::resize( ResizeEvent event )
{
	// make sure the camera's aspect ratio remains correct
	mCamera.setAspectRatio( event.getAspectRatio() );
	mMayaCam.setCurrentCam( mCamera );
}

void StereoscopicRenderingApp::render()
{
	float seconds = (float) getElapsedSeconds();

	if( mShader && mMesh && mNote ) {
		// enable phong shading
		mShader.bind();

		// draw trombone
		gl::pushModelView();
		{
			gl::color( Color(0.7f, 0.6f, 0.0f) );
			gl::rotate( Vec3f::yAxis() * 10.0f * seconds );
			gl::draw( mMesh );

			// reflection
			gl::scale( 1.0f, -1.0f, 1.0f );
			gl::draw( mMesh );
		}
		gl::popModelView();

		// draw animated notes
		Rand rnd;
		for(int i=-100; i<=100; ++i) {
			rnd.seed(i);

			float t = rnd.nextFloat() * 200.0f + 2.0f * seconds;
			float r = rnd.nextFloat() * 360.0f + 60.0f * seconds;
			float z = fmodf( 5.0f * t, 200.0f ) - 100.0f;

			gl::pushModelView();
			{
				gl::color( Color( CM_HSV, rnd.nextFloat(), 1.0f, 1.0f ) );

				gl::pushModelView();
				gl::translate( i * 0.5f, 0.15f + 1.0f * math<float>::abs( sinf(3.0f * t) ), -z );
				gl::rotate( Vec3f::yAxis() * r );
				gl::draw( mNote );
				gl::popModelView();

				// reflection
				gl::pushModelView();
				gl::scale( 1.0f, -1.0f, 1.0f );
				gl::translate( i * 0.5f, 0.15f + 1.0f * math<float>::abs( sinf(3.0f * t) ), -z );
				gl::rotate( Vec3f::yAxis() * r );
				gl::draw( mNote );
				gl::popModelView();
			}
			gl::popModelView();
		}

		mShader.unbind();
	}

	// draw grid
	gl::color( Color(0.8f, 0.8f, 0.8f) );
	for(int i=-100; i<=100; ++i) {
		gl::drawLine( Vec3f((float) i, 0, -100), Vec3f((float) i, 0, 100) );
		gl::drawLine( Vec3f(-100, 0, (float) i), Vec3f(100, 0, (float) i) );
	}

	// draw floor
	gl::enableAlphaBlending();
	gl::color( ColorA(1,1,1,0.75f) );
	gl::drawCube( Vec3f(0.0f, -0.5f, 0.0f), Vec3f(200.0f, 1.0f, 200.0f) );
	gl::disableAlphaBlending();
}

void StereoscopicRenderingApp::renderUI()
{
	float w = (float) getWindowWidth() * 0.5f;
	float h = (float) getWindowHeight();

	boost::format fmt = boost::format( "%.3f\n%.3f\n%.3f\n%.3f" ) % mCamera.getFocalLength() % mCamera.getEyeSeparation() % mAF.getAutoFocusDepth() % mAF.getAutoFocusSpeed();

	gl::enableAlphaBlending();
	gl::drawString( "Focal Length:\nEye Distance:\nAuto Focus Depth:\nAuto Focus Speed:", Vec2f( w - 200.0f, h - 150.0f ), Color::black(), mFont );
	gl::drawStringRight( fmt.str(), Vec2f( w + 200.0f, h - 150.0f ), Color::black(), mFont );
	gl::disableAlphaBlending();
}

CINDER_APP_BASIC( StereoscopicRenderingApp, RendererGl )<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: CurrentMasterPagesSelector.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 14:43:25 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SD_TOOLPANEL_CONTROLS_CURRENT_MASTER_PAGES_SELECTOR_HXX
#define SD_TOOLPANEL_CONTROLS_CURRENT_MASTER_PAGES_SELECTOR_HXX

#include "MasterPagesSelector.hxx"
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

namespace sd { namespace toolpanel { namespace controls {

class CurrentMasterPagesSelector
    : public MasterPagesSelector
{
public:
    CurrentMasterPagesSelector (
        TreeNode* pParent,
        SdDrawDocument& rDocument,
        ViewShellBase& rBase,
        DrawViewShell& rViewShell);
    virtual ~CurrentMasterPagesSelector (void);

    virtual void LateInit (void);

    /** Set the selection so that the master page is selected that is
        used by the currently selected page of the document in the
        center pane.
    */
    virtual void UpdateSelection (void);

    /** Clear the list of currently used master pages and fill it
        with anew.
    */
    virtual void Fill (void);

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent>
        mxListener;
};

} } } // end of namespace ::sd::toolpanel::controls

#endif
<commit_msg>INTEGRATION: CWS impress33 (1.2.220); FILE MERGED 2005/02/03 14:11:55 af 1.2.220.2: #i41507# Adaption to modifications in base class MasterPagesSelector. 2005/02/01 15:40:23 af 1.2.220.1: #i41507# Replaced references of master pages in MasterPageContainer by pointers into application document.<commit_after>/*************************************************************************
 *
 *  $RCSfile: CurrentMasterPagesSelector.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2005-02-16 16:59:06 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SD_TOOLPANEL_CONTROLS_CURRENT_MASTER_PAGES_SELECTOR_HXX
#define SD_TOOLPANEL_CONTROLS_CURRENT_MASTER_PAGES_SELECTOR_HXX

#include "MasterPagesSelector.hxx"
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif

namespace sd { namespace toolpanel { namespace controls {

/** Adaption of a value set control that shows previews of master pages that
    are currently used by the document of the application.

    It does not use the approach of the base class of storing tokens as item
    data in the value set that identify entries in the MasterPageContainer.
    Instead it stores pointers directly to master pages in the document.
    The base class is used to have access to the code that assigns master
    pages to the document.
*/
class CurrentMasterPagesSelector
    : public MasterPagesSelector
{
public:
    CurrentMasterPagesSelector (
        TreeNode* pParent,
        SdDrawDocument& rDocument,
        ViewShellBase& rBase,
        DrawViewShell& rViewShell);
    virtual ~CurrentMasterPagesSelector (void);

    virtual void LateInit (void);

    /** Set the selection so that the master page is selected that is
        used by the currently selected page of the document in the
        center pane.
    */
    virtual void UpdateSelection (void);

    /** Clear the list of currently used master pages and fill it
        with anew.
    */
    virtual void Fill (void);
    virtual void Clear (void);

    virtual void InvalidatePreview (const SdPage* pPage);

protected:
    /** Return the master page whose preview is currently selected in the
        value set control.
        @return
            The returned page belongs to the main document, not to the local
            document of the MasterPageContainer.
    */
    virtual SdPage* GetSelectedMasterPage (void);

    /** For all currently used master pages a new preview is rendered and
        put into the value set control.
    */
    virtual void UpdateAllPreviews (void);
    virtual void UpdatePreview (USHORT nIndex);

private:
    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent>
        mxListener;
};

} } } // end of namespace ::sd::toolpanel::controls

#endif
<|endoftext|>


<commit_before>//
// Projectname: amos-ss16-proj5
//
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

#include "detection.h"
#include "element.h"

using namespace std;
using namespace cv;

Detection::Detection(Detector * people_detector, Detector * vehicle_detector) {

    people_detector_ = people_detector;
    vehicle_detector_ = vehicle_detector;
    image_view_ = new ImageView();
}

Detection::~Detection(){
    delete image_view_;
    image_view_ = NULL;
}

FrameDetectionData* Detection::ProcessFrame(Image * image) {

    Mat frame = image->GetRGBImage();
    Mat resized_frame = ResizeFrame(&frame);

    std::vector<Rect> detected_people = people_detector_->Detect(&resized_frame);
    std::vector<Rect> detected_vehicles = vehicle_detector_->Detect(&resized_frame);

    // write the detected people and vehicle data into frame detection data and return it
    // resize the position and the box of detected elements to real size again
    FrameDetectionData* detected_objects = new FrameDetectionData();
    std::vector<Element> people_elements;
    std::vector<Element> vehicle_elements;

    for(int i=0; i<detected_people.size(); i++) {

        Rect current_rec = detected_people.at(i);

        std::vector<int> position;
        std::vector<int> box;

        int pos_x_resized = current_rec.x/0.3125;
        int pos_y_resized = current_rec.y/0.3125;

        if(pos_x_resized < 0){
            pos_x_resized = 0;
        }
        if(pos_x_resized > image->GetImageWidth()){
            pos_x_resized = image->GetImageWidth();
        }

        if(pos_y_resized < 0){
            pos_y_resized = 0;
        }
        if(pos_y_resized > image->GetImageHeight()){
            pos_y_resized = image->GetImageHeight();
        }

        position.push_back(pos_x_resized);
        position.push_back(pos_y_resized);

        int box_width_resized = current_rec.width/0.3125;
        int box_height_resized = current_rec.height/0.3125;

        if((position.at(0) + box_width_resized) > image->GetImageWidth()){
            box_width_resized = image->GetImageWidth()-position.at(0);
        }
        if((position.at(1) + box_height_resized) > image->GetImageHeight()){
            box_height_resized = image->GetImageHeight()-position.at(1);
        }

        box.push_back(box_width_resized);
        box.push_back(box_height_resized);

        //std::cout << "Process Frame: position of elem: " << position.at(0) << " " << position.at(1) << std::endl;
        //std::cout << "Process Frame: width and height: " << box.at(0) << " " << box.at(1) << std::endl;

        Element current_elem(position, box);

        people_elements.push_back(current_elem);
    }

    detected_objects->AddElementsOfType(OBJECT_HUMAN, people_elements);

    for(int i=0; i<detected_vehicles.size(); i++) {

        Rect current_rec = detected_vehicles.at(i);

        std::vector<int> position;
        std::vector<int> box;

        position.push_back(current_rec.x/0.3125);
        position.push_back(current_rec.y/0.3125);

        box.push_back(current_rec.width/0.3125);
        box.push_back(current_rec.height/0.3125);

        Element current_elem(position, box);

        vehicle_elements.push_back(current_elem);
    }

    detected_objects->AddElementsOfType(OBJECT_VEHICLE, vehicle_elements);

    // display image and detections

    image_view_->ShowImageAndDetections(image, people_elements, vehicle_elements);

    return detected_objects;
}

Mat Detection::ResizeFrame(Mat *frame) {
    //resize the image to width of 400px to reduce detection time and improve detection accuracy
    //0.3125 is used because the test video is 1280 x 720, so the width resized images is 400px this has to be changed to our image size (best would be no hard coded scaling so other images sizes work too!)
    // TODO: dynamic risizeing depending on input (min width 400px)

    Mat resized_frame;
    resize(*frame, resized_frame, Size(0, 0), 0.3125, 0.3125, CV_INTER_AREA);
    return resized_frame;
}
<commit_msg>implemnted method for function adjustContrastAndBrightness in class Detection<commit_after>//
// Projectname: amos-ss16-proj5
//
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

#include "detection.h"
#include "element.h"

using namespace std;
using namespace cv;

Detection::Detection(Detector * people_detector, Detector * vehicle_detector) {

    people_detector_ = people_detector;
    vehicle_detector_ = vehicle_detector;
    image_view_ = new ImageView();
}

Detection::~Detection(){
    delete image_view_;
    image_view_ = NULL;
}

FrameDetectionData* Detection::ProcessFrame(Image * image) {

    Mat frame = image->GetRGBImage();
    Mat resized_frame = ResizeFrame(&frame);

    std::vector<Rect> detected_people = people_detector_->Detect(&resized_frame);
    std::vector<Rect> detected_vehicles = vehicle_detector_->Detect(&resized_frame);

    // write the detected people and vehicle data into frame detection data and return it
    // resize the position and the box of detected elements to real size again
    FrameDetectionData* detected_objects = new FrameDetectionData();
    std::vector<Element> people_elements;
    std::vector<Element> vehicle_elements;

    for(int i=0; i<detected_people.size(); i++) {

        Rect current_rec = detected_people.at(i);

        std::vector<int> position;
        std::vector<int> box;

        int pos_x_resized = current_rec.x/0.3125;
        int pos_y_resized = current_rec.y/0.3125;

        if(pos_x_resized < 0){
            pos_x_resized = 0;
        }
        if(pos_x_resized > image->GetImageWidth()){
            pos_x_resized = image->GetImageWidth();
        }

        if(pos_y_resized < 0){
            pos_y_resized = 0;
        }
        if(pos_y_resized > image->GetImageHeight()){
            pos_y_resized = image->GetImageHeight();
        }

        position.push_back(pos_x_resized);
        position.push_back(pos_y_resized);

        int box_width_resized = current_rec.width/0.3125;
        int box_height_resized = current_rec.height/0.3125;

        if((position.at(0) + box_width_resized) > image->GetImageWidth()){
            box_width_resized = image->GetImageWidth()-position.at(0);
        }
        if((position.at(1) + box_height_resized) > image->GetImageHeight()){
            box_height_resized = image->GetImageHeight()-position.at(1);
        }

        box.push_back(box_width_resized);
        box.push_back(box_height_resized);

        //std::cout << "Process Frame: position of elem: " << position.at(0) << " " << position.at(1) << std::endl;
        //std::cout << "Process Frame: width and height: " << box.at(0) << " " << box.at(1) << std::endl;

        Element current_elem(position, box);

        people_elements.push_back(current_elem);
    }

    detected_objects->AddElementsOfType(OBJECT_HUMAN, people_elements);

    for(int i=0; i<detected_vehicles.size(); i++) {

        Rect current_rec = detected_vehicles.at(i);

        std::vector<int> position;
        std::vector<int> box;

        position.push_back(current_rec.x/0.3125);
        position.push_back(current_rec.y/0.3125);

        box.push_back(current_rec.width/0.3125);
        box.push_back(current_rec.height/0.3125);

        Element current_elem(position, box);

        vehicle_elements.push_back(current_elem);
    }

    detected_objects->AddElementsOfType(OBJECT_VEHICLE, vehicle_elements);

    // display image and detections

    image_view_->ShowImageAndDetections(image, people_elements, vehicle_elements);

    return detected_objects;
}

Mat Detection::ResizeFrame(Mat *frame) {
    //resize the image to width of 400px to reduce detection time and improve detection accuracy
    //0.3125 is used because the test video is 1280 x 720, so the width resized images is 400px this has to be changed to our image size (best would be no hard coded scaling so other images sizes work too!)
    // TODO: dynamic risizeing depending on input (min width 400px)

    Mat resized_frame;
    resize(*frame, resized_frame, Size(0, 0), 0.3125, 0.3125, CV_INTER_AREA);
    return resized_frame;
}

cv::Mat adjustContrastAndBrightness(cv::Mat *frame,  double contrastValue, int brightnessValue){
    Mat adjusted_image = Mat::zeros( frame->size(), frame->type() );
        for( int x = 0; x < frame->rows; x++ ){
            for( int y = 0; y < frame->cols; y++ ){
                // c: use all colours of RGB / BGR
                for( int c = 0; c < 3; c++ ){
                    adjusted_image.at<Vec3b>(x,y)[c] = saturate_cast<uchar>(contrastValue* (frame->at<Vec3b>(x,y)[c])+ brightnessValue );
            }
        }
    }
    return adjusted_image;
}
<|endoftext|>


<commit_before>#include <eosio/chain/fork_database.hpp>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <fc/io/fstream.hpp>
#include <fstream>

namespace eosio { namespace chain {
   using boost::multi_index_container;
   using namespace boost::multi_index;

   struct by_block_id;
   struct by_block_num;
   struct by_lib_block_num;
   struct by_prev;
   typedef multi_index_container<
      block_state_ptr,
      indexed_by<
         hashed_unique< tag<by_block_id>, member<block_header_state, block_id_type, &block_header_state::id>, std::hash<block_id_type>>,
         ordered_non_unique< tag<by_prev>, const_mem_fun<block_header_state, const block_id_type&, &block_header_state::prev> >,
         ordered_non_unique< tag<by_block_num>,
            composite_key< block_state,
               member<block_header_state,uint32_t,&block_header_state::block_num>,
               member<block_state,bool,&block_state::in_current_chain>
            >,
            composite_key_compare< std::less<uint32_t>, std::greater<bool> >
         >,
         ordered_non_unique< tag<by_lib_block_num>,
            composite_key< block_header_state,
                member<block_header_state,uint32_t,&block_header_state::dpos_irreversible_blocknum>,
                member<block_header_state,uint32_t,&block_header_state::bft_irreversible_blocknum>,
                member<block_header_state,uint32_t,&block_header_state::block_num>
            >,
            composite_key_compare< std::greater<uint32_t>, std::greater<uint32_t>, std::greater<uint32_t> >
         >
      >
   > fork_multi_index_type;

   struct fork_database_impl {
      fork_multi_index_type index;
      block_state_ptr       head;
      fc::path              datadir;
   };

   fork_database::fork_database( const fc::path& data_dir ):my( new fork_database_impl() ) {
      my->datadir = data_dir;

      if (!fc::is_directory(my->datadir))
         fc::create_directories(my->datadir);

      auto fork_db_dat = my->datadir / config::forkdb_filename;
      if( fc::exists( fork_db_dat ) ) {
         string content;
         fc::read_file_contents( fork_db_dat, content );

         fc::datastream<const char*> ds( content.data(), content.size() );
         unsigned_int size; fc::raw::unpack( ds, size );
         for( uint32_t i = 0, n = size.value; i < n; ++i ) {
            block_state s;
            fc::raw::unpack( ds, s );
            set( std::make_shared<block_state>( move( s ) ) );
         }
         block_id_type head_id;
         fc::raw::unpack( ds, head_id );

         my->head = get_block( head_id );

         fc::remove( fork_db_dat );
      }
   }

   void fork_database::close() {
      if( my->index.size() == 0 ) return;

      auto fork_db_dat = my->datadir / config::forkdb_filename;
      std::ofstream out( fork_db_dat.generic_string().c_str(), std::ios::out | std::ios::binary | std::ofstream::trunc );
      uint32_t num_blocks_in_fork_db = my->index.size();
      fc::raw::pack( out, unsigned_int{num_blocks_in_fork_db} );
      for( const auto& s : my->index ) {
         fc::raw::pack( out, *s );
      }
      if( my->head )
         fc::raw::pack( out, my->head->id );
      else
         fc::raw::pack( out, block_id_type() );

      /// we don't normally indicate the head block as irreversible
      /// we cannot normally prune the lib if it is the head block because
      /// the next block needs to build off of the head block. We are exiting
      /// now so we can prune this block as irreversible before exiting.
      auto lib    = my->head->dpos_irreversible_blocknum;
      auto oldest = *my->index.get<by_block_num>().begin();
      if( oldest->block_num <= lib ) {
         prune( oldest );
      }

      my->index.clear();
   }

   fork_database::~fork_database() {
      close();
   }

   void fork_database::set( block_state_ptr s ) {
      auto result = my->index.insert( s );
      FC_ASSERT( s->id == s->header.id() );

         //FC_ASSERT( s->block_num == s->header.block_num() );

      FC_ASSERT( result.second, "unable to insert block state, duplicate state detected" );
      if( !my->head ) {
         my->head =  s;
      } else if( my->head->block_num < s->block_num ) {
         my->head =  s;
      }
   }

   block_state_ptr fork_database::add( block_state_ptr n ) {
      auto inserted = my->index.insert(n);
      FC_ASSERT( inserted.second, "duplicate block added?" );

      my->head = *my->index.get<by_lib_block_num>().begin();

      auto lib    = my->head->dpos_irreversible_blocknum;
      auto oldest = *my->index.get<by_block_num>().begin();

      if( oldest->block_num < lib ) {
         prune( oldest );
      }

      return n;
   }

   block_state_ptr fork_database::add( signed_block_ptr b, bool trust ) {
      FC_ASSERT( b, "attempt to add null block" );
      FC_ASSERT( my->head, "no head block set" );

      const auto& by_id_idx = my->index.get<by_block_id>();
      auto existing = by_id_idx.find( b->id() );
      FC_ASSERT( existing == by_id_idx.end(), "we already know about this block" );

      auto prior = by_id_idx.find( b->previous );
      FC_ASSERT( prior != by_id_idx.end(), "unlinkable block", ("id", b->id())("previous", b->previous) );

      auto result = std::make_shared<block_state>( **prior, move(b), trust );
      FC_ASSERT( result );
      return add(result);
   }

   const block_state_ptr& fork_database::head()const { return my->head; }

   /**
    *  Given two head blocks, return two branches of the fork graph that
    *  end with a common ancestor (same prior block)
    */
   pair< branch_type, branch_type >  fork_database::fetch_branch_from( const block_id_type& first,
                                                                       const block_id_type& second )const {
      pair<branch_type,branch_type> result;
      auto first_branch = get_block(first);
      auto second_branch = get_block(second);

      while( first_branch->block_num > second_branch->block_num )
      {
         result.first.push_back(first_branch);
         first_branch = get_block( first_branch->header.previous );
         FC_ASSERT( first_branch );
      }

      while( second_branch->block_num > first_branch->block_num )
      {
         result.second.push_back( second_branch );
         second_branch = get_block( second_branch->header.previous );
         FC_ASSERT( second_branch );
      }

      while( first_branch->header.previous != second_branch->header.previous )
      {
         result.first.push_back(first_branch);
         result.second.push_back(second_branch);
         first_branch = get_block( first_branch->header.previous );
         second_branch = get_block( second_branch->header.previous );
         FC_ASSERT( first_branch && second_branch );
      }

      if( first_branch && second_branch )
      {
         result.first.push_back(first_branch);
         result.second.push_back(second_branch);
      }
      return result;
   } /// fetch_branch_from

   /// remove all of the invalid forks built of this id including this id
   void fork_database::remove( const block_id_type& id ) {
      vector<block_id_type> remove_queue{id};

      for( uint32_t i = 0; i < remove_queue.size(); ++i ) {
         auto itr = my->index.find( remove_queue[i] );
         if( itr != my->index.end() )
            my->index.erase(itr);

         auto& previdx = my->index.get<by_prev>();
         auto  previtr = previdx.lower_bound(remove_queue[i]);
         while( previtr != previdx.end() && (*previtr)->header.previous == remove_queue[i] ) {
            remove_queue.push_back( (*previtr)->id );
            ++previtr;
         }
      }
      //wdump((my->index.size()));
      my->head = *my->index.get<by_lib_block_num>().begin();
   }

   void fork_database::set_validity( const block_state_ptr& h, bool valid ) {
      if( !valid ) {
         remove( h->id );
      } else {
         /// remove older than irreversible and mark block as valid
         h->validated = true;
      }
   }

   void fork_database::mark_in_current_chain( const block_state_ptr& h, bool in_current_chain ) {
      if( h->in_current_chain == in_current_chain )
         return;

      auto& by_id_idx = my->index.get<by_block_id>();
      auto itr = by_id_idx.find( h->id );
      FC_ASSERT( itr != by_id_idx.end(), "could not find block in fork database" );

      by_id_idx.modify( itr, [&]( auto& bsp ) { // Need to modify this way rather than directly so that Boost MultiIndex can re-sort
         bsp->in_current_chain = in_current_chain;
      });
   }

   void fork_database::prune( const block_state_ptr& h ) {
      auto num = h->block_num;

      auto& by_bn = my->index.get<by_block_num>();
      auto bni = by_bn.begin();
      while( bni != by_bn.end() && (*bni)->block_num < num ) {
         prune( *bni );
         bni = by_bn.begin();
      }

      auto itr = my->index.find( h->id );
      if( itr != my->index.end() ) {
         irreversible(*itr); //XXX
         my->index.erase(itr);
      }

      auto& numidx = my->index.get<by_block_num>();
      auto nitr = numidx.lower_bound( num );
      while( nitr != numidx.end() && (*nitr)->block_num == num ) {
         auto itr_to_remove = nitr;
         ++nitr;
         auto id = (*itr_to_remove)->id;
         remove( id );
      }
   }

   block_state_ptr   fork_database::get_block(const block_id_type& id)const {
      auto itr = my->index.find( id );
      if( itr != my->index.end() )
         return *itr;
      return block_state_ptr();
   }

   block_state_ptr   fork_database::get_block_in_current_chain_by_num( uint32_t n )const {
      const auto& numidx = my->index.get<by_block_num>();
      auto nitr = numidx.lower_bound( n );
      // following asserts removed so null can be returned
      //FC_ASSERT( nitr != numidx.end() && (*nitr)->block_num == n,
      //           "could not find block in fork database with block number ${block_num}", ("block_num", n) );
      //FC_ASSERT( (*nitr)->in_current_chain == true,
      //           "block (with block number ${block_num}) found in fork database is not in the current chain", ("block_num", n) );
      if( nitr == numidx.end() || (*nitr)->block_num != n || (*nitr)->in_current_chain != true )
         return block_state_ptr();
      return *nitr;
   }

   void fork_database::add( const header_confirmation& c ) {
      auto b = get_block( c.block_id );
      FC_ASSERT( b, "unable to find block id ${id}", ("id",c.block_id));
      b->add_confirmation( c );

      if( b->bft_irreversible_blocknum < b->block_num &&
         b->confirmations.size() > ((b->active_schedule.producers.size() * 2) / 3) ) {
         set_bft_irreversible( c.block_id );
      }
   }

   /**
    *  This method will set this block as being BFT irreversible and will update
    *  all blocks which build off of it to have the same bft_irb if their existing
    *  bft irb is less than this block num.
    *
    *  This will require a search over all forks
    */
   void fork_database::set_bft_irreversible( block_id_type id ) {
      auto& idx = my->index.get<by_block_id>();
      auto itr = idx.find(id);
      uint32_t block_num = (*itr)->block_num;
      idx.modify( itr, [&]( auto& bsp ) {
           bsp->bft_irreversible_blocknum = bsp->block_num;
      });

      /** to prevent stack-overflow, we perform a bredth-first traversal of the
       * fork database. At each stage we iterate over the leafs from the prior stage
       * and find all nodes that link their previous. If we update the bft lib then we
       * add it to a queue for the next layer.  This lambda takes one layer and returns
       * all block ids that need to be iterated over for next layer.
       */
      auto update = [&]( const vector<block_id_type>& in ) {
         vector<block_id_type> updated;

         for( const auto& i : in ) {
            auto& pidx = my->index.get<by_prev>();
            auto pitr  = pidx.lower_bound( i );
            auto epitr = pidx.upper_bound( i );
            while( pitr != epitr ) {
               pidx.modify( pitr, [&]( auto& bsp ) {
                 if( bsp->bft_irreversible_blocknum < block_num ) {
                    bsp->bft_irreversible_blocknum = block_num;
                    updated.push_back( bsp->id );
                 }
               });
               ++pitr;
            }
         }
         return updated;
      };

      vector<block_id_type> queue{id};
      while( queue.size() ) {
         queue = update( queue );
      }
   }

} } /// eosio::chain
<commit_msg>temporary change reverted #4196<commit_after>#include <eosio/chain/fork_database.hpp>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <fc/io/fstream.hpp>
#include <fstream>

namespace eosio { namespace chain {
   using boost::multi_index_container;
   using namespace boost::multi_index;

   struct by_block_id;
   struct by_block_num;
   struct by_lib_block_num;
   struct by_prev;
   typedef multi_index_container<
      block_state_ptr,
      indexed_by<
         hashed_unique< tag<by_block_id>, member<block_header_state, block_id_type, &block_header_state::id>, std::hash<block_id_type>>,
         ordered_non_unique< tag<by_prev>, const_mem_fun<block_header_state, const block_id_type&, &block_header_state::prev> >,
         ordered_non_unique< tag<by_block_num>,
            composite_key< block_state,
               member<block_header_state,uint32_t,&block_header_state::block_num>,
               member<block_state,bool,&block_state::in_current_chain>
            >,
            composite_key_compare< std::less<uint32_t>, std::greater<bool> >
         >,
         ordered_non_unique< tag<by_lib_block_num>,
            composite_key< block_header_state,
                member<block_header_state,uint32_t,&block_header_state::dpos_irreversible_blocknum>,
                member<block_header_state,uint32_t,&block_header_state::bft_irreversible_blocknum>,
                member<block_header_state,uint32_t,&block_header_state::block_num>
            >,
            composite_key_compare< std::greater<uint32_t>, std::greater<uint32_t>, std::greater<uint32_t> >
         >
      >
   > fork_multi_index_type;

   struct fork_database_impl {
      fork_multi_index_type index;
      block_state_ptr       head;
      fc::path              datadir;
   };

   fork_database::fork_database( const fc::path& data_dir ):my( new fork_database_impl() ) {
      my->datadir = data_dir;

      if (!fc::is_directory(my->datadir))
         fc::create_directories(my->datadir);

      auto fork_db_dat = my->datadir / config::forkdb_filename;
      if( fc::exists( fork_db_dat ) ) {
         string content;
         fc::read_file_contents( fork_db_dat, content );

         fc::datastream<const char*> ds( content.data(), content.size() );
         unsigned_int size; fc::raw::unpack( ds, size );
         for( uint32_t i = 0, n = size.value; i < n; ++i ) {
            block_state s;
            fc::raw::unpack( ds, s );
            set( std::make_shared<block_state>( move( s ) ) );
         }
         block_id_type head_id;
         fc::raw::unpack( ds, head_id );

         my->head = get_block( head_id );

         fc::remove( fork_db_dat );
      }
   }

   void fork_database::close() {
      if( my->index.size() == 0 ) return;

      auto fork_db_dat = my->datadir / config::forkdb_filename;
      std::ofstream out( fork_db_dat.generic_string().c_str(), std::ios::out | std::ios::binary | std::ofstream::trunc );
      uint32_t num_blocks_in_fork_db = my->index.size();
      fc::raw::pack( out, unsigned_int{num_blocks_in_fork_db} );
      for( const auto& s : my->index ) {
         fc::raw::pack( out, *s );
      }
      if( my->head )
         fc::raw::pack( out, my->head->id );
      else
         fc::raw::pack( out, block_id_type() );

      /// we don't normally indicate the head block as irreversible
      /// we cannot normally prune the lib if it is the head block because
      /// the next block needs to build off of the head block. We are exiting
      /// now so we can prune this block as irreversible before exiting.
      auto lib    = my->head->dpos_irreversible_blocknum;
      auto oldest = *my->index.get<by_block_num>().begin();
      if( oldest->block_num <= lib ) {
         prune( oldest );
      }

      my->index.clear();
   }

   fork_database::~fork_database() {
      close();
   }

   void fork_database::set( block_state_ptr s ) {
      auto result = my->index.insert( s );
      FC_ASSERT( s->id == s->header.id() );

         //FC_ASSERT( s->block_num == s->header.block_num() );

      FC_ASSERT( result.second, "unable to insert block state, duplicate state detected" );
      if( !my->head ) {
         my->head =  s;
      } else if( my->head->block_num < s->block_num ) {
         my->head =  s;
      }
   }

   block_state_ptr fork_database::add( block_state_ptr n ) {
      auto inserted = my->index.insert(n);
      FC_ASSERT( inserted.second, "duplicate block added?" );

      my->head = *my->index.get<by_lib_block_num>().begin();

      auto lib    = my->head->dpos_irreversible_blocknum;
      auto oldest = *my->index.get<by_block_num>().begin();

      if( oldest->block_num < lib ) {
         prune( oldest );
      }

      return n;
   }

   block_state_ptr fork_database::add( signed_block_ptr b, bool trust ) {
      FC_ASSERT( b, "attempt to add null block" );
      FC_ASSERT( my->head, "no head block set" );

      const auto& by_id_idx = my->index.get<by_block_id>();
      auto existing = by_id_idx.find( b->id() );
      FC_ASSERT( existing == by_id_idx.end(), "we already know about this block" );

      auto prior = by_id_idx.find( b->previous );
      FC_ASSERT( prior != by_id_idx.end(), "unlinkable block", ("id", b->id())("previous", b->previous) );

      auto result = std::make_shared<block_state>( **prior, move(b), trust );
      FC_ASSERT( result );
      return add(result);
   }

   const block_state_ptr& fork_database::head()const { return my->head; }

   /**
    *  Given two head blocks, return two branches of the fork graph that
    *  end with a common ancestor (same prior block)
    */
   pair< branch_type, branch_type >  fork_database::fetch_branch_from( const block_id_type& first,
                                                                       const block_id_type& second )const {
      pair<branch_type,branch_type> result;
      auto first_branch = get_block(first);
      auto second_branch = get_block(second);

      while( first_branch->block_num > second_branch->block_num )
      {
         result.first.push_back(first_branch);
         first_branch = get_block( first_branch->header.previous );
         FC_ASSERT( first_branch );
      }

      while( second_branch->block_num > first_branch->block_num )
      {
         result.second.push_back( second_branch );
         second_branch = get_block( second_branch->header.previous );
         FC_ASSERT( second_branch );
      }

      while( first_branch->header.previous != second_branch->header.previous )
      {
         result.first.push_back(first_branch);
         result.second.push_back(second_branch);
         first_branch = get_block( first_branch->header.previous );
         second_branch = get_block( second_branch->header.previous );
         FC_ASSERT( first_branch && second_branch );
      }

      if( first_branch && second_branch )
      {
         result.first.push_back(first_branch);
         result.second.push_back(second_branch);
      }
      return result;
   } /// fetch_branch_from

   /// remove all of the invalid forks built of this id including this id
   void fork_database::remove( const block_id_type& id ) {
      vector<block_id_type> remove_queue{id};

      for( uint32_t i = 0; i < remove_queue.size(); ++i ) {
         auto itr = my->index.find( remove_queue[i] );
         if( itr != my->index.end() )
            my->index.erase(itr);

         auto& previdx = my->index.get<by_prev>();
         auto  previtr = previdx.lower_bound(remove_queue[i]);
         while( previtr != previdx.end() && (*previtr)->header.previous == remove_queue[i] ) {
            remove_queue.push_back( (*previtr)->id );
            ++previtr;
         }
      }
      //wdump((my->index.size()));
      my->head = *my->index.get<by_lib_block_num>().begin();
   }

   void fork_database::set_validity( const block_state_ptr& h, bool valid ) {
      if( !valid ) {
         remove( h->id );
      } else {
         /// remove older than irreversible and mark block as valid
         h->validated = true;
      }
   }

   void fork_database::mark_in_current_chain( const block_state_ptr& h, bool in_current_chain ) {
      if( h->in_current_chain == in_current_chain )
         return;

      auto& by_id_idx = my->index.get<by_block_id>();
      auto itr = by_id_idx.find( h->id );
      FC_ASSERT( itr != by_id_idx.end(), "could not find block in fork database" );

      by_id_idx.modify( itr, [&]( auto& bsp ) { // Need to modify this way rather than directly so that Boost MultiIndex can re-sort
         bsp->in_current_chain = in_current_chain;
      });
   }

   void fork_database::prune( const block_state_ptr& h ) {
      auto num = h->block_num;

      auto& by_bn = my->index.get<by_block_num>();
      auto bni = by_bn.begin();
      while( bni != by_bn.end() && (*bni)->block_num < num ) {
         prune( *bni );
         bni = by_bn.begin();
      }

      auto itr = my->index.find( h->id );
      if( itr != my->index.end() ) {
         irreversible(*itr);
         my->index.erase(itr);
      }

      auto& numidx = my->index.get<by_block_num>();
      auto nitr = numidx.lower_bound( num );
      while( nitr != numidx.end() && (*nitr)->block_num == num ) {
         auto itr_to_remove = nitr;
         ++nitr;
         auto id = (*itr_to_remove)->id;
         remove( id );
      }
   }

   block_state_ptr   fork_database::get_block(const block_id_type& id)const {
      auto itr = my->index.find( id );
      if( itr != my->index.end() )
         return *itr;
      return block_state_ptr();
   }

   block_state_ptr   fork_database::get_block_in_current_chain_by_num( uint32_t n )const {
      const auto& numidx = my->index.get<by_block_num>();
      auto nitr = numidx.lower_bound( n );
      // following asserts removed so null can be returned
      //FC_ASSERT( nitr != numidx.end() && (*nitr)->block_num == n,
      //           "could not find block in fork database with block number ${block_num}", ("block_num", n) );
      //FC_ASSERT( (*nitr)->in_current_chain == true,
      //           "block (with block number ${block_num}) found in fork database is not in the current chain", ("block_num", n) );
      if( nitr == numidx.end() || (*nitr)->block_num != n || (*nitr)->in_current_chain != true )
         return block_state_ptr();
      return *nitr;
   }

   void fork_database::add( const header_confirmation& c ) {
      auto b = get_block( c.block_id );
      FC_ASSERT( b, "unable to find block id ${id}", ("id",c.block_id));
      b->add_confirmation( c );

      if( b->bft_irreversible_blocknum < b->block_num &&
         b->confirmations.size() > ((b->active_schedule.producers.size() * 2) / 3) ) {
         set_bft_irreversible( c.block_id );
      }
   }

   /**
    *  This method will set this block as being BFT irreversible and will update
    *  all blocks which build off of it to have the same bft_irb if their existing
    *  bft irb is less than this block num.
    *
    *  This will require a search over all forks
    */
   void fork_database::set_bft_irreversible( block_id_type id ) {
      auto& idx = my->index.get<by_block_id>();
      auto itr = idx.find(id);
      uint32_t block_num = (*itr)->block_num;
      idx.modify( itr, [&]( auto& bsp ) {
           bsp->bft_irreversible_blocknum = bsp->block_num;
      });

      /** to prevent stack-overflow, we perform a bredth-first traversal of the
       * fork database. At each stage we iterate over the leafs from the prior stage
       * and find all nodes that link their previous. If we update the bft lib then we
       * add it to a queue for the next layer.  This lambda takes one layer and returns
       * all block ids that need to be iterated over for next layer.
       */
      auto update = [&]( const vector<block_id_type>& in ) {
         vector<block_id_type> updated;

         for( const auto& i : in ) {
            auto& pidx = my->index.get<by_prev>();
            auto pitr  = pidx.lower_bound( i );
            auto epitr = pidx.upper_bound( i );
            while( pitr != epitr ) {
               pidx.modify( pitr, [&]( auto& bsp ) {
                 if( bsp->bft_irreversible_blocknum < block_num ) {
                    bsp->bft_irreversible_blocknum = block_num;
                    updated.push_back( bsp->id );
                 }
               });
               ++pitr;
            }
         }
         return updated;
      };

      vector<block_id_type> queue{id};
      while( queue.size() ) {
         queue = update( queue );
      }
   }

} } /// eosio::chain
<|endoftext|>


<commit_before>#include "Connection.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>

Connection::Connection(Driver* pDriver)
    : m_pDriver(pDriver)
{
}

void Connection::handleMessage(std::string message) {
    m_pDriver->HandleMessage("12");
}
crow::json::wvalue Connection::GetPatientStatus() {
    return m_pDriver->GetPatientStatus();
}
void Connection::BolusDrug(std::string drugName, double concentration, double dose){
    m_pDriver->BolusDrug(drugName, concentration, dose);
}

void Connection::operator()()
{
    SetRunning(true);

    crow::SimpleApp app;

    CROW_ROUTE(app, "/")([this](){
        return "BioGear Server by Screen Based Simulation Team";
    });

    CROW_ROUTE(app, "/patient/status")
    .methods("GET"_method)
    ([this](){
        crow::json::wvalue x = GetPatientStatus();
        return x;
    });

    CROW_ROUTE(app,"/patient/injection")
    .methods("POST"_method)
    ([this](const crow::request& req){
        auto x = crow::json::load(req.body);
        if (!x)
            return crow::response(400);
        std::string drugName = x["drug_name"].s();
        double concentration = x["concentration"].d();
        double dose = x["dose"].d();

        BolusDrug(drugName, concentration, dose);
        return crow::response{"successful"};
    });

    app.port(18080).multithreaded().run();

}
<commit_msg>change port to 23333<commit_after>#include "Connection.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>

Connection::Connection(Driver* pDriver)
    : m_pDriver(pDriver)
{
}

void Connection::handleMessage(std::string message) {
    m_pDriver->HandleMessage("12");
}
crow::json::wvalue Connection::GetPatientStatus() {
    return m_pDriver->GetPatientStatus();
}
void Connection::BolusDrug(std::string drugName, double concentration, double dose){
    m_pDriver->BolusDrug(drugName, concentration, dose);
}

void Connection::operator()()
{
    SetRunning(true);

    crow::SimpleApp app;

    CROW_ROUTE(app, "/")([this](){
        return "BioGear Server by Screen Based Simulation Team";
    });

    CROW_ROUTE(app, "/patient/status")
    .methods("GET"_method)
    ([this](){
        crow::json::wvalue x = GetPatientStatus();
        return x;
    });

    CROW_ROUTE(app,"/patient/injection")
    .methods("POST"_method)
    ([this](const crow::request& req){
        auto x = crow::json::load(req.body);
        if (!x)
            return crow::response(400);
        std::string drugName = x["drug_name"].s();
        double concentration = x["concentration"].d();
        double dose = x["dose"].d();

        BolusDrug(drugName, concentration, dose);
        return crow::response{"successful"};
    });

    app.port(23333).multithreaded().run();

}
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SysTimer_windows.h"

#include <intrin.h>

static ULONGLONG win_cpu_time() {
    FILETIME createTime;
    FILETIME exitTime;
    FILETIME usrTime;
    FILETIME sysTime;
    if (0 == GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &sysTime, &usrTime)) {
        return 0;
    }
    ULARGE_INTEGER start_cpu_sys;
    ULARGE_INTEGER start_cpu_usr;
    start_cpu_sys.LowPart  = sysTime.dwLowDateTime;
    start_cpu_sys.HighPart = sysTime.dwHighDateTime;
    start_cpu_usr.LowPart  = usrTime.dwLowDateTime;
    start_cpu_usr.HighPart = usrTime.dwHighDateTime;
    return start_cpu_sys.QuadPart + start_cpu_usr.QuadPart;
}

void SysTimer::startCpu() {
    fStartCpu = win_cpu_time();
}

double SysTimer::endCpu() {
    ULONGLONG end_cpu = win_cpu_time();
    return static_cast<double>(end_cpu - fStartCpu) / 10000.0L;
}

static void wall_timestamp(LARGE_INTEGER* now) {
    _ReadWriteBarrier();
    if (0 == ::QueryPerformanceCounter(now)) {
        now->QuadPart = 0;
    }
    _ReadWriteBarrier();
}

void SysTimer::startWall() {
    wall_timestamp(&fStartWall);
}

double SysTimer::endWall() {
    LARGE_INTEGER end_wall;
    wall_timestamp(&end_wall);

    LARGE_INTEGER ticks_elapsed;
    ticks_elapsed.QuadPart = end_wall.QuadPart - fStartWall.QuadPart;

    LARGE_INTEGER frequency;
    if (0 == ::QueryPerformanceFrequency(&frequency)) {
        return 0.0L;
    } else {
        return static_cast<double>(ticks_elapsed.QuadPart)
             / static_cast<double>(frequency.QuadPart)
             * 1000.0L;
    }
}
<commit_msg>revert timer changes<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SysTimer_windows.h"

static ULONGLONG win_cpu_time() {
    FILETIME createTime;
    FILETIME exitTime;
    FILETIME usrTime;
    FILETIME sysTime;
    if (0 == GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &sysTime, &usrTime)) {
        return 0;
    }
    ULARGE_INTEGER start_cpu_sys;
    ULARGE_INTEGER start_cpu_usr;
    start_cpu_sys.LowPart  = sysTime.dwLowDateTime;
    start_cpu_sys.HighPart = sysTime.dwHighDateTime;
    start_cpu_usr.LowPart  = usrTime.dwLowDateTime;
    start_cpu_usr.HighPart = usrTime.dwHighDateTime;
    return start_cpu_sys.QuadPart + start_cpu_usr.QuadPart;
}

void SysTimer::startWall() {
    if (0 == ::QueryPerformanceCounter(&fStartWall)) {
        fStartWall.QuadPart = 0;
    }
}
void SysTimer::startCpu() {
    fStartCpu = win_cpu_time();
}

double SysTimer::endCpu() {
    ULONGLONG end_cpu = win_cpu_time();
    return static_cast<double>(end_cpu - fStartCpu) / 10000.0L;
}
double SysTimer::endWall() {
    LARGE_INTEGER end_wall;
    if (0 == ::QueryPerformanceCounter(&end_wall)) {
        end_wall.QuadPart = 0;
    }

    LARGE_INTEGER ticks_elapsed;
    ticks_elapsed.QuadPart = end_wall.QuadPart - fStartWall.QuadPart;

    LARGE_INTEGER frequency;
    if (0 == ::QueryPerformanceFrequency(&frequency)) {
        return 0.0L;
    } else {
        return static_cast<double>(ticks_elapsed.QuadPart)
             / static_cast<double>(frequency.QuadPart)
             * 1000.0L;
    }
}
<|endoftext|>


<commit_before>//===========================================
//  Lumina-DE source code
//  Copyright (c) 2014, Susanne Jaeckel
//  Available under the 3-clause BSD license
//  See the LICENSE file for full details
//===========================================
#include "LBattery.h"
#include "LSession.h"

LBattery::LBattery(QWidget *parent, QString id, bool horizontal) : LPPlugin(parent, id, horizontal){
  iconOld = -1;
  //Setup the widget
  label = new QLabel(this);
    label->setScaledContents(true);
    //label->setAlignment(Qt::AlignCenter);
  this->layout()->addWidget(label);
  //Setup the timer
  timer = new QTimer();
  timer->setInterval(5000); //update every 5 seconds
  connect(timer,SIGNAL(timeout()), this, SLOT(updateBattery()) );
  timer->start();
  QTimer::singleShot(0,this,SLOT(OrientationChange()) ); //update the sizing/icon
}

LBattery::~LBattery(){
  timer->stop();
  delete timer;
}

void LBattery::updateBattery(bool force){
  // Get current state of charge
  //QStringList result = LUtils::getCmdOutput("/usr/sbin/apm", QStringList() << "-al");
  int charge = LOS::batteryCharge(); //result.at(1).toInt();
//qDebug() << "1: " << result.at(0).toInt() << " 2: " << result.at(1).toInt();
  int icon = -1;
  if (charge > 90) { icon = 4; }
  else if (charge > 70) { icon = 3; }
  else if (charge > 20) { icon = 2; }
  else if (charge > 5) { icon = 1; }
  else if (charge > 0 ) { icon = 0; }
  if(LOS::batteryIsCharging()){ icon = icon+10; }
  //icon = icon + result.at(0).toInt() * 10;
  if (icon != iconOld || force) {
    switch (icon) {
      case 0:
        label->setPixmap( LXDG::findIcon("battery-caution", "").pixmap(label->size()) );
        break;
      case 1:
        label->setPixmap( LXDG::findIcon("battery-040", "").pixmap(label->size()) );
        break;
      case 2:
        label->setPixmap( LXDG::findIcon("battery-060", "").pixmap(label->size()) );
        break;
      case 3:
        label->setPixmap( LXDG::findIcon("battery-080", "").pixmap(label->size()) );
        break;
      case 4:
        label->setPixmap( LXDG::findIcon("battery-100", "").pixmap(label->size()) );
        break;
      case 10:
        label->setPixmap( LXDG::findIcon("battery-charging-caution", "").pixmap(label->size()) );
        break;
      case 11:
        label->setPixmap( LXDG::findIcon("battery-charging-040", "").pixmap(label->size()) );
        break;
      case 12:
        label->setPixmap( LXDG::findIcon("battery-charging-060", "").pixmap(label->size()) );
        break;
      case 13:
        label->setPixmap( LXDG::findIcon("battery-charging-080", "").pixmap(label->size()) );
        break;
      case 14:
        label->setPixmap( LXDG::findIcon("battery-charging", "").pixmap(label->size()) );
        break;
      default:
        label->setPixmap( LXDG::findIcon("battery-missing", "").pixmap(label->size()) );
        break;
    }
    if(icon<iconOld && icon==0){
      //Play some audio warning chime when
      LSession::handle()->playAudioFile(LOS::LuminaShare()+"low-battery.ogg");
    }
    if(icon==0){ label->setStyleSheet("background: red;"); }
    else{ label->setStyleSheet("background: transparent;"); }
    iconOld = icon;

  }
  //Now update the display
  QString tt;
  //Make sure the tooltip can be properly translated as necessary (Ken Moore 5/9/14)
  if(icon > 9 && icon < 15){ tt = QString(tr("%1 % (Charging)")).arg(QString::number(charge)); }
  else{ tt = QString( tr("%1 % (%2 Remaining)") ).arg(QString::number(charge), getRemainingTime() ); }
  label->setToolTip(tt);
}

QString LBattery::getRemainingTime(){
  int secs = LOS::batterySecondsLeft();
  if(secs < 0){ return "??"; }
  QString rem; //remaining
  if(secs > 3600){
    int hours = secs/3600;
    rem.append( QString::number(hours)+"h ");
    secs = secs - (hours*3600);
  }
  if(secs > 60){
    int min = secs/60;
    rem.append( QString::number(min)+"m ");
    secs = secs - (min*60);
  }
  if(secs > 0){
    rem.append(QString::number(secs)+"s");
  }
  return rem;
}
<commit_msg>Fix up the stylesheet for the battery monitor. Don't change any properties other than the background color based on battery level.<commit_after>//===========================================
//  Lumina-DE source code
//  Copyright (c) 2014, Susanne Jaeckel
//  Available under the 3-clause BSD license
//  See the LICENSE file for full details
//===========================================
#include "LBattery.h"
#include "LSession.h"

LBattery::LBattery(QWidget *parent, QString id, bool horizontal) : LPPlugin(parent, id, horizontal){
  iconOld = -1;
  //Setup the widget
  label = new QLabel(this);
    label->setScaledContents(true);
    //label->setAlignment(Qt::AlignCenter);
  this->layout()->addWidget(label);
  //Setup the timer
  timer = new QTimer();
  timer->setInterval(5000); //update every 5 seconds
  connect(timer,SIGNAL(timeout()), this, SLOT(updateBattery()) );
  timer->start();
  QTimer::singleShot(0,this,SLOT(OrientationChange()) ); //update the sizing/icon
}

LBattery::~LBattery(){
  timer->stop();
  delete timer;
}

void LBattery::updateBattery(bool force){
  // Get current state of charge
  //QStringList result = LUtils::getCmdOutput("/usr/sbin/apm", QStringList() << "-al");
  int charge = LOS::batteryCharge(); //result.at(1).toInt();
//qDebug() << "1: " << result.at(0).toInt() << " 2: " << result.at(1).toInt();
  int icon = -1;
  if (charge > 90) { icon = 4; }
  else if (charge > 70) { icon = 3; }
  else if (charge > 20) { icon = 2; }
  else if (charge > 5) { icon = 1; }
  else if (charge > 0 ) { icon = 0; }
  if(LOS::batteryIsCharging()){ icon = icon+10; }
  //icon = icon + result.at(0).toInt() * 10;
  if (icon != iconOld || force) {
    switch (icon) {
      case 0:
        label->setPixmap( LXDG::findIcon("battery-caution", "").pixmap(label->size()) );
        break;
      case 1:
        label->setPixmap( LXDG::findIcon("battery-040", "").pixmap(label->size()) );
        break;
      case 2:
        label->setPixmap( LXDG::findIcon("battery-060", "").pixmap(label->size()) );
        break;
      case 3:
        label->setPixmap( LXDG::findIcon("battery-080", "").pixmap(label->size()) );
        break;
      case 4:
        label->setPixmap( LXDG::findIcon("battery-100", "").pixmap(label->size()) );
        break;
      case 10:
        label->setPixmap( LXDG::findIcon("battery-charging-caution", "").pixmap(label->size()) );
        break;
      case 11:
        label->setPixmap( LXDG::findIcon("battery-charging-040", "").pixmap(label->size()) );
        break;
      case 12:
        label->setPixmap( LXDG::findIcon("battery-charging-060", "").pixmap(label->size()) );
        break;
      case 13:
        label->setPixmap( LXDG::findIcon("battery-charging-080", "").pixmap(label->size()) );
        break;
      case 14:
        label->setPixmap( LXDG::findIcon("battery-charging", "").pixmap(label->size()) );
        break;
      default:
        label->setPixmap( LXDG::findIcon("battery-missing", "").pixmap(label->size()) );
        break;
    }
    if(icon<iconOld && icon==0){
      //Play some audio warning chime when
      LSession::handle()->playAudioFile(LOS::LuminaShare()+"low-battery.ogg");
    }
    if(icon==0){ label->setStyleSheet("QLabel{ background: red;}"); }
    else{ label->setStyleSheet("QLabel{ background: transparent;}"); }
    iconOld = icon;

  }
  //Now update the display
  QString tt;
  //Make sure the tooltip can be properly translated as necessary (Ken Moore 5/9/14)
  if(icon > 9 && icon < 15){ tt = QString(tr("%1 % (Charging)")).arg(QString::number(charge)); }
  else{ tt = QString( tr("%1 % (%2 Remaining)") ).arg(QString::number(charge), getRemainingTime() ); }
  label->setToolTip(tt);
}

QString LBattery::getRemainingTime(){
  int secs = LOS::batterySecondsLeft();
  if(secs < 0){ return "??"; }
  QString rem; //remaining
  if(secs > 3600){
    int hours = secs/3600;
    rem.append( QString::number(hours)+"h ");
    secs = secs - (hours*3600);
  }
  if(secs > 60){
    int min = secs/60;
    rem.append( QString::number(min)+"m ");
    secs = secs - (min*60);
  }
  if(secs > 0){
    rem.append(QString::number(secs)+"s");
  }
  return rem;
}
<|endoftext|>


<commit_before>/*
 * Copyright(c) Records For Living, Inc. 2004-2011.  All rights reserved
 */
#include	"Stroika/Foundation/StroikaPreComp.h"

#include	<iostream>
#include	<sstream>

#include	"Stroika/Foundation/Containers/VectorUtils.h"
#include	"Stroika/Foundation/DataExchangeFormat/JSON/Reader.h"
#include	"Stroika/Foundation/DataExchangeFormat/JSON/Writer.h"
#include	"Stroika/Foundation/Debug/Assertions.h"
#include	"Stroika/Foundation/Memory/VariantValue.h"

#include	"../TestHarness/TestHarness.h"

using	namespace	Stroika::Foundation;

using	Memory::VariantValue;

/*
 * Validating JSON parse results:
 *		http://json.parser.online.fr/
 */

namespace	{
	void	CheckMatchesExpected_WRITER_ (const VariantValue& v, const string& expected)
		{
			stringstream	out;
			DataExchangeFormat::JSON::PrettyPrint (v, out);
			string x = out.str ();
			for (string::size_type i = 0; i < min (x.length (), expected.length ()); ++i) {
				if (x[i] != expected[i]) {
					VerifyTestResult (false);
				}
			}
			VerifyTestResult (out.str () == expected);
		}

	void	DoRegressionTests_Writer_ ()
		{
			{
				VariantValue	v1 = L"hello world";
				CheckMatchesExpected_WRITER_ (v1, "\"hello world\"");
			}
			{
				VariantValue	v1 =	3;
				CheckMatchesExpected_WRITER_ (v1, "3");
			}
			{
				VariantValue	v1 =	4.7f;
				CheckMatchesExpected_WRITER_ (v1, "4.7");
			}
			{
				// array
				vector<VariantValue>	v;
				v.push_back (3);
				v.push_back (7);
				v.push_back (L"cookie");
				VariantValue	v1 =	v;
				CheckMatchesExpected_WRITER_ (v1, "[\n    3,\n    7,\n    \"cookie\"\n]");
			}
			{
				// object
				map<wstring,VariantValue>	v;
				v[L"Arg1"] = 32;
				v[L"Arg2"] = L"Cookies";
				v[L"Arg3"] = Containers::mkV<VariantValue> (19);
				VariantValue	v1 =	v;
				CheckMatchesExpected_WRITER_ (v1, "{\n    \"Arg1\" : 32,\n    \"Arg2\" : \"Cookies\",\n    \"Arg3\" : [\n        19\n    ]\n}");
			}
		}
}

namespace	{
	void	CheckMatchesExpected_READER_ (const string& v, const VariantValue& expected)
		{
			stringstream	tmp;
			tmp << v;
			VariantValue	v1	=	DataExchangeFormat::JSON::Reader (tmp);
			VerifyTestResult (v1.GetType () == expected.GetType ());
			VerifyTestResult (v1 == expected);
		}

	void	DoRegressionTests_Reader_ ()
		{
			{
				VariantValue	v1 = L"hello world";
				CheckMatchesExpected_READER_ ("\"hello world\"", v1);
			}
			{
				VariantValue	v1 =	3;
				CheckMatchesExpected_READER_ ("3", v1);
			}
			{
				VariantValue	v1 =	4.7f;
				CheckMatchesExpected_READER_ ("4.7", v1);
			}
			{
				// array
				vector<VariantValue>	v;
				v.push_back (3);
				v.push_back (7);
				v.push_back (L"cookie");
				VariantValue	v1 =	v;
				CheckMatchesExpected_READER_ ("[\n    3,\n    7,\n    \"cookie\"\n]", v1);
			}
			{
				// object
				map<wstring,VariantValue>	v;
				v[L"Arg1"] = 32;
				v[L"Arg2"] = L"Cookies";
				v[L"Arg3"] = Containers::mkV<VariantValue> (19);
				VariantValue	v1 =	v;
				CheckMatchesExpected_READER_ ("{\n    \"Arg1\" : 32,\n    \"Arg2\" : \"Cookies\",\n    \"Arg3\" : [\n        19\n    ]\n}", v1);
			}
			{
				// Bug found in another JSON reader (sent me by Ryan - 2011-07-27)
				const	string	kExample	=	"{\"nav_items\":[{\"main_link\":{\"href\":\"/about/index.html\",\"text\":\"Who We Are\"},\"column\":[{\"link_list\":[{},{\"header\":{\"href\":\"/about/company-management.html\",\"text\":\"Management\"}},{\"header\":{\"href\":\"/about/mission-statement.html\",\"text\":\"Mission\"}},{\"header\":{\"href\":\"/about/company-history.html\",\"text\":\" History\"}},{\"header\":{\"href\":\"/about/headquarters.html\",\"text\":\"Corporate Headquarters\"}},{\"header\":{\"href\":\"/about/diversity.html\",\"text\":\"Diversity\"}},{\"header\":{\"href\":\"/about/supplier-diversity.html\",\"text\":\"Supplier Diversity\"}}]}]},{\"main_link\":{\"href\":\"http://investor.compuware.com\",\"text\":\"Investor Relations\"}},{\"main_link\":{\"href\":\"/about/newsroom.html\",\"text\":\"News Room\"},\"column\":[{\"link_list\":[{},{\"header\":{\"href\":\"/about/analyst-reports\",\"text\":\"Analyst Reports\"}},{\"header\":{\"href\":\"/about/awards-recognition.html\",\"text\":\"Awards and Recognition\"}},{\"header\":{\"href\":\"/about/blogs.html\",\"text\":\"Blog Home\"}},{\"header\":{\"href\":\"/about/press-analyst-contacts.html\",\"text\":\"Contact Us\"}},{\"header\":{\"href\":\"/about/customers.html\",\"text\":\"Customers\"}},{\"header\":{\"href\":\"/about/press-mentions\",\"text\":\"Press Mentions\"}},{\"header\":{\"href\":\"/about/press-releases\",\"text\":\"Press Releases\"}},{\"header\":{\"href\":\"/about/press-resources.html\",\"text\":\"Press Resources\"}}]}]},{\"main_link\":{\"href\":\"#top\",\"text\":\"Sponsorships\"},\"column\":[{\"link_list\":[{\"header\":{\"href\":\"/about/lemans-sponsorship.html\",\"text\":\"Le Mans\"}},{\"header\":{\"href\":\"/about/nhl-sponsorship.html\",\"text\":\"NHL\"}},{}]}]},{\"main_link\":{\"href\":\"/about/community-involvement.html\",\"text\":\"Community Involvement\"},\"column\":[{\"link_list\":[{\"header\":{\"href\":\"http://communityclicks.compuware.com\",\"text\":\"Community Clicks Blog\"}},{\"header\":{\"href\":\"javascript:securenav('/forms/grant-eligibility-form.html')\",\"text\":\"Grant Eligibility Form\"}},{}]}]},{\"main_link\":{\"href\":\"/government/\",\"text\":\"Government\"}}]}";
				stringstream	tmp;
				tmp << kExample;
				VariantValue	v1	=	DataExchangeFormat::JSON::Reader (tmp);
				VerifyTestResult (v1.GetType () == VariantValue::eMap);
			}

		}
}

namespace	{

	void	DoRegressionTests_ ()
		{
			DoRegressionTests_Writer_ ();
			DoRegressionTests_Reader_ ();
		}
}

#if qOnlyOneMain
extern  int TestJSON ()
#else
int main (int argc, const char* argv[])
#endif
{
	Stroika::TestHarness::Setup ();
	Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
	return EXIT_SUCCESS;
}

<commit_msg>tweeked VariantValue regression tests (comparing for equal - now must avoid comparing 4.7f with 4.7 (effectively) for Eqaulity)<commit_after>/*
 * Copyright(c) Records For Living, Inc. 2004-2011.  All rights reserved
 */
#include	"Stroika/Foundation/StroikaPreComp.h"

#include	<iostream>
#include	<sstream>

#include	"Stroika/Foundation/Containers/VectorUtils.h"
#include	"Stroika/Foundation/DataExchangeFormat/JSON/Reader.h"
#include	"Stroika/Foundation/DataExchangeFormat/JSON/Writer.h"
#include	"Stroika/Foundation/Debug/Assertions.h"
#include	"Stroika/Foundation/Memory/VariantValue.h"

#include	"../TestHarness/TestHarness.h"

using	namespace	Stroika::Foundation;

using	Memory::VariantValue;

/*
 * Validating JSON parse results:
 *		http://json.parser.online.fr/
 */

namespace	{
	void	CheckMatchesExpected_WRITER_ (const VariantValue& v, const string& expected)
		{
			stringstream	out;
			DataExchangeFormat::JSON::PrettyPrint (v, out);
			string x = out.str ();
			for (string::size_type i = 0; i < min (x.length (), expected.length ()); ++i) {
				if (x[i] != expected[i]) {
					VerifyTestResult (false);
				}
			}
			VerifyTestResult (out.str () == expected);
		}

	void	DoRegressionTests_Writer_ ()
		{
			{
				VariantValue	v1 = L"hello world";
				CheckMatchesExpected_WRITER_ (v1, "\"hello world\"");
			}
			{
				VariantValue	v1 =	3;
				CheckMatchesExpected_WRITER_ (v1, "3");
			}
			{
				VariantValue	v1 =	4.7;
				CheckMatchesExpected_WRITER_ (v1, "4.7");
			}
			{
				// array
				vector<VariantValue>	v;
				v.push_back (3);
				v.push_back (7);
				v.push_back (L"cookie");
				VariantValue	v1 =	v;
				CheckMatchesExpected_WRITER_ (v1, "[\n    3,\n    7,\n    \"cookie\"\n]");
			}
			{
				// object
				map<wstring,VariantValue>	v;
				v[L"Arg1"] = 32;
				v[L"Arg2"] = L"Cookies";
				v[L"Arg3"] = Containers::mkV<VariantValue> (19);
				VariantValue	v1 =	v;
				CheckMatchesExpected_WRITER_ (v1, "{\n    \"Arg1\" : 32,\n    \"Arg2\" : \"Cookies\",\n    \"Arg3\" : [\n        19\n    ]\n}");
			}
		}
}

namespace	{
	void	CheckMatchesExpected_READER_ (const string& v, const VariantValue& expected)
		{
			stringstream	tmp;
			tmp << v;
			VariantValue	v1	=	DataExchangeFormat::JSON::Reader (tmp);
			VerifyTestResult (v1.GetType () == expected.GetType ());
			VerifyTestResult (v1 == expected);
		}

	void	DoRegressionTests_Reader_ ()
		{
			{
				VariantValue	v1 = L"hello world";
				CheckMatchesExpected_READER_ ("\"hello world\"", v1);
			}
			{
				VariantValue	v1 =	3;
				CheckMatchesExpected_READER_ ("3", v1);
			}
			{
				VariantValue	v1 =	4.7;
				CheckMatchesExpected_READER_ ("4.7", v1);
			}
			{
				// array
				vector<VariantValue>	v;
				v.push_back (3);
				v.push_back (7);
				v.push_back (L"cookie");
				VariantValue	v1 =	v;
				CheckMatchesExpected_READER_ ("[\n    3,\n    7,\n    \"cookie\"\n]", v1);
			}
			{
				// object
				map<wstring,VariantValue>	v;
				v[L"Arg1"] = 32;
				v[L"Arg2"] = L"Cookies";
				v[L"Arg3"] = Containers::mkV<VariantValue> (19);
				VariantValue	v1 =	v;
				CheckMatchesExpected_READER_ ("{\n    \"Arg1\" : 32,\n    \"Arg2\" : \"Cookies\",\n    \"Arg3\" : [\n        19\n    ]\n}", v1);
			}
			{
				// Bug found in another JSON reader (sent me by Ryan - 2011-07-27)
				const	string	kExample	=	"{\"nav_items\":[{\"main_link\":{\"href\":\"/about/index.html\",\"text\":\"Who We Are\"},\"column\":[{\"link_list\":[{},{\"header\":{\"href\":\"/about/company-management.html\",\"text\":\"Management\"}},{\"header\":{\"href\":\"/about/mission-statement.html\",\"text\":\"Mission\"}},{\"header\":{\"href\":\"/about/company-history.html\",\"text\":\" History\"}},{\"header\":{\"href\":\"/about/headquarters.html\",\"text\":\"Corporate Headquarters\"}},{\"header\":{\"href\":\"/about/diversity.html\",\"text\":\"Diversity\"}},{\"header\":{\"href\":\"/about/supplier-diversity.html\",\"text\":\"Supplier Diversity\"}}]}]},{\"main_link\":{\"href\":\"http://investor.compuware.com\",\"text\":\"Investor Relations\"}},{\"main_link\":{\"href\":\"/about/newsroom.html\",\"text\":\"News Room\"},\"column\":[{\"link_list\":[{},{\"header\":{\"href\":\"/about/analyst-reports\",\"text\":\"Analyst Reports\"}},{\"header\":{\"href\":\"/about/awards-recognition.html\",\"text\":\"Awards and Recognition\"}},{\"header\":{\"href\":\"/about/blogs.html\",\"text\":\"Blog Home\"}},{\"header\":{\"href\":\"/about/press-analyst-contacts.html\",\"text\":\"Contact Us\"}},{\"header\":{\"href\":\"/about/customers.html\",\"text\":\"Customers\"}},{\"header\":{\"href\":\"/about/press-mentions\",\"text\":\"Press Mentions\"}},{\"header\":{\"href\":\"/about/press-releases\",\"text\":\"Press Releases\"}},{\"header\":{\"href\":\"/about/press-resources.html\",\"text\":\"Press Resources\"}}]}]},{\"main_link\":{\"href\":\"#top\",\"text\":\"Sponsorships\"},\"column\":[{\"link_list\":[{\"header\":{\"href\":\"/about/lemans-sponsorship.html\",\"text\":\"Le Mans\"}},{\"header\":{\"href\":\"/about/nhl-sponsorship.html\",\"text\":\"NHL\"}},{}]}]},{\"main_link\":{\"href\":\"/about/community-involvement.html\",\"text\":\"Community Involvement\"},\"column\":[{\"link_list\":[{\"header\":{\"href\":\"http://communityclicks.compuware.com\",\"text\":\"Community Clicks Blog\"}},{\"header\":{\"href\":\"javascript:securenav('/forms/grant-eligibility-form.html')\",\"text\":\"Grant Eligibility Form\"}},{}]}]},{\"main_link\":{\"href\":\"/government/\",\"text\":\"Government\"}}]}";
				stringstream	tmp;
				tmp << kExample;
				VariantValue	v1	=	DataExchangeFormat::JSON::Reader (tmp);
				VerifyTestResult (v1.GetType () == VariantValue::eMap);
			}

		}
}

namespace	{

	void	DoRegressionTests_ ()
		{
			DoRegressionTests_Writer_ ();
			DoRegressionTests_Reader_ ();
		}
}

#if qOnlyOneMain
extern  int TestJSON ()
#else
int main (int argc, const char* argv[])
#endif
{
	Stroika::TestHarness::Setup ();
	Stroika::TestHarness::PrintPassOrFail (DoRegressionTests_);
	return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>/*
 * timer.c
 *
 * Created: 1/6/2013 6:54:53 PM
 *  Author: Collin Kidder
 */

#include "timer.h"

volatile int8_t tickReady;
volatile int8_t AgingTimer;

volatile void due_timer_interrupt();

/*
Make the timer0 interrupt every specified number of microseconds
*/
void setupTimer(long microSeconds) {
	//Setup timer 0 to operate
  //sam3x timer routine wants frequency instead of microseconds so a conversion is necessary
  uint32_t freq = 1000000ul / microSeconds;
  startTimer3(freq, due_timer_interrupt);
}

volatile void due_timer_interrupt() {
  tickReady = true;
  AgingTimer++;
}
<commit_msg>Updated to use a different branch of the DueTimer library<commit_after>/*
 * timer.c
 *
 * Created: 1/6/2013 6:54:53 PM
 *  Author: Collin Kidder
 */

#include "timer.h"

volatile int8_t tickReady;
volatile int8_t AgingTimer;

void due_timer_interrupt();

/*
Make the timer0 interrupt every specified number of microseconds
*/
void setupTimer(long microSeconds) {
	//Setup timer 0 to operate
  //sam3x timer routine wants frequency instead of microseconds so a conversion is necessary
  uint32_t freq = 1000000ul / microSeconds;
  Timer3.setFrequency(freq).attachInterrupt(due_timer_interrupt).start();
  //startTimer3(freq, due_timer_interrupt);
}

void due_timer_interrupt() {
  tickReady = true;
  AgingTimer++;
}
<|endoftext|>