<commit_before>/*
 * Copyright 2012-2013 BrewPi/Elco Jacobs.
 *
 * This file is part of BrewPi.
 *
 * BrewPi is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * BrewPi is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with BrewPi.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Brewpi.h"
#include "RotaryEncoder.h"

#include "Pins.h"
#include <limits.h>
#include "Ticks.h"
#include "Display.h"
#include "Brewpi.h"
#include "TempControl.h"

RotaryEncoder rotaryEncoder;

int16_t RotaryEncoder::maximum;
int16_t RotaryEncoder::minimum;
volatile int16_t RotaryEncoder::steps;
volatile bool RotaryEncoder::pushFlag;

#if BREWPI_STATIC_CONFIG!=BREWPI_SHIELD_DIY
	#if rotarySwitchPin != 7
		#error Review interrupt vectors when not using pin 7 for menu push
	#endif
	#if rotaryAPin != 8
		#error Review interrupt vectors when not using pin 8 for menu right
	#endif
	#if rotaryBPin != 9
		#error Review interrupt vectors when not using pin 9 for menu left
	#endif
#else
	#if rotarySwitchPin != 0
	#error Review interrupt vectors when not using pin 0 for menu push
	#endif
	#if rotaryAPin != 2
	#error Review interrupt vectors when not using pin 2 for menu right
	#endif
	#if rotaryBPin != 1
	#error Review interrupt vectors when not using pin 1 for menu left
	#endif

#endif

// Implementation based on work of Ben Buxton:

/* Rotary encoder handler for arduino. v1.1
 *
 * Copyright 2011 Ben Buxton. Licenced under the GNU GPL Version 3.
 * Contact: bb@cactii.net
 *
 * A typical mechanical rotary encoder emits a two bit gray code
 * on 3 output pins. Every step in the output (often accompanied
 * by a physical 'click') generates a specific sequence of output
 * codes on the pins.
 *
 * There are 3 pins used for the rotary encoding - one common and
 * two 'bit' pins.
 *
 * The following is the typical sequence of code on the output when
 * moving from one step to the next:
 *
 *   Position   Bit1   Bit2
 *   ----------------------
 *     Step1     0      0
 *      1/4      1      0
 *      1/2      1      1
 *      3/4      0      1
 *     Step2     0      0
 *
 * From this table, we can see that when moving from one 'click' to
 * the next, there are 4 changes in the output code.
 *
 * - From an initial 0 - 0, Bit1 goes high, Bit0 stays low.
 * - Then both bits are high, halfway through the step.
 * - Then Bit1 goes low, but Bit2 stays high.
 * - Finally at the end of the step, both bits return to 0.
 *
 * Detecting the direction is easy - the table simply goes in the other
 * direction (read up instead of down).
 *
 * To decode this, we use a simple state machine. Every time the output
 * code changes, it follows state, until finally a full steps worth of
 * code is received (in the correct order). At the final 0-0, it returns
 * a value indicating a step in one direction or the other.
 *
 * It's also possible to use 'half-step' mode. This just emits an event
 * at both the 0-0 and 1-1 positions. This might be useful for some
 * encoders where you want to detect all positions.
 *
 * If an invalid state happens (for example we go from '0-1' straight
 * to '1-0'), the state machine resets to the start until 0-0 and the
 * next valid codes occur.
 *
 * The biggest advantage of using a state machine over other algorithms
 * is that this has inherent debounce built in. Other algorithms emit spurious
 * output with switch bounce, but this one will simply flip between
 * sub-states until the bounce settles, then continue along the state
 * machine.
 * A side effect of debounce is that fast rotations can cause steps to
 * be skipped. By not requiring debounce, fast rotations can be accurately
 * measured.
 * Another advantage is the ability to properly handle bad state, such
 * as due to EMI, etc.
 * It is also a lot simpler than others - a static state table and less
 * than 10 lines of logic.
 */

/*
 * The below state table has, for each state (row), the new state
 * to set based on the next encoder output. From left to right in,
 * the table, the encoder outputs are 00, 01, 10, 11, and the value
 * in that position is the new state to set.
 */

#define R_START 0x0
// #define HALF_STEP

// Use the half-step state table (emits a code at 00 and 11)
#define HS_R_CCW_BEGIN 0x1
#define HS_R_CW_BEGIN 0x2
#define HS_R_START_M 0x3
#define HS_R_CW_BEGIN_M 0x4
#define HS_R_CCW_BEGIN_M 0x5
const uint8_t PROGMEM hs_ttable[7][4] = {
	// R_START (00)
	{HS_R_START_M,            HS_R_CW_BEGIN,     HS_R_CCW_BEGIN,  R_START},
	// HS_R_CCW_BEGIN
	{HS_R_START_M | DIR_CCW, R_START,        HS_R_CCW_BEGIN,  R_START},
	// HS_R_CW_BEGIN
	{HS_R_START_M | DIR_CW,  HS_R_CW_BEGIN,     R_START,      R_START},
	// HS_R_START_M (11)
	{HS_R_START_M,            HS_R_CCW_BEGIN_M,  HS_R_CW_BEGIN_M, R_START},
	// HS_R_CW_BEGIN_M
	{HS_R_START_M,            HS_R_START_M,      HS_R_CW_BEGIN_M, R_START | DIR_CW},
	// HS_R_CCW_BEGIN_M
	{HS_R_START_M,            HS_R_CCW_BEGIN_M,  HS_R_START_M,    R_START | DIR_CCW},
	{R_START, R_START, R_START, R_START}
};

// Use the full-step state table (emits a code at 00 only)
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6

