<commit_before>
#include "pch.h"
#include "slackapp.h"
#include "utils.h"

using namespace utility;              // Common utilities like string conversions
using namespace web;                  // Common features like URIs.
using namespace web::http;            // Common HTTP functionality
using namespace web::http::client;    // HTTP client features
using namespace concurrency::streams; // Asynchronous streams

//web::http::client::http_client::~http_client() noexcept {}

pplx::task<bool> slack_app::test_access_token(const string_t &access_token)
{
    printf("authing\n");
    auto path = U("auth.test?token=") + access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    })
        .then([=](json::value json) {
        return json.as_object()
            .at(U("ok"))
            .as_bool();
    });
}

pplx::task<web::uri> slack_app::get_ws_url()
{
    auto path = U("rtm.connect?token=") + _bot_access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    })
        .then([=](json::value json) {
        auto obj = json.as_object();
        auto isok = obj.at(U("ok")).as_bool();

        if (isok)
        {
            auto url = obj.at(U("url")).as_string();
            return web::uri{ url };
        }
        else
        {
            //throw std::runtime_error("TODO");
            throw std::runtime_error(N(obj.at(U("error")).as_string()));
        }
    });
}

pplx::task<void> slack_app::verify_access_tokens()
{
    printf("verifying\n");
    std::array<pplx::task<bool>, 2> tasks
    {
        test_access_token(_access_token),
        test_access_token(_bot_access_token)
    };

    pplx::task<void> combined = pplx::when_all(std::begin(tasks), std::end(tasks))
        .then([](std::vector<bool> results) {
        printf("checking\n");
        auto at_ok = results[0];
        auto bat_ok = results[1];
        if (!at_ok || !bat_ok)
        {
            std::string messages("Could not authenticate");

            if (!at_ok)
            {
                messages += "\n  Problem with access token";
            }
            if (!bat_ok)
            {
                messages += "\n  Problem with bot access token";
            }

            throw std::runtime_error(messages);
        }
    });

    return combined;
}

pplx::task<void> slack_app::listen()
{
    pplx::task_completion_event<void> tce;
    pplx::task<void> completed(tce);

    return async_do_while([=]() {
        return _rtm_client.receive().then([=](web::websockets::client::websocket_incoming_message in_msg) {

            return in_msg.extract_string().then([=](std::string msg_str) {

                printf("message: %s\n", msg_str.c_str());
                // string_t msg_str_t = to_string_t(msg_str);
                // json::value json_val = json::value::parse(msg_str_t);
                // ServerClientPacket packet(json_val);
                // receive_message(packet);

            });

        }).then([=](pplx::task<void> end_task) {
            try
            {
                end_task.get();
                return true;
            }
            catch (std::exception &e)
            {
                printf("ws error: %s\n", e.what());
            }
            catch (...)
            {
                printf("unkown error\n");
            }

            // We are here means we encountered some exception.
            // Return false to break the asynchronous loop.

            return false;
        });
    });
}

pplx::task<void> slack_app::process_loop()
{
    pplx::task<void> at_verified
    {
        _access_ok ? pplx::task_from_result() : verify_access_tokens()
    };

    // the task will resolve on disconnect
    return at_verified.then([this] {
        _access_ok = true;
        printf("verified\n");

        pplx::task<web::uri> uri_task
        {
            _rtm_url.is_empty() ? get_ws_url() : pplx::task_from_result(_rtm_url)
        };

        return uri_task;
    }).then([this](web::uri wsurl) {

        printf("got ws url\n");
        _rtm_url = wsurl;

        return _rtm_client.connect(_rtm_url);
    }).then([this](pplx::task<void> task) {

        try
        {
            task.get();
            printf("connected.\n");

            _rtm_url = U("");
        }
        catch (...)
        {
            printf("connection error.\n");

            // force re-getting url
            _rtm_url = U("");
            _access_ok = false;
            return pplx::task_from_result();
        }

        return listen();
    }).then([] {
        printf("listen over\n");
    });
}

void slack_app::run()
{
    printf("enteing\n");

    auto task = async_do_while([=] {
        return process_loop().then([=] {
            return true;
        });
    });

    task.wait();

}<commit_msg>Removed a todo comment<commit_after>
#include "pch.h"
#include "slackapp.h"
#include "utils.h"

using namespace utility;              // Common utilities like string conversions
using namespace web;                  // Common features like URIs.
using namespace web::http;            // Common HTTP functionality
using namespace web::http::client;    // HTTP client features
using namespace concurrency::streams; // Asynchronous streams

//web::http::client::http_client::~http_client() noexcept {}

pplx::task<bool> slack_app::test_access_token(const string_t &access_token)
{
    printf("authing\n");
    auto path = U("auth.test?token=") + access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    })
        .then([=](json::value json) {
        return json.as_object()
            .at(U("ok"))
            .as_bool();
    });
}

pplx::task<web::uri> slack_app::get_ws_url()
{
    auto path = U("rtm.connect?token=") + _bot_access_token;

    return _client.request(methods::POST, path)
        .then([=](http_response response) {
        return response.extract_json();
    })
        .then([=](json::value json) {
        auto obj = json.as_object();
        auto isok = obj.at(U("ok")).as_bool();

        if (isok)
        {
            auto url = obj.at(U("url")).as_string();
            return web::uri{ url };
        }
        else
        {
            throw std::runtime_error(N(obj.at(U("error")).as_string()));
        }
    });
}

pplx::task<void> slack_app::verify_access_tokens()
{
    printf("verifying\n");
    std::array<pplx::task<bool>, 2> tasks
    {
        test_access_token(_access_token),
        test_access_token(_bot_access_token)
    };

    pplx::task<void> combined = pplx::when_all(std::begin(tasks), std::end(tasks))
        .then([](std::vector<bool> results) {
        printf("checking\n");
        auto at_ok = results[0];
        auto bat_ok = results[1];
        if (!at_ok || !bat_ok)
        {
            std::string messages("Could not authenticate");

            if (!at_ok)
            {
                messages += "\n  Problem with access token";
            }
            if (!bat_ok)
            {
                messages += "\n  Problem with bot access token";
            }

            throw std::runtime_error(messages);
        }
    });

    return combined;
}

pplx::task<void> slack_app::listen()
{
    pplx::task_completion_event<void> tce;
    pplx::task<void> completed(tce);

    return async_do_while([=]() {
        return _rtm_client.receive().then([=](web::websockets::client::websocket_incoming_message in_msg) {

            return in_msg.extract_string().then([=](std::string msg_str) {

                printf("message: %s\n", msg_str.c_str());
                // string_t msg_str_t = to_string_t(msg_str);
                // json::value json_val = json::value::parse(msg_str_t);
                // ServerClientPacket packet(json_val);
                // receive_message(packet);

            });

        }).then([=](pplx::task<void> end_task) {
            try
            {
                end_task.get();
                return true;
            }
            catch (std::exception &e)
            {
                printf("ws error: %s\n", e.what());
            }
            catch (...)
            {
                printf("unkown error\n");
            }

            // We are here means we encountered some exception.
            // Return false to break the asynchronous loop.

            return false;
        });
    });
}

pplx::task<void> slack_app::process_loop()
{
    pplx::task<void> at_verified
    {
        _access_ok ? pplx::task_from_result() : verify_access_tokens()
    };

    // the task will resolve on disconnect
    return at_verified.then([this] {
        _access_ok = true;
        printf("verified\n");

        pplx::task<web::uri> uri_task
        {
            _rtm_url.is_empty() ? get_ws_url() : pplx::task_from_result(_rtm_url)
        };

        return uri_task;
    }).then([this](web::uri wsurl) {

        printf("got ws url\n");
        _rtm_url = wsurl;

        return _rtm_client.connect(_rtm_url);
    }).then([this](pplx::task<void> task) {

        try
        {
            task.get();
            printf("connected.\n");

            _rtm_url = U("");
        }
        catch (...)
        {
            printf("connection error.\n");

            // force re-getting url
            _rtm_url = U("");
            _access_ok = false;
            return pplx::task_from_result();
        }

        return listen();
    }).then([] {
        printf("listen over\n");
    });
}

void slack_app::run()
{
    printf("enteing\n");

    auto task = async_do_while([=] {
        return process_loop().then([=] {
            return true;
        });
    });

    task.wait();

}<|endoftext|>


<commit_before>#include "compare.h"
#include <cassert>
#include <cmath>

int remove_single_exon_transcripts(genome &gm)
{
	for(int i = 0; i < gm.genes.size(); i++)
	{
		gm.genes[i].remove_single_exon_transcripts();
	}
	return 0;
}

bool compare_structure(const transcript &x, const transcript &y)
{
	if(x.exons.size() != y.exons.size()) return false;
	for(int i = 0; i < x.exons.size(); i++)
	{
		if(x.exons[i].first != y.exons[i].first) return false;
		if(x.exons[i].second != y.exons[i].second) return false;
	}
	return true;
}

bool compare_intron_chain(const transcript &x, const transcript &y)
{
	if(x.exons.size() != y.exons.size()) return false;
	double diff1;
	double diff2;
	for(int i = 0; i < x.exons.size(); i++)
	{
		if(i == 0) diff1 = 200;
		else diff1 = 0.5;

		if(i == x.exons.size() - 1) diff2 = 200;
		else diff2 = 0.5;

		if(fabs(x.exons[i].first - y.exons[i].first) > diff1) return false;
		if(fabs(x.exons[i].second - y.exons[i].second) > diff2) return false;
	}
	return true;
}

bool compare_expression(const transcript &x, const transcript &y)
{
	if(x.expression == y.expression) return true;
	else return false;
}

int compare_gene(const gene &x, const gene &y, int mode)
{
	return compare_transcripts(x.transcripts, y.transcripts, mode);
}

int compare_transcripts(const vector<transcript> &y, const vector<transcript> &x, int mode)
{
	int cnt = 0;
	vector<bool> v;
	v.assign(y.size(), false);
	for(int i = 0; i < x.size(); i++)
	{
		const transcript &t1 = x[i];
		bool flag = false;
		for(int j = 0; j < y.size(); j++)
		{
			if(v[j] == true) continue;
			const transcript &t2 = y[j];
			bool b = false;
			if(mode == 1)
			{
				if(compare_structure(t1, t2) == false) b = false;
				if(compare_expression(t1, t2) == false) b = false;
			}
			if(mode == 2)
			{
				b = compare_intron_chain(t1, t2);
				//if(t1.strand != t2.strand) b = false;
			}

			if(b == false) continue;

			//printf("%s %s matched, reference expression = %d predicted expression = %d, strands = (%c, %c)\n",
			//	t1.transcript_id.c_str(), t2.transcript_id.c_str(), t1.expression, t2.expression, t1.strand, t2.strand);

			printf("TRUE %s %s %s %s\n", t1.gene_id.c_str(), t1.transcript_id.c_str(), t1.label().c_str(), t2.transcript_id.c_str());

			flag = true;
			v[j] = true;
			cnt++;
			break;
		}

		if(flag == false) printf("FALSE %s %s %s\n", t1.gene_id.c_str(), t1.transcript_id.c_str(), t1.label().c_str());
	}
	return cnt;
}

int compare_genome1(const genome &x, const genome &y)
{
	int gequal = 0;
	int tequal = 0;
	int gtotal = x.genes.size();
	int ttotal = 0;
	for(int i = 0; i < x.genes.size(); i++)
	{
		const gene* gx = &(x.genes[i]);
		const gene* gy = y.get_gene(x.genes[i].get_gene_id());
		if(gx == NULL || gy == NULL) continue;
		int tx = gx->transcripts.size();
		int ty = gy->transcripts.size();
		int t0 = compare_gene(*gx, *gy, 1);
		assert(t0 <= tx);
		assert(t0 <= ty);
		ttotal += tx;
		tequal += t0;
		if(t0 == tx) gequal++;
		string s;
		if(tx == ty) s = "EQUAL";
		else if(tx > ty) s = "GREATER";
		else s = "LESS";
		printf("%s %d and %d transcripts, %d are equal, %s, %s\n", gx->get_gene_id().c_str(), tx, ty, t0, (t0 == tx) ? "TRUE" : "FALSE", s.c_str());
	}
	printf("summary: %d out of %d genes are equal, %d out of %d transcripts are equal\n",
			gequal, gtotal, tequal, ttotal);
	return 0;
}

