<commit_before>//Author: Julian Yi
//Date: 14 July 2017
//board functions

#include <iostream>
#include "board.h"
#include "pieceutils.h"

board::board() : squares()
{ }

void board::promote(coord pos, TeamColor color)
{
	auto current = &squares[pos.x][pos.y];

	std::string Command = "";

	std::cout << colorToString(current->pieces.front()->team) << " Pawn has reached a promotion area Pick a type: ";
	std::cin >> Command;
	PieceType newType = pieceFromString(Command);

	deletePiece(pos);

	std::cout << "You picked " << Command << std::endl;

	placePiece(newType, pos, color);

}

bool board::placePiece(PieceType piece, coord pos, TeamColor color)
{
	auto current = &squares[pos.x][pos.y];

	if (!current->occupied())
	{
		current->canMove = false;
		current->pieces.push_back(PieceUtils::pieceFromType(piece, pos));
		current->pieces.front()->team = color;

		std::cout << colorToString(color) << " " << pieceToString(piece) << " is Placed at (" << pos.x << ", " << pos.y << ")" << std::endl;

		return true;
	}
	else
	{
		std::cout << "unable to place Piece " << pieceToString(piece) << " at (" << pos.x << ", " << pos.y << "). "
				  << pieceToString(current->pieces.front()->type) << " is Occupying the space." << std::endl;

		return false;
	}
}

bool board::movePiece(coord oldPos, coord newPos)
{
	//  Input validation
	if (oldPos.x > boardSize::x || oldPos.x < 0) {
		std::cout << "Old position X out of bounds (0, " << boardSize::x << ")" << std::endl;
		return false;
	}
	if (oldPos.y > boardSize::y || oldPos.y < 0) {
		std::cout << "Old position Y out of bounds (0, " << boardSize::y << ")" << std::endl;
		return false;
	}
	if (newPos.x > boardSize::x || newPos.x < 0) {
		std::cout << "Old position X out of bounds (0, " << boardSize::x << ")" << std::endl;
		return false;
	}
	if (newPos.y > boardSize::y || newPos.y < 0) {
		std::cout << "Old position Y out of bounds (0, " << boardSize::y << ")" << std::endl;
		return false;
	}

	auto oldS = &squares[oldPos.x][oldPos.y];
	if (oldS->pieces.empty()) {
		std::cout << "No piece to move at (" << oldPos.x << ", " << oldPos.y << ")" << std::endl;
		return false;
	}

	auto newS = &squares[newPos.x][newPos.y];

	// Get the moves for the piece located in the old square
	auto availableMoves = oldS->pieces.front()->calculateMoves({boardSize::x, boardSize::y}, squares);
	if (availableMoves.empty()) {
		std::cout << "No available moves for (" << oldPos.x << ", " << oldPos.y << ")" << std::endl;
		return false;
	}
	/*
	for (auto move : availableMoves) {
		std::cout << "(" << move.x << ", " << move.y << ") ";
	}
	std::cout << std::endl;
	*/
	if (std::find(availableMoves.begin(), availableMoves.end(), newPos) != availableMoves.end()) {
		// move to newpos.
		std::cout << colorToString(oldS->pieces.front()->team) << " " << pieceToString(oldS->pieces.front()->type) << " Attempting to move to (" << newPos.x << ", " << newPos.y << ")" << std::endl;

		if (!newS->pieces.empty()) {
			if (newS->pieces.front()->team == oldS->pieces.front()->team) {
				 std::cout << "Friendly piece at (" << newPos.x << ", " << newPos.y << "), against the rules." << std::endl;
				 return false;
			}

			std::cout << "(" << newPos.x << ", " << newPos.y << ") " << "is occupied by " << colorToString(newS->pieces.front()->team) << " "  << pieceToString(newS->pieces.front()->type) << std::endl;
			std::cout << colorToString(newS->pieces.front()->team) << " " << pieceToString(newS->pieces.front()->type) << " destroyed by " << colorToString(oldS->pieces.front()->team) << " " << pieceToString(oldS->pieces.front()->type) << " at (" << newPos.x << ", " << newPos.y << ")" << std::endl;
			newS->pieces.clear();
		}

		newS->pieces.push_back(oldS->pieces.front());
		newS->pieces.front()->setPosition(newPos); //position needs to change to the new position otherwise the piece pointer will still have the old positions
		oldS->pieces.clear();

		/* made for testing purpose
			coord pos = newS->pieces.front()->getPosition();
			std::cout << pos.x << pos.y;
		*/
		std::cout << "Successful move. " << colorToString(newS->pieces.front()->team) << " " << pieceToString(newS->pieces.front()->type) << " was moved to (" << newPos.x << ", " << newPos.y << ")" << std::endl;

		/*
			call promote if a Pawn Piece type reaches a y coordinate of 0 or 7 depending on their color
		*/
		if (newS->pieces.front()->type == PieceType::Pawn)
		{
			if (newS->pieces.front()->team == TeamColor::White && newPos.y == 7)
			{
				promote(newPos, TeamColor::White);
			}
			else if (newS->pieces.front()->team == TeamColor::Black && newPos.y == 0)
			{
				promote(newPos, TeamColor::Black);
			}
		}

	} else {
		// Not in the move list.
		std::cout << "Cannot move to (" << newPos.x << ", " << newPos.y << "), against the rules." << std::endl;
		return false;
	}

	return true;
}

bool board::deletePiece(coord pos)
{
	auto current = &squares[pos.x][pos.y];
	if (current->occupied())
	{
		current->canMove = true;
		//don't change the boardTag
		current->pieces.pop_back();
		return true;
	}
	return false;
}

void board::initializeBoard()
{
	int Ascii = 65;
	std::string boardTag = "";

	for (int index = 0; index < boardSize::y; ++index)
	{
		for (int jindex = 0; jindex < boardSize::x; ++jindex)
		{
			boardTag = (char(Ascii));
			boardTag += std::to_string(jindex);
			auto current = &squares[index][jindex];
			current->canMove = true;
			//squares[index]->tag = (char(Ascii) + '-' + char(index));
			current->tag = boardTag;
		}
		Ascii++;
	}
}

PieceType board::getSquareType(coord pos) const
{
	if (squares[pos.x][pos.y].occupied()) {
		return squares[pos.x][pos.y].pieces.front()->type;
	}
	return PieceType::None;
}

TeamColor board::getSquareColor(coord pos) const
{
	if (squares[pos.x][pos.y].occupied()) {
		return squares[pos.x][pos.y].pieces.front()->team;
	}
	return TeamColor::None;
}

//created for testing purpose
void board::printBoard()
{
	for (int index = 0; index < boardSize::y; ++index)
	{
		for (int jindex = 0; jindex < boardSize::x; ++jindex)
		{
			std::cout << squares[index][jindex].tag;
		}

		std::cout << std::endl;
	}
}
<commit_msg>Removed Can Move<commit_after>//Author: Julian Yi
//Date: 14 July 2017
//board functions

#include <iostream>
#include "board.h"
#include "pieceutils.h"

board::board() : squares()
{ }

void board::promote(coord pos, TeamColor color)
{
	auto current = &squares[pos.x][pos.y];

	std::string Command = "";

	std::cout << colorToString(current->pieces.front()->team) << " Pawn has reached a promotion area Pick a type: ";
	std::cin >> Command;
	PieceType newType = pieceFromString(Command);

	deletePiece(pos);

	std::cout << "You picked " << Command << std::endl;

	placePiece(newType, pos, color);

}

bool board::placePiece(PieceType piece, coord pos, TeamColor color)
{
	auto current = &squares[pos.x][pos.y];

	if (!current->occupied())
	{
		current->pieces.push_back(PieceUtils::pieceFromType(piece, pos));
		current->pieces.front()->team = color;

		std::cout << colorToString(color) << " " << pieceToString(piece) << " is Placed at (" << pos.x << ", " << pos.y << ")" << std::endl;

		return true;
	}
	else
	{
		std::cout << "unable to place Piece " << pieceToString(piece) << " at (" << pos.x << ", " << pos.y << "). "
				  << pieceToString(current->pieces.front()->type) << " is Occupying the space." << std::endl;

		return false;
	}
}

