<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_COLOR_HPP
#define MAPNIK_COLOR_HPP

// mapnik
#include <mapnik/config.hpp>
#include <mapnik/global.hpp>

//boost
#include <boost/cstdint.hpp>
#include <boost/operators.hpp>

// stl
#include <sstream>

namespace mapnik {

class MAPNIK_DECL color
    : boost::equality_comparable<color>
{
private:
    boost::uint8_t red_;
    boost::uint8_t green_;
    boost::uint8_t blue_;
    boost::uint8_t alpha_;

public:
    color()
      : red_(0xff),
        green_(0xff),
        blue_(0xff),
        alpha_(0xff)
        {}

    color(boost::uint8_t red, boost::uint8_t green, boost::uint8_t blue, boost::uint8_t alpha = 0xff)
      : red_(red),
        green_(green),
        blue_(blue),
        alpha_(alpha)
        {}

    color(const color& rhs)
      : red_(rhs.red_),
        green_(rhs.green_),
        blue_(rhs.blue_),
        alpha_(rhs.alpha_)
        {}

    color( std::string const& str);

    std::string to_string() const;
    std::string to_hex_string() const;
    void premultiply();
    void demultiply();

    color& operator=(color const& rhs)
    {
        if (this==&rhs)
            return *this;

        red_   = rhs.red_;
        green_ = rhs.green_;
        blue_  = rhs.blue_;
        alpha_ = rhs.alpha_;

        return *this;
    }

    inline bool operator==(color const& rhs) const
    {
        return (red_== rhs.red()) &&
               (green_ == rhs.green()) &&
               (blue_  == rhs.blue()) &&
               (alpha_ == rhs.alpha());
    }

    inline boost::uint8_t red() const
    {
        return red_;
    }

    inline boost::uint8_t green() const
    {
        return green_;
    }
    inline boost::uint8_t blue() const
    {
        return blue_;
    }
    inline boost::uint8_t alpha() const
    {
        return alpha_;
    }

    inline void set_red(boost::uint8_t red)
    {
        red_ = red;
    }
    inline void set_green(boost::uint8_t green)
    {
        green_ = green;
    }

    inline void set_blue(boost::uint8_t blue)
    {
        blue_ = blue;
    }
    inline void set_alpha(boost::uint8_t alpha)
    {
        alpha_ = alpha;
    }

    inline unsigned rgba() const
    {
#ifdef MAPNIK_BIG_ENDIAN
        return static_cast<unsigned>((alpha_) | (blue_ << 8) | (green_ << 16) | (red_ << 24)) ;
#else
        return static_cast<unsigned>((alpha_ << 24) | (blue_ << 16) | (green_ << 8) | (red_)) ;
#endif
    }
};

template <typename charT, typename traits>
std::basic_ostream<charT, traits> &
operator << ( std::basic_ostream<charT, traits> & s, mapnik::color const& c )
{
    std::string hex_string( c.to_string() );
    s << hex_string;
    return s;
}

}

#endif // MAPNIK_COLOR_HPP
<commit_msg>mapnik::color operator=<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_COLOR_HPP
#define MAPNIK_COLOR_HPP

// mapnik
#include <mapnik/config.hpp>
#include <mapnik/global.hpp>

//boost
#include <boost/cstdint.hpp>
#include <boost/operators.hpp>

// stl
#include <sstream>

namespace mapnik {

class MAPNIK_DECL color
    : boost::equality_comparable<color>
{
private:
    boost::uint8_t red_;
    boost::uint8_t green_;
    boost::uint8_t blue_;
    boost::uint8_t alpha_;

public:
    color()
      : red_(0xff),
        green_(0xff),
        blue_(0xff),
        alpha_(0xff)
        {}

    color(boost::uint8_t red, boost::uint8_t green, boost::uint8_t blue, boost::uint8_t alpha = 0xff)
      : red_(red),
        green_(green),
        blue_(blue),
        alpha_(alpha)
        {}

    color(const color& rhs)
      : red_(rhs.red_),
        green_(rhs.green_),
        blue_(rhs.blue_),
        alpha_(rhs.alpha_)
        {}

    color( std::string const& str);

    std::string to_string() const;
    std::string to_hex_string() const;
    void premultiply();
    void demultiply();

    color& operator=(color rhs)
    {
        swap(rhs);
        return *this;
    }

    inline bool operator==(color const& rhs) const
    {
        return (red_== rhs.red()) &&
               (green_ == rhs.green()) &&
               (blue_  == rhs.blue()) &&
               (alpha_ == rhs.alpha());
    }

    inline boost::uint8_t red() const
    {
        return red_;
    }

    inline boost::uint8_t green() const
    {
        return green_;
    }
    inline boost::uint8_t blue() const
    {
        return blue_;
    }
    inline boost::uint8_t alpha() const
    {
        return alpha_;
    }

    inline void set_red(boost::uint8_t red)
    {
        red_ = red;
    }
    inline void set_green(boost::uint8_t green)
    {
        green_ = green;
    }

    inline void set_blue(boost::uint8_t blue)
    {
        blue_ = blue;
    }
    inline void set_alpha(boost::uint8_t alpha)
    {
        alpha_ = alpha;
    }

    inline unsigned rgba() const
    {
#ifdef MAPNIK_BIG_ENDIAN
        return static_cast<unsigned>((alpha_) | (blue_ << 8) | (green_ << 16) | (red_ << 24)) ;
#else
        return static_cast<unsigned>((alpha_ << 24) | (blue_ << 16) | (green_ << 8) | (red_)) ;
#endif
    }
private:
    void swap(color & rhs)
    {
        std::swap(red_, rhs.red_);
        std::swap(green_,rhs.green_);
        std::swap(blue_,rhs.blue_);
        std::swap(alpha_,rhs.alpha_);
    }
};

template <typename charT, typename traits>
std::basic_ostream<charT, traits> &
operator << ( std::basic_ostream<charT, traits> & s, mapnik::color const& c )
{
    std::string hex_string( c.to_string() );
    s << hex_string;
    return s;
}

}

#endif // MAPNIK_COLOR_HPP
<|endoftext|>


<commit_before>#include "node.h"
#include <iostream>
#include <thread>
#include <sstream>
#include <mutex>
#include <tuple>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

using namespace DVSim;

Node::Node(const NodeConfig& config) :
	node_name_(config.node_name), port_(config.port)//, should_interrupt_(false)
{
	for (auto& nbor : config.neighbors) {
		NodeName nbor_name;
		Distance nbor_dist;
		std::string nbor_ip;
		std::tie(nbor_name, nbor_dist, nbor_ip) = nbor;

		// Add to neighbor and distance vector tables
		nbors_.insert(std::make_pair(
					nbor_name, std::move(IPAndDist(nbor_ip, nbor_dist))));
		dv_.insert(std::make_pair(
					nbor_name, std::move(DistAndNextHop(nbor_dist, nbor_name))));
	}
}

// Print neighbors table. Need to lock access to tables before printing.
void Node::print_nbors_table()
{
	std::cout << "Neighbor Table" << std::endl;
	std::unique_lock<std::mutex> lg(table_mutex_);
	for (const auto& entry : nbors_) {
		NodeName name;
		std::string ip;
		Distance d;
		IPAndDist id;
		std::tie(name, id) = entry;
		std::tie(ip, d) = id;
		std::cout << name << "\t" << ip << "\t" << d << std::endl;
	}
}

// Print distance vector table. Need to lock access to tables before printing.
void Node::print_dv_table()
{
	std::unique_lock<std::mutex> lg(table_mutex_);
	for (const auto& entry : dv_) {
		NodeName name;
		DistAndNextHop dn;
		Distance d;
		NextHop next_hop;
		std::tie(name, dn) = entry;
		std::tie(d, next_hop) = dn;
		std::cout << name << "\t" << d << "\t" << next_hop << std::endl;
	}
}

// Procedure that spawns a new thread and periodically sends current distance
// vector table to neighbors
void Node::periodic_send(int32_t interval_ms)
{
	std::thread([this, interval_ms]() {
			while (true) {
				std::cout << "periodic send to neighbors" << std::endl;
				this->nbor_broadcast();
				std::this_thread::sleep_for(std::chrono::milliseconds(interval_ms));
			}
		}).detach();
}

// Sends update to neighbor. Note that it must lock the two tables before using
// them
void Node::nbor_broadcast()
{
	// Lock tables before we do anything
	std::unique_lock<std::mutex> lock(table_mutex_);
	std::string msg = create_message();

	std::vector<std::pair<NodeName, std::string>> nbors;
	for (const auto nbor : nbors_) {
		nbors.emplace_back(nbor.first, nbor.second.first);
	}
	// Done with critical section stuff
	lock.unlock();

	// Send messages to neighbors
	for (const auto& pair : nbors) {
		NodeName name;
		std::string ip_addr;
		std::tie(name, ip_addr) = pair;

		std::cout << msg << std::endl;
		send_message(ip_addr, msg);
	}
}

// Send a msg to the specified ip_addr
void Node::send_message(const std::string& ip_addr, const std::string& msg)
{
	// Networking code to set up address/socket
    struct addrinfo hints;
	std::memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
	std::string port_str = std::to_string(port_);

	// Debug
	std::cout << "(" << ip_addr << ", " << port_str << ")" << std::endl;

    struct addrinfo *server_info;
    int err = getaddrinfo(ip_addr.c_str(), port_str.c_str(), &hints, &server_info);
    if (err != 0) {
		std::cerr << "[get_addr_por]: getaddrinfo "
			      << gai_strerror(err) << std::endl;
		return;
    }

    // Loop through to find socket to bind to
	int sock;
    struct addrinfo *p;
    for (p = server_info; p != NULL; p = p->ai_next) {

		// Get a socket
		sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (sock == -1) {
            perror("[get_addr_port]: socket");
            continue;
        }

		// Connect to it
		if (connect(sock, p->ai_addr, p->ai_addrlen) == -1) {
			close(sock);
			perror("[send_message]: connect");
			continue;
		}
        break;
    }

    // Did we bind to a socket?
    if (p == NULL) {
		std::cerr << "[get_addr_port]: could not get socket" << std::endl;
		return;
    }
    freeaddrinfo(server_info);

	// Add msg len to the beginning of the msg (+1 for null terminator)
	uint32_t msg_size = uint32_t(msg.size() + 1);
	uint32_t buf_size = msg_size + uint32_t(sizeof(msg_size));
	auto buf = std::unique_ptr<char>(new char[buf_size]);
	uint32_t net_order_msg_size = htonl(msg_size);
	std::memcpy(buf.get(), &net_order_msg_size, sizeof(net_order_msg_size));
	std::strncpy(buf.get() + sizeof(net_order_msg_size), msg.c_str(), msg_size);

	// Send (and make sure all data gets sent)
	ssize_t send_len = send(sock, buf.get(), buf_size, 0);
	if (send_len == -1) {
		perror("[send_message]: send");
		return;
	}
	while (send_len < buf_size) {
		send_len += send(sock, buf.get() + send_len,
				         buf_size - uint32_t(send_len), 0);
	}
}

// Main entry point to start the algorithm
void Node::start()
{
	// Setup listener
	int32_t listener_sock = set_listen_for_connections();
	if (listener_sock == -1) {
		std::cerr << "[start]: could not listen for connections" << std::endl;
		std::exit(1);
	}

	// Start the periodic send
	std::cout << "Initial routing table" << std::endl;
	print_dv_table();
	std::cout << std::endl;
	periodic_send();

	while (true) {
		// receive_connection() is blocking!
		int32_t newsock = receive_connection(listener_sock);
		if (newsock == -1) {
			std::cerr << "[start]: couldn't receive connection" << std::endl;
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));
			continue;
		}

		// Spawn thread to handle responses
		std::thread([this, newsock]() {
			std::string serialized_msg = this->receive_message(newsock);
			DVMessage msg = deserialize(serialized_msg);
			std::cout << "received message from " << msg.sender << std::endl;
			std::cout << serialized_msg << std::endl;
			if (this->update_dv_table(msg)) {
				this->nbor_broadcast();
			}
		}).detach();
	}
}

