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

#ifndef _SVGCOM_HXX
#define _SVGCOM_HXX

#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif
#ifndef __RTL_USTRING_
#include <rtl/ustring>
#endif
#ifndef _DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _STACK_HXX
#include <tools/stack.hxx>
#endif
#ifndef _SALBTYPE_HXX
#include <vcl/salbtype.hxx>
#endif
#ifndef _GDIMTF_HXX
#include <vcl/gdimtf.hxx>
#endif
#ifndef _METAACT_HXX
#include <vcl/metaact.hxx>
#endif

#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
#include <com/sun/star/svg/XSVGWriter.hpp>
#include <com/sun/star/svg/XSVGPrinter.hpp>

#ifndef _XMLOFF_XMLEXP_HXX
#include <xmloff/xmlexp.hxx>
#endif
#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

// -----------------------------------------------------------------------------

#define NMSP_CPPU       cppu
#define NMSP_RTL        rtl
#define NMSP_UNO        com::sun::star::uno
#define NMSP_LANG       com::sun::star::lang
#define NMSP_SAX        com::sun::star::xml::sax
#define NMSP_SVG        com::sun::star::svg
#define NMSP_REGISTRY   com::sun::star::registry

#define REF( _def_Obj )                     NMSP_UNO::Reference< _def_Obj >
#define SEQ( _def_Obj )                     NMSP_UNO::Sequence< _def_Obj >
#define ANY                                 NMSP_UNO::Any
#define B2UCONST( _def_pChar )              (NMSP_RTL::OUString(RTL_CONSTASCII_USTRINGPARAM(_def_pChar )))
#define SVG_DTD_STRING                      B2UCONST( "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20001102//EN\" \"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd\">" )

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

#ifndef _SVGCOM_HXX
#define _SVGCOM_HXX

#ifndef _CPPUHELPER_WEAK_HXX_
#include <cppuhelper/weak.hxx>
#endif
#ifndef __RTL_USTRING_
#include <rtl/ustring>
#endif
#ifndef _DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef _STACK_HXX
#include <tools/stack.hxx>
#endif
#ifndef _SALBTYPE_HXX
#include <vcl/salbtype.hxx>
#endif
#ifndef _GDIMTF_HXX
#include <vcl/gdimtf.hxx>
#endif
#ifndef _METAACT_HXX
#include <vcl/metaact.hxx>
#endif

#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/xml/sax/XDocumentHandler.hpp>
#include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
#include <com/sun/star/svg/XSVGWriter.hpp>
#include <com/sun/star/svg/XSVGPrinter.hpp>

#ifndef _XMLOFF_XMLEXP_HXX
#include <xmloff/xmlexp.hxx>
#endif
#ifndef _XMLOFF_NMSPMAP_HXX
#include <xmloff/nmspmap.hxx>
#endif

// -----------------------------------------------------------------------------

#define NMSP_CPPU       cppu
#define NMSP_RTL        rtl
#define NMSP_UNO        com::sun::star::uno
#define NMSP_LANG       com::sun::star::lang
#define NMSP_SAX        com::sun::star::xml::sax
#define NMSP_SVG        com::sun::star::svg
#define NMSP_REGISTRY   com::sun::star::registry

#define REF( _def_Obj )                     NMSP_UNO::Reference< _def_Obj >
#define SEQ( _def_Obj )                     NMSP_UNO::Sequence< _def_Obj >
#define ANY                                 NMSP_UNO::Any
#define B2UCONST( _def_pChar )              (NMSP_RTL::OUString(RTL_CONSTASCII_USTRINGPARAM(_def_pChar )))
#define SVG_DTD_STRING                      B2UCONST( "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">" )

#endif // _SYNCCOM_HXX
<|endoftext|>


<commit_before>#include "SlitherlinkDatabase.h"
#include "SlitherlinkDatabaseMethod.hpp"
#include "../common/SolverConstant.h"

namespace Penciloid
{
int *SlitherlinkDatabase::database = nullptr;
const int SlitherlinkDatabase::DATABASE_DX[] = { -2, -2, -1, -1, -1, 0, 0, 1, 1, 1, 2, 2 };
const int SlitherlinkDatabase::DATABASE_DY[] = { -1, 1, -2, 0, 2, -1, 1, -2, 0, 2, -1, 1 };

void SlitherlinkDatabase::CreateDatabase()
{
	const int pow3[] = { 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441 };

	ReleaseDatabase();
	database = new int[pow3[12] * 4];

	int styles[12];

	for (int hint = 0; hint <= 3; ++hint) {
		for (int id = pow3[12] - 1; id >= 0; --id) {
			int tmp = id;
			int undecided_pos = -1;

			for (int i = 0; i < 12; ++i) {
				styles[i] = tmp % 3;
				tmp /= 3;

				if (styles[i] == 0) undecided_pos = i;
			}

			if (undecided_pos == -1) {
				bool consistency = true;

				if (8 - (styles[3] + styles[5] + styles[6] + styles[8]) != hint) {
					consistency = false;
				}

				tmp = 8 - (styles[0] + styles[2] + styles[3] + styles[5]);
				if (tmp != 0 && tmp != 2) consistency = false;
				tmp = 8 - (styles[1] + styles[3] + styles[4] + styles[6]);
				if (tmp != 0 && tmp != 2) consistency = false;
				tmp = 8 - (styles[5] + styles[7] + styles[8] + styles[10]);
				if (tmp != 0 && tmp != 2) consistency = false;
				tmp = 8 - (styles[6] + styles[8] + styles[9] + styles[11]);
				if (tmp != 0 && tmp != 2) consistency = false;

				if (consistency) {
					int tmp = 0;
					for (int i = 0; i < 12; ++i) tmp |= styles[i] << (2 * i);
					database[hint * pow3[12] + id] = tmp;
				} else {
					database[hint * pow3[12] + id] = -1;
				}
			} else {
				int base1 = database[hint * pow3[12] + id + pow3[undecided_pos]];
				int base2 = database[hint * pow3[12] + id + pow3[undecided_pos] * 2];

				database[hint * pow3[12] + id] = base1 & base2;
			}
		}
	}
}

void SlitherlinkDatabase::CreateReducedDatabase(SlitherlinkDatabaseMethod &method)
{
	const int pow3[] = { 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441 };

	ReleaseDatabase();
	database = new int[pow3[12] * 4];

	int styles[12];

	for (int hint = 0; hint <= 3; ++hint) {
		for (int id = pow3[12] - 1; id >= 0; --id) {
			int tmp = id;

			for (int i = 0; i < 12; ++i) {
				styles[i] = tmp % 3;
				tmp /= 3;
			}

			database[hint * pow3[12] + id] = SolveLocal(hint, styles, method);
		}
	}
}

void SlitherlinkDatabase::ReleaseDatabase()
{
	if (database) {
		delete[] database;
		database = nullptr;
	}
}

int SlitherlinkDatabase::SolveLocal(int clue, int styles[12], SlitherlinkDatabaseMethod &method)
{
	const int UNDECIDED = 0, LINE = 1, BLANK = 2;
	int segments[5][5];

	for (int i = 0; i < 12; ++i) segments[2 + DATABASE_DY[i]][2 + DATABASE_DX[i]] = styles[i];

	if (method.adjacent_lines) {
		int n_lines =
			(segments[2][1] == LINE ? 1 : 0) +
			(segments[2][3] == LINE ? 1 : 0) +
			(segments[1][2] == LINE ? 1 : 0) +
			(segments[3][2] == LINE ? 1 : 0);
		int n_blanks =
			(segments[2][1] == BLANK ? 1 : 0) +
			(segments[2][3] == BLANK ? 1 : 0) +
			(segments[1][2] == BLANK ? 1 : 0) +
			(segments[3][2] == BLANK ? 1 : 0);

		if (n_lines > clue || 4 - n_blanks < clue) return -1;

		if (n_lines == clue) {
			if (segments[2][1] == UNDECIDED) segments[2][1] = BLANK;
			if (segments[2][3] == UNDECIDED) segments[2][3] = BLANK;
			if (segments[1][2] == UNDECIDED) segments[1][2] = BLANK;
			if (segments[3][2] == UNDECIDED) segments[3][2] = BLANK;
		}
		if (4 - n_blanks == clue) {
			if (segments[2][1] == UNDECIDED) segments[2][1] = LINE;
			if (segments[2][3] == UNDECIDED) segments[2][3] = LINE;
			if (segments[1][2] == UNDECIDED) segments[1][2] = LINE;
			if (segments[3][2] == UNDECIDED) segments[3][2] = LINE;
		}
	}

	for (int dir = 0; dir < 4; ++dir) {
		int dy1 = GridConstant::GRID_DY[dir], dx1 = GridConstant::GRID_DX[dir];
		int dy2 = GridConstant::GRID_DY[(dir + 1) % 4], dx2 = GridConstant::GRID_DX[(dir + 1) % 4];

		if (segments[2 + dy1 * 2 + dy2][2 + dx1 * 2 + dx2] == BLANK && segments[2 + dy1 + dy2 * 2][2 + dx1 + dx2 * 2] == BLANK) {
			// this cell is corner

			if (clue == 1 && method.corner_1) {
				segments[2 + dy1][2 + dx1] = segments[2 + dy2][2 + dx2] = BLANK;
			}
			if (clue == 2 && method.corner_2) {
				int out_y1, out_x1, out_y2, out_x2;

				out_y1 = 2 + dy1 * 2 - dy2, out_x1 = 2 + dx1 * 2 - dx2;
				out_y2 = 2 + dy1 - dy2 * 2, out_x2 = 2 + dx1 - dx2 * 2;

				if (segments[out_y1][out_x1] == LINE) segments[out_y2][out_x2] |= BLANK;
				if (segments[out_y1][out_x1] == BLANK) segments[out_y2][out_x2] |= LINE;
				if (segments[out_y2][out_x2] == LINE) segments[out_y1][out_x1] |= BLANK;
				if (segments[out_y2][out_x2] == BLANK) segments[out_y1][out_x1] |= LINE;

				out_y1 = 2 - dy1 * 2 + dy2, out_x1 = 2 - dx1 * 2 + dx2;
				out_y2 = 2 - dy1 + dy2 * 2, out_x2 = 2 - dx1 + dx2 * 2;

				if (segments[out_y1][out_x1] == LINE) segments[out_y2][out_x2] |= BLANK;
				if (segments[out_y1][out_x1] == BLANK) segments[out_y2][out_x2] |= LINE;
				if (segments[out_y2][out_x2] == LINE) segments[out_y1][out_x1] |= BLANK;
				if (segments[out_y2][out_x2] == BLANK) segments[out_y1][out_x1] |= LINE;
			}
			if (clue == 3 && method.corner_3) {
				segments[2 + dy1][2 + dx1] = segments[2 + dy2][2 + dx2] = LINE;
			}
		}

		int in_y1, in_x1, in_y2, in_x2;
		in_y1 = 2 + dy1 * 2 + dy2, in_x1 = 2 + dx1 * 2 + dx2;
		in_y2 = 2 + dy1 + dy2 * 2, in_x2 = 2 + dx1 + dx2 * 2;

		if (clue == 3 && method.line_to_3) {
			if (segments[in_y1][in_x1] == LINE || segments[in_y2][in_x2] == LINE) {
				segments[2 - dy1][2 - dx1] |= LINE;
				segments[2 - dy2][2 - dx2] |= LINE;

				if (segments[in_y1][in_x1] == LINE) segments[in_y2][in_x2] |= BLANK;
				if (segments[in_y2][in_x2] == LINE) segments[in_y1][in_x1] |= BLANK;
			}
		}

		if (clue == 1 && method.line_to_1) {
			if ((segments[in_y1][in_x1] == LINE && segments[in_y2][in_x2] == BLANK) ||
				(segments[in_y1][in_x1] == BLANK && segments[in_y2][in_x2] == LINE)) {
				segments[2 - dy1][2 - dx1] |= BLANK;
				segments[2 - dy2][2 - dx2] |= BLANK;
			}
		}

		if (clue == 2 && method.line_to_2) {
			if ((segments[in_y1][in_x1] == LINE && segments[in_y2][in_x2] == BLANK) ||
				(segments[in_y1][in_x1] == BLANK && segments[in_y2][in_x2] == LINE)) {
				int out_y1, out_x1, out_y2, out_x2;

				out_y1 = 2 - dy1, out_x1 = 2 - dx1;
				out_y2 = 2 - dy2, out_x2 = 2 - dx2;

				if (segments[out_y1][out_x1] == BLANK) segments[out_y2][out_x2] |= LINE;
				if (segments[out_y1][out_x1] == LINE) segments[out_y2][out_x2] |= BLANK;
				if (segments[out_y2][out_x2] == BLANK) segments[out_y1][out_x1] |= LINE;
				if (segments[out_y2][out_x2] == LINE) segments[out_y1][out_x1] |= BLANK;

				out_y1 = 2 - dy1 * 2 - dy2, out_x1 = 2 - dx1 * 2 - dx2;
				out_y2 = 2 - dy1 - dy2 * 2, out_x2 = 2 - dx1 - dx2 * 2;

				if (segments[out_y1][out_x1] == BLANK) segments[out_y2][out_x2] |= LINE;
				if (segments[out_y1][out_x1] == LINE) segments[out_y2][out_x2] |= BLANK;
				if (segments[out_y2][out_x2] == BLANK) segments[out_y1][out_x1] |= LINE;
				if (segments[out_y2][out_x2] == LINE) segments[out_y1][out_x1] |= BLANK;
			}
		}

		if ((clue == 1 && method.line_from_1 && segments[2 - dy1][2 - dx1] == BLANK && segments[2 - dy2][2 - dx2] == BLANK) ||
			(clue == 3 && method.line_from_3 && segments[2 - dy1][2 - dx1] == LINE && segments[2 - dy2][2 - dx2] == LINE)) {
			if (segments[in_y1][in_x1] == LINE) segments[in_y2][in_x2] |= BLANK;
			if (segments[in_y1][in_x1] == BLANK) segments[in_y2][in_x2] |= LINE;
			if (segments[in_y2][in_x2] == LINE) segments[in_y1][in_x1] |= BLANK;
			if (segments[in_y2][in_x2] == BLANK) segments[in_y1][in_x1] |= LINE;
		}
	}

	int ret = 0;
	for (int i = 0; i < 12; ++i) {
		int y = 2 + DATABASE_DY[i], x = 2 + DATABASE_DX[i];
		if (segments[y][x] == 3) return -1;
		ret |= segments[y][x] << (2 * i);
	}

	return ret;
}
}
<commit_msg>Apply the methods as long as new facts are revealed in SolveLocal<commit_after>#include "SlitherlinkDatabase.h"
#include "SlitherlinkDatabaseMethod.hpp"
#include "../common/SolverConstant.h"

