<commit_before>/*
Request handlers for WSGI apps and static files

Copyright (c) 2016 Roman Miroshnychenko <romanvm@yandex.ua>
License: MIT, see License.txt
*/

#include "request_handlers.h"

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/copy.hpp>

#include <fstream>
#include <iostream>
#include <sstream>

using namespace std;
namespace py = boost::python;
namespace fs = boost::filesystem;
namespace sys = boost::system;
namespace alg = boost::algorithm;

namespace wsgi_boost
{
#pragma region StaticRequestHandler

	void StaticRequestHandler::handle()
	{
		const auto content_dir_path = fs::path{ m_request.content_dir };
		if (!fs::exists(content_dir_path))
		{
			m_response.send_mesage("500 Internal Server Error", "Error 500: Internal server error! Invalid content directory.");
			return;
		}
		if (m_request.method != "GET" && m_request.method != "HEAD")
		{
			m_response.send_mesage("405 Method Not Allowed");
			return;
		}
		open_file(content_dir_path);
	}

	void StaticRequestHandler::open_file(const fs::path& content_dir_path)
	{
		fs::path path = content_dir_path;
		path /= boost::regex_replace(m_request.path, m_request.path_regex, "");
		if (fs::exists(path))
		{
			path = fs::canonical(path);
			// Checking if path is inside content_dir
			if (distance(content_dir_path.begin(), content_dir_path.end()) <= distance(path.begin(), path.end()) &&
				equal(content_dir_path.begin(), content_dir_path.end(), path.begin()))
			{
				if (fs::is_directory(path))
				{
					path /= "index.html";
				}
				if (fs::exists(path) && fs::is_regular_file(path))
				{
					ifstream ifs;
					ifs.open(path.string(), ifstream::in | ios::binary);
					if (ifs)
					{
						headers_type out_headers;
						out_headers.emplace_back("Cache-Control", m_cache_control);
						time_t last_modified = fs::last_write_time(path);
						out_headers.emplace_back("Last-Modified", time_to_header(last_modified));
						string ims = m_request.get_header("If-Modified-Since");
						if (ims != "" && header_to_time(ims) >= last_modified)
						{
							out_headers.emplace_back("Content-Length", "0");
							m_response.send_header("304 Not Modified", out_headers, true);
							return;
						}
						string ext = path.extension().string();
						string mime = get_mime(ext);
						out_headers.emplace_back("Content-Type", mime);
						if (m_request.use_gzip && is_compressable(ext) && m_request.check_header("Accept-Encoding", "gzip"))
						{
							boost::iostreams::filtering_istream gzstream;
							gzstream.push(boost::iostreams::gzip_compressor());
							gzstream.push(ifs);
							stringstream compressed;
							boost::iostreams::copy(gzstream, compressed);
							out_headers.emplace_back("Content-Encoding", "gzip");
							send_file(compressed, out_headers);
						}
						else
						{
							out_headers.emplace_back("Accept-Ranges", "bytes");
							send_file(ifs, out_headers);
						}
						ifs.close();
						return;
					}
				}
			}
		}
		m_response.send_mesage("404 Not Found", "Error 404: Requested content not found!");
	}

	void StaticRequestHandler::send_file(istream& content_stream, headers_type& headers)
	{
		content_stream.seekg(0, ios::end);
		size_t length = content_stream.tellg();
		headers.emplace_back("Content-Length", to_string(length));
		size_t start_pos = 0;
		size_t end_pos = length - 1;
		string requested_range = m_request.get_header("Range");
		pair<string, string> range;
		if (requested_range != "" && ((range = parse_range(requested_range)) != pair<string, string>()))
		{
			if (range.first != string())
			{
				start_pos = stoull(range.first);
			}
			else
			{
				range.first = to_string(start_pos);
			}
			if (range.second != string())
			{
				end_pos = stoull(range.second);
			}
			else
			{
				range.second = to_string(end_pos);
			}
			if (start_pos > end_pos || start_pos >= length || end_pos >= length)
			{
				m_response.send_mesage("416 Range Not Satisfiable");
				return;
			}
			else
			{
				headers.emplace_back("Content-Range", "bytes " + range.first + "-" + range.second + "/" + to_string(length));
				m_response.send_header("206 Partial Content", headers, true);
			}
		}
		else
		{
			m_response.send_header("200 OK", headers, true);
		}
		if (start_pos > 0)
		{
			content_stream.seekg(start_pos);
		}
		else
		{
			content_stream.seekg(0, ios::beg);
		}
		if (m_request.method == "GET")
		{
			const size_t buffer_size = 131072;
			vector<char> buffer(buffer_size);
			size_t read_length;
			size_t bytes_left = end_pos - start_pos + 1;
			while (bytes_left > 0 && ((read_length = content_stream.read(&buffer[0], min(bytes_left, buffer_size)).gcount()) > 0))
			{
				sys::error_code ec = m_response.send_data(string(&buffer[0], read_length), true);
				if (ec)
					return;
				bytes_left -= read_length;
			}
		}
	}

#pragma endregion

#pragma region WsgiRequestHandler

	WsgiRequestHandler::WsgiRequestHandler(Request& request, Response& response, py::object& app, bool async) :
		BaseRequestHandler(request, response), m_app{ app }, m_async{ async }
	{
		function<void(py::object)> wr{
			[this](py::object data)
			{
				sys::error_code ec = m_response.send_header(m_status, m_out_headers);
				if (ec)
					return;
				m_headers_sent = true;
				string cpp_data = py::extract<string>(data);
				GilRelease release_gil;
				m_response.send_data(cpp_data);
			}
		};
		m_write = py::make_function(wr, py::default_call_policies(), py::args("data"), boost::mpl::vector<void, py::object>());
		function<py::object(py::str, py::list, py::object)> sr{
			[this](py::str status, py::list headers, py::object exc_info = py::object())
			{
				if (!exc_info.is_none())
				{
					py::object format_exc = py::import("traceback").attr("format_exc")();
					string exc_msg = py::extract<string>(format_exc);
					cerr << exc_msg << '\n';
					exc_info = py::object();
				}
				this->m_status = py::extract<string>(status);
				m_out_headers.clear();
				bool has_cont_len = false;
				bool has_chunked = false;
				for (size_t i = 0; i < py::len(headers); ++i)
				{
					py::object header = headers[i];
					string header_name = py::extract<string>(header[0]);
					string header_value = py::extract<string>(header[1]);
					// If a WSGI app does not provide Content-Length header (e.g. Django)
					// we use Transfer-Encoding: chunked
					if (alg::iequals(header_name, "Content-Length"))
						has_cont_len = true;
					if (alg::iequals(header_name, "Transfer-Encoding") && header_value.find("chunked") == string::npos)
						has_chunked = true;
					m_out_headers.emplace_back(header_name, header_value);
				}
				if (!(has_cont_len || has_chunked))
				{
					this->m_send_chunked = true;
					m_out_headers.emplace_back("Transfer-Encoding", "chunked");
				}
				return m_write;
			}
		};
		m_start_response = py::make_function(sr, py::default_call_policies(),
			(py::arg("status"), "headers", py::arg("exc_info") = py::object()),
			boost::mpl::vector<py::object, py::str, py::list, py::object>());
	}

	void WsgiRequestHandler::handle()
	{
		if (m_app.is_none())
		{
			m_response.send_mesage("500 Internal Server Error", "Error 500: Internal server error! WSGI application is not set.");
			return;
		}
		prepare_environ();
		if (m_request.check_header("Expect", "100-continue"))
		{
			m_response.send_mesage("100 Continue");
		}
		py::object args = get_python_object(Py_BuildValue("(O,O)", m_environ.ptr(), m_start_response.ptr()));
		Iterator iterable{ get_python_object(PyEval_CallObject(m_app.ptr(), args.ptr())) };
		send_iterable(iterable);
	}

	void WsgiRequestHandler::prepare_environ()
	{
		m_environ["REQUEST_METHOD"] = m_request.method;
		m_environ["SCRIPT_NAME"] = "";
		pair<string, string> path_and_query = split_path(m_request.path);
		m_environ["PATH_INFO"] = path_and_query.first;
		m_environ["QUERY_STRING"] = path_and_query.second;
		string ct = m_request.get_header("Content-Type");
		if (ct != "")
		{
			m_environ["CONTENT_TYPE"] = ct;
		}
		string cl = m_request.get_header("Content-Length");
		if (cl != "")
		{
			m_environ["CONTENT_LENGTH"] = cl;
		}
		m_environ["SERVER_NAME"] = m_request.host_name;
		m_environ["SERVER_PORT"] = to_string(m_request.local_endpoint_port);
		m_environ["SERVER_PROTOCOL"] = m_request.http_version;
		for (const auto& header : m_request.headers)
		{
			std::string env_header = transform_header(header.first);
			if (env_header == "HTTP_CONTENT_TYPE" || env_header == "HTTP_CONTENT_LENGTH")
			{
				continue;
			}
			if (!py::extract<bool>(m_environ.attr("__contains__")(env_header)))
			{
				m_environ[env_header] = header.second;
			}
			else
			{
				m_environ[env_header] = m_environ[env_header] + "," + header.second;
			}
		}
		m_environ["REMOTE_ADDR"] = m_environ["REMOTE_HOST"] = m_request.remote_address();
		m_environ["REMOTE_PORT"] = to_string(m_request.remote_port());
		m_environ["wsgi.version"] = py::make_tuple<int, int>(1, 0);
		m_environ["wsgi.url_scheme"] = m_request.url_scheme;
		InputWrapper input{ m_request.connection(), m_async };
		m_environ["wsgi.input"] = input;
		m_environ["wsgi.errors"] = py::import("sys").attr("stderr");
		m_environ["wsgi.multithread"] = true;
		m_environ["wsgi.multiprocess"] = false;
		m_environ["wsgi.run_once"] = false;
		m_environ["wsgi.file_wrapper"] = py::import("wsgiref.util").attr("FileWrapper");
	}

	void WsgiRequestHandler::send_iterable(Iterator& iterable)
	{
		py::object iterator = iterable.attr("__iter__")();
		while (true)
		{
			try
			{
#if PY_MAJOR_VERSION < 3
				std::string chunk = py::extract<string>(iterator.attr("next")());
#else
				std::string chunk = py::extract<string>(iterator.attr("__next__")());
#endif
				GilRelease release_gil;
				sys::error_code ec;
				if (!m_headers_sent)
				{
					ec = m_response.send_header(m_status, m_out_headers);
					if (ec)
						break;
					m_headers_sent = true;
				}
				if (m_send_chunked)
					chunk = hex(chunk.length()) + "\r\n" + chunk + "\r\n";
				ec = m_response.send_data(chunk, m_async);
				if (ec)
					break;
			}
			catch (const py::error_already_set&)
			{
				if (PyErr_ExceptionMatches(PyExc_StopIteration))
				{
					PyErr_Clear();
					if (m_send_chunked)
						m_response.send_data("0\r\n\r\n");
					break;
				}
				throw;
			}
		}
	}
#pragma endregion
}
<commit_msg>Fix bug with incorrect determiming chunked transfer encoding from a WSGI app<commit_after>/*
Request handlers for WSGI apps and static files

Copyright (c) 2016 Roman Miroshnychenko <romanvm@yandex.ua>
License: MIT, see License.txt
*/

#include "request_handlers.h"

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/copy.hpp>

#include <fstream>
#include <iostream>
#include <sstream>

using namespace std;
namespace py = boost::python;
namespace fs = boost::filesystem;
namespace sys = boost::system;
namespace alg = boost::algorithm;

namespace wsgi_boost
{
#pragma region StaticRequestHandler

	void StaticRequestHandler::handle()
	{
		const auto content_dir_path = fs::path{ m_request.content_dir };
		if (!fs::exists(content_dir_path))
		{
			m_response.send_mesage("500 Internal Server Error", "Error 500: Internal server error! Invalid content directory.");
			return;
		}
		if (m_request.method != "GET" && m_request.method != "HEAD")
		{
			m_response.send_mesage("405 Method Not Allowed");
			return;
		}
		open_file(content_dir_path);
	}

