<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/atomicops.h"
#include "testing/gtest/include/gtest/gtest.h"

template <class AtomicType>
static void TestAtomicIncrement() {
  // For now, we just test single threaded execution

  // use a guard value to make sure the NoBarrier_AtomicIncrement doesn't go
  // outside the expected address bounds.  This is in particular to
  // test that some future change to the asm code doesn't cause the
  // 32-bit NoBarrier_AtomicIncrement doesn't do the wrong thing on 64-bit
  // machines.
  struct {
    AtomicType prev_word;
    AtomicType count;
    AtomicType next_word;
  } s;

  AtomicType prev_word_value, next_word_value;
  memset(&prev_word_value, 0xFF, sizeof(AtomicType));
  memset(&next_word_value, 0xEE, sizeof(AtomicType));

  s.prev_word = prev_word_value;
  s.count = 0;
  s.next_word = next_word_value;

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 1), 1);
  EXPECT_EQ(s.count, 1);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 2), 3);
  EXPECT_EQ(s.count, 3);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 3), 6);
  EXPECT_EQ(s.count, 6);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -3), 3);
  EXPECT_EQ(s.count, 3);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -2), 1);
  EXPECT_EQ(s.count, 1);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -1), 0);
  EXPECT_EQ(s.count, 0);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -1), -1);
  EXPECT_EQ(s.count, -1);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -4), -5);
  EXPECT_EQ(s.count, -5);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 5), 0);
  EXPECT_EQ(s.count, 0);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);
}

#define NUM_BITS(T) (sizeof(T) * 8)

template <class AtomicType>
static void TestCompareAndSwap() {
  AtomicType value = 0;
  AtomicType prev = base::subtle::NoBarrier_CompareAndSwap(&value, 0, 1);
  EXPECT_EQ(1, value);
  EXPECT_EQ(0, prev);

  // Use test value that has non-zero bits in both halves, more for testing
  // 64-bit implementation on 32-bit platforms.
  const AtomicType k_test_val = (GG_ULONGLONG(1) <<
                                 (NUM_BITS(AtomicType) - 2)) + 11;
  value = k_test_val;
  prev = base::subtle::NoBarrier_CompareAndSwap(&value, 0, 5);
  EXPECT_EQ(k_test_val, value);
  EXPECT_EQ(k_test_val, prev);

  value = k_test_val;
  prev = base::subtle::NoBarrier_CompareAndSwap(&value, k_test_val, 5);
  EXPECT_EQ(5, value);
  EXPECT_EQ(k_test_val, prev);
}

template <class AtomicType>
static void TestAtomicExchange() {
  AtomicType value = 0;
  AtomicType new_value = base::subtle::NoBarrier_AtomicExchange(&value, 1);
  EXPECT_EQ(1, value);
  EXPECT_EQ(0, new_value);

  // Use test value that has non-zero bits in both halves, more for testing
  // 64-bit implementation on 32-bit platforms.
  const AtomicType k_test_val = (GG_ULONGLONG(1) <<
                                 (NUM_BITS(AtomicType) - 2)) + 11;
  value = k_test_val;
  new_value = base::subtle::NoBarrier_AtomicExchange(&value, k_test_val);
  EXPECT_EQ(k_test_val, value);
  EXPECT_EQ(k_test_val, new_value);

  value = k_test_val;
  new_value = base::subtle::NoBarrier_AtomicExchange(&value, 5);
  EXPECT_EQ(5, value);
  EXPECT_EQ(k_test_val, new_value);
}

template <class AtomicType>
static void TestAtomicIncrementBounds() {
  // Test at rollover boundary between int_max and int_min
  AtomicType test_val = (GG_ULONGLONG(1) <<
                         (NUM_BITS(AtomicType) - 1));
  AtomicType value = -1 ^ test_val;
  AtomicType new_value = base::subtle::NoBarrier_AtomicIncrement(&value, 1);
  EXPECT_EQ(test_val, value);
  EXPECT_EQ(value, new_value);

  base::subtle::NoBarrier_AtomicIncrement(&value, -1);
  EXPECT_EQ(-1 ^ test_val, value);

  // Test at 32-bit boundary for 64-bit atomic type.
  test_val = GG_ULONGLONG(1) << (NUM_BITS(AtomicType) / 2);
  value = test_val - 1;
  new_value = base::subtle::NoBarrier_AtomicIncrement(&value, 1);
  EXPECT_EQ(test_val, value);
  EXPECT_EQ(value, new_value);

  base::subtle::NoBarrier_AtomicIncrement(&value, -1);
  EXPECT_EQ(test_val - 1, value);
}

// This is a simple sanity check that values are correct. Not testing
// atomicity
template <class AtomicType>
static void TestStore() {
  const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL);
  const AtomicType kVal2 = static_cast<AtomicType>(-1);

  AtomicType value;

  base::subtle::NoBarrier_Store(&value, kVal1);
  EXPECT_EQ(kVal1, value);
  base::subtle::NoBarrier_Store(&value, kVal2);
  EXPECT_EQ(kVal2, value);

  base::subtle::Acquire_Store(&value, kVal1);
  EXPECT_EQ(kVal1, value);
  base::subtle::Acquire_Store(&value, kVal2);
  EXPECT_EQ(kVal2, value);

  base::subtle::Release_Store(&value, kVal1);
  EXPECT_EQ(kVal1, value);
  base::subtle::Release_Store(&value, kVal2);
  EXPECT_EQ(kVal2, value);
}

// This is a simple sanity check that values are correct. Not testing
// atomicity
template <class AtomicType>
static void TestLoad() {
  const AtomicType kVal1 = static_cast<AtomicType>(0xa5a5a5a5a5a5a5a5LL);
  const AtomicType kVal2 = static_cast<AtomicType>(-1);

  AtomicType value;

  value = kVal1;
  EXPECT_EQ(kVal1, base::subtle::NoBarrier_Load(&value));
  value = kVal2;
  EXPECT_EQ(kVal2, base::subtle::NoBarrier_Load(&value));

  value = kVal1;
  EXPECT_EQ(kVal1, base::subtle::Acquire_Load(&value));
  value = kVal2;
  EXPECT_EQ(kVal2, base::subtle::Acquire_Load(&value));

  value = kVal1;
  EXPECT_EQ(kVal1, base::subtle::Release_Load(&value));
  value = kVal2;
  EXPECT_EQ(kVal2, base::subtle::Release_Load(&value));
}

TEST(AtomicOpsTest, Inc) {
  TestAtomicIncrement<base::subtle::Atomic32>();
  TestAtomicIncrement<base::subtle::AtomicWord>();
}

TEST(AtomicOpsTest, CompareAndSwap) {
  TestCompareAndSwap<base::subtle::Atomic32>();
  TestCompareAndSwap<base::subtle::AtomicWord>();
}

TEST(AtomicOpsTest, Exchange) {
  TestAtomicExchange<base::subtle::Atomic32>();
  TestAtomicExchange<base::subtle::AtomicWord>();
}

TEST(AtomicOpsTest, IncrementBounds) {
  TestAtomicIncrementBounds<base::subtle::Atomic32>();
  TestAtomicIncrementBounds<base::subtle::AtomicWord>();
}

TEST(AtomicOpsTest, Store) {
  TestStore<base::subtle::Atomic32>();
  TestStore<base::subtle::AtomicWord>();
}

TEST(AtomicOpsTest, Load) {
  TestLoad<base::subtle::Atomic32>();
  TestLoad<base::subtle::AtomicWord>();
}
<commit_msg>Fix a test to avoid a MSVC warning as error about constant truncation.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/atomicops.h"
#include "testing/gtest/include/gtest/gtest.h"

template <class AtomicType>
static void TestAtomicIncrement() {
  // For now, we just test single threaded execution

  // use a guard value to make sure the NoBarrier_AtomicIncrement doesn't go
  // outside the expected address bounds.  This is in particular to
  // test that some future change to the asm code doesn't cause the
  // 32-bit NoBarrier_AtomicIncrement doesn't do the wrong thing on 64-bit
  // machines.
  struct {
    AtomicType prev_word;
    AtomicType count;
    AtomicType next_word;
  } s;

  AtomicType prev_word_value, next_word_value;
  memset(&prev_word_value, 0xFF, sizeof(AtomicType));
  memset(&next_word_value, 0xEE, sizeof(AtomicType));

  s.prev_word = prev_word_value;
  s.count = 0;
  s.next_word = next_word_value;

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 1), 1);
  EXPECT_EQ(s.count, 1);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 2), 3);
  EXPECT_EQ(s.count, 3);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 3), 6);
  EXPECT_EQ(s.count, 6);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -3), 3);
  EXPECT_EQ(s.count, 3);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -2), 1);
  EXPECT_EQ(s.count, 1);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -1), 0);
  EXPECT_EQ(s.count, 0);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -1), -1);
  EXPECT_EQ(s.count, -1);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, -4), -5);
  EXPECT_EQ(s.count, -5);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);

  EXPECT_EQ(base::subtle::NoBarrier_AtomicIncrement(&s.count, 5), 0);
  EXPECT_EQ(s.count, 0);
  EXPECT_EQ(s.prev_word, prev_word_value);
  EXPECT_EQ(s.next_word, next_word_value);
}

#define NUM_BITS(T) (sizeof(T) * 8)

template <class AtomicType>
static void TestCompareAndSwap() {
  AtomicType value = 0;
  AtomicType prev = base::subtle::NoBarrier_CompareAndSwap(&value, 0, 1);
  EXPECT_EQ(1, value);
  EXPECT_EQ(0, prev);

  // Use test value that has non-zero bits in both halves, more for testing
  // 64-bit implementation on 32-bit platforms.
  const AtomicType k_test_val = (GG_ULONGLONG(1) <<
                                 (NUM_BITS(AtomicType) - 2)) + 11;
  value = k_test_val;
  prev = base::subtle::NoBarrier_CompareAndSwap(&value, 0, 5);
  EXPECT_EQ(k_test_val, value);
  EXPECT_EQ(k_test_val, prev);

  value = k_test_val;
  prev = base::subtle::NoBarrier_CompareAndSwap(&value, k_test_val, 5);
  EXPECT_EQ(5, value);
  EXPECT_EQ(k_test_val, prev);
}

template <class AtomicType>
static void TestAtomicExchange() {
  AtomicType value = 0;
  AtomicType new_value = base::subtle::NoBarrier_AtomicExchange(&value, 1);
  EXPECT_EQ(1, value);
  EXPECT_EQ(0, new_value);

  // Use test value that has non-zero bits in both halves, more for testing
  // 64-bit implementation on 32-bit platforms.
  const AtomicType k_test_val = (GG_ULONGLONG(1) <<
                                 (NUM_BITS(AtomicType) - 2)) + 11;
  value = k_test_val;
  new_value = base::subtle::NoBarrier_AtomicExchange(&value, k_test_val);
  EXPECT_EQ(k_test_val, value);
  EXPECT_EQ(k_test_val, new_value);

  value = k_test_val;
  new_value = base::subtle::NoBarrier_AtomicExchange(&value, 5);
  EXPECT_EQ(5, value);
  EXPECT_EQ(k_test_val, new_value);
}

template <class AtomicType>
static void TestAtomicIncrementBounds() {
  // Test at rollover boundary between int_max and int_min
  AtomicType test_val = (GG_ULONGLONG(1) <<
                         (NUM_BITS(AtomicType) - 1));
  AtomicType value = -1 ^ test_val;
  AtomicType new_value = base::subtle::NoBarrier_AtomicIncrement(&value, 1);
  EXPECT_EQ(test_val, value);
  EXPECT_EQ(value, new_value);

  base::subtle::NoBarrier_AtomicIncrement(&value, -1);
  EXPECT_EQ(-1 ^ test_val, value);

  // Test at 32-bit boundary for 64-bit atomic type.
  test_val = GG_ULONGLONG(1) << (NUM_BITS(AtomicType) / 2);
  value = test_val - 1;
  new_value = base::subtle::NoBarrier_AtomicIncrement(&value, 1);
  EXPECT_EQ(test_val, value);
  EXPECT_EQ(value, new_value);

  base::subtle::NoBarrier_AtomicIncrement(&value, -1);
  EXPECT_EQ(test_val - 1, value);
}

// Return an AtomicType with the value 0xa5a5a5..
template <class AtomicType>
static AtomicType TestFillValue() {
  AtomicType val = 0;
  memset(&val, 0xa5, sizeof(AtomicType));
  return val;
}

