<commit_before>#include <stdio.h>
#include "allocore/io/al_App.hpp"

namespace al{
//______________________________________________________________________________

Viewpoint::Viewpoint(const Pose& transform)
:	mViewport(0,0,0,0),
	mParentTransform(NULL),
	mAnchorX(0), mAnchorY(0), mStretchX(1), mStretchY(1),
	mLens(NULL), mClearColor(NULL)
{}

Viewpoint& Viewpoint::anchor(float ax, float ay){
	mAnchorX=ax; mAnchorY=ay; return *this;
}

Viewpoint& Viewpoint::stretch(float sx, float sy){
	mStretchX=sx; mStretchY=sy; return *this;
}

Frustumd Viewpoint::frustum() const {
	Frustumd fr;
	lens().frustum(fr, worldTransform(), viewport().aspect());
	return fr;
}

void Viewpoint::onParentResize(int w, int h){
	mViewport.l = w * anchorX();
	mViewport.b = h * anchorY();
	mViewport.w = w * stretchX();
	mViewport.h = h * stretchY();
}

//______________________________________________________________________________

ViewpointWindow::ViewpointWindow(){
	init();
}

ViewpointWindow::ViewpointWindow(
	const Dim& dims,
	const std::string title,
	double fps,
	DisplayMode mode
){
	init();
	create(dims, title, fps, mode);
}

bool ViewpointWindow::onResize(int w, int h){
	//printf("ViewpointWindow onResize: %d %d\n", dw, dh);
	Viewpoints::iterator iv = mViewpoints.begin();

	while(iv != mViewpoints.end()){
		(*iv)->onParentResize(w, h);
		++iv;
		//printf("%g %g %g %g\n", vp.viewport().l, vp.viewport().b, vp.viewport().w, vp.viewport().h);
	}

	mResized = true;

	return true;
}

ViewpointWindow& ViewpointWindow::add(Viewpoint& v){
	mViewpoints.push_back(&v);

	// If the window is already created, then we need to manually update the
	// Viewpoint. Otherwise, this happens through ViewpointWindow::onResize().
	if(created()){
		v.onParentResize(width(), height());
	}
	return *this;
}

void ViewpointWindow::init(){
	append(mStandardKeyControls);
}

//______________________________________________________________________________

struct SceneInputHandler : public InputEventHandler{
	ViewpointWindow& win;
	App& app;

	SceneInputHandler(ViewpointWindow& w, App& a): win(w), app(a){}

	bool onKeyDown(const Keyboard& k){
		app.onKeyDown(win, k);
		switch(k.key()){
			case Keyboard::TAB:
				app.stereo().stereo(!app.stereo().stereo());
				return false;
			default:;
		}
		return true;
	}
	bool onKeyUp(const Keyboard& k){ app.onKeyUp(win,k); return true;}
	bool onMouseDown(const Mouse& m){ app.onMouseDown(win,m); return true;}
	bool onMouseUp(const Mouse& m){ app.onMouseUp(win,m); return true;}
	bool onMouseDrag(const Mouse& m){ app.onMouseDrag(win,m); return true;}
	bool onMouseMove(const Mouse& m){ app.onMouseMove(win,m); return true;}
};

// attached to each ViewpointWindow
struct SceneWindowHandler : public WindowEventHandler{
	ViewpointWindow& win;
	App& app;

	SceneWindowHandler(ViewpointWindow& w, App& a): win(w), app(a){}

	bool onCreate(){

		// Enable color material to simplify cases where materials are not used
		// explicitly (e.g., only mesh colors are used).
		glEnable(GL_COLOR_MATERIAL);
		glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

		app.onCreate(win);
		return true;
	}
	bool onDestroy(){ app.onDestroy(win); return true; }
	bool onResize(int dw, int dh){ app.onResize(win, dw,dh); return true; }

	virtual bool onFrame();
};

bool SceneWindowHandler::onFrame(){

	if(app.clockNav() == &win){
		double dt = win.spfActual();
		app.nav().smooth(::pow(0.0001, dt));
		app.nav().step(dt * 40./*FPS*/);
		//app.nav().smooth(0.8);
		//app.nav().step(1.);
	}

	app.navDraw() = app.nav();
	app.navDraw().quat().normalize();

	if(app.clockAnimate() == &win){
		app.onAnimate(win.spfActual());
	}

	Graphics& g = app.graphics();
	g.depthTesting(true);
	g.lighting(false);

	struct DrawFunc : public Drawable {
		App& app;
		Viewpoint& vp;
		ViewpointWindow& win;

		DrawFunc(App& a, Viewpoint& v, ViewpointWindow& w)
		:	app(a), vp(v), win(w){}

		void onDraw(Graphics& g){
			g.pushMatrix(g.MODELVIEW);
			for(auto& drawCall : win.drawCalls()) drawCall();
			app.onDraw(g,vp);
			g.popMatrix(g.MODELVIEW);
		}
	};

	ViewpointWindow::Viewpoints::const_iterator iv = win.viewpoints().begin();

	// Draw scene for each viewpoint (pose + viewport)
	for(; iv != win.viewpoints().end(); ++iv){
		Viewpoint& vp = *(*iv);

		// if no camera, set to default scene camera
		if(!vp.hasLens()) vp.lens(app.lens());
		const Lens& lens = vp.lens();
		Stereographic& stereo = app.stereo();

		Color defaultClearColor = stereo.clearColor();
		if(!vp.hasClearColor()){
			vp.clearColor(const_cast<Color&>(stereo.clearColor()));
		}
		else{
			stereo.clearColor(vp.clearColor());
		}

		bool doClear = (stereo.clearColor().a >= 1) || win.mResized;

		// Interpolate between existing color buffer and background color
		if(!doClear){

			// TODO: Not 100% sure what to do with depth buffer.
			// If we don't clear it, then if depth testing is enabled we won't
			// get the expected overdraw blend. By clearing it, we effectively
			// "flatten" the previous scene.
			glEnable(GL_SCISSOR_TEST);
			glScissor(vp.viewport().l, vp.viewport().b, vp.viewport().w, vp.viewport().h);
			glClear(GL_DEPTH_BUFFER_BIT);
			glDisable(GL_SCISSOR_TEST);

			if(stereo.clearColor().a != 0){
				glViewport(vp.viewport().l, vp.viewport().b, vp.viewport().w, vp.viewport().h);
				g.pushMatrix(g.MODELVIEW);
				g.loadIdentity();
				g.pushMatrix(g.PROJECTION);
				g.loadIdentity();
					Mesh& mesh = g.mesh();
					mesh.reset();
					mesh.primitive(Graphics::TRIANGLE_STRIP);
					mesh.color(stereo.clearColor());
					mesh.vertex(-1,-1);
					mesh.vertex( 1,-1);
					mesh.vertex(-1, 1);
					mesh.vertex( 1, 1);
					g.blendTrans();
					//glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
						g.draw(mesh);
					g.blendOff();
				g.popMatrix();
				g.popMatrix(g.MODELVIEW);
			}
		}

		DrawFunc drawFunc(app, vp, win);
		stereo.draw(g, lens, vp.worldTransform(), vp.viewport(), drawFunc, doClear);
		stereo.clearColor(defaultClearColor);
	}

	win.mResized = false;

	return true;
}

App::App()
:	mName(""),
	mNavControl(mNav),
	mClockAnimate(0), mClockNav(0),
	mOSCRecv(12001, "", 0.001),
	mOSCSend(12000, "bossanova.mat.ucsb.edu", 0)
{}

App::~App(){
	// delete factory objects
	for(unsigned i=0; i<mFacWindows.size(); ++i){
		delete mFacWindows[i];
	}
	for(unsigned i=0; i<mFacViewpoints.size(); ++i){
		delete mFacViewpoints[i];
	}

	if(oscSend().opened() && !name().empty()) sendDisconnect();
}

static void AppAudioCB(AudioIOData& io){
	App& app = io.user<App>();
	//int numFrames = io.framesPerBuffer();

	//w.mNavMaster.velScale(4);
	//w.mNavMaster.step(io.secondsPerBuffer());
	if(app.clockNav() == &app.audioIO()){
		app.nav().smooth(0.95);
		app.nav().step(1./4);
	}
	//app.mListeners[0]->pose(app.nav());

	if(app.clockAnimate() == &app.audioIO()){
		app.onAnimate(io.secondsPerBuffer());
	}

	io.frame(0);
	app.onSound(app.audioIO());

	//app.mAudioScene.encode(numFrames, io.framesPerSecond());
	//app.mAudioScene.render(&io.out(0,0), numFrames);
	//printf("%f\n", io.out(0,0));
}

void App::initAudio(
	double audioRate, int audioBlockSize,
	int audioOutputs, int audioInputs
){
	mAudioIO.callback = AppAudioCB;
	mAudioIO.user(this);
	mAudioIO.framesPerSecond(audioRate);
	mAudioIO.framesPerBuffer(audioBlockSize);
	mAudioIO.channelsOut(audioOutputs);
	mAudioIO.channelsIn(audioInputs);
//	mAudioScene(3,2, audioBlockSize);
//	mListeners.push_back(mAudioScene.createListener(2));
//	mListeners[0]->speakerPos(0,0, -45);
//	mListeners[0]->speakerPos(1,1,  45);
}

ViewpointWindow * App::initWindow(
	const Window::Dim& dims,
	const std::string title,
	double fps,
	Window::DisplayMode mode,
	int flags
){
	//ViewpointWindow * win = new ViewpointWindow(dims, title, fps, mode);

	ViewpointWindow * win = new ViewpointWindow;
	win->dimensions(dims);
	win->title(title);
	win->fps(fps);
	win->displayMode(mode);

	mFacViewpoints.push_back(new Viewpoint);

	int last = mFacViewpoints.size()-1;
	{
		Viewpoint& vp = *mFacViewpoints[last];
		vp.parentTransform(nav().transformed());
		win->add(vp);
	}

	mFacWindows.push_back(win);
	add(*win);
	return win;
}

App& App::add(ViewpointWindow& win){

	win.append(mNavControl);
	win.append(*new SceneWindowHandler(win, *this));
	win.append(*new SceneInputHandler(win, *this));
	mWindows.push_back(&win);

	// TODO: for now, first window will clock master Nav
	if(mWindows.size() == 1){
		mClockNav = mWindows[0];
	}
	return *this;
}

void App::start(){
	if(!clockAnimate() && !mWindows.empty()){
		clockAnimate(mWindows[0]);
	}
	if(usingAudio()) mAudioIO.start();
	if(oscSend().opened() && !name().empty()) sendHandshake();

//	// factories OKAY
//	for(unsigned i=0; i<mFacViewpoints.size(); ++i)
//		printf("%p\n", mFacViewpoints[i].parentTransform());
//
//	// window pointers OKAY
//	for(unsigned j=0; j<windows().size(); ++j){
//		ViewpointWindow& w = *windows()[j];
//		for(unsigned i=0; i<w.viewpoints().size(); ++i){
//			Viewpoint& vp = *w.viewpoints()[i];
//			printf("%d,%d: %p\n", j,i, vp.parentTransform());
//			printf("anchor : %g %g\n", vp.anchorX(), vp.anchorY());
//			printf("stretch: %g %g\n", vp.stretchX(), vp.stretchY());
//		}
//	}

	/* Add a handler to close i/o when Main exits.
	This is done to ensure members of derived classes are not accessed by i/o
	threads after they have been destructed! We must stop all i/o before any
	destructors are called.
	*/
	struct AppMainHandler : Main::Handler{
		App& app;
		AppMainHandler(App& a): app(a){}

		void onExit(){
			//printf("App exiting\n");
			app.audioIO().close();

			// Ensures windows get destroyed in case the user does, for example,
			// a hard exit with exit(0).
			for(unsigned i=0; i<app.mFacWindows.size(); ++i){
				app.mFacWindows[i]->destroy();
			}

			// ctrl-q will destroy all windows before stopping the main loop
			// so we call onExit last
			app.onExit();
		}
	} appMainHandler(*this);

	Main::get().add(appMainHandler);

	if(windows().size()){
		// create the windows
		for(auto& w : windows()) w->create();

		// start the main loop
		Main::get().start();
	}
	else{
		printf("\nPress 'enter' to quit...\n"); getchar();
		// ensure exit handler gets called
		Main::get().exit();
	}
}

void App::sendHandshake(){
	oscSend().send("/handshake", name(), oscRecv().port());
}

void App::sendDisconnect(){
	oscSend().send("/disconnectApplication", name());
}

bool App::usingAudio() const {
	return audioIO().callback == AppAudioCB;
}

/// Get a pick ray from screen space coordinates
 // i.e. use mouse xy
Rayd App::getPickRay(const ViewpointWindow& w, int screenX, int screenY){
  Rayd r;
  Vec3d screenPos;
  screenPos.x = (screenX*1. / w.width()) * 2. - 1.;
  screenPos.y = ((w.height() - screenY)*1. / w.height()) * 2. - 1.;
  screenPos.z = -1.;
  Vec3d worldPos = stereo().unproject(screenPos);
  r.origin().set(worldPos);

  screenPos.z = 1.;
  worldPos = stereo().unproject(screenPos);
  r.direction().set( worldPos );
  r.direction() -= r.origin();
  r.direction().normalize();
  return r;
}

//class Clocked{
//public:
//	virtual void onUpdate(double dt){}
//protected:
//};
//
//
//class Clock{
//public:
//
//	void add(Clocked& v){ mListeners.push_back(&v); }
//
//	void update(double dt){
//		Listeners::iterator it = mListeners.begin();
//		while(it != mListeners.end()){
//			(*it)->onUpdate(dt);
//		}
//	}
//
//protected:
//	typedef std::vector<Clocked *> Listeners;
//	Listeners mListeners;
//};

} // al::