namespace Penciloid
{
int *SlitherlinkDatabase::database = nullptr;
const int SlitherlinkDatabase::DATABASE_DX[] = { -2, -2, -1, -1, -1, 0, 0, 1, 1, 1, 2, 2 };
const int SlitherlinkDatabase::DATABASE_DY[] = { -1, 1, -2, 0, 2, -1, 1, -2, 0, 2, -1, 1 };

void SlitherlinkDatabase::CreateDatabase()
{
	const int pow3[] = { 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441 };

	ReleaseDatabase();
	database = new int[pow3[12] * 4];

	int styles[12];

	for (int hint = 0; hint <= 3; ++hint) {
		for (int id = pow3[12] - 1; id >= 0; --id) {
			int tmp = id;
			int undecided_pos = -1;

			for (int i = 0; i < 12; ++i) {
				styles[i] = tmp % 3;
				tmp /= 3;

				if (styles[i] == 0) undecided_pos = i;
			}

			if (undecided_pos == -1) {
				bool consistency = true;

				if (8 - (styles[3] + styles[5] + styles[6] + styles[8]) != hint) {
					consistency = false;
				}

				tmp = 8 - (styles[0] + styles[2] + styles[3] + styles[5]);
				if (tmp != 0 && tmp != 2) consistency = false;
				tmp = 8 - (styles[1] + styles[3] + styles[4] + styles[6]);
				if (tmp != 0 && tmp != 2) consistency = false;
				tmp = 8 - (styles[5] + styles[7] + styles[8] + styles[10]);
				if (tmp != 0 && tmp != 2) consistency = false;
				tmp = 8 - (styles[6] + styles[8] + styles[9] + styles[11]);
				if (tmp != 0 && tmp != 2) consistency = false;

				if (consistency) {
					int tmp = 0;
					for (int i = 0; i < 12; ++i) tmp |= styles[i] << (2 * i);
					database[hint * pow3[12] + id] = tmp;
				} else {
					database[hint * pow3[12] + id] = -1;
				}
			} else {
				int base1 = database[hint * pow3[12] + id + pow3[undecided_pos]];
				int base2 = database[hint * pow3[12] + id + pow3[undecided_pos] * 2];

				database[hint * pow3[12] + id] = base1 & base2;
			}
		}
	}
}

void SlitherlinkDatabase::CreateReducedDatabase(SlitherlinkDatabaseMethod &method)
{
	const int pow3[] = { 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441 };

	ReleaseDatabase();
	database = new int[pow3[12] * 4];

	int styles[12];

	for (int hint = 0; hint <= 3; ++hint) {
		for (int id = pow3[12] - 1; id >= 0; --id) {
			int tmp = id;

			for (int i = 0; i < 12; ++i) {
				styles[i] = tmp % 3;
				tmp /= 3;
			}

			database[hint * pow3[12] + id] = SolveLocal(hint, styles, method);
		}
	}
}

void SlitherlinkDatabase::ReleaseDatabase()
{
	if (database) {
		delete[] database;
		database = nullptr;
	}
}

int SlitherlinkDatabase::SolveLocal(int clue, int styles[12], SlitherlinkDatabaseMethod &method)
{
	const int UNDECIDED = 0, LINE = 1, BLANK = 2;
	int segments[5][5];
	int ret = 0, ret_previous = 0;

	for (int i = 0; i < 12; ++i) segments[2 + DATABASE_DY[i]][2 + DATABASE_DX[i]] = styles[i];

	int nt = 0;
	do {
		ret_previous = ret;
		if (method.adjacent_lines) {
			int n_lines =
				(segments[2][1] == LINE ? 1 : 0) +
				(segments[2][3] == LINE ? 1 : 0) +
				(segments[1][2] == LINE ? 1 : 0) +
				(segments[3][2] == LINE ? 1 : 0);
			int n_blanks =
				(segments[2][1] == BLANK ? 1 : 0) +
				(segments[2][3] == BLANK ? 1 : 0) +
				(segments[1][2] == BLANK ? 1 : 0) +
				(segments[3][2] == BLANK ? 1 : 0);

			if (n_lines > clue || 4 - n_blanks < clue) return -1;

			if (n_lines == clue) {
				if (segments[2][1] == UNDECIDED) segments[2][1] = BLANK;
				if (segments[2][3] == UNDECIDED) segments[2][3] = BLANK;
				if (segments[1][2] == UNDECIDED) segments[1][2] = BLANK;
				if (segments[3][2] == UNDECIDED) segments[3][2] = BLANK;
			}
			if (4 - n_blanks == clue) {
				if (segments[2][1] == UNDECIDED) segments[2][1] = LINE;
				if (segments[2][3] == UNDECIDED) segments[2][3] = LINE;
				if (segments[1][2] == UNDECIDED) segments[1][2] = LINE;
				if (segments[3][2] == UNDECIDED) segments[3][2] = LINE;
			}
		}

		for (int dir = 0; dir < 4; ++dir) {
			int dy1 = GridConstant::GRID_DY[dir], dx1 = GridConstant::GRID_DX[dir];
			int dy2 = GridConstant::GRID_DY[(dir + 1) % 4], dx2 = GridConstant::GRID_DX[(dir + 1) % 4];

			if (segments[2 + dy1 * 2 + dy2][2 + dx1 * 2 + dx2] == BLANK && segments[2 + dy1 + dy2 * 2][2 + dx1 + dx2 * 2] == BLANK) {
				// this cell is corner

				if (clue == 1 && method.corner_1) {
					segments[2 + dy1][2 + dx1] = segments[2 + dy2][2 + dx2] = BLANK;
				}
				if (clue == 2 && method.corner_2) {
					int out_y1, out_x1, out_y2, out_x2;

					out_y1 = 2 + dy1 * 2 - dy2, out_x1 = 2 + dx1 * 2 - dx2;
					out_y2 = 2 + dy1 - dy2 * 2, out_x2 = 2 + dx1 - dx2 * 2;

					if (segments[out_y1][out_x1] == LINE) segments[out_y2][out_x2] |= BLANK;
					if (segments[out_y1][out_x1] == BLANK) segments[out_y2][out_x2] |= LINE;
					if (segments[out_y2][out_x2] == LINE) segments[out_y1][out_x1] |= BLANK;
					if (segments[out_y2][out_x2] == BLANK) segments[out_y1][out_x1] |= LINE;

					out_y1 = 2 - dy1 * 2 + dy2, out_x1 = 2 - dx1 * 2 + dx2;
					out_y2 = 2 - dy1 + dy2 * 2, out_x2 = 2 - dx1 + dx2 * 2;

					if (segments[out_y1][out_x1] == LINE) segments[out_y2][out_x2] |= BLANK;
					if (segments[out_y1][out_x1] == BLANK) segments[out_y2][out_x2] |= LINE;
					if (segments[out_y2][out_x2] == LINE) segments[out_y1][out_x1] |= BLANK;
					if (segments[out_y2][out_x2] == BLANK) segments[out_y1][out_x1] |= LINE;
				}
				if (clue == 3 && method.corner_3) {
					segments[2 + dy1][2 + dx1] = segments[2 + dy2][2 + dx2] = LINE;
				}
			}

			int in_y1, in_x1, in_y2, in_x2;
			in_y1 = 2 + dy1 * 2 + dy2, in_x1 = 2 + dx1 * 2 + dx2;
			in_y2 = 2 + dy1 + dy2 * 2, in_x2 = 2 + dx1 + dx2 * 2;

			if (clue == 3 && method.line_to_3) {
				if (segments[in_y1][in_x1] == LINE || segments[in_y2][in_x2] == LINE) {
					segments[2 - dy1][2 - dx1] |= LINE;
					segments[2 - dy2][2 - dx2] |= LINE;

					if (segments[in_y1][in_x1] == LINE) segments[in_y2][in_x2] |= BLANK;
					if (segments[in_y2][in_x2] == LINE) segments[in_y1][in_x1] |= BLANK;
				}
			}

			if (clue == 1 && method.line_to_1) {
				if ((segments[in_y1][in_x1] == LINE && segments[in_y2][in_x2] == BLANK) ||
					(segments[in_y1][in_x1] == BLANK && segments[in_y2][in_x2] == LINE)) {
					segments[2 - dy1][2 - dx1] |= BLANK;
					segments[2 - dy2][2 - dx2] |= BLANK;
				}
			}

			if (clue == 2 && method.line_to_2) {
				if ((segments[in_y1][in_x1] == LINE && segments[in_y2][in_x2] == BLANK) ||
					(segments[in_y1][in_x1] == BLANK && segments[in_y2][in_x2] == LINE)) {
					int out_y1, out_x1, out_y2, out_x2;

					out_y1 = 2 - dy1, out_x1 = 2 - dx1;
					out_y2 = 2 - dy2, out_x2 = 2 - dx2;

					if (segments[out_y1][out_x1] == BLANK) segments[out_y2][out_x2] |= LINE;
					if (segments[out_y1][out_x1] == LINE) segments[out_y2][out_x2] |= BLANK;
					if (segments[out_y2][out_x2] == BLANK) segments[out_y1][out_x1] |= LINE;
					if (segments[out_y2][out_x2] == LINE) segments[out_y1][out_x1] |= BLANK;

					out_y1 = 2 - dy1 * 2 - dy2, out_x1 = 2 - dx1 * 2 - dx2;
					out_y2 = 2 - dy1 - dy2 * 2, out_x2 = 2 - dx1 - dx2 * 2;

					if (segments[out_y1][out_x1] == BLANK) segments[out_y2][out_x2] |= LINE;
					if (segments[out_y1][out_x1] == LINE) segments[out_y2][out_x2] |= BLANK;
					if (segments[out_y2][out_x2] == BLANK) segments[out_y1][out_x1] |= LINE;
					if (segments[out_y2][out_x2] == LINE) segments[out_y1][out_x1] |= BLANK;
				}
			}

			if ((clue == 1 && method.line_from_1 && segments[2 - dy1][2 - dx1] == BLANK && segments[2 - dy2][2 - dx2] == BLANK) ||
				(clue == 3 && method.line_from_3 && segments[2 - dy1][2 - dx1] == LINE && segments[2 - dy2][2 - dx2] == LINE)) {
				if (segments[in_y1][in_x1] == LINE) segments[in_y2][in_x2] |= BLANK;
				if (segments[in_y1][in_x1] == BLANK) segments[in_y2][in_x2] |= LINE;
				if (segments[in_y2][in_x2] == LINE) segments[in_y1][in_x1] |= BLANK;
				if (segments[in_y2][in_x2] == BLANK) segments[in_y1][in_x1] |= LINE;
			}
		}

		ret = 0;
		for (int i = 0; i < 12; ++i) {
			int y = 2 + DATABASE_DY[i], x = 2 + DATABASE_DX[i];
			if (segments[y][x] == 3) return -1;
			ret |= segments[y][x] << (2 * i);
		}
	} while (ret != ret_previous);

	return ret;
}
}
<|endoftext|>


