<commit_before>// Pocket.cpp

#include "stdafx.h"
#include "Pocket.h"
#include "CNCConfig.h"
#include "ProgramCanvas.h"
#include "../../interface/HeeksObj.h"
#include "../../interface/PropertyDouble.h"
#include "../../interface/PropertyString.h"
#include "../../interface/PropertyChoice.h"
#include "../../interface/PropertyVertex.h"
#include "../../interface/PropertyCheck.h"
#include "../../tinyxml/tinyxml.h"

CPocketParams::CPocketParams()
{
	m_tool_diameter = 0.0;
	m_step_over = 0.0;
	m_round_corner_factor = 0.0;
	m_clearance_height = 0.0;
	m_final_depth = 0.0;
	m_rapid_down_to_height = 0.0;
	m_horizontal_feed_rate = 0.0;
	m_vertical_feed_rate = 0.0;
	m_spindle_speed = 0.0;
}

void CPocketParams::set_initial_values()
{
	CNCConfig config;
	config.Read(_T("PocketToolDiameter"), &m_tool_diameter, 3.0);
	config.Read(_T("PocketStepOver"), &m_step_over, 1.0);
	config.Read(_T("PocketRoundCornerFactor"), &m_round_corner_factor, 1.5);
	config.Read(_T("PocketClearanceHeight"), &m_clearance_height, 5.0);
	config.Read(_T("PocketFinalDepth"), &m_final_depth, -0.1);
	config.Read(_T("PocketRapidDown"), &m_rapid_down_to_height, 2.0);
	config.Read(_T("PocketHorizFeed"), &m_horizontal_feed_rate, 100.0);
	config.Read(_T("PocketVertFeed"), &m_vertical_feed_rate, 100.0);
	config.Read(_T("PocketSpindleSpeed"), &m_spindle_speed, 7000);
}

void CPocketParams::write_values_to_config()
{
	CNCConfig config;
	config.Write(_T("PocketToolDiameter"), m_tool_diameter);
	config.Write(_T("PocketStepOver"), m_step_over);
	config.Write(_T("PocketRoundCornerFactor"), m_round_corner_factor);
	config.Write(_T("PocketClearanceHeight"), m_clearance_height);
	config.Write(_T("PocketFinalDepth"), m_final_depth);
	config.Write(_T("PocketRapidDown"), m_rapid_down_to_height);
	config.Write(_T("PocketHorizFeed"), m_horizontal_feed_rate);
	config.Write(_T("PocketVertFeed"), m_vertical_feed_rate);
	config.Write(_T("PocketSpindleSpeed"), m_spindle_speed);
}

static void on_set_tool_diameter(double value, HeeksObj* object){((CPocket*)object)->m_params.m_tool_diameter = value;}
static void on_set_step_over(double value, HeeksObj* object){((CPocket*)object)->m_params.m_step_over = value;}
static void on_set_round_corner_factor(double value, HeeksObj* object){((CPocket*)object)->m_params.m_round_corner_factor = value;}
static void on_set_clearance_height(double value, HeeksObj* object){((CPocket*)object)->m_params.m_clearance_height = value;}
static void on_set_final_depth(double value, HeeksObj* object){((CPocket*)object)->m_params.m_final_depth = value;}
static void on_set_rapid_down_to_height(double value, HeeksObj* object){((CPocket*)object)->m_params.m_rapid_down_to_height = value;}
static void on_set_horizontal_feed_rate(double value, HeeksObj* object){((CPocket*)object)->m_params.m_horizontal_feed_rate = value;}
static void on_set_vertical_feed_rate(double value, HeeksObj* object){((CPocket*)object)->m_params.m_vertical_feed_rate = value;}
static void on_set_spindle_speed(double value, HeeksObj* object){((CPocket*)object)->m_params.m_spindle_speed = value;}

void CPocketParams::GetProperties(CPocket* parent, std::list<Property *> *list)
{
	list->push_back(new PropertyDouble(_("tool diameter"), m_tool_diameter, parent, on_set_tool_diameter));
	list->push_back(new PropertyDouble(_("step over"), m_step_over, parent, on_set_step_over));
	list->push_back(new PropertyDouble(_("round corner factor"), m_round_corner_factor, parent, on_set_round_corner_factor));
	list->push_back(new PropertyString(wxString(_T("( ")) + _("for 90 degree corners") + _T(" )"), wxString(_T("( ")) + _("1.5 for square, 1.0 for round")  + _T(" )"), NULL));
	list->push_back(new PropertyDouble(_("clearance height"), m_clearance_height, parent, on_set_clearance_height));
	list->push_back(new PropertyDouble(_("final depth"), m_final_depth, parent, on_set_final_depth));
	list->push_back(new PropertyDouble(_("rapid down to height"), m_rapid_down_to_height, parent, on_set_rapid_down_to_height));
	list->push_back(new PropertyDouble(_("horizontal feed rate"), m_horizontal_feed_rate, parent, on_set_horizontal_feed_rate));
	list->push_back(new PropertyDouble(_("vertical feed rate"), m_vertical_feed_rate, parent, on_set_vertical_feed_rate));
	list->push_back(new PropertyDouble(_("spindle speed"), m_spindle_speed, parent, on_set_spindle_speed));
}

void CPocketParams::WriteXMLAttributes(TiXmlNode *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "params" );
	root->LinkEndChild( element );
	element->SetAttribute("toold", m_tool_diameter);
	element->SetAttribute("step", m_step_over);
	element->SetAttribute("rf", m_round_corner_factor);
	element->SetAttribute("clear", m_clearance_height);
	element->SetAttribute("depth", m_final_depth);
	element->SetAttribute("r", m_rapid_down_to_height);
	element->SetAttribute("hfeed", m_horizontal_feed_rate);
	element->SetAttribute("vfeed", m_vertical_feed_rate);
	element->SetAttribute("spin", m_spindle_speed);
}

void CPocketParams::ReadFromXMLElement(TiXmlElement* pElem)
{
	// get the attributes
	for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "toold"){m_tool_diameter = a->DoubleValue();}
		else if(name == "step"){m_step_over = a->DoubleValue();}
		else if(name == "rf"){m_round_corner_factor = a->DoubleValue();}
		else if(name == "clear"){m_clearance_height = a->DoubleValue();}
		else if(name == "depth"){m_final_depth = a->DoubleValue();}
		else if(name == "r"){m_rapid_down_to_height = a->DoubleValue();}
		else if(name == "hfeed"){m_horizontal_feed_rate = a->DoubleValue();}
		else if(name == "vfeed"){m_vertical_feed_rate = a->DoubleValue();}
		else if(name == "spin"){m_spindle_speed = a->DoubleValue();}
	}
}

static void WriteSketchDefn(HeeksObj* sketch)
{
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("a%d = area.new()\n"), sketch->m_id));

	bool started = false;

	for(HeeksObj* span_object = sketch->GetFirstChild(); span_object; span_object = sketch->GetNextChild())
	{
		double s[3] = {0, 0, 0};
		double e[3] = {0, 0, 0};
		double c[3] = {0, 0, 0};

		if(span_object){
			int type = span_object->GetType();
			if(type == LineType || type == ArcType)
			{
				if(!started)
				{
					span_object->GetStartPoint(s);
					theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("area.add_point(a%d, %d, %g, %g, %g, %g)\n"), sketch->m_id, 0, s[0], s[1], 0.0, 0.0));
					started = true;
				}
				span_object->GetEndPoint(e);
				if(type == LineType)
				{
					theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("area.add_point(a%d, %d, %g, %g, %g, %g)\n"), sketch->m_id, 0, e[0], e[1], 0.0, 0.0));
				}
				else if(type == ArcType)
				{
					span_object->GetCentrePoint(c);
					double pos[3];
					heeksCAD->GetArcAxis(span_object, pos);
					int span_type = (pos[2] >=0) ? 1:-1;
					theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("area.add_point(a%d, %d, %g, %g, %g, %g)\n"), sketch->m_id, span_type, e[0], e[1], c[0], c[1]));
				}
			}
		}
	}

	theApp.m_program_canvas->m_textCtrl->AppendText(_T("\n"));
}

void CPocket::AppendTextToProgram()
{
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("clearance = float(%g)\n"), m_params.m_clearance_height));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("rapid_down_to_height = float(%g)\n"), m_params.m_rapid_down_to_height));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("final_depth = float(%g)\n"), m_params.m_final_depth));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("tool_diameter = float(%g)\n"), m_params.m_tool_diameter));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("spindle(%g)\n"), m_params.m_spindle_speed));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("feedrate(%g)\n"), m_params.m_horizontal_feed_rate));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("tool_change(1)\n")));
	for(std::list<int>::iterator It = m_sketches.begin(); It != m_sketches.end(); It++)
	{
		int sketch = *It;

		// write an area definition
		HeeksObj* object = heeksCAD->GetIDObject(SketchType, sketch);
		if(object == NULL || object->GetNumChildren() == 0)continue;

		if(object)
		{
			WriteSketchDefn(object);

			// start - assume we are at a suitable clearance height

			// Pocket the area
			theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("stdops.pocket(a%d, tool_diameter/2, %lf, %lf)\n"), sketch, m_params.m_step_over, m_params.m_round_corner_factor));

			// rapid back up to clearance plane
			theApp.m_program_canvas->m_textCtrl->AppendText(wxString(_T("rapid(z = clearance)\n")));
		}
	}
}

void CPocket::glCommands(bool select, bool marked, bool no_color)
{
	if(marked && !no_color)
	{
		for(std::list<int>::iterator It = m_sketches.begin(); It != m_sketches.end(); It++)
		{
			int sketch = *It;
			HeeksObj* object = heeksCAD->GetIDObject(SketchType, sketch);
			if(object)object->glCommands(false, true, false);
		}
	}
}

void CPocket::GetProperties(std::list<Property *> *list)
{
	m_params.GetProperties(this, list);
	HeeksObj::GetProperties(list);
}

HeeksObj *CPocket::MakeACopy(void)const
{
	return new CPocket(*this);
}

void CPocket::CopyFrom(const HeeksObj* object)
{
	operator=(*((CPocket*)object));
}

bool CPocket::CanAddTo(HeeksObj* owner)
{
	return owner->GetType() == OperationsType;
}

void CPocket::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element = new TiXmlElement( "Pocket" );
	root->LinkEndChild( element );
	m_params.WriteXMLAttributes(element);

	// write sketch ids
	for(std::list<int>::iterator It = m_sketches.begin(); It != m_sketches.end(); It++)
	{
		int sketch = *It;
		TiXmlElement * sketch_element = new TiXmlElement( "sketch" );
		element->LinkEndChild( sketch_element );
		sketch_element->SetAttribute("id", sketch);
	}

	WriteBaseXML(element);
}

// static member function
HeeksObj* CPocket::ReadFromXMLElement(TiXmlElement* element)
{
	CPocket* new_object = new CPocket;

	// read sketch ids
	for(TiXmlElement* pElem = TiXmlHandle(element).FirstChildElement().Element(); pElem; pElem = pElem->NextSiblingElement())
	{
		std::string name(pElem->Value());
		if(name == "params"){
			new_object->m_params.ReadFromXMLElement(pElem);
		}
		else if(name == "sketch"){
			for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
			{
				std::string name(a->Name());
				if(name == "id"){
					int id = a->IntValue();
					new_object->m_sketches.push_back(id);
				}
			}
		}
	}

	new_object->ReadBaseXML(element);

	return new_object;
}
<commit_msg>work on libarea Issue 2:  	 Islands<commit_after>// Pocket.cpp

#include "stdafx.h"
#include "Pocket.h"
#include "CNCConfig.h"
#include "ProgramCanvas.h"
#include "../../interface/HeeksObj.h"
#include "../../interface/PropertyDouble.h"
#include "../../interface/PropertyString.h"
#include "../../interface/PropertyChoice.h"
#include "../../interface/PropertyVertex.h"
#include "../../interface/PropertyCheck.h"
#include "../../tinyxml/tinyxml.h"

