<commit_before>/* Copyright 2014 Andrew Schwartzmeyer
 *
 * University of Idaho - CS 472: Evolutionary Computation by Terry Soule
 *
 * Project #1 Genetic Algorithm
 *
 * This program uses C++11 extensions (array template, range-based for
 * loop, random library)
 */

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <memory>

// boost
#include <boost/program_options.hpp>

// aliases
#include "aliases.hpp"

// individual
#include "individual/individual.hpp"

// algorithms
#include "algorithm/algorithm.hpp"
#include "algorithm/genetic_algorithm.hpp"
#include "algorithm/hill_climbing_algorithm.hpp"
#include "algorithm/simulated_annealing_algorithm.hpp"
#include "algorithm/mutator/mutator.hpp"
#include "algorithm/mutator/mutator_creep.hpp"
#include "algorithm/mutator/mutator_gaussian.hpp"
#include "algorithm/mutator/mutator_jumping.hpp"
#include "algorithm/recombinator/recombinator.hpp"
#include "algorithm/recombinator/recombinator_arithmetic.hpp"
#include "algorithm/recombinator/recombinator_two_point.hpp"
#include "algorithm/recombinator/recombinator_uniform.hpp"

// problems
#include "problem/problem.hpp"
#include "problem/ackley_problem.hpp"
#include "problem/griewangk_problem.hpp"
#include "problem/rastrigin_problem.hpp"
#include "problem/rosenbrock_problem.hpp"
#include "problem/schwefel_problem.hpp"
#include "problem/spherical_problem.hpp"

int main(int argc, char * argv[]) {
  namespace po = boost::program_options;
  using namespace std;
  using aliases::parameter;
  using namespace algorithm;
  using namespace problem;
  // setup program options
  string po_algorithm;
  vector<string> po_problems;
  long po_iterations;
  parameter po_goal;
  po::positional_options_description positionals;
  po::variables_map variables_map;
  po::options_description desc("Allowed options");
  desc.add_options()
    ("help,h", "produce help message")
    ("algorithm,a",
     po::value<string>(&po_algorithm)->default_value("Genetic"),
     "choose algorithm, currently unimplemented")
    ("problem,p",
     po::value<vector<string>>(&po_problems),
     "choose problem(s), must be Title case, defaults to all")
    ("mutator,m",
     po::value<string>(&po_mutator)->default_value("Jumping"),
     "choose mutator, creep, gaussian, jumping")
    ("iterations,i",
     po::value<long>(&po_iterations)->default_value(256),
     "set max iterations/generations")
    ("goal,g",
     po::value<parameter>(&po_goal)->default_value(0),
     "set goal, default will run until iterations is exhausted");
  try {
    po::store(po::command_line_parser(argc, argv).
	      options(desc).positional(positionals).run(), variables_map);
    if (variables_map.count("help")) {
      cout << "Search algorithms implemented in C++ by Andrew Schwartzmeyer\n\n"
	   << "Code located at https://github.com/andschwa/uidaho-cs472-project1\n\n"
	   << "Algorithms: Genetic, HillClimbing, and SimulatedAnnealing\n\n"
	   << "Problems: Ackley, Griewangk, Rastrigin, Rosenbrock, Schwefel, and Spherical\n\n"
	   << "Mutators: Creep, Gaussian, Jumping"
	   << "Logs saved to logs/<Problem>.dat\n"
	   << "GNUPlot settings in logs/<Problem>.p\n\n"
	   << desc << endl;
      return 0;
    }
    po::notify(variables_map);
    // add all problems if none specified
    if (po_problems.size() == 0) {
      po_problems.emplace_back("Ackley");
      po_problems.emplace_back("Griewangk");
      po_problems.emplace_back("Rastrigin");
      po_problems.emplace_back("Rosenbrock");
      po_problems.emplace_back("Schwefel");
      po_problems.emplace_back("Spherical");
    }
  }
  catch(exception& e) {
    cout << e.what() << '\n';
    return 1;
  }

  // setup mutator
  unique_ptr<const Mutator> working_mutator;
  if (po_mutator.compare("creep") == 0 || po_mutator.compare("Creep") == 0)
    working_mutator = unique_ptr<const Mutator>(new mutator::Creep());
  else if (po_mutator.compare("gaussian") == 0 || po_mutator.compare("Gaussian") == 0)
    working_mutator = unique_ptr<const Mutator>(new mutator::Gaussian());
  else if (po_mutator.compare("jumping") == 0 || po_mutator.compare("Jumping") == 0)
    working_mutator = unique_ptr<const Mutator>(new mutator::Jumping());

  // setup recombinator
  shared_ptr<const Recombinator> working_recombinator;
  if (po_recombinator.compare("arithmetic") == 0 || po_recombinator.compare("Arithmetic") == 0)
    working_recombinator = shared_ptr<const Recombinator>(new recombinator::Arithmetic());
  else if (po_recombinator.compare("two-point") == 0 || po_recombinator.compare("Two-Point") == 0)
    working_recombinator = shared_ptr<const Recombinator>(new recombinator::TwoPoint());
  else if (po_recombinator.compare("uniform") == 0 || po_recombinator.compare("Uniform") == 0)
    working_recombinator = shared_ptr<const Recombinator>(new recombinator::Uniform());

  // setup each problem and run the GA on it
  unique_ptr<Problem> working_problem;
  for (const string name : po_problems) {
    // Ugly replace of switch(name), better than find_if
    if (name.compare("Ackley") == 0 || name.compare("ackley") == 0)
      working_problem = unique_ptr<Problem>(new Ackley(po_iterations, po_goal));
    else if (name.compare("Griewangk") == 0 || name.compare("griewangk") == 0)
      working_problem = unique_ptr<Problem>(new Griewangk(po_iterations, po_goal));
    else if (name.compare("Rastrigin") == 0 || name.compare("rastrigin") == 0)
      working_problem = unique_ptr<Problem>(new Rastrigin(po_iterations, po_goal));
    else if (name.compare("Rosenbrock") == 0 || name.compare("rosenbrock") == 0)
      working_problem = unique_ptr<Problem>(new Rosenbrock(po_iterations, po_goal));
    else if (name.compare("Schwefel") == 0 || name.compare("schwefel") == 0)
      working_problem = unique_ptr<Problem>(new Schwefel(po_iterations, po_goal));
    else if (name.compare("Spherical") == 0 || name.compare("spherical") == 0)
      working_problem = unique_ptr<Problem>(new Spherical(po_iterations, po_goal));
    // Run GA on problem
    if (working_problem != nullptr) {
      Genetic algorithm(*working_problem, *working_mutator, working_recombinator);
      const Individual solution = algorithm.solve();
      cout << working_problem->represent() << solution.represent()
	   << "Raw fitness: " << solution.fitness << '\n' << endl;
    }
  }
  return 0;
}
<commit_msg>Updating program options<commit_after>/* Copyright 2014 Andrew Schwartzmeyer
 *
 * University of Idaho - CS 472: Evolutionary Computation by Terry Soule
 *
 * Project #1 Genetic Algorithm
 *
 * This program uses C++11 extensions (array template, range-based for
 * loop, random library)
 */

#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <memory>

// boost
#include <boost/program_options.hpp>

// aliases
#include "aliases.hpp"

// individual
#include "individual/individual.hpp"

// algorithms
#include "algorithm/algorithm.hpp"
#include "algorithm/genetic_algorithm.hpp"
#include "algorithm/hill_climbing_algorithm.hpp"
#include "algorithm/simulated_annealing_algorithm.hpp"
#include "algorithm/mutator/mutator.hpp"
#include "algorithm/mutator/mutator_creep.hpp"
#include "algorithm/mutator/mutator_gaussian.hpp"
#include "algorithm/mutator/mutator_jumping.hpp"
#include "algorithm/recombinator/recombinator.hpp"
#include "algorithm/recombinator/recombinator_arithmetic.hpp"
#include "algorithm/recombinator/recombinator_two_point.hpp"
#include "algorithm/recombinator/recombinator_uniform.hpp"

// problems
#include "problem/problem.hpp"
#include "problem/ackley_problem.hpp"
#include "problem/griewangk_problem.hpp"
#include "problem/rastrigin_problem.hpp"
#include "problem/rosenbrock_problem.hpp"
#include "problem/schwefel_problem.hpp"
#include "problem/spherical_problem.hpp"

int main(int argc, char * argv[]) {
  namespace po = boost::program_options;
  using namespace std;
  using aliases::parameter;
  using namespace algorithm;
  using namespace problem;
  // setup program options
  string po_algorithm;
  vector<string> po_problems;
  string po_mutator;
  string po_recombinator;
  long po_iterations;
  parameter po_goal;
  po::positional_options_description positionals;
  po::variables_map variables_map;
  po::options_description desc("Allowed options");
  desc.add_options()
    ("help,h", "produce help message")
    ("algorithm,a",
     po::value<string>(&po_algorithm)->default_value("Genetic"),
     "choose algorithm, currently unimplemented")
    ("problem,p",
     po::value<vector<string>>(&po_problems),
     "choose problem(s), defaults to all")
    ("mutator,m",
     po::value<string>(&po_mutator)->default_value("Jumping"),
     "choose mutator, creep, gaussian, jumping")
    ("recombinator,r",
     po::value<string>(&po_recombinator)->default_value("Two-Point"),
     "choose recombinator, arithmetic, two-point, uniform")
    ("iterations,i",
     po::value<long>(&po_iterations)->default_value(256),
     "set max iterations/generations")
    ("goal,g",
     po::value<parameter>(&po_goal)->default_value(0),
     "set goal, default will run until iterations is exhausted");
  try {
    po::store(po::command_line_parser(argc, argv).
	      options(desc).positional(positionals).run(), variables_map);
    if (variables_map.count("help")) {
      cout << "Search algorithms implemented in C++ by Andrew Schwartzmeyer\n\n"
	   << "Code located at https://github.com/andschwa/uidaho-cs472-project1\n\n"
	   << "Algorithms: Genetic, HillClimbing, and SimulatedAnnealing\n\n"
	   << "Problems: Ackley, Griewangk, Rastrigin, Rosenbrock, Schwefel, and Spherical\n\n"
	   << "Mutators: Creep, Gaussian, Jumping"
	   << "Recombinators: Arithmetic, Two-Point, Uniform"
	   << "Logs saved to logs/<Problem>.dat\n"
	   << "GNUPlot settings in logs/<Problem>.p\n\n"
	   << desc << endl;
      return 0;
    }
    po::notify(variables_map);
    // add all problems if none specified
    if (po_problems.size() == 0) {
      po_problems.emplace_back("Ackley");
      po_problems.emplace_back("Griewangk");
      po_problems.emplace_back("Rastrigin");
      po_problems.emplace_back("Rosenbrock");
      po_problems.emplace_back("Schwefel");
      po_problems.emplace_back("Spherical");
    }
  }
  catch(exception& e) {
    cout << e.what() << '\n';
    return 1;
  }

  // setup mutator
  unique_ptr<const Mutator> working_mutator;
  if (po_mutator.compare("creep") == 0 || po_mutator.compare("Creep") == 0)
    working_mutator = unique_ptr<const Mutator>(new mutator::Creep());
  else if (po_mutator.compare("gaussian") == 0 || po_mutator.compare("Gaussian") == 0)
    working_mutator = unique_ptr<const Mutator>(new mutator::Gaussian());
  else if (po_mutator.compare("jumping") == 0 || po_mutator.compare("Jumping") == 0)
    working_mutator = unique_ptr<const Mutator>(new mutator::Jumping());

  // setup recombinator
  shared_ptr<const Recombinator> working_recombinator;
  if (po_recombinator.compare("arithmetic") == 0 || po_recombinator.compare("Arithmetic") == 0)
    working_recombinator = shared_ptr<const Recombinator>(new recombinator::Arithmetic());
  else if (po_recombinator.compare("two-point") == 0 || po_recombinator.compare("Two-Point") == 0)
    working_recombinator = shared_ptr<const Recombinator>(new recombinator::TwoPoint());
  else if (po_recombinator.compare("uniform") == 0 || po_recombinator.compare("Uniform") == 0)
    working_recombinator = shared_ptr<const Recombinator>(new recombinator::Uniform());

  // setup each problem and run the GA on it
  unique_ptr<Problem> working_problem;
  for (const string name : po_problems) {
    // Ugly replace of switch(name), better than find_if
    if (name.compare("Ackley") == 0 || name.compare("ackley") == 0)
      working_problem = unique_ptr<Problem>(new Ackley(po_iterations, po_goal));
    else if (name.compare("Griewangk") == 0 || name.compare("griewangk") == 0)
      working_problem = unique_ptr<Problem>(new Griewangk(po_iterations, po_goal));
    else if (name.compare("Rastrigin") == 0 || name.compare("rastrigin") == 0)
      working_problem = unique_ptr<Problem>(new Rastrigin(po_iterations, po_goal));
    else if (name.compare("Rosenbrock") == 0 || name.compare("rosenbrock") == 0)
      working_problem = unique_ptr<Problem>(new Rosenbrock(po_iterations, po_goal));
    else if (name.compare("Schwefel") == 0 || name.compare("schwefel") == 0)
      working_problem = unique_ptr<Problem>(new Schwefel(po_iterations, po_goal));
    else if (name.compare("Spherical") == 0 || name.compare("spherical") == 0)
      working_problem = unique_ptr<Problem>(new Spherical(po_iterations, po_goal));
    // Run GA on problem
    if (working_problem != nullptr) {
      Genetic algorithm(*working_problem, *working_mutator, working_recombinator);
      const Individual solution = algorithm.solve();
      cout << working_problem->represent() << solution.represent()
	   << "Raw fitness: " << solution.fitness << '\n' << endl;
    }
  }
  return 0;
}
<|endoftext|>