	void StaticRequestHandler::open_file(const fs::path& content_dir_path)
	{
		fs::path path = content_dir_path;
		path /= boost::regex_replace(m_request.path, m_request.path_regex, "");
		if (fs::exists(path))
		{
			path = fs::canonical(path);
			// Checking if path is inside content_dir
			if (distance(content_dir_path.begin(), content_dir_path.end()) <= distance(path.begin(), path.end()) &&
				equal(content_dir_path.begin(), content_dir_path.end(), path.begin()))
			{
				if (fs::is_directory(path))
				{
					path /= "index.html";
				}
				if (fs::exists(path) && fs::is_regular_file(path))
				{
					ifstream ifs;
					ifs.open(path.string(), ifstream::in | ios::binary);
					if (ifs)
					{
						headers_type out_headers;
						out_headers.emplace_back("Cache-Control", m_cache_control);
						time_t last_modified = fs::last_write_time(path);
						out_headers.emplace_back("Last-Modified", time_to_header(last_modified));
						string ims = m_request.get_header("If-Modified-Since");
						if (ims != "" && header_to_time(ims) >= last_modified)
						{
							out_headers.emplace_back("Content-Length", "0");
							m_response.send_header("304 Not Modified", out_headers, true);
							return;
						}
						string ext = path.extension().string();
						string mime = get_mime(ext);
						out_headers.emplace_back("Content-Type", mime);
						if (m_request.use_gzip && is_compressable(ext) && m_request.check_header("Accept-Encoding", "gzip"))
						{
							boost::iostreams::filtering_istream gzstream;
							gzstream.push(boost::iostreams::gzip_compressor());
							gzstream.push(ifs);
							stringstream compressed;
							boost::iostreams::copy(gzstream, compressed);
							out_headers.emplace_back("Content-Encoding", "gzip");
							send_file(compressed, out_headers);
						}
						else
						{
							out_headers.emplace_back("Accept-Ranges", "bytes");
							send_file(ifs, out_headers);
						}
						ifs.close();
						return;
					}
				}
			}
		}
		m_response.send_mesage("404 Not Found", "Error 404: Requested content not found!");
	}

	void StaticRequestHandler::send_file(istream& content_stream, headers_type& headers)
	{
		content_stream.seekg(0, ios::end);
		size_t length = content_stream.tellg();
		headers.emplace_back("Content-Length", to_string(length));
		size_t start_pos = 0;
		size_t end_pos = length - 1;
		string requested_range = m_request.get_header("Range");
		pair<string, string> range;
		if (requested_range != "" && ((range = parse_range(requested_range)) != pair<string, string>()))
		{
			if (range.first != string())
			{
				start_pos = stoull(range.first);
			}
			else
			{
				range.first = to_string(start_pos);
			}
			if (range.second != string())
			{
				end_pos = stoull(range.second);
			}
			else
			{
				range.second = to_string(end_pos);
			}
			if (start_pos > end_pos || start_pos >= length || end_pos >= length)
			{
				m_response.send_mesage("416 Range Not Satisfiable");
				return;
			}
			else
			{
				headers.emplace_back("Content-Range", "bytes " + range.first + "-" + range.second + "/" + to_string(length));
				m_response.send_header("206 Partial Content", headers, true);
			}
		}
		else
		{
			m_response.send_header("200 OK", headers, true);
		}
		if (start_pos > 0)
		{
			content_stream.seekg(start_pos);
		}
		else
		{
			content_stream.seekg(0, ios::beg);
		}
		if (m_request.method == "GET")
		{
			const size_t buffer_size = 131072;
			vector<char> buffer(buffer_size);
			size_t read_length;
			size_t bytes_left = end_pos - start_pos + 1;
			while (bytes_left > 0 && ((read_length = content_stream.read(&buffer[0], min(bytes_left, buffer_size)).gcount()) > 0))
			{
				sys::error_code ec = m_response.send_data(string(&buffer[0], read_length), true);
				if (ec)
					return;
				bytes_left -= read_length;
			}
		}
	}

#pragma endregion

#pragma region WsgiRequestHandler

	WsgiRequestHandler::WsgiRequestHandler(Request& request, Response& response, py::object& app, bool async) :
		BaseRequestHandler(request, response), m_app{ app }, m_async{ async }
	{
		function<void(py::object)> wr{
			[this](py::object data)
			{
				sys::error_code ec = m_response.send_header(m_status, m_out_headers);
				if (ec)
					return;
				m_headers_sent = true;
				string cpp_data = py::extract<string>(data);
				GilRelease release_gil;
				m_response.send_data(cpp_data);
			}
		};
		m_write = py::make_function(wr, py::default_call_policies(), py::args("data"), boost::mpl::vector<void, py::object>());
		function<py::object(py::str, py::list, py::object)> sr{
			[this](py::str status, py::list headers, py::object exc_info = py::object())
			{
				if (!exc_info.is_none())
				{
					py::object format_exc = py::import("traceback").attr("format_exc")();
					string exc_msg = py::extract<string>(format_exc);
					cerr << exc_msg << '\n';
					exc_info = py::object();
				}
				this->m_status = py::extract<string>(status);
				m_out_headers.clear();
				bool has_cont_len = false;
				bool has_chunked = false;
				for (size_t i = 0; i < py::len(headers); ++i)
				{
					py::object header = headers[i];
					string header_name = py::extract<string>(header[0]);
					string header_value = py::extract<string>(header[1]);
					// If a WSGI app does not provide Content-Length header (e.g. Django)
					// we use Transfer-Encoding: chunked
					if (alg::iequals(header_name, "Content-Length"))
						has_cont_len = true;
					if (alg::iequals(header_name, "Transfer-Encoding") && header_value.find("chunked") != string::npos)
						has_chunked = true;
					m_out_headers.emplace_back(header_name, header_value);
				}
				if (!(has_cont_len || has_chunked))
				{
					this->m_send_chunked = true;
					m_out_headers.emplace_back("Transfer-Encoding", "chunked");
				}
				return m_write;
			}
		};
		m_start_response = py::make_function(sr, py::default_call_policies(),
			(py::arg("status"), "headers", py::arg("exc_info") = py::object()),
			boost::mpl::vector<py::object, py::str, py::list, py::object>());
	}

	void WsgiRequestHandler::handle()
	{
		if (m_app.is_none())
		{
			m_response.send_mesage("500 Internal Server Error", "Error 500: Internal server error! WSGI application is not set.");
			return;
		}
		prepare_environ();
		if (m_request.check_header("Expect", "100-continue"))
		{
			m_response.send_mesage("100 Continue");
		}
		py::object args = get_python_object(Py_BuildValue("(O,O)", m_environ.ptr(), m_start_response.ptr()));
		Iterator iterable{ get_python_object(PyEval_CallObject(m_app.ptr(), args.ptr())) };
		send_iterable(iterable);
	}

	void WsgiRequestHandler::prepare_environ()
	{
		m_environ["REQUEST_METHOD"] = m_request.method;
		m_environ["SCRIPT_NAME"] = "";
		pair<string, string> path_and_query = split_path(m_request.path);
		m_environ["PATH_INFO"] = path_and_query.first;
		m_environ["QUERY_STRING"] = path_and_query.second;
		string ct = m_request.get_header("Content-Type");
		if (ct != "")
		{
			m_environ["CONTENT_TYPE"] = ct;
		}
		string cl = m_request.get_header("Content-Length");
		if (cl != "")
		{
			m_environ["CONTENT_LENGTH"] = cl;
		}
		m_environ["SERVER_NAME"] = m_request.host_name;
		m_environ["SERVER_PORT"] = to_string(m_request.local_endpoint_port);
		m_environ["SERVER_PROTOCOL"] = m_request.http_version;
		for (const auto& header : m_request.headers)
		{
			std::string env_header = transform_header(header.first);
			if (env_header == "HTTP_CONTENT_TYPE" || env_header == "HTTP_CONTENT_LENGTH")
			{
				continue;
			}
			if (!py::extract<bool>(m_environ.attr("__contains__")(env_header)))
			{
				m_environ[env_header] = header.second;
			}
			else
			{
				m_environ[env_header] = m_environ[env_header] + "," + header.second;
			}
		}
		m_environ["REMOTE_ADDR"] = m_environ["REMOTE_HOST"] = m_request.remote_address();
		m_environ["REMOTE_PORT"] = to_string(m_request.remote_port());
		m_environ["wsgi.version"] = py::make_tuple<int, int>(1, 0);
		m_environ["wsgi.url_scheme"] = m_request.url_scheme;
		InputWrapper input{ m_request.connection(), m_async };
		m_environ["wsgi.input"] = input;
		m_environ["wsgi.errors"] = py::import("sys").attr("stderr");
		m_environ["wsgi.multithread"] = true;
		m_environ["wsgi.multiprocess"] = false;
		m_environ["wsgi.run_once"] = false;
		m_environ["wsgi.file_wrapper"] = py::import("wsgiref.util").attr("FileWrapper");
	}

	void WsgiRequestHandler::send_iterable(Iterator& iterable)
	{
		py::object iterator = iterable.attr("__iter__")();
		while (true)
		{
			try
			{
#if PY_MAJOR_VERSION < 3
				std::string chunk = py::extract<string>(iterator.attr("next")());
#else
				std::string chunk = py::extract<string>(iterator.attr("__next__")());
#endif
				GilRelease release_gil;
				sys::error_code ec;
				if (!m_headers_sent)
				{
					ec = m_response.send_header(m_status, m_out_headers);
					if (ec)
						break;
					m_headers_sent = true;
				}
				if (m_send_chunked)
					chunk = hex(chunk.length()) + "\r\n" + chunk + "\r\n";
				ec = m_response.send_data(chunk, m_async);
				if (ec)
					break;
			}
			catch (const py::error_already_set&)
			{
				if (PyErr_ExceptionMatches(PyExc_StopIteration))
				{
					PyErr_Clear();
					if (m_send_chunked)
						m_response.send_data("0\r\n\r\n");
					break;
				}
				throw;
			}
		}
	}
#pragma endregion
}
<|endoftext|>


<commit_before>#include <QtGui/QGuiApplication>
#include <QtWidgets/QApplication>
#include <QQuickItem>
#include <QDebug>
#include <QSettings>
#include <QQmlContext>
#include <QSortFilterProxyModel>
#include <QtWidgets/QFileDialog>
#include <QTime>
#include "qtquick2applicationviewer.h"

#include "resourcelistmodel.h"
#include "humanlistmodel.h"
#include "savedgamelistmodel.h"
#include "settings.h"
#include "savesaccess.h"

#define TESTING 0

QString appVersion()
{
    // Version History
    // ---------------------
    // 0.4 - first release, only resource editing
    // 0.5 - second release, only tweaked resource list
    // 1.0 - units: add and remove
    //
    return "1.0 beta 2";
}

