<commit_before>/**
 * Copyright (c) Sjors Gielen, 2010-2012
 * See LICENSE for license.
 */

#include "network.h"
#include "server.h"
#include "utils.h"
#include <stdio.h>

std::string Network::toString(const Network *n)
{
	std::stringstream res;
	res << "Network[";
	if(n  == 0) {
		res << "0";
	} else {
		const NetworkConfig *nc = n->config();
		res << nc->displayName << ":" << Server::toString(n->activeServer());
	}
	res << "]";

	return res.str();
}

/**
 * @brief Constructor.
 */
Network::Network( const NetworkConfig *c )
: activeServer_(0)
, config_(c)
, undesirables_()
, deleteServer_(false)
, identifiedUsers_()
, knownUsers_()
, topics_()
, networkListeners_()
, nick_(c->nickName)
{}

/**
 * @brief Destructor.
 */
Network::~Network()
{
	disconnectFromNetwork();
}

/**
 * Returns the active server in this network, or 0 if there is none.
 */
Server *Network::activeServer() const
{
	return activeServer_;
}

/**
 * @brief Whether this network is marked for autoconnection.
 */
bool Network::autoConnectEnabled() const
{
	return config_->autoConnect;
}

void Network::action( std::string destination, std::string message )
{
	if( !activeServer_ )
		return;
	activeServer_->ctcpAction( destination, message );
}

void Network::names( std::string channel )
{
	if( !activeServer_ )
		return;
	activeServer_->names( channel );
}

std::vector<std::string> Network::joinedChannels() const
{
	std::vector<std::string> res;
	std::map<std::string,std::vector<std::string> >::const_iterator it;
	for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
		res.push_back(it->first);
	}
	return res;
}

std::map<std::string,std::string> Network::topics() const
{
	return topics_;
}

std::map<std::string,Network::ChannelMode> Network::usersInChannel(std::string channel) const
{
	std::map<std::string, ChannelMode> res;
	std::map<std::string, std::vector<std::string> >::const_iterator it;
	for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
		if(it->first != channel)
			continue;
		std::vector<std::string> users = it->second;
		std::vector<std::string>::const_iterator it2;
		for(it2 = users.begin(); it2 != users.end(); ++it2) {
			// TODO: remember the mode
			res[*it2] = Network::UserMode;
		}
	}
	return res;
}

/**
 * @brief Chooses one server or the other based on the priority and failure
 *        rate.
 * Failure rate is recorded in the Network object that the ServerConfig object
 * links to via the NetworkConfig, if there is such a NetworkConfig object.
 * You must give two servers of the same Network.
 */
struct ServerSorter {
	private:
	Network *n_;

	public:
	ServerSorter(Network *n) : n_(n) {}
	bool operator()(const ServerConfig *c1, const ServerConfig *c2) {
		assert(c1->network == c2->network);
		assert(c1->network == n_->config());

		int prio1 = c1->priority - n_->serverUndesirability(c1);
		int prio2 = c2->priority - n_->serverUndesirability(c2);

		if( prio1 == prio2 ) // choose randomly
			return (rand() % 2) == 0 ? -1 : 1;
		return prio1 < prio2;
	}
};

const NetworkConfig *Network::config() const
{
	return config_;
}

void Network::connectToNetwork( bool reconnect )
{
	if( !reconnect && activeServer_ )
		return;

	printf("Connecting to network: %s\n", Network::toString(this).c_str());

	// Check if there *is* a server to use
	if( servers().size() == 0 )
	{
		printf("Trying to connect to network '%s', but there are no servers to connect to!\n",
		config_->displayName.c_str());
		return;
	}

	// Find the best server to use

	// First, sort the list by priority and earlier failures
	std::vector<ServerConfig*> sortedServers = servers();
	std::sort( sortedServers.begin(), sortedServers.end(), ServerSorter(this) );

	// Then, take the first one and create a Server around it
	ServerConfig *best = sortedServers[0];

	// And set it as the active server, and connect.
	connectToServer( best, true );
}

void Network::connectToServer( ServerConfig *server, bool reconnect )
{
	if( !reconnect && activeServer_ )
		return;
	assert(knownUsers_.size() == 0);
	assert(identifiedUsers_.size() == 0);

	if( activeServer_ )
	{
		activeServer_->disconnectFromServer( SwitchingServersReason );
		// TODO: maybe deleteLater?
		delete(activeServer_);
	}

	activeServer_ = new Server( server, this );
	activeServer_->connectToServer();
}

void Network::joinedChannel(const std::string &user, const std::string &receiver)
{
	if(user == nick_ && !contains(knownUsers_, strToLower(receiver))) {
		knownUsers_[strToLower(receiver)] = std::vector<std::string>();
	}
	std::vector<std::string> users = knownUsers_[strToLower(receiver)];
	if(!contains(users, strToLower(user)))
		knownUsers_[strToLower(receiver)].push_back(strToLower(user));
}

void Network::partedChannel(const std::string &user, const std::string &, const std::string &receiver)
{
	if(user == nick_) {
		knownUsers_.erase(strToLower(receiver));
	} else {
		erase(knownUsers_[strToLower(receiver)], strToLower(user));
	}
	if(!isKnownUser(user)) {
		erase(identifiedUsers_, strToLower(user));
	}
}

void Network::slotQuit(const std::string &origin, const std::string&, const std::string &)
{
	std::map<std::string,std::vector<std::string> >::iterator it;
	for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
		erase(it->second, strToLower(origin));
	}
	if(!isKnownUser(origin)) {
		erase(identifiedUsers_, strToLower(origin));
	}
}

void Network::slotNickChanged( const std::string &origin, const std::string &nick, const std::string & )
{
	erase(identifiedUsers_, strToLower(origin));
	erase(identifiedUsers_, strToLower(nick));

	if(nick_ == origin)
		nick_ = nick;

	std::map<std::string,std::vector<std::string> >::iterator it;
	for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
		if(contains(it->second, strToLower(origin))) {
			erase(it->second, strToLower(origin));
			it->second.push_back(strToLower(nick));
		}
	}
}

void Network::kickedChannel(const std::string&, const std::string &user, const std::string&, const std::string &receiver)
{
	if(user == nick_) {
		knownUsers_.erase(strToLower(receiver));
	} else {
		erase(knownUsers_[strToLower(receiver)], strToLower(user));
	}
	if(!isKnownUser(user)) {
		erase(identifiedUsers_, strToLower(user));
	}
}

void Network::onFailedConnection()
{
	fprintf(stderr, "Connection failed on %s\n", Network::toString(this).c_str());

	identifiedUsers_.clear();
	knownUsers_.clear();

	slotIrcEvent("DISCONNECT", "", std::vector<std::string>());

	// Flag old server as undesirable
	// Don't destroy it here yet; it is still in the stack. It will be destroyed
	// in processDescriptors().
	flagUndesirableServer( activeServer_->config() );
	deleteServer_ = true;
}

void Network::ctcp( std::string destination, std::string message )
{
	if( !activeServer_ )
		return;
	activeServer_->ctcpAction( destination, message );
}

/**
 * @brief Disconnect from the network.
 */
void Network::disconnectFromNetwork( DisconnectReason reason )
{
	if( activeServer_ == 0 )
		return;

	identifiedUsers_.clear();
	knownUsers_.clear();

	activeServer_->disconnectFromServer( reason );
	// TODO: maybe deleteLater?
	delete activeServer_;
	activeServer_ = 0;
}

void Network::joinChannel( std::string channel )
{
	if( !activeServer_ )
		return;
	activeServer_->join( channel );
}

void Network::leaveChannel( std::string channel )
{
	if( !activeServer_ )
		return;
	activeServer_->part( channel );
}

void Network::say( std::string destination, std::string message )
{
	if( !activeServer_ )
		return;
	activeServer_->message( destination, message );
}

void Network::sendWhois( std::string destination )
{
	activeServer_->whois(destination);
}

const std::vector<ServerConfig*> &Network::servers() const
{
	return config_->servers;
}

std::string Network::nick() const
{
	return nick_;
}

std::string Network::networkName() const
{
	return config()->name;
}

int Network::serverUndesirability( const ServerConfig *sc ) const
{
	return contains(undesirables_, sc) ? undesirables_.find(sc)->second : 0;
}

void Network::flagUndesirableServer( const ServerConfig *sc )
{
	if(contains(undesirables_, sc))
		undesirables_[sc] = undesirables_[sc] + 1;
	undesirables_[sc] = 1;
}

void Network::serverIsActuallyOkay( const ServerConfig *sc )
{
	undesirables_.erase(sc);
}

bool Network::isIdentified(const std::string &user) const {
	return contains(identifiedUsers_, strToLower(user));
}

bool Network::isKnownUser(const std::string &user) const {
	std::map<std::string,std::vector<std::string> >::const_iterator it;
	for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
		if(contains(it->second, strToLower(user))) {
			return true;
		}
	}
	return false;
}

void Network::slotWhoisReceived(const std::string &, const std::string &nick, bool identified) {
	if(!identified) {
		erase(identifiedUsers_, strToLower(nick));
	} else if(identified && !contains(identifiedUsers_, strToLower(nick)) && isKnownUser(nick)) {
		identifiedUsers_.push_back(strToLower(nick));
	}
}

