<commit_before>#pragma once
/*
* Covariant Mozart Utility Library: Any
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2017 Michael Lee(李登淳)
* Email: China-LDC@outlook.com
* Github: https://github.com/mikecovlee
* Website: http://ldc.atd3.cn
*
* Version: 17.5.1
*/
#include "./base.hpp"
#include "./memory.hpp"
#include <functional>
#include <iostream>

namespace std {
	template<typename T> std::string to_string(const T&)
	{
		throw cov::error("E000D");
	}
	template<> std::string to_string<std::string>(const std::string& str)
	{
		return str;
	}
	template<> std::string to_string<bool>(const bool& v)
	{
		if(v)
			return "true";
		else
			return "false";
	}
}
#define COV_ANY_POOL_SIZE 128
namespace cov {
	template<typename _Tp> class compare_helper {
		template<typename T,typename X=bool>struct matcher;
		template<typename T> static constexpr bool match(T*)
		{
			return false;
		}
		template<typename T> static constexpr bool match(matcher < T, decltype(std::declval<T>()==std::declval<T>()) > *)
		{
			return true;
		}
	public:
		static constexpr bool value = match < _Tp > (nullptr);
	};
	template<typename,bool> struct compare_if;
	template<typename T>struct compare_if<T,true> {
		static bool compare(const T& a,const T& b)
		{
			return a==b;
		}
	};
	template<typename T>struct compare_if<T,false> {
		static bool compare(const T& a,const T& b)
		{
			return &a==&b;
		}
	};
	template<typename T>bool compare(const T& a,const T& b)
	{
		return compare_if<T,compare_helper<T>::value>::compare(a,b);
	}
	template<typename _Tp> class hash_helper {
		template<typename T,decltype(&std::hash<T>::operator()) X>struct matcher;
		template<typename T> static constexpr bool match(T*)
		{
			return false;
		}
		template<typename T> static constexpr bool match(matcher<T,&std::hash<T>::operator()>*)
		{
			return true;
		}
	public:
		static constexpr bool value = match < _Tp > (nullptr);
	};
	template<typename,bool> struct hash_if;
	template<typename T>struct hash_if<T,true> {
		static std::size_t hash(const T& val)
		{
			static std::hash<T> gen;
			return gen(val);
		}
	};
	template<typename T>struct hash_if<T,false> {
		static std::size_t hash(const T& val)
		{
			throw cov::error("E000F");
		}
	};
	template<typename T>std::size_t hash(const T& val)
	{
		return hash_if<T,hash_helper<T>::value>::hash(val);
	}
	template<typename T>void detach(T& val)
	{
		// Do something if you want when data is copying.
	}
	class any final {
		class baseHolder {
		public:
			baseHolder() = default;
			virtual ~ baseHolder() = default;
			virtual const std::type_info& type() const = 0;
			virtual baseHolder* duplicate() = 0;
			virtual bool compare(const baseHolder *) const = 0;
			virtual std::string to_string() const = 0;
			virtual std::size_t hash() const = 0;
			virtual void detach() = 0;
			virtual void kill() = 0;
		};
		template < typename T > class holder:public baseHolder {
		protected:
			T mDat;
		public:
			static cov::allocator<holder<T>,COV_ANY_POOL_SIZE> allocator;
			holder() = default;
			template<typename...ArgsT>holder(ArgsT&&...args):mDat(std::forward<ArgsT>(args)...) {}
			virtual ~ holder() = default;
			virtual const std::type_info& type() const override
			{
				return typeid(T);
			}
			virtual baseHolder* duplicate() override
			{
				return allocator.alloc(mDat);
			}
			virtual bool compare(const baseHolder* obj) const override
			{
				if (obj->type()==this->type()) {
					const holder<T>* ptr=dynamic_cast<const holder<T>*>(obj);
					return ptr!=nullptr?cov::compare(mDat,ptr->data()):false;
				}
				return false;
			}
			virtual std::string to_string() const override
			{
				return std::to_string(mDat);
			}
			virtual std::size_t hash() const override
			{
				return cov::hash<T>(mDat);
			}
			virtual void detach() override
			{
				cov::detach(mDat);
			}
			virtual void kill() override
			{
				allocator.free(this);
			}
			T& data()
			{
				return mDat;
			}
			const T& data() const
			{
				return mDat;
			}
			void data(const T& dat)
			{
				mDat = dat;
			}
		};
		using size_t=unsigned long;
		struct proxy {
			size_t refcount=1;
			baseHolder* data=nullptr;
			proxy()=default;
			proxy(size_t rc,baseHolder* d):refcount(rc),data(d) {}
			~proxy()
			{
				if(data!=nullptr)
					data->kill();
			}
		};
		static cov::allocator<proxy,COV_ANY_POOL_SIZE> allocator;
		proxy* mDat=nullptr;
		proxy* duplicate() const noexcept
		{
			if(mDat!=nullptr) {
				++mDat->refcount;
			}
			return mDat;
		}
		void recycle() noexcept
		{
			if(mDat!=nullptr) {
				--mDat->refcount;
				if(mDat->refcount==0) {
					allocator.free(mDat);
					mDat=nullptr;
				}
			}
		}
		any(proxy* dat):mDat(dat) {}
	public:
		void swap(any& obj,bool raw=false) noexcept
		{
			if(this->mDat!=nullptr&&obj.mDat!=nullptr&&raw) {
				baseHolder* tmp=this->mDat->data;
				this->mDat->data=obj.mDat->data;
				obj.mDat->data=tmp;
			}
			else {
				proxy* tmp=this->mDat;
				this->mDat=obj.mDat;
				obj.mDat=tmp;
			}
		}
		void swap(any&& obj,bool raw=false) noexcept
		{
			if(this->mDat!=nullptr&&obj.mDat!=nullptr&&raw) {
				baseHolder* tmp=this->mDat->data;
				this->mDat->data=obj.mDat->data;
				obj.mDat->data=tmp;
			}
			else {
				proxy* tmp=this->mDat;
				this->mDat=obj.mDat;
				obj.mDat=tmp;
			}
		}
		void clone() noexcept
		{
			if(mDat!=nullptr) {
				proxy* dat=allocator.alloc(1,mDat->data->duplicate());
				recycle();
				mDat=dat;
			}
		}
		bool usable() const noexcept
		{
			return mDat!=nullptr;
		}
		template<typename T,typename...ArgsT>static any make(ArgsT&&...args)
		{
			return any(allocator.alloc(1,holder<T>::allocator.alloc(std::forward<ArgsT>(args)...)));
		}
		any()=default;
		template<typename T> any(const T & dat):mDat(allocator.alloc(1,holder<T>::allocator.alloc(dat))) {}
		any(const any & v):mDat(v.duplicate()) {}
		any(any&& v) noexcept
		{
			swap(std::forward<any>(v));
		}
		~any()
		{
			recycle();
		}
		const std::type_info& type() const
		{
			return this->mDat!=nullptr?this->mDat->data->type():typeid(void);
		}
		std::string to_string() const
		{
			if(this->mDat==nullptr)
				return "Null";
			return this->mDat->data->to_string();
		}
		std::size_t hash() const
		{
			if(this->mDat==nullptr)
				return cov::hash<void*>(nullptr);
			return this->mDat->data->hash();
		}
		void detach()
		{
			if(this->mDat!=nullptr)
				this->mDat->data->detach();
		}
		bool is_same(const any& obj) const
		{
			return this->mDat==obj.mDat;
		}
		any& operator=(const any& var)
		{
			if(&var!=this) {
				recycle();
				mDat=var.duplicate();
			}
			return *this;
		}
		any& operator=(any&& var) noexcept
		{
			if(&var!=this)
				swap(std::forward<any>(var));
			return *this;
		}
		bool operator==(const any& var) const
		{
			return usable()?this->mDat->data->compare(var.mDat->data):!var.usable();
		}
		bool operator!=(const any& var)const
		{
			return usable()?!this->mDat->data->compare(var.mDat->data):var.usable();
		}
		template<typename T> T& val(bool raw=false)
		{
			if(typeid(T)!=this->type())
				throw cov::error("E0006");
			if(this->mDat==nullptr)
				throw cov::error("E0005");
			if(!raw)
				clone();
			return dynamic_cast<holder<T>*>(this->mDat->data)->data();
		}
		template<typename T> const T& val(bool raw=false) const
		{
			if(typeid(T)!=this->type())
				throw cov::error("E0006");
			if(this->mDat==nullptr)
				throw cov::error("E0005");
			return dynamic_cast<const holder<T>*>(this->mDat->data)->data();
		}
		template<typename T> const T& const_val() const
		{
			if(typeid(T)!=this->type())
				throw cov::error("E0006");
			if(this->mDat==nullptr)
				throw cov::error("E0005");
			return dynamic_cast<const holder<T>*>(this->mDat->data)->data();
		}
		template<typename T> operator const T&() const
		{
			return this->const_val<T>();
		}
		void assign(const any& obj,bool raw=false)
		{
			if(&obj!=this&&obj.mDat!=mDat) {
				if(mDat!=nullptr&&obj.mDat!=nullptr&&raw) {
					mDat->data->kill();
					mDat->data=obj.mDat->data->duplicate();
				}
				else {
					recycle();
					if(obj.mDat!=nullptr)
						mDat=allocator.alloc(1,obj.mDat->data->duplicate());
					else
						mDat=nullptr;
				}
			}
		}
		template<typename T> void assign(const T& dat,bool raw=false)
		{
			if(raw) {
				mDat->data->kill();
				mDat->data=holder<T>::allocator.alloc(dat);
			}
			else {
				recycle();
				mDat=allocator.alloc(1,holder<T>::allocator.alloc(dat));
			}
		}
		template<typename T> any & operator=(const T& dat)
		{
			assign(dat);
			return *this;
		}
	};
	template<typename T> cov::allocator<any::holder<T>,COV_ANY_POOL_SIZE> any::holder<T>::allocator;
	cov::allocator<any::proxy,COV_ANY_POOL_SIZE> any::allocator;
	template<int N> class any::holder<char[N]>:public any::holder<std::string> {
	public:
		using holder<std::string>::holder;
	};
	template<> class any::holder<std::type_info>:public any::holder<std::type_index> {
	public:
		using holder<std::type_index>::holder;
	};
}