int main(int argc, char *argv[])
{
    // Seed the random number generator
    QTime time = QTime::currentTime();
    qsrand((uint)time.msec());

    QApplication app(argc, argv);
    QtQuick2ApplicationViewer viewer;
    viewer.setMinimumWidth(400);
    viewer.setMinimumHeight(350);

    QStringList libPaths = QCoreApplication::libraryPaths();
    libPaths.append(QCoreApplication::applicationDirPath() + "/plugins");
    app.setLibraryPaths(libPaths);

#if TESTING
    QByteArray binary;
    unsigned int result;
    bool failed(false);
    for( unsigned int value=0; value<65000; value++ )
    {
        binary = SavesAccess::toBinary(value);
        result = SavesAccess::toInt(binary);
        if( result != value)
        {
            qDebug() << "Value" << value << "returned" << result;
            failed = true;
            break;
        }
    }
    if( failed )
    {
        qDebug() << "[FAILURE] The tests did NOT succeed!";
    }
    else
    {
        qDebug() << "[PASSED]  All tests passed.";
    }
#endif

    QCoreApplication::setApplicationName("Axe and Pick");
    QCoreApplication::setOrganizationDomain("potatominingcorp.com");
    QCoreApplication::setOrganizationName("Potato Mining Corporation");

    app.setWindowIcon(QIcon());
    viewer.setTitle(QCoreApplication::applicationName() + " v" + appVersion());

    // Register the list item types for the enumerations in QML
    qmlRegisterType<Resource>("Resource", 1,0, "Resource");

    // Load and create the settings. Give QML access.
    Settings settings;
    viewer.rootContext()->setContextProperty("settings", &settings);

    //
    // SAVED GAMES
    //
    // This holds the info for all the saved games.
    SavesAccess savesAccess;
    savesAccess.setFilePath(settings.value("TimberAndStone/GameInstallationDirectory").toString());
    SavedGameListModel * savedGameModel = new SavedGameListModel(new SavedGame, qApp);
    savesAccess.setSavedGameListModel(savedGameModel);
    savesAccess.loadGamesList();
    viewer.rootContext()->setContextProperty("savesAccess", &savesAccess);
    viewer.rootContext()->setContextProperty("savedGameModel", savedGameModel);

    //
    // RESOURCES
    //
    // Create a model that holds our resource data, and
    // add the data to it. Then make it available to QML.
    ResourceListModel * resourceModel = new ResourceListModel(new Resource, qApp);
    savesAccess.setResourceListModel(resourceModel);
    viewer.rootContext()->setContextProperty("resourceModel", resourceModel);

    // Create the proxy model that contains the results of the filter.
    QSortFilterProxyModel * proxyResourceModel = new QSortFilterProxyModel();
    proxyResourceModel->setSourceModel(resourceModel);
    proxyResourceModel->setFilterRole(Resource::FilterStringRole);
    // This prevents unknown items from showing up in the list.
    proxyResourceModel->setFilterRegExp("^(?!unknown).*");
    viewer.rootContext()->setContextProperty("resourceModelProxy", proxyResourceModel);

    // Enable the case insensitivity
    proxyResourceModel->setFilterCaseSensitivity(Qt::CaseInsensitive);

    // Setup sorting the resources
    //proxyResourceModel->setSortRole(Resource::TypeRole);
    //proxyResourceModel->sort(0);

    //
    // UNITS
    //
    // Humans
    HumanListModel * humanModel = new HumanListModel(new Human, qApp);
    savesAccess.setHumanModel(humanModel);
    viewer.rootContext()->setContextProperty("humanModel", humanModel);
    QSortFilterProxyModel * proxyHumanModel = new QSortFilterProxyModel();
    proxyHumanModel->setSourceModel(humanModel);
    proxyHumanModel->setFilterRole(Human::FilterStringRole);
    proxyHumanModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("humanModelProxy", proxyHumanModel);
    proxyHumanModel->setFilterRegExp("^(?!unknown).*");

    // Neutral Mobs
    NeutralMobListModel * neutralMobModel = new NeutralMobListModel(new NeutralMob, qApp);
    savesAccess.setNeutralMobModel(neutralMobModel);
    viewer.rootContext()->setContextProperty("neutralMobModel", neutralMobModel);
    QSortFilterProxyModel * proxyNeutralMobModel = new QSortFilterProxyModel();
    proxyNeutralMobModel->setSourceModel(neutralMobModel);
    proxyNeutralMobModel->setFilterRole(NeutralMob::FilterStringRole);
    proxyNeutralMobModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("neutralMobModelProxy", proxyNeutralMobModel);

    // Violent Mobs
    ViolentMobListModel * violentMobModel = new ViolentMobListModel(new ViolentMob, qApp);
    savesAccess.setViolentMobModel(violentMobModel);
    viewer.rootContext()->setContextProperty("violentMobModel", violentMobModel);
    QSortFilterProxyModel * proxyViolentMobModel = new QSortFilterProxyModel();
    proxyViolentMobModel->setSourceModel(violentMobModel);
    proxyViolentMobModel->setFilterRole(ViolentMob::FilterStringRole);
    proxyViolentMobModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("violentMobModelProxy", proxyViolentMobModel);

    // Load the QML
    viewer.setMainQmlFile(QStringLiteral("qml/AxeAndPick/main.qml"));

    // Show the GUI
    viewer.showExpanded();

    return app.exec();
}
<commit_msg>Updated version information to version 1.0, beta 3<commit_after>#include <QtGui/QGuiApplication>
#include <QtWidgets/QApplication>
#include <QQuickItem>
#include <QDebug>
#include <QSettings>
#include <QQmlContext>
#include <QSortFilterProxyModel>
#include <QtWidgets/QFileDialog>
#include <QTime>
#include "qtquick2applicationviewer.h"

#include "resourcelistmodel.h"
#include "humanlistmodel.h"
#include "savedgamelistmodel.h"
#include "settings.h"
#include "savesaccess.h"

#define TESTING 0

QString appVersion()
{
    // Version History
    // ---------------------
    // 0.4 - first release, only resource editing
    // 0.5 - second release, only tweaked resource list
    // 1.0 - units: add and remove, added error display
    //
    return "1.0 beta 3";
}

int main(int argc, char *argv[])
{
    // Seed the random number generator
    QTime time = QTime::currentTime();
    qsrand((uint)time.msec());

    QApplication app(argc, argv);
    QtQuick2ApplicationViewer viewer;
    viewer.setMinimumWidth(400);
    viewer.setMinimumHeight(350);

    QStringList libPaths = QCoreApplication::libraryPaths();
    libPaths.append(QCoreApplication::applicationDirPath() + "/plugins");
    app.setLibraryPaths(libPaths);

#if TESTING
    QByteArray binary;
    unsigned int result;
    bool failed(false);
    for( unsigned int value=0; value<65000; value++ )
    {
        binary = SavesAccess::toBinary(value);
        result = SavesAccess::toInt(binary);
        if( result != value)
        {
            qDebug() << "Value" << value << "returned" << result;
            failed = true;
            break;
        }
    }
    if( failed )
    {
        qDebug() << "[FAILURE] The tests did NOT succeed!";
    }
    else
    {
        qDebug() << "[PASSED]  All tests passed.";
    }
#endif

    QCoreApplication::setApplicationName("Axe and Pick");
    QCoreApplication::setOrganizationDomain("potatominingcorp.com");
    QCoreApplication::setOrganizationName("Potato Mining Corporation");

    app.setWindowIcon(QIcon());
    viewer.setTitle(QCoreApplication::applicationName() + " v" + appVersion());

    // Register the list item types for the enumerations in QML
    qmlRegisterType<Resource>("Resource", 1,0, "Resource");

    // Load and create the settings. Give QML access.
    Settings settings;
    viewer.rootContext()->setContextProperty("settings", &settings);

    //
    // SAVED GAMES
    //
    // This holds the info for all the saved games.
    SavesAccess savesAccess;
    savesAccess.setFilePath(settings.value("TimberAndStone/GameInstallationDirectory").toString());
    SavedGameListModel * savedGameModel = new SavedGameListModel(new SavedGame, qApp);
    savesAccess.setSavedGameListModel(savedGameModel);
    savesAccess.loadGamesList();
    viewer.rootContext()->setContextProperty("savesAccess", &savesAccess);
    viewer.rootContext()->setContextProperty("savedGameModel", savedGameModel);

    //
    // RESOURCES
    //
    // Create a model that holds our resource data, and
    // add the data to it. Then make it available to QML.
    ResourceListModel * resourceModel = new ResourceListModel(new Resource, qApp);
    savesAccess.setResourceListModel(resourceModel);
    viewer.rootContext()->setContextProperty("resourceModel", resourceModel);

    // Create the proxy model that contains the results of the filter.
    QSortFilterProxyModel * proxyResourceModel = new QSortFilterProxyModel();
    proxyResourceModel->setSourceModel(resourceModel);
    proxyResourceModel->setFilterRole(Resource::FilterStringRole);
    // This prevents unknown items from showing up in the list.
    proxyResourceModel->setFilterRegExp("^(?!unknown).*");
    viewer.rootContext()->setContextProperty("resourceModelProxy", proxyResourceModel);

    // Enable the case insensitivity
    proxyResourceModel->setFilterCaseSensitivity(Qt::CaseInsensitive);

    // Setup sorting the resources
    //proxyResourceModel->setSortRole(Resource::TypeRole);
    //proxyResourceModel->sort(0);

    //
    // UNITS
    //
    // Humans
    HumanListModel * humanModel = new HumanListModel(new Human, qApp);
    savesAccess.setHumanModel(humanModel);
    viewer.rootContext()->setContextProperty("humanModel", humanModel);
    QSortFilterProxyModel * proxyHumanModel = new QSortFilterProxyModel();
    proxyHumanModel->setSourceModel(humanModel);
    proxyHumanModel->setFilterRole(Human::FilterStringRole);
    proxyHumanModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("humanModelProxy", proxyHumanModel);
    proxyHumanModel->setFilterRegExp("^(?!unknown).*");

    // Neutral Mobs
    NeutralMobListModel * neutralMobModel = new NeutralMobListModel(new NeutralMob, qApp);
    savesAccess.setNeutralMobModel(neutralMobModel);
    viewer.rootContext()->setContextProperty("neutralMobModel", neutralMobModel);
    QSortFilterProxyModel * proxyNeutralMobModel = new QSortFilterProxyModel();
    proxyNeutralMobModel->setSourceModel(neutralMobModel);
    proxyNeutralMobModel->setFilterRole(NeutralMob::FilterStringRole);
    proxyNeutralMobModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("neutralMobModelProxy", proxyNeutralMobModel);

    // Violent Mobs
    ViolentMobListModel * violentMobModel = new ViolentMobListModel(new ViolentMob, qApp);
    savesAccess.setViolentMobModel(violentMobModel);
    viewer.rootContext()->setContextProperty("violentMobModel", violentMobModel);
    QSortFilterProxyModel * proxyViolentMobModel = new QSortFilterProxyModel();
    proxyViolentMobModel->setSourceModel(violentMobModel);
    proxyViolentMobModel->setFilterRole(ViolentMob::FilterStringRole);
    proxyViolentMobModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    viewer.rootContext()->setContextProperty("violentMobModelProxy", proxyViolentMobModel);

    // Load the QML
    viewer.setMainQmlFile(QStringLiteral("qml/AxeAndPick/main.qml"));

    // Show the GUI
    viewer.showExpanded();

    return app.exec();
}
<|endoftext|>


<commit_before>#include "neural_network.h"
#include <cmath>
#include <algorithm>
#include <map>

NeuralNetwork::NeuralNetwork(const TrainingParameters & parameters):
	parameters(parameters),
	genome(parameters),
	inputNeurons(parameters.numberOfInputs),
	outputNeurons(parameters.numberOfOutputs)
{
	MutateGenesAndBuildNetwork();
}

NeuralNetwork::NeuralNetwork(const Genome& genome):
	parameters(genome.GetTrainingParameters()),
	genome(genome),
	inputNeurons(genome.GetTrainingParameters().numberOfInputs),
	outputNeurons(genome.GetTrainingParameters().numberOfOutputs)
{
	MutateGenesAndBuildNetwork();
}

NeuralNetwork::NeuralNetwork(Genome&& genome):
	parameters(genome.GetTrainingParameters()),
	genome(std::move(genome)),
	inputNeurons(genome.GetTrainingParameters().numberOfInputs),
	outputNeurons(genome.GetTrainingParameters().numberOfOutputs)
{
	MutateGenesAndBuildNetwork();
}

NeuralNetwork::NeuralNetwork(const NeuralNetwork& other) :
	parameters(other.parameters),
	genome(other.genome),
	neurons(other.neurons.size()),
	inputNeurons(other.inputNeurons.size()),
	outputNeurons(other.outputNeurons.size())
{
	BuildNetworkFromGenes();
}

NeuralNetwork::NeuralNetwork(NeuralNetwork&& other) :
	parameters(std::move(other.parameters)),
	genome(std::move(other.genome)),
	neurons(other.neurons.size()),
	inputNeurons(std::move(other.inputNeurons.size())),
	outputNeurons(std::move(other.outputNeurons.size()))
{
	BuildNetworkFromGenes();
}

NeuralNetwork& NeuralNetwork::operator=(const NeuralNetwork& other) {
    layerMap = other.layerMap;
	genome = other.genome;
	neurons = other.neurons;
	inputNeurons.resize(other.inputNeurons.size());
	outputNeurons.resize(other.outputNeurons.size());
	const_cast<TrainingParameters&>(this->parameters) = other.parameters;

	InterpretInputsAndOutputs();
	return *this;
}

void NeuralNetwork::BuildNetworkFromGenes() {
	neurons.resize(genome.GetNeuronCount());
	for (const auto& gene : genome) {
		if (gene.isEnabled) {
            Neuron::IncomingConnection connection;
            connection.neuron = &neurons[gene.from];
            connection.weight = gene.weight;
            connection.isRecursive = gene.isRecursive;
			neurons[gene.to].AddConnection(std::move(connection));
		}
	}
	InterpretInputsAndOutputs();
    CategorizeNeuronsIntoLayers();
}