void Network::slotNamesReceived(const std::string&, const std::string &channel, const std::vector<std::string> &names, const std::string & ) {
	assert(contains(knownUsers_, strToLower(channel)));
	std::vector<std::string> &users = knownUsers_[strToLower(channel)];
	std::vector<std::string>::const_iterator it;
	for(it = names.begin(); it != names.end(); ++it) {
		std::string n = *it;
		unsigned int nickStart;
		for(nickStart = 0; nickStart < n.length(); ++nickStart) {
			if(n[nickStart] != '@' && n[nickStart] != '~' && n[nickStart] != '+'
			&& n[nickStart] != '%' && n[nickStart] != '!') {
				break;
			}
		}
		n = n.substr(nickStart);
		if(!contains(users, strToLower(n)))
			users.push_back(strToLower(n));
	}
}

void Network::slotTopicChanged(const std::string&, const std::string &channel, const std::string &topic) {
	topics_[channel] = topic;
}

void Network::slotIrcEvent(const std::string &event, const std::string &origin, const std::vector<std::string> &params) {
	std::string receiver;
	if(params.size() > 0)
		receiver = params[0];

#define MIN(a) if(params.size() < a) { fprintf(stderr, "Too few parameters for event %s\n", event.c_str()); return; }
	if(event == "CONNECT") {
		serverIsActuallyOkay(activeServer_->config());
	} else if(event == "JOIN") {
		MIN(1);
		joinedChannel(origin, receiver);
	} else if(event == "PART") {
		MIN(1);
		partedChannel(origin, std::string(), receiver);
	} else if(event == "KICK") {
		MIN(2);
		kickedChannel(origin, params[1], std::string(), receiver);
	} else if(event == "QUIT") {
		std::string message;
		if(params.size() > 0) {
			message = params[0];
		}
		slotQuit(origin, message, receiver);
	} else if(event == "NICK") {
		MIN(1);
		slotNickChanged(origin, params[0], receiver);
	} else if(event == "TOPIC") {
		MIN(2);
		slotTopicChanged(origin, params[0], params[1]);
	}
#undef MIN
	std::vector<NetworkListener*>::iterator nlit;
	for(nlit = networkListeners_.begin(); nlit != networkListeners_.end();
	    nlit++) {
		(*nlit)->ircEvent(event, origin, params, this);
	}
}

void Network::addDescriptors(fd_set *in_set, fd_set *out_set, int *maxfd) {
	activeServer_->addDescriptors(in_set, out_set, maxfd);
}

void Network::processDescriptors(fd_set *in_set, fd_set *out_set) {
	deleteServer_ = false;
	activeServer_->processDescriptors(in_set, out_set);
	if(deleteServer_) {
		delete activeServer_;
		activeServer_ = 0;
		connectToNetwork();
	}
}
<commit_msg>Nicer stringify for Network<commit_after>/**
 * Copyright (c) Sjors Gielen, 2010-2012
 * See LICENSE for license.
 */

#include "network.h"
#include "server.h"
#include "utils.h"
#include <stdio.h>

std::string Network::toString(const Network *n)
{
	std::stringstream res;
	res << "Network[";
	if(n  == 0) {
		res << "0";
	} else {
		const NetworkConfig *nc = n->config();
		res << nc->displayName << ", " << Server::toString(n->activeServer());
	}
	res << "]";

	return res.str();
}

/**
 * @brief Constructor.
 */
Network::Network( const NetworkConfig *c )
: activeServer_(0)
, config_(c)
, undesirables_()
, deleteServer_(false)
, identifiedUsers_()
, knownUsers_()
, topics_()
, networkListeners_()
, nick_(c->nickName)
{}

/**
 * @brief Destructor.
 */
Network::~Network()
{
	disconnectFromNetwork();
}

/**
 * Returns the active server in this network, or 0 if there is none.
 */
Server *Network::activeServer() const
{
	return activeServer_;
}

/**
 * @brief Whether this network is marked for autoconnection.
 */
bool Network::autoConnectEnabled() const
{
	return config_->autoConnect;
}

void Network::action( std::string destination, std::string message )
{
	if( !activeServer_ )
		return;
	activeServer_->ctcpAction( destination, message );
}

void Network::names( std::string channel )
{
	if( !activeServer_ )
		return;
	activeServer_->names( channel );
}

std::vector<std::string> Network::joinedChannels() const
{
	std::vector<std::string> res;
	std::map<std::string,std::vector<std::string> >::const_iterator it;
	for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
		res.push_back(it->first);
	}
	return res;
}

std::map<std::string,std::string> Network::topics() const
{
	return topics_;
}

std::map<std::string,Network::ChannelMode> Network::usersInChannel(std::string channel) const
{
	std::map<std::string, ChannelMode> res;
	std::map<std::string, std::vector<std::string> >::const_iterator it;
	for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
		if(it->first != channel)
			continue;
		std::vector<std::string> users = it->second;
		std::vector<std::string>::const_iterator it2;
		for(it2 = users.begin(); it2 != users.end(); ++it2) {
			// TODO: remember the mode
			res[*it2] = Network::UserMode;
		}
	}
	return res;
}

/**
 * @brief Chooses one server or the other based on the priority and failure
 *        rate.
 * Failure rate is recorded in the Network object that the ServerConfig object
 * links to via the NetworkConfig, if there is such a NetworkConfig object.
 * You must give two servers of the same Network.
 */
struct ServerSorter {
	private:
	Network *n_;

	public:
	ServerSorter(Network *n) : n_(n) {}
	bool operator()(const ServerConfig *c1, const ServerConfig *c2) {
		assert(c1->network == c2->network);
		assert(c1->network == n_->config());

		int prio1 = c1->priority - n_->serverUndesirability(c1);
		int prio2 = c2->priority - n_->serverUndesirability(c2);

		if( prio1 == prio2 ) // choose randomly
			return (rand() % 2) == 0 ? -1 : 1;
		return prio1 < prio2;
	}
};

const NetworkConfig *Network::config() const
{
	return config_;
}

void Network::connectToNetwork( bool reconnect )
{
	if( !reconnect && activeServer_ )
		return;

	printf("Connecting to network: %s\n", Network::toString(this).c_str());

	// Check if there *is* a server to use
	if( servers().size() == 0 )
	{
		printf("Trying to connect to network '%s', but there are no servers to connect to!\n",
		config_->displayName.c_str());
		return;
	}

	// Find the best server to use

	// First, sort the list by priority and earlier failures
	std::vector<ServerConfig*> sortedServers = servers();
	std::sort( sortedServers.begin(), sortedServers.end(), ServerSorter(this) );

	// Then, take the first one and create a Server around it
	ServerConfig *best = sortedServers[0];

	// And set it as the active server, and connect.
	connectToServer( best, true );
}

void Network::connectToServer( ServerConfig *server, bool reconnect )
{
	if( !reconnect && activeServer_ )
		return;
	assert(knownUsers_.size() == 0);
	assert(identifiedUsers_.size() == 0);

	if( activeServer_ )
	{
		activeServer_->disconnectFromServer( SwitchingServersReason );
		// TODO: maybe deleteLater?
		delete(activeServer_);
	}

	activeServer_ = new Server( server, this );
	activeServer_->connectToServer();
}

void Network::joinedChannel(const std::string &user, const std::string &receiver)
{
	if(user == nick_ && !contains(knownUsers_, strToLower(receiver))) {
		knownUsers_[strToLower(receiver)] = std::vector<std::string>();
	}
	std::vector<std::string> users = knownUsers_[strToLower(receiver)];
	if(!contains(users, strToLower(user)))
		knownUsers_[strToLower(receiver)].push_back(strToLower(user));
}

void Network::partedChannel(const std::string &user, const std::string &, const std::string &receiver)
{
	if(user == nick_) {
		knownUsers_.erase(strToLower(receiver));
	} else {
		erase(knownUsers_[strToLower(receiver)], strToLower(user));
	}
	if(!isKnownUser(user)) {
		erase(identifiedUsers_, strToLower(user));
	}
}

void Network::slotQuit(const std::string &origin, const std::string&, const std::string &)
{
	std::map<std::string,std::vector<std::string> >::iterator it;
	for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
		erase(it->second, strToLower(origin));
	}
	if(!isKnownUser(origin)) {
		erase(identifiedUsers_, strToLower(origin));
	}
}

void Network::slotNickChanged( const std::string &origin, const std::string &nick, const std::string & )
{
	erase(identifiedUsers_, strToLower(origin));
	erase(identifiedUsers_, strToLower(nick));

	if(nick_ == origin)
		nick_ = nick;

	std::map<std::string,std::vector<std::string> >::iterator it;
	for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
		if(contains(it->second, strToLower(origin))) {
			erase(it->second, strToLower(origin));
			it->second.push_back(strToLower(nick));
		}
	}
}

void Network::kickedChannel(const std::string&, const std::string &user, const std::string&, const std::string &receiver)
{
	if(user == nick_) {
		knownUsers_.erase(strToLower(receiver));
	} else {
		erase(knownUsers_[strToLower(receiver)], strToLower(user));
	}
	if(!isKnownUser(user)) {
		erase(identifiedUsers_, strToLower(user));
	}
}

void Network::onFailedConnection()
{
	fprintf(stderr, "Connection failed on %s\n", Network::toString(this).c_str());

	identifiedUsers_.clear();
	knownUsers_.clear();

	slotIrcEvent("DISCONNECT", "", std::vector<std::string>());

	// Flag old server as undesirable
	// Don't destroy it here yet; it is still in the stack. It will be destroyed
	// in processDescriptors().
	flagUndesirableServer( activeServer_->config() );
	deleteServer_ = true;
}

void Network::ctcp( std::string destination, std::string message )
{
	if( !activeServer_ )
		return;
	activeServer_->ctcpAction( destination, message );
}

/**
 * @brief Disconnect from the network.
 */