const uint8_t PROGMEM ttable[7][4] = {
	// R_START
	{R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
	// R_CW_FINAL
	{R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
	// R_CW_BEGIN
	{R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
	// R_CW_NEXT
	{R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
	// R_CCW_BEGIN
	{R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
	// R_CCW_FINAL
	{R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
	// R_CCW_NEXT
	{R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};

#if BREWPI_ROTARY_ENCODER
#include "util/atomic.h"
#include "FastDigitalPin.h"

#if BREWPI_STATIC_CONFIG==BREWPI_SHIELD_DIY
#if !defined(USBCON)
	#error DIY shield ONLY compatible with Leonardo board.
#endif

ISR(INT2_vect) {
	rotaryEncoder.setPushed();
}
#elif defined(USBCON)  // Arduino Leonardo
ISR(INT6_vect){
	rotaryEncoder.setPushed();
}
#else  // Arduino UNO or older
ISR(PCINT2_vect){
	if(!bitRead(PIND,7)){
		// high to low transition
		rotaryEncoder.setPushed();
	}
}
#endif

#if BREWPI_STATIC_CONFIG!=BREWPI_SHIELD_DIY
	ISR(PCINT0_vect){
		rotaryEncoder.process();
	}
#else
ISR(INT3_vect) {
	rotaryEncoder.process();
}
ISR(INT1_vect) {
	rotaryEncoder.process();
}
#endif

void RotaryEncoder::process(void){
	static uint8_t state=R_START;
	// Grab state of input pins.
	#if defined(USBCON)
	// Arduino Leonardo
	uint8_t currPinA = !bitRead(PINB,4);
	uint8_t currPinB = !bitRead(PINB,5);
	#else
	uint8_t currPinA = bitRead(PINB,0);
	uint8_t currPinB = bitRead(PINB,1);
	#endif

	unsigned char pinstate = (currPinB << 1) | currPinA;

	// Determine new state from the pins and state table.
	if(tempControl.cc.rotaryHalfSteps){
		state = pgm_read_byte(&(hs_ttable[state & 0xf][pinstate]));
	}
	else{
		state = pgm_read_byte(&(ttable[state & 0xf][pinstate]));
	}

	// Get emit bits, ie the generated event.

	uint8_t dir = state & 0x30;

	if(dir){
		int16_t s = steps;	// steps is volatile - save a copy here to avoid multiple fetches
		s = (dir==DIR_CW) ? s+1 : s-1;
		if (s > maximum)
			s = minimum;
		else if (s < minimum)
			s = maximum;
		steps = s;
		display.resetBacklightTimer();
	}
}
#endif  // BREWPI_ROTARY_ENCODER

void RotaryEncoder::setPushed(void){
	pushFlag = true;
	display.resetBacklightTimer();
}

void RotaryEncoder::init(void){
#if BREWPI_ROTARY_ENCODER
	#if(USE_INTERNAL_PULL_UP_RESISTORS)
	fastPinMode(rotaryAPin, INPUT_PULLUP);
	fastPinMode(rotaryBPin, INPUT_PULLUP);
	fastPinMode(rotarySwitchPin, INPUT_PULLUP);
	#else
	fastPinMode(rotaryAPin, INPUT);
	fastPinMode(rotaryBPin, INPUT);
	fastPinMode(rotarySwitchPin, INPUT);
	#endif

	#if BREWPI_STATIC_CONFIG==BREWPI_SHIELD_DIY
		EICRA |= (1<<ISC21) | (1<<ISC10) | (1<<ISC30);; // any logical change for encoder pins, falling edge for switch
		EIMSK |= (1<<INT2) | (1<<INT1) | (1<<INT3); // enable interrupts for each pin
	#elif defined(USBCON) // Arduino Leonardo
		// falling edge interrupt for switch on INT6
		EICRB |= (1<<ISC61) | (0<<ISC60);
		// enable interrupt for INT6
		EIMSK |= (1<<INT6);
		// enable pin change interrupts
		PCICR |= (1<<PCIE0);
		// enable pin change interrupt on Arduino pin 8 and 9
		PCMSK0 |= (1<<PCINT5) | (1<<PCINT4);
	#else // Arduino UNO
		// enable PCINT0 (PCINT0 and PCINT1 pin) and PCINT2 vector (PCINT23 pin)
		PCICR |= (1<<PCIE2) | (1<<PCIE0);
		// enable mask bits for PCINT0 and PCINT1
		PCMSK0 |= (1<<PCINT0) | (1<<PCINT1);
		// enable mask bit for PCINT23
		PCMSK2 |= (1<<PCINT23);
	#endif
#endif
}

void RotaryEncoder::setRange(int16_t start, int16_t minVal, int16_t maxVal){
#if BREWPI_ROTARY_ENCODER
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
		// this part cannot be interrupted
		// Multiply by two to convert to half steps
		steps = start;
		minimum = minVal;
		maximum = maxVal; // +1 to make sure that one step is still two half steps at overflow
	}
#endif
}

bool RotaryEncoder::changed(void){
	// returns one if the value changed since the last call of changed.
	static int16_t prevValue = 0;
	int16_t r = read();
	if(r != prevValue){
		prevValue = r;
		return 1;
	}
	if(pushFlag == true){
		return 1;
	}
	return 0;
}

int16_t RotaryEncoder::read(void){
#if BREWPI_ROTARY_ENCODER
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
		return steps;
	}
#endif
	return 0;
}
<commit_msg>Changed how internal pullup resistors are set for rotary encoder<commit_after>/*
 * Copyright 2012-2013 BrewPi/Elco Jacobs.
 *
 * This file is part of BrewPi.
 *
 * BrewPi is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * BrewPi is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with BrewPi.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Brewpi.h"
#include "RotaryEncoder.h"

#include "Pins.h"
#include <limits.h>
#include "Ticks.h"
#include "Display.h"
#include "Brewpi.h"
#include "TempControl.h"

RotaryEncoder rotaryEncoder;

int16_t RotaryEncoder::maximum;
int16_t RotaryEncoder::minimum;
volatile int16_t RotaryEncoder::steps;
volatile bool RotaryEncoder::pushFlag;

#if BREWPI_STATIC_CONFIG!=BREWPI_SHIELD_DIY
	#if rotarySwitchPin != 7
		#error Review interrupt vectors when not using pin 7 for menu push
	#endif
	#if rotaryAPin != 8
		#error Review interrupt vectors when not using pin 8 for menu right
	#endif
	#if rotaryBPin != 9
		#error Review interrupt vectors when not using pin 9 for menu left
	#endif
#else
	#if rotarySwitchPin != 0
	#error Review interrupt vectors when not using pin 0 for menu push
	#endif
	#if rotaryAPin != 2
	#error Review interrupt vectors when not using pin 2 for menu right
	#endif
	#if rotaryBPin != 1
	#error Review interrupt vectors when not using pin 1 for menu left
	#endif

#endif

// Implementation based on work of Ben Buxton:

/* Rotary encoder handler for arduino. v1.1
 *
 * Copyright 2011 Ben Buxton. Licenced under the GNU GPL Version 3.
 * Contact: bb@cactii.net
 *
 * A typical mechanical rotary encoder emits a two bit gray code
 * on 3 output pins. Every step in the output (often accompanied
 * by a physical 'click') generates a specific sequence of output
 * codes on the pins.
 *
 * There are 3 pins used for the rotary encoding - one common and
 * two 'bit' pins.
 *
 * The following is the typical sequence of code on the output when
 * moving from one step to the next:
 *
 *   Position   Bit1   Bit2
 *   ----------------------
 *     Step1     0      0
 *      1/4      1      0
 *      1/2      1      1
 *      3/4      0      1
 *     Step2     0      0
 *
 * From this table, we can see that when moving from one 'click' to
 * the next, there are 4 changes in the output code.
 *
 * - From an initial 0 - 0, Bit1 goes high, Bit0 stays low.
 * - Then both bits are high, halfway through the step.
 * - Then Bit1 goes low, but Bit2 stays high.
 * - Finally at the end of the step, both bits return to 0.
 *
 * Detecting the direction is easy - the table simply goes in the other
 * direction (read up instead of down).
 *
 * To decode this, we use a simple state machine. Every time the output
 * code changes, it follows state, until finally a full steps worth of
 * code is received (in the correct order). At the final 0-0, it returns
 * a value indicating a step in one direction or the other.
 *
 * It's also possible to use 'half-step' mode. This just emits an event
 * at both the 0-0 and 1-1 positions. This might be useful for some
 * encoders where you want to detect all positions.
 *
 * If an invalid state happens (for example we go from '0-1' straight
 * to '1-0'), the state machine resets to the start until 0-0 and the
 * next valid codes occur.
 *
 * The biggest advantage of using a state machine over other algorithms
 * is that this has inherent debounce built in. Other algorithms emit spurious
 * output with switch bounce, but this one will simply flip between
 * sub-states until the bounce settles, then continue along the state
 * machine.
 * A side effect of debounce is that fast rotations can cause steps to
 * be skipped. By not requiring debounce, fast rotations can be accurately
 * measured.
 * Another advantage is the ability to properly handle bad state, such
 * as due to EMI, etc.
 * It is also a lot simpler than others - a static state table and less
 * than 10 lines of logic.
 */

/*
 * The below state table has, for each state (row), the new state
 * to set based on the next encoder output. From left to right in,
 * the table, the encoder outputs are 00, 01, 10, 11, and the value
 * in that position is the new state to set.
 */

#define R_START 0x0
// #define HALF_STEP

// Use the half-step state table (emits a code at 00 and 11)
#define HS_R_CCW_BEGIN 0x1
#define HS_R_CW_BEGIN 0x2
#define HS_R_START_M 0x3
#define HS_R_CW_BEGIN_M 0x4
#define HS_R_CCW_BEGIN_M 0x5
const uint8_t PROGMEM hs_ttable[7][4] = {
	// R_START (00)
	{HS_R_START_M,            HS_R_CW_BEGIN,     HS_R_CCW_BEGIN,  R_START},
	// HS_R_CCW_BEGIN
	{HS_R_START_M | DIR_CCW, R_START,        HS_R_CCW_BEGIN,  R_START},
	// HS_R_CW_BEGIN
	{HS_R_START_M | DIR_CW,  HS_R_CW_BEGIN,     R_START,      R_START},
	// HS_R_START_M (11)
	{HS_R_START_M,            HS_R_CCW_BEGIN_M,  HS_R_CW_BEGIN_M, R_START},
	// HS_R_CW_BEGIN_M
	{HS_R_START_M,            HS_R_START_M,      HS_R_CW_BEGIN_M, R_START | DIR_CW},
	// HS_R_CCW_BEGIN_M
	{HS_R_START_M,            HS_R_CCW_BEGIN_M,  HS_R_START_M,    R_START | DIR_CCW},
	{R_START, R_START, R_START, R_START}
};

// Use the full-step state table (emits a code at 00 only)
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6

const uint8_t PROGMEM ttable[7][4] = {
	// R_START
	{R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
	// R_CW_FINAL
	{R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
	// R_CW_BEGIN
	{R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
	// R_CW_NEXT
	{R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
	// R_CCW_BEGIN
	{R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
	// R_CCW_FINAL
	{R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
	// R_CCW_NEXT
	{R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};

#if BREWPI_ROTARY_ENCODER
#include "util/atomic.h"
#include "FastDigitalPin.h"

#if BREWPI_STATIC_CONFIG==BREWPI_SHIELD_DIY
#if !defined(USBCON)
	#error DIY shield ONLY compatible with Leonardo board.
#endif

ISR(INT2_vect) {
	rotaryEncoder.setPushed();
}
#elif defined(USBCON)  // Arduino Leonardo
ISR(INT6_vect){
	rotaryEncoder.setPushed();
}
#else  // Arduino UNO or older
ISR(PCINT2_vect){
	if(!bitRead(PIND,7)){
		// high to low transition
		rotaryEncoder.setPushed();
	}
}
#endif

#if BREWPI_STATIC_CONFIG!=BREWPI_SHIELD_DIY
	ISR(PCINT0_vect){
		rotaryEncoder.process();
	}
#else
ISR(INT3_vect) {
	rotaryEncoder.process();
}
ISR(INT1_vect) {
	rotaryEncoder.process();
}
#endif

void RotaryEncoder::process(void){
	static uint8_t state=R_START;
	// Grab state of input pins.
	#if defined(USBCON)
	// Arduino Leonardo
	uint8_t currPinA = !bitRead(PINB,4);
	uint8_t currPinB = !bitRead(PINB,5);
	#else
	uint8_t currPinA = bitRead(PINB,0);
	uint8_t currPinB = bitRead(PINB,1);
	#endif

	unsigned char pinstate = (currPinB << 1) | currPinA;

	// Determine new state from the pins and state table.
	if(tempControl.cc.rotaryHalfSteps){
		state = pgm_read_byte(&(hs_ttable[state & 0xf][pinstate]));
	}
	else{
		state = pgm_read_byte(&(ttable[state & 0xf][pinstate]));
	}

	// Get emit bits, ie the generated event.

	uint8_t dir = state & 0x30;

	if(dir){
		int16_t s = steps;	// steps is volatile - save a copy here to avoid multiple fetches
		s = (dir==DIR_CW) ? s+1 : s-1;
		if (s > maximum)
			s = minimum;
		else if (s < minimum)
			s = maximum;
		steps = s;
		display.resetBacklightTimer();
	}
}
#endif  // BREWPI_ROTARY_ENCODER

void RotaryEncoder::setPushed(void){
	pushFlag = true;
	display.resetBacklightTimer();
}

void RotaryEncoder::init(void){
#if BREWPI_ROTARY_ENCODER
	#define BREWPI_INPUT_PULLUP (USE_INTERNAL_PULL_UP_RESISTORS ? INPUT_PULLUP : INPUT)
	fastPinMode(rotaryAPin, BREWPI_INPUT_PULLUP);
	fastPinMode(rotaryBPin, BREWPI_INPUT_PULLUP);
	fastPinMode(rotarySwitchPin, BREWPI_INPUT_PULLUP);

	#if BREWPI_STATIC_CONFIG==BREWPI_SHIELD_DIY
		EICRA |= (1<<ISC21) | (1<<ISC10) | (1<<ISC30);; // any logical change for encoder pins, falling edge for switch
		EIMSK |= (1<<INT2) | (1<<INT1) | (1<<INT3); // enable interrupts for each pin
	#elif defined(USBCON) // Arduino Leonardo
		// falling edge interrupt for switch on INT6
		EICRB |= (1<<ISC61) | (0<<ISC60);
		// enable interrupt for INT6
		EIMSK |= (1<<INT6);
		// enable pin change interrupts
		PCICR |= (1<<PCIE0);
		// enable pin change interrupt on Arduino pin 8 and 9
		PCMSK0 |= (1<<PCINT5) | (1<<PCINT4);
	#else // Arduino UNO
		// enable PCINT0 (PCINT0 and PCINT1 pin) and PCINT2 vector (PCINT23 pin)
		PCICR |= (1<<PCIE2) | (1<<PCIE0);
		// enable mask bits for PCINT0 and PCINT1
		PCMSK0 |= (1<<PCINT0) | (1<<PCINT1);
		// enable mask bit for PCINT23
		PCMSK2 |= (1<<PCINT23);
	#endif
#endif
}

void RotaryEncoder::setRange(int16_t start, int16_t minVal, int16_t maxVal){
#if BREWPI_ROTARY_ENCODER
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
		// this part cannot be interrupted
		// Multiply by two to convert to half steps
		steps = start;
		minimum = minVal;
		maximum = maxVal; // +1 to make sure that one step is still two half steps at overflow
	}
#endif
}

bool RotaryEncoder::changed(void){
	// returns one if the value changed since the last call of changed.
	static int16_t prevValue = 0;
	int16_t r = read();
	if(r != prevValue){
		prevValue = r;
		return 1;
	}
	if(pushFlag == true){
		return 1;
	}
	return 0;
}

int16_t RotaryEncoder::read(void){
#if BREWPI_ROTARY_ENCODER
	ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
		return steps;
	}
#endif
	return 0;
}
<|endoftext|>


<commit_before>#include "task_mnist.h"
#include "common/logger.h"
#include "common/math.hpp"
#include "common/cast.hpp"
#include "loss.h"
#include <fstream>

namespace ncv
{
        mnist_task_t::mnist_task_t(const string_t& configuration)
                :       task_t(configuration)
        {
        }

        bool mnist_task_t::load(const string_t& dir)
        {
                const string_t test_ifile = dir + "/t10k-images-idx3-ubyte";
                const string_t test_gfile = dir + "/t10k-labels-idx1-ubyte";
                const size_t n_test_samples = 10000;

                const string_t train_ifile = dir + "/train-images-idx3-ubyte";
                const string_t train_gfile = dir + "/train-labels-idx1-ubyte";
                const size_t n_train_samples = 60000;

                clear_memory(n_train_samples + n_test_samples);

                return  load(train_ifile, train_gfile, protocol::train) == n_train_samples &&
                        load(test_ifile, test_gfile, protocol::test) == n_test_samples;
        }

        size_t mnist_task_t::load(const string_t& ifile, const string_t& gfile, protocol p)
        {
                std::vector<char> vbuffer(n_rows() * n_cols());
                char* buffer = vbuffer.data();
                char label[2];

                log_info() << "MNIST: loading file <" << ifile << "> ...";

                // image and label data streams
                std::ifstream fimage(ifile.c_str(), std::ios::in | std::ios::binary);
                std::ifstream flabel(gfile.c_str(), std::ios::in | std::ios::binary);

                if (!fimage.is_open() || !flabel.is_open())
                {
                        log_error() << "MNIST: failed to load files!";
                        return 0;
                }

                // read headers
                fimage.read(buffer, 16);
                flabel.read(buffer, 8);

                // load annotations and images
                size_t cnt = 0;
                while ( flabel.read(label, 1) &&
                        fimage.read(buffer, vbuffer.size()))
                {
                        const size_t ilabel = math::cast<size_t>(label[0]);
                        if (ilabel >= n_outputs())
                        {
                                continue;
                        }

                        sample_t sample(m_images.size(), sample_region(0, 0));
                        sample.m_label = "digit" + text::to_string(ilabel);
                        sample.m_target = ncv::class_target(ilabel, n_outputs());
                        sample.m_fold = { 0, p };
                        m_samples.push_back(sample);

                        image_t image;
                        image.load_luma(buffer, n_rows(), n_cols());
                        m_images.push_back(image);

                        ++ cnt;
                }

                log_info() << "MNIST: loaded " << cnt << " samples.";

                return cnt;
        }
}
<commit_msg>use original .gz files to load the MNIST task<commit_after>#include "task_mnist.h"
#include "common/logger.h"
#include "common/math.hpp"
#include "common/cast.hpp"
#include "common/io_arch.h"
#include "common/io_stream.h"
#include "loss.h"

namespace ncv
{
        mnist_task_t::mnist_task_t(const string_t& configuration)
                :       task_t(configuration)
        {
        }

        bool mnist_task_t::load(const string_t& dir)
        {
                const string_t test_ifile = dir + "/t10k-images-idx3-ubyte.gz";
                const string_t test_gfile = dir + "/t10k-labels-idx1-ubyte.gz";
                const size_t n_test_samples = 10000;

                const string_t train_ifile = dir + "/train-images-idx3-ubyte.gz";
                const string_t train_gfile = dir + "/train-labels-idx1-ubyte.gz";
                const size_t n_train_samples = 60000;

                clear_memory(n_train_samples + n_test_samples);

                return  load(train_ifile, train_gfile, protocol::train) == n_train_samples &&
                        load(test_ifile, test_gfile, protocol::test) == n_test_samples;
        }

        size_t mnist_task_t::load(const string_t& ifile, const string_t& gfile, protocol p)
        {
                size_t icnt = 0, isize = m_images.size();
                size_t gcnt = 0;

                std::vector<char> vbuffer(n_rows() * n_cols());
                char* buffer = vbuffer.data();
                char label[2];

                // load image file
                const auto iop = [&] (const string_t&, const io::data_t& data)
                {
                        io::stream_t stream(data);

                        stream.read(buffer, 16);
                        while (stream.read(buffer, vbuffer.size()) && stream.gcount() == vbuffer.size())
                        {
                                image_t image;
                                image.load_luma(buffer, n_rows(), n_cols());
                                m_images.push_back(image);

                                ++ icnt;
                        }
                };

                log_info() << "MNIST: loading file <" << ifile << "> ...";
                if (!io::decode(ifile, "MNIST: ", iop))
                {
                        log_error() << "MNIST: failed to load file <" << ifile << ">!";
                        return 0;
                }

                // load ground truth file
                const auto gop = [&] (const string_t&, const io::data_t& data)
                {
                        io::stream_t stream(data);

                        stream.read(buffer, 8);
                        while (stream.read(label, 1) && stream.gcount() == 1)
                        {
                                const size_t ilabel = math::cast<size_t>(label[0]);

                                sample_t sample(isize, sample_region(0, 0));
                                sample.m_label = "digit" + text::to_string(ilabel);
                                sample.m_target = ncv::class_target(ilabel, n_outputs());
                                sample.m_fold = { 0, p };
                                m_samples.push_back(sample);

                                ++ gcnt;
                                ++ isize;
                        }
                };

                log_info() << "MNIST: loading file <" << gfile << "> ...";
                if (!io::decode(gfile, "MNIST: ", gop))
                {
                        log_error() << "MNIST: failed to load file <" << gfile << ">!";
                        return 0;
                }

                // OK
                log_info() << "MNIST: loaded " << icnt << "/" << gcnt << " samples.";
                return std::max(icnt, gcnt);
        }
}
<|endoftext|>


<commit_before>//===- UnifyFunctionExitNodes.cpp - Make all functions have a single exit -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass is used to ensure that functions have at most one return
// instruction in them.  Additionally, it keeps track of which node is the new
// exit node of the CFG.  If there are no exit nodes in the CFG, the getExitNode
// method will return a null pointer.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/BasicBlock.h"
#include "llvm/Function.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/Type.h"
using namespace llvm;

static RegisterOpt<UnifyFunctionExitNodes>
X("mergereturn", "Unify function exit nodes");

Pass *llvm::createUnifyFunctionExitNodesPass() {
  return new UnifyFunctionExitNodes();
}

void UnifyFunctionExitNodes::getAnalysisUsage(AnalysisUsage &AU) const{
  // We preserve the non-critical-edgeness property
  AU.addPreservedID(BreakCriticalEdgesID);
}

// UnifyAllExitNodes - Unify all exit nodes of the CFG by creating a new
// BasicBlock, and converting all returns to unconditional branches to this
// new basic block.  The singular exit node is returned.
//
// If there are no return stmts in the Function, a null pointer is returned.
//
bool UnifyFunctionExitNodes::runOnFunction(Function &F) {
  // Loop over all of the blocks in a function, tracking all of the blocks that
  // return.
  //
  std::vector<BasicBlock*> ReturningBlocks;
  std::vector<BasicBlock*> UnwindingBlocks;
  for(Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
    if (isa<ReturnInst>(I->getTerminator()))
      ReturningBlocks.push_back(I);
    else if (isa<UnwindInst>(I->getTerminator()))
      UnwindingBlocks.push_back(I);

  // Handle unwinding blocks first...
  if (UnwindingBlocks.empty()) {
    UnwindBlock = 0;
  } else if (UnwindingBlocks.size() == 1) {
    UnwindBlock = UnwindingBlocks.front();
  } else {
    UnwindBlock = new BasicBlock("UnifiedUnwindBlock", &F);
    new UnwindInst(UnwindBlock);

    for (std::vector<BasicBlock*>::iterator I = UnwindingBlocks.begin(),
           E = UnwindingBlocks.end(); I != E; ++I) {
      BasicBlock *BB = *I;
      BB->getInstList().pop_back();  // Remove the return insn
      new BranchInst(UnwindBlock, 0, 0, BB);
    }
  }

  // Now handle return blocks...
  if (ReturningBlocks.empty()) {
    ReturnBlock = 0;
    return false;                          // No blocks return
  } else if (ReturningBlocks.size() == 1) {
    ReturnBlock = ReturningBlocks.front(); // Already has a single return block
    return false;
  }

  // Otherwise, we need to insert a new basic block into the function, add a PHI
  // node (if the function returns a value), and convert all of the return
  // instructions into unconditional branches.
  //
  BasicBlock *NewRetBlock = new BasicBlock("UnifiedReturnBlock", &F);

  PHINode *PN = 0;
  if (F.getReturnType() != Type::VoidTy) {
    // If the function doesn't return void... add a PHI node to the block...
    PN = new PHINode(F.getReturnType(), "UnifiedRetVal");
    NewRetBlock->getInstList().push_back(PN);
  }
  new ReturnInst(PN, NewRetBlock);

  // Loop over all of the blocks, replacing the return instruction with an
  // unconditional branch.
  //
  for (std::vector<BasicBlock*>::iterator I = ReturningBlocks.begin(),
         E = ReturningBlocks.end(); I != E; ++I) {
    BasicBlock *BB = *I;

    // Add an incoming element to the PHI node for every return instruction that
    // is merging into this new block...
    if (PN) PN->addIncoming(BB->getTerminator()->getOperand(0), BB);

    BB->getInstList().pop_back();  // Remove the return insn
    new BranchInst(NewRetBlock, BB);
  }
  ReturnBlock = NewRetBlock;
  return true;
}
<commit_msg>Use one destination constructor for the unconditional branch.<commit_after>//===- UnifyFunctionExitNodes.cpp - Make all functions have a single exit -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass is used to ensure that functions have at most one return
// instruction in them.  Additionally, it keeps track of which node is the new
// exit node of the CFG.  If there are no exit nodes in the CFG, the getExitNode
// method will return a null pointer.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/BasicBlock.h"
#include "llvm/Function.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/Type.h"
using namespace llvm;

static RegisterOpt<UnifyFunctionExitNodes>
X("mergereturn", "Unify function exit nodes");

Pass *llvm::createUnifyFunctionExitNodesPass() {
  return new UnifyFunctionExitNodes();
}

void UnifyFunctionExitNodes::getAnalysisUsage(AnalysisUsage &AU) const{
  // We preserve the non-critical-edgeness property
  AU.addPreservedID(BreakCriticalEdgesID);
}

// UnifyAllExitNodes - Unify all exit nodes of the CFG by creating a new
// BasicBlock, and converting all returns to unconditional branches to this
// new basic block.  The singular exit node is returned.
//
// If there are no return stmts in the Function, a null pointer is returned.
//
bool UnifyFunctionExitNodes::runOnFunction(Function &F) {
  // Loop over all of the blocks in a function, tracking all of the blocks that
  // return.
  //
  std::vector<BasicBlock*> ReturningBlocks;
  std::vector<BasicBlock*> UnwindingBlocks;
  for(Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
    if (isa<ReturnInst>(I->getTerminator()))
      ReturningBlocks.push_back(I);
    else if (isa<UnwindInst>(I->getTerminator()))
      UnwindingBlocks.push_back(I);

  // Handle unwinding blocks first...
  if (UnwindingBlocks.empty()) {
    UnwindBlock = 0;
  } else if (UnwindingBlocks.size() == 1) {
    UnwindBlock = UnwindingBlocks.front();
  } else {
    UnwindBlock = new BasicBlock("UnifiedUnwindBlock", &F);
    new UnwindInst(UnwindBlock);

    for (std::vector<BasicBlock*>::iterator I = UnwindingBlocks.begin(),
           E = UnwindingBlocks.end(); I != E; ++I) {
      BasicBlock *BB = *I;
      BB->getInstList().pop_back();  // Remove the return insn
      new BranchInst(UnwindBlock, BB);
    }
  }

  // Now handle return blocks...
  if (ReturningBlocks.empty()) {
    ReturnBlock = 0;
    return false;                          // No blocks return
  } else if (ReturningBlocks.size() == 1) {
    ReturnBlock = ReturningBlocks.front(); // Already has a single return block
    return false;
  }

  // Otherwise, we need to insert a new basic block into the function, add a PHI
  // node (if the function returns a value), and convert all of the return
  // instructions into unconditional branches.
  //
  BasicBlock *NewRetBlock = new BasicBlock("UnifiedReturnBlock", &F);

  PHINode *PN = 0;
  if (F.getReturnType() != Type::VoidTy) {
    // If the function doesn't return void... add a PHI node to the block...
    PN = new PHINode(F.getReturnType(), "UnifiedRetVal");
    NewRetBlock->getInstList().push_back(PN);
  }
  new ReturnInst(PN, NewRetBlock);

  // Loop over all of the blocks, replacing the return instruction with an
  // unconditional branch.
  //
  for (std::vector<BasicBlock*>::iterator I = ReturningBlocks.begin(),
         E = ReturningBlocks.end(); I != E; ++I) {
    BasicBlock *BB = *I;

    // Add an incoming element to the PHI node for every return instruction that
    // is merging into this new block...
    if (PN) PN->addIncoming(BB->getTerminator()->getOperand(0), BB);

    BB->getInstList().pop_back();  // Remove the return insn
    new BranchInst(NewRetBlock, BB);
  }
  ReturnBlock = NewRetBlock;
  return true;
}
<|endoftext|>


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

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <qt/optionsdialog.h>
#include <qt/forms/ui_optionsdialog.h>

#include <qt/bitcoinunits.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>

#include <interfaces/node.h>
#include <validation.h> // for DEFAULT_SCRIPTCHECK_THREADS and MAX_SCRIPTCHECK_THREADS
#include <netbase.h>
#include <txdb.h> // for -dbcache defaults

#include <QDataWidgetMapper>
#include <QDir>
#include <QIntValidator>
#include <QLocale>
#include <QMessageBox>
#include <QTimer>

OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
    QDialog(parent),
    ui(new Ui::OptionsDialog),
    model(0),
    mapper(0)
{
    ui->setupUi(this);

    /* Main elements init */
    ui->databaseCache->setMinimum(nMinDbCache);
    ui->databaseCache->setMaximum(nMaxDbCache);
    static const uint64_t GiB = 1024 * 1024 * 1024;
    static const uint64_t nMinDiskSpace = MIN_DISK_SPACE_FOR_BLOCK_FILES / GiB +
                          (MIN_DISK_SPACE_FOR_BLOCK_FILES % GiB) ? 1 : 0;
    ui->pruneSize->setMinimum(nMinDiskSpace);
    ui->threadsScriptVerif->setMinimum(-GetNumCores());
    ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS);
    ui->pruneWarning->setVisible(false);
    ui->pruneWarning->setStyleSheet("QLabel { color: red; }");

    ui->pruneSize->setEnabled(false);
    connect(ui->prune, SIGNAL(toggled(bool)), ui->pruneSize, SLOT(setEnabled(bool)));

    /* Network elements init */
#ifndef USE_UPNP
    ui->mapPortUpnp->setEnabled(false);
#endif

    ui->proxyIp->setEnabled(false);
    ui->proxyPort->setEnabled(false);
    ui->proxyPort->setValidator(new QIntValidator(1, 65535, this));

    ui->proxyIpTor->setEnabled(false);
    ui->proxyPortTor->setEnabled(false);
    ui->proxyPortTor->setValidator(new QIntValidator(1, 65535, this));

    connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool)));
    connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool)));
    connect(ui->connectSocks, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState()));

    connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyIpTor, SLOT(setEnabled(bool)));
    connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyPortTor, SLOT(setEnabled(bool)));
    connect(ui->connectSocksTor, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState()));

    /* Window elements init */
#ifdef Q_OS_MAC
    /* remove Window tab on Mac */
    ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWindow));