CPocketParams::CPocketParams()
{
	m_tool_diameter = 0.0;
	m_step_over = 0.0;
	m_round_corner_factor = 0.0;
	m_clearance_height = 0.0;
	m_final_depth = 0.0;
	m_rapid_down_to_height = 0.0;
	m_horizontal_feed_rate = 0.0;
	m_vertical_feed_rate = 0.0;
	m_spindle_speed = 0.0;
}

void CPocketParams::set_initial_values()
{
	CNCConfig config;
	config.Read(_T("PocketToolDiameter"), &m_tool_diameter, 3.0);
	config.Read(_T("PocketStepOver"), &m_step_over, 1.0);
	config.Read(_T("PocketRoundCornerFactor"), &m_round_corner_factor, 1.5);
	config.Read(_T("PocketClearanceHeight"), &m_clearance_height, 5.0);
	config.Read(_T("PocketFinalDepth"), &m_final_depth, -0.1);
	config.Read(_T("PocketRapidDown"), &m_rapid_down_to_height, 2.0);
	config.Read(_T("PocketHorizFeed"), &m_horizontal_feed_rate, 100.0);
	config.Read(_T("PocketVertFeed"), &m_vertical_feed_rate, 100.0);
	config.Read(_T("PocketSpindleSpeed"), &m_spindle_speed, 7000);
}

void CPocketParams::write_values_to_config()
{
	CNCConfig config;
	config.Write(_T("PocketToolDiameter"), m_tool_diameter);
	config.Write(_T("PocketStepOver"), m_step_over);
	config.Write(_T("PocketRoundCornerFactor"), m_round_corner_factor);
	config.Write(_T("PocketClearanceHeight"), m_clearance_height);
	config.Write(_T("PocketFinalDepth"), m_final_depth);
	config.Write(_T("PocketRapidDown"), m_rapid_down_to_height);
	config.Write(_T("PocketHorizFeed"), m_horizontal_feed_rate);
	config.Write(_T("PocketVertFeed"), m_vertical_feed_rate);
	config.Write(_T("PocketSpindleSpeed"), m_spindle_speed);
}

static void on_set_tool_diameter(double value, HeeksObj* object){((CPocket*)object)->m_params.m_tool_diameter = value;}
static void on_set_step_over(double value, HeeksObj* object){((CPocket*)object)->m_params.m_step_over = value;}
static void on_set_round_corner_factor(double value, HeeksObj* object){((CPocket*)object)->m_params.m_round_corner_factor = value;}
static void on_set_clearance_height(double value, HeeksObj* object){((CPocket*)object)->m_params.m_clearance_height = value;}
static void on_set_final_depth(double value, HeeksObj* object){((CPocket*)object)->m_params.m_final_depth = value;}
static void on_set_rapid_down_to_height(double value, HeeksObj* object){((CPocket*)object)->m_params.m_rapid_down_to_height = value;}
static void on_set_horizontal_feed_rate(double value, HeeksObj* object){((CPocket*)object)->m_params.m_horizontal_feed_rate = value;}
static void on_set_vertical_feed_rate(double value, HeeksObj* object){((CPocket*)object)->m_params.m_vertical_feed_rate = value;}
static void on_set_spindle_speed(double value, HeeksObj* object){((CPocket*)object)->m_params.m_spindle_speed = value;}

void CPocketParams::GetProperties(CPocket* parent, std::list<Property *> *list)
{
	list->push_back(new PropertyDouble(_("tool diameter"), m_tool_diameter, parent, on_set_tool_diameter));
	list->push_back(new PropertyDouble(_("step over"), m_step_over, parent, on_set_step_over));
	list->push_back(new PropertyDouble(_("round corner factor"), m_round_corner_factor, parent, on_set_round_corner_factor));
	list->push_back(new PropertyString(wxString(_T("( ")) + _("for 90 degree corners") + _T(" )"), wxString(_T("( ")) + _("1.5 for square, 1.0 for round")  + _T(" )"), NULL));
	list->push_back(new PropertyDouble(_("clearance height"), m_clearance_height, parent, on_set_clearance_height));
	list->push_back(new PropertyDouble(_("final depth"), m_final_depth, parent, on_set_final_depth));
	list->push_back(new PropertyDouble(_("rapid down to height"), m_rapid_down_to_height, parent, on_set_rapid_down_to_height));
	list->push_back(new PropertyDouble(_("horizontal feed rate"), m_horizontal_feed_rate, parent, on_set_horizontal_feed_rate));
	list->push_back(new PropertyDouble(_("vertical feed rate"), m_vertical_feed_rate, parent, on_set_vertical_feed_rate));
	list->push_back(new PropertyDouble(_("spindle speed"), m_spindle_speed, parent, on_set_spindle_speed));
}

void CPocketParams::WriteXMLAttributes(TiXmlNode *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "params" );
	root->LinkEndChild( element );
	element->SetAttribute("toold", m_tool_diameter);
	element->SetAttribute("step", m_step_over);
	element->SetAttribute("rf", m_round_corner_factor);
	element->SetAttribute("clear", m_clearance_height);
	element->SetAttribute("depth", m_final_depth);
	element->SetAttribute("r", m_rapid_down_to_height);
	element->SetAttribute("hfeed", m_horizontal_feed_rate);
	element->SetAttribute("vfeed", m_vertical_feed_rate);
	element->SetAttribute("spin", m_spindle_speed);
}

void CPocketParams::ReadFromXMLElement(TiXmlElement* pElem)
{
	// get the attributes
	for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "toold"){m_tool_diameter = a->DoubleValue();}
		else if(name == "step"){m_step_over = a->DoubleValue();}
		else if(name == "rf"){m_round_corner_factor = a->DoubleValue();}
		else if(name == "clear"){m_clearance_height = a->DoubleValue();}
		else if(name == "depth"){m_final_depth = a->DoubleValue();}
		else if(name == "r"){m_rapid_down_to_height = a->DoubleValue();}
		else if(name == "hfeed"){m_horizontal_feed_rate = a->DoubleValue();}
		else if(name == "vfeed"){m_vertical_feed_rate = a->DoubleValue();}
		else if(name == "spin"){m_spindle_speed = a->DoubleValue();}
	}
}

static void WriteSketchDefn(HeeksObj* sketch)
{
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("a%d = area.new()\n"), sketch->m_id));

	bool started = false;

	double prev_e[3];

	for(HeeksObj* span_object = sketch->GetFirstChild(); span_object; span_object = sketch->GetNextChild())
	{
		double s[3] = {0, 0, 0};
		double e[3] = {0, 0, 0};
		double c[3] = {0, 0, 0};

		if(span_object){
			int type = span_object->GetType();
			if(type == LineType || type == ArcType)
			{
				span_object->GetStartPoint(s);
				if(started && (fabs(s[0] - prev_e[0]) > 0.000000001 || fabs(s[1] - prev_e[1]) > 0.000000001))
				{
					theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("area.start_new_curve(a%d)\n"), sketch->m_id));
					started = false;
				}

				if(!started)
				{
					theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("area.add_point(a%d, %d, %g, %g, %g, %g)\n"), sketch->m_id, 0, s[0], s[1], 0.0, 0.0));
					started = true;
				}
				span_object->GetEndPoint(e);
				if(type == LineType)
				{
					theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("area.add_point(a%d, %d, %g, %g, %g, %g)\n"), sketch->m_id, 0, e[0], e[1], 0.0, 0.0));
				}
				else if(type == ArcType)
				{
					span_object->GetCentrePoint(c);
					double pos[3];
					heeksCAD->GetArcAxis(span_object, pos);
					int span_type = (pos[2] >=0) ? 1:-1;
					theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("area.add_point(a%d, %d, %g, %g, %g, %g)\n"), sketch->m_id, span_type, e[0], e[1], c[0], c[1]));
				}
				memcpy(prev_e, e, 3*sizeof(double));
			}
		}
	}

	theApp.m_program_canvas->m_textCtrl->AppendText(_T("\n"));
}

void CPocket::AppendTextToProgram()
{
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("clearance = float(%g)\n"), m_params.m_clearance_height));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("rapid_down_to_height = float(%g)\n"), m_params.m_rapid_down_to_height));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("final_depth = float(%g)\n"), m_params.m_final_depth));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("tool_diameter = float(%g)\n"), m_params.m_tool_diameter));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("spindle(%g)\n"), m_params.m_spindle_speed));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("feedrate(%g)\n"), m_params.m_horizontal_feed_rate));
	theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("tool_change(1)\n")));
	for(std::list<int>::iterator It = m_sketches.begin(); It != m_sketches.end(); It++)
	{
		int sketch = *It;

		// write an area definition
		HeeksObj* object = heeksCAD->GetIDObject(SketchType, sketch);
		if(object == NULL || object->GetNumChildren() == 0)continue;

		if(object)
		{
			WriteSketchDefn(object);

			// start - assume we are at a suitable clearance height

			// Pocket the area
			theApp.m_program_canvas->m_textCtrl->AppendText(wxString::Format(_T("stdops.pocket(a%d, tool_diameter/2, %lf, %lf)\n"), sketch, m_params.m_step_over, m_params.m_round_corner_factor));

			// rapid back up to clearance plane
			theApp.m_program_canvas->m_textCtrl->AppendText(wxString(_T("rapid(z = clearance)\n")));
		}
	}
}

void CPocket::glCommands(bool select, bool marked, bool no_color)
{
	if(marked && !no_color)
	{
		for(std::list<int>::iterator It = m_sketches.begin(); It != m_sketches.end(); It++)
		{
			int sketch = *It;
			HeeksObj* object = heeksCAD->GetIDObject(SketchType, sketch);
			if(object)object->glCommands(false, true, false);
		}
	}
}

void CPocket::GetProperties(std::list<Property *> *list)
{
	m_params.GetProperties(this, list);
	HeeksObj::GetProperties(list);
}

HeeksObj *CPocket::MakeACopy(void)const
{
	return new CPocket(*this);
}

void CPocket::CopyFrom(const HeeksObj* object)
{
	operator=(*((CPocket*)object));
}

bool CPocket::CanAddTo(HeeksObj* owner)
{
	return owner->GetType() == OperationsType;
}

void CPocket::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element = new TiXmlElement( "Pocket" );
	root->LinkEndChild( element );
	m_params.WriteXMLAttributes(element);

	// write sketch ids
	for(std::list<int>::iterator It = m_sketches.begin(); It != m_sketches.end(); It++)
	{
		int sketch = *It;
		TiXmlElement * sketch_element = new TiXmlElement( "sketch" );
		element->LinkEndChild( sketch_element );
		sketch_element->SetAttribute("id", sketch);
	}

	WriteBaseXML(element);
}