std::ostream& operator<<(std::ostream& out,const cov::any& val)
{
	out<<val.to_string();
	return out;
}

namespace std {
	template<> struct hash<cov::any> {
		std::size_t operator()(const cov::any& val) const
		{
			return val.hash();
		}
	};
}
<commit_msg>适当调整缓冲池的大小<commit_after>#pragma once
/*
* Covariant Mozart Utility Library: Any
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright (C) 2017 Michael Lee(李登淳)
* Email: China-LDC@outlook.com
* Github: https://github.com/mikecovlee
* Website: http://ldc.atd3.cn
*
* Version: 17.5.1
*/
#include "./base.hpp"
#include "./memory.hpp"
#include <functional>
#include <iostream>

namespace std {
	template<typename T> std::string to_string(const T&)
	{
		throw cov::error("E000D");
	}
	template<> std::string to_string<std::string>(const std::string& str)
	{
		return str;
	}
	template<> std::string to_string<bool>(const bool& v)
	{
		if(v)
			return "true";
		else
			return "false";
	}
}
#define COV_ANY_POOL_SIZE 96
namespace cov {
	template<typename _Tp> class compare_helper {
		template<typename T,typename X=bool>struct matcher;
		template<typename T> static constexpr bool match(T*)
		{
			return false;
		}
		template<typename T> static constexpr bool match(matcher < T, decltype(std::declval<T>()==std::declval<T>()) > *)
		{
			return true;
		}
	public:
		static constexpr bool value = match < _Tp > (nullptr);
	};
	template<typename,bool> struct compare_if;
	template<typename T>struct compare_if<T,true> {
		static bool compare(const T& a,const T& b)
		{
			return a==b;
		}
	};
	template<typename T>struct compare_if<T,false> {
		static bool compare(const T& a,const T& b)
		{
			return &a==&b;
		}
	};
	template<typename T>bool compare(const T& a,const T& b)
	{
		return compare_if<T,compare_helper<T>::value>::compare(a,b);
	}
	template<typename _Tp> class hash_helper {
		template<typename T,decltype(&std::hash<T>::operator()) X>struct matcher;
		template<typename T> static constexpr bool match(T*)
		{
			return false;
		}
		template<typename T> static constexpr bool match(matcher<T,&std::hash<T>::operator()>*)
		{
			return true;
		}
	public:
		static constexpr bool value = match < _Tp > (nullptr);
	};
	template<typename,bool> struct hash_if;
	template<typename T>struct hash_if<T,true> {
		static std::size_t hash(const T& val)
		{
			static std::hash<T> gen;
			return gen(val);
		}
	};
	template<typename T>struct hash_if<T,false> {
		static std::size_t hash(const T& val)
		{
			throw cov::error("E000F");
		}
	};
	template<typename T>std::size_t hash(const T& val)
	{
		return hash_if<T,hash_helper<T>::value>::hash(val);
	}
	template<typename T>void detach(T& val)
	{
		// Do something if you want when data is copying.
	}
	class any final {
		class baseHolder {
		public:
			baseHolder() = default;
			virtual ~ baseHolder() = default;
			virtual const std::type_info& type() const = 0;
			virtual baseHolder* duplicate() = 0;
			virtual bool compare(const baseHolder *) const = 0;
			virtual std::string to_string() const = 0;
			virtual std::size_t hash() const = 0;
			virtual void detach() = 0;
			virtual void kill() = 0;
		};
		template < typename T > class holder:public baseHolder {
		protected:
			T mDat;
		public:
			static cov::allocator<holder<T>,COV_ANY_POOL_SIZE> allocator;
			holder() = default;
			template<typename...ArgsT>holder(ArgsT&&...args):mDat(std::forward<ArgsT>(args)...) {}
			virtual ~ holder() = default;
			virtual const std::type_info& type() const override
			{
				return typeid(T);
			}
			virtual baseHolder* duplicate() override
			{
				return allocator.alloc(mDat);
			}
			virtual bool compare(const baseHolder* obj) const override
			{
				if (obj->type()==this->type()) {
					const holder<T>* ptr=dynamic_cast<const holder<T>*>(obj);
					return ptr!=nullptr?cov::compare(mDat,ptr->data()):false;
				}
				return false;
			}
			virtual std::string to_string() const override
			{
				return std::to_string(mDat);
			}
			virtual std::size_t hash() const override
			{
				return cov::hash<T>(mDat);
			}
			virtual void detach() override
			{
				cov::detach(mDat);
			}
			virtual void kill() override
			{
				allocator.free(this);
			}
			T& data()
			{
				return mDat;
			}
			const T& data() const
			{
				return mDat;
			}
			void data(const T& dat)
			{
				mDat = dat;
			}
		};
		using size_t=unsigned long;
		struct proxy {
			size_t refcount=1;
			baseHolder* data=nullptr;
			proxy()=default;
			proxy(size_t rc,baseHolder* d):refcount(rc),data(d) {}
			~proxy()
			{
				if(data!=nullptr)
					data->kill();
			}
		};
		static cov::allocator<proxy,COV_ANY_POOL_SIZE> allocator;
		proxy* mDat=nullptr;
		proxy* duplicate() const noexcept
		{
			if(mDat!=nullptr) {
				++mDat->refcount;
			}
			return mDat;
		}
		void recycle() noexcept
		{
			if(mDat!=nullptr) {
				--mDat->refcount;
				if(mDat->refcount==0) {
					allocator.free(mDat);
					mDat=nullptr;
				}
			}
		}
		any(proxy* dat):mDat(dat) {}
	public:
		void swap(any& obj,bool raw=false) noexcept
		{
			if(this->mDat!=nullptr&&obj.mDat!=nullptr&&raw) {
				baseHolder* tmp=this->mDat->data;
				this->mDat->data=obj.mDat->data;
				obj.mDat->data=tmp;
			}
			else {
				proxy* tmp=this->mDat;
				this->mDat=obj.mDat;
				obj.mDat=tmp;
			}
		}
		void swap(any&& obj,bool raw=false) noexcept
		{
			if(this->mDat!=nullptr&&obj.mDat!=nullptr&&raw) {
				baseHolder* tmp=this->mDat->data;
				this->mDat->data=obj.mDat->data;
				obj.mDat->data=tmp;
			}
			else {
				proxy* tmp=this->mDat;
				this->mDat=obj.mDat;
				obj.mDat=tmp;
			}
		}
		void clone() noexcept
		{
			if(mDat!=nullptr) {
				proxy* dat=allocator.alloc(1,mDat->data->duplicate());
				recycle();
				mDat=dat;
			}
		}
		bool usable() const noexcept
		{
			return mDat!=nullptr;
		}
		template<typename T,typename...ArgsT>static any make(ArgsT&&...args)
		{
			return any(allocator.alloc(1,holder<T>::allocator.alloc(std::forward<ArgsT>(args)...)));
		}
		any()=default;
		template<typename T> any(const T & dat):mDat(allocator.alloc(1,holder<T>::allocator.alloc(dat))) {}
		any(const any & v):mDat(v.duplicate()) {}
		any(any&& v) noexcept
		{
			swap(std::forward<any>(v));
		}
		~any()
		{
			recycle();
		}
		const std::type_info& type() const
		{
			return this->mDat!=nullptr?this->mDat->data->type():typeid(void);
		}
		std::string to_string() const
		{
			if(this->mDat==nullptr)
				return "Null";
			return this->mDat->data->to_string();
		}
		std::size_t hash() const
		{
			if(this->mDat==nullptr)
				return cov::hash<void*>(nullptr);
			return this->mDat->data->hash();
		}
		void detach()
		{
			if(this->mDat!=nullptr)
				this->mDat->data->detach();
		}
		bool is_same(const any& obj) const
		{
			return this->mDat==obj.mDat;
		}
		any& operator=(const any& var)
		{
			if(&var!=this) {
				recycle();
				mDat=var.duplicate();
			}
			return *this;
		}
		any& operator=(any&& var) noexcept
		{
			if(&var!=this)
				swap(std::forward<any>(var));
			return *this;
		}
		bool operator==(const any& var) const
		{
			return usable()?this->mDat->data->compare(var.mDat->data):!var.usable();
		}
		bool operator!=(const any& var)const
		{
			return usable()?!this->mDat->data->compare(var.mDat->data):var.usable();
		}
		template<typename T> T& val(bool raw=false)
		{
			if(typeid(T)!=this->type())
				throw cov::error("E0006");
			if(this->mDat==nullptr)
				throw cov::error("E0005");
			if(!raw)
				clone();
			return dynamic_cast<holder<T>*>(this->mDat->data)->data();
		}
		template<typename T> const T& val(bool raw=false) const
		{
			if(typeid(T)!=this->type())
				throw cov::error("E0006");
			if(this->mDat==nullptr)
				throw cov::error("E0005");
			return dynamic_cast<const holder<T>*>(this->mDat->data)->data();
		}
		template<typename T> const T& const_val() const
		{
			if(typeid(T)!=this->type())
				throw cov::error("E0006");
			if(this->mDat==nullptr)
				throw cov::error("E0005");
			return dynamic_cast<const holder<T>*>(this->mDat->data)->data();
		}
		template<typename T> operator const T&() const
		{
			return this->const_val<T>();
		}
		void assign(const any& obj,bool raw=false)
		{
			if(&obj!=this&&obj.mDat!=mDat) {
				if(mDat!=nullptr&&obj.mDat!=nullptr&&raw) {
					mDat->data->kill();
					mDat->data=obj.mDat->data->duplicate();
				}
				else {
					recycle();
					if(obj.mDat!=nullptr)
						mDat=allocator.alloc(1,obj.mDat->data->duplicate());
					else
						mDat=nullptr;
				}
			}
		}
		template<typename T> void assign(const T& dat,bool raw=false)
		{
			if(raw) {
				mDat->data->kill();
				mDat->data=holder<T>::allocator.alloc(dat);
			}
			else {
				recycle();
				mDat=allocator.alloc(1,holder<T>::allocator.alloc(dat));
			}
		}
		template<typename T> any & operator=(const T& dat)
		{
			assign(dat);
			return *this;
		}
	};
	template<typename T> cov::allocator<any::holder<T>,COV_ANY_POOL_SIZE> any::holder<T>::allocator;
	cov::allocator<any::proxy,COV_ANY_POOL_SIZE> any::allocator;
	template<int N> class any::holder<char[N]>:public any::holder<std::string> {
	public:
		using holder<std::string>::holder;
	};
	template<> class any::holder<std::type_info>:public any::holder<std::type_index> {
	public:
		using holder<std::type_index>::holder;
	};
}