#endif

    /* remove Wallet tab in case of -disablewallet */
    if (!enableWallet) {
        ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWallet));
    }

    /* Display elements init */
    QDir translations(":translations");

    ui->bitcoinAtStartup->setToolTip(ui->bitcoinAtStartup->toolTip().arg(tr(PACKAGE_NAME)));
    ui->bitcoinAtStartup->setText(ui->bitcoinAtStartup->text().arg(tr(PACKAGE_NAME)));

    ui->openBitcoinConfButton->setToolTip(ui->openBitcoinConfButton->toolTip().arg(tr(PACKAGE_NAME)));

    ui->lang->setToolTip(ui->lang->toolTip().arg(tr(PACKAGE_NAME)));
    ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant(""));
    for (const QString &langStr : translations.entryList())
    {
        QLocale locale(langStr);

        /** check if the locale name consists of 2 parts (language_country) */
        if(langStr.contains("_"))
        {
            /** display language strings as "native language - native country (locale name)", e.g. "Deutsch - Deutschland (de)" */
            ui->lang->addItem(locale.nativeLanguageName() + QString(" - ") + locale.nativeCountryName() + QString(" (") + langStr + QString(")"), QVariant(langStr));
        }
        else
        {
            /** display language strings as "native language (locale name)", e.g. "Deutsch (de)" */
            ui->lang->addItem(locale.nativeLanguageName() + QString(" (") + langStr + QString(")"), QVariant(langStr));
        }
    }
    ui->thirdPartyTxUrls->setPlaceholderText("https://example.com/tx/%s");

    ui->unit->setModel(new BitcoinUnits(this));

    /* Widget-to-option mapper */
    mapper = new QDataWidgetMapper(this);
    mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
    mapper->setOrientation(Qt::Vertical);

    /* setup/change UI elements when proxy IPs are invalid/valid */
    ui->proxyIp->setCheckValidator(new ProxyAddressValidator(parent));
    ui->proxyIpTor->setCheckValidator(new ProxyAddressValidator(parent));
    connect(ui->proxyIp, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState()));
    connect(ui->proxyIpTor, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState()));
    connect(ui->proxyPort, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState()));
    connect(ui->proxyPortTor, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState()));
}

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

