<commit_before>#include <sge/engine.hpp>
#include <sge/node.hpp>
#include <sstream>
#include <string>
#include <list>

using namespace std;

namespace sge
{
    Node::Node(const string &name, Engine &engine) : name(name), engine(engine)
    {
    }

    void Node::init()
    {
    }

    const char *Node::get_name() const
    {
        return name.c_str();
    }

    vector<string> Node::mro() const
    {
        return {"Node"};
    }

    bool Node::is_of(const string &nodetype) const
    {
        for (auto &_nodetype : mro())
        {
            if (_nodetype == nodetype)
            {
                return true;
            }
        }

        return false;
    }

    shared_ptr<Node> Node::get_root()
    {
        shared_ptr<Node> root = shared_from_this();

        while (root->get_parent() != nullptr)
        {
            root = root->get_parent();
        }

        return root;
    }

    shared_ptr<Node> Node::get_parent() const
    {
        return parent.lock();
    }

    vector<shared_ptr<Node>> Node::get_children() const
    {
        return children;
    }

    shared_ptr<Node> Node::get_node(const string &path)
    {
        if (path.empty())
        {
            return shared_from_this();
        }
        else if (path[0] == '/')
        {
            return get_root()->get_node(path.substr(1));
        }
        else
        {
            size_t pos = path.find("/");
            string childpath = path.substr(0, pos);

            if (childpath == ".")
            {
                if (pos == string::npos)
                {
                    return shared_from_this();
                }
                else
                {
                    return get_node(path.substr(pos + 1));
                }
            }
            else if (childpath == "..")
            {
                if (pos == string::npos)
                {
                    return get_parent();
                }
                else
                {
                    return get_parent()->get_node(path.substr(pos + 1));
                }
            }
            else
            {
                shared_ptr<Node> child = nullptr;

                for (auto &_child : children)
                {
                    if (_child->get_name() == childpath)
                    {
                        child = _child;
                        break;
                    }
                }

                if (pos == string::npos)
                {
                    return child;
                }
                else
                {
                    return child->get_node(path.substr(pos + 1));
                }
            }
        }
    }

    vector<shared_ptr<Node>> Node::find_children_by_type(const vector<string> &types) const
    {
        vector<shared_ptr<Node>> result;

        for (auto &child : children)
        {
            for (auto &nodetype : types)
            {
                if (child->is_of(nodetype))
                {
                    result.push_back(child);
                    break;
                }
            }

            auto child_result = child->find_children_by_type(types);

            if (!child_result.empty())
            {
                result.insert(result.end(), child_result.begin(), child_result.end());
            }
        }

        return result;
    }

    shared_ptr<Node> Node::find_first_ancestor_by_type(const string &type) const
    {
        shared_ptr<Node> result = get_parent();

        if (result == nullptr)
        {
            return nullptr;
        }
        else if (result->is_of(type))
        {
            return result;
        }
        else
        {
            return result->find_first_ancestor_by_type(type);
        }
    }

    void Node::add_child(shared_ptr<Node> child, bool reparent)
    {
        children.push_back(child);

        if (reparent)
        {
            child->reparent(shared_from_this(), true, false);
        }
    }

    void Node::remove_child(shared_ptr<Node> child, bool reparent)
    {
        for (auto it = children.begin(); it != children.end(); it++)
        {
            if (*it == child)
            {
                children.erase(it);
                break;
            }
        }

        if (reparent)
        {
            child->reparent(nullptr, false, true);
        }
    }

    void Node::reparent(shared_ptr<Node> newparent, bool remove, bool add)
    {
        if (get_parent() != nullptr)
        {
            if (is_in_tree())
            {
                send_exit_tree();
            }

            if (remove)
            {
                get_parent()->remove_child(shared_from_this(), false);
            }
        }

        parent = newparent;

        if (get_parent() != nullptr)
        {
            if (add)
            {
                get_parent()->add_child(shared_from_this(), false);
            }

            if (!is_in_tree())
            {
                send_enter_tree();
            }
        }
    }

    bool Node::has_input() const
    {
        return input_enabled;
    }

    void Node::set_input(bool enabled)
    {
        input_enabled = enabled;
    }

    bool Node::send_input(SDL_Event *event)
    {
        bool result = true;

        if (has_input())
        {
            result = result && input(event);
        }

        for (auto &child : children)
        {
            result = result && child->send_input(event);
        }

        return result;
    }

    bool Node::input(SDL_Event *)
    {
        return true;
    }

    bool Node::has_process() const
    {
        return process_enabled;
    }

    void Node::set_process(bool enabled)
    {
        process_enabled = enabled;
    }

    void Node::send_process(Uint32 delta)
    {
        if (has_process())
        {
            process(delta);
        }

        for (auto &child : children)
        {
            child->send_process(delta);
        }
    }

    void Node::process(Uint32) {}

    bool Node::has_draw() const
    {
        return draw_enabled;
    }

    void Node::set_draw(bool enabled)
    {
        draw_enabled = enabled;
    }

    void Node::send_draw()
    {
        if (has_draw())
        {
            draw();
        }

        for (auto &child : children)
        {
            child->send_draw();
        }
    }

    void Node::draw() {}

    void Node::send_enter_tree()
    {
        enter_tree();

        for (auto &child : children)
        {
            child->send_enter_tree();
        }

        in_tree = true;

        ready ();
    }

    void Node::enter_tree() {}
    void Node::ready() {}

    void Node::send_exit_tree()
    {
        for (auto &child : children)
        {
            child->send_exit_tree();
        }

        exit_tree();

        in_tree = false;
    }

    void Node::exit_tree() {}

    bool Node::is_in_tree() const
    {
        return in_tree;
    }
}
<commit_msg>:fix: use get_children() method instead of accessing children directly<commit_after>#include <sge/engine.hpp>
#include <sge/node.hpp>
#include <sstream>
#include <string>
#include <list>

using namespace std;

namespace sge
{
    Node::Node(const string &name, Engine &engine) : name(name), engine(engine)
    {
    }

    void Node::init()
    {
    }

    const char *Node::get_name() const
    {
        return name.c_str();
    }

    vector<string> Node::mro() const
    {
        return {"Node"};
    }

    bool Node::is_of(const string &nodetype) const
    {
        for (auto &_nodetype : mro())
        {
            if (_nodetype == nodetype)
            {
                return true;
            }
        }

        return false;
    }

    shared_ptr<Node> Node::get_root()
    {
        shared_ptr<Node> root = shared_from_this();

        while (root->get_parent() != nullptr)
        {
            root = root->get_parent();
        }

        return root;
    }

    shared_ptr<Node> Node::get_parent() const
    {
        return parent.lock();
    }

    vector<shared_ptr<Node>> Node::get_children() const
    {
        return children;
    }

    shared_ptr<Node> Node::get_node(const string &path)
    {
        if (path.empty())
        {
            return shared_from_this();
        }
        else if (path[0] == '/')
        {
            return get_root()->get_node(path.substr(1));
        }
        else
        {
            size_t pos = path.find("/");
            string childpath = path.substr(0, pos);

            if (childpath == ".")
            {
                if (pos == string::npos)
                {
                    return shared_from_this();
                }
                else
                {
                    return get_node(path.substr(pos + 1));
                }
            }
            else if (childpath == "..")
            {
                if (pos == string::npos)
                {
                    return get_parent();
                }
                else
                {
                    return get_parent()->get_node(path.substr(pos + 1));
                }
            }
            else
            {
                shared_ptr<Node> child = nullptr;

                for (auto &_child : children)
                {
                    if (_child->get_name() == childpath)
                    {
                        child = _child;
                        break;
                    }
                }

                if (pos == string::npos)
                {
                    return child;
                }
                else
                {
                    return child->get_node(path.substr(pos + 1));
                }
            }
        }
    }

    vector<shared_ptr<Node>> Node::find_children_by_type(const vector<string> &types) const
    {
        vector<shared_ptr<Node>> result;

        for (auto &child : children)
        {
            for (auto &nodetype : types)
            {
                if (child->is_of(nodetype))
                {
                    result.push_back(child);
                    break;
                }
            }

            auto child_result = child->find_children_by_type(types);

            if (!child_result.empty())
            {
                result.insert(result.end(), child_result.begin(), child_result.end());
            }
        }

        return result;
    }

    shared_ptr<Node> Node::find_first_ancestor_by_type(const string &type) const
    {
        shared_ptr<Node> result = get_parent();

        if (result == nullptr)
        {
            return nullptr;
        }
        else if (result->is_of(type))
        {
            return result;
        }
        else
        {
            return result->find_first_ancestor_by_type(type);
        }
    }

    void Node::add_child(shared_ptr<Node> child, bool reparent)
    {
        children.push_back(child);

        if (reparent)
        {
            child->reparent(shared_from_this(), true, false);
        }
    }

    void Node::remove_child(shared_ptr<Node> child, bool reparent)
    {
        for (auto it = children.begin(); it != children.end(); it++)
        {
            if (*it == child)
            {
                children.erase(it);
                break;
            }
        }

        if (reparent)
        {
            child->reparent(nullptr, false, true);
        }
    }

    void Node::reparent(shared_ptr<Node> newparent, bool remove, bool add)
    {
        if (get_parent() != nullptr)
        {
            if (is_in_tree())
            {
                send_exit_tree();
            }

            if (remove)
            {
                get_parent()->remove_child(shared_from_this(), false);
            }
        }

        parent = newparent;

        if (get_parent() != nullptr)
        {
            if (add)
            {
                get_parent()->add_child(shared_from_this(), false);
            }

            if (!is_in_tree())
            {
                send_enter_tree();
            }
        }
    }

    bool Node::has_input() const
    {
        return input_enabled;
    }

    void Node::set_input(bool enabled)
    {
        input_enabled = enabled;
    }

    bool Node::send_input(SDL_Event *event)
    {
        bool result = true;

        if (has_input())
        {
            result = result && input(event);
        }

        for (auto &child : get_children())
        {
            result = result && child->send_input(event);
        }

        return result;
    }

    bool Node::input(SDL_Event *)
    {
        return true;
    }

    bool Node::has_process() const
    {
        return process_enabled;
    }

    void Node::set_process(bool enabled)
    {
        process_enabled = enabled;
    }

    void Node::send_process(Uint32 delta)
    {
        if (has_process())
        {
            process(delta);
        }

        for (auto &child : get_children())
        {
            child->send_process(delta);
        }
    }

    void Node::process(Uint32) {}

    bool Node::has_draw() const
    {
        return draw_enabled;
    }

    void Node::set_draw(bool enabled)
    {
        draw_enabled = enabled;
    }

    void Node::send_draw()
    {
        if (has_draw())
        {
            draw();
        }

        for (auto &child : children)
        {
            child->send_draw();
        }
    }

    void Node::draw() {}

    void Node::send_enter_tree()
    {
        enter_tree();

        for (auto &child : get_children())
        {
            child->send_enter_tree();
        }

        in_tree = true;

        ready ();
    }

    void Node::enter_tree() {}
    void Node::ready() {}

    void Node::send_exit_tree()
    {
        for (auto &child : get_children())
        {
            child->send_exit_tree();
        }

        exit_tree();

        in_tree = false;
    }

    void Node::exit_tree() {}

    bool Node::is_in_tree() const
    {
        return in_tree;
    }
}
<|endoftext|>


<commit_before>
#include "id_func.h"
#include "list_graph.h"
#include "multi_arc.h"
#include "sort_arc.h"
#include "chain.h"
#include "flow_cutter.h"
#include "greedy_order.h"

#include "node_flow_cutter.h"
#include "contraction_graph.h"
#include "cch_order.h"
#include "tree_decomposition.h"
#include "separator.h"

#include <limits>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sstream>
#ifdef PARALLELIZE
#include <omp.h>
#include <atomic>
#endif

#include <sys/time.h>
#include <unistd.h>
using namespace std;

ArrayIDIDFunc tail, head;
const char*volatile best_decomposition = 0;
int best_bag_size = numeric_limits<int>::max();

void ignore_return_value(int){}

int compute_max_bag_size(const ArrayIDIDFunc&order){
	auto inv_order = inverse_permutation(order);
	int current_tail = -1;
	int current_tail_up_deg = 0;
	int max_up_deg = 0;
	compute_chordal_supergraph(
		chain(tail, inv_order), chain(head, inv_order),
		[&](int x, int y){
			if(current_tail != x){
				current_tail = x;
				max_to(max_up_deg, current_tail_up_deg);
				current_tail_up_deg = 0;
			}
			++current_tail_up_deg;
		}
	);
	return max_up_deg+1;
}