int32_t Node::set_listen_for_connections()
{
	// Starting to connect to socket for receiving
	struct addrinfo hints;
	std::memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;
	std::string port_str = std::to_string(port_);
    struct addrinfo *server_info;
    int err = getaddrinfo(nullptr, port_str.c_str(), &hints, &server_info);
    if (err != 0) {
		std::cerr << "[get_addr_por]: getaddrinfo "
			      << gai_strerror(err) << std::endl;
		return -1;
    }

	// Loop through until we find a socket to bind to
	struct addrinfo* p;
	int sock;
	for(p = server_info; p != NULL; p = p->ai_next) {
        if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
            perror("[receive_connection]: socket");
            continue;
        }

		// Fix the "port unavailable" message
		int32_t yes = 1;
        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int32_t)) == -1) {
            perror("[receive_connection]: setsockopt");
			return -1;
        }

		// bind to the socket
        if (bind(sock, p->ai_addr, p->ai_addrlen) == -1) {
            close(sock);
            perror("[receive_connection]: bind");
            continue;
        }
        break;
    }

	freeaddrinfo(server_info);

	// Check if we actually bound to a socket
	if (p == NULL) {
		std::cerr << "[receive_connection]: could not bind to receiver socket"
			      << std::endl;
		return -1;
	}

	// Listen on socket
	if (listen(sock, 10) != 0) {
		perror("[receive_connection]: listen");
		return -1;
	}

	return sock;
}

int32_t Node::receive_connection(int32_t sock)
{
	// Accept connection on that socket
	struct sockaddr_storage their_addr;
	socklen_t sin_size;
	int newsock = accept(sock, (struct sockaddr*) &their_addr, &sin_size);
	if (newsock == -1) {
		perror("[receive_connection]: accept");
		return -1;
	}

	return newsock;
}

// Receive message from node connected through conn
std::string Node::receive_message(int32_t conn)
{
	// Receive first sizeof(int32_t) bytes for message size
	uint32_t msg_size;
	uint32_t bytes_recvd = 0;
	while (bytes_recvd < sizeof(msg_size)) {
		int32_t bytecount = (int32_t) recv(
				conn, (uint32_t *)&msg_size + bytes_recvd, sizeof(msg_size), 0);
		if (bytecount == -1) {
			perror("[receive_message]: recv");
			continue;
		}
		bytes_recvd += uint32_t(bytecount);
	}
	msg_size = ntohl(msg_size);

	// Receive the next msg_size bytes that contain the message
	// XXX Need + 1 for null terminator?
	auto buf = std::unique_ptr<char>(new char[bytes_recvd]);
	bytes_recvd = 0;
	while (bytes_recvd < msg_size) {
		int32_t bytecount = (int32_t) recv(
				conn, buf.get() + bytes_recvd, msg_size, 0);
		if (bytecount == -1) {
			perror("[receive_message]: recv");
			continue;
		}
		bytes_recvd += uint32_t(bytecount);
	}

	// Returns copy of buf
	return std::string(buf.get());
}

bool Node::update_dv_table(const DVMessage& msg)
{
	// Lock access while messing with tables
	std::lock_guard<std::mutex> lg(table_mutex_);
	bool did_update_table = false;

	for (const auto& triplet : msg.entries) {
		NodeName node;
		Distance sender_to_node_dist;
		NextHop node_nh;
		std::tie(node, sender_to_node_dist, node_nh) = triplet;

		// Distance to sender (neighbor)
		if (dv_.find(msg.sender) == std::end(dv_)) {
			std::cerr << "[update_tables]: sender " << msg.sender
				      << " not in dv table" << std::endl;
			continue;
		}
		Distance dist_to_sender = std::get<0>(dv_[msg.sender]);

		// node is not currently in the table - make a new entry
		if (dv_.find(node) == std::end(dv_)) {
			// Distance will be dist to sender + distance provided by sender
			DistAndNextHop dnh =
				DistAndNextHop(dist_to_sender + sender_to_node_dist, msg.sender);
			dv_.insert(std::make_pair(node, std::move(dnh)));
			did_update_table = true;
		}

		// otherwise node is in table - update if necessary
		Distance recv_to_node_dist;
		NextHop recv_to_node_nh;
		std::tie(recv_to_node_dist, recv_to_node_nh) = dv_[node];

		// Only update if dist to sender + sender to node less than what we've
		// already got
		if (dist_to_sender + sender_to_node_dist < recv_to_node_dist) {
			dv_[node].first = dist_to_sender + sender_to_node_dist;
			dv_[node].second = msg.sender;
			did_update_table = true;
		}
	}

	return did_update_table;
}

/*
 * XXX Assumes tables have already been locked
 * Serializes the dv_ table into the expected format:
 * 	   sender_name
 * 	   number_of_destinations
 * 	   dest_1_name dist_1
 * 	   dest_2_name dist_2
 * 	   dest_3_name dist_3
 * 	   dest_4_name dist_4
 * 	   dest_5_name dist_5
 *
 * Puts a \r\n\r\n at the end of the message
 */
std::string Node::create_message()
{
	std::string msg;
	std::stringstream ss(msg);
	ss << node_name_ << std::endl;
	ss << dv_.size() << std::endl;
	for (const auto& dest : dv_) {
		NodeName n;
		DistAndNextHop dnh;
		Distance d;
		NextHop nh;
		std::tie(n, dnh) = dest;
		std::tie(d, nh) = dnh;
		ss << n << " " << d << " " << nh << std::endl;
	}
	return ss.str();
}
<commit_msg>Adding delay after listen to wait for everyone to start listening<commit_after>#include "node.h"
#include <iostream>
#include <thread>
#include <sstream>
#include <mutex>
#include <tuple>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

using namespace DVSim;

Node::Node(const NodeConfig& config) :
	node_name_(config.node_name), port_(config.port)//, should_interrupt_(false)
{
	for (auto& nbor : config.neighbors) {
		NodeName nbor_name;
		Distance nbor_dist;
		std::string nbor_ip;
		std::tie(nbor_name, nbor_dist, nbor_ip) = nbor;

		// Add to neighbor and distance vector tables
		nbors_.insert(std::make_pair(
					nbor_name, std::move(IPAndDist(nbor_ip, nbor_dist))));
		dv_.insert(std::make_pair(
					nbor_name, std::move(DistAndNextHop(nbor_dist, nbor_name))));
	}
}

// Print neighbors table. Need to lock access to tables before printing.
void Node::print_nbors_table()
{
	std::cout << "Neighbor Table" << std::endl;
	std::unique_lock<std::mutex> lg(table_mutex_);
	for (const auto& entry : nbors_) {
		NodeName name;
		std::string ip;
		Distance d;
		IPAndDist id;
		std::tie(name, id) = entry;
		std::tie(ip, d) = id;
		std::cout << name << "\t" << ip << "\t" << d << std::endl;
	}
}

// Print distance vector table. Need to lock access to tables before printing.
void Node::print_dv_table()
{
	std::unique_lock<std::mutex> lg(table_mutex_);
	for (const auto& entry : dv_) {
		NodeName name;
		DistAndNextHop dn;
		Distance d;
		NextHop next_hop;
		std::tie(name, dn) = entry;
		std::tie(d, next_hop) = dn;
		std::cout << name << "\t" << d << "\t" << next_hop << std::endl;
	}
}

// Procedure that spawns a new thread and periodically sends current distance
// vector table to neighbors
void Node::periodic_send(int32_t interval_ms)
{
	std::thread([this, interval_ms]() {
			while (true) {
				std::cout << "periodic send to neighbors" << std::endl;
				this->nbor_broadcast();
				std::this_thread::sleep_for(std::chrono::milliseconds(interval_ms));
			}
		}).detach();
}

// Sends update to neighbor. Note that it must lock the two tables before using
// them
void Node::nbor_broadcast()
{
	// Lock tables before we do anything
	std::unique_lock<std::mutex> lock(table_mutex_);
	std::string msg = create_message();

	std::vector<std::pair<NodeName, std::string>> nbors;
	for (const auto nbor : nbors_) {
		nbors.emplace_back(nbor.first, nbor.second.first);
	}
	// Done with critical section stuff
	lock.unlock();

	// Send messages to neighbors
	for (const auto& pair : nbors) {
		NodeName name;
		std::string ip_addr;
		std::tie(name, ip_addr) = pair;

		std::cout << msg << std::endl;
		send_message(ip_addr, msg);
	}
}

// Send a msg to the specified ip_addr
void Node::send_message(const std::string& ip_addr, const std::string& msg)
{
	// Networking code to set up address/socket
    struct addrinfo hints;
	std::memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
	std::string port_str = std::to_string(port_);
    struct addrinfo *server_info;
    int err = getaddrinfo(ip_addr.c_str(), port_str.c_str(), &hints, &server_info);
    if (err != 0) {
		std::cerr << "[get_addr_por]: getaddrinfo "
			      << gai_strerror(err) << std::endl;
		return;
    }

    // Loop through to find socket to bind to
	int sock;
    struct addrinfo *p;
    for (p = server_info; p != NULL; p = p->ai_next) {

		// Get a socket
		sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
        if (sock == -1) {
            perror("[get_addr_port]: socket");
            continue;
        }

		// Connect to it
		if (connect(sock, p->ai_addr, p->ai_addrlen) == -1) {
			close(sock);
			std::cerr << "[send_message]: connect (" << ip_addr << ")" << std::endl;
			continue;
		}
        break;
    }

    // Did we bind to a socket?
    if (p == NULL) {
		std::cerr << "[get_addr_port]: could not get socket" << std::endl;
		return;
    }
    freeaddrinfo(server_info);

	// Add msg len to the beginning of the msg (+1 for null terminator)
	uint32_t msg_size = uint32_t(msg.size() + 1);
	uint32_t buf_size = msg_size + uint32_t(sizeof(msg_size));
	auto buf = std::unique_ptr<char>(new char[buf_size]);
	uint32_t net_order_msg_size = htonl(msg_size);
	std::memcpy(buf.get(), &net_order_msg_size, sizeof(net_order_msg_size));
	std::strncpy(buf.get() + sizeof(net_order_msg_size), msg.c_str(), msg_size);

	// Send (and make sure all data gets sent)
	ssize_t send_len = send(sock, buf.get(), buf_size, 0);
	if (send_len == -1) {
		perror("[send_message]: send");
		return;
	}
	while (send_len < buf_size) {
		send_len += send(sock, buf.get() + send_len,
				         buf_size - uint32_t(send_len), 0);
	}
}

// Main entry point to start the algorithm
void Node::start()
{
	// Setup listener
	int32_t listener_sock = set_listen_for_connections();
	if (listener_sock == -1) {
		std::cerr << "[start]: could not listen for connections" << std::endl;
		std::exit(1);
	}

	// Start the periodic send
	std::cout << "Initial routing table" << std::endl;
	print_dv_table();
	std::cout << std::endl;

	// Wait for all nodes to start listening before sending messages
	std::this_thread::sleep_for(std::chrono::milliseconds(1000));
	periodic_send();

	while (true) {
		// receive_connection() is blocking!
		int32_t newsock = receive_connection(listener_sock);
		if (newsock == -1) {
			std::cerr << "[start]: couldn't receive connection" << std::endl;
			std::this_thread::sleep_for(std::chrono::milliseconds(1000));
			continue;
		}

		// Spawn thread to handle responses
		std::thread([this, newsock]() {
			std::string serialized_msg = this->receive_message(newsock);
			DVMessage msg = deserialize(serialized_msg);
			std::cout << "received message from " << msg.sender << std::endl;
			std::cout << serialized_msg << std::endl;
			if (this->update_dv_table(msg)) {
				this->nbor_broadcast();
			}
		}).detach();
	}
}

int32_t Node::set_listen_for_connections()
{
	// Starting to connect to socket for receiving
	struct addrinfo hints;
	std::memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;
	std::string port_str = std::to_string(port_);
    struct addrinfo *server_info;
    int err = getaddrinfo(nullptr, port_str.c_str(), &hints, &server_info);
    if (err != 0) {
		std::cerr << "[get_addr_por]: getaddrinfo "
			      << gai_strerror(err) << std::endl;
		return -1;
    }

	// Loop through until we find a socket to bind to
	struct addrinfo* p;
	int sock;
	for(p = server_info; p != NULL; p = p->ai_next) {
        if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
            perror("[receive_connection]: socket");
            continue;
        }

		// Fix the "port unavailable" message
		int32_t yes = 1;
        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int32_t)) == -1) {
            perror("[receive_connection]: setsockopt");
			return -1;
        }

		// bind to the socket
        if (bind(sock, p->ai_addr, p->ai_addrlen) == -1) {
            close(sock);
            perror("[receive_connection]: bind");
            continue;
        }
        break;
    }

	freeaddrinfo(server_info);

	// Check if we actually bound to a socket
	if (p == NULL) {
		std::cerr << "[receive_connection]: could not bind to receiver socket"
			      << std::endl;
		return -1;
	}

	// Listen on socket
	if (listen(sock, 10) != 0) {
		perror("[receive_connection]: listen");
		return -1;
	}

	return sock;
}