void NeuralNetwork::SetInputs(const std::vector<float>& inputs) {
	if (inputNeurons.size() != inputs.size()) {
		throw std::out_of_range("Number of inputs provided doesn't match genetic information");
	}
	for(size_t i = 0U; i < inputNeurons.size(); ++i) {
		inputNeurons[i]->SetInput(inputs[i]);
	};
}

std::vector<float> NeuralNetwork::GetOutputs() {
    for (size_t i = 1; i < layerMap.size() - 1; ++i) {
        for (auto& neuron : layerMap[i]){
            neuron->RequestDataAndGetActionPotential();
        }
    }
	std::vector<float> outputs;
	outputs.reserve(outputNeurons.size());
	for(auto& outputNeuron : outputNeurons) {
		outputs.push_back(outputNeuron->RequestDataAndGetActionPotential());
	}
	return outputs;
}

std::vector<float> NeuralNetwork::GetOutputs(const std::vector<float>& inputs) {
	SetInputs(inputs);
	return GetOutputs();
}

void NeuralNetwork::InterpretInputsAndOutputs() {
    // Bias
    for (auto i = 0U; i < parameters.advanced.structure.numberOfBiasNeurons; i++) {
        neurons[i].SetInput(1.0f);
    }

    // Inputs
	for (auto i = 0U; i < parameters.numberOfInputs; i++) {
		inputNeurons[i] = &neurons[i + parameters.advanced.structure.numberOfBiasNeurons];
	}

    // Outputs
	for (auto i = 0U; i < parameters.numberOfOutputs; i++) {
		outputNeurons[i] = &neurons[genome[i * parameters.numberOfOutputs].to];
	}
}

bool NeuralNetwork::ShouldAddConnection() const {
	const bool hasChanceOccured = DidChanceOccure(parameters.advanced.mutation.chanceForConnectionalMutation);
	const bool hasSpaceForNewConnections = GetGenome().GetNeuronCount() > (parameters.numberOfInputs + parameters.numberOfOutputs + parameters.advanced.structure.numberOfBiasNeurons);
	return hasChanceOccured && hasSpaceForNewConnections;
}

bool NeuralNetwork::DidChanceOccure(float chance) {
	auto num = rand() % 100;
	return num < int(100.0f * chance);
}

size_t NeuralNetwork::GetRandomNumberBetween(size_t min, size_t max) {
	if (min == max) {
		return min;
	}
	return rand() % (max - min) + min;
}

void NeuralNetwork::AddRandomNeuron() {
	auto& randGene = GetRandomEnabledGene();
	auto indexOfNewNeuron = genome.GetNeuronCount();

	Gene g1;
	g1.from = randGene.from;
	g1.to = indexOfNewNeuron;
	g1.weight = randGene.weight;

	Gene g2;
	g2.from = indexOfNewNeuron;
	g2.to = randGene.to;
	g2.weight = randGene.weight;

	randGene.isEnabled = false;

	genome.AppendGene(std::move(g1));
	genome.AppendGene(std::move(g2));
}

void NeuralNetwork::AddRandomConnection() {
    size_t fromNeuronIndex = rand() % neurons.size();
    size_t toNeuronIndex = (rand() % (neurons.size() -1)) + 1;
    if (fromNeuronIndex == toNeuronIndex) {
        if (fromNeuronIndex < (neurons.size() - 1)) {
            fromNeuronIndex++;
        } else {
            fromNeuronIndex--;
        }
    }
    Gene newConnectionGene;
    newConnectionGene.from = fromNeuronIndex;
    newConnectionGene.to = toNeuronIndex;
    auto& fromNeuron = neurons[fromNeuronIndex];
    auto& toNeuron = neurons[toNeuronIndex];

    auto& lowerNeuron = fromNeuron.GetLayer() <= toNeuron.GetLayer() ? fromNeuron : toNeuron;
    auto& higherNeuron = fromNeuron.GetLayer() <= toNeuron.GetLayer() ? toNeuron : fromNeuron;

    newConnectionGene.isRecursive = &lowerNeuron == &toNeuron;
    if (!genome.DoesContainGene(newConnectionGene)) {
        Neuron::IncomingConnection newConnection;
        newConnection.isRecursive = newConnectionGene.isRecursive;
        newConnection.neuron = &lowerNeuron;
        newConnection.weight = newConnectionGene.weight;

        genome.AppendGene(std::move(newConnectionGene));
        higherNeuron.AddConnection(std::move(newConnection));
    }
}

void NeuralNetwork::ShuffleWeights() {
	for (size_t i = 0; i < genome.GetGeneCount(); i++) {
		if (ShouldMutateWeight()) {
			MutateWeightOfGeneAt(i);
		}
	}
}

void NeuralNetwork::MutateWeightOfGeneAt(size_t index) {
	if (DidChanceOccure(parameters.advanced.mutation.chanceOfTotalWeightReset)) {
        genome[index].SetRandomWeight();
	}
	else {
		PerturbWeightAt(index);
	}
}