unsigned long long get_milli_time(){
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return (unsigned long long)(tv.tv_sec) * 1000
	   + (unsigned long long)(tv.tv_usec) / 1000;
}

const char*compute_decomposition(const ArrayIDIDFunc&order){
	ostringstream out;
	print_tree_decompostion(out, tail, head, move(order));
	char*buf = new char[out.str().length()+1];
	memcpy(buf, out.str().c_str(), out.str().length()+1);
	return buf;
}

void test_new_order(ArrayIDIDFunc order){
	int x = compute_max_bag_size(order);
	#ifdef PARALLELIZE
	#pragma omp critical
	#endif
	{
		if(x < best_bag_size){
			best_bag_size = x;
			const char*old_decomposition = best_decomposition;
			best_decomposition = compute_decomposition(move(order));
			delete[]old_decomposition;
			{
				string msg = "c status "+to_string(best_bag_size)+" "+to_string(get_milli_time())+"\n";
				ignore_return_value(write(STDOUT_FILENO, msg.data(), msg.length()));
			}
		}
	}
}

char no_decomposition_message[] = "c info programm was aborted before any decomposition was computed\n";

#ifdef PARALLELIZE
volatile atomic_flag only_one_thread_in_signal_handler = ATOMIC_FLAG_INIT;
#endif

void signal_handler(int)
{
	#ifdef PARALLELIZE
	while (only_one_thread_in_signal_handler.test_and_set()) {}
	#endif

	const char*x = best_decomposition;
	if(x != 0)
		ignore_return_value(write(STDOUT_FILENO, x, strlen(x)));
	else
		ignore_return_value(write(STDOUT_FILENO, no_decomposition_message, sizeof(no_decomposition_message)));

	_Exit(EXIT_SUCCESS);
}

int main(int argc, char*argv[]){
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	signal(SIGSEGV, signal_handler);
	try{
		{
			string file_name = "-";
			if(argc == 2)
				file_name = argv[1];
			auto g = uncached_load_pace_graph(file_name);
			tail = std::move(g.tail);
			head = std::move(g.head);
		}

		test_new_order(identity_permutation(tail.image_count()));
		test_new_order(compute_greedy_min_degree_order(tail, head));
		test_new_order(compute_greedy_min_shortcut_order(tail, head));

		int random_seed = 0;

		if(argc == 3){
			if(string(argv[1]) == "-s"){
				random_seed = atoi(argv[2]);
			}
		}

		#ifdef PARALLELIZE
		#pragma omp parallel
		#endif
		{
			try{
				std::minstd_rand rand_gen;
				rand_gen.seed(
					random_seed
					#ifdef PARALLELIZE
					+ omp_get_thread_num()
					#endif
				);

				flow_cutter::Config config;
				config.cutter_count = 1;
				config.random_seed = rand_gen();

				for(int i=0;;++i){
					config.random_seed = rand_gen();
					if(i % 32 == 0)
						++config.cutter_count;

					test_new_order(cch_order::compute_cch_graph_order(tail, head, flow_cutter::ComputeSeparator(config)));
				}
			}catch(...){
				signal_handler(0);
			}
		}
	}catch(...){
		signal_handler(0);
	}
}

<commit_msg>do no longer try input order, evaluating it can be too slow on some instances<commit_after>
#include "id_func.h"
#include "list_graph.h"
#include "multi_arc.h"
#include "sort_arc.h"
#include "chain.h"
#include "flow_cutter.h"
#include "greedy_order.h"

#include "node_flow_cutter.h"
#include "contraction_graph.h"
#include "cch_order.h"
#include "tree_decomposition.h"
#include "separator.h"

#include <limits>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sstream>
#ifdef PARALLELIZE
#include <omp.h>
#include <atomic>
#endif

#include <sys/time.h>
#include <unistd.h>
using namespace std;

ArrayIDIDFunc tail, head;
const char*volatile best_decomposition = 0;
int best_bag_size = numeric_limits<int>::max();

void ignore_return_value(int){}

int compute_max_bag_size(const ArrayIDIDFunc&order){
	auto inv_order = inverse_permutation(order);
	int current_tail = -1;
	int current_tail_up_deg = 0;
	int max_up_deg = 0;
	compute_chordal_supergraph(
		chain(tail, inv_order), chain(head, inv_order),
		[&](int x, int y){
			if(current_tail != x){
				current_tail = x;
				max_to(max_up_deg, current_tail_up_deg);
				current_tail_up_deg = 0;
			}
			++current_tail_up_deg;
		}
	);
	return max_up_deg+1;
}

unsigned long long get_milli_time(){
	struct timeval tv;
	gettimeofday(&tv, NULL);
	return (unsigned long long)(tv.tv_sec) * 1000
	   + (unsigned long long)(tv.tv_usec) / 1000;
}

const char*compute_decomposition(const ArrayIDIDFunc&order){
	ostringstream out;
	print_tree_decompostion(out, tail, head, move(order));
	char*buf = new char[out.str().length()+1];
	memcpy(buf, out.str().c_str(), out.str().length()+1);
	return buf;
}

void test_new_order(ArrayIDIDFunc order){
	int x = compute_max_bag_size(order);
	#ifdef PARALLELIZE
	#pragma omp critical
	#endif
	{
		if(x < best_bag_size){
			best_bag_size = x;
			const char*old_decomposition = best_decomposition;
			best_decomposition = compute_decomposition(move(order));
			delete[]old_decomposition;
			{
				string msg = "c status "+to_string(best_bag_size)+" "+to_string(get_milli_time())+"\n";
				ignore_return_value(write(STDOUT_FILENO, msg.data(), msg.length()));
			}
		}
	}
}

char no_decomposition_message[] = "c info programm was aborted before any decomposition was computed\n";

#ifdef PARALLELIZE
volatile atomic_flag only_one_thread_in_signal_handler = ATOMIC_FLAG_INIT;
#endif

void signal_handler(int)
{
	#ifdef PARALLELIZE
	while (only_one_thread_in_signal_handler.test_and_set()) {}
	#endif

	const char*x = best_decomposition;
	if(x != 0)
		ignore_return_value(write(STDOUT_FILENO, x, strlen(x)));
	else
		ignore_return_value(write(STDOUT_FILENO, no_decomposition_message, sizeof(no_decomposition_message)));

	_Exit(EXIT_SUCCESS);
}

int main(int argc, char*argv[]){
	signal(SIGTERM, signal_handler);
	signal(SIGINT, signal_handler);

	signal(SIGSEGV, signal_handler);
	try{
		{
			string file_name = "-";
			if(argc == 2)
				file_name = argv[1];
			auto g = uncached_load_pace_graph(file_name);
			tail = std::move(g.tail);
			head = std::move(g.head);
		}

		test_new_order(compute_greedy_min_degree_order(tail, head));
		test_new_order(compute_greedy_min_shortcut_order(tail, head));

		int random_seed = 0;

		if(argc == 3){
			if(string(argv[1]) == "-s"){
				random_seed = atoi(argv[2]);
			}
		}

		#ifdef PARALLELIZE
		#pragma omp parallel
		#endif
		{
			try{
				std::minstd_rand rand_gen;
				rand_gen.seed(
					random_seed
					#ifdef PARALLELIZE
					+ omp_get_thread_num()
					#endif
				);

				flow_cutter::Config config;
				config.cutter_count = 1;
				config.random_seed = rand_gen();

				for(int i=0;;++i){
					config.random_seed = rand_gen();
					if(i % 32 == 0)
						++config.cutter_count;

					test_new_order(cch_order::compute_cch_graph_order(tail, head, flow_cutter::ComputeSeparator(config)));
				}
			}catch(...){
				signal_handler(0);
			}
		}
	}catch(...){
		signal_handler(0);
	}
}

<|endoftext|>


<commit_before>#include "ch.hpp"
#include "hal.h"

#include "communication.hpp"
#include "unit_config.hpp"
#include "variant/platform.hpp"
#include "variant/unit.hpp"

// static platform::HeartbeatThread heartbeatThread;
static CommunicationThread<255> communicationThread(
    reinterpret_cast<chibios_rt::BaseSequentialStreamInterface&>(SD1));

int main(void) {
  halInit();
  chibios_rt::System::init();

  Platform platform;
  Unit unit(platform);

  // Start the background threads
  // heartbeatThread.start(LOWPRIO);
  communicationThread.start(LOWPRIO);

  // Build and initialize the system
  platform.init();
  unit.init();

  // Loop at a fixed rate forever
  // NOTE: If the deadline is ever missed then the loop will hang indefinitely.
  systime_t deadline = chTimeNow();
  while(true) {
    deadline += MS2ST(DT * 1000);

    unit.getSystem().update();

    chibios_rt::BaseThread::sleepUntil(deadline);
  }

  return 0;
}
<commit_msg>Use chibios_rt when possible.<commit_after>#include "ch.hpp"
#include "hal.h"

#include "communication.hpp"
#include "unit_config.hpp"
#include "variant/platform.hpp"
#include "variant/unit.hpp"

// static platform::HeartbeatThread heartbeatThread;
static CommunicationThread<255> communicationThread(
    reinterpret_cast<chibios_rt::BaseSequentialStreamInterface&>(SD1));

int main(void) {
  halInit();
  chibios_rt::System::init();

  Platform platform;
  Unit unit(platform);

  // Start the background threads
  // heartbeatThread.start(LOWPRIO);
  communicationThread.start(LOWPRIO);

  // Build and initialize the system
  platform.init();
  unit.init();

  // Loop at a fixed rate forever
  // NOTE: If the deadline is ever missed then the loop will hang indefinitely.
  systime_t deadline = chibios_rt::System::getTime();
  while(true) {
    deadline += MS2ST(DT * 1000);

    unit.getSystem().update();

    chibios_rt::BaseThread::sleepUntil(deadline);
  }

  return 0;
}
<|endoftext|>


<commit_before>#include <QUrl>
#include <QDir>
#include <QDebug>
#include <QTimer>
#include <QCoreApplication>
#include <QCommandLineParser>

#include "Util.h"
#include "Version.h"
#include "Downloader.h"

int main(int argc, char **argv) {
  QCoreApplication app(argc, argv);
  QCoreApplication::setApplicationName("efdl");
  QCoreApplication::setApplicationVersion(versionString(false));

  QCommandLineParser parser;
  parser.setApplicationDescription(QObject::tr("Efficient downloading application."));
  parser.addHelpOption();
  parser.addVersionOption();
  parser.addPositionalArgument("URL", QObject::tr("URL to download."));

  QCommandLineOption verboseOpt(QStringList{"verbose"},
                                QObject::tr("Verbose mode."));
  parser.addOption(verboseOpt);

  QCommandLineOption confirmOpt(QStringList{"confirm"},
                                QObject::tr("Confirm to download on redirections."));
  parser.addOption(confirmOpt);

  QCommandLineOption outputOpt(QStringList{"o", "output"},
                              QObject::tr("Where to save file. (defaults to "
                                          "current directory)"),
                              QObject::tr("dir"));
  parser.addOption(outputOpt);

  QCommandLineOption connsOpt(QStringList{"c", "conns"},
                              QObject::tr("Number of simultaneous connections to"
                                          " use. (defaults to 1)"),
                              QObject::tr("num"));
  parser.addOption(connsOpt);

  QCommandLineOption chunksOpt(QStringList{"chunks"},
                               QObject::tr("Number of chunks to split the download"
                                           "up into. Cannot be used with --chunk-size."),
                               QObject::tr("num"));
  parser.addOption(chunksOpt);

  QCommandLineOption chunkSizeOpt(QStringList{"chunk-size"},
                               QObject::tr("Size of each chunk which dictates "
                                           "how many to use. Cannot be used with --chunks."),
                               QObject::tr("bytes"));
  parser.addOption(chunkSizeOpt);

  // Process CLI arguments.
  parser.process(app);
  const QStringList args = parser.positionalArguments();
  if (args.size() != 1) {
    parser.showHelp(-1);
  }

  int conns = 1, chunks = -1, chunkSize = -1;
  bool ok, confirm = parser.isSet(confirmOpt),
    verbose = parser.isSet(verboseOpt);
  QString dir;

  if (parser.isSet(outputOpt)) {
    dir = parser.value(outputOpt);
    if (!QDir().exists(dir)) {
      qCritical() << "ERROR Output directory does not exist:" << dir;
      return -1;
    }
  }

  if (parser.isSet(connsOpt)) {
    conns = parser.value(connsOpt).toInt(&ok);
    if (!ok || conns <= 0) {
      qCritical() << "ERROR Number of connections must be a positive number!";
      return -1;
    }
  }

  if (parser.isSet(chunksOpt)) {
    chunks = parser.value(chunksOpt).toInt(&ok);
    if (!ok || chunks <= 0) {
      qCritical() << "ERROR Number of chunks must be a positive number!";
      return -1;
    }
  }

  if (parser.isSet(chunkSizeOpt)) {
    chunkSize = parser.value(chunkSizeOpt).toInt(&ok);
    if (!ok || chunkSize <= 0) {
      qCritical() << "ERROR Chunk size must be a positive number!";
      return -1;
    }
  }

  if (chunks != -1 && chunkSize != -1) {
    qCritical() << "ERROR --chunks and --chunk-size cannot be used at the same time!";
    return -1;
  }

  QUrl url{args[0], QUrl::StrictMode};
  if (!url.isValid()) {
    qCritical() << "ERROR Invalid URL!";
    return -1;
  }

  const QStringList schemes{"http", "https"};
  if (!schemes.contains(url.scheme().toLower())) {
    qCritical() << "ERROR Invalid scheme! Valid ones are:" <<
      qPrintable(schemes.join(" "));
    return -1;
  }

  Util::registerCustomTypes();

  // Begin transfer in event loop.
  Downloader dl{url, dir, conns, chunks, chunkSize, confirm, verbose};
  QObject::connect(&dl, &Downloader::finished, &app, &QCoreApplication::quit);
  QTimer::singleShot(0, &dl, SLOT(start()));

  return app.exec();
}
<commit_msg>Initializer lists..<commit_after>#include <QUrl>
#include <QDir>
#include <QDebug>
#include <QTimer>
#include <QCoreApplication>
#include <QCommandLineParser>