int32_t Node::receive_connection(int32_t sock)
{
	// Accept connection on that socket
	struct sockaddr_storage their_addr;
	socklen_t sin_size;
	int newsock = accept(sock, (struct sockaddr*) &their_addr, &sin_size);
	if (newsock == -1) {
		perror("[receive_connection]: accept");
		return -1;
	}

	return newsock;
}

// Receive message from node connected through conn
std::string Node::receive_message(int32_t conn)
{
	// Receive first sizeof(int32_t) bytes for message size
	uint32_t msg_size;
	uint32_t bytes_recvd = 0;
	while (bytes_recvd < sizeof(msg_size)) {
		int32_t bytecount = (int32_t) recv(
				conn, (uint32_t *)&msg_size + bytes_recvd, sizeof(msg_size), 0);
		if (bytecount == -1) {
			perror("[receive_message]: recv");
			continue;
		}
		bytes_recvd += uint32_t(bytecount);
	}
	msg_size = ntohl(msg_size);

	// Receive the next msg_size bytes that contain the message
	// XXX Need + 1 for null terminator?
	auto buf = std::unique_ptr<char>(new char[bytes_recvd]);
	bytes_recvd = 0;
	while (bytes_recvd < msg_size) {
		int32_t bytecount = (int32_t) recv(
				conn, buf.get() + bytes_recvd, msg_size, 0);
		if (bytecount == -1) {
			perror("[receive_message]: recv");
			continue;
		}
		bytes_recvd += uint32_t(bytecount);
	}

	// Returns copy of buf
	return std::string(buf.get());
}

bool Node::update_dv_table(const DVMessage& msg)
{
	// Lock access while messing with tables
	std::lock_guard<std::mutex> lg(table_mutex_);
	bool did_update_table = false;

	for (const auto& triplet : msg.entries) {
		NodeName node;
		Distance sender_to_node_dist;
		NextHop node_nh;
		std::tie(node, sender_to_node_dist, node_nh) = triplet;

		// Distance to sender (neighbor)
		if (dv_.find(msg.sender) == std::end(dv_)) {
			std::cerr << "[update_tables]: sender " << msg.sender
				      << " not in dv table" << std::endl;
			continue;
		}
		Distance dist_to_sender = std::get<0>(dv_[msg.sender]);

		// node is not currently in the table - make a new entry
		if (dv_.find(node) == std::end(dv_)) {
			// Distance will be dist to sender + distance provided by sender
			DistAndNextHop dnh =
				DistAndNextHop(dist_to_sender + sender_to_node_dist, msg.sender);
			dv_.insert(std::make_pair(node, std::move(dnh)));
			did_update_table = true;
		}

		// otherwise node is in table - update if necessary
		Distance recv_to_node_dist;
		NextHop recv_to_node_nh;
		std::tie(recv_to_node_dist, recv_to_node_nh) = dv_[node];

		// Only update if dist to sender + sender to node less than what we've
		// already got
		if (dist_to_sender + sender_to_node_dist < recv_to_node_dist) {
			dv_[node].first = dist_to_sender + sender_to_node_dist;
			dv_[node].second = msg.sender;
			did_update_table = true;
		}
	}

	return did_update_table;
}

/*
 * XXX Assumes tables have already been locked
 * Serializes the dv_ table into the expected format:
 * 	   sender_name
 * 	   number_of_destinations
 * 	   dest_1_name dist_1
 * 	   dest_2_name dist_2
 * 	   dest_3_name dist_3
 * 	   dest_4_name dist_4
 * 	   dest_5_name dist_5
 *
 * Puts a \r\n\r\n at the end of the message
 */
std::string Node::create_message()
{
	std::string msg;
	std::stringstream ss(msg);
	ss << node_name_ << std::endl;
	ss << dv_.size() << std::endl;
	for (const auto& dest : dv_) {
		NodeName n;
		DistAndNextHop dnh;
		Distance d;
		NextHop nh;
		std::tie(n, dnh) = dest;
		std::tie(d, nh) = dnh;
		ss << n << " " << d << " " << nh << std::endl;
	}
	return ss.str();
}
<|endoftext|>


<commit_before>#include "note.h"
#include "textformattingtoolbar.h"
#include "newnotename.h"
#include "textbrowser.h"
#include "textsearchtoolbar.h"
#include "highlighter.h"
#include "textdocument.h"
#include "notedescriptor.h"
#include <QFile>
#include <QPushButton>
#include <QDir>
#include <QToolBar>
#include <QColorDialog>
#include <QSettings>

Note::Note(QString filePath, QWidget *parent) : QMainWindow(parent){

     setupUi(this);
     setAttribute(Qt::WA_DeleteOnClose);

     //notePath = filePath;

     searchbarVisible = false; //initializing

     buttonBox = new QDialogButtonBox(this);
     buttonBox->setStandardButtons(QDialogButtonBox::Reset);
     gridLayout->addWidget(buttonBox, 1, 0, 1, 1);

     textBrowser = new TextBrowser(this);
     textDocument = new TextDocument(this);
     textBrowser->setDocument(textDocument);
     textBrowser->setOpenExternalLinks(true);
     textBrowser->ensureCursorVisible();

     noteDescriptor_ = new NoteDescriptor(filePath,textBrowser, textDocument,this); // must be constructed after TextDocument
     textBrowser->setReadOnly(noteDescriptor_->readOnly());

     gridLayout->addWidget(textBrowser, 0, 0, 1, 1);
     textBrowser->setFocus();

     highlighter = new Highlighter(textBrowser->document());

     alreadyAsked = false;

     toolbar = new TextFormattingToolbar(textBrowser,this);
     toolbar->setFocusPolicy(Qt::TabFocus);
     addToolBar(toolbar);

     addToolBarBreak(Qt::TopToolBarArea);

     searchB = new TextSearchToolbar(textBrowser,this);
     searchB->setFocusPolicy(Qt::TabFocus);
     addToolBar(searchB);

     restoreState(QSettings().value("Toolbars/state").toByteArray());

     searchB->setVisible(false);

     connect(noteDescriptor_,SIGNAL(close()),this,SLOT(close()));
     connect(buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked(bool)),
       this, SLOT(undoAll()));
     connect(textBrowser,SIGNAL(signalFocusInEvent()),this->noteDescriptor_,SLOT(stateChange()));

     connect(searchB->searchLine, SIGNAL(textChanged(QString)), this, SLOT(selectNextExpression()));
     connect(searchB->findNext, SIGNAL(clicked(bool)), SLOT(selectNextExpression()));
     connect(searchB->findPrevious, SIGNAL(clicked(bool)), SLOT(selectPreviousExpression()));
}

Note::~Note(){ /*save_or_not(); */}

void Note::showEvent(QShowEvent* show_Note){
//     load();
     if(searchbarVisible)
       searchB->setVisible(true);

     QMainWindow::showEvent(show_Note);
}

void Note::closeEvent(QCloseEvent* close_Note){
     QSettings().setValue("Toolbars/state", saveState());

      if(textDocument->isModified())
        noteDescriptor_->stateChange();

     QMainWindow::closeEvent(close_Note);
}

void Note::keyPressEvent(QKeyEvent *k){
     if((k->modifiers() == Qt::ControlModifier) && (k->key() == Qt::Key_F)){
       if(textBrowser->textCursor().hasSelection()){
         searchB->searchLine->setText(textBrowser->textCursor().selectedText());
         highlightText(textBrowser->textCursor().selectedText());
       }
       if(!searchB->isVisible())
         searchB->setVisible(true);
         searchB->searchLine->setFocus();
     }
}

void Note::undoAll(){
     while(textBrowser->document()->availableUndoSteps() > 0)
       textBrowser->undo();
}

void Note::selectNextExpression(){
     if(searchB->caseSensitiveBox->isChecked()){
       if(!textBrowser->find(searchB->searchLine->text(), QTextDocument::FindCaseSensitively)){
         textBrowser->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
         textBrowser->find(searchB->searchLine->text(), QTextDocument::FindCaseSensitively);
       }
     }
     else{
       if(!textBrowser->find(searchB->searchLine->text())){
         textBrowser->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
         textBrowser->find(searchB->searchLine->text());
       }
     }
     highlightText(searchB->searchLine->text());
}

void Note::selectPreviousExpression(){
     if(searchB->caseSensitiveBox->isChecked()){
       if(!textBrowser->find(searchB->searchLine->text(), QTextDocument::FindCaseSensitively |
           QTextDocument::FindBackward)){
         textBrowser->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
         textBrowser->find(searchB->searchLine->text(), QTextDocument::FindCaseSensitively |
           QTextDocument::FindBackward);
       }
     }
     else{
       if(!textBrowser->find(searchB->searchLine->text(), QTextDocument::FindBackward)){
         textBrowser->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
         textBrowser->find(searchB->searchLine->text(), QTextDocument::FindBackward);
       }
     }
     highlightText(searchB->searchLine->text());
}

void Note::highlightText(QString str){
     highlighter = new Highlighter(textBrowser->document());
     highlighter->expression = str;
     if(searchB->caseSensitiveBox->isChecked())
       highlighter->caseSensitive = true;
     else
       highlighter->caseSensitive = false;
     connect(searchB->closeSearch, SIGNAL(clicked(bool)), highlighter, SLOT(deleteLater()));
     connect(searchB->closeSearch, SIGNAL(clicked(bool)), textBrowser, SLOT(setFocus()));
     connect(searchB->closeSearch, SIGNAL(clicked(bool)), searchB->searchLine, SLOT(clear()));
}

void Note::setSearchBarText(QString str){ searchB->searchLine->setText(str); }
<commit_msg>making links accessable by mouse<commit_after>#include "note.h"
#include "textformattingtoolbar.h"
#include "newnotename.h"
#include "textbrowser.h"
#include "textsearchtoolbar.h"
#include "highlighter.h"
#include "textdocument.h"
#include "notedescriptor.h"
#include <QFile>
#include <QPushButton>
#include <QDir>
#include <QToolBar>
#include <QColorDialog>
#include <QSettings>

Note::Note(QString filePath, QWidget *parent) : QMainWindow(parent){

     setupUi(this);
     setAttribute(Qt::WA_DeleteOnClose);

     //notePath = filePath;

     searchbarVisible = false; //initializing

     buttonBox = new QDialogButtonBox(this);
     buttonBox->setStandardButtons(QDialogButtonBox::Reset);
     gridLayout->addWidget(buttonBox, 1, 0, 1, 1);

     textBrowser = new TextBrowser(this);
     textDocument = new TextDocument(this);
     textBrowser->setDocument(textDocument);
     textBrowser->setOpenExternalLinks(true);
     textBrowser->ensureCursorVisible();

     noteDescriptor_ = new NoteDescriptor(filePath,textBrowser, textDocument,this); // must be constructed after TextDocument
     textBrowser->setReadOnly(noteDescriptor_->readOnly());
     textBrowser->setTextInteractionFlags(textBrowser->textInteractionFlags()|
                                             Qt::LinksAccessibleByMouse);

     gridLayout->addWidget(textBrowser, 0, 0, 1, 1);
     textBrowser->setFocus();

     highlighter = new Highlighter(textBrowser->document());

     alreadyAsked = false;

     toolbar = new TextFormattingToolbar(textBrowser,this);
     toolbar->setFocusPolicy(Qt::TabFocus);
     addToolBar(toolbar);

     addToolBarBreak(Qt::TopToolBarArea);

     searchB = new TextSearchToolbar(textBrowser,this);
     searchB->setFocusPolicy(Qt::TabFocus);
     addToolBar(searchB);

     restoreState(QSettings().value("Toolbars/state").toByteArray());

     searchB->setVisible(false);

     connect(noteDescriptor_,SIGNAL(close()),this,SLOT(close()));
     connect(buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked(bool)),
       this, SLOT(undoAll()));
     connect(textBrowser,SIGNAL(signalFocusInEvent()),this->noteDescriptor_,SLOT(stateChange()));

     connect(searchB->searchLine, SIGNAL(textChanged(QString)), this, SLOT(selectNextExpression()));
     connect(searchB->findNext, SIGNAL(clicked(bool)), SLOT(selectNextExpression()));
     connect(searchB->findPrevious, SIGNAL(clicked(bool)), SLOT(selectPreviousExpression()));
}

Note::~Note(){ /*save_or_not(); */}

void Note::showEvent(QShowEvent* show_Note){
//     load();
     if(searchbarVisible)
       searchB->setVisible(true);

     QMainWindow::showEvent(show_Note);
}