<commit_msg>App: set window title from app name<commit_after>#include <stdio.h>
#include "allocore/io/al_App.hpp"

namespace al{
//______________________________________________________________________________

Viewpoint::Viewpoint(const Pose& transform)
:	mViewport(0,0,0,0),
	mParentTransform(NULL),
	mAnchorX(0), mAnchorY(0), mStretchX(1), mStretchY(1),
	mLens(NULL), mClearColor(NULL)
{}

Viewpoint& Viewpoint::anchor(float ax, float ay){
	mAnchorX=ax; mAnchorY=ay; return *this;
}

Viewpoint& Viewpoint::stretch(float sx, float sy){
	mStretchX=sx; mStretchY=sy; return *this;
}

Frustumd Viewpoint::frustum() const {
	Frustumd fr;
	lens().frustum(fr, worldTransform(), viewport().aspect());
	return fr;
}

void Viewpoint::onParentResize(int w, int h){
	mViewport.l = w * anchorX();
	mViewport.b = h * anchorY();
	mViewport.w = w * stretchX();
	mViewport.h = h * stretchY();
}

//______________________________________________________________________________

ViewpointWindow::ViewpointWindow(){
	init();
}

ViewpointWindow::ViewpointWindow(
	const Dim& dims,
	const std::string title,
	double fps,
	DisplayMode mode
){
	init();
	create(dims, title, fps, mode);
}

bool ViewpointWindow::onResize(int w, int h){
	//printf("ViewpointWindow onResize: %d %d\n", dw, dh);
	Viewpoints::iterator iv = mViewpoints.begin();

	while(iv != mViewpoints.end()){
		(*iv)->onParentResize(w, h);
		++iv;
		//printf("%g %g %g %g\n", vp.viewport().l, vp.viewport().b, vp.viewport().w, vp.viewport().h);
	}

	mResized = true;

	return true;
}

ViewpointWindow& ViewpointWindow::add(Viewpoint& v){
	mViewpoints.push_back(&v);

	// If the window is already created, then we need to manually update the
	// Viewpoint. Otherwise, this happens through ViewpointWindow::onResize().
	if(created()){
		v.onParentResize(width(), height());
	}
	return *this;
}

void ViewpointWindow::init(){
	append(mStandardKeyControls);
}

//______________________________________________________________________________

struct SceneInputHandler : public InputEventHandler{
	ViewpointWindow& win;
	App& app;

	SceneInputHandler(ViewpointWindow& w, App& a): win(w), app(a){}

	bool onKeyDown(const Keyboard& k){
		app.onKeyDown(win, k);
		switch(k.key()){
			case Keyboard::TAB:
				app.stereo().stereo(!app.stereo().stereo());
				return false;
			default:;
		}
		return true;
	}
	bool onKeyUp(const Keyboard& k){ app.onKeyUp(win,k); return true;}
	bool onMouseDown(const Mouse& m){ app.onMouseDown(win,m); return true;}
	bool onMouseUp(const Mouse& m){ app.onMouseUp(win,m); return true;}
	bool onMouseDrag(const Mouse& m){ app.onMouseDrag(win,m); return true;}
	bool onMouseMove(const Mouse& m){ app.onMouseMove(win,m); return true;}
};

// attached to each ViewpointWindow
struct SceneWindowHandler : public WindowEventHandler{
	ViewpointWindow& win;
	App& app;

	SceneWindowHandler(ViewpointWindow& w, App& a): win(w), app(a){}

	bool onCreate(){

		// Enable color material to simplify cases where materials are not used
		// explicitly (e.g., only mesh colors are used).
		glEnable(GL_COLOR_MATERIAL);
		glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

		app.onCreate(win);
		return true;
	}
	bool onDestroy(){ app.onDestroy(win); return true; }
	bool onResize(int dw, int dh){ app.onResize(win, dw,dh); return true; }

	virtual bool onFrame();
};

bool SceneWindowHandler::onFrame(){

	if(app.clockNav() == &win){
		double dt = win.spfActual();
		app.nav().smooth(::pow(0.0001, dt));
		app.nav().step(dt * 40./*FPS*/);
		//app.nav().smooth(0.8);
		//app.nav().step(1.);
	}

	app.navDraw() = app.nav();
	app.navDraw().quat().normalize();

	if(app.clockAnimate() == &win){
		app.onAnimate(win.spfActual());
	}

	Graphics& g = app.graphics();
	g.depthTesting(true);
	g.lighting(false);

	struct DrawFunc : public Drawable {
		App& app;
		Viewpoint& vp;
		ViewpointWindow& win;

		DrawFunc(App& a, Viewpoint& v, ViewpointWindow& w)
		:	app(a), vp(v), win(w){}

		void onDraw(Graphics& g){
			g.pushMatrix(g.MODELVIEW);
			for(auto& drawCall : win.drawCalls()) drawCall();
			app.onDraw(g,vp);
			g.popMatrix(g.MODELVIEW);
		}
	};

	ViewpointWindow::Viewpoints::const_iterator iv = win.viewpoints().begin();

	// Draw scene for each viewpoint (pose + viewport)
	for(; iv != win.viewpoints().end(); ++iv){
		Viewpoint& vp = *(*iv);

		// if no camera, set to default scene camera
		if(!vp.hasLens()) vp.lens(app.lens());
		const Lens& lens = vp.lens();
		Stereographic& stereo = app.stereo();

		Color defaultClearColor = stereo.clearColor();
		if(!vp.hasClearColor()){
			vp.clearColor(const_cast<Color&>(stereo.clearColor()));
		}
		else{
			stereo.clearColor(vp.clearColor());
		}

		bool doClear = (stereo.clearColor().a >= 1) || win.mResized;

		// Interpolate between existing color buffer and background color
		if(!doClear){

			// TODO: Not 100% sure what to do with depth buffer.
			// If we don't clear it, then if depth testing is enabled we won't
			// get the expected overdraw blend. By clearing it, we effectively
			// "flatten" the previous scene.
			glEnable(GL_SCISSOR_TEST);
			glScissor(vp.viewport().l, vp.viewport().b, vp.viewport().w, vp.viewport().h);
			glClear(GL_DEPTH_BUFFER_BIT);
			glDisable(GL_SCISSOR_TEST);

			if(stereo.clearColor().a != 0){
				glViewport(vp.viewport().l, vp.viewport().b, vp.viewport().w, vp.viewport().h);
				g.pushMatrix(g.MODELVIEW);
				g.loadIdentity();
				g.pushMatrix(g.PROJECTION);
				g.loadIdentity();
					Mesh& mesh = g.mesh();
					mesh.reset();
					mesh.primitive(Graphics::TRIANGLE_STRIP);
					mesh.color(stereo.clearColor());
					mesh.vertex(-1,-1);
					mesh.vertex( 1,-1);
					mesh.vertex(-1, 1);
					mesh.vertex( 1, 1);
					g.blendTrans();
					//glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
						g.draw(mesh);
					g.blendOff();
				g.popMatrix();
				g.popMatrix(g.MODELVIEW);
			}
		}

		DrawFunc drawFunc(app, vp, win);
		stereo.draw(g, lens, vp.worldTransform(), vp.viewport(), drawFunc, doClear);
		stereo.clearColor(defaultClearColor);
	}

	win.mResized = false;

	return true;
}

App::App()
:	mName(""),
	mNavControl(mNav),
	mClockAnimate(0), mClockNav(0),
	mOSCRecv(12001, "", 0.001),
	mOSCSend(12000, "bossanova.mat.ucsb.edu", 0)
{}

App::~App(){
	// delete factory objects
	for(unsigned i=0; i<mFacWindows.size(); ++i){
		delete mFacWindows[i];
	}
	for(unsigned i=0; i<mFacViewpoints.size(); ++i){
		delete mFacViewpoints[i];
	}

	if(oscSend().opened() && !name().empty()) sendDisconnect();
}

static void AppAudioCB(AudioIOData& io){
	App& app = io.user<App>();
	//int numFrames = io.framesPerBuffer();

	//w.mNavMaster.velScale(4);
	//w.mNavMaster.step(io.secondsPerBuffer());
	if(app.clockNav() == &app.audioIO()){
		app.nav().smooth(0.95);
		app.nav().step(1./4);
	}
	//app.mListeners[0]->pose(app.nav());

	if(app.clockAnimate() == &app.audioIO()){
		app.onAnimate(io.secondsPerBuffer());
	}

	io.frame(0);
	app.onSound(app.audioIO());

	//app.mAudioScene.encode(numFrames, io.framesPerSecond());
	//app.mAudioScene.render(&io.out(0,0), numFrames);
	//printf("%f\n", io.out(0,0));
}

void App::initAudio(
	double audioRate, int audioBlockSize,
	int audioOutputs, int audioInputs
){
	mAudioIO.callback = AppAudioCB;
	mAudioIO.user(this);
	mAudioIO.framesPerSecond(audioRate);
	mAudioIO.framesPerBuffer(audioBlockSize);
	mAudioIO.channelsOut(audioOutputs);
	mAudioIO.channelsIn(audioInputs);
//	mAudioScene(3,2, audioBlockSize);
//	mListeners.push_back(mAudioScene.createListener(2));
//	mListeners[0]->speakerPos(0,0, -45);
//	mListeners[0]->speakerPos(1,1,  45);
}

ViewpointWindow * App::initWindow(
	const Window::Dim& dims,
	const std::string title,
	double fps,
	Window::DisplayMode mode,
	int flags
){
	auto& win = *new ViewpointWindow;
	win.dimensions(dims);
	if(title.empty()){ // if no title, use app name, if any
		if(!name().empty()) win.title(name());
	} else {
		win.title(title);
	}

	win.fps(fps);
	win.displayMode(mode);

	auto& newVP = *new Viewpoint;
	mFacViewpoints.push_back(&newVP);
	newVP.parentTransform(nav().transformed());
	win.add(newVP);

	mFacWindows.push_back(&win);
	add(win);
	return &win;
}

App& App::add(ViewpointWindow& win){

	win.append(mNavControl);
	win.append(*new SceneWindowHandler(win, *this));
	win.append(*new SceneInputHandler(win, *this));
	mWindows.push_back(&win);

	// TODO: for now, first window will clock master Nav
	if(mWindows.size() == 1){
		mClockNav = mWindows[0];
	}
	return *this;
}

void App::start(){
	if(!clockAnimate() && !mWindows.empty()){
		clockAnimate(mWindows[0]);
	}
	if(usingAudio()) mAudioIO.start();
	if(oscSend().opened() && !name().empty()) sendHandshake();

//	// factories OKAY
//	for(unsigned i=0; i<mFacViewpoints.size(); ++i)
//		printf("%p\n", mFacViewpoints[i].parentTransform());
//
//	// window pointers OKAY
//	for(unsigned j=0; j<windows().size(); ++j){
//		ViewpointWindow& w = *windows()[j];
//		for(unsigned i=0; i<w.viewpoints().size(); ++i){
//			Viewpoint& vp = *w.viewpoints()[i];
//			printf("%d,%d: %p\n", j,i, vp.parentTransform());
//			printf("anchor : %g %g\n", vp.anchorX(), vp.anchorY());
//			printf("stretch: %g %g\n", vp.stretchX(), vp.stretchY());
//		}
//	}

	/* Add a handler to close i/o when Main exits.
	This is done to ensure members of derived classes are not accessed by i/o
	threads after they have been destructed! We must stop all i/o before any
	destructors are called.
	*/
	struct AppMainHandler : Main::Handler{
		App& app;
		AppMainHandler(App& a): app(a){}

		void onExit(){
			//printf("App exiting\n");
			app.audioIO().close();

			// Ensures windows get destroyed in case the user does, for example,
			// a hard exit with exit(0).
			for(unsigned i=0; i<app.mFacWindows.size(); ++i){
				app.mFacWindows[i]->destroy();
			}

			// ctrl-q will destroy all windows before stopping the main loop
			// so we call onExit last
			app.onExit();
		}
	} appMainHandler(*this);

	Main::get().add(appMainHandler);

	if(windows().size()){
		// create the windows
		for(auto& w : windows()) w->create();

		// start the main loop
		Main::get().start();
	}
	else{
		printf("\nPress 'enter' to quit...\n"); getchar();
		// ensure exit handler gets called
		Main::get().exit();
	}
}

void App::sendHandshake(){
	oscSend().send("/handshake", name(), oscRecv().port());
}

void App::sendDisconnect(){
	oscSend().send("/disconnectApplication", name());
}

bool App::usingAudio() const {
	return audioIO().callback == AppAudioCB;
}

/// Get a pick ray from screen space coordinates
 // i.e. use mouse xy
Rayd App::getPickRay(const ViewpointWindow& w, int screenX, int screenY){
  Rayd r;
  Vec3d screenPos;
  screenPos.x = (screenX*1. / w.width()) * 2. - 1.;
  screenPos.y = ((w.height() - screenY)*1. / w.height()) * 2. - 1.;
  screenPos.z = -1.;
  Vec3d worldPos = stereo().unproject(screenPos);
  r.origin().set(worldPos);

  screenPos.z = 1.;
  worldPos = stereo().unproject(screenPos);
  r.direction().set( worldPos );
  r.direction() -= r.origin();
  r.direction().normalize();
  return r;
}

//class Clocked{
//public:
//	virtual void onUpdate(double dt){}
//protected:
//};
//
//
//class Clock{
//public:
//
//	void add(Clocked& v){ mListeners.push_back(&v); }
//
//	void update(double dt){
//		Listeners::iterator it = mListeners.begin();
//		while(it != mListeners.end()){
//			(*it)->onUpdate(dt);
//		}
//	}
//
//protected:
//	typedef std::vector<Clocked *> Listeners;
//	Listeners mListeners;
//};

} // al::