#include "Util.h"
#include "Version.h"
#include "Downloader.h"

int main(int argc, char **argv) {
  QCoreApplication app(argc, argv);
  QCoreApplication::setApplicationName("efdl");
  QCoreApplication::setApplicationVersion(versionString(false));

  QCommandLineParser parser;
  parser.setApplicationDescription(QObject::tr("Efficient downloading application."));
  parser.addHelpOption();
  parser.addVersionOption();
  parser.addPositionalArgument("URL", QObject::tr("URL to download."));

  QCommandLineOption verboseOpt(QStringList{"verbose"},
                                QObject::tr("Verbose mode."));
  parser.addOption(verboseOpt);

  QCommandLineOption confirmOpt(QStringList{"confirm"},
                                QObject::tr("Confirm to download on redirections."));
  parser.addOption(confirmOpt);

  QCommandLineOption outputOpt(QStringList{"o", "output"},
                              QObject::tr("Where to save file. (defaults to "
                                          "current directory)"),
                              QObject::tr("dir"));
  parser.addOption(outputOpt);

  QCommandLineOption connsOpt(QStringList{"c", "conns"},
                              QObject::tr("Number of simultaneous connections to"
                                          " use. (defaults to 1)"),
                              QObject::tr("num"));
  parser.addOption(connsOpt);

  QCommandLineOption chunksOpt(QStringList{"chunks"},
                               QObject::tr("Number of chunks to split the download"
                                           "up into. Cannot be used with --chunk-size."),
                               QObject::tr("num"));
  parser.addOption(chunksOpt);

  QCommandLineOption chunkSizeOpt(QStringList{"chunk-size"},
                               QObject::tr("Size of each chunk which dictates "
                                           "how many to use. Cannot be used with --chunks."),
                               QObject::tr("bytes"));
  parser.addOption(chunkSizeOpt);

  // Process CLI arguments.
  parser.process(app);
  const QStringList args = parser.positionalArguments();
  if (args.size() != 1) {
    parser.showHelp(-1);
  }

  int conns{1}, chunks{-1}, chunkSize{-1};
  bool ok{false}, confirm{parser.isSet(confirmOpt)},
    verbose{parser.isSet(verboseOpt)};
  QString dir;

  if (parser.isSet(outputOpt)) {
    dir = parser.value(outputOpt);
    if (!QDir().exists(dir)) {
      qCritical() << "ERROR Output directory does not exist:" << dir;
      return -1;
    }
  }

  if (parser.isSet(connsOpt)) {
    conns = parser.value(connsOpt).toInt(&ok);
    if (!ok || conns <= 0) {
      qCritical() << "ERROR Number of connections must be a positive number!";
      return -1;
    }
  }

  if (parser.isSet(chunksOpt)) {
    chunks = parser.value(chunksOpt).toInt(&ok);
    if (!ok || chunks <= 0) {
      qCritical() << "ERROR Number of chunks must be a positive number!";
      return -1;
    }
  }

  if (parser.isSet(chunkSizeOpt)) {
    chunkSize = parser.value(chunkSizeOpt).toInt(&ok);
    if (!ok || chunkSize <= 0) {
      qCritical() << "ERROR Chunk size must be a positive number!";
      return -1;
    }
  }

  if (chunks != -1 && chunkSize != -1) {
    qCritical() << "ERROR --chunks and --chunk-size cannot be used at the same time!";
    return -1;
  }

  QUrl url{args[0], QUrl::StrictMode};
  if (!url.isValid()) {
    qCritical() << "ERROR Invalid URL!";
    return -1;
  }

  const QStringList schemes{"http", "https"};
  if (!schemes.contains(url.scheme().toLower())) {
    qCritical() << "ERROR Invalid scheme! Valid ones are:" <<
      qPrintable(schemes.join(" "));
    return -1;
  }

  Util::registerCustomTypes();

  // Begin transfer in event loop.
  Downloader dl{url, dir, conns, chunks, chunkSize, confirm, verbose};
  QObject::connect(&dl, &Downloader::finished, &app, &QCoreApplication::quit);
  QTimer::singleShot(0, &dl, SLOT(start()));

  return app.exec();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdexcept>
#include <sstream>
#include <cstring>

#include "types.h"
#include "bus.h"
#include "cpu.h"
#include "ppu.h"
#include "ram.h"
#include "sdl_renderer.h"

class Emulator
{
public:
    Emulator();

    void read(const std::string& filename);

    int run();

private:
    BUS bus_;
    CPU cpu_;
    PPU ppu_;
    RAM ram_;
};

Emulator::Emulator()
    : bus_(cpu_, ppu_, ram_)
    , cpu_(bus_)
    , ppu_(bus_)
{
}

void Emulator::read(const std::string& filename)
{
    std::ifstream ifs(filename, std::ios_base::binary);

    if (ifs)
    {
        char header[4];
        ifs.read(header, 4);
        if (std::memcmp(header, "NES", 3) != 0 && header[3] != 0x1a)
            throw std::runtime_error(std::string("Bad file format"));

        char num_16kb_rom_banks;
        ifs.read(&num_16kb_rom_banks, 1);
        std::cout << "num_16kb_rom_banks: " << (int)num_16kb_rom_banks << std::endl;

        char num_8kb_vrom_banks;
        ifs.read(&num_8kb_vrom_banks, 1);
        std::cout << "num_8kb_vrom_banks: " << (int)num_8kb_vrom_banks << std::endl;

        char config[2];
        ifs.read(config, 2);
        std::cout << "config:\n"
            << "    mirroring: " << ((0x1 & config[0]) ? "vertical" : "horizontal") << "\n"
            << "    battery: " << ((0x2 & config[0]) >> 1) << "\n"
            << "    trainer: " << ((0x4 & config[0]) >> 2) << "\n"
            << "    four-screen: " << ((0x8 & config[0]) >> 3) << "\n"
            << "    VS-System cartige: " << ((0x1 & config[1])) << "\n";

        byte_t mapper = (byte_t)(config[1] & 0xf0 + (config[0] & 0xf0 >> 4));
        std::cout << "mapper: " << (int)mapper << std::endl;

        Mirroring mir = Mirroring::None;
        if (!((0x8 & config[0]) >> 3))
        {
            mir = (0x1 & config[0]) ? Mirroring::Vertical : Mirroring::Horizontal;
        }
        ppu_.set_mirroring(mir);

        char num_8kb_ram_banks;
        ifs.read(&num_8kb_ram_banks, 1);
        if (num_8kb_ram_banks == 0)
            num_8kb_ram_banks = 1;
        std::cout << "num_8kb_ram_banks: " << (int)num_8kb_ram_banks << std::endl;

        char cartige_type;
        ifs.read(&cartige_type, 1);
        std::cout << "cartige_type: " << (cartige_type >> 7) << std::endl;

        ifs.seekg(16);

        // trainer is 512B, skip it for now
        if (((0x4 & config[0]) >> 2) != 0)
            ifs.seekg(16 + 512);

        std::stringstream ss;
        ss << ifs.rdbuf();
        std::string buf{ss.str()};

        // Program rom (PRG-ROM) is loaded in $8000
        std::memcpy(ram_.data() + 0x8000, buf.data(), 0x8000);

        if (num_16kb_rom_banks == 1)
            std::memcpy(ram_.data() + 0xC000, buf.data(), 0x4000);

        // Character rom (CHR-ROM) is loaded in ppu $0000
        std::memcpy(ram_.data(), buf.data() + (0x4000 * num_16kb_rom_banks), 0x2000);
    }
    else
    {
        throw std::runtime_error(std::string("Can't open file ") + filename);
    }
}

int Emulator::run()
{
    SDLRenderer renderer;

    cpu_.reset();
    ppu_.reset();

    for (;;)
    {
        cpu_.next();
        for (int i = 0; i < 3; ++i) ppu_.next();

        if (renderer.timeout())
        {
            if (!renderer.update(ppu_))
                break;
        }
    }

    return 0;
}

int main(int argc, char* argv[])
{
    if (argc < 2)
        return 1;

    try
    {
        Emulator emul;
        emul.read(argv[1]);

        return emul.run();
    }
    catch (const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    return 0;
}
<commit_msg>Fixed typo<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdexcept>
#include <sstream>
#include <cstring>

#include "types.h"
#include "bus.h"
#include "cpu.h"
#include "ppu.h"
#include "ram.h"
#include "sdl_renderer.h"

class Emulator
{
public:
    Emulator();

    void read(const std::string& filename);

    int run();

private:
    BUS bus_;
    CPU cpu_;
    PPU ppu_;
    RAM ram_;
};

Emulator::Emulator()
    : bus_(cpu_, ppu_, ram_)
    , cpu_(bus_)
    , ppu_(bus_)
{
}

void Emulator::read(const std::string& filename)
{
    std::ifstream ifs(filename, std::ios_base::binary);

    if (ifs)
    {
        char header[4];
        ifs.read(header, 4);
        if (std::memcmp(header, "NES", 3) != 0 && header[3] != 0x1a)
            throw std::runtime_error(std::string("Bad file format"));

        char num_16kb_rom_banks;
        ifs.read(&num_16kb_rom_banks, 1);
        std::cout << "num_16kb_rom_banks: " << (int)num_16kb_rom_banks << std::endl;

        char num_8kb_vrom_banks;
        ifs.read(&num_8kb_vrom_banks, 1);
        std::cout << "num_8kb_vrom_banks: " << (int)num_8kb_vrom_banks << std::endl;

        char config[2];
        ifs.read(config, 2);
        std::cout << "config:\n"
            << "    mirroring: " << ((0x1 & config[0]) ? "vertical" : "horizontal") << "\n"
            << "    battery: " << ((0x2 & config[0]) >> 1) << "\n"
            << "    trainer: " << ((0x4 & config[0]) >> 2) << "\n"
            << "    four-screen: " << ((0x8 & config[0]) >> 3) << "\n"
            << "    VS-System cartige: " << ((0x1 & config[1])) << "\n";

        byte_t mapper = (byte_t)(config[1] & 0xf0 + (config[0] & 0xf0 >> 4));
        std::cout << "mapper: " << (int)mapper << std::endl;

        Mirroring mir = Mirroring::None;
        if (!((0x8 & config[0]) >> 3))
        {
            mir = (0x1 & config[0]) ? Mirroring::Vertical : Mirroring::Horizontal;
        }
        ppu_.set_mirroring(mir);

        char num_8kb_ram_banks;
        ifs.read(&num_8kb_ram_banks, 1);
        if (num_8kb_ram_banks == 0)
            num_8kb_ram_banks = 1;
        std::cout << "num_8kb_ram_banks: " << (int)num_8kb_ram_banks << std::endl;

        char cartige_type;
        ifs.read(&cartige_type, 1);
        std::cout << "cartige_type: " << (cartige_type >> 7) << std::endl;

        ifs.seekg(16);

        // trainer is 512B, skip it for now
        if (((0x4 & config[0]) >> 2) != 0)
            ifs.seekg(16 + 512);

        std::stringstream ss;
        ss << ifs.rdbuf();
        std::string buf{ss.str()};

        // Program rom (PRG-ROM) is loaded in $8000
        std::memcpy(ram_.data() + 0x8000, buf.data(), 0x8000);

        if (num_16kb_rom_banks == 1)
            std::memcpy(ram_.data() + 0xC000, buf.data(), 0x4000);

        // Character rom (CHR-ROM) is loaded in ppu $0000
        std::memcpy(ppu_.data(), buf.data() + (0x4000 * num_16kb_rom_banks), 0x2000);
    }
    else
    {
        throw std::runtime_error(std::string("Can't open file ") + filename);
    }
}

int Emulator::run()
{
    SDLRenderer renderer;

    cpu_.reset();
    ppu_.reset();

    for (;;)
    {
        cpu_.next();
        for (int i = 0; i < 3; ++i) ppu_.next();

        if (renderer.timeout())
        {
            if (!renderer.update(ppu_))
                break;
        }
    }

    return 0;
}

int main(int argc, char* argv[])
{
    if (argc < 2)
        return 1;

    try
    {
        Emulator emul;
        emul.read(argv[1]);

        return emul.run();
    }
    catch (const std::exception& e)
    {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    return 0;
}
<|endoftext|>


<commit_before>/**
 *  \file   perft.cc
 *  \author Jason Fernandez
 *  \date   11/10/2022
 */

#include <chrono>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <string>

#include "argparse/argparse.hpp"

#include "chess/position.h"
#include "chess/movegen.h"

/**
 * @brief PERFormance Test
 */
class Perft final {
public:
    /**
     * Run the performance test, computing the number of nodes
     * in the subtree below each move
     *
     * @param pos   The root position
     * @param depth Maximum recursive depth, in plies
     *
     * @return The total node count
     */
    std::size_t Divide(chess::Position* pos, std::size_t depth) {
        if (pos->ToMove() == chess::Player::kWhite) {
            return Divide_<chess::Player::kWhite>(pos, depth);
        } else {
            return Divide_<chess::Player::kBlack>(pos, depth);
        }
    }

    /**
     * Run the performance test
     *
     * @param pos   The root position
     * @param depth Maximum recursive depth, in plies
     *
     * @return The total node count
     */
    std::size_t Run(chess::Position* pos, std::size_t depth) {
        max_depth_ = depth;
        node_count_ = 0;

        if (pos->ToMove() == chess::Player::kWhite) {
            Trace<chess::Player::kWhite>(pos, 0);
        } else {
            Trace<chess::Player::kBlack>(pos, 0);
        }

        return node_count_;
    }

private:
    /**
     * Run divide() on the specified player
     *
     * @param pos   The root position
     * @param depth Maximum recursive depth, in plies
     *
     * @return The total node count
     */
    template <chess::Player P>
    std::size_t Divide_(chess::Position* pos, std::size_t depth) {
        max_depth_ = depth-1;

        std::size_t total_nodes = 0;

        std::uint32_t moves[chess::kMaxMoves];
        const std::size_t n_moves = !pos->InCheck<P>() ?
            chess::GenerateLegalMoves<P>(*pos, moves) :
            chess::GenerateCheckEvasions<P>(*pos, moves);

        for (std::size_t i = 0; i < n_moves; i++) {
            node_count_ = 0;

            const std::uint32_t move = moves[i];

            pos->MakeMove<P>(move, 0);

            Trace<chess::util::opponent<P>()>(pos, 1);

            pos->UnMakeMove<P>(move, 0);

            chess::Square orig = chess::util::ExtractFrom(move);
            chess::Square dest = chess::util::ExtractTo(move);

            std::cout << chess::kSquareStr[orig]
                      << chess::kSquareStr[dest] << ": " << node_count_
                      << std::endl;

            total_nodes += node_count_;
        }

        return total_nodes;
    }

    /**
     * @brief Internal recursive routine
     *
     * @tparam P The player whose turn it is at this depth
     *
     * @param pos   The current position
     * @param depth The current depth
     */
    template <chess::Player P>
    void Trace(chess::Position* pos, std::uint32_t depth) {
        if (depth >= max_depth_) {
            node_count_++;
        } else {
            std::uint32_t moves[chess::kMaxMoves];
            const std::size_t n_moves = !pos->InCheck<P>() ?
                chess::GenerateLegalMoves<P>(*pos, moves) :
                chess::GenerateCheckEvasions<P>(*pos, moves);

            if (n_moves == 0) {
                node_count_++;
            } else {
                for (std::size_t i = 0; i < n_moves; i++) {
                    const std::uint32_t move = moves[i];
                    pos->MakeMove<P>(move, depth);

                    Trace<chess::util::opponent<P>()>(pos, depth+1);

                    pos->UnMakeMove<P>(move, depth);
                }
            }
        }
    }

    /**
     * Maximum recursive trace depth
     */
    std::size_t max_depth_;

    /**
     * The total number of nodes visited
     */
    std::size_t node_count_;
};

/**
 * @brief Parse command line and run this program
 *
 * @param parser Command line parser
 *
 * @return True on success
 */
bool go(const argparse::ArgumentParser& parser) {
    const auto max_depth = parser.get<std::size_t>("--depth");
    const auto do_divide = parser.get<bool>("--divide");
    const auto fen       = parser.get<std::string>("--fen");

    chess::Position position;
    chess::Position::FenError error = position.Reset(fen);
    if (error != chess::Position::FenError::kSuccess) {
        std::cout << chess::Position::ErrorToString(error) << std::endl;
        return false;
    }

    Perft perft;

    const auto start = std::chrono::steady_clock::now();
    const std::size_t node_count =
        do_divide ? perft.Divide(&position, max_depth) :
                    perft.Run(&position, max_depth);
    const auto stop  = std::chrono::steady_clock::now();

    std::size_t ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                        start - stop).count();

    std::cout << "Nodes=" << node_count << " Time=" << ms << "ms"
              << std::endl;

    return true;
}

int main(int argc, char** argv) {
    argparse::ArgumentParser parser("perft");

    parser.add_argument("--depth")
        .help("The maximum recursive trace depth, in plies")
        .scan<'u', std::size_t>()
        .required();
    parser.add_argument("--divide")
        .help("If true, generate divide() results")
        .default_value(false)
        .implicit_value(true);
    parser.add_argument("--fen")
        .help("The root position in Forsyth-Edwards notation")
        .default_value(std::string());

    try {
        parser.parse_args(argc, argv);
    } catch (const std::runtime_error& error) {
        std::cerr << error.what() << std::endl;
        std::cerr << parser;
        return EXIT_FAILURE;
    }

    return go(parser) ? EXIT_SUCCESS : EXIT_FAILURE;
}
<commit_msg>Fix minimum depth bug<commit_after>/**
 *  \file   perft.cc
 *  \author Jason Fernandez
 *  \date   11/10/2022
 */

#include <chrono>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <string>

#include "argparse/argparse.hpp"

#include "chess/position.h"
#include "chess/movegen.h"

/**
 * @brief PERFormance Test
 */
class Perft final {
public:
    /**
     * Run the performance test, computing the number of nodes
     * in the subtree below each move
     *
     * @param pos   The root position
     * @param depth Maximum recursive depth, in plies
     *
     * @return The total node count
     */
    std::size_t Divide(chess::Position* pos, std::size_t depth) {
        if (pos->ToMove() == chess::Player::kWhite) {
            return Divide_<chess::Player::kWhite>(pos, depth);
        } else {
            return Divide_<chess::Player::kBlack>(pos, depth);
        }
    }

    /**
     * Run the performance test
     *
     * @param pos   The root position
     * @param depth Maximum recursive depth, in plies
     *
     * @return The total node count
     */
    std::size_t Run(chess::Position* pos, std::size_t depth) {
        max_depth_ = depth;
        node_count_ = 0;

        if (pos->ToMove() == chess::Player::kWhite) {
            Trace<chess::Player::kWhite>(pos, 0);
        } else {
            Trace<chess::Player::kBlack>(pos, 0);
        }

        return node_count_;
    }

private:
    /**
     * Run divide() on the specified player
     *
     * @param pos   The root position
     * @param depth Maximum recursive depth, in plies
     *
     * @return The total node count
     */
    template <chess::Player P>
    std::size_t Divide_(chess::Position* pos, std::size_t depth) {
        max_depth_ = depth == 0 ? depth : (depth-1);

        std::size_t total_nodes = 0;

        std::uint32_t moves[chess::kMaxMoves];
        const std::size_t n_moves = !pos->InCheck<P>() ?
            chess::GenerateLegalMoves<P>(*pos, moves) :
            chess::GenerateCheckEvasions<P>(*pos, moves);

        for (std::size_t i = 0; i < n_moves; i++) {
            node_count_ = 0;

            const std::uint32_t move = moves[i];

            pos->MakeMove<P>(move, 0);

            Trace<chess::util::opponent<P>()>(pos, 1);

            pos->UnMakeMove<P>(move, 0);

            chess::Square orig = chess::util::ExtractFrom(move);
            chess::Square dest = chess::util::ExtractTo(move);

            std::cout << chess::kSquareStr[orig]
                      << chess::kSquareStr[dest] << ": " << node_count_
                      << std::endl;

            total_nodes += node_count_;
        }

        return total_nodes;
    }

    /**
     * @brief Internal recursive routine
     *
     * @tparam P The player whose turn it is at this depth
     *
     * @param pos   The current position
     * @param depth The current depth
     */
    template <chess::Player P>
    void Trace(chess::Position* pos, std::uint32_t depth) {
        if (depth >= max_depth_) {
            node_count_++;
        } else {
            std::uint32_t moves[chess::kMaxMoves];
            const std::size_t n_moves = !pos->InCheck<P>() ?
                chess::GenerateLegalMoves<P>(*pos, moves) :
                chess::GenerateCheckEvasions<P>(*pos, moves);

            if (n_moves == 0) {
                node_count_++;
            } else {
                for (std::size_t i = 0; i < n_moves; i++) {
                    const std::uint32_t move = moves[i];
                    pos->MakeMove<P>(move, depth);

                    Trace<chess::util::opponent<P>()>(pos, depth+1);

                    pos->UnMakeMove<P>(move, depth);
                }
            }
        }
    }

    /**
     * Maximum recursive trace depth
     */
    std::size_t max_depth_;

    /**
     * The total number of nodes visited
     */
    std::size_t node_count_;
};

/**
 * @brief Parse command line and run this program
 *
 * @param parser Command line parser
 *
 * @return True on success
 */
bool go(const argparse::ArgumentParser& parser) {
    const auto max_depth = parser.get<std::size_t>("--depth");
    const auto do_divide = parser.get<bool>("--divide");
    const auto fen       = parser.get<std::string>("--fen");

    chess::Position position;
    chess::Position::FenError error = position.Reset(fen);
    if (error != chess::Position::FenError::kSuccess) {
        std::cout << chess::Position::ErrorToString(error) << std::endl;
        return false;
    }

    Perft perft;

    const auto start = std::chrono::steady_clock::now();
    const std::size_t node_count =
        do_divide ? perft.Divide(&position, max_depth) :
                    perft.Run(&position, max_depth);
    const auto stop  = std::chrono::steady_clock::now();

    std::size_t ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                        start - stop).count();

    std::cout << "Nodes=" << node_count << " Time=" << ms << "ms"
              << std::endl;

    return true;
}

int main(int argc, char** argv) {
    argparse::ArgumentParser parser("perft");

    parser.add_argument("--depth")
        .help("The maximum recursive trace depth, in plies")
        .scan<'u', std::size_t>()
        .required();
    parser.add_argument("--divide")
        .help("If true, generate divide() results")
        .default_value(false)
        .implicit_value(true);
    parser.add_argument("--fen")
        .help("The root position in Forsyth-Edwards notation")
        .default_value(std::string());

    try {
        parser.parse_args(argc, argv);
    } catch (const std::runtime_error& error) {
        std::cerr << error.what() << std::endl;
        std::cerr << parser;
        return EXIT_FAILURE;
    }

    return go(parser) ? EXIT_SUCCESS : EXIT_FAILURE;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <array>
#include <vector>
#include <list>
#include <functional>
#include <random>
#include <memory>
#include "GL/gl.h"
#include "GL/wglext.h"
#include "GL/glu.h"
#include "GLFW/glfw3.h"
#include "countof.h"

using std::cout;
using std::cerr;
using std::endl;
using std::vector;
using std::array;
using std::list;
using std::function;

struct vec2 {
	float x;
	float y;

	float dist2(vec2 b) {
		float dx = b.x-x, dy = b.y-y, len2=dx*dx+dy*dy;
		return len2;
	}
};

std::mt19937 rng;

typedef unsigned long long guid;
guid random_guid() {
	return std::uniform_int_distribution<guid>()(rng);
}

struct Object {
	Object() {}
	Object(vec2 pos, vec2 speed) : pos(pos), speed(speed) {}
	long guid = random_guid();
	vec2 pos;
	vec2 speed;

	bool operator==(const Object& other) {
		return guid == other.guid;
	}
};

template<typename T, typename... Args>
struct OwnedCallback {
	Object& o;
	function<T(Args...)> cb;

	T operator()(Args... args) {
		return cb(args...);
	}
};

struct Collision {
	// For now, simple quadratic collision
	struct Entry {
		Object& o;
	};
	list<Entry> chaff;
	list<Entry> bullets;

	void check(function<void(Object&, Object&)> fn) {
		float size = 0.1;
		for (auto x : chaff) {
			for (auto y : bullets) {
				if (x.o.pos.dist2(y.o.pos) < size*size) fn(x.o, y.o);
			}
		}
		for (auto x : chaff) {
			for (auto y : chaff) {
				if (x.o == y.o) continue;
				if (x.o.pos.dist2(y.o.pos) < size*size) fn(x.o, y.o);
			}
		}
	}
};

const float AST[] {
	0.4, 0,
	0, 0.4,
	-0.4, 0,
	0, -0.4,
};
const float SDX =.4, SYG=.8, SYD=.2, SYDD=.4;
const float SHIP[] {
	-SDX, -SYDD,
	0, SYG,
	SDX, -SYDD,
	0, -SYD,
};
const float BULLET[] {
	-1, 0,
	1, 0
};

const float* const MODELS[] { AST, SHIP, BULLET };
static constexpr int SIZES[] { 4, 4, 2 };

struct Renderer {

	struct Entry {
		Object& o;
		unsigned model;
		float* rotation;
	};
	list<Entry> entries;

	void add(Object& o, unsigned model) {
		entries.push_back(Entry { o, model, nullptr});
	}
	void add_with_rotation(Object& o, unsigned model, float* rotation) {
		entries.push_back(Entry { o, model, rotation});
	}

	void render() {
		glEnableClientState(GL_VERTEX_ARRAY);
		for (auto& e: entries) {
			render(e);
		}
	}

	void render(Entry& e) {
		float x = e.o.pos.x;
		float y = e.o.pos.y;
		const float* p = MODELS[e.model];
		int c = SIZES[e.model];
		glPushMatrix();
		glTranslatef(x, y, 0);
		if (e.rotation) {
			float angle = (*e.rotation) - M_PI/2;
			glRotatef(angle*180/M_PI, 0, 0, 1);
		}
		glVertexPointer(2, GL_FLOAT, 0, p);
		glDrawArrays(GL_LINE_LOOP, 0, c);
		glPopMatrix();
	}
};

struct World {
	list<Object> objects; // could be a vector, but reallocs will kill references in callbacks
	list<OwnedCallback<void>> tick_events;
	list<OwnedCallback<void>> queue;
	list<OwnedCallback<void, int, int, int, int>> key_events;
	list<Object*> killQueue;

	Collision collisions;
	Renderer renderer;

	void tick(float dt) {
		for (auto& o : objects) {
			o.pos.x += o.speed.x * dt;
			o.pos.y += o.speed.y * dt;
		}
		for (auto t : tick_events) {
			t();
		}
		collisions.check([](Object& a, Object& b) {
			cout << "collision: " << a.guid << " x " << b.guid << endl;
		});
		for (auto o : killQueue) {
			real_kill(*o);
		}
		killQueue.erase(killQueue.begin(), killQueue.end());
	}

	Object* find_by_guid(guid g) {
		for (auto& o : objects) {
			if (o.guid == g) {
				return &o;
			}
		}
		return 0;

	}

	Object& add_object() {
		objects.push_back(Object());
		return objects.back();
	}

	void keyfun(int key, int scancode, int action, int mods) {
		/*
		 * [in]	window	The window that received the event.
		 * [in]	key	The keyboard key that was pressed or released.
		 * [in]	scancode	The system-specific scancode of the key.
		 * [in]	action	GLFW_PRESS, GLFW_RELEASE or GLFW_REPEAT.
		 * [in]	mods	Bit field describing which modifier keys were held down
		 */
		for (auto x : key_events) {
			x(key, scancode, action, mods);
		}
	}

	void bind_key(int key, Object& o, std::function<void()> callback) {
		key_events.push_back(OwnedCallback<void, int, int, int, int>{o, [=](int key2, int scancode, int action, int mods){
			if (key2 == key and action == GLFW_PRESS) {
				callback();
			}
		}});
	}

	void on_tick(Object& o, std::function<void()> callback) {
		tick_events.push_back(OwnedCallback<void>{o, callback});
	}

	void kill(Object& o) {
		killQueue.push_back(&o);
	}

	void real_kill(Object& o) {
		cout << "Killing: " << o.guid << endl;
		key_events.remove_if([&](OwnedCallback<void, int, int, int, int>& oc) { return oc.o == o; });
		tick_events.remove_if([&](OwnedCallback<void>& oc) { return oc.o == o; });
		queue.remove_if([&](OwnedCallback<void>& oc) { return oc.o == o; });
		collisions.chaff.remove_if([&](Collision::Entry& e) { return e.o == o; });
		collisions.bullets.remove_if([&](Collision::Entry& e) { return e.o == o; });
		renderer.entries.remove_if([&](Renderer::Entry& e) { return e.o == o; });
		objects.remove(o);

	}
};

GLFWwindow* window;
World* cb_world;
void cb_key(GLFWwindow*, int key, int scancode, int action, int mods) {
	cb_world->keyfun(key, scancode, action, mods);
}

void WrapScreen(World& w, Object& o) {
	w.tick_events.push_back(OwnedCallback<void>{o, [&o](){
		float m = 0.1;
		float xa = -16-m, xb = 16+m, ya=-9-m, yb=9+m;
		float xw=xb-xa, yw=yb-ya;
		if (o.pos.x < xa) {
			o.pos.x += xw;
		}
		if (o.pos.x > xb) {
			o.pos.x -= xw;
		}
		if (o.pos.y < ya) {
			o.pos.y += yw;
		}
		if (o.pos.y > yb) {
			o.pos.y -= yw;
		}
	}});
}

void KillWhenExitingScreen(World& w, Object& o) {
	w.tick_events.push_back(OwnedCallback<void>{o, [&w, &o]() { // This can run less often
		float xa=-16, xb=16, ya=-9, yb=9;
		if (o.pos.x < xa or o.pos.x > xb or o.pos.y < ya or o.pos.y > yb) {
			w.kill(o);
		}
	}});
}

void Asteroid(World& w, Object& o) {
	w.renderer.add(o, 0);
	o.pos.x = std::uniform_real_distribution<float>(-16, 16)(rng);
	o.pos.y = std::uniform_real_distribution<float>(-9, 9)(rng);
	float speed = 0.3;
	float angle = std::uniform_real_distribution<float>(0, 44./7)(rng);
	o.speed.x = cos(angle)*speed;
	o.speed.y = sin(angle)*speed;
	WrapScreen(w, o);
	w.collisions.chaff.push_back(Collision::Entry{o});
}

void Bullet(World& w, Object& o) {
	KillWhenExitingScreen(w, o);
	w.renderer.add(o, 2);
	w.collisions.bullets.push_back(Collision::Entry{o});
}

void Player(World& w, Object& o) {
	o.pos.x = o.pos.y = 0;
	o.speed.x = o.speed.y = 0;
	WrapScreen(w, o);
	w.collisions.chaff.push_back(Collision::Entry{o});
	std::shared_ptr<float> angle(new float);
	w.renderer.add_with_rotation(o, 1, angle.get());

	w.on_tick(o, [&o, angle](){
		if (glfwGetKey(window, GLFW_KEY_RIGHT)) {
			*angle -= 0.1;
		}
		if (glfwGetKey(window, GLFW_KEY_LEFT)) {
			*angle += 0.1;
		}
		if (glfwGetKey(window, GLFW_KEY_UP)) {
			float acc = 0.1;
			o.speed.x += cos(*angle)*acc;
			o.speed.y += sin(*angle)*acc;
		}
		//ding_r(o.pos.x, o.pos.y, *angle);
	});
	w.bind_key(GLFW_KEY_SPACE, o, [&w, &o, angle](){
		auto& as = w.add_object();
		Bullet(w, as);
		as.pos = o.pos;
		float v = 16;
		as.speed.x = cos(*angle)*v;
		as.speed.y = sin(*angle)*v;
	});
}

int main(void)
{
	if (!glfwInit())
		return -1;
	glfwWindowHint(GLFW_SAMPLES, 4);

	// window = glfwCreateWindow(1366, 768, "Hello World", glfwGetPrimaryMonitor(), 0);
	window = glfwCreateWindow(800, 480, "Hello World", 0, 0);

	if (!window)
	{
		cerr << "Could not create window" << endl;
		glfwTerminate();
		exit(-1);
	}

	World world;
	cb_world = &world;
	glfwSetKeyCallback(window, cb_key);

	for (int i=0; i<5; ++i) {
		Asteroid(world, world.add_object());
	}
	Player(world, world.add_object());

	/* Make the window's context current */
	glfwMakeContextCurrent(window);
	double t0 = glfwGetTime();
	cout << glGetString(GL_VENDOR) << endl;
	cout << glGetString(GL_VERSION) << endl;
	cout << glGetString(GL_RENDERER) << endl;

	PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)glfwGetProcAddress("wglSwapIntervalEXT");
	if (wglSwapIntervalEXT) {
		wglSwapIntervalEXT(1);
	} else {
		cerr << "VSync not available" << endl;
	}

	glMatrixMode(GL_PROJECTION);
	glOrtho(-16, 16, -9, 9, 1, -1);
	glMatrixMode(GL_MODELVIEW);

	/* Loop until the user closes the window */
	while (!glfwWindowShouldClose(window))
	{
		double t1 = glfwGetTime();
		float dt = (t1 - t0);
		t0 = t1;
		/* Render here */
		glClearColor(1,.98, 1 ,0);
		glClear(GL_COLOR_BUFFER_BIT);

		glColor3f(.5,.2,0);
		world.tick(dt);
		world.renderer.render();

		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}
<commit_msg>Simplify stuff. Let each object have an angle<commit_after>#include <iostream>
#include <array>
#include <vector>
#include <list>
#include <functional>
#include <random>
#include <memory>
#include "GL/gl.h"
#include "GL/wglext.h"
#include "GL/glu.h"
#include "GLFW/glfw3.h"
#include "countof.h"

using std::cout;
using std::cerr;
using std::endl;
using std::vector;
using std::array;
using std::list;
using std::function;

struct vec2 {
	float x;
	float y;

	float dist2(vec2 b) {
		float dx = b.x-x, dy = b.y-y, len2=dx*dx+dy*dy;
		return len2;
	}
};

std::mt19937 rng;

typedef unsigned long long guid;
guid random_guid() {
	return std::uniform_int_distribution<guid>()(rng);
}

struct Object {
	long guid = random_guid();
	vec2 pos;
	vec2 speed;
	float angle = 0;
	float angular = 0;

	bool operator==(const Object& other) {
		return guid == other.guid;
	}
};

template<typename T, typename... Args>
struct OwnedCallback {
	Object& o;
	function<T(Args...)> cb;

	T operator()(Args... args) {
		return cb(args...);
	}
};

struct Collision {
	// For now, simple quadratic collision
	struct Entry {
		Object& o;
	};
	list<Entry> chaff;
	list<Entry> bullets;

	void check(function<void(Object&, Object&)> fn) {
		float size = 0.5;
		for (auto x : chaff) {
			for (auto y : bullets) {
				if (x.o.pos.dist2(y.o.pos) < size*size) fn(x.o, y.o);
			}
		}
		for (auto x : chaff) {
			for (auto y : chaff) {
				if (x.o == y.o) continue;
				if (x.o.pos.dist2(y.o.pos) < size*size) fn(x.o, y.o);
			}
		}
	}
};

const float AST[] {
	0.4, 0,
	0, 0.4,
	-0.4, 0,
	0, -0.4,
};
const float SDX =.4, SYG=.8, SYD=.2, SYDD=.4;
const float SHIP[] {
	-SDX, -SYDD,
	0, SYG,
	SDX, -SYDD,
	0, -SYD,
};
const float BULLET[] {
	0, -.3,
	0, .3,
};

const float* const MODELS[] { AST, SHIP, BULLET };
static constexpr int SIZES[] { 4, 4, 2 };

struct Renderer {

	struct Entry {
		Object& o;
		unsigned model;
	};
	list<Entry> entries;

	void add(Object& o, unsigned model) {
		entries.push_back(Entry { o, model });
	}

	void render() {
		glEnableClientState(GL_VERTEX_ARRAY);
		for (auto& e: entries) {
			render(e);
		}
	}

	void render(Entry& e) {
		float x = e.o.pos.x;
		float y = e.o.pos.y;
		const float* p = MODELS[e.model];
		int c = SIZES[e.model];
		glPushMatrix();
		glTranslatef(x, y, 0);
		if (e.o.angle) {
			float angle = (e.o.angle) - M_PI/2;
			glRotatef(angle*180/M_PI, 0, 0, 1);
		}
		glVertexPointer(2, GL_FLOAT, 0, p);
		glDrawArrays(GL_LINE_LOOP, 0, c);
		glPopMatrix();
	}
};

struct World {
	list<Object> objects; // could be a vector, but reallocs will kill references in callbacks
	list<OwnedCallback<void>> tick_events;
	list<OwnedCallback<void>> queue;
	list<OwnedCallback<void, int, int, int, int>> key_events;
	list<Object*> killQueue;

	Collision collisions;
	Renderer renderer;

	void tick(float dt) {
		for (auto& o : objects) {
			o.pos.x += o.speed.x * dt;
			o.pos.y += o.speed.y * dt;
			o.angle += o.angular * dt;
		}
		for (auto t : tick_events) {
			t();
		}
		collisions.check([](Object& a, Object& b) {
			cout << "collision: " << a.guid << " x " << b.guid << endl;
		});
		for (auto o : killQueue) {
			real_kill(*o);
		}
		killQueue.erase(killQueue.begin(), killQueue.end());
	}

	Object* find_by_guid(guid g) {
		for (auto& o : objects) {
			if (o.guid == g) {
				return &o;
			}
		}
		return 0;

	}

	Object& add_object() {
		objects.push_back(Object());
		return objects.back();
	}

	void keyfun(int key, int scancode, int action, int mods) {
		/*
		 * [in]	window	The window that received the event.
		 * [in]	key	The keyboard key that was pressed or released.
		 * [in]	scancode	The system-specific scancode of the key.
		 * [in]	action	GLFW_PRESS, GLFW_RELEASE or GLFW_REPEAT.
		 * [in]	mods	Bit field describing which modifier keys were held down
		 */
		for (auto x : key_events) {
			x(key, scancode, action, mods);
		}
	}

	void bind_key(int key, Object& o, std::function<void()> callback) {
		key_events.push_back(OwnedCallback<void, int, int, int, int>{o, [=](int key2, int scancode, int action, int mods){
			if (key2 == key and action == GLFW_PRESS) {
				callback();
			}
		}});
	}

	void on_tick(Object& o, std::function<void()> callback) {
		tick_events.push_back(OwnedCallback<void>{o, callback});
	}

	void kill(Object& o) {
		killQueue.push_back(&o);
	}

	void real_kill(Object& o) {
		cout << "Killing: " << o.guid << endl;
		key_events.remove_if([&](OwnedCallback<void, int, int, int, int>& oc) { return oc.o == o; });
		tick_events.remove_if([&](OwnedCallback<void>& oc) { return oc.o == o; });
		queue.remove_if([&](OwnedCallback<void>& oc) { return oc.o == o; });
		collisions.chaff.remove_if([&](Collision::Entry& e) { return e.o == o; });
		collisions.bullets.remove_if([&](Collision::Entry& e) { return e.o == o; });
		renderer.entries.remove_if([&](Renderer::Entry& e) { return e.o == o; });
		objects.remove(o);

	}
};

GLFWwindow* window;
World* cb_world;
void cb_key(GLFWwindow*, int key, int scancode, int action, int mods) {
	cb_world->keyfun(key, scancode, action, mods);
}

void WrapScreen(World& w, Object& o) {
	w.tick_events.push_back(OwnedCallback<void>{o, [&o](){
		float m = 0.1;
		float xa = -16-m, xb = 16+m, ya=-9-m, yb=9+m;
		float xw=xb-xa, yw=yb-ya;
		if (o.pos.x < xa) {
			o.pos.x += xw;
		}
		if (o.pos.x > xb) {
			o.pos.x -= xw;
		}
		if (o.pos.y < ya) {
			o.pos.y += yw;
		}
		if (o.pos.y > yb) {
			o.pos.y -= yw;
		}
	}});
}

void KillWhenExitingScreen(World& w, Object& o) {
	w.tick_events.push_back(OwnedCallback<void>{o, [&w, &o]() { // This can run less often
		float xa=-16, xb=16, ya=-9, yb=9;
		if (o.pos.x < xa or o.pos.x > xb or o.pos.y < ya or o.pos.y > yb) {
			w.kill(o);
		}
	}});
}

void Asteroid(World& w, Object& o) {
	w.renderer.add(o, 0);
	o.angular = 0.1;
	o.pos.x = std::uniform_real_distribution<float>(-16, 16)(rng);
	o.pos.y = std::uniform_real_distribution<float>(-9, 9)(rng);
	float speed = 0.3;
	float angle = std::uniform_real_distribution<float>(0, 44./7)(rng);
	o.speed.x = cos(angle)*speed;
	o.speed.y = sin(angle)*speed;
	WrapScreen(w, o);
	w.collisions.chaff.push_back(Collision::Entry{o});
}

void Bullet(World& w, Object& o) {
	KillWhenExitingScreen(w, o);
	w.renderer.add(o, 2);
	w.collisions.bullets.push_back(Collision::Entry{o});
}

void Player(World& w, Object& o) {
	o.pos.x = o.pos.y = 0;
	o.speed.x = o.speed.y = 0;
	WrapScreen(w, o);
	w.collisions.chaff.push_back(Collision::Entry{o});
	w.renderer.add(o, 1);

	w.on_tick(o, [&o](){
		if (glfwGetKey(window, GLFW_KEY_RIGHT)) {
			o.angle -= 0.1;
		}
		if (glfwGetKey(window, GLFW_KEY_LEFT)) {
			o.angle += 0.1;
		}
		if (glfwGetKey(window, GLFW_KEY_UP)) {
			float acc = 0.1;
			o.speed.x += cos(o.angle)*acc;
			o.speed.y += sin(o.angle)*acc;
		}
	});
	w.bind_key(GLFW_KEY_SPACE, o, [&w, &o](){
		auto& as = w.add_object();
		Bullet(w, as);
		as.pos = o.pos;
		as.angle = o.angle;
		float v = 16;
		as.speed.x = cos(o.angle)*v;
		as.speed.y = sin(o.angle)*v;
	});
}

int main(void)
{
	if (!glfwInit())
		return -1;
	glfwWindowHint(GLFW_SAMPLES, 4);

	// window = glfwCreateWindow(1366, 768, "Hello World", glfwGetPrimaryMonitor(), 0);
	window = glfwCreateWindow(800, 480, "Hello World", 0, 0);

	if (!window)
	{
		cerr << "Could not create window" << endl;
		glfwTerminate();
		exit(-1);
	}

	World world;
	cb_world = &world;
	glfwSetKeyCallback(window, cb_key);

	for (int i=0; i<5; ++i) {
		Asteroid(world, world.add_object());
	}
	Player(world, world.add_object());

	/* Make the window's context current */
	glfwMakeContextCurrent(window);
	double t0 = glfwGetTime();
	cout << glGetString(GL_VENDOR) << endl;
	cout << glGetString(GL_VERSION) << endl;
	cout << glGetString(GL_RENDERER) << endl;

	PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)glfwGetProcAddress("wglSwapIntervalEXT");
	if (wglSwapIntervalEXT) {
		wglSwapIntervalEXT(1);
	} else {
		cerr << "VSync not available" << endl;
	}

	glMatrixMode(GL_PROJECTION);
	glOrtho(-16, 16, -9, 9, 1, -1);
	glMatrixMode(GL_MODELVIEW);

	/* Loop until the user closes the window */
	while (!glfwWindowShouldClose(window))
	{
		double t1 = glfwGetTime();
		float dt = (t1 - t0);
		t0 = t1;
		/* Render here */
		glClearColor(1,.98, 1 ,0);
		glClear(GL_COLOR_BUFFER_BIT);

		glColor3f(.5,.2,0);
		world.tick(dt);
		world.renderer.render();

		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}
<|endoftext|>


<commit_before>/*
 * wiring-skeleton.cpp
 *
 *  Created on: 15.03.2017
 *      Author: niklausd
 */

#include <Arduino.h>

// PlatformIO libraries
#include <SerialCommand.h>  // pio lib install 173, lib details see https://github.com/kroimon/Arduino-SerialCommand
#include <Timer.h>          // pio lib install 1699, lib details see https://github.com/dniklaus/wiring-timer

// private libraries
#include <DbgCliNode.h>
#include <DbgCliTopic.h>
#include <DbgCliCommand.h>
#include <DbgTracePort.h>
#include <DbgTraceContext.h>
#include <DbgTraceOut.h>
#include <DbgPrintConsole.h>
#include <DbgTraceLevel.h>
#include <AppDebug.h>
#include <ProductDebug.h>
#include <RamUtils.h>

#ifndef BUILTIN_LED
#define BUILTIN_LED 13
#endif

SerialCommand* sCmd = 0;

void setup()
{
  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, 0);

  setupProdDebugEnv();
}

void loop()
{
  if (0 != sCmd)
  {
    sCmd->readSerial();     // process serial commands
  }
  yield();                  // process Timers
}
<commit_msg>call scheduleTimers() instead of yield() in the main loop (in order to be more portable)<commit_after>/*
 * wiring-skeleton.cpp
 *
 *  Created on: 15.03.2017
 *      Author: niklausd
 */

#include <Arduino.h>

// PlatformIO libraries
#include <SerialCommand.h>  // pio lib install 173, lib details see https://github.com/kroimon/Arduino-SerialCommand
#include <Timer.h>          // pio lib install 1699, lib details see https://github.com/dniklaus/wiring-timer

// private libraries
#include <DbgCliNode.h>
#include <DbgCliTopic.h>
#include <DbgCliCommand.h>
#include <DbgTracePort.h>
#include <DbgTraceContext.h>
#include <DbgTraceOut.h>
#include <DbgPrintConsole.h>
#include <DbgTraceLevel.h>
#include <AppDebug.h>
#include <ProductDebug.h>
#include <RamUtils.h>

#ifndef BUILTIN_LED
#define BUILTIN_LED 13
#endif

SerialCommand* sCmd = 0;

void setup()
{
  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, 0);

  setupProdDebugEnv();
}