// This is a simple sanity check that values are correct. Not testing
// atomicity
template <class AtomicType>
static void TestStore() {
  const AtomicType kVal1 = TestFillValue<AtomicType>();
  const AtomicType kVal2 = static_cast<AtomicType>(-1);

  AtomicType value;

  base::subtle::NoBarrier_Store(&value, kVal1);
  EXPECT_EQ(kVal1, value);
  base::subtle::NoBarrier_Store(&value, kVal2);
  EXPECT_EQ(kVal2, value);

  base::subtle::Acquire_Store(&value, kVal1);
  EXPECT_EQ(kVal1, value);
  base::subtle::Acquire_Store(&value, kVal2);
  EXPECT_EQ(kVal2, value);

  base::subtle::Release_Store(&value, kVal1);
  EXPECT_EQ(kVal1, value);
  base::subtle::Release_Store(&value, kVal2);
  EXPECT_EQ(kVal2, value);
}

// This is a simple sanity check that values are correct. Not testing
// atomicity
template <class AtomicType>
static void TestLoad() {
  const AtomicType kVal1 = TestFillValue<AtomicType>();
  const AtomicType kVal2 = static_cast<AtomicType>(-1);

  AtomicType value;

  value = kVal1;
  EXPECT_EQ(kVal1, base::subtle::NoBarrier_Load(&value));
  value = kVal2;
  EXPECT_EQ(kVal2, base::subtle::NoBarrier_Load(&value));

  value = kVal1;
  EXPECT_EQ(kVal1, base::subtle::Acquire_Load(&value));
  value = kVal2;
  EXPECT_EQ(kVal2, base::subtle::Acquire_Load(&value));

  value = kVal1;
  EXPECT_EQ(kVal1, base::subtle::Release_Load(&value));
  value = kVal2;
  EXPECT_EQ(kVal2, base::subtle::Release_Load(&value));
}

TEST(AtomicOpsTest, Inc) {
  TestAtomicIncrement<base::subtle::Atomic32>();
  TestAtomicIncrement<base::subtle::AtomicWord>();
}

TEST(AtomicOpsTest, CompareAndSwap) {
  TestCompareAndSwap<base::subtle::Atomic32>();
  TestCompareAndSwap<base::subtle::AtomicWord>();
}

TEST(AtomicOpsTest, Exchange) {
  TestAtomicExchange<base::subtle::Atomic32>();
  TestAtomicExchange<base::subtle::AtomicWord>();
}

TEST(AtomicOpsTest, IncrementBounds) {
  TestAtomicIncrementBounds<base::subtle::Atomic32>();
  TestAtomicIncrementBounds<base::subtle::AtomicWord>();
}

TEST(AtomicOpsTest, Store) {
  TestStore<base::subtle::Atomic32>();
  TestStore<base::subtle::AtomicWord>();
}

TEST(AtomicOpsTest, Load) {
  TestLoad<base::subtle::Atomic32>();
  TestLoad<base::subtle::AtomicWord>();
}
<|endoftext|>


<commit_before>#include <fstream>
#include <string>
#include <ncurses.h>

#include "feCharacter.h"
#include "feClass.h"
#include "feUtils.h"

std::string get_file_contents(const char *);

int main() {
  // initialize
  initscr();
	int row, col, dispr, dispc;
	std::string logopath = "dat/logo_jp.txt";

	// get row, column, and displacements
	getmaxyx(stdscr,row,col);
	dispr = 20;
	dispc = 100;
	row = (row - dispr) / 2;
	col = (col - dispc) / 2;
	row -= 8; // move it up 8 rows to make room for menu

  // get splash & print to center of screen
	std::ifstream inf(logopath, std::ios::in | std::ios::binary);
	for(std::string line; getline(inf, line); ) {
		mvprintw(row++, col, "%s", line.c_str());
	}
	refresh();

	// get char to keep window open, and exit
  getch();
  endwin();
  return 0;
}

std::string get_file_contents(const char *filename) {
  std::ifstream in(filename, std::ios::in | std::ios::binary);
  if (in)
  {
    std::string contents;
    in.seekg(0, std::ios::end);
    contents.resize(in.tellg());
    in.seekg(0, std::ios::beg);
    in.read(&contents[0], contents.size());
    in.close();
    return(contents);
  }
  throw(errno);
	/* std::ifstream ifs(filename); */
	/* std::string content( (std::istreambuf_iterator<char>(ifs) ), */
                       /* (std::istreambuf_iterator<char>()    ) ); */
	/* return content; */
}
<commit_msg>add menu<commit_after>#include <cstdlib>
#include <fstream>
#include <string>
#include <ncurses.h>
#include <menu.h>

#include "feCharacter.h"
#include "feClass.h"
#include "feUtils.h"

// lazy af
#define ARRAY_SIZE(array) (sizeof((array))/sizeof((array[0])))

std::string get_file_contents(const char *);

int main() {
  // initialize
  initscr();
	cbreak();
	noecho();
	keypad(stdscr, true);

	int row, col, dispr, dispc;
	std::string logopath = "dat/logo_jp.txt";

	const char *menu[] = {
		"Start",
		"Rosters",
		"Options",
		"Exit"
	};
	ITEM **items;
	ITEM *cur_item;
	MENU *game_menu;

	// get row, column, and displacements
	getmaxyx(stdscr,row,col);
	dispr = 20;
	dispc = 100;
	row = (row - dispr) / 2;
	col = (col - dispc) / 2;
	row -= 8; // move it up 8 rows to make room for menu

  // get splash & print to center of screen
	std::ifstream inf(logopath, std::ios::in | std::ios::binary);
	for(std::string line; getline(inf, line); ) {
		mvprintw(row++, col, "%s", line.c_str());
	}
	refresh();

	// build menu (looks more c than c++ to me...)
	int c, n_choices;
	n_choices = ARRAY_SIZE(menu);
	items = (ITEM **) calloc(n_choices + 1, sizeof(ITEM *));
	for(int i = 0; i < n_choices; ++i) items[i] = new_item(menu[i], menu[i]);
	items[n_choices] = (ITEM *) NULL;
	game_menu = new_menu((ITEM **) items);
	post_menu(game_menu);

	// exit handler
	while((c = getch()) != 10){
		switch(c) {
			case KEY_DOWN:
		    menu_driver(game_menu, REQ_DOWN_ITEM);
				break;
			case KEY_UP:
				menu_driver(game_menu, REQ_UP_ITEM);
				break;
		}
	}

	// free stuff up and exit
	free_item(items[0]);
	free_item(items[1]);
	free_menu(game_menu);
  endwin();
  return 0;
}

/**
 * store file contents into a string
 */
std::string get_file_contents(const char *filename) {
  std::ifstream in(filename, std::ios::in | std::ios::binary);
  if (in)
  {
    std::string contents;
    in.seekg(0, std::ios::end);
    contents.resize(in.tellg());
    in.seekg(0, std::ios::beg);
    in.read(&contents[0], contents.size());
    in.close();
    return(contents);
  }
  throw(errno);
	/* std::ifstream ifs(filename); */
	/* std::string content( (std::istreambuf_iterator<char>(ifs) ), */
                       /* (std::istreambuf_iterator<char>()    ) ); */
	/* return content; */
}
<|endoftext|>


<commit_before>/*
 * File:   main.cpp
 * Author: vlad
 *
 * Created on December 12, 2013, 10:38 PM
 */

#include <iostream>

#include "qpp.h"
#include "internal.h"
//#include "matlab.h" // support for MATLAB

#include "exception.h"

// TODO: expandout function
// TODO: dyad function
// TODO: proj (dya) function
// TODO: ip (inner product function) function, make it general to return matrices
// TODO: use .data() raw pointer instead of looping
// TODO: optimize syspermute: ?Eigen::Map?
// TODO: IMPORTANT Rewrite partial trace without syspermute
// TODO: further parallelization

using namespace std;

using namespace qpp;
using namespace qpp::types;

//int main(int argc, char **argv)
int main()
{
	cout << "Starting qpp..." << endl;
	_init();

	// Display formatting
	cout << std::fixed; // use fixed format for nice formatting
//	cout << std::scientific;
	cout << std::setprecision(4); // only for fixed or scientific modes

	// statistics tests
	cout << endl << "Statistics tests." << endl;
	std::vector<cplx> ampl = { 1. + ct::ii, 1. - ct::ii };
	cmat va(1, 4);
	va << 0.1, 1, 1. + ct::ii, 1. + 2. * ct::ii;
	stat::DiscreteDistributionFromComplex dc(va);
	cout << "The probabilities are: [";
	internal::_disp_container(dc.probabilities());
	cout << "]" << endl;

	// other tests
	size_t n = 12; // number of qubits
	size_t N = std::pow(2, n);
	vector<size_t> dims; // local dimensions
	for (size_t i = 0; i < n; i++)
		dims.push_back(2);
	cout << "n = " << n << " qubits, matrix size " << N << " x " << N << "."
			<< endl;

	// TIMING
	Timer t, total;  // start the timer, automatic tic() in the constructor

	// Matrix initialization
	cout << endl << "Matrix initialization timing." << endl;
	cmat randcmat = cmat::Random(N, N);
	t.toc(); // read the time
	cout << "Took " << t << " seconds." << endl;

	// Lazy matrix product
	cout << endl << "Lazy matrix product timing." << endl;
	auto b = randcmat * randcmat;
	t.toc(); // read the time
	cout << "Took " << t << " seconds." << endl;

	// Matrix product
	cout << endl << "Matrix product timing." << endl;
	t.tic(); // reset the chronometer
	cmat prodmat;
	prodmat = randcmat * randcmat; // need this (otherwise lazy evaluation)
	t.toc(); // read the time
	cout << "Took " << t << " seconds." << endl;

	// ptrace2 timing
	cout << endl << "ptrace2 timing." << endl;
	t.tic(); // reset the chronometer
	// trace away half of the qubits
	ptrace2(randcmat, { (size_t) std::sqrt(N), (size_t) std::sqrt(N) });
	t.toc(); // read the time
	cout << "Took " << t << " seconds." << endl;

	// ptrace SLOW SLOW SLOW (because of syspermute, do it without)
	cout << endl << "ptrace timing." << endl;
	vector<size_t> subsys_ptrace = { 0 }; // trace away the first qubit
	cout << "Subsytem(s): [";
	internal::_disp_container(subsys_ptrace);
	cout << "]" << endl;
	t.tic();
	ptrace(randcmat, subsys_ptrace, dims);
	t.toc();
	cout << "Took " << t << " seconds." << endl;

	// ptranspose
	cout << endl << "ptranspose timing." << endl;
	vector<size_t> subsys_ptranspose; // partially transpose all subsystems
	for (size_t i = 0; i < n; i++)
		subsys_ptranspose.push_back(i);
	cout << "Subsytem(s): [";
	internal::_disp_container(subsys_ptranspose);
	cout << "]" << endl;
	t.tic();
	ptranspose(randcmat, subsys_ptranspose, dims);
	t.toc();
	cout << "Took " << t << " seconds." << endl;

	// syspermute SLOW SLOW SLOW
	cout << endl << "syspermute timing." << endl;
	vector<size_t> perm; // left-shift all subsystems by 1
	for (size_t i = 0; i < n; i++)
		perm.push_back((i + 1) % n);
	cout << "Subsytem(s): [";
	internal::_disp_container(perm);
	cout << "]" << endl;
	t.tic();
	syspermute(randcmat, perm, dims);
	t.toc();
	cout << "Took " << t << " seconds." << endl;

	total.toc(); // read the total running time
	cout << endl << "Total time: " << total.seconds() << " seconds." << endl;
	// END TIMING

	cout << "Exiting qpp..." << endl;
}
<commit_msg>commit<commit_after>/*
 * File:   main.cpp
 * Author: vlad
 *
 * Created on December 12, 2013, 10:38 PM
 */

#include <iostream>

#include "qpp.h"
#include "internal.h"
//#include "matlab.h" // support for MATLAB

#include "exception.h"

// TODO: expandout function
// TODO: dya/dyad function
// TODO: proj (dya) function
// TODO: ip (inner product function) function, make it general to return matrices
// TODO: use .data() raw pointer instead of looping
// TODO: optimize syspermute: ?Eigen::Map?
// TODO: IMPORTANT Rewrite partial trace without syspermute
// TODO: further parallelization

using namespace std;

using namespace qpp;
using namespace qpp::types;