void Network::disconnectFromNetwork( DisconnectReason reason )
{
	if( activeServer_ == 0 )
		return;

	identifiedUsers_.clear();
	knownUsers_.clear();

	activeServer_->disconnectFromServer( reason );
	// TODO: maybe deleteLater?
	delete activeServer_;
	activeServer_ = 0;
}

void Network::joinChannel( std::string channel )
{
	if( !activeServer_ )
		return;
	activeServer_->join( channel );
}

void Network::leaveChannel( std::string channel )
{
	if( !activeServer_ )
		return;
	activeServer_->part( channel );
}

void Network::say( std::string destination, std::string message )
{
	if( !activeServer_ )
		return;
	activeServer_->message( destination, message );
}

void Network::sendWhois( std::string destination )
{
	activeServer_->whois(destination);
}

const std::vector<ServerConfig*> &Network::servers() const
{
	return config_->servers;
}

std::string Network::nick() const
{
	return nick_;
}

std::string Network::networkName() const
{
	return config()->name;
}

int Network::serverUndesirability( const ServerConfig *sc ) const
{
	return contains(undesirables_, sc) ? undesirables_.find(sc)->second : 0;
}

void Network::flagUndesirableServer( const ServerConfig *sc )
{
	if(contains(undesirables_, sc))
		undesirables_[sc] = undesirables_[sc] + 1;
	undesirables_[sc] = 1;
}

void Network::serverIsActuallyOkay( const ServerConfig *sc )
{
	undesirables_.erase(sc);
}

bool Network::isIdentified(const std::string &user) const {
	return contains(identifiedUsers_, strToLower(user));
}

bool Network::isKnownUser(const std::string &user) const {
	std::map<std::string,std::vector<std::string> >::const_iterator it;
	for(it = knownUsers_.begin(); it != knownUsers_.end(); ++it) {
		if(contains(it->second, strToLower(user))) {
			return true;
		}
	}
	return false;
}

void Network::slotWhoisReceived(const std::string &, const std::string &nick, bool identified) {
	if(!identified) {
		erase(identifiedUsers_, strToLower(nick));
	} else if(identified && !contains(identifiedUsers_, strToLower(nick)) && isKnownUser(nick)) {
		identifiedUsers_.push_back(strToLower(nick));
	}
}

void Network::slotNamesReceived(const std::string&, const std::string &channel, const std::vector<std::string> &names, const std::string & ) {
	assert(contains(knownUsers_, strToLower(channel)));
	std::vector<std::string> &users = knownUsers_[strToLower(channel)];
	std::vector<std::string>::const_iterator it;
	for(it = names.begin(); it != names.end(); ++it) {
		std::string n = *it;
		unsigned int nickStart;
		for(nickStart = 0; nickStart < n.length(); ++nickStart) {
			if(n[nickStart] != '@' && n[nickStart] != '~' && n[nickStart] != '+'
			&& n[nickStart] != '%' && n[nickStart] != '!') {
				break;
			}
		}
		n = n.substr(nickStart);
		if(!contains(users, strToLower(n)))
			users.push_back(strToLower(n));
	}
}

void Network::slotTopicChanged(const std::string&, const std::string &channel, const std::string &topic) {
	topics_[channel] = topic;
}

void Network::slotIrcEvent(const std::string &event, const std::string &origin, const std::vector<std::string> &params) {
	std::string receiver;
	if(params.size() > 0)
		receiver = params[0];

#define MIN(a) if(params.size() < a) { fprintf(stderr, "Too few parameters for event %s\n", event.c_str()); return; }
	if(event == "CONNECT") {
		serverIsActuallyOkay(activeServer_->config());
	} else if(event == "JOIN") {
		MIN(1);
		joinedChannel(origin, receiver);
	} else if(event == "PART") {
		MIN(1);
		partedChannel(origin, std::string(), receiver);
	} else if(event == "KICK") {
		MIN(2);
		kickedChannel(origin, params[1], std::string(), receiver);
	} else if(event == "QUIT") {
		std::string message;
		if(params.size() > 0) {
			message = params[0];
		}
		slotQuit(origin, message, receiver);
	} else if(event == "NICK") {
		MIN(1);
		slotNickChanged(origin, params[0], receiver);
	} else if(event == "TOPIC") {
		MIN(2);
		slotTopicChanged(origin, params[0], params[1]);
	}
#undef MIN
	std::vector<NetworkListener*>::iterator nlit;
	for(nlit = networkListeners_.begin(); nlit != networkListeners_.end();
	    nlit++) {
		(*nlit)->ircEvent(event, origin, params, this);
	}
}

void Network::addDescriptors(fd_set *in_set, fd_set *out_set, int *maxfd) {
	activeServer_->addDescriptors(in_set, out_set, maxfd);
}

void Network::processDescriptors(fd_set *in_set, fd_set *out_set) {
	deleteServer_ = false;
	activeServer_->processDescriptors(in_set, out_set);
	if(deleteServer_) {
		delete activeServer_;
		activeServer_ = 0;
		connectToNetwork();
	}
}
<|endoftext|>


<commit_before>#include "nzruler.h"

#include <string>
#include <iostream>
using namespace std;

void NZRuler::initValues() {
    this->yellow = wxColor(255, 255, 128, 255);
    this->blue = wxColor(0, 0, 170, 255);

    this->mouseOffset.x = 0;
    this->mouseOffset.y = 0;
    this->mouseOffset.dx = 0;
    this->mouseOffset.dy = 0;

    this->mouseIsPressed = false;
    this->resizeArea = 12;
    this->oldCursor = wxCURSOR_ARROW;
    this->mouse.x = 0;
    this->mouse.y = 0;

    this->font = wxFont(wxFontInfo(9).FaceName("FreeSans, Helvetica, Arial, sans-serif").Bold());
    this->safePos = 33;
    this->vertical = false;

    this->panel = unique_ptr<wxPanel>(new wxPanel(this, wxID_ANY));
    this->settings = unique_ptr<wxFileConfig>(new wxFileConfig(
        "nzruler",
        "nzruler",
        wxEmptyString,
        wxEmptyString,
        wxCONFIG_USE_LOCAL_FILE
    ));
}

NZRuler::NZRuler():
    wxFrame(
        NULL,
        wxID_ANY,
        "NZRuler",
        wxDefaultPosition,
        wxDefaultSize,
        wxNO_BORDER | wxWANTS_CHARS
    ) {
    this->initValues();

    wxPoint firstPos;
    wxSize firstSize;
    bool firstVertical;

    int position_x, position_y;
    int size_w, size_h;
    bool vertical;

    if(
        this->settings->Read("position_x", &position_x)
        && this->settings->Read("position_y", &position_y)
    ) {
        firstPos = wxPoint(position_x, position_y);
    } else {
        firstPos = wxPoint(100, 100);
    }

    if(
        this->settings->Read("size_w", &size_w)
        && this->settings->Read("size_h", &size_h)
    ) {
        firstSize = wxSize(size_w, size_h);
    } else {
        firstSize = wxSize(200, 60);
    }

    if(this->settings->Read("vertical", &vertical)) {
        firstVertical = vertical;
    } else {
        firstVertical = false;
    }

    this->vertical = firstVertical;
    this->SetPosition(firstPos);
    this->SetSize(firstSize);

    this->panel->Bind(wxEVT_PAINT, &NZRuler::paintEvent, this);
    this->panel->Bind(wxEVT_KEY_DOWN, &NZRuler::keyDownEvent, this);
    this->panel->Bind(wxEVT_MOTION, &NZRuler::motionEvent, this);
    this->panel->Bind(wxEVT_LEFT_DOWN, &NZRuler::leftDownEvent, this);
    this->panel->Bind(wxEVT_LEFT_UP, &NZRuler::leftUpEvent, this);
    this->Bind(wxEVT_CLOSE_WINDOW, &NZRuler::closeWindowEvent, this);
}

void NZRuler::closeWindowEvent(wxCloseEvent & evt) {
    auto size = this->GetSize();
    auto position = this->GetPosition();
    this->settings->Write("position_x", position.x);
    this->settings->Write("position_y", position.y);
    this->settings->Write("size_w", size.GetWidth());
    this->settings->Write("size_h", size.GetHeight());
    this->settings->Write("vertical", this->vertical);

    evt.Skip();
}

void NZRuler::leftDownEvent(wxMouseEvent & evt) {
    wxSize size = this->GetSize();

    wxPoint screen_pos = wxGetMousePosition();
    wxPoint frame_pos = this->ScreenToClient(screen_pos);

    this->mouseIsPressed = true;
    this->mouseOffset.x = frame_pos.x;
    this->mouseOffset.y = frame_pos.y;
    this->mouseOffset.dx = size.GetWidth() - this->mouseOffset.x;
    this->mouseOffset.dy = size.GetHeight() - this->mouseOffset.y;
}

void NZRuler::leftUpEvent(wxMouseEvent & event) {
    if(this->mouseIsPressed) {
        this->mouseIsPressed = false;
    }
}