void OptionsDialog::setModel(OptionsModel *_model)
{
    this->model = _model;

    if(_model)
    {
        /* check if client restart is needed and show persistent message */
        if (_model->isRestartRequired())
            showRestartWarning(true);

        QString strLabel = _model->getOverriddenByCommandLine();
        if (strLabel.isEmpty())
            strLabel = tr("none");
        ui->overriddenByCommandLineLabel->setText(strLabel);

        mapper->setModel(_model);
        setMapper();
        mapper->toFirst();

        updateDefaultProxyNets();
    }

    /* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */

    /* Main */
    connect(ui->prune, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
    connect(ui->prune, SIGNAL(clicked(bool)), this, SLOT(togglePruneWarning(bool)));
    connect(ui->pruneSize, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
    connect(ui->databaseCache, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
    connect(ui->threadsScriptVerif, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
    /* Wallet */
    connect(ui->spendZeroConfChange, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
    /* Network */
    connect(ui->allowIncoming, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
    connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
    connect(ui->connectSocksTor, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
    /* Display */
    connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
    connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning()));

#ifndef ENABLE_CHECKPOINTS
    ui->checkpointEnforce->setVisible(false);
#endif
}

void OptionsDialog::setMapper()
{
    /* Main */
    mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
    mapper->addMapping(ui->threadsScriptVerif, OptionsModel::ThreadsScriptVerif);
    mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache);
    mapper->addMapping(ui->checkpointEnforce, OptionsModel::CheckpointEnforce);

    /* Wallet */
    mapper->addMapping(ui->spendZeroConfChange, OptionsModel::SpendZeroConfChange);
    mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures);

    /* Network */
    mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
    mapper->addMapping(ui->allowIncoming, OptionsModel::Listen);

    mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
    mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP);
    mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort);

    mapper->addMapping(ui->connectSocksTor, OptionsModel::ProxyUseTor);
    mapper->addMapping(ui->proxyIpTor, OptionsModel::ProxyIPTor);
    mapper->addMapping(ui->proxyPortTor, OptionsModel::ProxyPortTor);

    /* Window */
#ifndef Q_OS_MAC
    mapper->addMapping(ui->hideTrayIcon, OptionsModel::HideTrayIcon);
    mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray);
    mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose);
#endif

    /* Display */
    mapper->addMapping(ui->lang, OptionsModel::Language);
    mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
    mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls);
}

void OptionsDialog::setOkButtonState(bool fState)
{
    ui->okButton->setEnabled(fState);
}

void OptionsDialog::on_resetButton_clicked()
{
    if(model)
    {
        // confirmation dialog
        QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm options reset"),
            tr("Client restart required to activate changes.") + "

" + tr("Client will be shut down. Do you want to proceed?"),
            QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);

        if(btnRetVal == QMessageBox::Cancel)
            return;

        /* reset all options and close GUI */
        model->Reset();
        QApplication::quit();
    }
}

void OptionsDialog::on_openBitcoinConfButton_clicked()
{
    /* explain the purpose of the config file */
    QMessageBox::information(this, tr("Configuration options"),
        tr("The configuration file is used to specify advanced user options which override GUI settings. "
           "Additionally, any command-line options will override this configuration file."));

    /* show an error if there was some problem opening the file */
    if (!GUIUtil::openBitcoinConf())
        QMessageBox::critical(this, tr("Error"), tr("The configuration file could not be opened."));
}

void OptionsDialog::on_okButton_clicked()
{
    mapper->submit();
    accept();
    updateDefaultProxyNets();
}

void OptionsDialog::on_cancelButton_clicked()
{
    reject();
}

void OptionsDialog::on_hideTrayIcon_stateChanged(int fState)
{
    if(fState)
    {
        ui->minimizeToTray->setChecked(false);
        ui->minimizeToTray->setEnabled(false);
    }
    else
    {
        ui->minimizeToTray->setEnabled(true);
    }
}

void OptionsDialog::togglePruneWarning(bool enabled)
{
    ui->pruneWarning->setVisible(!ui->pruneWarning->isVisible());
}

void OptionsDialog::showRestartWarning(bool fPersistent)
{
    ui->statusLabel->setStyleSheet("QLabel { color: red; }");

    if(fPersistent)
    {
        ui->statusLabel->setText(tr("Client restart required to activate changes."));
    }
    else
    {
        ui->statusLabel->setText(tr("This change would require a client restart."));
        // clear non-persistent status label after 10 seconds
        // Todo: should perhaps be a class attribute, if we extend the use of statusLabel
        QTimer::singleShot(10000, this, SLOT(clearStatusLabel()));
    }
}

void OptionsDialog::clearStatusLabel()
{
    ui->statusLabel->clear();
    if (model && model->isRestartRequired()) {
        showRestartWarning(true);
    }
}

void OptionsDialog::updateProxyValidationState()
{
    QValidatedLineEdit *pUiProxyIp = ui->proxyIp;
    QValidatedLineEdit *otherProxyWidget = (pUiProxyIp == ui->proxyIpTor) ? ui->proxyIp : ui->proxyIpTor;
    if (pUiProxyIp->isValid() && (!ui->proxyPort->isEnabled() || ui->proxyPort->text().toInt() > 0) && (!ui->proxyPortTor->isEnabled() || ui->proxyPortTor->text().toInt() > 0))
    {
        setOkButtonState(otherProxyWidget->isValid()); //only enable ok button if both proxys are valid
        clearStatusLabel();
    }
    else
    {
        setOkButtonState(false);
        ui->statusLabel->setStyleSheet("QLabel { color: red; }");
        ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
    }
}