<commit_before>//
// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”)
// All rights reserved.
//
//    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.
//

#include "source/adapter/adapter_pipeline.hpp"

#include "agent.hpp"
#include "configuration/agent_config.hpp"
#include "configuration/config_options.hpp"
#include "pipeline/convert_sample.hpp"
#include "pipeline/deliver.hpp"
#include "pipeline/delta_filter.hpp"
#include "pipeline/duplicate_filter.hpp"
#include "pipeline/period_filter.hpp"
#include "pipeline/timestamp_extractor.hpp"
#include "pipeline/topic_mapper.hpp"
#include "pipeline/upcase_value.hpp"
#include "source/adapter/adapter.hpp"

using namespace std;
using namespace std::literals;

namespace mtconnect {
  using namespace observation;
  using namespace entity;
  using namespace pipeline;

  namespace source::adapter {
    std::unique_ptr<Handler> AdapterPipeline::makeHandler()
    {
      auto handler = make_unique<Handler>();

      // Build the pipeline for an adapter
      handler->m_connecting = [this](const std::string &id) {
        auto entity = make_shared<Entity>("ConnectionStatus",
                                          Properties {{"VALUE", "CONNECTING"s}, {"source", id}});
        run(entity);
      };
      handler->m_connected = [this](const std::string &id) {
        auto entity = make_shared<Entity>("ConnectionStatus",
                                          Properties {{"VALUE", "CONNECTED"s}, {"source", id}});
        run(entity);
      };
      handler->m_disconnected = [this](const std::string &id) {
        auto entity = make_shared<Entity>("ConnectionStatus",
                                          Properties {{"VALUE", "DISCONNECTED"s}, {"source", id}});
        run(entity);
      };
      handler->m_processData = [this](const std::string &data, const std::string &source) {
        auto entity = make_shared<Entity>("Data", Properties {{"VALUE", data}, {"source", source}});
        run(entity);
      };
      handler->m_processMessage = [this](const std::string &topic, const std::string &data,
                                         const std::string &source) {
        auto entity = make_shared<PipelineMessage>(
            "Message", Properties {{"VALUE", data}, {"topic", topic}, {"source", source}});
        run(entity);
      };
      handler->m_command = [this](const std::string &data, const std::string &source) {
        auto entity =
            make_shared<Entity>("Command", Properties {{"VALUE", data}, {"source", source}});
        run(entity);
      };

      return handler;
    }

    void AdapterPipeline::build(const ConfigOptions &options)
    {
      clear();
      m_options = options;

      m_identity = GetOption<string>(m_options, configuration::AdapterIdentity).value_or("unknown");
    }

    void AdapterPipeline::buildDeviceList()
    {
      m_identity = *GetOption<string>(m_options, configuration::AdapterIdentity);

      auto list = GetOption<StringList>(m_options, configuration::AdditionalDevices);
      if (list)
        m_devices = *list;
      m_device = GetOption<string>(m_options, configuration::Device);
      if (m_device)
      {
        m_devices.emplace_front(*m_device);
        auto dp = m_context->m_contract->findDevice(*m_device);
        if (dp)
        {
          dp->setOptions(m_options);
        }
      }
    }

    void AdapterPipeline::buildCommandAndStatusDelivery()
    {
      bind(make_shared<DeliverConnectionStatus>(
          m_context, m_devices, IsOptionSet(m_options, configuration::AutoAvailable)));
      bind(make_shared<DeliverCommand>(m_context, m_device));
    }

    void AdapterPipeline::buildAssetDelivery(pipeline::TransformPtr next)
    {
      // Go directly to asset delivery
      std::optional<string> assetMetrics;
      assetMetrics = m_identity + "_asset_update_rate";

      next->bind(make_shared<DeliverAsset>(m_context, assetMetrics));
      next->bind(make_shared<DeliverAssetCommand>(m_context));
    }

    void AdapterPipeline::buildObservationDelivery(pipeline::TransformPtr next)
    {
      // Uppercase Events
      if (IsOptionSet(m_options, configuration::UpcaseDataItemValue))
        next = next->bind(make_shared<UpcaseValue>());

      // Filter dups, by delta, and by period
      next = next->bind(make_shared<DuplicateFilter>(m_context));
      next = next->bind(make_shared<DeltaFilter>(m_context));
      next = next->bind(make_shared<PeriodFilter>(m_context, m_strand));

      // Convert values
      if (IsOptionSet(m_options, configuration::ConversionRequired))
        next = next->bind(make_shared<ConvertSample>());

      // Deliver
      std::optional<string> obsMetrics;
      obsMetrics = m_identity + "_observation_update_rate";
      next->bind(make_shared<DeliverObservation>(m_context, obsMetrics));
    }
  }  // namespace source::adapter
}  // namespace mtconnect
<commit_msg>Removed setting m_identity in the buildDeviceList method. Should already be set in build.<commit_after>//
// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”)
// All rights reserved.
//
//    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.
//

#include "source/adapter/adapter_pipeline.hpp"