void NZRuler::keyDownEvent(wxKeyEvent & evt) {
    auto key = evt.GetKeyCode();

    if(key == WXK_ESCAPE) {
        this->Close();
    } else {
        unsigned short int increment;
        auto modifiers = evt.GetModifiers();

        if (modifiers & wxMOD_SHIFT) {
            increment = 3;
        } else {
            increment = 1;
        }

        if(modifiers & wxMOD_ALT) {
            wxSize size = this->GetSize();

            int new_width = 0;
            int new_height = 0;

            bool resize = true;

            switch (key) {
                case WXK_LEFT:
                    new_width = size.GetWidth() - increment;
                    new_height = size.GetHeight();
                    break;

                case WXK_UP:
                    new_width = size.GetWidth();
                    new_height = size.GetHeight() - increment;
                    break;

                case WXK_RIGHT:
                    new_width = size.GetWidth() + increment;
                    new_height = size.GetHeight();
                    break;

                case WXK_DOWN:
                    new_width = size.GetWidth();
                    new_height = size.GetHeight() + increment;
                    break;

                default:
                    resize = false;
            }

            if (resize) {
                this->SetSize(new_width, new_height);
            }

        } else {

            wxPoint pos = this->GetPosition();
            int new_x = 0;
            int new_y = 0;

            bool move = true;

            switch (key) {
                case WXK_LEFT:
                    new_x = pos.x - increment;
                    new_y = pos.y;
                    break;

                case WXK_UP:
                    new_x = pos.x;
                    new_y = pos.y - increment;
                    break;

                case WXK_RIGHT:
                    new_x = pos.x + increment;
                    new_y = pos.y;
                    break;

                case WXK_DOWN:
                    new_x = pos.x;
                    new_y = pos.y + increment;
                    break;

                default:
                    move = false;
            }

            if (move) {
                this->Move(new_x, new_y);
            }
        }
    }
}

void NZRuler::motionEvent(wxMouseEvent & evt) {

    wxPoint screen_pos = wxGetMousePosition();
    wxPoint frame_pos = this->ScreenToClient(screen_pos);
    wxSize frame_size = this->GetSize();

    int x = screen_pos.x;
    int y = screen_pos.y;
    int lx = frame_pos.x;
    int ly = frame_pos.y;

    int w = frame_size.GetWidth();
    int h = frame_size.GetHeight();

    this->mouse.x = lx;
    this->mouse.y = ly;

    if (this->mouseIsPressed) {
        if (this->oldCursor == wxCURSOR_SIZEWE) {
            this->SetSize(lx + this->mouseOffset.dx, h);
        }

        else if (this->oldCursor == wxCURSOR_SIZENS) {
            this->SetSize(w, ly + this->mouseOffset.dy);
        }

        else if (this->oldCursor == wxCURSOR_SIZING) {
            this->SetSize(lx + this->mouseOffset.dx, ly + this->mouseOffset.dy);
        }

        else {
            this->Move(x - this->mouseOffset.x, y - this->mouseOffset.y);
        }

    } else {
        wxStockCursor newCursor;

        if (lx > (w - this->resizeArea) && ly > (h - this->resizeArea)) {
            newCursor = wxCURSOR_SIZING;

        } else if (lx > (w - this->resizeArea)) {
            newCursor = wxCURSOR_SIZEWE;
        }

        else if (ly > (h - this->resizeArea)) {
            newCursor = wxCURSOR_SIZENS;
        }

        else {
            newCursor = wxCURSOR_ARROW;
        }

        if (newCursor != this->oldCursor) {
            this->SetCursor(newCursor);
            this->oldCursor = newCursor;
        }

        this->paintNow();
    }
}

void NZRuler::SetSize(wxSize size) {
    this->SetSize(size.GetWidth(), size.GetHeight());
}
void NZRuler::SetSize(int width, int height) {
    int minWidth = 60;
    int minHeight = 60;

    if (width < minWidth) {
        width = minWidth;
    }
    if (height < minHeight) {
        height = minHeight;
    }

    if (width != height) {
        this->vertical = (width < height);
    }

    this->wxFrame::SetSize(width, height);
}

void NZRuler::paintEvent(wxPaintEvent & evt) {
    wxPaintDC dc(this->panel.get());
    this->render(dc);
}

void NZRuler::paintNow()
{
    wxClientDC dc(this->panel.get());
    this->render(dc);
}

void NZRuler::render(wxDC & dc) {

    dc.SetFont(this->font);

    wxSize size_obj = this->GetSize();
    int width = size_obj.GetWidth();
    int height = size_obj.GetHeight();

    dc.SetBrush(wxBrush(this->yellow));
    dc.SetPen(* wxBLACK_PEN);
    dc.DrawRectangle(0, 0, width, height);

    this->safePos = this->vertical ? 0 : 33;

    int size = this->vertical ? height : width;

    dc.SetTextForeground(* wxRED);
    int limit;

    if (this->vertical) {
        string str = to_string(height);

        wxCoord w, h;
        dc.GetTextExtent(str, &w, &h);

        limit = height - 3 - h;

        dc.DrawText(str, 17.5, limit);
    } else {
        string str = to_string(width);

        wxCoord w, h;
        dc.GetTextExtent(str, &w, &h);

        limit = (width - 3 - w);

        dc.DrawText(str, limit, 17.5);
    }

    dc.SetTextForeground(* wxBLACK);

    for (int i = 0; i < size; i += 2) {
        int length;

        if (i % 50 == 0) {
            length = 15;

        } else if (i % 10 == 0) {
            length = 10;
        } else {
            length = 5;
        }

        if (this->vertical) {
            dc.DrawLine(0, i, length, i);
        } else {
            dc.DrawLine(i, 0, i, length);
        }

        if (length == 15) {
            string label = to_string(i);

            wxCoord w, h;
            dc.GetTextExtent(label, &w, &h);

            float labelX;
            float labelY;

            bool drawLabel;

            if (this->vertical) {
                labelX = 17.5;
                labelY = i - (h / 2);

                if (this->safePos < w) {
                    this->safePos = w + 5;
                }

                drawLabel = (labelY + h) < limit;
            } else {
                labelX = i - (w / 2);
                labelY = 17.5;

                drawLabel = (labelX + w) < limit;
            }

            if(drawLabel) {
                dc.DrawText(label, labelX, labelY);
            }
        }
    }

    if (!this->mouseIsPressed) {
        dc.SetPen(wxPen(this->blue));
        dc.SetTextForeground(this->blue);

        if (this->vertical) {
            dc.DrawLine(0, this->mouse.y, width, this->mouse.y);
        } else {
            dc.DrawLine(this->mouse.x, 0, this->mouse.x, height);
        }

        string label = to_string(this->vertical ? this->mouse.y : this->mouse.x);

        wxCoord w, h;
        dc.GetTextExtent(label, &w, &h);

        int posX, posY;
        bool drawLabel;

        if (this->vertical) {
            posX = this->safePos;
            posY = this->mouse.y + 5;

            drawLabel = (posY + h) > limit;
        } else {
            posX = this->mouse.x + 5;
            posY = this->safePos;

            if (posX + w > (width - 5)) {
                posX = this->mouse.x - 5 - w;
            }
        }

        dc.DrawText(label, posX, posY);
    }
}<commit_msg>Double buffering to prevent flickering<commit_after>#include "nzruler.h"

#include <string>
#include <wx/dcbuffer.h>

void NZRuler::initValues() {
    this->yellow = wxColor(255, 255, 128, 255);
    this->blue = wxColor(0, 0, 170, 255);

    this->mouseOffset.x = 0;
    this->mouseOffset.y = 0;
    this->mouseOffset.dx = 0;
    this->mouseOffset.dy = 0;

    this->mouseIsPressed = false;
    this->resizeArea = 12;
    this->oldCursor = wxCURSOR_ARROW;
    this->mouse.x = 0;
    this->mouse.y = 0;

    this->font = wxFont(wxFontInfo(9).FaceName("FreeSans, Helvetica, Arial, sans-serif").Bold());
    this->safePos = 33;
    this->vertical = false;

    this->panel = unique_ptr<wxPanel>(new wxPanel(this, wxID_ANY));
    this->settings = unique_ptr<wxFileConfig>(new wxFileConfig(
        "nzruler",
        "nzruler",
        wxEmptyString,
        wxEmptyString,
        wxCONFIG_USE_LOCAL_FILE
    ));
}

NZRuler::NZRuler():
    wxFrame(
        NULL,
        wxID_ANY,
        "NZRuler",
        wxDefaultPosition,
        wxDefaultSize,
        wxNO_BORDER | wxWANTS_CHARS
    ) {
    this->initValues();

    wxPoint firstPos;
    wxSize firstSize;
    bool firstVertical;

    int position_x, position_y;
    int size_w, size_h;
    bool vertical;

    if(
        this->settings->Read("position_x", &position_x)
        && this->settings->Read("position_y", &position_y)
    ) {
        firstPos = wxPoint(position_x, position_y);
    } else {
        firstPos = wxPoint(100, 100);
    }

    if(
        this->settings->Read("size_w", &size_w)
        && this->settings->Read("size_h", &size_h)
    ) {
        firstSize = wxSize(size_w, size_h);
    } else {
        firstSize = wxSize(200, 60);
    }

    if(this->settings->Read("vertical", &vertical)) {
        firstVertical = vertical;
    } else {
        firstVertical = false;
    }

    this->vertical = firstVertical;
    this->SetPosition(firstPos);
    this->SetSize(firstSize);

    this->panel->Bind(wxEVT_PAINT, &NZRuler::paintEvent, this);
    this->panel->Bind(wxEVT_KEY_DOWN, &NZRuler::keyDownEvent, this);
    this->panel->Bind(wxEVT_MOTION, &NZRuler::motionEvent, this);
    this->panel->Bind(wxEVT_LEFT_DOWN, &NZRuler::leftDownEvent, this);
    this->panel->Bind(wxEVT_LEFT_UP, &NZRuler::leftUpEvent, this);
    this->Bind(wxEVT_CLOSE_WINDOW, &NZRuler::closeWindowEvent, this);
}