void Note::closeEvent(QCloseEvent* close_Note){
     QSettings().setValue("Toolbars/state", saveState());

      if(textDocument->isModified())
        noteDescriptor_->stateChange();

     QMainWindow::closeEvent(close_Note);
}

void Note::keyPressEvent(QKeyEvent *k){
     if((k->modifiers() == Qt::ControlModifier) && (k->key() == Qt::Key_F)){
       if(textBrowser->textCursor().hasSelection()){
         searchB->searchLine->setText(textBrowser->textCursor().selectedText());
         highlightText(textBrowser->textCursor().selectedText());
       }
       if(!searchB->isVisible())
         searchB->setVisible(true);
         searchB->searchLine->setFocus();
     }
}

void Note::undoAll(){
     while(textBrowser->document()->availableUndoSteps() > 0)
       textBrowser->undo();
}

void Note::selectNextExpression(){
     if(searchB->caseSensitiveBox->isChecked()){
       if(!textBrowser->find(searchB->searchLine->text(), QTextDocument::FindCaseSensitively)){
         textBrowser->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
         textBrowser->find(searchB->searchLine->text(), QTextDocument::FindCaseSensitively);
       }
     }
     else{
       if(!textBrowser->find(searchB->searchLine->text())){
         textBrowser->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
         textBrowser->find(searchB->searchLine->text());
       }
     }
     highlightText(searchB->searchLine->text());
}

void Note::selectPreviousExpression(){
     if(searchB->caseSensitiveBox->isChecked()){
       if(!textBrowser->find(searchB->searchLine->text(), QTextDocument::FindCaseSensitively |
           QTextDocument::FindBackward)){
         textBrowser->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
         textBrowser->find(searchB->searchLine->text(), QTextDocument::FindCaseSensitively |
           QTextDocument::FindBackward);
       }
     }
     else{
       if(!textBrowser->find(searchB->searchLine->text(), QTextDocument::FindBackward)){
         textBrowser->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
         textBrowser->find(searchB->searchLine->text(), QTextDocument::FindBackward);
       }
     }
     highlightText(searchB->searchLine->text());
}

void Note::highlightText(QString str){
     highlighter = new Highlighter(textBrowser->document());
     highlighter->expression = str;
     if(searchB->caseSensitiveBox->isChecked())
       highlighter->caseSensitive = true;
     else
       highlighter->caseSensitive = false;
     connect(searchB->closeSearch, SIGNAL(clicked(bool)), highlighter, SLOT(deleteLater()));
     connect(searchB->closeSearch, SIGNAL(clicked(bool)), textBrowser, SLOT(setFocus()));
     connect(searchB->closeSearch, SIGNAL(clicked(bool)), searchB->searchLine, SLOT(clear()));
}

void Note::setSearchBarText(QString str){ searchB->searchLine->setText(str); }
<|endoftext|>


<commit_before>/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     Guido Tack <guido.tack@monash.edu>
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef __MINIZINC_TYPE_HH__
#define __MINIZINC_TYPE_HH__

#include <string>
#include <sstream>

namespace MiniZinc {

  /// Type of a MiniZinc expression
  class Type {
  public:
    /// Type-inst
    enum TypeInst { TI_PAR, TI_VAR, TI_SVAR };
    /// Basic type
    enum BaseType { BT_TOP, BT_BOOL, BT_INT, BT_FLOAT, BT_STRING, BT_ANN,
                    BT_BOT, BT_UNKNOWN };
    /// Whether the expression is plain or set
    enum SetType { ST_PLAIN, ST_SET };
    /// Whether the expression is normal or optional
    enum OptType { OT_PRESENT, OT_OPTIONAL };
    /// Whether the par expression contains a var argument
    enum ContainsVarType { CV_NO, CV_YES };
  private:
    unsigned int _ti : 3;
    unsigned int _bt : 4;
    unsigned int _st  : 1;
    unsigned int _ot  : 1;
    unsigned int _cv  : 1;
    /// Number of array dimensions
    int _dim : 19;
  public:
    /// Default constructor
    Type(void) : _ti(TI_PAR), _bt(BT_UNKNOWN), _st(ST_PLAIN),
                 _ot(OT_PRESENT), _cv(CV_NO), _dim(0) {}

    /// Access type-inst
    TypeInst ti(void) const { return static_cast<TypeInst>(_ti); }
    /// Set type-inst
    void ti(const TypeInst& t) {
      _ti = t;
      if (t==TI_VAR)
        _cv=CV_YES;
    }

    /// Access basic type
    BaseType bt(void) const { return static_cast<BaseType>(_bt); }
    /// Set basic type
    void bt(const BaseType& b) { _bt = b; }

    /// Access set type
    SetType st(void) const { return static_cast<SetType>(_st); }
    /// Set set type
    void st(const SetType& s) { _st = s; }

    /// Access opt type
    OptType ot(void) const { return static_cast<OptType>(_ot); }
    /// Set opt type
    void ot(const OptType& o) { _ot = o; }

    /// Access var-in-par type
    bool cv(void) const { return static_cast<ContainsVarType>(_cv) == CV_YES; }
    /// Set var-in-par type
    void cv(bool b) { _cv = b ? CV_YES : CV_NO; }

    /// Access dimensions
    int dim(void) const { return _dim; }
    /// Set dimensions
    void dim(int d) { _dim = d; }

  protected:
    /// Constructor
    Type(const TypeInst& ti, const BaseType& bt, const SetType& st,
         int dim)
      : _ti(ti), _bt(bt), _st(st), _ot(OT_PRESENT), _cv(ti==TI_VAR ? CV_YES : CV_NO), _dim(dim) {}
  public:
    static Type parint(int dim=0) {
      return Type(TI_PAR,BT_INT,ST_PLAIN,dim);
    }
    static Type parbool(int dim=0) {
      return Type(TI_PAR,BT_BOOL,ST_PLAIN,dim);
    }
    static Type parfloat(int dim=0) {
      return Type(TI_PAR,BT_FLOAT,ST_PLAIN,dim);
    }
    static Type parstring(int dim=0) {
      return Type(TI_PAR,BT_STRING,ST_PLAIN,dim);
    }
    static Type ann(int dim=0) {
      return Type(TI_PAR,BT_ANN,ST_PLAIN,dim);
    }
    static Type parsetint(int dim=0) {
      return Type(TI_PAR,BT_INT,ST_SET,dim);
    }
    static Type parsetbool(int dim=0) {
      return Type(TI_PAR,BT_BOOL,ST_SET,dim);
    }
    static Type parsetfloat(int dim=0) {
      return Type(TI_PAR,BT_FLOAT,ST_SET,dim);
    }
    static Type parsetstring(int dim=0) {
      return Type(TI_PAR,BT_STRING,ST_SET,dim);
    }
    static Type varint(int dim=0) {
      return Type(TI_VAR,BT_INT,ST_PLAIN,dim);
    }
    static Type varbool(int dim=0) {
      return Type(TI_VAR,BT_BOOL,ST_PLAIN,dim);
    }
    static Type varfloat(int dim=0) {
      return Type(TI_VAR,BT_FLOAT,ST_PLAIN,dim);
    }
    static Type varsetint(int dim=0) {
      return Type(TI_VAR,BT_INT,ST_SET,dim);
    }
    static Type varbot(int dim=0) {
      return Type(TI_VAR,BT_BOT,ST_PLAIN,dim);
    }
    static Type bot(int dim=0) {
      return Type(TI_PAR,BT_BOT,ST_PLAIN,dim);
    }
    static Type top(int dim=0) {
      return Type(TI_PAR,BT_TOP,ST_PLAIN,dim);
    }
    static Type vartop(int dim=0) {
      return Type(TI_VAR,BT_TOP,ST_PLAIN,dim);
    }
    static Type optvartop(int dim=0) {
      Type t(TI_VAR,BT_TOP,ST_PLAIN,dim);
      t._ot = OT_OPTIONAL;
      return t;
    }

    bool isunknown(void) const { return _bt==BT_UNKNOWN; }
    bool isplain(void) const {
      return _dim==0 && _st==ST_PLAIN && _ot==OT_PRESENT;
    }
    bool isint(void) const { return _dim==0 && _st==ST_PLAIN && _bt==BT_INT; }
    bool isbot(void) const { return _bt==BT_BOT; }
    bool isfloat(void) const { return _dim==0 && _st==ST_PLAIN && _bt==BT_FLOAT; }
    bool isbool(void) const { return _dim==0 && _st==ST_PLAIN && _bt==BT_BOOL; }
    bool isstring(void) const { return isplain() && _bt==BT_STRING; }
    bool isvar(void) const { return _ti!=TI_PAR; }
    bool isvarbool(void) const { return _ti==TI_VAR && _dim==0 && _st==ST_PLAIN && _bt==BT_BOOL && _ot==OT_PRESENT; }
    bool isvarint(void) const { return _ti==TI_VAR && _dim==0 && _st==ST_PLAIN && _bt==BT_INT && _ot==OT_PRESENT; }
    bool issvar(void) const { return _ti==TI_SVAR; }
    bool ispar(void) const { return _ti==TI_PAR; }
    bool isopt(void) const { return _ot==OT_OPTIONAL; }
    bool ispresent(void) const { return _ot==OT_PRESENT; }
    bool isset(void) const { return _dim==0 && _st==ST_SET; }
    bool isintset(void) const {
      return isset() && (_bt==BT_INT || _bt==BT_BOT);
    }
    bool isann(void) const { return isplain() && _bt==BT_ANN; }
    bool isintarray(void) const {
      return _dim==1 && _st==ST_PLAIN && _ot==OT_PRESENT && _bt==BT_INT;
    }
    bool isboolarray(void) const {
      return _dim==1 && _st==ST_PLAIN && _ot==OT_PRESENT && _bt==BT_BOOL;
    }
    bool isintsetarray(void) const {
      return _dim==1 && _st==ST_SET && _bt==BT_INT;
    }

    bool operator== (const Type& t) const {
      return _ti==t._ti && _bt==t._bt && _st==t._st &&
             _ot==t._ot && _dim==t._dim;
    }
    bool operator!= (const Type& t) const {
      return !this->operator==(t);
    }
  // protected:

    int toInt(void) const {
      return
      + ((1-static_cast<int>(_st))<<28)
      + (static_cast<int>(_bt)<<24)
      + (static_cast<int>(_ti)<<21)
      + (static_cast<int>(_ot)<<20)
      + (_dim == -1 ? 1 : (_dim == 0 ? 0 : _dim+1));
    }
    static Type fromInt(int i) {
      Type t;
      t._st = 1-static_cast<SetType>((i >> 28) & 0x1);
      t._bt = static_cast<BaseType>((i >> 24) & 0xF);
      t._ti = static_cast<TypeInst>((i >> 21) & 0x7);
      t._ot = static_cast<OptType>((i >> 20) & 0x1);
      int dim = (i & 0xFFFFF);
      t._dim =  (dim == 0 ? 0 : (dim==1 ? -1 : dim-1));
      return t;
    }
    std::string toString(void) const {
      std::ostringstream oss;
      if (_dim>0) {
        oss<<"array[int";
        for (int i=1; i<_dim; i++)
          oss << ",int";
        oss<<"] of ";
      }
      if (_dim<0)
        oss<<"array[$_] of ";
      switch (_ti) {
        case TI_PAR: break;
        case TI_VAR: oss<<"var "; break;
        case TI_SVAR: oss<<"svar "; break;
      }
      if (_ot==OT_OPTIONAL) oss<<"opt ";
      if (_st==ST_SET) oss<<"set of ";
      switch (_bt) {
        case BT_INT: oss<<"int"; break;
        case BT_BOOL: oss<<"bool"; break;
        case BT_FLOAT: oss<<"float"; break;
        case BT_STRING: oss<<"string"; break;
        case BT_ANN: oss<<"ann"; break;
        case BT_BOT: oss<<"bot"; break;
        case BT_TOP: oss<<"top"; break;
        case BT_UNKNOWN: oss<<"??? "; break;
      }
      return oss.str();
    }
  public:
    /// Check if this type is a subtype of \a t
    bool isSubtypeOf(const Type& t) const {
      if (_dim==0 && t._dim!=0 && _st==ST_SET && t._st==ST_PLAIN &&
          ( bt()==BT_BOT || bt_subtype(bt(), t.bt()) || t.bt()==BT_TOP) && (_ti==t._ti || _ti==TI_PAR || _ti==TI_SVAR) &&
          (_ot==OT_PRESENT || _ot==t._ot) )
        return true;
      // either same dimension or t has variable dimension
      if (_dim!=t._dim && (_dim==0 || t._dim!=-1))
        return false;
      // same type, this is present or both optional
      if (_ti==t._ti && bt_subtype(bt(),t.bt()) && _st==t._st)
        return _ot==OT_PRESENT || _ot==t._ot;
      // this is par or svar, other than that same type as t
      if ((_ti==TI_PAR || _ti==TI_SVAR) && bt_subtype(bt(),t.bt()) && _st==t._st)
        return _ot==OT_PRESENT || _ot==t._ot;
      // t is svar, other than that same type as this
      if (t._ti==TI_SVAR && bt_subtype(bt(),t.bt()) && _st==t._st)
        return _ot==OT_PRESENT || _ot==t._ot;
      if ( (_ti==TI_PAR || _ti==TI_SVAR) && t._bt==BT_BOT)
        return true;
      if ((_ti==t._ti || _ti==TI_PAR || _ti==TI_SVAR) && _bt==BT_BOT && _st==t._st)
        return _ot==OT_PRESENT || _ot==t._ot;
      if (t._bt==BT_TOP && (_ot==OT_PRESENT || _ot==t._ot) &&
          (t._st==ST_PLAIN || _st==t._st) &&
          (_ti==TI_PAR || t._ti==TI_VAR))
        return true;
      return false;
    }