#include "agent.hpp"
#include "configuration/agent_config.hpp"
#include "configuration/config_options.hpp"
#include "pipeline/convert_sample.hpp"
#include "pipeline/deliver.hpp"
#include "pipeline/delta_filter.hpp"
#include "pipeline/duplicate_filter.hpp"
#include "pipeline/period_filter.hpp"
#include "pipeline/timestamp_extractor.hpp"
#include "pipeline/topic_mapper.hpp"
#include "pipeline/upcase_value.hpp"
#include "source/adapter/adapter.hpp"

using namespace std;
using namespace std::literals;

namespace mtconnect {
  using namespace observation;
  using namespace entity;
  using namespace pipeline;

  namespace source::adapter {
    std::unique_ptr<Handler> AdapterPipeline::makeHandler()
    {
      auto handler = make_unique<Handler>();

      // Build the pipeline for an adapter
      handler->m_connecting = [this](const std::string &id) {
        auto entity = make_shared<Entity>("ConnectionStatus",
                                          Properties {{"VALUE", "CONNECTING"s}, {"source", id}});
        run(entity);
      };
      handler->m_connected = [this](const std::string &id) {
        auto entity = make_shared<Entity>("ConnectionStatus",
                                          Properties {{"VALUE", "CONNECTED"s}, {"source", id}});
        run(entity);
      };
      handler->m_disconnected = [this](const std::string &id) {
        auto entity = make_shared<Entity>("ConnectionStatus",
                                          Properties {{"VALUE", "DISCONNECTED"s}, {"source", id}});
        run(entity);
      };
      handler->m_processData = [this](const std::string &data, const std::string &source) {
        auto entity = make_shared<Entity>("Data", Properties {{"VALUE", data}, {"source", source}});
        run(entity);
      };
      handler->m_processMessage = [this](const std::string &topic, const std::string &data,
                                         const std::string &source) {
        auto entity = make_shared<PipelineMessage>(
            "Message", Properties {{"VALUE", data}, {"topic", topic}, {"source", source}});
        run(entity);
      };
      handler->m_command = [this](const std::string &data, const std::string &source) {
        auto entity =
            make_shared<Entity>("Command", Properties {{"VALUE", data}, {"source", source}});
        run(entity);
      };

      return handler;
    }

    void AdapterPipeline::build(const ConfigOptions &options)
    {
      clear();
      m_options = options;

      m_identity = GetOption<string>(m_options, configuration::AdapterIdentity).value_or("unknown");
    }

    void AdapterPipeline::buildDeviceList()
    {
      auto list = GetOption<StringList>(m_options, configuration::AdditionalDevices);
      if (list)
        m_devices = *list;
      m_device = GetOption<string>(m_options, configuration::Device);
      if (m_device)
      {
        m_devices.emplace_front(*m_device);
        auto dp = m_context->m_contract->findDevice(*m_device);
        if (dp)
        {
          dp->setOptions(m_options);
        }
      }
    }

    void AdapterPipeline::buildCommandAndStatusDelivery()
    {
      bind(make_shared<DeliverConnectionStatus>(
          m_context, m_devices, IsOptionSet(m_options, configuration::AutoAvailable)));
      bind(make_shared<DeliverCommand>(m_context, m_device));
    }

    void AdapterPipeline::buildAssetDelivery(pipeline::TransformPtr next)
    {
      // Go directly to asset delivery
      std::optional<string> assetMetrics;
      assetMetrics = m_identity + "_asset_update_rate";

      next->bind(make_shared<DeliverAsset>(m_context, assetMetrics));
      next->bind(make_shared<DeliverAssetCommand>(m_context));
    }

    void AdapterPipeline::buildObservationDelivery(pipeline::TransformPtr next)
    {
      // Uppercase Events
      if (IsOptionSet(m_options, configuration::UpcaseDataItemValue))
        next = next->bind(make_shared<UpcaseValue>());

      // Filter dups, by delta, and by period
      next = next->bind(make_shared<DuplicateFilter>(m_context));
      next = next->bind(make_shared<DeltaFilter>(m_context));
      next = next->bind(make_shared<PeriodFilter>(m_context, m_strand));

      // Convert values
      if (IsOptionSet(m_options, configuration::ConversionRequired))
        next = next->bind(make_shared<ConvertSample>());

      // Deliver
      std::optional<string> obsMetrics;
      obsMetrics = m_identity + "_observation_update_rate";
      next->bind(make_shared<DeliverObservation>(m_context, obsMetrics));
    }
  }  // namespace source::adapter
}  // namespace mtconnect
<|endoftext|>


<commit_before>//
// PROJECT:         Aspia Remote Desktop
// FILE:            host/console_session_launcher.cc
// LICENSE:         See top-level directory
// PROGRAMMERS:     Dmitry Chapyshev (dmitry@aspia.ru)
//

#include "host/console_session_launcher.h"

#include <userenv.h>
#include <wtsapi32.h>
#include <string>

#include "base/version_helpers.h"
#include "base/process_helpers.h"
#include "base/service_manager.h"
#include "base/scoped_object.h"
#include "base/scoped_wts_memory.h"
#include "base/scoped_impersonator.h"
#include "base/object_watcher.h"
#include "base/unicode.h"
#include "base/path.h"
#include "base/process.h"
#include "base/logging.h"

namespace aspia {

static const WCHAR kServiceShortName[] = L"aspia-desktop-session-launcher";
static const WCHAR kServiceFullName[] = L"Aspia Desktop Session Launcher";

// Name of the default session desktop.
static WCHAR kDefaultDesktopName[] = L"winsta0\\default";

ConsoleSessionLauncher::ConsoleSessionLauncher(const std::wstring& service_id) :
    Service(ServiceManager::CreateUniqueServiceName(kServiceShortName, service_id))
{
    // Nothing
}

static bool CopyProcessToken(DWORD desired_access, ScopedHandle& token_out)
{
    ScopedHandle process_token;

    if (!OpenProcessToken(GetCurrentProcess(),
                          TOKEN_DUPLICATE | desired_access,
                          process_token.Recieve()))
    {
        LOG(ERROR) << "OpenProcessToken() failed: " << GetLastSystemErrorString();
        return false;
    }

    if (!DuplicateTokenEx(process_token,
                          desired_access,
                          nullptr,
                          SecurityImpersonation,
                          TokenPrimary,
                          token_out.Recieve()))
    {
        LOG(ERROR) << "DuplicateTokenEx() failed: " << GetLastSystemErrorString();
        return false;
    }

    return true;
}

// Creates a copy of the current process with SE_TCB_NAME privilege enabled.
static bool CreatePrivilegedToken(ScopedHandle& token_out)
{
    ScopedHandle privileged_token;
    DWORD desired_access = TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE |
        TOKEN_DUPLICATE | TOKEN_QUERY;

    if (!CopyProcessToken(desired_access, privileged_token))
        return false;

    // Get the LUID for the SE_TCB_NAME privilege.
    TOKEN_PRIVILEGES state;
    state.PrivilegeCount = 1;
    state.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!LookupPrivilegeValueW(nullptr, SE_TCB_NAME, &state.Privileges[0].Luid))
    {
        LOG(ERROR) << "LookupPrivilegeValueW() failed: " << GetLastSystemErrorString();
        return false;
    }

    // Enable the SE_TCB_NAME privilege.
    if (!AdjustTokenPrivileges(privileged_token, FALSE, &state, 0, nullptr, 0))
    {
        LOG(ERROR) << "AdjustTokenPrivileges() failed: " << GetLastSystemErrorString();
        return false;
    }

    token_out.Reset(privileged_token.Release());
    return true;
}

// Creates a copy of the current process token for the given |session_id| so
// it can be used to launch a process in that session.
static bool CreateSessionToken(uint32_t session_id, ScopedHandle& token_out)
{
    ScopedHandle session_token;
    DWORD desired_access = TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID |
        TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY;

    if (!CopyProcessToken(desired_access, session_token))
        return false;

    ScopedHandle privileged_token;

    if (!CreatePrivilegedToken(privileged_token))
        return false;

    {
        ScopedImpersonator impersonator;

        if (!impersonator.ImpersonateLoggedOnUser(privileged_token))
            return false;

        // Change the session ID of the token.
        DWORD new_session_id = session_id;
        if (!SetTokenInformation(session_token,
                                 TokenSessionId,
                                 &new_session_id,
                                 sizeof(new_session_id)))
        {
            LOG(ERROR) << "SetTokenInformation() failed: " << GetLastSystemErrorString();
            return false;
        }
    }

    token_out.Reset(session_token.Release());
    return true;
}

static bool CreateProcessWithToken(HANDLE user_token, const std::wstring& command_line)
{
    PROCESS_INFORMATION process_info = { 0 };
    STARTUPINFOW startup_info = { 0 };

    startup_info.cb = sizeof(startup_info);
    startup_info.lpDesktop = kDefaultDesktopName;

    if (!CreateProcessAsUserW(user_token,
                              nullptr,
                              const_cast<LPWSTR>(command_line.c_str()),
                              nullptr,
                              nullptr,
                              FALSE,
                              0,
                              nullptr,
                              nullptr,
                              &startup_info,
                              &process_info))
    {
        LOG(ERROR) << "CreateProcessAsUserW() failed: " << GetLastSystemErrorString();
        return false;
    }

    CloseHandle(process_info.hThread);
    CloseHandle(process_info.hProcess);

    return true;
}

static bool LaunchProcessInSession(uint32_t session_id,
                                   const std::wstring& input_channel_id,
                                   const std::wstring& output_channel_id)
{
    std::wstring command_line;

    if (!GetPathW(PathKey::FILE_EXE, command_line))
        return false;

    command_line.append(L" --run_mode=");

    command_line.append(kDesktopSessionSwitch);

    command_line.append(L" --input_channel_id=");
    command_line.append(input_channel_id);
    command_line.append(L" --output_channel_id=");
    command_line.append(output_channel_id);

    ScopedHandle session_token;

    if (!CreateSessionToken(session_id, session_token))
        return false;

    return CreateProcessWithToken(session_token, command_line);
}

void ConsoleSessionLauncher::Worker()
{
    LaunchProcessInSession(session_id_, input_channel_id_, output_channel_id_);
}

void ConsoleSessionLauncher::OnStop()
{
    // Nothing
}