// static member function
HeeksObj* CPocket::ReadFromXMLElement(TiXmlElement* element)
{
	CPocket* new_object = new CPocket;

	// read sketch ids
	for(TiXmlElement* pElem = TiXmlHandle(element).FirstChildElement().Element(); pElem; pElem = pElem->NextSiblingElement())
	{
		std::string name(pElem->Value());
		if(name == "params"){
			new_object->m_params.ReadFromXMLElement(pElem);
		}
		else if(name == "sketch"){
			for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
			{
				std::string name(a->Name());
				if(name == "id"){
					int id = a->IntValue();
					new_object->m_sketches.push_back(id);
				}
			}
		}
	}

	new_object->ReadBaseXML(element);

	return new_object;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <mutex>
#include <queue>
#include <thread>
#include <tuple>
#include <condition_variable>
#include <algorithm>

#include "input_file_reader.hpp"
#include "minimize.hpp"
#include "comparator.hpp"
#include "result.hpp"
#include "minimizer.hpp"

// mutex for shared resources
static std::mutex g_resource_mutex;

// mutex for result vector
static std::mutex g_result_mutex;

// global queue with two pointers to the sequences
// they are compared directly if the both sequence lengths are small enough
static std::queue<std::tuple<uint32_t, OLC::Sequence*, uint32_t, OLC::Sequence*>> g_sequence_pairs;

// global queue with two pointers to vectors of minimizers
// we use this instead if the sequences are too long
static std::queue<std::tuple<uint32_t, std::vector<OLC::Minimizer>*, uint32_t, std::vector<OLC::Minimizer>*>> g_minimizer_pairs;

// global vector with results
static std::vector<OLC::Result*> g_results;

static const uint32_t SEQUENCE_THRESHOLD_LENGTH = 20000;

void worker()
{
  while(true)
  {
    // Get the task and remove it from the pool
    uint32_t first_read_number;
    OLC::Sequence* first_sequence;
    std::vector<OLC::Minimizer>* first_minimizer;

    uint32_t second_read_number;
    OLC::Sequence* second_sequence;
    std::vector<OLC::Minimizer>* second_minimizer;

    {
      std::lock_guard<std::mutex> resource_lock(g_resource_mutex);

      if (g_sequence_pairs.empty())
        return;

      std::tie(first_read_number, first_sequence, second_read_number, second_sequence) = g_sequence_pairs.front();
      g_sequence_pairs.pop();
      std::tie(first_read_number, first_minimizer, second_read_number, second_minimizer) = g_minimizer_pairs.front();
      g_minimizer_pairs.pop();
    }

    // Pull out the wrapped nucleotide vectors
    const std::vector<OLC::Nucleotide> nucleotides1 = first_sequence->getNucleotides()->getSequence();
    const std::vector<OLC::Nucleotide> nucleotides2 = second_sequence->getNucleotides()->getSequence();

    // If small enough, no need to use minimizers
    if (nucleotides1.size() < SEQUENCE_THRESHOLD_LENGTH && nucleotides2.size() < SEQUENCE_THRESHOLD_LENGTH)
    {
      const OLC::Overlap overlap = compare(nucleotides1, nucleotides2);
      const uint32_t overlapFirstEnd = overlap.getEndFirst();
      const uint32_t overlapSecondEnd = overlap.getEndSecond();
      const uint32_t overlapFirstStart = overlap.getStartFirst();
      const uint32_t overlapSecondStart = overlap.getStartSecond();
      const uint32_t overlapLength = overlapFirstEnd - overlapFirstStart + 1;

      int32_t ahang = overlapFirstStart;
      int32_t bhang = nucleotides2.size() - overlapSecondEnd;

      if (overlapSecondStart > overlapFirstStart)
        ahang *= -1;

      if (nucleotides1.size() > overlapSecondEnd)
        bhang *= -1;

      OLC::Result* result = new OLC::Result(first_read_number, second_read_number, overlapLength, ahang, bhang);

      {
        std::lock_guard<std::mutex> result_lock(g_result_mutex);
        g_results.push_back(result);
      }
    }
    else
    {
      std::vector<OLC::Minimizer> allMinimizers;
      allMinimizers.reserve(first_minimizer->size() + second_minimizer->size());

      for (size_t i = 0; i < first_minimizer->size(); ++i)
        allMinimizers.push_back((*first_minimizer)[i]);

      std::sort(allMinimizers.begin(), allMinimizers.end());

      for (size_t i = 0; i < second_minimizer->size(); ++i)
      {
        if (!std::binary_search(allMinimizers.begin(), allMinimizers.end(), (*second_minimizer)[i]))
          allMinimizers.push_back((*second_minimizer)[i]);
      }

      std::sort(allMinimizers.begin(), allMinimizers.end());

      std::vector<int> codedSequence1;
      codedSequence1.reserve(first_minimizer->size());

      for (size_t i = 0; i < first_minimizer->size(); ++i)
      {
        const auto lower = std::lower_bound(allMinimizers.begin(), allMinimizers.end(), (*first_minimizer)[i]);
        codedSequence1.emplace_back(std::distance(allMinimizers.begin(), lower));
      }

      std::vector<int> codedSequence2;
      codedSequence2.reserve(second_minimizer->size());

      for (size_t i = 0; i < second_minimizer->size(); ++i)
      {
        const auto lower = std::lower_bound(allMinimizers.begin(), allMinimizers.end(), (*second_minimizer)[i]);
        codedSequence2.emplace_back(std::distance(allMinimizers.begin(), lower));
      }

      allMinimizers.clear();
      std::vector<OLC::Minimizer>().swap(allMinimizers);

      const OLC::Overlap overlap = OLC::compare(codedSequence1, codedSequence2);
      const uint32_t overlapFirstEnd = (*first_minimizer)[overlap.getEndFirst()].getPosition() + (*first_minimizer)[overlap.getEndFirst()].size();
      const uint32_t overlapSecondEnd = (*second_minimizer)[overlap.getEndSecond()].getPosition() + (*second_minimizer)[overlap.getEndSecond()].size();
      const uint32_t overlapFirstStart = (*first_minimizer)[overlap.getStartFirst()].getPosition();
      const uint32_t overlapSecondStart = (*second_minimizer)[overlap.getStartSecond()].getPosition();
      const uint32_t overlapLength = overlapFirstEnd - overlapFirstStart + 1;
      int32_t ahang = overlapFirstStart;
      int32_t bhang = nucleotides2.size() - overlapSecondEnd;

      if (overlapSecondStart > overlapFirstStart)
        ahang *= -1;

      if (nucleotides1.size() > overlapSecondEnd)
        bhang *= -1;

      OLC::Result* result = new OLC::Result(first_read_number, second_read_number, overlapLength, ahang, bhang);

      {
        std::lock_guard<std::mutex> result_lock(g_result_mutex);
        g_results.push_back(result);
      }

    }
  }
}

int main(int argc, char** argv)
{
  std::ios_base::sync_with_stdio(false);

  if (argc != 4)
  {
    std::cout << "Usage: " << argv[0] << " <minimum overlap length L> <FASTQ or FASTA file> <output file>\n";
    return 1;
  }

  // file with the data
  const std::string file = std::string(argv[2]);

  // output file
  const std::string output = std::string(argv[3]);

  // L is the minimum overlap length
  const uint32_t L = std::stoi(argv[1]);

  // window size
  const uint32_t w = (L + 1) / 2;

  // size of the k-mer
  const uint32_t k = (L + 1) / 2;

  // read phase
  OLC::InputFileReader reader(file);
  const std::vector<OLC::Sequence*> sequences = reader.readSequences();
  std::vector<std::vector<OLC::Minimizer>*> minimizers;

  uint32_t max_sequence_size = 0;

  for (size_t i = 0; i < sequences.size(); ++i)
  {
    const auto sequence = sequences[i]->getNucleotides()->getSequence();

    if (max_sequence_size < sequence.size())
      max_sequence_size = sequence.size();

    // calculate minimizers - both interior and end minimizers
    if (sequence.size() >= SEQUENCE_THRESHOLD_LENGTH)
      minimizers.push_back(minimize(sequence, w, k));
    else
      minimizers.push_back(nullptr);
  }

  // generate tasks so we can do this in parallel if possible
  std::queue<std::tuple<uint32_t, uint32_t>> tasks;

  for (uint32_t i = 0; i < sequences.size(); ++i)
  {
    for (uint32_t j = i + 1; j < sequences.size(); ++j)
    {
      g_sequence_pairs.emplace(i + 1, sequences[i], j + 1, sequences[j]);
      g_minimizer_pairs.emplace(i + 1, minimizers[i], j + 1, minimizers[j]);
    }
  }

  // use concurrent minimizer matching
  uint32_t num_threads = std::thread::hardware_concurrency();

  // scale thread number based on sequence size
  if (10000 <= max_sequence_size && max_sequence_size <= 100000)
    num_threads >>= 1;
  else if (100000 <= max_sequence_size)
    num_threads = 1;

  std::vector<std::thread> threads(3);

  for (uint8_t i = 0; i < threads.size(); ++i)
    threads[i] = std::thread(worker);

  for (uint8_t i = 0; i < threads.size(); ++i)
    threads[i].join();

  std::ofstream output_stream(output);

  for (size_t i = 0; i < g_results.size(); ++i)
  {
    auto identifiers = g_results[i]->getIdentifiers();

    output_stream << "{OVL\nadj:N\nrds:"<< std::get<0>(identifiers) << "," << std::get<1>(identifiers) << "\nscr:0\nahg:" << g_results[i]->getAhng() << "\nbhg:" << g_results[i]->getBhng() << "\n}\n";
  }

  output_stream.close();

  // cleanup
  for (size_t i = 0; i < minimizers.size(); ++i)
    delete minimizers[i];

  for (size_t i = 0; i < sequences.size(); ++i)
    delete sequences[i];

  for (size_t i = 0; i < g_results.size(); ++i)
    delete g_results[i];

  return 0;
}
<commit_msg>main: protect against trivial case of empty overlap<commit_after>#include <iostream>
#include <mutex>
#include <queue>
#include <thread>
#include <tuple>
#include <condition_variable>
#include <algorithm>

#include "input_file_reader.hpp"
#include "minimize.hpp"
#include "comparator.hpp"
#include "result.hpp"
#include "minimizer.hpp"

// mutex for shared resources
static std::mutex g_resource_mutex;

// mutex for result vector
static std::mutex g_result_mutex;

// global queue with two pointers to the sequences
// they are compared directly if the both sequence lengths are small enough
static std::queue<std::tuple<uint32_t, OLC::Sequence*, uint32_t, OLC::Sequence*>> g_sequence_pairs;

// global queue with two pointers to vectors of minimizers
// we use this instead if the sequences are too long
static std::queue<std::tuple<uint32_t, std::vector<OLC::Minimizer>*, uint32_t, std::vector<OLC::Minimizer>*>> g_minimizer_pairs;

// global vector with results
static std::vector<OLC::Result*> g_results;

static const uint32_t SEQUENCE_THRESHOLD_LENGTH = 20000;

void worker()
{
  while(true)
  {
    // Get the task and remove it from the pool
    uint32_t first_read_number;
    OLC::Sequence* first_sequence;
    std::vector<OLC::Minimizer>* first_minimizer;

    uint32_t second_read_number;
    OLC::Sequence* second_sequence;
    std::vector<OLC::Minimizer>* second_minimizer;

    {
      std::lock_guard<std::mutex> resource_lock(g_resource_mutex);

      if (g_sequence_pairs.empty())
        return;

      std::tie(first_read_number, first_sequence, second_read_number, second_sequence) = g_sequence_pairs.front();
      g_sequence_pairs.pop();
      std::tie(first_read_number, first_minimizer, second_read_number, second_minimizer) = g_minimizer_pairs.front();
      g_minimizer_pairs.pop();
    }

    // Pull out the wrapped nucleotide vectors
    const std::vector<OLC::Nucleotide> nucleotides1 = first_sequence->getNucleotides()->getSequence();
    const std::vector<OLC::Nucleotide> nucleotides2 = second_sequence->getNucleotides()->getSequence();

    // If small enough, no need to use minimizers
    if (nucleotides1.size() < SEQUENCE_THRESHOLD_LENGTH && nucleotides2.size() < SEQUENCE_THRESHOLD_LENGTH)
    {
      const OLC::Overlap overlap = compare(nucleotides1, nucleotides2);
      const uint32_t overlapFirstEnd = overlap.getEndFirst();
      const uint32_t overlapSecondEnd = overlap.getEndSecond();
      const uint32_t overlapFirstStart = overlap.getStartFirst();
      const uint32_t overlapSecondStart = overlap.getStartSecond();
      const uint32_t overlapLength = overlapFirstEnd - overlapFirstStart + 1;

      int32_t ahang = overlapFirstStart;
      int32_t bhang = nucleotides2.size() - overlapSecondEnd;

      if (overlapSecondStart > overlapFirstStart)
        ahang *= -1;

      if (nucleotides1.size() > overlapSecondEnd)
        bhang *= -1;

      OLC::Result* result = new OLC::Result(first_read_number, second_read_number, overlapLength, ahang, bhang);

      {
        std::lock_guard<std::mutex> result_lock(g_result_mutex);
        g_results.push_back(result);
      }
    }
    else
    {
      std::vector<OLC::Minimizer> allMinimizers;
      allMinimizers.reserve(first_minimizer->size() + second_minimizer->size());

      for (size_t i = 0; i < first_minimizer->size(); ++i)
        allMinimizers.push_back((*first_minimizer)[i]);

      std::sort(allMinimizers.begin(), allMinimizers.end());

      for (size_t i = 0; i < second_minimizer->size(); ++i)
      {
        if (!std::binary_search(allMinimizers.begin(), allMinimizers.end(), (*second_minimizer)[i]))
          allMinimizers.push_back((*second_minimizer)[i]);
      }

      std::sort(allMinimizers.begin(), allMinimizers.end());

      std::vector<int> codedSequence1;
      codedSequence1.reserve(first_minimizer->size());

      for (size_t i = 0; i < first_minimizer->size(); ++i)
      {
        const auto lower = std::lower_bound(allMinimizers.begin(), allMinimizers.end(), (*first_minimizer)[i]);
        codedSequence1.emplace_back(std::distance(allMinimizers.begin(), lower));
      }

      std::vector<int> codedSequence2;
      codedSequence2.reserve(second_minimizer->size());

      for (size_t i = 0; i < second_minimizer->size(); ++i)
      {
        const auto lower = std::lower_bound(allMinimizers.begin(), allMinimizers.end(), (*second_minimizer)[i]);
        codedSequence2.emplace_back(std::distance(allMinimizers.begin(), lower));
      }

      allMinimizers.clear();
      std::vector<OLC::Minimizer>().swap(allMinimizers);

      const OLC::Overlap overlap = OLC::compare(codedSequence1, codedSequence2);
      const uint32_t overlapFirstEnd = (*first_minimizer)[overlap.getEndFirst()].getPosition() + (*first_minimizer)[overlap.getEndFirst()].size();
      const uint32_t overlapSecondEnd = (*second_minimizer)[overlap.getEndSecond()].getPosition() + (*second_minimizer)[overlap.getEndSecond()].size();
      const uint32_t overlapFirstStart = (*first_minimizer)[overlap.getStartFirst()].getPosition();
      const uint32_t overlapSecondStart = (*second_minimizer)[overlap.getStartSecond()].getPosition();
      const uint32_t overlapLength = overlapFirstEnd - overlapFirstStart + 1;
      int32_t ahang = overlapFirstStart;
      int32_t bhang = nucleotides2.size() - overlapSecondEnd;

      if (overlapSecondStart > overlapFirstStart)
        ahang *= -1;

      if (nucleotides1.size() > overlapSecondEnd)
        bhang *= -1;

      OLC::Result* result = new OLC::Result(first_read_number, second_read_number, overlapLength, ahang, bhang);

      if (overlapLength > 0)
      {
        std::lock_guard<std::mutex> result_lock(g_result_mutex);
        g_results.push_back(result);
      }

    }
  }
}

int main(int argc, char** argv)
{
  std::ios_base::sync_with_stdio(false);

  if (argc != 4)
  {
    std::cout << "Usage: " << argv[0] << " <minimum overlap length L> <FASTQ or FASTA file> <output file>\n";
    return 1;
  }

  // file with the data
  const std::string file = std::string(argv[2]);

  // output file
  const std::string output = std::string(argv[3]);

  // L is the minimum overlap length
  const uint32_t L = std::stoi(argv[1]);

  // window size
  const uint32_t w = (L + 1) / 2;

  // size of the k-mer
  const uint32_t k = (L + 1) / 2;

  // read phase
  OLC::InputFileReader reader(file);
  const std::vector<OLC::Sequence*> sequences = reader.readSequences();
  std::vector<std::vector<OLC::Minimizer>*> minimizers;

  uint32_t max_sequence_size = 0;

  for (size_t i = 0; i < sequences.size(); ++i)
  {
    const auto sequence = sequences[i]->getNucleotides()->getSequence();

    if (max_sequence_size < sequence.size())
      max_sequence_size = sequence.size();

    // calculate minimizers - both interior and end minimizers
    if (sequence.size() >= SEQUENCE_THRESHOLD_LENGTH)
      minimizers.push_back(minimize(sequence, w, k));
    else
      minimizers.push_back(nullptr);
  }

  // generate tasks so we can do this in parallel if possible
  std::queue<std::tuple<uint32_t, uint32_t>> tasks;

  for (uint32_t i = 0; i < sequences.size(); ++i)
  {
    for (uint32_t j = i + 1; j < sequences.size(); ++j)
    {
      g_sequence_pairs.emplace(i + 1, sequences[i], j + 1, sequences[j]);
      g_minimizer_pairs.emplace(i + 1, minimizers[i], j + 1, minimizers[j]);
    }
  }

  // use concurrent minimizer matching
  uint32_t num_threads = std::thread::hardware_concurrency();

  // scale thread number based on sequence size
  if (10000 <= max_sequence_size && max_sequence_size <= 100000)
    num_threads >>= 1;
  else if (100000 <= max_sequence_size)
    num_threads = 1;

  std::vector<std::thread> threads(3);

  for (uint8_t i = 0; i < threads.size(); ++i)
    threads[i] = std::thread(worker);

  for (uint8_t i = 0; i < threads.size(); ++i)
    threads[i].join();

  std::ofstream output_stream(output);

  for (size_t i = 0; i < g_results.size(); ++i)
  {
    auto identifiers = g_results[i]->getIdentifiers();

    output_stream << "{OVL\nadj:N\nrds:"<< std::get<0>(identifiers) << "," << std::get<1>(identifiers) << "\nscr:0\nahg:" << g_results[i]->getAhng() << "\nbhg:" << g_results[i]->getBhng() << "\n}\n";
  }

  output_stream.close();

  // cleanup
  for (size_t i = 0; i < minimizers.size(); ++i)
    delete minimizers[i];

  for (size_t i = 0; i < sequences.size(); ++i)
    delete sequences[i];

  for (size_t i = 0; i < g_results.size(); ++i)
    delete g_results[i];

  return 0;
}
<|endoftext|>


<commit_before>/*
 * main.cpp
 *
 * main file for derelict app
 *
 * starts GLUT and runs callbacks
 */

#include <iostream>
#include <GL/glfw.h>

#include "Key.h"
#include "Cam.h"
#include "Player.h"
#include "World.h"

#include "DisplayFuncs.h"

World w;

void Init() {
	glClearColor(1, 1, 1, 0);

	w.Load("world/main.world");
}

void Display() {
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	w.Draw();

	glPushMatrix();

	glTranslatef(0, 0, 5.0);

	glColor3f(1, 0, 0);

	Pyramid();

	glTranslatef(0, 0, 5.0);

	glColor3f(0, 1, 0);

	Cube();

	glPopMatrix();
}

void Update() {
	w.Update();
}

int main(int argc, char ** argv) {
	glfwInit();

	glfwOpenWindow(800, 600, 0, 0, 0, 0, 16, 0, GLFW_WINDOW);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	Init();

	glfwSetKeyCallback(Key::KeyEvent);
	glfwSetWindowSizeCallback(Cam::ResizeCallback);

	bool running = true;

	while(running) {
		Display();

		Update();
		Key::I().Update();

		glfwSwapBuffers();

		running = !glfwGetKey(GLFW_KEY_ESC) &&
		          glfwGetWindowParam(GLFW_OPENED);

		glfwSleep(0.01);
	}

	glfwCloseWindow();

	glfwTerminate();
}
<commit_msg>Added glfw mouse callbacks in main<commit_after>/*
 * main.cpp
 *
 * main file for derelict app
 *
 * starts GLUT and runs callbacks
 */

#include <iostream>
#include <GL/glfw.h>

#include "Key.h"
#include "Cam.h"
#include "Player.h"
#include "World.h"
#include "Mouse.h"

#include "DisplayFuncs.h"

World w;

void Init() {
	glClearColor(1, 1, 1, 0);

	w.Load("world/main.world");
}

void Display() {
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	w.Draw();

	glPushMatrix();

	glTranslatef(0, 0, 5.0);

	glColor3f(1, 0, 0);

	Pyramid();

	glTranslatef(0, 0, 5.0);

	glColor3f(0, 1, 0);

	Cube();

	glPopMatrix();
}

void Update() {
	w.Update();
}

int main(int argc, char ** argv) {
	glfwInit();

	glfwOpenWindow(800, 600, 0, 0, 0, 0, 16, 0, GLFW_WINDOW);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	Init();

	glfwSetKeyCallback(Key::KeyEvent);
	glfwSetWindowSizeCallback(Cam::ResizeCallback);

	glfwSetMousePosCallback(Mouse::MouseMove);
	glfwSetMouseButtonCallback(Mouse::MouseButton);

	bool running = true;

	while(running) {
		Display();

		Update();
		Key::I().Update();

		glfwSwapBuffers();

		running = !glfwGetKey(GLFW_KEY_ESC) &&
		          glfwGetWindowParam(GLFW_OPENED);

		glfwSleep(0.01);
	}

	glfwCloseWindow();

	glfwTerminate();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <list>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <netdb.h>
#include <pwd.h>
#include <sys/socket.h>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost::algorithm;

//Virtual Base Class
class Base  {
    public:
        Base(){};
        //Function Inherited by each class
        virtual bool evaluate() = 0;
};

// Command Class that each command will inherit from
class Command: public Base {
    private:

    //Vector of commands
    vector<string> commandVec;

    public:

    //Contructor to take in vector and set it to commands vectors
    Command(vector<string>s){
        commandVec = s;
    }
    bool evaluate(){

        //exit if cmd is "exit"
        if(commandVec[0] == "exit")
            exit(0);

        //this chunk is to format the vector in the way we want it
        vector<char *> temp2;
        for(unsigned int i = 0; i < commandVec.size(); i++) {
            temp2.push_back(const_cast<char *>(commandVec.at(i).c_str()));
        }
        temp2.push_back('\0'); //'\0 is to make sure there is a null char in c-str'
        char** arr = &temp2[0];

        //here we will use fork() so we can do multiple process at once
        int status;
        pid_t pid = fork();
        if (pid < 0) { //to chck if fork failed
            perror("FORK has FAILED");
            exit(1);
        }
        else if (pid == 0) {
            //if it reaches here, you can pass into execvp
            //execvp will do all the work for you
            execvp(const_cast<char *>(arr[0]), arr);
            //if it reaches here there is some error
            exit(127); // exit 127 "command not found"
        }
        else if(pid > 0){
            //have to wait until child finishes
            // use wait pid or wait ???? waitpid(pid, &status, 0);
            wait(&status);
            if(wait(&status) != -1){
                perror("ERROR: wait");
            }
            if(WIFEXITED(status)){
                if(WEXITSTATUS(status) == 0) {

                    //program is succesful
                    return true;
                }
                else {

                    //this return is false, then the program failed but exiting was normal
                    return false;
                }
            }
            else{

                //the program messed up and exited abnormally
                perror("EXIT: ABNORMAL CHILD");
                return false;
            }
        }
        return false;
    }
};

class Connectors : public Base {
    private:
        Connectors(){};

    protected:
        bool leftCommand; //command b4 the connector
        Base* rightCommand; //command @ft3r the connect0r
};

//will run the rightCommand if the LeftCommand fails
class Or : public Connectors{
    public:
    Or(bool l, Base* r){
        leftCommand = l; rightCommand = r;
    }
    bool evaluate(){
        if(!leftCommand)
            return rightCommand->evaluate();
        return false;
    }
};

//will always attempt to run rightCommand
class Semicolon : public Connectors{
    public:
    Semicolon(bool l, Base* r){
        leftCommand = l; rightCommand = r;
    }
    bool evaluate{
        return rightCommand->evaluate();
    }
};

class Or : public Connectors {
    public:
        Or(bool first, Base* right) {leftCommand = first; rightCommand = right}
        bool evaluate() {
            if (!leftCommand) {
                return rightCommand->evaluate();
            }
            else {
                return false;
            }
        }
};

vector<string> parser(string toSplit, const char* delimiters) {
    char* toTokenize = new char[toSplit.size() + 1];
    strcpy(toTokenize, toSplit.c_str());
    toTokenize[toSplit.size() + 1] = '\0';
    char* cutThis;
    //begin parsing
    cutThis = strtok(toTokenize, delimiters);
    vector<string> returnThis;
    while (cutThis != NULL) {
        string currWord(cutThis);
        trim(currWord);
        returnThis.push_back(currWord);
        cutThis = strtok(NULL, delimiters);
    }
    return returnThis;
}

int main () {

    //take user input
    string initialCommand = "";

    while (true) { //infinite loop is there until exit is found
        //this is the extra credit part
        string login = getlogin();
        char hostname[100];
        gethostname(hostname, 100);
        cout << "[" << login << "@" << hostname << "] $ ";

        getline(cin, initialCommand);
        trim(initialCommand);
        bool noCMD = false;
        if(initialCommand == ""){
            noCMD = true;
        }
        while(noCMD == false){
            //FIXME:: NEED TO ADD STUFF HERE

            noCMD = true; //this means done with this command and wants next one
        }

    }

    return 0;
}
<commit_msg>Added && connector because it got deleted -my bad<commit_after>#include <iostream>
#include <vector>
#include <list>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <netdb.h>
#include <pwd.h>
#include <sys/socket.h>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost::algorithm;

//Virtual Base Class
class Base  {
    public:
        Base(){};
        //Function Inherited by each class
        virtual bool evaluate() = 0;
};

// Command Class that each command will inherit from
class Command: public Base {
    private:

    //Vector of commands
    vector<string> commandVec;

    public:

    //Contructor to take in vector and set it to commands vectors
    Command(vector<string>s){
        commandVec = s;
    }
    bool evaluate(){

        //exit if cmd is "exit"
        if(commandVec[0] == "exit")
            exit(0);

        //this chunk is to format the vector in the way we want it
        vector<char *> temp2;
        for(unsigned int i = 0; i < commandVec.size(); i++) {
            temp2.push_back(const_cast<char *>(commandVec.at(i).c_str()));
        }
        temp2.push_back('\0'); //'\0 is to make sure there is a null char in c-str'
        char** arr = &temp2[0];

        //here we will use fork() so we can do multiple process at once
        int status;
        pid_t pid = fork();
        if (pid < 0) { //to chck if fork failed
            perror("FORK has FAILED");
            exit(1);
        }
        else if (pid == 0) {
            //if it reaches here, you can pass into execvp
            //execvp will do all the work for you
            execvp(const_cast<char *>(arr[0]), arr);
            //if it reaches here there is some error
            exit(127); // exit 127 "command not found"
        }
        else if(pid > 0){
            //have to wait until child finishes
            // use wait pid or wait ???? waitpid(pid, &status, 0);
            wait(&status);
            if(wait(&status) != -1){
                perror("ERROR: wait");
            }
            if(WIFEXITED(status)){
                if(WEXITSTATUS(status) == 0) {

                    //program is succesful
                    return true;
                }
                else {

                    //this return is false, then the program failed but exiting was normal
                    return false;
                }
            }
            else{

                //the program messed up and exited abnormally
                perror("EXIT: ABNORMAL CHILD");
                return false;
            }
        }
        return false;
    }
};

class Connectors : public Base {
    private:
        Connectors(){};

    protected:
        bool leftCommand; //command b4 the connector
        Base* rightCommand; //command @ft3r the connect0r
};

//will run the rightcommand if leftcommand succededs
class And : public Connectors{
    public:
    Or(bool l, Base* r){
        leftCommand = l; rightCommand = r;
    }
    bool evaluate(){
        if(leftCommand)
            return rightCommand->evaluate();
        return false;
    }
};

//will run the rightCommand if the LeftCommand fails
class Or : public Connectors{
    public:
    Or(bool l, Base* r){
        leftCommand = l; rightCommand = r;
    }
    bool evaluate(){
        if(!leftCommand)
            return rightCommand->evaluate();
        return false;
    }
};

//will always attempt to run rightCommand
class Semicolon : public Connectors{
    public:
    Semicolon(bool l, Base* r){
        leftCommand = l; rightCommand = r;
    }
    bool evaluate{
        return rightCommand->evaluate();
    }
};

class Or : public Connectors {
    public:
        Or(bool first, Base* right) {leftCommand = first; rightCommand = right}
        bool evaluate() {
            if (!leftCommand) {
                return rightCommand->evaluate();
            }
            else {
                return false;
            }
        }
};

vector<string> parser(string toSplit, const char* delimiters) {
    char* toTokenize = new char[toSplit.size() + 1];
    strcpy(toTokenize, toSplit.c_str());
    toTokenize[toSplit.size() + 1] = '\0';
    char* cutThis;
    //begin parsing
    cutThis = strtok(toTokenize, delimiters);
    vector<string> returnThis;
    while (cutThis != NULL) {
        string currWord(cutThis);
        trim(currWord);
        returnThis.push_back(currWord);
        cutThis = strtok(NULL, delimiters);
    }
    return returnThis;
}

int main () {

    //take user input
    string initialCommand = "";

    while (true) { //infinite loop is there until exit is found
        //this is the extra credit part
        string login = getlogin();
        char hostname[100];
        gethostname(hostname, 100);
        cout << "[" << login << "@" << hostname << "] $ ";

        getline(cin, initialCommand);
        trim(initialCommand);
        bool noCMD = false;
        if(initialCommand == ""){
            noCMD = true;
        }
        while(noCMD == false){
            //FIXME:: NEED TO ADD STUFF HERE

            noCMD = true; //this means done with this command and wants next one
        }

    }

    return 0;
}
<|endoftext|>


<commit_before>#include "make_ref.h"
#include "InfoVisitor.h"
#include "board_def.h"
#include "Board.h"
#include "NPC.h"
#include "GhostFactory.h"
#include "FPSManipulator.h"

#include <iostream>
#include <thread>

#include <osg/ShapeDrawable>
#include <osg/Geode>
#include <osgViewer/Viewer>
#include <osg/MatrixTransform>
#include <osg/Fog>
#include <osgUtil/Optimizer>
#include <osgDB/ReadFile>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/OrbitManipulator>
#include <osg/Texture2D>

bool loadShaderSource(osg::Shader* obj, const std::string& fileName )
{
    std::string fqFileName = osgDB::findDataFile(fileName);
    if( fqFileName.length() == 0 )
    {
        std::cout << "File \"" << fileName << "\" not found." << std::endl;
        return false;
    }
    bool success = obj->loadShaderSourceFromFile( fqFileName.c_str());
    if ( !success  )
    {
        std::cout << "Couldn't load file: " << fileName << std::endl;
        return false;
    }
    else
    {
        return true;
    }
}

int main(int argc, char** argv)
{
    osg::ArgumentParser arguments( &argc, argv );

    std::string dbPath;
    arguments.read("--db_path", dbPath);

    std::srand ( unsigned ( std::time(0) ) );

    auto board = Board(boardDefinition, boardSizeX, boardSizeY, dbPath);
    auto ghostFactory = GhostFactory();

    auto main_obj = make_ref<osg::Group>();
    main_obj->addChild(board.draw().get());

    auto ghostModel = osgDB::readNodeFile(dbPath + "/cow.osg");
    auto ghostCount = 16;
    while(ghostCount--)
    {
        main_obj->addChild(ghostFactory.drawGhost(board, ghostModel).get());
    }

    // init rotate
    auto init_rotate = make_ref<osg::MatrixTransform>();
    init_rotate->setMatrix( osg::Matrix::rotate(osg::PI * 2, osg::Vec3(1.0f, 0.0f, 0.0f)) );

    // chain rotates
    init_rotate->addChild(main_obj);

    // Root group
    auto root = make_ref<osg::Group>();
    root->addChild(init_rotate);

    // Setup fog
    if(FogEnabled) {
        osg::ref_ptr<osg::Fog> fog = new osg::Fog;
        fog->setMode( osg::Fog::EXP2 );
        fog->setStart( 0.0f );
        fog->setEnd(board.getFieldSizeX() * 20);
        fog->setDensity(0.02);
        fog->setColor( osg::Vec4(0., 0., 0., 1.0) );

        root->getOrCreateStateSet()->setAttributeAndModes(fog.get());
    }

    // Start viewer
    osgViewer::Viewer viewer;

    double height = std::min(board.getFieldSizeX(), board.getFieldSizeY()) / 1.5;

    auto fpsManipulator = make_ref<FPSManipulator>(board, viewer);
    fpsManipulator->setHomePosition(
        osg::Vec3d(board.getFieldCenterX(1), board.getFieldCenterY(10), height),
        osg::Vec3d(0.0f, 0.0f, height),
        osg::Vec3d(0.0f, 0.0f, 1.0f)
    );

    auto keySwitch = make_ref<osgGA::KeySwitchMatrixManipulator>();
    keySwitch->addNumberedMatrixManipulator(make_ref<osgGA::OrbitManipulator>());
    keySwitch->addNumberedMatrixManipulator(fpsManipulator);
    viewer.setCameraManipulator(keySwitch);

    viewer.home();
    viewer.setSceneData( root );

    osgViewer::Viewer::Windows windows;
    viewer.getWindows(windows);
    viewer.getCamera()->setClearColor(osg::Vec4{0, 0, 0, 0});

    viewer.getCamera()->getView()->setLightingMode(osg::View::HEADLIGHT);
    auto defaultLight = viewer.getCamera()->getView()->getLight();
    defaultLight->setDiffuse(osg::Vec4(0, 0, 0, 1));
    defaultLight->setAmbient(osg::Vec4(0, 0, 0, 1));
    defaultLight->setSpecular(osg::Vec4(0, 0, 0, 1));

    auto lightSource = make_ref<osg::LightSource>();
    lightSource->setReferenceFrame(osg::LightSource::ABSOLUTE_RF);
    auto light = lightSource->getLight();
    const osg::Vec3 lightPosition{1.5, -.5, -1}; // right, down, front
    light->setPosition(osg::Vec4{lightPosition, 1});
    light->setDirection(osg::Vec3{0, 0, -1} * 30 - lightPosition);
    light->setSpotExponent(200);
    light->setSpotCutoff(100);
    light->setDiffuse(osg::Vec4(1, 1, 1, 1));
    light->setAmbient(osg::Vec4(0.6, 0.6, 0.6, 1));
    light->setSpecular(osg::Vec4(1, 1, 1, 1));
    light->setLinearAttenuation(0.005);
    light->setConstantAttenuation(0);

    root->addChild(lightSource);

    // Shaders
    auto program = make_ref<osg::Program>();
    auto fragmentObject = make_ref<osg::Shader>(osg::Shader::FRAGMENT);
    loadShaderSource(fragmentObject, dbPath + "/shader.frag");
    auto vertexObject = make_ref<osg::Shader>(osg::Shader::VERTEX);
    loadShaderSource(vertexObject, dbPath + "/shader.vert");
    program->addShader(vertexObject);
    program->addShader(fragmentObject);
    root->getOrCreateStateSet()->setAttributeAndModes(program, osg::StateAttribute::ON);

    root->getOrCreateStateSet()->addUniform(new osg::Uniform("samplerName", TEXTURE_UNIT));
    root->getOrCreateStateSet()->addUniform(new osg::Uniform("Shininess", BoardObjectsShininess));
    root->getOrCreateStateSet()->addUniform(new osg::Uniform("FogEnabled", FogEnabled));

    // Optimize
    osgUtil::Optimizer optimzer;
    optimzer.optimize(root);

    return viewer.run();
}
<commit_msg>Tweak fog density and light attenuation.<commit_after>#include "make_ref.h"
#include "InfoVisitor.h"
#include "board_def.h"
#include "Board.h"
#include "NPC.h"
#include "GhostFactory.h"
#include "FPSManipulator.h"

#include <iostream>
#include <thread>

#include <osg/ShapeDrawable>
#include <osg/Geode>
#include <osgViewer/Viewer>
#include <osg/MatrixTransform>
#include <osg/Fog>
#include <osgUtil/Optimizer>
#include <osgDB/ReadFile>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/OrbitManipulator>
#include <osg/Texture2D>

bool loadShaderSource(osg::Shader* obj, const std::string& fileName )
{
    std::string fqFileName = osgDB::findDataFile(fileName);
    if( fqFileName.length() == 0 )
    {
        std::cout << "File \"" << fileName << "\" not found." << std::endl;
        return false;
    }
    bool success = obj->loadShaderSourceFromFile( fqFileName.c_str());
    if ( !success  )
    {
        std::cout << "Couldn't load file: " << fileName << std::endl;
        return false;
    }
    else
    {
        return true;
    }
}

int main(int argc, char** argv)
{
    osg::ArgumentParser arguments( &argc, argv );

    std::string dbPath;
    arguments.read("--db_path", dbPath);

    std::srand ( unsigned ( std::time(0) ) );

    auto board = Board(boardDefinition, boardSizeX, boardSizeY, dbPath);
    auto ghostFactory = GhostFactory();

    auto main_obj = make_ref<osg::Group>();
    main_obj->addChild(board.draw().get());

    auto ghostModel = osgDB::readNodeFile(dbPath + "/cow.osg");
    auto ghostCount = 16;
    while(ghostCount--)
    {
        main_obj->addChild(ghostFactory.drawGhost(board, ghostModel).get());
    }

    // init rotate
    auto init_rotate = make_ref<osg::MatrixTransform>();
    init_rotate->setMatrix( osg::Matrix::rotate(osg::PI * 2, osg::Vec3(1.0f, 0.0f, 0.0f)) );

    // chain rotates
    init_rotate->addChild(main_obj);

    // Root group
    auto root = make_ref<osg::Group>();
    root->addChild(init_rotate);

    // Setup fog
    if(FogEnabled) {
        osg::ref_ptr<osg::Fog> fog = new osg::Fog;
        fog->setMode( osg::Fog::EXP2 );
        fog->setStart( 0.0f );
        fog->setEnd(board.getFieldSizeX() * 20);
        fog->setDensity(0.015);
        fog->setColor( osg::Vec4(0., 0., 0., 1.0) );

        root->getOrCreateStateSet()->setAttributeAndModes(fog.get());
    }

    // Start viewer
    osgViewer::Viewer viewer;

    double height = std::min(board.getFieldSizeX(), board.getFieldSizeY()) / 1.5;

    auto fpsManipulator = make_ref<FPSManipulator>(board, viewer);
    fpsManipulator->setHomePosition(
        osg::Vec3d(board.getFieldCenterX(1), board.getFieldCenterY(10), height),
        osg::Vec3d(0.0f, 0.0f, height),
        osg::Vec3d(0.0f, 0.0f, 1.0f)
    );

    auto keySwitch = make_ref<osgGA::KeySwitchMatrixManipulator>();
    keySwitch->addNumberedMatrixManipulator(make_ref<osgGA::OrbitManipulator>());
    keySwitch->addNumberedMatrixManipulator(fpsManipulator);
    viewer.setCameraManipulator(keySwitch);

    viewer.home();
    viewer.setSceneData( root );

    osgViewer::Viewer::Windows windows;
    viewer.getWindows(windows);
    viewer.getCamera()->setClearColor(osg::Vec4{0, 0, 0, 0});

    viewer.getCamera()->getView()->setLightingMode(osg::View::HEADLIGHT);
    auto defaultLight = viewer.getCamera()->getView()->getLight();
    defaultLight->setDiffuse(osg::Vec4(0, 0, 0, 1));
    defaultLight->setAmbient(osg::Vec4(0, 0, 0, 1));
    defaultLight->setSpecular(osg::Vec4(0, 0, 0, 1));

    auto lightSource = make_ref<osg::LightSource>();
    lightSource->setReferenceFrame(osg::LightSource::ABSOLUTE_RF);
    auto light = lightSource->getLight();
    const osg::Vec3 lightPosition{1.5, -1, -1}; // right, down, front
    light->setPosition(osg::Vec4{lightPosition, 1});
    light->setDirection(osg::Vec3{0, 0, -1} * 30 - lightPosition);
    light->setSpotExponent(200);
    light->setSpotCutoff(100);
    light->setDiffuse(osg::Vec4(1, 1, 1, 1));
    light->setAmbient(osg::Vec4(0.6, 0.6, 0.6, 1));
    light->setSpecular(osg::Vec4(1, 1, 1, 1));
    light->setLinearAttenuation(0.001);
    light->setConstantAttenuation(0.5);

    root->addChild(lightSource);

    // Shaders
    auto program = make_ref<osg::Program>();
    auto fragmentObject = make_ref<osg::Shader>(osg::Shader::FRAGMENT);
    loadShaderSource(fragmentObject, dbPath + "/shader.frag");
    auto vertexObject = make_ref<osg::Shader>(osg::Shader::VERTEX);
    loadShaderSource(vertexObject, dbPath + "/shader.vert");
    program->addShader(vertexObject);
    program->addShader(fragmentObject);
    root->getOrCreateStateSet()->setAttributeAndModes(program, osg::StateAttribute::ON);

    root->getOrCreateStateSet()->addUniform(new osg::Uniform("samplerName", TEXTURE_UNIT));
    root->getOrCreateStateSet()->addUniform(new osg::Uniform("Shininess", BoardObjectsShininess));
    root->getOrCreateStateSet()->addUniform(new osg::Uniform("FogEnabled", FogEnabled));

    // Optimize
    osgUtil::Optimizer optimzer;
    optimzer.optimize(root);

    return viewer.run();
}
<|endoftext|>


<commit_before>/*
 * TODO list
 * - Line wrapping on current input buffer
 * - Response lines for each line of input after CR
 * - Better / alternative build method instead of eclipse maintained makefiles
 * - Movable input cursor / implement delete key
 * - Open / close console with some key
 */

#include <console/Console.h>
#include <drawing/DisplayBox.h>
#include <drawing/DrawingContext.h>
#include <drawing/TextBox.h>
#include <gl/glut.h>
#include <GL/gl.h>
#include <sstream>
#include <string>

#define WINDOW_WIDTH  1024
#define WINDOW_HEIGHT 760

#define WORLD_MOVE_STEP_SIZE 3

void handleMouseMove(int x, int y);

DrawingContext context;
Console console(&context);
TextBox coordinates(&context);

void handleDisplay() {
  // Clear the window
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glClear(GL_COLOR_BUFFER_BIT);

  console.draw();
  coordinates.draw();

  // Swap buffers (color buffers, makes previous render visible)
  glutSwapBuffers();
}

void handleKeyboard(unsigned char key, int x, int y) {
#pragma unused (x, y)

  if(key == '`' || key == '~') {
    static bool motionCallbackSet = false;
    if(motionCallbackSet) {
      motionCallbackSet = false;
      glutPassiveMotionFunc(NULL);
    }
    else {
      motionCallbackSet = true;
      glutPassiveMotionFunc(handleMouseMove);
    }
  }
  else if(console.handleKey(key)) {
    glutPostRedisplay();
  }
}

void handleSpecialKeyboard(int key, int x, int y) {
#pragma unused (x, y)

  int modifiers = glutGetModifiers();
  if(modifiers & GLUT_ACTIVE_SHIFT) {
    switch(key) {
      case GLUT_KEY_UP:
        console.moveY(WORLD_MOVE_STEP_SIZE);
        break;

      case GLUT_KEY_DOWN:
        console.moveY(-WORLD_MOVE_STEP_SIZE);
        break;

      case GLUT_KEY_LEFT:
        console.moveX(-WORLD_MOVE_STEP_SIZE);
        break;

      case GLUT_KEY_RIGHT:
        console.moveX(WORLD_MOVE_STEP_SIZE);
        break;

      default:
        return;
      }

      glutPostRedisplay();
  }
}

void handleMouse(int button, int state, int x, int y) {
  handleMouseMove(x, y);
}

void handleMouseMove(int x, int y) {
  std::ostringstream msg;
    msg << "X:" << x << ", Y:" << y;

  coordinates.setText(msg.str());
  glutPostRedisplay();
}

/* Note that this results with an origin in the center of the screen.  Not sure that
 * I'm too wild about this so that might change in the future.
 */
void handleReshape(int width, int height) {
  GLdouble size;
  GLdouble aspect;

  /* Use the whole window. */
  glViewport(0, 0, width, height);

  /* We are going to do some 2-D orthographic drawing. */
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  size = (GLdouble) ((width >= height) ? width : height) / 2.0;
  if (width <= height) {
    aspect = (GLdouble) height / (GLdouble) width;
    glOrtho(-size, size, -size * aspect, size * aspect, -100000.0, 100000.0);
  } else {
    aspect = (GLdouble) width / (GLdouble) height;
    glOrtho(-size * aspect, size * aspect, -size, size, -100000.0, 100000.0);
  }

  /* Make the world and window coordinates coincide so that 1.0 in */
  /* model space equals one pixel in window space.                 */
  glScaled(aspect, aspect, 1.0);

  /* Now determine where to draw things. */
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  coordinates.setLocation(-width / 2.0 + 2, height / 2.0 - 2);
}

int main(int argc, char** argv) {
  glutInit(&argc, argv);
  glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  glutCreateWindow("OGL Console Sandbox");

  console.setLocation(-240, 120);
  console.setSize(480, 240);

  coordinates.setLocation(0, 0);
  coordinates.setSize(150, 30);

  glutDisplayFunc(handleDisplay);
  glutKeyboardFunc(handleKeyboard);
  glutSpecialFunc(handleSpecialKeyboard);
  glutReshapeFunc(handleReshape);
  glutMouseFunc(handleMouse);

  glutMainLoop();
}
<commit_msg>Update todo list<commit_after>/*
 * TODO list
 * - Line wrapping on current input buffer
 * - Response lines for each line of input after CR
 * - Better / alternative build method instead of eclipse maintained makefiles?
 * - Movable input cursor / implement delete key
 * - Add toggle button for console
 * - Up arrow should cycle the previous buffer lines into the current line
 * - Auto-complete on commands for tab key?
 * - Implement concept of focus via mouse location in order to route to appropriate key handlers
 * - Add FPS to coordinates box
 * - Add window dimensions to coordinates box
 * - Add toggle button for coordinates box
 * - Build scene graph object to better manage visual objects
 */

#include <console/Console.h>
#include <drawing/DisplayBox.h>
#include <drawing/DrawingContext.h>
#include <drawing/TextBox.h>
#include <gl/glut.h>
#include <GL/gl.h>
#include <sstream>
#include <string>

#define WINDOW_WIDTH  1024
#define WINDOW_HEIGHT 760

#define WORLD_MOVE_STEP_SIZE 3

void handleMouseMove(int x, int y);

DrawingContext context;
Console console(&context);
TextBox coordinates(&context);

void handleDisplay() {
  // Clear the window
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glClear(GL_COLOR_BUFFER_BIT);

  console.draw();
  coordinates.draw();

  // Swap buffers (color buffers, makes previous render visible)
  glutSwapBuffers();
}

void handleKeyboard(unsigned char key, int x, int y) {
#pragma unused (x, y)

  if(key == '`' || key == '~') {
    static bool motionCallbackSet = false;
    if(motionCallbackSet) {
      motionCallbackSet = false;
      glutPassiveMotionFunc(NULL);
    }
    else {
      motionCallbackSet = true;
      glutPassiveMotionFunc(handleMouseMove);
    }
  }
  else if(console.handleKey(key)) {
    glutPostRedisplay();
  }
}

void handleSpecialKeyboard(int key, int x, int y) {
#pragma unused (x, y)

  int modifiers = glutGetModifiers();
  if(modifiers & GLUT_ACTIVE_SHIFT) {
    switch(key) {
      case GLUT_KEY_UP:
        console.moveY(WORLD_MOVE_STEP_SIZE);
        break;

      case GLUT_KEY_DOWN:
        console.moveY(-WORLD_MOVE_STEP_SIZE);
        break;

      case GLUT_KEY_LEFT:
        console.moveX(-WORLD_MOVE_STEP_SIZE);
        break;

      case GLUT_KEY_RIGHT:
        console.moveX(WORLD_MOVE_STEP_SIZE);
        break;

      default:
        return;
      }

      glutPostRedisplay();
  }
}

void handleMouse(int button, int state, int x, int y) {
  handleMouseMove(x, y);
}

void handleMouseMove(int x, int y) {
  std::ostringstream msg;
    msg << "X:" << x << ", Y:" << y;

  coordinates.setText(msg.str());
  glutPostRedisplay();
}

/* Note that this results with an origin in the center of the screen.  Not sure that
 * I'm too wild about this so that might change in the future.
 */
void handleReshape(int width, int height) {
  GLdouble size;
  GLdouble aspect;

  /* Use the whole window. */
  glViewport(0, 0, width, height);

  /* We are going to do some 2-D orthographic drawing. */
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  size = (GLdouble) ((width >= height) ? width : height) / 2.0;
  if (width <= height) {
    aspect = (GLdouble) height / (GLdouble) width;
    glOrtho(-size, size, -size * aspect, size * aspect, -100000.0, 100000.0);
  } else {
    aspect = (GLdouble) width / (GLdouble) height;
    glOrtho(-size * aspect, size * aspect, -size, size, -100000.0, 100000.0);
  }

  /* Make the world and window coordinates coincide so that 1.0 in */
  /* model space equals one pixel in window space.                 */
  glScaled(aspect, aspect, 1.0);

  /* Now determine where to draw things. */
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  coordinates.setLocation(-width / 2.0 + 2, height / 2.0 - 2);
}

int main(int argc, char** argv) {
  glutInit(&argc, argv);
  glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  glutCreateWindow("OGL Console Sandbox");

  console.setLocation(-240, 120);
  console.setSize(480, 240);

  coordinates.setLocation(0, 0);
  coordinates.setSize(150, 30);

  glutDisplayFunc(handleDisplay);
  glutKeyboardFunc(handleKeyboard);
  glutSpecialFunc(handleSpecialKeyboard);
  glutReshapeFunc(handleReshape);
  glutMouseFunc(handleMouse);

  glutMainLoop();
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <time.h>
#include <unistd.h>
#include <sys/shm.h>

#include "bcm_host.h"

#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

#include "shader.h"

#include "inotify-cxx.h"

typedef struct {
    uint32_t screen_width;
    uint32_t screen_height;

    int mouse_x;
    int mouse_y;

    // OpenGL|ES objects
    EGLDisplay display;
    EGLSurface surface;
    EGLContext context;

    GLuint buf;

} CUBE_STATE_T;
static CUBE_STATE_T _state, *state=&_state;

bool* fragHasChanged;
std::string fragFile;
std::string vertSource =
"attribute vec4 a_position;"
"varying vec2 v_texcoord;"
"void main(void) {"
"    gl_Position = a_position;"
"    v_texcoord = a_position.xy*0.5+0.5;"
"}";

Shader shader;

static void init_ogl(CUBE_STATE_T *state){
    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
                                               0/*layer*/, &dst_rect, 0/*src*/,
                                               &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );

    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);

    // Set background color and clear buffers
    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );
}