    /// Compare types
    int cmp(const Type& t) const {
      return toInt()<t.toInt() ? -1 : (toInt()>t.toInt() ? 1 : 0);
    }

    /// Check if \a bt0 is a subtype of \a bt1
    static bool bt_subtype(const BaseType& bt0, const BaseType& bt1) {
      if (bt0==bt1)
        return true;
      switch (bt0) {
        case BT_BOOL: return (bt1==BT_INT || bt1==BT_FLOAT);
        case BT_INT: return bt1==BT_FLOAT;
        default: return false;
      }
    }
  };

};

#endif
<commit_msg>Automatic set2array coercion is only available for par sets<commit_after>/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     Guido Tack <guido.tack@monash.edu>
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef __MINIZINC_TYPE_HH__
#define __MINIZINC_TYPE_HH__

#include <string>
#include <sstream>

namespace MiniZinc {

  /// Type of a MiniZinc expression
  class Type {
  public:
    /// Type-inst
    enum TypeInst { TI_PAR, TI_VAR, TI_SVAR };
    /// Basic type
    enum BaseType { BT_TOP, BT_BOOL, BT_INT, BT_FLOAT, BT_STRING, BT_ANN,
                    BT_BOT, BT_UNKNOWN };
    /// Whether the expression is plain or set
    enum SetType { ST_PLAIN, ST_SET };
    /// Whether the expression is normal or optional
    enum OptType { OT_PRESENT, OT_OPTIONAL };
    /// Whether the par expression contains a var argument
    enum ContainsVarType { CV_NO, CV_YES };
  private:
    unsigned int _ti : 3;
    unsigned int _bt : 4;
    unsigned int _st  : 1;
    unsigned int _ot  : 1;
    unsigned int _cv  : 1;
    /// Number of array dimensions
    int _dim : 19;
  public:
    /// Default constructor
    Type(void) : _ti(TI_PAR), _bt(BT_UNKNOWN), _st(ST_PLAIN),
                 _ot(OT_PRESENT), _cv(CV_NO), _dim(0) {}

    /// Access type-inst
    TypeInst ti(void) const { return static_cast<TypeInst>(_ti); }
    /// Set type-inst
    void ti(const TypeInst& t) {
      _ti = t;
      if (t==TI_VAR)
        _cv=CV_YES;
    }

    /// Access basic type
    BaseType bt(void) const { return static_cast<BaseType>(_bt); }
    /// Set basic type
    void bt(const BaseType& b) { _bt = b; }

    /// Access set type
    SetType st(void) const { return static_cast<SetType>(_st); }
    /// Set set type
    void st(const SetType& s) { _st = s; }

    /// Access opt type
    OptType ot(void) const { return static_cast<OptType>(_ot); }
    /// Set opt type
    void ot(const OptType& o) { _ot = o; }

    /// Access var-in-par type
    bool cv(void) const { return static_cast<ContainsVarType>(_cv) == CV_YES; }
    /// Set var-in-par type
    void cv(bool b) { _cv = b ? CV_YES : CV_NO; }

    /// Access dimensions
    int dim(void) const { return _dim; }
    /// Set dimensions
    void dim(int d) { _dim = d; }

  protected:
    /// Constructor
    Type(const TypeInst& ti, const BaseType& bt, const SetType& st,
         int dim)
      : _ti(ti), _bt(bt), _st(st), _ot(OT_PRESENT), _cv(ti==TI_VAR ? CV_YES : CV_NO), _dim(dim) {}
  public:
    static Type parint(int dim=0) {
      return Type(TI_PAR,BT_INT,ST_PLAIN,dim);
    }
    static Type parbool(int dim=0) {
      return Type(TI_PAR,BT_BOOL,ST_PLAIN,dim);
    }
    static Type parfloat(int dim=0) {
      return Type(TI_PAR,BT_FLOAT,ST_PLAIN,dim);
    }
    static Type parstring(int dim=0) {
      return Type(TI_PAR,BT_STRING,ST_PLAIN,dim);
    }
    static Type ann(int dim=0) {
      return Type(TI_PAR,BT_ANN,ST_PLAIN,dim);
    }
    static Type parsetint(int dim=0) {
      return Type(TI_PAR,BT_INT,ST_SET,dim);
    }
    static Type parsetbool(int dim=0) {
      return Type(TI_PAR,BT_BOOL,ST_SET,dim);
    }
    static Type parsetfloat(int dim=0) {
      return Type(TI_PAR,BT_FLOAT,ST_SET,dim);
    }
    static Type parsetstring(int dim=0) {
      return Type(TI_PAR,BT_STRING,ST_SET,dim);
    }
    static Type varint(int dim=0) {
      return Type(TI_VAR,BT_INT,ST_PLAIN,dim);
    }
    static Type varbool(int dim=0) {
      return Type(TI_VAR,BT_BOOL,ST_PLAIN,dim);
    }
    static Type varfloat(int dim=0) {
      return Type(TI_VAR,BT_FLOAT,ST_PLAIN,dim);
    }
    static Type varsetint(int dim=0) {
      return Type(TI_VAR,BT_INT,ST_SET,dim);
    }
    static Type varbot(int dim=0) {
      return Type(TI_VAR,BT_BOT,ST_PLAIN,dim);
    }
    static Type bot(int dim=0) {
      return Type(TI_PAR,BT_BOT,ST_PLAIN,dim);
    }
    static Type top(int dim=0) {
      return Type(TI_PAR,BT_TOP,ST_PLAIN,dim);
    }
    static Type vartop(int dim=0) {
      return Type(TI_VAR,BT_TOP,ST_PLAIN,dim);
    }
    static Type optvartop(int dim=0) {
      Type t(TI_VAR,BT_TOP,ST_PLAIN,dim);
      t._ot = OT_OPTIONAL;
      return t;
    }

    bool isunknown(void) const { return _bt==BT_UNKNOWN; }
    bool isplain(void) const {
      return _dim==0 && _st==ST_PLAIN && _ot==OT_PRESENT;
    }
    bool isint(void) const { return _dim==0 && _st==ST_PLAIN && _bt==BT_INT; }
    bool isbot(void) const { return _bt==BT_BOT; }
    bool isfloat(void) const { return _dim==0 && _st==ST_PLAIN && _bt==BT_FLOAT; }
    bool isbool(void) const { return _dim==0 && _st==ST_PLAIN && _bt==BT_BOOL; }
    bool isstring(void) const { return isplain() && _bt==BT_STRING; }
    bool isvar(void) const { return _ti!=TI_PAR; }
    bool isvarbool(void) const { return _ti==TI_VAR && _dim==0 && _st==ST_PLAIN && _bt==BT_BOOL && _ot==OT_PRESENT; }
    bool isvarint(void) const { return _ti==TI_VAR && _dim==0 && _st==ST_PLAIN && _bt==BT_INT && _ot==OT_PRESENT; }
    bool issvar(void) const { return _ti==TI_SVAR; }
    bool ispar(void) const { return _ti==TI_PAR; }
    bool isopt(void) const { return _ot==OT_OPTIONAL; }
    bool ispresent(void) const { return _ot==OT_PRESENT; }
    bool isset(void) const { return _dim==0 && _st==ST_SET; }
    bool isintset(void) const {
      return isset() && (_bt==BT_INT || _bt==BT_BOT);
    }
    bool isann(void) const { return isplain() && _bt==BT_ANN; }
    bool isintarray(void) const {
      return _dim==1 && _st==ST_PLAIN && _ot==OT_PRESENT && _bt==BT_INT;
    }
    bool isboolarray(void) const {
      return _dim==1 && _st==ST_PLAIN && _ot==OT_PRESENT && _bt==BT_BOOL;
    }
    bool isintsetarray(void) const {
      return _dim==1 && _st==ST_SET && _bt==BT_INT;
    }

    bool operator== (const Type& t) const {
      return _ti==t._ti && _bt==t._bt && _st==t._st &&
             _ot==t._ot && _dim==t._dim;
    }
    bool operator!= (const Type& t) const {
      return !this->operator==(t);
    }
  // protected:

    int toInt(void) const {
      return
      + ((1-static_cast<int>(_st))<<28)
      + (static_cast<int>(_bt)<<24)
      + (static_cast<int>(_ti)<<21)
      + (static_cast<int>(_ot)<<20)
      + (_dim == -1 ? 1 : (_dim == 0 ? 0 : _dim+1));
    }
    static Type fromInt(int i) {
      Type t;
      t._st = 1-static_cast<SetType>((i >> 28) & 0x1);
      t._bt = static_cast<BaseType>((i >> 24) & 0xF);
      t._ti = static_cast<TypeInst>((i >> 21) & 0x7);
      t._ot = static_cast<OptType>((i >> 20) & 0x1);
      int dim = (i & 0xFFFFF);
      t._dim =  (dim == 0 ? 0 : (dim==1 ? -1 : dim-1));
      return t;
    }
    std::string toString(void) const {
      std::ostringstream oss;
      if (_dim>0) {
        oss<<"array[int";
        for (int i=1; i<_dim; i++)
          oss << ",int";
        oss<<"] of ";
      }
      if (_dim<0)
        oss<<"array[$_] of ";
      switch (_ti) {
        case TI_PAR: break;
        case TI_VAR: oss<<"var "; break;
        case TI_SVAR: oss<<"svar "; break;
      }
      if (_ot==OT_OPTIONAL) oss<<"opt ";
      if (_st==ST_SET) oss<<"set of ";
      switch (_bt) {
        case BT_INT: oss<<"int"; break;
        case BT_BOOL: oss<<"bool"; break;
        case BT_FLOAT: oss<<"float"; break;
        case BT_STRING: oss<<"string"; break;
        case BT_ANN: oss<<"ann"; break;
        case BT_BOT: oss<<"bot"; break;
        case BT_TOP: oss<<"top"; break;
        case BT_UNKNOWN: oss<<"??? "; break;
      }
      return oss.str();
    }
  public:
    /// Check if this type is a subtype of \a t
    bool isSubtypeOf(const Type& t) const {
      if (_dim==0 && t._dim!=0 && _st==ST_SET && t._st==ST_PLAIN &&
          ( bt()==BT_BOT || bt_subtype(bt(), t.bt()) || t.bt()==BT_TOP) && (_ti==TI_PAR || _ti==TI_SVAR) &&
          (_ot==OT_PRESENT || _ot==t._ot) )
        return true;
      // either same dimension or t has variable dimension
      if (_dim!=t._dim && (_dim==0 || t._dim!=-1))
        return false;
      // same type, this is present or both optional
      if (_ti==t._ti && bt_subtype(bt(),t.bt()) && _st==t._st)
        return _ot==OT_PRESENT || _ot==t._ot;
      // this is par or svar, other than that same type as t
      if ((_ti==TI_PAR || _ti==TI_SVAR) && bt_subtype(bt(),t.bt()) && _st==t._st)
        return _ot==OT_PRESENT || _ot==t._ot;
      // t is svar, other than that same type as this
      if (t._ti==TI_SVAR && bt_subtype(bt(),t.bt()) && _st==t._st)
        return _ot==OT_PRESENT || _ot==t._ot;
      if ( (_ti==TI_PAR || _ti==TI_SVAR) && t._bt==BT_BOT)
        return true;
      if ((_ti==t._ti || _ti==TI_PAR || _ti==TI_SVAR) && _bt==BT_BOT && _st==t._st)
        return _ot==OT_PRESENT || _ot==t._ot;
      if (t._bt==BT_TOP && (_ot==OT_PRESENT || _ot==t._ot) &&
          (t._st==ST_PLAIN || _st==t._st) &&
          (_ti==TI_PAR || t._ti==TI_VAR))
        return true;
      return false;
    }