std::ostream& operator<<(std::ostream& out,const cov::any& val)
{
	out<<val.to_string();
	return out;
}

namespace std {
	template<> struct hash<cov::any> {
		std::size_t operator()(const cov::any& val) const
		{
			return val.hash();
		}
	};
}
<|endoftext|>


<commit_before>/******************************************************************************
*	Main script for the 2017 RoboFishy Scripps AUV
******************************************************************************/

#include "Mapper.h"

// Multithreading
#include <pthread.h>
#include <sched.h>
#include <unistd.h>

// Sampling Values
#define SAMPLE_RATE 200 // sample rate of main control loop (Hz)
#define DT 0.005				// timestep; make sure this is equal to 1/SAMPLE_RATE!

// Conversion Factors
#define UNITS_KPA 0.1		// converts pressure from mbar to kPa

/******************************************************************************
* Controller Gains
******************************************************************************/

// Yaw Controller
#define KP_YAW 0.01
#define KI_YAW 0
#define KD_YAW 1

// Depth Controller
#define KP_DEPTH 0
#define KI_DEPTH 0
#define KD_DEPTH 0

// Saturation Constants
#define YAW_SAT 1			// upper limit of yaw controller
#define DEPTH_SAT 1		// upper limit of depth controller
#define INT_SAT 10		// upper limit of integral windup
#define DINT_SAT 10		// upper limit of depth integral windup

// Fluid Densities in kg/m^3
#define DENSITY_FRESHWATER 997
#define DENSITY_SALTWATER 1029

// Acceleration Due to Gravity in m/s^2
#define GRAVITY 9.81

// Depth Start Value
#define DEPTH_START 50 // starting depth (mm)

// Stop Timer
#define STOP_TIME 10		// seconds

// Leak Sensor Inpu and Power Pin
#define LEAKPIN 27		// connected to GPIO 27
#define LEAKPOWERPIN 17 // providing Vcc to leak board

/******************************************************************************
 * Declare Threads
******************************************************************************/

void *navigation_thread(void* arg);
void *depth_thread(void* arg);
void *safety_thread(void* arg);
void *userInterface(void* arg);

/******************************************************************************
 * Global Variables
******************************************************************************/

// Holds the setpoint data structure with current setpoints
//setpoint_t setpoint;

// Holds the latest pressure value from the MS5837 pressure sensor
ms5837_t ms5837;

// Holds the latest temperature value from the temperature temperature sensor
float temperature;

// Holds the constants and latest errors of the yaw pid controller
pid_data_t yaw_pid;

// Holds the constants and latest errors of the depth pid controller
pid_data_t depth_pid;

// Motor channels
int motor_channels[] = {CHANNEL_1, CHANNEL_2, CHANNEL_3};

// Ignoring sstate
float depth = 0;

// setmotor intialization
float portmotorspeed = 0;
float starmotorspeed = 0;

// Start time for stop timer
time_t start;

/******************************************************************************
* Main Function
******************************************************************************/

int main()
{
	// capture ctrl+c and exit
	signal(SIGINT, ctrl_c);

	// Set up RasPi GPIO pins through wiringPi
	wiringPiSetupGpio();

	// Check if AUV is initialized correctly
	if( initialize_sensors() < 0 )
	{
		return -1;
	}
	printf("\nAll components are initialized\n");
	substate.mode = INITIALIZING;
  substate.laserarmed = ARMED;

	printf("Starting Threads\n");
	initializeTAttr();

	// Thread handles
	pthread_t navigationThread;
	pthread_t depthThread;
	//pthread_t safetyThread;
	//pthread_t disarmlaserThread;
	pthread_t uiThread;

	// Create threads using modified attributes
	//pthread_create (&disarmlaserThread, &tattrlow, disarmLaser, NULL);
	//pthread_create (&safetyThread, &tattrlow, safety_thread, NULL);
	pthread_create (&depthThread, &tattrmed, depth_thread, NULL);
	pthread_create (&navigationThread, &tattrmed, navigation_thread, NULL);
	pthread_create (&uiThread, &tattrmed, userInterface, NULL);

  // Destroy the thread attributes
 	destroyTAttr();

  printf("Threads started\n");

	// Start timer!
	start = time(0);

	// Run main while loop, wait until it's time to stop
	while(substate.mode != STOPPED)
	{
		// Check if we've passed the stop time
		if(difftime(time(0),start) > STOP_TIME)
			substate.mode = PAUSED;

		// Sleep a little
		auv_usleep(100000);
	}

	// Exit cleanly
	cleanup_auv();
	return 0;
}

/******************************************************************************
* Depth Thread
*
* For Recording Depth & Determining If AUV is in Water or not
******************************************************************************/

void *depth_thread(void* arg)
{
	printf("Depth Thread Started\n");

	while(substate.mode!=STOPPED)
	{
	  // Read pressure values
		ms5837 = read_pressure_fifo();

		// read IMU values from fifo file
		substate.imu = read_imu_fifo();

    // Only print while RUNNING
    if(substate.mode == RUNNING)
    {
      printf("\nCurrent Depth:\t %.3f m, Current water temp:\t %.3f C\n",
              ms5837.depth, ms5837.water_temp);

      printf("Current battery temp:\t %.2f\n", read_temp_fifo());

      // Write IMU data
      printf("\nYaw: %5.2f Roll: %5.2f Pitch: %5.2f p: %5.2f q: %5.2f r: %5.2f \nSys: %i Gyro: "
        "%i Accel: %i Mag: %i X_acc: %f Y_acc: %f Z_acc: %f\n ",
         substate.imu.yaw,	substate.imu.roll,	substate.imu.pitch,
         substate.imu.p, 		substate.imu.q,			substate.imu.r,
         substate.imu.sys,	substate.imu.gyro,	substate.imu.accel,
         substate.imu.mag,	substate.imu.x_acc,	substate.imu.y_acc,
         substate.imu.z_acc);
    }
		auv_usleep(1000000);
	}
	pthread_exit(NULL);
}//*/

/******************************************************************************
 * Navigation Thread
 *
 * For yaw control
 *****************************************************************************/
void *navigation_thread(void* arg)
{
	printf("Nav Thread Started\n");

	initialize_motors(motor_channels, HERTZ);

	float yaw = 0; 			  //Local variable for if statements
  float motorpercent;
  float basespeed = 0.2;

  ////////////////////////////////
  // Yaw Control Initialization //
  ////////////////////////////////
	yaw_pid.old 			= 0;	 	// Initialize old imu data
	yaw_pid.setpoint 	= 0;		// Initialize setpoint

	yaw_pid.derr = 0;
	yaw_pid.ierr = 0;					// Initialize error values
	yaw_pid.perr = 0;

	yaw_pid.kp = KP_YAW;
	yaw_pid.kd = KD_YAW;			// Initialize gain values
	yaw_pid.ki = KI_YAW;

	yaw_pid.isat = INT_SAT;		// Initialize saturation values
	yaw_pid.sat  = YAW_SAT;

	yaw_pid.dt   = DT;				// initialize time step

  //////////////////////////////////
  // Depth Control Initialization //
  //////////////////////////////////
	depth_pid.setpoint	= 2;		// Range-from-bottom setpoint (meters)
	depth_pid.old				= 0;		// Initialize old depth
	depth_pid.dt				= DT;		// Initialize depth controller time step

	depth_pid.kp = KP_DEPTH;
	depth_pid.kd = KD_DEPTH;		// Depth controller gain initialization
	depth_pid.ki = KI_DEPTH;

	depth_pid.perr = 0;
	depth_pid.ierr = 0;					// Initialize depth controller error values
	depth_pid.derr = 0;

	depth_pid.isat = INT_SAT;		// Depth controller saturation values
	depth_pid.sat  = DEPTH_SAT;

	while(substate.mode!=STOPPED)
	{
		// read IMU values from fifo file
		substate.imu = read_imu_fifo();

	  if (substate.imu.yaw < 180) // AUV pointed right
		{
			yaw = substate.imu.yaw;
		}
		else // AUV pointed left
		{
			yaw =(substate.imu.yaw-360);
		}

    // Only tell motors to run if we are RUNNING
    if( substate.mode == RUNNING)
    {
      //calculate yaw controller output
      motorpercent = marchPID(yaw_pid, yaw);

      // Set port and starboard
      portmotorspeed = basespeed + motorpercent;
      starmotorspeed = basespeed - motorpercent;

      // Set port motor
      set_motor(0, portmotorspeed);

      // Set starboard motor
      set_motor(1, starmotorspeed);

		} // end if RUNNING
		else if( substate.mode == PAUSED)
		{
		  // Stop horizontal motors
		  set_motor(0, 0);
		  set_motor(1, 0);

		  // Wipe integral error
		  yaw_pid.ierr = 0;

		  // Sleep a while (we're not doing anything anyways)
		  auv_usleep(100000);

		} // end if PAUSED

		// Sleep for 5 ms
		auv_usleep(DT);
	}

	// Turn motors off
	set_motor(0, 0);
	set_motor(1, 0);
	set_motor(2, 0);

	pthread_exit(NULL);
}//*/

/******************************************************************************
 * Safety Thread
 *
 * Shuts down AUV if vehicle goes belows 10m, temperature gets too high, or
 * water intrusion is detected
 *****************************************************************************/