void NZRuler::closeWindowEvent(wxCloseEvent & evt) {
    auto size = this->GetSize();
    auto position = this->GetPosition();
    this->settings->Write("position_x", position.x);
    this->settings->Write("position_y", position.y);
    this->settings->Write("size_w", size.GetWidth());
    this->settings->Write("size_h", size.GetHeight());
    this->settings->Write("vertical", this->vertical);

    evt.Skip();
}

void NZRuler::leftDownEvent(wxMouseEvent & evt) {
    wxSize size = this->GetSize();

    wxPoint screen_pos = wxGetMousePosition();
    wxPoint frame_pos = this->ScreenToClient(screen_pos);

    this->mouseIsPressed = true;
    this->mouseOffset.x = frame_pos.x;
    this->mouseOffset.y = frame_pos.y;
    this->mouseOffset.dx = size.GetWidth() - this->mouseOffset.x;
    this->mouseOffset.dy = size.GetHeight() - this->mouseOffset.y;
}

void NZRuler::leftUpEvent(wxMouseEvent & event) {
    if(this->mouseIsPressed) {
        this->mouseIsPressed = false;
    }
}

void NZRuler::keyDownEvent(wxKeyEvent & evt) {
    auto key = evt.GetKeyCode();

    if(key == WXK_ESCAPE) {
        this->Close();
    } else {
        unsigned short int increment;
        auto modifiers = evt.GetModifiers();

        if (modifiers & wxMOD_SHIFT) {
            increment = 3;
        } else {
            increment = 1;
        }

        if(modifiers & wxMOD_ALT) {
            wxSize size = this->GetSize();

            int new_width = 0;
            int new_height = 0;

            bool resize = true;

            switch (key) {
                case WXK_LEFT:
                    new_width = size.GetWidth() - increment;
                    new_height = size.GetHeight();
                    break;

                case WXK_UP:
                    new_width = size.GetWidth();
                    new_height = size.GetHeight() - increment;
                    break;

                case WXK_RIGHT:
                    new_width = size.GetWidth() + increment;
                    new_height = size.GetHeight();
                    break;

                case WXK_DOWN:
                    new_width = size.GetWidth();
                    new_height = size.GetHeight() + increment;
                    break;

                default:
                    resize = false;
            }

            if (resize) {
                this->SetSize(new_width, new_height);
            }

        } else {

            wxPoint pos = this->GetPosition();
            int new_x = 0;
            int new_y = 0;

            bool move = true;

            switch (key) {
                case WXK_LEFT:
                    new_x = pos.x - increment;
                    new_y = pos.y;
                    break;

                case WXK_UP:
                    new_x = pos.x;
                    new_y = pos.y - increment;
                    break;

                case WXK_RIGHT:
                    new_x = pos.x + increment;
                    new_y = pos.y;
                    break;

                case WXK_DOWN:
                    new_x = pos.x;
                    new_y = pos.y + increment;
                    break;

                default:
                    move = false;
            }

            if (move) {
                this->Move(new_x, new_y);
            }
        }
    }
}

void NZRuler::motionEvent(wxMouseEvent & evt) {

    wxPoint screen_pos = wxGetMousePosition();
    wxPoint frame_pos = this->ScreenToClient(screen_pos);
    wxSize frame_size = this->GetSize();

    int x = screen_pos.x;
    int y = screen_pos.y;
    int lx = frame_pos.x;
    int ly = frame_pos.y;

    int w = frame_size.GetWidth();
    int h = frame_size.GetHeight();

    this->mouse.x = lx;
    this->mouse.y = ly;

    if (this->mouseIsPressed) {
        if (this->oldCursor == wxCURSOR_SIZEWE) {
            this->SetSize(lx + this->mouseOffset.dx, h);
        }

        else if (this->oldCursor == wxCURSOR_SIZENS) {
            this->SetSize(w, ly + this->mouseOffset.dy);
        }

        else if (this->oldCursor == wxCURSOR_SIZING) {
            this->SetSize(lx + this->mouseOffset.dx, ly + this->mouseOffset.dy);
        }

        else {
            this->Move(x - this->mouseOffset.x, y - this->mouseOffset.y);
        }

    } else {
        wxStockCursor newCursor;

        if (lx > (w - this->resizeArea) && ly > (h - this->resizeArea)) {
            newCursor = wxCURSOR_SIZING;

        } else if (lx > (w - this->resizeArea)) {
            newCursor = wxCURSOR_SIZEWE;
        }

        else if (ly > (h - this->resizeArea)) {
            newCursor = wxCURSOR_SIZENS;
        }

        else {
            newCursor = wxCURSOR_ARROW;
        }

        if (newCursor != this->oldCursor) {
            this->SetCursor(newCursor);
            this->oldCursor = newCursor;
        }

        this->paintNow();
    }
}

void NZRuler::SetSize(wxSize size) {
    this->SetSize(size.GetWidth(), size.GetHeight());
}
void NZRuler::SetSize(int width, int height) {
    int minWidth = 60;
    int minHeight = 60;

    if (width < minWidth) {
        width = minWidth;
    }
    if (height < minHeight) {
        height = minHeight;
    }

    if (width != height) {
        this->vertical = (width < height);
    }

    this->wxFrame::SetSize(width, height);
}

void NZRuler::paintEvent(wxPaintEvent & evt) {
    wxBufferedPaintDC bdc(this->panel.get());
    this->render(bdc);
}

void NZRuler::paintNow()
{
    wxClientDC dc(this->panel.get());
    wxBufferedDC bdc(&dc);
    this->render(bdc);
    bdc.UnMask();
}

void NZRuler::render(wxDC & dc) {

    dc.SetFont(this->font);

    wxSize size_obj = this->GetSize();
    int width = size_obj.GetWidth();
    int height = size_obj.GetHeight();

    dc.SetBrush(wxBrush(this->yellow));
    dc.SetPen(* wxBLACK_PEN);
    dc.DrawRectangle(0, 0, width, height);

    this->safePos = this->vertical ? 0 : 33;

    int size = this->vertical ? height : width;

    dc.SetTextForeground(* wxRED);
    int limit;

    if (this->vertical) {
        string str = to_string(height);

        wxCoord w, h;
        dc.GetTextExtent(str, &w, &h);

        limit = height - 3 - h;

        dc.DrawText(str, 17.5, limit);
    } else {
        string str = to_string(width);

        wxCoord w, h;
        dc.GetTextExtent(str, &w, &h);

        limit = (width - 3 - w);

        dc.DrawText(str, limit, 17.5);
    }

    dc.SetTextForeground(* wxBLACK);

    for (int i = 0; i < size; i += 2) {
        int length;

        if (i % 50 == 0) {
            length = 15;

        } else if (i % 10 == 0) {
            length = 10;
        } else {
            length = 5;
        }

        if (this->vertical) {
            dc.DrawLine(0, i, length, i);
        } else {
            dc.DrawLine(i, 0, i, length);
        }

        if (length == 15) {
            string label = to_string(i);

            wxCoord w, h;
            dc.GetTextExtent(label, &w, &h);

            float labelX;
            float labelY;

            bool drawLabel;

            if (this->vertical) {
                labelX = 17.5;
                labelY = i - (h / 2);

                if (this->safePos < w) {
                    this->safePos = w + 5;
                }

                drawLabel = (labelY + h) < limit;
            } else {
                labelX = i - (w / 2);
                labelY = 17.5;

                drawLabel = (labelX + w) < limit;
            }

            if(drawLabel) {
                dc.DrawText(label, labelX, labelY);
            }
        }
    }

    if (!this->mouseIsPressed) {
        dc.SetPen(wxPen(this->blue));
        dc.SetTextForeground(this->blue);

        if (this->vertical) {
            dc.DrawLine(0, this->mouse.y, width, this->mouse.y);
        } else {
            dc.DrawLine(this->mouse.x, 0, this->mouse.x, height);
        }

        string label = to_string(this->vertical ? this->mouse.y : this->mouse.x);

        wxCoord w, h;
        dc.GetTextExtent(label, &w, &h);

        int posX, posY;
        bool drawLabel;

        if (this->vertical) {
            posX = this->safePos;
            posY = this->mouse.y + 5;

            drawLabel = (posY + h) > limit;
        } else {
            posX = this->mouse.x + 5;
            posY = this->safePos;

            if (posX + w > (width - 5)) {
                posX = this->mouse.x - 5 - w;
            }
        }

        dc.DrawText(label, posX, posY);
    }
}<|endoftext|>


<commit_before>#ifndef OBJECTS_HPP_
#define OBJECTS_HPP_

#include <string>
#include <vector>
#include <functional>
#include <unordered_map>
#include <sstream>

#include "global.hpp"

namespace lang {
  typedef std::vector<std::string> TypeList;
  class Object : Stringifyable {
  public:
    typedef std::function<Object*(Object*, Object*)> BinaryOp;
    typedef std::function<Object*(Object*)> UnaryOp;

    virtual ~Object() {};

    virtual bool isTruthy() = 0;
    virtual std::string toString() = 0;
    virtual std::string getTypeData() = 0; // Pure virtual, derived classes must implement this
  };

  class Name : public Object {
  private:
    std::string name;
  public:
    Name(std::string name): name(name) {};
    bool isTruthy() {return false;}
    std::string toString() {return name;}
    std::string getTypeData() {return "Name";}
  };

  class Variable : public Object {
  private:
    Object* internal = nullptr;
    std::string currentType = "";
    TypeList types {};
  public:
    Variable() {}
    Variable(Object* obj, TypeList types):
      internal(obj),
      types(types) {
      if (obj != nullptr) currentType = obj->getTypeData();
    }