<|endoftext|>


<commit_before>#include "xchainer/check_backward.h"

#include <algorithm>
#include <functional>
#include <memory>
#include <sstream>
#include <vector>

#include <gtest/gtest.h>

#include "xchainer/array.h"
#include "xchainer/array_node.h"
#include "xchainer/backprop.h"
#include "xchainer/error.h"
#include "xchainer/gradient_check.h"
#include "xchainer/numeric.h"

namespace xchainer {
namespace {

Arrays BackwardGradients(std::function<Arrays(const Arrays&)> func, const Arrays& inputs, const Arrays& grad_outputs) {
    Arrays outputs = func(inputs);

    const int nout = outputs.size();
    for (int i = 0; i < nout; ++i) {
        outputs[i].mutable_node()->set_grad(grad_outputs[i]);
    }

    // TODO(hvy): Currently only supporting functions with single outputs, support any number of outputs instead
    if (outputs.size() > 1) {
        throw NotImplementedError("Number of inputs must match the number of epsilon");
    }
    Backward(outputs[0]);

    Arrays backward_grads;
    std::transform(inputs.begin(), inputs.end(), std::back_inserter(backward_grads), [](const Array& input) { return *input.grad(); });

    return backward_grads;
}

}  // namespace

void CheckBackwardComputation(std::function<Arrays(const Arrays&)> func, const Arrays& inputs, const Arrays& grad_outputs,
                              const Arrays& eps, float atol, float rtol) {
    const Arrays numerical_grads = CalculateNumericalGradient(func, inputs, grad_outputs, eps);
    const Arrays backward_grads = BackwardGradients(func, inputs, grad_outputs);
    assert(backward_grads.size() == numerical_grads.size());

    std::ostringstream failure_os;
    const int nin = backward_grads.size();
    for (int i = 0; i < nin; ++i) {
        if (!AllClose(backward_grads[i], numerical_grads[i], atol, rtol)) {
            failure_os << "Backward check failure on input " << i << " (Total inputs: " << inputs.size() << ")\n"
                       << "Atol: " << atol << "\n"
                       << "Rtol: " << rtol << "\n"
                       << "Eps (perturbation):\n"
                       << eps[i] << "\n"
                       << "Backward gradients:\n"
                       << backward_grads[i] << "\n"
                       << "Numerical gradients:\n"
                       << numerical_grads[i];
        }
    }

    // Do nothing if all backward-numerical gradient pairs were close, else generate a nonfatal failure
    std::string failure_message = failure_os.str();
    if (failure_message.size() > 0) {
        ADD_FAILURE() << failure_message;
    }
}

}  // namespace xchainer
<commit_msg>Fix failure caused by accessing nullopt<commit_after>#include "xchainer/check_backward.h"

#include <algorithm>
#include <functional>
#include <memory>
#include <sstream>
#include <vector>

#include <gtest/gtest.h>

#include "xchainer/array.h"
#include "xchainer/array_node.h"
#include "xchainer/backprop.h"
#include "xchainer/error.h"
#include "xchainer/gradient_check.h"
#include "xchainer/numeric.h"

namespace xchainer {
namespace {

using OptionalArrays = std::vector<nonstd::optional<Array>>;

OptionalArrays BackwardGradients(std::function<Arrays(const Arrays&)> func, const Arrays& inputs, const Arrays& grad_outputs) {
    Arrays outputs = func(inputs);

    const int nout = outputs.size();
    for (int i = 0; i < nout; ++i) {
        outputs[i].mutable_node()->set_grad(grad_outputs[i]);
    }

    // TODO(hvy): Currently only supporting functions with single outputs, support any number of outputs instead
    if (outputs.size() > 1) {
        throw NotImplementedError("Number of inputs must match the number of epsilon");
    }
    Backward(outputs[0]);

    OptionalArrays backward_grads;
    std::transform(inputs.begin(), inputs.end(), std::back_inserter(backward_grads), [](const Array& input) { return input.grad(); });

    return backward_grads;
}

}  // namespace

void CheckBackwardComputation(std::function<Arrays(const Arrays&)> func, const Arrays& inputs, const Arrays& grad_outputs,
                              const Arrays& eps, float atol, float rtol) {
    const Arrays numerical_grads = CalculateNumericalGradient(func, inputs, grad_outputs, eps);
    const OptionalArrays backward_grads = BackwardGradients(func, inputs, grad_outputs);
    assert(backward_grads.size() == numerical_grads.size());

    std::ostringstream failure_os;
    const int nin = backward_grads.size();
    for (int i = 0; i < nin; ++i) {
        if (backward_grads[i]) {  // All inputs do not necessarily require gradients
            if (!AllClose(*backward_grads[i], numerical_grads[i], atol, rtol)) {
                failure_os << "Backward check failure on input " << i << " (Total inputs: " << inputs.size() << ")\n"
                           << "Atol: " << atol << "\n"
                           << "Rtol: " << rtol << "\n"
                           << "Eps (perturbation):\n"
                           << eps[i] << "\n"
                           << "Backward gradients:\n"
                           << *backward_grads[i] << "\n"
                           << "Numerical gradients:\n"
                           << numerical_grads[i];
            }
        }
    }

    // Do nothing if all backward-numerical gradient pairs were close, else generate a nonfatal failure
    std::string failure_message = failure_os.str();
    if (failure_message.size() > 0) {
        ADD_FAILURE() << failure_message;
    }
}

}  // namespace xchainer
<|endoftext|>


<commit_before>class RMM {
	class client {
//		class taskhint {};
//		class taskupdate {};
	};
	class common {
		class ExMP {};
//		class failSafeLS {};
//		class isAlive {};
//		class landForTime {};
//		class supplyDrop {};
	};
	class server {
//		class spawnVehiclePath {};
//		class taskDefend {};
	};
};
class CRB {
	class common {
		class selectRandomBias {};
	};
	class server {
//		class initLocations {};
	};
};
class BIS {
	class server {
		class dynocreate {};
	};
};
<commit_msg>Removed redundant functions.<commit_after>class RMM {
	class common {
		class ExMP {};
	};
};
class CRB {
	class common {
		class selectRandomBias {};
	};
};
class BIS {
	class server {
		class dynocreate {};
	};
};
<|endoftext|>


<commit_before>#include "robot_interface/gripper.h"

#include <iostream>
#include <string>

using namespace baxter_core_msgs;
using namespace std;

Gripper::Gripper(std::string _limb, bool _use_robot) :
                 rnh(_limb), limb(_limb), use_robot(_use_robot), first_run(true), prop_set(false),
                 spinner(1), cmd_sequence(0), cmd_sender(ros::this_node::getName())
{
    if (not use_robot) return;

    // create a publisher for the gripper's commands
    pub_cmd = rnh.advertise<EndEffectorCommand>( "/robot/end_effector/" +
                                                _limb + "_gripper/command", 1);

    // create a subscriber to the gripper's properties
    sub_prop  = rnh.subscribe("/robot/end_effector/" + _limb + "_gripper/properties",
                                   SUBSCRIBER_BUFFER, &Gripper::gripperPropCb, this);

    // create a subscriber to the gripper's state
    sub_state = rnh.subscribe("/robot/end_effector/" + _limb + "_gripper/state",
                                  SUBSCRIBER_BUFFER, &Gripper::gripperCb, this);

    //Initially all the interesting properties of the state are unknown
    EndEffectorState init_state;
    init_state.calibrated = EndEffectorState::STATE_UNKNOWN;
    init_state.enabled    = EndEffectorState::STATE_UNKNOWN;
    init_state.error      = EndEffectorState::STATE_UNKNOWN;
    init_state.gripping   = EndEffectorState::STATE_UNKNOWN;
    init_state.missed     = EndEffectorState::STATE_UNKNOWN;
    init_state.ready      = EndEffectorState::STATE_UNKNOWN;
    init_state.moving     = EndEffectorState::STATE_UNKNOWN;

    setGripperState(init_state);

    spinner.start();

    // sleep to wait for the publisher to be ready
    ros::Duration(0.5).sleep();

    // set the gripper parameters to their defaults
    setParameters("", true);
}

void Gripper::setGripperState(const baxter_core_msgs::EndEffectorState& _state)
{
    std::lock_guard<std::mutex> lock(mutex_state);
    state = _state;
}

baxter_core_msgs::EndEffectorState Gripper::getGripperState()
{
    std::lock_guard<std::mutex> lock(mutex_state);
    return state;
}

void Gripper::setGripperProperties(const baxter_core_msgs::EndEffectorProperties& _properties)
{
    std::lock_guard<std::mutex> lock(mutex_properties);
    properties = _properties;
}