/*void *safety_thread(void* arg)
{
	printf("Safety Thread Started\n");

	// Set up WiringPi for use // (not sure if actually needed)
	wiringPiSetup();

	// Leak detection pins
	pinMode(LEAKPIN, INPUT);					// set LEAKPIN as an INPUT
	pinMode(LEAKPOWERPIN, OUTPUT);		// set as output to provide Vcc
	digitalWrite(LEAKPOWERPIN, HIGH);	// write high to provide Vcc

	// Leak checking variables
	int leakState;	// holds the state (HIGH or LOW) of the LEAKPIN

	// Test if temp sensor reads anything
	temperature = read_temp_fifo();
	printf("Temperature: %f degC\n", temperature);

	while( substate.mode != STOPPED )
	{
		// Check if depth threshold has been exceeded
		if( substate.fdepth > DEPTH_STOP )
		{
			substate.mode = STOPPED;
			printf("We're too deep! Shutting down...\n");
			continue;
		}
		else
		{
			// We're still good
			substate.mode = RUNNING;
		}

		// Check temperature
		// Shut down AUV if housing temperature gets too high

		if( temperature > TEMP_STOP )
		{
			substate.mode = STOPPED;
			printf("It's too hot! Shutting down...\n");
			continue;
		}
		else
		{
			// We're still good
			substate.mode = RUNNING;
		}

		// Check for leak
		leakState = digitalRead(LEAKPIN);	// check the state of LEAKPIN
		if( leakState == HIGH )
		{
			substate.mode = STOPPED;
			printf("LEAK DETECTED! Shutting down...\n");
			continue;
		}
		else if (leakState == LOW)
		{
			// We're still good
			substate.mode = RUNNING;
		}

		// Check IMU accelerometer for collision (1+ g detected)
		if( (float)fabs(substate.imu.x_acc) > 1.0*GRAVITY
			|| (float)fabs(substate.imu.y_acc) > 1.0*GRAVITY
			|| (float)fabs(substate.imu.z_acc) > 1.0*GRAVITY )
		{
			substate.mode = STOPPED;
			printf("Collision detected. Shutting down...");
			continue;
		}
		else
		{
			// We're still good
			substate.mode = RUNNING;
		}

	}
    pthread_exit(NULL);

}//*/

/******************************************************************************
 * Logging Thread
 *
 * Logs the sensor output data into a file
 *****************************************************************************/
/*
PI_THREAD (logging_thread)
{
	while(substate.mode!=STOPPED){
		FILE *fd = fopen("log.txt", "a");
		char buffer[100] = {0};
		// add logging values to the next line
		sprintf(buffer, "%f %f %f %f %i %i %i %i %f %f %f %f\n",sstate.roll, sstate.pitch[0], sstate.yaw[0], sstate.depth[0],sstate.x[0],
		sstate.y[0], sstate.radius[0], setpoint.x - sstate.x[0], sstate.esc_out[0], sstate.esc_out[1], sstate.esc_out[2], sstate.esc_out[3]);
		fputs(buffer, fd);
		fclose(fd);
		//sleep for 100 ms

		usleep(100000);
	}
	return 0;
}
*/

/******************************************************************************
 * User Interface Thread
 * void* userInterface(void* arg)
 *
 * Interfaces with the user, asks for input
 *****************************************************************************/
 void* userInterface(void* arg)
 {
  // Declare local constant variables
  float _kp, _ki, _kd;

  // Wait a until everything is initialized before starting
  while(substate.mode == INITIALIZING)
  {
    // Waiting...
    auv_usleep(100000);
  }

  // Prompt user for values continuously until the program exits
  while(substate.mode != STOPPED)
  {
    // Prompt for kp
    std::cout << "Kp: ";
    std::cin >> _kp;

    // Prompt for ki
    std::cout << "Ki: ";
    std::cin >> _ki;

    // Prompt for kd
    std::cout << "Kd: ";
    std::cin >> _kd;

    // Give a newline
    std::cout << std::endl;

    // Reset gain values
    yaw_pid.kp = _kp;
    yaw_pid.ki = _ki;
    yaw_pid.kd = _kd;

    // Clear errors
    yaw_pid.perr = 0;
    yaw_pid.ierr = 0;
    yaw_pid.derr = 0;

    // Start RUNNING again
    substate.mode = RUNNING;

    // Restart timer!
	  start = time(0);
  }

  // Exit thread
  pthread_exit(NULL);
 }
<commit_msg>Prettied some comments<commit_after>/******************************************************************************
*	Main script for the 2017 RoboFishy Scripps AUV
******************************************************************************/

#include "Mapper.h"

// Multithreading
#include <pthread.h>
#include <sched.h>
#include <unistd.h>

// Sampling Values
#define SAMPLE_RATE 200 // sample rate of main control loop (Hz)
#define DT 0.005				// timestep; make sure this is equal to 1/SAMPLE_RATE!

// Conversion Factors
#define UNITS_KPA 0.1		// converts pressure from mbar to kPa

/******************************************************************************
* Controller Gains
******************************************************************************/

// Yaw Controller
#define KP_YAW 0.01
#define KI_YAW 0
#define KD_YAW 1

// Depth Controller
#define KP_DEPTH 0
#define KI_DEPTH 0
#define KD_DEPTH 0

// Saturation Constants
#define YAW_SAT 1			// upper limit of yaw controller
#define DEPTH_SAT 1		// upper limit of depth controller
#define INT_SAT 10		// upper limit of integral windup
#define DINT_SAT 10		// upper limit of depth integral windup

// Fluid Densities in kg/m^3
#define DENSITY_FRESHWATER 997
#define DENSITY_SALTWATER 1029

// Acceleration Due to Gravity in m/s^2
#define GRAVITY 9.81

// Depth Start Value
#define DEPTH_START 50 // starting depth (mm)

// Stop Timer
#define STOP_TIME 10		// seconds

// Leak Sensor Inpu and Power Pin
#define LEAKPIN 27		// connected to GPIO 27
#define LEAKPOWERPIN 17 // providing Vcc to leak board

/******************************************************************************
 * Declare Threads
******************************************************************************/

void *navigation_thread(void* arg);
void *depth_thread(void* arg);
void *safety_thread(void* arg);
void *userInterface(void* arg);

/******************************************************************************
 * Global Variables
******************************************************************************/

// Holds the setpoint data structure with current setpoints
//setpoint_t setpoint;

// Holds the latest pressure value from the MS5837 pressure sensor
ms5837_t ms5837;

// Holds the latest temperature value from the temperature temperature sensor
float temperature;

// Holds the constants and latest errors of the yaw pid controller
pid_data_t yaw_pid;

// Holds the constants and latest errors of the depth pid controller
pid_data_t depth_pid;

// Motor channels
int motor_channels[] = {CHANNEL_1, CHANNEL_2, CHANNEL_3};

// Ignoring sstate
float depth = 0;

// setmotor intialization
float portmotorspeed = 0;
float starmotorspeed = 0;

// Start time for stop timer
time_t start;

/******************************************************************************
* Main Function
******************************************************************************/

int main()
{
	// capture ctrl+c and exit
	signal(SIGINT, ctrl_c);

	// Set up RasPi GPIO pins through wiringPi
	wiringPiSetupGpio();

	// Check if AUV is initialized correctly
	if( initialize_sensors() < 0 )
	{
		return -1;
	}
	printf("\nAll components are initialized\n");
	substate.mode = INITIALIZING;
  substate.laserarmed = ARMED;

	printf("Starting Threads\n");
	initializeTAttr();

	// Thread handles
	pthread_t navigationThread;
	pthread_t depthThread;
	//pthread_t safetyThread;
	//pthread_t disarmlaserThread;
	pthread_t uiThread;

	// Create threads using modified attributes
	//pthread_create (&disarmlaserThread, &tattrlow, disarmLaser, NULL);
	//pthread_create (&safetyThread, &tattrlow, safety_thread, NULL);
	pthread_create (&depthThread, &tattrmed, depth_thread, NULL);
	pthread_create (&navigationThread, &tattrmed, navigation_thread, NULL);
	pthread_create (&uiThread, &tattrmed, userInterface, NULL);

  // Destroy the thread attributes
 	destroyTAttr();

  printf("Threads started\n");

	// Start timer!
	start = time(0);

	// Run main while loop, wait until it's time to stop
	while(substate.mode != STOPPED)
	{
		// Check if we've passed the stop time
		if(difftime(time(0),start) > STOP_TIME)
			substate.mode = PAUSED;

		// Sleep a little
		auv_usleep(100000);
	}

	// Exit cleanly
	cleanup_auv();
	return 0;
}

/******************************************************************************
* Depth Thread
*
* For Recording Depth & Determining If AUV is in Water or not
******************************************************************************/

void *depth_thread(void* arg)
{
	printf("Depth Thread Started\n");

	while(substate.mode!=STOPPED)
	{
	  // Read pressure values
		ms5837 = read_pressure_fifo();

		// read IMU values from fifo file
		substate.imu = read_imu_fifo();

    // Only print while RUNNING
    if(substate.mode == RUNNING)
    {
      printf("\nCurrent Depth:\t %.3f m, Current water temp:\t %.3f C\n",
              ms5837.depth, ms5837.water_temp);

      printf("Current battery temp:\t %.2f\n", read_temp_fifo());

      // Write IMU data
      printf("\nYaw: %5.2f Roll: %5.2f Pitch: %5.2f p: %5.2f q: %5.2f r: %5.2f \nSys: %i Gyro: "
        "%i Accel: %i Mag: %i X_acc: %f Y_acc: %f Z_acc: %f\n ",
         substate.imu.yaw,	substate.imu.roll,	substate.imu.pitch,
         substate.imu.p, 		substate.imu.q,			substate.imu.r,
         substate.imu.sys,	substate.imu.gyro,	substate.imu.accel,
         substate.imu.mag,	substate.imu.x_acc,	substate.imu.y_acc,
         substate.imu.z_acc);
    }
		auv_usleep(1000000);
	}
	pthread_exit(NULL);
}//*/

/******************************************************************************
 * Navigation Thread
 *
 * For yaw control
 *****************************************************************************/