bool board::movePiece(coord oldPos, coord newPos)
{
	//  Input validation
	if (oldPos.x > boardSize::x || oldPos.x < 0) {
		std::cout << "Old position X out of bounds (0, " << boardSize::x << ")" << std::endl;
		return false;
	}
	if (oldPos.y > boardSize::y || oldPos.y < 0) {
		std::cout << "Old position Y out of bounds (0, " << boardSize::y << ")" << std::endl;
		return false;
	}
	if (newPos.x > boardSize::x || newPos.x < 0) {
		std::cout << "Old position X out of bounds (0, " << boardSize::x << ")" << std::endl;
		return false;
	}
	if (newPos.y > boardSize::y || newPos.y < 0) {
		std::cout << "Old position Y out of bounds (0, " << boardSize::y << ")" << std::endl;
		return false;
	}

	auto oldS = &squares[oldPos.x][oldPos.y];
	if (oldS->pieces.empty()) {
		std::cout << "No piece to move at (" << oldPos.x << ", " << oldPos.y << ")" << std::endl;
		return false;
	}

	auto newS = &squares[newPos.x][newPos.y];

	// Get the moves for the piece located in the old square
	auto availableMoves = oldS->pieces.front()->calculateMoves({boardSize::x, boardSize::y}, squares);
	if (availableMoves.empty()) {
		std::cout << "No available moves for (" << oldPos.x << ", " << oldPos.y << ")" << std::endl;
		return false;
	}
	/*
	for (auto move : availableMoves) {
		std::cout << "(" << move.x << ", " << move.y << ") ";
	}
	std::cout << std::endl;
	*/
	if (std::find(availableMoves.begin(), availableMoves.end(), newPos) != availableMoves.end()) {
		// move to newpos.
		std::cout << colorToString(oldS->pieces.front()->team) << " " << pieceToString(oldS->pieces.front()->type) << " Attempting to move to (" << newPos.x << ", " << newPos.y << ")" << std::endl;

		if (!newS->pieces.empty()) {
			if (newS->pieces.front()->team == oldS->pieces.front()->team) {
				 std::cout << "Friendly piece at (" << newPos.x << ", " << newPos.y << "), against the rules." << std::endl;
				 return false;
			}

			std::cout << "(" << newPos.x << ", " << newPos.y << ") " << "is occupied by " << colorToString(newS->pieces.front()->team) << " "  << pieceToString(newS->pieces.front()->type) << std::endl;
			std::cout << colorToString(newS->pieces.front()->team) << " " << pieceToString(newS->pieces.front()->type) << " destroyed by " << colorToString(oldS->pieces.front()->team) << " " << pieceToString(oldS->pieces.front()->type) << " at (" << newPos.x << ", " << newPos.y << ")" << std::endl;
			newS->pieces.clear();
		}

		newS->pieces.push_back(oldS->pieces.front());
		newS->pieces.front()->setPosition(newPos); //position needs to change to the new position otherwise the piece pointer will still have the old positions
		oldS->pieces.clear();

		/* made for testing purpose
			coord pos = newS->pieces.front()->getPosition();
			std::cout << pos.x << pos.y;
		*/
		std::cout << "Successful move. " << colorToString(newS->pieces.front()->team) << " " << pieceToString(newS->pieces.front()->type) << " was moved to (" << newPos.x << ", " << newPos.y << ")" << std::endl;

		/*
			call promote if a Pawn Piece type reaches a y coordinate of 0 or 7 depending on their color
		*/
		if (newS->pieces.front()->type == PieceType::Pawn)
		{
			if (newS->pieces.front()->team == TeamColor::White && newPos.y == 7)
			{
				promote(newPos, TeamColor::White);
			}
			else if (newS->pieces.front()->team == TeamColor::Black && newPos.y == 0)
			{
				promote(newPos, TeamColor::Black);
			}
		}

	} else {
		// Not in the move list.
		std::cout << "Cannot move to (" << newPos.x << ", " << newPos.y << "), against the rules." << std::endl;
		return false;
	}

	return true;
}

bool board::deletePiece(coord pos)
{
	auto current = &squares[pos.x][pos.y];
	if (current->occupied())
	{
		//don't change the boardTag
		current->pieces.pop_back();
		return true;
	}
	return false;
}

void board::initializeBoard()
{
	int Ascii = 65;
	std::string boardTag = "";

	for (int index = 0; index < boardSize::y; ++index)
	{
		for (int jindex = 0; jindex < boardSize::x; ++jindex)
		{
			boardTag = (char(Ascii));
			boardTag += std::to_string(jindex);
			auto current = &squares[index][jindex];
			//squares[index]->tag = (char(Ascii) + '-' + char(index));
			current->tag = boardTag;
		}
		Ascii++;
	}
}

PieceType board::getSquareType(coord pos) const
{
	if (squares[pos.x][pos.y].occupied()) {
		return squares[pos.x][pos.y].pieces.front()->type;
	}
	return PieceType::None;
}

TeamColor board::getSquareColor(coord pos) const
{
	if (squares[pos.x][pos.y].occupied()) {
		return squares[pos.x][pos.y].pieces.front()->team;
	}
	return TeamColor::None;
}

//created for testing purpose
void board::printBoard()
{
	for (int index = 0; index < boardSize::y; ++index)
	{
		for (int jindex = 0; jindex < boardSize::x; ++jindex)
		{
			std::cout << squares[index][jindex].tag;
		}

		std::cout << std::endl;
	}
}
<|endoftext|>


<commit_before>// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

#include "config.h"

#include <cppunit/TextTestRunner.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/extensions/HelperMacros.h>

#include <sstream>
#include <string.h>

#include "Byte.h"
#include "Int8.h"
#include "Int16.h"
#include "UInt16.h"
#include "Int32.h"
#include "UInt32.h"
#include "Int64.h"
#include "UInt64.h"
#include "Float32.h"
#include "Float64.h"
#include "Str.h"
#include "Url.h"
#include "Array.h"
#include "Structure.h"
#include "Sequence.h"
#include "Grid.h"
#include "crc.h"

#include "DDS.h"

#include "GNURegex.h"
#include "GetOpt.h"
#include "util.h"
#include "debug.h"
#include "ce_expr.tab.hh"

#include "testFile.h"
#include "test_config.h"

static bool debug = false;

#undef DBG
#define DBG(x) do { if (debug) {x;} } while(false)

using namespace CppUnit;
using namespace std;

namespace libdap {

class UInt16Test: public TestFixture {
private:
    UInt16 *i1, *i2;
    char a[1024];

public:
    UInt16Test() : i1(0), i2(0)
    {
    }
    ~UInt16Test()
    {
    }

    void setUp()
    {
        i1 = new UInt16("a", "b");
        i2 = new UInt16("e");
    }

    void tearDown()
    {
        delete i1;
        delete i2;
    }

    CPPUNIT_TEST_SUITE(UInt16Test);

    CPPUNIT_TEST(cons_UInt16_test);
    CPPUNIT_TEST(checksum_test);
    CPPUNIT_TEST(val2buf_test);
    CPPUNIT_TEST(buf2val_test);
    CPPUNIT_TEST(set_value_test);
    CPPUNIT_TEST(equals_test);
    CPPUNIT_TEST(type_compare_test);
    CPPUNIT_TEST(ops_exception_1_test);
    CPPUNIT_TEST(ops_exception_2_test);
    CPPUNIT_TEST(dump_test);
    CPPUNIT_TEST(print_test);
    CPPUNIT_TEST(check_types);

    CPPUNIT_TEST_SUITE_END();

    void cons_UInt16_test()
    {
        CPPUNIT_ASSERT(i1->value() == 0 && i1->dataset() == "b" && i1->name() == "a" &&
                       i1->type() == dods_uint16_c);
        CPPUNIT_ASSERT(i2->value() == 0);
    }

    void checksum_test()
    {
        Crc32 cs;
        i2->compute_checksum(cs);
    }

    void val2buf_test()
    {
        int i = 42;
        i2->val2buf(&i, true);
        CPPUNIT_ASSERT(i2->value() == 42);
        CPPUNIT_ASSERT_THROW(i2->val2buf(NULL, true), InternalErr);
    }

    void buf2val_test()
    {
        int i = 42;
        void *v = &i;
        void *v2 = NULL;
        CPPUNIT_ASSERT(i2->set_value(0));
        CPPUNIT_ASSERT(i2->buf2val(&v) == 2 && i == 0);
        // CPPUNIT_ASSERT_THROW(i2->buf2val(NULL), InternalErr);
        // CPPUNIT_ASSERT(i2->buf2val(&v2) == 2 && *(int *)v2 == 0);
    }

    void set_value_test()
    {
        CPPUNIT_ASSERT(i2->set_value(42) && i2->value() == 42);
    }

    void equals_test()
    {
        UInt16 i3 = UInt16("a", "b");
        UInt16 i4 = UInt16("e");
        CPPUNIT_ASSERT(i4.set_value(42) && i4.value() == 42);
        i3 = i4;
        CPPUNIT_ASSERT(i3.value() == 42);
        i3 = i3;
    }

    void type_compare_test()
    {
        Byte b1 = Byte("a");
        Int8 i8 = Int8("a");
        Int16 i16 = Int16("a");
        UInt16 ui16 = UInt16("a");
        Int32 i32 = Int32("a", "b");
        UInt32 ui32 = UInt32("a", "b");
        Int64 i64 = Int64("a", "b");
        UInt64 ui64 = UInt64("a", "b");
        Float32 f32 = Float32("a");
        Float64 f64 = Float64("a");
        Url url = Url("a");
        Str str = Str("a");
        Array array = Array("a", &i16, true);

        b1.set_value(42);
        i8.set_value(42);
        i16.set_value(42);
        ui16.set_value(42);
        i32.set_value(42);
        ui32.set_value(42);
        i64.set_value(42);
        ui64.set_value(42);
        f32.set_value(42);
        f64.set_value(42);
        CPPUNIT_ASSERT(ui16.value() == 42);
        CPPUNIT_ASSERT(ui16.ops(&b1, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&b1, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&i8, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&i16, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&ui16, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&i32, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&ui32, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&i64, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&ui64, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&f32, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&f64, SCAN_EQUAL));

        CPPUNIT_ASSERT_THROW(ui16.ops(&url, SCAN_EQUAL), Error);
        CPPUNIT_ASSERT_THROW(ui16.ops(&str, SCAN_EQUAL), Error);
        CPPUNIT_ASSERT_THROW(ui16.ops(&array, SCAN_EQUAL), Error);
    }