void ConsoleSessionLauncher::ExecuteService(uint32_t session_id,
                                            const std::wstring& input_channel_id,
                                            const std::wstring& output_channel_id)
{
    session_id_ = session_id;
    input_channel_id_ = input_channel_id;
    output_channel_id_ = output_channel_id;

    Run();

    ServiceManager(ServiceName()).Remove();
}

// static
bool ConsoleSessionLauncher::LaunchSession(uint32_t session_id,
                                           const std::wstring& input_channel_id,
                                           const std::wstring& output_channel_id)
{
    std::wstring command_line;

    if (!GetPathW(PathKey::FILE_EXE, command_line))
        return false;

    command_line.append(L" --input_channel_id=");
    command_line.append(input_channel_id);
    command_line.append(L" --output_channel_id=");
    command_line.append(output_channel_id);

    if (!IsCallerHasAdminRights())
    {
        command_line.append(L" --run_mode=");
        command_line.append(kDesktopSessionSwitch);

        ScopedHandle token;

        if (!CopyProcessToken(TOKEN_ALL_ACCESS, token))
            return false;

        return CreateProcessWithToken(token, command_line);
    }
    else
    {
        typedef BOOL(WINAPI *ProcessIdToSessionIdFn)(DWORD, DWORD*);

        HMODULE kernel32_module = GetModuleHandleW(L"kernel32.dll");
        CHECK(kernel32_module);

        ProcessIdToSessionIdFn process_id_to_session_id =
            reinterpret_cast<ProcessIdToSessionIdFn>(
                GetProcAddress(kernel32_module, "ProcessIdToSessionId"));
        CHECK(process_id_to_session_id);

        DWORD current_process_session_id;

        if (!process_id_to_session_id(GetCurrentProcessId(), &current_process_session_id))
        {
            LOG(WARNING) << "ProcessIdToSessionId() failed: " << GetLastSystemErrorString();
            return false;
        }

        // If the current process is started not in session 0 (not as a service),
        // then we create a service to start the process in the required session.
        if (!IsWindowsVistaOrGreater() || current_process_session_id != 0)
        {
            std::wstring service_id =
                ServiceManager::GenerateUniqueServiceId();

            std::wstring unique_short_name =
                ServiceManager::CreateUniqueServiceName(kServiceShortName, service_id);

            std::wstring unique_full_name =
                ServiceManager::CreateUniqueServiceName(kServiceFullName, service_id);

            command_line.append(L" --run_mode=");
            command_line.append(kDesktopSessionLauncherSwitch);
            command_line.append(L" --session_id=");
            command_line.append(std::to_wstring(session_id));

            command_line.append(L" --service_id=");
            command_line.append(service_id);

            // Install the service in the system.
            ServiceManager manager(ServiceManager::Create(command_line,
                                                          unique_full_name,
                                                          unique_short_name));

            // If the service was not installed.
            if (!manager.IsValid())
                return false;

            return manager.Start();
        }
        else // The code is executed from the service.
        {
            // Start the process directly.
            return LaunchProcessInSession(session_id, input_channel_id, output_channel_id);
        }
    }
}

} // namespace aspia
<commit_msg>- Getting session id moved to separate function<commit_after>//
// PROJECT:         Aspia Remote Desktop
// FILE:            host/console_session_launcher.cc
// LICENSE:         See top-level directory
// PROGRAMMERS:     Dmitry Chapyshev (dmitry@aspia.ru)
//

#include "host/console_session_launcher.h"

#include <userenv.h>
#include <wtsapi32.h>
#include <string>

#include "base/version_helpers.h"
#include "base/process_helpers.h"
#include "base/service_manager.h"
#include "base/scoped_object.h"
#include "base/scoped_wts_memory.h"
#include "base/scoped_impersonator.h"
#include "base/object_watcher.h"
#include "base/unicode.h"
#include "base/path.h"
#include "base/process.h"
#include "base/logging.h"

namespace aspia {

static const WCHAR kServiceShortName[] = L"aspia-desktop-session-launcher";
static const WCHAR kServiceFullName[] = L"Aspia Desktop Session Launcher";

// Name of the default session desktop.
static WCHAR kDefaultDesktopName[] = L"winsta0\\default";

ConsoleSessionLauncher::ConsoleSessionLauncher(const std::wstring& service_id) :
    Service(ServiceManager::CreateUniqueServiceName(kServiceShortName, service_id))
{
    // Nothing
}

static bool CopyProcessToken(DWORD desired_access, ScopedHandle& token_out)
{
    ScopedHandle process_token;

    if (!OpenProcessToken(GetCurrentProcess(),
                          TOKEN_DUPLICATE | desired_access,
                          process_token.Recieve()))
    {
        LOG(ERROR) << "OpenProcessToken() failed: " << GetLastSystemErrorString();
        return false;
    }

    if (!DuplicateTokenEx(process_token,
                          desired_access,
                          nullptr,
                          SecurityImpersonation,
                          TokenPrimary,
                          token_out.Recieve()))
    {
        LOG(ERROR) << "DuplicateTokenEx() failed: " << GetLastSystemErrorString();
        return false;
    }

    return true;
}

// Creates a copy of the current process with SE_TCB_NAME privilege enabled.
static bool CreatePrivilegedToken(ScopedHandle& token_out)
{
    ScopedHandle privileged_token;
    DWORD desired_access = TOKEN_ADJUST_PRIVILEGES | TOKEN_IMPERSONATE |
        TOKEN_DUPLICATE | TOKEN_QUERY;

    if (!CopyProcessToken(desired_access, privileged_token))
        return false;

    // Get the LUID for the SE_TCB_NAME privilege.
    TOKEN_PRIVILEGES state;
    state.PrivilegeCount = 1;
    state.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!LookupPrivilegeValueW(nullptr, SE_TCB_NAME, &state.Privileges[0].Luid))
    {
        LOG(ERROR) << "LookupPrivilegeValueW() failed: " << GetLastSystemErrorString();
        return false;
    }

    // Enable the SE_TCB_NAME privilege.
    if (!AdjustTokenPrivileges(privileged_token, FALSE, &state, 0, nullptr, 0))
    {
        LOG(ERROR) << "AdjustTokenPrivileges() failed: " << GetLastSystemErrorString();
        return false;
    }

    token_out.Reset(privileged_token.Release());
    return true;
}

// Creates a copy of the current process token for the given |session_id| so
// it can be used to launch a process in that session.
static bool CreateSessionToken(uint32_t session_id, ScopedHandle& token_out)
{
    ScopedHandle session_token;
    DWORD desired_access = TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID |
        TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY;

    if (!CopyProcessToken(desired_access, session_token))
        return false;

    ScopedHandle privileged_token;

    if (!CreatePrivilegedToken(privileged_token))
        return false;

    {
        ScopedImpersonator impersonator;

        if (!impersonator.ImpersonateLoggedOnUser(privileged_token))
            return false;

        // Change the session ID of the token.
        DWORD new_session_id = session_id;
        if (!SetTokenInformation(session_token,
                                 TokenSessionId,
                                 &new_session_id,
                                 sizeof(new_session_id)))
        {
            LOG(ERROR) << "SetTokenInformation() failed: " << GetLastSystemErrorString();
            return false;
        }
    }

    token_out.Reset(session_token.Release());
    return true;
}

static bool CreateProcessWithToken(HANDLE user_token, const std::wstring& command_line)
{
    PROCESS_INFORMATION process_info = { 0 };
    STARTUPINFOW startup_info = { 0 };

    startup_info.cb = sizeof(startup_info);
    startup_info.lpDesktop = kDefaultDesktopName;

    if (!CreateProcessAsUserW(user_token,
                              nullptr,
                              const_cast<LPWSTR>(command_line.c_str()),
                              nullptr,
                              nullptr,
                              FALSE,
                              0,
                              nullptr,
                              nullptr,
                              &startup_info,
                              &process_info))
    {
        LOG(ERROR) << "CreateProcessAsUserW() failed: " << GetLastSystemErrorString();
        return false;
    }

    CloseHandle(process_info.hThread);
    CloseHandle(process_info.hProcess);

    return true;
}

static bool LaunchProcessInSession(uint32_t session_id,
                                   const std::wstring& input_channel_id,
                                   const std::wstring& output_channel_id)
{
    std::wstring command_line;

    if (!GetPathW(PathKey::FILE_EXE, command_line))
        return false;

    command_line.append(L" --run_mode=");

    command_line.append(kDesktopSessionSwitch);

    command_line.append(L" --input_channel_id=");
    command_line.append(input_channel_id);
    command_line.append(L" --output_channel_id=");
    command_line.append(output_channel_id);

    ScopedHandle session_token;

    if (!CreateSessionToken(session_id, session_token))
        return false;

    return CreateProcessWithToken(session_token, command_line);
}

void ConsoleSessionLauncher::Worker()
{
    LaunchProcessInSession(session_id_, input_channel_id_, output_channel_id_);
}

void ConsoleSessionLauncher::OnStop()
{
    // Nothing
}

void ConsoleSessionLauncher::ExecuteService(uint32_t session_id,
                                            const std::wstring& input_channel_id,
                                            const std::wstring& output_channel_id)
{
    session_id_ = session_id;
    input_channel_id_ = input_channel_id;
    output_channel_id_ = output_channel_id;

    Run();

    ServiceManager(ServiceName()).Remove();
}

static bool GetSessionIdForCurrentProcess(DWORD& session_id)
{
    typedef BOOL(WINAPI *ProcessIdToSessionIdFn)(DWORD, DWORD*);

    HMODULE kernel32_module = GetModuleHandleW(L"kernel32.dll");
    if (!kernel32_module)
    {
        LOG(ERROR) << "Failed to get kernel32.dll module handle";
        return false;
    }

    ProcessIdToSessionIdFn process_id_to_session_id =
        reinterpret_cast<ProcessIdToSessionIdFn>(
            GetProcAddress(kernel32_module, "ProcessIdToSessionId"));
    if (!process_id_to_session_id)
    {
        LOG(ERROR) << "Failed to load ProcessIdToSessionId function";
        return false;
    }

    if (!process_id_to_session_id(GetCurrentProcessId(), &session_id))
    {
        LOG(ERROR) << "ProcessIdToSessionId() failed: "
                   << GetLastSystemErrorString();
        return false;
    }

    return true;
}