void NeuralNetwork::PerturbWeightAt(size_t index) {
	constexpr float perturbanceBoundaries = 0.5f;
	auto perturbance = (float)(rand() % 10'000) / 9'999.0f * perturbanceBoundaries;
	if (rand() % 2) {
		perturbance = -perturbance;
	}
	genome[index].weight += perturbance;
	if (genome[index].weight < -1.0f) {
		genome[index].weight = -1.0f;
	} else
	if (genome[index].weight > 1.0f) {
		genome[index].weight = 1.0f;
	}
}

void NeuralNetwork::MutateGenesAndBuildNetwork() {
	if (ShouldAddConnection()) {
		BuildNetworkFromGenes();
		AddRandomConnection();
	} else
	if (ShouldAddNeuron()) {
		AddRandomNeuron();
		BuildNetworkFromGenes();
	}
	else {
		ShuffleWeights();
		BuildNetworkFromGenes();
	}
}

void NeuralNetwork::CategorizeNeuronsIntoLayers() {
	for (auto* out : outputNeurons) {
		CategorizeNeuronBranchIntoLayers(*out);
	}
	size_t highestLayer = 0U;
	for (auto* out : outputNeurons) {
		if (out->GetLayer() > highestLayer) {
			highestLayer = out->GetLayer();
		};
	}
	for (auto* out : outputNeurons) {
		out->SetLayer(highestLayer);
	}

    for (auto& neuron : neurons) {
        layerMap[neuron.GetLayer()].push_back(&neuron);
    }
}

void NeuralNetwork::CategorizeNeuronBranchIntoLayers(Neuron& currNode) {
	for (auto &in : currNode.GetConnections()) {
        if (!in.isRecursive) {
            CategorizeNeuronBranchIntoLayers(*in.neuron);
            currNode.SetLayer(in.neuron->GetLayer() + 1);
        }
	}
}

Gene& NeuralNetwork::GetRandomEnabledGene() {
	size_t num = rand() % genome.GetGeneCount();
	auto& randGene = genome.begin() + num;
	while (randGene != genome.end() && !randGene->isEnabled) {
		++randGene;
	}
	if (randGene == genome.end()) {
		randGene = genome.begin() + num;
		while (randGene != genome.begin() && !randGene->isEnabled) {
			--randGene;
		}
	}
	if (!randGene->isEnabled) {
		throw std::exception("Could not insert neuron because every gene is disabled");
	}
	return *randGene;
}<commit_msg>Same as last<commit_after>#include "neural_network.h"
#include <cmath>
#include <algorithm>
#include <map>

NeuralNetwork::NeuralNetwork(const TrainingParameters & parameters):
	parameters(parameters),
	genome(parameters),
	inputNeurons(parameters.numberOfInputs),
	outputNeurons(parameters.numberOfOutputs)
{
	MutateGenesAndBuildNetwork();
}

NeuralNetwork::NeuralNetwork(const Genome& genome):
	parameters(genome.GetTrainingParameters()),
	genome(genome),
	inputNeurons(genome.GetTrainingParameters().numberOfInputs),
	outputNeurons(genome.GetTrainingParameters().numberOfOutputs)
{
	MutateGenesAndBuildNetwork();
}

NeuralNetwork::NeuralNetwork(Genome&& genome):
	parameters(genome.GetTrainingParameters()),
	genome(std::move(genome)),
	inputNeurons(genome.GetTrainingParameters().numberOfInputs),
	outputNeurons(genome.GetTrainingParameters().numberOfOutputs)
{
	MutateGenesAndBuildNetwork();
}

NeuralNetwork::NeuralNetwork(const NeuralNetwork& other) :
	parameters(other.parameters),
	genome(other.genome),
	neurons(other.neurons.size()),
	inputNeurons(other.inputNeurons.size()),
	outputNeurons(other.outputNeurons.size())
{
	BuildNetworkFromGenes();
}

NeuralNetwork::NeuralNetwork(NeuralNetwork&& other) :
	parameters(std::move(other.parameters)),
	genome(std::move(other.genome)),
	neurons(other.neurons.size()),
	inputNeurons(std::move(other.inputNeurons.size())),
	outputNeurons(std::move(other.outputNeurons.size()))
{
	BuildNetworkFromGenes();
}

NeuralNetwork& NeuralNetwork::operator=(const NeuralNetwork& other) {
    layerMap = other.layerMap;
	genome = other.genome;
	neurons = other.neurons;
	inputNeurons.resize(other.inputNeurons.size());
	outputNeurons.resize(other.outputNeurons.size());
	const_cast<TrainingParameters&>(this->parameters) = other.parameters;

	InterpretInputsAndOutputs();
	return *this;
}

void NeuralNetwork::BuildNetworkFromGenes() {
	neurons.resize(genome.GetNeuronCount());
	for (const auto& gene : genome) {
		if (gene.isEnabled) {
            Neuron::IncomingConnection connection;
            connection.neuron = &neurons[gene.from];
            connection.weight = gene.weight;
            connection.isRecursive = gene.isRecursive;
			neurons[gene.to].AddConnection(std::move(connection));
		}
	}
	InterpretInputsAndOutputs();
    CategorizeNeuronsIntoLayers();
}

void NeuralNetwork::SetInputs(const std::vector<float>& inputs) {
	if (inputNeurons.size() != inputs.size()) {
		throw std::out_of_range("Number of inputs provided doesn't match genetic information");
	}
	for(size_t i = 0U; i < inputNeurons.size(); ++i) {
		inputNeurons[i]->SetInput(inputs[i]);
	};
}

std::vector<float> NeuralNetwork::GetOutputs() {
    for (size_t i = 1; i < layerMap.size() - 1; ++i) {
        for (auto& neuron : layerMap[i]){
            neuron->RequestDataAndGetActionPotential();
        }
    }
	std::vector<float> outputs;
	outputs.reserve(outputNeurons.size());
	for(auto& outputNeuron : outputNeurons) {
		outputs.push_back(outputNeuron->RequestDataAndGetActionPotential());
	}
	return outputs;
}

std::vector<float> NeuralNetwork::GetOutputs(const std::vector<float>& inputs) {
	SetInputs(inputs);
	return GetOutputs();
}

void NeuralNetwork::InterpretInputsAndOutputs() {
    // Bias
    for (auto i = 0U; i < parameters.advanced.structure.numberOfBiasNeurons; i++) {
        neurons[i].SetInput(1.0f);
    }

    // Inputs
	for (auto i = 0U; i < parameters.numberOfInputs; i++) {
		inputNeurons[i] = &neurons[i + parameters.advanced.structure.numberOfBiasNeurons];
	}

    // Outputs
	for (auto i = 0U; i < parameters.numberOfOutputs; i++) {
		outputNeurons[i] = &neurons[genome[i * parameters.numberOfOutputs].to];
	}
}

bool NeuralNetwork::ShouldAddConnection() const {
	const bool hasChanceOccured = DidChanceOccure(parameters.advanced.mutation.chanceForConnectionalMutation);
	const bool hasSpaceForNewConnections = GetGenome().GetNeuronCount() > (parameters.numberOfInputs + parameters.numberOfOutputs + parameters.advanced.structure.numberOfBiasNeurons);
	return hasChanceOccured && hasSpaceForNewConnections;
}

bool NeuralNetwork::DidChanceOccure(float chance) {
	auto num = rand() % 100;
	return num < int(100.0f * chance);
}

size_t NeuralNetwork::GetRandomNumberBetween(size_t min, size_t max) {
	if (min == max) {
		return min;
	}
	return rand() % (max - min) + min;
}

void NeuralNetwork::AddRandomNeuron() {
	auto& randGene = GetRandomEnabledGene();
	auto indexOfNewNeuron = genome.GetNeuronCount();

	Gene g1;
	g1.from = randGene.from;
	g1.to = indexOfNewNeuron;
	g1.weight = randGene.weight;

	Gene g2;
	g2.from = indexOfNewNeuron;
	g2.to = randGene.to;
	g2.weight = randGene.weight;

	randGene.isEnabled = false;

	genome.AppendGene(std::move(g1));
	genome.AppendGene(std::move(g2));
}

void NeuralNetwork::AddRandomConnection() {
    size_t fromNeuronIndex = rand() % neurons.size();
	auto inputRange = parameters.advanced.structure.numberOfBiasNeurons + parameters.numberOfInputs;
    size_t toNeuronIndex = (rand() % (neurons.size() - inputRange)) + inputRange;
    if (fromNeuronIndex == toNeuronIndex) {
        if (fromNeuronIndex < (neurons.size() - 1)) {
            fromNeuronIndex++;
        } else {
            fromNeuronIndex--;
        }
    }
    Gene newConnectionGene;
    newConnectionGene.from = fromNeuronIndex;
    newConnectionGene.to = toNeuronIndex;
    auto& fromNeuron = neurons[fromNeuronIndex];
    auto& toNeuron = neurons[toNeuronIndex];

    auto& lowerNeuron = fromNeuron.GetLayer() <= toNeuron.GetLayer() ? fromNeuron : toNeuron;
    auto& higherNeuron = fromNeuron.GetLayer() <= toNeuron.GetLayer() ? toNeuron : fromNeuron;

    newConnectionGene.isRecursive = &lowerNeuron == &toNeuron;
    if (!genome.DoesContainGene(newConnectionGene)) {
        Neuron::IncomingConnection newConnection;
        newConnection.isRecursive = newConnectionGene.isRecursive;
        newConnection.neuron = &lowerNeuron;
        newConnection.weight = newConnectionGene.weight;

        genome.AppendGene(std::move(newConnectionGene));
        higherNeuron.AddConnection(std::move(newConnection));
    }
}

void NeuralNetwork::ShuffleWeights() {
	for (size_t i = 0; i < genome.GetGeneCount(); i++) {
		if (ShouldMutateWeight()) {
			MutateWeightOfGeneAt(i);
		}
	}
}

void NeuralNetwork::MutateWeightOfGeneAt(size_t index) {
	if (DidChanceOccure(parameters.advanced.mutation.chanceOfTotalWeightReset)) {
        genome[index].SetRandomWeight();
	}
	else {
		PerturbWeightAt(index);
	}
}

void NeuralNetwork::PerturbWeightAt(size_t index) {
	constexpr float perturbanceBoundaries = 0.5f;
	auto perturbance = (float)(rand() % 10'000) / 9'999.0f * perturbanceBoundaries;
	if (rand() % 2) {
		perturbance = -perturbance;
	}
	genome[index].weight += perturbance;
	if (genome[index].weight < -1.0f) {
		genome[index].weight = -1.0f;
	} else
	if (genome[index].weight > 1.0f) {
		genome[index].weight = 1.0f;
	}
}

void NeuralNetwork::MutateGenesAndBuildNetwork() {
	if (ShouldAddConnection()) {
		BuildNetworkFromGenes();
		AddRandomConnection();
	} else
	if (ShouldAddNeuron()) {
		AddRandomNeuron();
		BuildNetworkFromGenes();
	}
	else {
		ShuffleWeights();
		BuildNetworkFromGenes();
	}
}

void NeuralNetwork::CategorizeNeuronsIntoLayers() {
	for (auto* out : outputNeurons) {
		CategorizeNeuronBranchIntoLayers(*out);
	}
	size_t highestLayer = 0U;
	for (auto* out : outputNeurons) {
		if (out->GetLayer() > highestLayer) {
			highestLayer = out->GetLayer();
		};
	}
	for (auto* out : outputNeurons) {
		out->SetLayer(highestLayer);
	}

    for (auto& neuron : neurons) {
        layerMap[neuron.GetLayer()].push_back(&neuron);
    }
}

void NeuralNetwork::CategorizeNeuronBranchIntoLayers(Neuron& currNode) {
	for (auto &in : currNode.GetConnections()) {
        if (!in.isRecursive) {
            CategorizeNeuronBranchIntoLayers(*in.neuron);
            currNode.SetLayer(in.neuron->GetLayer() + 1);
        }
	}
}

Gene& NeuralNetwork::GetRandomEnabledGene() {
	size_t num = rand() % genome.GetGeneCount();
	auto& randGene = genome.begin() + num;
	while (randGene != genome.end() && !randGene->isEnabled) {
		++randGene;
	}
	if (randGene == genome.end()) {
		randGene = genome.begin() + num;
		while (randGene != genome.begin() && !randGene->isEnabled) {
			--randGene;
		}
	}
	if (!randGene->isEnabled) {
		throw std::exception("Could not insert neuron because every gene is disabled");
	}
	return *randGene;
}<|endoftext|>


<commit_before>void CreateOnlineCalibPars(){
  // Create TOF Online Calibration Object for reconstruction
  // and write it on CDB
  AliTOFcalib *tofcalib = new AliTOFcalib();
  tofcalib->CreateCalArrays();
  TObjArray *tofCalOnline = (TObjArray*) tofcalib->GetTOFCalArrayOnline();
  // Write the offline calibration object on CDB

  AliCDBManager *man = AliCDBManager::Instance();
  man->SetDefaultStorage("local://$ALICE");
  Int_t nChannels = AliTOFGeometry::NSectors()*(2*(AliTOFGeometry::NStripC()+AliTOFGeometry::NStripB())+AliTOFGeometry::NStripA())*AliTOFGeometry::NpadZ()*AliTOFGeometry::NpadX();
  Float_t delay=0.;
  Float_t meanDelay=0.3;
  Float_t sigmaDelay=0.08;
  TRandom *rnd   = new TRandom(4357);
  for (Int_t ipad = 0 ; ipad<nChannels; ipad++){
    AliTOFChannelOnline *calChannelOnline = (AliTOFChannelOnline*)tofCalOnline->At(ipad);
    delay = rnd->Gaus(meanDelay,sigmaDelay);
    calChannelOnline->SetDelay(delay);
    calChannelOnline->SetStatus(AliTOFChannelOnline::kTOFOnlineOk);
  }
  tofcalib->WriteParOnlineOnCDB("TOF/Calib");
  return;
}
<commit_msg>Replacing obsolete file & Updating macro to create online delays in CDB to new calibration objects<commit_after>void CreateOnlineCalibPars(){
  // Create TOF Online Calibration Object for reconstruction
  // and write it on CDB;
  // NB: only delay set, status still ok
  AliTOFcalib *tofcalib = new AliTOFcalib();
  tofcalib->CreateCalArrays();
  TObjArray *tofCalOnline = (TObjArray*) tofcalib->GetTOFCalArrayOnline();
  TObjArray *tofCalOnlinePulser = (TObjArray*) tofcalib->GetTOFCalArrayOnlinePulser();
  TObjArray *tofCalOnlineNoise = (TObjArray*) tofcalib->GetTOFCalArrayOnlineNoise();
  TObjArray *tofCalOnlineHW = (TObjArray*) tofcalib->GetTOFCalArrayOnlineHW();
  // Write the offline calibration object on CDB

  AliCDBManager *man = AliCDBManager::Instance();
  man->SetDefaultStorage("local://$ALICE");
  Int_t nChannels = AliTOFGeometry::NSectors()*(2*(AliTOFGeometry::NStripC()+AliTOFGeometry::NStripB())+AliTOFGeometry::NStripA())*AliTOFGeometry::NpadZ()*AliTOFGeometry::NpadX();
  Float_t delay=0.;
  Float_t meanDelay=0.3;
  Float_t sigmaDelay=0.08;
  TRandom *rnd   = new TRandom(4357);
  for (Int_t ipad = 0 ; ipad<nChannels; ipad++){
    AliTOFChannelOnline *calChannelOnline = (AliTOFChannelOnline*)tofCalOnline->At(ipad);
    AliTOFChannelOnlineStatus *calChannelOnlinePulser = (AliTOFChannelOnlineStatus*)tofCalOnlinePulser->At(ipad);
    AliTOFChannelOnlineStatus *calChannelOnlineNoise = (AliTOFChannelOnlineStatus*)tofCalOnlineNoise->At(ipad);
    AliTOFChannelOnlineStatus *calChannelOnlineHW = (AliTOFChannelOnlineStatus*)tofCalOnlineHW->At(ipad);
    delay = rnd->Gaus(meanDelay,sigmaDelay);
    calChannelOnline->SetDelay(delay);
    calChannelOnlinePulser->SetStatus(AliTOFChannelOnlineStatus::kTOFPulserOk);
    calChannelOnlineNoise->SetStatus(AliTOFChannelOnlineStatus::kTOFNoiseOk);
    calChannelOnlineHW->SetStatus(AliTOFChannelOnlineStatus::kTOFHWOk);
  }
  tofcalib->WriteParOnlineOnCDB("TOF/Calib");
  tofcalib->WriteParOnlinePulserOnCDB("TOF/Calib");
  tofcalib->WriteParOnlineNoiseOnCDB("TOF/Calib");
  tofcalib->WriteParOnlineHWOnCDB("TOF/Calib");
  return;
}
<|endoftext|>


<commit_before>af438c5e-4b02-11e5-92ad-28cfe9171a43<commit_msg>fixed bug<commit_after>af508b0f-4b02-11e5-9ac4-28cfe9171a43<|endoftext|>


<commit_before>/*	opendatacon
 *
 *	Copyright (c) 2014:
 *
 *		DCrip3fJguWgVCLrZFfA7sIGgvx1Ou3fHfCxnrz4svAi
 *		yxeOtDhDCXf1Z4ApgXvX5ahqQmzRfJ2DoX8S05SqHA==
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *
 *		http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */
/*
 * JSONClientDataPort.cpp
 *
 *  Created on: 22/07/2014
 *      Author: Neil Stephens <dearknarl@gmail.com>
 */

#include <thread>
#include <chrono>
#include <opendnp3/LogLevels.h>
#include "JSONClientPort.h"

JSONClientPort::JSONClientPort(std::string aName, std::string aConfFilename, const Json::Value aConfOverrides):
	JSONPort(aName, aConfFilename, aConfOverrides)
{};

void JSONClientPort::BuildOrRebuild(asiodnp3::DNP3Manager& DNP3Mgr, openpal::LogFilters& LOG_LEVEL)
{}

void JSONClientPort::Enable()
{
	if(enabled) return;
	JSONPortConf* pConf = static_cast<JSONPortConf*>(this->pConf.get());
	try
	{
		asio::ip::tcp::resolver resolver(*pIOS);
		asio::ip::tcp::resolver::query query(pConf->mAddrConf.IP, std::to_string(pConf->mAddrConf.Port));
		auto endpoint_iterator = resolver.resolve(query);
		pSock.reset(new asio::ip::tcp::socket(*pIOS));
		asio::async_connect(*pSock.get(), endpoint_iterator,std::bind(&JSONClientPort::ConnectCompletionHandler,this,std::placeholders::_1));
	}
	catch(std::exception& e)
	{
		std::string msg = "Problem opening connection: "+Name+": "+e.what();
		auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::ERR,"", msg.c_str(), -1);
		pLoggers->Log(log_entry);
		return;
	}
};
void JSONClientPort::ConnectCompletionHandler(asio::error_code err_code)
{
	if(err_code)
	{
		std::string msg = Name+": Connect error: '"+err_code.message()+"'";
		auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::INFO,"", msg.c_str(), -1);
		pLoggers->Log(log_entry);
		//try again later
		JSONPortConf* pConf = static_cast<JSONPortConf*>(this->pConf.get());
		pTCPRetryTimer.reset(new Timer_t(*pIOS, std::chrono::milliseconds(pConf->retry_time_ms)));
		pTCPRetryTimer->async_wait(
		      [this](asio::error_code err_code)
		      {
		            if(err_code != asio::error::operation_aborted)
					Enable();
			});
		return;
	}
	std::string msg = Name+": Connect success!";
	auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::INFO,"", msg.c_str(), -1);
	pLoggers->Log(log_entry);

	enabled = true;
	Read();
}
void JSONClientPort::Read()
{
	asio::async_read(*pSock.get(), buf,asio::transfer_at_least(1), std::bind(&JSONClientPort::ReadCompletionHandler,this,std::placeholders::_1));
}
void JSONClientPort::ReadCompletionHandler(asio::error_code err_code)
{
	if(err_code)
	{
		if(err_code != asio::error::eof)
		{
			std::string msg = Name+": Read error: '"+err_code.message()+"'";
			auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::ERR,"", msg.c_str(), -1);
			pLoggers->Log(log_entry);
			return;
		}
		else
		{
			std::string msg = Name+": '"+err_code.message()+"' : Retrying...";
			auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::WARN,"", msg.c_str(), -1);
			pLoggers->Log(log_entry);
		}
	}

	//transfer content between matched braces to get processed as json
	char ch;
	std::string braced;
	size_t count_open_braces = 0, count_close_braces = 0;
	while(buf.size() > 0)
	{
		ch = buf.sgetc();
		buf.consume(1);
		if(ch=='{')
		{
			count_open_braces++;
			if(count_open_braces == 1)
				braced.clear(); //discard anything before the first brace
		}
		if(ch=='}')
		{
			count_close_braces++;
			if(count_close_braces > count_open_braces)
			{
				braced.clear(); //discard because it must be outside matched braces
				count_close_braces = count_open_braces = 0;
			}
		}
		braced.push_back(ch);
		//check if we've found a match to the first brace
		if(count_open_braces > 0 && count_close_braces == count_open_braces)
		{
			ProcessBraced(braced);
			braced.clear();
			count_close_braces = count_open_braces = 0;
		}
	}
	//put back the leftovers
	for(auto ch : braced)
		buf.sputc(ch);

	if(!err_code) //not eof - read more
		Read();
	else
	{
		//remote end closed the connection - reset and try reconnecting
		Disable();
		Enable();
	}
}