//int main(int argc, char **argv)
int main()
{
	cout << "Starting qpp..." << endl;
	_init();

	// Display formatting
	cout << std::fixed; // use fixed format for nice formatting
//	cout << std::scientific;
	cout << std::setprecision(4); // only for fixed or scientific modes

	// statistics tests
	cout << endl << "Statistics tests." << endl;
	std::vector<cplx> ampl = { 1. + ct::ii, 1. - ct::ii };
	cmat va(1, 4);
	va << 0.1, 1, 1. + ct::ii, 1. + 2. * ct::ii;
	stat::DiscreteDistributionFromComplex dc(va);
	cout << "The probabilities are: [";
	internal::_disp_container(dc.probabilities());
	cout << "]" << endl;

	// other tests
	size_t n = 12; // number of qubits
	size_t N = std::pow(2, n);
	vector<size_t> dims; // local dimensions
	for (size_t i = 0; i < n; i++)
		dims.push_back(2);
	cout << "n = " << n << " qubits, matrix size " << N << " x " << N << "."
			<< endl;

	// TIMING
	Timer t, total;  // start the timer, automatic tic() in the constructor

	// Matrix initialization
	cout << endl << "Matrix initialization timing." << endl;
	cmat randcmat = cmat::Random(N, N);
	t.toc(); // read the time
	cout << "Took " << t << " seconds." << endl;

	// Lazy matrix product
	cout << endl << "Lazy matrix product timing." << endl;
	auto b = randcmat * randcmat;
	t.toc(); // read the time
	cout << "Took " << t << " seconds." << endl;

	// Matrix product
	cout << endl << "Matrix product timing." << endl;
	t.tic(); // reset the chronometer
	cmat prodmat;
	prodmat = randcmat * randcmat; // need this (otherwise lazy evaluation)
	t.toc(); // read the time
	cout << "Took " << t << " seconds." << endl;

	// ptrace2 timing
	cout << endl << "ptrace2 timing." << endl;
	t.tic(); // reset the chronometer
	// trace away half of the qubits
	ptrace2(randcmat, { (size_t) std::sqrt(N), (size_t) std::sqrt(N) });
	t.toc(); // read the time
	cout << "Took " << t << " seconds." << endl;

	// ptrace SLOW SLOW SLOW (because of syspermute, do it without)
	cout << endl << "ptrace timing." << endl;
	vector<size_t> subsys_ptrace = { 0 }; // trace away the first qubit
	cout << "Subsytem(s): [";
	internal::_disp_container(subsys_ptrace);
	cout << "]" << endl;
	t.tic();
	ptrace(randcmat, subsys_ptrace, dims);
	t.toc();
	cout << "Took " << t << " seconds." << endl;

	// ptranspose
	cout << endl << "ptranspose timing." << endl;
	vector<size_t> subsys_ptranspose; // partially transpose all subsystems
	for (size_t i = 0; i < n; i++)
		subsys_ptranspose.push_back(i);
	cout << "Subsytem(s): [";
	internal::_disp_container(subsys_ptranspose);
	cout << "]" << endl;
	t.tic();
	ptranspose(randcmat, subsys_ptranspose, dims);
	t.toc();
	cout << "Took " << t << " seconds." << endl;

	// syspermute SLOW SLOW SLOW
	cout << endl << "syspermute timing." << endl;
	vector<size_t> perm; // left-shift all subsystems by 1
	for (size_t i = 0; i < n; i++)
		perm.push_back((i + 1) % n);
	cout << "Subsytem(s): [";
	internal::_disp_container(perm);
	cout << "]" << endl;
	t.tic();
	syspermute(randcmat, perm, dims);
	t.toc();
	cout << "Took " << t << " seconds." << endl;

	total.toc(); // read the total running time
	cout << endl << "Total time: " << total.seconds() << " seconds." << endl;
	// END TIMING

	cout << "Exiting qpp..." << endl;
}
<|endoftext|>


<commit_before>
#include "test_suite.h"

int main(int argc, char **argv) {
  bool run_benchmark_all = false;
  bool run_test = false;
  bool run_benchmark_bwtree = false;
  bool run_benchmark_bwtree_full = false;
  bool run_stress = false;
  bool run_epoch_test = false;
  bool run_infinite_insert_test = false;
  bool run_email_test = false;
  bool run_mixed_test = false;

  int opt_index = 1;
  while(opt_index < argc) {
    char *opt_p = argv[opt_index];

    if(strcmp(opt_p, "--benchmark-all") == 0) {
      run_benchmark_all = true;
    } else if(strcmp(opt_p, "--test") == 0) {
      run_test = true;
    } else if(strcmp(opt_p, "--benchmark-bwtree") == 0) {
      run_benchmark_bwtree = true;
    } else if(strcmp(opt_p, "--benchmark-bwtree-full") == 0) {
      run_benchmark_bwtree_full = true;
    } else if(strcmp(opt_p, "--stress-test") == 0) {
      run_stress = true;
    } else if(strcmp(opt_p, "--epoch-test") == 0) {
      run_epoch_test = true;
    } else if(strcmp(opt_p, "--infinite-insert-test") == 0) {
      run_infinite_insert_test = true;
    } else if(strcmp(opt_p, "--email-test") == 0) {
      run_email_test = true;
    } else if(strcmp(opt_p, "--mixed-test") == 0) {
      run_mixed_test = true;
    } else {
      printf("ERROR: Unknown option: %s\n", opt_p);

      return 0;
    }

    opt_index++;
  }

  bwt_printf("RUN_BENCHMARK_ALL = %d\n", run_benchmark_all);
  bwt_printf("RUN_BENCHMARK_BWTREE = %d\n", run_benchmark_bwtree);
  bwt_printf("RUN_BENCHMARK_BWTREE_FULL = %d\n", run_benchmark_bwtree_full);
  bwt_printf("RUN_TEST = %d\n", run_test);
  bwt_printf("RUN_STRESS = %d\n", run_stress);
  bwt_printf("RUN_EPOCH_TEST = %d\n", run_epoch_test);
  bwt_printf("RUN_INFINITE_INSERT_TEST = %d\n", run_infinite_insert_test);
  bwt_printf("RUN_EMAIL_TEST = %d\n", run_email_test);
  bwt_printf("RUN_MIXED_TEST = %d\n", run_mixed_test);
  bwt_printf("======================================\n");

  //////////////////////////////////////////////////////
  // Next start running test cases
  //////////////////////////////////////////////////////

  TreeType *t1 = nullptr;

  if(run_mixed_test == true) {
    print_flag = true;
    t1 = new TreeType{true,
                      KeyComparator{1},
                      KeyEqualityChecker{1}};
    print_flag = false;

    printf("Starting mixed testing...\n");
    LaunchParallelTestID(mixed_thread_num, MixedTest1, t1);
    printf("Finished mixed testing\n");

    PrintStat(t1);

    MixedGetValueTest(t1);

    print_flag = true;
    delete t1;
    print_flag = false;
  }

  if(run_email_test == true) {
    print_flag = true;
    auto t2 = new BwTree<std::string, long int>{};
    print_flag = false;

    TestBwTreeEmailInsertPerformance(t2, "emails_dump.txt");

    // t2 has already been deleted for memory reason
  }

  if(run_infinite_insert_test == true) {
    print_flag = true;
    t1 = new TreeType{true,
                      KeyComparator{1},
                      KeyEqualityChecker{1}};
    print_flag = false;

    InfiniteRandomInsertTest(t1);

    print_flag = true;
    delete t1;
    print_flag = false;
  }

  if(run_epoch_test == true) {
    print_flag = true;
    t1 = new TreeType{true,
                      KeyComparator{1},
                      KeyEqualityChecker{1}};
    print_flag = false;

    TestEpochManager(t1);

    print_flag = true;
    delete t1;
    print_flag = false;
  }

  if(run_benchmark_bwtree == true ||
     run_benchmark_bwtree_full == true) {
    print_flag = true;
    t1 = new TreeType{true,
                      KeyComparator{1},
                      KeyEqualityChecker{1}};

    int key_num = 3 * 1024 * 1024;

    if(run_benchmark_bwtree_full == true) {
      key_num *= 10;
    }

    bwt_printf("Using key size = %d (%f million)\n",
               key_num,
               key_num / (1024.0 * 1024.0));

    print_flag = false;

    if(run_benchmark_bwtree_full == true) {
      // First we rely on this test to fill bwtree with 30 million keys
      TestBwTreeMultiThreadInsertPerformance(t1, key_num);

      // And then do a multithreaded read
      TestBwTreeMultiThreadReadPerformance(t1, key_num);
    } else {
      // This function will delete all keys at the end, so the tree
      // is empty after it returns
      TestBwTreeInsertReadDeletePerformance(t1, key_num);

      delete t1;
      t1 = new TreeType{true,
                        KeyComparator{1},
                        KeyEqualityChecker{1}};

      // Tests random insert using one thread
      RandomInsertSpeedTest(t1, key_num);

      delete t1;
      t1 = new TreeType{true,
                        KeyComparator{1},
                        KeyEqualityChecker{1}};

      // Test random insert seq read
      RandomInsertSeqReadSpeedTest(t1, key_num);

      delete t1;
      t1 = new TreeType{true,
                        KeyComparator{1},
                        KeyEqualityChecker{1}};

      // Test seq insert random read
      SeqInsertRandomReadSpeedTest(t1, key_num);

      // Use stree_multimap as a reference
      RandomBtreeMultimapInsertSpeedTest(key_num);

      // Use cuckoohash_map
      RandomCuckooHashMapInsertSpeedTest(key_num);
    }

    print_flag = true;
    delete t1;
    print_flag = false;
  }

  if(run_benchmark_all == true) {
    print_flag = true;
    t1 = new TreeType{true,
                      KeyComparator{1},
                      KeyEqualityChecker{1}};

    int key_num = 1024 * 1024 * 3;
    bwt_printf("Using key size = %d (%f million)\n",
               key_num,
               key_num / (1024.0 * 1024.0));

    print_flag = false;

    TestStdMapInsertReadPerformance(key_num);
    TestStdUnorderedMapInsertReadPerformance(key_num);
    TestBTreeInsertReadPerformance(key_num);
    TestBTreeMultimapInsertReadPerformance(key_num);
    TestCuckooHashTableInsertReadPerformance(key_num);
    TestBwTreeInsertReadPerformance(t1, key_num);

    print_flag = true;
    delete t1;
    print_flag = false;
  }

  if(run_test == true) {
    print_flag = true;
    t1 = new TreeType{true,
                      KeyComparator{1},
                      KeyEqualityChecker{1}};
    print_flag = false;

    //////////////
    // Test iterator
    //////////////

    printf("Testing iterator...\n");

    IteratorTest(t1);
    PrintStat(t1);

    printf("Finised testing iterator\n");

    //////////////////////
    // Test random insert
    //////////////////////

    printf("Testing random insert...\n");

    // Do not print here otherwise we could not see result
    delete t1;
    t1 = new TreeType{true,
                      KeyComparator{1},
                      KeyEqualityChecker{1}};

    LaunchParallelTestID(8, RandomInsertTest, t1);
    RandomInsertVerify(t1);

    printf("Finished random insert testing. Delete the tree.\n");

    delete t1;
    t1 = new TreeType{true,
                      KeyComparator{1},
                      KeyEqualityChecker{1}};

    ////////////////////////////
    // Test mixed insert/delete
    ////////////////////////////

    LaunchParallelTestID(basic_test_thread_num, MixedTest1, t1);
    printf("Finished mixed testing\n");

    PrintStat(t1);

    MixedGetValueTest(t1);

    LaunchParallelTestID(basic_test_thread_num, InsertTest2, t1);
    printf("Finished inserting all keys\n");

    PrintStat(t1);

    InsertGetValueTest(t1);
    printf("Finished verifying all inserted values\n");

    LaunchParallelTestID(basic_test_thread_num, DeleteTest1, t1);
    printf("Finished deleting all keys\n");

    PrintStat(t1);

    DeleteGetValueTest(t1);
    printf("Finished verifying all deleted values\n");

    LaunchParallelTestID(basic_test_thread_num, InsertTest1, t1);
    printf("Finished inserting all keys\n");

    PrintStat(t1);

    InsertGetValueTest(t1);
    printf("Finished verifying all inserted values\n");

    LaunchParallelTestID(basic_test_thread_num, DeleteTest2, t1);
    printf("Finished deleting all keys\n");

    PrintStat(t1);

    DeleteGetValueTest(t1);
    printf("Finished verifying all deleted values\n");

    LaunchParallelTestID(basic_test_thread_num, InsertTest1, t1);
    printf("Finished inserting all keys\n");

    PrintStat(t1);

    InsertGetValueTest(t1);
    printf("Finished verifying all inserted values\n");

    LaunchParallelTestID(basic_test_thread_num, DeleteTest1, t1);
    printf("Finished deleting all keys\n");

    PrintStat(t1);

    DeleteGetValueTest(t1);
    printf("Finished verifying all deleted values\n");

    LaunchParallelTestID(basic_test_thread_num, InsertTest2, t1);
    printf("Finished inserting all keys\n");

    PrintStat(t1);

    InsertGetValueTest(t1);
    printf("Finished verifying all inserted values\n");

    LaunchParallelTestID(basic_test_thread_num, DeleteTest2, t1);
    printf("Finished deleting all keys\n");

    PrintStat(t1);

    DeleteGetValueTest(t1);
    printf("Finished verifying all deleted values\n");

    print_flag = true;
    delete t1;
    print_flag = false;
  }

  if(run_stress == true) {
    print_flag = true;

    // NOTE: For stress test we must start the GC thread in order
    // to let the tree run indefinitely
    t1 = new TreeType{true,
                      KeyComparator{1},
                      KeyEqualityChecker{1}};
    print_flag = false;

    LaunchParallelTestID(8, StressTest, t1);

    print_flag = true;
    delete t1;
    print_flag = false;
  }

  return 0;
}