// static
bool ConsoleSessionLauncher::LaunchSession(uint32_t session_id,
                                           const std::wstring& input_channel_id,
                                           const std::wstring& output_channel_id)
{
    std::wstring command_line;

    if (!GetPathW(PathKey::FILE_EXE, command_line))
        return false;

    command_line.append(L" --input_channel_id=");
    command_line.append(input_channel_id);
    command_line.append(L" --output_channel_id=");
    command_line.append(output_channel_id);

    if (!IsCallerHasAdminRights())
    {
        command_line.append(L" --run_mode=");
        command_line.append(kDesktopSessionSwitch);

        ScopedHandle token;

        if (!CopyProcessToken(TOKEN_ALL_ACCESS, token))
            return false;

        return CreateProcessWithToken(token, command_line);
    }
    else
    {
        DWORD current_process_session_id;

        if (!GetSessionIdForCurrentProcess(current_process_session_id))
            return false;

        // If the current process is started not in session 0 (not as a service),
        // then we create a service to start the process in the required session.
        if (!IsWindowsVistaOrGreater() || current_process_session_id != 0)
        {
            std::wstring service_id =
                ServiceManager::GenerateUniqueServiceId();

            std::wstring unique_short_name =
                ServiceManager::CreateUniqueServiceName(kServiceShortName, service_id);

            std::wstring unique_full_name =
                ServiceManager::CreateUniqueServiceName(kServiceFullName, service_id);

            command_line.append(L" --run_mode=");
            command_line.append(kDesktopSessionLauncherSwitch);
            command_line.append(L" --session_id=");
            command_line.append(std::to_wstring(session_id));

            command_line.append(L" --service_id=");
            command_line.append(service_id);

            // Install the service in the system.
            ServiceManager manager(ServiceManager::Create(command_line,
                                                          unique_full_name,
                                                          unique_short_name));

            // If the service was not installed.
            if (!manager.IsValid())
                return false;

            return manager.Start();
        }
        else // The code is executed from the service.
        {
            // Start the process directly.
            return LaunchProcessInSession(session_id, input_channel_id, output_channel_id);
        }
    }
}

} // namespace aspia
<|endoftext|>


<commit_before>// main.cpp: Santiago Arias
// Description: HW4 the HEX program
// c++11
// to compile: g++ -std=c++11 graph.cpp shortest_path.cpp main.cpp;
#include <iostream>

#include "graph.h"
#include "shortest_path.h"

using namespace std;

int main(){
  cout << "HW 4" << endl;
}
<commit_msg>starting the hex board<commit_after>// main.cpp: Santiago Arias
// Description: HW4 the HEX program
// c++11
// to compile: g++ -std=c++11 graph.cpp shortest_path.cpp main.cpp;
#include <iostream>

#include "graph.h"
#include "shortest_path.h"

using namespace std;

int main(){
  cout << "HW 4" << endl;
  int size = 7;

  string space =  "";
  for(int j = 0; j < 7; j++){
    cout << space;
    for(int i = 0; i < 7; i++){
      cout << " . ";
      if(i != 6)
	cout << " - ";
    }
    cout << endl;
    if(j != 6){
      space += " ";
      cout << space;
      cout << " \\ ";
      for(int i = 0; i < 6; i++){
	cout << "  / " << "\\ ";
      }
      cout << endl;
      space += " ";
    }
  }
  cout << endl << endl;
// .  -  .  -  .  -  .  -  .
//  \   / \

}
<|endoftext|>


<commit_before>#include <catch.hpp>
#include <memory>

#include "GCodeWriter.hpp"
#include "test_options.hpp"

using namespace Slic3r;
using namespace std::literals::string_literals;

SCENARIO("lift() is not ignored after unlift() at large values of Z", "[!mayfail]") {
    GIVEN("A config from a file and a single extruder.")
    auto writer {std::make_unique(GCodeWriter())}; // ensure cleanup later
    auto& config {writer->config};
    config.set_defaults();
    config.load(std::string(testfile_dir) + "test_gcodewriter/config_lift_unlift.ini"s);

    std::vector<unsigned int> extruder_ids {0};
    writer->set_extruders(extruder_ids);
    writer->set_extruder(0);

    double trouble_Z = 9007199254740992;
    WHEN("Z is set to 9007199254740992") {
        writer->travel_to_z(trouble_Z);
        AND_WHEN("GcodeWriter::Lift() is called") {
            REQUIRE(writer->lift().size() > 0);
            AND_WHEN("Z is moved post-lift to the same delta as the config Z lift") {
                writer->travel_to_z(trouble_z + config.retract_lift);
                AND_WHEN("GCodeWriter::Lift() is called after GCodeWriter::Unlift()") {
                    REQUIRE(writer->unlift().size() > 0);
                    THEN("GCodeWriter::Lift() emits gcode.") {
                        REQUIRE(writer->lift().size() > 0);
                    }
                }
            }
        }
    }
}
<commit_msg>Fall back to not using make::unique for now<commit_after>#include <catch.hpp>
#include <memory>

#include "GCodeWriter.hpp"
#include "test_options.hpp"

using namespace Slic3r;
using namespace std::literals::string_literals;

SCENARIO("lift() is not ignored after unlift() at large values of Z", "[!mayfail]") {
    GIVEN("A config from a file and a single extruder.")
    auto* writer {new GCodeWriter()};
    auto& config {writer->config};
    config.set_defaults();
    config.load(std::string(testfile_dir) + "test_gcodewriter/config_lift_unlift.ini"s);

    std::vector<unsigned int> extruder_ids {0};
    writer->set_extruders(extruder_ids);
    writer->set_extruder(0);

    WHEN("Z is set to 9007199254740992") {
        double trouble_Z = 9007199254740992;
        writer->travel_to_z(trouble_Z);
        AND_WHEN("GcodeWriter::Lift() is called") {
            REQUIRE(writer->lift().size() > 0);
            AND_WHEN("Z is moved post-lift to the same delta as the config Z lift") {
                REQUIRE(writer->travel_to_z(trouble_z + config.retract_lift).size() == 0);
                AND_WHEN("GCodeWriter::Lift() is called after GCodeWriter::Unlift()") {
                    REQUIRE(writer->unlift().size() > 0);
                    THEN("GCodeWriter::Lift() emits gcode.") {
                        REQUIRE(writer->lift().size() > 0);
                    }
                }
            }
        }
    }
    delete writer;
}
<|endoftext|>


<commit_before>#include "Base64.h"

const char b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		"abcdefghijklmnopqrstuvwxyz"
		"0123456789+/";

/* 'Private' declarations */
inline void a3_to_a4(unsigned char * a4, unsigned char * a3);
inline void a4_to_a3(unsigned char * a3, unsigned char * a4);
inline unsigned char b64_lookup(char c);

int base64_encode(char *output, char *input, int inputLen) {
	int i = 0, j = 0;
	int encLen = 0;
	unsigned char a3[3];
	unsigned char a4[4];

	while(inputLen--) {
		a3[i++] = *(input++);
		if(i == 3) {
			a3_to_a4(a4, a3);

			for(i = 0; i < 4; i++) {
				output[encLen++] = b64_alphabet[a4[i]];
			}

			i = 0;
		}
	}

	if(i) {
		for(j = i; j < 3; j++) {
			a3[j] = '\0';
		}

		a3_to_a4(a4, a3);

		for(j = 0; j < i + 1; j++) {
			output[encLen++] = b64_alphabet[a4[j]];
		}

		while((i++ < 3)) {
			output[encLen++] = '=';
		}
	}
	output[encLen] = '\0';
	return encLen;
}

int base64_decode(char * output, char * input, int inputLen) {
	int i = 0, j = 0;
	int decLen = 0;
	unsigned char a3[3];
	unsigned char a4[4];

	while (inputLen--) {
		if(*input == '=') {
			break;
		}

		a4[i++] = *(input++);
		if (i == 4) {
			for (i = 0; i <4; i++) {
				a4[i] = b64_lookup(a4[i]);
			}

			a4_to_a3(a3,a4);

			for (i = 0; i < 3; i++) {
				output[decLen++] = a3[i];
			}
			i = 0;
		}
	}

	if (i) {
		for (j = i; j < 4; j++) {
			a4[j] = '\0';
		}

		for (j = 0; j <4; j++) {
			a4[j] = b64_lookup(a4[j]);
		}

		a4_to_a3(a3,a4);

		for (j = 0; j < i - 1; j++) {
			output[decLen++] = a3[j];
		}
	}
	output[decLen] = '\0';
	return decLen;
}

int base64_enc_len(int plainLen) {
	int n = plainLen;
	return (n + 2 - ((n + 2) % 3)) / 3 * 4;
}

int base64_dec_len(char * input, int inputLen) {
	int i = 0;
	int numEq = 0;
	for(i = inputLen - 1; input[i] == '='; i--) {
		numEq++;
	}

	return ((6 * inputLen) / 8) - numEq;
}

inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
	a4[0] = (a3[0] & 0xfc) >> 2;
	a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
	a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
	a4[3] = (a3[2] & 0x3f);
}

inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
	a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
	a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
	a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
}

inline unsigned char b64_lookup(char c) {
	if(c >='A' && c <='Z') return c - 'A';
	if(c >='a' && c <='z') return c - 71;
	if(c >='0' && c <='9') return c + 4;
	if(c == '+') return 62;
	if(c == '/') return 63;
	return -1;
}
<commit_msg>Moved the base 64 alphabet into PROGMEM to save ram<commit_after>#include "Base64.h"
#include <avr/pgmspace.h>
const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		"abcdefghijklmnopqrstuvwxyz"
		"0123456789+/";

/* 'Private' declarations */
inline void a3_to_a4(unsigned char * a4, unsigned char * a3);
inline void a4_to_a3(unsigned char * a3, unsigned char * a4);
inline unsigned char b64_lookup(char c);

int base64_encode(char *output, char *input, int inputLen) {
	int i = 0, j = 0;
	int encLen = 0;
	unsigned char a3[3];
	unsigned char a4[4];

	while(inputLen--) {
		a3[i++] = *(input++);
		if(i == 3) {
			a3_to_a4(a4, a3);

			for(i = 0; i < 4; i++) {
				output[encLen++] = pgm_read_byte(&b64_alphabet[a4[i]]);
			}

			i = 0;
		}
	}

	if(i) {
		for(j = i; j < 3; j++) {
			a3[j] = '\0';
		}

		a3_to_a4(a4, a3);

		for(j = 0; j < i + 1; j++) {
			output[encLen++] = pgm_read_byte(&b64_alphabet[a4[j]]);
		}

		while((i++ < 3)) {
			output[encLen++] = '=';
		}
	}
	output[encLen] = '\0';
	return encLen;
}