//At this point we have a whole (hopefully JSON) object - ie. {.*}
//Here we parse it and extract any paths that match our point config
void JSONClientPort::ProcessBraced(std::string braced)
{
	Json::Value JSONRoot; // will contain the root value after parsing.
	Json::Reader JSONReader;
	bool parsing_success = JSONReader.parse(braced, JSONRoot);
	if (parsing_success)
	{
		JSONPortConf* pConf = static_cast<JSONPortConf*>(this->pConf.get());

		//little functor to traverse any paths, starting at the root
		//pass a JSON array of nodes representing the path (that's how we store our point config after all)
		auto TraversePath = [&JSONRoot](const Json::Value nodes)
		{
			//val will traverse any paths, starting at the root
			auto val = JSONRoot;
			//traverse
			for(unsigned int n = 0; n < nodes.size(); ++n)
				if((val = val[nodes[n].asCString()]).isNull())
					break;
			return val;
		};

		Json::Value timestamp_val = TraversePath(pConf->pPointConf->TimestampPath);

		for(auto& point_pair : pConf->pPointConf->Analogs)
		{
			Json::Value val = TraversePath(point_pair.second["JSONPath"]);
			//if the path existed, load up the point
			if(!val.isNull())
			{
				if(val.isNumeric())
					LoadT(opendnp3::Analog(val.asDouble(),static_cast<uint8_t>(opendnp3::AnalogQuality::ONLINE)),point_pair.first, timestamp_val);
				else if(val.isString())
				{
					double value;
					try
					{
						value = std::stod(val.asString());
					}
					catch(std::exception&)
					{
						LoadT(opendnp3::Analog(0,static_cast<uint8_t>(opendnp3::AnalogQuality::COMM_LOST)),point_pair.first, timestamp_val);
						continue;
					}
					LoadT(opendnp3::Analog(value,static_cast<uint8_t>(opendnp3::AnalogQuality::ONLINE)),point_pair.first, timestamp_val);
				}
			}
		}

		for(auto& point_pair : pConf->pPointConf->Binaries)
		{
			Json::Value val = TraversePath(point_pair.second["JSONPath"]);
			//if the path existed, load up the point
			if(!val.isNull())
			{
				bool true_val = false; opendnp3::BinaryQuality qual = opendnp3::BinaryQuality::ONLINE;
				if(!point_pair.second["TrueVal"].isNull())
				{
					true_val = (val == point_pair.second["TrueVal"]);
					if(!point_pair.second["FalseVal"].isNull())
						if (!true_val && (val != point_pair.second["FalseVal"]))
							qual = opendnp3::BinaryQuality::COMM_LOST;
				}
				else if(!point_pair.second["FlaseVal"].isNull())
					true_val = !(val == point_pair.second["FalseVal"]);
				else if(val.isNumeric() || val.isBool())
					true_val = val.asBool();
				else if(val.isString())
				{
					true_val = (val.asString() == "true");
					if(!true_val && (val.asString() != "false"))
						qual = opendnp3::BinaryQuality::COMM_LOST;
				}
				else
					qual = opendnp3::BinaryQuality::COMM_LOST;

				LoadT(opendnp3::Binary(true_val,static_cast<uint8_t>(qual)),point_pair.first,timestamp_val);
			}
		}
		//TODO: implement controls
	}
	else
	{
		std::string msg = "Error parsing JSON string: '"+braced+"'";
		auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::WARN,"", msg.c_str(), -1);
		pLoggers->Log(log_entry);
	}
}
template<typename T>
inline void JSONClientPort::LoadT(T meas, uint16_t index, Json::Value timestamp_val)
{
	std::string msg = "Measurement Event '"+std::string(typeid(meas).name())+"'";
	auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::DBG,"", msg.c_str(), -1);
	pLoggers->Log(log_entry);

	if(!timestamp_val.isNull() && timestamp_val.isUInt64())
	{
		meas = T(meas.value, meas.quality, timestamp_val.asUInt64());
	}

	for(auto IOHandler_pair : Subscribers)
		IOHandler_pair.second->Event(meas, index, this->Name);
}
void JSONClientPort::Disable()
{
	//cancel the retry timer (otherwise it would tie up the io_service on shutdown)
	if(pTCPRetryTimer.get() != nullptr)
		pTCPRetryTimer->cancel();
	//shutdown and close socket by using destructor
	pSock.reset(nullptr);
	enabled = false;
};
<commit_msg>JSONClientPort: Fix incorrect check of JSON point FalseVal<commit_after>/*	opendatacon
 *
 *	Copyright (c) 2014:
 *
 *		DCrip3fJguWgVCLrZFfA7sIGgvx1Ou3fHfCxnrz4svAi
 *		yxeOtDhDCXf1Z4ApgXvX5ahqQmzRfJ2DoX8S05SqHA==
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *
 *		http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */
/*
 * JSONClientDataPort.cpp
 *
 *  Created on: 22/07/2014
 *      Author: Neil Stephens <dearknarl@gmail.com>
 */

#include <thread>
#include <chrono>
#include <opendnp3/LogLevels.h>
#include "JSONClientPort.h"

JSONClientPort::JSONClientPort(std::string aName, std::string aConfFilename, const Json::Value aConfOverrides):
	JSONPort(aName, aConfFilename, aConfOverrides)
{};

void JSONClientPort::BuildOrRebuild(asiodnp3::DNP3Manager& DNP3Mgr, openpal::LogFilters& LOG_LEVEL)
{}

void JSONClientPort::Enable()
{
	if(enabled) return;
	JSONPortConf* pConf = static_cast<JSONPortConf*>(this->pConf.get());
	try
	{
		asio::ip::tcp::resolver resolver(*pIOS);
		asio::ip::tcp::resolver::query query(pConf->mAddrConf.IP, std::to_string(pConf->mAddrConf.Port));
		auto endpoint_iterator = resolver.resolve(query);
		pSock.reset(new asio::ip::tcp::socket(*pIOS));
		asio::async_connect(*pSock.get(), endpoint_iterator,std::bind(&JSONClientPort::ConnectCompletionHandler,this,std::placeholders::_1));
	}
	catch(std::exception& e)
	{
		std::string msg = "Problem opening connection: "+Name+": "+e.what();
		auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::ERR,"", msg.c_str(), -1);
		pLoggers->Log(log_entry);
		return;
	}
};
void JSONClientPort::ConnectCompletionHandler(asio::error_code err_code)
{
	if(err_code)
	{
		std::string msg = Name+": Connect error: '"+err_code.message()+"'";
		auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::INFO,"", msg.c_str(), -1);
		pLoggers->Log(log_entry);
		//try again later
		JSONPortConf* pConf = static_cast<JSONPortConf*>(this->pConf.get());
		pTCPRetryTimer.reset(new Timer_t(*pIOS, std::chrono::milliseconds(pConf->retry_time_ms)));
		pTCPRetryTimer->async_wait(
		      [this](asio::error_code err_code)
		      {
		            if(err_code != asio::error::operation_aborted)
					Enable();
			});
		return;
	}
	std::string msg = Name+": Connect success!";
	auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::INFO,"", msg.c_str(), -1);
	pLoggers->Log(log_entry);

	enabled = true;
	Read();
}
void JSONClientPort::Read()
{
	asio::async_read(*pSock.get(), buf,asio::transfer_at_least(1), std::bind(&JSONClientPort::ReadCompletionHandler,this,std::placeholders::_1));
}
void JSONClientPort::ReadCompletionHandler(asio::error_code err_code)
{
	if(err_code)
	{
		if(err_code != asio::error::eof)
		{
			std::string msg = Name+": Read error: '"+err_code.message()+"'";
			auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::ERR,"", msg.c_str(), -1);
			pLoggers->Log(log_entry);
			return;
		}
		else
		{
			std::string msg = Name+": '"+err_code.message()+"' : Retrying...";
			auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::WARN,"", msg.c_str(), -1);
			pLoggers->Log(log_entry);
		}
	}

	//transfer content between matched braces to get processed as json
	char ch;
	std::string braced;
	size_t count_open_braces = 0, count_close_braces = 0;
	while(buf.size() > 0)
	{
		ch = buf.sgetc();
		buf.consume(1);
		if(ch=='{')
		{
			count_open_braces++;
			if(count_open_braces == 1)
				braced.clear(); //discard anything before the first brace
		}
		if(ch=='}')
		{
			count_close_braces++;
			if(count_close_braces > count_open_braces)
			{
				braced.clear(); //discard because it must be outside matched braces
				count_close_braces = count_open_braces = 0;
			}
		}
		braced.push_back(ch);
		//check if we've found a match to the first brace
		if(count_open_braces > 0 && count_close_braces == count_open_braces)
		{
			ProcessBraced(braced);
			braced.clear();
			count_close_braces = count_open_braces = 0;
		}
	}
	//put back the leftovers
	for(auto ch : braced)
		buf.sputc(ch);

	if(!err_code) //not eof - read more
		Read();
	else
	{
		//remote end closed the connection - reset and try reconnecting
		Disable();
		Enable();
	}
}