void loop()
{
  if (0 != sCmd)
  {
    sCmd->readSerial();     // process serial commands
  }
  scheduleTimers();         // process Timers
}
<|endoftext|>


<commit_before>#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream>
#include "math.hpp"
#include "window.hpp"
#include "vectors.hpp"

vec3s camera = {3,0,0}; // положение камеры в сферических координатах
float dtheta = 0.01;
float dphi = 0.01;
WindowManager window( "Game Of Life On fieldace" );

void draw_quad( vec3d p0, vec3d p1, vec3d p2, vec3d p3 ) {
    glVertex3f( p0.x, p0.y, p0.z );
    glVertex3f( p1.x, p1.y, p1.z );
    glVertex3f( p2.x, p2.y, p2.z );
    glVertex3f( p3.x, p3.y, p3.z );
}

void draw_sphere( float radius, int UResolution, int VResolution ) {
    const float startU = 0.0f;
    const float startV = 0.0f;
    const float endU = M_PI;
    const float endV = M_2PI;
    const float stepU = ( endU - startU ) / (float) UResolution;
    const float stepV = ( endV - startV ) / (float) VResolution;
    glBegin( GL_QUADS );
    for ( int i = 0; i < UResolution; i++ ) {
        for ( int j = 0; j < VResolution; j++ ) {
            float u = (float) i * stepU + startU;
            float v = (float) j * stepV + startV;
            float un = (float) ( i + 1 ) * stepU + startU;
            float vn = (float) ( j + 1 ) * stepV + startV;
            vec3d p0 = vec3d( radius, u, v, true );
            vec3d p1 = vec3d( radius, u, vn, true );
            vec3d p2 = vec3d( radius, un, vn, true );
            vec3d p3 = vec3d( radius, un, v, true );
            draw_quad( p0, p1, p2, p3 );
        }
    }
    glEnd();
}