void OptionsDialog::updateDefaultProxyNets()
{
    proxyType proxy;
    std::string strProxy;
    QString strDefaultProxyGUI;

    model->node().getProxy(NET_IPV4, proxy);
    strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
    strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
    (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachIPv4->setChecked(true) : ui->proxyReachIPv4->setChecked(false);

    model->node().getProxy(NET_IPV6, proxy);
    strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
    strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
    (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachIPv6->setChecked(true) : ui->proxyReachIPv6->setChecked(false);

    model->node().getProxy(NET_ONION, proxy);
    strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
    strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
    (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachTor->setChecked(true) : ui->proxyReachTor->setChecked(false);
}

ProxyAddressValidator::ProxyAddressValidator(QObject *parent) :
QValidator(parent)
{
}

QValidator::State ProxyAddressValidator::validate(QString &input, int &pos) const
{
    Q_UNUSED(pos);
    // Validate the proxy
    CService serv(LookupNumeric(input.toStdString().c_str(), DEFAULT_GUI_PROXY_PORT));
    proxyType addrProxy = proxyType(serv, true);
    if (addrProxy.IsValid())
        return QValidator::Acceptable;

    return QValidator::Invalid;
}
<commit_msg>gui: Reject options dialog when key escape is pressed<commit_after>// Copyright (c) 2011-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <qt/optionsdialog.h>
#include <qt/forms/ui_optionsdialog.h>

#include <qt/bitcoinunits.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>

#include <interfaces/node.h>
#include <validation.h> // for DEFAULT_SCRIPTCHECK_THREADS and MAX_SCRIPTCHECK_THREADS
#include <netbase.h>
#include <txdb.h> // for -dbcache defaults

#include <QDataWidgetMapper>
#include <QDir>
#include <QIntValidator>
#include <QLocale>
#include <QMessageBox>
#include <QTimer>

OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
    QDialog(parent),
    ui(new Ui::OptionsDialog),
    model(0),
    mapper(0)
{
    ui->setupUi(this);

    /* Main elements init */
    ui->databaseCache->setMinimum(nMinDbCache);
    ui->databaseCache->setMaximum(nMaxDbCache);
    static const uint64_t GiB = 1024 * 1024 * 1024;
    static const uint64_t nMinDiskSpace = MIN_DISK_SPACE_FOR_BLOCK_FILES / GiB +
                          (MIN_DISK_SPACE_FOR_BLOCK_FILES % GiB) ? 1 : 0;
    ui->pruneSize->setMinimum(nMinDiskSpace);
    ui->threadsScriptVerif->setMinimum(-GetNumCores());
    ui->threadsScriptVerif->setMaximum(MAX_SCRIPTCHECK_THREADS);
    ui->pruneWarning->setVisible(false);
    ui->pruneWarning->setStyleSheet("QLabel { color: red; }");

    ui->pruneSize->setEnabled(false);
    connect(ui->prune, SIGNAL(toggled(bool)), ui->pruneSize, SLOT(setEnabled(bool)));

    /* Network elements init */
#ifndef USE_UPNP
    ui->mapPortUpnp->setEnabled(false);
#endif

    ui->proxyIp->setEnabled(false);
    ui->proxyPort->setEnabled(false);
    ui->proxyPort->setValidator(new QIntValidator(1, 65535, this));

    ui->proxyIpTor->setEnabled(false);
    ui->proxyPortTor->setEnabled(false);
    ui->proxyPortTor->setValidator(new QIntValidator(1, 65535, this));

    connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool)));
    connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool)));
    connect(ui->connectSocks, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState()));

    connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyIpTor, SLOT(setEnabled(bool)));
    connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyPortTor, SLOT(setEnabled(bool)));
    connect(ui->connectSocksTor, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState()));

    /* Window elements init */
#ifdef Q_OS_MAC
    /* remove Window tab on Mac */
    ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWindow));
#endif

    /* remove Wallet tab in case of -disablewallet */
    if (!enableWallet) {
        ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->tabWallet));
    }

    /* Display elements init */
    QDir translations(":translations");

    ui->bitcoinAtStartup->setToolTip(ui->bitcoinAtStartup->toolTip().arg(tr(PACKAGE_NAME)));
    ui->bitcoinAtStartup->setText(ui->bitcoinAtStartup->text().arg(tr(PACKAGE_NAME)));

    ui->openBitcoinConfButton->setToolTip(ui->openBitcoinConfButton->toolTip().arg(tr(PACKAGE_NAME)));

    ui->lang->setToolTip(ui->lang->toolTip().arg(tr(PACKAGE_NAME)));
    ui->lang->addItem(QString("(") + tr("default") + QString(")"), QVariant(""));
    for (const QString &langStr : translations.entryList())
    {
        QLocale locale(langStr);

        /** check if the locale name consists of 2 parts (language_country) */
        if(langStr.contains("_"))
        {
            /** display language strings as "native language - native country (locale name)", e.g. "Deutsch - Deutschland (de)" */
            ui->lang->addItem(locale.nativeLanguageName() + QString(" - ") + locale.nativeCountryName() + QString(" (") + langStr + QString(")"), QVariant(langStr));
        }
        else
        {
            /** display language strings as "native language (locale name)", e.g. "Deutsch (de)" */
            ui->lang->addItem(locale.nativeLanguageName() + QString(" (") + langStr + QString(")"), QVariant(langStr));
        }
    }
    ui->thirdPartyTxUrls->setPlaceholderText("https://example.com/tx/%s");

    ui->unit->setModel(new BitcoinUnits(this));

    /* Widget-to-option mapper */
    mapper = new QDataWidgetMapper(this);
    mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
    mapper->setOrientation(Qt::Vertical);

    GUIUtil::ItemDelegate* delegate = new GUIUtil::ItemDelegate(mapper);
    connect(delegate, &GUIUtil::ItemDelegate::keyEscapePressed, this, &OptionsDialog::reject);
    mapper->setItemDelegate(delegate);

    /* setup/change UI elements when proxy IPs are invalid/valid */
    ui->proxyIp->setCheckValidator(new ProxyAddressValidator(parent));
    ui->proxyIpTor->setCheckValidator(new ProxyAddressValidator(parent));
    connect(ui->proxyIp, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState()));
    connect(ui->proxyIpTor, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState()));
    connect(ui->proxyPort, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState()));
    connect(ui->proxyPortTor, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState()));
}

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