    std::string toString() {
      std::stringstream ss; ss << this;
      return std::string("Variable ") + ss.str() + ": " + (this->internal == nullptr ? "Unassigned" : this->internal->toString());
    }
    bool isTruthy() {return this->read()->isTruthy();}
    std::string getTypeData() {return "Variable";}

    void assign(Object* newObj) {
      if (newObj == nullptr) throw Error("Attemptted assignment of nullptr on " + this->toString(), "NullPointerError", -2); // TODO: line numbers
      if (!contains(std::string("define"), types) && !contains(newObj->getTypeData(), types))
        throw Error("Invalid assignment of type " + newObj->getTypeData(), "TypeError", -2); // TODO: line numbers
      currentType = newObj->getTypeData();
      this->internal = newObj;
    }
    Object* read() {return this->internal;}
    std::string getCurrentType() {return this->currentType;}
    TypeList getTypes() {return this->types;}
  };

  enum Visibility : int {
    PRIVATE, PUBLIC
  };

  class Member : public Object {
  private:
    Variable* var = nullptr;
    Visibility access = PRIVATE;
  public:
    Member(Variable* var, Visibility access = PRIVATE):
      var(var),
      access(access) {
    }

    bool isTruthy() {return this->var->isTruthy();}
    std::string toString() {
      return "Member with " + this->var->toString() + " and visibility " + std::to_string(this->access);
    }
    std::string getTypeData() {return "Member";}

    Variable* getVariable() {return this->var;}
    void setVariable(Variable* var) {this->var = var;}
    Visibility getVisibility() {return this->access;}
  };

  class Instance;

  typedef std::unordered_map<std::string, Member*> MemberMap;

  class Type : public Object {
    friend class Instance;
  private:
    std::string name;
  protected:
    MemberMap staticMembers;
    MemberMap instanceMembers;
  public:
    Type(std::string name, MemberMap staticMembers, MemberMap instanceMembers):
      name(name),
      staticMembers(staticMembers),
      instanceMembers(instanceMembers) {}

    bool isTruthy() {return false;}
    std::string toString() {return "Type " + this->name;}
    std::string getTypeData() {return "Type";}

    std::string getName() {return this->name;}
    Member* getStaticMember(std::string identifier) {
      auto member = staticMembers[identifier];
      if (member == nullptr) throw Error("Could not find static member " + identifier, "NullPointerError", -2); // TODO: line number
      return member;
    }
    MemberMap& getStaticMap() {return staticMembers;}
    MemberMap& getInstanceMap() {return instanceMembers;}
  };

  class Instance : public Object {
  private:
    Type* type = nullptr;
    MemberMap members;
  public:
    Instance(Type* t):
      type(t),
      members(t->instanceMembers) {
    }

    bool isTruthy() {return false;}
    std::string toString() {
      return "Instance of " + this->type->toString();
    }
    std::string getTypeData() {return "Instance";}

    Member* getMember(std::string identifier) {
      // TODO: these ifs don't make sense
      auto member = this->members[identifier];
      if (member == nullptr) member = this->type->getStaticMember(identifier); // Check for a static member
      if (member == nullptr) throw Error("Could not find member " + identifier, "NullPointerError", -2); // TODO: line number
      if (member->getVisibility() != PUBLIC) throw Error("Member " + identifier + " is not visible", "Error", -2); // TODO: line number
      return member;
    }
  };

  typedef std::unordered_map<std::string, Variable*> Scope;

  inline std::ostream& operator<<(std::ostream& os, Object& obj) {
    return os << "Object[" << obj.toString() << "]";
  }
} /* namespace lang */

#endif /* OBJECTS_HPP_ */
<commit_msg>Fixed logic error<commit_after>#ifndef OBJECTS_HPP_
#define OBJECTS_HPP_

#include <string>
#include <vector>
#include <functional>
#include <unordered_map>
#include <sstream>

#include "global.hpp"

namespace lang {
  typedef std::vector<std::string> TypeList;
  class Object : Stringifyable {
  public:
    typedef std::function<Object*(Object*, Object*)> BinaryOp;
    typedef std::function<Object*(Object*)> UnaryOp;

    virtual ~Object() {};

    virtual bool isTruthy() = 0;
    virtual std::string toString() = 0;
    virtual std::string getTypeData() = 0; // Pure virtual, derived classes must implement this
  };

  class Name : public Object {
  private:
    std::string name;
  public:
    Name(std::string name): name(name) {};
    bool isTruthy() {return false;}
    std::string toString() {return name;}
    std::string getTypeData() {return "Name";}
  };

  class Variable : public Object {
  private:
    Object* internal = nullptr;
    std::string currentType = "";
    TypeList types {};
  public:
    Variable() {}
    Variable(Object* obj, TypeList types):
      internal(obj),
      types(types) {
      if (obj != nullptr) currentType = obj->getTypeData();
    }

    std::string toString() {
      std::stringstream ss; ss << this;
      return std::string("Variable ") + ss.str() + ": " + (this->internal == nullptr ? "Unassigned" : this->internal->toString());
    }
    bool isTruthy() {return this->read()->isTruthy();}
    std::string getTypeData() {return "Variable";}

    void assign(Object* newObj) {
      if (newObj == nullptr) throw Error("Attemptted assignment of nullptr on " + this->toString(), "NullPointerError", -2); // TODO: line numbers
      if (!(newObj->getTypeData() == "Variable" || contains(std::string("define"), types) || contains(newObj->getTypeData(), types)))
        throw Error("Invalid assignment of type " + newObj->getTypeData(), "TypeError", -2); // TODO: line numbers
      currentType = newObj->getTypeData();
      this->internal = newObj;
    }
    Object* read() {return this->internal;}
    std::string getCurrentType() {return this->currentType;}
    TypeList getTypes() {return this->types;}
  };

  enum Visibility : int {
    PRIVATE, PUBLIC
  };

  class Member : public Object {
  private:
    Variable* var = nullptr;
    Visibility access = PRIVATE;
  public:
    Member(Variable* var, Visibility access = PRIVATE):
      var(var),
      access(access) {
    }

    bool isTruthy() {return this->var->isTruthy();}
    std::string toString() {
      return "Member with " + this->var->toString() + " and visibility " + std::to_string(this->access);
    }
    std::string getTypeData() {return "Member";}

    Variable* getVariable() {return this->var;}
    void setVariable(Variable* var) {this->var = var;}
    Visibility getVisibility() {return this->access;}
  };

  class Instance;

  typedef std::unordered_map<std::string, Member*> MemberMap;

  class Type : public Object {
    friend class Instance;
  private:
    std::string name;
  protected:
    MemberMap staticMembers;
    MemberMap instanceMembers;
  public:
    Type(std::string name, MemberMap staticMembers, MemberMap instanceMembers):
      name(name),
      staticMembers(staticMembers),
      instanceMembers(instanceMembers) {}

    bool isTruthy() {return false;}
    std::string toString() {return "Type " + this->name;}
    std::string getTypeData() {return "Type";}

    std::string getName() {return this->name;}
    Member* getStaticMember(std::string identifier) {
      auto member = staticMembers[identifier];
      if (member == nullptr) throw Error("Could not find static member " + identifier, "NullPointerError", -2); // TODO: line number
      return member;
    }
    MemberMap& getStaticMap() {return staticMembers;}
    MemberMap& getInstanceMap() {return instanceMembers;}
  };

  class Instance : public Object {
  private:
    Type* type = nullptr;
    MemberMap members;
  public:
    Instance(Type* t):
      type(t),
      members(t->instanceMembers) {
    }

    bool isTruthy() {return false;}
    std::string toString() {
      return "Instance of " + this->type->toString();
    }
    std::string getTypeData() {return "Instance";}

    Member* getMember(std::string identifier) {
      // TODO: these ifs don't make sense
      auto member = this->members[identifier];
      if (member == nullptr) member = this->type->getStaticMember(identifier); // Check for a static member
      if (member == nullptr) throw Error("Could not find member " + identifier, "NullPointerError", -2); // TODO: line number
      if (member->getVisibility() != PUBLIC) throw Error("Member " + identifier + " is not visible", "Error", -2); // TODO: line number
      return member;
    }
  };

  typedef std::unordered_map<std::string, Variable*> Scope;

  inline std::ostream& operator<<(std::ostream& os, Object& obj) {
    return os << "Object[" << obj.toString() << "]";
  }
} /* namespace lang */

#endif /* OBJECTS_HPP_ */
<|endoftext|>


<commit_before>#include "virtualhdd.hpp"
#include <string.h>
#include <iostream>
VirtualHdd::VirtualHdd()
{
   cylinder = new track_array[cylinder_amount];
}

VirtualHdd::~VirtualHdd(){
    delete[] cylinder;
}

int VirtualHdd::getClusterSize(){
    return cluster_size;
}

availablesector VirtualHdd::getNextSector()
{
    for(int track = 0; track < TRACKSIZE; track++){
        for(int cylin = 0; cylin < cylinder_amount; cylin++){
            for(int cluster = 0; cluster < SECTORSIZE; cluster+=4){
                auto sector = cluster*cluster_size;
                if(cylinder->isClusterAvailable(track, sector))
                    return availablesector(cylin, track, sector);
            }
        }
    }

    return availablesector();
}

void VirtualHdd::write(char *buffer, availablesector sector)
{
    unsigned char* sec_buffer = getbuffer(sector);
    for(int i = 0; i < 512; i++){
        sec_buffer[i] = (unsigned char) buffer[i];
    }
    std::cout << sec_buffer << std::endl;
    getchar();

}

unsigned char* VirtualHdd::getbuffer(availablesector sector)
{
    return (unsigned char*) cylinder[sector.cylinder_index].track[sector.track_index].sector[sector.sector_index].bytes_s;
}