void *navigation_thread(void* arg)
{
	printf("Nav Thread Started\n");

	initialize_motors(motor_channels, HERTZ);

	float yaw = 0; 			  //Local variable for if statements
  float motorpercent;
  float basespeed = 0.2;

  ////////////////////////////////
  // Yaw Control Initialization //
  ////////////////////////////////
	yaw_pid.old 		= 0;	 	// Initialize old imu data
	yaw_pid.setpoint 	= 0;		// Initialize setpoint

	yaw_pid.derr = 0;
	yaw_pid.ierr = 0;					// Initialize error values
	yaw_pid.perr = 0;

	yaw_pid.kp = KP_YAW;
	yaw_pid.kd = KD_YAW;			// Initialize gain values
	yaw_pid.ki = KI_YAW;

	yaw_pid.isat = INT_SAT;		// Initialize saturation values
	yaw_pid.sat  = YAW_SAT;

	yaw_pid.dt   = DT;				// initialize time step

  //////////////////////////////////
  // Depth Control Initialization //
  //////////////////////////////////
	depth_pid.setpoint			= 2;		// Range-from-bottom setpoint (meters)
	depth_pid.old				= 0;		// Initialize old depth
	depth_pid.dt				= DT;		// Initialize depth controller time step

	depth_pid.kp = KP_DEPTH;
	depth_pid.kd = KD_DEPTH;		// Depth controller gain initialization
	depth_pid.ki = KI_DEPTH;

	depth_pid.perr = 0;
	depth_pid.ierr = 0;					// Initialize depth controller error values
	depth_pid.derr = 0;

	depth_pid.isat = INT_SAT;		// Depth controller saturation values
	depth_pid.sat  = DEPTH_SAT;

	while(substate.mode!=STOPPED)
	{
		// read IMU values from fifo file
		substate.imu = read_imu_fifo();

	  if (substate.imu.yaw < 180) // AUV pointed right
		{
			yaw = substate.imu.yaw;
		}
		else // AUV pointed left
		{
			yaw =(substate.imu.yaw-360);
		}

    // Only tell motors to run if we are RUNNING
    if( substate.mode == RUNNING)
    {
      //calculate yaw controller output
      motorpercent = marchPID(yaw_pid, yaw);

      // Set port and starboard
      portmotorspeed = basespeed + motorpercent;
      starmotorspeed = basespeed - motorpercent;

      // Set port motor
      set_motor(0, portmotorspeed);

      // Set starboard motor
      set_motor(1, starmotorspeed);

		} // end if RUNNING
		else if( substate.mode == PAUSED)
		{
		  // Stop horizontal motors
		  set_motor(0, 0);
		  set_motor(1, 0);

		  // Wipe integral error
		  yaw_pid.ierr = 0;

		  // Sleep a while (we're not doing anything anyways)
		  auv_usleep(100000);

		} // end if PAUSED

		// Sleep for 5 ms
		auv_usleep(DT);
	}

	// Turn motors off
	set_motor(0, 0);
	set_motor(1, 0);
	set_motor(2, 0);

	pthread_exit(NULL);
}//*/

/******************************************************************************
 * Safety Thread
 *
 * Shuts down AUV if vehicle goes belows 10m, temperature gets too high, or
 * water intrusion is detected
 *****************************************************************************/
/*void *safety_thread(void* arg)
{
	printf("Safety Thread Started\n");

	// Set up WiringPi for use // (not sure if actually needed)
	wiringPiSetup();

	// Leak detection pins
	pinMode(LEAKPIN, INPUT);					// set LEAKPIN as an INPUT
	pinMode(LEAKPOWERPIN, OUTPUT);		// set as output to provide Vcc
	digitalWrite(LEAKPOWERPIN, HIGH);	// write high to provide Vcc

	// Leak checking variables
	int leakState;	// holds the state (HIGH or LOW) of the LEAKPIN

	// Test if temp sensor reads anything
	temperature = read_temp_fifo();
	printf("Temperature: %f degC\n", temperature);

	while( substate.mode != STOPPED )
	{
		// Check if depth threshold has been exceeded
		if( substate.fdepth > DEPTH_STOP )
		{
			substate.mode = STOPPED;
			printf("We're too deep! Shutting down...\n");
			continue;
		}
		else
		{
			// We're still good
			substate.mode = RUNNING;
		}

		// Check temperature
		// Shut down AUV if housing temperature gets too high

		if( temperature > TEMP_STOP )
		{
			substate.mode = STOPPED;
			printf("It's too hot! Shutting down...\n");
			continue;
		}
		else
		{
			// We're still good
			substate.mode = RUNNING;
		}

		// Check for leak
		leakState = digitalRead(LEAKPIN);	// check the state of LEAKPIN
		if( leakState == HIGH )
		{
			substate.mode = STOPPED;
			printf("LEAK DETECTED! Shutting down...\n");
			continue;
		}
		else if (leakState == LOW)
		{
			// We're still good
			substate.mode = RUNNING;
		}

		// Check IMU accelerometer for collision (1+ g detected)
		if( (float)fabs(substate.imu.x_acc) > 1.0*GRAVITY
			|| (float)fabs(substate.imu.y_acc) > 1.0*GRAVITY
			|| (float)fabs(substate.imu.z_acc) > 1.0*GRAVITY )
		{
			substate.mode = STOPPED;
			printf("Collision detected. Shutting down...");
			continue;
		}
		else
		{
			// We're still good
			substate.mode = RUNNING;
		}

	}
    pthread_exit(NULL);

}//*/

/******************************************************************************
 * Logging Thread
 *
 * Logs the sensor output data into a file
 *****************************************************************************/
/*
PI_THREAD (logging_thread)
{
	while(substate.mode!=STOPPED){
		FILE *fd = fopen("log.txt", "a");
		char buffer[100] = {0};
		// add logging values to the next line
		sprintf(buffer, "%f %f %f %f %i %i %i %i %f %f %f %f\n",sstate.roll, sstate.pitch[0], sstate.yaw[0], sstate.depth[0],sstate.x[0],
		sstate.y[0], sstate.radius[0], setpoint.x - sstate.x[0], sstate.esc_out[0], sstate.esc_out[1], sstate.esc_out[2], sstate.esc_out[3]);
		fputs(buffer, fd);
		fclose(fd);
		//sleep for 100 ms

		usleep(100000);
	}
	return 0;
}
*/

/******************************************************************************
 * User Interface Thread
 * void* userInterface(void* arg)
 *
 * Interfaces with the user, asks for input
 *****************************************************************************/
 void* userInterface(void* arg)
 {
  // Declare local constant variables
  float _kp, _ki, _kd;

  // Wait a until everything is initialized before starting
  while(substate.mode == INITIALIZING)
  {
    // Waiting...
    auv_usleep(100000);
  }

  // Prompt user for values continuously until the program exits
  while(substate.mode != STOPPED)
  {
    // Prompt for kp
    std::cout << "Kp: ";
    std::cin >> _kp;

    // Prompt for ki
    std::cout << "Ki: ";
    std::cin >> _ki;

    // Prompt for kd
    std::cout << "Kd: ";
    std::cin >> _kd;

    // Give a newline
    std::cout << std::endl;

    // Reset gain values
    yaw_pid.kp = _kp;
    yaw_pid.ki = _ki;
    yaw_pid.kd = _kd;

    // Clear errors
    yaw_pid.perr = 0;
    yaw_pid.ierr = 0;
    yaw_pid.derr = 0;

    // Start RUNNING again
    substate.mode = RUNNING;

    // Restart timer!
	  start = time(0);
  }

  // Exit thread
  pthread_exit(NULL);
 }
<|endoftext|>


<commit_before>#pragma once

namespace stx {

struct handle_socket {
	virtual void on_handle_destroyed() noexcept = 0;
};

class handle {
	handle_socket* m_socket;

public:
	handle() : m_socket(nullptr) {}
	handle(handle_socket* s) : m_socket(s) {}
	handle(handle&& h) : m_socket(h.m_socket) { h.m_socket = nullptr; }
	~handle() {
		if(m_socket) { m_socket->on_handle_destroyed(); }
	}

	handle& reset(handle_socket* new_sock = nullptr) {
		if(m_socket) { m_socket->on_handle_destroyed(); }
		m_socket = new_sock;
		return *this;
	}

	handle& operator=(handle_socket* s) { return reset(s); }

	handle& operator=(handle&& s) {
		reset(s.m_socket);
		s.m_socket = nullptr;
		return *this;
	}
};

class handles {
	std::vector<handle> m_handles;

public:
	handles& operator<<(handle&& h) {
		m_handles.emplace_back(std::move(h));
		return *this;
	}
};

} // namespace stx
<commit_msg>Added handles.clear()<commit_after>#pragma once

namespace stx {

struct handle_socket {
	virtual void on_handle_destroyed() noexcept = 0;
};

class handle {
	handle_socket* m_socket;

public:
	handle() : m_socket(nullptr) {}
	handle(handle_socket* s) : m_socket(s) {}
	handle(handle&& h) : m_socket(h.m_socket) { h.m_socket = nullptr; }
	~handle() {
		if(m_socket) { m_socket->on_handle_destroyed(); }
	}

	handle& reset(handle_socket* new_sock = nullptr) {
		if(m_socket) { m_socket->on_handle_destroyed(); }
		m_socket = new_sock;
		return *this;
	}

	handle& operator=(handle_socket* s) { return reset(s); }

	handle& operator=(handle&& s) {
		reset(s.m_socket);
		s.m_socket = nullptr;
		return *this;
	}
};

class handles {
	std::vector<handle> m_handles;

public:
	handles& operator<<(handle&& h) {
		m_handles.emplace_back(std::move(h));
		return *this;
	}

	void clear() {
		m_handles.clear();
	}
};

} // namespace stx
<|endoftext|>


<commit_before><commit_msg>bool improvements<commit_after><|endoftext|>


<commit_before>//
// Created by cheyulin on 5/9/16.
//

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <semaphore.h>
#include <vector>