    void ops_exception_1_test()
    {
        Byte b1 = Byte("a");
        UInt16 ui16 = UInt16("a", "b");
        b1.set_read_p(false);
        CPPUNIT_ASSERT_THROW(ui16.ops(&b1, SCAN_EQUAL), InternalErr);
    }

    void ops_exception_2_test()
    {
        Byte b1 = Byte("a");
        UInt16 ui16 = UInt16("a", "b");
        ui16.set_read_p(false);
        CPPUNIT_ASSERT_THROW(ui16.ops(&b1, SCAN_EQUAL), InternalErr);
    }

    void dump_test()
    {
        ofstream ofs("UInt16Test_dump.output", ios::trunc);
        i1->set_value(21);
        i1->dump(ofs);
        ofs.close();
        ifstream ifs("UInt16Test_dump.output");
        while(!ifs.eof())
            ifs >> a;
        ifs.close();
        CPPUNIT_ASSERT(!strcmp(a, "21"));
    }

    void print_test()
    {
        FILE *fp;
        CPPUNIT_ASSERT(fp = fopen("UInt16Test.output", "w"));
        i1->set_value(22);
        i1->print_val(fp, " ", true);
        fclose(fp);
        ifstream ifs("UInt16Test.output");
        while(!ifs.eof())
            ifs >> a;
        ifs.close();
        CPPUNIT_ASSERT(!strcmp(a, "22;"));
    }

    void check_types()
    {
        Byte *b1 = new Byte("b");
        b1->set_value(14);
        i1->set_value(14);
//        CPPUNIT_ASSERT(b1 == i1);
        delete b1;
    }

};

CPPUNIT_TEST_SUITE_REGISTRATION(UInt16Test);

} // namespace libdap

int main(int argc, char *argv[])
{
    GetOpt getopt(argc, argv, "dh");
    int option_char;

    while ((option_char = getopt()) != -1)
        switch (option_char) {
        case 'd':
            debug = 1;  // debug is a static global
            break;

        case 'h': {     // help - show test names
            cerr << "Usage: UInt16Test has the following tests:" << endl;
            const std::vector<Test*> &tests = libdap::UInt16Test::suite()->getTests();
            unsigned int prefix_len = libdap::UInt16Test::suite()->getName().append("::").length();
            for (std::vector<Test*>::const_iterator i = tests.begin(), e = tests.end(); i != e; ++i) {
                cerr << (*i)->getName().replace(0, prefix_len, "") << endl;
            }
            return 1;
            break;
        }

        default:
            break;
        }

    CppUnit::TextTestRunner runner;
    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());

    bool wasSuccessful = true;
    string test = "";
    int i = getopt.optind;
    if (i == argc) {
        // run them all
        wasSuccessful = runner.run("");
    }
    else {
        for (; i < argc; ++i) {
            if (debug) cerr << "Running " << argv[i] << endl;
            test = libdap::UInt16Test::suite()->getName().append("::").append(argv[i]);
            wasSuccessful = wasSuccessful && runner.run(test);
        }
    }

    return wasSuccessful ? 0 : 1;
}

<commit_msg>attempting to fix second problem with travis<commit_after>// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

#include "config.h"

#include <cppunit/TextTestRunner.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/extensions/HelperMacros.h>

#include <sstream>
#include <string.h>

#include "Byte.h"
#include "Int8.h"
#include "Int16.h"
#include "UInt16.h"
#include "Int32.h"
#include "UInt32.h"
#include "Int64.h"
#include "UInt64.h"
#include "Float32.h"
#include "Float64.h"
#include "Str.h"
#include "Url.h"
#include "Array.h"
#include "Structure.h"
#include "Sequence.h"
#include "Grid.h"
#include "crc.h"

#include "DDS.h"

#include "GNURegex.h"
#include "GetOpt.h"
#include "util.h"
#include "debug.h"
#include "ce_expr.tab.hh"

#include "testFile.h"
#include "test_config.h"

static bool debug = false;

#undef DBG
#define DBG(x) do { if (debug) {x;} } while(false)

using namespace CppUnit;
using namespace std;

namespace libdap {

class UInt16Test: public TestFixture {
private:
    UInt16 *i1, *i2;
    char a[1024];

public:
    UInt16Test() : i1(0), i2(0)
    {
    }
    ~UInt16Test()
    {
    }

    void setUp()
    {
        i1 = new UInt16("a", "b");
        i2 = new UInt16("e");
    }

    void tearDown()
    {
        delete i1;
        delete i2;
    }

    CPPUNIT_TEST_SUITE(UInt16Test);

    CPPUNIT_TEST(cons_UInt16_test);
    CPPUNIT_TEST(checksum_test);
    CPPUNIT_TEST(val2buf_test);
    CPPUNIT_TEST(buf2val_test);
    CPPUNIT_TEST(set_value_test);
    CPPUNIT_TEST(equals_test);
    CPPUNIT_TEST(type_compare_test);
    CPPUNIT_TEST(ops_exception_1_test);
    CPPUNIT_TEST(ops_exception_2_test);
    CPPUNIT_TEST(dump_test);
    CPPUNIT_TEST(print_test);
    CPPUNIT_TEST(check_types);

    CPPUNIT_TEST_SUITE_END();

    void cons_UInt16_test()
    {
        CPPUNIT_ASSERT(i1->value() == 0 && i1->dataset() == "b" && i1->name() == "a" &&
                       i1->type() == dods_uint16_c);
        CPPUNIT_ASSERT(i2->value() == 0);
    }

    void checksum_test()
    {
        Crc32 cs;
        i2->compute_checksum(cs);
    }

    void val2buf_test()
    {
        int i = 42;
        i2->val2buf(&i, true);
        CPPUNIT_ASSERT(i2->value() == 42);
        CPPUNIT_ASSERT_THROW(i2->val2buf(NULL, true), InternalErr);
    }

    void buf2val_test()
    {
        int i = 42;
        void *v = &i;
        void *v2 = NULL;
        CPPUNIT_ASSERT(i2->set_value(0));
        CPPUNIT_ASSERT(i2->buf2val(&v) == 2 && i == 0);
        CPPUNIT_ASSERT_THROW(i2->buf2val(NULL), InternalErr);
        // CPPUNIT_ASSERT(i2->buf2val(&v2) == 2 && *(int *)v2 == 0);
    }

    void set_value_test()
    {
        CPPUNIT_ASSERT(i2->set_value(42) && i2->value() == 42);
    }

    void equals_test()
    {
        UInt16 i3 = UInt16("a", "b");
        UInt16 i4 = UInt16("e");
        CPPUNIT_ASSERT(i4.set_value(42) && i4.value() == 42);
        i3 = i4;
        CPPUNIT_ASSERT(i3.value() == 42);
        i3 = i3;
    }

    void type_compare_test()
    {
        Byte b1 = Byte("a");
        Int8 i8 = Int8("a");
        Int16 i16 = Int16("a");
        UInt16 ui16 = UInt16("a");
        Int32 i32 = Int32("a", "b");
        UInt32 ui32 = UInt32("a", "b");
        Int64 i64 = Int64("a", "b");
        UInt64 ui64 = UInt64("a", "b");
        Float32 f32 = Float32("a");
        Float64 f64 = Float64("a");
        Url url = Url("a");
        Str str = Str("a");
        Array array = Array("a", &i16, true);

        b1.set_value(42);
        i8.set_value(42);
        i16.set_value(42);
        ui16.set_value(42);
        i32.set_value(42);
        ui32.set_value(42);
        i64.set_value(42);
        ui64.set_value(42);
        f32.set_value(42);
        f64.set_value(42);
        CPPUNIT_ASSERT(ui16.value() == 42);
        CPPUNIT_ASSERT(ui16.ops(&b1, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&b1, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&i8, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&i16, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&ui16, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&i32, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&ui32, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&i64, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&ui64, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&f32, SCAN_EQUAL));
        CPPUNIT_ASSERT(ui16.ops(&f64, SCAN_EQUAL));

        CPPUNIT_ASSERT_THROW(ui16.ops(&url, SCAN_EQUAL), Error);
        CPPUNIT_ASSERT_THROW(ui16.ops(&str, SCAN_EQUAL), Error);
        CPPUNIT_ASSERT_THROW(ui16.ops(&array, SCAN_EQUAL), Error);
    }

    void ops_exception_1_test()
    {
        Byte b1 = Byte("a");
        UInt16 ui16 = UInt16("a", "b");
        b1.set_read_p(false);
        CPPUNIT_ASSERT_THROW(ui16.ops(&b1, SCAN_EQUAL), InternalErr);
    }

    void ops_exception_2_test()
    {
        Byte b1 = Byte("a");
        UInt16 ui16 = UInt16("a", "b");
        ui16.set_read_p(false);
        CPPUNIT_ASSERT_THROW(ui16.ops(&b1, SCAN_EQUAL), InternalErr);
    }

    void dump_test()
    {
        ofstream ofs("UInt16Test_dump.output", ios::trunc);
        i1->set_value(21);
        i1->dump(ofs);
        ofs.close();
        ifstream ifs("UInt16Test_dump.output");
        while(!ifs.eof())
            ifs >> a;
        ifs.close();
        CPPUNIT_ASSERT(!strcmp(a, "21"));
    }

    void print_test()
    {
        FILE *fp;
        CPPUNIT_ASSERT(fp = fopen("UInt16Test.output", "w"));
        i1->set_value(22);
        i1->print_val(fp, " ", true);
        fclose(fp);
        ifstream ifs("UInt16Test.output");
        while(!ifs.eof())
            ifs >> a;
        ifs.close();
        CPPUNIT_ASSERT(!strcmp(a, "22;"));
    }