baxter_core_msgs::EndEffectorProperties Gripper::getGripperProperties()
{
    std::lock_guard<std::mutex> lock(mutex_properties);
    return properties;
}

void Gripper::gripperCb(const EndEffectorState &msg)
{
    setGripperState(msg);

    if (first_run)
    {
        // wait for the properties to be set before issuing calibration command
        while(not prop_set)
        {
            ros::Duration(0.05).sleep();
        }

        if (!is_calibrated())
        {
            ROS_INFO("[%s_gripper] Calibrating the gripper..",
                                    getGripperLimb().c_str());
            calibrate();
        }

        first_run=false;
    }
}

void Gripper::gripperPropCb(const EndEffectorProperties &msg)
{
    setGripperProperties(msg);
    prop_set = true;

    // shut down the subscriber after the properties are set once
    // because these properties do not change
    sub_prop.shutdown();
}

void Gripper::setParameters(std::string _parameters, bool _defaults)
{
    if(_defaults)
    {
        parameters = validParameters();
    }
    else
    {
        if(_parameters != "")
        {
            // some error checking needed here to prevent invalid parameters being set
            // this would involve converting between strings and dict-type objects
            // and comparing to valid_parameters' keys
            parameters = _parameters;
        }
    }
    // send the parameters to the gripper
    std::string param_cmd = EndEffectorCommand::CMD_CONFIGURE;
    command(param_cmd, false, 0.0, parameters);
}

std::string Gripper::validParameters()
{
    std::string valid;

    if(type() == "electric")
    {
        valid = "{\"velocity\" : 50.0, \"moving_force\" : 40.0, \"holding_force\" : 30.0, \"dead_zone\" : 5.0}";
    }
    else if(type() == "suction")
    {
        valid = "{\"vacuum_sensor_threshold\" : 18.0, \"blow_off_seconds\" : 0.4}";
    }
    else
    {
        valid = "";
    }

    return valid;
}

void Gripper::calibrate(bool _block, double _timeout)
{
    if(type() != "electric") { capabilityWarning("calibrate"); }

    std::string calibrate_cmd = EndEffectorCommand::CMD_CALIBRATE;
    command(calibrate_cmd, _block, _timeout, "");
}

void Gripper::clearCalibration()
{
    if(type() != "electric") { capabilityWarning("clearCalibration"); }

    std::string clear_calibrate_cmd = EndEffectorCommand::CMD_CLEAR_CALIBRATION;
    command(clear_calibrate_cmd, false, 0.0, "");
}

bool Gripper::reboot()
{
    // give a warning if not capable and return
    if(type() != "electric")
    {
        capabilityWarning("reboot");
        return false;
    }

    ROS_INFO("Rebooting %s gripper of type %s. Please wait...",
             getGripperLimb().c_str(), type().c_str());

    std::string reboot_cmd = EndEffectorCommand::CMD_REBOOT;
    command(reboot_cmd, true, 5.0, "");

    ROS_INFO("Reboot complete");
    return true;
}

int Gripper::get_id()
{
    return getGripperState().id;
}

bool Gripper::is_enabled()
{
    return getGripperState().enabled==EndEffectorState::STATE_TRUE;
}

bool Gripper::is_calibrated()
{
    return getGripperState().calibrated==EndEffectorState::STATE_TRUE;
}

bool Gripper::is_ready_to_grip()
{
    return getGripperState().ready==EndEffectorState::STATE_TRUE;
}

bool Gripper::has_error()
{
    return getGripperState().error==EndEffectorState::STATE_TRUE;
}

bool Gripper::is_sucking()
{
    if(type() != "suction") { capabilityWarning("is_sucking"); }

    // ROS_INFO("force is: %g\n",getGripperState().force);
    return getGripperState().position<80;
}

bool Gripper::is_gripping()
{
    return getGripperState().gripping==EndEffectorState::STATE_TRUE;
}

bool Gripper::hasForce()
{
    return getGripperProperties().controls_force == true;
}

bool Gripper::hasPosition()
{
    return getGripperProperties().controls_position == true;
}

bool Gripper::open(bool _block, double _timeout)
{
    if(type() == "electric")
    {
        return commandPosition(100.0, _block, _timeout);
    }
    else if (type() == "suction")
    {
        // check if the gripper is already not sucking
        if(not is_sucking())
        {
            ROS_WARN("%s gripper of type %s is already open",
                      getGripperLimb().c_str(), type().c_str());

            return false;
        }

        return stop(_block, _timeout);
    }
    else
    {
        // give a warning if not capable and return
        capabilityWarning("open");
        return false;
    }
}

bool Gripper::close(bool _block, double _timeout)
{
    if(type() == "electric")
    {
        return commandPosition(0.0, _block, _timeout);
    }
    else if (type() == "suction")
    {
        // no checks here for is_sucking() so that the suction time may be extended as necessary
        return commandSuction(_block, _timeout);
    }
    else
    {
        // give a warning if not capable and return
        capabilityWarning("close");
        return false;
    }
}

bool Gripper::commandPosition(double _position, bool _block, double _timeout)
{
    // give a warning if not capable and return
    if(type() != "electric")
    {
        capabilityWarning("commandPosition");
        return false;
    }

    // calibrate the electric gripper if needed
    // do it in a blocking manner so that the gripper does not move before calibration
    if(not is_calibrated())
    {
        ROS_INFO("Calibrating gripper. Please wait...");
        calibrate(true, 3.0);
        ROS_INFO("Calibration complete");
    }

    // ensures that the gripper is positioned within physical limits
    if(_position >= 0.0 && _position <= 100.0)
    {
        ROS_DEBUG("Commanding position %g", _position);
        std::string position_cmd = EndEffectorCommand::CMD_GO;
        std::string position_args = "{\"position\": " +
                                     std::to_string(_position) + "}";

        return command(position_cmd, _block, _timeout, position_args);
    }
    else
    {
        ROS_WARN("%s gripper of type %s must have position between 0.0 and 100.0",
                                        getGripperLimb().c_str(), type().c_str());
        return false;
    }
}

bool Gripper::commandSuction(bool _block, double _timeout)
{
    // give a warning if not capable and return
    if(type() != "suction")
    {
        capabilityWarning("commandSuction");
        return false;
    }

    std::string suction_cmd = EndEffectorCommand::CMD_GO;
    std::string suction_args = "{\"grip_attempt_seconds\": " +
                                std::to_string(_timeout) + "}";

    return command(suction_cmd, _block, _timeout, suction_args);
}

bool Gripper::stop(bool _block, double _timeout)
{
    std::string stop_cmd;

    if(type() == "electric")
    {
        stop_cmd = EndEffectorCommand::CMD_STOP;
    }
    else if(type() == "suction")
    {
        stop_cmd = EndEffectorCommand::CMD_RELEASE;
    }
    else
    {
        // give a warning if not capable and return
        capabilityWarning("stop");
        return false;
    }

    return command(stop_cmd, _block, _timeout);
}

bool Gripper::command(std::string _cmd, bool _block,
                      double _timeout, std::string _args)
{
    EndEffectorCommand ee_cmd;
    ee_cmd.id = get_id();
    ee_cmd.command = _cmd;
    ee_cmd.sender = cmd_sender;
    ee_cmd.sequence = incCmdSeq();
    ee_cmd.args = "";
    if(_args != "")
    {
        ee_cmd.args = _args;
    }

    pub_cmd.publish(ee_cmd);

    if(_block)
    {
        ros::Duration timeout(_timeout);
        return wait(timeout);
    }

    return true;
}

void Gripper::capabilityWarning(std::string _function)
{
    ROS_WARN("%s gripper of type %s is not capable of %s",
              getGripperLimb().c_str(), type().c_str(), _function.c_str());
}

int Gripper::incCmdSeq()
{
    // prevents cmd_sequence from overflowing the integer limit
    cmd_sequence = (cmd_sequence % std::numeric_limits<int>::max()) + 1;
    return cmd_sequence;
}

std::string Gripper::type()
{
    int ui_code = (int) getGripperProperties().ui_type;

    if (ui_code == 1)
    {
        return "suction";
    }
    else if (ui_code == 2)
    {
        return "electric";
    }
    else
    {
        return "uninitialized";
    }
}

bool Gripper::wait(ros::Duration _timeout)
{
    // waits until the difference between the start and
    // current time catches up to the timeout
    ros::Rate r(100);
    ros::Time start = ros::Time::now();

    while(ros::ok())
    {
        ROS_DEBUG("Waiting...");
        if (ros::Time::now() - start > _timeout) { return true; };

        r.sleep();
    }

    return false;
}

Gripper::~Gripper()
{
    spinner.stop();
}
<commit_msg>[gripper] Increased number of parallel threads to 4 (up from 1)<commit_after>#include "robot_interface/gripper.h"

#include <iostream>
#include <string>

using namespace baxter_core_msgs;
using namespace std;

Gripper::Gripper(std::string _limb, bool _use_robot) :
                 rnh(_limb), limb(_limb), use_robot(_use_robot), first_run(true), prop_set(false),
                 spinner(4), cmd_sequence(0), cmd_sender(ros::this_node::getName())
{
    if (not use_robot) return;

    // create a publisher for the gripper's commands
    pub_cmd = rnh.advertise<EndEffectorCommand>( "/robot/end_effector/" +
                                                _limb + "_gripper/command", 1);

    // create a subscriber to the gripper's properties
    sub_prop  = rnh.subscribe("/robot/end_effector/" + _limb + "_gripper/properties",
                                   SUBSCRIBER_BUFFER, &Gripper::gripperPropCb, this);

    // create a subscriber to the gripper's state
    sub_state = rnh.subscribe("/robot/end_effector/" + _limb + "_gripper/state",
                                  SUBSCRIBER_BUFFER, &Gripper::gripperCb, this);

    //Initially all the interesting properties of the state are unknown
    EndEffectorState init_state;
    init_state.calibrated = EndEffectorState::STATE_UNKNOWN;
    init_state.enabled    = EndEffectorState::STATE_UNKNOWN;
    init_state.error      = EndEffectorState::STATE_UNKNOWN;
    init_state.gripping   = EndEffectorState::STATE_UNKNOWN;
    init_state.missed     = EndEffectorState::STATE_UNKNOWN;
    init_state.ready      = EndEffectorState::STATE_UNKNOWN;
    init_state.moving     = EndEffectorState::STATE_UNKNOWN;

    setGripperState(init_state);

    spinner.start();

    // sleep to wait for the publisher to be ready
    ros::Duration(0.5).sleep();

    // set the gripper parameters to their defaults
    setParameters("", true);
}

void Gripper::setGripperState(const baxter_core_msgs::EndEffectorState& _state)
{
    std::lock_guard<std::mutex> lock(mutex_state);
    state = _state;
}

baxter_core_msgs::EndEffectorState Gripper::getGripperState()
{
    std::lock_guard<std::mutex> lock(mutex_state);
    return state;
}

void Gripper::setGripperProperties(const baxter_core_msgs::EndEffectorProperties& _properties)
{
    std::lock_guard<std::mutex> lock(mutex_properties);
    properties = _properties;
}

baxter_core_msgs::EndEffectorProperties Gripper::getGripperProperties()
{
    std::lock_guard<std::mutex> lock(mutex_properties);
    return properties;
}

void Gripper::gripperCb(const EndEffectorState &msg)
{
    ROS_DEBUG("[%s_gripper] Received new state", getGripperLimb().c_str());
    setGripperState(msg);

    if (first_run)
    {
        // wait for the properties to be set before issuing calibration command
        while(not prop_set)
        {
            ros::Duration(0.05).sleep();
        }

        if (!is_calibrated())
        {
            ROS_INFO("[%s_gripper] Calibrating the gripper..",
                                    getGripperLimb().c_str());
            calibrate();
        }

        first_run=false;
    }
}

void Gripper::gripperPropCb(const EndEffectorProperties &msg)
{
    ROS_DEBUG("[%s_gripper] Received gripper properties", getGripperLimb().c_str());
    setGripperProperties(msg);
    prop_set = true;

    // shut down the subscriber after the properties are set once
    // because these properties do not change
    sub_prop.shutdown();
}