int thread_count;
pthread_mutex_t mutex;
pthread_cond_t cond_var;
int idle_count = 0;
using namespace std;
vector<int> global_vec;
bool is_end = false;

void *ThreadFunction(void *thread_label) {
    long thread_id = (long) thread_label;
    pthread_mutex_lock(&mutex);
    long local_result = 1;
    while (!is_end) {
        global_vec.push_back(local_result);
        if (global_vec.size() >= 2) {
            local_result = 0;
            for (auto i = 0; i < 2; i++) {
                local_result += global_vec.back();
                global_vec.erase(global_vec.end() - 1);
            }
        }
        else {
            if (idle_count == thread_count - 1) {
                is_end = true;
                pthread_cond_broadcast(&cond_var);
            }
            else {
                idle_count++;
                while (pthread_cond_wait(&cond_var, &mutex) != 0);
            }
        }
    }
    cout << "Thread " << thread_id << " ready to exit" << endl;
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main(int argc, char *argv[]) {
    thread_count = strtol(argv[1], NULL, 10);
    long thread;
    pthread_t *thread_handles;

    /* Get number of threads from command line*/
    thread_handles = (pthread_t *) malloc(thread_count * sizeof(pthread_t));
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond_var, NULL);
    for (thread = 0; thread < thread_count; thread++) {
        pthread_create(&thread_handles[thread], NULL, ThreadFunction, (void *) thread);
    }

    for (thread = 0; thread < thread_count; thread++) {
        pthread_join(thread_handles[thread], NULL);
    }

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond_var);
    free(thread_handles);

    cout << "Global sum:" << global_vec[0] << endl;
    getchar();

    return 0;

}<commit_msg>fix bug in reduce impl<commit_after>//
// Created by cheyulin on 5/9/16.
//

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
#include <unistd.h>
#include <semaphore.h>
#include <vector>

int thread_count;
pthread_mutex_t mutex;
pthread_cond_t cond_var;
int idle_count = 0;
using namespace std;
vector<int> global_vec;
bool is_end = false;

void *ThreadFunction(void *thread_label) {
    long thread_id = (long) thread_label;

    long local_result = 1;
    while (!is_end) {
        pthread_mutex_lock(&mutex);
        global_vec.push_back(local_result);
        if (global_vec.size() >= 2) {
            vector<int> local_vec;
            for (auto i = 0; i < 2; i++) {
                local_vec.push_back(global_vec.back());
                global_vec.erase(global_vec.end() - 1);
            }
            pthread_mutex_unlock(&mutex);
            //Do the computation After release the lock
            local_result = 0;
            for (auto integer:local_vec) {
                local_result += integer;
            }
        }
        else {
            if (idle_count == thread_count - 1) {
                is_end = true;
                pthread_cond_broadcast(&cond_var);
            }
            else {
                idle_count++;
                while (pthread_cond_wait(&cond_var, &mutex) != 0);
            }
            pthread_mutex_unlock(&mutex);

        }
    }
#pragma omp critical
    cout << "Thread " << thread_id << " ready to exit" << endl;

    return NULL;
}

int main(int argc, char *argv[]) {
    thread_count = strtol(argv[1], NULL, 10);
    long thread;
    pthread_t *thread_handles;

    /* Get number of threads from command line*/
    thread_handles = (pthread_t *) malloc(thread_count * sizeof(pthread_t));
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond_var, NULL);
    for (thread = 0; thread < thread_count; thread++) {
        pthread_create(&thread_handles[thread], NULL, ThreadFunction, (void *) thread);
    }

    for (thread = 0; thread < thread_count; thread++) {
        pthread_join(thread_handles[thread], NULL);
    }

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond_var);
    free(thread_handles);

    cout << "Global sum:" << global_vec[0] << endl;
    getchar();

    return 0;

}<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDecimate.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
// .NAME vtkDecimate - reduce the number of triangles in a mesh
// .SECTION Description
// vtkDecimate is a filter to reduce the number of triangles in a triangle
// mesh, while preserving the original topology and a forming good
// approximation to the original geometry. The input to vtkDecimate is a
// vtkPolyData object, and only triangles are treated. If you desire to
// decimate polygonal meshes, first triangulate the polygons with the
// vtkTriangleFilter object.
//
// The algorithm proceeds as follows. Each vertex in the triangle
// list is evaluated for local planarity (i.e., the triangles using
// the vertex are gathered and compared to an "average" plane). If the
// region is locally planar, that is if the target vertex is within a
// certain distance of the average plane (i.e., the error), and
// there are no edges radiating from the vertex that have a dihedral angle
// greater than a user-specified edge angle (i.e., feature angle), and
// topology is not altered, then that vertex is deleted. The resulting
// hole is then patched by re-triangulation. The process creates over
// the entire vertex list (this constitutes an iteration). Iterations
// proceed until a target reduction is reached or a maximum iteration
// count is exceeded.
//
// There are a number of additional parameters you can set to control the
// decimation algorithm. The error may be increased over each iteration
// with the error increment. Edge preservation may be disabled or enabled.
// You can turn on/off edge vertex deletion. (Edge vertices are vertices that
// lie along boundaries of meshes.) Sub iterations are iterations that are
// performed without changing the decimation criterion. The aspect ratio
// controls the shape of the triangles that are created, and is the ratio
// of maximum edge length to minimum edge length. The degree is the number
// of triangles using a single vertex. Vertices of high degree are considered
// "complex" and are never deleted.
//
// This implementation has been adapted for a global error bound decimation
// criterion. That is, the error is a global bound on distance to original
// surface.

#ifndef __vtkDecimate_h
#define __vtkDecimate_h

#include "vtkPolyToPolyFilter.hh"
#include "vtkMath.hh"
#include "vtkTriangle.hh"
#include "vtkPlane.hh"
#include "vtkPolygon.hh"
#include "vtkLine.hh"

#define VTK_NUMBER_STATISTICS 12

// Special structures for building loops
typedef struct _vtkLocalVertex
  {
  int     id;
  float   x[3];
  float   FAngle;
  int     deRefs; //monitor memory requirements; new only when necessary
  int     newRefs;
  } vtkLocalVertex, *vtkLocalVertexPtr;

typedef struct _vtkLocalTri
  {
  int     id;
  float   area;
  float   n[3];
  int     verts[3];
  } vtkLocalTri, *vtkLocalTriPtr;

//
// Special classes for manipulating data
//
//BTX - begin tcl exclude
//
class vtkVertexArray { //;prevent man page generation
public:
  vtkVertexArray(const int sz)
    {this->MaxId = -1; this->Array = new vtkLocalVertex[sz];};
  ~vtkVertexArray() {if (this->Array) delete [] this->Array;};
  int GetNumberOfVertices() {return this->MaxId + 1;};
  void InsertNextVertex(vtkLocalVertex& v)
    {this->MaxId++; this->Array[this->MaxId] = v;};
  vtkLocalVertex& GetVertex(int i) {return this->Array[i];};
  void Reset() {this->MaxId = -1;};

  vtkLocalVertex *Array;  // pointer to data
  int MaxId;             // maximum index inserted thus far
};

class vtkTriArray { //;prevent man page generation
public:
  vtkTriArray(const int sz)
    {this->MaxId = -1; this->Array = new vtkLocalTri[sz];};
  ~vtkTriArray() {if (this->Array) delete [] this->Array;};
  int GetNumberOfTriangles() {return this->MaxId + 1;};
  void InsertNextTriangle(vtkLocalTri& t)
    {this->MaxId++; this->Array[this->MaxId] = t;};
  vtkLocalTri& GetTriangle(int i) {return this->Array[i];};
  void Reset() {this->MaxId = -1;};

  vtkLocalTri *Array;  // pointer to data
  int MaxId;            // maximum index inserted thus far
};
//ETX - end tcl exclude
//

class vtkDecimate : public vtkPolyToPolyFilter
{
public:
  vtkDecimate();
  char *GetClassName() {return "vtkDecimate";};
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Set the decimation error bounds. Expressed as a fraction of the longest
  // side of the input data's bounding box.
  vtkSetClampMacro(InitialError,float,0.0,1.0);
  vtkGetMacro(InitialError,float);

  // Description:
  // Set the value of the increment by which to increase the decimation
  // error after each iteration.
  vtkSetClampMacro(ErrorIncrement,float,0.0,1.0);
  vtkGetMacro(ErrorIncrement,float);

  // Description:
  // Set the largest decimation error that can be achieved
  // by incrementing the error.
  vtkSetClampMacro(MaximumError,float,0.0,1.0);
  vtkGetMacro(MaximumError,float);

  // Description:
  // Specify the desired reduction in the total number of polygons. Because
  // of various constraints, this level of reduction may not be realizable.
  vtkSetClampMacro(TargetReduction,float,0.0,1.0);
  vtkGetMacro(TargetReduction,float);

  // Description:
  // Specify the maximum number of iterations to attempt. If decimation target
  // is reached first, this value will not be reached.
  vtkSetClampMacro(MaximumIterations,int,1,VTK_LARGE_INTEGER);
  vtkGetMacro(MaximumIterations,int);

  // Description:
  // Specify the maximum sub-iterations to perform. If no triangles are deleted
  // in a sub-iteration, the sub-iteration process is stopped.
  vtkSetClampMacro(MaximumSubIterations,int,1,VTK_LARGE_INTEGER);
  vtkGetMacro(MaximumSubIterations,int);

  // Description:
  // Specify the mesh feature angles.
  vtkSetClampMacro(InitialFeatureAngle,float,0.0,180.0);
  vtkGetMacro(InitialFeatureAngle,float);

  // Description:
  // Set/Get the angle by which to increase feature angle over each iteration.
  vtkSetClampMacro(FeatureAngleIncrement,float,0.0,180.0);
  vtkGetMacro(FeatureAngleIncrement,float);

  // Description:
  // Set the largest permissible feature angle.
  vtkSetClampMacro(MaximumFeatureAngle,float,0.0,180.0);
  vtkGetMacro(MaximumFeatureAngle,float);