    /// Compare types
    int cmp(const Type& t) const {
      return toInt()<t.toInt() ? -1 : (toInt()>t.toInt() ? 1 : 0);
    }

    /// Check if \a bt0 is a subtype of \a bt1
    static bool bt_subtype(const BaseType& bt0, const BaseType& bt1) {
      if (bt0==bt1)
        return true;
      switch (bt0) {
        case BT_BOOL: return (bt1==BT_INT || bt1==BT_FLOAT);
        case BT_INT: return bt1==BT_FLOAT;
        default: return false;
      }
    }
  };

};

#endif
<|endoftext|>


<commit_before>/*
Copyright (C) 2016 - Gbor "Razzie" Grzsny

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
*/

#pragma once

#include <mutex>
#include <vector>

namespace raz
{
	template<class T>
	class CallbackSystem;

	template<class T>
	class Callback
	{
	public:
		typedef T ValueType;
		typedef void(Callback::*Handler)(const T&); // should be a member function of derived class

		template<class Derived>
		Callback(CallbackSystem<T>& system, void(Derived::*handler)(const T&)) :
			m_system(&system),
			m_handler(static_cast<Handler>(handler))
		{
			m_system->bind(this);
		}

		Callback(const Callback& other) :
			m_system(other.m_system),
			m_handler(other.m_handler)
		{
			m_system->bind(this);
		}

		~Callback()
		{
			if (m_system) m_system->unbind(this);
		}

		void handle(const T& t)
		{
			(*this.*m_handler)(t);
		}

	private:
		friend class CallbackSystem<T>;

		CallbackSystem<T>* m_system;
		Handler m_handler;
	};

	template<class T>
	class CallbackSystem
	{
	public:
		CallbackSystem() = default;

		CallbackSystem(const CallbackSystem& other) = delete;

		~CallbackSystem()
		{
			for (auto callback : m_callbacks)
			{
				callback->m_system = nullptr;
			}
		}

		void handle(const T& t) const
		{
			std::lock_guard<decltype(m_lock)> guard(m_lock);
			for (auto callback : m_callbacks)
			{
				callback->handle(t); // adding or deleting a callback here causes a deadlock
			}
		}

	private:
		mutable std::mutex m_lock;
		std::vector<Callback<T>*> m_callbacks;

		friend class Callback<T>;

		void bind(Callback<T>* callback)
		{
			std::lock_guard<decltype(m_lock)> guard(m_lock);
			m_callbacks.push_back(callback);
		}

		void unbind(Callback<T>* callback)
		{
			std::lock_guard<decltype(m_lock)> guard(m_lock);
			for (auto it = m_callbacks.begin(), end = m_callbacks.end(); it != end; ++it)
			{
				if (*it == callback)
				{
					m_callbacks.erase(it);
					return;
				}
			}
		}
	};
}
<commit_msg>Fixed a Callback copy constructor bug<commit_after>/*
Copyright (C) 2016 - Gbor "Razzie" Grzsny

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
*/

#pragma once

#include <mutex>
#include <vector>

namespace raz
{
	template<class T>
	class CallbackSystem;

	template<class T>
	class Callback
	{
	public:
		typedef T ValueType;
		typedef void(Callback::*Handler)(const T&); // should be a member function of derived class

		template<class Derived>
		Callback(CallbackSystem<T>& system, void(Derived::*handler)(const T&)) :
			m_system(&system),
			m_handler(static_cast<Handler>(handler))
		{
			m_system->bind(this);
		}

		Callback(const Callback& other) :
			m_system(other.m_system),
			m_handler(other.m_handler)
		{
			if (m_system) m_system->bind(this);
		}

		~Callback()
		{
			if (m_system) m_system->unbind(this);
		}

		void handle(const T& t)
		{
			(*this.*m_handler)(t);
		}

	private:
		friend class CallbackSystem<T>;

		CallbackSystem<T>* m_system;
		Handler m_handler;
	};

	template<class T>
	class CallbackSystem
	{
	public:
		CallbackSystem() = default;

		CallbackSystem(const CallbackSystem& other) = delete;

		~CallbackSystem()
		{
			for (auto callback : m_callbacks)
			{
				callback->m_system = nullptr;
			}
		}

		void handle(const T& t) const
		{
			std::lock_guard<decltype(m_lock)> guard(m_lock);
			for (auto callback : m_callbacks)
			{
				callback->handle(t); // adding or deleting a callback here causes a deadlock
			}
		}

	private:
		mutable std::mutex m_lock;
		std::vector<Callback<T>*> m_callbacks;

		friend class Callback<T>;

		void bind(Callback<T>* callback)
		{
			std::lock_guard<decltype(m_lock)> guard(m_lock);
			m_callbacks.push_back(callback);
		}

		void unbind(Callback<T>* callback)
		{
			std::lock_guard<decltype(m_lock)> guard(m_lock);
			for (auto it = m_callbacks.begin(), end = m_callbacks.end(); it != end; ++it)
			{
				if (*it == callback)
				{
					m_callbacks.erase(it);
					return;
				}
			}
		}
	};
}
<|endoftext|>


<commit_before><commit_msg>convert include/svx/ucsubset.hxx from String to OUString<commit_after><|endoftext|>


<commit_before>#include "VseApp.hpp"

#include <stdint.h>
#include <iostream>

#include "OgreMath.h"
#include "OgreEntity.h"
#include "SDL.h"

#include "RigidBodySys.hpp"
#include "RigidBodyComp.hpp"
#include "SceneNodeComp.hpp"
#include "LocalPlayerComp.hpp"
#include "LegSpringComp.hpp"
#include "WalkSignal.hpp"
#include "EntSignal.hpp"
#include "LocationSignal.hpp"

#include "Vec3f.hpp"

namespace vse {

void VseApp::onEntityExists(nres::Entity* entity) {}
void VseApp::onEntityDestroyed(nres::Entity* entity) {}

void VseApp::onEntityBroadcast(nres::Entity* entity, const EntSignal* data) {
    switch(data->getType()) {
        case EntSignal::Type::LOCATION: {
            LocationSignal* signal = (LocationSignal*) data;

            mCamLocNode->setPosition(signal->mLocationUpdate);

            break;
        }
        default: {
            break;
        }
    }
}

VseApp& VseApp::getSingleton() {
    static VseApp instance;
    return instance;
}

VseApp::VseApp() {}
VseApp::~VseApp() {}

void VseApp::onAppBegin(Ogre::Root* ogreRoot, Ogre::RenderWindow* ogreWindow, SDL_Window* sdlWindow) {
    mOgreRoot = ogreRoot;
    mOgreWindow = ogreWindow;
    mSdlWindow = sdlWindow;

    SDL_SetRelativeMouseMode(SDL_TRUE);

    mSmgr = mOgreRoot->createSceneManager(Ogre::ST_GENERIC);
    mRootNode = mSmgr->getRootSceneNode();

    mCam = mSmgr->createCamera("Camera");
    mCam->setNearClipDistance(0.1f);

    mCamLocNode = mRootNode->createChildSceneNode("CameraNode");
    mCamYawNode = mCamLocNode->createChildSceneNode();
    mCamPitchNode = mCamYawNode->createChildSceneNode();
    mCamRollNode = mCamPitchNode->createChildSceneNode();
    mCamRollNode->attachObject(mCam);

    mCamPitch = Ogre::Degree(0);
    mCamYaw = Ogre::Degree(0);
    mCamRoll = Ogre::Degree(0);

    mDollyScale = 5.f;
    mDollyMax = 10.f;
    mDollyMin = 0.f;

    mDollyAngle = Ogre::Degree(10);
    mDollyXCoeff = Ogre::Math::Sin(mDollyAngle);
    mDollyZCoeff = Ogre::Math::Cos(mDollyAngle);

    updateCamDolly();

    mCam->setAspectRatio(Ogre::Real(1280) / Ogre::Real(720));

    mSmgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
    mSmgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
    mSmgr->setSkyBox(true, "Test");

    Ogre::Viewport* viewport = ogreWindow->addViewport(mCam);
    viewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

    Ogre::SceneNode* groundNode = mSmgr->getRootSceneNode()->createChildSceneNode();
    Ogre::Entity* groundEnt = mSmgr->createEntity("Ground", "ground.mesh");
    groundNode->attachObject(groundEnt);

    Ogre::Light* light = mSmgr->createLight("Light");
    light->setType(Ogre::Light::LT_DIRECTIONAL);
    light->setDirection(-1, -1, -1);

    mBroadphase = new btDbvtBroadphase();
    mCollisionConfiguration = new btDefaultCollisionConfiguration();
    mDispatcher = new btCollisionDispatcher(mCollisionConfiguration);
    mSolver = new btSequentialImpulseConstraintSolver();
    mDynamicsWorld = new btDiscreteDynamicsWorld(mDispatcher, mBroadphase, mSolver, mCollisionConfiguration);
    mDynamicsWorld->setGravity(btVector3(0, -9.8067, 0));

	btStaticPlaneShape* planeShape = new btStaticPlaneShape(btVector3(0, 1, 0), 0);
	btRigidBody* planeRigid = new btRigidBody(0, 0, planeShape);
	mDynamicsWorld->addRigidBody(planeRigid);

    mRigidBodySys = new RigidBodySys(mDynamicsWorld);
    mWorld.attachSystem(mRigidBodySys);

    mLegSpringSys = new LegSpringSys(mDynamicsWorld);
    mWorld.attachSystem(mLegSpringSys);

    mSceneNodeSys = new SceneNodeSys(mSmgr);
    mWorld.attachSystem(mSceneNodeSys);

    mLocalPlayer = mWorld.newEntity();
    btVector3 size(1, 1, 1);
    mLocalPlayer->add(new RigidBodyComp(new btBoxShape(size)));
    mLocalPlayer->add(new SceneNodeComp("Cube.mesh"));
    mLocalPlayer->add(new LocalPlayerComp());
    mLocalPlayer->add(new LegSpringComp(
        Vec3f(0, 0, 0), // Leg start
        Vec3f(0, -3, 0), // Leg end
        80, // Stiffness
        10, // Damping
        30, // Acceleration
        20 // Deceleration
    ));
    mLocalPlayer->addListener(this);
    mLocalPlayer->publish();

}

void VseApp::onAppEnd() {
    delete mDynamicsWorld;
    delete mSolver;
    delete mDispatcher;
    delete mCollisionConfiguration;
    delete mBroadphase;
}
void VseApp::onTick(float tps) {

    mDynamicsWorld->stepSimulation(tps, 5);
    mRigidBodySys->onTick();
    mLegSpringSys->onTick();

    const Uint8* keyStates = SDL_GetKeyboardState(NULL);

    Vec3f moveVec;
    if(keyStates[SDL_GetScancodeFromKey(SDLK_w)]) {
        moveVec.z = -1;
    }
    if(keyStates[SDL_GetScancodeFromKey(SDLK_a)]) {
        moveVec.x = -1;
    }
    if(keyStates[SDL_GetScancodeFromKey(SDLK_s)]) {
        moveVec.z = 1;
    }
    if(keyStates[SDL_GetScancodeFromKey(SDLK_d)]) {
        moveVec.x = 1;
    }

    if(!moveVec.isZero()) {
        Vec3f transl = mCamYawNode->getOrientation() * mCamPitchNode->getOrientation() * moveVec;
        transl.normalize();
        transl *= 5;
        mLocalPlayer->broadcast(new WalkSignal(transl));
    }

    if(keyStates[SDL_GetScancodeFromKey(SDLK_p)]) {
        //mLocalPlayer->broadcast(new LocalPlayerMoveSignal(Vec3f(0, 100, 0)));
    }
}

void VseApp::onKeyPress(const SDL_KeyboardEvent& event) {
    switch(event.keysym.sym) {
        case SDLK_w: {
            break;
        }
        case SDLK_a: {
            break;
        }
        case SDLK_s: {
            break;
        }
        case SDLK_d: {
            break;
        }
        case SDLK_q: {
            nres::Entity* testCube = mWorld.newEntity();
            testCube->add(new RigidBodyComp(new btSphereShape(1)));
            testCube->add(new SceneNodeComp("Ball.mesh"));
            testCube->publish();
            break;
        }
        default: {
            break;
        }
    }
}
void VseApp::onKeyRelease(const SDL_KeyboardEvent& event) {
}
void VseApp::onMouseMove(const SDL_MouseMotionEvent& event) {

    float dx = -event.xrel;
    float dy = -event.yrel;
    Ogre::Radian dYaw = Ogre::Radian(dx / 200);
    Ogre::Radian dPitch = Ogre::Radian(dy / 200);

    mCamPitch += dPitch;
    mCamYaw += dYaw;

    if(mCamPitch > Ogre::Degree(90)) {
        mCamPitch = Ogre::Degree(90);
    }
    else if(mCamPitch < Ogre::Degree(-90)) {
        mCamPitch = Ogre::Degree(-90);
    }

    updateCamDolly();
}

void VseApp::updateCamDolly() {
    mCamYawNode->resetOrientation();
    mCamYawNode->yaw(mCamYaw);
    mCamPitchNode->resetOrientation();
    mCamPitchNode->pitch(mCamPitch);

    mCamPitchNode->setPosition(mDollyXCoeff * mDollyScale, 0, 0);
    mCamRollNode->setPosition(0, 0, mDollyZCoeff * mDollyScale);
}

void VseApp::onMousePress(const SDL_MouseButtonEvent& event) {
}
void VseApp::onMouseRelease(const SDL_MouseButtonEvent& event) {

}

void VseApp::onMouseWheel(const SDL_MouseWheelEvent& event) {
    float delta = -event.y;
    delta *= 0.5f;

    mDollyScale += delta;

    if(mDollyScale < mDollyMin) {
        mDollyScale = mDollyMin;
    }
    if(mDollyScale > mDollyMax) {
        mDollyScale = mDollyMax;
    }

    updateCamDolly();
}
}