void Gripper::setParameters(std::string _parameters, bool _defaults)
{
    if(_defaults)
    {
        parameters = validParameters();
    }
    else
    {
        if(_parameters != "")
        {
            // some error checking needed here to prevent invalid parameters being set
            // this would involve converting between strings and dict-type objects
            // and comparing to valid_parameters' keys
            parameters = _parameters;
        }
    }
    // send the parameters to the gripper
    std::string param_cmd = EndEffectorCommand::CMD_CONFIGURE;
    command(param_cmd, false, 0.0, parameters);
}

std::string Gripper::validParameters()
{
    std::string valid;

    if(type() == "electric")
    {
        valid = "{\"velocity\" : 50.0, \"moving_force\" : 40.0, \"holding_force\" : 30.0, \"dead_zone\" : 5.0}";
    }
    else if(type() == "suction")
    {
        valid = "{\"vacuum_sensor_threshold\" : 18.0, \"blow_off_seconds\" : 0.4}";
    }
    else
    {
        valid = "";
    }

    return valid;
}

void Gripper::calibrate(bool _block, double _timeout)
{
    if(type() != "electric") { capabilityWarning("calibrate"); }

    std::string calibrate_cmd = EndEffectorCommand::CMD_CALIBRATE;
    command(calibrate_cmd, _block, _timeout, "");
}

void Gripper::clearCalibration()
{
    if(type() != "electric") { capabilityWarning("clearCalibration"); }

    std::string clear_calibrate_cmd = EndEffectorCommand::CMD_CLEAR_CALIBRATION;
    command(clear_calibrate_cmd, false, 0.0, "");
}

bool Gripper::reboot()
{
    // give a warning if not capable and return
    if(type() != "electric")
    {
        capabilityWarning("reboot");
        return false;
    }

    ROS_INFO("Rebooting %s gripper of type %s. Please wait...",
             getGripperLimb().c_str(), type().c_str());

    std::string reboot_cmd = EndEffectorCommand::CMD_REBOOT;
    command(reboot_cmd, true, 5.0, "");

    ROS_INFO("Reboot complete");
    return true;
}

int Gripper::get_id()
{
    return getGripperState().id;
}

bool Gripper::is_enabled()
{
    return getGripperState().enabled==EndEffectorState::STATE_TRUE;
}

bool Gripper::is_calibrated()
{
    return getGripperState().calibrated==EndEffectorState::STATE_TRUE;
}

bool Gripper::is_ready_to_grip()
{
    return getGripperState().ready==EndEffectorState::STATE_TRUE;
}

bool Gripper::has_error()
{
    return getGripperState().error==EndEffectorState::STATE_TRUE;
}

bool Gripper::is_sucking()
{
    if(type() != "suction") { capabilityWarning("is_sucking"); }

    // ROS_INFO("force is: %g\n",getGripperState().force);
    return getGripperState().position<80;
}

bool Gripper::is_gripping()
{
    return getGripperState().gripping==EndEffectorState::STATE_TRUE;
}

bool Gripper::hasForce()
{
    return getGripperProperties().controls_force == true;
}

bool Gripper::hasPosition()
{
    return getGripperProperties().controls_position == true;
}

bool Gripper::open(bool _block, double _timeout)
{
    if(type() == "electric")
    {
        return commandPosition(100.0, _block, _timeout);
    }
    else if (type() == "suction")
    {
        // check if the gripper is already not sucking
        if(not is_sucking())
        {
            ROS_WARN("%s gripper of type %s is already open",
                      getGripperLimb().c_str(), type().c_str());

            return false;
        }

        return stop(_block, _timeout);
    }
    else
    {
        // give a warning if not capable and return
        capabilityWarning("open");
        return false;
    }
}

bool Gripper::close(bool _block, double _timeout)
{
    if(type() == "electric")
    {
        return commandPosition(0.0, _block, _timeout);
    }
    else if (type() == "suction")
    {
        // no checks here for is_sucking() so that the suction time may be extended as necessary
        return commandSuction(_block, _timeout);
    }
    else
    {
        // give a warning if not capable and return
        capabilityWarning("close");
        return false;
    }
}

bool Gripper::commandPosition(double _position, bool _block, double _timeout)
{
    // give a warning if not capable and return
    if(type() != "electric")
    {
        capabilityWarning("commandPosition");
        return false;
    }

    // calibrate the electric gripper if needed
    // do it in a blocking manner so that the gripper does not move before calibration
    if(not is_calibrated())
    {
        ROS_INFO("Calibrating gripper. Please wait...");
        calibrate(true, 3.0);
        ROS_INFO("Calibration complete");
    }

    // ensures that the gripper is positioned within physical limits
    if(_position >= 0.0 && _position <= 100.0)
    {
        ROS_DEBUG("Commanding position %g", _position);
        std::string position_cmd = EndEffectorCommand::CMD_GO;
        std::string position_args = "{\"position\": " +
                                     std::to_string(_position) + "}";

        return command(position_cmd, _block, _timeout, position_args);
    }
    else
    {
        ROS_WARN("%s gripper of type %s must have position between 0.0 and 100.0",
                                        getGripperLimb().c_str(), type().c_str());
        return false;
    }
}

bool Gripper::commandSuction(bool _block, double _timeout)
{
    // give a warning if not capable and return
    if(type() != "suction")
    {
        capabilityWarning("commandSuction");
        return false;
    }

    std::string suction_cmd = EndEffectorCommand::CMD_GO;
    std::string suction_args = "{\"grip_attempt_seconds\": " +
                                std::to_string(_timeout) + "}";

    return command(suction_cmd, _block, _timeout, suction_args);
}

bool Gripper::stop(bool _block, double _timeout)
{
    std::string stop_cmd;

    if(type() == "electric")
    {
        stop_cmd = EndEffectorCommand::CMD_STOP;
    }
    else if(type() == "suction")
    {
        stop_cmd = EndEffectorCommand::CMD_RELEASE;
    }
    else
    {
        // give a warning if not capable and return
        capabilityWarning("stop");
        return false;
    }

    return command(stop_cmd, _block, _timeout);
}

bool Gripper::command(std::string _cmd, bool _block,
                      double _timeout, std::string _args)
{
    EndEffectorCommand ee_cmd;
    ee_cmd.id = get_id();
    ee_cmd.command = _cmd;
    ee_cmd.sender = cmd_sender;
    ee_cmd.sequence = incCmdSeq();
    ee_cmd.args = "";
    if(_args != "")
    {
        ee_cmd.args = _args;
    }

    ROS_DEBUG("[%s_gripper] Publishing: %s", getGripperLimb().c_str(), _cmd.c_str());
    pub_cmd.publish(ee_cmd);

    if(_block)
    {
        ros::Duration timeout(_timeout);
        return wait(timeout);
    }

    return true;
}

void Gripper::capabilityWarning(std::string _function)
{
    ROS_WARN("%s gripper of type %s is not capable of %s",
              getGripperLimb().c_str(), type().c_str(), _function.c_str());
}

int Gripper::incCmdSeq()
{
    // prevents cmd_sequence from overflowing the integer limit
    cmd_sequence = (cmd_sequence % std::numeric_limits<int>::max()) + 1;
    return cmd_sequence;
}

std::string Gripper::type()
{
    int ui_code = (int) getGripperProperties().ui_type;

    if (ui_code == 1)
    {
        return "suction";
    }
    else if (ui_code == 2)
    {
        return "electric";
    }
    else
    {
        return "uninitialized";
    }
}

bool Gripper::wait(ros::Duration _timeout)
{
    // waits until the difference between the start and
    // current time catches up to the timeout
    ros::Rate r(100);
    ros::Time start = ros::Time::now();

    while(ros::ok())
    {
        ROS_DEBUG("Waiting...");
        if (ros::Time::now() - start > _timeout) { return true; };

        r.sleep();
    }

    return false;
}

Gripper::~Gripper()
{
    spinner.stop();
}
<|endoftext|>


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

/*
 * This file implements a test harness for using h2o with LibFuzzer.
 * See http://llvm.org/docs/LibFuzzer.html for more info.
 */

#define H2O_USE_EPOLL 1
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>

#include "h2o.h"
#include "h2o/http1.h"
#include "h2o/http2.h"
#include "h2o/url.h"
#include "h2o/memcached.h"

#if !defined(HTTP1) && !defined(HTTP2)
#error "Please defined one of HTTP1 or HTTP2"
#endif

#if defined(HTTP1) && defined(HTTP2)
#error "Please defined one of HTTP1 or HTTP2, but not both"
#endif

static h2o_globalconf_t config;
static h2o_context_t ctx;
static h2o_accept_ctx_t accept_ctx;
static int client_timeout_ms;
static char unix_listener[PATH_MAX];

/*
 * Registers a request handler with h2o
 */
static h2o_pathconf_t *register_handler(h2o_hostconf_t *hostconf, const char *path, int (*on_req)(h2o_handler_t *, h2o_req_t *))
{
    h2o_pathconf_t *pathconf = h2o_config_register_path(hostconf, path, 0);
    h2o_handler_t *handler = h2o_create_handler(pathconf, sizeof(*handler));
    handler->on_req = on_req;
    return pathconf;
}

/*
 * Request handler used for testing. Returns a basic "200 OK" response.
 */
static int chunked_test(h2o_handler_t *self, h2o_req_t *req)
{
    static h2o_generator_t generator = {NULL, NULL};

    if (!h2o_memis(req->method.base, req->method.len, H2O_STRLIT("GET")))
        return -1;

    h2o_iovec_t body = h2o_strdup(&req->pool, "hello world\n", SIZE_MAX);
    req->res.status = 200;
    req->res.reason = "OK";
    h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, NULL, H2O_STRLIT("text/plain"));
    h2o_start_response(req, &generator);
    h2o_send(req, &body, 1, H2O_SEND_STATE_FINAL);

    return 0;
}

/* copy from src to dst, return true if src has EOF */
static int drain(int fd)
{
    char buf[4096];
    ssize_t n;

    n = read(fd, buf, sizeof(buf));
    if (n <= 0) {
        return 1;
    }
    return 0;
}

/* A request sent from client thread to h2o server */
struct writer_thread_arg {
    char *buf;
    size_t len;
    int fd;
    h2o_barrier_t barrier;
};

/*
 * Reads writer_thread_arg from fd and stores to buf
 */
static void read_fully(int fd, char *buf, size_t len)
{
    int done = 0;
    while (len) {
        int ret;
        while ((ret = read(fd, buf + done, len)) == -1 && errno == EINTR)
            ;
        if (ret <= 0) {
            abort();
        }
        done += ret;
        len -= ret;
    }
}

/*
 * Writes the writer_thread_args at buf to fd
 */
static void write_fully(int fd, char *buf, size_t len, int abort_on_err)
{
    int done = 0;
    while (len) {
        int ret;
        while ((ret = write(fd, buf + done, len)) == -1 && errno == EINTR)
            ;
        if (ret <= 0) {
            if (abort_on_err)
                abort();
            else
                return;
        }
        done += ret;
        len -= ret;
    }
}

#define OK_RESP                                                                                \
    "HTTP/1.0 200 OK\r\n"                                                                                \
    "Connection: Close\r\n\r\nOk"
#define OK_RESP_LEN (sizeof(OK_RESP) - 1)

void *upstream_thread(void *arg)
{
    char *dirname = (char *)arg;
    char path[PATH_MAX];
    char rbuf[1 * 1024 * 1024];
    snprintf(path, sizeof(path), "/%s/_.sock", dirname);
    int sd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sd < 0) {
        abort();
    }
    struct sockaddr_un addr;
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
    if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
        abort();
    }
    if (listen(sd, 100) != 0) {
        abort();
    }

    while (1) {
        struct sockaddr_un caddr;
        socklen_t slen = 0;
        int cfs = accept(sd, (struct sockaddr *)&caddr, &slen);
        if (cfs < 0) {
            continue;
        }
        read(cfs, rbuf, sizeof(rbuf));
        write_fully(cfs, (char *)OK_RESP, OK_RESP_LEN, 0);
        close(cfs);
    }
}
/*
 * Thread: Loops writing fuzzed req to socket and then reading results back.
 * Acts as a client to h2o. *arg points to file descripter to read
 * writer_thread_args from.
 */
