<commit_before>/*
 * FPGAFitnessCalculator.cpp
 *
 *  Created on: 26/03/2015
 *      Author: Vitor
 */

#include "FPGAFitnessCalculator.h"

void FPGAFitnessCalculator::fitness(std::vector<Cromossomo>& populacao,
		int num_inputs, int le_num_inputs, int num_outputs) {
	compilar(populacao, le_num_inputs);

	carregar();

	int bauds = 115200;
	int comport_num = 6;
	char mode[10] = "8N1";
	if (RS232_OpenComport(comport_num, bauds, mode)) {
		fprintf(stderr, "Nao consegui abrir COM port %d\n", comport_num + 1);
		exit(1);
	}

	for (unsigned int i = 0; i < populacao.size(); i++) {
		RS232_SendByte(comport_num, (unsigned char) SET_CIRCUIT);
		RS232_SendByte(comport_num, (unsigned char) i);
		populacao[i].set_fitness(
				fitness_calculator(receive_data(num_inputs, comport_num)));
	}

	RS232_CloseComport(comport_num);
}

void FPGAFitnessCalculator::compilar(const std::vector<Cromossomo>& populacao,
		int le_num_inputs) {
	auto project_path = std::string("Verilog/circ_gen/");
	gerar_arquivo_logic_e(project_path + "logic_e.v", le_num_inputs);
	for (unsigned int i = 0; i < populacao.size(); i++) {
		populacao[i].criar_arquivo_verilog(
				project_path + "genetico" + to_string(i) + ".v",
				"genetico" + to_string(i));
	}
	auto system_call = std::string("quartus_map ") + project_path
			+ "circ_gen > NUL";
	if (system(system_call.c_str()) != 0) {
		std::cerr << "Erro na chamada quartus_map.\n";
		exit(1);
	}
	system_call = std::string("quartus_fit ") + project_path + "circ_gen > NUL";
	if (system(system_call.c_str()) != 0) {
		std::cerr << "Erro na chamada quartus_fit.\n";
		exit(1);
	}
	system_call = std::string("quartus_asm ") + project_path + "circ_gen > NUL";
	if (system(system_call.c_str()) != 0) {
		std::cerr << "Erro na chamada quartus_asm.\n";
		exit(1);
	}
}

void FPGAFitnessCalculator::carregar() {
	auto project_path = std::string("Verilog/circ_gen/");
	auto system_call = std::string("quartus_pgm -c USB-Blaster -m jtag -o p;")
			+ project_path + "circ_gen.sof > NUL";
	if (system(system_call.c_str()) != 0) {
		std::cerr << "Erro na chamada quartus_pgm.\n";
		exit(1);
	}
}

std::vector<std::vector<std::bitset<8>>> FPGAFitnessCalculator::receive_data(
		int num_inputs, int comport_num) {
	unsigned char buffer[4096];
	std::vector<std::vector<std::bitset<8>>> results;

	for (int i = 0; i < (int) pow(2, num_inputs); i++) {
		int total = 0;
		RS232_SendByte(comport_num, (unsigned char) SET_VALUE);
		RS232_SendByte(comport_num, (unsigned char) i);
		results.emplace_back(std::vector<std::bitset<8>>());

		Timer timeout_timer;
		timeout_timer.start(1000);
		while (total < NUM_SAMPLES) {
			timeout_timer.update();
			if (timeout_timer.isDone()) {
				std::cout << "TIMEOUT Detectado com " << total << " amostras coletadas." << std::endl;
				std::cout << "Replicando a ultima amostra." << std::endl;
				for (int j = total; j < NUM_SAMPLES; j++) {
					results[i].emplace_back(results[i][total - 1]);
				}
				break;
			}
			int n = RS232_PollComport(comport_num, buffer, 4096);
			if (n != 0) { // Se dados foram recebidos
				timeout_timer.start(1000);
			}
			for (int j = 0; j < n; j++, total++) {
				results[i].emplace_back(std::bitset<8>(buffer[j]));
			}
		}

		Sleep(100);
	}

	return results;
}

void replace(std::string& source, const std::string& to_replace,
		const std::string& replace_with) {
	source.replace(source.find(to_replace), to_replace.length(), replace_with);
}

void FPGAFitnessCalculator::cria_arquivo_genetico() {
	std::ifstream arquivo_modelo("genetico_modelo");
	std::ofstream arquivo_resultado("genetico.v");
	std::stringstream buffer;
	buffer << arquivo_modelo.rdbuf();
	auto arquivo_modelo_str = buffer.str();

	const int total_pinos = genetic_params.r * genetic_params.c
			+ genetic_params.num_in;
	const int bits_pinos = ceil(log2(total_pinos));
	const int tam_le = ceil(log2(genetic_params.num_funcs))
			+ ceil(log2(total_pinos)) * genetic_params.le_num_in;

	replace(arquivo_modelo_str, "#tam_le", to_string(tam_le - 1));
	replace(arquivo_modelo_str, "#r_x_c",
			to_string(genetic_params.r * genetic_params.c - 1));
	replace(arquivo_modelo_str, "#num_in",
			to_string(genetic_params.num_in - 1));
	replace(arquivo_modelo_str, "#num_out",
			to_string(genetic_params.num_out - 1));
	replace(arquivo_modelo_str, "#num_out",
			to_string(genetic_params.num_out - 1));
	replace(arquivo_modelo_str, "#r_x_c",
			to_string(genetic_params.r * genetic_params.c - 1));
	replace(arquivo_modelo_str, "#bits_pinos", to_string(bits_pinos - 1));
	replace(arquivo_modelo_str, "#num_pinos", to_string(total_pinos - 1));
	replace(arquivo_modelo_str, "#all_inputs_for_out", gera_string_saida());
	replace(arquivo_modelo_str, "#les", gera_les());

	arquivo_resultado << arquivo_modelo_str;
}

void FPGAFitnessCalculator::cria_arquivo_logic_e() {
	std::ifstream arquivo_modelo("logic_e_modelo");
	std::ofstream arquivo_resultado("logic_e.v");
	std::stringstream buffer;
	buffer << arquivo_modelo.rdbuf();
	auto arquivo_modelo_str = buffer.str();

	const int bits_func = ceil(log2(genetic_params.num_funcs));
	const int total_pinos = genetic_params.r * genetic_params.c
			+ genetic_params.num_in;
	const int bits_pinos = ceil(log2(total_pinos));
	const int bits_inputs = bits_pinos * genetic_params.le_num_in;

	replace(arquivo_modelo_str, "#bits_func", to_string(bits_func - 1));
	replace(arquivo_modelo_str, "#bits_inputs", to_string(bits_inputs - 1));
	replace(arquivo_modelo_str, "#total_pinos", to_string(total_pinos - 1));

	std::string output;
	for (int i = genetic_params.le_num_in; i > 0; i--) {
		const int current_max = (i * bits_pinos) - 1;
		const int current_min = current_max - (bits_pinos - 1);
		output += std::string("all_inputs[conf_ins[") + to_string(current_max)
				+ ":" + to_string(current_min) + "]]";
		if (i != 1) {
			output += ", ";
		}
	}

	replace(arquivo_modelo_str, "#all_inputs_le_out", output);

	arquivo_resultado << arquivo_modelo_str;
}

std::string FPGAFitnessCalculator::gera_string_saida() {
	std::string resultado;
	for (int i = genetic_params.num_out - 1; i >= 0; i--) {
		resultado += std::string("all_inputs[conf_outs[") + to_string(i) + "]]";
		if (i != 0) {
			resultado += ", ";
		}
	}
	return resultado;
}

std::string FPGAFitnessCalculator::gera_les() {
	std::string resultado;
	const std::string base = std::string("logic_e le#r#c(\n")
			+ std::string("\t.conf_func(conf_les[#n][#bits_top:#bits_next]),\n")
			+ std::string("\t.conf_ins(conf_les[#n][#bits_rest:0]),\n")
			+ std::string("\t.all_inputs(all_inputs),\n")
			+ std::string("\t.out(le_out[#n])\n") + ");\n\n";

	const int total_pinos = genetic_params.r * genetic_params.c
			+ genetic_params.num_in;
	const int bits_pinos = ceil(log2(total_pinos));
	const int bits_func = ceil(log2(genetic_params.num_funcs));
	const int bits_top = bits_func + genetic_params.le_num_in * bits_pinos;

	for (unsigned int j = 0; j < genetic_params.c; j++) {
		for (unsigned int i = 0; i < genetic_params.r; i++) {
			const int current = j * genetic_params.r + i;
			auto current_le = base;
			replace(current_le, "#r", to_string(i));
			replace(current_le, "#c", to_string(j));
			replace(current_le, "#n", to_string(current));
			replace(current_le, "#n", to_string(current));
			replace(current_le, "#n", to_string(current));
			replace(current_le, "#bits_top", to_string(bits_top - 1));
			replace(current_le, "#bits_next", to_string(bits_top - bits_func));
			replace(current_le, "#bits_rest", to_string((bits_top - bits_func) - 1));
			resultado += current_le;
		}
	}

	return resultado;
}
<commit_msg>Corrigida criacao da saida do logic_e.<commit_after>/*
 * FPGAFitnessCalculator.cpp
 *
 *  Created on: 26/03/2015
 *      Author: Vitor
 */

#include "FPGAFitnessCalculator.h"

void FPGAFitnessCalculator::fitness(std::vector<Cromossomo>& populacao,
		int num_inputs, int le_num_inputs, int num_outputs) {
	compilar(populacao, le_num_inputs);

	carregar();

	int bauds = 115200;
	int comport_num = 6;
	char mode[10] = "8N1";
	if (RS232_OpenComport(comport_num, bauds, mode)) {
		fprintf(stderr, "Nao consegui abrir COM port %d\n", comport_num + 1);
		exit(1);
	}

	for (unsigned int i = 0; i < populacao.size(); i++) {
		RS232_SendByte(comport_num, (unsigned char) SET_CIRCUIT);
		RS232_SendByte(comport_num, (unsigned char) i);
		populacao[i].set_fitness(
				fitness_calculator(receive_data(num_inputs, comport_num)));
	}

	RS232_CloseComport(comport_num);
}