<commit_msg>minor changes<commit_after>#include "virtualhdd.hpp"
#include <string.h>
#include <iostream>
VirtualHdd::VirtualHdd()
{
   cylinder = new track_array[cylinder_amount];
}

VirtualHdd::~VirtualHdd(){
    delete[] cylinder;
}

int VirtualHdd::getClusterSize(){
    return cluster_size;
}

availablesector VirtualHdd::getNextSector()
{
    for(int track = 0; track < TRACKSIZE; track++){
        for(int cylin = 0; cylin < cylinder_amount; cylin++){
            for(int cluster = 0; cluster < SECTORSIZE; cluster+=4){
                auto sector = cluster*cluster_size;
                if(cylinder[cylin].isClusterAvailable(track, sector))
                    return availablesector(cylin, track, sector);
            }
        }
    }

    return availablesector();
}

void VirtualHdd::write(char *buffer, availablesector sector)
{
    unsigned char* sec_buffer = getbuffer(sector);
    for(int i = 0; i < 512; i++){
        sec_buffer[i] = (unsigned char) buffer[i];
    }
    std::cout << sec_buffer << std::endl;
    getchar();

}

unsigned char* VirtualHdd::getbuffer(availablesector sector)
{
    return (unsigned char*) cylinder[sector.cylinder_index].track[sector.track_index].sector[sector.sector_index].bytes_s;
}

<|endoftext|>


<commit_before>#include "virtualhdd.hpp"
#include <string.h>
#include <iostream>
VirtualHdd::VirtualHdd()
{
   cylinder = new track_array[cylinder_amount];
}

VirtualHdd::~VirtualHdd(){
    delete[] cylinder;
}

int VirtualHdd::getClusterSize(){
    return cluster_size;
}

availablesector VirtualHdd::getNextSector()
{
    for(int track = 0; track < TRACKSIZE; track++){
        for(int cylin = 0; cylin < cylinder_amount; cylin++){
            for(int cluster = 0; cluster < SECTORSIZE; cluster+=4){
                auto sector = cluster*cluster_size;
                if(cylinder->isClusterAvailable(track, sector))
                    return availablesector(cylin, track, sector);
            }
        }
    }

    return availablesector();
}

void VirtualHdd::write(char *buffer, availablesector sector)
{
    unsigned char* sec_buffer = getbuffer(sector);

}

unsigned char* VirtualHdd::getbuffer(availablesector sector)
{
    //return (unsigned char*) cylinder[sector.cylinder_index].track[sector.track_index].sector[sector.sector_index].bytes_s;
}

<commit_msg>missing logic for track jumping<commit_after>#include "virtualhdd.hpp"
#include <string.h>
#include <iostream>
VirtualHdd::VirtualHdd()
{
   cylinder = new track_array[cylinder_amount];
}

VirtualHdd::~VirtualHdd(){
    delete[] cylinder;
}

int VirtualHdd::getClusterSize(){
    return cluster_size;
}

availablesector VirtualHdd::getNextSector()
{
    for(int track = 0; track < TRACKSIZE; track++){
        for(int cylin = 0; cylin < cylinder_amount; cylin++){
            for(int cluster = 0; cluster < SECTORSIZE; cluster+=4){
                auto sector = cluster*cluster_size;
                if(cylinder->isClusterAvailable(track, sector))
                    return availablesector(cylin, track, sector);
            }
        }
    }

    return availablesector();
}

void VirtualHdd::write(char *buffer, availablesector sector)
{
    unsigned char* sec_buffer = getbuffer(sector);
    for(int i = 0; i < 512; i++){
        sec_buffer[i] = (unsigned char) buffer[i];
    }
    std::cout << sec_buffer << std::endl;
    getchar();

}

unsigned char* VirtualHdd::getbuffer(availablesector sector)
{
    return (unsigned char*) cylinder[sector.cylinder_index].track[sector.track_index].sector[sector.sector_index].bytes_s;
}

<|endoftext|>


<commit_before>/** @copyright
 * Copyright (c) 2017, Stuart W Baker
 * All rights reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @file MDNS.hxx
 *
 * A simple abstraction to publish mDNS sevices.
 *
 * @author Stuart Baker
 * @date 30 January 2017
 */

#ifndef _OS_MDNS_HXX_
#define _OS_MDNS_HXX_

#if !defined (__linux__) && \
    !defined (TARGET_IS_CC3200)
#error target not support for MDNS
#endif

#if defined (__linux__)
#include <stdio.h>
#include <semaphore.h>
#include <avahi-client/client.h>
#include <avahi-common/error.h>
#include <avahi-common/malloc.h>
#include <avahi-client/publish.h>
#include <avahi-common/simple-watch.h>
#include "os/OS.hxx"
#endif

#if defined (TARGET_IS_CC3200)
#include <string>
#include "netapp.h"
#undef OK // this is to fix the namespace polution in netapp.h
#endif

#include "utils/macros.h"

/** MDNS abstraction object.
 */
class MDNS
#if defined (__linux__)
    : public OSThread
#endif
{
public:
    /** Constructor.
     */
    MDNS()
#if defined (__linux__)
        :
          OSThread()
        , sem()
        , group(nullptr)
        , simplePoll(nullptr)
        , client(nullptr)
#endif
    {
#if defined (__linux__)
        start("mDNS Server", 0, 2048);
        printf("client start\n");
        sem.wait();
#endif
    }

    /** Destructor.
     */
    ~MDNS()
    {
    }

    /** Publish an mDNS name.
     */
    void publish(const char *name, const char *service, uint16_t port)
    {
#if defined (__linux__)
        name = avahi_strdup(name);

        if (!group)
        {
            group = avahi_entry_group_new(client, entry_group_callback, this);
            HASSERT(group);
        }

        int result = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC,
                                                   AVAHI_PROTO_UNSPEC,
                                                   (AvahiPublishFlags)0, name,
                                                   service, NULL, NULL,
                                                   port, NULL);

        HASSERT(result == 0);
#elif defined (TARGET_IS_CC3200)
        string full_name(name);
        full_name.append(1, '.');
        full_name.append(service);
        full_name.append(".local");
        sl_NetAppMDNSRegisterService((const signed char*)full_name.c_str(),
                                     full_name.length(),
                                     (const signed char*)"OLCB", strlen("OLCB"),
                                     port, 200, 0);
#endif
    }

    void commit()
    {
#if defined (__linux__)
        avahi_entry_group_commit(group);
#endif
    }

private:
#if defined (__linux__)
    /** Avahi group callback.
     */
    static void entry_group_callback(AvahiEntryGroup *g,
                                     AvahiEntryGroupState state, void *userdata)
    {
        MDNS *mdns = static_cast<MDNS *>(userdata);
        mdns->group = g;
    }

    /** Avahi client callback.
     */
    static void client_callback(AvahiClient *c, AvahiClientState state,
                                void * userdata)
    {
        switch (state)
        {
            default:
                break;
            case AVAHI_CLIENT_S_RUNNING:
                printf("client running\n");
                break;
        }
    }

    /** mdns polling thread.
     * @return should never return
     */
    void *entry() override
    {
        int error;

        simplePoll = avahi_simple_poll_new();
        HASSERT(simplePoll);

        client = avahi_client_new(avahi_simple_poll_get(simplePoll),
                                  (AvahiClientFlags)0, client_callback, this,
                                  &error);
        printf("client created\n");
        HASSERT(client);

        sem.post();
        avahi_simple_poll_loop(simplePoll);

        printf("mdns_thread exit\n");

        return nullptr;
    }

    /** Synchronize the startup of AVAHI */
    OSSem sem;

    /** AVAHI group */
    AvahiEntryGroup *group;

    /** AVAHI polling client */
    AvahiSimplePoll *simplePoll;

    /** AVAHI client */
    AvahiClient *client;
#endif

    DISALLOW_COPY_AND_ASSIGN(MDNS);
};

#endif /* _OS_MDNS_HXX_ */
<commit_msg>Adds debug printouts for mdns errors under linux.<commit_after>/** @copyright
 * Copyright (c) 2017, Stuart W Baker
 * All rights reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @file MDNS.hxx
 *
 * A simple abstraction to publish mDNS sevices.
 *
 * @author Stuart Baker
 * @date 30 January 2017
 */

#ifndef _OS_MDNS_HXX_
#define _OS_MDNS_HXX_

#if !defined (__linux__) && \
    !defined (TARGET_IS_CC3200)
#error target not support for MDNS
#endif

#if defined (__linux__)
#include <stdio.h>
#include <semaphore.h>
#include <avahi-client/client.h>
#include <avahi-common/error.h>
#include <avahi-common/malloc.h>
#include <avahi-client/publish.h>
#include <avahi-common/simple-watch.h>
#include "os/OS.hxx"
#endif

#if defined (TARGET_IS_CC3200)
#include <string>
#include "netapp.h"
#undef OK // this is to fix the namespace polution in netapp.h
#endif

#include "utils/macros.h"

/** MDNS abstraction object.
 */
class MDNS
#if defined (__linux__)
    : public OSThread