void OptionsDialog::setModel(OptionsModel *_model)
{
    this->model = _model;

    if(_model)
    {
        /* check if client restart is needed and show persistent message */
        if (_model->isRestartRequired())
            showRestartWarning(true);

        QString strLabel = _model->getOverriddenByCommandLine();
        if (strLabel.isEmpty())
            strLabel = tr("none");
        ui->overriddenByCommandLineLabel->setText(strLabel);

        mapper->setModel(_model);
        setMapper();
        mapper->toFirst();

        updateDefaultProxyNets();
    }

    /* warn when one of the following settings changes by user action (placed here so init via mapper doesn't trigger them) */

    /* Main */
    connect(ui->prune, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
    connect(ui->prune, SIGNAL(clicked(bool)), this, SLOT(togglePruneWarning(bool)));
    connect(ui->pruneSize, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
    connect(ui->databaseCache, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
    connect(ui->threadsScriptVerif, SIGNAL(valueChanged(int)), this, SLOT(showRestartWarning()));
    /* Wallet */
    connect(ui->spendZeroConfChange, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
    /* Network */
    connect(ui->allowIncoming, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
    connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
    connect(ui->connectSocksTor, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning()));
    /* Display */
    connect(ui->lang, SIGNAL(valueChanged()), this, SLOT(showRestartWarning()));
    connect(ui->thirdPartyTxUrls, SIGNAL(textChanged(const QString &)), this, SLOT(showRestartWarning()));

#ifndef ENABLE_CHECKPOINTS
    ui->checkpointEnforce->setVisible(false);
#endif
}

void OptionsDialog::setMapper()
{
    /* Main */
    mapper->addMapping(ui->bitcoinAtStartup, OptionsModel::StartAtStartup);
    mapper->addMapping(ui->threadsScriptVerif, OptionsModel::ThreadsScriptVerif);
    mapper->addMapping(ui->databaseCache, OptionsModel::DatabaseCache);
    mapper->addMapping(ui->checkpointEnforce, OptionsModel::CheckpointEnforce);

    /* Wallet */
    mapper->addMapping(ui->spendZeroConfChange, OptionsModel::SpendZeroConfChange);
    mapper->addMapping(ui->coinControlFeatures, OptionsModel::CoinControlFeatures);

    /* Network */
    mapper->addMapping(ui->mapPortUpnp, OptionsModel::MapPortUPnP);
    mapper->addMapping(ui->allowIncoming, OptionsModel::Listen);

    mapper->addMapping(ui->connectSocks, OptionsModel::ProxyUse);
    mapper->addMapping(ui->proxyIp, OptionsModel::ProxyIP);
    mapper->addMapping(ui->proxyPort, OptionsModel::ProxyPort);

    mapper->addMapping(ui->connectSocksTor, OptionsModel::ProxyUseTor);
    mapper->addMapping(ui->proxyIpTor, OptionsModel::ProxyIPTor);
    mapper->addMapping(ui->proxyPortTor, OptionsModel::ProxyPortTor);

    /* Window */
#ifndef Q_OS_MAC
    mapper->addMapping(ui->hideTrayIcon, OptionsModel::HideTrayIcon);
    mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray);
    mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose);
#endif

    /* Display */
    mapper->addMapping(ui->lang, OptionsModel::Language);
    mapper->addMapping(ui->unit, OptionsModel::DisplayUnit);
    mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls);
}

void OptionsDialog::setOkButtonState(bool fState)
{
    ui->okButton->setEnabled(fState);
}

void OptionsDialog::on_resetButton_clicked()
{
    if(model)
    {
        // confirmation dialog
        QMessageBox::StandardButton btnRetVal = QMessageBox::question(this, tr("Confirm options reset"),
            tr("Client restart required to activate changes.") + "

" + tr("Client will be shut down. Do you want to proceed?"),
            QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);

        if(btnRetVal == QMessageBox::Cancel)
            return;

        /* reset all options and close GUI */
        model->Reset();
        QApplication::quit();
    }
}

void OptionsDialog::on_openBitcoinConfButton_clicked()
{
    /* explain the purpose of the config file */
    QMessageBox::information(this, tr("Configuration options"),
        tr("The configuration file is used to specify advanced user options which override GUI settings. "
           "Additionally, any command-line options will override this configuration file."));

    /* show an error if there was some problem opening the file */
    if (!GUIUtil::openBitcoinConf())
        QMessageBox::critical(this, tr("Error"), tr("The configuration file could not be opened."));
}

void OptionsDialog::on_okButton_clicked()
{
    mapper->submit();
    accept();
    updateDefaultProxyNets();
}

void OptionsDialog::on_cancelButton_clicked()
{
    reject();
}

void OptionsDialog::on_hideTrayIcon_stateChanged(int fState)
{
    if(fState)
    {
        ui->minimizeToTray->setChecked(false);
        ui->minimizeToTray->setEnabled(false);
    }
    else
    {
        ui->minimizeToTray->setEnabled(true);
    }
}

void OptionsDialog::togglePruneWarning(bool enabled)
{
    ui->pruneWarning->setVisible(!ui->pruneWarning->isVisible());
}

void OptionsDialog::showRestartWarning(bool fPersistent)
{
    ui->statusLabel->setStyleSheet("QLabel { color: red; }");

    if(fPersistent)
    {
        ui->statusLabel->setText(tr("Client restart required to activate changes."));
    }
    else
    {
        ui->statusLabel->setText(tr("This change would require a client restart."));
        // clear non-persistent status label after 10 seconds
        // Todo: should perhaps be a class attribute, if we extend the use of statusLabel
        QTimer::singleShot(10000, this, SLOT(clearStatusLabel()));
    }
}

void OptionsDialog::clearStatusLabel()
{
    ui->statusLabel->clear();
    if (model && model->isRestartRequired()) {
        showRestartWarning(true);
    }
}

void OptionsDialog::updateProxyValidationState()
{
    QValidatedLineEdit *pUiProxyIp = ui->proxyIp;
    QValidatedLineEdit *otherProxyWidget = (pUiProxyIp == ui->proxyIpTor) ? ui->proxyIp : ui->proxyIpTor;
    if (pUiProxyIp->isValid() && (!ui->proxyPort->isEnabled() || ui->proxyPort->text().toInt() > 0) && (!ui->proxyPortTor->isEnabled() || ui->proxyPortTor->text().toInt() > 0))
    {
        setOkButtonState(otherProxyWidget->isValid()); //only enable ok button if both proxys are valid
        clearStatusLabel();
    }
    else
    {
        setOkButtonState(false);
        ui->statusLabel->setStyleSheet("QLabel { color: red; }");
        ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
    }
}

void OptionsDialog::updateDefaultProxyNets()
{
    proxyType proxy;
    std::string strProxy;
    QString strDefaultProxyGUI;

    model->node().getProxy(NET_IPV4, proxy);
    strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
    strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
    (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachIPv4->setChecked(true) : ui->proxyReachIPv4->setChecked(false);

    model->node().getProxy(NET_IPV6, proxy);
    strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
    strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
    (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachIPv6->setChecked(true) : ui->proxyReachIPv6->setChecked(false);

    model->node().getProxy(NET_ONION, proxy);
    strProxy = proxy.proxy.ToStringIP() + ":" + proxy.proxy.ToStringPort();
    strDefaultProxyGUI = ui->proxyIp->text() + ":" + ui->proxyPort->text();
    (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachTor->setChecked(true) : ui->proxyReachTor->setChecked(false);
}

ProxyAddressValidator::ProxyAddressValidator(QObject *parent) :
QValidator(parent)
{
}

QValidator::State ProxyAddressValidator::validate(QString &input, int &pos) const
{
    Q_UNUSED(pos);
    // Validate the proxy
    CService serv(LookupNumeric(input.toStdString().c_str(), DEFAULT_GUI_PROXY_PORT));
    proxyType addrProxy = proxyType(serv, true);
    if (addrProxy.IsValid())
        return QValidator::Acceptable;

    return QValidator::Invalid;
}
<|endoftext|>


<commit_before>#include "nodes/NonOptimizingNode.hpp"
#include <sstream>

using namespace std;

NonOptimizingNode::NonOptimizingNode(
	unsigned int populationSize,
	vector<Locus*> loci,
	vector<ObjectiveFunction*> objectives,
	ToStringFunction * populationToString,
	vector<EndCondition*> conditions,
	string nodeName
) : PopulationNode(
	populationSize,
	loci,
	objectives,
	populationToString,
	conditions,
	nodeName
) {}

void NonOptimizingNode::nextIteration() {
	if (!done()) evaluateFitnesses();
}

std::vector<Genome*> NonOptimizingNode::getNextPopulation() {
	return this->population;
}

node_type_t NonOptimizingNode::type() {
	return NON_OPT_TYPE;
}

PopulationNode * NonOptimizingNode::duplicate(std::string newNodeName) {
	return new NonOptimizingNode(
		this->populationSize(),
		this->getCanonicalLoci(),
		this->getObjectives(),
		this->getToString(),
		this->getConditions(),
		newNodeName
	);
}
<commit_msg>[Non-Optimizing Node]: Removed namespace std::<commit_after>#include "nodes/NonOptimizingNode.hpp"
#include <sstream>

NonOptimizingNode::NonOptimizingNode(
	unsigned int populationSize,
	std::vector<Locus*> loci,
	std::vector<ObjectiveFunction*> objectives,
	ToStringFunction* populationToString,
	std::vector<EndCondition*> conditions,
	std::string nodeName
) : PopulationNode(
	populationSize,
	loci,
	objectives,
	populationToString,
	conditions,
	nodeName
) {}

void NonOptimizingNode::nextIteration() {
	if (!done()) evaluateFitnesses();
}

std::vector<Genome*> NonOptimizingNode::getNextPopulation() {
	return this->population;
}

node_type_t NonOptimizingNode::type() {
	return NON_OPT_TYPE;
}

PopulationNode* NonOptimizingNode::duplicate(std::string newNodeName) {
	return new NonOptimizingNode(
		this->populationSize(),
		this->getCanonicalLoci(),
		this->getObjectives(),
		this->getToString(),
		this->getConditions(),
		newNodeName
	);
}
<|endoftext|>


<commit_before>//
//  ofxModernOscMessage.cpp
//
//  Created by ISHII 2bit on 2016/03/20.
//
//

#include "ofxModernOscMessage.h"
#include "ofLog.h"

#define BEGIN_NAMESPACE_OFX_MODERN_OSC namespace ofx {\
    namespace ModernOsc {

#define END_NAMESPACE_OFX_MODERN_OSC\
    };\
};

BEGIN_NAMESPACE_OFX_MODERN_OSC

END_NAMESPACE_OFX_MODERN_OSC

std::ostream &operator<<(std::ostream &os, const ofxModernOscMessage &mess) {
    os << mess.address << " :[" << std::endl;
    for(std::size_t i = 0; i < mess.size(); i++) {
        os << "  " << i << ": " << mess[i] << std::endl;
    }
    return os << "]";
}
<commit_msg>operator <<<commit_after>//
//  ofxModernOscMessage.cpp
//
//  Created by ISHII 2bit on 2016/03/20.
//
//

#include "ofxModernOscMessage.h"
#include "ofLog.h"

#define BEGIN_NAMESPACE_OFX_MODERN_OSC namespace ofx {\
    namespace ModernOsc {

#define END_NAMESPACE_OFX_MODERN_OSC\
    };\
};

BEGIN_NAMESPACE_OFX_MODERN_OSC

std::ostream &operator<<(std::ostream &os, const Message &mess) {
    os << mess.address << " :[" << std::endl;
    for(std::size_t i = 0; i < mess.size(); i++) {
        os << "  " << i << ": " << mess[i].stringValue() << std::endl;
    }
    return os << "]";
}

END_NAMESPACE_OFX_MODERN_OSC<|endoftext|>


<commit_before>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Crytek
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include <winsock2.h>
#include <ws2tcpip.h>

#include "os/os_specific.h"

namespace Network
{

void Init()
{
	WSAData wsaData = {0};
	WSAStartup(MAKEWORD(2, 2), &wsaData);
}

void Shutdown()
{
	WSACleanup();
}

Socket::~Socket()
{
	Shutdown();
}

void Socket::Shutdown()
{
	if(Connected())
	{
		shutdown((SOCKET)socket, SD_BOTH);
		closesocket((SOCKET)socket);
		socket = -1;
	}
}

bool Socket::Connected() const
{
	return (SOCKET)socket != INVALID_SOCKET;
}

Socket *Socket::AcceptClient(bool wait)
{
	do
	{
		SOCKET s = accept(socket, NULL, NULL);

		if(s != INVALID_SOCKET)
		{
			u_long enable = 1;
			ioctlsocket(s, FIONBIO, &enable);

			BOOL nodelay = TRUE;
			setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay));

			return new Socket((ptrdiff_t)s);
		}

		int err = WSAGetLastError();

		if(err != WSAEWOULDBLOCK)
		{
			RDCWARN("accept: %d", err);
			Shutdown();
		}

		Threading::Sleep(4);
	} while(wait);

	return NULL;
}

bool Socket::SendDataBlocking(const void *buf, uint32_t length)
{
	if(length == 0) return true;

	uint32_t sent = 0;

	char *src = (char *)buf;

	u_long enable = 0;
	ioctlsocket(socket, FIONBIO, &enable);

	DWORD timeout = 3000;
	setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout));

	while(sent < length)
	{
		int ret = send(socket, src, length-sent, 0);

		if(ret <= 0)
		{
			int err = WSAGetLastError();

			if(err == WSAEWOULDBLOCK)
			{
				ret = 0;
			}
			else
			{
				RDCWARN("send: %d", err);
				Shutdown();
				return false;
			}
		}

		sent += ret;
		src += ret;
	}

	enable = 1;
	ioctlsocket(socket, FIONBIO, &enable);

	timeout = 600000;
	setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout));

	RDCASSERT(sent == length);

	return true;
}

bool Socket::IsRecvDataWaiting()
{
	char dummy;
	int ret = recv(socket, &dummy, 1, MSG_PEEK);

	if(ret == 0)
	{
		Shutdown();
		return false;
	}
	else if(ret <= 0)
	{
		int err = WSAGetLastError();

		if(err == WSAEWOULDBLOCK)
		{
			ret = 0;
		}
		else
		{
			RDCWARN("recv: %d", err);
			Shutdown();
			return false;
		}
	}

	return ret > 0;
}

bool Socket::RecvDataBlocking(void *buf, uint32_t length)
{
	if(length == 0) return true;

	uint32_t received = 0;

	char *dst = (char *)buf;

	u_long enable = 0;
	ioctlsocket(socket, FIONBIO, &enable);

	DWORD timeout = 3000;
	setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));

	while(received < length)
	{
		int ret = recv(socket, dst, length-received, 0);

		if(ret == 0)
		{
			Shutdown();
			return false;
		}
		else if(ret <= 0)
		{
			int err = WSAGetLastError();

			if(err == WSAEWOULDBLOCK)
			{
				ret = 0;
			}
			else
			{
				RDCWARN("recv: %d", err);
				Shutdown();
				return false;
			}
		}

		received += ret;
		dst += ret;
	}

	enable = 1;
	ioctlsocket(socket, FIONBIO, &enable);

	timeout = 600000;
	setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));

	RDCASSERT(received == length);

	return true;
}

Socket *CreateServerSocket(const char *bindaddr, uint16_t port, int queuesize)
{
	SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if(s == INVALID_SOCKET)
		return NULL;

	sockaddr_in addr;
	RDCEraseEl(addr);

	addr.sin_family = AF_INET;
	inet_pton(AF_INET, bindaddr, &addr.sin_addr);
	addr.sin_port = htons(port);

	int result = bind(s, (SOCKADDR *)&addr, sizeof(addr));
	if(result == SOCKET_ERROR)
	{
		RDCWARN("Failed to bind to %hs:%d - %d", bindaddr, port, WSAGetLastError());
		closesocket(s);
		return NULL;
	}

	result = listen(s, queuesize);
	if(result == SOCKET_ERROR)
	{
		RDCWARN("Failed to listen on %hs:%d - %d", bindaddr, port, WSAGetLastError());
		closesocket(s);
		return NULL;
	}

	u_long nonblock = 1;
	ioctlsocket(s, FIONBIO, &nonblock);

	return new Socket((ptrdiff_t)s);
}

Socket *CreateClientSocket(const wchar_t *host, uint16_t port, int timeoutMS)
{
	wchar_t portstr[7] = {0};
	StringFormat::wsnprintf(portstr, 6, L"%d", port);

    addrinfoW hints;
	RDCEraseEl(hints);
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

    addrinfoW *result = NULL;
	GetAddrInfoW(host, portstr, &hints, &result);

    for(addrinfoW *ptr = result; ptr != NULL; ptr = ptr->ai_next)
	{
		SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

		if(s == INVALID_SOCKET)
			return NULL;

		u_long enable = 1;
		ioctlsocket(s, FIONBIO, &enable);

		int result = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen);
		if(result == SOCKET_ERROR)
		{
			fd_set set;
			FD_ZERO(&set);
			FD_SET(s, &set);

			int err = WSAGetLastError();

			if(err == WSAEWOULDBLOCK)
			{
				timeval timeout;
				timeout.tv_sec = (timeoutMS/1000);
				timeout.tv_usec = (timeoutMS%1000)*1000;
				result = select(0, NULL, &set, NULL, &timeout);

				if(result <= 0)
				{
					RDCDEBUG("connect timed out");
					closesocket(s);
					continue;
				}
				else
				{
					RDCDEBUG("connect before timeout");
				}
			}
			else
			{
				RDCDEBUG("problem other than blocking");
				closesocket(s);
				continue;
			}
		}
		else
		{
			RDCDEBUG("connected immediately");
		}

		BOOL nodelay = TRUE;
		setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay));

		return new Socket((ptrdiff_t)s);
	}

	RDCWARN("Failed to connect to %ls:%d", host, port);
	return NULL;
}

};<commit_msg>Set sockets to be specifically non-inheritable<commit_after>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Crytek
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include <winsock2.h>
#include <ws2tcpip.h>

#include "os/os_specific.h"

#ifndef WSA_FLAG_NO_HANDLE_INHERIT
#define WSA_FLAG_NO_HANDLE_INHERIT 0x80
#endif