    void check_types()
    {
        Byte *b1 = new Byte("b");
        b1->set_value(14);
        i1->set_value(14);
//        CPPUNIT_ASSERT(b1 == i1);
        delete b1;
    }

};

CPPUNIT_TEST_SUITE_REGISTRATION(UInt16Test);

} // namespace libdap

int main(int argc, char *argv[])
{
    GetOpt getopt(argc, argv, "dh");
    int option_char;

    while ((option_char = getopt()) != -1)
        switch (option_char) {
        case 'd':
            debug = 1;  // debug is a static global
            break;

        case 'h': {     // help - show test names
            cerr << "Usage: UInt16Test has the following tests:" << endl;
            const std::vector<Test*> &tests = libdap::UInt16Test::suite()->getTests();
            unsigned int prefix_len = libdap::UInt16Test::suite()->getName().append("::").length();
            for (std::vector<Test*>::const_iterator i = tests.begin(), e = tests.end(); i != e; ++i) {
                cerr << (*i)->getName().replace(0, prefix_len, "") << endl;
            }
            return 1;
            break;
        }

        default:
            break;
        }

    CppUnit::TextTestRunner runner;
    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());

    bool wasSuccessful = true;
    string test = "";
    int i = getopt.optind;
    if (i == argc) {
        // run them all
        wasSuccessful = runner.run("");
    }
    else {
        for (; i < argc; ++i) {
            if (debug) cerr << "Running " << argv[i] << endl;
            test = libdap::UInt16Test::suite()->getName().append("::").append(argv[i]);
            wasSuccessful = wasSuccessful && runner.run(test);
        }
    }

    return wasSuccessful ? 0 : 1;
}

<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in LICENSE

#include "StableHeaders.h"
#define MATH_BULLET_INTEROP
#include "DebugOperatorNew.h"

#include "PhysicsWorld.h"
#include "EC_PhysicsConstraint.h"
#include "EC_RigidBody.h"

#include "FrameAPI.h"
#include "Scene.h"
#include "Entity.h"
#include "Math/MathFunc.h"
#include "EC_Placeable.h"

#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"

#include "AttributeMetadata.h"

using namespace Physics;

Quat FromEulerDegToQuat(float3 degEuler)
{
    float3 radEuler = DegToRad(degEuler);
    return Quat::FromEulerXYZ(radEuler.x, radEuler.y, radEuler.z);
}

EC_PhysicsConstraint::EC_PhysicsConstraint(Scene* scene):
    IComponent(scene),
    constraint_(0),
    checkForRigidBodies(false),
    INIT_ATTRIBUTE_VALUE(enabled, "Enabled", false),
    INIT_ATTRIBUTE_VALUE(disableCollision, "Disable collision", false),
    INIT_ATTRIBUTE_VALUE(type, "Constraint type", 0),
    INIT_ATTRIBUTE_VALUE(otherEntity, "Other entity", EntityReference()),
    INIT_ATTRIBUTE_VALUE(position, "Position", float3::zero),
    INIT_ATTRIBUTE_VALUE(otherPosition, "Other position", float3::zero),
    INIT_ATTRIBUTE_VALUE(rotation, "Rotation", float3::zero),
    INIT_ATTRIBUTE_VALUE(otherRotation, "Other rotation", float3::zero),
    INIT_ATTRIBUTE_VALUE(linearLimit, "Linear limit", float2::zero),
    INIT_ATTRIBUTE_VALUE(angularLimit, "Angular limit", float2::zero)
{
    static AttributeMetadata constraintTypeMetadata;
    static bool metadataInitialized = false;
    if(!metadataInitialized)
    {
        constraintTypeMetadata.enums[Hinge] = "Hinge";
        constraintTypeMetadata.enums[PointToPoint] = "Point to point";
        constraintTypeMetadata.enums[Slider] = "Slider";
        constraintTypeMetadata.enums[ConeTwist] = "Cone twist";
        metadataInitialized = true;
    }
    type.SetMetadata(&constraintTypeMetadata);

    connect(this, SIGNAL(ParentEntitySet()), this, SLOT(UpdateSignals()), Qt::UniqueConnection);
}

EC_PhysicsConstraint::~EC_PhysicsConstraint()
{
    Remove();
}

void EC_PhysicsConstraint::UpdateSignals()
{
    Entity *parentEntity = ParentEntity();
    if (!parentEntity)
        return;

    Scene* scene = parentEntity->ParentScene();
    physicsWorld_ = scene->GetWorld<PhysicsWorld>();

    connect(GetFramework()->Frame(), SIGNAL(Updated(float)), SLOT(CheckForBulletRigidBody()), Qt::UniqueConnection);
    connect(parentEntity, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), SLOT(OnComponentAdded(IComponent*)), Qt::UniqueConnection);
    connect(parentEntity, SIGNAL(ComponentRemoved(IComponent*, AttributeChange::Type)), SLOT(OnComponentRemoved(IComponent*)), Qt::UniqueConnection);
}

void EC_PhysicsConstraint::OnComponentAdded(IComponent *component)
{
    if (component->TypeId() == EC_RigidBody::TypeIdStatic())
        Create();
}

void EC_PhysicsConstraint::OnComponentRemoved(IComponent *component)
{
    if (component->TypeId() == EC_RigidBody::TypeIdStatic())
        Remove();
}

void EC_PhysicsConstraint::CheckForBulletRigidBody()
{
    if (!checkForRigidBodies)
        return;

    EC_RigidBody *rigidBody = rigidBody_.lock().get();
    EC_RigidBody *otherRigidBody = otherRigidBody_.lock().get();
    bool rigidBodyCreated = rigidBody && rigidBody->GetRigidBody();
    bool otherBodyCreated = otherRigidBody && otherRigidBody->GetRigidBody();

    if (rigidBodyCreated || otherBodyCreated)
    {
        Create();
        if (constraint_)
            checkForRigidBodies = false;
    }
}

void EC_PhysicsConstraint::AttributesChanged()
{
    bool recreate = false;
    bool applyAttributes = false;
    bool applyLimits = false;

    if (enabled.ValueChanged())
    {
        if (constraint_)
            constraint_->setEnabled(getenabled());
        else
            recreate = true;
    }

    if (disableCollision.ValueChanged())
        recreate = true;
    if (type.ValueChanged())
        recreate = true;
    if (otherEntity.ValueChanged())
        recreate = true;
    if (position.ValueChanged())
        applyAttributes = true;
    if (otherPosition.ValueChanged())
        applyAttributes = true;
    if (rotation.ValueChanged())
        applyAttributes = true;
    if (otherRotation.ValueChanged())
        applyAttributes = true;
    if (linearLimit.ValueChanged())
        applyLimits = true;
    if (angularLimit.ValueChanged())
        applyLimits = true;

    if (recreate)
        Create();
    if (!recreate && applyAttributes)
        ApplyAttributes();
    if (!recreate && applyLimits)
        ApplyLimits();
}

void EC_PhysicsConstraint::Create()
{
    if (!ParentEntity() || physicsWorld_.expired())
        return;

    Remove();

    rigidBody_ = ParentEntity()->GetComponent<EC_RigidBody>();

    Entity *otherEntity = 0;
    if (!getotherEntity().IsEmpty())
    {
        otherEntity = getotherEntity().Lookup(ParentScene()).get();
        if (otherEntity)
        {
            otherRigidBody_ = otherEntity->GetComponent<EC_RigidBody>();
            connect(otherEntity, SIGNAL(EntityRemoved(Entity*, AttributeChange::Type)), SLOT(Remove()), Qt::UniqueConnection);
            connect(otherEntity, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), SLOT(OnComponentAdded(IComponent*)), Qt::UniqueConnection);
            connect(otherEntity, SIGNAL(ComponentRemoved(IComponent*, AttributeChange::Type)), SLOT(OnComponentRemoved(IComponent*)), Qt::UniqueConnection);
        }
        else
            otherRigidBody_.reset();
    }
    else
        otherRigidBody_.reset();

    EC_RigidBody *rigidBodyComp = rigidBody_.lock().get();
    EC_RigidBody *otherRigidBodyComp = otherRigidBody_.lock().get();
    btRigidBody *ownBody = rigidBodyComp ? rigidBodyComp->GetRigidBody() : 0;
    btRigidBody *otherBody = otherRigidBodyComp ? otherRigidBodyComp->GetRigidBody() : 0;

    if (!ownBody && !rigidBodyComp)
        return;

    else if (!ownBody && rigidBodyComp)
    {
        checkForRigidBodies = true;
        return;
    }

    if (!otherBody && !otherRigidBodyComp)
        otherBody = &btTypedConstraint::getFixedBody();
    else if (!otherBody && otherRigidBodyComp)
    {
        checkForRigidBodies = true;
        return;
    }

    float3 worldScale(1,1,1);
    float3 otherWorldScale(1,1,1);

    EC_Placeable *placeable = ParentEntity()->GetComponent<EC_Placeable>().get();
    EC_Placeable *otherPlaceable = 0;
    if (otherEntity)
        otherPlaceable = otherEntity->GetComponent<EC_Placeable>().get();

    if (placeable)
        worldScale = placeable->WorldScale();
    if (otherPlaceable)
        otherWorldScale = otherPlaceable->WorldScale();

    btTransform ownTransform(FromEulerDegToQuat(getrotation()), getposition().Mul(worldScale));
    btTransform otherTransform(FromEulerDegToQuat(getotherRotation()), getotherPosition().Mul(otherWorldScale));

    switch(gettype())
    {
        case PointToPoint:
            constraint_ = new btPoint2PointConstraint(*ownBody, *otherBody, getposition().Mul(worldScale), getotherPosition().Mul(otherWorldScale));
            break;

        case Hinge:
            constraint_ = new btHingeConstraint(*ownBody, *otherBody, ownTransform, otherTransform);
            break;

        case Slider:
            constraint_ = new btSliderConstraint(*ownBody, *otherBody, ownTransform, otherTransform, false);
            break;

        case ConeTwist:
            constraint_ = new btConeTwistConstraint(*ownBody, *otherBody, ownTransform, otherTransform);
            break;

        default:
            break;
    }

    if (constraint_)
    {
        constraint_->setUserConstraintPtr(this);
        constraint_->setEnabled(getenabled());
        ApplyLimits();

        PhysicsWorld *world = physicsWorld_.lock().get();
        world->BulletWorld()->addConstraint(constraint_, getdisableCollision());
        world->BulletWorld()->debugDrawConstraint(constraint_);
    }
}