  // Description:
  // Turn on/off the preservation of feature edges.
  vtkSetMacro(PreserveEdges,int);
  vtkGetMacro(PreserveEdges,int);
  vtkBooleanMacro(PreserveEdges,int);

  // Description:
  // Turn on/off the deletion of vertices on the boundary of a mesh.
  vtkSetMacro(BoundaryVertexDeletion,int);
  vtkGetMacro(BoundaryVertexDeletion,int);
  vtkBooleanMacro(BoundaryVertexDeletion,int);

  // Description:
  // Specify the maximum allowable aspect ratio during triangulation.
  vtkSetClampMacro(AspectRatio,float,1.0,1000.0);
  vtkGetMacro(AspectRatio,float);

  // Description:
  // If the number of triangles connected to a vertex exceeds "Degree", then
  // the vertex is considered complex and is never deleted. (NOTE: the
  // complexity of the triangulation algorithm is proportional to Degree^2.)
  vtkSetClampMacro(Degree,int,25,VTK_CELL_SIZE);
  vtkGetMacro(Degree,int);

protected:
  void Execute();

  float InitialFeatureAngle; // dihedral angle constraint
  float FeatureAngleIncrement;
  float MaximumFeatureAngle;
  int PreserveEdges; // do/don't worry about feature edges
  int BoundaryVertexDeletion;
  float InitialError; // decimation error in fraction of bounding box
  float ErrorIncrement; // each iteration will bump error this amount
  float MaximumError; // maximum error
  float TargetReduction; //target reduction of mesh (fraction)
  int MaximumIterations; // maximum number of passes over data
  int MaximumSubIterations; // maximum non-incrementing passes
  float AspectRatio; // control triangle shape during triangulation
  int Degree; // maximum number of triangles incident on vertex
  int Stats[VTK_NUMBER_STATISTICS]; // keep track of interesting statistics
  int GenerateErrorScalars; // turn on/off vertex error scalar generation

  void CreateOutput(int numPts, int numTris, int numEliminated,
                    vtkPointData *pd, vtkPoints *inPts);
  int BuildLoop(int ptId, unsigned short int nTris, int* tris);
  void EvaluateLoop(int& vtype, int& numFEdges, vtkLocalVertexPtr fedges[]);
  int CanSplitLoop(vtkLocalVertexPtr fedges[2], int numVerts,
                   vtkLocalVertexPtr verts[], int& n1, vtkLocalVertexPtr l1[],
                   int& n2, vtkLocalVertexPtr l2[], float& ar);
  void SplitLoop(vtkLocalVertexPtr fedges[2], int numVerts,
                 vtkLocalVertexPtr *verts, int& n1, vtkLocalVertexPtr *l1,
                 int& n2, vtkLocalVertexPtr *l2);
  void Triangulate(int numVerts, vtkLocalVertexPtr verts[]);
  int CheckError();
};

#endif

<commit_msg>ERR: Added error control to limit number of warnings.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDecimate.hh
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
// .NAME vtkDecimate - reduce the number of triangles in a mesh
// .SECTION Description
// vtkDecimate is a filter to reduce the number of triangles in a triangle
// mesh, while preserving the original topology and a forming good
// approximation to the original geometry. The input to vtkDecimate is a
// vtkPolyData object, and only triangles are treated. If you desire to
// decimate polygonal meshes, first triangulate the polygons with the
// vtkTriangleFilter object.
//
// The algorithm proceeds as follows. Each vertex in the triangle
// list is evaluated for local planarity (i.e., the triangles using
// the vertex are gathered and compared to an "average" plane). If the
// region is locally planar, that is if the target vertex is within a
// certain distance of the average plane (i.e., the error), and
// there are no edges radiating from the vertex that have a dihedral angle
// greater than a user-specified edge angle (i.e., feature angle), and
// topology is not altered, then that vertex is deleted. The resulting
// hole is then patched by re-triangulation. The process continues over
// the entire vertex list (this constitutes an iteration). Iterations
// proceed until a target reduction is reached or a maximum iteration
// count is exceeded.
//
// There are a number of additional parameters you can set to control
// the decimation algorithm. The Error ivar may be increased over each
// iteration with the ErrorIncrement. (These two variables have the
// largest effect.) Edge preservation (i.e., PreserveEdges ivar) may
// be disabled or enabled. You can turn on/off edge vertex deletion
// (i.e., BoundaryVertexDeletion ivar). (Edge vertices are vertices
// that lie along boundaries of meshes.) Sub iterations are iterations
// that are performed without changing the decimation criterion. The
// AspectRatio ivar controls the shape of the triangles that are
// created, and is the ratio of maximum edge length to minimum edge
// length. The Degree is the number of triangles using a single
// vertex. Vertices of high degree are considered "complex" and are
// never deleted.
//
// This implementation has been adapted for a global error bound decimation
// criterion. That is, the error is a global bound on distance to original
// surface. This is an improvement over the original Siggraph paper ("Decimation
// of Triangle Meshes", Proc Siggraph `92.)

#ifndef __vtkDecimate_h
#define __vtkDecimate_h

#include "vtkPolyToPolyFilter.hh"
#include "vtkMath.hh"
#include "vtkTriangle.hh"
#include "vtkPlane.hh"
#include "vtkPolygon.hh"
#include "vtkLine.hh"

#define VTK_NUMBER_STATISTICS 12

// Special structures for building loops
typedef struct _vtkLocalVertex
  {
  int     id;
  float   x[3];
  float   FAngle;
  int     deRefs; //monitor memory requirements; new only when necessary
  int     newRefs;
  } vtkLocalVertex, *vtkLocalVertexPtr;

typedef struct _vtkLocalTri
  {
  int     id;
  float   area;
  float   n[3];
  int     verts[3];
  } vtkLocalTri, *vtkLocalTriPtr;

//
// Special classes for manipulating data
//
//BTX - begin tcl exclude
//
class vtkVertexArray { //;prevent man page generation
public:
  vtkVertexArray(const int sz)
    {this->MaxId = -1; this->Array = new vtkLocalVertex[sz];};
  ~vtkVertexArray() {if (this->Array) delete [] this->Array;};
  int GetNumberOfVertices() {return this->MaxId + 1;};
  void InsertNextVertex(vtkLocalVertex& v)
    {this->MaxId++; this->Array[this->MaxId] = v;};
  vtkLocalVertex& GetVertex(int i) {return this->Array[i];};
  void Reset() {this->MaxId = -1;};

  vtkLocalVertex *Array;  // pointer to data
  int MaxId;             // maximum index inserted thus far
};

class vtkTriArray { //;prevent man page generation
public:
  vtkTriArray(const int sz)
    {this->MaxId = -1; this->Array = new vtkLocalTri[sz];};
  ~vtkTriArray() {if (this->Array) delete [] this->Array;};
  int GetNumberOfTriangles() {return this->MaxId + 1;};
  void InsertNextTriangle(vtkLocalTri& t)
    {this->MaxId++; this->Array[this->MaxId] = t;};
  vtkLocalTri& GetTriangle(int i) {return this->Array[i];};
  void Reset() {this->MaxId = -1;};

  vtkLocalTri *Array;  // pointer to data
  int MaxId;            // maximum index inserted thus far
};
//ETX - end tcl exclude
//

class vtkDecimate : public vtkPolyToPolyFilter
{
public:
  vtkDecimate();
  char *GetClassName() {return "vtkDecimate";};
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Set the decimation error bounds. Expressed as a fraction of the longest
  // side of the input data's bounding box.
  vtkSetClampMacro(InitialError,float,0.0,1.0);
  vtkGetMacro(InitialError,float);

  // Description:
  // Set the value of the increment by which to increase the decimation
  // error after each iteration.
  vtkSetClampMacro(ErrorIncrement,float,0.0,1.0);
  vtkGetMacro(ErrorIncrement,float);

  // Description:
  // Set the largest decimation error that can be achieved
  // by incrementing the error.
  vtkSetClampMacro(MaximumError,float,0.0,1.0);
  vtkGetMacro(MaximumError,float);

  // Description:
  // Specify the desired reduction in the total number of polygons. Because
  // of various constraints, this level of reduction may not be realizable.
  vtkSetClampMacro(TargetReduction,float,0.0,1.0);
  vtkGetMacro(TargetReduction,float);

  // Description:
  // Specify the maximum number of iterations to attempt. If decimation target
  // is reached first, this value will not be reached.
  vtkSetClampMacro(MaximumIterations,int,1,VTK_LARGE_INTEGER);
  vtkGetMacro(MaximumIterations,int);

  // Description:
  // Specify the maximum sub-iterations to perform. If no triangles are deleted
  // in a sub-iteration, the sub-iteration process is stopped.
  vtkSetClampMacro(MaximumSubIterations,int,1,VTK_LARGE_INTEGER);
  vtkGetMacro(MaximumSubIterations,int);

  // Description:
  // Specify the mesh feature angles.
  vtkSetClampMacro(InitialFeatureAngle,float,0.0,180.0);
  vtkGetMacro(InitialFeatureAngle,float);

  // Description:
  // Set/Get the angle by which to increase feature angle over each iteration.
  vtkSetClampMacro(FeatureAngleIncrement,float,0.0,180.0);
  vtkGetMacro(FeatureAngleIncrement,float);

  // Description:
  // Set the largest permissible feature angle.
  vtkSetClampMacro(MaximumFeatureAngle,float,0.0,180.0);
  vtkGetMacro(MaximumFeatureAngle,float);

  // Description:
  // Turn on/off the preservation of feature edges.
  vtkSetMacro(PreserveEdges,int);
  vtkGetMacro(PreserveEdges,int);
  vtkBooleanMacro(PreserveEdges,int);

  // Description:
  // Turn on/off the deletion of vertices on the boundary of a mesh.
  vtkSetMacro(BoundaryVertexDeletion,int);
  vtkGetMacro(BoundaryVertexDeletion,int);
  vtkBooleanMacro(BoundaryVertexDeletion,int);

  // Description:
  // Specify the maximum allowable aspect ratio during triangulation.
  vtkSetClampMacro(AspectRatio,float,1.0,1000.0);
  vtkGetMacro(AspectRatio,float);