int base64_decode(char * output, char * input, int inputLen) {
	int i = 0, j = 0;
	int decLen = 0;
	unsigned char a3[3];
	unsigned char a4[4];

	while (inputLen--) {
		if(*input == '=') {
			break;
		}

		a4[i++] = *(input++);
		if (i == 4) {
			for (i = 0; i <4; i++) {
				a4[i] = b64_lookup(a4[i]);
			}

			a4_to_a3(a3,a4);

			for (i = 0; i < 3; i++) {
				output[decLen++] = a3[i];
			}
			i = 0;
		}
	}

	if (i) {
		for (j = i; j < 4; j++) {
			a4[j] = '\0';
		}

		for (j = 0; j <4; j++) {
			a4[j] = b64_lookup(a4[j]);
		}

		a4_to_a3(a3,a4);

		for (j = 0; j < i - 1; j++) {
			output[decLen++] = a3[j];
		}
	}
	output[decLen] = '\0';
	return decLen;
}

int base64_enc_len(int plainLen) {
	int n = plainLen;
	return (n + 2 - ((n + 2) % 3)) / 3 * 4;
}

int base64_dec_len(char * input, int inputLen) {
	int i = 0;
	int numEq = 0;
	for(i = inputLen - 1; input[i] == '='; i--) {
		numEq++;
	}

	return ((6 * inputLen) / 8) - numEq;
}

inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
	a4[0] = (a3[0] & 0xfc) >> 2;
	a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
	a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
	a4[3] = (a3[2] & 0x3f);
}

inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
	a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
	a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
	a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
}

inline unsigned char b64_lookup(char c) {
	if(c >='A' && c <='Z') return c - 'A';
	if(c >='a' && c <='z') return c - 71;
	if(c >='0' && c <='9') return c + 4;
	if(c == '+') return 62;
	if(c == '/') return 63;
	return -1;
}
<|endoftext|>


<commit_before>#include "interpreter.h"

#include "details/autoconfigurer.h"

#include <QtCore/QDebug>

using namespace qReal;
using namespace interpreters::robots;
using namespace interpreters::robots::details;

const Id startingElementType = Id("RobotsMetamodel", "RobotsDiagram", "InitialNode");
const Id startingElementType1 = Id("RobotsMetamodel", "RobotsDiagram", "InitialBlock");

Interpreter::Interpreter()
	: mGraphicalModelApi(NULL)
	, mLogicalModelApi(NULL)
	, mInterpretersInterface(NULL)
	, mState(idle)
	, mRobotModel(new RobotModel())
	, mBlocksTable(NULL)
	, mBluetoothRobotCommunication(NULL)
{
	mParser = NULL;
	mBlocksTable = NULL;
	mTimer = new QTimer();

	mD2RobotModel = new d2Model::D2RobotModel();
	mD2ModelWidget = mD2RobotModel->createModelWidget();
}

void Interpreter::init(GraphicalModelAssistInterface const &graphicalModelApi
	, LogicalModelAssistInterface const &logicalModelApi
	, qReal::gui::MainWindowInterpretersInterface &interpretersInterface)
{
	mGraphicalModelApi = &graphicalModelApi;
	mLogicalModelApi = &logicalModelApi;
	mInterpretersInterface = &interpretersInterface;

	mParser = new RobotsBlockParser(mInterpretersInterface->errorReporter());
	mBlocksTable = new BlocksTable(graphicalModelApi, logicalModelApi, mRobotModel, mInterpretersInterface->errorReporter(), mParser);

	QString const comPort = SettingsManager::instance()->value("bluetoothPortName", "").toString();
	mBluetoothRobotCommunication = new BluetoothRobotCommunication(comPort);
	robotModelType::robotModelTypeEnum const modelType = static_cast<robotModelType::robotModelTypeEnum>(SettingsManager::value("robotModel", "1").toInt());
	setRobotImplementation(modelType, mBluetoothRobotCommunication);
}

Interpreter::~Interpreter()
{
	foreach (Thread * const thread, mThreads)
		delete thread;
	delete mBlocksTable;
}

void Interpreter::interpret()
{
	mInterpretersInterface->errorReporter()->clear();

	Id const &currentDiagramId = mInterpretersInterface->activeDiagram();

	if (!mConnected) {
		mInterpretersInterface->errorReporter()->addInformation(tr("No connection to robot"));
		return;
	}
	if (mState == interpreting) {
		mInterpretersInterface->errorReporter()->addInformation(tr("Interpreter is already running"));
		return;
	}

	mState = interpreting;

	mBlocksTable->setIdleForBlocks();

	Id const startingElement = findStartingElement(currentDiagramId);
	if (startingElement == Id()) {
		mInterpretersInterface->errorReporter()->addError(tr("No entry point found, please add Initial Node to a diagram"));
		return;
	}

	Autoconfigurer configurer(*mGraphicalModelApi, mBlocksTable, mInterpretersInterface->errorReporter(), mRobotModel);
	if (!configurer.configure(currentDiagramId))
		return;

	if (dynamic_cast<UnrealRobotModelImplementation*>(mRobotModel->robotImpl()))
		showD2ModelWidget(true);

	Thread * const initialThread = new Thread(*mInterpretersInterface, *mBlocksTable, startingElement);
	addThread(initialThread);
}

void Interpreter::stop()
{
	mRobotModel->stopRobot();
	mState = idle;
	foreach (Thread *thread, mThreads)
		delete thread;
	mBlocksTable->setFailure();
	/*mBlocksTable->clear();
	mThreads.clear();
	mTimer->stop();*/
}

void Interpreter::stopRobot()
{
	stop();
}

void Interpreter::showD2ModelWidget(bool isVisible)
{
	mD2ModelWidget->init(isVisible);
}

void Interpreter::setD2ModelWidgetActions(QAction *runAction, QAction *stopAction)
{
	mD2ModelWidget->setD2ModelWidgetActions(runAction, stopAction);
}

void Interpreter::setRobotImplementation(robotModelType::robotModelTypeEnum implementationType, RobotCommunicationInterface * const robotCommunicationInterface)
{
	disconnect(&mRobotModel->robotImpl(), SIGNAL(connected(bool)), this, SLOT(connectedSlot(bool)));
	mConnected = false;
	if (implementationType != robotModelType::real)
		mConnected = true;
	robotImplementations::AbstractRobotModelImplementation *robotImpl =
			robotImplementations::AbstractRobotModelImplementation::robotModel(implementationType, robotCommunicationInterface, mD2RobotModel);
	setRobotImplementation(robotImpl);
	connect(robotImpl, SIGNAL(connected(bool)), this, SLOT(connectedSlot(bool)));
}

void Interpreter::connectedSlot(bool success)
{
	if (success) {
		mConnected = true;
		mInterpretersInterface->errorReporter()->addInformation(tr("Connected successfully"));
	} else {
		mConnected = false;
		mInterpretersInterface->errorReporter()->addError(tr("Can't connect to a robot."));
	}
}

Id const Interpreter::findStartingElement(Id const &diagram) const
{
	IdList const children = mGraphicalModelApi->graphicalRepoApi().children(diagram);

	foreach (Id const child, children) {
		if (child.type() == startingElementType || child.type() == startingElementType1)
			return child;
	}

	return Id();
}

void Interpreter::threadStopped()
{
	Thread *thread = static_cast<Thread *>(sender());

	mThreads.removeAll(thread);
	delete thread;

	if (mThreads.isEmpty())
		stop();
}

void Interpreter::newThread(details::blocks::Block * const startBlock)
{
	Thread * const thread = new Thread(*mInterpretersInterface, *mBlocksTable, startBlock->id());
	addThread(thread);
}

void Interpreter::configureSensors(sensorType::SensorTypeEnum const &port1
		, sensorType::SensorTypeEnum const &port2
		, sensorType::SensorTypeEnum const &port3
		, sensorType::SensorTypeEnum const &port4)
{
	mRobotModel->configureSensors(port1, port2, port3, port4);
}

void Interpreter::addThread(details::Thread * const thread)
{
	mThreads.append(thread);
	connect(thread, SIGNAL(stopped()), this, SLOT(threadStopped()));
	connect(thread, SIGNAL(newThread(details::blocks::Block*const)), this, SLOT(newThread(details::blocks::Block*const)));

	thread->interpret();
}

interpreters::robots::details::RobotModel *Interpreter::robotModel()
{
	return mRobotModel;
}

void Interpreter::setRobotModel(details::RobotModel * const robotModel)
{
	mRobotModel = robotModel;
}

void Interpreter::setRobotImplementation(details::robotImplementations::AbstractRobotModelImplementation *robotImpl)
{
	mRobotModel->setRobotImplementation(robotImpl);
	if (robotImpl)
		connect(&mRobotModel->robotImpl(), SIGNAL(connected(bool)), this, SLOT(runTimer()));
}

void Interpreter::runTimer()
{
	mTimer->start(1000);
	connect(mTimer, SIGNAL(timeout()), this, SLOT(readSensorValues()));
	if (mRobotModel->sensor(inputPort::port1)) {
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot1(int)));
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port2)) {
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot2(int)));
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port3)) {
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot3(int)));
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port4)) {
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot4(int)));
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
}

void Interpreter::readSensorValues()
{
	if (mState == idle)
		return;

	if (mRobotModel->sensor(inputPort::port1))
		mRobotModel->sensor(inputPort::port1)->read();
	if (mRobotModel->sensor(inputPort::port2))
		mRobotModel->sensor(inputPort::port2)->read();
	if (mRobotModel->sensor(inputPort::port3))
		mRobotModel->sensor(inputPort::port3)->read();
	if (mRobotModel->sensor(inputPort::port4))
		mRobotModel->sensor(inputPort::port4)->read();
}

void Interpreter::slotFailure()
{
	qDebug() << "slotFailure";
}

void Interpreter::responseSlot1(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor1"), sensorValue);
}