void golos_init( void ) {
    // init OpenGL params
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    glClearDepth( 1.0 );
    glDepthFunc( GL_LESS );
    glEnable( GL_DEPTH_TEST );
    glShadeModel( GL_SMOOTH );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 60.0f, (float) window.GetWidth() / (float) window.GetHeight(), 0.1f, 100.0f );
    glMatrixMode( GL_MODELVIEW );
}

void golos_event( SDL_Event * event ) {
    SDL_PollEvent( event );
    switch ( event->type ) {
        case SDL_QUIT:
            window.KillWindow();
            break;
        case SDL_KEYDOWN:
            switch ( event->key.keysym.sym ) {
                case SDLK_ESCAPE:
                case SDLK_q:
                    window.KillWindow();
                    break;
                case SDLK_DOWN:
                    camera.theta += dtheta;
                    if (camera.theta > M_PI) {
                        camera.phi += M_PI;
                        camera.theta -= M_PI;
                    }
                    break;
                case SDLK_UP:
                    camera.theta -= dtheta;
                    if (camera.theta < 0) {
                        camera.phi -= M_PI;
                        camera.theta += M_PI;
                    }
                    break;
                case SDLK_RIGHT:
                    camera.phi += dphi;
                    break;
                case SDLK_LEFT:
                    camera.phi -= dphi;
                    break;
                default:
                    break;
            }
            break;
        default:
            break;
    }
    //auto rc = vec3d(camera);
    //std::cout << "( " << camera.theta << ", " << camera.phi << " ) -> (" <<
    //"( " << rc.x << ", " << rc.y << ", " << rc.z << " )" << std::endl;
}