namespace Network
{

void Init()
{
	WSAData wsaData = {0};
	WSAStartup(MAKEWORD(2, 2), &wsaData);
}

void Shutdown()
{
	WSACleanup();
}

Socket::~Socket()
{
	Shutdown();
}

void Socket::Shutdown()
{
	if(Connected())
	{
		shutdown((SOCKET)socket, SD_BOTH);
		closesocket((SOCKET)socket);
		socket = -1;
	}
}

bool Socket::Connected() const
{
	return (SOCKET)socket != INVALID_SOCKET;
}

Socket *Socket::AcceptClient(bool wait)
{
	do
	{
		SOCKET s = accept(socket, NULL, NULL);

		if(s != INVALID_SOCKET)
		{
			u_long enable = 1;
			ioctlsocket(s, FIONBIO, &enable);

			BOOL nodelay = TRUE;
			setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay));

			return new Socket((ptrdiff_t)s);
		}

		int err = WSAGetLastError();

		if(err != WSAEWOULDBLOCK)
		{
			RDCWARN("accept: %d", err);
			Shutdown();
		}

		Threading::Sleep(4);
	} while(wait);

	return NULL;
}

bool Socket::SendDataBlocking(const void *buf, uint32_t length)
{
	if(length == 0) return true;

	uint32_t sent = 0;

	char *src = (char *)buf;

	u_long enable = 0;
	ioctlsocket(socket, FIONBIO, &enable);

	DWORD timeout = 3000;
	setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout));

	while(sent < length)
	{
		int ret = send(socket, src, length-sent, 0);

		if(ret <= 0)
		{
			int err = WSAGetLastError();

			if(err == WSAEWOULDBLOCK)
			{
				ret = 0;
			}
			else
			{
				RDCWARN("send: %d", err);
				Shutdown();
				return false;
			}
		}

		sent += ret;
		src += ret;
	}

	enable = 1;
	ioctlsocket(socket, FIONBIO, &enable);

	timeout = 600000;
	setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout));

	RDCASSERT(sent == length);

	return true;
}

bool Socket::IsRecvDataWaiting()
{
	char dummy;
	int ret = recv(socket, &dummy, 1, MSG_PEEK);

	if(ret == 0)
	{
		Shutdown();
		return false;
	}
	else if(ret <= 0)
	{
		int err = WSAGetLastError();

		if(err == WSAEWOULDBLOCK)
		{
			ret = 0;
		}
		else
		{
			RDCWARN("recv: %d", err);
			Shutdown();
			return false;
		}
	}

	return ret > 0;
}

bool Socket::RecvDataBlocking(void *buf, uint32_t length)
{
	if(length == 0) return true;

	uint32_t received = 0;

	char *dst = (char *)buf;

	u_long enable = 0;
	ioctlsocket(socket, FIONBIO, &enable);

	DWORD timeout = 3000;
	setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));

	while(received < length)
	{
		int ret = recv(socket, dst, length-received, 0);

		if(ret == 0)
		{
			Shutdown();
			return false;
		}
		else if(ret <= 0)
		{
			int err = WSAGetLastError();

			if(err == WSAEWOULDBLOCK)
			{
				ret = 0;
			}
			else
			{
				RDCWARN("recv: %d", err);
				Shutdown();
				return false;
			}
		}

		received += ret;
		dst += ret;
	}

	enable = 1;
	ioctlsocket(socket, FIONBIO, &enable);

	timeout = 600000;
	setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));

	RDCASSERT(received == length);

	return true;
}

Socket *CreateServerSocket(const char *bindaddr, uint16_t port, int queuesize)
{
	SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT);

	if(s == INVALID_SOCKET)
		return NULL;

	sockaddr_in addr;
	RDCEraseEl(addr);

	addr.sin_family = AF_INET;
	inet_pton(AF_INET, bindaddr, &addr.sin_addr);
	addr.sin_port = htons(port);

	int result = bind(s, (SOCKADDR *)&addr, sizeof(addr));
	if(result == SOCKET_ERROR)
	{
		RDCWARN("Failed to bind to %hs:%d - %d", bindaddr, port, WSAGetLastError());
		closesocket(s);
		return NULL;
	}

	result = listen(s, queuesize);
	if(result == SOCKET_ERROR)
	{
		RDCWARN("Failed to listen on %hs:%d - %d", bindaddr, port, WSAGetLastError());
		closesocket(s);
		return NULL;
	}

	u_long nonblock = 1;
	ioctlsocket(s, FIONBIO, &nonblock);

	return new Socket((ptrdiff_t)s);
}

Socket *CreateClientSocket(const wchar_t *host, uint16_t port, int timeoutMS)
{
	wchar_t portstr[7] = {0};
	StringFormat::wsnprintf(portstr, 6, L"%d", port);

    addrinfoW hints;
	RDCEraseEl(hints);
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

    addrinfoW *result = NULL;
	GetAddrInfoW(host, portstr, &hints, &result);

    for(addrinfoW *ptr = result; ptr != NULL; ptr = ptr->ai_next)
	{
		SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT);

		if(s == INVALID_SOCKET)
			return NULL;

		u_long enable = 1;
		ioctlsocket(s, FIONBIO, &enable);

		int result = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen);
		if(result == SOCKET_ERROR)
		{
			fd_set set;
			FD_ZERO(&set);
			FD_SET(s, &set);

			int err = WSAGetLastError();

			if(err == WSAEWOULDBLOCK)
			{
				timeval timeout;
				timeout.tv_sec = (timeoutMS/1000);
				timeout.tv_usec = (timeoutMS%1000)*1000;
				result = select(0, NULL, &set, NULL, &timeout);

				if(result <= 0)
				{
					RDCDEBUG("connect timed out");
					closesocket(s);
					continue;
				}
				else
				{
					RDCDEBUG("connect before timeout");
				}
			}
			else
			{
				RDCDEBUG("problem other than blocking");
				closesocket(s);
				continue;
			}
		}
		else
		{
			RDCDEBUG("connected immediately");
		}

		BOOL nodelay = TRUE;
		setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay));

		return new Socket((ptrdiff_t)s);
	}

	RDCWARN("Failed to connect to %ls:%d", host, port);
	return NULL;
}

};<|endoftext|>


<commit_before>#include <osg/GL>
#include <osg/Matrix>
#include <osg/io_utils>
#include <osg/ComputeBoundsVisitor>
#include <osgGA/CameraManipulator>
#include <string.h>

using namespace osg;
using namespace osgGA;

CameraManipulator::CameraManipulator()
{
    _intersectTraversalMask = 0xffffffff;

    _autoComputeHomePosition = true;

    _homeEye.set(0.0,-1.0,0.0);
    _homeCenter.set(0.0,0.0,0.0);
    _homeUp.set(0.0,0.0,1.0);
}

CameraManipulator::CameraManipulator(const CameraManipulator& mm, const CopyOp& copyOp):
     osg::Object(mm,copyOp),
     osg::Callback(mm,copyOp),
     inherited(mm, copyOp),
     _intersectTraversalMask(mm._intersectTraversalMask),
     _autoComputeHomePosition(mm._autoComputeHomePosition),
     _homeEye(mm._homeEye),
     _homeCenter(mm._homeCenter),
     _homeUp(mm._homeUp),
     _coordinateFrameCallback(dynamic_cast<CoordinateFrameCallback*>(copyOp(mm._coordinateFrameCallback.get())))
{
}

CameraManipulator::~CameraManipulator()
{
}

std::string CameraManipulator::getManipulatorName() const
{
    const char* className = this->className();
    const char* manipString = strstr(className, "Manipulator");
    if (!manipString)
        return std::string(className);
    else
        return std::string(className, manipString-className);
}

bool CameraManipulator::handle(const GUIEventAdapter&,GUIActionAdapter&)
{
    return false;
}

/** Compute the home position.
 *
 *  The computation considers camera's fov (field of view) and model size and
 *  positions camera far enough to fit the model to the screen.
 *
 *  camera parameter enables computations of camera's fov. If camera is NULL,
 *  scene to camera distance can not be computed and default value is used,
 *  based on model size only.
 *
 *  useBoundingBox parameter enables to use bounding box instead of bounding sphere
 *  for scene bounds. Bounding box provide more precise scene center that may be
 *  important for many applications.*/
void CameraManipulator::computeHomePosition(const osg::Camera *camera, bool useBoundingBox)
{
    if (getNode())
    {
        osg::BoundingSphere boundingSphere;

        OSG_INFO<<" CameraManipulator::computeHomePosition("<<camera<<", "<<useBoundingBox<<")"<<std::endl;

        if (useBoundingBox)
        {
            // compute bounding box
            // (bounding box computes model center more precisely than bounding sphere)
            osg::ComputeBoundsVisitor cbVisitor;
            getNode()->accept(cbVisitor);
            osg::BoundingBox &bb = cbVisitor.getBoundingBox();

            if (bb.valid()) boundingSphere.expandBy(bb);
            else boundingSphere = getNode()->getBound();
        }
        else
        {
            // compute bounding sphere
            boundingSphere = getNode()->getBound();
        }

        OSG_INFO<<"    boundingSphere.center() = ("<<boundingSphere.center()<<")"<<std::endl;
        OSG_INFO<<"    boundingSphere.radius() = "<<boundingSphere.radius()<<std::endl;

        // set dist to default
        double dist = 3.5f * boundingSphere.radius();

        if (camera)
        {

            // try to compute dist from frustum
            double left,right,bottom,top,zNear,zFar;
            if (camera->getProjectionMatrixAsFrustum(left,right,bottom,top,zNear,zFar))
            {
                double vertical2 = fabs(right - left) / zNear / 2.;
                double horizontal2 = fabs(top - bottom) / zNear / 2.;
                double dim = horizontal2 < vertical2 ? horizontal2 : vertical2;
                double viewAngle = atan2(dim,1.);
                dist = boundingSphere.radius() / sin(viewAngle);
            }
            else
            {
                // try to compute dist from ortho
                if (camera->getProjectionMatrixAsOrtho(left,right,bottom,top,zNear,zFar))
                {
                    dist = fabs(zFar - zNear) / 2.;
                }
            }
        }

        // set home position
        setHomePosition(boundingSphere.center() + osg::Vec3d(0.0,-dist,0.0f),
                        boundingSphere.center(),
                        osg::Vec3d(0.0f,0.0f,1.0f),
                        _autoComputeHomePosition);
    }
}
<commit_msg>Added handling of zero radius models<commit_after>#include <osg/GL>
#include <osg/Matrix>
#include <osg/io_utils>
#include <osg/ComputeBoundsVisitor>
#include <osgGA/CameraManipulator>
#include <string.h>

using namespace osg;
using namespace osgGA;

CameraManipulator::CameraManipulator()
{
    _intersectTraversalMask = 0xffffffff;

    _autoComputeHomePosition = true;

    _homeEye.set(0.0,-1.0,0.0);
    _homeCenter.set(0.0,0.0,0.0);
    _homeUp.set(0.0,0.0,1.0);
}

CameraManipulator::CameraManipulator(const CameraManipulator& mm, const CopyOp& copyOp):
     osg::Object(mm,copyOp),
     osg::Callback(mm,copyOp),
     inherited(mm, copyOp),
     _intersectTraversalMask(mm._intersectTraversalMask),
     _autoComputeHomePosition(mm._autoComputeHomePosition),
     _homeEye(mm._homeEye),
     _homeCenter(mm._homeCenter),
     _homeUp(mm._homeUp),
     _coordinateFrameCallback(dynamic_cast<CoordinateFrameCallback*>(copyOp(mm._coordinateFrameCallback.get())))
{
}

CameraManipulator::~CameraManipulator()
{
}