<commit_msg>Enable texture shadows<commit_after>#include "VseApp.hpp"

#include <stdint.h>
#include <iostream>

#include "OgreMath.h"
#include "OgreEntity.h"
#include "OgreSubEntity.h"
#include "SDL.h"

#include "RigidBodySys.hpp"
#include "RigidBodyComp.hpp"
#include "SceneNodeComp.hpp"
#include "LocalPlayerComp.hpp"
#include "LegSpringComp.hpp"
#include "WalkSignal.hpp"
#include "EntSignal.hpp"
#include "LocationSignal.hpp"

#include "Vec3f.hpp"

namespace vse {

void VseApp::onEntityExists(nres::Entity* entity) {}
void VseApp::onEntityDestroyed(nres::Entity* entity) {}

void VseApp::onEntityBroadcast(nres::Entity* entity, const EntSignal* data) {
    switch(data->getType()) {
        case EntSignal::Type::LOCATION: {
            LocationSignal* signal = (LocationSignal*) data;

            mCamLocNode->setPosition(signal->mLocationUpdate);

            break;
        }
        default: {
            break;
        }
    }
}

VseApp& VseApp::getSingleton() {
    static VseApp instance;
    return instance;
}

VseApp::VseApp() {}
VseApp::~VseApp() {}

void VseApp::onAppBegin(Ogre::Root* ogreRoot, Ogre::RenderWindow* ogreWindow, SDL_Window* sdlWindow) {
    mOgreRoot = ogreRoot;
    mOgreWindow = ogreWindow;
    mSdlWindow = sdlWindow;

    SDL_SetRelativeMouseMode(SDL_TRUE);

    mSmgr = mOgreRoot->createSceneManager(Ogre::ST_GENERIC);
    mRootNode = mSmgr->getRootSceneNode();

    mCam = mSmgr->createCamera("Camera");
    mCam->setNearClipDistance(0.1f);

    mCamLocNode = mRootNode->createChildSceneNode("CameraNode");
    mCamYawNode = mCamLocNode->createChildSceneNode();
    mCamPitchNode = mCamYawNode->createChildSceneNode();
    mCamRollNode = mCamPitchNode->createChildSceneNode();
    mCamRollNode->attachObject(mCam);

    mCamPitch = Ogre::Degree(0);
    mCamYaw = Ogre::Degree(0);
    mCamRoll = Ogre::Degree(0);

    mDollyScale = 5.f;
    mDollyMax = 10.f;
    mDollyMin = 0.f;

    mDollyAngle = Ogre::Degree(10);
    mDollyXCoeff = Ogre::Math::Sin(mDollyAngle);
    mDollyZCoeff = Ogre::Math::Cos(mDollyAngle);

    updateCamDolly();

    mCam->setAspectRatio(Ogre::Real(1280) / Ogre::Real(720));

    mSmgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
    mSmgr->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_ADDITIVE);
    mSmgr->setSkyBox(true, "Test");

    Ogre::Viewport* viewport = ogreWindow->addViewport(mCam);
    viewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

    Ogre::SceneNode* groundNode = mSmgr->getRootSceneNode()->createChildSceneNode();
    Ogre::Entity* groundEnt = mSmgr->createEntity("Ground", "ground.mesh");
    //groundEnt->getSubEntity(0)->getMaterial()->setReceiveShadows(true);
    groundEnt->setCastShadows(false);
    groundNode->attachObject(groundEnt);

    Ogre::Light* light = mSmgr->createLight("Light");
    light->setType(Ogre::Light::LT_DIRECTIONAL);
    light->setDirection(-1, -1, -1);

    mBroadphase = new btDbvtBroadphase();
    mCollisionConfiguration = new btDefaultCollisionConfiguration();
    mDispatcher = new btCollisionDispatcher(mCollisionConfiguration);
    mSolver = new btSequentialImpulseConstraintSolver();
    mDynamicsWorld = new btDiscreteDynamicsWorld(mDispatcher, mBroadphase, mSolver, mCollisionConfiguration);
    mDynamicsWorld->setGravity(btVector3(0, -9.8067, 0));

	btStaticPlaneShape* planeShape = new btStaticPlaneShape(btVector3(0, 1, 0), 0);
	btRigidBody* planeRigid = new btRigidBody(0, 0, planeShape);
	mDynamicsWorld->addRigidBody(planeRigid);

    mRigidBodySys = new RigidBodySys(mDynamicsWorld);
    mWorld.attachSystem(mRigidBodySys);

    mLegSpringSys = new LegSpringSys(mDynamicsWorld);
    mWorld.attachSystem(mLegSpringSys);

    mSceneNodeSys = new SceneNodeSys(mSmgr);
    mWorld.attachSystem(mSceneNodeSys);

    mLocalPlayer = mWorld.newEntity();
    btVector3 size(1, 1, 1);
    mLocalPlayer->add(new RigidBodyComp(new btBoxShape(size)));
    mLocalPlayer->add(new SceneNodeComp("Cube.mesh"));
    mLocalPlayer->add(new LocalPlayerComp());
    mLocalPlayer->add(new LegSpringComp(
        Vec3f(0, 0, 0), // Leg start
        Vec3f(0, -3, 0), // Leg end
        80, // Stiffness
        10, // Damping
        30, // Acceleration
        20 // Deceleration
    ));
    mLocalPlayer->addListener(this);
    mLocalPlayer->publish();

}

void VseApp::onAppEnd() {
    delete mDynamicsWorld;
    delete mSolver;
    delete mDispatcher;
    delete mCollisionConfiguration;
    delete mBroadphase;
}
void VseApp::onTick(float tps) {

    mDynamicsWorld->stepSimulation(tps, 5);
    mRigidBodySys->onTick();
    mLegSpringSys->onTick();

    const Uint8* keyStates = SDL_GetKeyboardState(NULL);

    Vec3f moveVec;
    if(keyStates[SDL_GetScancodeFromKey(SDLK_w)]) {
        moveVec.z = -1;
    }
    if(keyStates[SDL_GetScancodeFromKey(SDLK_a)]) {
        moveVec.x = -1;
    }
    if(keyStates[SDL_GetScancodeFromKey(SDLK_s)]) {
        moveVec.z = 1;
    }
    if(keyStates[SDL_GetScancodeFromKey(SDLK_d)]) {
        moveVec.x = 1;
    }

    if(!moveVec.isZero()) {
        Vec3f transl = mCamYawNode->getOrientation() * mCamPitchNode->getOrientation() * moveVec;
        transl.normalize();
        transl *= 5;
        mLocalPlayer->broadcast(new WalkSignal(transl));
    }

    if(keyStates[SDL_GetScancodeFromKey(SDLK_p)]) {
        //mLocalPlayer->broadcast(new LocalPlayerMoveSignal(Vec3f(0, 100, 0)));
    }
}

void VseApp::onKeyPress(const SDL_KeyboardEvent& event) {
    switch(event.keysym.sym) {
        case SDLK_w: {
            break;
        }
        case SDLK_a: {
            break;
        }
        case SDLK_s: {
            break;
        }
        case SDLK_d: {
            break;
        }
        case SDLK_q: {
            nres::Entity* testCube = mWorld.newEntity();
            testCube->add(new RigidBodyComp(new btSphereShape(1)));
            testCube->add(new SceneNodeComp("Ball.mesh"));
            testCube->publish();
            break;
        }
        default: {
            break;
        }
    }
}
void VseApp::onKeyRelease(const SDL_KeyboardEvent& event) {
}
void VseApp::onMouseMove(const SDL_MouseMotionEvent& event) {

    float dx = -event.xrel;
    float dy = -event.yrel;
    Ogre::Radian dYaw = Ogre::Radian(dx / 200);
    Ogre::Radian dPitch = Ogre::Radian(dy / 200);

    mCamPitch += dPitch;
    mCamYaw += dYaw;

    if(mCamPitch > Ogre::Degree(90)) {
        mCamPitch = Ogre::Degree(90);
    }
    else if(mCamPitch < Ogre::Degree(-90)) {
        mCamPitch = Ogre::Degree(-90);
    }

    updateCamDolly();
}

void VseApp::updateCamDolly() {
    mCamYawNode->resetOrientation();
    mCamYawNode->yaw(mCamYaw);
    mCamPitchNode->resetOrientation();
    mCamPitchNode->pitch(mCamPitch);

    mCamPitchNode->setPosition(mDollyXCoeff * mDollyScale, 0, 0);
    mCamRollNode->setPosition(0, 0, mDollyZCoeff * mDollyScale);
}

void VseApp::onMousePress(const SDL_MouseButtonEvent& event) {
}
void VseApp::onMouseRelease(const SDL_MouseButtonEvent& event) {

}

void VseApp::onMouseWheel(const SDL_MouseWheelEvent& event) {
    float delta = -event.y;
    delta *= 0.5f;

    mDollyScale += delta;

    if(mDollyScale < mDollyMin) {
        mDollyScale = mDollyMin;
    }
    if(mDollyScale > mDollyMax) {
        mDollyScale = mDollyMax;
    }

    updateCamDolly();
}
}

<|endoftext|>


<commit_before>/*!
 *  \file File component.cpp
 *  \brief Implementation of Component class
 *
 *  Here is the implementation of Component's methods
 *
 *  \sa component.hpp
 */

#include <component.hpp>
#include <gameObject.hpp>

/*!
  @fn       void Component::own(GameObject *go)
  @brief    Assigns a object as property (like a ownage thing) of a component
  @param    GameObject *go
  @return   void
  @warning  none
*/

void Component::own(GameObject *go) {
    entity = go->uid;
}

/*!
  @fn       bool Component::kills_component(float time)
  @brief    Sets the death of a component
  @param    float time
  @return   boolean value
  @warning  none
*/

bool Component::kills_component(float time) {
    UNUSED(time);

    return true;
}
<commit_msg>[ASSERTS] adds assertions at component.cpp<commit_after>/*!
 *  \file File component.cpp
 *  \brief Implementation of Component class
 *
 *  Here is the implementation of Component's methods
 *
 *  \sa component.hpp
 */

#include <component.hpp>
#include <gameObject.hpp>

/*!
  @fn       void Component::own(GameObject *go)
  @brief    Assigns a object as property (like a ownage thing) of a component
  @param    GameObject *go
  @return   void
  @warning  none
*/

void Component::own(GameObject *go) {
  assert(go != NULL);

  entity = go->uid;
}

/*!
  @fn       bool Component::kills_component(float time)
  @brief    Sets the death of a component
  @param    float time
  @return   boolean value
  @warning  none
*/

bool Component::kills_component(float time) {
    UNUSED(time);

    return true;
}
<|endoftext|>


<commit_before>/*
Copyright libCellML Contributors

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 "libcellml/component.h"

#include <algorithm>
#include <string>
#include <vector>

#include "libcellml/units.h"
#include "libcellml/variable.h"
#include "utilities.h"

namespace libcellml {

/**
 * @brief The Component::ComponentImpl struct.
 *
 * This struct is the private implementation struct for the Component class.  Separating
 * the implementation from the definition allows for greater flexibility when
 * distributing the code.
 */