int compare_genome2(const genome &x, const genome &y)
{
	typedef pair< string, vector<transcript> > PSVT;
	typedef map< string, vector<transcript> > MSVT;
	MSVT m1;
	MSVT m2;

	int xtotal = 0;
	int ytotal = 0;
	for(int i = 0; i < x.genes.size(); i++)
	{
		string chrm = x.genes[i].get_seqname();
		const vector<transcript> &v = x.genes[i].transcripts;
		xtotal += v.size();
		if(m1.find(chrm) == m1.end())
		{
			m1.insert(PSVT(chrm, v));
		}
		else
		{
			m1[chrm].insert(m1[chrm].end(), v.begin(), v.end());
		}
	}

	for(int i = 0; i < y.genes.size(); i++)
	{
		string chrm = y.genes[i].get_seqname();
		const vector<transcript> &v = y.genes[i].transcripts;
		ytotal += v.size();
		if(m2.find(chrm) == m2.end())
		{
			m2.insert(PSVT(chrm, v));
		}
		else
		{
			m2[chrm].insert(m2[chrm].end(), v.begin(), v.end());
		}
	}

	int correct = 0;
	for(MSVT::iterator it = m1.begin(); it != m1.end(); it++)
	{
		const vector<transcript> &v1 = it->second;
		if(m2.find(it->first) == m2.end()) continue;
		const vector<transcript> &v2 = m2[it->first];

		correct += compare_transcripts(v1, v2, 2);
	}

	double s = (xtotal == 0) ? 0 : correct * 100.0 / xtotal;
	double p = (ytotal == 0) ? 0 : correct * 100.0 / ytotal;
	printf("reference = %d prediction = %d correct = %d sensitivity = %.2lf precision = %.2lf\n", xtotal, ytotal, correct, s, p);

	return 0;
}

<commit_msg>recover comparing strand<commit_after>#include "compare.h"
#include <cassert>
#include <cmath>

int remove_single_exon_transcripts(genome &gm)
{
	for(int i = 0; i < gm.genes.size(); i++)
	{
		gm.genes[i].remove_single_exon_transcripts();
	}
	return 0;
}

bool compare_structure(const transcript &x, const transcript &y)
{
	if(x.exons.size() != y.exons.size()) return false;
	for(int i = 0; i < x.exons.size(); i++)
	{
		if(x.exons[i].first != y.exons[i].first) return false;
		if(x.exons[i].second != y.exons[i].second) return false;
	}
	return true;
}

bool compare_intron_chain(const transcript &x, const transcript &y)
{
	if(x.exons.size() != y.exons.size()) return false;

	if(x.exons.size() == 0) return false;

	if(x.exons.size() == 1)
	{
		if(fabs(x.exons[0].first - y.exons[0].first) > 100) return false;
		if(fabs(x.exons[0].second - y.exons[0].second) > 100) return false;
		return true;
	}

	for(int i = 0; i < x.exons.size(); i++)
	{
		double diff1 = 0.5;
		double diff2 = 0.5;
		if(i == 0) diff1 = 9999999999;
		if(i == x.exons.size() - 1) diff2 = 9999999999;

		if(fabs(x.exons[i].first - y.exons[i].first) > diff1) return false;
		if(fabs(x.exons[i].second - y.exons[i].second) > diff2) return false;
	}
	return true;
}

bool compare_expression(const transcript &x, const transcript &y)
{
	if(x.expression == y.expression) return true;
	else return false;
}

int compare_gene(const gene &x, const gene &y, int mode)
{
	return compare_transcripts(x.transcripts, y.transcripts, mode);
}

int compare_transcripts(const vector<transcript> &y, const vector<transcript> &x, int mode)
{
	int cnt = 0;
	vector<bool> v;
	v.assign(y.size(), false);
	for(int i = 0; i < x.size(); i++)
	{
		const transcript &t1 = x[i];
		bool flag = false;
		for(int j = 0; j < y.size(); j++)
		{
			if(v[j] == true) continue;
			const transcript &t2 = y[j];
			bool b = false;
			if(mode == 1)
			{
				if(compare_structure(t1, t2) == false) b = false;
				if(compare_expression(t1, t2) == false) b = false;
			}
			if(mode == 2)
			{
				b = compare_intron_chain(t1, t2);
				if(t1.strand != t2.strand) b = false;
			}

			if(b == false) continue;

			//printf("%s %s matched, reference expression = %d predicted expression = %d, strands = (%c, %c)\n",
			//	t1.transcript_id.c_str(), t2.transcript_id.c_str(), t1.expression, t2.expression, t1.strand, t2.strand);

			printf("TRUE %s %s %s %s\n", t1.gene_id.c_str(), t1.transcript_id.c_str(), t1.label().c_str(), t2.transcript_id.c_str());

			flag = true;
			v[j] = true;
			cnt++;
			break;
		}

		if(flag == false) printf("FALSE %s %s %s\n", t1.gene_id.c_str(), t1.transcript_id.c_str(), t1.label().c_str());
	}
	return cnt;
}

int compare_genome1(const genome &x, const genome &y)
{
	int gequal = 0;
	int tequal = 0;
	int gtotal = x.genes.size();
	int ttotal = 0;
	for(int i = 0; i < x.genes.size(); i++)
	{
		const gene* gx = &(x.genes[i]);
		const gene* gy = y.get_gene(x.genes[i].get_gene_id());
		if(gx == NULL || gy == NULL) continue;
		int tx = gx->transcripts.size();
		int ty = gy->transcripts.size();
		int t0 = compare_gene(*gx, *gy, 1);
		assert(t0 <= tx);
		assert(t0 <= ty);
		ttotal += tx;
		tequal += t0;
		if(t0 == tx) gequal++;
		string s;
		if(tx == ty) s = "EQUAL";
		else if(tx > ty) s = "GREATER";
		else s = "LESS";
		printf("%s %d and %d transcripts, %d are equal, %s, %s\n", gx->get_gene_id().c_str(), tx, ty, t0, (t0 == tx) ? "TRUE" : "FALSE", s.c_str());
	}
	printf("summary: %d out of %d genes are equal, %d out of %d transcripts are equal\n",
			gequal, gtotal, tequal, ttotal);
	return 0;
}