//At this point we have a whole (hopefully JSON) object - ie. {.*}
//Here we parse it and extract any paths that match our point config
void JSONClientPort::ProcessBraced(std::string braced)
{
	Json::Value JSONRoot; // will contain the root value after parsing.
	Json::Reader JSONReader;
	bool parsing_success = JSONReader.parse(braced, JSONRoot);
	if (parsing_success)
	{
		JSONPortConf* pConf = static_cast<JSONPortConf*>(this->pConf.get());

		//little functor to traverse any paths, starting at the root
		//pass a JSON array of nodes representing the path (that's how we store our point config after all)
		auto TraversePath = [&JSONRoot](const Json::Value nodes)
		{
			//val will traverse any paths, starting at the root
			auto val = JSONRoot;
			//traverse
			for(unsigned int n = 0; n < nodes.size(); ++n)
				if((val = val[nodes[n].asCString()]).isNull())
					break;
			return val;
		};

		Json::Value timestamp_val = TraversePath(pConf->pPointConf->TimestampPath);

		for(auto& point_pair : pConf->pPointConf->Analogs)
		{
			Json::Value val = TraversePath(point_pair.second["JSONPath"]);
			//if the path existed, load up the point
			if(!val.isNull())
			{
				if(val.isNumeric())
					LoadT(opendnp3::Analog(val.asDouble(),static_cast<uint8_t>(opendnp3::AnalogQuality::ONLINE)),point_pair.first, timestamp_val);
				else if(val.isString())
				{
					double value;
					try
					{
						value = std::stod(val.asString());
					}
					catch(std::exception&)
					{
						LoadT(opendnp3::Analog(0,static_cast<uint8_t>(opendnp3::AnalogQuality::COMM_LOST)),point_pair.first, timestamp_val);
						continue;
					}
					LoadT(opendnp3::Analog(value,static_cast<uint8_t>(opendnp3::AnalogQuality::ONLINE)),point_pair.first, timestamp_val);
				}
			}
		}

		for(auto& point_pair : pConf->pPointConf->Binaries)
		{
			Json::Value val = TraversePath(point_pair.second["JSONPath"]);
			//if the path existed, load up the point
			if(!val.isNull())
			{
				bool true_val = false; opendnp3::BinaryQuality qual = opendnp3::BinaryQuality::ONLINE;
				if(!point_pair.second["TrueVal"].isNull())
				{
					true_val = (val == point_pair.second["TrueVal"]);
					if(!point_pair.second["FalseVal"].isNull())
						if (!true_val && (val != point_pair.second["FalseVal"]))
							qual = opendnp3::BinaryQuality::COMM_LOST;
				}
				else if(!point_pair.second["FalseVal"].isNull())
					true_val = !(val == point_pair.second["FalseVal"]);
				else if(val.isNumeric() || val.isBool())
					true_val = val.asBool();
				else if(val.isString())
				{
					true_val = (val.asString() == "true");
					if(!true_val && (val.asString() != "false"))
						qual = opendnp3::BinaryQuality::COMM_LOST;
				}
				else
					qual = opendnp3::BinaryQuality::COMM_LOST;

				LoadT(opendnp3::Binary(true_val,static_cast<uint8_t>(qual)),point_pair.first,timestamp_val);
			}
		}
		//TODO: implement controls
	}
	else
	{
		std::string msg = "Error parsing JSON string: '"+braced+"'";
		auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::WARN,"", msg.c_str(), -1);
		pLoggers->Log(log_entry);
	}
}
template<typename T>
inline void JSONClientPort::LoadT(T meas, uint16_t index, Json::Value timestamp_val)
{
	std::string msg = "Measurement Event '"+std::string(typeid(meas).name())+"'";
	auto log_entry = openpal::LogEntry("JSONClientPort", openpal::logflags::DBG,"", msg.c_str(), -1);
	pLoggers->Log(log_entry);

	if(!timestamp_val.isNull() && timestamp_val.isUInt64())
	{
		meas = T(meas.value, meas.quality, timestamp_val.asUInt64());
	}

	for(auto IOHandler_pair : Subscribers)
		IOHandler_pair.second->Event(meas, index, this->Name);
}
void JSONClientPort::Disable()
{
	//cancel the retry timer (otherwise it would tie up the io_service on shutdown)
	if(pTCPRetryTimer.get() != nullptr)
		pTCPRetryTimer->cancel();
	//shutdown and close socket by using destructor
	pSock.reset(nullptr);
	enabled = false;
};
<|endoftext|>


<commit_before>/*********************************
**********************************
**                              **
** Wababa: Simple Question Game **
**                              **
**********************************
*********************************/

// Preprocessor Commands
#include <iostream>
#include <string>
//Global Scope Namespace
using namespace std;

// Wababa Answer Variables
int a = 5;
int apples;
string b = "woof";
string c = "sally";
string bark;
string dollname;

void answerA (int answer, int thevar) {

if ( answer == thevar )
    cout << "Yes!\n";
else
    cout << "Wrong!\n";
}

void answerQ (string answer, string thevar) {

if ( answer == thevar )
    cout << "Yes!\n";
else
    cout << "Wrong!\n";
}

int main () {

    // Wababa Welcome.
    string wababa;
    wababa = "Wababa!\n\n";
    cout << wababa;

    // Question #1
    cout << "How many red items are there: ";
    cin >> apples;
    answerA(apples, a);

    // Question #2
    cout << "What did the pet say: ";
    cin >> bark;
    answerQ(bark,b);

    // Question #3
    cout << "What's her name: ";
    cin >> dollname;
    answerQ(dollname,c);

    // Returns 0
    return 0;

}
<commit_msg>Made the third answer more cryptic.<commit_after>/*********************************
**********************************
**                              **
** Wababa: Simple Question Game **
**                              **
**********************************
*********************************/

// Preprocessor Commands
#include <iostream>
#include <string>
//Global Scope Namespace
using namespace std;

// Wababa Answer Variables
int a = 5;
int apples;
string b = "woof";
string c = "sally";
string bark;
string dollname;

void answerA (int answer, int thevar) {

if ( answer == thevar )
    cout << "Yes!\n";
else
    cout << "Wrong!\n";
}

void answerQ (string answer, string thevar) {

if ( answer == thevar )
    cout << "Yes!\n";
else
    cout << "Wrong!\n";
}

int main () {

    // Wababa Welcome.
    string wababa;
    wababa = "Wababa!\n\n";
    cout << wababa;

    // Question #1
    cout << "How many red items are there: ";
    cin >> apples;
    answerA(apples, a);

    // Question #2
    cout << "What did the pet say: ";
    cin >> bark;
    answerQ(bark,b);

    // Question #3
    cout << "What's the pretty thing's name: ";
    cin >> dollname;
    answerQ(dollname,c);

    // Returns 0
    return 0;

}
<|endoftext|>


<commit_before>#define PARSE_TABLE_ROWS 18
#define PARSE_TABLE_COLS 7

#include "parse.h"

#include <iostream>
#include <string>
#include <vector>
#include <utility>

using namespace parse;

struct S;
struct V;
struct E;

struct S : public Nonterminal<S> {
private:
	std::string s;
public:
	S(E e);
	S(V v, std::string s, E e);

	std::string to_string() { return s; }
};

struct V : public Nonterminal<V> {
private:
	std::string s;
public:
	V(std::string s);
	V(std::string s, E e);

	std::string to_string() { return s; }
};

struct E : public Nonterminal<E> {
private:
	std::string s;
public:
	E(V v);

	std::string to_string() { return s; }
};

S::S(E e) : s("E[" + e.to_string() + "]") {}
S::S(V v, std::string s, E e) : s("V[" + v.to_string() + "], " + s + ", E[" + e.to_string() + "]") {}

V::V(std::string s) : s(s) {}
V::V(std::string s, E e) : s(s + ", E[" + e.to_string() + "]") {}

E::E(V v) : s("V[" + v.to_string() + "]") {}

struct Rule1 {
	S operator()(V v, std::string s, E e) {
		return S(v, s, e);
	}
};

struct Rule2 {
	S operator()(E e) {
		return S(e);
	}
};

struct Rule3 {
	E operator()(V v) {
		return E(v);
	}
};

struct Rule4 {
	V operator()(std::string s) {
		return V(s);
	}
};

struct Rule5 {
	V operator()(std::string s, E e) {
		return V(s, e);
	}
};

int main(int argc, char* argv []) {
	using x = Terminal<0>;
	using deref = Terminal<1>;
	using assign = Terminal<2>;

	using Parser = LrParser<
		Production<
			S,
			Right<V, assign, E>,
			Rule1
		>,
		Production<
			S,
			Right<E>,
			Rule2
		>,
		Production<
			E,
			Right<V>,
			Rule3
		>,
		Production<
			V,
			Right<x>,
			Rule4
		>,
		Production<
			V,
			Right<deref, E>,
			Rule5
		>
	>;

	std::vector<std::pair<std::string, int>> tokens = { {"x", 0}, {"=", 2}, {"*", 1}, {"*", 1}, {"*", 1}, {"x", 0}, {"", -1}};

	auto res = Parser::parse(tokens.begin(), tokens.end());
	if(res) {
		std::cout << res.get().to_string() << std::endl;
	}
	else {
		std::cout << "Input is malformed" << std::endl;
	}

	return 0;
}
<commit_msg>Delete main.cpp<commit_after><|endoftext|>


<commit_before>// Rectangles

#include <cassert>
#include <fstream>
#include <iostream>
#include <unordered_map>
#include <vector>

#include "named_rect.h"

struct Results {
  std::vector<char> overlaps;
  std::vector<char> contains;
  std::vector<char> containedBy;
  std::vector<char> touches;
};

using ResultsType = std::unordered_map<char, Results>;

// Get the corresponding Result object for the given rectangle name.
Results* getResults(ResultsType* results, char name) {
  bool inserted = false;
  auto it = results->find(name);
  if (it == std::end(*results))
    std::tie(it, inserted) = results->insert(std::make_pair(name, Results()));

  return &it->second;
}

// Given a list of rectangle names, print them out in a comma separated line.
void printNames(std::ostream& os, const std::vector<char>& names) {
  if (names.empty()) {
    os << '0';
  } else {
    const size_t size = names.size();
    for (size_t i = 0; i < size; ++i) {
      os << names[i];
      if (i < size - 1)
        os << ',';
    }
  }
  os << std::endl;
}

void printResults(std::ostream& os, const ResultsType& results) {
  for (const auto& it : results) {
    os << it.first << std::endl;
    printNames(os, it.second.overlaps);
    printNames(os, it.second.contains);
    printNames(os, it.second.containedBy);
    printNames(os, it.second.touches);
    os << std::endl;
  }
}

int main() {
  std::vector<NamedRect> rectangles;

  // Read the rectangles in the file into our list of rectangles.
  readRectanglesFromFile("rectangles.txt", &rectangles);

  for (const auto& rect : rectangles)
    std::cout << "Rect: " << rect << std::endl;

  ResultsType results;

  for (const auto& first : rectangles) {
    Results* r = getResults(&results, first.name);

    for (const auto& second : rectangles) {
      if (first.rect.overlaps(second.rect))
        r->overlaps.push_back(second.name);
      if (first.rect.contains(second.rect))
        r->contains.push_back(second.name);
      if (second.rect.contains(first.rect))
        r->containedBy.push_back(first.name);
      if (first.rect.touches(second.rect))
        r->touches.push_back(second.name);
    }
  }

#if 0
  printResults(std::cout, results);
#else
  std::ofstream outFile("results.txt", std::ios::out);
  printResults(outFile, results);
#endif

  return 0;
}
<commit_msg>Added some logging.<commit_after>// Rectangles

#include <cassert>
#include <fstream>
#include <iostream>
#include <unordered_map>
#include <vector>

#include "named_rect.h"

struct Results {
  std::vector<char> overlaps;
  std::vector<char> contains;
  std::vector<char> containedBy;
  std::vector<char> touches;
};

using ResultsType = std::unordered_map<char, Results>;

// Get the corresponding Result object for the given rectangle name.
Results* getResults(ResultsType* results, char name) {
  bool inserted = false;
  auto it = results->find(name);
  if (it == std::end(*results))
    std::tie(it, inserted) = results->insert(std::make_pair(name, Results()));

  return &it->second;
}

// Given a list of rectangle names, print them out in a comma separated line.
void printNames(std::ostream& os, const std::vector<char>& names) {
  if (names.empty()) {
    os << '0';
  } else {
    const size_t size = names.size();
    for (size_t i = 0; i < size; ++i) {
      os << names[i];
      if (i < size - 1)
        os << ',';
    }
  }
  os << std::endl;
}

void printResults(std::ostream& os, const ResultsType& results) {
  for (const auto& it : results) {
    os << it.first << std::endl;
    printNames(os, it.second.overlaps);
    printNames(os, it.second.contains);
    printNames(os, it.second.containedBy);
    printNames(os, it.second.touches);
    os << std::endl;
  }
}

int main() {
  std::vector<NamedRect> rectangles;

  // Read the rectangles in the file into our list of rectangles.
  std::cout << "Loading rectangles from file: rectangles.txt" << std::endl;
  readRectanglesFromFile("rectangles.txt", &rectangles);

#if 0
  for (const auto& rect : rectangles)
    std::cout << "Rect: " << rect << std::endl;
#endif  // 0

  std::cout << "Calculating results..." << std::endl;

  ResultsType results;
  for (const auto& first : rectangles) {
    Results* r = getResults(&results, first.name);

    for (const auto& second : rectangles) {
      if (first.rect.overlaps(second.rect))
        r->overlaps.push_back(second.name);
      if (first.rect.contains(second.rect))
        r->contains.push_back(second.name);
      if (second.rect.contains(first.rect))
        r->containedBy.push_back(first.name);
      if (first.rect.touches(second.rect))
        r->touches.push_back(second.name);
    }
  }

  std::cout << "Writing output to file: results.txt" << std::endl;
#if 0
  printResults(std::cout, results);
#else
  std::ofstream outFile("results.txt", std::ios::out);
  printResults(outFile, results);
#endif

  return 0;
}
<|endoftext|>