<commit_before>#include <ShObjIdl.h>
#include <atlbase.h>
#include <wchar.h>

int wmain(int argc, wchar_t* argv[])
{
    HRESULT hr = S_OK;

    if (argc < 2)
    {
        hr = E_INVALIDARG;
        wprintf(L"Supply an app ID (AppUserModelId) for the application to launch.");
        return hr;
    }

    const wchar_t* appId = argv[1];

    hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
    if (FAILED(hr))
    {
        wprintf(L"Error initializing COM");
        return hr;
    }

    CComPtr<IApplicationActivationManager> aam = nullptr;
    hr = CoCreateInstance(CLSID_ApplicationActivationManager, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&aam));
    if (FAILED(hr))
    {
        wprintf(L"Error creating ApplicationActivationManager");
        CoUninitialize();
        return hr;
    }

    hr = CoAllowSetForegroundWindow(aam, nullptr);
    if (FAILED(hr))
    {
        wprintf(L"Error calling CoAllowSetForegroundWindow");
        CoUninitialize();
        return hr;
    }

    unsigned long pid = 0;
    hr = aam->ActivateApplication(appId, nullptr, AO_NONE, &pid);
    if (FAILED(hr))
    {
        wprintf(L"Error calling ActivateApplication");
        CoUninitialize();
        return hr;
    }

    CoUninitialize();
    return hr;
}
<commit_msg>Switch to nesting for less repetitive error handling.<commit_after>#include <ShObjIdl.h>
#include <wchar.h>

HRESULT CreateAAM(IApplicationActivationManager*& aam)
{
    return CoCreateInstance(CLSID_ApplicationActivationManager, nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&aam));
}

HRESULT ActivateApp(IApplicationActivationManager* aam, const wchar_t* appId)
{
    unsigned long unused = 0;
    return aam->ActivateApplication(appId, nullptr, AO_NONE, &unused);
}

int wmain(int argc, wchar_t* argv[])
{
    HRESULT hr = S_OK;

    if (argc < 2)
    {
        hr = E_INVALIDARG;
        wprintf(L"Supply an app ID (AppUserModelId) for the application to launch.");
    }
    else
    {
        hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
        if (FAILED(hr))
        {
            wprintf(L"Error initializing COM");
        }
        else
        {
            IApplicationActivationManager* aam = nullptr;
            hr = CreateAAM(aam);
            if (FAILED(hr))
            {
                wprintf(L"Error creating ApplicationActivationManager");
            }
            else
            {
                hr = CoAllowSetForegroundWindow(aam, nullptr);
                if (FAILED(hr))
                {
                    wprintf(L"Error calling CoAllowSetForegroundWindow");
                }
                else
                {
                    hr = ActivateApp(aam, argv[1]);
                    if (FAILED(hr))
                    {
                        wprintf(L"Error calling ActivateApplication");
                    }
                }

                aam->Release();
            }

            CoUninitialize();
        }
    }

    return hr;
}
<|endoftext|>


<commit_before>#include <errno.h>
#include <iostream>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <vector>
#include <pwd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <boost/foreach.hpp>
#include <boost/tokenizer.hpp>

using namespace std;
using namespace boost;

string shell_prompt(); //prototype for prompt function
void cmd_interpreter(vector<string>); //prototype for command interpreter

int main (int argc, char** argv)
{
	vector<string> inVector;
	string input;

	while(true)
	{
		input = shell_prompt();
		//while (inVector.back() != "")
		if (input == "exit")
		{
			cout << "Exiting." << endl;
			exit(0);
		}
		else
		{
			char_separator<char> sep(";|&");
			string t;
			tokenizer< char_separator<char> > tokens(input, sep);
			BOOST_FOREACH(t, tokens);
			{
				inVector.push_back(t);
//				cout << t << endl;
			}
		}
		cmd_interpreter(inVector);
	}

	return 0;
}

void cmd_interpreter(vector<string> input)
{
	unsigned size = input.size();

//	if (!input.empty())
	{
	for (unsigned i = 0; i < size  ; i++)
		cout << "test " << input.at(i) << endl;
	}
	return;

	/*
	int pid = fork();
	if (pid == 0)
	{
		int error = execvp(argv[0], argv);
		if (error == -1)
		{
			perror("execvp"); //throw an error
			exit(1);
		}
		else
		{
			if (argv[0] != "exit")
			{
				//execute
			}
			exit(0);
		}
	}
	else
	{
		wait(NULL);
	}
	*/
}

string shell_prompt()
{
	string in;
	//TODO - error checking for getlogin and gethostname
	//implement later
	/*
	char name[256];
	int maxlen = 64;
	if (!gethostname(name, maxlen))
	{
		string strname(name);
		cout << getlogin() << "@" << name  << "$ "; //custom prompt with hostname and login name
		cin >> in;
	}
	else
	{
		perror("gethostname"); //throw error if not found
	}
	*/
	cout << "rshell$ ";
	getline(cin, in);
	cin.clear();
	return in;
}
<commit_msg>execvp parsing in progress<commit_after>#include <errno.h>
#include <iostream>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <vector>
#include <pwd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <boost/foreach.hpp>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;

string shell_prompt(); //prototype for prompt function
void cmd_interpreter(vector<string>); //prototype for command interpreter

int main (int argc, char** argv)
{
	vector<string> inVector;
	string input;

	while(true)
	{
		input = shell_prompt();
		//while (inVector.back() != "")
		if (input == "exit")
		{
			cout << "Exiting rshell." << endl;
			exit(0);
		}
		else
		{
			char_separator<char> sep(";|&");
			string t;
			tokenizer< char_separator<char> > tokens(input, sep);
			BOOST_FOREACH(t, tokens);
			{
				inVector.push_back(t);
//				cout << t << endl;
			}
		}
		cmd_interpreter(inVector);
	}

	return 0;
}

void cmd_interpreter(vector<string> input)
{
	unsigned size = input.size();
	string cmd = input.back();
	string file;
	string param;
	vector<string> strs;

//	cout << "last " << input.back() << endl;
//	for (unsigned i = 0; i < size ; i++)
//		cout << "test " << input.at(i) << endl;

	//parse command to seperate command and parameters

	split(strs, cmd, is_any_of(" "));
	file = strs.front();
	for (unsigned i = 1; i < strs.size(); i++)
	{
		param.append(strs.at(i));
	}
	param.append('\0'); //null termination
//	const char* filec = file.c_str();
//	const char* paramc = param.c_str();

	char* filec[size];
//	char* paramc[];
	strcpy(filec, file.c_str());

	//fork execution to it's own process
	int pid = fork();
	if(pid == 0)
	{
		int error = execvp(filec[0], filec);
		if (error == -1)
		{
			perror("execvp"); // throw an error
			exit(1);
		}
		else
		{
			execvp(filec[0], filec);
		}
	}
	else
	{
		//parent wait
		waitpid(-1, NULL, 0);
	}

	return;

	/*
	int pid = fork();
	if (pid == 0)
	{
		int error = execvp(argv[0], argv);
		if (error == -1)
		{
			perror("execvp"); //throw an error
			exit(1);
		}
		else
		{
			if (argv[0] != "exit")
			{
				//execute
			}
			exit(0);
		}
	}
	else
	{
		wait(NULL);
	}
	*/
}

string shell_prompt()
{
	string in;
	//TODO - error checking for getlogin and gethostname
	//implement later
	/*
	char name[256];
	int maxlen = 64;
	if (!gethostname(name, maxlen))
	{
		string strname(name);
		cout << getlogin() << "@" << name  << "$ "; //custom prompt with hostname and login name
		cin >> in;
	}
	else
	{
		perror("gethostname"); //throw error if not found
	}
	*/
	cout << "rshell$ ";
	getline(cin, in);
	cin.clear();
	return in;
}
<|endoftext|>


<commit_before>#include <eosiolib/types.hpp>
#include <eosiolib/currency.hpp>
#include <boost/container/flat_map.hpp>
#include <cmath>
#include <exchange/market_state.hpp>

namespace eosio {

   /**
    *  This contract enables users to create an exchange between any pair of
    *  standard currency types. A new exchange is created by funding it with
    *  an equal value of both sides of the order book and giving the issuer
    *  the initial shares in that orderbook.
    *
    *  To prevent exessive rounding errors, the initial deposit should include
    *  a sizeable quantity of both the base and quote currencies and the exchange
    *  shares should have a quantity 100x the quantity of the largest initial
    *  deposit.
    *
    *  Users must deposit funds into the exchange before they can trade on the
    *  exchange.
    *
    *  Each time an exchange is created a new currency for that exchanges market
    *  maker is also created. This currencies supply and symbol must be unique and
    *  it uses the currency contract's tables to manage it.
    */
   class exchange {
      private:
         account_name      _this_contract;
         currency          _excurrencies;
         exchange_accounts _accounts;