void *writer_thread(void *arg)
{
    int rfd = (long)arg;
    while (1) {
        int pos, sockinp, sockoutp, cnt, len;
        char *buf;
        struct writer_thread_arg *wta;

        /* Get fuzzed request */
        read_fully(rfd, (char *)&wta, sizeof(wta));

        pos = 0;
        sockinp = wta->fd;
        sockoutp = wta->fd;
        cnt = 0;
        buf = wta->buf;
        len = wta->len;

        /*
         * Send fuzzed req and read results until the socket is closed (or
         * something spurious happens)
         */
        while (cnt++ < 20 && (pos < len || sockinp >= 0)) {
#define MARKER "\n--MARK--\n"
            /* send 1 packet */
            if (pos < len) {
                char *p = (char *)memmem(buf + pos, len - pos, MARKER, sizeof(MARKER) - 1);
                if (p) {
                    int l = p - (buf + pos);
                    write(sockoutp, buf + pos, l);
                    pos += l;
                    pos += sizeof(MARKER) - 1;
                }
            } else {
                if (sockinp >= 0) {
                    shutdown(sockinp, SHUT_WR);
                }
            }

            /* drain socket */
            if (sockinp >= 0) {
                struct timeval timeo;
                fd_set rd;
                int n;

                FD_ZERO(&rd);
                FD_SET(sockinp, &rd);
                timeo.tv_sec = 0;
                timeo.tv_usec = client_timeout_ms * 1000;
                n = select(sockinp + 1, &rd, NULL, NULL, &timeo);
                if (n > 0 && FD_ISSET(sockinp, &rd) && drain(sockinp)) {
                    sockinp = -1;
                }
            }
        }
        close(wta->fd);
        h2o_barrier_wait(&wta->barrier);
        h2o_barrier_destroy(&wta->barrier);
        free(wta);
    }
}

/*
 * Creates socket pair and passes fuzzed req to a thread (the HTTP[/2] client)
 * for writing to the target h2o server. Returns the server socket fd.
 */
static int feeder(int sfd, char *buf, size_t len, h2o_barrier_t **barrier)
{
    int pair[2];
    struct writer_thread_arg *wta;

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
        return -1;

    wta = (struct writer_thread_arg *)malloc(sizeof(*wta));
    wta->fd = pair[0];
    wta->buf = buf;
    wta->len = len;
    h2o_barrier_init(&wta->barrier, 2);
    *barrier = &wta->barrier;

    write_fully(sfd, (char *)&wta, sizeof(wta), 1);
    return pair[1];
}

/*
 * Creates/connects socket pair for client/server interaction and passes
 * fuzzed request to client for sending.
 * Returns server socket fd.
 */
static int create_accepted(int sfd, char *buf, size_t len, h2o_barrier_t **barrier)
{
    int fd;
    h2o_socket_t *sock;
    struct timeval connected_at = *h2o_get_timestamp(&ctx, NULL, NULL);

    /* Create an HTTP[/2] client that will send the fuzzed request */
    fd = feeder(sfd, buf, len, barrier);
    if (fd < 0) {
        abort();
    }

    /* Pass the server socket to h2o and invoke request processing */
    sock = h2o_evloop_socket_create(ctx.loop, fd, H2O_SOCKET_FLAG_IS_ACCEPTED_CONNECTION);

#if defined(HTTP1)
    h2o_http1_accept(&accept_ctx, sock, connected_at);
#else
    h2o_http2_accept(&accept_ctx, sock, connected_at);
#endif

    return fd;
}

/*
 * Returns true if fd if valid. Used to determine when connection is closed.
 */
static int is_valid_fd(int fd)
{
    return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}

/*
 * Entry point for libfuzzer.
 * See http://llvm.org/docs/LibFuzzer.html for more info
 */
static int init_done;
static int job_queue[2];
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
    int c;
    h2o_loop_t *loop;
    h2o_hostconf_t *hostconf;
    pthread_t twriter;
    pthread_t tupstream;

    /*
     * Perform one-time initialization
     */
    if (!init_done) {
        const char *client_timeout_ms_str;
        static char tmpname[] = "/tmp/h2o-fuzz-XXXXXX";
        char *dirname;
        h2o_url_t upstream;
        signal(SIGPIPE, SIG_IGN);

        dirname = mkdtemp(tmpname);
        snprintf(unix_listener, sizeof(unix_listener), "http://[unix://%s/_.sock]/proxy", dirname);
        if ((client_timeout_ms_str = getenv("H2O_FUZZER_CLIENT_TIMEOUT")) != NULL)
            client_timeout_ms = atoi(client_timeout_ms_str);
        if (!client_timeout_ms)
            client_timeout_ms = 10;

        /* Create a single h2o host with multiple request handlers */
        h2o_config_init(&config);
        config.http2.idle_timeout = 10 * 1000;
        config.http1.req_timeout = 10 * 1000;
        config.proxy.io_timeout = 10 * 1000;
        h2o_proxy_config_vars_t proxy_config = {};
        proxy_config.io_timeout = 10 * 1000;
        hostconf = h2o_config_register_host(&config, h2o_iovec_init(H2O_STRLIT(unix_listener)), 65535);
        register_handler(hostconf, "/chunked-test", chunked_test);
        h2o_url_parse(unix_listener, strlen(unix_listener), &upstream);
        h2o_socketpool_t sockpool = {};
        h2o_socketpool_init_specific(&sockpool, SIZE_MAX /* FIXME */, &upstream, 1, NULL, NULL, NULL);
        h2o_socketpool_set_timeout(&sockpool, 2000);
        h2o_socketpool_set_ssl_ctx(&sockpool, NULL);
        h2o_proxy_register_reverse_proxy(h2o_config_register_path(hostconf, "/reproxy-test", 0), &proxy_config, &sockpool);
        h2o_file_register(h2o_config_register_path(hostconf, "/", 0), "./examples/doc_root", NULL, NULL, 0);

        loop = h2o_evloop_create();
        h2o_context_init(&ctx, loop, &config);

        accept_ctx.ctx = &ctx;
        accept_ctx.hosts = config.hosts;

        /* Create a thread to act as the HTTP client */
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, job_queue) != 0) {
            abort();
        }
        if (pthread_create(&twriter, NULL, writer_thread, (void *)(long)job_queue[1]) != 0) {
            abort();
        }
        if (pthread_create(&tupstream, NULL, upstream_thread, dirname) != 0) {
            abort();
        }
        init_done = 1;
    }

    /*
     * Pass fuzzed request to client thread and get h2o server socket for
     * use below
     */
    h2o_barrier_t *end;
    c = create_accepted(job_queue[0], (char *)Data, (size_t)Size, &end);
    if (c < 0) {
        goto Error;
    }

    /* Loop until the connection is closed by the client or server */
    while (is_valid_fd(c)) {
        h2o_evloop_run(ctx.loop, 10);
    }

    h2o_barrier_wait(end);
    return 0;
Error:
    return 1;
}
<commit_msg>fix fuzzer. should be correct.<commit_after>/*
 * Copyright (c) 2016 Fastly, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

/*
 * This file implements a test harness for using h2o with LibFuzzer.
 * See http://llvm.org/docs/LibFuzzer.html for more info.
 */

#define H2O_USE_EPOLL 1
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>

#include "h2o.h"
#include "h2o/http1.h"
#include "h2o/http2.h"
#include "h2o/url.h"
#include "h2o/memcached.h"

#if !defined(HTTP1) && !defined(HTTP2)
#error "Please defined one of HTTP1 or HTTP2"
#endif

#if defined(HTTP1) && defined(HTTP2)
#error "Please defined one of HTTP1 or HTTP2, but not both"
#endif

static h2o_globalconf_t config;
static h2o_context_t ctx;
static h2o_accept_ctx_t accept_ctx;
static int client_timeout_ms;
static char unix_listener[PATH_MAX];

/*
 * Registers a request handler with h2o
 */
static h2o_pathconf_t *register_handler(h2o_hostconf_t *hostconf, const char *path, int (*on_req)(h2o_handler_t *, h2o_req_t *))
{
    h2o_pathconf_t *pathconf = h2o_config_register_path(hostconf, path, 0);
    h2o_handler_t *handler = h2o_create_handler(pathconf, sizeof(*handler));
    handler->on_req = on_req;
    return pathconf;
}

/*
 * Request handler used for testing. Returns a basic "200 OK" response.
 */
static int chunked_test(h2o_handler_t *self, h2o_req_t *req)
{
    static h2o_generator_t generator = {NULL, NULL};

    if (!h2o_memis(req->method.base, req->method.len, H2O_STRLIT("GET")))
        return -1;

    h2o_iovec_t body = h2o_strdup(&req->pool, "hello world\n", SIZE_MAX);
    req->res.status = 200;
    req->res.reason = "OK";
    h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, NULL, H2O_STRLIT("text/plain"));
    h2o_start_response(req, &generator);
    h2o_send(req, &body, 1, H2O_SEND_STATE_FINAL);

    return 0;
}

/* copy from src to dst, return true if src has EOF */
static int drain(int fd)
{
    char buf[4096];
    ssize_t n;

    n = read(fd, buf, sizeof(buf));
    if (n <= 0) {
        return 1;
    }
    return 0;
}

/* A request sent from client thread to h2o server */
struct writer_thread_arg {
    char *buf;
    size_t len;
    int fd;
    h2o_barrier_t barrier;
};

/*
 * Reads writer_thread_arg from fd and stores to buf
 */
static void read_fully(int fd, char *buf, size_t len)
{
    int done = 0;
    while (len) {
        int ret;
        while ((ret = read(fd, buf + done, len)) == -1 && errno == EINTR)
            ;
        if (ret <= 0) {
            abort();
        }
        done += ret;
        len -= ret;
    }
}

/*
 * Writes the writer_thread_args at buf to fd
 */
static void write_fully(int fd, char *buf, size_t len, int abort_on_err)
{
    int done = 0;
    while (len) {
        int ret;
        while ((ret = write(fd, buf + done, len)) == -1 && errno == EINTR)
            ;
        if (ret <= 0) {
            if (abort_on_err)
                abort();
            else
                return;
        }
        done += ret;
        len -= ret;
    }
}

#define OK_RESP                                                                                \
    "HTTP/1.0 200 OK\r\n"                                                                                \
    "Connection: Close\r\n\r\nOk"
#define OK_RESP_LEN (sizeof(OK_RESP) - 1)

void *upstream_thread(void *arg)
{
    char *dirname = (char *)arg;
    char path[PATH_MAX];
    char rbuf[1 * 1024 * 1024];
    snprintf(path, sizeof(path), "/%s/_.sock", dirname);
    int sd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sd < 0) {
        abort();
    }
    struct sockaddr_un addr;
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
    if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
        abort();
    }
    if (listen(sd, 100) != 0) {
        abort();
    }

    while (1) {
        struct sockaddr_un caddr;
        socklen_t slen = 0;
        int cfs = accept(sd, (struct sockaddr *)&caddr, &slen);
        if (cfs < 0) {
            continue;
        }
        read(cfs, rbuf, sizeof(rbuf));
        write_fully(cfs, (char *)OK_RESP, OK_RESP_LEN, 0);
        close(cfs);
    }
}
/*
 * Thread: Loops writing fuzzed req to socket and then reading results back.
 * Acts as a client to h2o. *arg points to file descripter to read
 * writer_thread_args from.
 */