void FPGAFitnessCalculator::compilar(const std::vector<Cromossomo>& populacao,
		int le_num_inputs) {
	auto project_path = std::string("Verilog/circ_gen/");
	gerar_arquivo_logic_e(project_path + "logic_e.v", le_num_inputs);
	for (unsigned int i = 0; i < populacao.size(); i++) {
		populacao[i].criar_arquivo_verilog(
				project_path + "genetico" + to_string(i) + ".v",
				"genetico" + to_string(i));
	}
	auto system_call = std::string("quartus_map ") + project_path
			+ "circ_gen > NUL";
	if (system(system_call.c_str()) != 0) {
		std::cerr << "Erro na chamada quartus_map.\n";
		exit(1);
	}
	system_call = std::string("quartus_fit ") + project_path + "circ_gen > NUL";
	if (system(system_call.c_str()) != 0) {
		std::cerr << "Erro na chamada quartus_fit.\n";
		exit(1);
	}
	system_call = std::string("quartus_asm ") + project_path + "circ_gen > NUL";
	if (system(system_call.c_str()) != 0) {
		std::cerr << "Erro na chamada quartus_asm.\n";
		exit(1);
	}
}

void FPGAFitnessCalculator::carregar() {
	auto project_path = std::string("Verilog/circ_gen/");
	auto system_call = std::string("quartus_pgm -c USB-Blaster -m jtag -o p;")
			+ project_path + "circ_gen.sof > NUL";
	if (system(system_call.c_str()) != 0) {
		std::cerr << "Erro na chamada quartus_pgm.\n";
		exit(1);
	}
}

std::vector<std::vector<std::bitset<8>>> FPGAFitnessCalculator::receive_data(
		int num_inputs, int comport_num) {
	unsigned char buffer[4096];
	std::vector<std::vector<std::bitset<8>>> results;

	for (int i = 0; i < (int) pow(2, num_inputs); i++) {
		int total = 0;
		RS232_SendByte(comport_num, (unsigned char) SET_VALUE);
		RS232_SendByte(comport_num, (unsigned char) i);
		results.emplace_back(std::vector<std::bitset<8>>());

		Timer timeout_timer;
		timeout_timer.start(1000);
		while (total < NUM_SAMPLES) {
			timeout_timer.update();
			if (timeout_timer.isDone()) {
				std::cout << "TIMEOUT Detectado com " << total << " amostras coletadas." << std::endl;
				std::cout << "Replicando a ultima amostra." << std::endl;
				for (int j = total; j < NUM_SAMPLES; j++) {
					results[i].emplace_back(results[i][total - 1]);
				}
				break;
			}
			int n = RS232_PollComport(comport_num, buffer, 4096);
			if (n != 0) { // Se dados foram recebidos
				timeout_timer.start(1000);
			}
			for (int j = 0; j < n; j++, total++) {
				results[i].emplace_back(std::bitset<8>(buffer[j]));
			}
		}

		Sleep(100);
	}

	return results;
}

void replace(std::string& source, const std::string& to_replace,
		const std::string& replace_with) {
	source.replace(source.find(to_replace), to_replace.length(), replace_with);
}

void FPGAFitnessCalculator::cria_arquivo_genetico() {
	std::ifstream arquivo_modelo("genetico_modelo");
	std::ofstream arquivo_resultado("genetico.v");
	std::stringstream buffer;
	buffer << arquivo_modelo.rdbuf();
	auto arquivo_modelo_str = buffer.str();

	const int total_pinos = genetic_params.r * genetic_params.c
			+ genetic_params.num_in;
	const int bits_pinos = ceil(log2(total_pinos));
	const int tam_le = ceil(log2(genetic_params.num_funcs))
			+ ceil(log2(total_pinos)) * genetic_params.le_num_in;

	replace(arquivo_modelo_str, "#tam_le", to_string(tam_le - 1));
	replace(arquivo_modelo_str, "#r_x_c",
			to_string(genetic_params.r * genetic_params.c - 1));
	replace(arquivo_modelo_str, "#num_in",
			to_string(genetic_params.num_in - 1));
	replace(arquivo_modelo_str, "#num_out",
			to_string(genetic_params.num_out - 1));
	replace(arquivo_modelo_str, "#num_out",
			to_string(genetic_params.num_out - 1));
	replace(arquivo_modelo_str, "#r_x_c",
			to_string(genetic_params.r * genetic_params.c - 1));
	replace(arquivo_modelo_str, "#bits_pinos", to_string(bits_pinos - 1));
	replace(arquivo_modelo_str, "#num_pinos", to_string(total_pinos - 1));
	replace(arquivo_modelo_str, "#all_inputs_for_out", gera_string_saida());
	replace(arquivo_modelo_str, "#les", gera_les());

	arquivo_resultado << arquivo_modelo_str;
}

void FPGAFitnessCalculator::cria_arquivo_logic_e() {
	std::ifstream arquivo_modelo("logic_e_modelo");
	std::ofstream arquivo_resultado("logic_e.v");
	std::stringstream buffer;
	buffer << arquivo_modelo.rdbuf();
	auto arquivo_modelo_str = buffer.str();

	const int bits_func = ceil(log2(genetic_params.num_funcs));
	const int bits_bits_func = log2(bits_func);
	const int total_pinos = genetic_params.r * genetic_params.c
			+ genetic_params.num_in;
	const int bits_pinos = ceil(log2(total_pinos));
	const int bits_inputs = bits_pinos * genetic_params.le_num_in;

	replace(arquivo_modelo_str, "#bits_func", to_string(bits_func - 1));
	replace(arquivo_modelo_str, "#bits_inputs", to_string(bits_inputs - 1));
	replace(arquivo_modelo_str, "#total_pinos", to_string(total_pinos - 1));

	std::string output;
	for (int i = bits_bits_func; i > 0; i--) {
		const int current_max = (i * bits_pinos) - 1;
		const int current_min = current_max - (bits_pinos - 1);
		output += std::string("all_inputs[conf_ins[") + to_string(current_max)
				+ ":" + to_string(current_min) + "]]";
		if (i != 1) {
			output += ", ";
		}
	}

	replace(arquivo_modelo_str, "#all_inputs_le_out", output);

	arquivo_resultado << arquivo_modelo_str;
}

std::string FPGAFitnessCalculator::gera_string_saida() {
	std::string resultado;
	for (int i = genetic_params.num_out - 1; i >= 0; i--) {
		resultado += std::string("all_inputs[conf_outs[") + to_string(i) + "]]";
		if (i != 0) {
			resultado += ", ";
		}
	}
	return resultado;
}

std::string FPGAFitnessCalculator::gera_les() {
	std::string resultado;
	const std::string base = std::string("logic_e le#r#c(\n")
			+ std::string("\t.conf_func(conf_les[#n][#bits_top:#bits_next]),\n")
			+ std::string("\t.conf_ins(conf_les[#n][#bits_rest:0]),\n")
			+ std::string("\t.all_inputs(all_inputs),\n")
			+ std::string("\t.out(le_out[#n])\n") + ");\n\n";

	const int total_pinos = genetic_params.r * genetic_params.c
			+ genetic_params.num_in;
	const int bits_pinos = ceil(log2(total_pinos));
	const int bits_func = ceil(log2(genetic_params.num_funcs));
	const int bits_top = bits_func + genetic_params.le_num_in * bits_pinos;

	for (unsigned int j = 0; j < genetic_params.c; j++) {
		for (unsigned int i = 0; i < genetic_params.r; i++) {
			const int current = j * genetic_params.r + i;
			auto current_le = base;
			replace(current_le, "#r", to_string(i));
			replace(current_le, "#c", to_string(j));
			replace(current_le, "#n", to_string(current));
			replace(current_le, "#n", to_string(current));
			replace(current_le, "#n", to_string(current));
			replace(current_le, "#bits_top", to_string(bits_top - 1));
			replace(current_le, "#bits_next", to_string(bits_top - bits_func));
			replace(current_le, "#bits_rest", to_string((bits_top - bits_func) - 1));
			resultado += current_le;
		}
	}

	return resultado;
}
<|endoftext|>


<commit_before>#include "math.h"
#include "stdlib.h"
#include "sys/time.h"
#include "time.h"
#include "time.h"
#include "string.h"
#include "stdio.h"
#include "stdint.h"
#include "jni.h"
#include "jni-util.h"

#ifdef WIN32
#  include "windows.h"
#else
#  undef JNIEXPORT
#  define JNIEXPORT __attribute__ ((visibility("default")))
#endif

#ifdef WIN32
#  define SO_PREFIX ""
#else
#  define SO_PREFIX "lib"
#endif

#ifdef __APPLE__
#  define SO_SUFFIX ".jnilib"
#elif defined WIN32
#  define SO_SUFFIX ".dll"
#else
#  define SO_SUFFIX ".so"
#endif

extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_getProperty(JNIEnv* e, jclass, jint code)
{
  enum {
    LineSeparator = 100,
    FileSeparator = 101,
    OsName = 102,
    JavaIoTmpdir = 103,
    UserHome = 104
  };

  switch (code) {
#ifdef WIN32
  case LineSeparator:
    return e->NewStringUTF("\r\n");

  case FileSeparator:
    return e->NewStringUTF("\\");

  case OsName:
    return e->NewStringUTF("Windows");

  case JavaIoTmpdir: {
    TCHAR buffer[MAX_PATH];
    GetTempPath(MAX_PATH, buffer);
    return e->NewStringUTF(buffer);
  }

  case UserHome: {
    LPWSTR home = _wgetenv(L"USERPROFILE");
    return e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
  }
#else
  case LineSeparator:
    return e->NewStringUTF("\n");

  case FileSeparator:
    return e->NewStringUTF("/");

  case OsName:
    return e->NewStringUTF("posix");

  case JavaIoTmpdir:
    return e->NewStringUTF("/tmp");

  case UserHome:
    return e->NewStringUTF(getenv("HOME"));
  }
#endif

  default:
    throwNew(e, "java/lang/RuntimeException", 0);
    return 0;
  }
}