void Interpreter::responseSlot2(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor2"), sensorValue);
}

void Interpreter::responseSlot3(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor3"), sensorValue);
}

void Interpreter::responseSlot4(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor4"), sensorValue);
}

void Interpreter::updateSensorValues(const QString &sensorVariableName, int sensorValue)
{
	(*(mParser->getVariables()))[sensorVariableName] = Number(sensorValue, Number::intType);
//	qDebug() << sensorVariableName << sensorValue;
}

void Interpreter::connectToRobot()
{
	mRobotModel->init();
}

void Interpreter::setBluetoothPortName(QString const &portName)
{
	mBluetoothRobotCommunication->setPortName(portName);
}

void Interpreter::setRobotModelType(robotModelType::robotModelTypeEnum robotModelType)
{
	setRobotImplementation(robotModelType, mBluetoothRobotCommunication);
}
<commit_msg>build fixed<commit_after>#include "interpreter.h"

#include "details/autoconfigurer.h"
#include "details/robotImplementations/unrealRobotModelImplementation.h"

#include <QtCore/QDebug>

using namespace qReal;
using namespace interpreters::robots;
using namespace interpreters::robots::details;

const Id startingElementType = Id("RobotsMetamodel", "RobotsDiagram", "InitialNode");
const Id startingElementType1 = Id("RobotsMetamodel", "RobotsDiagram", "InitialBlock");

Interpreter::Interpreter()
	: mGraphicalModelApi(NULL)
	, mLogicalModelApi(NULL)
	, mInterpretersInterface(NULL)
	, mState(idle)
	, mRobotModel(new RobotModel())
	, mBlocksTable(NULL)
	, mBluetoothRobotCommunication(NULL)
{
	mParser = NULL;
	mBlocksTable = NULL;
	mTimer = new QTimer();

	mD2RobotModel = new d2Model::D2RobotModel();
	mD2ModelWidget = mD2RobotModel->createModelWidget();
}

void Interpreter::init(GraphicalModelAssistInterface const &graphicalModelApi
	, LogicalModelAssistInterface const &logicalModelApi
	, qReal::gui::MainWindowInterpretersInterface &interpretersInterface)
{
	mGraphicalModelApi = &graphicalModelApi;
	mLogicalModelApi = &logicalModelApi;
	mInterpretersInterface = &interpretersInterface;

	mParser = new RobotsBlockParser(mInterpretersInterface->errorReporter());
	mBlocksTable = new BlocksTable(graphicalModelApi, logicalModelApi, mRobotModel, mInterpretersInterface->errorReporter(), mParser);

	QString const comPort = SettingsManager::instance()->value("bluetoothPortName", "").toString();
	mBluetoothRobotCommunication = new BluetoothRobotCommunication(comPort);
	robotModelType::robotModelTypeEnum const modelType = static_cast<robotModelType::robotModelTypeEnum>(SettingsManager::value("robotModel", "1").toInt());
	setRobotImplementation(modelType, mBluetoothRobotCommunication);
}

Interpreter::~Interpreter()
{
	foreach (Thread * const thread, mThreads)
		delete thread;
	delete mBlocksTable;
}

void Interpreter::interpret()
{
	mInterpretersInterface->errorReporter()->clear();

	Id const &currentDiagramId = mInterpretersInterface->activeDiagram();

	if (!mConnected) {
		mInterpretersInterface->errorReporter()->addInformation(tr("No connection to robot"));
		return;
	}
	if (mState == interpreting) {
		mInterpretersInterface->errorReporter()->addInformation(tr("Interpreter is already running"));
		return;
	}

	mState = interpreting;

	mBlocksTable->setIdleForBlocks();

	Id const startingElement = findStartingElement(currentDiagramId);
	if (startingElement == Id()) {
		mInterpretersInterface->errorReporter()->addError(tr("No entry point found, please add Initial Node to a diagram"));
		return;
	}

	Autoconfigurer configurer(*mGraphicalModelApi, mBlocksTable, mInterpretersInterface->errorReporter(), mRobotModel);
	if (!configurer.configure(currentDiagramId))
		return;

	if (dynamic_cast<robotImplementations::UnrealRobotModelImplementation*>(&(mRobotModel->robotImpl())))
		showD2ModelWidget(true);

	Thread * const initialThread = new Thread(*mInterpretersInterface, *mBlocksTable, startingElement);
	addThread(initialThread);
}

void Interpreter::stop()
{
	mRobotModel->stopRobot();
	mState = idle;
	foreach (Thread *thread, mThreads)
		delete thread;
	mBlocksTable->setFailure();
	/*mBlocksTable->clear();
	mThreads.clear();
	mTimer->stop();*/
}

void Interpreter::stopRobot()
{
	stop();
}

void Interpreter::showD2ModelWidget(bool isVisible)
{
	mD2ModelWidget->init(isVisible);
}

void Interpreter::setD2ModelWidgetActions(QAction *runAction, QAction *stopAction)
{
	mD2ModelWidget->setD2ModelWidgetActions(runAction, stopAction);
}

void Interpreter::setRobotImplementation(robotModelType::robotModelTypeEnum implementationType, RobotCommunicationInterface * const robotCommunicationInterface)
{
	disconnect(&mRobotModel->robotImpl(), SIGNAL(connected(bool)), this, SLOT(connectedSlot(bool)));
	mConnected = false;
	if (implementationType != robotModelType::real)
		mConnected = true;
	robotImplementations::AbstractRobotModelImplementation *robotImpl =
			robotImplementations::AbstractRobotModelImplementation::robotModel(implementationType, robotCommunicationInterface, mD2RobotModel);
	setRobotImplementation(robotImpl);
	connect(robotImpl, SIGNAL(connected(bool)), this, SLOT(connectedSlot(bool)));
}

void Interpreter::connectedSlot(bool success)
{
	if (success) {
		mConnected = true;
		mInterpretersInterface->errorReporter()->addInformation(tr("Connected successfully"));
	} else {
		mConnected = false;
		mInterpretersInterface->errorReporter()->addError(tr("Can't connect to a robot."));
	}
}

Id const Interpreter::findStartingElement(Id const &diagram) const
{
	IdList const children = mGraphicalModelApi->graphicalRepoApi().children(diagram);

	foreach (Id const child, children) {
		if (child.type() == startingElementType || child.type() == startingElementType1)
			return child;
	}

	return Id();
}

void Interpreter::threadStopped()
{
	Thread *thread = static_cast<Thread *>(sender());

	mThreads.removeAll(thread);
	delete thread;

	if (mThreads.isEmpty())
		stop();
}

void Interpreter::newThread(details::blocks::Block * const startBlock)
{
	Thread * const thread = new Thread(*mInterpretersInterface, *mBlocksTable, startBlock->id());
	addThread(thread);
}

void Interpreter::configureSensors(sensorType::SensorTypeEnum const &port1
		, sensorType::SensorTypeEnum const &port2
		, sensorType::SensorTypeEnum const &port3
		, sensorType::SensorTypeEnum const &port4)
{
	mRobotModel->configureSensors(port1, port2, port3, port4);
}

void Interpreter::addThread(details::Thread * const thread)
{
	mThreads.append(thread);
	connect(thread, SIGNAL(stopped()), this, SLOT(threadStopped()));
	connect(thread, SIGNAL(newThread(details::blocks::Block*const)), this, SLOT(newThread(details::blocks::Block*const)));

	thread->interpret();
}

interpreters::robots::details::RobotModel *Interpreter::robotModel()
{
	return mRobotModel;
}

void Interpreter::setRobotModel(details::RobotModel * const robotModel)
{
	mRobotModel = robotModel;
}

void Interpreter::setRobotImplementation(details::robotImplementations::AbstractRobotModelImplementation *robotImpl)
{
	mRobotModel->setRobotImplementation(robotImpl);
	if (robotImpl)
		connect(&mRobotModel->robotImpl(), SIGNAL(connected(bool)), this, SLOT(runTimer()));
}

void Interpreter::runTimer()
{
	mTimer->start(1000);
	connect(mTimer, SIGNAL(timeout()), this, SLOT(readSensorValues()));
	if (mRobotModel->sensor(inputPort::port1)) {
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot1(int)));
		connect(mRobotModel->sensor(inputPort::port1)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port2)) {
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot2(int)));
		connect(mRobotModel->sensor(inputPort::port2)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port3)) {
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot3(int)));
		connect(mRobotModel->sensor(inputPort::port3)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
	if (mRobotModel->sensor(inputPort::port4)) {
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(response(int)), this, SLOT(responseSlot4(int)));
		connect(mRobotModel->sensor(inputPort::port4)->sensorImpl(), SIGNAL(failure()), this, SLOT(slotFailure()));
	}
}

void Interpreter::readSensorValues()
{
	if (mState == idle)
		return;

	if (mRobotModel->sensor(inputPort::port1))
		mRobotModel->sensor(inputPort::port1)->read();
	if (mRobotModel->sensor(inputPort::port2))
		mRobotModel->sensor(inputPort::port2)->read();
	if (mRobotModel->sensor(inputPort::port3))
		mRobotModel->sensor(inputPort::port3)->read();
	if (mRobotModel->sensor(inputPort::port4))
		mRobotModel->sensor(inputPort::port4)->read();
}

void Interpreter::slotFailure()
{
	qDebug() << "slotFailure";
}

void Interpreter::responseSlot1(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor1"), sensorValue);
}

void Interpreter::responseSlot2(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor2"), sensorValue);
}

void Interpreter::responseSlot3(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor3"), sensorValue);
}

void Interpreter::responseSlot4(int sensorValue)
{
	updateSensorValues(QObject::tr("Sensor4"), sensorValue);
}

void Interpreter::updateSensorValues(const QString &sensorVariableName, int sensorValue)
{
	(*(mParser->getVariables()))[sensorVariableName] = Number(sensorValue, Number::intType);
//	qDebug() << sensorVariableName << sensorValue;
}

void Interpreter::connectToRobot()
{
	mRobotModel->init();
}

void Interpreter::setBluetoothPortName(QString const &portName)
{
	mBluetoothRobotCommunication->setPortName(portName);
}

void Interpreter::setRobotModelType(robotModelType::robotModelTypeEnum robotModelType)
{
	setRobotImplementation(robotModelType, mBluetoothRobotCommunication);
}
<|endoftext|>