int compare_genome2(const genome &x, const genome &y)
{
	typedef pair< string, vector<transcript> > PSVT;
	typedef map< string, vector<transcript> > MSVT;
	MSVT m1;
	MSVT m2;

	int xtotal = 0;
	int ytotal = 0;
	for(int i = 0; i < x.genes.size(); i++)
	{
		string chrm = x.genes[i].get_seqname();
		const vector<transcript> &v = x.genes[i].transcripts;
		xtotal += v.size();
		if(m1.find(chrm) == m1.end())
		{
			m1.insert(PSVT(chrm, v));
		}
		else
		{
			m1[chrm].insert(m1[chrm].end(), v.begin(), v.end());
		}
	}

	for(int i = 0; i < y.genes.size(); i++)
	{
		string chrm = y.genes[i].get_seqname();
		const vector<transcript> &v = y.genes[i].transcripts;
		ytotal += v.size();
		if(m2.find(chrm) == m2.end())
		{
			m2.insert(PSVT(chrm, v));
		}
		else
		{
			m2[chrm].insert(m2[chrm].end(), v.begin(), v.end());
		}
	}

	int correct = 0;
	for(MSVT::iterator it = m1.begin(); it != m1.end(); it++)
	{
		const vector<transcript> &v1 = it->second;
		if(m2.find(it->first) == m2.end()) continue;
		const vector<transcript> &v2 = m2[it->first];

		correct += compare_transcripts(v1, v2, 2);
	}

	double s = (xtotal == 0) ? 0 : correct * 100.0 / xtotal;
	double p = (ytotal == 0) ? 0 : correct * 100.0 / ytotal;
	printf("reference = %d prediction = %d correct = %d sensitivity = %.2lf precision = %.2lf\n", xtotal, ytotal, correct, s, p);

	return 0;
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007-2014 Frank Mertens.
 *
 * Use of this source is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 */

#include <flux/System.h>
#include <flux/LineSource.h>
#include <flux/stream/TransferLimiter.h>
#include <flux/stream/StreamTap.h>
#include <flux/stream/LineBuffer.h>
#include "exceptions.h"
#include "ErrorLog.h"
#include "TapBuffer.h"
#include "RequestStream.h"
#include "ClientConnection.h"

namespace fluxnode
{

using namespace flux::stream;

Ref<ClientConnection> ClientConnection::create(StreamSocket *socket, SocketAddress *address)
{
	return new ClientConnection(socket, address);
}

ClientConnection::ClientConnection(StreamSocket *socket, SocketAddress *address)
	: requestStream_(RequestStream::open(socket)),
	  stream_(requestStream_),
	  address_(address),
	  visit_(Visit::create(address_))
{
	if (errorLog()->level() >= DebugLogLevel) {
		Ref<Stream> requestBuffer = TapBuffer::open(errorLog()->debugStream(), address_->networkAddress() + " > ");
		Ref<Stream> responseBuffer = TapBuffer::open(errorLog()->debugStream(), address_->networkAddress() + " < ");
		stream_ = StreamTap::open(stream_, requestBuffer, responseBuffer);
	}
}

Ref<Request> ClientConnection::readRequest()
{
	if (pendingRequest_) {
		Ref<Request> h = pendingRequest_;
		pendingRequest_ = 0;
		return h;
	}
	request_ = 0;
	request_ = scanRequest();
	return request_;
}

void ClientConnection::putBack(Request *request)
{
	pendingRequest_ = request;
}

void ClientConnection::setupTimeout(double interval)
{
	requestStream_->setupTimeout(interval);
}

bool ClientConnection::isPayloadConsumed() const
{
	return requestStream_->isPayloadConsumed();
}

Ref<Request> ClientConnection::scanRequest()
{
	requestStream_->nextHeader();

	Ref<Request> request = Request::create();
	request->payload_ = stream_;
	request->time_ = System::now();

	try {
		Ref<TransferLimiter> limiter = TransferLimiter::open(stream_, 0x10000);
		Ref<ByteArray> buf = ByteArray::create(0xFFF);
		Ref<LineSource> source = LineSource::open(limiter, buf);

		String line;

		if (!source->read(&line)) throw CloseRequest();
		request->line_ = line;

		if (line->count(' ') != 2) throw BadRequest();
		{
			int i0 = 0, i1 = line->find(' ');
			request->method_ = line->copy(i0, i1);
			i0 = i1 + 1; i1 = line->find(' ', i0);
			request->target_ = line->copy(i0, i1);
			request->version_ = line->copy(i1 + 1, line->count());
		}

		if (request->version_ != "HTTP/1.1") throw UnsupportedVersion();

		String name, value;
		Ref<StringList> multiValue;
		while (source->read(&line)) {
			if (line == "")
				break;
			if (line->at(0) == ' ' || line->at(0) == '\t') {
				if (!multiValue) {
					multiValue = StringList::create();
					multiValue->append(value);
				}
				multiValue->append(line->trimInsitu());
				continue;
			}
			if (multiValue) {
				request->establish(name, multiValue->join());
				multiValue = 0;
			}
			int i = line->find(':');
			if (i == line->count()) throw BadRequest();
			name = line->copy(0, i)->trimInsitu();
			value = line->copy(i + 1, line->count())->trimInsitu();
			request->establish(name, value);
		}
		if (multiValue)
			request->establish(name, multiValue->join());
	}
	catch (ReadLimitExceeded &) {
		throw BadRequest();
	}

	request->host_ = request->value("Host");
	request->host_->downcaseInsitu();
	if (request->host_ == "") throw BadRequest();

	if (request->value("Transfer-Encoding") == "chunked") {
		requestStream_->nextChunk();
	}
	else {
		int64_t length = 0;
		String h;
		if (request->lookup("Content-Length", &h)) {
			bool ok = true;
			length = h->toInt64(&ok);
			if (!ok || length < 0) throw BadRequest();
		}
		requestStream_->nextPayload(length);
	}

	return request;
}

} // namespace fluxnode
<commit_msg>Improved version check, also accept HTTP/1.0 requests<commit_after>/*
 * Copyright (C) 2007-2014 Frank Mertens.
 *
 * Use of this source is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 */

#include <flux/System.h>
#include <flux/LineSource.h>
#include <flux/stream/TransferLimiter.h>
#include <flux/stream/StreamTap.h>
#include <flux/stream/LineBuffer.h>
#include "exceptions.h"
#include "ErrorLog.h"
#include "TapBuffer.h"
#include "RequestStream.h"
#include "ClientConnection.h"

namespace fluxnode
{

using namespace flux::stream;

Ref<ClientConnection> ClientConnection::create(StreamSocket *socket, SocketAddress *address)
{
	return new ClientConnection(socket, address);
}

ClientConnection::ClientConnection(StreamSocket *socket, SocketAddress *address)
	: requestStream_(RequestStream::open(socket)),
	  stream_(requestStream_),
	  address_(address),
	  visit_(Visit::create(address_))
{
	if (errorLog()->level() >= DebugLogLevel) {
		Ref<Stream> requestBuffer = TapBuffer::open(errorLog()->debugStream(), address_->networkAddress() + " > ");
		Ref<Stream> responseBuffer = TapBuffer::open(errorLog()->debugStream(), address_->networkAddress() + " < ");
		stream_ = StreamTap::open(stream_, requestBuffer, responseBuffer);
	}
}

Ref<Request> ClientConnection::readRequest()
{
	if (pendingRequest_) {
		Ref<Request> h = pendingRequest_;
		pendingRequest_ = 0;
		return h;
	}
	request_ = 0;
	request_ = scanRequest();
	return request_;
}

void ClientConnection::putBack(Request *request)
{
	pendingRequest_ = request;
}

void ClientConnection::setupTimeout(double interval)
{
	requestStream_->setupTimeout(interval);
}

bool ClientConnection::isPayloadConsumed() const
{
	return requestStream_->isPayloadConsumed();
}

Ref<Request> ClientConnection::scanRequest()
{
	requestStream_->nextHeader();

	Ref<Request> request = Request::create();
	request->payload_ = stream_;
	request->time_ = System::now();

	try {
		Ref<TransferLimiter> limiter = TransferLimiter::open(stream_, 0x10000);
		Ref<ByteArray> buf = ByteArray::create(0xFFF);
		Ref<LineSource> source = LineSource::open(limiter, buf);

		String line;

		if (!source->read(&line)) throw CloseRequest();
		request->line_ = line;

		if (line->count(' ') != 2) throw BadRequest();
		{
			int i0 = 0, i1 = line->find(' ');
			request->method_ = line->copy(i0, i1);
			i0 = i1 + 1; i1 = line->find(' ', i0);
			request->target_ = line->copy(i0, i1);
			request->version_ = line->copy(i1 + 1, line->count());
		}

		{
			int majorVersion = 1, minorVersion = 1;
			int i = request->version_->find('/');
			i = request->version_->scanInt(&majorVersion, i + 1);
			request->version_->scanInt(&minorVersion, i + 1);
			if (majorVersion > 1) throw UnsupportedVersion();
		}

		String name, value;
		Ref<StringList> multiValue;
		while (source->read(&line)) {
			if (line == "")
				break;
			if (line->at(0) == ' ' || line->at(0) == '\t') {
				if (!multiValue) {
					multiValue = StringList::create();
					multiValue->append(value);
				}
				multiValue->append(line->trimInsitu());
				continue;
			}
			if (multiValue) {
				request->establish(name, multiValue->join());
				multiValue = 0;
			}
			int i = line->find(':');
			if (i == line->count()) throw BadRequest();
			name = line->copy(0, i)->trimInsitu();
			value = line->copy(i + 1, line->count())->trimInsitu();
			request->establish(name, value);
		}
		if (multiValue)
			request->establish(name, multiValue->join());
	}
	catch (ReadLimitExceeded &) {
		throw BadRequest();
	}

	request->host_ = request->value("Host");
	request->host_->downcaseInsitu();
	if (request->host_ == "") throw BadRequest();

	if (request->value("Transfer-Encoding") == "chunked") {
		requestStream_->nextChunk();
	}
	else {
		int64_t length = 0;
		String h;
		if (request->lookup("Content-Length", &h)) {
			bool ok = true;
			length = h->toInt64(&ok);
			if (!ok || length < 0) throw BadRequest();
		}
		requestStream_->nextPayload(length);
	}

	return request;
}

} // namespace fluxnode
<|endoftext|>


<commit_before>#include <QString>
#include <functional>
#include <future>
#include <memory>
#include "kernel.h"
#include "ilwisdata.h"
#include "datadefinition.h"
#include "columndefinition.h"
#include "attributedefinition.h"
#include "raster.h"
#include "table.h"
#include "featurecoverage.h"
#include "feature.h"
#include "symboltable.h"
#include "operationExpression.h"
#include "operationmetadata.h"
#include "operation.h"
#include "commandhandler.h"
#include "operationhelper.h"

using namespace Ilwis;

OperationHelper::OperationHelper()
{
}

void OperationHelper::initialize(const IIlwisObject &inputObject, Ilwis::IIlwisObject &outputObject, IlwisTypes tp, quint64 what)
{
    if (inputObject->ilwisType() & itCOVERAGE) {
        ICoverage covInput = inputObject.as<Coverage>();
        ICoverage covOutput = outputObject.as<Coverage>();
        if ( what & itENVELOPE) {
            Envelope bounds = covInput->envelope();
            covOutput->envelope(bounds);
        }
        if ( what & itCOORDSYSTEM) {
            covOutput->coordinateSystem(covInput->coordinateSystem());
        }
        if ( hasType(what,itDOMAIN) && hasType(tp, itRASTER) ) {
            IRasterCoverage rasCoverageIn = inputObject.as<RasterCoverage>();
            IRasterCoverage rasCoverageOut = outputObject.as<RasterCoverage>();
            rasCoverageOut->datadefRef() = rasCoverageIn->datadef();
        }

        if ( hasType(what,itGEOREF) && hasType(tp, itRASTER) ) {
            IRasterCoverage rasCoverageIn = inputObject.as<RasterCoverage>();
            IRasterCoverage rasCoverageOut = outputObject.as<RasterCoverage>();
            rasCoverageOut->georeference(rasCoverageIn->georeference());
        }

        if ( hasType(what,itRASTERSIZE) && hasType(tp, itRASTER) ) {
            IRasterCoverage rasCoverageIn = inputObject.as<RasterCoverage>();
            IRasterCoverage rasCoverageOut = outputObject.as<RasterCoverage>();
            rasCoverageOut->size(rasCoverageIn->size());
        }

        if ( hasType(what,itTABLE)) {
            if ( hasType(tp, itRASTER)) {
                IRasterCoverage rasCoverageIn = inputObject.as<RasterCoverage>();
                IRasterCoverage rasCoverageOut = outputObject.as<RasterCoverage>();
                if ( !rasCoverageIn.isValid() || !rasCoverageOut.isValid())
                    return;
                if(rasCoverageIn->datadef().domain<>() != rasCoverageOut->datadef().domain<>())
                    return;
                rasCoverageOut->attributeTable(rasCoverageIn->attributeTable());
            }
        }
    }
}
<commit_msg>incorrect initialization of rastercoverage. leftover of the changes to indexes etc. a month ago<commit_after>#include <QString>
#include <functional>
#include <future>
#include <memory>
#include "kernel.h"
#include "ilwisdata.h"
#include "datadefinition.h"
#include "columndefinition.h"
#include "attributedefinition.h"
#include "raster.h"
#include "table.h"
#include "featurecoverage.h"
#include "feature.h"
#include "symboltable.h"
#include "operationExpression.h"
#include "operationmetadata.h"
#include "operation.h"
#include "commandhandler.h"
#include "operationhelper.h"

using namespace Ilwis;

OperationHelper::OperationHelper()
{
}

void OperationHelper::initialize(const IIlwisObject &inputObject, Ilwis::IIlwisObject &outputObject, IlwisTypes tp, quint64 what)
{
    if (inputObject->ilwisType() & itCOVERAGE) {
        ICoverage covInput = inputObject.as<Coverage>();
        ICoverage covOutput = outputObject.as<Coverage>();
        if ( what & itENVELOPE) {
            Envelope bounds = covInput->envelope();
            covOutput->envelope(bounds);
        }
        if ( what & itCOORDSYSTEM) {
            covOutput->coordinateSystem(covInput->coordinateSystem());
        }
        if ( hasType(what,itDOMAIN) && hasType(tp, itRASTER) ) {
            IRasterCoverage rasCoverageIn = inputObject.as<RasterCoverage>();
            IRasterCoverage rasCoverageOut = outputObject.as<RasterCoverage>();
            rasCoverageOut->datadefRef() = rasCoverageIn->datadef();
            rasCoverageOut->datadefRef(0) = rasCoverageIn->datadef();
            IDomain dom("integer");
            std::vector<double> stack{0.0};
            rasCoverageOut->stackDefinitionRef().setSubDefinition(dom, stack);

        }

        if ( hasType(what,itGEOREF) && hasType(tp, itRASTER) ) {
            IRasterCoverage rasCoverageIn = inputObject.as<RasterCoverage>();
            IRasterCoverage rasCoverageOut = outputObject.as<RasterCoverage>();
            rasCoverageOut->georeference(rasCoverageIn->georeference());
        }

        if ( hasType(what,itRASTERSIZE) && hasType(tp, itRASTER) ) {
            IRasterCoverage rasCoverageIn = inputObject.as<RasterCoverage>();
            IRasterCoverage rasCoverageOut = outputObject.as<RasterCoverage>();
            rasCoverageOut->size(rasCoverageIn->size());
        }

        if ( hasType(what,itTABLE)) {
            if ( hasType(tp, itRASTER)) {
                IRasterCoverage rasCoverageIn = inputObject.as<RasterCoverage>();
                IRasterCoverage rasCoverageOut = outputObject.as<RasterCoverage>();
                if ( !rasCoverageIn.isValid() || !rasCoverageOut.isValid())
                    return;
                if(rasCoverageIn->datadef().domain<>() != rasCoverageOut->datadef().domain<>())
                    return;
                rasCoverageOut->attributeTable(rasCoverageIn->attributeTable());
            }
        }
    }
}
<|endoftext|>


<commit_before>/*
 *  GF256.cpp
 *  zxing
 *
 *  Created by Christian Brunschen on 05/05/2008.
 *  Copyright 2008 Google UK. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <vector>
#include <iostream>
#include <zxing/common/reedsolomon/GF256.h>
#include <zxing/common/reedsolomon/GF256Poly.h>
#include <zxing/common/IllegalArgumentException.h>
#include <zxing/common/Array.h>
#include <zxing/common/Counted.h>

namespace zxing {
using namespace std;

static inline ArrayRef<int> makeArray(int value) {
  ArrayRef<int> valuesRef(new Array<int> (value, 1));
  return valuesRef;
}

static inline Ref<GF256Poly> refPoly(GF256 &field, int value) {
  ArrayRef<int> values(makeArray(value));
  Ref<GF256Poly> result(new GF256Poly(field, values));
  return result;
}

GF256::GF256(int primitive) :
    exp_(256, (const int)0), log_(256, (const int)0), zero_(refPoly(*this, 0)), one_(refPoly(*this, 1)) {
  int x = 1;
  for (int i = 0; i < 256; i++) {
    exp_[i] = x;
    x <<= 1;
    if (x >= 0x100) {
      x ^= primitive;
    }
  }

  // log(0) == 0, but should never be used
  log_[0] = 0;
  for (int i = 0; i < 255; i++) {
    log_[exp_[i]] = i;
  }
}

Ref<GF256Poly> GF256::getZero() {
  return zero_;
}

Ref<GF256Poly> GF256::getOne() {
  return one_;
}

Ref<GF256Poly> GF256::buildMonomial(int degree, int coefficient) {
#ifdef DEBUG
  cout << __FUNCTION__ << "\n";
#endif
  if (degree < 0) {
    throw IllegalArgumentException("Degree must be non-negative");
  }
  if (coefficient == 0) {
    return zero_;
  }
  int nCoefficients = degree + 1;
  ArrayRef<int> coefficients(new Array<int> (nCoefficients));
  coefficients[0] = coefficient;
  Ref<GF256Poly> result(new GF256Poly(*this, coefficients));
  return result;
}

int GF256::addOrSubtract(int a, int b) {
  return a ^ b;
}

int GF256::exp(int a) {
  return exp_[a];
}

int GF256::log(int a) {
  if (a == 0) {
    throw IllegalArgumentException("Cannot take the logarithm of 0");
  }
  return log_[a];
}

int GF256::inverse(int a) {
  if (a == 0) {
    throw IllegalArgumentException("Cannot calculate the inverse of 0");
  }
  return exp_[255 - log_[a]];
}

int GF256::multiply(int a, int b) {
  if (a == 0 || b == 0) {
    return 0;
  }
  if (a == 1) {
    return b;
  }
  if (b == 1) {
    return a;
  }
  return exp_[(log_[a] + log_[b]) % 255];
}

GF256 GF256::QR_CODE_FIELD(0x011D); // x^8 + x^4 + x^3 + x^2 + 1
GF256 GF256::DATA_MATRIX_FIELD(0x012D); // x^8 + x^5 + x^3 + x^2 + 1

ostream& operator<<(ostream& out, const GF256& field) {
  out << "Field[\nexp=(";
  out << field.exp_[0];
  for (int i = 1; i < 256; i++) {
    out << "," << field.exp_[i];
  }
  out << "),\nlog=(";
  out << field.log_[0];
  for (int i = 1; i < 256; i++) {
    out << "," << field.log_[i];
  }
  out << ")\n]";
  return out;
}

}
<commit_msg>Same change as Revision r1395 for C++ port: Small speedup, per issue 422<commit_after>/*
 *  GF256.cpp
 *  zxing
 *
 *  Created by Christian Brunschen on 05/05/2008.
 *  Copyright 2008 Google UK. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <vector>
#include <iostream>
#include <zxing/common/reedsolomon/GF256.h>
#include <zxing/common/reedsolomon/GF256Poly.h>
#include <zxing/common/IllegalArgumentException.h>
#include <zxing/common/Array.h>
#include <zxing/common/Counted.h>

namespace zxing {
using namespace std;

static inline ArrayRef<int> makeArray(int value) {
  ArrayRef<int> valuesRef(new Array<int> (value, 1));
  return valuesRef;
}

static inline Ref<GF256Poly> refPoly(GF256 &field, int value) {
  ArrayRef<int> values(makeArray(value));
  Ref<GF256Poly> result(new GF256Poly(field, values));
  return result;
}

GF256::GF256(int primitive) :
    exp_(256, (const int)0), log_(256, (const int)0), zero_(refPoly(*this, 0)), one_(refPoly(*this, 1)) {
  int x = 1;
  for (int i = 0; i < 256; i++) {
    exp_[i] = x;
    x <<= 1;
    if (x >= 0x100) {
      x ^= primitive;
    }
  }

  // log(0) == 0, but should never be used
  log_[0] = 0;
  for (int i = 0; i < 255; i++) {
    log_[exp_[i]] = i;
  }
}

Ref<GF256Poly> GF256::getZero() {
  return zero_;
}

Ref<GF256Poly> GF256::getOne() {
  return one_;
}

Ref<GF256Poly> GF256::buildMonomial(int degree, int coefficient) {
#ifdef DEBUG
  cout << __FUNCTION__ << "\n";
#endif
  if (degree < 0) {
    throw IllegalArgumentException("Degree must be non-negative");
  }
  if (coefficient == 0) {
    return zero_;
  }
  int nCoefficients = degree + 1;
  ArrayRef<int> coefficients(new Array<int> (nCoefficients));
  coefficients[0] = coefficient;
  Ref<GF256Poly> result(new GF256Poly(*this, coefficients));
  return result;
}

int GF256::addOrSubtract(int a, int b) {
  return a ^ b;
}

int GF256::exp(int a) {
  return exp_[a];
}

int GF256::log(int a) {
  if (a == 0) {
    throw IllegalArgumentException("Cannot take the logarithm of 0");
  }
  return log_[a];
}

int GF256::inverse(int a) {
  if (a == 0) {
    throw IllegalArgumentException("Cannot calculate the inverse of 0");
  }
  return exp_[255 - log_[a]];
}

int GF256::multiply(int a, int b) {
  if (a == 0 || b == 0) {
    return 0;
  }
  int logSum = log_[a] + log_[b];
  // index is a sped-up alternative to logSum % 255 since sum
  // is in [0,510]. Thanks to jmsachs for the idea
  return exp_[(logSum & 0xFF) + (logSum >> 8)];
}

GF256 GF256::QR_CODE_FIELD(0x011D); // x^8 + x^4 + x^3 + x^2 + 1
GF256 GF256::DATA_MATRIX_FIELD(0x012D); // x^8 + x^5 + x^3 + x^2 + 1

ostream& operator<<(ostream& out, const GF256& field) {
  out << "Field[\nexp=(";
  out << field.exp_[0];
  for (int i = 1; i < 256; i++) {
    out << "," << field.exp_[i];
  }
  out << "),\nlog=(";
  out << field.log_[0];
  for (int i = 1; i < 256; i++) {
    out << "," << field.log_[i];
  }
  out << ")\n]";
  return out;
}

}
<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/modtools.h"

#include <type_traits>

USING_YOSYS_NAMESPACE
using namespace RTLIL;

PRIVATE_NAMESPACE_BEGIN

struct WreduceConfig
{
	std::set<IdString> supported_cell_types;

	WreduceConfig()
	{
		supported_cell_types.insert("$not");
		supported_cell_types.insert("$pos");
		supported_cell_types.insert("$bu0");
		supported_cell_types.insert("$neg");

		supported_cell_types.insert("$and");
		supported_cell_types.insert("$or");
		supported_cell_types.insert("$xor");
		supported_cell_types.insert("$xnor");

		supported_cell_types.insert("$shl");
		supported_cell_types.insert("$shr");
		supported_cell_types.insert("$sshl");
		supported_cell_types.insert("$sshr");
		supported_cell_types.insert("$shift");
		supported_cell_types.insert("$shiftx");

		supported_cell_types.insert("$lt");
		supported_cell_types.insert("$le");
		supported_cell_types.insert("$eq");
		supported_cell_types.insert("$ne");
		supported_cell_types.insert("$eqx");
		supported_cell_types.insert("$nex");
		supported_cell_types.insert("$ge");
		supported_cell_types.insert("$gt");

		supported_cell_types.insert("$add");
		supported_cell_types.insert("$sub");
		// supported_cell_types.insert("$mul");
		// supported_cell_types.insert("$div");
		// supported_cell_types.insert("$mod");
		// supported_cell_types.insert("$pow");

		// supported_cell_types.insert("$mux");
		// supported_cell_types.insert("$pmux");
		// supported_cell_types.insert("$safe_pmux");
	}
};

struct WreduceWorker
{
	WreduceConfig *config;
	Module *module;
	ModIndex mi;

	std::set<Cell*, IdString::compare_ptr_by_name<Cell>> work_queue_cells;
	std::set<SigBit> work_queue_bits;
	SigMap constmap;

	WreduceWorker(WreduceConfig *config, Module *module) :
			config(config), module(module), mi(module) { }

	void run_reduce_inport(Cell *cell, char port)
	{
		bool is_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool();
		SigSpec sig = mi.sigmap(cell->getPort(stringf("\\%c", port)));

		int bits_removed = 0;
		if (is_signed) {
			while (SIZE(sig) > 1 && constmap(sig[SIZE(sig)-1]) == constmap(sig[SIZE(sig)-2]))
				work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++;
		} else {
			while (SIZE(sig) > 1 && constmap(sig[SIZE(sig)-1]) == S0)
				work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++;
		}

		if (bits_removed) {
			log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n",
					bits_removed, SIZE(sig) + bits_removed, port, log_id(module), log_id(cell), log_id(cell->type));
			cell->setPort(stringf("\\%c", port), sig);
		}
	}

	void run_cell(Cell *cell)
	{
		if (!cell->type.in(config->supported_cell_types))
			return;

		if (cell->type.in("$shl", "$shr", "$sshl", "$sshr"))
			cell->setParam("\\B_SIGNED", false);

		if (cell->hasParam("\\A_SIGNED"))
			run_reduce_inport(cell, 'A');

		if (cell->hasParam("\\B_SIGNED"))
			run_reduce_inport(cell, 'B');

		SigSpec sig = mi.sigmap(cell->getPort("\\Y"));

		int bits_removed = 0;
		while (SIZE(sig) > 0)
		{
			auto info = mi.query(sig[SIZE(sig)-1]);

			if (info->is_output || SIZE(info->ports) > 1)
				break;

			sig.remove(SIZE(sig)-1);
			bits_removed++;
		}

		if (cell->type.in("$pos", "$bu0", "$add", "$mul", "$and", "$or", "$xor"))
		{
			bool is_signed = cell->getParam("\\A_SIGNED").as_bool();

			int a_size = 0, b_size = 0;
			if (cell->hasPort("\\A")) a_size = SIZE(cell->getPort("\\A"));
			if (cell->hasPort("\\B")) b_size = SIZE(cell->getPort("\\B"));

			int max_y_size = std::max(a_size, b_size);

			if (cell->type == "$add")
				max_y_size++;

			if (cell->type == "$mul")
				max_y_size = a_size + b_size;

			while (SIZE(sig) > 1 && SIZE(sig) > max_y_size) {
				module->connect(sig[SIZE(sig)-1], is_signed ? sig[SIZE(sig)-2] : S0);
				sig.remove(SIZE(sig)-1);
				bits_removed++;
			}
		}

		if (bits_removed) {
			log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n",
					bits_removed, SIZE(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type));
			cell->setPort("\\Y", sig);
		}

		cell->fixup_parameters();
	}

	void run()
	{
		for (auto c : module->selected_cells())
			work_queue_cells.insert(c);

		while (!work_queue_cells.empty())
		{
			work_queue_bits.clear();
			for (auto c : work_queue_cells)
				run_cell(c);

			work_queue_cells.clear();
			for (auto bit : work_queue_bits)
			for (auto port : mi.query_ports(bit))
				work_queue_cells.insert(port.cell);
		}
	}
};

struct WreducePass : public Pass {
	WreducePass() : Pass("wreduce", "reduce the word size of operations is possible") { }
	virtual void help()
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    wreduce [options] [selection]\n");
		log("\n");
		log("This command reduces the word size of operations.\n");
		log("\n");
	}
	virtual void execute(std::vector<std::string> args, Design *design)
	{
		WreduceConfig config;

		log_header("Executing WREDUCE pass (reducing word size of cells).\n");

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			break;
		}
		extra_args(args, argidx, design);

		for (auto module : design->selected_modules())
		{
			if (module->has_processes_warn())
				continue;

			WreduceWorker worker(&config, module);
			worker.run();
		}
	}
} WreducePass;

PRIVATE_NAMESPACE_END

<commit_msg>Added mux support to wreduce command<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/modtools.h"

#include <type_traits>

USING_YOSYS_NAMESPACE
using namespace RTLIL;

PRIVATE_NAMESPACE_BEGIN

static inline std::set<IdString> &operator<<(std::set<IdString> &set, IdString id) {
	set.insert(id);
	return set;
}

struct WreduceConfig
{
	std::set<IdString> supported_cell_types;

	WreduceConfig()
	{
		supported_cell_types << "$not" << "$pos" << "$bu0" << "$neg";
		supported_cell_types << "$and" << "$or" << "$xor" << "$xnor";
		supported_cell_types << "$shl" << "$shr" << "$sshl" << "$sshr" << "$shift" << "$shiftx";
		supported_cell_types << "$lt" << "$le" << "$eq" << "$ne" << "$eqx" << "$nex" << "$ge" << "$gt";
		supported_cell_types << "$add" << "$sub"; // << "$mul" << "$div" << "$mod" << "$pow"
		supported_cell_types << "$mux" << "$pmux" << "$safe_pmux";
	}
};

struct WreduceWorker
{
	WreduceConfig *config;
	Module *module;
	ModIndex mi;

	std::set<Cell*, IdString::compare_ptr_by_name<Cell>> work_queue_cells;
	std::set<SigBit> work_queue_bits;
	SigMap constmap;

	WreduceWorker(WreduceConfig *config, Module *module) :
			config(config), module(module), mi(module) { }

	void run_cell_mux(Cell *cell)
	{
		SigSpec sig_a = mi.sigmap(cell->getPort("\\A"));
		SigSpec sig_b = mi.sigmap(cell->getPort("\\B"));
		SigSpec sig_s = mi.sigmap(cell->getPort("\\S"));
		SigSpec sig_y = mi.sigmap(cell->getPort("\\Y"));
		std::vector<SigBit> bits_removed;

		for (int i = SIZE(sig_y)-1; i >= 0; i--)
		{
			auto info = mi.query(sig_y[i]);
			if (!info->is_output && SIZE(info->ports) <= 1) {
				bits_removed.push_back(Sx);
				continue;
			}

			SigBit ref = sig_a[i];
			for (int k = 0; k < SIZE(sig_s); k++) {
				if (ref != Sx && sig_b[k*SIZE(sig_a) + i] != Sx && ref != sig_b[k*SIZE(sig_a) + i])
					goto no_match_ab;
				if (sig_b[k*SIZE(sig_a) + i] != Sx)
					ref = sig_b[k*SIZE(sig_a) + i];
			}
			if (0)
		no_match_ab:
				break;
			bits_removed.push_back(ref);
		}

		if (!bits_removed.empty())
		{
			SigSpec sig_removed;
			for (int i = SIZE(bits_removed)-1; i >= 0; i--)
				sig_removed.append_bit(bits_removed[i]);

			log("Removed top %d bits (of %d) from mux cell %s.%s (%s).\n",
					SIZE(sig_removed), SIZE(sig_y), log_id(module), log_id(cell), log_id(cell->type));

			int n_removed = SIZE(sig_removed);
			int n_kept = SIZE(sig_y) - SIZE(sig_removed);

			SigSpec new_work_queue_bits;
			new_work_queue_bits.append(sig_a.extract(n_kept, n_removed));
			new_work_queue_bits.append(sig_y.extract(n_kept, n_removed));

			SigSpec new_sig_a = sig_a.extract(0, n_kept);
			SigSpec new_sig_y = sig_y.extract(0, n_kept);
			SigSpec new_sig_b;

			for (int k = 0; k < SIZE(sig_s); k++) {
				new_sig_b.append(sig_b.extract(k*SIZE(sig_a), n_kept));
				new_work_queue_bits.append(sig_b.extract(k*SIZE(sig_a) + n_kept, n_removed));
			}

			for (auto bit : new_work_queue_bits)
				work_queue_bits.insert(bit);

			cell->setPort("\\A", new_sig_a);
			cell->setPort("\\B", new_sig_b);
			cell->setPort("\\Y", new_sig_y);
			cell->fixup_parameters();

			module->connect(sig_y.extract(n_kept, n_removed), sig_removed);
		}
	}

	void run_reduce_inport(Cell *cell, char port)
	{
		bool is_signed = cell->getParam(stringf("\\%c_SIGNED", port)).as_bool();
		SigSpec sig = mi.sigmap(cell->getPort(stringf("\\%c", port)));

		int bits_removed = 0;
		if (is_signed) {
			while (SIZE(sig) > 1 && constmap(sig[SIZE(sig)-1]) == constmap(sig[SIZE(sig)-2]))
				work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++;
		} else {
			while (SIZE(sig) > 1 && constmap(sig[SIZE(sig)-1]) == S0)
				work_queue_bits.insert(sig[SIZE(sig)-1]), sig.remove(SIZE(sig)-1), bits_removed++;
		}

		if (bits_removed) {
			log("Removed top %d bits (of %d) from port %c of cell %s.%s (%s).\n",
					bits_removed, SIZE(sig) + bits_removed, port, log_id(module), log_id(cell), log_id(cell->type));
			cell->setPort(stringf("\\%c", port), sig);
		}
	}

	void run_cell(Cell *cell)
	{
		if (!cell->type.in(config->supported_cell_types))
			return;

		if (cell->type.in("$mux", "$pmux", "$safe_pmux")) {
			run_cell_mux(cell);
			return;
		}

		if (cell->type.in("$shl", "$shr", "$sshl", "$sshr"))
			cell->setParam("\\B_SIGNED", false);

		if (cell->hasParam("\\A_SIGNED"))
			run_reduce_inport(cell, 'A');

		if (cell->hasParam("\\B_SIGNED"))
			run_reduce_inport(cell, 'B');

		SigSpec sig = mi.sigmap(cell->getPort("\\Y"));

		int bits_removed = 0;
		while (SIZE(sig) > 0)
		{
			auto info = mi.query(sig[SIZE(sig)-1]);

			if (info->is_output || SIZE(info->ports) > 1)
				break;

			sig.remove(SIZE(sig)-1);
			bits_removed++;
		}

		if (cell->type.in("$pos", "$bu0", "$add", "$mul", "$and", "$or", "$xor"))
		{
			bool is_signed = cell->getParam("\\A_SIGNED").as_bool();

			int a_size = 0, b_size = 0;
			if (cell->hasPort("\\A")) a_size = SIZE(cell->getPort("\\A"));
			if (cell->hasPort("\\B")) b_size = SIZE(cell->getPort("\\B"));

			int max_y_size = std::max(a_size, b_size);

			if (cell->type == "$add")
				max_y_size++;

			if (cell->type == "$mul")
				max_y_size = a_size + b_size;

			while (SIZE(sig) > 1 && SIZE(sig) > max_y_size) {
				module->connect(sig[SIZE(sig)-1], is_signed ? sig[SIZE(sig)-2] : S0);
				sig.remove(SIZE(sig)-1);
				bits_removed++;
			}
		}

		if (bits_removed) {
			log("Removed top %d bits (of %d) from port Y of cell %s.%s (%s).\n",
					bits_removed, SIZE(sig) + bits_removed, log_id(module), log_id(cell), log_id(cell->type));
			cell->setPort("\\Y", sig);
		}

		cell->fixup_parameters();
	}

	void run()
	{
		for (auto c : module->selected_cells())
			work_queue_cells.insert(c);

		while (!work_queue_cells.empty())
		{
			work_queue_bits.clear();
			for (auto c : work_queue_cells)
				run_cell(c);

			work_queue_cells.clear();
			for (auto bit : work_queue_bits)
			for (auto port : mi.query_ports(bit))
				work_queue_cells.insert(port.cell);
		}
	}
};

struct WreducePass : public Pass {
	WreducePass() : Pass("wreduce", "reduce the word size of operations is possible") { }
	virtual void help()
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    wreduce [options] [selection]\n");
		log("\n");
		log("This command reduces the word size of operations.\n");
		log("\n");
	}
	virtual void execute(std::vector<std::string> args, Design *design)
	{
		WreduceConfig config;

		log_header("Executing WREDUCE pass (reducing word size of cells).\n");

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			break;
		}
		extra_args(args, argidx, design);

		for (auto module : design->selected_modules())
		{
			if (module->has_processes_warn())
				continue;

			WreduceWorker worker(&config, module);
			worker.run();
		}
	}
} WreducePass;

PRIVATE_NAMESPACE_END

<|endoftext|>


<commit_before>#include"Screen.h"

Screen::Screen(RF24 *radio) {
	tft = new Adafruit_TFTLCD(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
	this->radio = radio;
	menu = Menu(tft, radio);
}

void Screen::init() {
	tft->reset();
	tft->begin(0x9341);
	tft->setRotation(3);
	initial_view();
	print_servo_default();
}

bool Screen::update() {
	if (millis() - update_counter > SCREENUPDATE) {
		update_counter = millis();
		return true;
	}
	return false;
}

void Screen::navigate(bool left, bool right, bool up, bool down, bool x, bool circle, bool options) {
	char *action = menu.execute(left, right, x, circle);

	if (action == "exit") {
		switch_view("control");
	}

	if (up) {
		menu.previous();
	}
	else if (down) {
		menu.next();
	}
	if (options || circle) {
		switch_view("control");
	}
}

void Screen::print_peripheral_status(int id, char *type, char *message) {
	int color = WHITE;
	if (type == "success") color = GREEN;
	else if (type == "warning") color = YELLOW;
	else if (type == "danger") color = RED;

	tft->setTextColor(color);
	tft->setCursor(150, 40 + 10 * id);
	tft->fillRect(150, 40 + 10 * id, 320, 10, BLACK);
	tft->println(message);
}

void Screen::print_servo_default() {
	// Servo field dim 175x130, pos 67,100
	tft->drawLine(67 + 175 / 2, 120, 67 + 175 / 2, 210, GREEN);
	tft->drawLine(67 + 20, 100 + 130 / 2, 67 + 175 - 20, 100 + 130 / 2, GREEN);
}

/*void Screen::update_analog_axis(uint8_t axis, uint8_t x, uint8_t) {
	// axis 0 -> left x
	// axis 1 -> left y
	// axis 2 -> right x
	// axis 3 -> right y
	int i = axis%2;
	int j = floor(axis / 2);
	tft->fillRect(261 + i * 30, 101 + j * 75 + (53 - (value / 255) * 53), 4, (value / 255) * 53, ORANGE);
	tft->fillRect(261 + i * 30, 101 + j * 75, 4, 53 - (value / 255) * 53, DARKGRAY);
}*/

void Screen::update_analog_axis(uint8_t axis, uint8_t x, uint8_t y) {
	// axis 0 -> left x
	// axis 1 -> left y
	// axis 2 -> right x
	// axis 3 -> right y
	//uint8_t i = axis%2;
	//uint8_t j = floor(axis / 2);

	uint8_t width = 48;
	uint8_t height = 48;

	//tft->fillRect(261 + i * 30, 101 + j * 75 + (53 - (value / 255) * 53), 4, (value / 255) * 53, ORANGE);
	//tft->fillRect(261 + i * 30, 101 + j * 75, 4, 53 - (value / 255) * 53, DARKGRAY);

	if (axis == 0) { // Left Stick
		if (x != left_axis_pos[0] || y != left_axis_pos[1]) {
			tft->drawLine(11 + left_axis_pos[0] / 255.0*width, 177 + left_axis_pos[1] / 255.0*height, 15 + left_axis_pos[0] / 255.0*width, 177 + left_axis_pos[1] / 255.0 * height, BLACK);
			tft->drawLine(13 + left_axis_pos[0] / 255.0*width, 175 + left_axis_pos[1] / 255.0*height, 13 + left_axis_pos[0] / 255.0*width, 179 + left_axis_pos[1] / 255.0 * height, BLACK);

			tft->drawLine(11 + x / 255.0*width, 177 + y / 255.0*height, 15 + x / 255.0*width, 177 + y / 255.0 * height, ORANGE);
			tft->drawLine(13 + x / 255.0*width, 175 + y / 255.0*height, 13 + x / 255.0*width, 179 + y / 255.0 * height, ORANGE);

			left_axis_pos[0] = x;
			left_axis_pos[1] = y;
		}
	}
}

void Screen::update_motor(float value) {
	tft->fillRect(11, 101, 4, 54 - value / 100 * 54, DARKGRAY);
	tft->fillRect(11, 101 + 54 - value / 100 * 54, 4, value / 100 * 54, ORANGE);
}

void Screen::switch_view(String change_to) {
	view = change_to;
	if (view == "control") initial_view();
	else if (view == "options") menu.display("");
}

void Screen::initial_view() {
	tft->fillScreen(BLACK);
	tft->setCursor(10, 10);
	tft->setTextColor(ORANGE);
	tft->setTextSize(2);
	tft->println("RC Flight Control");
	tft->setTextColor(WHITE);
	tft->setTextSize(1);

	// Add peripherals entry under title
	tft->setCursor(10, 40);
	tft->println("NRF24L01+");
	tft->setCursor(10, 50);
	tft->println("USB Host Shield");
	tft->setCursor(10, 60);
	tft->println("PS4 Controller");

	// Add subsection titles
	tft->setTextColor(ORANGE);
	tft->setCursor(10, 75);
	tft->println("Device Feedback");
	tft->drawLine(10, 85, 242, 85, ORANGE);
	tft->setCursor(260, 75);
	tft->println("DS4");
	tft->drawLine(260, 85, 310, 85, ORANGE);
	tft->setTextColor(WHITE);

	// Draw Motor Status box
	tft->setCursor(10, 90);
	tft->println("Motor");
	tft->drawRect(10, 100, 25, 56, WHITE);
	tft->setTextColor(TEALBLUE);
	/*tft->setCursor(40, 95);
	tft->println("100");
	tft->setCursor(40, 160);
	tft->println("50");
	tft->setCursor(40, 225);
	tft->println("0");
	tft->setTextColor(WHITE);
	*/
	// Draw Left Axis Box
	tft->drawRect(10, 174, 56, 56, WHITE);

	// Draw Right Axis Box
	tft->drawRect(254, 174, 56, 56, WHITE);

	// Draw Accelerometer box
	tft->setCursor(67, 90);
	tft->println("Servo");
	tft->drawRect(76, 100, 168, 130, WHITE);

	// Draw PS4 Status box
	/*for (int i = 0; i<2; i++) {
		for (int j = 0; j<2; j++) {
			tft->drawRect(260 + i * 30, 100 + j * 75, 20, 55, WHITE);
			tft->drawLine(256 + i * 30, 101 + 26 + j * 75, 259 + i * 30, 101 + 26 + j * 75, WHITE);
		}
	}*/
}
<commit_msg>Both crosshairs now working<commit_after>#include"Screen.h"

Screen::Screen(RF24 *radio) {
	tft = new Adafruit_TFTLCD(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
	this->radio = radio;
	menu = Menu(tft, radio);
}

void Screen::init() {
	tft->reset();
	tft->begin(0x9341);
	tft->setRotation(3);
	initial_view();
	print_servo_default();
}

bool Screen::update() {
	if (millis() - update_counter > SCREENUPDATE) {
		update_counter = millis();
		return true;
	}
	return false;
}

void Screen::navigate(bool left, bool right, bool up, bool down, bool x, bool circle, bool options) {
	char *action = menu.execute(left, right, x, circle);

	if (action == "exit") {
		switch_view("control");
	}

	if (up) {
		menu.previous();
	}
	else if (down) {
		menu.next();
	}
	if (options || circle) {
		switch_view("control");
	}
}

void Screen::print_peripheral_status(int id, char *type, char *message) {
	int color = WHITE;
	if (type == "success") color = GREEN;
	else if (type == "warning") color = YELLOW;
	else if (type == "danger") color = RED;

	tft->setTextColor(color);
	tft->setCursor(150, 40 + 10 * id);
	tft->fillRect(150, 40 + 10 * id, 320, 10, BLACK);
	tft->println(message);
}

void Screen::print_servo_default() {
	// Servo field dim 175x130, pos 67,100
	tft->drawLine(67 + 175 / 2, 120, 67 + 175 / 2, 210, GREEN);
	tft->drawLine(67 + 20, 100 + 130 / 2, 67 + 175 - 20, 100 + 130 / 2, GREEN);
}

/*void Screen::update_analog_axis(uint8_t axis, uint8_t x, uint8_t) {
	// axis 0 -> left x
	// axis 1 -> left y
	// axis 2 -> right x
	// axis 3 -> right y
	int i = axis%2;
	int j = floor(axis / 2);
	tft->fillRect(261 + i * 30, 101 + j * 75 + (53 - (value / 255) * 53), 4, (value / 255) * 53, ORANGE);
	tft->fillRect(261 + i * 30, 101 + j * 75, 4, 53 - (value / 255) * 53, DARKGRAY);
}*/

void Screen::update_analog_axis(uint8_t axis, uint8_t x, uint8_t y) {
	// axis 0 -> left x
	// axis 1 -> left y
	// axis 2 -> right x
	// axis 3 -> right y
	//uint8_t i = axis%2;
	//uint8_t j = floor(axis / 2);

	uint8_t width = 48;
	uint8_t height = 48;

	//tft->fillRect(261 + i * 30, 101 + j * 75 + (53 - (value / 255) * 53), 4, (value / 255) * 53, ORANGE);
	//tft->fillRect(261 + i * 30, 101 + j * 75, 4, 53 - (value / 255) * 53, DARKGRAY);

	if (axis == 0) { // Left Stick
		if (x != left_axis_pos[0] || y != left_axis_pos[1]) {
			tft->drawLine(11 + left_axis_pos[0] / 255.0*width, 177 + left_axis_pos[1] / 255.0*height, 15 + left_axis_pos[0] / 255.0*width, 177 + left_axis_pos[1] / 255.0 * height, BLACK);
			tft->drawLine(13 + left_axis_pos[0] / 255.0*width, 175 + left_axis_pos[1] / 255.0*height, 13 + left_axis_pos[0] / 255.0*width, 179 + left_axis_pos[1] / 255.0 * height, BLACK);

			tft->drawLine(11 + x / 255.0*width, 177 + y / 255.0*height, 15 + x / 255.0*width, 177 + y / 255.0 * height, ORANGE);
			tft->drawLine(13 + x / 255.0*width, 175 + y / 255.0*height, 13 + x / 255.0*width, 179 + y / 255.0 * height, ORANGE);

			left_axis_pos[0] = x;
			left_axis_pos[1] = y;
		}
	}else if (axis == 1) { // Left Stick
		if (x != right_axis_pos[0] || y != right_axis_pos[1]) {
			tft->drawLine(255 + right_axis_pos[0] / 255.0*width, 177 + right_axis_pos[1] / 255.0*height, 259 + right_axis_pos[0] / 255.0*width, 177 + right_axis_pos[1] / 255.0 * height, BLACK);
			tft->drawLine(257 + right_axis_pos[0] / 255.0*width, 175 + right_axis_pos[1] / 255.0*height, 257 + right_axis_pos[0] / 255.0*width, 179 + right_axis_pos[1] / 255.0 * height, BLACK);

			tft->drawLine(255 + x / 255.0*width, 177 + y / 255.0*height, 259 + x / 255.0*width, 177 + y / 255.0 * height, ORANGE);
			tft->drawLine(257 + x / 255.0*width, 175 + y / 255.0*height, 257 + x / 255.0*width, 179 + y / 255.0 * height, ORANGE);

			right_axis_pos[0] = x;
			right_axis_pos[1] = y;
		}
	}
}

void Screen::update_motor(float value) {
	tft->fillRect(11, 101, 4, 62 - value / 100 * 62, DARKGRAY);
	tft->fillRect(11, 101 + 62 - value / 100 * 62, 4, value / 100 * 62, ORANGE);
}

void Screen::switch_view(String change_to) {
	view = change_to;
	if (view == "control") initial_view();
	else if (view == "options") menu.display("");
}

void Screen::initial_view() {
	tft->fillScreen(BLACK);
	tft->setCursor(10, 10);
	tft->setTextColor(ORANGE);
	tft->setTextSize(2);
	tft->println("RC Flight Control");
	tft->setTextColor(WHITE);
	tft->setTextSize(1);

	// Add peripherals entry under title
	tft->setCursor(10, 40);
	tft->println("NRF24L01+");
	tft->setCursor(10, 50);
	tft->println("USB Host Shield");
	tft->setCursor(10, 60);
	tft->println("PS4 Controller");

	// Add subsection titles
	tft->setTextColor(ORANGE);
	tft->setCursor(10, 75);
	tft->println("Device Feedback");
	tft->drawLine(10, 85, 242, 85, ORANGE);
	tft->setCursor(260, 75);
	tft->println("DS4");
	tft->drawLine(260, 85, 310, 85, ORANGE);
	tft->setTextColor(WHITE);

	// Draw Motor Status box
	tft->setCursor(10, 90);
	tft->println("Motor");
	tft->drawRect(10, 100, 6, 64, WHITE);
	tft->setTextColor(TEALBLUE);
	/*tft->setCursor(40, 95);
	tft->println("100");
	tft->setCursor(40, 160);
	tft->println("50");
	tft->setCursor(40, 225);
	tft->println("0");
	tft->setTextColor(WHITE);
	*/
	// Draw Left Axis Box
	tft->drawRect(10, 174, 56, 56, WHITE);

	// Draw Right Axis Box
	tft->drawRect(254, 174, 56, 56, WHITE);

	// Draw Accelerometer box
	tft->setCursor(67, 90);
	tft->println("Servo");
	tft->drawRect(76, 100, 168, 130, WHITE);

	// Draw PS4 Status box
	/*for (int i = 0; i<2; i++) {
		for (int j = 0; j<2; j++) {
			tft->drawRect(260 + i * 30, 100 + j * 75, 20, 55, WHITE);
			tft->drawLine(256 + i * 30, 101 + 26 + j * 75, 259 + i * 30, 101 + 26 + j * 75, WHITE);
		}
	}*/
}
<|endoftext|>


<commit_before>/*
    This file is part of KAddressBook.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <kabc/addressbook.h>
#include <kabc/resource.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kstaticdeleter.h>

#include "kablock.h"

class AddressBookWrapper : public KABC::AddressBook
{
  public:
    AddressBookWrapper( KABC::AddressBook* );

    KABC::Resource* getStandardResource()
    {
      return standardResource();
    }
};

KABLock *KABLock::mSelf = 0;

static KStaticDeleter<KABLock> kabLockDeleter;

KABLock::KABLock( KABC::AddressBook *ab )
  : mAddressBook( ab )
{
}

KABLock::~KABLock()
{
}

KABLock *KABLock::self( KABC::AddressBook *ab )
{
  if ( !mSelf )
    kabLockDeleter.setObject( mSelf, new KABLock( ab ) );

  return mSelf;
}

bool KABLock::lock( KABC::Resource *resource )
{
  if ( mLocks.find( resource ) == mLocks.end() ) { // not locked yet
    KABC::Ticket *ticket = mAddressBook->requestSaveTicket( resource );
    if ( !ticket ) {
      return false;
    } else {
      LockEntry entry;
      entry.ticket = ticket;
      entry.counter = 1;
      mLocks.insert( resource, entry );
    }
  } else {
    LockEntry &entry = mLocks[ resource ];
    entry.counter++;
  }

  return true;
}

bool KABLock::unlock( KABC::Resource *resource )
{
  AddressBookWrapper *wrapper = static_cast<AddressBookWrapper*>( mAddressBook );
  if ( resource == 0 )
    resource = wrapper->getStandardResource();

  if ( mLocks.find( resource ) == mLocks.end() ) { // hmm, not good...
    return false;
  } else {
    LockEntry &entry = mLocks[ resource ];
    entry.counter--;

    if ( entry.counter == 0 ) {
      mAddressBook->save( entry.ticket );
//      # Activate in KDE 4.0
//      mAddressBook->releaseSaveTicket( entry.ticket );

      mLocks.remove( resource );
    }
  }

  return true;
}
<commit_msg>Refresh the pointer stored to the addressbook whenever KABLock::self() is called, otherwise we risk that StdAddressbook::close() has deleted the reference addressbook and invalidated the pointer.<commit_after>/*
    This file is part of KAddressBook.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include <kabc/addressbook.h>
#include <kabc/resource.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kstaticdeleter.h>

#include "kablock.h"

class AddressBookWrapper : public KABC::AddressBook
{
  public:
    AddressBookWrapper( KABC::AddressBook* );

    KABC::Resource* getStandardResource()
    {
      return standardResource();
    }
};

KABLock *KABLock::mSelf = 0;

static KStaticDeleter<KABLock> kabLockDeleter;

KABLock::KABLock( KABC::AddressBook *ab )
  : mAddressBook( ab )
{
}

KABLock::~KABLock()
{
}

KABLock *KABLock::self( KABC::AddressBook *ab )
{
  if ( !mSelf )
    kabLockDeleter.setObject( mSelf, new KABLock( ab ) );
  else
    mSelf->mAddressBook = ab;

  return mSelf;
}

bool KABLock::lock( KABC::Resource *resource )
{
  if ( mLocks.find( resource ) == mLocks.end() ) { // not locked yet
    KABC::Ticket *ticket = mAddressBook->requestSaveTicket( resource );
    if ( !ticket ) {
      return false;
    } else {
      LockEntry entry;
      entry.ticket = ticket;
      entry.counter = 1;
      mLocks.insert( resource, entry );
    }
  } else {
    LockEntry &entry = mLocks[ resource ];
    entry.counter++;
  }

  return true;
}

bool KABLock::unlock( KABC::Resource *resource )
{
  AddressBookWrapper *wrapper = static_cast<AddressBookWrapper*>( mAddressBook );
  if ( resource == 0 )
    resource = wrapper->getStandardResource();

  if ( mLocks.find( resource ) == mLocks.end() ) { // hmm, not good...
    return false;
  } else {
    LockEntry &entry = mLocks[ resource ];
    entry.counter--;

    if ( entry.counter == 0 ) {
      mAddressBook->save( entry.ticket );
//      # Activate in KDE 4.0
//      mAddressBook->releaseSaveTicket( entry.ticket );

      mLocks.remove( resource );
    }
  }

  return true;
}
<|endoftext|>


<commit_before>#ifdef USE_ALLEGRO
#include <allegro.h>
#ifdef ALLEGRO_WINDOWS
#include <winalleg.h>
#endif
#endif

#ifdef USE_SDL
#include <SDL.h>
#endif

#ifndef WINDOWS
#include <signal.h>
#include <string.h>
#endif

/* don't be a boring tuna */
// #warning you are ugly

#include "globals.h"
#include "init.h"
#include <pthread.h>
#include "network/network.h"

#include <ostream>
#include "dumb/include/dumb.h"
#ifdef USE_ALLEGRO
#include "dumb/include/aldumb.h"
#endif
#include "loadpng/loadpng.h"
#include "util/bitmap.h"
#include "util/funcs.h"
#include "util/file-system.h"
#include "util/font.h"
#include "configuration.h"
#include "script/script.h"
#include "music.h"
#include "loading.h"

using namespace std;

volatile int Global::speed_counter = 0;

/* enough seconds for 136 years */
volatile unsigned int Global::second_counter = 0;

/* the original engine was running at 90 ticks per second, but we dont
 * need to render that fast, so TICS_PER_SECOND is really fps and
 * LOGIC_MULTIPLIER will be used to adjust the speed counter to its
 * original value.
 */
const int Global::TICS_PER_SECOND = 40;
const double Global::LOGIC_MULTIPLIER = (double) 90 / (double) Global::TICS_PER_SECOND;

#ifdef USE_ALLEGRO
const int Global::WINDOWED = GFX_AUTODETECT_WINDOWED;
const int Global::FULLSCREEN = GFX_AUTODETECT_FULLSCREEN;
#else
/* FIXME: use enums here or something */
const int Global::WINDOWED = 0;
const int Global::FULLSCREEN = 1;
#endif

/* game counter, controls FPS */
static void inc_speed_counter(){
    /* probably put input polling here, InputManager::poll() */
    Global::speed_counter += 1;
}
#ifdef USE_ALLEGRO
END_OF_FUNCTION( inc_speed_counter )
#endif

/* if you need to count seconds for some reason.. */
static void inc_second_counter() {
    Global::second_counter += 1;
}
#ifdef USE_ALLEGRO
END_OF_FUNCTION( inc_second_counter )
#endif

#ifndef WINDOWS
static void handleSigSegV(int i, siginfo_t * sig, void * data){
    const char * message = "Bug! Caught a memory violation. Shutting down..\n";
    int dont_care = write(1, message, 48);
    dont_care = dont_care;
    // Global::shutdown_message = "Bug! Caught a memory violation. Shutting down..";
    Bitmap::setGfxModeText();
#ifdef USE_ALLEGRO
    allegro_exit();
#endif
    /* write to a log file or something because sigsegv shouldn't
     * normally happen.
     */
    exit(1);
}
#else
#endif

/* catch a socket being closed prematurely on unix */
#ifndef WINDOWS
static void handleSigPipe( int i, siginfo_t * sig, void * data ){
}

/*
static void handleSigUsr1( int i, siginfo_t * sig, void * data ){
	pthread_exit( NULL );
}
*/
#endif

static void registerSignals(){
#ifndef WINDOWS
	struct sigaction action;
	memset( &action, 0, sizeof(struct sigaction) );
	action.sa_sigaction = handleSigPipe;
	sigaction( SIGPIPE, &action, NULL );

	memset( &action, 0, sizeof(struct sigaction) );
	action.sa_sigaction = handleSigSegV;
	sigaction( SIGSEGV, &action, NULL );

	/*
	action.sa_sigaction = handleSigUsr1;
	sigaction( SIGUSR1, &action, NULL );
	*/
#endif
}

/* should probably call the janitor here or something */
static void close_paintown(){
    Music::pause();
    Bitmap::setGfxModeText();
#ifdef USE_ALLEGRO
    allegro_exit();
#endif
    exit(0);
}

namespace Global{
    extern int do_shutdown;
}

static void close_window(){
    /* when do_shutdown is 1 the game will attempt to throw ShutdownException
     * wherever it is. If the game is stuck or the code doesn't throw
     * ShutdownException then when the user tries to close the window
     * twice we just forcifully shutdown.
     */
    Global::do_shutdown += 1;
    if (Global::do_shutdown == 2){
        close_paintown();
    }
}
#ifdef USE_ALLEGRO
END_OF_FUNCTION(close_window)
#endif

#ifdef USE_ALLEGRO
static void initSystem(ostream & out){
    out << "Allegro version: " << ALLEGRO_VERSION_STR << endl;
    out << "Allegro init: " <<allegro_init()<<endl;
    out << "Install timer: " <<install_timer()<<endl;

    /* default for alsa is 8, so reserve a few more */
    reserve_voices(16, -1);
    /* is calling this function a good idea? */
    set_volume_per_voice(0);
    out<<"Install sound: "<<install_sound( DIGI_AUTODETECT, MIDI_NONE, "" )<<endl;

    /* png */
    loadpng_init();

    out<<"Install keyboard: "<<install_keyboard()<<endl;
    /* do we need the mouse?? */
    // out<<"Install mouse: "<<install_mouse()<<endl;
    out<<"Install joystick: "<<install_joystick(JOY_TYPE_AUTODETECT)<<endl;
    /* 16 bit color depth */
    set_color_depth(16);

    LOCK_VARIABLE( speed_counter );
    LOCK_VARIABLE( second_counter );
    LOCK_FUNCTION( (void *)inc_speed_counter );
    LOCK_FUNCTION( (void *)inc_second_counter );
    /* set up the timers */
    out<<"Install game timer: "<< install_int_ex(inc_speed_counter, BPS_TO_TIMER(Global::TICS_PER_SECOND))<<endl;
    out<<"Install second timer: "<<install_int_ex(inc_second_counter, BPS_TO_TIMER(1))<<endl;

    /* keep running in the background */
    set_display_switch_mode(SWITCH_BACKGROUND);

    /* close window when the X is pressed */
    LOCK_FUNCTION(close_window);
    set_close_button_callback(close_window);

    dumb_register_packfiles();
}

static void moreInitSystem(){
}

#endif
#ifdef USE_SDL

static pthread_t events;

struct TimerInfo{
    TimerInfo(void (*x)(), int y):
        tick(x), frequency(y){}

    void (*tick)();
    int frequency;
};

static void * do_timer(void * arg){
    TimerInfo info = *(TimerInfo *) arg;
    uint32_t delay = (uint32_t)(1000.0 / (double) info.frequency);

    /* assuming SDL_GetTicks() starts at 0, this should last for about 50 days
     * before overflowing.
     * what happens when overflow occurs?
     */
    uint32_t ticks = SDL_GetTicks();

    /* TODO: pass in some variable that tells this loop to quit */
    while (true){
        int now = SDL_GetTicks();
        while (now - ticks > delay){
            // Global::debug(0) << "Tick!" << endl;
            info.tick();
            ticks += delay;
        }
        SDL_Delay(1);
    }

    delete (TimerInfo *) arg;

    return NULL;
}

static pthread_t start_timer(void (*func)(), int frequency){
    TimerInfo * speed = new TimerInfo(func, frequency);
	/*
    speed.tick = func;
    speed.frequency = frequency;
*/
    pthread_t thread;
    pthread_create(&thread, NULL, do_timer, (void*) speed);
    return thread;
}

static void * handleEvents(void * arg){
    bool done = false;
    while (!done){
        SDL_Event event;
        int ok = SDL_WaitEvent(&event);
        if (ok){
            switch (event.type){
                case SDL_QUIT : {
                    done = true;
                    close_window();
                    break;
                }
                default : {
                    // Global::debug(0) << "Ignoring SDL event " << event.type << endl;
                    break;
                }
            }
        }
    }
    return NULL;
}

static void doSDLQuit(){
    SDL_Event quit;
    quit.type = SDL_QUIT;
    SDL_PushEvent(&quit);
    Global::debug(0) << "Waiting for SDL event handler to finish" << endl;
    pthread_join(events, NULL);
    SDL_Quit();
}

static void initSystem(ostream & out){
    out << "SDL Init: " << SDL_Init(SDL_INIT_VIDEO |
                                    SDL_INIT_AUDIO |
                                    SDL_INIT_TIMER |
                                    SDL_INIT_JOYSTICK |
                                    SDL_INIT_NOPARACHUTE |
                                    SDL_INIT_EVENTTHREAD)
                        << endl;

    start_timer(inc_speed_counter, Global::TICS_PER_SECOND);
    start_timer(inc_second_counter, 1);

    SDL_WM_SetCaption("Paintown", NULL);

    atexit(doSDLQuit);
}

static void moreInitSystem(){
    pthread_create(&events, NULL, handleEvents, NULL);
}
#endif

bool Global::init( int gfx ){

    ostream & out = Global::debug( 0 );
    out << "-- BEGIN init --" << endl;
    out << "Data path is " << Util::getDataPath2().path() << endl;
    out << "Paintown version " << Global::getVersionString() << endl;
    out << "Build date " << __DATE__ << " " << __TIME__ << endl;

    /* do implementation specific setup */
    initSystem(out);

    Bitmap::SCALE_X = GFX_X;
    Bitmap::SCALE_Y = GFX_Y;

    Configuration::loadConfigurations();
    const int sx = Configuration::getScreenWidth();
    const int sy = Configuration::getScreenHeight();

    /* set up the screen */
    out<<"Set gfx mode: " << Bitmap::setGraphicsMode(gfx, sx, sy) << endl;

    /* music */
    atexit( &dumb_exit );
    atexit( Network::closeAll );

    out << "Initialize random number generator" << endl;
    /* initialize random number generator */
    srand(time(NULL));

    registerSignals();

    out << "Initialize network" << endl;
    Network::init();

    /* this mutex is used to show the loading screen while the game loads */
    pthread_mutex_init( &Loader::loading_screen_mutex, NULL );

    moreInitSystem();

    out<<"-- END init --"<<endl;

    const Font & font = Font::getDefaultFont();
    // font.setSize(30, 30);
    Bitmap temp(font.textLength("Loading") + 1, font.getHeight("Loading") + 1);
    font.printf(0, 0, Bitmap::makeColor(255, 255, 255), temp, "Loading", 0);
    temp.BlitToScreen(sx / 2, sy / 2);

    return true;
}
<commit_msg>check if sdl init fails<commit_after>#ifdef USE_ALLEGRO
#include <allegro.h>
#ifdef ALLEGRO_WINDOWS
#include <winalleg.h>
#endif
#endif

#ifdef USE_SDL
#include <SDL.h>
#endif

#ifndef WINDOWS
#include <signal.h>
#include <string.h>
#endif

/* don't be a boring tuna */
// #warning you are ugly

#include "globals.h"
#include "init.h"
#include <pthread.h>
#include "network/network.h"

#include <ostream>
#include "dumb/include/dumb.h"
#ifdef USE_ALLEGRO
#include "dumb/include/aldumb.h"
#endif
#include "loadpng/loadpng.h"
#include "util/bitmap.h"
#include "util/funcs.h"
#include "util/file-system.h"
#include "util/font.h"
#include "configuration.h"
#include "script/script.h"
#include "music.h"
#include "loading.h"

using namespace std;

volatile int Global::speed_counter = 0;

/* enough seconds for 136 years */
volatile unsigned int Global::second_counter = 0;

/* the original engine was running at 90 ticks per second, but we dont
 * need to render that fast, so TICS_PER_SECOND is really fps and
 * LOGIC_MULTIPLIER will be used to adjust the speed counter to its
 * original value.
 */
const int Global::TICS_PER_SECOND = 40;
const double Global::LOGIC_MULTIPLIER = (double) 90 / (double) Global::TICS_PER_SECOND;

#ifdef USE_ALLEGRO
const int Global::WINDOWED = GFX_AUTODETECT_WINDOWED;
const int Global::FULLSCREEN = GFX_AUTODETECT_FULLSCREEN;
#else
/* FIXME: use enums here or something */
const int Global::WINDOWED = 0;
const int Global::FULLSCREEN = 1;
#endif

/* game counter, controls FPS */
static void inc_speed_counter(){
    /* probably put input polling here, InputManager::poll() */
    Global::speed_counter += 1;
}
#ifdef USE_ALLEGRO
END_OF_FUNCTION( inc_speed_counter )
#endif

/* if you need to count seconds for some reason.. */
static void inc_second_counter() {
    Global::second_counter += 1;
}
#ifdef USE_ALLEGRO
END_OF_FUNCTION( inc_second_counter )
#endif

#ifndef WINDOWS
static void handleSigSegV(int i, siginfo_t * sig, void * data){
    const char * message = "Bug! Caught a memory violation. Shutting down..\n";
    int dont_care = write(1, message, 48);
    dont_care = dont_care;
    // Global::shutdown_message = "Bug! Caught a memory violation. Shutting down..";
    Bitmap::setGfxModeText();
#ifdef USE_ALLEGRO
    allegro_exit();
#endif
    /* write to a log file or something because sigsegv shouldn't
     * normally happen.
     */
    exit(1);
}
#else
#endif

/* catch a socket being closed prematurely on unix */
#ifndef WINDOWS
static void handleSigPipe( int i, siginfo_t * sig, void * data ){
}

/*
static void handleSigUsr1( int i, siginfo_t * sig, void * data ){
	pthread_exit( NULL );
}
*/
#endif

static void registerSignals(){
#ifndef WINDOWS
	struct sigaction action;
	memset( &action, 0, sizeof(struct sigaction) );
	action.sa_sigaction = handleSigPipe;
	sigaction( SIGPIPE, &action, NULL );

	memset( &action, 0, sizeof(struct sigaction) );
	action.sa_sigaction = handleSigSegV;
	sigaction( SIGSEGV, &action, NULL );

	/*
	action.sa_sigaction = handleSigUsr1;
	sigaction( SIGUSR1, &action, NULL );
	*/
#endif
}

/* should probably call the janitor here or something */
static void close_paintown(){
    Music::pause();
    Bitmap::setGfxModeText();
#ifdef USE_ALLEGRO
    allegro_exit();
#endif
    exit(0);
}

namespace Global{
    extern int do_shutdown;
}

static void close_window(){
    /* when do_shutdown is 1 the game will attempt to throw ShutdownException
     * wherever it is. If the game is stuck or the code doesn't throw
     * ShutdownException then when the user tries to close the window
     * twice we just forcifully shutdown.
     */
    Global::do_shutdown += 1;
    if (Global::do_shutdown == 2){
        close_paintown();
    }
}
#ifdef USE_ALLEGRO
END_OF_FUNCTION(close_window)
#endif

#ifdef USE_ALLEGRO
static void initSystem(ostream & out){
    out << "Allegro version: " << ALLEGRO_VERSION_STR << endl;
    out << "Allegro init: " <<allegro_init()<<endl;
    out << "Install timer: " <<install_timer()<<endl;

    /* default for alsa is 8, so reserve a few more */
    reserve_voices(16, -1);
    /* is calling this function a good idea? */
    set_volume_per_voice(0);
    out<<"Install sound: "<<install_sound( DIGI_AUTODETECT, MIDI_NONE, "" )<<endl;

    /* png */
    loadpng_init();

    out<<"Install keyboard: "<<install_keyboard()<<endl;
    /* do we need the mouse?? */
    // out<<"Install mouse: "<<install_mouse()<<endl;
    out<<"Install joystick: "<<install_joystick(JOY_TYPE_AUTODETECT)<<endl;
    /* 16 bit color depth */
    set_color_depth(16);

    LOCK_VARIABLE( speed_counter );
    LOCK_VARIABLE( second_counter );
    LOCK_FUNCTION( (void *)inc_speed_counter );
    LOCK_FUNCTION( (void *)inc_second_counter );
    /* set up the timers */
    out<<"Install game timer: "<< install_int_ex(inc_speed_counter, BPS_TO_TIMER(Global::TICS_PER_SECOND))<<endl;
    out<<"Install second timer: "<<install_int_ex(inc_second_counter, BPS_TO_TIMER(1))<<endl;

    /* keep running in the background */
    set_display_switch_mode(SWITCH_BACKGROUND);

    /* close window when the X is pressed */
    LOCK_FUNCTION(close_window);
    set_close_button_callback(close_window);

    dumb_register_packfiles();
}

static void moreInitSystem(){
}

#endif
#ifdef USE_SDL

static pthread_t events;

struct TimerInfo{
    TimerInfo(void (*x)(), int y):
        tick(x), frequency(y){}

    void (*tick)();
    int frequency;
};

static void * do_timer(void * arg){
    TimerInfo info = *(TimerInfo *) arg;
    uint32_t delay = (uint32_t)(1000.0 / (double) info.frequency);

    /* assuming SDL_GetTicks() starts at 0, this should last for about 50 days
     * before overflowing.
     * what happens when overflow occurs?
     */
    uint32_t ticks = SDL_GetTicks();

    /* TODO: pass in some variable that tells this loop to quit */
    while (true){
        int now = SDL_GetTicks();
        while (now - ticks > delay){
            // Global::debug(0) << "Tick!" << endl;
            info.tick();
            ticks += delay;
        }
        SDL_Delay(1);
    }

    delete (TimerInfo *) arg;

    return NULL;
}

static pthread_t start_timer(void (*func)(), int frequency){
    TimerInfo * speed = new TimerInfo(func, frequency);
	/*
    speed.tick = func;
    speed.frequency = frequency;
*/
    pthread_t thread;
    pthread_create(&thread, NULL, do_timer, (void*) speed);
    return thread;
}

static void * handleEvents(void * arg){
    bool done = false;
    while (!done){
        SDL_Event event;
        int ok = SDL_WaitEvent(&event);
        if (ok){
            switch (event.type){
                case SDL_QUIT : {
                    done = true;
                    close_window();
                    break;
                }
                default : {
                    // Global::debug(0) << "Ignoring SDL event " << event.type << endl;
                    break;
                }
            }
        }
    }
    return NULL;
}

static void doSDLQuit(){
    SDL_Event quit;
    quit.type = SDL_QUIT;
    SDL_PushEvent(&quit);
    Global::debug(0) << "Waiting for SDL event handler to finish" << endl;
    pthread_join(events, NULL);
    SDL_Quit();
}

static void initSystem(ostream & out){
    out << "SDL Init: ";
    int ok = SDL_Init(SDL_INIT_VIDEO |
                      SDL_INIT_AUDIO |
                      SDL_INIT_TIMER |
                      SDL_INIT_JOYSTICK |
                      SDL_INIT_NOPARACHUTE |
                      SDL_INIT_EVENTTHREAD);
    if (ok == 0){
        out << "Ok" << endl;
    } else {
	out << "Failed (" << ok << ") - " << SDL_GetError() << endl;
	exit(ok);
    }

    start_timer(inc_speed_counter, Global::TICS_PER_SECOND);
    start_timer(inc_second_counter, 1);

    SDL_WM_SetCaption("Paintown", NULL);

    atexit(doSDLQuit);
}

static void moreInitSystem(){
    pthread_create(&events, NULL, handleEvents, NULL);
}
#endif

bool Global::init( int gfx ){

    ostream & out = Global::debug( 0 );
    out << "-- BEGIN init --" << endl;
    out << "Data path is " << Util::getDataPath2().path() << endl;
    out << "Paintown version " << Global::getVersionString() << endl;
    out << "Build date " << __DATE__ << " " << __TIME__ << endl;

    /* do implementation specific setup */
    initSystem(out);

    Bitmap::SCALE_X = GFX_X;
    Bitmap::SCALE_Y = GFX_Y;

    Configuration::loadConfigurations();
    const int sx = Configuration::getScreenWidth();
    const int sy = Configuration::getScreenHeight();

    /* set up the screen */
    out<<"Set gfx mode: " << Bitmap::setGraphicsMode(gfx, sx, sy) << endl;

    /* music */
    atexit( &dumb_exit );
    atexit( Network::closeAll );

    out << "Initialize random number generator" << endl;
    /* initialize random number generator */
    srand(time(NULL));

    registerSignals();

    out << "Initialize network" << endl;
    Network::init();

    /* this mutex is used to show the loading screen while the game loads */
    pthread_mutex_init( &Loader::loading_screen_mutex, NULL );

    moreInitSystem();

    out<<"-- END init --"<<endl;

    const Font & font = Font::getDefaultFont();
    // font.setSize(30, 30);
    Bitmap temp(font.textLength("Loading") + 1, font.getHeight("Loading") + 1);
    font.printf(0, 0, Bitmap::makeColor(255, 255, 255), temp, "Loading", 0);
    temp.BlitToScreen(sx / 2, sy / 2);

    return true;
}
<|endoftext|>