static bool loadFromPath(const std::string& path, std::string* into) {
    std::ifstream file;
    std::string buffer;

    file.open(path.c_str());
    if(!file.is_open()) return false;
    while(!file.eof()) {
        getline(file, buffer);
        (*into) += buffer + "\n";
    }

    file.close();
    return true;
}

static void draw(CUBE_STATE_T *state){

    if(*fragHasChanged) {
        std::string fragSource;
        if(loadFromPath(fragFile, &fragSource)){
            state->shader.detach(GL_FRAGMENT_SHADER | GL_VERTEX_SHADER);
            state->shader.build(fragSource,vertSource);
            *fragHasChanged = false;
        }
    }

    // Now render to the main frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER,0);
    // Clear the background (not really necessary I suppose)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    state->shader.use();

    state->shader.sendUniform("u_time", ((float)clock())/CLOCKS_PER_SEC);
    state->shader.sendUniform("u_mouse", state->mouse_x, state_mouse_y);
    state->shader.sendUniform("u_resolution",state->screen_width, state->screen_height);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glFlush();
    glFinish();

    eglSwapBuffers(state->display, state->surface);
}

static int get_mouse(CUBE_STATE_T *state){
    static int fd = -1;
    const int width=state->screen_width, height=state->screen_height;
    static int x=width, y=height;
    const int XSIGN = 1<<4, YSIGN = 1<<5;
    if (fd<0) {
       fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
    }
    if (fd>=0) {
        struct {char buttons, dx, dy; } m;
        while (1) {
           int bytes = read(fd, &m, sizeof m);
           if (bytes < (int)sizeof m) goto _exit;
           if (m.buttons&8) {
              break; // This bit should always be set
           }
           read(fd, &m, 1); // Try to sync up again
        }
        if (m.buttons&3)
           return m.buttons&3;
        x+=m.dx;
        y+=m.dy;
        if (m.buttons&XSIGN)
           x-=256;
        if (m.buttons&YSIGN)
           y-=256;
        if (x<0) x=0;
        if (y<0) y=0;
        if (x>width) x=width;
        if (y>height) y=height;
   }

_exit:
   state->mouse_x = x;
   state->mouse_y = y;
   return 0;
}