#endif
{
public:
    /** Constructor.
     */
    MDNS()
#if defined (__linux__)
        :
          OSThread()
        , sem()
        , group(nullptr)
        , simplePoll(nullptr)
        , client(nullptr)
#endif
    {
#if defined (__linux__)
        start("mDNS Server", 0, 2048);
        printf("client start\n");
        sem.wait();
#endif
    }

    /** Destructor.
     */
    ~MDNS()
    {
    }

    /** Publish an mDNS name.
     */
    void publish(const char *name, const char *service, uint16_t port)
    {
#if defined (__linux__)
        name = avahi_strdup(name);

        if (!group)
        {
            group = avahi_entry_group_new(client, entry_group_callback, this);
            HASSERT(group);
        }

        int result = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC,
                                                   AVAHI_PROTO_UNSPEC,
                                                   (AvahiPublishFlags)0, name,
                                                   service, NULL, NULL,
                                                   port, NULL);

        if (result != 0)
        {
            fprintf(stderr, "Error exporting mDNS name (%d) %s\n", result,
                    avahi_strerror(result));
            return;
        }
        HASSERT(result == 0);
#elif defined (TARGET_IS_CC3200)
        string full_name(name);
        full_name.append(1, '.');
        full_name.append(service);
        full_name.append(".local");
        sl_NetAppMDNSRegisterService((const signed char*)full_name.c_str(),
                                     full_name.length(),
                                     (const signed char*)"OLCB", strlen("OLCB"),
                                     port, 200, 0);
#endif
    }

    void commit()
    {
#if defined (__linux__)
        avahi_entry_group_commit(group);
#endif
    }

private:
#if defined (__linux__)
    /** Avahi group callback.
     */
    static void entry_group_callback(AvahiEntryGroup *g,
                                     AvahiEntryGroupState state, void *userdata)
    {
        MDNS *mdns = static_cast<MDNS *>(userdata);
        mdns->group = g;
    }

    /** Avahi client callback.
     */
    static void client_callback(AvahiClient *c, AvahiClientState state,
                                void * userdata)
    {
        switch (state)
        {
            default:
                break;
            case AVAHI_CLIENT_S_RUNNING:
                printf("client running\n");
                break;
        }
    }

    /** mdns polling thread.
     * @return should never return
     */
    void *entry() override
    {
        int error;

        simplePoll = avahi_simple_poll_new();
        HASSERT(simplePoll);

        client = avahi_client_new(avahi_simple_poll_get(simplePoll),
                                  (AvahiClientFlags)0, client_callback, this,
                                  &error);
        if (!client)
        {
            fprintf(stderr, "Error creating AvaHi client (%d) %s\nmDNS export "
                            "will not be functional.\n",
                error, avahi_strerror(error));
            return nullptr;
        }
        printf("client created\n");
        HASSERT(client);

        sem.post();
        avahi_simple_poll_loop(simplePoll);

        printf("mdns_thread exit\n");

        return nullptr;
    }

    /** Synchronize the startup of AVAHI */
    OSSem sem;

    /** AVAHI group */
    AvahiEntryGroup *group;

    /** AVAHI polling client */
    AvahiSimplePoll *simplePoll;

    /** AVAHI client */
    AvahiClient *client;
#endif

    DISALLOW_COPY_AND_ASSIGN(MDNS);
};

#endif /* _OS_MDNS_HXX_ */
<|endoftext|>


<commit_before>//
//  RenderEngine.cpp
//  FluxOF
//
//  Created by Patricio Gonzalez Vivo on 6/14/14.
//
//

#include "RenderEngine.h"

void RenderEngine::setCalibration(CalibrationLoader *_calibration){
    calibration = _calibration;
}

void RenderEngine::addUiClass(UIClass *_ui){
    guiAdd( *_ui );
}

void RenderEngine::selfSceneTransformation(){

    if(!simulatorMode){
        calibration->shoe[currentViewPort].begin();
    }
}

vector<ofColor> getColorPalette(ofImage &_img, int _nColors){

    vector<ofColor> palette;

    //  Extract Color Palette
    //
    ofImage smallImg;
    smallImg = _img;
    smallImg.resize(_img.getWidth()*0.25, _img.getHeight()*0.25);
    const int colorCount = 5;
    const int sampleCount = smallImg.getHeight() * smallImg.getWidth();
    cv::Mat colorSamples( sampleCount, 1, CV_32FC3 );

    // get our pixels
    unsigned char * pixels = smallImg.getPixels();

    // build our matrix of samples
    cv::MatIterator_<cv::Vec3f> sampleIt = colorSamples.begin<cv::Vec3f>();
    for(int i=0; i<sampleCount; i++){
        int pos = i * 3;
        *sampleIt = cv::Vec3f( pixels[pos], pixels[pos+1], pixels[pos+2] );
        sampleIt++;
    }

    // call kmeans
    cv::Mat labels, clusters;
    cv::kmeans( colorSamples, _nColors, labels, cv::TermCriteria(), 2, cv::KMEANS_RANDOM_CENTERS, clusters ); //cv::TermCriteria::COUNT, 8, 0

    for( int i = 0; i < _nColors; ++i ){
        ofColor clusterColor = ofColor( clusters.at<cv::Vec3f>(i,0)[0], clusters.at<cv::Vec3f>(i,0)[1], clusters.at<cv::Vec3f>(i,0)[2] );
        palette.push_back(clusterColor);
    }

    return palette;
}

void RenderEngine::startTransitionTo(QueueItem queueItem){
    text = queueItem.username;

    //  Load Image
    //
    colorPalette = getColorPalette(queueItem.image, 5);

    //  Keep the image as a destinationTexture
    //
    shoeTexB = queueItem.image.getTextureReference();

    //  Start Animation
    //
    timeline->setPercentComplete(0.0);
    timeline->play();
}

void RenderEngine::drawMask(int viewPort){
    if(!simulatorMode){
        //calibration->shoe[currentViewPort].begin();

        ofSetColor(255);
        ofEnableBlendMode(OF_BLENDMODE_MULTIPLY);

        ofTexture tex;

        if(viewPort == 0){
            tex = assets->terrainMask1;
        } else {
            tex = assets->terrainMask2;
        }

        int s = tex.getWidth();
        tex.bind();
        glBegin(GL_QUADS);{
            glTexCoord2d(0, 0); glVertex2d(0, 0);
            glTexCoord2d(s, 0); glVertex2d(s, 0);
            glTexCoord2d(s, s); glVertex2d(s, s);
            glTexCoord2d(0, s); glVertex2d(0, s);
        }glEnd();
        tex.unbind();
        ofEnableAlphaBlending();
    }
}

bool RenderEngine::transitionDone(){
    return !timeline->getIsPlaying();
}<commit_msg>Comment<commit_after>//
//  RenderEngine.cpp
//  FluxOF
//
//  Created by Patricio Gonzalez Vivo on 6/14/14.
//
//

#include "RenderEngine.h"

void RenderEngine::setCalibration(CalibrationLoader *_calibration){
    calibration = _calibration;
}

void RenderEngine::addUiClass(UIClass *_ui){
    guiAdd( *_ui );
}

void RenderEngine::selfSceneTransformation(){

    if(!simulatorMode){
        calibration->shoe[currentViewPort].begin();
    }
}

vector<ofColor> getColorPalette(ofImage &_img, int _nColors){

    vector<ofColor> palette;

    //  Extract Color Palette
    //
    ofImage smallImg;
    smallImg = _img;
    smallImg.resize(_img.getWidth()*0.25, _img.getHeight()*0.25);
    const int colorCount = 5;
    const int sampleCount = smallImg.getHeight() * smallImg.getWidth();
    cv::Mat colorSamples( sampleCount, 1, CV_32FC3 );

    // get our pixels
    unsigned char * pixels = smallImg.getPixels();

    // build our matrix of samples
    cv::MatIterator_<cv::Vec3f> sampleIt = colorSamples.begin<cv::Vec3f>();
    for(int i=0; i<sampleCount; i++){
        int pos = i * 3;
        *sampleIt = cv::Vec3f( pixels[pos], pixels[pos+1], pixels[pos+2] );
        sampleIt++;
    }

    // call kmeans
    cv::Mat labels, clusters;
    cv::kmeans( colorSamples, _nColors, labels, cv::TermCriteria(), 2, cv::KMEANS_RANDOM_CENTERS, clusters ); //cv::TermCriteria::COUNT, 8, 0

    for( int i = 0; i < _nColors; ++i ){
        ofColor clusterColor = ofColor( clusters.at<cv::Vec3f>(i,0)[0], clusters.at<cv::Vec3f>(i,0)[1], clusters.at<cv::Vec3f>(i,0)[2] );
        palette.push_back(clusterColor);
    }

    return palette;
}

void RenderEngine::startTransitionTo(QueueItem queueItem){
    text = queueItem.username;

    //  Load Image
    //
    colorPalette = getColorPalette(queueItem.image, 5);

    //  Keep the image as a destinationTexture
    //
    shoeTexB = queueItem.image.getTextureReference();

    //  Start Animation
    //
    timeline->setPercentComplete(0.0);
    timeline->play();
}

//
// This will draw a mask image on the terrain that is multiplied to the background.
//
void RenderEngine::drawMask(int viewPort){
    if(!simulatorMode){
        ofSetColor(255);
        ofEnableBlendMode(OF_BLENDMODE_MULTIPLY);

        ofTexture tex;

        if(viewPort == 0){
            tex = assets->terrainMask1;
        } else {
            tex = assets->terrainMask2;
        }

        int s = tex.getWidth();
        tex.bind();
        glBegin(GL_QUADS);{
            glTexCoord2d(0, 0); glVertex2d(0, 0);
            glTexCoord2d(s, 0); glVertex2d(s, 0);
            glTexCoord2d(s, s); glVertex2d(s, s);
            glTexCoord2d(0, s); glVertex2d(0, s);
        }glEnd();
        tex.unbind();
        ofEnableAlphaBlending();
    }
}

bool RenderEngine::transitionDone(){
    return !timeline->getIsPlaying();
}<|endoftext|>