      public:
         exchange( account_name self )
         :_this_contract(self),
          _excurrencies(self),
          _accounts(self)
         {}

         void createx( account_name    creator,
                       asset           initial_supply,
                       uint32_t        fee,
                       extended_asset  base_deposit,
                       extended_asset  quote_deposit
                     );

         void deposit( account_name from, extended_asset quantity );
         void withdraw( account_name  from, extended_asset quantity );
         void lend( account_name lender, symbol_type market, extended_asset quantity );

         void unlend(
            account_name     lender,
            symbol_type      market,
            double           interest_shares,
            extended_symbol  interest_symbol
         );

         struct covermargin {
            account_name     borrower;
            symbol_type      market;
            extended_asset   cover_amount;
         };

         struct upmargin {
            account_name     borrower;
            symbol_type      market;
            extended_asset   delta_borrow;
            extended_asset   delta_collateral;
         };

         struct trade {
            account_name    seller;
            symbol_type     market;
            extended_asset  sell;
            extended_asset  min_receive;
            uint32_t        expire = 0;
            uint8_t         fill_or_kill = true;
         };

         void on( const trade& t    );
         void on( const upmargin& b );
         void on( const covermargin& b );
         void on( const currency::transfer& t, account_name code );

         void apply( account_name contract, account_name act );
   };
} // namespace eosio
<commit_msg>contracts/exchange/exchange.hpp: fix typo<commit_after>#include <eosiolib/types.hpp>
#include <eosiolib/currency.hpp>
#include <boost/container/flat_map.hpp>
#include <cmath>
#include <exchange/market_state.hpp>

namespace eosio {

   /**
    *  This contract enables users to create an exchange between any pair of
    *  standard currency types. A new exchange is created by funding it with
    *  an equal value of both sides of the order book and giving the issuer
    *  the initial shares in that orderbook.
    *
    *  To prevent excessive rounding errors, the initial deposit should include
    *  a sizeable quantity of both the base and quote currencies and the exchange
    *  shares should have a quantity 100x the quantity of the largest initial
    *  deposit.
    *
    *  Users must deposit funds into the exchange before they can trade on the
    *  exchange.
    *
    *  Each time an exchange is created a new currency for that exchanges market
    *  maker is also created. This currencies supply and symbol must be unique and
    *  it uses the currency contract's tables to manage it.
    */
   class exchange {
      private:
         account_name      _this_contract;
         currency          _excurrencies;
         exchange_accounts _accounts;

      public:
         exchange( account_name self )
         :_this_contract(self),
          _excurrencies(self),
          _accounts(self)
         {}

         void createx( account_name    creator,
                       asset           initial_supply,
                       uint32_t        fee,
                       extended_asset  base_deposit,
                       extended_asset  quote_deposit
                     );

         void deposit( account_name from, extended_asset quantity );
         void withdraw( account_name  from, extended_asset quantity );
         void lend( account_name lender, symbol_type market, extended_asset quantity );

         void unlend(
            account_name     lender,
            symbol_type      market,
            double           interest_shares,
            extended_symbol  interest_symbol
         );

         struct covermargin {
            account_name     borrower;
            symbol_type      market;
            extended_asset   cover_amount;
         };

         struct upmargin {
            account_name     borrower;
            symbol_type      market;
            extended_asset   delta_borrow;
            extended_asset   delta_collateral;
         };

         struct trade {
            account_name    seller;
            symbol_type     market;
            extended_asset  sell;
            extended_asset  min_receive;
            uint32_t        expire = 0;
            uint8_t         fill_or_kill = true;
         };

         void on( const trade& t    );
         void on( const upmargin& b );
         void on( const covermargin& b );
         void on( const currency::transfer& t, account_name code );

         void apply( account_name contract, account_name act );
   };
} // namespace eosio
<|endoftext|>


<commit_before>#include "./headers/Page.h"

/*!
    \fn Page::Page(GLint type, GLfloat x, GLfloat y, GLfloat z, char text[])
    \brief Constructor
    Sets x, y, z coordinate for the Page.
    text -> text to be rendered in that Page.
    type -> type of Page.
*/
Page::Page(GLint type, GLfloat x, GLfloat y, GLfloat z, char text[]){
    init(type, x, y, z);
    this->text=text;
}

/*!
    \fn Page::Page(GLint type, GLfloat x, GLfloat y, GLfloat z, void (*pageContent)(GLfloat, GLfloat, GLfloat, GLfloat, GLfloat))
    \brief Constructor
    Sets x, y, z coordinate for the Page.
    type -> type of Page.
    pageContent -> function pointer which renders the drawing from here to the Page.
*/
Page::Page(GLint type, GLfloat x, GLfloat y, GLfloat z, void (*pageContent)(GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)){
    init(type, x, y, z);
    if(type == PAGE_TYPE_DRAWING)
    {
        this->pageContent = pageContent;
    }
}

/*!
    \fn Page::init(GLint type, GLfloat x, GLfloat y, GLfloat z)
    \brief Initialisation of data members
    Constructor which initialises all the data members required for Page object
*/
void Page::init(GLint type, GLfloat x, GLfloat y, GLfloat z){
    this->x = x;
    this->y = y;
    this->z = z;
    this->type = type;
    this->width = PAGE_WIDTH;
    this->height = PAGE_HEIGHT;
    this->marginWidth = MARGIN_WIDTH;
    this->marginHeight = MARGIN_HEIGHT;
    this->lineHeight = LINE_HEIGHT;
    this->pageContent = NULL;
    this->text = NULL;
}

/*!
    \fn Page::renderPage()
    \brief Renders the specified Page
    Renders the Page onto the screen after setting the border, margin.
    text pages -> sets lines for the page and render the specified text.
    drawing pages -> calls the user defined function to draw inside the Page.
*/
void Page::renderPage(){
    glColor3f(0.0,0.0,0.0);
    setBorder();
    setMargin();
    if(type == PAGE_TYPE_TEXT && text != NULL){
        setPageLines();
        renderText();
    }
    else if(type == PAGE_TYPE_DRAWING && pageContent != NULL)
        pageContent(x + marginWidth, y, z, x + width, y + height - marginHeight);
}

/*!
    \fn Page::renderText()
    \brief Renders the specified text on the Page.
    Renders the text onto the page after calculating the offset value required
    for placing the character.
    On a newline entry goto the next line and so on.
*/
void Page::renderText(){
    char ch;
    int i=0, lines=0, characterHeight = 130, characterWidth, len=strlen(text);
    int bufferWidth = 5, bufferHeight = 5;
    GLfloat ratio = LINE_HEIGHT/130.0, sum = bufferWidth;
    for(i=0;i<len;i++){
        glPushMatrix();
            ch = text[i];
            characterWidth = glutStrokeWidth(GLUT_STROKE_ROMAN, ch);
            characterHeight = characterHeight * ratio;
            characterWidth = characterWidth * ratio;
            /*! Goto the next line for placing the character */
            if((sum + characterWidth > PAGE_WIDTH - MARGIN_WIDTH) || ch == '\n'){
                lines++;
                sum = characterWidth;
                glTranslatef(BOOK_BORDER_SIZE + MARGIN_WIDTH,
                    BOOK_BORDER_SIZE + PAGE_HEIGHT - MARGIN_HEIGHT - (lines + 1) * LINE_HEIGHT + bufferWidth,
                    z);
            }
            /*! Place the character in the current line */
            else{
                glTranslatef(BOOK_BORDER_SIZE + MARGIN_WIDTH + sum,
                    BOOK_BORDER_SIZE + PAGE_HEIGHT - MARGIN_HEIGHT - (lines + 1) * LINE_HEIGHT + bufferWidth,
                    z);
                    sum += characterWidth;
            }
            glScalef(ratio, ratio, 1);
            glutStrokeCharacter(GLUT_STROKE_ROMAN, ch); /*!< Place the character */
            glFlush();
        glPopMatrix();
    }

}

/*!
    \fn Page::setBorder()
    \brief Set Page border on the screen.
    Set page border which is rendered onto the screen
    from the config/constants file.
*/
void Page::setBorder(){
    GLfloat xLimit = x + width;
    GLfloat yLimit = y + height;
    GLfloat zLimit = z - PAGE_THICKNESS;
    glColor3f(0,0,0);
    cubeConstruction(x, y, z, xLimit, yLimit, zLimit);
    glColor3f(1,1,1);
    glBegin(GL_POLYGON);
        glVertex3f(x, y, z-PAGE_THICKNESS);
        glVertex3f(x + width, y, z-PAGE_THICKNESS);
        glVertex3f(x + width, y + height, z-PAGE_THICKNESS);
        glVertex3f(x, y + height, z-PAGE_THICKNESS);
    glEnd();
}

/*!
    \fn Page::setMargin()
    \brief Set Page Margin
    Set margin for the page which is to be rendered onto the screen
    from the config/constants file.
*/
void Page::setMargin(){
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_LINE_LOOP);
        glVertex3f(x + marginWidth, y, z);
        glVertex3f(x + marginWidth, y + height, z);
    glEnd();
    glBegin(GL_LINES);
        glVertex3f(x, y + height - marginHeight, z);
        glVertex3f(x + width, x + height - marginHeight, z);
    glEnd();
}

/*!
    \fn Page::setPageLines()
    \brief Set Page lines for text Page.
    Render pagelines for the Page from the margin where the line height is given
    by LINE_HEIGHT.
*/
void Page::setPageLines(){
    int index=0;
    float pageBodyStartx = x + marginWidth;
    float pageBodyStarty = y + height - marginHeight;
    float pageBodyEndx = x + width;
    glColor3f(1.0,0.0,0.0);
    for(index=1;index<MAX_LINES && index<((pageBodyStarty-y)/(lineHeight));index++)
    {
        lines[index] = (pageBodyStarty - (LINE_HEIGHT * index));
        glBegin(GL_LINES);
            glVertex3f(pageBodyStartx, lines[index],z);
            glVertex3f(x + width, lines[index],z);
        glEnd();
    }
    glColor3f(0.0,0.0,0.0);
    noOfLines=index-1;
}

/*!
    \fn squareConstruction(GLint a,GLint b,GLint c,GLint d,GLfloat vertices[][3])
    \brief construct a square
    Construction of a individual faces based on the input of each of the vertices to form a cube
*/
void squareConstruction(GLint a,GLint b,GLint c,GLint d,GLfloat vertices[][3]){
    glBegin(GL_LINE_LOOP);
        glVertex3fv(vertices[a]);
        glNormal3fv(vertices[a]);
        glVertex3fv(vertices[b]);
        glNormal3fv(vertices[b]);
        glVertex3fv(vertices[c]);
        glNormal3fv(vertices[c]);
        glVertex3fv(vertices[d]);
        glNormal3fv(vertices[d]);
    glEnd();
}