void drawThread() {
    setup();
    while (1) {
        if (get_mouse(state)) break;
        draw(state);
    }
}

void watchThread(const std::string& _file) {
    Inotify notify;

    InotifyWatch watch(".", IN_MODIFY);//IN_ALL_EVENTS);
    notify.Add(watch);

    for (;;) {

        if(!(*fragHasChanged)){
            notify.WaitForEvents();

            size_t count = notify.GetEventCount();
            while(count-- > 0) {
                InotifyEvent event;
                bool got_event = notify.GetEvent(&event);

                if(got_event){
                    std::string mask_str;
                    event.DumpTypes(mask_str);
                    std::string filename = event.GetName();
                    std::cout << "Child: " << filename << " have change " << mask_str << std::endl;
                    if (filename == _file){
                        *fragHasChanged = true;
                    }
                }
            }
        }
    }
}

void setup() {
    bcm_host_init();

    // Clear application state
    memset( state, 0, sizeof( *state ) );

    // Start OGLES
    init_ogl(state);

    //  Build shader;
    //
    std::string fragSource;
    if(!loadFromPath(fragFile, &fragSource)) {
        return;
    }
    state->shader.build(fragSource,vertSource);

    //  Make Quad
    //
    static const GLfloat vertex_data[] = {
        -1.0,-1.0,1.0,1.0,
        1.0,-1.0,1.0,1.0,
        1.0,1.0,1.0,1.0,
        -1.0,1.0,1.0,1.0
    };
    GLint posAttribut = state->shader.getAttribLocation("a_position");

    glClearColor ( 0.0, 1.0, 1.0, 1.0 );

    glGenBuffers(1, &state->buf);

    // Prepare viewport
    glViewport ( 0, 0, state->screen_width, state->screen_height );

    // Upload vertex data to a buffer
    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
                 vertex_data, GL_STATIC_DRAW);
    glVertexAttribPointer(posAttribut, 4, GL_FLOAT, 0, 16, 0);
    glEnableVertexAttribArray(posAttribut);

}