void *writer_thread(void *arg)
{
    int rfd = (long)arg;
    while (1) {
        int pos, sockinp, sockoutp, cnt, len;
        char *buf;
        struct writer_thread_arg *wta;

        /* Get fuzzed request */
        read_fully(rfd, (char *)&wta, sizeof(wta));

        pos = 0;
        sockinp = wta->fd;
        sockoutp = wta->fd;
        cnt = 0;
        buf = wta->buf;
        len = wta->len;

        /*
         * Send fuzzed req and read results until the socket is closed (or
         * something spurious happens)
         */
        while (cnt++ < 20 && (pos < len || sockinp >= 0)) {
#define MARKER "\n--MARK--\n"
            /* send 1 packet */
            if (pos < len) {
                char *p = (char *)memmem(buf + pos, len - pos, MARKER, sizeof(MARKER) - 1);
                if (p) {
                    int l = p - (buf + pos);
                    write(sockoutp, buf + pos, l);
                    pos += l;
                    pos += sizeof(MARKER) - 1;
                }
            } else {
                if (sockinp >= 0) {
                    shutdown(sockinp, SHUT_WR);
                }
            }

            /* drain socket */
            if (sockinp >= 0) {
                struct timeval timeo;
                fd_set rd;
                int n;

                FD_ZERO(&rd);
                FD_SET(sockinp, &rd);
                timeo.tv_sec = 0;
                timeo.tv_usec = client_timeout_ms * 1000;
                n = select(sockinp + 1, &rd, NULL, NULL, &timeo);
                if (n > 0 && FD_ISSET(sockinp, &rd) && drain(sockinp)) {
                    sockinp = -1;
                }
            }
        }
        close(wta->fd);
        h2o_barrier_wait(&wta->barrier);
        h2o_barrier_destroy(&wta->barrier);
        free(wta);
    }
}

/*
 * Creates socket pair and passes fuzzed req to a thread (the HTTP[/2] client)
 * for writing to the target h2o server. Returns the server socket fd.
 */
static int feeder(int sfd, char *buf, size_t len, h2o_barrier_t **barrier)
{
    int pair[2];
    struct writer_thread_arg *wta;

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
        return -1;

    wta = (struct writer_thread_arg *)malloc(sizeof(*wta));
    wta->fd = pair[0];
    wta->buf = buf;
    wta->len = len;
    h2o_barrier_init(&wta->barrier, 2);
    *barrier = &wta->barrier;

    write_fully(sfd, (char *)&wta, sizeof(wta), 1);
    return pair[1];
}

/*
 * Creates/connects socket pair for client/server interaction and passes
 * fuzzed request to client for sending.
 * Returns server socket fd.
 */
static int create_accepted(int sfd, char *buf, size_t len, h2o_barrier_t **barrier)
{
    int fd;
    h2o_socket_t *sock;
    struct timeval connected_at = *h2o_get_timestamp(&ctx, NULL, NULL);

    /* Create an HTTP[/2] client that will send the fuzzed request */
    fd = feeder(sfd, buf, len, barrier);
    if (fd < 0) {
        abort();
    }

    /* Pass the server socket to h2o and invoke request processing */
    sock = h2o_evloop_socket_create(ctx.loop, fd, H2O_SOCKET_FLAG_IS_ACCEPTED_CONNECTION);

#if defined(HTTP1)
    h2o_http1_accept(&accept_ctx, sock, connected_at);
#else
    h2o_http2_accept(&accept_ctx, sock, connected_at);
#endif

    return fd;
}

/*
 * Returns true if fd if valid. Used to determine when connection is closed.
 */
static int is_valid_fd(int fd)
{
    return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
}

/*
 * Entry point for libfuzzer.
 * See http://llvm.org/docs/LibFuzzer.html for more info
 */
static int init_done;
static int job_queue[2];
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
    int c;
    h2o_loop_t *loop;
    h2o_hostconf_t *hostconf;
    pthread_t twriter;
    pthread_t tupstream;

    /*
     * Perform one-time initialization
     */
    if (!init_done) {
        const char *client_timeout_ms_str;
        static char tmpname[] = "/tmp/h2o-fuzz-XXXXXX";
        char *dirname;
        h2o_url_t upstream;
        signal(SIGPIPE, SIG_IGN);

        dirname = mkdtemp(tmpname);
        snprintf(unix_listener, sizeof(unix_listener), "http://[unix://%s/_.sock]/proxy", dirname);
        if ((client_timeout_ms_str = getenv("H2O_FUZZER_CLIENT_TIMEOUT")) != NULL)
            client_timeout_ms = atoi(client_timeout_ms_str);
        if (!client_timeout_ms)
            client_timeout_ms = 10;

        /* Create a single h2o host with multiple request handlers */
        h2o_config_init(&config);
        config.http2.idle_timeout = 10 * 1000;
        config.http1.req_timeout = 10 * 1000;
        config.proxy.io_timeout = 10 * 1000;
        h2o_proxy_config_vars_t proxy_config = {};
        proxy_config.io_timeout = 10 * 1000;
        hostconf = h2o_config_register_host(&config, h2o_iovec_init(H2O_STRLIT(unix_listener)), 65535);
        register_handler(hostconf, "/chunked-test", chunked_test);
        h2o_url_parse(unix_listener, strlen(unix_listener), &upstream);
        h2o_socketpool_t *sockpool = new h2o_socketpool_t();
        h2o_socketpool_init_specific(sockpool, SIZE_MAX /* FIXME */, &upstream, 1, NULL, NULL, NULL);
        h2o_socketpool_set_timeout(sockpool, 2000);
        h2o_socketpool_set_ssl_ctx(sockpool, NULL);
        h2o_proxy_register_reverse_proxy(h2o_config_register_path(hostconf, "/reproxy-test", 0), &proxy_config, sockpool);
        h2o_file_register(h2o_config_register_path(hostconf, "/", 0), "./examples/doc_root", NULL, NULL, 0);

        loop = h2o_evloop_create();
        h2o_context_init(&ctx, loop, &config);

        accept_ctx.ctx = &ctx;
        accept_ctx.hosts = config.hosts;

        /* Create a thread to act as the HTTP client */
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, job_queue) != 0) {
            abort();
        }
        if (pthread_create(&twriter, NULL, writer_thread, (void *)(long)job_queue[1]) != 0) {
            abort();
        }
        if (pthread_create(&tupstream, NULL, upstream_thread, dirname) != 0) {
            abort();
        }
        init_done = 1;
    }

    /*
     * Pass fuzzed request to client thread and get h2o server socket for
     * use below
     */
    h2o_barrier_t *end;
    c = create_accepted(job_queue[0], (char *)Data, (size_t)Size, &end);
    if (c < 0) {
        goto Error;
    }

    /* Loop until the connection is closed by the client or server */
    while (is_valid_fd(c)) {
        h2o_evloop_run(ctx.loop, 10);
    }

    h2o_barrier_wait(end);
    return 0;
Error:
    return 1;
}
<|endoftext|>


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

#ifdef CS_TARGETPLATFORM_RPI

#include <ChilliSource/Core/Base/DeviceInfo.h>
#include <ChilliSource/Core/Base/ScreenInfo.h>
#include <ChilliSource/Core/Base/SystemInfo.h>
#include <ChilliSource/Core/String/StringUtils.h>

#include <CSBackend/Platform/RPi/Core/Base/Screen.h>
#include <CSBackend/Platform/RPi/Core/Base/SystemInfoFactory.h>
#include <CSBackend/Rendering/OpenGL/Base/RenderInfoFactory.h>

#include <sys/sysinfo.h>
#include <sys/utsname.h>

#include <algorithm>
#include <vector>

namespace CSBackend
{
    namespace RPi
    {
        namespace
        {
            const std::string k_deviceModel = "Raspberry Pi";
            const std::string k_deviceManufacturer = "Raspberry Pi Foundation";
            const std::string k_defaultLocale = "en_US";
            const std::string k_deviceUdid = "FAKE ID";

            /// Returns the language portion of a locale code.
            ///
            /// @param locale
            ///     The local code to parse
            ///
            /// @return The language code.
            ///
            std::string ParseLanguageFromLocale(const std::string& locale) noexcept
            {
                std::vector<std::string> localeBrokenUp = ChilliSource::StringUtils::Split(locale, "_", 0);

                if (localeBrokenUp.size() > 0)
                {
                    return localeBrokenUp[0];
                }
                else
                {
                    return k_defaultLocale;
                }
            }
        }

        //--------------------------------------------------------------------------------
        ChilliSource::SystemInfoCUPtr SystemInfoFactory::CreateSystemInfo() noexcept
        {
            utsname info;
            uname(&info);

            std::string osVersion("info.version");
            std::string machineType("info.machine");
            std::locale globalLocale; //Creating with the default constructor will set it to the global locale

            // Create DeviceInfo.
            ChilliSource::DeviceInfo deviceInfo(k_deviceModel, machineType, k_deviceManufacturer, k_deviceUdid, "globalLocale.name()", "ParseLanguageFromLocale(globalLocale.name())", osVersion, 1);

            // Create ScreenInfo.
            //ChilliSource::ScreenInfo screenInfo(GetScreenResolution(), 1.0f, 1.0f, GetSupportedResolutions());
            ChilliSource::ScreenInfo screenInfo(ChilliSource::Vector2(1920, 1080), 1.0f, 1.0f, std::vector<ChilliSource::Integer2>{ChilliSource::Integer2(1920, 1080)});

			//Create RenderInfo
			ChilliSource::RenderInfo renderInfo = OpenGL::RenderInfoFactory::CreateRenderInfo();

            // Create SystemInfo.
            ChilliSource::SystemInfoUPtr systemInfo(new ChilliSource::SystemInfo(deviceInfo, screenInfo, renderInfo, ""));

            return std::move(systemInfo);
        }

    }
}

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

#ifdef CS_TARGETPLATFORM_RPI

#include <ChilliSource/Core/Base/DeviceInfo.h>
#include <ChilliSource/Core/Base/ScreenInfo.h>
#include <ChilliSource/Core/Base/SystemInfo.h>
#include <ChilliSource/Core/String/StringUtils.h>

#include <CSBackend/Platform/RPi/Core/Base/Screen.h>
#include <CSBackend/Platform/RPi/Core/Base/SystemInfoFactory.h>
#include <CSBackend/Rendering/OpenGL/Base/RenderInfoFactory.h>

#include <sys/sysinfo.h>
#include <sys/utsname.h>

#include <algorithm>
#include <vector>

namespace CSBackend
{
    namespace RPi
    {
        namespace
        {
            const std::string k_deviceModel = "Raspberry Pi";
            const std::string k_deviceManufacturer = "Raspberry Pi Foundation";
            const std::string k_defaultLocale = "en_US";
            const std::string k_deviceUdid = "FAKE ID";

            /// Returns the language portion of a locale code.
            ///
            /// @param locale
            ///     The local code to parse
            ///
            /// @return The language code.
            ///
            std::string ParseLanguageFromLocale(const std::string& locale) noexcept
            {
                std::vector<std::string> localeBrokenUp = ChilliSource::StringUtils::Split(locale, "_", 0);

                if (localeBrokenUp.size() > 0)
                {
                    return localeBrokenUp[0];
                }
                else
                {
                    return k_defaultLocale;
                }
            }
        }

        //--------------------------------------------------------------------------------
        ChilliSource::SystemInfoCUPtr SystemInfoFactory::CreateSystemInfo() noexcept
        {
            utsname info;
            uname(&info);

            std::string osVersion(info.version);
            std::string machineType(info.machine);
            std::locale globalLocale; //Creating with the default constructor will set it to the global locale

            // Create DeviceInfo.
            ChilliSource::DeviceInfo deviceInfo(k_deviceModel, machineType, k_deviceManufacturer, k_deviceUdid, globalLocale.name(), ParseLanguageFromLocale(globalLocale.name()), osVersion, get_nprocs());

            // Create ScreenInfo.
            //ChilliSource::ScreenInfo screenInfo(GetScreenResolution(), 1.0f, 1.0f, GetSupportedResolutions());
            ChilliSource::ScreenInfo screenInfo(ChilliSource::Vector2(1920, 1080), 1.0f, 1.0f, std::vector<ChilliSource::Integer2>{ChilliSource::Integer2(1920, 1080)});

			//Create RenderInfo
			ChilliSource::RenderInfo renderInfo = OpenGL::RenderInfoFactory::CreateRenderInfo();

            // Create SystemInfo.
            ChilliSource::SystemInfoUPtr systemInfo(new ChilliSource::SystemInfo(deviceInfo, screenInfo, renderInfo, ""));

            return std::move(systemInfo);
        }

    }
}