void EC_PhysicsConstraint::Remove()
{
    if (constraint_)
    {
        EC_RigidBody *ownRigidComp = rigidBody_.lock().get();
        EC_RigidBody *otherRigidComp = otherRigidBody_.lock().get();
        if (otherRigidComp && otherRigidComp->GetRigidBody())
            otherRigidComp->GetRigidBody()->removeConstraintRef(constraint_);
        if (ownRigidComp && ownRigidComp->GetRigidBody())
            ownRigidComp->GetRigidBody()->removeConstraintRef(constraint_);

        PhysicsWorld *world = physicsWorld_.lock().get();
        if (world && world->BulletWorld())
            world->BulletWorld()->removeConstraint(constraint_);

        rigidBody_.reset();
        otherRigidBody_.reset();
        delete constraint_;
        constraint_ = 0;
    }
}

void EC_PhysicsConstraint::ApplyAttributes()
{
    if (!constraint_)
        return;

    float3 worldScale(1,1,1);
    float3 otherWorldScale(1,1,1);

    EC_Placeable *placeable = ParentEntity()->GetComponent<EC_Placeable>().get();
    Entity *entity = getotherEntity().Lookup(ParentScene()).get();
    EC_Placeable *otherPlaceable = 0;
    if (entity)
        otherPlaceable = entity->GetComponent<EC_Placeable>().get();

    if (placeable)
        worldScale = placeable->WorldScale();
    if (otherPlaceable)
        otherWorldScale = otherPlaceable->WorldScale();

    btTransform ownTransform(FromEulerDegToQuat(getrotation()), getposition().Mul(worldScale));
    btTransform otherTransform(FromEulerDegToQuat(getotherRotation()), getotherPosition().Mul(otherWorldScale));

    switch (constraint_->getConstraintType())
    {
        case POINT2POINT_CONSTRAINT_TYPE:
        {
            btPoint2PointConstraint* pointConstraint = static_cast<btPoint2PointConstraint*>(constraint_);
            pointConstraint->setPivotA(getposition().Mul(worldScale));
            pointConstraint->setPivotB(getotherPosition().Mul(otherWorldScale));
        }
            break;

        case HINGE_CONSTRAINT_TYPE:
        {
            btHingeConstraint* hingeConstraint = static_cast<btHingeConstraint*>(constraint_);
            hingeConstraint->setFrames(ownTransform, otherTransform);
        }
            break;

        case SLIDER_CONSTRAINT_TYPE:
        {
            btSliderConstraint* sliderConstraint = static_cast<btSliderConstraint*>(constraint_);
            sliderConstraint->setFrames(ownTransform, otherTransform);
        }
            break;

        case CONETWIST_CONSTRAINT_TYPE:
        {
            btConeTwistConstraint* coneTwistConstraint = static_cast<btConeTwistConstraint*>(constraint_);
            coneTwistConstraint->setFrames(ownTransform, otherTransform);
        }
            break;

        default:
            break;
    }
}

void EC_PhysicsConstraint::ApplyLimits()
{
    if (!constraint_)
        return;

    switch (constraint_->getConstraintType())
    {
        case HINGE_CONSTRAINT_TYPE:
        {
            btHingeConstraint* hingeConstraint = static_cast<btHingeConstraint*>(constraint_);
            hingeConstraint->setLimit(DegToRad(getangularLimit().x), DegToRad(getangularLimit().y));
        }
            break;

        case SLIDER_CONSTRAINT_TYPE:
        {
            btSliderConstraint* sliderConstraint = static_cast<btSliderConstraint*>(constraint_);

            sliderConstraint->setLowerLinLimit(getlinearLimit().x);
            sliderConstraint->setUpperLinLimit(getlinearLimit().y);

            sliderConstraint->setLowerAngLimit(DegToRad(getangularLimit().x));
            sliderConstraint->setUpperAngLimit(DegToRad(getangularLimit().y));
        }
            break;

        case CONETWIST_CONSTRAINT_TYPE:
        {
            btConeTwistConstraint* coneTwistConstraint = static_cast<btConeTwistConstraint*>(constraint_);
            coneTwistConstraint->setLimit(DegToRad(getangularLimit().y), DegToRad(getangularLimit().y), DegToRad(getlinearLimit().y));
        }
            break;

        default:
            break;
    }
}<commit_msg>Marked todo's for EC_PhysicsConstraint.<commit_after>// For conditions of distribution and use, see copyright notice in LICENSE

#include "StableHeaders.h"
#define MATH_BULLET_INTEROP
#include "DebugOperatorNew.h"

#include "PhysicsWorld.h"
#include "EC_PhysicsConstraint.h"
#include "EC_RigidBody.h"

#include "FrameAPI.h"
#include "Scene.h"
#include "Entity.h"
#include "Math/MathFunc.h"
#include "EC_Placeable.h"

#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"

#include "AttributeMetadata.h"

using namespace Physics;

Quat FromEulerDegToQuat(float3 degEuler)
{
    float3 radEuler = DegToRad(degEuler);
    return Quat::FromEulerXYZ(radEuler.x, radEuler.y, radEuler.z);
}

EC_PhysicsConstraint::EC_PhysicsConstraint(Scene* scene):
    IComponent(scene),
    constraint_(0),
    checkForRigidBodies(false),
    INIT_ATTRIBUTE_VALUE(enabled, "Enabled", false),
    INIT_ATTRIBUTE_VALUE(disableCollision, "Disable collision", false),
    INIT_ATTRIBUTE_VALUE(type, "Constraint type", 0),
    INIT_ATTRIBUTE_VALUE(otherEntity, "Other entity", EntityReference()),
    INIT_ATTRIBUTE_VALUE(position, "Position", float3::zero),
    INIT_ATTRIBUTE_VALUE(otherPosition, "Other position", float3::zero),
    INIT_ATTRIBUTE_VALUE(rotation, "Rotation", float3::zero),
    INIT_ATTRIBUTE_VALUE(otherRotation, "Other rotation", float3::zero),
    INIT_ATTRIBUTE_VALUE(linearLimit, "Linear limit", float2::zero),
    INIT_ATTRIBUTE_VALUE(angularLimit, "Angular limit", float2::zero)
{
    static AttributeMetadata constraintTypeMetadata;
    static bool metadataInitialized = false;
    if(!metadataInitialized)
    {
        constraintTypeMetadata.enums[Hinge] = "Hinge";
        constraintTypeMetadata.enums[PointToPoint] = "Point to point";
        constraintTypeMetadata.enums[Slider] = "Slider";
        constraintTypeMetadata.enums[ConeTwist] = "Cone twist";
        metadataInitialized = true;
    }
    type.SetMetadata(&constraintTypeMetadata);

    connect(this, SIGNAL(ParentEntitySet()), this, SLOT(UpdateSignals()), Qt::UniqueConnection);
}

EC_PhysicsConstraint::~EC_PhysicsConstraint()
{
    Remove();
}

void EC_PhysicsConstraint::UpdateSignals()
{
    Entity *parentEntity = ParentEntity();
    if (!parentEntity)
        return;

    Scene* scene = parentEntity->ParentScene();
    physicsWorld_ = scene->GetWorld<PhysicsWorld>();

    connect(GetFramework()->Frame(), SIGNAL(Updated(float)), SLOT(CheckForBulletRigidBody()), Qt::UniqueConnection);
    connect(parentEntity, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), SLOT(OnComponentAdded(IComponent*)), Qt::UniqueConnection);
    connect(parentEntity, SIGNAL(ComponentRemoved(IComponent*, AttributeChange::Type)), SLOT(OnComponentRemoved(IComponent*)), Qt::UniqueConnection);
}

void EC_PhysicsConstraint::OnComponentAdded(IComponent *component)
{
    if (component->TypeId() == EC_RigidBody::TypeIdStatic())
        Create();
}

void EC_PhysicsConstraint::OnComponentRemoved(IComponent *component)
{
    if (component->TypeId() == EC_RigidBody::TypeIdStatic())
        Remove();
}