/*!
    \fn cubeConstruction(GLfloat x, GLfloat y, GLfloat z, GLfloat xLimit, GLfloat yLimit, GLfloat zLimit)
    \brief Construct individual faces for the cube.
    Construction of a cube called from the square construction
*/
void cubeConstruction(GLfloat x, GLfloat y, GLfloat z, GLfloat xLimit, GLfloat yLimit, GLfloat zLimit){
    GLfloat vertices[][3]={
        {x, y, z}, {xLimit, y, z}, {xLimit, yLimit, z}, {x, yLimit, z},
        {x, y, zLimit}, {xLimit, y, zLimit}, {xLimit, yLimit, zLimit}, {x, yLimit, zLimit}
    };
    glPointSize(5.0);
    squareConstruction(0,3,2,1,vertices);
    squareConstruction(2,3,7,6,vertices);
    squareConstruction(0,4,7,3,vertices);
    squareConstruction(1,2,6,5,vertices);
    squareConstruction(4,5,6,7,vertices);
    squareConstruction(0,1,5,4,vertices);
}<commit_msg>Bugfix, Pointsize set to default value to fix text rendering problems on few systems<commit_after>#include "./headers/Page.h"

/*!
    \fn Page::Page(GLint type, GLfloat x, GLfloat y, GLfloat z, char text[])
    \brief Constructor
    Sets x, y, z coordinate for the Page.
    text -> text to be rendered in that Page.
    type -> type of Page.
*/
Page::Page(GLint type, GLfloat x, GLfloat y, GLfloat z, char text[]){
    init(type, x, y, z);
    this->text=text;
}

/*!
    \fn Page::Page(GLint type, GLfloat x, GLfloat y, GLfloat z, void (*pageContent)(GLfloat, GLfloat, GLfloat, GLfloat, GLfloat))
    \brief Constructor
    Sets x, y, z coordinate for the Page.
    type -> type of Page.
    pageContent -> function pointer which renders the drawing from here to the Page.
*/
Page::Page(GLint type, GLfloat x, GLfloat y, GLfloat z, void (*pageContent)(GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)){
    init(type, x, y, z);
    if(type == PAGE_TYPE_DRAWING)
    {
        this->pageContent = pageContent;
    }
}

/*!
    \fn Page::init(GLint type, GLfloat x, GLfloat y, GLfloat z)
    \brief Initialisation of data members
    Constructor which initialises all the data members required for Page object
*/
void Page::init(GLint type, GLfloat x, GLfloat y, GLfloat z){
    this->x = x;
    this->y = y;
    this->z = z;
    this->type = type;
    this->width = PAGE_WIDTH;
    this->height = PAGE_HEIGHT;
    this->marginWidth = MARGIN_WIDTH;
    this->marginHeight = MARGIN_HEIGHT;
    this->lineHeight = LINE_HEIGHT;
    this->pageContent = NULL;
    this->text = NULL;
}

/*!
    \fn Page::renderPage()
    \brief Renders the specified Page
    Renders the Page onto the screen after setting the border, margin.
    text pages -> sets lines for the page and render the specified text.
    drawing pages -> calls the user defined function to draw inside the Page.
*/
void Page::renderPage(){
    glColor3f(0.0,0.0,0.0);
    setBorder();
    setMargin();
    if(type == PAGE_TYPE_TEXT && text != NULL){
        setPageLines();
        renderText();
    }
    else if(type == PAGE_TYPE_DRAWING && pageContent != NULL)
        pageContent(x + marginWidth, y, z, x + width, y + height - marginHeight);
}

/*!
    \fn Page::renderText()
    \brief Renders the specified text on the Page.
    Renders the text onto the page after calculating the offset value required
    for placing the character.
    On a newline entry goto the next line and so on.
*/
void Page::renderText(){
    char ch;
    int i=0, lines=0, characterHeight = 130, characterWidth, len=strlen(text);
    int bufferWidth = 5, bufferHeight = 5;
    GLfloat ratio = LINE_HEIGHT/130.0, sum = bufferWidth;
    for(i=0;i<len;i++){
        glPushMatrix();
            ch = text[i];
            characterWidth = glutStrokeWidth(GLUT_STROKE_ROMAN, ch);
            characterHeight = characterHeight * ratio;
            characterWidth = characterWidth * ratio;
            /*! Goto the next line for placing the character */
            if((sum + characterWidth > PAGE_WIDTH - MARGIN_WIDTH) || ch == '\n'){
                lines++;
                sum = characterWidth;
                glTranslatef(BOOK_BORDER_SIZE + MARGIN_WIDTH,
                    BOOK_BORDER_SIZE + PAGE_HEIGHT - MARGIN_HEIGHT - (lines + 1) * LINE_HEIGHT + bufferWidth,
                    z);
            }
            /*! Place the character in the current line */
            else{
                glTranslatef(BOOK_BORDER_SIZE + MARGIN_WIDTH + sum,
                    BOOK_BORDER_SIZE + PAGE_HEIGHT - MARGIN_HEIGHT - (lines + 1) * LINE_HEIGHT + bufferWidth,
                    z);
                    sum += characterWidth;
            }
            glScalef(ratio, ratio, 1);
            glutStrokeCharacter(GLUT_STROKE_ROMAN, ch); /*!< Place the character */
            glFlush();
        glPopMatrix();
    }

}

/*!
    \fn Page::setBorder()
    \brief Set Page border on the screen.
    Set page border which is rendered onto the screen
    from the config/constants file.
*/
void Page::setBorder(){
    GLfloat xLimit = x + width;
    GLfloat yLimit = y + height;
    GLfloat zLimit = z - PAGE_THICKNESS;
    glColor3f(0,0,0);
    cubeConstruction(x, y, z, xLimit, yLimit, zLimit);
    glColor3f(1,1,1);
    glBegin(GL_POLYGON);
        glVertex3f(x, y, z-PAGE_THICKNESS);
        glVertex3f(x + width, y, z-PAGE_THICKNESS);
        glVertex3f(x + width, y + height, z-PAGE_THICKNESS);
        glVertex3f(x, y + height, z-PAGE_THICKNESS);
    glEnd();
}

/*!
    \fn Page::setMargin()
    \brief Set Page Margin
    Set margin for the page which is to be rendered onto the screen
    from the config/constants file.
*/
void Page::setMargin(){
    glColor3f(0.0,0.0,0.0);
    glBegin(GL_LINE_LOOP);
        glVertex3f(x + marginWidth, y, z);
        glVertex3f(x + marginWidth, y + height, z);
    glEnd();
    glBegin(GL_LINES);
        glVertex3f(x, y + height - marginHeight, z);
        glVertex3f(x + width, x + height - marginHeight, z);
    glEnd();
}

/*!
    \fn Page::setPageLines()
    \brief Set Page lines for text Page.
    Render pagelines for the Page from the margin where the line height is given
    by LINE_HEIGHT.
*/
void Page::setPageLines(){
    int index=0;
    float pageBodyStartx = x + marginWidth;
    float pageBodyStarty = y + height - marginHeight;
    float pageBodyEndx = x + width;
    glColor3f(1.0,0.0,0.0);
    for(index=1;index<MAX_LINES && index<((pageBodyStarty-y)/(lineHeight));index++)
    {
        lines[index] = (pageBodyStarty - (LINE_HEIGHT * index));
        glBegin(GL_LINES);
            glVertex3f(pageBodyStartx, lines[index],z);
            glVertex3f(x + width, lines[index],z);
        glEnd();
    }
    glColor3f(0.0,0.0,0.0);
    noOfLines=index-1;
}

/*!
    \fn squareConstruction(GLint a,GLint b,GLint c,GLint d,GLfloat vertices[][3])
    \brief construct a square
    Construction of a individual faces based on the input of each of the vertices to form a cube
*/
void squareConstruction(GLint a,GLint b,GLint c,GLint d,GLfloat vertices[][3]){
    glBegin(GL_LINE_LOOP);
        glVertex3fv(vertices[a]);
        glNormal3fv(vertices[a]);
        glVertex3fv(vertices[b]);
        glNormal3fv(vertices[b]);
        glVertex3fv(vertices[c]);
        glNormal3fv(vertices[c]);
        glVertex3fv(vertices[d]);
        glNormal3fv(vertices[d]);
    glEnd();
}

/*!
    \fn cubeConstruction(GLfloat x, GLfloat y, GLfloat z, GLfloat xLimit, GLfloat yLimit, GLfloat zLimit)
    \brief Construct individual faces for the cube.
    Construction of a cube called from the square construction
*/
void cubeConstruction(GLfloat x, GLfloat y, GLfloat z, GLfloat xLimit, GLfloat yLimit, GLfloat zLimit){
    GLfloat vertices[][3]={
        {x, y, z}, {xLimit, y, z}, {xLimit, yLimit, z}, {x, yLimit, z},
        {x, y, zLimit}, {xLimit, y, zLimit}, {xLimit, yLimit, zLimit}, {x, yLimit, zLimit}
    };
    squareConstruction(0,3,2,1,vertices);
    squareConstruction(2,3,7,6,vertices);
    squareConstruction(0,4,7,3,vertices);
    squareConstruction(1,2,6,5,vertices);
    squareConstruction(4,5,6,7,vertices);
    squareConstruction(0,1,5,4,vertices);
}<|endoftext|>


<commit_before>#include <sched/pthread-coro.hh>

#if defined LIBPORT_SCHED_CORO_OSTHREAD

#  include <cerrno>

#  include <libport/config.h>
#  include <libport/assert.hh>
#  include <libport/compiler.hh>
#  include <libport/semaphore.hh>
#  include <libport/thread.hh>

#  include <sched/configuration.hh>
#  include <sched/coroutine.hh>

/* Os-thread implementation of coroutines, using semaphores to ensure
   that only one coroutine is running at the same time.  */

Coro::Coro()
  : started_(false)
  , die_(false)
{}

Coro*
coroutine_new(size_t)
{
  return new Coro;
}

void
coroutine_free(Coro* c)
{
  // If the thread has not been created, do nothing, otherwise free it.
  if (c->started_)
  {
    c->die_ = true;
    c->sem_++;
    if (pthread_join(c->thread_, 0))
      errabort("pthread_join");
  }
}

void
coroutine_start(Coro* self, Coro* other,
                void (*callback)(void*), void* context)
{
#if defined WIN32
  unsigned long id;
  void* r =
    CreateThread(NULL, 0,
                 reinterpret_cast<void* (*)(void*)>(callback), context,
                 0, &id);
#else
  // Adjust to the requested stack size.
  static pthread_attr_t attr;
  static bool first = true;
  if (first)
  {
    first = false;
    if (pthread_attr_init(&attr))
      errabort("pthread_attr_init");

    if (pthread_attr_setstacksize(&attr,
                                  sched::configuration.default_stack_size))
      errabort("pthread_attr_setstacksize");
  }

  if (pthread_create(&other->thread_, &attr,
		     reinterpret_cast<void* (*)(void*)>(callback), context))
    errabort("pthread_create");
#endif
  other->started_ = true;
  self->sem_--;
}