std::string CameraManipulator::getManipulatorName() const
{
    const char* className = this->className();
    const char* manipString = strstr(className, "Manipulator");
    if (!manipString)
        return std::string(className);
    else
        return std::string(className, manipString-className);
}

bool CameraManipulator::handle(const GUIEventAdapter&,GUIActionAdapter&)
{
    return false;
}

/** Compute the home position.
 *
 *  The computation considers camera's fov (field of view) and model size and
 *  positions camera far enough to fit the model to the screen.
 *
 *  camera parameter enables computations of camera's fov. If camera is NULL,
 *  scene to camera distance can not be computed and default value is used,
 *  based on model size only.
 *
 *  useBoundingBox parameter enables to use bounding box instead of bounding sphere
 *  for scene bounds. Bounding box provide more precise scene center that may be
 *  important for many applications.*/
void CameraManipulator::computeHomePosition(const osg::Camera *camera, bool useBoundingBox)
{
    if (getNode())
    {
        osg::BoundingSphere boundingSphere;

        OSG_INFO<<" CameraManipulator::computeHomePosition("<<camera<<", "<<useBoundingBox<<")"<<std::endl;

        if (useBoundingBox)
        {
            // compute bounding box
            // (bounding box computes model center more precisely than bounding sphere)
            osg::ComputeBoundsVisitor cbVisitor;
            getNode()->accept(cbVisitor);
            osg::BoundingBox &bb = cbVisitor.getBoundingBox();

            if (bb.valid()) boundingSphere.expandBy(bb);
            else boundingSphere = getNode()->getBound();
        }
        else
        {
            // compute bounding sphere
            boundingSphere = getNode()->getBound();
        }

        OSG_INFO<<"    boundingSphere.center() = ("<<boundingSphere.center()<<")"<<std::endl;
        OSG_INFO<<"    boundingSphere.radius() = "<<boundingSphere.radius()<<std::endl;

        double radius = osg::maximum(double(boundingSphere.radius()), 1e-6);

        // set dist to default
        double dist = 3.5f * radius;

        if (camera)
        {

            // try to compute dist from frustum
            double left,right,bottom,top,zNear,zFar;
            if (camera->getProjectionMatrixAsFrustum(left,right,bottom,top,zNear,zFar))
            {
                double vertical2 = fabs(right - left) / zNear / 2.;
                double horizontal2 = fabs(top - bottom) / zNear / 2.;
                double dim = horizontal2 < vertical2 ? horizontal2 : vertical2;
                double viewAngle = atan2(dim,1.);
                dist = radius / sin(viewAngle);
            }
            else
            {
                // try to compute dist from ortho
                if (camera->getProjectionMatrixAsOrtho(left,right,bottom,top,zNear,zFar))
                {
                    dist = fabs(zFar - zNear) / 2.;
                }
            }
        }

        // set home position
        setHomePosition(boundingSphere.center() + osg::Vec3d(0.0,-dist,0.0f),
                        boundingSphere.center(),
                        osg::Vec3d(0.0f,0.0f,1.0f),
                        _autoComputeHomePosition);
    }
}
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "libmesh/quadrature_clough.h"
#include "libmesh/quadrature_gauss.h"

namespace libMesh
{

void QClough::init_2D(const ElemType _type,
                      unsigned int p)
{
#if LIBMESH_DIM > 1
  QGauss gauss_rule(2, _order);
  gauss_rule.init(TRI6, p);

  //-----------------------------------------------------------------------
  // 2D quadrature rules
  switch (_type)
    {

      //---------------------------------------------
      // Triangle quadrature rules
    case TRI3:
    case TRI6:
      {
	std::vector<Point> &gausspoints = gauss_rule.get_points();
	std::vector<Real> &gaussweights = gauss_rule.get_weights();
	std::size_t numgausspts = gausspoints.size();
	_points.resize(numgausspts*3);
	_weights.resize(numgausspts*3);
        for (std::size_t i = 0; i != numgausspts; ++i)
          {
	    _points[3*i](0) = gausspoints[i](0) +
			    gausspoints[i](1) / 3.;
	    _points[3*i](1) = gausspoints[i](1) / 3.;
	    _points[3*i+1](0) = gausspoints[i](1) / 3.;
	    _points[3*i+1](1) = gausspoints[i](0) +
			    gausspoints[i](1) / 3.;
	    _points[3*i+2](0) = 1./3. +
			    gausspoints[i](0) * 2./3. -
			    gausspoints[i](1) / 3.;
	    _points[3*i+2](1) = 1./3. -
			    gausspoints[i](0) / 3. +
			    gausspoints[i](1) * 2./3.;
	    _weights[3*i] = gaussweights[i] / 3.;
	    _weights[3*i+1] = _weights[3*i];
	    _weights[3*i+2] = _weights[3*i];
          }
	return;
      }

      //---------------------------------------------
      // Unsupported type
    default:
      {
	libMesh::err << "Element type not supported!:" << _type << std::endl;
	libmesh_error();
      }
    }

  libmesh_error();

  return;

#endif
}

} // namespace libMesh
<commit_msg>Changes in quadrature_clough_2D.C for -Wshadow.<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2012 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "libmesh/quadrature_clough.h"
#include "libmesh/quadrature_gauss.h"

namespace libMesh
{

void QClough::init_2D(const ElemType type_in,
                      unsigned int p)
{
#if LIBMESH_DIM > 1
  QGauss gauss_rule(2, _order);
  gauss_rule.init(TRI6, p);

  //-----------------------------------------------------------------------
  // 2D quadrature rules
  switch (type_in)
    {

      //---------------------------------------------
      // Triangle quadrature rules
    case TRI3:
    case TRI6:
      {
	std::vector<Point> &gausspoints = gauss_rule.get_points();
	std::vector<Real> &gaussweights = gauss_rule.get_weights();
	std::size_t numgausspts = gausspoints.size();
	_points.resize(numgausspts*3);
	_weights.resize(numgausspts*3);
        for (std::size_t i = 0; i != numgausspts; ++i)
          {
	    _points[3*i](0) = gausspoints[i](0) +
			    gausspoints[i](1) / 3.;
	    _points[3*i](1) = gausspoints[i](1) / 3.;
	    _points[3*i+1](0) = gausspoints[i](1) / 3.;
	    _points[3*i+1](1) = gausspoints[i](0) +
			    gausspoints[i](1) / 3.;
	    _points[3*i+2](0) = 1./3. +
			    gausspoints[i](0) * 2./3. -
			    gausspoints[i](1) / 3.;
	    _points[3*i+2](1) = 1./3. -
			    gausspoints[i](0) / 3. +
			    gausspoints[i](1) * 2./3.;
	    _weights[3*i] = gaussweights[i] / 3.;
	    _weights[3*i+1] = _weights[3*i];
	    _weights[3*i+2] = _weights[3*i];
          }
	return;
      }

      //---------------------------------------------
      // Unsupported type
    default:
      {
	libMesh::err << "Element type not supported!:" << type_in << std::endl;
	libmesh_error();
      }
    }

  libmesh_error();

  return;

#endif
}

} // namespace libMesh
<|endoftext|>


<commit_before>#define DEBUG 1

/**
 * File    : F2.cpp
 * Author  : Kazune Takahashi
 * Created : 2019-6-2 00:47:04
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

bool dp_L[2010][2010];
bool dp_R[2010][2010];
bool W[2010][2010];

int main()
{
  int N;
  cin >> N;
  for (auto i = 1; i < N; i++)
  {
    string S;
    cin >> S;
    for (auto j = 0; j < i; j++)
    {
      if (S[j] == '1')
      {
        W[i][j] = true;
        W[j][i] = false;
      }
      else
      {
        W[i][j] = false;
        W[j][i] = true;
      }
    }
  }
  for (auto i = 0; i < N; i++)
  {
    dp_L[i][i] = true;
    dp_R[i][i] = true;
  }
  for (auto n = 1; n < N; n++)
  {
    for (auto a = 0; a + n < N; a++)
    {
      int b = a + n;
      dp_L[a][b] = false;
      for (auto c = a + 1; c < b; c++)
      {
        if (dp_L[a][c] && dp_L[c][b])
        {
          dp_L[a][b] = true;
          break;
        }
      }
      if (!dp_L[a][b] && W[a][b])
      {
        for (auto c = a; c < b; c++)
        {
          if (dp_L[a][c] && dp_R[c + 1][b])
          {
            dp_L[a][b] = true;
            break;
          }
        }
      }
      dp_R[a][b] = false;
      for (auto c = a + 1; c < b; c++)
      {
        if (dp_R[a][c] && dp_R[c][b])
        {
          dp_R[a][b] = true;
          break;
        }
      }
      if (!dp_R[a][b] && W[b][a])
      {
        for (auto c = a; c < b; c++)
        {
          if (dp_L[a][c] && dp_R[c + 1][b])
          {
            dp_R[a][b] = true;
            break;
          }
        }
      }
#if DEBUG == 1
      cerr << "dp_L[" << a << "][" << b << "] = " << dp_L[a][b] << endl;
      cerr << "dp_R[" << a << "][" << b << "] = " << dp_R[a][b] << endl;
#endif
    }
  }
  int ans = 0;
  for (auto i = 0; i < N; i++)
  {
    if (dp_L[0][i] && dp_R[i][N - 1])
    {
      ans++;
    }
  }
  cout << ans << endl;
}<commit_msg>submit F2.cpp to 'F - Random Tournament' (m-solutions2019) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1

/**
 * File    : F2.cpp
 * Author  : Kazune Takahashi
 * Created : 2019-6-2 00:47:04
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

typedef long long ll;

bool dp_L[2010][2010];
bool dp_R[2010][2010];
bool W[2010][2010];

int main()
{
  int N;
  cin >> N;
  for (auto i = 1; i < N; i++)
  {
    string S;
    cin >> S;
    for (auto j = 0; j < i; j++)
    {
      if (S[j] == '1')
      {
        W[i][j] = true;
        W[j][i] = false;
      }
      else
      {
        W[i][j] = false;
        W[j][i] = true;
      }
    }
  }
  for (auto i = 0; i < N; i++)
  {
    dp_L[i][i] = true;
    dp_R[i][i] = true;
  }
  for (auto n = 1; n < N; n++)
  {
    for (auto a = 0; a + n < N; a++)
    {
      int b = a + n;
      dp_L[a][b] = false;
      for (auto c = a + 1; c < b; c++)
      {
        if (dp_L[a][c] && dp_L[c][b])
        {
          dp_L[a][b] = true;
          break;
        }
      }
      if (!dp_L[a][b] && W[a][b])
      {
        for (auto c = a; c < b; c++)
        {
          if (dp_L[a][c] && dp_R[c + 1][b])
          {
            dp_L[a][b] = true;
            break;
          }
        }
      }
      dp_R[a][b] = false;
      for (auto c = a + 1; c < b; c++)
      {
        if (dp_R[a][c] && dp_R[c][b])
        {
          dp_R[a][b] = true;
          break;
        }
      }
      if (!dp_R[a][b] && W[b][a])
      {
        for (auto c = a; c < b; c++)
        {
          if (dp_L[a][c] && dp_R[c + 1][b])
          {
            dp_R[a][b] = true;
            break;
          }
        }
      }
#if DEBUG == 1
      cerr << "dp_L[" << a << "][" << b << "] = " << dp_L[a][b] << endl;
      cerr << "dp_R[" << a << "][" << b << "] = " << dp_R[a][b] << endl;
#endif
    }
  }
  int ans = 0;
  for (auto i = 0; i < N; i++)
  {
    if (dp_R[0][i] && dp_L[i][N - 1])
    {
      ans++;
    }
  }
  cout << ans << endl;
}<|endoftext|>