void EC_PhysicsConstraint::CheckForBulletRigidBody()
{
    if (!checkForRigidBodies)
        return;

    EC_RigidBody *rigidBody = rigidBody_.lock().get();
    EC_RigidBody *otherRigidBody = otherRigidBody_.lock().get();
    bool rigidBodyCreated = rigidBody && rigidBody->GetRigidBody();
    bool otherBodyCreated = otherRigidBody && otherRigidBody->GetRigidBody();

    if (rigidBodyCreated || otherBodyCreated)
    {
        Create();
        if (constraint_)
            checkForRigidBodies = false;
    }
}

void EC_PhysicsConstraint::AttributesChanged()
{
    bool recreate = false;
    bool applyAttributes = false;
    bool applyLimits = false;

    if (enabled.ValueChanged())
    {
        if (constraint_)
            constraint_->setEnabled(getenabled());
        else
            recreate = true;
    }

    if (disableCollision.ValueChanged())
        recreate = true;
    if (type.ValueChanged())
        recreate = true;
    if (otherEntity.ValueChanged())
        recreate = true;
    if (position.ValueChanged())
        applyAttributes = true;
    if (otherPosition.ValueChanged())
        applyAttributes = true;
    if (rotation.ValueChanged())
        applyAttributes = true;
    if (otherRotation.ValueChanged())
        applyAttributes = true;
    if (linearLimit.ValueChanged())
        applyLimits = true;
    if (angularLimit.ValueChanged())
        applyLimits = true;

    if (recreate)
        Create();
    if (!recreate && applyAttributes)
        ApplyAttributes();
    if (!recreate && applyLimits)
        ApplyLimits();
}

void EC_PhysicsConstraint::Create()
{
    if (!ParentEntity() || physicsWorld_.expired())
        return;

    Remove();

    rigidBody_ = ParentEntity()->GetComponent<EC_RigidBody>();

    /// \todo If the other entity is not yet loaded, the constraint will be mistakenly created as a static one
    /// \todo Add warning logging if the other entity is not found, or for other error situations
    Entity *otherEntity = 0;
    if (!getotherEntity().IsEmpty())
    {
        otherEntity = getotherEntity().Lookup(ParentScene()).get();
        if (otherEntity)
        {
            otherRigidBody_ = otherEntity->GetComponent<EC_RigidBody>();
            /// \todo Disconnect these signals at constraint removal time, in case the other entity ID is changed at runtime
            connect(otherEntity, SIGNAL(EntityRemoved(Entity*, AttributeChange::Type)), SLOT(Remove()), Qt::UniqueConnection);
            connect(otherEntity, SIGNAL(ComponentAdded(IComponent*, AttributeChange::Type)), SLOT(OnComponentAdded(IComponent*)), Qt::UniqueConnection);
            connect(otherEntity, SIGNAL(ComponentRemoved(IComponent*, AttributeChange::Type)), SLOT(OnComponentRemoved(IComponent*)), Qt::UniqueConnection);
        }
        else
            otherRigidBody_.reset();
    }
    else
        otherRigidBody_.reset();

    EC_RigidBody *rigidBodyComp = rigidBody_.lock().get();
    EC_RigidBody *otherRigidBodyComp = otherRigidBody_.lock().get();
    btRigidBody *ownBody = rigidBodyComp ? rigidBodyComp->GetRigidBody() : 0;
    btRigidBody *otherBody = otherRigidBodyComp ? otherRigidBodyComp->GetRigidBody() : 0;

    if (!ownBody && !rigidBodyComp)
        return;

    else if (!ownBody && rigidBodyComp)
    {
        checkForRigidBodies = true;
        return;
    }

    if (!otherBody && !otherRigidBodyComp)
        otherBody = &btTypedConstraint::getFixedBody();
    else if (!otherBody && otherRigidBodyComp)
    {
        checkForRigidBodies = true;
        return;
    }

    float3 worldScale(1,1,1);
    float3 otherWorldScale(1,1,1);

    EC_Placeable *placeable = ParentEntity()->GetComponent<EC_Placeable>().get();
    EC_Placeable *otherPlaceable = 0;
    if (otherEntity)
        otherPlaceable = otherEntity->GetComponent<EC_Placeable>().get();

    if (placeable)
        worldScale = placeable->WorldScale();
    if (otherPlaceable)
        otherWorldScale = otherPlaceable->WorldScale();

    btTransform ownTransform(FromEulerDegToQuat(getrotation()), getposition().Mul(worldScale));
    btTransform otherTransform(FromEulerDegToQuat(getotherRotation()), getotherPosition().Mul(otherWorldScale));

    switch(gettype())
    {
        case PointToPoint:
            constraint_ = new btPoint2PointConstraint(*ownBody, *otherBody, getposition().Mul(worldScale), getotherPosition().Mul(otherWorldScale));
            break;

        case Hinge:
            constraint_ = new btHingeConstraint(*ownBody, *otherBody, ownTransform, otherTransform);
            break;

        case Slider:
            constraint_ = new btSliderConstraint(*ownBody, *otherBody, ownTransform, otherTransform, false);
            break;

        case ConeTwist:
            constraint_ = new btConeTwistConstraint(*ownBody, *otherBody, ownTransform, otherTransform);
            break;

        default:
            break;
    }

    if (constraint_)
    {
        constraint_->setUserConstraintPtr(this);
        constraint_->setEnabled(getenabled());
        ApplyLimits();

        PhysicsWorld *world = physicsWorld_.lock().get();
        world->BulletWorld()->addConstraint(constraint_, getdisableCollision());
        world->BulletWorld()->debugDrawConstraint(constraint_);
    }
}

void EC_PhysicsConstraint::Remove()
{
    if (constraint_)
    {
        EC_RigidBody *ownRigidComp = rigidBody_.lock().get();
        EC_RigidBody *otherRigidComp = otherRigidBody_.lock().get();
        if (otherRigidComp && otherRigidComp->GetRigidBody())
            otherRigidComp->GetRigidBody()->removeConstraintRef(constraint_);
        if (ownRigidComp && ownRigidComp->GetRigidBody())
            ownRigidComp->GetRigidBody()->removeConstraintRef(constraint_);

        PhysicsWorld *world = physicsWorld_.lock().get();
        if (world && world->BulletWorld())
            world->BulletWorld()->removeConstraint(constraint_);

        rigidBody_.reset();
        otherRigidBody_.reset();
        delete constraint_;
        constraint_ = 0;
    }
}

void EC_PhysicsConstraint::ApplyAttributes()
{
    if (!constraint_)
        return;

    float3 worldScale(1,1,1);
    float3 otherWorldScale(1,1,1);

    EC_Placeable *placeable = ParentEntity()->GetComponent<EC_Placeable>().get();
    Entity *entity = getotherEntity().Lookup(ParentScene()).get();
    EC_Placeable *otherPlaceable = 0;
    if (entity)
        otherPlaceable = entity->GetComponent<EC_Placeable>().get();

    if (placeable)
        worldScale = placeable->WorldScale();
    if (otherPlaceable)
        otherWorldScale = otherPlaceable->WorldScale();

    btTransform ownTransform(FromEulerDegToQuat(getrotation()), getposition().Mul(worldScale));
    btTransform otherTransform(FromEulerDegToQuat(getotherRotation()), getotherPosition().Mul(otherWorldScale));

    switch (constraint_->getConstraintType())
    {
        case POINT2POINT_CONSTRAINT_TYPE:
        {
            btPoint2PointConstraint* pointConstraint = static_cast<btPoint2PointConstraint*>(constraint_);
            pointConstraint->setPivotA(getposition().Mul(worldScale));
            pointConstraint->setPivotB(getotherPosition().Mul(otherWorldScale));
        }
            break;

        case HINGE_CONSTRAINT_TYPE:
        {
            btHingeConstraint* hingeConstraint = static_cast<btHingeConstraint*>(constraint_);
            hingeConstraint->setFrames(ownTransform, otherTransform);
        }
            break;

        case SLIDER_CONSTRAINT_TYPE:
        {
            btSliderConstraint* sliderConstraint = static_cast<btSliderConstraint*>(constraint_);
            sliderConstraint->setFrames(ownTransform, otherTransform);
        }
            break;

        case CONETWIST_CONSTRAINT_TYPE:
        {
            btConeTwistConstraint* coneTwistConstraint = static_cast<btConeTwistConstraint*>(constraint_);
            coneTwistConstraint->setFrames(ownTransform, otherTransform);
        }
            break;

        default:
            break;
    }
}

void EC_PhysicsConstraint::ApplyLimits()
{
    if (!constraint_)
        return;

    switch (constraint_->getConstraintType())
    {
        case HINGE_CONSTRAINT_TYPE:
        {
            btHingeConstraint* hingeConstraint = static_cast<btHingeConstraint*>(constraint_);
            hingeConstraint->setLimit(DegToRad(getangularLimit().x), DegToRad(getangularLimit().y));
        }
            break;

        case SLIDER_CONSTRAINT_TYPE:
        {
            btSliderConstraint* sliderConstraint = static_cast<btSliderConstraint*>(constraint_);

            sliderConstraint->setLowerLinLimit(getlinearLimit().x);
            sliderConstraint->setUpperLinLimit(getlinearLimit().y);

            sliderConstraint->setLowerAngLimit(DegToRad(getangularLimit().x));
            sliderConstraint->setUpperAngLimit(DegToRad(getangularLimit().y));
        }
            break;

        case CONETWIST_CONSTRAINT_TYPE:
        {
            btConeTwistConstraint* coneTwistConstraint = static_cast<btConeTwistConstraint*>(constraint_);
            coneTwistConstraint->setLimit(DegToRad(getangularLimit().y), DegToRad(getangularLimit().y), DegToRad(getlinearLimit().y));
        }
            break;

        default:
            break;
    }
}<|endoftext|>