extern "C" JNIEXPORT jlong JNICALL
Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass)
{
#ifdef WIN32
  static LARGE_INTEGER frequency;
  static LARGE_INTEGER time;
  static bool init = true;

  if (init) {
    QueryPerformanceFrequency(&frequency);

    if (frequency.QuadPart == 0) {
      return 0;
    }

    init = false;
  }

  QueryPerformanceCounter(&time);
  return static_cast<int64_t>
    (((static_cast<double>(time.QuadPart)) * 1000.0) /
     (static_cast<double>(frequency.QuadPart)));
#else
  timeval tv = { 0, 0 };
  gettimeofday(&tv, 0);
  return (static_cast<jlong>(tv.tv_sec) * 1000) +
    (static_cast<jlong>(tv.tv_usec) / 1000);
#endif
}

extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_doMapLibraryName(JNIEnv* e, jclass, jstring name)
{
  jstring r = 0;
  const char* chars = e->GetStringUTFChars(name, 0);
  if (chars) {
    unsigned nameLength = strlen(chars);
    unsigned size = sizeof(SO_PREFIX) + nameLength + sizeof(SO_SUFFIX);
    char buffer[size];
    snprintf(buffer, size, SO_PREFIX "%s" SO_SUFFIX, chars);
    r = e->NewStringUTF(buffer);

    e->ReleaseStringUTFChars(name, chars);
  }
  return r;
}

extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_sin(JNIEnv*, jclass, jdouble val)
{
  return sin(val);
}

extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_sqrt(JNIEnv*, jclass, jdouble val)
{
  return sqrt(val);
}

extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_pow(JNIEnv*, jclass, jdouble val, jdouble exp)
{
  return pow(val, exp);
}

extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_floor(JNIEnv*, jclass, jdouble val)
{
  return floor(val);
}

extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_ceil(JNIEnv*, jclass, jdouble val)
{
  return ceil(val);
}

extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Double_fillBufferWithDouble(JNIEnv* e, jclass, jdouble val,
					   jbyteArray buffer, jint bufferSize) {
  jboolean isCopy;
  jbyte* buf = e->GetByteArrayElements(buffer, &isCopy);
  jint count = snprintf(reinterpret_cast<char*>(buf), bufferSize, "%g", val);
  e->ReleaseByteArrayElements(buffer, buf, 0);
  return count;
}
<commit_msg>fix unix build breakage<commit_after>#include "math.h"
#include "stdlib.h"
#include "sys/time.h"
#include "time.h"
#include "time.h"
#include "string.h"
#include "stdio.h"
#include "stdint.h"
#include "jni.h"
#include "jni-util.h"

#ifdef WIN32
#  include "windows.h"
#else
#  undef JNIEXPORT
#  define JNIEXPORT __attribute__ ((visibility("default")))
#endif

#ifdef WIN32
#  define SO_PREFIX ""
#else
#  define SO_PREFIX "lib"
#endif

#ifdef __APPLE__
#  define SO_SUFFIX ".jnilib"
#elif defined WIN32
#  define SO_SUFFIX ".dll"
#else
#  define SO_SUFFIX ".so"
#endif

extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_getProperty(JNIEnv* e, jclass, jint code)
{
  enum {
    LineSeparator = 100,
    FileSeparator = 101,
    OsName = 102,
    JavaIoTmpdir = 103,
    UserHome = 104
  };

  switch (code) {
#ifdef WIN32
  case LineSeparator:
    return e->NewStringUTF("\r\n");

  case FileSeparator:
    return e->NewStringUTF("\\");

  case OsName:
    return e->NewStringUTF("Windows");

  case JavaIoTmpdir: {
    TCHAR buffer[MAX_PATH];
    GetTempPath(MAX_PATH, buffer);
    return e->NewStringUTF(buffer);
  }

  case UserHome: {
    LPWSTR home = _wgetenv(L"USERPROFILE");
    return e->NewString(reinterpret_cast<jchar*>(home), lstrlenW(home));
  }
#else
  case LineSeparator:
    return e->NewStringUTF("\n");

  case FileSeparator:
    return e->NewStringUTF("/");

  case OsName:
    return e->NewStringUTF("posix");

  case JavaIoTmpdir:
    return e->NewStringUTF("/tmp");

  case UserHome:
    return e->NewStringUTF(getenv("HOME"));
#endif

  default:
    throwNew(e, "java/lang/RuntimeException", 0);
    return 0;
  }
}

extern "C" JNIEXPORT jlong JNICALL
Java_java_lang_System_currentTimeMillis(JNIEnv*, jclass)
{
#ifdef WIN32
  static LARGE_INTEGER frequency;
  static LARGE_INTEGER time;
  static bool init = true;

  if (init) {
    QueryPerformanceFrequency(&frequency);

    if (frequency.QuadPart == 0) {
      return 0;
    }

    init = false;
  }

  QueryPerformanceCounter(&time);
  return static_cast<int64_t>
    (((static_cast<double>(time.QuadPart)) * 1000.0) /
     (static_cast<double>(frequency.QuadPart)));
#else
  timeval tv = { 0, 0 };
  gettimeofday(&tv, 0);
  return (static_cast<jlong>(tv.tv_sec) * 1000) +
    (static_cast<jlong>(tv.tv_usec) / 1000);
#endif
}

extern "C" JNIEXPORT jstring JNICALL
Java_java_lang_System_doMapLibraryName(JNIEnv* e, jclass, jstring name)
{
  jstring r = 0;
  const char* chars = e->GetStringUTFChars(name, 0);
  if (chars) {
    unsigned nameLength = strlen(chars);
    unsigned size = sizeof(SO_PREFIX) + nameLength + sizeof(SO_SUFFIX);
    char buffer[size];
    snprintf(buffer, size, SO_PREFIX "%s" SO_SUFFIX, chars);
    r = e->NewStringUTF(buffer);

    e->ReleaseStringUTFChars(name, chars);
  }
  return r;
}

extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_sin(JNIEnv*, jclass, jdouble val)
{
  return sin(val);
}

extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_sqrt(JNIEnv*, jclass, jdouble val)
{
  return sqrt(val);
}

extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_pow(JNIEnv*, jclass, jdouble val, jdouble exp)
{
  return pow(val, exp);
}

extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_floor(JNIEnv*, jclass, jdouble val)
{
  return floor(val);
}

extern "C" JNIEXPORT jdouble JNICALL
Java_java_lang_Math_ceil(JNIEnv*, jclass, jdouble val)
{
  return ceil(val);
}

extern "C" JNIEXPORT jint JNICALL
Java_java_lang_Double_fillBufferWithDouble(JNIEnv* e, jclass, jdouble val,
					   jbyteArray buffer, jint bufferSize) {
  jboolean isCopy;
  jbyte* buf = e->GetByteArrayElements(buffer, &isCopy);
  jint count = snprintf(reinterpret_cast<char*>(buf), bufferSize, "%g", val);
  e->ReleaseByteArrayElements(buffer, buf, 0);
  return count;
}
<|endoftext|>


<commit_before>#include "Arduino.h"
#include "Display.h"

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

#define SEGMENT_ON  LOW
#define SEGMENT_OFF HIGH

Display::Display() {
  pinMode(PIN_DISPLAY_SEGMENT_A, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_B, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_C, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_D, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_E, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_F, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_G, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_COLON, OUTPUT);

  pinMode(PIN_DISPLAY_DIGIT_1, OUTPUT);
  pinMode(PIN_DISPLAY_DIGIT_2, OUTPUT);
  pinMode(PIN_DISPLAY_DIGIT_3, OUTPUT);
  pinMode(PIN_DISPLAY_DIGIT_4, OUTPUT);

  digitalWrite(PIN_DISPLAY_SEGMENT_COLON, SEGMENT_OFF);
}

void Display::display_text(char* text) {
  // Serial.println(text);

  _pause_if_required();

  _display_digit(PIN_DISPLAY_DIGIT_1, text[0]);
  _display_digit(PIN_DISPLAY_DIGIT_2, text[1]);
  _display_digit(PIN_DISPLAY_DIGIT_3, text[2]);
  _display_digit(PIN_DISPLAY_DIGIT_4, text[3]);
}

void Display::display_time(int toDisplay) {

  int minutes = toDisplay / 60;
  int seconds = toDisplay % 60;
  char numbers_as_letters[] = "0123456789";

  _pause_if_required();
  _display_digit(PIN_DISPLAY_DIGIT_1, ':');
  _display_digit(PIN_DISPLAY_DIGIT_1, numbers_as_letters[minutes / 10 % 10]);
  _display_digit(PIN_DISPLAY_DIGIT_2, numbers_as_letters[minutes % 10     ]);
  _display_digit(PIN_DISPLAY_DIGIT_3, numbers_as_letters[seconds / 10     ]);
  _display_digit(PIN_DISPLAY_DIGIT_4, numbers_as_letters[seconds % 10     ]);
}

void Display::_pause_if_required() {
  // Pause if the display has been painted too recently;
  while( (millis() - _display_last_painted) < DISPLAY_LOOP_TIME) ;
  _display_last_painted = millis();
}

void Display::_display_digit(int digit, char toDisplay) {
  digitalWrite(digit, DIGIT_ON);
  _turn_segments_on(toDisplay);
  delayMicroseconds(DISPLAY_BRIGHTNESS);
  digitalWrite(digit, DIGIT_OFF);
  _turn_all_segments_off();
}

void Display::_turn_all_segments_off () {
  digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_COLON, SEGMENT_OFF);
}

// Given a number, turns on those segments
void Display::_turn_segments_on(char charToDisplay) {

  // TODO - change all these to use a byte per char and the bits in the byte to
  // represent the segments in the LED display.

  switch (charToDisplay) {

  case ' ':
  case 0: // nul
    _turn_all_segments_off();
    break;

  case '0':
  case 'O':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    break;

  case '1':
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    break;

  case '2':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '3':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '4':
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '5':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '6':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '7':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    break;

  case '8':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '9':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'B':
  case 'b':
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'i':
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    break;

  case 'E':
  case 'e':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'F':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'l':
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    break;

  case 'o':
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'R':
  case 'r':
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'Y':
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'v':
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    break;

  case ':': // Only works when PIN_DISPLAY_DIGIT_1 in active...
    digitalWrite(PIN_DISPLAY_SEGMENT_COLON, SEGMENT_ON);
    break;

  default:
    Serial.print("ERROR - can't light up segment for ascii decimal '");
    Serial.print((int)charToDisplay);
    Serial.println("'");
    break;

  }
}
<commit_msg>Tweak so that all segments stay on the same length of time.<commit_after>#include "Arduino.h"
#include "Display.h"

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