<commit_before>8597401e-4b02-11e5-9ec6-28cfe9171a43<commit_msg>more fixes<commit_after>85a2c1d1-4b02-11e5-bd19-28cfe9171a43<|endoftext|>


<commit_before>#include "mitkContour.h"
#include "mitkCommon.h"

#include <fstream>
int mitkContourTest(int argc, char* argv[])
{
  mitk::Contour::Pointer contour;
  std::cout << "Testing mitk::Contour::New(): ";
  contour = mitk::Contour::New();
  if (contour.IsNull()) {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else {
  std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Testing mitk::Contour::AddVertex(): ";
  mitk::ITKPoint3D p;
  p.Fill(0);
  contour->AddVertex(p);
  p.Fill(1);
  contour->AddVertex(p);
  p.Fill(2);
  contour->AddVertex(p);

  if (contour->GetNumberOfPoints() != 3)
    {
      std::cout<<"[FAILED]"<<std::endl;
      return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout << "Testing mitk::Contour::GetPoints()";
  mitk::Contour::PointsContainerPointer points = contour->GetPoints();
  if ( points.IsNull() )
    {
      std::cout<<"[FAILED]"<<std::endl;
      return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout << "Testing mitk::Contour::Initialize()";
  contour->Initialize();
  if (contour->GetNumberOfPoints() != 0)
    {
      std::cout<<"[FAILED]"<<std::endl;
      return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  contour->SetPoints(points);
  if ( contour->GetNumberOfPoints() != 3)
    {
      std::cout<<"[FAILED]"<<std::endl;
      return EXIT_FAILURE;
    };

  mitk::Contour::PathPointer path =  contour->GetContourPath();
  if ( path.IsNull() )
    {
    return EXIT_FAILURE;
    }

  std::cout<<"[TEST DONE]"<<std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>extended<commit_after>#include "mitkContour.h"
#include "mitkCommon.h"

#include <fstream>
int mitkContourTest(int argc, char* argv[])
{
  mitk::Contour::Pointer contour;
  std::cout << "Testing mitk::Contour::New(): ";
  contour = mitk::Contour::New();
  if (contour.IsNull()) {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else {
  std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Testing mitk::Contour::AddVertex(): ";
  mitk::ITKPoint3D p;
  p.Fill(0);
  contour->AddVertex(p);
  p.Fill(1);
  contour->AddVertex(p);
  p.Fill(2);
  contour->AddVertex(p);

  if (contour->GetNumberOfPoints() != 3)
    {
      std::cout<<"[FAILED]"<<std::endl;
      return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout << "Testing mitk::Contour::GetPoints()";
  mitk::Contour::PointsContainerPointer points = contour->GetPoints();
  if ( points.IsNull() )
    {
      std::cout<<"[FAILED]"<<std::endl;
      return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout << "Testing mitk::Contour::Initialize()";
  contour->Initialize();
  if (contour->GetNumberOfPoints() != 0)
    {
      std::cout<<"[FAILED]"<<std::endl;
      return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  contour->SetPoints(points);
  if ( contour->GetNumberOfPoints() != 3)
    {
      std::cout<<"[FAILED]"<<std::endl;
      return EXIT_FAILURE;
    };

  mitk::Contour::PathPointer path =  contour->GetContourPath();
  if ( path.IsNull() )
    {
    return EXIT_FAILURE;
    }

  contour->UpdateOutputInformation();
  contour->SetClosed(false);

  if (contour->GetClosed())
    {
    std::cout<<"[FAILED] "<<std::endl;
      return EXIT_FAILURE;
    }

  std::cout<<"[TEST DONE]"<<std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>61d52870-2749-11e6-8201-e0f84713e7b8<commit_msg>lets try again<commit_after>61e17863-2749-11e6-810c-e0f84713e7b8<|endoftext|>


<commit_before>#include <cstdio>
#include <iostream>
#include <vector>

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/opencv.hpp>

#include "linefinder.h"

#define PI 3.1415926

using namespace cv;
using namespace std;

int main()
{
	int houghVote=200;
	string arg=argv[1];
	bool showSteps=argv[2];

	string window_name="Processed Video";
	namedWindow(window_name,CV_WINDOW_KEEPRATIO); //resizable window;
	VideoCapture capture(arg);

	if (!capture.isOpened()) //if this fails, try to open as a video camera, through the use of an integer param
	{
		capture.open(atoi(arg.c_str()));
	}

	double dWidth=capture.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
	double dHeight=capture.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video

	cout<<"Frame Size = "<<dWidth<<"x"<<dHeight<<endl;

	Size frameSize(static_cast<int>(dWidth),static_cast<int>(dHeight));

	//VideoWriter oVideoWriter("LaneDetection.avi",CV_FOURCC('P','I','M','1'),20,frameSize,true); //initialize the VideoWriter object

	Mat image;
	image=imread(argv[1]);
	while(1)
	{
		capture>>image;
		if(image.empty())
			break;
		Mat gray;
		cvtColor(image,gray,CV_RGB2GRAY);
		//vector<string> codes;
		//Mat corners;
		//findDataMatrix(gray, codes, corners);
		//drawDataMatrixCodes(image, codes, corners);

		Rect roi(0,image.cols/3,image.cols-1,image.rows-image.cols/3);// set the ROI for the image
		Mat imgROI=image(roi);
		//Display the image
		if(showSteps)
		{
			namedWindow("Original Image");
			imshow("Original Image",imgROI);
		}

		//Canny algorithm
		Mat contours;
		Canny(imgROI,contours,50,250);
		Mat contoursInv;
		threshold(contours,contoursInv,128,255,THRESH_BINARY_INV);

		//Display Canny image
		if(showSteps)
		{
			namedWindow("Contours");
			imshow("Contours1",contoursInv);
		}

		 /*
		  *Hough tranform for line detection with feedback
		  *Increase by 25 for the next frame if we found some lines.
		  *This is so we don't miss other lines that may crop up in the next frame
		  *but at the same time we don't want to start the feed back loop from scratch.
		  */
		vector<Vec2f> lines;
		if(houghVote<1 or lines.size() > 2)
		{ //lost all lines. reset
			houghVote=200;
		}
		else
		{
			houghVote+=25;
		}
		while(lines.size()<5&&houghVote>0)
		{
			HoughLines(contours,lines,1,PI/180,houghVote);
			houghVote-=5;
		}
		cout<<houghVote<<"\n";
		Mat result(imgROI.size(),CV_8U,Scalar(255));
		imgROI.copyTo(result);

		//Draw the limes
		vector<Vec2f>::const_iterator it=lines.begin();
		Mat hough(imgROI.size(),CV_8U,Scalar(0));
		while(it!=lines.end())
		{
			float rho=(*it)[0];			//first element is distance rho
			float theta=(*it)[1];		//second element is angle theta

			if(theta>0.09 && theta<1.48||theta < 3.14 && theta > 1.66)
			// filter to remove vertical and horizontal lines
			{
				// point of intersection of the line with first row
				Point pt1(rho/cos(theta),0);
				// point of intersection of the line with last row
				Point pt2((rho-result.rows*sin(theta))/cos(theta),result.rows);
				// draw a white line
				line(result,pt1,pt2,Scalar(255),8);
				line(hough,pt1,pt2,Scalar(255),8);
			}

			//cout << "line: (" << rho << "," << theta << ")\n";
			++it;
		}

		//Display the detected line image
		if(showSteps)
		{
			namedWindow("Detected Lines with Hough");
			imshow("Detected Lines with Hough",result);
		}

		//Create LineFinder instance
		LineFinder ld;

		//Set probabilistic Hough parameters
		ld.setLineLengthAndGap(60,10);
		ld.setMinVote(4);

		//Detect lines
		vector<Vec4i> li=ld.findLines(contours);
		Mat houghP(imgROI.size(),CV_8U,Scalar(0));
		ld.setShift(0);
		ld.drawDetectedLines(houghP);
		cout<<"First Hough"<<"\n";

		if(showSteps)
		{
			namedWindow("Detected Lines with HoughP");
			imshow("Detected Lines with HoughP",houghP);
		}

		//bitwise AND of the two hough images
		bitwise_and(houghP,hough,houghP);
		Mat houghPinv(imgROI.size(),CV_8U,Scalar(0));
		Mat dst(imgROI.size(),CV_8U,Scalar(0));
		threshold(houghP,houghPinv,150,255,THRESH_BINARY_INV); // threshold and invert to black lines

		if(showSteps)
		{
			namedWindow("Detected Lines with Bitwise");
			imshow("Detected Lines with Bitwise",houghPinv);
		}

		Canny(houghPinv,contours,100,350);
		li=ld.findLines(contours);

		//Display Canny image
		if(showSteps)
		{
			namedWindow("Contours");
			imshow("Contours2",contours);
		}

		//Set probabilistic Hough parameters
		ld.setLineLengthAndGap(5,2);
		ld.setMinVote(1);
		ld.setShift(image.cols/3);
		ld.drawDetectedLines(image);

		stringstream stream;
		stream<<"Lines Segments: "<<lines.size();

		putText(image,stream.str(),Point(10,image.rows-10),2,0.8,Scalar(0,0,255),0);
		imshow(window_name,image);

		//oVideoWriter.write(image); //writer the frame into the file

		char key=(char)waitKey(10);
		lines.clear();
	}
}
<commit_msg>Optimization of codes<commit_after>#include <cstdio>
#include <iostream>
#include <vector>

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/opencv.hpp>

#include "linefinder.h"

#define PI 3.1415926

using namespace cv;
using namespace std;

int main()
{
	int houghVote=200;
	string arg="/dev/video0";
	bool showSteps=true;

	string window_name="Processed Image";
	namedWindow(window_name);
	VideoCapture capture(arg);

	if (!capture.isOpened())
	//If this fails, try to open as a video camera, through the use of an integer param
	{
		capture.open(atoi(arg.c_str()));
	}

	double dWidth=capture.get(CV_CAP_PROP_FRAME_WIDTH);			//get the width of frames of the video
	double dHeight=capture.get(CV_CAP_PROP_FRAME_HEIGHT);		//get the height of frames of the video
	cout<<"Frame Size: "<<dWidth<<"x"<<dHeight<<endl;

	Mat image;
	image=imread(arg);
	while(true)
	{
		capture>>image;
		if(image.empty())
			break;

		//Set the ROI for the image
		Rect roi((image.cols-image.rows)/2,0,image.rows,image.rows);
		Mat imgROI=image(roi);

		//Canny algorithm
		Mat contours;
		Canny(imgROI,contours,50,250);

		 /*
		  *Hough tranform for line detection with feedback
		  *Increase by 25 for the next frame if we found some lines.
		  *This is so we don't miss other lines that may crop up in the next frame
		  *but at the same time we don't want to start the feed back loop from scratch.
		  */
		vector<Vec2f> lines;
		if(houghVote<1||lines.size()>10)
		//All lines lost. Reset
			houghVote=200;
		else
			houghVote+=25;

		while(lines.size()<2&&houghVote>0)
		{
			HoughLines(contours,lines,1,PI/180,houghVote);
			houghVote-=5;
		}
		clog<<"houghVote="<<houghVote<<endl;
		Mat result(imgROI.size(),CV_8U,Scalar(255));
		imgROI.copyTo(result);

		//Draw the lines
		for(vector<Vec2f>::const_iterator it=lines.begin();it!=lines.end();++it)
		{
			float rho=(*it)[0];			//first element is distance rho
			float theta=(*it)[1];		//second element is angle theta

			//if((theta>0.09&&theta<1.48)||(theta<3.14&&theta>1.66))
			//filter to remove vertical and horizontal lines
			{
				//point of intersection of the line with first row
				Point pt1(rho/cos(theta),0);
				//point of intersection of the line with last row
				Point pt2((rho-result.rows*sin(theta))/cos(theta),result.rows);
				//Draw a line
				line(result,pt1,pt2,Scalar(0,255,255),3,CV_AA);
			}

			clog<<"Line: ("<<rho<<","<<theta<<")\n";
		}

		stringstream overlayedText;
		overlayedText<<"Lines Segments: "<<lines.size();

		putText(result,overlayedText.str(),Point(10,image.rows-10),2,0.8,Scalar(0,0,255),0);
		imshow(window_name,result);

		lines.clear();
		char key=(char)waitKey(1);
	}
}
<|endoftext|>