  // Description:
  // If the number of triangles connected to a vertex exceeds "Degree", then
  // the vertex is considered complex and is never deleted. (NOTE: the
  // complexity of the triangulation algorithm is proportional to Degree^2.)
  vtkSetClampMacro(Degree,int,25,VTK_CELL_SIZE);
  vtkGetMacro(Degree,int);

  // Description:
  // Control the printout of warnings. This flag limits the number of warnings
  // regarding non-manifold geometry and complex vertices. If set to zero, no
  // warnings will appear.
  vtkSetClampMacro(MaximumNumberOfSquawks,int,0,VTK_LARGE_INTEGER);
  vtkGetMacro(MaximumNumberOfSquawks,int);

protected:
  void Execute();

  float InitialFeatureAngle; // dihedral angle constraint
  float FeatureAngleIncrement;
  float MaximumFeatureAngle;
  int PreserveEdges; // do/don't worry about feature edges
  int BoundaryVertexDeletion;
  float InitialError; // decimation error in fraction of bounding box
  float ErrorIncrement; // each iteration will bump error this amount
  float MaximumError; // maximum error
  float TargetReduction; //target reduction of mesh (fraction)
  int MaximumIterations; // maximum number of passes over data
  int MaximumSubIterations; // maximum non-incrementing passes
  float AspectRatio; // control triangle shape during triangulation
  int Degree; // maximum number of triangles incident on vertex
  int Stats[VTK_NUMBER_STATISTICS]; // keep track of interesting statistics
  int GenerateErrorScalars; // turn on/off vertex error scalar generation
  int MaximumNumberOfSquawks; //control number of error messages

  void CreateOutput(int numPts, int numTris, int numEliminated,
                    vtkPointData *pd, vtkPoints *inPts);
  int BuildLoop(int ptId, unsigned short int nTris, int* tris);
  void EvaluateLoop(int& vtype, int& numFEdges, vtkLocalVertexPtr fedges[]);
  int CanSplitLoop(vtkLocalVertexPtr fedges[2], int numVerts,
                   vtkLocalVertexPtr verts[], int& n1, vtkLocalVertexPtr l1[],
                   int& n2, vtkLocalVertexPtr l2[], float& ar);
  void SplitLoop(vtkLocalVertexPtr fedges[2], int numVerts,
                 vtkLocalVertexPtr *verts, int& n1, vtkLocalVertexPtr *l1,
                 int& n2, vtkLocalVertexPtr *l2);
  void Triangulate(int numVerts, vtkLocalVertexPtr verts[]);
  int CheckError();
};

#endif

<|endoftext|>


<commit_before>#include "stdsneezy.h"
#include "database.h"
#include "session.cgi.h"

#include <cgicc/Cgicc.h>
#include <cgicc/HTTPCookie.h>
#include <cgicc/CgiEnvironment.h>

#include <sys/types.h>
#include <md5.h>

cgicc::HTTPCookie TSession::getCookie()
{
  cgicc::HTTPCookie cookie(cookiename, getSessionID());
  if(cookieduration>=0)
    cookie.setMaxAge(cookieduration);
  return cookie;
}

bool TSession::checkPasswd(sstring name, sstring passwd)
{
  TDatabase db(DB_SNEEZY);

  db.query("select account_id, passwd from account where name='%s'",
	   name.c_str());

  // account not found.  I debated whether or not we should let users know
  // about this and decided it's bad to let them figure out what account
  // names exist.
  if(!db.fetchRow())
    return false;

  // get the encrypted form.
  sstring crypted=crypt(passwd.c_str(), name.c_str());
  // sneezy truncates the encrypted password for some reason
  crypted=crypted.substr(0,10);

  // bad password
  if(crypted != db["passwd"])
    return false;

  account_id=convertTo<int>(db["account_id"]);
  if(!account_id){
    account_id=-1;
    return -1;
  }

  return true;
}

void TSession::logout()
{
  TDatabase db(DB_SNEEZY);
  db.query("delete from cgisession where session_id='%s'",
	   session_id.c_str());
  cookieduration=0;
}

bool TSession::isValid()
{
  if(session_id.empty() || account_id < 0){
    return false;
  }
  return true;
}

TSession::TSession(cgicc::Cgicc c, sstring cn)
{
  session_id="";
  account_id=-1;
  cookiename=cn;
  cookieduration=0;

  cgi=&c;
  session_id=getSessionCookie();

  if(!session_id.empty()){
    account_id=validateSessionID();
  }
}

int TSession::validateSessionID()
{
  TDatabase db(DB_SNEEZY);

  db.query("select account_id from cgisession where session_id='%s' and (timeset+duration) > %i",
	   session_id.c_str(), time(NULL));

  if(!db.fetchRow())
    return -1;

  int a=convertTo<int>(db["account_id"]);

  return (a ? a : -1);
}

// gets the value of the "mudmail" cookie and returns it
sstring TSession::getSessionCookie()
{
  cgicc::CgiEnvironment env = cgi->getEnvironment();
  vector<cgicc::HTTPCookie> cookies = env.getCookieList();

  if(!cookies.size())
    return "";

  for(unsigned int i=0;i<cookies.size();++i){
    if(cookies[i].getName() == cookiename)
      return cookies[i].getValue();
  }
  return "";
}

void TSession::createSession()
{
  createSession(60*60);
  cookieduration=-1;
}

void TSession::createSession(int duration)
{
  cookieduration=duration;
  TDatabase db(DB_SNEEZY);

  do {
    session_id=generateSessionID();
    db.query("select 1 from cgisession where session_id='%s'",
	     session_id.c_str());
  } while(db.fetchRow());

  db.query("delete from cgisession where account_id=%i", account_id);
  db.query("insert into cgisession values ('%s', %i, %i, %i)",
	   session_id.c_str(), account_id, duration, time(NULL));
}

sstring TSession::generateSessionID()
{
  unsigned char data[16];
  int length=16;
  int seed[4];

  srandomdev();

  seed[0]=time(NULL);
  seed[1]=random();
  seed[2]=getpid();
  seed[3]=(int)&seed;

  int c=0;
  for(int i=0;i<4;++i){
    for(int j=0;j<4;++j){
      data[c++]=(&seed[i])[j];
    }
  }

  return MD5Data(data, length, NULL);
}

<commit_msg>added a name field to cgisession to identify which app set that session this is just for convenience in debugging and so on.<commit_after>#include "stdsneezy.h"
#include "database.h"
#include "session.cgi.h"

#include <cgicc/Cgicc.h>
#include <cgicc/HTTPCookie.h>
#include <cgicc/CgiEnvironment.h>

#include <sys/types.h>
#include <md5.h>

cgicc::HTTPCookie TSession::getCookie()
{
  cgicc::HTTPCookie cookie(cookiename, getSessionID());
  if(cookieduration>=0)
    cookie.setMaxAge(cookieduration);
  return cookie;
}

bool TSession::checkPasswd(sstring name, sstring passwd)
{
  TDatabase db(DB_SNEEZY);

  db.query("select account_id, passwd from account where name='%s'",
	   name.c_str());

  // account not found.  I debated whether or not we should let users know
  // about this and decided it's bad to let them figure out what account
  // names exist.
  if(!db.fetchRow())
    return false;

  // get the encrypted form.
  sstring crypted=crypt(passwd.c_str(), name.c_str());
  // sneezy truncates the encrypted password for some reason
  crypted=crypted.substr(0,10);

  // bad password
  if(crypted != db["passwd"])
    return false;

  account_id=convertTo<int>(db["account_id"]);
  if(!account_id){
    account_id=-1;
    return -1;
  }

  return true;
}

void TSession::logout()
{
  TDatabase db(DB_SNEEZY);
  db.query("delete from cgisession where session_id='%s'",
	   session_id.c_str());
  cookieduration=0;
}

bool TSession::isValid()
{
  if(session_id.empty() || account_id < 0){
    return false;
  }
  return true;
}

TSession::TSession(cgicc::Cgicc c, sstring cn)
{
  session_id="";
  account_id=-1;
  cookiename=cn;
  cookieduration=0;

  cgi=&c;
  session_id=getSessionCookie();

  if(!session_id.empty()){
    account_id=validateSessionID();
  }
}

int TSession::validateSessionID()
{
  TDatabase db(DB_SNEEZY);

  db.query("select account_id from cgisession where session_id='%s' and (timeset+duration) > %i",
	   session_id.c_str(), time(NULL));

  if(!db.fetchRow())
    return -1;

  int a=convertTo<int>(db["account_id"]);

  return (a ? a : -1);
}

// gets the value of the "mudmail" cookie and returns it
sstring TSession::getSessionCookie()
{
  cgicc::CgiEnvironment env = cgi->getEnvironment();
  vector<cgicc::HTTPCookie> cookies = env.getCookieList();

  if(!cookies.size())
    return "";

  for(unsigned int i=0;i<cookies.size();++i){
    if(cookies[i].getName() == cookiename)
      return cookies[i].getValue();
  }
  return "";
}

void TSession::createSession()
{
  createSession(60*60);
  cookieduration=-1;
}

void TSession::createSession(int duration)
{
  cookieduration=duration;
  TDatabase db(DB_SNEEZY);

  do {
    session_id=generateSessionID();
    db.query("select 1 from cgisession where session_id='%s'",
	     session_id.c_str());
  } while(db.fetchRow());

  db.query("delete from cgisession where account_id=%i", account_id);
  db.query("insert into cgisession values ('%s', %i, %i, %i, '%s')",
	   session_id.c_str(), account_id, duration,
	   time(NULL), cookiename.c_str());
}

sstring TSession::generateSessionID()
{
  unsigned char data[16];
  int length=16;
  int seed[4];

  srandomdev();

  seed[0]=time(NULL);
  seed[1]=random();
  seed[2]=getpid();
  seed[3]=(int)&seed;

  int c=0;
  for(int i=0;i<4;++i){
    for(int j=0;j<4;++j){
      data[c++]=(&seed[i])[j];
    }
  }

  return MD5Data(data, length, NULL);
}

<|endoftext|>