#endif
<|endoftext|>


<commit_before>#include <iostream>

#include <boost/filesystem.hpp>

#include <opencv2/highgui/highgui.hpp>

#include "elm/core/core.h"
#include "elm/core/cv/mat_utils.h"
#include "elm/core/debug_utils.h"
#include "elm/core/layerconfig.h"
#include "elm/core/inputname.h"
#include "elm/io/readnyudepthv2labeled.h"
#include "elm/layers/layerfactory.h"
#include "elm/layers/mlp.h"

using namespace std;
namespace bfs=boost::filesystem;
using namespace cv;
using namespace elm;

int main() {

    cout<<elm::GetVersion()<<endl;

    bfs::path p("/media/win/Users/woodstock/dev/data/nyu_depth_v2_labeled.mat");

    ReadNYUDepthV2Labeled reader;
    int nb_items = reader.ReadHeader(p.string());

    ELM_COUT_VAR(nb_items);

    for(int i=0; i<10; i++) {

        ELM_COUT_VAR(i);

        cv::Mat bgr, labels, depth;
        reader.Next(bgr, depth, labels);

        cv::imshow("image", bgr);
        cv::imshow("depth", elm::ConvertTo8U(depth));
        cv::imshow("labels", elm::ConvertTo8U(labels));
        cv::waitKey(0);
    }

    return 0;
}
<commit_msg>remove sample project<commit_after><|endoftext|>


<commit_before>//
//  RenderingCapabilities.cpp
//  Chilli Source
//  Created by Ian Copland on 27/01/2014.
//
//  The MIT License (MIT)
//
//  Copyright (c) 2010 Tag Games Limited
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

#include <CSBackend/Rendering/OpenGL/Base/RenderCapabilities.h>

#include <CSBackend/Rendering/OpenGL/Base/GLError.h>
#include <CSBackend/Rendering/OpenGL/Base/GLIncludes.h>

namespace CSBackend
{
    namespace OpenGL
    {
        namespace
        {
            //----------------------------------------------------------
            /// Check for OpenGL Extension support
            ///
            /// @author Ian Copland
            ///
            /// @param Extension ID
            ///
            /// @return Whether it is supported
            //----------------------------------------------------------
            bool CheckForOpenGLExtension(const std::string& in_extension)
            {
                return false;

                std::string extensions = (const char*)glGetString(GL_EXTENSIONS);
                return extensions.find(in_extension) != extensions.npos;
            }
        }

        CS_DEFINE_NAMEDTYPE(RenderCapabilities);
        //-------------------------------------------------
        //-------------------------------------------------
        RenderCapabilities::RenderCapabilities()
        : m_areShadowMapsSupported(false), m_areDepthTexturesSupported(false), m_areMapBuffersSupported(false), m_maxTextureSize(0), m_maxTextureUnits(0)
        {
        }
        //-------------------------------------------------
        //-------------------------------------------------
        bool RenderCapabilities::IsA(ChilliSource::InterfaceIDType in_interfaceId) const
        {
            return (ChilliSource::RenderCapabilities::InterfaceID == in_interfaceId || RenderCapabilities::InterfaceID == in_interfaceId);
        }
        //-------------------------------------------------
        //-------------------------------------------------
        void RenderCapabilities::DetermineCapabilities()
        {
			bool areHighPrecFragmentsSupported = true;
            m_areMapBuffersSupported = true;

#ifdef CS_OPENGLVERSION_ES
            s32 fragmentHighRanges[2];
            s32 fragmentHighPrecision;

            glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, fragmentHighRanges, &fragmentHighPrecision);
            areHighPrecFragmentsSupported = fragmentHighPrecision != 0 && fragmentHighRanges[0] != 0 && fragmentHighRanges[1] != 0;

#ifdef CS_TARGETPLATFORM_ANDROID
            //Check for map buffer support
            m_areMapBuffersSupported = CheckForOpenGLExtension("GL_OES_mapbuffer");
#endif

#endif

#ifdef CS_OPENGLVERSION_STANDARD
			m_areDepthTexturesSupported = CheckForOpenGLExtension("GL_ARB_depth_texture");
#elif defined(CS_OPENGLVERSION_ES)
			m_areDepthTexturesSupported = CheckForOpenGLExtension("GL_OES_depth_texture");
#endif
            m_areShadowMapsSupported = (m_areDepthTexturesSupported && areHighPrecFragmentsSupported);
            glGetIntegerv(GL_MAX_TEXTURE_SIZE, (s32*)&m_maxTextureSize);
            glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, (s32*)&m_maxTextureUnits);

            CS_ASSERT_NOGLERROR("An OpenGL error occurred while getting render capabilities.");
        }
        //-------------------------------------------------
        //-------------------------------------------------
        bool RenderCapabilities::IsShadowMappingSupported() const
        {
            return m_areShadowMapsSupported;
        }
        //-------------------------------------------------
        //-------------------------------------------------
        bool RenderCapabilities::IsDepthTextureSupported() const
        {
            return m_areDepthTexturesSupported;
        }
        //-------------------------------------------------
        //-------------------------------------------------
        bool RenderCapabilities::IsMapBufferSupported() const
        {
            return m_areMapBuffersSupported;
        }
        //-------------------------------------------------
        //-------------------------------------------------
        u32 RenderCapabilities::GetMaxTextureSize() const
        {
            return m_maxTextureSize;
        }
        //-------------------------------------------------
        //-------------------------------------------------
        u32 RenderCapabilities::GetNumTextureUnits() const
        {
            return m_maxTextureUnits;
        }
    }
}
<commit_msg>WIP: Removed previous debug change.<commit_after>//
//  RenderingCapabilities.cpp
//  Chilli Source
//  Created by Ian Copland on 27/01/2014.
//
//  The MIT License (MIT)
//
//  Copyright (c) 2010 Tag Games Limited
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

#include <CSBackend/Rendering/OpenGL/Base/RenderCapabilities.h>

#include <CSBackend/Rendering/OpenGL/Base/GLError.h>
#include <CSBackend/Rendering/OpenGL/Base/GLIncludes.h>

namespace CSBackend
{
    namespace OpenGL
    {
        namespace
        {
            //----------------------------------------------------------
            /// Check for OpenGL Extension support
            ///
            /// @author Ian Copland
            ///
            /// @param Extension ID
            ///
            /// @return Whether it is supported
            //----------------------------------------------------------
            bool CheckForOpenGLExtension(const std::string& in_extension)
            {
                std::string extensions = (const char*)glGetString(GL_EXTENSIONS);
                return extensions.find(in_extension) != extensions.npos;
            }
        }

        CS_DEFINE_NAMEDTYPE(RenderCapabilities);
        //-------------------------------------------------
        //-------------------------------------------------
        RenderCapabilities::RenderCapabilities()
        : m_areShadowMapsSupported(false), m_areDepthTexturesSupported(false), m_areMapBuffersSupported(false), m_maxTextureSize(0), m_maxTextureUnits(0)
        {
        }
        //-------------------------------------------------
        //-------------------------------------------------
        bool RenderCapabilities::IsA(ChilliSource::InterfaceIDType in_interfaceId) const
        {
            return (ChilliSource::RenderCapabilities::InterfaceID == in_interfaceId || RenderCapabilities::InterfaceID == in_interfaceId);
        }
        //-------------------------------------------------
        //-------------------------------------------------
        void RenderCapabilities::DetermineCapabilities()
        {
			bool areHighPrecFragmentsSupported = true;
            m_areMapBuffersSupported = true;

#ifdef CS_OPENGLVERSION_ES
            s32 fragmentHighRanges[2];
            s32 fragmentHighPrecision;

            glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, fragmentHighRanges, &fragmentHighPrecision);
            areHighPrecFragmentsSupported = fragmentHighPrecision != 0 && fragmentHighRanges[0] != 0 && fragmentHighRanges[1] != 0;

#ifdef CS_TARGETPLATFORM_ANDROID
            //Check for map buffer support
            m_areMapBuffersSupported = CheckForOpenGLExtension("GL_OES_mapbuffer");
#endif

#endif

#ifdef CS_OPENGLVERSION_STANDARD
			m_areDepthTexturesSupported = CheckForOpenGLExtension("GL_ARB_depth_texture");
#elif defined(CS_OPENGLVERSION_ES)
			m_areDepthTexturesSupported = CheckForOpenGLExtension("GL_OES_depth_texture");
#endif
            m_areShadowMapsSupported = (m_areDepthTexturesSupported && areHighPrecFragmentsSupported);
            glGetIntegerv(GL_MAX_TEXTURE_SIZE, (s32*)&m_maxTextureSize);
            glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, (s32*)&m_maxTextureUnits);

            CS_ASSERT_NOGLERROR("An OpenGL error occurred while getting render capabilities.");
        }
        //-------------------------------------------------
        //-------------------------------------------------
        bool RenderCapabilities::IsShadowMappingSupported() const
        {
            return m_areShadowMapsSupported;
        }
        //-------------------------------------------------
        //-------------------------------------------------
        bool RenderCapabilities::IsDepthTextureSupported() const
        {
            return m_areDepthTexturesSupported;
        }
        //-------------------------------------------------
        //-------------------------------------------------
        bool RenderCapabilities::IsMapBufferSupported() const
        {
            return m_areMapBuffersSupported;
        }
        //-------------------------------------------------
        //-------------------------------------------------
        u32 RenderCapabilities::GetMaxTextureSize() const
        {
            return m_maxTextureSize;
        }
        //-------------------------------------------------
        //-------------------------------------------------
        u32 RenderCapabilities::GetNumTextureUnits() const
        {
            return m_maxTextureUnits;
        }
    }
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2018 The nanoFramework project contributors
// See LICENSE file in the project root for full license information.
//

#include "nf_hardware_stm32_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::ReadBytes___STATIC__VOID__U4__SZARRAY_U1,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::WriteBytes___STATIC__VOID__U4__SZARRAY_U1,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::GetSize___STATIC__I4,
    NULL,
    NULL,
    NULL,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_RTC::Native_RTC_SetAlarm___STATIC__VOID__U1__U1__U1__U1,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_RTC::Native_RTC_GetAlarm___STATIC__I8,
    NULL,
    NULL,
    NULL,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Utilities::NativeGetDeviceUniqueId___STATIC__VOID__SZARRAY_U1,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Utilities::NativeGetDeviceId___STATIC__U4,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Utilities::NativeGetDeviceRevisionId___STATIC__U4,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Stm32 =
{
    "nanoFramework.Hardware.Stm32",
    0x0427DBEE,
    method_lookup,
    { 1, 0, 2, 17 }
};
<commit_msg>Update nanoFramework.Hardware.Stm32 version to 1.0.2-preview-019 (#1042)<commit_after>//
// Copyright (c) 2018 The nanoFramework project contributors
// See LICENSE file in the project root for full license information.
//

#include "nf_hardware_stm32_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::ReadBytes___STATIC__VOID__U4__SZARRAY_U1,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::WriteBytes___STATIC__VOID__U4__SZARRAY_U1,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::GetSize___STATIC__I4,
    NULL,
    NULL,
    NULL,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_RTC::Native_RTC_SetAlarm___STATIC__VOID__U1__U1__U1__U1,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_RTC::Native_RTC_GetAlarm___STATIC__I8,
    NULL,
    NULL,
    NULL,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Utilities::NativeGetDeviceUniqueId___STATIC__VOID__SZARRAY_U1,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Utilities::NativeGetDeviceId___STATIC__U4,
    Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Utilities::NativeGetDeviceRevisionId___STATIC__U4,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Stm32 =
{
    "nanoFramework.Hardware.Stm32",
    0x0427DBEE,
    method_lookup,
    { 1, 0, 2, 19 }
};
<|endoftext|>