<commit_msg>Use common routines to create and destroy trees<commit_after>
#include "test_suite.h"

int main(int argc, char **argv) {
  bool run_benchmark_all = false;
  bool run_test = false;
  bool run_benchmark_bwtree = false;
  bool run_benchmark_bwtree_full = false;
  bool run_stress = false;
  bool run_epoch_test = false;
  bool run_infinite_insert_test = false;
  bool run_email_test = false;
  bool run_mixed_test = false;

  int opt_index = 1;
  while(opt_index < argc) {
    char *opt_p = argv[opt_index];

    if(strcmp(opt_p, "--benchmark-all") == 0) {
      run_benchmark_all = true;
    } else if(strcmp(opt_p, "--test") == 0) {
      run_test = true;
    } else if(strcmp(opt_p, "--benchmark-bwtree") == 0) {
      run_benchmark_bwtree = true;
    } else if(strcmp(opt_p, "--benchmark-bwtree-full") == 0) {
      run_benchmark_bwtree_full = true;
    } else if(strcmp(opt_p, "--stress-test") == 0) {
      run_stress = true;
    } else if(strcmp(opt_p, "--epoch-test") == 0) {
      run_epoch_test = true;
    } else if(strcmp(opt_p, "--infinite-insert-test") == 0) {
      run_infinite_insert_test = true;
    } else if(strcmp(opt_p, "--email-test") == 0) {
      run_email_test = true;
    } else if(strcmp(opt_p, "--mixed-test") == 0) {
      run_mixed_test = true;
    } else {
      printf("ERROR: Unknown option: %s\n", opt_p);

      return 0;
    }

    opt_index++;
  }

  bwt_printf("RUN_BENCHMARK_ALL = %d\n", run_benchmark_all);
  bwt_printf("RUN_BENCHMARK_BWTREE = %d\n", run_benchmark_bwtree);
  bwt_printf("RUN_BENCHMARK_BWTREE_FULL = %d\n", run_benchmark_bwtree_full);
  bwt_printf("RUN_TEST = %d\n", run_test);
  bwt_printf("RUN_STRESS = %d\n", run_stress);
  bwt_printf("RUN_EPOCH_TEST = %d\n", run_epoch_test);
  bwt_printf("RUN_INFINITE_INSERT_TEST = %d\n", run_infinite_insert_test);
  bwt_printf("RUN_EMAIL_TEST = %d\n", run_email_test);
  bwt_printf("RUN_MIXED_TEST = %d\n", run_mixed_test);
  bwt_printf("======================================\n");

  //////////////////////////////////////////////////////
  // Next start running test cases
  //////////////////////////////////////////////////////

  TreeType *t1 = nullptr;

  if(run_mixed_test == true) {
    t1 = GetEmptyTree();

    printf("Starting mixed testing...\n");
    LaunchParallelTestID(mixed_thread_num, MixedTest1, t1);
    printf("Finished mixed testing\n");

    PrintStat(t1);

    MixedGetValueTest(t1);

    DestroyTree(t1);
  }

  if(run_email_test == true) {
    auto t2 = new BwTree<std::string, long int>{true};

    TestBwTreeEmailInsertPerformance(t2, "emails_dump.txt");

    // t2 has already been deleted for memory reason
  }

  if(run_epoch_test == true) {
    t1 = GetEmptyTree();

    TestEpochManager(t1);

    DestroyTree(t1);
  }

  if(run_benchmark_bwtree == true ||
     run_benchmark_bwtree_full == true) {
    t1 = GetEmptyTree();

    int key_num = 3 * 1024 * 1024;

    if(run_benchmark_bwtree_full == true) {
      key_num *= 10;
    }

    printf("Using key size = %d (%f million)\n",
           key_num,
           key_num / (1024.0 * 1024.0));

    if(run_benchmark_bwtree_full == true) {
      // First we rely on this test to fill bwtree with 30 million keys
      TestBwTreeMultiThreadInsertPerformance(t1, key_num);

      // And then do a multithreaded read
      TestBwTreeMultiThreadReadPerformance(t1, key_num);
    } else {
      // This function will delete all keys at the end, so the tree
      // is empty after it returns
      TestBwTreeInsertReadDeletePerformance(t1, key_num);

      DestroyTree(t1, true);
      t1 = GetEmptyTree(true);

      // Tests random insert using one thread
      RandomInsertSpeedTest(t1, key_num);

      DestroyTree(t1, true);
      t1 = GetEmptyTree(true);

      // Test random insert seq read
      RandomInsertSeqReadSpeedTest(t1, key_num);

      DestroyTree(t1, true);
      t1 = GetEmptyTree(true);

      // Test seq insert random read
      SeqInsertRandomReadSpeedTest(t1, key_num);

      // Use stree_multimap as a reference
      RandomBtreeMultimapInsertSpeedTest(key_num);

      // Use cuckoohash_map
      RandomCuckooHashMapInsertSpeedTest(key_num);
    }

    DestroyTree(t1);
  }

  if(run_benchmark_all == true) {
    t1 = GetEmptyTree();

    int key_num = 1024 * 1024 * 3;
    printf("Using key size = %d (%f million)\n",
           key_num,
           key_num / (1024.0 * 1024.0));

    TestStdMapInsertReadPerformance(key_num);
    TestStdUnorderedMapInsertReadPerformance(key_num);
    TestBTreeInsertReadPerformance(key_num);
    TestBTreeMultimapInsertReadPerformance(key_num);
    TestCuckooHashTableInsertReadPerformance(key_num);
    TestBwTreeInsertReadPerformance(t1, key_num);

    DestroyTree(t1);
  }

  if(run_test == true) {

    /////////////////////////////////////////////////////////////////
    // Test iterator
    /////////////////////////////////////////////////////////////////

    // This could print
    t1 = GetEmptyTree();

    printf("Testing iterator...\n");

    IteratorTest(t1);
    PrintStat(t1);

    printf("Finised testing iterator\n");

    /////////////////////////////////////////////////////////////////
    // Test random insert
    /////////////////////////////////////////////////////////////////

    printf("Testing random insert...\n");

    // Do not print here otherwise we could not see result
    t1 = GetEmptyTree(true);

    LaunchParallelTestID(8, RandomInsertTest, t1);
    RandomInsertVerify(t1);

    printf("Finished random insert testing. Delete the tree.\n");

    // no print
    DestroyTree(t1, true);

    /////////////////////////////////////////////////////////////////
    // Test mixed insert/delete
    /////////////////////////////////////////////////////////////////

    // no print
    t1 = GetEmptyTree(true);

    LaunchParallelTestID(basic_test_thread_num, MixedTest1, t1);
    printf("Finished mixed testing\n");

    PrintStat(t1);

    MixedGetValueTest(t1);

    /////////////////////////////////////////////////////////////////
    // Test Basic Insert/Delete/GetValue
    //   with different patterns and multi thread
    /////////////////////////////////////////////////////////////////

    LaunchParallelTestID(basic_test_thread_num, InsertTest2, t1);
    printf("Finished inserting all keys\n");

    PrintStat(t1);

    InsertGetValueTest(t1);
    printf("Finished verifying all inserted values\n");

    LaunchParallelTestID(basic_test_thread_num, DeleteTest1, t1);
    printf("Finished deleting all keys\n");

    PrintStat(t1);

    DeleteGetValueTest(t1);
    printf("Finished verifying all deleted values\n");

    LaunchParallelTestID(basic_test_thread_num, InsertTest1, t1);
    printf("Finished inserting all keys\n");

    PrintStat(t1);

    InsertGetValueTest(t1);
    printf("Finished verifying all inserted values\n");

    LaunchParallelTestID(basic_test_thread_num, DeleteTest2, t1);
    printf("Finished deleting all keys\n");

    PrintStat(t1);

    DeleteGetValueTest(t1);
    printf("Finished verifying all deleted values\n");

    LaunchParallelTestID(basic_test_thread_num, InsertTest1, t1);
    printf("Finished inserting all keys\n");

    PrintStat(t1);

    InsertGetValueTest(t1);
    printf("Finished verifying all inserted values\n");

    LaunchParallelTestID(basic_test_thread_num, DeleteTest1, t1);
    printf("Finished deleting all keys\n");

    PrintStat(t1);

    DeleteGetValueTest(t1);
    printf("Finished verifying all deleted values\n");

    LaunchParallelTestID(basic_test_thread_num, InsertTest2, t1);
    printf("Finished inserting all keys\n");

    PrintStat(t1);

    InsertGetValueTest(t1);
    printf("Finished verifying all inserted values\n");

    LaunchParallelTestID(basic_test_thread_num, DeleteTest2, t1);
    printf("Finished deleting all keys\n");

    PrintStat(t1);

    DeleteGetValueTest(t1);
    printf("Finished verifying all deleted values\n");

    DestroyTree(t1);
  }

  if(run_infinite_insert_test == true) {
    t1 = GetEmptyTree();

    InfiniteRandomInsertTest(t1);

    DestroyTree(t1);
  }

  if(run_stress == true) {
    t1 = GetEmptyTree();

    LaunchParallelTestID(8, StressTest, t1);

    DestroyTree(t1);
  }

  return 0;
}

<|endoftext|>


<commit_before>
#include <docopt.h>

#include <cstddef>
#include <iostream>

#ifdef _MSC_VER
#include <direct.h>
#define getcwd _getcwd
#else
#include <unistd.h>
#endif // _MSC_VER

#include <cstdlib>
#include <ctgmath>
#include <dirent.h>

#include <omp.h>

#include "SRTM.h"
#include "Mesh.h"
#include "Parsing.h"
#include "Utilities.h"

static const char USAGE[] =
R"(
Create meshes from SRTM files.

Usage:
   srtm2ply [options] <p1> <p2> [<INPUT_DIRECTORY> [<OUTPUT_DIRECTORY>]]

Options:
   -h --help                         Print this page.
   -v --version                      Display the application's version number.
   -o --origin=<origin>              Define the origin of the generated tiles (in WGS84 coordinates).
   -s --tile-size=wxh                Set the maximum size of tiles (in sampling points).
   -a --ascii-ply                    Generate ASCII-PLY meshes.
   -j <n>                            Generate N meshes in parallel.  [default: #CPUs]
   --srtm3                           The input directory contains SRTM data using a 90m resolution.

p1 and p2 denote two diagonally located corners of the bounding box of the desired mesh (using the WGS84
coordinate system), and have to be specified as WGS84 coordinates (as well as the desired origin).

The generated PLY-File will contain a mesh consisting only out of triangles. The data type for the vertex
indices in the PLY-File will be chosen according to the maximum amount of possible points in the mesh.
Thus, the -s option should be chosen accordingly to generate indices of a certain size (i.e. a tile size
of 256x256 sampling points will result in 16 bit indices).

WGS84 coordinates have to be specified using the following format (using degrees as the unit of angle):
<latitude>[N|S] [-]<longitude>[E|W] [<altitude>m], e.g. "51.48125N 0.008069W" for Greenwich.

Tile sizes should be specified as <width>x<height> in integer numbers, with 1 representing the distance between
two sampling points in the SRTM dataset (i.e. an arc second for the newest data).
)";

void printArguments(const std::map<std::string, docopt::value> &args)
{
    std::cout << "Arguments:\n\n";
    for (auto &entry: args)
    {
        const std::string &name = entry.first;
        const docopt::value &value = entry.second;

        std::cout << name << ": \n";

        if (value.isString())
            std::cout << "       (string)   " << value.asString() << "\n\n";
        else if (value.isLong())
            std::cout << "       (long)     " << value.asLong() << "\n\n";
        else if (value.isBool())
            std::cout << "       (bool)     " << value.asBool() << "\n\n";
        else if (value.isStringList())
        {
            const auto &list = value.asStringList();
            std::cout << "       (str_list) [\n";

            for (auto &str: list)
            std::cout << "                        " << str << ",\n";
            std::cout << "                  ]\n\n";
        }
        else if (!value) std::cout << "       (empty)\n\n";
        else std::cout << "       (unknown)\n\n";

    }
    std::cout << std::endl;
}

template<class T>
Mesh meshFromSrtmTile(const T &tile, const LCS &coordinateSystem)
{
    Mesh mesh;

    auto &coordinates = tile.coordinates();
    mesh.vertexPositions.resize(tile.numValues());
    std::transform(coordinates.begin(), coordinates.end(), mesh.vertexPositions.begin(),
                   [&](WGS84::Point coord) -> Eigen::Vector3f {
                       return coordinateSystem.fromECEF(coord).cast<float>();
                   });

    auto size = tile.size();
    mesh.faces.clear();
    mesh.faces.reserve(2*(size[0]-1)*(size[1]-1));
    for (int x = 0; x < size[0]-1; ++x)
    {
        for (int y = 0; y < size[1]-1; ++y)
        {
            auto idx1 = tile.indexAtPosition({x  ,y  });
            auto idx2 = tile.indexAtPosition({x+1,y  });
            auto idx3 = tile.indexAtPosition({x  ,y+1});
            auto idx4 = tile.indexAtPosition({x+1,y+1});

            mesh.faces.push_back({idx1,idx2,idx3});
            mesh.faces.push_back({idx2,idx4,idx3});
        }
    }

    return mesh;
}