<commit_before>/*
 * Copyright 2011, 2012 Esrille Inc.
 *
 * 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 <GL/freeglut.h>

#include "WindowImp.h"
#include "Test.util.h"
#include "http/HTTPConnection.h"

using namespace org::w3c::dom::bootstrap;
using namespace org::w3c::dom;

extern html::Window window;

void reshape(int w, int h)
{
    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, w, h, 0, -1000.0, 1.0);

    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->setSize(w, h);
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->render();
    glutSwapBuffers();  // This would block until the sync happens
}

unsigned getCharKeyCode(int key)
{
    // US Qwerty
    static unsigned map[] = {
        0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 12, 13, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 27, 0, 0, 0, 0,
        32, 49 /* ! */, 222 /* " */, 51 /* # */, 52 /* $ */, 53 /* % */, 55 /* & */, 222 /* ' */,
        57 /* ( */, 48 /* ) */, 56 /* * */, 187 /* + */, 188 /* , */, 189 /* - */, 190 /* . */, 191 /* / */,
        48 /* 0 */, 49 /* 1 */, 50 /* 2 */, 51 /* 3 */, 52 /* 4 */, 53 /* 5 */, 54 /* 6 */, 55 /* 7 */,
        56 /* 8 */, 57 /* 9 */, 186 /* : */, 186 /* ; */, 188 /* < */, 187 /* = */, 190 /* > */, 191 /* ? */,
        50 /* @ */, 65 /* A */, 66 /* B */, 67 /* C */, 68 /* D */, 69 /* E */, 70 /* F */, 71 /* G */,
        72 /* H */, 73 /* I */, 74 /* J */, 75 /* K */, 76 /* L */, 77 /* M */, 78 /* N */, 79 /* O */,
        80 /* P */, 81 /* Q */, 82 /* R */, 83 /* S */, 84 /* T */, 85 /* U */, 86 /* V */, 87 /* W */,
        88 /* X */, 89 /* Y */, 90 /* Z */, 219 /* [ */, 220 /* \ */, 221 /* ] */, 54 /* ^ */, 189 /* _ */,
        192 /* ` */, 65 /* a */, 66 /* b */, 67 /* c */, 68 /* d */, 69 /* e */, 70 /* f */, 71 /* g */,
        72 /* h */, 73 /* i */, 74 /* j */, 75 /* k */, 76 /* l */, 77 /* m */, 78 /* n */, 79 /* o */,
        80 /* p */, 81 /* q */, 82 /* r */, 83 /* s */, 84 /* t */, 85 /* u */, 86 /* v */, 87 /* w */,
        88 /* x */, 89 /* y */, 90 /* z */, 219 /* { */, 220 /* | */, 221 /* } */, 192 /* ~ */, 46 /* DEL */
    };
    static_assert(sizeof map /sizeof map[0] == 128, "invalid map");
    return (0 <= key && key <= 127) ? map[key] : 0;
}

void keyboard(unsigned char key, int x, int y)
{
    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->keydown(isprint(key) ? key : 0, getCharKeyCode(key), glutGetModifiers());
}

void keyboardUp(unsigned char key, int x, int y)
{
    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->keyup(isprint(key) ? key : 0, getCharKeyCode(key), glutGetModifiers());
}

unsigned getSpecialKeyCode(int key)
{
    switch (key) {
    case GLUT_KEY_F1:
        return 112;
    case GLUT_KEY_F2:
        return 113;
    case GLUT_KEY_F3:
        return 114;
    case GLUT_KEY_F4:
        return 115;
    case GLUT_KEY_F5:
        return 116;
    case GLUT_KEY_F6:
        return 117;
    case GLUT_KEY_F7:
        return 118;
    case GLUT_KEY_F8:
        return 119;
    case GLUT_KEY_F9:
        return 120;
    case GLUT_KEY_F10:
        return 121;
    case GLUT_KEY_F11:
        return 122;
    case GLUT_KEY_F12:
        return 123;
    case GLUT_KEY_LEFT:
        return 37;
    case GLUT_KEY_UP:
        return 38;
    case GLUT_KEY_RIGHT:
        return 39;
    case GLUT_KEY_DOWN:
        return 40;
    case GLUT_KEY_PAGE_UP:
        return 33;
    case GLUT_KEY_PAGE_DOWN:
        return 34;
    case GLUT_KEY_HOME:
        return 36;
    case GLUT_KEY_END:
        return 35;
    case GLUT_KEY_INSERT:
        return 45;
    case 109:  // Num Lock
        return 144;
    default:
        return 0;
    }
}

void special(int key, int x, int y)
{
    unsigned keycode = getSpecialKeyCode(key);
    if (keycode) {
        if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
            imp->keydown(0, keycode, glutGetModifiers());
    }
}

void specialUp(int key, int x, int y)
{
    unsigned keycode = getSpecialKeyCode(key);
    if (keycode) {
        if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
            imp->keyup(0, keycode, glutGetModifiers());
    }
}

void mouse(int button, int state, int x, int y)
{
    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->mouse(button, state, x, y, glutGetModifiers());
}

void mouseMove(int x, int y)
{
    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->mouseMove(x, y, glutGetModifiers());
}

void timer(int value)
{
    HttpConnectionManager::getInstance().poll();    // TODO: This line should not be necessary.
    if (WindowImp* imp = static_cast<WindowImp*>(window.self())) {
        if (imp->poll())
            glutPostRedisplay();
    }
    glutTimerFunc(50, timer, 0);
    // TODO: do GC here or maybe in the idle proc
}

void init(int* argc, char* argv[])
{
    glutInit(argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
    glutInitWindowSize(816, 1056);
    glutCreateWindow(argv[0]);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glEnable(GL_TEXTURE_2D);
    glDepthFunc(GL_LEQUAL);
    glDisable(GL_CULL_FACE);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_ALPHA_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glutKeyboardFunc(keyboard);
    glutKeyboardUpFunc(keyboardUp);
    glutSpecialFunc(special);
    glutSpecialUpFunc(specialUp);
    glutMouseFunc(mouse);
    glutMotionFunc(mouseMove);
    glutPassiveMotionFunc(mouseMove);
    glutTimerFunc(50, timer, 0);
    glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);

#ifndef NDEBUG
    GLint stencilBits;
    glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
    std::cout << "GL_STENCIL_BITS: " << stencilBits << '\n';
#endif
    // TODO: assuming 8 <= stencilBits for now
    glClearStencil(0x00);
    glEnable(GL_STENCIL_TEST);
}
<commit_msg>(init) : Check GL_STENCIL_BITS.<commit_after>/*
 * Copyright 2011, 2012 Esrille Inc.
 *
 * 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 <GL/freeglut.h>

#include "WindowImp.h"
#include "Test.util.h"
#include "http/HTTPConnection.h"

using namespace org::w3c::dom::bootstrap;
using namespace org::w3c::dom;

extern html::Window window;

void reshape(int w, int h)
{
    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, w, h, 0, -1000.0, 1.0);

    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->setSize(w, h);
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->render();
    glutSwapBuffers();  // This would block until the sync happens
}

unsigned getCharKeyCode(int key)
{
    // US Qwerty
    static unsigned map[] = {
        0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 12, 13, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 27, 0, 0, 0, 0,
        32, 49 /* ! */, 222 /* " */, 51 /* # */, 52 /* $ */, 53 /* % */, 55 /* & */, 222 /* ' */,
        57 /* ( */, 48 /* ) */, 56 /* * */, 187 /* + */, 188 /* , */, 189 /* - */, 190 /* . */, 191 /* / */,
        48 /* 0 */, 49 /* 1 */, 50 /* 2 */, 51 /* 3 */, 52 /* 4 */, 53 /* 5 */, 54 /* 6 */, 55 /* 7 */,
        56 /* 8 */, 57 /* 9 */, 186 /* : */, 186 /* ; */, 188 /* < */, 187 /* = */, 190 /* > */, 191 /* ? */,
        50 /* @ */, 65 /* A */, 66 /* B */, 67 /* C */, 68 /* D */, 69 /* E */, 70 /* F */, 71 /* G */,
        72 /* H */, 73 /* I */, 74 /* J */, 75 /* K */, 76 /* L */, 77 /* M */, 78 /* N */, 79 /* O */,
        80 /* P */, 81 /* Q */, 82 /* R */, 83 /* S */, 84 /* T */, 85 /* U */, 86 /* V */, 87 /* W */,
        88 /* X */, 89 /* Y */, 90 /* Z */, 219 /* [ */, 220 /* \ */, 221 /* ] */, 54 /* ^ */, 189 /* _ */,
        192 /* ` */, 65 /* a */, 66 /* b */, 67 /* c */, 68 /* d */, 69 /* e */, 70 /* f */, 71 /* g */,
        72 /* h */, 73 /* i */, 74 /* j */, 75 /* k */, 76 /* l */, 77 /* m */, 78 /* n */, 79 /* o */,
        80 /* p */, 81 /* q */, 82 /* r */, 83 /* s */, 84 /* t */, 85 /* u */, 86 /* v */, 87 /* w */,
        88 /* x */, 89 /* y */, 90 /* z */, 219 /* { */, 220 /* | */, 221 /* } */, 192 /* ~ */, 46 /* DEL */
    };
    static_assert(sizeof map /sizeof map[0] == 128, "invalid map");
    return (0 <= key && key <= 127) ? map[key] : 0;
}