#define SEGMENT_ON  LOW
#define SEGMENT_OFF HIGH

Display::Display() {
  pinMode(PIN_DISPLAY_SEGMENT_A, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_B, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_C, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_D, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_E, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_F, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_G, OUTPUT);
  pinMode(PIN_DISPLAY_SEGMENT_COLON, OUTPUT);

  pinMode(PIN_DISPLAY_DIGIT_1, OUTPUT);
  pinMode(PIN_DISPLAY_DIGIT_2, OUTPUT);
  pinMode(PIN_DISPLAY_DIGIT_3, OUTPUT);
  pinMode(PIN_DISPLAY_DIGIT_4, OUTPUT);

  digitalWrite(PIN_DISPLAY_SEGMENT_COLON, SEGMENT_OFF);
}

void Display::display_text(char* text) {
  // Serial.println(text);

  _pause_if_required();

  _display_digit(PIN_DISPLAY_DIGIT_1, text[0]);
  _display_digit(PIN_DISPLAY_DIGIT_2, text[1]);
  _display_digit(PIN_DISPLAY_DIGIT_3, text[2]);
  _display_digit(PIN_DISPLAY_DIGIT_4, text[3]);
}

void Display::display_time(int toDisplay) {

  int minutes = toDisplay / 60;
  int seconds = toDisplay % 60;
  char numbers_as_letters[] = "0123456789";

  _pause_if_required();
  _display_digit(PIN_DISPLAY_DIGIT_1, ':');
  _display_digit(PIN_DISPLAY_DIGIT_1, numbers_as_letters[minutes / 10 % 10]);
  _display_digit(PIN_DISPLAY_DIGIT_2, numbers_as_letters[minutes % 10     ]);
  _display_digit(PIN_DISPLAY_DIGIT_3, numbers_as_letters[seconds / 10     ]);
  _display_digit(PIN_DISPLAY_DIGIT_4, numbers_as_letters[seconds % 10     ]);
}

void Display::_pause_if_required() {
  // Pause if the display has been painted too recently;
  while( (millis() - _display_last_painted) < DISPLAY_LOOP_TIME) ;
  _display_last_painted = millis();
}

void Display::_display_digit(int digit, char toDisplay) {
  _turn_segments_on(toDisplay);
  digitalWrite(digit, DIGIT_ON);
  delayMicroseconds(DISPLAY_BRIGHTNESS);
  digitalWrite(digit, DIGIT_OFF);
  _turn_all_segments_off();
}

void Display::_turn_all_segments_off () {
  digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_OFF);
  digitalWrite(PIN_DISPLAY_SEGMENT_COLON, SEGMENT_OFF);
}

// Given a number, turns on those segments
void Display::_turn_segments_on(char charToDisplay) {

  // TODO - change all these to use a byte per char and the bits in the byte to
  // represent the segments in the LED display.

  switch (charToDisplay) {

  case ' ':
  case 0: // nul
    _turn_all_segments_off();
    break;

  case '0':
  case 'O':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    break;

  case '1':
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    break;

  case '2':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '3':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '4':
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '5':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '6':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '7':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    break;

  case '8':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case '9':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'B':
  case 'b':
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'i':
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    break;

  case 'E':
  case 'e':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'F':
    digitalWrite(PIN_DISPLAY_SEGMENT_A, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'l':
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    break;

  case 'o':
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'R':
  case 'r':
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'Y':
    digitalWrite(PIN_DISPLAY_SEGMENT_B, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_F, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_G, SEGMENT_ON);
    break;

  case 'v':
    digitalWrite(PIN_DISPLAY_SEGMENT_C, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_D, SEGMENT_ON);
    digitalWrite(PIN_DISPLAY_SEGMENT_E, SEGMENT_ON);
    break;

  case ':': // Only works when PIN_DISPLAY_DIGIT_1 in active...
    digitalWrite(PIN_DISPLAY_SEGMENT_COLON, SEGMENT_ON);
    break;

  default:
    Serial.print("ERROR - can't light up segment for ascii decimal '");
    Serial.print((int)charToDisplay);
    Serial.println("'");
    break;

  }
}
<|endoftext|>


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

#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <Time.h>

#include "Nmea.h"
#include "StrUtils.h"

BWCSentence::BWCSentence() : Sentence("GP", NMEA_BWC) {
   waypointId[0] = '\0';
}

BWCSentence::~BWCSentence() {
}

char* BWCSentence::get(char str[], size_t buflen) const {
  if (str == NULL || buflen < NMEA_MAX_LENGTH)
    return NULL;

  str[0] = '$';
  str[1] = '\0';
  strcat(str, talker);
  strcat(str, tag);

  addComma(str);

  timeToString(datetime, milliseconds, strchr(str, '\0'));

  addComma(str);

  pointToString(waypoint, strchr(str, '\0'));

  addComma(str);

  if (bearingTrue >= 0)
    ftoa(bearingTrue, strchr(str, '\0'), 2);

  addComma(str);

  strcat(str, "T");

  addComma(str);

  if (bearingMagnetic >= 0)
    ftoa(bearingMagnetic, strchr(str, '\0'), 2);

  addComma(str);

  strcat(str, "M");

  addComma(str);

  if (distance >= 0)
    ftoa(distance, strchr(str, '\0'), 2);

  addComma(str);

  strcat(str, "N");

  addComma(str);

  strcat(str, waypointId);

  return addChecksum(str);
}

bool BWCSentence::set(const char nmea[]) {
  if (!valid(nmea))
    return false;

  if (!matches(nmea))
    return false;

  const char *p = nmea;

  // get time
  p = nextToken(p);

  p = parseTime(p, datetime, milliseconds);

  p = parsePoint(p, waypoint);

  if (',' != *p)
    bearingTrue = atof(p);
  else
    bearingTrue = -1;

  p = nextToken(p);
  p = nextToken(p);

  if (',' != *p)
    bearingMagnetic = atof(p);
  else
    bearingMagnetic = -1;

  p = nextToken(p);
  p = nextToken(p);

  if (',' != *p)
    distance = atof(p);
  else
    distance = -1;

  p = nextToken(p);
  p = nextToken(p);

  if (',' != *p)
    strncpy(waypointId, p, strchr(p, '*') - p);
  else
    waypointId[0] = '\0';

  return true;
}

<commit_msg>Added members initialization to BWCSentence constructor<commit_after> /*
 * BWCSentence.cpp
 *
 * (C) Copyright 2016 Pavel Bobov.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <Time.h>

#include "Nmea.h"
#include "StrUtils.h"

BWCSentence::BWCSentence() :  Sentence("GP", NMEA_BWC),
   bearingMagnetic(-1), bearingTrue(-1), milliseconds(0), distance(-1) {
   waypointId[0] = '\0';
}

BWCSentence::~BWCSentence() {
}

char* BWCSentence::get(char str[], size_t buflen) const {
  if (str == NULL || buflen < NMEA_MAX_LENGTH)
    return NULL;

  str[0] = '$';
  str[1] = '\0';
  strcat(str, talker);
  strcat(str, tag);

  addComma(str);

  timeToString(datetime, milliseconds, strchr(str, '\0'));

  addComma(str);

  pointToString(waypoint, strchr(str, '\0'));

  addComma(str);

  if (bearingTrue >= 0)
    ftoa(bearingTrue, strchr(str, '\0'), 2);

  addComma(str);

  strcat(str, "T");

  addComma(str);

  if (bearingMagnetic >= 0)
    ftoa(bearingMagnetic, strchr(str, '\0'), 2);

  addComma(str);

  strcat(str, "M");

  addComma(str);

  if (distance >= 0)
    ftoa(distance, strchr(str, '\0'), 2);

  addComma(str);

  strcat(str, "N");

  addComma(str);

  strcat(str, waypointId);

  return addChecksum(str);
}

bool BWCSentence::set(const char nmea[]) {
  if (!valid(nmea))
    return false;

  if (!matches(nmea))
    return false;

  const char *p = nmea;

  // get time
  p = nextToken(p);

  p = parseTime(p, datetime, milliseconds);

  p = parsePoint(p, waypoint);

  if (',' != *p)
    bearingTrue = atof(p);
  else
    bearingTrue = -1;

  p = nextToken(p);
  p = nextToken(p);

  if (',' != *p)
    bearingMagnetic = atof(p);
  else
    bearingMagnetic = -1;

  p = nextToken(p);
  p = nextToken(p);

  if (',' != *p)
    distance = atof(p);
  else
    distance = -1;

  p = nextToken(p);
  p = nextToken(p);

  if (',' != *p)
    strncpy(waypointId, p, strchr(p, '*') - p);
  else
    waypointId[0] = '\0';

  return true;
}

<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** ServerMediaSubsession.cpp
**
** -------------------------------------------------------------------------*/

#include <sstream>
#include <linux/videodev2.h>

// project
#include "ServerMediaSubsession.h"
#include "MJPEGVideoSource.h"
#include "DeviceSource.h"

// ---------------------------------
//   BaseServerMediaSubsession
// ---------------------------------
FramedSource* BaseServerMediaSubsession::createSource(UsageEnvironment& env, FramedSource* videoES, const std::string& format)
{
	FramedSource* source = NULL;
	if (format == "video/MP2T")
	{
		source = MPEG2TransportStreamFramer::createNew(env, videoES);
	}
	else if (format == "video/H264")
	{
		source = H264VideoStreamDiscreteFramer::createNew(env, videoES);
	}
#if LIVEMEDIA_LIBRARY_VERSION_INT > 1414454400
	else if (format == "video/H265")
	{
		source = H265VideoStreamDiscreteFramer::createNew(env, videoES);
	}
#endif
	else if (format == "video/JPEG")
	{
		source = MJPEGVideoSource::createNew(env, videoES);
	}
	else
	{
		source = videoES;
	}
	return source;
}

RTPSink*  BaseServerMediaSubsession::createSink(UsageEnvironment& env, Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, const std::string& format, V4L2DeviceSource* source)
{
	RTPSink* videoSink = NULL;
	if (format == "video/MP2T")
	{
		videoSink = SimpleRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic, 90000, "video", "MP2T", 1, True, False);
	}
	else if (format == "video/H264")
        {
		videoSink = H264VideoRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic);
	}
	else if (format == "video/VP8")
	{
		videoSink = VP8VideoRTPSink::createNew (env, rtpGroupsock,rtpPayloadTypeIfDynamic);
	}