template<class T>
void generateMeshes(std::map<std::string, docopt::value> &args)
{
    typedef T Tile;
    typedef typename Tile::Size Size;
    typedef typename Tile::Bounds Bounds;
    typedef typename Tile::Cache Cache;

    const std::string cwd(getcwd(nullptr,0));

    std::string inputDir  = args["<INPUT_DIRECTORY>" ].isString() ? args["<INPUT_DIRECTORY>" ].asString() : cwd;
    std::string outputDir = args["<OUTPUT_DIRECTORY>"].isString() ? args["<OUTPUT_DIRECTORY>"].asString() : cwd;

    inputDir  = absolutePath(inputDir.c_str());
    outputDir = absolutePath(outputDir.c_str());

    WGS84::Point from, to, origin;
    from = parseWGS84(args["<p1>"].asString());
    to   = parseWGS84(args["<p2>"].asString());

    if (args["<origin>"].isString())
        origin = parseWGS84(args["<origin>"].asString());
    else
        origin = WGS84::Point(Eigen::Vector3d((from+to)/2.0));

    auto mapBoundaries = Tile::bounds(from,to);
    Eigen::Vector2i mapSize = mapBoundaries.diagonal() + Eigen::Vector2i(1,1);

    Eigen::Vector2i tileSize;
    if (args["--tile-size"].isString())
        tileSize = parseSize(args["--tile-size"].asString());
    else
        tileSize = mapSize;

    omp_set_nested(0);
    {
        int num_threads = parseNumberOfThreads(args["-j"].asString());
        omp_set_num_threads(num_threads);
    }

    static const auto ceil = [](double a){ return std::ceil(a); };
    Eigen::Vector2i numTiles = Eigen::Vector2d( //Element-wise division -> ceiling
                                    (mapSize.cast<double>().array()/tileSize.cast<double>().array()
                               ).unaryExpr(ceil)).cast<int>();

    std::cout << "Input  directory: " << inputDir  << "\n";
    std::cout << "Output directory: " << outputDir << "\n\n";

    std::cout << "From:      " << std::setw(5) << from[0]      << " / " << std::setw(5) << from[1]   << " / " << std::setw(5) << from[2]   << "\n";
    std::cout << "To:        " << std::setw(5) << to[0]        << " / " << std::setw(5) << to[1]     << " / " << std::setw(5) << to[2]     << "\n";
    std::cout << "Origin:    " << std::setw(5) << origin[0]    << " / " << std::setw(5) << origin[1] << " / " << std::setw(5) << origin[2] << "\n\n";

    std::cout << "Tile Size: " << std::setw(5) << tileSize[0]  << " / " << std::setw(5) << tileSize[1] << "\n";
    std::cout << "#Tiles:    " << std::setw(5) << numTiles[0]  << " / " << std::setw(5) << numTiles[1] << "\n\n";

    Tensor<Bounds, 2> tileDefinitions(numTiles);
    for (int y = 0; y < numTiles[1]; ++y)
    {
        for (int x = 0; x < numTiles[0]; ++x)
        {
            Eigen::Vector2i position = (tileSize.array() -1) * Eigen::Array2i(x,y);
            Size size = tileSize.array().min(Eigen::Array2i(mapSize - position));
            tileDefinitions[{x,y}] = Tile::bounds(mapBoundaries.min()+position, size);
        }
    }

    LCS lcs(origin);
    Cache cache(inputDir);

    #pragma omp parallel for default(shared)
    for (int i = 0; i < tileDefinitions.numValues(); ++i)
    {
        try
        {
            std::stringstream ss;
            ss << outputDir << "/" << i << ".ply";

            auto filename = ss.str();
            //ScopedTimer timer(filename);

            auto &bounds = tileDefinitions[i];
            auto tile = Tile::stitch(bounds,cache);
            auto mesh = meshFromSrtmTile(tile, lcs);

            std::ofstream file(filename);

            if (!args["--ascii-ply"])
                mesh.toBinaryPly(file);
            else
                mesh.toAsciiPly(file);
        }
        catch(std::exception &e)
        { //Exceptions break the omp loop and lead to a terminate(). Handle them here.
            std::cerr << "An unexpected error occurred: \n"
                      << e.what() << std::endl;
            exit(-1);
        }
        catch(...)
        {
            std::cerr << "An unexpected error occurred (unknown type)." << std::endl;
            exit(-1);
        }
    }

}

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

        auto args = docopt::docopt(USAGE,
                                   { argv + 1, argv + argc },
                                   true,                       // show help if requested
                                   "SRTM2PLY 0.1"              // version string
                                   );

        printArguments(args);

        if (args["--srtm3"] && args["--srtm3"].asBool())
            generateMeshes<SRTM3::Tile>(args);
        else
            generateMeshes<SRTM1::Tile>(args);

    } catch(std::exception &e)
    {
        std::cerr << "An unexpected error occurred: \n"
                  << e.what() << std::endl;
        exit(-1);
    }
}
<commit_msg>Commented out argument debugging code<commit_after>
#include <docopt.h>

#include <cstddef>
#include <iostream>

#ifdef _MSC_VER
#include <direct.h>
#define getcwd _getcwd
#else
#include <unistd.h>
#endif // _MSC_VER

#include <cstdlib>
#include <ctgmath>
#include <dirent.h>

#include <omp.h>

#include "SRTM.h"
#include "Mesh.h"
#include "Parsing.h"
#include "Utilities.h"

static const char USAGE[] =
R"(
Create meshes from SRTM files.

Usage:
   srtm2ply [options] <p1> <p2> [<INPUT_DIRECTORY> [<OUTPUT_DIRECTORY>]]

Options:
   -h --help                         Print this page.
   -v --version                      Display the application's version number.
   -o --origin=<origin>              Define the origin of the generated tiles (in WGS84 coordinates).
   -s --tile-size=wxh                Set the maximum size of tiles (in sampling points).
   -a --ascii-ply                    Generate ASCII-PLY meshes.
   -j <n>                            Generate N meshes in parallel.  [default: #CPUs]
   --srtm3                           The input directory contains SRTM data using a 90m resolution.

p1 and p2 denote two diagonally located corners of the bounding box of the desired mesh (using the WGS84
coordinate system), and have to be specified as WGS84 coordinates (as well as the desired origin).

The generated PLY-File will contain a mesh consisting only out of triangles. The data type for the vertex
indices in the PLY-File will be chosen according to the maximum amount of possible points in the mesh.
Thus, the -s option should be chosen accordingly to generate indices of a certain size (i.e. a tile size
of 256x256 sampling points will result in 16 bit indices).

WGS84 coordinates have to be specified using the following format (using degrees as the unit of angle):
<latitude>[N|S] [-]<longitude>[E|W] [<altitude>m], e.g. "51.48125N 0.008069W" for Greenwich.

Tile sizes should be specified as <width>x<height> in integer numbers, with 1 representing the distance between
two sampling points in the SRTM dataset (i.e. an arc second for the newest data).
)";

void printArguments(const std::map<std::string, docopt::value> &args)
{
    std::cout << "Arguments:\n\n";
    for (auto &entry: args)
    {
        const std::string &name = entry.first;
        const docopt::value &value = entry.second;

        std::cout << name << ": \n";

        if (value.isString())
            std::cout << "       (string)   " << value.asString() << "\n\n";
        else if (value.isLong())
            std::cout << "       (long)     " << value.asLong() << "\n\n";
        else if (value.isBool())
            std::cout << "       (bool)     " << value.asBool() << "\n\n";
        else if (value.isStringList())
        {
            const auto &list = value.asStringList();
            std::cout << "       (str_list) [\n";

            for (auto &str: list)
            std::cout << "                        " << str << ",\n";
            std::cout << "                  ]\n\n";
        }
        else if (!value) std::cout << "       (empty)\n\n";
        else std::cout << "       (unknown)\n\n";

    }
    std::cout << std::endl;
}

template<class T>
Mesh meshFromSrtmTile(const T &tile, const LCS &coordinateSystem)
{
    Mesh mesh;

    auto &coordinates = tile.coordinates();
    mesh.vertexPositions.resize(tile.numValues());
    std::transform(coordinates.begin(), coordinates.end(), mesh.vertexPositions.begin(),
                   [&](WGS84::Point coord) -> Eigen::Vector3f {
                       return coordinateSystem.fromECEF(coord).cast<float>();
                   });

    auto size = tile.size();
    mesh.faces.clear();
    mesh.faces.reserve(2*(size[0]-1)*(size[1]-1));
    for (int x = 0; x < size[0]-1; ++x)
    {
        for (int y = 0; y < size[1]-1; ++y)
        {
            auto idx1 = tile.indexAtPosition({x  ,y  });
            auto idx2 = tile.indexAtPosition({x+1,y  });
            auto idx3 = tile.indexAtPosition({x  ,y+1});
            auto idx4 = tile.indexAtPosition({x+1,y+1});

            mesh.faces.push_back({idx1,idx2,idx3});
            mesh.faces.push_back({idx2,idx4,idx3});
        }
    }

    return mesh;
}

template<class T>
void generateMeshes(std::map<std::string, docopt::value> &args)
{
    typedef T Tile;
    typedef typename Tile::Size Size;
    typedef typename Tile::Bounds Bounds;
    typedef typename Tile::Cache Cache;

    const std::string cwd(getcwd(nullptr,0));

    std::string inputDir  = args["<INPUT_DIRECTORY>" ].isString() ? args["<INPUT_DIRECTORY>" ].asString() : cwd;
    std::string outputDir = args["<OUTPUT_DIRECTORY>"].isString() ? args["<OUTPUT_DIRECTORY>"].asString() : cwd;

    inputDir  = absolutePath(inputDir.c_str());
    outputDir = absolutePath(outputDir.c_str());

    WGS84::Point from, to, origin;
    from = parseWGS84(args["<p1>"].asString());
    to   = parseWGS84(args["<p2>"].asString());

    if (args["<origin>"].isString())
        origin = parseWGS84(args["<origin>"].asString());
    else
        origin = WGS84::Point(Eigen::Vector3d((from+to)/2.0));

    auto mapBoundaries = Tile::bounds(from,to);
    Eigen::Vector2i mapSize = mapBoundaries.diagonal() + Eigen::Vector2i(1,1);

    Eigen::Vector2i tileSize;
    if (args["--tile-size"].isString())
        tileSize = parseSize(args["--tile-size"].asString());
    else
        tileSize = mapSize;

    omp_set_nested(0);
    {
        int num_threads = parseNumberOfThreads(args["-j"].asString());
        omp_set_num_threads(num_threads);
    }

    static const auto ceil = [](double a){ return std::ceil(a); };
    Eigen::Vector2i numTiles = Eigen::Vector2d( //Element-wise division -> ceiling
                                    (mapSize.cast<double>().array()/tileSize.cast<double>().array()
                               ).unaryExpr(ceil)).cast<int>();

    std::cout << "Input  directory: " << inputDir  << "\n";
    std::cout << "Output directory: " << outputDir << "\n\n";

    std::cout << "From:      " << std::setw(5) << from[0]      << " / " << std::setw(5) << from[1]   << " / " << std::setw(5) << from[2]   << "\n";
    std::cout << "To:        " << std::setw(5) << to[0]        << " / " << std::setw(5) << to[1]     << " / " << std::setw(5) << to[2]     << "\n";
    std::cout << "Origin:    " << std::setw(5) << origin[0]    << " / " << std::setw(5) << origin[1] << " / " << std::setw(5) << origin[2] << "\n\n";

    std::cout << "Tile Size: " << std::setw(5) << tileSize[0]  << " / " << std::setw(5) << tileSize[1] << "\n";
    std::cout << "#Tiles:    " << std::setw(5) << numTiles[0]  << " / " << std::setw(5) << numTiles[1] << "\n\n";

    Tensor<Bounds, 2> tileDefinitions(numTiles);
    for (int y = 0; y < numTiles[1]; ++y)
    {
        for (int x = 0; x < numTiles[0]; ++x)
        {
            Eigen::Vector2i position = (tileSize.array() -1) * Eigen::Array2i(x,y);
            Size size = tileSize.array().min(Eigen::Array2i(mapSize - position));
            tileDefinitions[{x,y}] = Tile::bounds(mapBoundaries.min()+position, size);
        }
    }

    LCS lcs(origin);
    Cache cache(inputDir);

    #pragma omp parallel for default(shared)
    for (int i = 0; i < tileDefinitions.numValues(); ++i)
    {
        try
        {
            std::stringstream ss;
            ss << outputDir << "/" << i << ".ply";

            auto filename = ss.str();
            //ScopedTimer timer(filename);

            auto &bounds = tileDefinitions[i];
            auto tile = Tile::stitch(bounds,cache);
            auto mesh = meshFromSrtmTile(tile, lcs);

            std::ofstream file(filename);

            if (!args["--ascii-ply"])
                mesh.toBinaryPly(file);
            else
                mesh.toAsciiPly(file);
        }
        catch(std::exception &e)
        { //Exceptions break the omp loop and lead to a terminate(). Handle them here.
            std::cerr << "An unexpected error occurred: \n"
                      << e.what() << std::endl;
            exit(-1);
        }
        catch(...)
        {
            std::cerr << "An unexpected error occurred (unknown type)." << std::endl;
            exit(-1);
        }
    }

}

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

        auto args = docopt::docopt(USAGE,
                                   { argv + 1, argv + argc },
                                   true,                       // show help if requested
                                   "SRTM2PLY 0.1"              // version string
                                   );

        //printArguments(args);

        if (args["--srtm3"] && args["--srtm3"].asBool())
            generateMeshes<SRTM3::Tile>(args);
        else
            generateMeshes<SRTM1::Tile>(args);

    } catch(std::exception &e)
    {
        std::cerr << "An unexpected error occurred: \n"
                  << e.what() << std::endl;
        exit(-1);
    }
}
<|endoftext|>