//==============================================================================

int main(int argc, char **argv){
    fragFile = std::string(argv[1]);

    int shmId = shmget(IPC_PRIVATE, sizeof(bool), 0666);
    pid_t pid = fork();
    fragHasChanged = (bool *) shmat(shmId, NULL, 0);

    switch(pid) {
        case -1: //error
        break;

        case 0: // child
        {
            *fragHasChanged = false;
            watchThread(fragFile);
        }
        break;

        default:
        {
            drawThread();

            kill(pid, SIGKILL);
        }
        break;
    }

    shmctl(shmId, IPC_RMID, NULL);
    return 0;
}

<commit_msg>reorganizing<commit_after>#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <time.h>
#include <unistd.h>
#include <sys/shm.h>

#include "bcm_host.h"

#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

#include "shader.h"

#include "inotify-cxx.h"

typedef struct {
    uint32_t screen_width;
    uint32_t screen_height;

    int mouse_x;
    int mouse_y;

    // OpenGL|ES objects
    EGLDisplay display;
    EGLSurface surface;
    EGLContext context;

    GLuint buf;

} CUBE_STATE_T;
static CUBE_STATE_T _state, *state=&_state;

bool* fragHasChanged;
std::string fragFile;
std::string vertSource =
"attribute vec4 a_position;"
"varying vec2 v_texcoord;"
"void main(void) {"
"    gl_Position = a_position;"
"    v_texcoord = a_position.xy*0.5+0.5;"
"}";