#if LIVEMEDIA_LIBRARY_VERSION_INT > 1414454400
	else if (format == "video/VP9")
	{
		videoSink = VP9VideoRTPSink::createNew (env, rtpGroupsock,rtpPayloadTypeIfDynamic);
	}
	else if (format == "video/H265")
        {
		videoSink = H265VideoRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic);
	}
#endif
	else if (format == "video/JPEG")
	{
		videoSink = JPEGVideoRTPSink::createNew (env, rtpGroupsock);
    }
#if LIVEMEDIA_LIBRARY_VERSION_INT >= 1536192000
	else if (format =="video/RAW")
	{
		std::string sampling;
		switch (source->getCaptureFormat()) {
			case V4L2_PIX_FMT_YUV444: sampling = "YCbCr-4:4:4"; break;
			case V4L2_PIX_FMT_YUYV: sampling = "YCbCr-4:2:2"; break;
		}
		videoSink = RawVideoRTPSink::createNew(env, rtpGroupsock, rtpPayloadTypeIfDynamic, source->getHeight(), source->getWidth(), 8, sampling.c_str());
		if (videoSink) {
			source->setAuxLine(videoSink->auxSDPLine());
		}
    }
#endif
	else if (format.find("audio/L16") == 0)
	{
		std::istringstream is(format);
		std::string dummy;
		getline(is, dummy, '/');
		getline(is, dummy, '/');
		std::string sampleRate("44100");
		getline(is, sampleRate, '/');
		std::string channels("2");
		getline(is, channels);
		videoSink = SimpleRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic, std::stoi(sampleRate), "audio", "L16", std::stoi(channels), True, False);
	}
	return videoSink;
}

char const* BaseServerMediaSubsession::getAuxLine(V4L2DeviceSource* source,unsigned char rtpPayloadType)
{
	const char* auxLine = NULL;
	if (source)
	{
		std::ostringstream os;
		os << "a=fmtp:" << int(rtpPayloadType) << " ";
		os << source->getAuxLine();
		os << "\r\n";
		int width = source->getWidth();
		int height = source->getHeight();
		if ( (width > 0) && (height>0) ) {
			os << "a=x-dimensions:" << width << "," <<  height  << "\r\n";
		}
		auxLine = strdup(os.str().c_str());
	}
	return auxLine;
}

<commit_msg>replace std::stoi with atoi<commit_after>/* ---------------------------------------------------------------------------
** This software is in the public domain, furnished "as is", without technical
** support, and with no warranty, express or implied, as to its usefulness for
** any purpose.
**
** ServerMediaSubsession.cpp
**
** -------------------------------------------------------------------------*/

#include <sstream>
#include <linux/videodev2.h>

// project
#include "ServerMediaSubsession.h"
#include "MJPEGVideoSource.h"
#include "DeviceSource.h"

// ---------------------------------
//   BaseServerMediaSubsession
// ---------------------------------
FramedSource* BaseServerMediaSubsession::createSource(UsageEnvironment& env, FramedSource* videoES, const std::string& format)
{
	FramedSource* source = NULL;
	if (format == "video/MP2T")
	{
		source = MPEG2TransportStreamFramer::createNew(env, videoES);
	}
	else if (format == "video/H264")
	{
		source = H264VideoStreamDiscreteFramer::createNew(env, videoES);
	}
#if LIVEMEDIA_LIBRARY_VERSION_INT > 1414454400
	else if (format == "video/H265")
	{
		source = H265VideoStreamDiscreteFramer::createNew(env, videoES);
	}
#endif
	else if (format == "video/JPEG")
	{
		source = MJPEGVideoSource::createNew(env, videoES);
	}
	else
	{
		source = videoES;
	}
	return source;
}

RTPSink*  BaseServerMediaSubsession::createSink(UsageEnvironment& env, Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, const std::string& format, V4L2DeviceSource* source)
{
	RTPSink* videoSink = NULL;
	if (format == "video/MP2T")
	{
		videoSink = SimpleRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic, 90000, "video", "MP2T", 1, True, False);
	}
	else if (format == "video/H264")
        {
		videoSink = H264VideoRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic);
	}
	else if (format == "video/VP8")
	{
		videoSink = VP8VideoRTPSink::createNew (env, rtpGroupsock,rtpPayloadTypeIfDynamic);
	}
#if LIVEMEDIA_LIBRARY_VERSION_INT > 1414454400
	else if (format == "video/VP9")
	{
		videoSink = VP9VideoRTPSink::createNew (env, rtpGroupsock,rtpPayloadTypeIfDynamic);
	}
	else if (format == "video/H265")
        {
		videoSink = H265VideoRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic);
	}
#endif
	else if (format == "video/JPEG")
	{
		videoSink = JPEGVideoRTPSink::createNew (env, rtpGroupsock);
    }
#if LIVEMEDIA_LIBRARY_VERSION_INT >= 1536192000
	else if (format =="video/RAW")
	{
		std::string sampling;
		switch (source->getCaptureFormat()) {
			case V4L2_PIX_FMT_YUV444: sampling = "YCbCr-4:4:4"; break;
			case V4L2_PIX_FMT_YUYV: sampling = "YCbCr-4:2:2"; break;
		}
		videoSink = RawVideoRTPSink::createNew(env, rtpGroupsock, rtpPayloadTypeIfDynamic, source->getHeight(), source->getWidth(), 8, sampling.c_str());
		if (videoSink) {
			source->setAuxLine(videoSink->auxSDPLine());
		}
    }
#endif
	else if (format.find("audio/L16") == 0)
	{
		std::istringstream is(format);
		std::string dummy;
		getline(is, dummy, '/');
		getline(is, dummy, '/');
		std::string sampleRate("44100");
		getline(is, sampleRate, '/');
		std::string channels("2");
		getline(is, channels);
		videoSink = SimpleRTPSink::createNew(env, rtpGroupsock,rtpPayloadTypeIfDynamic, atoi(sampleRate), "audio", "L16", atoi(channels), True, False);
	}
	return videoSink;
}

char const* BaseServerMediaSubsession::getAuxLine(V4L2DeviceSource* source,unsigned char rtpPayloadType)
{
	const char* auxLine = NULL;
	if (source)
	{
		std::ostringstream os;
		os << "a=fmtp:" << int(rtpPayloadType) << " ";
		os << source->getAuxLine();
		os << "\r\n";
		int width = source->getWidth();
		int height = source->getHeight();
		if ( (width > 0) && (height>0) ) {
			os << "a=x-dimensions:" << width << "," <<  height  << "\r\n";
		}
		auxLine = strdup(os.str().c_str());
	}
	return auxLine;
}

<|endoftext|>


<commit_before>/*
 NUI3 - C++ cross-platform GUI framework for OpenGL based applications
 Copyright (C) 2002-2003 Sebastien Metrot

 licence: see nui3/LICENCE.TXT
 */

#include "nui.h"
#include "nuiHTMLText.h"

///////////////////////////////////////// nuiHTMLText
nuiHTMLText::nuiHTMLText(nuiHTMLNode* pNode, nuiHTMLNode* pAnchor, const nglString& rText)
: nuiHTMLItem(pNode, pAnchor, true), mText(rText), mpLayout(NULL), mpFont(NULL), mpCompositeLayout(NULL), mpNextInRun(NULL), mFirstInRun(false), mUnderline(false), mStrikeThrough(false)
{

}

nuiHTMLText::~nuiHTMLText()
{
  if (mpFont)
    mpFont->Release();
  delete mpLayout;
  delete mpCompositeLayout;
  mpNextInRun = NULL;
}

void nuiHTMLText::Draw(nuiDrawContext* pContext)
{
  if (!mFirstInRun)
    return;

  pContext->SetTextColor(mTextFgColor);
  //nuiColor mTextBgColor;
  pContext->SetFont(mpFont, false);

  if (!mpCompositeLayout)
  {
    nuiHTMLText* pIt = this;
    nglString str(nglString::Empty);
    do
    {
      if (!pIt->mFirstInRun)
        str.Add(_T(" "));
      str.Add(pIt->mText);
      pIt = pIt->mpNextInRun;
    } while (pIt);

    mpCompositeLayout = new nuiFontLayout(*mpFont, 0, 0, nuiHorizontal);
    mpCompositeLayout->SetUnderline(mUnderline);
    mpCompositeLayout->SetStrikeThrough(mStrikeThrough);
    mpCompositeLayout->Layout(str);
  }

  pContext->DrawText(0, mpCompositeLayout->GetAscender() , *mpCompositeLayout);
}

void nuiHTMLText::Layout(nuiHTMLContext& rContext)
{
  delete mpLayout;
  if (mpFont)
    mpFont->Release();
  mpFont = rContext.mpFont;
  mpFont->Acquire();

  mpLayout = new nuiFontLayout(*mpFont, 0, 0, nuiHorizontal);
  mpLayout->SetUnderline(rContext.mUnderline);
  mpLayout->SetStrikeThrough(rContext.mStrikeThrough);
  mUnderline = rContext.mUnderline;
  mStrikeThrough = rContext.mStrikeThrough;

  mpLayout->Layout(mText);
  mIdealRect = mpLayout->GetRect();
  mIdealRect.SetWidth(mIdealRect.GetWidth() + rContext.mHSpace);
  mTextFgColor = rContext.mTextFgColor;
  mTextBgColor = rContext.mTextBgColor;
  //printf("text layout done (%ls)\n", mIdealRect.GetValue().GetChars());

  delete mpCompositeLayout;
  mpCompositeLayout = NULL;
}

float nuiHTMLText::GetAscender() const
{
  return mpLayout->GetAscender();
}

float nuiHTMLText::GetDescender() const
{
  return mpLayout->GetDescender();
}

void nuiHTMLText::SetNextInRun(nuiHTMLText* pNext)
{
  mpNextInRun = pNext;
}

void nuiHTMLText::SetFirstInRun(bool set)
{
  mFirstInRun = set;
}
<commit_msg>fixed one more html layout bug<commit_after>/*
 NUI3 - C++ cross-platform GUI framework for OpenGL based applications
 Copyright (C) 2002-2003 Sebastien Metrot

 licence: see nui3/LICENCE.TXT
 */