void*
coroutine_stack_addr(Coro*)
{
  void* res = 0;
  pthread_attr_t attr;
  if (pthread_attr_init(&attr))
    errabort("pthread_attr_init");
  if (pthread_attr_getstackaddr(&attr, &res))
    errabort("pthread_attr_getstackaddr");
  return res;
}

void
coroutine_switch_to(Coro* self, Coro* next)
{
  next->sem_++;
  self->sem_--;
  if (self->die_)
  {
    delete self;
    pthread_exit(0);
  }
}

void*
coroutine_current_stack_pointer(Coro*)
{
  uint8_t a;
  uint8_t *b = &a; // to avoid compiler warning about unused variables
  return b;
}

size_t
coroutine_stack_size(Coro*)
{
  size_t res = 0;
  pthread_attr_t attr;
  if (pthread_attr_init(&attr))
    errabort("pthread_attr_init");
  if (pthread_attr_getstacksize(&attr, &res))
    errabort("pthread_attr_getstacksizeaddr");
  return res;
}

void
coroutine_initialize_main(Coro*)
{
}

#endif //! LIBPORT_SCHED_CORO_OSTHREAD
<commit_msg>Fix pthread's stack_addr and stack_size implementations.<commit_after>#include <sched/pthread-coro.hh>

#if defined LIBPORT_SCHED_CORO_OSTHREAD

#  include <cerrno>

#  include <libport/config.h>
#  include <libport/assert.hh>
#  include <libport/compiler.hh>
#  include <libport/semaphore.hh>
#  include <libport/thread.hh>

#  include <sched/configuration.hh>
#  include <sched/coroutine.hh>

/* Os-thread implementation of coroutines, using semaphores to ensure
   that only one coroutine is running at the same time.  */

Coro::Coro()
  : started_(false)
  , die_(false)
{}

Coro*
coroutine_new(size_t)
{
  return new Coro;
}

void
coroutine_free(Coro* c)
{
  // If the thread has not been created, do nothing, otherwise free it.
  if (c->started_)
  {
    c->die_ = true;
    c->sem_++;
    if (pthread_join(c->thread_, 0))
      errabort("pthread_join");
  }
}

void
coroutine_start(Coro* self, Coro* other,
                void (*callback)(void*), void* context)
{
#if defined WIN32
  unsigned long id;
  void* r =
    CreateThread(NULL, 0,
                 reinterpret_cast<void* (*)(void*)>(callback), context,
                 0, &id);
#else
  // Adjust to the requested stack size.
  static pthread_attr_t attr;
  static bool first = true;
  if (first)
  {
    first = false;
    if (pthread_attr_init(&attr))
      errabort("pthread_attr_init");

    if (pthread_attr_setstacksize(&attr,
                                  sched::configuration.default_stack_size))
      errabort("pthread_attr_setstacksize");
  }

  if (pthread_create(&other->thread_, &attr,
		     reinterpret_cast<void* (*)(void*)>(callback), context))
    errabort("pthread_create");
#endif
  other->started_ = true;
  self->sem_--;
}

void*
coroutine_stack_addr(Coro*)
{
  // Undocumented, but works on OS X 10.5.
  return pthread_get_stackaddr_np(pthread_self());
}

void
coroutine_switch_to(Coro* self, Coro* next)
{
  next->sem_++;
  self->sem_--;
  if (self->die_)
  {
    delete self;
    pthread_exit(0);
  }
}

void*
coroutine_current_stack_pointer(Coro*)
{
  uint8_t a;
  uint8_t *b = &a; // to avoid compiler warning about unused variables
  return b;
}

size_t
coroutine_stack_size(Coro*)
{
  // Undocumented, but works on OS X 10.5.
  return pthread_get_stacksize_np(pthread_self());
}

void
coroutine_initialize_main(Coro*)
{
}

#endif //! LIBPORT_SCHED_CORO_OSTHREAD
<|endoftext|>


<commit_before>#pragma once

#include <SFML/Graphics.hpp>
#include <bitset>
#include <string>
#include "SceneManager.hpp"
#include "SoundManager.hpp"

// window properties
static const int screenWidth = 800;
static const int screenHeight = 600;

// define number of keyboards binding
#define INPUT_SIZE 5
typedef std::bitset<INPUT_SIZE> InputType;
extern sf::Keyboard::Key keyboardBinding[INPUT_SIZE];

extern sf::RenderWindow window;
extern SceneManager sceneManager;
extern SoundManager soundManager;

extern bool focus;
extern InputType input;
extern sf::Clock globalClock;

// use absolute paths on windows and disable audio (strange behaviour)
#ifndef OS_WINDOWS
	static const std::string path =  "./";
	static const bool enableAudio = true;
#else
	static const std::string path =  "C:/GalacticIrrweg/trunk/VSPROJ/Project1/Debug/";
	static const bool enableAudio = false;
#endif
<commit_msg>changed OS_WINDOWS to _WIN32<commit_after>#pragma once

#include <SFML/Graphics.hpp>
#include <bitset>
#include <string>
#include "SceneManager.hpp"
#include "SoundManager.hpp"

// window properties
static const int screenWidth = 800;
static const int screenHeight = 600;

// define number of keyboards binding
#define INPUT_SIZE 5
typedef std::bitset<INPUT_SIZE> InputType;
extern sf::Keyboard::Key keyboardBinding[INPUT_SIZE];

extern sf::RenderWindow window;
extern SceneManager sceneManager;
extern SoundManager soundManager;

extern bool focus;
extern InputType input;
extern sf::Clock globalClock;

// use absolute paths on windows and disable audio (strange behaviour)
#ifndef _WIN32
	static const std::string path =  "./";
	static const bool enableAudio = true;
#else
	static const std::string path =  "C:/GalacticIrrweg/trunk/VSPROJ/Project1/Debug/";
	static const bool enableAudio = false;
#endif
<|endoftext|>


<commit_before>//
#include "stdafx.h"
using namespace std;
//int ID_valid();
int main()
{
	/*
	if (!ID_valid()) {
		cout << "Invalid !";
		cin.get();
		return 1;
	}
	*/
	cmdEngine *engine = new cmdEngine;
	engine->start_cmdEngine(); //starts the command Line Engine
	delete engine;
	return 0;
}
/*
int ID_valid() {
	string pass;
	int attempts = 2;
	cout << "Hello Keshav Sharma \n";
	do {
		cout << "Enter Security Key : ";
		getline(cin, pass);
		if (pass == "keshav15157") {
			cout << "Valid Key\n";
			cin.get();
			break;
		}
		else {
			cout << "\n Invalid ! Attempts left : " << attempts-1 << endl;
			if (attempts - 1 == 0)
				return 0;
		}
	} while (attempts--);

	return 1;
}
*/
<commit_msg>Create pico_cli.cpp<commit_after>//
#include "stdafx.h"
using namespace std;
//int ID_valid();
int main()
{
	/*
	if (!ID_valid()) {
		cout << "Invalid !";
		cin.get();
		return 1;
	}
	*/
	cmdEngine *engine = new cmdEngine;
	engine->start_cmdEngine(); //starts the command Line Engine
	delete engine;
	return 0;
}
/*
int ID_valid() {
	string pass;
	int attempts = 2;
	cout << "Hello Keshav Sharma \n";
	do {
		cout << "Enter Security Key : ";
		getline(cin, pass);
		if (pass == "password") {
			cout << "Valid Key\n";
			cin.get();
			break;
		}
		else {
			cout << "\n Invalid ! Attempts left : " << attempts-1 << endl;
			if (attempts - 1 == 0)
				return 0;
		}
	} while (attempts--);

	return 1;
}
*/
<|endoftext|>


<commit_before>#include "PackAnimation.h"
#include "PackNodeFactory.h"
#include "binary_io.h"
#include "to_int.h"

#include <easyanim.h>
#include <easybuilder.h>
namespace lua = ebuilder::lua;

#include <simp/NodeAnimation.h>
#include <simp/simp_define.h>
#include <simp/simp_types.h>

#include <algorithm>