<commit_before>#include "obd2.h"
#include "can/canutil.h"
#include "util/timer.h"
#include "util/log.h"
#include "shared_handlers.h"
#include "config.h"
#include <limits.h>

namespace time = openxc::util::time;

using openxc::diagnostics::DiagnosticsManager;
using openxc::diagnostics::obd2::Obd2Pid;
using openxc::util::log::debug;
using openxc::diagnostics::ActiveDiagnosticRequest;
using openxc::config::getConfiguration;
using openxc::config::PowerManagement;

#define ENGINE_SPEED_PID 0xc
#define VEHICLE_SPEED_PID 0xd

static bool ENGINE_STARTED = false;
static bool VEHICLE_IN_MOTION = false;

static openxc::util::time::FrequencyClock IGNITION_STATUS_TIMER = {0.2};

const Obd2Pid OBD2_PIDS[] = {
    { pid: ENGINE_SPEED_PID, name: "engine_speed", frequency: 5 },
    { pid: VEHICLE_SPEED_PID, name: "vehicle_speed", frequency: 5 },
    { pid: 0x4, name: "engine_load", frequency: 5 },
    { pid: 0x33, name: "barometric_pressure", frequency: 1 },
    { pid: 0x4c, name: "commanded_throttle_position", frequency: 1 },
    { pid: 0x5, name: "engine_coolant_temperature", frequency: 1 },
    { pid: 0x27, name: "fuel_level", frequency: 1 },
    { pid: 0xf, name: "intake_air_temperature", frequency: 1 },
    { pid: 0xb, name: "intake_manifold_pressure", frequency: 1 },
    { pid: 0x1f, name: "running_time", frequency: 1 },
    { pid: 0x11, name: "throttle_position", frequency: 5 },
    { pid: 0xa, name: "fuel_pressure", frequency: 1 },
    { pid: 0x66, name: "mass_airflow", frequency: 5 },
    { pid: 0x5a, name: "accelerator_pedal_position", frequency: 5 },
    { pid: 0x52, name: "ethanol_fuel_percentage", frequency: 1 },
    { pid: 0x5c, name: "engine_oil_temperature", frequency: 1 },
    { pid: 0x63, name: "engine_torque", frequency: 1 },
};

static void checkIgnitionStatus(DiagnosticsManager* manager,
        const ActiveDiagnosticRequest* request,
        const DiagnosticResponse* response,
        float parsedPayload) {
    bool match = false;
    if(response->pid == ENGINE_SPEED_PID) {
        match = ENGINE_STARTED = parsedPayload != 0;
    } else if(response->pid == VEHICLE_SPEED_PID) {
        match = VEHICLE_IN_MOTION = parsedPayload != 0;
    }

    if(match) {
        time::tick(&IGNITION_STATUS_TIMER);
    }
}

static void requestIgnitionStatus(DiagnosticsManager* manager) {
    if(manager->obd2Bus != NULL && (getConfiguration()->powerManagement ==
                PowerManagement::OBD2_IGNITION_CHECK ||
            getConfiguration()->recurringObd2Requests)) {
        DiagnosticRequest request = {arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID,
                mode: 0x1, has_pid: true, pid: ENGINE_SPEED_PID};
        addRequest(manager, manager->obd2Bus, &request, "engine_speed",
                false, false, 1, 0, NULL, checkIgnitionStatus);

        request.pid = VEHICLE_SPEED_PID;
        addRequest(manager, manager->obd2Bus, &request, "vehicle_speed",
                false, false, 1, 0, NULL, checkIgnitionStatus);
        time::tick(&IGNITION_STATUS_TIMER);
    }
}

static void checkSupportedPids(DiagnosticsManager* manager,
        const ActiveDiagnosticRequest* request,
        const DiagnosticResponse* response,
        float parsedPayload) {
    if(manager->obd2Bus == NULL || !getConfiguration()->recurringObd2Requests) {
        return;
    }

    for(int i = 0; i < response->payload_length; i++) {
        for(int j = CHAR_BIT - 1; j >= 0; j--) {
            if(response->payload[i] >> j & 0x1) {
                uint16_t pid = response->pid + (i * CHAR_BIT) + j + 1;
                DiagnosticRequest request = {
                        arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID,
                        mode: 0x1, has_pid: true, pid: pid};
                for(size_t i = 0; i < sizeof(OBD2_PIDS) / sizeof(Obd2Pid); i++) {
                    if(OBD2_PIDS[i].pid == pid) {
                        debug("Vehicle supports PID %d", pid);
                        addRecurringRequest(manager, manager->obd2Bus, &request,
                                OBD2_PIDS[i].name, false, false, 1, 0,
                                openxc::signals::handlers::handleObd2Pid,
                                checkIgnitionStatus,
                                OBD2_PIDS[i].frequency);
                        break;
                    }
                }
            }
        }
    }
}

void openxc::diagnostics::obd2::initialize(DiagnosticsManager* manager) {
    requestIgnitionStatus(manager);
}

// * CAN traffic will eventualy stop, and we will suspend.
// * When do we wake up?
// * If normal CAN is open, bus activity will wake us up and we will resume.
// * If normal CAN is blocked, we rely on a watchdog to wake us up every 15
// seconds to start this process over again.
void openxc::diagnostics::obd2::loop(DiagnosticsManager* manager, CanBus* bus) {
    static bool ignitionWasOn = false;
    static bool pidSupportQueried = false;
    static bool sentFinalIgnitionCheck = false;

    if(!manager->initialized) {
        return;
    }

    if(time::elapsed(&IGNITION_STATUS_TIMER, false)) {
        if(sentFinalIgnitionCheck) {
            // remove all open diagnostic requests, which shuld cause the bus to go
            // silent if the car is off, and thus the VI to suspend. TODO kick off
            // watchdog! TODO when it wakes keep in a minimum run level (i.e. don't
            // turn on bluetooth) until we decide the vehicle is actually on.
            if(manager->initialized && getConfiguration()->powerManagement ==
                        PowerManagement::OBD2_IGNITION_CHECK) {
                debug("Ceasing diagnostic requests as ignition went off");
                diagnostics::reset(manager);
                manager->initialized = false;
            }
            ignitionWasOn = false;
            pidSupportQueried = false;
        } else {
            // We haven't received an ignition in 5 seconds. Either the user didn't
            // have either OBD-II request configured as a recurring request (which
            // is fine) or they did, but the car stopped responding. Kick off
            // another request to see which is true. It will take 5+5 seconds after
            // ignition off to decide we should shut down.
            requestIgnitionStatus(manager);
            sentFinalIgnitionCheck = true;
        }
    } else if(!ignitionWasOn && (ENGINE_STARTED || VEHICLE_IN_MOTION)) {
        ignitionWasOn = true;
        sentFinalIgnitionCheck = false;
        if(getConfiguration()->recurringObd2Requests && !pidSupportQueried) {
            debug("Ignition is on - querying for supported OBD-II PIDs");
            pidSupportQueried = true;
            DiagnosticRequest request = {
                    arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID,
                    mode: 0x1,
                    has_pid: true,
                    pid: 0x0};
            for(int i = 0x0; i <= 0x80; i += 0x20) {
                request.pid = i;
                addRequest(manager, bus, &request, NULL, false, false, 1, 0,
                        NULL, checkSupportedPids);
            }
        }
    }
}
<commit_msg>When engine starts after a stop, reset number of chances to recover.<commit_after>#include "obd2.h"
#include "can/canutil.h"
#include "util/timer.h"
#include "util/log.h"
#include "shared_handlers.h"
#include "config.h"
#include <limits.h>

namespace time = openxc::util::time;

using openxc::diagnostics::DiagnosticsManager;
using openxc::diagnostics::obd2::Obd2Pid;
using openxc::util::log::debug;
using openxc::diagnostics::ActiveDiagnosticRequest;
using openxc::config::getConfiguration;
using openxc::config::PowerManagement;

#define ENGINE_SPEED_PID 0xc
#define VEHICLE_SPEED_PID 0xd

static bool ENGINE_STARTED = false;
static bool VEHICLE_IN_MOTION = false;

static openxc::util::time::FrequencyClock IGNITION_STATUS_TIMER = {0.2};

const Obd2Pid OBD2_PIDS[] = {
    { pid: ENGINE_SPEED_PID, name: "engine_speed", frequency: 5 },
    { pid: VEHICLE_SPEED_PID, name: "vehicle_speed", frequency: 5 },
    { pid: 0x4, name: "engine_load", frequency: 5 },
    { pid: 0x33, name: "barometric_pressure", frequency: 1 },
    { pid: 0x4c, name: "commanded_throttle_position", frequency: 1 },
    { pid: 0x5, name: "engine_coolant_temperature", frequency: 1 },
    { pid: 0x27, name: "fuel_level", frequency: 1 },
    { pid: 0xf, name: "intake_air_temperature", frequency: 1 },
    { pid: 0xb, name: "intake_manifold_pressure", frequency: 1 },
    { pid: 0x1f, name: "running_time", frequency: 1 },
    { pid: 0x11, name: "throttle_position", frequency: 5 },
    { pid: 0xa, name: "fuel_pressure", frequency: 1 },
    { pid: 0x66, name: "mass_airflow", frequency: 5 },
    { pid: 0x5a, name: "accelerator_pedal_position", frequency: 5 },
    { pid: 0x52, name: "ethanol_fuel_percentage", frequency: 1 },
    { pid: 0x5c, name: "engine_oil_temperature", frequency: 1 },
    { pid: 0x63, name: "engine_torque", frequency: 1 },
};

static void checkIgnitionStatus(DiagnosticsManager* manager,
        const ActiveDiagnosticRequest* request,
        const DiagnosticResponse* response,
        float parsedPayload) {
    bool match = false;
    if(response->pid == ENGINE_SPEED_PID) {
        match = ENGINE_STARTED = parsedPayload != 0;
    } else if(response->pid == VEHICLE_SPEED_PID) {
        match = VEHICLE_IN_MOTION = parsedPayload != 0;
    }

    if(match) {
        time::tick(&IGNITION_STATUS_TIMER);
    }
}

static void requestIgnitionStatus(DiagnosticsManager* manager) {
    if(manager->obd2Bus != NULL && (getConfiguration()->powerManagement ==
                PowerManagement::OBD2_IGNITION_CHECK ||
            getConfiguration()->recurringObd2Requests)) {
        debug("Sending requests to check ignition status");
        DiagnosticRequest request = {arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID,
                mode: 0x1, has_pid: true, pid: ENGINE_SPEED_PID};
        addRequest(manager, manager->obd2Bus, &request, "engine_speed",
                false, false, 1, 0, NULL, checkIgnitionStatus);

        request.pid = VEHICLE_SPEED_PID;
        addRequest(manager, manager->obd2Bus, &request, "vehicle_speed",
                false, false, 1, 0, NULL, checkIgnitionStatus);
        time::tick(&IGNITION_STATUS_TIMER);
    }
}

static void checkSupportedPids(DiagnosticsManager* manager,
        const ActiveDiagnosticRequest* request,
        const DiagnosticResponse* response,
        float parsedPayload) {
    if(manager->obd2Bus == NULL || !getConfiguration()->recurringObd2Requests) {
        return;
    }

    for(int i = 0; i < response->payload_length; i++) {
        for(int j = CHAR_BIT - 1; j >= 0; j--) {
            if(response->payload[i] >> j & 0x1) {
                uint16_t pid = response->pid + (i * CHAR_BIT) + j + 1;
                DiagnosticRequest request = {
                        arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID,
                        mode: 0x1, has_pid: true, pid: pid};
                for(size_t i = 0; i < sizeof(OBD2_PIDS) / sizeof(Obd2Pid); i++) {
                    if(OBD2_PIDS[i].pid == pid) {
                        debug("Vehicle supports PID %d", pid);
                        addRecurringRequest(manager, manager->obd2Bus, &request,
                                OBD2_PIDS[i].name, false, false, 1, 0,
                                openxc::signals::handlers::handleObd2Pid,
                                checkIgnitionStatus,
                                OBD2_PIDS[i].frequency);
                        break;
                    }
                }
            }
        }
    }
}