#include "nui.h"
#include "nuiHTMLText.h"

///////////////////////////////////////// nuiHTMLText
nuiHTMLText::nuiHTMLText(nuiHTMLNode* pNode, nuiHTMLNode* pAnchor, const nglString& rText)
: nuiHTMLItem(pNode, pAnchor, true), mText(rText), mpLayout(NULL), mpFont(NULL), mpCompositeLayout(NULL), mpNextInRun(NULL), mFirstInRun(false), mUnderline(false), mStrikeThrough(false)
{

}

nuiHTMLText::~nuiHTMLText()
{
  if (mpFont)
    mpFont->Release();
  delete mpLayout;
  delete mpCompositeLayout;
  mpNextInRun = NULL;
}

void nuiHTMLText::Draw(nuiDrawContext* pContext)
{
  if (!mFirstInRun)
    return;

  pContext->SetTextColor(mTextFgColor);
  //nuiColor mTextBgColor;
  pContext->SetFont(mpFont, false);

  if (!mpCompositeLayout)
  {
    nuiHTMLText* pIt = this;
    nglString str(nglString::Empty);
    do
    {
      str.Add(pIt->mText);
      str.Add(_T(" "));
      pIt = pIt->mpNextInRun;
    } while (pIt && !pIt->mFirstInRun);

    mpCompositeLayout = new nuiFontLayout(*mpFont, 0, 0, nuiHorizontal);
    mpCompositeLayout->SetUnderline(mUnderline);
    mpCompositeLayout->SetStrikeThrough(mStrikeThrough);
    mpCompositeLayout->Layout(str);

    NGL_OUT(_T("Draw HTMLText: %ls\n"), str.GetChars());
  }

  pContext->DrawText(0, mpCompositeLayout->GetAscender() , *mpCompositeLayout);
}

void nuiHTMLText::Layout(nuiHTMLContext& rContext)
{
  delete mpLayout;
  if (mpFont)
    mpFont->Release();
  mpFont = rContext.mpFont;
  mpFont->Acquire();

  mpLayout = new nuiFontLayout(*mpFont, 0, 0, nuiHorizontal);
  mpLayout->SetUnderline(rContext.mUnderline);
  mpLayout->SetStrikeThrough(rContext.mStrikeThrough);
  mUnderline = rContext.mUnderline;
  mStrikeThrough = rContext.mStrikeThrough;

  mpLayout->Layout(mText);
  mIdealRect = mpLayout->GetRect();
  mIdealRect.SetWidth(mIdealRect.GetWidth() + rContext.mHSpace);
  mTextFgColor = rContext.mTextFgColor;
  mTextBgColor = rContext.mTextBgColor;
  //printf("text layout done (%ls)\n", mIdealRect.GetValue().GetChars());

  delete mpCompositeLayout;
  mpCompositeLayout = NULL;
}

float nuiHTMLText::GetAscender() const
{
  return mpLayout->GetAscender();
}

float nuiHTMLText::GetDescender() const
{
  return mpLayout->GetDescender();
}

void nuiHTMLText::SetNextInRun(nuiHTMLText* pNext)
{
  mpNextInRun = pNext;
}

void nuiHTMLText::SetFirstInRun(bool set)
{
  mFirstInRun = set;
}
<|endoftext|>


<commit_before>/*

  expal.cpp - Arduino Class that provides easy interfacing to a shift register along with multiplexing via registers/latches

  Copyright (C) 2015 James Vess
  All Rights Reserved

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

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

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

 =-= Notes =-=

 If you're going to increase the maximum registers from 25 ( Wow ) then you'll need to make
 sure you increase the array sizes of REGDATA and REGPINS.

*/

#include "Arduino.h"
#include "Expal.h"

// Private Functions

void Expal::blinkBit(int pin) {
  digitalWrite(pin, HIGH);
  digitalWrite(pin, LOW);
}

void Expal::blinkBitI(int pin) {
  digitalWrite(pin, LOW);
  digitalWrite(pin, HIGH);
}

void Expal::shiftOutByte(byte data) {

  // Reset the Shift Register
  blinkBitI(SHIFTREG_R);

  // Write out the bits
  int pin = 0;
  byte mask = B00000000;
  for (mask = 10000000; mask>0; mask >>= 1) { //iterate through bit mask
    if (data & mask){ // if bitwise AND resolves to true
      digitalWrite(SHIFTREG_D,HIGH); // send 1
    }
    else{ //if bitwise and resolves to false
      digitalWrite(SHIFTREG_D,LOW); // send 0
    }
    // Write the bit
    blinkBit(SHIFTREG_C);
    pin++;
  }

}

int Expal::isNumeric(int num) {
  if( num >= 0 && num <= 99999 ) {
    return 1;
  }
  return 0;
}

int Expal::isReg(int num) {
  if ( num >= 0 && num <= REGINT ) {
    return 1;
  }
  return 0;
}

// Public Functions

Expal::Expal(int shift_data, int shift_clear, int shift_clock, int registers[] ) {

  // Setup Vars
  SHIFTREG_D = shift_data;
  SHIFTREG_R = shift_clear;
  SHIFTREG_C = shift_clock;

  // Set Shiftreg Pins
  pinMode(SHIFTREG_D, OUTPUT);
  pinMode(SHIFTREG_R, OUTPUT);
  pinMode(SHIFTREG_C, OUTPUT);

  // Set the clear pin to high
  digitalWrite(SHIFTREG_R, HIGH);

  // Iterate the max register to pull all supplied registers
  for(int i = 0; i < sizeof(registers); ++i) {

    if ( !isNumeric(registers[i]) ) {
      continue;
    }
    REGDATA[REGINT] = B00000000;
    REGPINS[REGINT] = registers[i];
    pinMode(registers[i], OUTPUT);
    ++REGINT;
  }

}

void Expal::clear(int registerid) {
  if ( !isReg(registerid) ) {
    return;
  }
  // Reset the Shift Register
  blinkBit(REGPINS[registerid]);
}

void Expal::writeByte(int registerid, byte data) {
  if ( !isReg(registerid) ) {
    return;
  }
  shiftOutByte(data);
  blinkBit(REGPINS[registerid]);
  REGDATA[registerid] = data;
}

void Expal::clearAll() {
  for(int i = 0; i < REGINT; ++i) {
    clear(i);
  }
}

void Expal::setPin(int registerid, int pin, int value) {

  if ( !isReg(registerid) ) {
    return;
  }
  if ( pin < 0 || pin > 8 ) {
    return;
  }

  byte newval;

  if ( value ) {
    byte bytemask = B00000001;
    bytemask =  bytemask << pin;
    newval = REGDATA[registerid] | bytemask;
  } else {
    byte bytemask = B11111110;
    bytemask =  bytemask << pin;
    newval = REGDATA[registerid] & bytemask;
  }

  writeByte(registerid, newval);
}
<commit_msg>Wow, yet more fun. Resolved issues with endianness again<commit_after>/*

  expal.cpp - Arduino Class that provides easy interfacing to a shift register along with multiplexing via registers/latches

  Copyright (C) 2015 James Vess
  All Rights Reserved

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

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

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

 =-= Notes =-=

 If you're going to increase the maximum registers from 25 ( Wow ) then you'll need to make
 sure you increase the array sizes of REGDATA and REGPINS.

*/

#include "Arduino.h"
#include "Expal.h"

// Private Functions

void Expal::blinkBit(int pin) {
  digitalWrite(pin, HIGH);
  digitalWrite(pin, LOW);
}

void Expal::blinkBitI(int pin) {
  digitalWrite(pin, LOW);
  digitalWrite(pin, HIGH);
}

void Expal::shiftOutByte(byte data) {

  // Reset the Shift Register
  blinkBitI(SHIFTREG_R);

  // Write out the bits
  int pin = 0;
  byte mask = B00000000;
  for (mask = 00000001; mask>0; mask <<= 1) { //iterate through bit mask
    if (data & mask){ // if bitwise AND resolves to true
      digitalWrite(SHIFTREG_D,HIGH); // send 1
    }
    else{ //if bitwise and resolves to false
      digitalWrite(SHIFTREG_D,LOW); // send 0
    }
    // Write the bit
    blinkBit(SHIFTREG_C);
    pin++;
  }

}

int Expal::isNumeric(int num) {
  if( num >= 0 && num <= 99999 ) {
    return 1;
  }
  return 0;
}

int Expal::isReg(int num) {
  if ( num >= 0 && num <= REGINT ) {
    return 1;
  }
  return 0;
}

// Public Functions

Expal::Expal(int shift_data, int shift_clear, int shift_clock, int registers[] ) {

  // Setup Vars
  SHIFTREG_D = shift_data;
  SHIFTREG_R = shift_clear;
  SHIFTREG_C = shift_clock;

  // Set Shiftreg Pins
  pinMode(SHIFTREG_D, OUTPUT);
  pinMode(SHIFTREG_R, OUTPUT);
  pinMode(SHIFTREG_C, OUTPUT);

  // Set the clear pin to high
  digitalWrite(SHIFTREG_R, HIGH);

  // Iterate the max register to pull all supplied registers
  for(int i = 0; i < sizeof(registers); ++i) {

    if ( !isNumeric(registers[i]) ) {
      continue;
    }
    REGDATA[REGINT] = B00000000;
    REGPINS[REGINT] = registers[i];
    pinMode(registers[i], OUTPUT);
    ++REGINT;
  }

}

void Expal::clear(int registerid) {
  if ( !isReg(registerid) ) {
    return;
  }
  // Reset the Shift Register
  blinkBit(REGPINS[registerid]);
}

void Expal::writeByte(int registerid, byte data) {
  if ( !isReg(registerid) ) {
    return;
  }
  shiftOutByte(data);
  blinkBit(REGPINS[registerid]);
  REGDATA[registerid] = data;
}

void Expal::clearAll() {
  for(int i = 0; i < REGINT; ++i) {
    clear(i);
  }
}