void golos_render( void ) {
    vec3d rect_camera = vec3d(camera); // положение камеры в прямоугольных координатах

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glColor3f( 0.0f, 1.0f, 0.0f );
    glLoadIdentity();
    gluLookAt( rect_camera.x, rect_camera.y, rect_camera.z, 0,  0, 0, 0, 0, 1 );
    glPolygonMode( GL_BACK, GL_LINE );
    glPolygonMode( GL_FRONT, GL_POINT );
    glColor3f( 0.0f, 1.0f, 0.0f );
    draw_sphere( 1.0f, 16, 32 );
    glFlush();
}

void golos_destroy( void ) {
    // insert code here
}

int main( int argc, char ** argv ) {
    window.SetInitFunc( golos_init );
    window.SetRenderFunc( golos_render );
    window.SetEventFunc( golos_event );
    window.MainLoop();
    golos_destroy();
    return EXIT_SUCCESS;
}
<commit_msg>[fix] направление рисования фигуры<commit_after>#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream>
#include "math.hpp"
#include "window.hpp"
#include "vectors.hpp"

vec3s camera = {3,0,0}; // положение камеры в сферических координатах
float dtheta = 0.01;
float dphi = 0.01;
WindowManager window( "Game Of Life On fieldace" );

void draw_quad( vec3d p0, vec3d p1, vec3d p2, vec3d p3 ) {
    glVertex3f( p0.x, p0.y, p0.z );
    glVertex3f( p1.x, p1.y, p1.z );
    glVertex3f( p2.x, p2.y, p2.z );
    glVertex3f( p3.x, p3.y, p3.z );
}