namespace esprpacker
{

PackAnimation::PackAnimation(const eanim::Symbol* sym)
{
	Init(sym);
}

PackAnimation::~PackAnimation()
{
	for_each(m_layers.begin(), m_layers.end(), cu::RemoveRefFonctor<Layer>());
}

void PackAnimation::PackToLuaString(ebuilder::CodeGenerator& gen, const ee::TexturePacker& tp, float scale) const
{
	gen.line("{");
	gen.tab();

	lua::comments(gen, "file: " + GetFilepath());

	lua::assign_with_end(gen, "type", "\"animation\"");
	lua::assign_with_end(gen, "id", ee::StringHelper::ToString(m_id));

	lua::TableAssign ta(gen, "layers", true);
	for (int i = 0, n = m_layers.size(); i < n; ++i) {
		lua::TableAssign assign(gen, "", true);
		m_layers[i]->PackToLuaString(gen);
	}

	gen.detab();
	gen.line("},");
}

int PackAnimation::SizeOfUnpackFromBin() const
{
	int sz = simp::NodeAnimation::Size();
	for (int i = 0, n = m_layers.size(); i < n; ++i) {
		sz += m_layers[i]->SizeOfUnpackFromBin();
	}
	return sz;
}

int PackAnimation::SizeOfPackToBin() const
{
	int sz = 0;
	sz += sizeof(uint32_t);			// id
	sz += sizeof(uint8_t);			// type
	// layers
	sz += sizeof(uint16_t);
	for (int i = 0, n = m_layers.size(); i < n; ++i) {
		sz += m_layers[i]->SizeOfPackToBin();
	}
	return sz;
}

void PackAnimation::PackToBin(uint8_t** ptr, const ee::TexturePacker& tp, float scale) const
{
	uint32_t id = m_id;
	pack(id, ptr);

	uint8_t type = simp::TYPE_ANIMATION;
	pack(type, ptr);

	// layers
	uint16_t n = m_layers.size();
	pack(n, ptr);
	for (int i = 0; i < n; ++i) {
		m_layers[i]->PackToBin(ptr);
	}
}

void PackAnimation::Init(const eanim::Symbol* sym)
{
	const std::vector<s2::AnimSymbol::Layer*>& layers = sym->GetLayers();
	m_layers.reserve(layers.size());
	for (int i = 0, n = layers.size(); i < n; ++i) {
		m_layers.push_back(new Layer(layers[i]));
	}
}

/************************************************************************/
/* class PackAnimation::Actor                                           */
/************************************************************************/

PackAnimation::Actor::
Actor(const s2::Sprite* spr)
	: m_trans(*spr, true)
{
	m_node = PackNodeFactory::Instance()->Create(dynamic_cast<const ee::Sprite*>(spr));
}

PackAnimation::Actor::
~Actor()
{
	m_node->RemoveReference();
}

void PackAnimation::Actor::
PackToLuaString(ebuilder::CodeGenerator& gen) const
{
	lua::TableAssign assign(gen, "", true);
	std::string sid = lua::assign("id", ee::StringHelper::ToString(m_node->GetID()));
	lua::connect(gen, 1, sid);
	m_trans.PackToLua(gen);
}

int PackAnimation::Actor::
SizeOfUnpackFromBin() const
{
	int sz = simp::NodeAnimation::ActorSize();
	sz += m_trans.SizeOfUnpackFromBin();
	return sz;
}

int PackAnimation::Actor::
SizeOfPackToBin() const
{
	int sz = 0;
	sz += sizeof(uint32_t);				// node id
	sz += m_trans.SizeOfPackToBin();	// trans
	return sz;
}

void PackAnimation::Actor::
PackToBin(uint8_t** ptr) const
{
	uint32_t id = m_node->GetID();
	pack(id, ptr);

	m_trans.PackToBin(ptr);
}

/************************************************************************/
/* class PackAnimation::Frame                                           */
/************************************************************************/

PackAnimation::Frame::
Frame(const s2::AnimSymbol::Frame* frame)
{
	m_index = frame->index;
	m_tween = frame->tween;
	m_actors.reserve(frame->sprs.size());
	for (int spr = 0, spr_n = frame->sprs.size(); spr < spr_n; ++spr) {
		m_actors.push_back(new Actor(frame->sprs[spr]));
	}
}

PackAnimation::Frame::
~Frame()
{
	for_each(m_actors.begin(), m_actors.end(), cu::RemoveRefFonctor<Actor>());
}

void PackAnimation::Frame::
PackToLuaString(ebuilder::CodeGenerator& gen) const
{
	lua::connect(gen, 2,
		lua::assign("index", m_index),
		lua::assign("tween", m_tween));

	lua::TableAssign ta(gen, "actors", true);
	for (int i = 0, n = m_actors.size(); i < n; ++i) {
		lua::TableAssign assign(gen, "", true);
		m_actors[i]->PackToLuaString(gen);
	}
}

int PackAnimation::Frame::
SizeOfUnpackFromBin() const
{
	int sz = simp::NodeAnimation::FrameSize();
	for (int i = 0, n = m_actors.size(); i < n; ++i) {
		sz += m_actors[i]->SizeOfUnpackFromBin();
	}
	return sz;
}

int PackAnimation::Frame::
SizeOfPackToBin() const
{
	int sz = 0;
	sz += sizeof(uint16_t);		// index
	sz += sizeof(uint8_t);		// tween
	// actors
	sz += sizeof(uint16_t);
	for (int i = 0, n = m_actors.size(); i < n; ++i) {
		sz += m_actors[i]->SizeOfPackToBin();
	}
	return sz;
}

void PackAnimation::Frame::
PackToBin(uint8_t** ptr) const
{
	uint16_t idx = m_index;
	pack(idx, ptr);

	uint8_t tween = bool2int(m_tween);
	pack(tween, ptr);

	uint16_t n = m_actors.size();
	pack(n, ptr);
	for (int i = 0; i < n; ++i) {
		m_actors[i]->PackToBin(ptr);
	}
}

/************************************************************************/
/* class PackAnimation::Layer                                           */
/************************************************************************/

PackAnimation::Layer::
Layer(const s2::AnimSymbol::Layer* layer)
{
	m_frames.reserve(layer->frames.size());
	for (int frame = 0, frame_n = layer->frames.size(); frame < frame_n; ++frame)
	{
		s2::AnimSymbol::Frame* src_frame = layer->frames[frame];
		Frame* dst_frame = new Frame(src_frame);
		m_frames.push_back(dst_frame);
	}
}

PackAnimation::Layer::
~Layer()
{
	for_each(m_frames.begin(), m_frames.end(), cu::RemoveRefFonctor<Frame>());
}

void PackAnimation::Layer::
PackToLuaString(ebuilder::CodeGenerator& gen) const
{
	lua::TableAssign ta(gen, "frames", true);
	for (int i = 0, n = m_frames.size(); i < n; ++i) {
		lua::TableAssign assign(gen, "", true);
		m_frames[i]->PackToLuaString(gen);
	}
}

int PackAnimation::Layer::
SizeOfUnpackFromBin() const
{
	int sz = simp::NodeAnimation::LayerSize();
	for (int i = 0, n = m_frames.size(); i < n; ++i) {
		sz += m_frames[i]->SizeOfUnpackFromBin();
	}
	return sz;
}

int PackAnimation::Layer::
SizeOfPackToBin() const
{
	int sz = 0;
	// frames
	sz += sizeof(uint16_t);
	for (int i = 0, n = m_frames.size(); i < n; ++i) {
		sz += m_frames[i]->SizeOfPackToBin();
	}
	return sz;
}

void PackAnimation::Layer::
PackToBin(uint8_t** ptr) const
{
	uint16_t n = m_frames.size();
	pack(n, ptr);
	for (int i = 0; i < n; ++i) {
		m_frames[i]->PackToBin(ptr);
	}
}

}<commit_msg>[CHANGED] pack anim lua format<commit_after>#include "PackAnimation.h"
#include "PackNodeFactory.h"
#include "binary_io.h"
#include "to_int.h"

#include <easyanim.h>
#include <easybuilder.h>
namespace lua = ebuilder::lua;

#include <simp/NodeAnimation.h>
#include <simp/simp_define.h>
#include <simp/simp_types.h>

#include <algorithm>

namespace esprpacker
{

PackAnimation::PackAnimation(const eanim::Symbol* sym)
{
	Init(sym);
}

PackAnimation::~PackAnimation()
{
	for_each(m_layers.begin(), m_layers.end(), cu::RemoveRefFonctor<Layer>());
}

void PackAnimation::PackToLuaString(ebuilder::CodeGenerator& gen, const ee::TexturePacker& tp, float scale) const
{
	gen.line("{");
	gen.tab();

	lua::comments(gen, "file: " + GetFilepath());

	lua::assign_with_end(gen, "type", "\"animation\"");
	lua::assign_with_end(gen, "id", ee::StringHelper::ToString(m_id));

	lua::TableAssign ta(gen, "layers", true);
	for (int i = 0, n = m_layers.size(); i < n; ++i) {
		m_layers[i]->PackToLuaString(gen);
	}

	gen.detab();
	gen.line("},");
}

int PackAnimation::SizeOfUnpackFromBin() const
{
	int sz = simp::NodeAnimation::Size();
	for (int i = 0, n = m_layers.size(); i < n; ++i) {
		sz += m_layers[i]->SizeOfUnpackFromBin();
	}
	return sz;
}

int PackAnimation::SizeOfPackToBin() const
{
	int sz = 0;
	sz += sizeof(uint32_t);			// id
	sz += sizeof(uint8_t);			// type
	// layers
	sz += sizeof(uint16_t);
	for (int i = 0, n = m_layers.size(); i < n; ++i) {
		sz += m_layers[i]->SizeOfPackToBin();
	}
	return sz;
}

void PackAnimation::PackToBin(uint8_t** ptr, const ee::TexturePacker& tp, float scale) const
{
	uint32_t id = m_id;
	pack(id, ptr);

	uint8_t type = simp::TYPE_ANIMATION;
	pack(type, ptr);

	// layers
	uint16_t n = m_layers.size();
	pack(n, ptr);
	for (int i = 0; i < n; ++i) {
		m_layers[i]->PackToBin(ptr);
	}
}

void PackAnimation::Init(const eanim::Symbol* sym)
{
	const std::vector<s2::AnimSymbol::Layer*>& layers = sym->GetLayers();
	m_layers.reserve(layers.size());
	for (int i = 0, n = layers.size(); i < n; ++i) {
		m_layers.push_back(new Layer(layers[i]));
	}
}

/************************************************************************/
/* class PackAnimation::Actor                                           */
/************************************************************************/

PackAnimation::Actor::
Actor(const s2::Sprite* spr)
	: m_trans(*spr, true)
{
	m_node = PackNodeFactory::Instance()->Create(dynamic_cast<const ee::Sprite*>(spr));
}

PackAnimation::Actor::
~Actor()
{
	m_node->RemoveReference();
}

void PackAnimation::Actor::
PackToLuaString(ebuilder::CodeGenerator& gen) const
{
	lua::TableAssign assign(gen, "", true);

	std::string sid = lua::assign("id", ee::StringHelper::ToString(m_node->GetID()));
	lua::connect(gen, 1, sid);
	m_trans.PackToLua(gen);
}

int PackAnimation::Actor::
SizeOfUnpackFromBin() const
{
	int sz = simp::NodeAnimation::ActorSize();
	sz += m_trans.SizeOfUnpackFromBin();
	return sz;
}

int PackAnimation::Actor::
SizeOfPackToBin() const
{
	int sz = 0;
	sz += sizeof(uint32_t);				// node id
	sz += m_trans.SizeOfPackToBin();	// trans
	return sz;
}

void PackAnimation::Actor::
PackToBin(uint8_t** ptr) const
{
	uint32_t id = m_node->GetID();
	pack(id, ptr);

	m_trans.PackToBin(ptr);
}

/************************************************************************/
/* class PackAnimation::Frame                                           */
/************************************************************************/

PackAnimation::Frame::
Frame(const s2::AnimSymbol::Frame* frame)
{
	m_index = frame->index;
	m_tween = frame->tween;
	m_actors.reserve(frame->sprs.size());
	for (int spr = 0, spr_n = frame->sprs.size(); spr < spr_n; ++spr) {
		m_actors.push_back(new Actor(frame->sprs[spr]));
	}
}

PackAnimation::Frame::
~Frame()
{
	for_each(m_actors.begin(), m_actors.end(), cu::RemoveRefFonctor<Actor>());
}

void PackAnimation::Frame::
PackToLuaString(ebuilder::CodeGenerator& gen) const
{
	lua::TableAssign assign(gen, "", true);

	lua::connect(gen, 2,
		lua::assign("index", m_index),
		lua::assign("tween", m_tween));

	lua::TableAssign ta(gen, "actors", true);
	for (int i = 0, n = m_actors.size(); i < n; ++i) {
		m_actors[i]->PackToLuaString(gen);
	}
}

int PackAnimation::Frame::
SizeOfUnpackFromBin() const
{
	int sz = simp::NodeAnimation::FrameSize();
	for (int i = 0, n = m_actors.size(); i < n; ++i) {
		sz += m_actors[i]->SizeOfUnpackFromBin();
	}
	return sz;
}

int PackAnimation::Frame::
SizeOfPackToBin() const
{
	int sz = 0;
	sz += sizeof(uint16_t);		// index
	sz += sizeof(uint8_t);		// tween
	// actors
	sz += sizeof(uint16_t);
	for (int i = 0, n = m_actors.size(); i < n; ++i) {
		sz += m_actors[i]->SizeOfPackToBin();
	}
	return sz;
}

void PackAnimation::Frame::
PackToBin(uint8_t** ptr) const
{
	uint16_t idx = m_index;
	pack(idx, ptr);

	uint8_t tween = bool2int(m_tween);
	pack(tween, ptr);

	uint16_t n = m_actors.size();
	pack(n, ptr);
	for (int i = 0; i < n; ++i) {
		m_actors[i]->PackToBin(ptr);
	}
}

/************************************************************************/
/* class PackAnimation::Layer                                           */
/************************************************************************/

PackAnimation::Layer::
Layer(const s2::AnimSymbol::Layer* layer)
{
	m_frames.reserve(layer->frames.size());
	for (int frame = 0, frame_n = layer->frames.size(); frame < frame_n; ++frame)
	{
		s2::AnimSymbol::Frame* src_frame = layer->frames[frame];
		Frame* dst_frame = new Frame(src_frame);
		m_frames.push_back(dst_frame);
	}
}

PackAnimation::Layer::
~Layer()
{
	for_each(m_frames.begin(), m_frames.end(), cu::RemoveRefFonctor<Frame>());
}

void PackAnimation::Layer::
PackToLuaString(ebuilder::CodeGenerator& gen) const
{
	lua::TableAssign ta(gen, "frames", true);
	for (int i = 0, n = m_frames.size(); i < n; ++i) {
		m_frames[i]->PackToLuaString(gen);
	}
}

int PackAnimation::Layer::
SizeOfUnpackFromBin() const
{
	int sz = simp::NodeAnimation::LayerSize();
	for (int i = 0, n = m_frames.size(); i < n; ++i) {
		sz += m_frames[i]->SizeOfUnpackFromBin();
	}
	return sz;
}

int PackAnimation::Layer::
SizeOfPackToBin() const
{
	int sz = 0;
	// frames
	sz += sizeof(uint16_t);
	for (int i = 0, n = m_frames.size(); i < n; ++i) {
		sz += m_frames[i]->SizeOfPackToBin();
	}
	return sz;
}

void PackAnimation::Layer::
PackToBin(uint8_t** ptr) const
{
	uint16_t n = m_frames.size();
	pack(n, ptr);
	for (int i = 0; i < n; ++i) {
		m_frames[i]->PackToBin(ptr);
	}
}

}<|endoftext|>