void openxc::diagnostics::obd2::initialize(DiagnosticsManager* manager) {
    requestIgnitionStatus(manager);
}

// * CAN traffic will eventualy stop, and we will suspend.
// * When do we wake up?
// * If normal CAN is open, bus activity will wake us up and we will resume.
// * If normal CAN is blocked, we rely on a watchdog to wake us up every 15
// seconds to start this process over again.
void openxc::diagnostics::obd2::loop(DiagnosticsManager* manager, CanBus* bus) {
    static bool ignitionWasOn = false;
    static bool pidSupportQueried = false;
    static bool sentFinalIgnitionCheck = false;

    if(!manager->initialized) {
        return;
    }

    if(time::elapsed(&IGNITION_STATUS_TIMER, false)) {
        if(sentFinalIgnitionCheck) {
            // remove all open diagnostic requests, which shuld cause the bus to go
            // silent if the car is off, and thus the VI to suspend. TODO kick off
            // watchdog! TODO when it wakes keep in a minimum run level (i.e. don't
            // turn on bluetooth) until we decide the vehicle is actually on.
            if(manager->initialized && getConfiguration()->powerManagement ==
                        PowerManagement::OBD2_IGNITION_CHECK) {
                debug("Ceasing diagnostic requests as ignition went off");
                diagnostics::reset(manager);
                manager->initialized = false;
            }
            ignitionWasOn = false;
            pidSupportQueried = false;
        } else {
            // We haven't received an ignition in 5 seconds. Either the user didn't
            // have either OBD-II request configured as a recurring request (which
            // is fine) or they did, but the car stopped responding. Kick off
            // another request to see which is true. It will take 5+5 seconds after
            // ignition off to decide we should shut down.
            requestIgnitionStatus(manager);
            sentFinalIgnitionCheck = true;
        }
    } else if(ENGINE_STARTED || VEHICLE_IN_MOTION) {
        ignitionWasOn = true;
        sentFinalIgnitionCheck = false;
        if(getConfiguration()->recurringObd2Requests && !pidSupportQueried) {
            debug("Ignition is on - querying for supported OBD-II PIDs");
            pidSupportQueried = true;
            DiagnosticRequest request = {
                    arbitration_id: OBD2_FUNCTIONAL_BROADCAST_ID,
                    mode: 0x1,
                    has_pid: true,
                    pid: 0x0};
            for(int i = 0x0; i <= 0x80; i += 0x20) {
                request.pid = i;
                addRequest(manager, bus, &request, NULL, false, false, 1, 0,
                        NULL, checkSupportedPids);
            }
        }
    }
}
<|endoftext|>


<commit_before>//#include <windows.h>
#include <iostream>

#include "global.h"
#include "Map.h"
#include "Character.h"

using namespace std;

void menu();
void game();
int text(void *);
void options();
void about();
void gamePaused();
void loadImages();
void releaseImages();

int callcontrol(void *);
int callAction(void *);
int callAction2(void *);
int callAction3(void *);

void SDL_startup();
int menuoption=0;
bool close= false;
list<int> pressing;
int first = 128;
int enabledsound=1;

#if defined(_WIN32) || defined(_WIN64)
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
#endif
#ifdef __unix__
int main (int argc, char *argv[]){
#endif
    SDL_startup();
    loadImages();

    while(!close){
        while(SDL_PollEvent(&event)) {
            menu();
            if(!close){
                switch(menuoption){
                    case 0:
                        if(enabledsound)
                           playSound("data/jingle_bells.wav", true, SDL_MIX_MAXVOLUME);
                        game();
                        break;
                    case 1:
                        options();
                        break;
                    case 2:
                        about();
                        break;
                }
            }
        }
    }
    releaseImages();
    SDL_CloseAudio();
    TTF_Quit();
    SDL_Quit(); //it finishes SDL initialisations
    return 0;
}

void menu(){
    menuoption=0;
    int sx,sy;
    sx=80;
    sy=115;
    color = {0, 0, 0};
    bool choose = false;
    while(!choose){
        if(!close){
        SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );
        displayImage(menuImage,0,0);
        drawText("Aperte B para selecionar", screen, 80, 390,color);
        while(SDL_PollEvent(&event)){
            switch(event.type){
                case SDL_KEYDOWN:
                    switch(event.key.keysym.sym){
                        case SDLK_UP:
                            if(menuoption>0)
                                menuoption=(menuoption-1)%3;
                             break;
                        case SDLK_DOWN:
                            menuoption=(menuoption+1)%3;
                            break;
                        case SDLK_b:
                            choose=true;
                             break;
                        default:
                            break;
                    }
                break;
            }
        }
        if (event.type == SDL_QUIT) {
            close=true;
            choose=true;
        }

        int colorkey = SDL_MapRGB(screen->format, 255, 0, 255);
        switch(menuoption){
            case 0:
                sy=190;
                displaySpriteImage(item_sprite, sx,sy, GRID_SIZE, 3*GRID_SIZE, GRID_SIZE, colorkey);
                break;
            case 1:
                sy=255;
                displaySpriteImage(item_sprite, sx,sy, GRID_SIZE, 3*GRID_SIZE, GRID_SIZE, colorkey);
                break;
            case 2:
                sy=320;
                displaySpriteImage(item_sprite, sx,sy, GRID_SIZE, 3*GRID_SIZE, GRID_SIZE, colorkey);
                break;
        }
        SDL_Flip(screen);
        }
    }
}

void game(){
    map.loadMap("src/map.txt");
    player = new Player(0, 0, 0, PLAYER_SPRITE_SIZE, PLAYER_SPRITE_SIZE);
    enemy = new Enemy(9, 0, 1, 0, 0, ENEMY_SPRITE_SIZE);
    enemy2 = new Enemy(7, 6, 2, 0, ENEMY_SPRITE_SIZE, ENEMY_SPRITE_SIZE);
    enemy3 = new Enemy(5, 10, 3, 0, ENEMY_SPRITE_SIZE*2, ENEMY_SPRITE_SIZE);

    while(!close) {
        while(SDL_PollEvent(&event)) {
            switch(event.type){
                case SDL_KEYDOWN:
                    if(event.key.keysym.sym == SDLK_ESCAPE) {
                        gamePaused();
                    }
                    else {
                        pressing.push_back(event.key.keysym.sym);
                    }
                    //inserir na lista event.key.keysym.sym
                    break;
                case SDL_KEYUP:
                    pressing.remove(event.key.keysym.sym);
                    //remover da lista event.key.keysym.sym
                    break;
            }
            if (event.type == SDL_QUIT) {
                close=true;
            }
        }
        player->handleControl(pressing);
        enemy->action();
        enemy2->action();
        enemy3->action();
        //threadplayer = SDL_CreateThread(callcontrol, NULL);
        //threadenemy1 = SDL_CreateThread(callAction, NULL);
        //threadenemy2 = SDL_CreateThread(callAction2, NULL);
        //threadenemy3 = SDL_CreateThread(callAction3, NULL);
        enemy->killPlayer();
        enemy2->killPlayer();
        enemy3->killPlayer();
        map.action();
        map.paint(player->life);
        map.moveAnimation();
        enemy->moveAnimation();
        enemy2->moveAnimation();
        enemy3->moveAnimation();
        player->moveAnimation();
        threadtext = SDL_CreateThread(text, NULL);
        SDL_Flip(screen);
        SDL_Delay(delay);
    }
}

int callcontrol(void * unused){
   player->handleControl(pressing);
   //cout<<"Player executou"<<endl;
}

int callAction(void * unused){
    enemy->action();
    //cout<<"Enemy 1 executou"<<endl;
}

int callAction2(void * unused){
    enemy2->action();
    //cout<<"Enemy 2 executou"<<endl;
}

int callAction3(void * unused){
    enemy3->action();
    //cout<<"Enemy 3 executou"<<endl;
}

int text(void * unused){
    color ={255,255,255};
    if(first){
        if(first>96)
            drawText("Direcionais movimentam o Bomberman...", screen, 120, 20,color);
        else if(first>64)
            drawText("aperte B para soltar Bomba...", screen, 120, 20,color);
        else if(first>32)
            drawText("ESC pausa o jogo.",screen, 120, 20,color);
        else
            drawText("Encontre a Chave!",screen, 200, 20,color);
        first--;
    }
    if(player->state==WIN){
        drawText("YOU WIN!", screen, 350, 15,color);
    }
    else if(player->state==LOSE){
        drawText("YOU LOSE!", screen, 350, 15,color);
    }
    else if(player->imuneTime && player->state!=DEAD){
        drawText("Imune por", screen, 350, 15,color);
        char * imuneTimestr = new char [32];
        drawText(to_string(player->imuneTime), screen, 430, 15,color);
    }
}

void options(){
    int sx,sy;
    sx=180;
    sy=190;
    color = {255, 255, 255};
    int colorkey = SDL_MapRGB(screen->format, 255, 0, 255);
    bool choose = false;
    SDL_Surface *optionsImage = IMG_Load("data/options.png");
    while(!choose){
        if(!close){
            SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );
            displayImage(optionsImage,0,0);
            drawText("Aperte B para selecionar", screen, 180, 390,color);
            while(SDL_PollEvent(&event)){
                switch(event.type){
                    case SDL_KEYDOWN:
                        switch(event.key.keysym.sym){
                            case SDLK_UP:
                                    enabledsound = 1;
                                    sy=190;
                                 break;
                            case SDLK_DOWN:
                                    enabledsound = 0;
                                    sy=255;
                                break;
                            case SDLK_b:
                                choose=true;
                                 break;
                            default:
                                break;
                        }
                    break;
                }
            }
            if (event.type == SDL_QUIT) {
                close=true;
                choose=true;
            }
            displaySpriteImage(item_sprite, sx,sy, GRID_SIZE, 3*GRID_SIZE, GRID_SIZE, colorkey);
            SDL_Flip(screen);
        }
    }
    SDL_FreeSurface(optionsImage);
}

void about(){
    bool done=false;
    color = {255, 255, 255};
    SDL_Surface *aboutImage = IMG_Load("data/about.png");
    while(!done){
        SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );
        displayImage(aboutImage,0,0);
        drawText("Aperte B para voltar ao menu", screen, 180, 390,color);
        SDL_Flip(screen);
        while(SDL_PollEvent(&event)){
            switch(event.type){
                case SDL_KEYDOWN:
                    switch(event.key.keysym.sym){
                        case SDLK_b:
                            done=true;
                             break;
                        default:
                            break;
                    }
                break;
            }
            if (event.type == SDL_QUIT) {
                done=true;
                close=true;
            }
        }
    }
    SDL_FreeSurface(aboutImage);
}

void gamePaused(){
    color={255,255,255};
    bool choose=false;
    drawText("GAME PAUSED", screen, 200, 10,color);
    while(!choose){
        if(!close){
            while(SDL_PollEvent(&event)){
                switch(event.type){
                    case SDL_KEYDOWN:
                        switch(event.key.keysym.sym){
                            case SDLK_ESCAPE:
                                choose=true;
                                 break;
                            default:
                                break;
                        }
                    break;
                }
                if (event.type == SDL_QUIT) {
                    choose=true;
                    close=true;
                }
            }
            SDL_Flip(screen);
        }
    }

}

void SDL_startup()
{
    if( SDL_Init(SDL_INIT_VIDEO) != 0) {
        printf("Unable to initialise SDL: %s\n", SDL_GetError());
        exit(1);
    }

    //it's used to guarantee that the SDL_Quit function is called when the application exits;
    atexit(SDL_Quit);

    screen = SDL_SetVideoMode(515, 442, 16, SDL_SWSURFACE); //width, height, bitdepth

    if(screen==NULL){
        printf("Unable to set video mode: %s\n", SDL_GetError());
        exit(1);
    }
    SDL_WM_SetCaption("Bomberman", "Bomberman"); //topTitle, iconTitle
    SDL_Surface* icon = IMG_Load("data/icon.png");
    SDL_WM_SetIcon(icon, NULL);
    if(TTF_Init() == -1) {
        printf("Unable to set font : %s\n", SDL_GetError());
        exit(1);
    }
    font = TTF_OpenFont("data/manaspc.ttf", 12);
    /* ajusta para áudio em  16-bit stereo com 22Khz */
    //audioFmt.freq = 22050;
    audioFmt.freq = SOUND_FREQUENCY;
    audioFmt.format = AUDIO_S16;
    audioFmt.channels = 1;//2
    audioFmt.samples = 1024;//512;        /* um bom valor para jogos */
    audioFmt.callback = mixaudio;
    audioFmt.userdata = NULL;
    if ( SDL_OpenAudio(&audioFmt, NULL) < 0 ) {
        fprintf(stderr, "Unable to open the audio: %s\n", SDL_GetError());
        exit(1);
    }
    SDL_PauseAudio(0);

    SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );//parado
}