void Expal::setPin(int registerid, int pin, int value) {

  if ( !isReg(registerid) ) {
    return;
  }
  if ( pin < 0 || pin > 8 ) {
    return;
  }

  byte newval;
  byte bytemask = B10000000;
  bytemask =  bytemask >> pin;
  if ( value ) {
    newval = REGDATA[registerid] | bytemask;
  } else {
    bytemask = ~bytemask;
    newval = REGDATA[registerid] & bytemask;
  }

  writeByte(registerid, newval);
}
<|endoftext|>


<commit_before>// Copyright 2015 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 "services/asset_bundle/asset_bundle_impl.h"

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "mojo/common/data_pipe_utils.h"

namespace mojo {
namespace asset_bundle {
namespace {

void Ignored(bool) {
}

}  // namespace

AssetBundleImpl::AssetBundleImpl(InterfaceRequest<AssetBundle> request,
                                 scoped_ptr<base::ScopedTempDir> asset_dir,
                                 scoped_refptr<base::TaskRunner> worker_runner)
    : binding_(this, request.Pass()),
      asset_dir_(asset_dir.Pass()),
      worker_runner_(worker_runner.Pass()) {
}

AssetBundleImpl::~AssetBundleImpl() {
}

void AssetBundleImpl::GetAsStream(
    const String& asset_name,
    const Callback<void(ScopedDataPipeConsumerHandle)>& callback) {
  DataPipe pipe;
  callback.Run(pipe.consumer_handle.Pass());

  std::string asset_string = asset_name.To<std::string>();
  base::FilePath asset_path =
      base::MakeAbsoluteFilePath(asset_dir_->path().Append(asset_string));

  if (!asset_dir_->path().IsParent(asset_path)) {
    LOG(WARNING) << "Requested asset '" << asset_string << "' does not exist.";
    return;
  }

  common::CopyFromFile(asset_path, pipe.producer_handle.Pass(), 0,
                       worker_runner_.get(), base::Bind(&Ignored));
}

}  // namespace asset_bundle
}  // namespace mojo
<commit_msg>Fix IsParent() check in asset_bundle<commit_after>// Copyright 2015 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 "services/asset_bundle/asset_bundle_impl.h"

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "mojo/common/data_pipe_utils.h"

namespace mojo {
namespace asset_bundle {
namespace {

void Ignored(bool) {
}

}  // namespace

AssetBundleImpl::AssetBundleImpl(InterfaceRequest<AssetBundle> request,
                                 scoped_ptr<base::ScopedTempDir> asset_dir,
                                 scoped_refptr<base::TaskRunner> worker_runner)
    : binding_(this, request.Pass()),
      asset_dir_(asset_dir.Pass()),
      worker_runner_(worker_runner.Pass()) {
}

AssetBundleImpl::~AssetBundleImpl() {
}

void AssetBundleImpl::GetAsStream(
    const String& asset_name,
    const Callback<void(ScopedDataPipeConsumerHandle)>& callback) {
  DataPipe pipe;
  callback.Run(pipe.consumer_handle.Pass());

  std::string asset_string = asset_name.To<std::string>();
  base::FilePath asset_path =
      base::MakeAbsoluteFilePath(asset_dir_->path().Append(asset_string));

  auto asset_dir_abs = base::MakeAbsoluteFilePath(asset_dir_->path());
  if (!asset_dir_abs.IsParent(asset_path)) {
    LOG(WARNING) << "Requested asset '" << asset_string << "' does not exist.";
    return;
  }

  common::CopyFromFile(asset_path, pipe.producer_handle.Pass(), 0,
                       worker_runner_.get(), base::Bind(&Ignored));
}

}  // namespace asset_bundle
}  // namespace mojo
<|endoftext|>


<commit_before>#include "aboutdialog.h"
#include "ui_aboutdialog.h"

#include "clientmodel.h"
#include "clientversion.h"

// Copyright year (2009-this)
// Todo: update this when changing our copyright comments in the source
const int ABOUTDIALOG_COPYRIGHT_YEAR = 2013;

AboutDialog::AboutDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AboutDialog)
{
    ui->setupUi(this);

    // Set current copyright year
    ui->copyrightLabel->setText(tr("Copyright") + QString(" © 2009-%1 ").arg(COPYRIGHT_YEAR) + tr("The Bitcoin developers") + QString("
") + tr("Copyright") + QString(" © ") + tr("2011-%1 The mtgoxcoin developers").arg(ABOUTDIALOG_COPYRIGHT_YEAR));
}

void AboutDialog::setModel(ClientModel *model)
{
    if(model)
    {
        ui->versionLabel->setText(model->formatFullVersion());
    }
}

AboutDialog::~AboutDialog()
{
    delete ui;
}

void AboutDialog::on_buttonBox_accepted()
{
    close();
}
<commit_msg>added copyrights in about qt<commit_after>#include "aboutdialog.h"
#include "ui_aboutdialog.h"

#include "clientmodel.h"
#include "clientversion.h"

// Copyright year (2009-this)
// Todo: update this when changing our copyright comments in the source
const int ABOUTDIALOG_COPYRIGHT_YEAR = 2013;

AboutDialog::AboutDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AboutDialog)
{
    ui->setupUi(this);

    // Set current copyright year
    ui->copyrightLabel->setText(tr("Copyright") + QString(" © 2009-%1 ").arg(COPYRIGHT_YEAR) + tr("The Bitcoin developers") + QString("
") + tr("Copyright") + QString(" © ") + tr("2011-%1 The litecoin developers") + QString("
") + tr("Copyright") + QString(" © ") + tr("2014 The mtgoxcoin developers").arg(ABOUTDIALOG_COPYRIGHT_YEAR));
}

void AboutDialog::setModel(ClientModel *model)
{
    if(model)
    {
        ui->versionLabel->setText(model->formatFullVersion());
    }
}

AboutDialog::~AboutDialog()
{
    delete ui;
}

void AboutDialog::on_buttonBox_accepted()
{
    close();
}
<|endoftext|>


<commit_before>// Copyright (c) 2011-2015 The Bitcoin Core developers
// Copyright (c) 2015-2017 The Bitcoin Unlimited developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "clientmodel.h"

#include "bantablemodel.h"
#include "guiconstants.h"
#include "peertablemodel.h"

#include "chainparams.h"
#include "checkpoints.h"
#include "clientversion.h"
#include "net.h"
#include "txmempool.h"
#include "ui_interface.h"
#include "util.h"

#include <stdint.h>

#include <QDebug>
#include <QTimer>

class CBlockIndex;

static const int64_t nClientStartupTime = GetTime();
static int64_t nLastBlockTipUpdateNotification = 0;

ClientModel::ClientModel(OptionsModel *optionsModel, UnlimitedModel *ul, QObject *parent)
    : QObject(parent), unlimitedModel(ul), optionsModel(optionsModel), peerTableModel(0), banTableModel(0),
      pollTimer1(0), pollTimer2(0)
{
    peerTableModel = new PeerTableModel(this);
    banTableModel = new BanTableModel(this);

    pollTimer1 = new QTimer(this);
    connect(pollTimer1, SIGNAL(timeout()), this, SLOT(updateTimer1()));
    pollTimer1->start(MODEL_UPDATE_DELAY1);

    pollTimer2 = new QTimer(this);
    connect(pollTimer2, SIGNAL(timeout()), this, SLOT(updateTimer2()));
    pollTimer2->start(MODEL_UPDATE_DELAY2);

    subscribeToCoreSignals();
}

ClientModel::~ClientModel() { unsubscribeFromCoreSignals(); }
int ClientModel::getNumConnections(unsigned int flags) const
{
    LOCK(cs_vNodes);
    if (flags == CONNECTIONS_ALL) // Shortcut if we want total
        return vNodes.size();

    int nNum = 0;
    BOOST_FOREACH (const CNode *pnode, vNodes)
        if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT))
            nNum++;

    return nNum;
}

int ClientModel::getNumBlocks() const
{
    LOCK(cs_main);
    return chainActive.Height();
}

quint64 ClientModel::getTotalBytesRecv() const { return CNode::GetTotalBytesRecv(); }
quint64 ClientModel::getTotalBytesSent() const { return CNode::GetTotalBytesSent(); }
QDateTime ClientModel::getLastBlockDate() const
{
    LOCK(cs_main);

    if (chainActive.Tip())
        return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());

    return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
}

long ClientModel::getMempoolSize() const { return mempool.size(); }
long ClientModel::getOrphanPoolSize() const
{
    LOCK(cs_orphancache);
    return mapOrphanTransactions.size();
}

size_t ClientModel::getMempoolDynamicUsage() const { return mempool.DynamicMemoryUsage(); }
// BU: begin
double ClientModel::getTransactionsPerSecond() const { return mempool.TransactionsPerSecond(); }
// BU: end

double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const
{
    CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn);
    if (!tip)
    {
        LOCK(cs_main);
        tip = chainActive.Tip();
    }
    return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), tip);
}

void ClientModel::updateTimer1()
{
    // no locking required at this point
    // the following calls will acquire the required lock
    Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage());
    Q_EMIT transactionsPerSecondChanged(getTransactionsPerSecond());
}

void ClientModel::updateTimer2()
{
    // no locking required at this point
    // the following calls will aquire the required lock
    Q_EMIT orphanPoolSizeChanged(getOrphanPoolSize());
    Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent());

    uiInterface.BannedListChanged();
}

void ClientModel::updateNumConnections(int numConnections) { Q_EMIT numConnectionsChanged(numConnections); }
void ClientModel::updateAlert() { Q_EMIT alertsChanged(getStatusBarWarnings()); }
bool ClientModel::inInitialBlockDownload() const { return IsInitialBlockDownload(); }
enum BlockSource ClientModel::getBlockSource() const
{
    if (fReindex)
        return BLOCK_SOURCE_REINDEX;
    else if (fImporting)
        return BLOCK_SOURCE_DISK;
    else if (getNumConnections() > 0)
        return BLOCK_SOURCE_NETWORK;

    return BLOCK_SOURCE_NONE;
}