<commit_before>#include <QtCore>
#include <iostream>

#include <pHash.h>

static QString TMPPATH;                 // name of temporary dir (usually below /tmp)
static const double THRESHOLD = 0.6;    // find at least x% dupe frames to consider video duped
static int FRAMES = 5;                  // how many frames to compare
static int HAMMINGDIST = 16;            // hamming distance threshold for frame comparison

void
ffmpegMissing()
{
    std::cout << "Error: ffmpeg could not be found!" << std::endl;
    std::exit( 1 );
}

QString
timeToString( int seconds )
{
    int mins = seconds / 60 % 60;
    int secs = seconds % 60;

    if ( seconds < 0 )
    {
        mins = secs = 0;
    }

    return QString( "%1:%2" )
        .arg( mins < 10 ? "0" + QString::number( mins ) : QString::number( mins ) )
        .arg( secs < 10 ? "0" + QString::number( secs ) : QString::number( secs ) );
}

QVariantMap
videoMetaData( const QString& file )
{
    QStringList args;
    args
         << "-i" << file
         << "-show_format";

    QProcess p;
    p.start( "ffprobe", args );
    if ( !p.waitForFinished( 60000 ) )  // wait one minute at most
    {
        ffmpegMissing();    // this aborts the app
    }

    QString output = p.readAll();
    QStringList lines = output.split( "\n" );
    QVariantMap res;

    foreach ( const QString& l, lines )
    {
        const QString value = l.split("=").last();

        if ( l.startsWith( "duration" ) )
        {
            res[ "duration" ] = value.toDouble();
        }
        if ( l.startsWith( "bit_rate" ) )
        {
            res[ "bitrate" ] = value.toInt();
        }
    }

    return res;
}

// create snapshots from video file
void
createSnaps( const QString& file, const QString& tmpPath )
{
    // get meta data
    QVariantMap metadata = videoMetaData( file );
    std::cout << "   --> Duration: " << metadata[ "duration" ].toInt() << " - bitrate: " << metadata[ "bitrate" ].toInt() << std::endl;

    int start = metadata[ "duration" ].toInt() / 10;
    int step = metadata[ "duration" ].toInt() / ( FRAMES * 1.5 );

    for ( int i = 0; i < FRAMES; i++ )
    {
        QStringList args;
        args
             << "-ss" << timeToString( i * step + start )
             << "-i" << file
             << "-y"
             << "-f" << "image2"
             << "-vcodec" << "mjpeg"
             << "-vframes" << "1"
             << "-vf" << "scale=128:-1"
             << QString( "%1.jpg" ).arg( i );

        QProcess p;
        p.setWorkingDirectory( tmpPath );
        p.start( "ffmpeg", args );
        if ( !p.waitForFinished( 60000 ) )  // wait one minute at most
        {
            ffmpegMissing();    // this aborts the app
        }
    }
}

// create perceptual hash for snapshots
QHash<ulong64, int>
hashSnaps( const QString& path )
{
    QHash<ulong64, int> hashes;

    QDir dir( path );
    QFileInfoList list = dir.entryInfoList();
    for ( int i = 0; i < list.size(); ++i )
    {
        QFileInfo fileInfo = list.at( i );
        if ( !fileInfo.fileName().endsWith( ".jpg" ) )
            continue;

        ulong64 hash;
        int err = ph_dct_imagehash( fileInfo.absoluteFilePath().toLocal8Bit(), hash );
        if ( err )
            continue;

        hashes.insertMulti( hash, i );

        // delete snapshot
        QFile::remove( fileInfo.absoluteFilePath() );
    }

    return hashes;
}

// finds similar hashes by hamming distance
QList <QPair <int, QString> >
closestHashes( QHash<ulong64, QPair<int, QString> >& hashes, const ulong64& searchKey )
{
    QList <QPair <int, QString> > res;

    for ( int i = 0; i < hashes.keys().count(); i++ )
    {
        ulong64 key = hashes.keys().at( i );
        if ( ph_hamming_distance( searchKey, key ) < HAMMINGDIST )
        {
            QPair<int, QString> pair = hashes.values().at( i );
            res << pair;
        }
    }

    return res;
}

// find the files matching most of the p-hashes
QHash<QString, int>
fileMatches( const QString& file, const QHash<ulong64, int>& hash, QHash<ulong64, QPair<int, QString> >& hashes )
{
    QPair<int, QString> pair;       // snapshot #, filename
    QHash<QString, int> matches;    // filename, matches

    // go through all extracted snapshots and find dupes
    for ( int j = 0; j < hash.keys().count(); j++ )
    {
        ulong64 key = hash.keys().at( j );  // hash
        int value = hash.values().at( j );  // snapshot #

        {
            QList<QPair<int, QString> > res;    // snapshot #, filename

            // find closest snapshots by hamming distance
            res = closestHashes( hashes, key );
            for ( int x = 0; x < res.count(); x++ )
            {
                pair = res.at( x );
                if ( pair.second == file )
                {
                    // ignore matches to self
                    continue;
                }

                // add/increment match count
                if ( !matches.contains( pair.second ) )
                    matches[pair.second] = 1;
                else
                    matches[pair.second] = matches[pair.second] + 1;
            }
        }

        // store hashes for future comparisons
        pair.first = value;
        pair.second = file;
        hashes.insertMulti( key, pair );
    }

    return matches;
}

QByteArray
sha1Sum( const QString& path )
{
    QCryptographicHash hash( QCryptographicHash::Sha1 );
    QFile file( path );

    if ( file.open( QIODevice::ReadOnly ) )
    {
        hash.addData( file.readAll() );
        return hash.result();
    }

    return QByteArray();
}

bool
hasValidExtension( const QFileInfo& file )
{
    static QStringList exts;
    if ( !exts.count() )
        exts << ".3gp" << ".aaf" << ".asf" << ".avi" << ".divx" << ".flv"
             << ".m1v" << ".m2v" << ".m4v" << ".mkv" << ".mov" << ".mp4" << ".mpg" << ".mpeg"
             << ".rm" << ".ts" << ".wmv";

    foreach ( const QString& ext, exts )
    {
        if ( file.fileName().endsWith( ext ) )
        {
            return true;
        }
    }

    return false;
}

void
scanDir( QHash<ulong64, QPair<int, QString> >& hashes, const QString& path )
{
//    qDebug() << "Scanning dir:" << path;

    QDir dir( path );
    QFileInfoList list = dir.entryInfoList();
    for ( int i = 0; i < list.size(); ++i )
    {
        QFileInfo fileInfo = list.at( i );
        if ( fileInfo.isSymLink() )
            continue;
        if ( fileInfo.fileName().startsWith( "." ) )
            continue;

        if ( fileInfo.isDir() )
        {
            // scan recursively
            scanDir( hashes, fileInfo.absolutePath() + "/" + fileInfo.fileName() );
            continue;
        }
        if ( !hasValidExtension( fileInfo ) )
        {
            // only index videos
            continue;
        }

        std::cout << "Indexing \"" << qPrintable( fileInfo.absoluteFilePath() ) << "\" - size: " << fileInfo.size() << std::endl;

        // create snapshots
        createSnaps( fileInfo.absoluteFilePath(), TMPPATH );

        // analyze and hash snapshots
        QHash<ulong64, int> hash = hashSnaps( TMPPATH );

        // find known files matching the extracted hashes
        QHash<QString, int> matches;    // filename, matches
        matches = fileMatches( fileInfo.absoluteFilePath(), hash, hashes );

        for ( int y = 0; y < matches.keys().count(); y++ )
        {
            // threshold of matched snapshots to consider duped
            if ( (double)matches.values().at( y ) / (double)hash.count() >= THRESHOLD )
            {
                QFileInfo dupeFile( matches.keys().at( y ) );
                QByteArray sha1;
                if ( matches.values().at( y ) == hash.count()
                    && fileInfo.size() == dupeFile.size()
                    && ( sha1 = sha1Sum( fileInfo.absoluteFilePath() ) ) == sha1Sum( dupeFile.absoluteFilePath() ) )
                {
                    std::cout << "   --> Exact copy of \"" << qPrintable( matches.keys().at( y ) ) << "\" - sha1: " << qPrintable( sha1.toHex() ) << std::endl;
                }
                else
                {
                    std::cout << "   --> Perceptual dupe of \"" << qPrintable( matches.keys().at( y ) ) << "\" - size: " << QFileInfo( matches.keys().at( y ) ).size()
                              << " (scores " << qMin( FRAMES, matches.values().at( y ) ) << " out of " << qMin( FRAMES, hash.count() ) << ")" << std::endl;
                }
            }
        }
    }
}