void draw_sphere( float radius, int UResolution, int VResolution ) {
    const float startU = 0.0f;
    const float startV = 0.0f;
    const float endU = M_PI;
    const float endV = M_2PI;
    const float stepU = ( endU - startU ) / (float) UResolution;
    const float stepV = ( endV - startV ) / (float) VResolution;
    glBegin( GL_QUADS );
    for ( int i = 0; i < UResolution; i++ ) {
        for ( int j = 0; j < VResolution; j++ ) {
            float u = (float) i * stepU + startU;
            float v = (float) j * stepV + startV;
            float un = (float) ( i + 1 ) * stepU + startU;
            float vn = (float) ( j + 1 ) * stepV + startV;
            vec3d p0 = vec3d( radius, u, v, true );
            vec3d p1 = vec3d( radius, un, v, true );
            vec3d p2 = vec3d( radius, un, vn, true );
            vec3d p3 = vec3d( radius, u, vn, true );
            draw_quad( p0, p1, p2, p3 );
        }
    }
    glEnd();
}

void golos_init( void ) {
    // init OpenGL params
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    glClearDepth( 1.0 );
    glDepthFunc( GL_LESS );
    glEnable( GL_DEPTH_TEST );
    glShadeModel( GL_SMOOTH );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 60.0f, (float) window.GetWidth() / (float) window.GetHeight(), 0.1f, 100.0f );
    glMatrixMode( GL_MODELVIEW );
}

void golos_event( SDL_Event * event ) {
    SDL_PollEvent( event );
    switch ( event->type ) {
        case SDL_QUIT:
            window.KillWindow();
            break;
        case SDL_KEYDOWN:
            switch ( event->key.keysym.sym ) {
                case SDLK_ESCAPE:
                case SDLK_q:
                    window.KillWindow();
                    break;
                case SDLK_DOWN:
                    camera.theta += dtheta;
                    if (camera.theta > M_PI) {
                        camera.phi += M_PI;
                        camera.theta -= M_PI;
                    }
                    break;
                case SDLK_UP:
                    camera.theta -= dtheta;
                    if (camera.theta < 0) {
                        camera.phi -= M_PI;
                        camera.theta += M_PI;
                    }
                    break;
                case SDLK_RIGHT:
                    camera.phi += dphi;
                    break;
                case SDLK_LEFT:
                    camera.phi -= dphi;
                    break;
                default:
                    break;
            }
            break;
        default:
            break;
    }
    //auto rc = vec3d(camera);
    //std::cout << "( " << camera.theta << ", " << camera.phi << " ) -> (" <<
    //"( " << rc.x << ", " << rc.y << ", " << rc.z << " )" << std::endl;
}

void golos_render( void ) {
    vec3d rect_camera = vec3d(camera); // положение камеры в прямоугольных координатах

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glColor3f( 0.0f, 1.0f, 0.0f );
    glLoadIdentity();
    gluLookAt( rect_camera.x, rect_camera.y, rect_camera.z, 0,  0, 0, 0, 0, 1 );
    glPolygonMode( GL_BACK, GL_POINT );
    glPolygonMode( GL_FRONT, GL_LINE );
    glColor3f( 0.0f, 1.0f, 0.0f );
    draw_sphere( 1.0f, 16, 32 );
    glFlush();
}

void golos_destroy( void ) {
    // insert code here
}

int main( int argc, char ** argv ) {
    window.SetInitFunc( golos_init );
    window.SetRenderFunc( golos_render );
    window.SetEventFunc( golos_event );
    window.MainLoop();
    golos_destroy();
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <time.h>

#include "bcm_host.h"

#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

#include "shader.h"
#include "inotify-cxx.h"

typedef struct {
    uint32_t screen_width;
    uint32_t screen_height;
    // OpenGL|ES objects
    EGLDisplay display;
    EGLSurface surface;
    EGLContext context;

    GLuint buf;

    Shader shader;

} CUBE_STATE_T;

static CUBE_STATE_T _state, *state=&_state;

#define check() assert(glGetError() == 0)

static void init_ogl(CUBE_STATE_T *state){
    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);
    check();

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);
    check();

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);
    check();

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);
    check();

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);
    check();

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
                                               0/*layer*/, &dst_rect, 0/*src*/,
                                               &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );
    check();

    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);
    check();

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);
    check();

    // Set background color and clear buffers
    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );

    check();
}

static bool loadFromPath(const std::string& path, std::string* into) {
    std::ifstream file;
    std::string buffer;

    file.open(path.c_str());
    if(!file.is_open()) return false;
    while(!file.eof()) {
        getline(file, buffer);
        (*into) += buffer + "\n";
    }

    file.close();
    return true;
}

static void draw(CUBE_STATE_T *state, GLfloat cx, GLfloat cy){
    // Now render to the main frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER,0);
    // Clear the background (not really necessary I suppose)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    check();

    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    check();
    state->shader.use();
    check();

    state->shader.sendUniform("u_time",((float)clock())/CLOCKS_PER_SEC);
    state->shader.sendUniform("u_mouse",cx, cy);
    state->shader.sendUniform("u_resolution",state->screen_width, state->screen_height);
    check();

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    check();

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glFlush();
    glFinish();
    check();

    eglSwapBuffers(state->display, state->surface);
    check();
}

static int get_mouse(CUBE_STATE_T *state, int *outx, int *outy){
    static int fd = -1;
    const int width=state->screen_width, height=state->screen_height;
    static int x=800, y=400;
    const int XSIGN = 1<<4, YSIGN = 1<<5;
    if (fd<0) {
       fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
    }
    if (fd>=0) {
        struct {char buttons, dx, dy; } m;
        while (1) {
           int bytes = read(fd, &m, sizeof m);
           if (bytes < (int)sizeof m) goto _exit;
           if (m.buttons&8) {
              break; // This bit should always be set
           }
           read(fd, &m, 1); // Try to sync up again
        }
        if (m.buttons&3)
           return m.buttons&3;
        x+=m.dx;
        y+=m.dy;
        if (m.buttons&XSIGN)
           x-=256;
        if (m.buttons&YSIGN)
           y-=256;
        if (x<0) x=0;
        if (y<0) y=0;
        if (x>width) x=width;
        if (y>height) y=height;
   }
_exit:
   if (outx) *outx = x;
   if (outy) *outy = y;
   return 0;
}

//==============================================================================

int main(int argc, char **argv){
   int terminate = 0;
   GLfloat cx, cy;
   bcm_host_init();

   // Clear application state
    memset( state, 0, sizeof( *state ) );

    // Start OGLES
    init_ogl(state);
    // init_shaders(state, std::string(argv[1]) );

    //  Build shader;
    //
    std::string fragSource;
    std::string vertSource =
    "attribute vec4 a_position;"
    "varying vec2 v_texcoord;"
    "void main(void) {"
    "    gl_Position = a_position;"
    "    v_texcoord = a_position.xy*0.5+0.5;"
    "}";
    if(!loadFromPath(std::string(argv[1]), &fragSource)) {
        return;
    }
    state->shader.build(fragSource,vertSource);

    //  Make Quad
    //
    static const GLfloat vertex_data[] = {
        -1.0,-1.0,1.0,1.0,
        1.0,-1.0,1.0,1.0,
        1.0,1.0,1.0,1.0,
        -1.0,1.0,1.0,1.0
    };
    GLint posAttribut = state->shader.getAttribLocation("a_position");

    glClearColor ( 0.0, 1.0, 1.0, 1.0 );

    glGenBuffers(1, &state->buf);
    check();

    // Prepare viewport
    glViewport ( 0, 0, state->screen_width, state->screen_height );
    check();

    // Upload vertex data to a buffer
    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
                 vertex_data, GL_STATIC_DRAW);
    glVertexAttribPointer(posAttribut, 4, GL_FLOAT, 0, 16, 0);
    glEnableVertexAttribArray(posAttribut);
    check();

    while (!terminate){
        int x, y, b;
        b = get_mouse(state, &x, &y);
        if (b) break;
        draw(state, x, y);
    }
    return 0;
}

<commit_msg>trying inotify<commit_after>#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <time.h>

#include "bcm_host.h"

#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

#include "shader.h"
#include "inotify-cxx.h"

typedef struct {
    uint32_t screen_width;
    uint32_t screen_height;
    // OpenGL|ES objects
    EGLDisplay display;
    EGLSurface surface;
    EGLContext context;

    GLuint buf;

    Shader shader;

} CUBE_STATE_T;

static CUBE_STATE_T _state, *state=&_state;