Shader shader;

static void init_ogl(CUBE_STATE_T *state){
    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
                                               0/*layer*/, &dst_rect, 0/*src*/,
                                               &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );

    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);

    // Set background color and clear buffers
    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );
}

static bool loadFromPath(const std::string& path, std::string* into) {
    std::ifstream file;
    std::string buffer;

    file.open(path.c_str());
    if(!file.is_open()) return false;
    while(!file.eof()) {
        getline(file, buffer);
        (*into) += buffer + "\n";
    }

    file.close();
    return true;
}

static void draw(CUBE_STATE_T *state){

    if(*fragHasChanged) {
        std::string fragSource;
        if(loadFromPath(fragFile, &fragSource)){
            shader.detach(GL_FRAGMENT_SHADER | GL_VERTEX_SHADER);
            shader.build(fragSource,vertSource);
            *fragHasChanged = false;
        }
    }

    // Now render to the main frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER,0);
    // Clear the background (not really necessary I suppose)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    shader.use();

    shader.sendUniform("u_time", ((float)clock())/CLOCKS_PER_SEC);
    shader.sendUniform("u_mouse", state->mouse_x, state_mouse_y);
    shader.sendUniform("u_resolution",state->screen_width, state->screen_height);

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glFlush();
    glFinish();

    eglSwapBuffers(state->display, state->surface);
}

static int get_mouse(CUBE_STATE_T *state){
    static int fd = -1;
    const int width=state->screen_width, height=state->screen_height;
    static int x=width, y=height;
    const int XSIGN = 1<<4, YSIGN = 1<<5;
    if (fd<0) {
       fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
    }
    if (fd>=0) {
        struct {char buttons, dx, dy; } m;
        while (1) {
           int bytes = read(fd, &m, sizeof m);
           if (bytes < (int)sizeof m) goto _exit;
           if (m.buttons&8) {
              break; // This bit should always be set
           }
           read(fd, &m, 1); // Try to sync up again
        }
        if (m.buttons&3)
           return m.buttons&3;
        x+=m.dx;
        y+=m.dy;
        if (m.buttons&XSIGN)
           x-=256;
        if (m.buttons&YSIGN)
           y-=256;
        if (x<0) x=0;
        if (y<0) y=0;
        if (x>width) x=width;
        if (y>height) y=height;
   }

_exit:
   state->mouse_x = x;
   state->mouse_y = y;
   return 0;
}

void drawThread() {
    setup();
    while (1) {
        if (get_mouse(state)) break;
        draw(state);
    }
}

void watchThread(const std::string& _file) {
    Inotify notify;

    InotifyWatch watch(".", IN_MODIFY);//IN_ALL_EVENTS);
    notify.Add(watch);

    for (;;) {

        if(!(*fragHasChanged)){
            notify.WaitForEvents();

            size_t count = notify.GetEventCount();
            while(count-- > 0) {
                InotifyEvent event;
                bool got_event = notify.GetEvent(&event);

                if(got_event){
                    std::string mask_str;
                    event.DumpTypes(mask_str);
                    std::string filename = event.GetName();
                    std::cout << "Child: " << filename << " have change " << mask_str << std::endl;
                    if (filename == _file){
                        *fragHasChanged = true;
                    }
                }
            }
        }
    }
}

void setup() {
    bcm_host_init();

    // Clear application state
    memset( state, 0, sizeof( *state ) );

    // Start OGLES
    init_ogl(state);

    //  Build shader;
    //
    std::string fragSource;
    if(!loadFromPath(fragFile, &fragSource)) {
        return;
    }
    shader.build(fragSource,vertSource);

    //  Make Quad
    //
    static const GLfloat vertex_data[] = {
        -1.0,-1.0,1.0,1.0,
        1.0,-1.0,1.0,1.0,
        1.0,1.0,1.0,1.0,
        -1.0,1.0,1.0,1.0
    };
    GLint posAttribut = shader.getAttribLocation("a_position");

    glClearColor ( 0.0, 1.0, 1.0, 1.0 );

    glGenBuffers(1, &state->buf);

    // Prepare viewport
    glViewport ( 0, 0, state->screen_width, state->screen_height );

    // Upload vertex data to a buffer
    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
                 vertex_data, GL_STATIC_DRAW);
    glVertexAttribPointer(posAttribut, 4, GL_FLOAT, 0, 16, 0);
    glEnableVertexAttribArray(posAttribut);

}

//==============================================================================