int
main(int argc, char *argv[])
{
    QCoreApplication app( argc, argv );
    QCoreApplication::setApplicationName( "xray" );
    QCoreApplication::setApplicationVersion( "0.0.1" );

    QCommandLineParser cliParser;
    cliParser.setApplicationDescription( "xray indexes video files by their perceptual hash and finds duplicates.\n"
                                         "This means files are not compared byte for byte, but by their visual content.\n"
                                         "It will/should find dupes of videos, even when they are encoded in different formats and resolutions." );
    cliParser.addHelpOption();
    cliParser.addVersionOption();
    cliParser.addPositionalArgument( "path", QCoreApplication::translate( "main", "Directory to analyze" ) );

    QCommandLineOption framesOption( QStringList() << "f" << "frames",
                                     QCoreApplication::translate( "main", "Number of <frames> to analyze per video" ),
                                     "frames", "5" );
    cliParser.addOption( framesOption );

    QCommandLineOption hammingOption( QStringList() << "d" << "hamming-distance",
                                      QCoreApplication::translate( "main", "Maximum <distance> between two frames" ),
                                      "distance", "16" );
    cliParser.addOption( hammingOption );

    cliParser.process( app );

    const QStringList args = cliParser.positionalArguments();
    if ( !args.count() )
    {
        cliParser.showHelp( 1 );
    }

    FRAMES = cliParser.value( framesOption ).toInt();
    HAMMINGDIST = cliParser.value( hammingOption ).toInt();

    QHash<ulong64, QPair<int, QString> > hashes;    // perceptual hash, pair<snapshot #, filename>
    QTemporaryDir tmpDir;
    TMPPATH = tmpDir.path();
    scanDir( hashes, args.first() );

    return 0;
}
<commit_msg>* Slight code cleanup.<commit_after>#include <QtCore>
#include <iostream>

#include <pHash.h>

static QString TMPPATH;                 // name of temporary dir (usually below /tmp)
static const double THRESHOLD = 0.6;    // find at least x% dupe frames to consider video duped
static int FRAMES = 5;                  // how many frames to compare
static int HAMMINGDIST = 16;            // hamming distance threshold for frame comparison

void
ffmpegMissing()
{
    std::cout << "Error: ffmpeg could not be found!" << std::endl;
    std::exit( 1 );
}

QString
timeToString( int seconds )
{
    int mins = seconds / 60 % 60;
    int secs = seconds % 60;

    if ( seconds < 0 )
    {
        mins = secs = 0;
    }

    return QString( "%1:%2" )
        .arg( mins < 10 ? "0" + QString::number( mins ) : QString::number( mins ) )
        .arg( secs < 10 ? "0" + QString::number( secs ) : QString::number( secs ) );
}

QVariantMap
videoMetaData( const QString& file )
{
    QStringList args;
    args
         << "-i" << file
         << "-show_format";

    QProcess p;
    p.start( "ffprobe", args );
    if ( !p.waitForFinished( 60000 ) )  // wait one minute at most
    {
        ffmpegMissing();    // this aborts the app
    }

    QString output = p.readAll();
    QStringList lines = output.split( "\n" );
    QVariantMap res;

    foreach ( const QString& l, lines )
    {
        const QString value = l.split("=").last();

        if ( l.startsWith( "duration" ) )
        {
            res[ "duration" ] = value.toDouble();
        }
        if ( l.startsWith( "bit_rate" ) )
        {
            res[ "bitrate" ] = value.toInt();
        }
    }

    return res;
}

// create snapshots from video file
void
createSnaps( const QString& file, const QString& tmpPath )
{
    // get meta data
    QVariantMap metadata = videoMetaData( file );
    std::cout << "   --> Duration: " << metadata[ "duration" ].toInt() << " - bitrate: " << metadata[ "bitrate" ].toInt() << std::endl;

    int start = metadata[ "duration" ].toInt() / 10;
    int step = metadata[ "duration" ].toInt() / ( FRAMES * 1.5 );

    for ( int i = 0; i < FRAMES; i++ )
    {
        QStringList args;
        args
             << "-ss" << timeToString( i * step + start )
             << "-i" << file
             << "-y"
             << "-f" << "image2"
             << "-vcodec" << "mjpeg"
             << "-vframes" << "1"
             << "-vf" << "scale=128:-1"
             << QString( "%1.jpg" ).arg( i );

        QProcess p;
        p.setWorkingDirectory( tmpPath );
        p.start( "ffmpeg", args );
        if ( !p.waitForFinished( 60000 ) )  // wait one minute at most
        {
            ffmpegMissing();    // this aborts the app
        }
    }
}

// create perceptual hash for snapshots
QHash<ulong64, int>
hashSnaps( const QString& path )
{
    QHash<ulong64, int> hashes;

    QDir dir( path );
    QFileInfoList list = dir.entryInfoList();
    for ( int i = 0; i < list.size(); ++i )
    {
        QFileInfo fileInfo = list.at( i );
        if ( !fileInfo.fileName().endsWith( ".jpg" ) )
            continue;

        ulong64 hash;
        int err = ph_dct_imagehash( fileInfo.absoluteFilePath().toLocal8Bit(), hash );
        if ( err )
            continue;

        hashes.insertMulti( hash, i );

        // delete snapshot
        QFile::remove( fileInfo.absoluteFilePath() );
    }

    return hashes;
}

// finds similar hashes by hamming distance
QList <QPair <int, QString> >
closestHashes( QHash<ulong64, QPair<int, QString> >& hashes, const ulong64& searchKey )
{
    QList <QPair <int, QString> > res;

    for ( int i = 0; i < hashes.keys().count(); i++ )
    {
        ulong64 key = hashes.keys().at( i );
        if ( ph_hamming_distance( searchKey, key ) < HAMMINGDIST )
        {
            QPair<int, QString> pair = hashes.values().at( i );
            res << pair;
        }
    }

    return res;
}

// find the files matching most of the p-hashes
QHash<QString, int>
fileMatches( const QString& file, const QHash<ulong64, int>& hash, QHash<ulong64, QPair<int, QString> >& hashes )
{
    QHash<QString, int> matches;    // filename, matches

    // go through all extracted snapshots and find dupes
    for ( int j = 0; j < hash.keys().count(); j++ )
    {
        ulong64 key = hash.keys().at( j );  // hash
        int value = hash.values().at( j );  // snapshot #

        QPair<int, QString> pair;           // snapshot #, filename
        QList<QPair<int, QString> > res;    // snapshot #, filename

        // find closest snapshots by hamming distance
        res = closestHashes( hashes, key );
        for ( int x = 0; x < res.count(); x++ )
        {
            pair = res.at( x );
            if ( pair.second == file )
            {
                // ignore matches to self
                continue;
            }

            // add/increment match count
            if ( !matches.contains( pair.second ) )
                matches[pair.second] = 1;
            else
                matches[pair.second] = matches[pair.second] + 1;
        }

        // store hashes for future comparisons
        pair.first = value;
        pair.second = file;
        hashes.insertMulti( key, pair );
    }

    return matches;
}

QByteArray
sha1Sum( const QString& path )
{
    QCryptographicHash hash( QCryptographicHash::Sha1 );
    QFile file( path );

    if ( file.open( QIODevice::ReadOnly ) )
    {
        hash.addData( file.readAll() );
        return hash.result();
    }

    return QByteArray();
}

bool
hasValidExtension( const QFileInfo& file )
{
    static QStringList exts;
    if ( !exts.count() )
        exts << ".3gp" << ".aaf" << ".asf" << ".avi" << ".divx" << ".flv"
             << ".m1v" << ".m2v" << ".m4v" << ".mkv" << ".mov" << ".mp4" << ".mpg" << ".mpeg"
             << ".rm" << ".ts" << ".wmv";

    foreach ( const QString& ext, exts )
    {
        if ( file.fileName().endsWith( ext ) )
        {
            return true;
        }
    }

    return false;
}

void
scanDir( QHash<ulong64, QPair<int, QString> >& hashes, const QString& path )
{
//    qDebug() << "Scanning dir:" << path;

    QDir dir( path );
    QFileInfoList list = dir.entryInfoList();
    for ( int i = 0; i < list.size(); ++i )
    {
        QFileInfo fileInfo = list.at( i );
        if ( fileInfo.isSymLink() )
            continue;
        if ( fileInfo.fileName().startsWith( "." ) )
            continue;

        if ( fileInfo.isDir() )
        {
            // scan recursively
            scanDir( hashes, fileInfo.absolutePath() + "/" + fileInfo.fileName() );
            continue;
        }
        if ( !hasValidExtension( fileInfo ) )
        {
            // only index videos
            continue;
        }

        std::cout << "Indexing \"" << qPrintable( fileInfo.absoluteFilePath() ) << "\" - size: " << fileInfo.size() << std::endl;

        // create snapshots
        createSnaps( fileInfo.absoluteFilePath(), TMPPATH );

        // analyze and hash snapshots
        QHash<ulong64, int> hash = hashSnaps( TMPPATH );

        // find known files matching the extracted hashes
        QHash<QString, int> matches;    // filename, matches
        matches = fileMatches( fileInfo.absoluteFilePath(), hash, hashes );

        for ( int y = 0; y < matches.keys().count(); y++ )
        {
            // threshold of matched snapshots to consider duped
            if ( (double)matches.values().at( y ) / (double)hash.count() >= THRESHOLD )
            {
                QFileInfo dupeFile( matches.keys().at( y ) );
                QByteArray sha1;
                if ( matches.values().at( y ) == hash.count()
                    && fileInfo.size() == dupeFile.size()
                    && ( sha1 = sha1Sum( fileInfo.absoluteFilePath() ) ) == sha1Sum( dupeFile.absoluteFilePath() ) )
                {
                    std::cout << "   --> Exact copy of \"" << qPrintable( matches.keys().at( y ) ) << "\" - sha1: " << qPrintable( sha1.toHex() ) << std::endl;
                }
                else
                {
                    std::cout << "   --> Perceptual dupe of \"" << qPrintable( matches.keys().at( y ) ) << "\" - size: " << QFileInfo( matches.keys().at( y ) ).size()
                              << " (scores " << qMin( FRAMES, matches.values().at( y ) ) << " out of " << qMin( FRAMES, hash.count() ) << ")" << std::endl;
                }
            }
        }
    }
}

int
main(int argc, char *argv[])
{
    QCoreApplication app( argc, argv );
    QCoreApplication::setApplicationName( "xray" );
    QCoreApplication::setApplicationVersion( "0.0.1" );

    QCommandLineParser cliParser;
    cliParser.setApplicationDescription( "xray indexes video files by their perceptual hash and finds duplicates.\n"
                                         "This means files are not compared byte for byte, but by their visual content.\n"
                                         "It will/should find dupes of videos, even when they are encoded in different formats and resolutions." );
    cliParser.addHelpOption();
    cliParser.addVersionOption();
    cliParser.addPositionalArgument( "path", QCoreApplication::translate( "main", "Directory to analyze" ) );

    QCommandLineOption framesOption( QStringList() << "f" << "frames",
                                     QCoreApplication::translate( "main", "Number of <frames> to analyze per video" ),
                                     "frames", "5" );
    cliParser.addOption( framesOption );

    QCommandLineOption hammingOption( QStringList() << "d" << "hamming-distance",
                                      QCoreApplication::translate( "main", "Maximum <distance> between two frames" ),
                                      "distance", "16" );
    cliParser.addOption( hammingOption );

    cliParser.process( app );

    const QStringList args = cliParser.positionalArguments();
    if ( !args.count() )
    {
        cliParser.showHelp( 1 );
    }

    FRAMES = cliParser.value( framesOption ).toInt();
    HAMMINGDIST = cliParser.value( hammingOption ).toInt();

    QHash<ulong64, QPair<int, QString> > hashes;    // perceptual hash, pair<snapshot #, filename>
    QTemporaryDir tmpDir;
    TMPPATH = tmpDir.path();
    scanDir( hashes, args.first() );

    return 0;
}
<|endoftext|>