#define check() assert(glGetError() == 0)

static void init_ogl(CUBE_STATE_T *state){
    int32_t success = 0;
    EGLBoolean result;
    EGLint num_config;

    static EGL_DISPMANX_WINDOW_T nativewindow;

    DISPMANX_ELEMENT_HANDLE_T dispman_element;
    DISPMANX_DISPLAY_HANDLE_T dispman_display;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;

    static const EGLint attribute_list[] = {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };

    static const EGLint context_attributes[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    EGLConfig config;

    // get an EGL display connection
    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    assert(state->display!=EGL_NO_DISPLAY);
    check();

    // initialize the EGL display connection
    result = eglInitialize(state->display, NULL, NULL);
    assert(EGL_FALSE != result);
    check();

    // get an appropriate EGL frame buffer configuration
    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
    assert(EGL_FALSE != result);
    check();

    // get an appropriate EGL frame buffer configuration
    result = eglBindAPI(EGL_OPENGL_ES_API);
    assert(EGL_FALSE != result);
    check();

    // create an EGL rendering context
    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes);
    assert(state->context!=EGL_NO_CONTEXT);
    check();

    // create an EGL window surface
    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
    assert( success >= 0 );

    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = state->screen_width;
    dst_rect.height = state->screen_height;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = state->screen_width << 16;
    src_rect.height = state->screen_height << 16;

    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
    dispman_update = vc_dispmanx_update_start( 0 );
    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
                                               0/*layer*/, &dst_rect, 0/*src*/,
                                               &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);

    nativewindow.element = dispman_element;
    nativewindow.width = state->screen_width;
    nativewindow.height = state->screen_height;
    vc_dispmanx_update_submit_sync( dispman_update );
    check();

    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
    assert(state->surface != EGL_NO_SURFACE);
    check();

    // connect the context to the surface
    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
    assert(EGL_FALSE != result);
    check();

    // Set background color and clear buffers
    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
    glClear( GL_COLOR_BUFFER_BIT );

    check();
}

static bool loadFromPath(const std::string& path, std::string* into) {
    std::ifstream file;
    std::string buffer;

    file.open(path.c_str());
    if(!file.is_open()) return false;
    while(!file.eof()) {
        getline(file, buffer);
        (*into) += buffer + "\n";
    }

    file.close();
    return true;
}

static void draw(CUBE_STATE_T *state, GLfloat cx, GLfloat cy){
    // Now render to the main frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER,0);
    // Clear the background (not really necessary I suppose)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    check();

    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    check();
    state->shader.use();
    check();

    state->shader.sendUniform("u_time",((float)clock())/CLOCKS_PER_SEC);
    state->shader.sendUniform("u_mouse",cx, cy);
    state->shader.sendUniform("u_resolution",state->screen_width, state->screen_height);
    check();

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    check();

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glFlush();
    glFinish();
    check();

    eglSwapBuffers(state->display, state->surface);
    check();
}

static int get_mouse(CUBE_STATE_T *state, int *outx, int *outy){
    static int fd = -1;
    const int width=state->screen_width, height=state->screen_height;
    static int x=800, y=400;
    const int XSIGN = 1<<4, YSIGN = 1<<5;
    if (fd<0) {
       fd = open("/dev/input/mouse0",O_RDONLY|O_NONBLOCK);
    }
    if (fd>=0) {
        struct {char buttons, dx, dy; } m;
        while (1) {
           int bytes = read(fd, &m, sizeof m);
           if (bytes < (int)sizeof m) goto _exit;
           if (m.buttons&8) {
              break; // This bit should always be set
           }
           read(fd, &m, 1); // Try to sync up again
        }
        if (m.buttons&3)
           return m.buttons&3;
        x+=m.dx;
        y+=m.dy;
        if (m.buttons&XSIGN)
           x-=256;
        if (m.buttons&YSIGN)
           y-=256;
        if (x<0) x=0;
        if (y<0) y=0;
        if (x>width) x=width;
        if (y>height) y=height;
   }
_exit:
   if (outx) *outx = x;
   if (outy) *outy = y;
   return 0;
}

//==============================================================================

int main(int argc, char **argv){

    Inotify notify;

    InotifyWatch watch(string(argv[1]), IN_ALL_EVENTS);
    notify.Add(watch);

    for (;;) {
            notify.WaitForEvents();

            size_t count = notify.GetEventCount();
            while (count > 0) {
                InotifyEvent event;
                bool got_event = notify.GetEvent(&event);

                if (got_event) {
                    std::string mask_str;
                    event.DumpTypes(mask_str);

                    std::string filename = event.GetName();

                    std::cout << "[watch " << watch_dir << "] ";
                    std::cout << "event mask: \"" << mask_str << "\", ";
                    std::cout << "filename: \"" << filename << "\"" << std::endl;
                }

                count--;
            }
        }

        return 0;

    int terminate = 0;
    GLfloat cx, cy;
    bcm_host_init();

    // Clear application state
    memset( state, 0, sizeof( *state ) );

    // Start OGLES
    init_ogl(state);
    // init_shaders(state, std::string(argv[1]) );

    //  Build shader;
    //
    std::string fragSource;
    std::string vertSource =
    "attribute vec4 a_position;"
    "varying vec2 v_texcoord;"
    "void main(void) {"
    "    gl_Position = a_position;"
    "    v_texcoord = a_position.xy*0.5+0.5;"
    "}";
    if(!loadFromPath(std::string(argv[1]), &fragSource)) {
        return;
    }
    state->shader.build(fragSource,vertSource);

    //  Make Quad
    //
    static const GLfloat vertex_data[] = {
        -1.0,-1.0,1.0,1.0,
        1.0,-1.0,1.0,1.0,
        1.0,1.0,1.0,1.0,
        -1.0,1.0,1.0,1.0
    };
    GLint posAttribut = state->shader.getAttribLocation("a_position");

    glClearColor ( 0.0, 1.0, 1.0, 1.0 );

    glGenBuffers(1, &state->buf);
    check();

    // Prepare viewport
    glViewport ( 0, 0, state->screen_width, state->screen_height );
    check();

    // Upload vertex data to a buffer
    glBindBuffer(GL_ARRAY_BUFFER, state->buf);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
                 vertex_data, GL_STATIC_DRAW);
    glVertexAttribPointer(posAttribut, 4, GL_FLOAT, 0, 16, 0);
    glEnableVertexAttribArray(posAttribut);
    check();

    while (!terminate){
        int x, y, b;
        b = get_mouse(state, &x, &y);
        if (b) break;
        draw(state, x, y);
    }
    return 0;
}

<|endoftext|>


<commit_before>#define GLM_FORCE_RADIANS
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <iostream>
#include <stdio.h>

#include "gfx/Renderer.h"
#include "gfx/VertexArray.h"
#include "gfx/shader/SimpleShader.h"
#include "input/Input.h"
#include "input/Action.h"

static void error_callback(int error, const char* description)
{
  fputs(description, stderr);
}
auto camera = std::make_shared<Camera>();
float step = 0.01f;

const int width = 640;
const int height = 480;
int main(int argc, char ** argv) {
  glfwSetErrorCallback(error_callback);
  if (!glfwInit())
    exit(EXIT_FAILURE);

  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  GLFWwindow* window = glfwCreateWindow(width, height, "Simple example", NULL, NULL);
  if (!window) {
    glfwTerminate();
    exit(EXIT_FAILURE);
  }
  glfwMakeContextCurrent(window);

  glewExperimental = GL_TRUE;
  GLenum err = glewInit();
  if(GLEW_OK != err) {
    std::cout << glewGetErrorString(err) << std::endl;
  }

  {
    const GLubyte* renderer = glGetString(GL_RENDERER);
    const GLubyte* version = glGetString(GL_VERSION);
    printf("Renderer: %s\n", renderer);
    printf("Version: %s\n", version);
    glfwSetCursorPosCallback(window, Input::cursor_pos_callback);
    glfwSetKeyCallback(window, Input::key_callback);
  }

  auto vArray = VertexArray{{
      {0, 0.5f, 0},
      {0.5f, 0, 0},
      {0.5f, 0.5f, 0}
      }};
  vArray.flip();
  auto vArrayPtr = std::make_shared<VertexArray>(vArray);

  Input::on(Action::Forward, []() {
    camera->translate({0, 0, -step});
  });
  Input::on(Action::Backward, []() {
    camera->translate({0, 0, step});
  });
  Input::on(Action::Left, []() {
    camera->translate({-step, 0, 0});
  });
  Input::on(Action::Right, []() {
    camera->translate({step, 0, 0});
  });
  Input::on(Action::Up, []() {
    camera->translate({0, -step, 0});
  });
  Input::on(Action::Down, []() {
    camera->translate({0, step, 0});
  });

  auto rObj1 = std::make_shared<RenderObject>(vArrayPtr);
  auto rObj2 = std::make_shared<RenderObject>(vArrayPtr);
  Renderer renderer(width, height);
  renderer.addObject(rObj1);
  renderer.addObject(rObj2);
  renderer.setCamera(camera);
  rObj1->translate({0,0,3});
  rObj2->translate({0.25f, 0.5f, 5});
  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  while (!glfwWindowShouldClose(window)) {
    Input::handleInput();
    glfwPollEvents();
    glClear(GL_COLOR_BUFFER_BIT);
    renderer.render();
    glfwSwapBuffers(window);
    Input::resetDelta();
  }
  glfwDestroyWindow(window);
  glfwTerminate();
  exit(EXIT_SUCCESS);
}
<commit_msg>Removed unneccessary copy of vertexarray<commit_after>#define GLM_FORCE_RADIANS
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <iostream>
#include <stdio.h>

#include "gfx/Renderer.h"
#include "gfx/VertexArray.h"
#include "gfx/shader/SimpleShader.h"
#include "input/Input.h"
#include "input/Action.h"

static void error_callback(int error, const char* description)
{
  fputs(description, stderr);
}
auto camera = std::make_shared<Camera>();
float step = 0.01f;

const int width = 640;
const int height = 480;
int main(int argc, char ** argv) {
  glfwSetErrorCallback(error_callback);
  if (!glfwInit())
    exit(EXIT_FAILURE);

  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  GLFWwindow* window = glfwCreateWindow(width, height, "Simple example", NULL, NULL);
  if (!window) {
    glfwTerminate();
    exit(EXIT_FAILURE);
  }
  glfwMakeContextCurrent(window);

  glewExperimental = GL_TRUE;
  GLenum err = glewInit();
  if(GLEW_OK != err) {
    std::cout << glewGetErrorString(err) << std::endl;
  }

  {
    const GLubyte* renderer = glGetString(GL_RENDERER);
    const GLubyte* version = glGetString(GL_VERSION);
    printf("Renderer: %s\n", renderer);
    printf("Version: %s\n", version);
    glfwSetCursorPosCallback(window, Input::cursor_pos_callback);
    glfwSetKeyCallback(window, Input::key_callback);
  }

  auto vArrayPtr = std::shared_ptr<VertexArray>(new VertexArray{{
      {0, 0.5f, 0},
      {0.5f, 0, 0},
      {0.5f, 0.5f, 0}
      }});
  vArrayPtr->flip();

  Input::on(Action::Forward, []() {
    camera->translate({0, 0, -step});
  });
  Input::on(Action::Backward, []() {
    camera->translate({0, 0, step});
  });
  Input::on(Action::Left, []() {
    camera->translate({-step, 0, 0});
  });
  Input::on(Action::Right, []() {
    camera->translate({step, 0, 0});
  });
  Input::on(Action::Up, []() {
    camera->translate({0, -step, 0});
  });
  Input::on(Action::Down, []() {
    camera->translate({0, step, 0});
  });

  auto rObj1 = std::make_shared<RenderObject>(vArrayPtr);
  auto rObj2 = std::make_shared<RenderObject>(vArrayPtr);
  Renderer renderer(width, height);
  renderer.addObject(rObj1);
  renderer.addObject(rObj2);
  renderer.setCamera(camera);
  rObj1->translate({0,0,3});
  rObj2->translate({0.25f, 0.5f, 5});
  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  while (!glfwWindowShouldClose(window)) {
    Input::handleInput();
    glfwPollEvents();
    glClear(GL_COLOR_BUFFER_BIT);
    renderer.render();
    glfwSwapBuffers(window);
    Input::resetDelta();
  }
  glfwDestroyWindow(window);
  glfwTerminate();
  exit(EXIT_SUCCESS);
}
<|endoftext|>