void keyboard(unsigned char key, int x, int y)
{
    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->keydown(isprint(key) ? key : 0, getCharKeyCode(key), glutGetModifiers());
}

void keyboardUp(unsigned char key, int x, int y)
{
    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->keyup(isprint(key) ? key : 0, getCharKeyCode(key), glutGetModifiers());
}

unsigned getSpecialKeyCode(int key)
{
    switch (key) {
    case GLUT_KEY_F1:
        return 112;
    case GLUT_KEY_F2:
        return 113;
    case GLUT_KEY_F3:
        return 114;
    case GLUT_KEY_F4:
        return 115;
    case GLUT_KEY_F5:
        return 116;
    case GLUT_KEY_F6:
        return 117;
    case GLUT_KEY_F7:
        return 118;
    case GLUT_KEY_F8:
        return 119;
    case GLUT_KEY_F9:
        return 120;
    case GLUT_KEY_F10:
        return 121;
    case GLUT_KEY_F11:
        return 122;
    case GLUT_KEY_F12:
        return 123;
    case GLUT_KEY_LEFT:
        return 37;
    case GLUT_KEY_UP:
        return 38;
    case GLUT_KEY_RIGHT:
        return 39;
    case GLUT_KEY_DOWN:
        return 40;
    case GLUT_KEY_PAGE_UP:
        return 33;
    case GLUT_KEY_PAGE_DOWN:
        return 34;
    case GLUT_KEY_HOME:
        return 36;
    case GLUT_KEY_END:
        return 35;
    case GLUT_KEY_INSERT:
        return 45;
    case 109:  // Num Lock
        return 144;
    default:
        return 0;
    }
}

void special(int key, int x, int y)
{
    unsigned keycode = getSpecialKeyCode(key);
    if (keycode) {
        if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
            imp->keydown(0, keycode, glutGetModifiers());
    }
}

void specialUp(int key, int x, int y)
{
    unsigned keycode = getSpecialKeyCode(key);
    if (keycode) {
        if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
            imp->keyup(0, keycode, glutGetModifiers());
    }
}

void mouse(int button, int state, int x, int y)
{
    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->mouse(button, state, x, y, glutGetModifiers());
}

void mouseMove(int x, int y)
{
    if (WindowImp* imp = static_cast<WindowImp*>(window.self()))
        imp->mouseMove(x, y, glutGetModifiers());
}

void timer(int value)
{
    HttpConnectionManager::getInstance().poll();    // TODO: This line should not be necessary.
    if (WindowImp* imp = static_cast<WindowImp*>(window.self())) {
        if (imp->poll())
            glutPostRedisplay();
    }
    glutTimerFunc(50, timer, 0);
    // TODO: do GC here or maybe in the idle proc
}

void init(int* argc, char* argv[])
{
    glutInit(argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
    glutInitWindowSize(816, 1056);
    glutCreateWindow(argv[0]);
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glEnable(GL_TEXTURE_2D);
    glDepthFunc(GL_LEQUAL);
    glDisable(GL_CULL_FACE);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_ALPHA_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glutKeyboardFunc(keyboard);
    glutKeyboardUpFunc(keyboardUp);
    glutSpecialFunc(special);
    glutSpecialUpFunc(specialUp);
    glutMouseFunc(mouse);
    glutMotionFunc(mouseMove);
    glutPassiveMotionFunc(mouseMove);
    glutTimerFunc(50, timer, 0);
    glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);

    GLint stencilBits;
    glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
    if (stencilBits < 8) {
        std::cout << "error: The number of the OpenGL stencil bits needs to be greater than or equal to 8. Current: " << stencilBits << ".\n";
        exit(EXIT_FAILURE);
    }
    glClearStencil(0x00);
    glEnable(GL_STENCIL_TEST);
}
<|endoftext|>


<commit_before>///
/// @file  nth_prime.cpp
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount.hpp>
#include <primesieve.hpp>
#include <stdint.h>

namespace primecount {

/// Calculate the nth prime using a combination of an efficient prime
/// counting function implementation and the sieve of Eratosthenes.
/// Run time: O(x/(log x)^4) operations, O(x^0.5) space.
///
int64_t nth_prime(int64_t n, int threads)
{
  if (n < 1)
    return 0;

  int64_t prime_approx = 0;
  int64_t count_approx = 0;

  if (n > 100000)
  {
    // Li_inverse(n) < nth_prime(n) for 7 <= n <= ~ 10^316
    prime_approx = Li_inverse(n);
    count_approx = pi(prime_approx, threads);
  }

  primesieve::set_num_threads(threads);
  int64_t prime = primesieve::parallel_nth_prime(n - count_approx, prime_approx);

  return prime;
}

} // namespace primecount
<commit_msg>Port to primesieve-5.2<commit_after>///
/// @file  nth_prime.cpp
///
/// Copyright (C) 2014 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount.hpp>
#include <primesieve.hpp>
#include <stdint.h>

namespace primecount {

/// Calculate the nth prime using a combination of an efficient prime
/// counting function implementation and the sieve of Eratosthenes.
/// Run time: O(x/(log x)^4) operations, O(x^0.5) space.
///
int64_t nth_prime(int64_t n, int threads)
{
  if (n < 0)
    return 0;

  if (n == 0)
    n = 1;

  int64_t prime_approx = 0;
  int64_t count_approx = 0;

  if (n > 100000)
  {
    // Li_inverse(n) < nth_prime(n) for 7 <= n <= ~ 10^316
    prime_approx = Li_inverse(n);
    count_approx = pi(prime_approx, threads);
  }

  primesieve::set_num_threads(threads);
  int64_t prime = primesieve::parallel_nth_prime(n - count_approx, prime_approx);

  return prime;
}

} // namespace primecount
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/python.hpp"

#include <cassert>

#include "maya/MFnDependencyNode.h"

#include "IECore/SceneInterface.h"

#include "IECoreMaya/bindings/FnSceneShapeBinding.h"
#include "IECoreMaya/StatusException.h"
#include "IECoreMaya/SceneShapeInterface.h"

using namespace IECoreMaya;
using namespace boost::python;

static IECore::SceneInterfacePtr sceneInterface( MFnDependencyNode *fnDN )
{
	assert( fnDN );
	MPxNode *userNode = fnDN->userNode();
	SceneShapeInterface *sc = dynamic_cast<SceneShapeInterface *>( userNode );
	assert( sc );
	IECore::ConstSceneInterfacePtr scnInterface = sc->getSceneInterface();
	return const_cast<IECore::SceneInterface*>( scnInterface.get() );
}

static list componentNames( MFnDependencyNode *fnDN )
{
	assert( fnDN );
	MPxNode *userNode = fnDN->userNode();
	SceneShapeInterface *sc = dynamic_cast<SceneShapeInterface *>( userNode );
	assert( sc );
	std::vector<IECore::InternedString> names = sc->componentNames();

	list result;
	for( std::vector<IECore::InternedString>::const_iterator it = names.begin(); it!=names.end(); it++ )
	{
		result.append( (*it).value() );
	}

	return result;
}

void IECoreMaya::bindFnSceneShape()
{

	def( "_sceneShapeSceneInterface", &sceneInterface );
	def( "_sceneShapeComponentNames", &componentNames );

}
<commit_msg>Preventing maya crashes when nodes are not scene shapes in scene shape bindings.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2013, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/python.hpp"

#include <cassert>

#include "maya/MFnDependencyNode.h"

#include "IECore/SceneInterface.h"

#include "IECoreMaya/bindings/FnSceneShapeBinding.h"
#include "IECoreMaya/StatusException.h"
#include "IECoreMaya/SceneShapeInterface.h"

using namespace IECoreMaya;
using namespace boost::python;

static IECore::SceneInterfacePtr sceneInterface( MFnDependencyNode *fnDN )
{
	assert( fnDN );
	MPxNode *userNode = fnDN->userNode();
	SceneShapeInterface *sc = dynamic_cast<SceneShapeInterface *>( userNode );
	if( sc )
	{
		IECore::ConstSceneInterfacePtr scnInterface = sc->getSceneInterface();
		return const_cast<IECore::SceneInterface*>( scnInterface.get() );
	}

	// failed
	throw IECore::Exception( ( MString("Node \"") + fnDN->name() + "\" is not a SceneShape" ).asChar() );
}

static list componentNames( MFnDependencyNode *fnDN )
{
	assert( fnDN );
	MPxNode *userNode = fnDN->userNode();
	SceneShapeInterface *sc = dynamic_cast<SceneShapeInterface *>( userNode );
	if( sc )
	{
		std::vector<IECore::InternedString> names = sc->componentNames();

		list result;
		for( std::vector<IECore::InternedString>::const_iterator it = names.begin(); it!=names.end(); it++ )
		{
			result.append( (*it).value() );
		}

		return result;
	}
	// failed
	throw IECore::Exception( ( MString("Node \"") + fnDN->name() + "\" is not a SceneShape" ).asChar() );
}

void IECoreMaya::bindFnSceneShape()
{

	def( "_sceneShapeSceneInterface", &sceneInterface );
	def( "_sceneShapeComponentNames", &componentNames );

}
<|endoftext|>