void loadImages()
{
    SDL_Surface * temp;

    menuImage =IMG_Load("data/bgmenu.png");
    mapImage = IMG_Load("data/bg.png");

    temp  = SDL_LoadBMP("data/enemies_sprite.bmp");
    enemy_sprite = SDL_DisplayFormat(temp);
    SDL_FreeSurface(temp);

    temp  = SDL_LoadBMP("data/item_sprite.bmp");
    item_sprite = SDL_DisplayFormat(temp);
    SDL_FreeSurface(temp);

    temp  = SDL_LoadBMP("data/player_sprite.bmp");
    player_sprite = SDL_DisplayFormat(temp);
    SDL_FreeSurface(temp);

    temp  = SDL_LoadBMP("data/fire_sprite.bmp");
    fire_sprite = SDL_DisplayFormat(temp);
    SDL_FreeSurface(temp);
}

void releaseImages()
{
    SDL_FreeSurface(enemy_sprite);
    SDL_FreeSurface(item_sprite);
    SDL_FreeSurface(player_sprite);
    SDL_FreeSurface(fire_sprite);

    SDL_FreeSurface(menuImage);
    SDL_FreeSurface(mapImage);

}
<commit_msg>Minor changes<commit_after>//#include <windows.h>
#include <iostream>

#include "global.h"
#include "Map.h"
#include "Character.h"

using namespace std;

void menu();
void game();
int text(void *);
void options();
void about();
void gamePaused();
void loadImages();
void releaseImages();

int callcontrol(void *);
int callAction(void *);
int callAction2(void *);
int callAction3(void *);

void SDL_startup();
int menuoption=0;
bool close= false;
list<int> pressing;
int first = 128;
int enabledsound=1;

#if defined(_WIN32) || defined(_WIN64)
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
#endif
#ifdef __unix__
int main (int argc, char *argv[]){
#endif
    SDL_startup();
    loadImages();

    while(!close){
        while(SDL_PollEvent(&event)) {
            menu();
            if(!close){
                switch(menuoption){
                    case 0:
                        if(enabledsound)
                           playSound("data/jingle_bells.wav", true, SDL_MIX_MAXVOLUME);
                        game();
                        break;
                    case 1:
                        options();
                        break;
                    case 2:
                        about();
                        break;
                }
            }
        }
    }
    releaseImages();
    SDL_CloseAudio();
    TTF_Quit();
    SDL_Quit(); //it finishes SDL initialisations
    return 0;
}

void menu(){
    menuoption=0;
    int sx,sy;
    sx=80;
    sy=115;
    color = {0, 0, 0};
    bool choose = false;
    while(!choose){
        if(!close){
        SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );
        displayImage(menuImage,0,0);
        drawText("Aperte B para selecionar", screen, 80, 390,color);
        while(SDL_PollEvent(&event)){
            switch(event.type){
                case SDL_KEYDOWN:
                    switch(event.key.keysym.sym){
                        case SDLK_UP:
                            if(menuoption>0)
                                menuoption=(menuoption-1)%3;
                             break;
                        case SDLK_DOWN:
                            menuoption=(menuoption+1)%3;
                            break;
                        case SDLK_b:
                            choose=true;
                             break;
                        default:
                            break;
                    }
                break;
            }
        }
        if (event.type == SDL_QUIT) {
            close=true;
            choose=true;
        }

        int colorkey = SDL_MapRGB(screen->format, 255, 0, 255);
        switch(menuoption){
            case 0:
                sy=190;
                break;
            case 1:
                sy=255;
                break;
            case 2:
                sy=320;
                break;
        }
        displaySpriteImage(item_sprite, sx,sy, GRID_SIZE, 3*GRID_SIZE, GRID_SIZE, colorkey);
        SDL_Flip(screen);
        }
    }
}

void game(){
    map.loadMap("src/map.txt");
    player = new Player(0, 0, 0, PLAYER_SPRITE_SIZE, PLAYER_SPRITE_SIZE);
    enemy = new Enemy(9, 0, 1, 0, 0, ENEMY_SPRITE_SIZE);
    enemy2 = new Enemy(7, 6, 2, 0, ENEMY_SPRITE_SIZE, ENEMY_SPRITE_SIZE);
    enemy3 = new Enemy(5, 10, 3, 0, ENEMY_SPRITE_SIZE*2, ENEMY_SPRITE_SIZE);

    while(!close) {
        while(SDL_PollEvent(&event)) {
            switch(event.type){
                case SDL_KEYDOWN:
                    if(event.key.keysym.sym == SDLK_ESCAPE) {
                        gamePaused();
                    }
                    else {
                        pressing.push_back(event.key.keysym.sym);
                    }
                    //inserir na lista event.key.keysym.sym
                    break;
                case SDL_KEYUP:
                    pressing.remove(event.key.keysym.sym);
                    //remover da lista event.key.keysym.sym
                    break;
            }
            if (event.type == SDL_QUIT) {
                close=true;
            }
        }
        player->handleControl(pressing);
        enemy->action();
        enemy2->action();
        enemy3->action();
        //threadplayer = SDL_CreateThread(callcontrol, NULL);
        //threadenemy1 = SDL_CreateThread(callAction, NULL);
        //threadenemy2 = SDL_CreateThread(callAction2, NULL);
        //threadenemy3 = SDL_CreateThread(callAction3, NULL);
        enemy->killPlayer();
        enemy2->killPlayer();
        enemy3->killPlayer();
        map.action();
        map.paint(player->life);
        map.moveAnimation();
        enemy->moveAnimation();
        enemy2->moveAnimation();
        enemy3->moveAnimation();
        player->moveAnimation();
        threadtext = SDL_CreateThread(text, NULL);
        SDL_Flip(screen);
        SDL_Delay(delay);
    }
}

int callcontrol(void * unused){
   player->handleControl(pressing);
   //cout<<"Player executou"<<endl;
}

int callAction(void * unused){
    enemy->action();
    //cout<<"Enemy 1 executou"<<endl;
}

int callAction2(void * unused){
    enemy2->action();
    //cout<<"Enemy 2 executou"<<endl;
}

int callAction3(void * unused){
    enemy3->action();
    //cout<<"Enemy 3 executou"<<endl;
}

int text(void * unused){
    color ={255,255,255};
    if(first){
        if(first>96)
            drawText("Direcionais movimentam o Bomberman...", screen, 120, 20,color);
        else if(first>64)
            drawText("aperte B para soltar Bomba...", screen, 120, 20,color);
        else if(first>32)
            drawText("ESC pausa o jogo.",screen, 120, 20,color);
        else
            drawText("Encontre a Chave!",screen, 200, 20,color);
        first--;
    }
    if(player->state==WIN){
        drawText("YOU WIN!", screen, 350, 15,color);
    }
    else if(player->state==LOSE){
        drawText("YOU LOSE!", screen, 350, 15,color);
    }
    else if(player->imuneTime && player->state!=DEAD){
        drawText("Imune por", screen, 350, 15,color);
        char * imuneTimestr = new char [32];
        drawText(to_string(player->imuneTime), screen, 430, 15,color);
    }
}

void options(){
    int sx,sy;
    sx=180;
    sy=190;
    color = {255, 255, 255};
    int colorkey = SDL_MapRGB(screen->format, 255, 0, 255);
    bool choose = false;
    SDL_Surface *optionsImage = IMG_Load("data/options.png");
    while(!choose){
        if(!close){
            SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );
            displayImage(optionsImage,0,0);
            drawText("Aperte B para selecionar", screen, 180, 390,color);
            while(SDL_PollEvent(&event)){
                switch(event.type){
                    case SDL_KEYDOWN:
                        switch(event.key.keysym.sym){
                            case SDLK_UP:
                                    enabledsound = 1;
                                    sy=190;
                                 break;
                            case SDLK_DOWN:
                                    enabledsound = 0;
                                    sy=255;
                                break;
                            case SDLK_b:
                                choose=true;
                                 break;
                            default:
                                break;
                        }
                    break;
                }
            }
            if (event.type == SDL_QUIT) {
                close=true;
                choose=true;
            }
            displaySpriteImage(item_sprite, sx,sy, GRID_SIZE, 3*GRID_SIZE, GRID_SIZE, colorkey);
            SDL_Flip(screen);
        }
    }
    SDL_FreeSurface(optionsImage);
}

void about(){
    bool done=false;
    color = {255, 255, 255};
    SDL_Surface *aboutImage = IMG_Load("data/about.png");
    while(!done){
        SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );
        displayImage(aboutImage,0,0);
        drawText("Aperte B para voltar ao menu", screen, 180, 390,color);
        SDL_Flip(screen);
        while(SDL_PollEvent(&event)){
            switch(event.type){
                case SDL_KEYDOWN:
                    switch(event.key.keysym.sym){
                        case SDLK_b:
                            done=true;
                             break;
                        default:
                            break;
                    }
                break;
            }
            if (event.type == SDL_QUIT) {
                done=true;
                close=true;
            }
        }
    }
    SDL_FreeSurface(aboutImage);
}

void gamePaused(){
    color={255,255,255};
    bool choose=false;
    drawText("GAME PAUSED", screen, 200, 10,color);
    while(!choose){
        if(!close){
            while(SDL_PollEvent(&event)){
                switch(event.type){
                    case SDL_KEYDOWN:
                        switch(event.key.keysym.sym){
                            case SDLK_ESCAPE:
                                choose=true;
                                 break;
                            default:
                                break;
                        }
                    break;
                }
                if (event.type == SDL_QUIT) {
                    choose=true;
                    close=true;
                }
            }
            SDL_Flip(screen);
        }
    }

}

void SDL_startup()
{
    if( SDL_Init(SDL_INIT_VIDEO) != 0) {
        printf("Unable to initialise SDL: %s\n", SDL_GetError());
        exit(1);
    }

    //it's used to guarantee that the SDL_Quit function is called when the application exits;
    atexit(SDL_Quit);

    screen = SDL_SetVideoMode(515, 442, 16, SDL_SWSURFACE); //width, height, bitdepth

    if(screen==NULL){
        printf("Unable to set video mode: %s\n", SDL_GetError());
        exit(1);
    }
    SDL_WM_SetCaption("Bomberman", "Bomberman"); //topTitle, iconTitle
    SDL_Surface* icon = IMG_Load("data/icon.png");
    SDL_WM_SetIcon(icon, NULL);
    if(TTF_Init() == -1) {
        printf("Unable to set font : %s\n", SDL_GetError());
        exit(1);
    }
    font = TTF_OpenFont("data/manaspc.ttf", 12);
    /* ajusta para áudio em  16-bit stereo com 22Khz */
    //audioFmt.freq = 22050;
    audioFmt.freq = SOUND_FREQUENCY;
    audioFmt.format = AUDIO_S16;
    audioFmt.channels = 1;//2
    audioFmt.samples = 1024;//512;        /* um bom valor para jogos */
    audioFmt.callback = mixaudio;
    audioFmt.userdata = NULL;
    if ( SDL_OpenAudio(&audioFmt, NULL) < 0 ) {
        fprintf(stderr, "Unable to open the audio: %s\n", SDL_GetError());
        exit(1);
    }
    SDL_PauseAudio(0);

    SDL_FillRect( SDL_GetVideoSurface(), NULL, 0 );//parado
}

void loadImages()
{
    SDL_Surface * temp;

    menuImage =IMG_Load("data/bgmenu.png");
    mapImage = IMG_Load("data/bg.png");

    temp  = SDL_LoadBMP("data/enemies_sprite.bmp");
    enemy_sprite = SDL_DisplayFormat(temp);
    SDL_FreeSurface(temp);

    temp  = SDL_LoadBMP("data/item_sprite.bmp");
    item_sprite = SDL_DisplayFormat(temp);
    SDL_FreeSurface(temp);

    temp  = SDL_LoadBMP("data/player_sprite.bmp");
    player_sprite = SDL_DisplayFormat(temp);
    SDL_FreeSurface(temp);

    temp  = SDL_LoadBMP("data/fire_sprite.bmp");
    fire_sprite = SDL_DisplayFormat(temp);
    SDL_FreeSurface(temp);
}

void releaseImages()
{
    SDL_FreeSurface(enemy_sprite);
    SDL_FreeSurface(item_sprite);
    SDL_FreeSurface(player_sprite);
    SDL_FreeSurface(fire_sprite);

    SDL_FreeSurface(menuImage);
    SDL_FreeSurface(mapImage);

}
<|endoftext|>