int main(int argc, char **argv){
    fragFile = std::string(argv[1]);

    int shmId = shmget(IPC_PRIVATE, sizeof(bool), 0666);
    pid_t pid = fork();
    fragHasChanged = (bool *) shmat(shmId, NULL, 0);

    switch(pid) {
        case -1: //error
        break;

        case 0: // child
        {
            *fragHasChanged = false;
            watchThread(fragFile);
        }
        break;

        default:
        {
            drawThread();

            kill(pid, SIGKILL);
        }
        break;
    }

    shmctl(shmId, IPC_RMID, NULL);
    return 0;
}

<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** main.cpp
**
** -------------------------------------------------------------------------*/

#include <iostream>

#include "rtc_base/ssladapter.h"
#include "rtc_base/thread.h"
#include "p2p/base/stunserver.h"

#include "PeerConnectionManager.h"
#include "HttpServerRequestHandler.h"

/* ---------------------------------------------------------------------------
**  main
** -------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
	const char* turnurl       = "";
	const char* defaultlocalstunurl  = "0.0.0.0:3478";
	const char* localstunurl  = NULL;
	const char* stunurl       = "stun.l.google.com:19302";
	int logLevel              = rtc::LERROR;
	const char* webroot       = "./html";
	std::string sslCertificate;
	webrtc::AudioDeviceModule::AudioLayer audioLayer = webrtc::AudioDeviceModule::kLinuxAlsaAudio;
	std::string streamName;
	std::map<std::string,std::string> urlList;

	std::string httpAddress("0.0.0.0:");
	std::string httpPort = "8000";
	const char * port = getenv("PORT");
	if (port)
	{
		httpPort = port;
	}
	httpAddress.append(httpPort);

	int c = 0;
	while ((c = getopt (argc, argv, "hVv::" "c:H:w:" "t:S::s::" "a::n:u:")) != -1)
	{
		switch (c)
		{
			case 'H': httpAddress = optarg; break;
			case 'c': sslCertificate = optarg; break;
			case 'w': webroot = optarg; break;

			case 't': turnurl = optarg; break;
			case 'S': localstunurl = optarg ? optarg : defaultlocalstunurl; stunurl = localstunurl; break;
			case 's': localstunurl = NULL; if (optarg) stunurl = optarg; break;

			case 'a': audioLayer = optarg ? (webrtc::AudioDeviceModule::AudioLayer)atoi(optarg) : webrtc::AudioDeviceModule::kDummyAudio; break;
			case 'n': streamName = optarg; break;
			case 'u': {
				if (!streamName.empty()) {
					urlList[streamName]=optarg;
					streamName.clear();
				}
			}
			break;

			case 'v':
				logLevel--;
				if (optarg) {
					logLevel-=strlen(optarg);
				}
			break;
			case 'V':
				std::cout << VERSION << std::endl;
				exit(0);
			break;
			case 'h':
			default:
				std::cout << argv[0] << " [-H http port] [-S[embeded stun address]] [-t [username:password@]turn_address] -[v[v]]  [url1]...[urln]" << std::endl;
				std::cout << argv[0] << " [-H http port] [-s[externel stun address]] [-t [username:password@]turn_address] -[v[v]] [url1]...[urln]" << std::endl;
				std::cout << argv[0] << " -V" << std::endl;
				std::cout << "\t -H hostname:port   : HTTP server binding (default "   << httpAddress    << ")"                   << std::endl;
				std::cout << "\t -w webroot         : path to get files"                                                          << std::endl;
				std::cout << "\t -c sslkeycert      : path to private key and certificate for HTTPS"                              << std::endl;

				std::cout << "\t -S[stun_address]   : start embeded STUN server bind to address (default " << defaultlocalstunurl << ")" << std::endl;
				std::cout << "\t -s[stun_address]   : use an external STUN server (default " << stunurl << ")"                    << std::endl;
				std::cout << "\t -t[username:password@]turn_address : use an external TURN relay server (default disabled)"       << std::endl;

				std::cout << "\t -a[audio layer]    : spefify audio capture layer to use (default:" << audioLayer << ")"          << std::endl;
				std::cout << "\t -n name -u url     : register a stream with name using url"                                      << std::endl;

				std::cout << "\t [url]              : url to register in the source list"                                         << std::endl;

				std::cout << "\t -v[v[v]]           : verbosity"                                                                  << std::endl;
				std::cout << "\t -V                 : print version"                                                              << std::endl;
				exit(0);
		}
	}

	while (optind<argc)
	{
		std::string url(argv[optind]);
		urlList[url]=url;
		optind++;
	}

	rtc::LogMessage::LogToDebug((rtc::LoggingSeverity)logLevel);
	rtc::LogMessage::LogTimestamps();
	rtc::LogMessage::LogThreads();
	std::cout << "Logger level:" <<  rtc::LogMessage::GetLogToDebug() << std::endl;

	rtc::Thread* thread = rtc::Thread::Current();
	rtc::InitializeSSL();

	// webrtc server
	PeerConnectionManager webRtcServer(stunurl, turnurl, urlList, audioLayer);
	if (!webRtcServer.InitializePeerConnection())
	{
		std::cout << "Cannot Initialize WebRTC server" << std::endl;
	}
	else
	{
		// http server
		std::vector<std::string> options;
		options.push_back("document_root");
		options.push_back(webroot);
		options.push_back("listening_ports");
		options.push_back(httpAddress);
		if (!sslCertificate.empty()) {
			options.push_back("ssl_certificate");
			options.push_back(sslCertificate);
		}

		try {
			std::cout << "HTTP Listen at " << httpAddress << std::endl;
			HttpServerRequestHandler httpServer(&webRtcServer, options);

			// start STUN server if needed
			std::unique_ptr<cricket::StunServer> stunserver;
			if (localstunurl != NULL)
			{
				rtc::SocketAddress server_addr;
				server_addr.FromString(localstunurl);
				rtc::AsyncUDPSocket* server_socket = rtc::AsyncUDPSocket::Create(thread->socketserver(), server_addr);
				if (server_socket)
				{
					stunserver.reset(new cricket::StunServer(server_socket));
					std::cout << "STUN Listening at " << server_addr.ToString() << std::endl;
				}
			}

			// mainloop
			thread->Run();

		} catch (const CivetException & ex) {
			std::cout << "Cannot Initialize start HTTP server exception:" << ex.what() << std::endl;
		}
	}

	rtc::CleanupSSL();
	return 0;
}

<commit_msg>add CORS header<commit_after>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** main.cpp
**
** -------------------------------------------------------------------------*/

#include <iostream>

#include "rtc_base/ssladapter.h"
#include "rtc_base/thread.h"
#include "p2p/base/stunserver.h"

#include "PeerConnectionManager.h"
#include "HttpServerRequestHandler.h"

/* ---------------------------------------------------------------------------
**  main
** -------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
	const char* turnurl       = "";
	const char* defaultlocalstunurl  = "0.0.0.0:3478";
	const char* localstunurl  = NULL;
	const char* stunurl       = "stun.l.google.com:19302";
	int logLevel              = rtc::LERROR;
	const char* webroot       = "./html";
	std::string sslCertificate;
	webrtc::AudioDeviceModule::AudioLayer audioLayer = webrtc::AudioDeviceModule::kLinuxAlsaAudio;
	std::string streamName;
	std::map<std::string,std::string> urlList;

	std::string httpAddress("0.0.0.0:");
	std::string httpPort = "8000";
	const char * port = getenv("PORT");
	if (port)
	{
		httpPort = port;
	}
	httpAddress.append(httpPort);

	int c = 0;
	while ((c = getopt (argc, argv, "hVv::" "c:H:w:" "t:S::s::" "a::n:u:")) != -1)
	{
		switch (c)
		{
			case 'H': httpAddress = optarg; break;
			case 'c': sslCertificate = optarg; break;
			case 'w': webroot = optarg; break;

			case 't': turnurl = optarg; break;
			case 'S': localstunurl = optarg ? optarg : defaultlocalstunurl; stunurl = localstunurl; break;
			case 's': localstunurl = NULL; if (optarg) stunurl = optarg; break;

			case 'a': audioLayer = optarg ? (webrtc::AudioDeviceModule::AudioLayer)atoi(optarg) : webrtc::AudioDeviceModule::kDummyAudio; break;
			case 'n': streamName = optarg; break;
			case 'u': {
				if (!streamName.empty()) {
					urlList[streamName]=optarg;
					streamName.clear();
				}
			}
			break;

			case 'v':
				logLevel--;
				if (optarg) {
					logLevel-=strlen(optarg);
				}
			break;
			case 'V':
				std::cout << VERSION << std::endl;
				exit(0);
			break;
			case 'h':
			default:
				std::cout << argv[0] << " [-H http port] [-S[embeded stun address]] [-t [username:password@]turn_address] -[v[v]]  [url1]...[urln]" << std::endl;
				std::cout << argv[0] << " [-H http port] [-s[externel stun address]] [-t [username:password@]turn_address] -[v[v]] [url1]...[urln]" << std::endl;
				std::cout << argv[0] << " -V" << std::endl;
				std::cout << "\t -H hostname:port   : HTTP server binding (default "   << httpAddress    << ")"                   << std::endl;
				std::cout << "\t -w webroot         : path to get files"                                                          << std::endl;
				std::cout << "\t -c sslkeycert      : path to private key and certificate for HTTPS"                              << std::endl;

				std::cout << "\t -S[stun_address]   : start embeded STUN server bind to address (default " << defaultlocalstunurl << ")" << std::endl;
				std::cout << "\t -s[stun_address]   : use an external STUN server (default " << stunurl << ")"                    << std::endl;
				std::cout << "\t -t[username:password@]turn_address : use an external TURN relay server (default disabled)"       << std::endl;

				std::cout << "\t -a[audio layer]    : spefify audio capture layer to use (default:" << audioLayer << ")"          << std::endl;
				std::cout << "\t -n name -u url     : register a stream with name using url"                                      << std::endl;

				std::cout << "\t [url]              : url to register in the source list"                                         << std::endl;

				std::cout << "\t -v[v[v]]           : verbosity"                                                                  << std::endl;
				std::cout << "\t -V                 : print version"                                                              << std::endl;
				exit(0);
		}
	}

	while (optind<argc)
	{
		std::string url(argv[optind]);
		urlList[url]=url;
		optind++;
	}

	rtc::LogMessage::LogToDebug((rtc::LoggingSeverity)logLevel);
	rtc::LogMessage::LogTimestamps();
	rtc::LogMessage::LogThreads();
	std::cout << "Logger level:" <<  rtc::LogMessage::GetLogToDebug() << std::endl;

	rtc::Thread* thread = rtc::Thread::Current();
	rtc::InitializeSSL();

	// webrtc server
	PeerConnectionManager webRtcServer(stunurl, turnurl, urlList, audioLayer);
	if (!webRtcServer.InitializePeerConnection())
	{
		std::cout << "Cannot Initialize WebRTC server" << std::endl;
	}
	else
	{
		// http server
		std::vector<std::string> options;
		options.push_back("document_root");
		options.push_back(webroot);
		options.push_back("access_control_allow_origin");
		options.push_back("*");
		options.push_back("listening_ports");
		options.push_back(httpAddress);
		if (!sslCertificate.empty()) {
			options.push_back("ssl_certificate");
			options.push_back(sslCertificate);
		}

		try {
			std::cout << "HTTP Listen at " << httpAddress << std::endl;
			HttpServerRequestHandler httpServer(&webRtcServer, options);

			// start STUN server if needed
			std::unique_ptr<cricket::StunServer> stunserver;
			if (localstunurl != NULL)
			{
				rtc::SocketAddress server_addr;
				server_addr.FromString(localstunurl);
				rtc::AsyncUDPSocket* server_socket = rtc::AsyncUDPSocket::Create(thread->socketserver(), server_addr);
				if (server_socket)
				{
					stunserver.reset(new cricket::StunServer(server_socket));
					std::cout << "STUN Listening at " << server_addr.ToString() << std::endl;
				}
			}

			// mainloop
			thread->Run();

		} catch (const CivetException & ex) {
			std::cout << "Cannot Initialize start HTTP server exception:" << ex.what() << std::endl;
		}
	}

	rtc::CleanupSSL();
	return 0;
}

<|endoftext|>