QString ClientModel::getStatusBarWarnings() const { return QString::fromStdString(GetWarnings("gui")); }
OptionsModel *ClientModel::getOptionsModel() { return optionsModel; }
PeerTableModel *ClientModel::getPeerTableModel() { return peerTableModel; }
BanTableModel *ClientModel::getBanTableModel() { return banTableModel; }
QString ClientModel::formatFullVersion() const { return QString::fromStdString(FormatFullVersion()); }
QString ClientModel::formatSubVersion() const { return QString::fromStdString(strSubVersion); }
bool ClientModel::isReleaseVersion() const { return CLIENT_VERSION_IS_RELEASE; }
QString ClientModel::clientName() const { return QString::fromStdString(CLIENT_NAME); }
QString ClientModel::formatClientStartupTime() const
{
    QString time_format = "MMM  d yyyy, HH:mm:ss";
    return QDateTime::fromTime_t(nClientStartupTime).toString(time_format);
}

QString ClientModel::dataDir() const { return QString::fromStdString(GetDataDir().string()); }
void ClientModel::updateBanlist() { banTableModel->refresh(); }
// Handlers for core signals
static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
{
    // emits signal "showProgress"
    QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
        Q_ARG(QString, QString::fromStdString(title)), Q_ARG(int, nProgress));
}

static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
{
    // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
    QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection, Q_ARG(int, newNumConnections));
}

static void NotifyAlertChanged(ClientModel *clientmodel)
{
    qDebug() << "NotifyAlertChanged";
    QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
}

static void BannedListChanged(ClientModel *clientmodel)
{
    qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
    QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
}

static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex)
{
    // lock free async UI updates in case we have a new block tip
    // during initial sync, only update the UI if the last update
    // was > 250ms (MODEL_UPDATE_DELAY1) ago
    int64_t now = 0;
    if (initialSync)
        now = GetTimeMillis();

    // if we are in-sync, update the UI regardless of last update time
    if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY1)
    {
        // pass a async signal to the UI thread
        QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection, Q_ARG(int, pIndex->nHeight),
            Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
            Q_ARG(double, clientmodel->getVerificationProgress(pIndex)));
        nLastBlockTipUpdateNotification = now;
    }
}

void ClientModel::subscribeToCoreSignals()
{
    // Connect signals to client
    uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
    uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
    uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2));
}

void ClientModel::unsubscribeFromCoreSignals()
{
    // Disconnect signals from client
    uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
    uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
    uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2));
}
<commit_msg>Fix for #846: remove extra space between year and month in debug ui.<commit_after>// Copyright (c) 2011-2015 The Bitcoin Core developers
// Copyright (c) 2015-2017 The Bitcoin Unlimited developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "clientmodel.h"

#include "bantablemodel.h"
#include "guiconstants.h"
#include "peertablemodel.h"

#include "chainparams.h"
#include "checkpoints.h"
#include "clientversion.h"
#include "net.h"
#include "txmempool.h"
#include "ui_interface.h"
#include "util.h"

#include <stdint.h>

#include <QDebug>
#include <QTimer>

class CBlockIndex;

static const int64_t nClientStartupTime = GetTime();
static int64_t nLastBlockTipUpdateNotification = 0;

ClientModel::ClientModel(OptionsModel *optionsModel, UnlimitedModel *ul, QObject *parent)
    : QObject(parent), unlimitedModel(ul), optionsModel(optionsModel), peerTableModel(0), banTableModel(0),
      pollTimer1(0), pollTimer2(0)
{
    peerTableModel = new PeerTableModel(this);
    banTableModel = new BanTableModel(this);

    pollTimer1 = new QTimer(this);
    connect(pollTimer1, SIGNAL(timeout()), this, SLOT(updateTimer1()));
    pollTimer1->start(MODEL_UPDATE_DELAY1);

    pollTimer2 = new QTimer(this);
    connect(pollTimer2, SIGNAL(timeout()), this, SLOT(updateTimer2()));
    pollTimer2->start(MODEL_UPDATE_DELAY2);

    subscribeToCoreSignals();
}

ClientModel::~ClientModel() { unsubscribeFromCoreSignals(); }
int ClientModel::getNumConnections(unsigned int flags) const
{
    LOCK(cs_vNodes);
    if (flags == CONNECTIONS_ALL) // Shortcut if we want total
        return vNodes.size();

    int nNum = 0;
    BOOST_FOREACH (const CNode *pnode, vNodes)
        if (flags & (pnode->fInbound ? CONNECTIONS_IN : CONNECTIONS_OUT))
            nNum++;

    return nNum;
}

int ClientModel::getNumBlocks() const
{
    LOCK(cs_main);
    return chainActive.Height();
}

quint64 ClientModel::getTotalBytesRecv() const { return CNode::GetTotalBytesRecv(); }
quint64 ClientModel::getTotalBytesSent() const { return CNode::GetTotalBytesSent(); }
QDateTime ClientModel::getLastBlockDate() const
{
    LOCK(cs_main);

    if (chainActive.Tip())
        return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());

    return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
}

long ClientModel::getMempoolSize() const { return mempool.size(); }
long ClientModel::getOrphanPoolSize() const
{
    LOCK(cs_orphancache);
    return mapOrphanTransactions.size();
}

size_t ClientModel::getMempoolDynamicUsage() const { return mempool.DynamicMemoryUsage(); }
// BU: begin
double ClientModel::getTransactionsPerSecond() const { return mempool.TransactionsPerSecond(); }
// BU: end

double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const
{
    CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn);
    if (!tip)
    {
        LOCK(cs_main);
        tip = chainActive.Tip();
    }
    return Checkpoints::GuessVerificationProgress(Params().Checkpoints(), tip);
}

void ClientModel::updateTimer1()
{
    // no locking required at this point
    // the following calls will acquire the required lock
    Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage());
    Q_EMIT transactionsPerSecondChanged(getTransactionsPerSecond());
}

void ClientModel::updateTimer2()
{
    // no locking required at this point
    // the following calls will aquire the required lock
    Q_EMIT orphanPoolSizeChanged(getOrphanPoolSize());
    Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent());

    uiInterface.BannedListChanged();
}

void ClientModel::updateNumConnections(int numConnections) { Q_EMIT numConnectionsChanged(numConnections); }
void ClientModel::updateAlert() { Q_EMIT alertsChanged(getStatusBarWarnings()); }
bool ClientModel::inInitialBlockDownload() const { return IsInitialBlockDownload(); }
enum BlockSource ClientModel::getBlockSource() const
{
    if (fReindex)
        return BLOCK_SOURCE_REINDEX;
    else if (fImporting)
        return BLOCK_SOURCE_DISK;
    else if (getNumConnections() > 0)
        return BLOCK_SOURCE_NETWORK;

    return BLOCK_SOURCE_NONE;
}

QString ClientModel::getStatusBarWarnings() const { return QString::fromStdString(GetWarnings("gui")); }
OptionsModel *ClientModel::getOptionsModel() { return optionsModel; }
PeerTableModel *ClientModel::getPeerTableModel() { return peerTableModel; }
BanTableModel *ClientModel::getBanTableModel() { return banTableModel; }
QString ClientModel::formatFullVersion() const { return QString::fromStdString(FormatFullVersion()); }
QString ClientModel::formatSubVersion() const { return QString::fromStdString(strSubVersion); }
bool ClientModel::isReleaseVersion() const { return CLIENT_VERSION_IS_RELEASE; }
QString ClientModel::clientName() const { return QString::fromStdString(CLIENT_NAME); }
QString ClientModel::formatClientStartupTime() const
{
    QString time_format = "MMM d yyyy, HH:mm:ss";
    return QDateTime::fromTime_t(nClientStartupTime).toString(time_format);
}

QString ClientModel::dataDir() const { return QString::fromStdString(GetDataDir().string()); }
void ClientModel::updateBanlist() { banTableModel->refresh(); }
// Handlers for core signals
static void ShowProgress(ClientModel *clientmodel, const std::string &title, int nProgress)
{
    // emits signal "showProgress"
    QMetaObject::invokeMethod(clientmodel, "showProgress", Qt::QueuedConnection,
        Q_ARG(QString, QString::fromStdString(title)), Q_ARG(int, nProgress));
}

static void NotifyNumConnectionsChanged(ClientModel *clientmodel, int newNumConnections)
{
    // Too noisy: qDebug() << "NotifyNumConnectionsChanged: " + QString::number(newNumConnections);
    QMetaObject::invokeMethod(clientmodel, "updateNumConnections", Qt::QueuedConnection, Q_ARG(int, newNumConnections));
}

static void NotifyAlertChanged(ClientModel *clientmodel)
{
    qDebug() << "NotifyAlertChanged";
    QMetaObject::invokeMethod(clientmodel, "updateAlert", Qt::QueuedConnection);
}

static void BannedListChanged(ClientModel *clientmodel)
{
    qDebug() << QString("%1: Requesting update for peer banlist").arg(__func__);
    QMetaObject::invokeMethod(clientmodel, "updateBanlist", Qt::QueuedConnection);
}

static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CBlockIndex *pIndex)
{
    // lock free async UI updates in case we have a new block tip
    // during initial sync, only update the UI if the last update
    // was > 250ms (MODEL_UPDATE_DELAY1) ago
    int64_t now = 0;
    if (initialSync)
        now = GetTimeMillis();

    // if we are in-sync, update the UI regardless of last update time
    if (!initialSync || now - nLastBlockTipUpdateNotification > MODEL_UPDATE_DELAY1)
    {
        // pass a async signal to the UI thread
        QMetaObject::invokeMethod(clientmodel, "numBlocksChanged", Qt::QueuedConnection, Q_ARG(int, pIndex->nHeight),
            Q_ARG(QDateTime, QDateTime::fromTime_t(pIndex->GetBlockTime())),
            Q_ARG(double, clientmodel->getVerificationProgress(pIndex)));
        nLastBlockTipUpdateNotification = now;
    }
}

void ClientModel::subscribeToCoreSignals()
{
    // Connect signals to client
    uiInterface.ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
    uiInterface.NotifyNumConnectionsChanged.connect(boost::bind(NotifyNumConnectionsChanged, this, _1));
    uiInterface.NotifyAlertChanged.connect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2));
}

void ClientModel::unsubscribeFromCoreSignals()
{
    // Disconnect signals from client
    uiInterface.ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
    uiInterface.NotifyNumConnectionsChanged.disconnect(boost::bind(NotifyNumConnectionsChanged, this, _1));
    uiInterface.NotifyAlertChanged.disconnect(boost::bind(NotifyAlertChanged, this));
    uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this));
    uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2));
}
<|endoftext|>