struct Component::ComponentImpl
{
    std::string mMath;
    std::vector<ResetPtr> mResets;
    std::vector<VariablePtr> mVariables;

    std::vector<ResetPtr>::iterator findReset(const ResetPtr &reset);
    std::vector<VariablePtr>::iterator findVariable(const std::string &name);
    std::vector<VariablePtr>::iterator findVariable(const VariablePtr &variable);
};

std::vector<VariablePtr>::iterator Component::ComponentImpl::findVariable(const std::string &name)
{
    return std::find_if(mVariables.begin(), mVariables.end(),
                        [=](const VariablePtr &v) -> bool { return v->name() == name; });
}

std::vector<VariablePtr>::iterator Component::ComponentImpl::findVariable(const VariablePtr &variable)
{
    return std::find_if(mVariables.begin(), mVariables.end(),
                        [=](const VariablePtr &v) -> bool { return v == variable; });
}

std::vector<ResetPtr>::iterator Component::ComponentImpl::findReset(const ResetPtr &reset)
{
    return std::find_if(mResets.begin(), mResets.end(),
                        [=](const ResetPtr &r) -> bool { return r == reset; });
}

Component::Component()
    : mPimpl(new ComponentImpl())
{
}

Component::Component(const std::string &name)
    : mPimpl(new ComponentImpl())
{
    setName(name);
}

Component::~Component()
{
    if (mPimpl != nullptr) {
        for (const auto &variable : mPimpl->mVariables) {
            variable->removeParent();
        }
    }
    delete mPimpl;
}

bool Component::doAddComponent(const ComponentPtr &component)
{
    bool hasParent = component->hasParent();
    if (hasParent) {
        if (hasAncestor(component)) {
            return false;
        }
        auto parent = component->parent();
        removeComponentFromEntity(parent, component);
    } else if (!hasParent && hasAncestor(component)) {
        return false;
    } else if (shared_from_this() == component) {
        return false;
    }
    component->setParent(shared_from_this());
    return ComponentEntity::doAddComponent(component);
}

void Component::setSourceComponent(const ImportSourcePtr &importSource, const std::string &name)
{
    setImportSource(importSource);
    setImportReference(name);
}

void Component::appendMath(const std::string &math)
{
    mPimpl->mMath.append(math);
}

std::string Component::math() const
{
    return mPimpl->mMath;
}

void Component::setMath(const std::string &math)
{
    mPimpl->mMath = math;
}

void Component::addVariable(const VariablePtr &variable)
{
    mPimpl->mVariables.push_back(variable);
    variable->setParent(shared_from_this());
}

bool Component::removeVariable(size_t index)
{
    if (index < mPimpl->mVariables.size()) {
        mPimpl->mVariables.erase(mPimpl->mVariables.begin() + int64_t(index));
        return true;
    }

    return false;
}

bool Component::removeVariable(const std::string &name)
{
    auto result = mPimpl->findVariable(name);
    if (result != mPimpl->mVariables.end()) {
        mPimpl->mVariables.erase(result);
        return true;
    }

    return false;
}

bool Component::removeVariable(const VariablePtr &variable)
{
    auto result = mPimpl->findVariable(variable);
    if (result != mPimpl->mVariables.end()) {
        mPimpl->mVariables.erase(result);
        variable->clearParent();
        return true;
    }

    return false;
}

void Component::removeAllVariables()
{
    for (const auto &variable : mPimpl->mVariables) {
        variable->clearParent();
    }
    mPimpl->mVariables.clear();
}

VariablePtr Component::variable(size_t index) const
{
    if (index < mPimpl->mVariables.size()) {
        return mPimpl->mVariables.at(index);
    }

    return nullptr;
}

VariablePtr Component::variable(const std::string &name) const
{
    auto result = mPimpl->findVariable(name);
    if (result != mPimpl->mVariables.end()) {
        return *result;
    }

    return nullptr;
}

VariablePtr Component::takeVariable(size_t index)
{
    VariablePtr res = nullptr;
    res = variable(index);
    removeVariable(index);

    return res;
}

VariablePtr Component::takeVariable(const std::string &name)
{
    VariablePtr res = nullptr;
    res = variable(name);
    removeVariable(name);

    return res;
}

size_t Component::variableCount() const
{
    return mPimpl->mVariables.size();
}

bool Component::hasVariable(const VariablePtr &variable) const
{
    return mPimpl->findVariable(variable) != mPimpl->mVariables.end();
}

bool Component::hasVariable(const std::string &name) const
{
    return mPimpl->findVariable(name) != mPimpl->mVariables.end();
}

void Component::addReset(const ResetPtr &reset)
{
    mPimpl->mResets.push_back(reset);
}

bool Component::removeReset(size_t index)
{
    if (index < mPimpl->mResets.size()) {
        mPimpl->mResets.erase(mPimpl->mResets.begin() + int64_t(index));
        return true;
    }

    return false;
}

bool Component::removeReset(const ResetPtr &reset)
{
    auto result = mPimpl->findReset(reset);
    if (result != mPimpl->mResets.end()) {
        mPimpl->mResets.erase(result);
        return true;
    }

    return false;
}

void Component::removeAllResets()
{
    mPimpl->mResets.clear();
}

ResetPtr Component::reset(size_t index) const
{
    if (index < mPimpl->mResets.size()) {
        return mPimpl->mResets.at(index);
    }

    return nullptr;
}

size_t Component::resetCount() const
{
    return mPimpl->mResets.size();
}

bool Component::hasReset(const ResetPtr &reset) const
{
    return mPimpl->findReset(reset) != mPimpl->mResets.end();
}

} // namespace libcellml
<commit_msg>Update to new removeParent API.<commit_after>/*
Copyright libCellML Contributors

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 "libcellml/component.h"

#include <algorithm>
#include <string>
#include <vector>

#include "libcellml/units.h"
#include "libcellml/variable.h"
#include "utilities.h"

namespace libcellml {

/**
 * @brief The Component::ComponentImpl struct.
 *
 * This struct is the private implementation struct for the Component class.  Separating
 * the implementation from the definition allows for greater flexibility when
 * distributing the code.
 */
struct Component::ComponentImpl
{
    std::string mMath;
    std::vector<ResetPtr> mResets;
    std::vector<VariablePtr> mVariables;

    std::vector<ResetPtr>::iterator findReset(const ResetPtr &reset);
    std::vector<VariablePtr>::iterator findVariable(const std::string &name);
    std::vector<VariablePtr>::iterator findVariable(const VariablePtr &variable);
};

std::vector<VariablePtr>::iterator Component::ComponentImpl::findVariable(const std::string &name)
{
    return std::find_if(mVariables.begin(), mVariables.end(),
                        [=](const VariablePtr &v) -> bool { return v->name() == name; });
}

std::vector<VariablePtr>::iterator Component::ComponentImpl::findVariable(const VariablePtr &variable)
{
    return std::find_if(mVariables.begin(), mVariables.end(),
                        [=](const VariablePtr &v) -> bool { return v == variable; });
}

std::vector<ResetPtr>::iterator Component::ComponentImpl::findReset(const ResetPtr &reset)
{
    return std::find_if(mResets.begin(), mResets.end(),
                        [=](const ResetPtr &r) -> bool { return r == reset; });
}

Component::Component()
    : mPimpl(new ComponentImpl())
{
}

Component::Component(const std::string &name)
    : mPimpl(new ComponentImpl())
{
    setName(name);
}

Component::~Component()
{
    if (mPimpl != nullptr) {
        for (const auto &variable : mPimpl->mVariables) {
            variable->removeParent();
        }
    }
    delete mPimpl;
}

bool Component::doAddComponent(const ComponentPtr &component)
{
    bool hasParent = component->hasParent();
    if (hasParent) {
        if (hasAncestor(component)) {
            return false;
        }
        auto parent = component->parent();
        removeComponentFromEntity(parent, component);
    } else if (!hasParent && hasAncestor(component)) {
        return false;
    } else if (shared_from_this() == component) {
        return false;
    }
    component->setParent(shared_from_this());
    return ComponentEntity::doAddComponent(component);
}

void Component::setSourceComponent(const ImportSourcePtr &importSource, const std::string &name)
{
    setImportSource(importSource);
    setImportReference(name);
}

void Component::appendMath(const std::string &math)
{
    mPimpl->mMath.append(math);
}

std::string Component::math() const
{
    return mPimpl->mMath;
}

void Component::setMath(const std::string &math)
{
    mPimpl->mMath = math;
}

void Component::addVariable(const VariablePtr &variable)
{
    mPimpl->mVariables.push_back(variable);
    variable->setParent(shared_from_this());
}

bool Component::removeVariable(size_t index)
{
    if (index < mPimpl->mVariables.size()) {
        mPimpl->mVariables.erase(mPimpl->mVariables.begin() + int64_t(index));
        return true;
    }

    return false;
}

bool Component::removeVariable(const std::string &name)
{
    auto result = mPimpl->findVariable(name);
    if (result != mPimpl->mVariables.end()) {
        mPimpl->mVariables.erase(result);
        return true;
    }

    return false;
}

bool Component::removeVariable(const VariablePtr &variable)
{
    auto result = mPimpl->findVariable(variable);
    if (result != mPimpl->mVariables.end()) {
        mPimpl->mVariables.erase(result);
        variable->removeParent();
        return true;
    }

    return false;
}

void Component::removeAllVariables()
{
    for (const auto &variable : mPimpl->mVariables) {
        variable->removeParent();
    }
    mPimpl->mVariables.clear();
}

VariablePtr Component::variable(size_t index) const
{
    if (index < mPimpl->mVariables.size()) {
        return mPimpl->mVariables.at(index);
    }

    return nullptr;
}

VariablePtr Component::variable(const std::string &name) const
{
    auto result = mPimpl->findVariable(name);
    if (result != mPimpl->mVariables.end()) {
        return *result;
    }

    return nullptr;
}

VariablePtr Component::takeVariable(size_t index)
{
    VariablePtr res = nullptr;
    res = variable(index);
    removeVariable(index);

    return res;
}

VariablePtr Component::takeVariable(const std::string &name)
{
    VariablePtr res = nullptr;
    res = variable(name);
    removeVariable(name);

    return res;
}

size_t Component::variableCount() const
{
    return mPimpl->mVariables.size();
}

bool Component::hasVariable(const VariablePtr &variable) const
{
    return mPimpl->findVariable(variable) != mPimpl->mVariables.end();
}

bool Component::hasVariable(const std::string &name) const
{
    return mPimpl->findVariable(name) != mPimpl->mVariables.end();
}

void Component::addReset(const ResetPtr &reset)
{
    mPimpl->mResets.push_back(reset);
}

bool Component::removeReset(size_t index)
{
    if (index < mPimpl->mResets.size()) {
        mPimpl->mResets.erase(mPimpl->mResets.begin() + int64_t(index));
        return true;
    }

    return false;
}

bool Component::removeReset(const ResetPtr &reset)
{
    auto result = mPimpl->findReset(reset);
    if (result != mPimpl->mResets.end()) {
        mPimpl->mResets.erase(result);
        return true;
    }

    return false;
}

void Component::removeAllResets()
{
    mPimpl->mResets.clear();
}

ResetPtr Component::reset(size_t index) const
{
    if (index < mPimpl->mResets.size()) {
        return mPimpl->mResets.at(index);
    }

    return nullptr;
}

size_t Component::resetCount() const
{
    return mPimpl->mResets.size();
}

bool Component::hasReset(const ResetPtr &reset) const
{
    return mPimpl->findReset(reset) != mPimpl->mResets.end();
}

} // namespace libcellml
<|endoftext|>


<commit_before>#include "player.h"

Player::Player()
{
    energy = 0;
    position = 0;
    bankrupt = false;
    mobile = true;
    character_type = NONE;
}

Player::~Player()
{

}

// Accessor Methods
int Player::getPosition()
{
    return position;
}

bool isMobile()
{
    return mobile;
}

// Methods
void Player::setPosition(int position)
{
    this->position = position;
}

int moveTo(int position)
{

}

bool checkWinStatus()
{

}
<commit_msg>woo hoot<commit_after>#include "player.h"

Player::Player()
{
    energy = 0;
    position = 0;
    bankrupt = false;
    mobile = true;
    character_type = NONE;
}

Player::~Player()
{

}

// Accessor Methods
int Player::getPosition()
{
    return position;
}

bool isMobile()
{
    return mobile;
}

// Methods
void Player::setPosition(int position)
{
    this->position = position;
}

int moveTo(int position)
{

}

bool checkWinStatus()
{
	return true;
}
<|endoftext|>