<commit_before>/*
  Automaton.cpp - Library for creating and running Finite State Machines.
  Published under the MIT License (MIT), Copyright (c) 2015, J.P. van der Landen
*/

#include "Automaton.h"

void atm_timer_millis::set( uint32_t v ) {
    value = v;
}

void atm_timer_micros::set( uint32_t v ) {
    value = v;
}

int atm_timer_millis::expired( BaseMachine * machine ) {
    return value == ATM_TIMER_OFF ? 0 : millis() - machine->state_millis >= value;
}

int atm_timer_micros::expired( Machine * machine ) {
    return value == ATM_TIMER_OFF ? 0 : micros() - machine->state_micros >= value;
}

void atm_counter::set( uint16_t v )
{
    value = v;
}

uint16_t atm_counter::decrement( void )
{
    return value > 0 && value != ATM_COUNTER_OFF ? --value : 0;
}

uint8_t atm_counter::expired()
{
    return value == ATM_COUNTER_OFF ? 0 : ( value > 0 ? 0 : 1 );
}

Machine & Machine::state(state_t state)
{
    next = state;
    last_trigger = -1;
    flags &= ~ATM_SLEEP_FLAG;
    return *this;
}

state_t Machine::state()
{
    return current;
}

Machine & Machine::trigger( int evt )
{
    cycle();
    if ( current > -1 ) {
        int new_state = read_state( state_table + ( current * state_width ) + evt + ATM_ON_EXIT + 1 );
        if ( new_state > -1 ) {
	      state( new_state );
          last_trigger = evt;
          return *this;
        }
    }
    return *this;
}

Machine & Machine::trace( Stream * stream, swcb_sym_t callback, const char sym_s[], const char sym_e[] )
{
    callback_trace = callback;
    stream_trace = stream;
    sym_states = sym_s;
    sym_events = sym_e;
    return *this;
}

Machine & Machine::label( const char label[] )
{
    inst_label = label;
    return *this;
}

int8_t Machine::priority()
{
    return prio;
}

Machine & Machine::priority( int8_t priority )
{
    prio = priority;
    return *this;
}

uint8_t BaseMachine::sleep( int8_t v /* = 1 */ )
{
    if ( v > -1 )
        flags = v ? flags | ATM_SLEEP_FLAG : flags & ~ATM_SLEEP_FLAG;
    return ( flags & ATM_SLEEP_FLAG ) > 0;
}

Machine & Machine::begin( const state_t* tbl, int width )
{
    state_table = tbl;
    state_width = ATM_ON_EXIT + width + 2;
    prio = ATM_DEFAULT_PRIO;
    if ( !inst_label ) inst_label = class_label;
    flags &= ~ATM_SLEEP_FLAG;
    return *this;
}

const char * Machine::mapSymbol( int id, const char map[] )
{
  int cnt = 0;
  int i = 0;
  if ( id == -1 ) return "*NONE*";
  if ( id ==  0 ) return map;
  while ( 1 ) {
    if ( map[i] == '\0' && ++cnt == id ) {
      i++;
      break;
    }
    i++;
  }
  return &map[i];
}

// .cycle() Executes one cycle of a state machine
Machine & Machine::cycle( uint32_t time /* = 0 */ )
{
    uint32_t cycle_start = millis();
    do {
        if ( ( flags & ( ATM_SLEEP_FLAG | ATM_CALLBACK_FLAG ) ) == 0 ) {
            cycles++;
            if ( next != -1 ) {
                action( ATM_ON_SWITCH );
                if ( callback_trace ) {
                    callback_trace( stream_trace, inst_label,
                        mapSymbol(      current, sym_states ),
                        mapSymbol(         next, sym_states ),
                        mapSymbol( last_trigger, sym_events ), millis() - state_millis, cycles );
                }
                if ( current > -1 )
                        action( read_state( state_table + ( current * state_width ) + ATM_ON_EXIT ) );
                current = next;
                next = -1;
                state_millis = millis();
                state_micros = micros();
                action( read_state( state_table + ( current * state_width ) + ATM_ON_ENTER ) );
                if ( read_state( state_table + ( current * state_width ) + ATM_ON_LOOP ) == ATM_SLEEP ) {
                      flags |= ATM_SLEEP_FLAG;
                } else {
                      flags &= ~ATM_SLEEP_FLAG;
                }
                cycles = 0;
            }
            state_t i = read_state( state_table + ( current * state_width ) + ATM_ON_LOOP );
            if ( i != -1 ) { action( i ); }
            for ( i = ATM_ON_EXIT + 1; i < state_width; i++ ) {
                if ( ( read_state( state_table + ( current * state_width ) + i ) != -1 ) && ( i == state_width - 1 || event( i - ATM_ON_EXIT - 1 ) ) ) {
                    state( read_state( state_table + ( current * state_width ) + i ) );
                    last_trigger = i - ATM_ON_EXIT - 1;
                    break;
                }
            }
        }
    } while ( millis() - cycle_start < time );
    return *this;
}

// TINY MACHINE

TinyMachine & TinyMachine::state( tiny_state_t state )
{
    next = state;
    flags &= ~ATM_SLEEP_FLAG;
    return *this;
}

tiny_state_t TinyMachine::state()
{
    return current;
}

TinyMachine & TinyMachine::trigger( int evt )
{
    cycle();
    if ( current > -1 ) {
        int new_state = tiny_read_state( state_table + ( current * state_width ) + evt + ATM_ON_EXIT + 1 );
        if ( new_state > -1 ) {
          state( new_state );
          return *this;
        }
    }
    return *this;
}

TinyMachine & TinyMachine::begin( const tiny_state_t* tbl, int width )
{
    state_table = tbl;
    state_width = ATM_ON_EXIT + width + 2;
    flags &= ~ATM_SLEEP_FLAG;
    return *this;
}

// .cycle() Executes one cycle of a state machine
TinyMachine & TinyMachine::cycle( uint32_t time /* = 0 */ )
{
    uint32_t cycle_start = millis();
    do {
        if ( ( flags & ( ATM_SLEEP_FLAG | ATM_CALLBACK_FLAG ) ) == 0 ) {
            if ( next != -1 ) {
                action( ATM_ON_SWITCH );
                if ( current > -1 )
                    action( tiny_read_state( state_table + ( current * state_width ) + ATM_ON_EXIT ) );
                current = next;
                next = -1;
                state_millis = millis();
                action( tiny_read_state( state_table + ( current * state_width ) + ATM_ON_ENTER ) );
                if ( read_state( state_table + ( current * state_width ) + ATM_ON_LOOP ) == ATM_SLEEP ) {
                      flags |= ATM_SLEEP_FLAG;
                } else {
                      flags &= ~ATM_SLEEP_FLAG;
                }
            }
            tiny_state_t i = tiny_read_state( state_table + ( current * state_width ) + ATM_ON_LOOP );
            if ( i != -1 ) { action( i ); }
            for ( i = ATM_ON_EXIT + 1; i < state_width; i++ ) {
                if ( ( tiny_read_state( state_table + ( current * state_width ) + i ) != -1 ) && ( i == state_width - 1 || event( i - ATM_ON_EXIT - 1 ) ) ) {
                    state( tiny_read_state( state_table + ( current * state_width ) + i ) );
                    break;
                }
            }
        }
    } while ( millis() - cycle_start < time );
    return *this;
}

// FACTORY

// .calibrate() Distributes the machines in the inventory to the appropriate priority queues
void Factory::calibrate( void )
{
    // Reset all priority queues to empty lists
    for ( int8_t i = 0; i < ATM_NO_OF_QUEUES; i++ )
        priority_root[i] = 0;
    // Walk the inventory list that contains all state machines in this factory
    Machine * m = inventory_root;
    while ( m ) {
        // Prepend every machine to the appropriate priority queue
        if ( m->prio < ATM_NO_OF_QUEUES ) {
            m->priority_next = priority_root[m->prio];
            priority_root[m->prio] = m;
        }
        m = m->inventory_next;
    }
    recalibrate = 0;
}

// .run( q ) Traverses an individual priority queue and cycles the machines in it once (except for queue 0)
void Factory::run( int q )
{
    Machine * m = priority_root[ q ];
    while ( m ) {
        if ( q > 0 && ( m->flags & ( ATM_SLEEP_FLAG | ATM_CALLBACK_FLAG ) ) == 0 ) m->cycle();
        // Request a recalibrate if the prio field doesn't match the current queue
        if ( m->prio != q ) recalibrate = 1;
        // Move to the next machine
        m = m->priority_next;
    }
}

// .add( machine ) Adds a state machine to the factory by prepending it to the inventory list
Factory & Factory::add( Machine & machine )
{
    machine.inventory_next = inventory_root;
    inventory_root = &machine;
    recalibrate = 1;
    return *this;
}

// .find() Search the factory inventory for a machine by instance label
Machine * Factory::find( const char label[] )
{
    Machine * m = inventory_root;
    while ( m ) {
        if ( strcmp( label, m->inst_label ) == 0 ) {
            return m;
        }
        m = m->inventory_next;
    }
    return 0;
}

int Factory::trigger( const char label[], int event )
{
    int r = 0;
    int l = 255;
    Machine * m = inventory_root;
    if ( label[strlen( label ) - 1 ] == '*' ) {
        l = strlen( label ) - 1;
    }
    if ( label[0] == '.' ) {
        l--;
        label++;
        while ( m ) {
            if ( strncmp( label, m->class_label, l ) == 0 ) {
                m->trigger( event );
                r++;
            }
            m = m->inventory_next;
        }
    } else {
        while ( m ) {
            if ( strncmp( label, m->inst_label, l ) == 0 ) {
                m->trigger( event );
                r++;
            }
            m = m->inventory_next;
        }
    }
    return r;
}

int Factory::state( const char label[], int state )
{
    int r = 0;
    int l = 255;
    Machine * m = inventory_root;
    if ( label[strlen( label ) - 1 ] == '*' ) {
        l = strlen( label ) - 1;
    }
    if ( label[0] == '.' ) {
        l--;
        label++;
        while ( m ) {
            if ( strncmp( label, m->class_label, l ) == 0 ) {
                m->state( state );
                r++;
            }
            m = m->inventory_next;
        }
    } else {
        while ( m ) {
            if ( strncmp( label, m->inst_label, l ) == 0 ) {
                m->state( state );
                r++;
            }
            m = m->inventory_next;
        }
    }
    return r;
}

int Factory::state( const char label[] )
{
    int r = 0;
    int l = 255;
    Machine * m = inventory_root;
    if ( label[strlen( label ) - 1 ] == '*' ) {
        l = strlen( label ) - 1;
    }
    if ( label[0] == '.' ) {
        l--;
        label++;
        while ( m ) {
            if ( strncmp( label, m->class_label, l ) == 0 ) {
                r += m->state();
            }
            m = m->inventory_next;
        }
    } else {
        while ( m ) {
            if ( strncmp( label, m->inst_label, l ) == 0 ) {
                r += m->state();
            }
            m = m->inventory_next;
        }
    }
    return r;
}

// .cycle() executes one factory cycle (runs all priority queues a certain number of times)
Factory & Factory::cycle( uint32_t time /* = 0 */ )
{
    uint32_t cycle_start = millis();
    if ( recalibrate ) calibrate();
    do {
        run( 1 ); run( 2 );	run( 1 ); run( 2 );
        run( 1 ); run( 3 );	run( 1 ); run( 4 );
        run( 1 ); run( 2 );	run( 1 ); run( 3 );
        run( 1 ); run( 2 );	run( 1 ); run( 0 );
    } while ( millis() - cycle_start < time );
    return  *this;
}

// TINYFACTORY - A factory for TinyMachines

// .add( machine ) Adds a state machine to the factory by prepending it to the inventory list
TinyFactory & TinyFactory::add( TinyMachine & machine )
{
    machine.inventory_next = inventory_root;
    inventory_root = &machine;
    return *this;
}

// .cycle() executes the factory cycle
TinyFactory &  TinyFactory::cycle( uint32_t time /* = 0 */ )
{
    TinyMachine * m;
    uint32_t cycle_start = millis();
    do {
        m = inventory_root;
        while ( m ) {
            if ( ( m->flags & ( ATM_SLEEP_FLAG | ATM_CALLBACK_FLAG ) ) == 0 ) m->cycle();
            // Move to the next machine
            m = m->inventory_next;
            //if ( time > 0 && ( millis() - cycle_start ) < time ) break;
        }
    } while ( ( millis() - cycle_start ) < time );
    return *this;
}

<commit_msg>Small trigger() fix<commit_after>/*
  Automaton.cpp - Library for creating and running Finite State Machines.
  Published under the MIT License (MIT), Copyright (c) 2015, J.P. van der Landen
*/

#include "Automaton.h"

void atm_timer_millis::set( uint32_t v ) {
    value = v;
}

void atm_timer_micros::set( uint32_t v ) {
    value = v;
}

int atm_timer_millis::expired( BaseMachine * machine ) {
    return value == ATM_TIMER_OFF ? 0 : millis() - machine->state_millis >= value;
}

int atm_timer_micros::expired( Machine * machine ) {
    return value == ATM_TIMER_OFF ? 0 : micros() - machine->state_micros >= value;
}

void atm_counter::set( uint16_t v )
{
    value = v;
}

uint16_t atm_counter::decrement( void )
{
    return value > 0 && value != ATM_COUNTER_OFF ? --value : 0;
}

uint8_t atm_counter::expired()
{
    return value == ATM_COUNTER_OFF ? 0 : ( value > 0 ? 0 : 1 );
}

Machine & Machine::state(state_t state)
{
    next = state;
    last_trigger = -1;
    flags &= ~ATM_SLEEP_FLAG;
    return *this;
}

state_t Machine::state()
{
    return current;
}

Machine & Machine::trigger( int evt )
{
    cycle();
    if ( current > -1 ) {
        int new_state = read_state( state_table + ( current * state_width ) + evt + ATM_ON_EXIT + 1 );
        if ( new_state > -1 ) {
	      state( new_state );
          last_trigger = evt;
        }
    }
    return *this;
}

Machine & Machine::trace( Stream * stream, swcb_sym_t callback, const char sym_s[], const char sym_e[] )
{
    callback_trace = callback;
    stream_trace = stream;
    sym_states = sym_s;
    sym_events = sym_e;
    return *this;
}

Machine & Machine::label( const char label[] )
{
    inst_label = label;
    return *this;
}

int8_t Machine::priority()
{
    return prio;
}

Machine & Machine::priority( int8_t priority )
{
    prio = priority;
    return *this;
}

uint8_t BaseMachine::sleep( int8_t v /* = 1 */ )
{
    if ( v > -1 )
        flags = v ? flags | ATM_SLEEP_FLAG : flags & ~ATM_SLEEP_FLAG;
    return ( flags & ATM_SLEEP_FLAG ) > 0;
}

Machine & Machine::begin( const state_t* tbl, int width )
{
    state_table = tbl;
    state_width = ATM_ON_EXIT + width + 2;
    prio = ATM_DEFAULT_PRIO;
    if ( !inst_label ) inst_label = class_label;
    flags &= ~ATM_SLEEP_FLAG;
    return *this;
}

const char * Machine::mapSymbol( int id, const char map[] )
{
  int cnt = 0;
  int i = 0;
  if ( id == -1 ) return "*NONE*";
  if ( id ==  0 ) return map;
  while ( 1 ) {
    if ( map[i] == '\0' && ++cnt == id ) {
      i++;
      break;
    }
    i++;
  }
  return &map[i];
}

// .cycle() Executes one cycle of a state machine
Machine & Machine::cycle( uint32_t time /* = 0 */ )
{
    uint32_t cycle_start = millis();
    do {
        if ( ( flags & ( ATM_SLEEP_FLAG | ATM_CALLBACK_FLAG ) ) == 0 ) {
            cycles++;
            if ( next != -1 ) {
                action( ATM_ON_SWITCH );
                if ( callback_trace ) {
                    callback_trace( stream_trace, inst_label,
                        mapSymbol(      current, sym_states ),
                        mapSymbol(         next, sym_states ),
                        mapSymbol( last_trigger, sym_events ), millis() - state_millis, cycles );
                }
                if ( current > -1 )
                        action( read_state( state_table + ( current * state_width ) + ATM_ON_EXIT ) );
                current = next;
                next = -1;
                state_millis = millis();
                state_micros = micros();
                action( read_state( state_table + ( current * state_width ) + ATM_ON_ENTER ) );
                if ( read_state( state_table + ( current * state_width ) + ATM_ON_LOOP ) == ATM_SLEEP ) {
                      flags |= ATM_SLEEP_FLAG;
                } else {
                      flags &= ~ATM_SLEEP_FLAG;
                }
                cycles = 0;
            }
            state_t i = read_state( state_table + ( current * state_width ) + ATM_ON_LOOP );
            if ( i != -1 ) { action( i ); }
            for ( i = ATM_ON_EXIT + 1; i < state_width; i++ ) {
                if ( ( read_state( state_table + ( current * state_width ) + i ) != -1 ) && ( i == state_width - 1 || event( i - ATM_ON_EXIT - 1 ) ) ) {
                    state( read_state( state_table + ( current * state_width ) + i ) );
                    last_trigger = i - ATM_ON_EXIT - 1;
                    break;
                }
            }
        }
    } while ( millis() - cycle_start < time );
    return *this;
}

// TINY MACHINE

TinyMachine & TinyMachine::state( tiny_state_t state )
{
    next = state;
    flags &= ~ATM_SLEEP_FLAG;
    return *this;
}

tiny_state_t TinyMachine::state()
{
    return current;
}

TinyMachine & TinyMachine::trigger( int evt )
{
    cycle();
    if ( current > -1 ) {
        int new_state = tiny_read_state( state_table + ( current * state_width ) + evt + ATM_ON_EXIT + 1 );
        if ( new_state > -1 ) {
          state( new_state );
        }
    }
    return *this;
}

TinyMachine & TinyMachine::begin( const tiny_state_t* tbl, int width )
{
    state_table = tbl;
    state_width = ATM_ON_EXIT + width + 2;
    flags &= ~ATM_SLEEP_FLAG;
    return *this;
}

// .cycle() Executes one cycle of a state machine
TinyMachine & TinyMachine::cycle( uint32_t time /* = 0 */ )
{
    uint32_t cycle_start = millis();
    do {
        if ( ( flags & ( ATM_SLEEP_FLAG | ATM_CALLBACK_FLAG ) ) == 0 ) {
            if ( next != -1 ) {
                action( ATM_ON_SWITCH );
                if ( current > -1 )
                    action( tiny_read_state( state_table + ( current * state_width ) + ATM_ON_EXIT ) );
                current = next;
                next = -1;
                state_millis = millis();
                action( tiny_read_state( state_table + ( current * state_width ) + ATM_ON_ENTER ) );
                if ( read_state( state_table + ( current * state_width ) + ATM_ON_LOOP ) == ATM_SLEEP ) {
                      flags |= ATM_SLEEP_FLAG;
                } else {
                      flags &= ~ATM_SLEEP_FLAG;
                }
            }
            tiny_state_t i = tiny_read_state( state_table + ( current * state_width ) + ATM_ON_LOOP );
            if ( i != -1 ) { action( i ); }
            for ( i = ATM_ON_EXIT + 1; i < state_width; i++ ) {
                if ( ( tiny_read_state( state_table + ( current * state_width ) + i ) != -1 ) && ( i == state_width - 1 || event( i - ATM_ON_EXIT - 1 ) ) ) {
                    state( tiny_read_state( state_table + ( current * state_width ) + i ) );
                    break;
                }
            }
        }
    } while ( millis() - cycle_start < time );
    return *this;
}

// FACTORY

// .calibrate() Distributes the machines in the inventory to the appropriate priority queues
void Factory::calibrate( void )
{
    // Reset all priority queues to empty lists
    for ( int8_t i = 0; i < ATM_NO_OF_QUEUES; i++ )
        priority_root[i] = 0;
    // Walk the inventory list that contains all state machines in this factory
    Machine * m = inventory_root;
    while ( m ) {
        // Prepend every machine to the appropriate priority queue
        if ( m->prio < ATM_NO_OF_QUEUES ) {
            m->priority_next = priority_root[m->prio];
            priority_root[m->prio] = m;
        }
        m = m->inventory_next;
    }
    recalibrate = 0;
}

// .run( q ) Traverses an individual priority queue and cycles the machines in it once (except for queue 0)
void Factory::run( int q )
{
    Machine * m = priority_root[ q ];
    while ( m ) {
        if ( q > 0 && ( m->flags & ( ATM_SLEEP_FLAG | ATM_CALLBACK_FLAG ) ) == 0 ) m->cycle();
        // Request a recalibrate if the prio field doesn't match the current queue
        if ( m->prio != q ) recalibrate = 1;
        // Move to the next machine
        m = m->priority_next;
    }
}

// .add( machine ) Adds a state machine to the factory by prepending it to the inventory list
Factory & Factory::add( Machine & machine )
{
    machine.inventory_next = inventory_root;
    inventory_root = &machine;
    recalibrate = 1;
    return *this;
}

// .find() Search the factory inventory for a machine by instance label
Machine * Factory::find( const char label[] )
{
    Machine * m = inventory_root;
    while ( m ) {
        if ( strcmp( label, m->inst_label ) == 0 ) {
            return m;
        }
        m = m->inventory_next;
    }
    return 0;
}

int Factory::trigger( const char label[], int event )
{
    int r = 0;
    int l = 255;
    Machine * m = inventory_root;
    if ( label[strlen( label ) - 1 ] == '*' ) {
        l = strlen( label ) - 1;
    }
    if ( label[0] == '.' ) {
        l--;
        label++;
        while ( m ) {
            if ( strncmp( label, m->class_label, l ) == 0 ) {
                m->trigger( event );
                r++;
            }
            m = m->inventory_next;
        }
    } else {
        while ( m ) {
            if ( strncmp( label, m->inst_label, l ) == 0 ) {
                m->trigger( event );
                r++;
            }
            m = m->inventory_next;
        }
    }
    return r;
}

int Factory::state( const char label[], int state )
{
    int r = 0;
    int l = 255;
    Machine * m = inventory_root;
    if ( label[strlen( label ) - 1 ] == '*' ) {
        l = strlen( label ) - 1;
    }
    if ( label[0] == '.' ) {
        l--;
        label++;
        while ( m ) {
            if ( strncmp( label, m->class_label, l ) == 0 ) {
                m->state( state );
                r++;
            }
            m = m->inventory_next;
        }
    } else {
        while ( m ) {
            if ( strncmp( label, m->inst_label, l ) == 0 ) {
                m->state( state );
                r++;
            }
            m = m->inventory_next;
        }
    }
    return r;
}

int Factory::state( const char label[] )
{
    int r = 0;
    int l = 255;
    Machine * m = inventory_root;
    if ( label[strlen( label ) - 1 ] == '*' ) {
        l = strlen( label ) - 1;
    }
    if ( label[0] == '.' ) {
        l--;
        label++;
        while ( m ) {
            if ( strncmp( label, m->class_label, l ) == 0 ) {
                r += m->state();
            }
            m = m->inventory_next;
        }
    } else {
        while ( m ) {
            if ( strncmp( label, m->inst_label, l ) == 0 ) {
                r += m->state();
            }
            m = m->inventory_next;
        }
    }
    return r;
}

// .cycle() executes one factory cycle (runs all priority queues a certain number of times)
Factory & Factory::cycle( uint32_t time /* = 0 */ )
{
    uint32_t cycle_start = millis();
    if ( recalibrate ) calibrate();
    do {
        run( 1 ); run( 2 );	run( 1 ); run( 2 );
        run( 1 ); run( 3 );	run( 1 ); run( 4 );
        run( 1 ); run( 2 );	run( 1 ); run( 3 );
        run( 1 ); run( 2 );	run( 1 ); run( 0 );
    } while ( millis() - cycle_start < time );
    return  *this;
}

// TINYFACTORY - A factory for TinyMachines

// .add( machine ) Adds a state machine to the factory by prepending it to the inventory list
TinyFactory & TinyFactory::add( TinyMachine & machine )
{
    machine.inventory_next = inventory_root;
    inventory_root = &machine;
    return *this;
}

// .cycle() executes the factory cycle
TinyFactory &  TinyFactory::cycle( uint32_t time /* = 0 */ )
{
    TinyMachine * m;
    uint32_t cycle_start = millis();
    do {
        m = inventory_root;
        while ( m ) {
            if ( ( m->flags & ( ATM_SLEEP_FLAG | ATM_CALLBACK_FLAG ) ) == 0 ) m->cycle();
            // Move to the next machine
            m = m->inventory_next;
            //if ( time > 0 && ( millis() - cycle_start ) < time ) break;
        }
    } while ( ( millis() - cycle_start ) < time );
    return *this;
}

<|endoftext|>


<commit_before>// Copyright (c) 2013, Matthew Harvey. All rights reserved.

#include "transaction_dialog.hpp"
#include "account.hpp"
#include "date.hpp"
#include "date_validator.hpp"
#include "decimal_text_ctrl.hpp"
#include "decimal_validator.hpp"
#include "finformat.hpp"
#include "locale.hpp"
#include <jewel/debug_log.hpp>
#include <jewel/decimal.hpp>
#include <wx/button.h>
#include <wx/calctrl.h>
#include <wx/dialog.h>
#include <wx/event.h>
#include <wx/msgdlg.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/string.h>
#include <wx/textctrl.h>
#include <cassert>
#include <iostream>
#include <vector>

using jewel::Decimal;
using std::endl;
using std::vector;

namespace phatbooks
{
namespace gui
{

BEGIN_EVENT_TABLE(TransactionDialog, wxDialog)
	EVT_BUTTON
	(	wxID_OK,
		TransactionDialog::on_ok_button_click
	)
END_EVENT_TABLE()

TransactionDialog::TransactionDialog(vector<Account> const& p_accounts):
	wxDialog
	(	0,  // Null parent implies top-level window is parent
		wxID_ANY,
		"New transaction",
		wxDefaultPosition,
		wxDefaultSize
		// , wxRESIZE_BORDER
	),
	m_top_sizer(0),
	m_date_ctrl(0),
	m_ok_button(0),
	m_cancel_button(0)
{
	assert (m_amount_boxes.empty());

	// We construct m_ok_button first as we want to be able to refer to its
	// size when sizing certain other controls below. But we will not add
	// the OK button to m_top_sizer till later.
	m_ok_button = new wxButton
	(	this,
		wxID_OK,
		wxString("&OK"),
		wxDefaultPosition,
		wxDefaultSize
	);

	m_top_sizer = new wxFlexGridSizer(p_accounts.size() + 2, 2, 0, 0);
	typedef vector<Account>::size_type Size;
	Size const sz = p_accounts.size();
	for (Size id = s_min_entry_row_id, i = 0 ; i != sz; ++i, ++id)
	{
		Account const account = p_accounts[i];
		wxStaticText* account_name_text = new wxStaticText
		(	this,
			id,
			bstring_to_wx(account.name()),
			wxDefaultPosition,
			wxDefaultSize
		);
		Decimal::places_type const precision =
			account.commodity().precision();
		DecimalTextCtrl* entry_ctrl = new DecimalTextCtrl
		(	this,
			id,
			m_ok_button->GetSize(),
			precision
		);
		int base_flag = wxLEFT | wxRIGHT;
		if (i == 0) base_flag |= wxTOP;
		m_top_sizer->Add(account_name_text, 1, base_flag | wxALIGN_LEFT, 16);
		m_top_sizer->Add(entry_ctrl, 1, base_flag | wxALIGN_RIGHT, 16);
		m_amount_boxes.push_back(entry_ctrl);
	}

	m_date_ctrl = new wxTextCtrl
	(	this,
		s_date_ctrl_id,
		wxEmptyString,
		wxDefaultPosition,
		m_ok_button->GetSize(),
		wxALIGN_RIGHT,
		DateValidator(today())
	);

	m_top_sizer->AddStretchSpacer();
	m_top_sizer->
		Add(m_date_ctrl, 1, wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxTOP, 16);

	m_cancel_button = new wxButton
	(	this,
		wxID_CANCEL,
		wxString("&Cancel"),
		wxDefaultPosition,
		wxDefaultSize
	);
	m_top_sizer->Add
	(	m_cancel_button,
		1,
		wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM | wxTOP,
		16
	);
	m_top_sizer->Add
	(	m_ok_button,
		1,
		wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxBOTTOM | wxTOP,
		16
	);

	SetSizer(m_top_sizer);
	m_top_sizer->Fit(this);
	m_top_sizer->SetSizeHints(this);
	Layout();
	CentreOnScreen();
}

void
TransactionDialog::on_ok_button_click(wxCommandEvent& event)
{
	(void)event;  // Silence compiler warning re. unused parameter.
	if (Validate() && TransferDataFromWindow())
	{
		assert (IsModal());
		if (is_balanced())
		{
			// TODO Actually post the transaction or etc.
			EndModal(wxID_OK);
		}
		else
		{
			wxMessageBox("Transaction does not balance.");
		}
	}
	else
	{
		JEWEL_DEBUG_LOG << "Problem validating and/or transferring data from window." << endl;
	}
	return;
}

bool
TransactionDialog::is_balanced() const
{
	Decimal balance(0, 0);
	vector<DecimalTextCtrl*>::size_type i = 0;
	vector<DecimalTextCtrl*>::size_type const sz = m_amount_boxes.size();
	for ( ; i != sz; ++i)
	{
		balance += wx_to_decimal(m_amount_boxes[i]->GetValue(), locale());
	}
	return balance == Decimal(0, 0);
}

}  // namespace gui
}  // namespace phatbooks
<commit_msg>Continued working on TransactionDialog. This columns now have titles, and there are boxes to enter Entry comments.<commit_after>// Copyright (c) 2013, Matthew Harvey. All rights reserved.

#include "transaction_dialog.hpp"
#include "account.hpp"
#include "date.hpp"
#include "date_validator.hpp"
#include "decimal_text_ctrl.hpp"
#include "decimal_validator.hpp"
#include "finformat.hpp"
#include "locale.hpp"
#include <jewel/debug_log.hpp>
#include <jewel/decimal.hpp>
#include <wx/button.h>
#include <wx/calctrl.h>
#include <wx/dialog.h>
#include <wx/event.h>
#include <wx/msgdlg.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/string.h>
#include <wx/textctrl.h>
#include <cassert>
#include <iostream>
#include <vector>

using jewel::Decimal;
using std::endl;
using std::vector;

namespace phatbooks
{
namespace gui
{

BEGIN_EVENT_TABLE(TransactionDialog, wxDialog)
	EVT_BUTTON
	(	wxID_OK,
		TransactionDialog::on_ok_button_click
	)
END_EVENT_TABLE()

TransactionDialog::TransactionDialog(vector<Account> const& p_accounts):
	wxDialog
	(	0,  // Null parent implies top-level window is parent
		wxID_ANY,
		"New transaction",
		wxDefaultPosition,
		wxDefaultSize
		// , wxRESIZE_BORDER
	),
	m_top_sizer(0),
	m_date_ctrl(0),
	m_ok_button(0),
	m_cancel_button(0)
{
	assert (m_amount_boxes.empty());

	// We construct m_ok_button first as we want to be able to refer to its
	// size when sizing certain other controls below. But we will not add
	// the OK button to m_top_sizer till later.
	m_ok_button = new wxButton
	(	this,
		wxID_OK,
		wxString("&OK"),
		wxDefaultPosition,
		wxDefaultSize
	);
	wxSize const ok_button_size = m_ok_button->GetSize();

	// Top sizer
	m_top_sizer = new wxFlexGridSizer(p_accounts.size() + 3, 3, 0, 0);

	// Column titles
	wxStaticText* header0 = new wxStaticText(this, wxID_ANY, "Account");
	wxStaticText* header1 = new wxStaticText(this, wxID_ANY, "Comment");
	wxStaticText* header2 = new wxStaticText(this, wxID_ANY, "Amount");
	m_top_sizer->Add(header0, 2, wxLEFT | wxRIGHT | wxBOTTOM, 10);
	m_top_sizer->Add(header1, 3, wxLEFT | wxRIGHT | wxBOTTOM, 10);
	m_top_sizer->Add(header2, 2, wxLEFT | wxRIGHT | wxBOTTOM, 10);

	// Rows for entering Entry details
	typedef vector<Account>::size_type Size;
	Size const sz = p_accounts.size();
	for (Size id = s_min_entry_row_id, i = 0 ; i != sz; ++i, ++id)
	{
		Account const account = p_accounts[i];
		wxStaticText* account_name_text = new wxStaticText
		(	this,
			id,
			bstring_to_wx(account.name()),
			wxDefaultPosition,
			wxDefaultSize
		);
		wxSize const account_name_text_size = account_name_text->GetSize();
		wxTextCtrl* comment_ctrl = new wxTextCtrl
		(	this,
			id,
			wxEmptyString,
			wxDefaultPosition,
			wxSize(ok_button_size.x * 2, account_name_text_size.y * 1.2),
			wxALIGN_LEFT
		);
		Decimal::places_type const precision =
			account.commodity().precision();
		DecimalTextCtrl* entry_ctrl = new DecimalTextCtrl
		(	this,
			id,
			wxSize(ok_button_size.x, account_name_text_size.y * 1.2),
			precision
		);
		int base_flag = wxLEFT | wxRIGHT;
		if (i == 0) base_flag |= wxTOP;
		m_top_sizer->Add(account_name_text, 2, base_flag | wxALIGN_LEFT, 10);
		m_top_sizer->Add(comment_ctrl, 3, base_flag | wxALIGN_LEFT, 10);
		m_top_sizer->Add(entry_ctrl, 2, base_flag | wxALIGN_RIGHT, 10);
		m_amount_boxes.push_back(entry_ctrl);
	}

	// Date control
	m_date_ctrl = new wxTextCtrl
	(	this,
		s_date_ctrl_id,
		wxEmptyString,
		wxDefaultPosition,
		m_ok_button->GetSize(),
		wxALIGN_RIGHT,
		DateValidator(today())
	);

	m_top_sizer->AddStretchSpacer();
	m_top_sizer->
		Add(m_date_ctrl, 2, wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxTOP, 10);
	m_top_sizer->AddStretchSpacer();

	// Cancel and OK buttons
	m_cancel_button = new wxButton
	(	this,
		wxID_CANCEL,
		wxString("&Cancel"),
		wxDefaultPosition,
		wxDefaultSize
	);
	m_top_sizer->Add
	(	m_cancel_button,
		1,
		wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM | wxTOP,
		10
	);
	m_top_sizer->AddStretchSpacer();
	m_top_sizer->Add
	(	m_ok_button,
		1,
		wxALIGN_RIGHT | wxLEFT | wxRIGHT | wxBOTTOM | wxTOP,
		10
	);

	// "Admin"
	SetSizer(m_top_sizer);
	m_top_sizer->Fit(this);
	m_top_sizer->SetSizeHints(this);
	Layout();
	CentreOnScreen();
}

void
TransactionDialog::on_ok_button_click(wxCommandEvent& event)
{
	(void)event;  // Silence compiler warning re. unused parameter.
	if (Validate() && TransferDataFromWindow())
	{
		assert (IsModal());
		if (is_balanced())
		{
			// TODO Actually post the transaction or etc.
			EndModal(wxID_OK);
		}
		else
		{
			wxMessageBox("Transaction does not balance.");
		}
	}
	else
	{
		JEWEL_DEBUG_LOG << "Problem validating and/or transferring data from window." << endl;
	}
	return;
}

bool
TransactionDialog::is_balanced() const
{
	Decimal balance(0, 0);
	vector<DecimalTextCtrl*>::size_type i = 0;
	vector<DecimalTextCtrl*>::size_type const sz = m_amount_boxes.size();
	for ( ; i != sz; ++i)
	{
		balance += wx_to_decimal(m_amount_boxes[i]->GetValue(), locale());
	}
	return balance == Decimal(0, 0);
}

}  // namespace gui
}  // namespace phatbooks
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Cloudius Systems
 */

#pragma once

#include "core/iostream.hh"
#include "core/fstream.hh"
#include "types.hh"
#include "compress.hh"

namespace sstables {

class file_writer {
    output_stream<char> _out;
    size_t _offset = 0;
public:
    file_writer(lw_shared_ptr<file> f, size_t buffer_size = 8192)
        : _out(make_file_output_stream(std::move(f), buffer_size)) {}

    file_writer(output_stream<char>&& out)
        : _out(std::move(out)) {}

    virtual future<> write(const char* buf, size_t n) {
        _offset += n;
        return _out.write(buf, n);
    }
    virtual future<> write(const bytes& s) {
        _offset += s.size();
        return _out.write(s);
    }
    future<> flush() {
        return _out.flush();
    }
    future<> close() {
        return _out.close();
    }
    size_t offset() {
        return _offset;
    }

    friend class checksummed_file_writer;
};

class checksummed_file_writer : public file_writer {
    checksum _c;
    uint32_t _per_chunk_checksum;
    uint32_t _full_checksum;
    bool _checksum_file;
private:
    void close_checksum() {
        if (!_checksum_file) {
            return;
        }
        if ((_offset % _c.chunk_size) != 0) {
            _c.checksums.push_back(_per_chunk_checksum);
        }
    }

    // NOTE: adler32 is the algorithm used to compute checksum.
    // compute a checksum per chunk of size _c.chunk_size
    void compute_checksum(const char* buf, size_t n) {
        if (!_checksum_file) {
            _offset += n;
            _full_checksum = checksum_adler32(_full_checksum, buf, n);
            return;
        }

        size_t remaining = n;
        while (remaining) {
            // available means available space in the current chunk.
            size_t available = _c.chunk_size - (_offset % _c.chunk_size);

            if (remaining < available) {
                _offset += remaining;
                _per_chunk_checksum = checksum_adler32(_per_chunk_checksum, buf, remaining);
                remaining = 0;
            } else {
                _offset += available;
                _per_chunk_checksum = checksum_adler32(_per_chunk_checksum, buf, available);
                _full_checksum = checksum_adler32_combine(_full_checksum, _per_chunk_checksum, _c.chunk_size);
                _c.checksums.push_back(_per_chunk_checksum);
                _per_chunk_checksum = init_checksum_adler32();
                buf += available;
                remaining -= available;
            }
        }
    }
public:
    checksummed_file_writer(lw_shared_ptr<file> f, size_t buffer_size = 8192, bool checksum_file = false)
            : file_writer(std::move(f), buffer_size) {
        _checksum_file = checksum_file;
        _c.chunk_size = DEFAULT_CHUNK_SIZE;
        _per_chunk_checksum = init_checksum_adler32();
        _full_checksum = init_checksum_adler32();
    }

    virtual future<> write(const char* buf, size_t n) {
        compute_checksum(buf, n);
        return _out.write(buf, n);
    }
    virtual future<> write(const bytes& s) {
        compute_checksum(reinterpret_cast<const char*>(s.c_str()), s.size());
        return _out.write(s);
    }
    checksum& finalize_checksum() {
        close_checksum();
        return _c;
    }
    uint32_t full_checksum() {
        if (!_checksum_file) {
            return _full_checksum;
        }
        return checksum_adler32_combine(_full_checksum, _per_chunk_checksum, _offset % _c.chunk_size);
    }
};

// compressed_file_data_sink_impl works as a filter for a file output stream,
// where the buffer flushed will be compressed and its checksum computed, then
// the result passed to a regular output stream.
class compressed_file_data_sink_impl : public data_sink_impl {
    output_stream<char> _out;
    sstables::compression* _compression_metadata;
    size_t _pos = 0;
public:
    compressed_file_data_sink_impl(lw_shared_ptr<file> f, sstables::compression* cm, file_output_stream_options options)
            : _out(make_file_output_stream(std::move(f), options))
            , _compression_metadata(cm) {}

    future<> put(net::packet data) { abort(); }
    virtual future<> put(temporary_buffer<char> buf) override {
        auto output_len = _compression_metadata->compress_max_size(buf.size());
        // account space for checksum that goes after compressed data.
        temporary_buffer<char> compressed(output_len + 4);

        // compress flushed data.
        auto len = _compression_metadata->compress(buf.get(), buf.size(), compressed.get_write(), output_len);
        if (len > output_len) {
            throw std::runtime_error("possible overflow during compression");
        }

        _compression_metadata->offsets.elements.push_back(_pos);
        // account compressed data + 32-bit checksum.
        _pos += len + 4;
        _compression_metadata->set_compressed_file_length(_pos);
        // total length of the uncompressed data.
        _compression_metadata->data_len += buf.size();

        // compute 32-bit checksum for compressed data.
        uint32_t per_chunk_checksum = checksum_adler32(compressed.get(), len);
        _compression_metadata->update_full_checksum(per_chunk_checksum, len);

        // write checksum into buffer after compressed data.
        *unaligned_cast<uint32_t*>(compressed.get_write() + len) = htonl(per_chunk_checksum);

        compressed.trim(len + 4);

        auto f = _out.write(compressed.get(), compressed.size());
        return f.then([compressed = std::move(compressed)] {});
    }
    virtual future<> close() {
        return _out.close();
    }
};

class compressed_file_data_sink : public data_sink {
public:
    compressed_file_data_sink(lw_shared_ptr<file> f, sstables::compression* cm, file_output_stream_options options)
        : data_sink(std::make_unique<compressed_file_data_sink_impl>(
                std::move(f), cm, options)) {}
};

static inline output_stream<char> make_compressed_file_output_stream(lw_shared_ptr<file> f, sstables::compression* cm) {
    file_output_stream_options options;
    // buffer of output stream is set to chunk length, because flush must
    // happen every time a chunk was filled up.
    options.buffer_size = cm->uncompressed_chunk_length();
    return output_stream<char>(compressed_file_data_sink(std::move(f), cm, options), options.buffer_size);
}

}
<commit_msg>sstables: add missing virtual destructor<commit_after>/*
 * Copyright 2015 Cloudius Systems
 */

#pragma once

#include "core/iostream.hh"
#include "core/fstream.hh"
#include "types.hh"
#include "compress.hh"

namespace sstables {

class file_writer {
    output_stream<char> _out;
    size_t _offset = 0;
public:
    file_writer(lw_shared_ptr<file> f, size_t buffer_size = 8192)
        : _out(make_file_output_stream(std::move(f), buffer_size)) {}

    file_writer(output_stream<char>&& out)
        : _out(std::move(out)) {}

    virtual ~file_writer() = default;
    file_writer(file_writer&&) = default;

    virtual future<> write(const char* buf, size_t n) {
        _offset += n;
        return _out.write(buf, n);
    }
    virtual future<> write(const bytes& s) {
        _offset += s.size();
        return _out.write(s);
    }
    future<> flush() {
        return _out.flush();
    }
    future<> close() {
        return _out.close();
    }
    size_t offset() {
        return _offset;
    }

    friend class checksummed_file_writer;
};

class checksummed_file_writer : public file_writer {
    checksum _c;
    uint32_t _per_chunk_checksum;
    uint32_t _full_checksum;
    bool _checksum_file;
private:
    void close_checksum() {
        if (!_checksum_file) {
            return;
        }
        if ((_offset % _c.chunk_size) != 0) {
            _c.checksums.push_back(_per_chunk_checksum);
        }
    }

    // NOTE: adler32 is the algorithm used to compute checksum.
    // compute a checksum per chunk of size _c.chunk_size
    void compute_checksum(const char* buf, size_t n) {
        if (!_checksum_file) {
            _offset += n;
            _full_checksum = checksum_adler32(_full_checksum, buf, n);
            return;
        }

        size_t remaining = n;
        while (remaining) {
            // available means available space in the current chunk.
            size_t available = _c.chunk_size - (_offset % _c.chunk_size);

            if (remaining < available) {
                _offset += remaining;
                _per_chunk_checksum = checksum_adler32(_per_chunk_checksum, buf, remaining);
                remaining = 0;
            } else {
                _offset += available;
                _per_chunk_checksum = checksum_adler32(_per_chunk_checksum, buf, available);
                _full_checksum = checksum_adler32_combine(_full_checksum, _per_chunk_checksum, _c.chunk_size);
                _c.checksums.push_back(_per_chunk_checksum);
                _per_chunk_checksum = init_checksum_adler32();
                buf += available;
                remaining -= available;
            }
        }
    }
public:
    checksummed_file_writer(lw_shared_ptr<file> f, size_t buffer_size = 8192, bool checksum_file = false)
            : file_writer(std::move(f), buffer_size) {
        _checksum_file = checksum_file;
        _c.chunk_size = DEFAULT_CHUNK_SIZE;
        _per_chunk_checksum = init_checksum_adler32();
        _full_checksum = init_checksum_adler32();
    }

    virtual future<> write(const char* buf, size_t n) {
        compute_checksum(buf, n);
        return _out.write(buf, n);
    }
    virtual future<> write(const bytes& s) {
        compute_checksum(reinterpret_cast<const char*>(s.c_str()), s.size());
        return _out.write(s);
    }
    checksum& finalize_checksum() {
        close_checksum();
        return _c;
    }
    uint32_t full_checksum() {
        if (!_checksum_file) {
            return _full_checksum;
        }
        return checksum_adler32_combine(_full_checksum, _per_chunk_checksum, _offset % _c.chunk_size);
    }
};

// compressed_file_data_sink_impl works as a filter for a file output stream,
// where the buffer flushed will be compressed and its checksum computed, then
// the result passed to a regular output stream.
class compressed_file_data_sink_impl : public data_sink_impl {
    output_stream<char> _out;
    sstables::compression* _compression_metadata;
    size_t _pos = 0;
public:
    compressed_file_data_sink_impl(lw_shared_ptr<file> f, sstables::compression* cm, file_output_stream_options options)
            : _out(make_file_output_stream(std::move(f), options))
            , _compression_metadata(cm) {}

    future<> put(net::packet data) { abort(); }
    virtual future<> put(temporary_buffer<char> buf) override {
        auto output_len = _compression_metadata->compress_max_size(buf.size());
        // account space for checksum that goes after compressed data.
        temporary_buffer<char> compressed(output_len + 4);

        // compress flushed data.
        auto len = _compression_metadata->compress(buf.get(), buf.size(), compressed.get_write(), output_len);
        if (len > output_len) {
            throw std::runtime_error("possible overflow during compression");
        }

        _compression_metadata->offsets.elements.push_back(_pos);
        // account compressed data + 32-bit checksum.
        _pos += len + 4;
        _compression_metadata->set_compressed_file_length(_pos);
        // total length of the uncompressed data.
        _compression_metadata->data_len += buf.size();

        // compute 32-bit checksum for compressed data.
        uint32_t per_chunk_checksum = checksum_adler32(compressed.get(), len);
        _compression_metadata->update_full_checksum(per_chunk_checksum, len);

        // write checksum into buffer after compressed data.
        *unaligned_cast<uint32_t*>(compressed.get_write() + len) = htonl(per_chunk_checksum);

        compressed.trim(len + 4);

        auto f = _out.write(compressed.get(), compressed.size());
        return f.then([compressed = std::move(compressed)] {});
    }
    virtual future<> close() {
        return _out.close();
    }
};

class compressed_file_data_sink : public data_sink {
public:
    compressed_file_data_sink(lw_shared_ptr<file> f, sstables::compression* cm, file_output_stream_options options)
        : data_sink(std::make_unique<compressed_file_data_sink_impl>(
                std::move(f), cm, options)) {}
};

static inline output_stream<char> make_compressed_file_output_stream(lw_shared_ptr<file> f, sstables::compression* cm) {
    file_output_stream_options options;
    // buffer of output stream is set to chunk length, because flush must
    // happen every time a chunk was filled up.
    options.buffer_size = cm->uncompressed_chunk_length();
    return output_stream<char>(compressed_file_data_sink(std::move(f), cm, options), options.buffer_size);
}

}
<|endoftext|>


<commit_before>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// Copyright (C) 1998-2003 Fast Search & Transfer ASA
// Copyright (C) 2003 Overture Services Norway AS

#include <vespa/fastos/fastos.h>
#include <vespa/log/log.h>
LOG_SETUP("fdispatch");

#include <vespa/searchcore/fdispatch/program/fdispatch.h>

#include <vespa/searchcore/fdispatch/common/perftask.h>

#include <vespa/vespalib/net/state_server.h>
#include <vespa/vespalib/net/simple_health_producer.h>
#include <vespa/vespalib/net/simple_metrics_producer.h>

#include <vespa/searchlib/expression/forcelink.hpp>
#include <vespa/searchlib/aggregation/forcelink.hpp>

#include <vespa/vespalib/util/signalhandler.h>

using fdispatch::Fdispatch;
using vespa::config::search::core::FdispatchrcConfig;

extern char FastS_VersionTag[];

class FastS_FDispatchApp : public FastOS_Application
{
private:
    FastS_FDispatchApp(const FastS_FDispatchApp &);
    FastS_FDispatchApp& operator=(const FastS_FDispatchApp &);

protected:
    vespalib::string _configId;

    bool CheckShutdownFlags ()
    {
        return (vespalib::SignalHandler::INT.check() || vespalib::SignalHandler::TERM.check());
    }

    void Usage(void);
    bool GetOptions(int *exitCode);

public:
    int Main();
    FastS_FDispatchApp(void);
    ~FastS_FDispatchApp(void);
};

FastS_FDispatchApp::FastS_FDispatchApp(void)
{
}

/**
 * Main program for a dispatcher node.
 */
int
FastS_FDispatchApp::Main()
{
    int exitCode;

    forcelink_searchlib_expression();
    forcelink_searchlib_aggregation();

    if (!GetOptions(&exitCode)) {
        EV_STOPPING("fdispatch",
                    (exitCode == 0) ? "clean shutdown" : "error");
        return exitCode;
    }

    exitCode = 0;

    EV_STARTED("fdispatch");

    vespalib::SignalHandler::INT.hook();
    vespalib::SignalHandler::TERM.hook();
    vespalib::SignalHandler::PIPE.ignore();

    std::unique_ptr<Fdispatch> myfdispatch;
    try {
        myfdispatch.reset(new Fdispatch(_configId));
    } catch (std::exception &ex) {
        LOG(error, "getting config: %s", (const char *) ex.what());
        exitCode = 1;
        EV_STOPPING("fdispatch", "error getting config");
        return exitCode;
    }

    try {
#ifdef RLIMIT_NOFILE
    struct rlimit  curlim;
    getrlimit(RLIMIT_NOFILE, &curlim);
    if (curlim.rlim_cur != (rlim_t)RLIM_INFINITY)
        LOG(debug, "Max number of open files = %d", (int) curlim.rlim_cur);
    else
        LOG(debug, "Max number of open files = unlimited");
    if (curlim.rlim_cur >= 64) {
    } else {
        LOG(error,
            "CRITICAL: Too few file descriptors available: %d",
            (int)curlim.rlim_cur);
        throw std::runtime_error("CRITICAL: Too few file descriptors available");
    }
#endif
#ifdef RLIMIT_DATA
    getrlimit(RLIMIT_DATA, &curlim);
    if (curlim.rlim_cur != (rlim_t)RLIM_INFINITY &&
        curlim.rlim_cur < (rlim_t) (400 * 1024 * 1024)) {
        if (curlim.rlim_max == (rlim_t)RLIM_INFINITY)
            curlim.rlim_cur = (rlim_t) (400 * 1024 * 1024);
        else
            curlim.rlim_cur = curlim.rlim_max;
        setrlimit(RLIMIT_DATA, &curlim);
        getrlimit(RLIMIT_DATA, &curlim);
    }
    if (curlim.rlim_cur != (rlim_t)RLIM_INFINITY)
        LOG(debug,
            "VERBOSE: Max data segment size = %dM",
            (int) ((curlim.rlim_cur + 512 * 1024) / (1024 * 1024)));
    else
        LOG(debug, "VERBOSE: Max data segment size = unlimited");
#endif

        if (!myfdispatch->Init()) {
            throw std::runtime_error("myfdispatch->Init(" + _configId + ") failed");
        }
        if (myfdispatch->Failed()) {
            throw std::runtime_error("myfdispatch->Failed()");
        }
        { // main loop scope
            vespalib::SimpleHealthProducer health;
            vespalib::SimpleMetricsProducer metrics;
            vespalib::StateServer stateServer(myfdispatch->getHealthPort(), health, metrics, myfdispatch->getComponentConfig());
            FastS_PerfTask perfTask(*myfdispatch, 300.0);
            while (!CheckShutdownFlags()) {
                if (myfdispatch->Failed()) {
                    throw std::runtime_error("myfdispatch->Failed()");
                }
                FastOS_Thread::Sleep(1000);
#ifndef NO_MONITOR_LATENCY_CHECK
                if (!myfdispatch->CheckTempFail())
                    break;
#endif
            }
        } // main loop scope
        if (myfdispatch->Failed()) {
            throw std::runtime_error("myfdispatch->Failed()");
        }
    } catch (std::exception &e) {
        LOG(error, "got exception during init: %s", e.what());
        exitCode = 1;
    } catch (...) {
        LOG(error, "got exception during init");
        exitCode = 1;
    }

    LOG(debug, "Deleting fdispatch");
    myfdispatch.reset();
    LOG(debug, "COMPLETION: Exiting");
    EV_STOPPING("fdispatch",
                (exitCode == 0) ? "clean shutdown" : "error");
    return exitCode;
}

bool
FastS_FDispatchApp::GetOptions(int *exitCode)
{
    int errflg = 0;
    int c;
    const char *optArgument;
    int longopt_index;	/* Shows which long option was used */
    static struct option longopts[] = {
        { "config-id", 1, NULL, 0 },
        { NULL, 0, NULL, 0 }
    };
    enum longopts_enum {
        LONGOPT_CONFIGID
    };
    int optIndex = 1;    // Start with argument 1
    while ((c = GetOptLong("c:",
                           optArgument,
                           optIndex,
                           longopts,
                           &longopt_index)) != -1) {
        switch (c) {
        case 0:
            switch (longopt_index) {
            case LONGOPT_CONFIGID:
                break;
            default:
                if (optArgument != NULL)
                    LOG(info,
                        "longopt %s with arg %s",
                        longopts[longopt_index].name, optArgument);
                else
                    LOG(info,
                        "longopt %s",
                        longopts[longopt_index].name);
                break;
            }
            break;
        case 'c':
            _configId = optArgument;
            break;
        case '?':
        default:
            errflg++;
        }
    }
    if (errflg) {
        Usage();
        *exitCode = 1;
        return false;
    }
    return true;
}

void
FastS_FDispatchApp::Usage(void)
{
    printf("FAST Search - fdispatch %s\n", FastS_VersionTag);
    printf("\n"
           "USAGE:\n"
           "\n"
           "fdispatch [-C fsroot] [-c rcFile] [-P preHttPort] [-V] [-w FFF]\n"
           "\n"
           "  -C fsroot      Fast Search's root directory\n"
           "                 (default /usr/fastsearch/fastserver4)\n"
           "  -c rcFile      fdispatchrc file (default FASTSEARCHROOT/etc/fdispatchrc)\n"
           "  -P preHttPort  pre-allocated socket number for http service\n"
           "  -V             show version and exit\n"
           "  -w FFF         hex value (max 32 bit) for the Verbose mask\n"
           "\n");
}

FastS_FDispatchApp::~FastS_FDispatchApp(void)
{
}

int
main(int argc, char **argv)
{
    FastS_FDispatchApp app;
    int retval;

    // Maybe this should be handeled by FastOS
    setlocale(LC_ALL, "C");

    retval = app.Entry(argc, argv);

    return retval;
}
<commit_msg>1 - error -> warning 2 - bracing 3 - std::this_thread::sleep_for<commit_after>// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// Copyright (C) 1998-2003 Fast Search & Transfer ASA
// Copyright (C) 2003 Overture Services Norway AS

#include <vespa/fastos/fastos.h>
#include <vespa/log/log.h>
LOG_SETUP("fdispatch");

#include <vespa/searchcore/fdispatch/program/fdispatch.h>

#include <vespa/searchcore/fdispatch/common/perftask.h>

#include <vespa/vespalib/net/state_server.h>
#include <vespa/vespalib/net/simple_health_producer.h>
#include <vespa/vespalib/net/simple_metrics_producer.h>

#include <vespa/searchlib/expression/forcelink.hpp>
#include <vespa/searchlib/aggregation/forcelink.hpp>

#include <vespa/vespalib/util/signalhandler.h>

using fdispatch::Fdispatch;
using vespa::config::search::core::FdispatchrcConfig;
using namespace std::literals;

extern char FastS_VersionTag[];

class FastS_FDispatchApp : public FastOS_Application
{
private:
    FastS_FDispatchApp(const FastS_FDispatchApp &);
    FastS_FDispatchApp& operator=(const FastS_FDispatchApp &);

protected:
    vespalib::string _configId;

    bool CheckShutdownFlags () const {
        return (vespalib::SignalHandler::INT.check() || vespalib::SignalHandler::TERM.check());
    }

    void Usage(void);
    bool GetOptions(int *exitCode);

public:
    int Main();
    FastS_FDispatchApp(void);
    ~FastS_FDispatchApp(void);
};

FastS_FDispatchApp::FastS_FDispatchApp(void)
{
}

/**
 * Main program for a dispatcher node.
 */
int
FastS_FDispatchApp::Main()
{
    int exitCode;

    forcelink_searchlib_expression();
    forcelink_searchlib_aggregation();

    if (!GetOptions(&exitCode)) {
        EV_STOPPING("fdispatch", (exitCode == 0) ? "clean shutdown" : "error");
        return exitCode;
    }

    exitCode = 0;

    EV_STARTED("fdispatch");

    vespalib::SignalHandler::INT.hook();
    vespalib::SignalHandler::TERM.hook();
    vespalib::SignalHandler::PIPE.ignore();

    std::unique_ptr<Fdispatch> myfdispatch;
    try {
        myfdispatch.reset(new Fdispatch(_configId));
    } catch (std::exception &ex) {
        LOG(error, "getting config: %s", (const char *) ex.what());
        exitCode = 1;
        EV_STOPPING("fdispatch", "error getting config");
        return exitCode;
    }

    try {
#ifdef RLIMIT_NOFILE
    struct rlimit  curlim;
    getrlimit(RLIMIT_NOFILE, &curlim);
    if (curlim.rlim_cur != (rlim_t)RLIM_INFINITY) {
        LOG(debug, "Max number of open files = %d", (int) curlim.rlim_cur);
    } else {
        LOG(debug, "Max number of open files = unlimited");
    }
    if (curlim.rlim_cur >= 64) {
    } else {
        LOG(error, "CRITICAL: Too few file descriptors available: %d", (int)curlim.rlim_cur);
        throw std::runtime_error("CRITICAL: Too few file descriptors available");
    }
#endif
#ifdef RLIMIT_DATA
    getrlimit(RLIMIT_DATA, &curlim);
    if (curlim.rlim_cur != (rlim_t)RLIM_INFINITY &&
        curlim.rlim_cur < (rlim_t) (400 * 1024 * 1024)) {
        if (curlim.rlim_max == (rlim_t)RLIM_INFINITY) {
            curlim.rlim_cur = (rlim_t) (400 * 1024 * 1024);
        } else {
            curlim.rlim_cur = curlim.rlim_max;
        }
        setrlimit(RLIMIT_DATA, &curlim);
        getrlimit(RLIMIT_DATA, &curlim);
    }
    if (curlim.rlim_cur != (rlim_t)RLIM_INFINITY) {
        LOG(debug,
            "VERBOSE: Max data segment size = %dM",
            (int) ((curlim.rlim_cur + 512 * 1024) / (1024 * 1024)));
    } else {
        LOG(debug, "VERBOSE: Max data segment size = unlimited");
    }
#endif

        if (!myfdispatch->Init()) {
            throw std::runtime_error("myfdispatch->Init(" + _configId + ") failed");
        }
        if (myfdispatch->Failed()) {
            throw std::runtime_error("myfdispatch->Failed()");
        }
        { // main loop scope
            vespalib::SimpleHealthProducer health;
            vespalib::SimpleMetricsProducer metrics;
            vespalib::StateServer stateServer(myfdispatch->getHealthPort(), health, metrics, myfdispatch->getComponentConfig());
            FastS_PerfTask perfTask(*myfdispatch, 300.0);
            while (!CheckShutdownFlags()) {
                if (myfdispatch->Failed()) {
                    throw std::runtime_error("myfdispatch->Failed()");
                }
                std::this_thread::sleep_for(100ms);
#ifndef NO_MONITOR_LATENCY_CHECK
                if (!myfdispatch->CheckTempFail())
                    break;
#endif
            }
        } // main loop scope
        if (myfdispatch->Failed()) {
            throw std::runtime_error("myfdispatch->Failed()");
        }
    } catch (std::runtime_error &e) {
        LOG(warning, "got std::runtime_error during init: %s", e.what());
        exitCode = 1;
    } catch (std::exception &e) {
        LOG(error, "got exception during init: %s", e.what());
        exitCode = 1;
    } catch (...) {
        LOG(error, "got exception during init");
        exitCode = 1;
    }

    LOG(debug, "Deleting fdispatch");
    myfdispatch.reset();
    LOG(debug, "COMPLETION: Exiting");
    EV_STOPPING("fdispatch", (exitCode == 0) ? "clean shutdown" : "error");
    return exitCode;
}

bool
FastS_FDispatchApp::GetOptions(int *exitCode)
{
    int errflg = 0;
    int c;
    const char *optArgument;
    int longopt_index;	/* Shows which long option was used */
    static struct option longopts[] = {
        { "config-id", 1, NULL, 0 },
        { NULL, 0, NULL, 0 }
    };
    enum longopts_enum {
        LONGOPT_CONFIGID
    };
    int optIndex = 1;    // Start with argument 1
    while ((c = GetOptLong("c:", optArgument, optIndex, longopts, &longopt_index)) != -1) {
        switch (c) {
        case 0:
            switch (longopt_index) {
            case LONGOPT_CONFIGID:
                break;
            default:
                if (optArgument != NULL) {
                    LOG(info, "longopt %s with arg %s", longopts[longopt_index].name, optArgument);
                } else {
                    LOG(info, "longopt %s", longopts[longopt_index].name);
                }
                break;
            }
            break;
        case 'c':
            _configId = optArgument;
            break;
        case '?':
        default:
            errflg++;
        }
    }
    if (errflg) {
        Usage();
        *exitCode = 1;
        return false;
    }
    return true;
}

void
FastS_FDispatchApp::Usage(void)
{
    printf("FAST Search - fdispatch %s\n", FastS_VersionTag);
    printf("\n"
           "USAGE:\n"
           "\n"
           "fdispatch [-C fsroot] [-c rcFile] [-P preHttPort] [-V] [-w FFF]\n"
           "\n"
           "  -C fsroot      Fast Search's root directory\n"
           "                 (default /usr/fastsearch/fastserver4)\n"
           "  -c rcFile      fdispatchrc file (default FASTSEARCHROOT/etc/fdispatchrc)\n"
           "  -P preHttPort  pre-allocated socket number for http service\n"
           "  -V             show version and exit\n"
           "  -w FFF         hex value (max 32 bit) for the Verbose mask\n"
           "\n");
}

FastS_FDispatchApp::~FastS_FDispatchApp(void)
{
}

int
main(int argc, char **argv)
{
    FastS_FDispatchApp app;
    int retval;

    // Maybe this should be handeled by FastOS
    setlocale(LC_ALL, "C");

    retval = app.Entry(argc, argv);

    return retval;
}
<|endoftext|>


<commit_before>#include <StdAfx.h>
#include <UI/Controls/SortList/SortHeader.h>
#include <UI/UIFunctions.h>
#include <core/utility/output.h>

namespace controls::sortlistctrl
{
	CSortHeader::CSortHeader() : m_bTooltipDisplayed(false)
	{
		m_hwndTip = nullptr;
		m_hwndParent = nullptr;
		ZeroMemory(&m_ti, sizeof(TOOLINFO));
	}

	BEGIN_MESSAGE_MAP(CSortHeader, CHeaderCtrl)
	ON_MESSAGE(WM_MFCMAPI_SAVECOLUMNORDERHEADER, msgOnSaveColumnOrder)
#pragma warning(push)
#pragma warning(disable : 26454)
	ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
#pragma warning(pop)
	END_MESSAGE_MAP()

	_Check_return_ bool CSortHeader::Init(_In_ CHeaderCtrl* pHeader, _In_ HWND hwndParent)
	{
		if (!pHeader) return false;

		if (!SubclassWindow(pHeader->GetSafeHwnd()))
		{
			output::DebugPrint(
				output::dbgLevel::CreateDialog, L"CSortHeader::Init Unable to subclass existing header!\n");
			return false;
		}
		m_hwndParent = hwndParent;
		m_bTooltipDisplayed = false;

		RegisterHeaderTooltip();

		return true;
	}

	void CSortHeader::RegisterHeaderTooltip()
	{
		if (!m_hwndTip)
		{
			m_hwndTip = EC_D(
				HWND,
				CreateWindowEx(
					WS_EX_TOPMOST,
					TOOLTIPS_CLASS,
					nullptr,
					TTS_NOPREFIX | TTS_ALWAYSTIP,
					CW_USEDEFAULT,
					CW_USEDEFAULT,
					CW_USEDEFAULT,
					CW_USEDEFAULT,
					m_hWnd,
					nullptr,
					AfxGetInstanceHandle(),
					nullptr));

			if (m_hwndTip)
			{
				EC_B_S(::SetWindowPos(m_hwndTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE));

				m_ti.cbSize = sizeof(TOOLINFO);
				m_ti.uFlags = TTF_TRACK | TTF_IDISHWND;
				m_ti.hwnd = m_hWnd;
				m_ti.uId = reinterpret_cast<UINT_PTR>(m_hWnd);
				m_ti.hinst = AfxGetInstanceHandle();
				m_ti.lpszText = L"";

				EC_B_S(::SendMessage(m_hwndTip, TTM_ADDTOOL, 0, LPARAM(&m_ti)));
				EC_B_S(::SendMessage(m_hwndTip, TTM_SETMAXTIPWIDTH, 0, LPARAM(500)));
			}
		}
	}

	LRESULT CSortHeader::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
	{
		if (m_hwndTip)
		{
			switch (message)
			{
			case WM_ERASEBKGND:
			{
				return true;
			}
			case WM_MOUSEMOVE:
				// This covers the case where we move from one header to another, but don't leave the control
				if (m_bTooltipDisplayed)
				{
					HDHITTESTINFO hdHitTestInfo = {0};
					hdHitTestInfo.pt.x = GET_X_LPARAM(lParam);
					hdHitTestInfo.pt.y = GET_Y_LPARAM(lParam);

					WC_B_S(::SendMessage(m_hWnd, HDM_HITTEST, 0, reinterpret_cast<LPARAM>(&hdHitTestInfo)));
					if (!(hdHitTestInfo.flags & HHT_ONHEADER))
					{
						// We were displaying a tooltip, but we're now on empty space in the header. Turn it off.
						EC_B_S(::SendMessage(m_hwndTip, TTM_TRACKACTIVATE, false, reinterpret_cast<LPARAM>(&m_ti)));
						m_bTooltipDisplayed = false;
					}
				}
				else
				{
					TRACKMOUSEEVENT tmEvent = {0};
					tmEvent.cbSize = sizeof(TRACKMOUSEEVENT);
					tmEvent.dwFlags = TME_HOVER;
					tmEvent.hwndTrack = m_hWnd;
					tmEvent.dwHoverTime = HOVER_DEFAULT;

					EC_B_S(TrackMouseEvent(&tmEvent));
				}

				break;
			case WM_MOUSEHOVER:
			{
				HDHITTESTINFO hdHitTestInfo = {0};
				hdHitTestInfo.pt.x = GET_X_LPARAM(lParam);
				hdHitTestInfo.pt.y = GET_Y_LPARAM(lParam);

				EC_B_S(::SendMessage(m_hWnd, HDM_HITTEST, 0, reinterpret_cast<LPARAM>(&hdHitTestInfo)));

				// We only turn on or modify our tooltip if we're on a column header
				if (hdHitTestInfo.flags & HHT_ONHEADER)
				{
					HDITEM hdItem = {0};
					hdItem.mask = HDI_LPARAM;

					EC_B_S(GetItem(hdHitTestInfo.iItem, &hdItem));

					const auto lpHeaderData = reinterpret_cast<LPHEADERDATA>(hdItem.lParam);

					// This will only display tips if we have a HeaderData structure saved
					if (lpHeaderData)
					{
						EC_B_S(::GetCursorPos(&hdHitTestInfo.pt));
						EC_B_S(::SendMessage(
							m_hwndTip,
							TTM_TRACKPOSITION,
							0,
							MAKELPARAM(hdHitTestInfo.pt.x + 10, hdHitTestInfo.pt.y + 20)));

						m_ti.lpszText = const_cast<LPWSTR>(lpHeaderData->szTipString.c_str());
						EC_B_S(::SendMessage(m_hwndTip, TTM_SETTOOLINFOW, true, reinterpret_cast<LPARAM>(&m_ti)));
						// Ask for notification when the mouse leaves the control
						TRACKMOUSEEVENT tmEvent = {0};
						tmEvent.cbSize = sizeof(TRACKMOUSEEVENT);
						tmEvent.dwFlags = TME_LEAVE;
						tmEvent.hwndTrack = m_hWnd;
						EC_B_S(TrackMouseEvent(&tmEvent));

						// Turn on the tooltip
						EC_B_S(::SendMessage(m_hwndTip, TTM_TRACKACTIVATE, true, reinterpret_cast<LPARAM>(&m_ti)));
						m_bTooltipDisplayed = true;
					}
				}
				break;
			}
			case WM_MOUSELEAVE:
				// We were displaying a tooltip, but we're now off of the header. Turn it off.
				EC_B_S(::SendMessage(m_hwndTip, TTM_TRACKACTIVATE, false, reinterpret_cast<LPARAM>(&m_ti)));
				m_bTooltipDisplayed = false;
				return NULL;
			}
		}

		return CHeaderCtrl::WindowProc(message, wParam, lParam);
	}

	// WM_MFCMAPI_SAVECOLUMNORDERHEADER
	_Check_return_ LRESULT CSortHeader::msgOnSaveColumnOrder(WPARAM /*wParam*/, LPARAM /*lParam*/)
	{
		if (m_hwndParent)
		{
			WC_B_S(::PostMessage(
				m_hwndParent,
				WM_MFCMAPI_SAVECOLUMNORDERLIST,
				reinterpret_cast<WPARAM>(nullptr),
				reinterpret_cast<LPARAM>(nullptr)));
		}
		return S_OK;
	}

	void CSortHeader::OnCustomDraw(_In_ NMHDR* pNMHDR, _In_ LRESULT* pResult) { ui::CustomDrawHeader(pNMHDR, pResult); }
} // namespace controls::sortlistctrl
<commit_msg>change flag<commit_after>#include <StdAfx.h>
#include <UI/Controls/SortList/SortHeader.h>
#include <UI/UIFunctions.h>
#include <core/utility/output.h>

namespace controls::sortlistctrl
{
	CSortHeader::CSortHeader() : m_bTooltipDisplayed(false)
	{
		m_hwndTip = nullptr;
		m_hwndParent = nullptr;
		ZeroMemory(&m_ti, sizeof(TOOLINFO));
	}

	BEGIN_MESSAGE_MAP(CSortHeader, CHeaderCtrl)
	ON_MESSAGE(WM_MFCMAPI_SAVECOLUMNORDERHEADER, msgOnSaveColumnOrder)
#pragma warning(push)
#pragma warning(disable : 26454)
	ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
#pragma warning(pop)
	END_MESSAGE_MAP()

	_Check_return_ bool CSortHeader::Init(_In_ CHeaderCtrl* pHeader, _In_ HWND hwndParent)
	{
		if (!pHeader) return false;

		if (!SubclassWindow(pHeader->GetSafeHwnd()))
		{
			output::DebugPrint(
				output::dbgLevel::UI, L"CSortHeader::Init Unable to subclass existing header!\n");
			return false;
		}
		m_hwndParent = hwndParent;
		m_bTooltipDisplayed = false;

		RegisterHeaderTooltip();

		return true;
	}

	void CSortHeader::RegisterHeaderTooltip()
	{
		if (!m_hwndTip)
		{
			m_hwndTip = EC_D(
				HWND,
				CreateWindowEx(
					WS_EX_TOPMOST,
					TOOLTIPS_CLASS,
					nullptr,
					TTS_NOPREFIX | TTS_ALWAYSTIP,
					CW_USEDEFAULT,
					CW_USEDEFAULT,
					CW_USEDEFAULT,
					CW_USEDEFAULT,
					m_hWnd,
					nullptr,
					AfxGetInstanceHandle(),
					nullptr));

			if (m_hwndTip)
			{
				EC_B_S(::SetWindowPos(m_hwndTip, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE));

				m_ti.cbSize = sizeof(TOOLINFO);
				m_ti.uFlags = TTF_TRACK | TTF_IDISHWND;
				m_ti.hwnd = m_hWnd;
				m_ti.uId = reinterpret_cast<UINT_PTR>(m_hWnd);
				m_ti.hinst = AfxGetInstanceHandle();
				m_ti.lpszText = L"";

				EC_B_S(::SendMessage(m_hwndTip, TTM_ADDTOOL, 0, LPARAM(&m_ti)));
				EC_B_S(::SendMessage(m_hwndTip, TTM_SETMAXTIPWIDTH, 0, LPARAM(500)));
			}
		}
	}

	LRESULT CSortHeader::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
	{
		if (m_hwndTip)
		{
			switch (message)
			{
			case WM_ERASEBKGND:
			{
				return true;
			}
			case WM_MOUSEMOVE:
				// This covers the case where we move from one header to another, but don't leave the control
				if (m_bTooltipDisplayed)
				{
					HDHITTESTINFO hdHitTestInfo = {0};
					hdHitTestInfo.pt.x = GET_X_LPARAM(lParam);
					hdHitTestInfo.pt.y = GET_Y_LPARAM(lParam);

					WC_B_S(::SendMessage(m_hWnd, HDM_HITTEST, 0, reinterpret_cast<LPARAM>(&hdHitTestInfo)));
					if (!(hdHitTestInfo.flags & HHT_ONHEADER))
					{
						// We were displaying a tooltip, but we're now on empty space in the header. Turn it off.
						EC_B_S(::SendMessage(m_hwndTip, TTM_TRACKACTIVATE, false, reinterpret_cast<LPARAM>(&m_ti)));
						m_bTooltipDisplayed = false;
					}
				}
				else
				{
					TRACKMOUSEEVENT tmEvent = {0};
					tmEvent.cbSize = sizeof(TRACKMOUSEEVENT);
					tmEvent.dwFlags = TME_HOVER;
					tmEvent.hwndTrack = m_hWnd;
					tmEvent.dwHoverTime = HOVER_DEFAULT;

					EC_B_S(TrackMouseEvent(&tmEvent));
				}

				break;
			case WM_MOUSEHOVER:
			{
				HDHITTESTINFO hdHitTestInfo = {0};
				hdHitTestInfo.pt.x = GET_X_LPARAM(lParam);
				hdHitTestInfo.pt.y = GET_Y_LPARAM(lParam);

				EC_B_S(::SendMessage(m_hWnd, HDM_HITTEST, 0, reinterpret_cast<LPARAM>(&hdHitTestInfo)));

				// We only turn on or modify our tooltip if we're on a column header
				if (hdHitTestInfo.flags & HHT_ONHEADER)
				{
					HDITEM hdItem = {0};
					hdItem.mask = HDI_LPARAM;

					EC_B_S(GetItem(hdHitTestInfo.iItem, &hdItem));

					const auto lpHeaderData = reinterpret_cast<LPHEADERDATA>(hdItem.lParam);

					// This will only display tips if we have a HeaderData structure saved
					if (lpHeaderData)
					{
						EC_B_S(::GetCursorPos(&hdHitTestInfo.pt));
						EC_B_S(::SendMessage(
							m_hwndTip,
							TTM_TRACKPOSITION,
							0,
							MAKELPARAM(hdHitTestInfo.pt.x + 10, hdHitTestInfo.pt.y + 20)));

						m_ti.lpszText = const_cast<LPWSTR>(lpHeaderData->szTipString.c_str());
						EC_B_S(::SendMessage(m_hwndTip, TTM_SETTOOLINFOW, true, reinterpret_cast<LPARAM>(&m_ti)));
						// Ask for notification when the mouse leaves the control
						TRACKMOUSEEVENT tmEvent = {0};
						tmEvent.cbSize = sizeof(TRACKMOUSEEVENT);
						tmEvent.dwFlags = TME_LEAVE;
						tmEvent.hwndTrack = m_hWnd;
						EC_B_S(TrackMouseEvent(&tmEvent));

						// Turn on the tooltip
						EC_B_S(::SendMessage(m_hwndTip, TTM_TRACKACTIVATE, true, reinterpret_cast<LPARAM>(&m_ti)));
						m_bTooltipDisplayed = true;
					}
				}
				break;
			}
			case WM_MOUSELEAVE:
				// We were displaying a tooltip, but we're now off of the header. Turn it off.
				EC_B_S(::SendMessage(m_hwndTip, TTM_TRACKACTIVATE, false, reinterpret_cast<LPARAM>(&m_ti)));
				m_bTooltipDisplayed = false;
				return NULL;
			}
		}

		return CHeaderCtrl::WindowProc(message, wParam, lParam);
	}

	// WM_MFCMAPI_SAVECOLUMNORDERHEADER
	_Check_return_ LRESULT CSortHeader::msgOnSaveColumnOrder(WPARAM /*wParam*/, LPARAM /*lParam*/)
	{
		if (m_hwndParent)
		{
			WC_B_S(::PostMessage(
				m_hwndParent,
				WM_MFCMAPI_SAVECOLUMNORDERLIST,
				reinterpret_cast<WPARAM>(nullptr),
				reinterpret_cast<LPARAM>(nullptr)));
		}
		return S_OK;
	}

	void CSortHeader::OnCustomDraw(_In_ NMHDR* pNMHDR, _In_ LRESULT* pResult) { ui::CustomDrawHeader(pNMHDR, pResult); }
} // namespace controls::sortlistctrl
<|endoftext|>


<commit_before>#include "WPILib.h"
#include "Commands/Command.h"
#include "Commands/ExampleCommand.h"
#include "CommandBase.h"
#include "Resources.h"

class Robot: public IterativeRobot
{
private:
	std::unique_ptr<Command> autonomousCommand;
	SendableChooser *chooser;
	Data *library;

	void RobotInit()
	{
		CommandBase::init();
		chooser = new SendableChooser();
		chooser->AddDefault("Default Auto", new ExampleCommand());
		//chooser->AddObject("My Auto", new MyAutoCommand());
		SmartDashboard::PutData("Auto Modes", chooser);
		library = &conjure::getLibrary();
	}

	/**
     * This function is called once each time the robot enters Disabled mode.
     * You can use it to reset any subsystem information you want to clear when
	 * the robot is disabled.
     */
	void DisabledInit()
	{
	}

	void DisabledPeriodic()
	{
		Scheduler::GetInstance()->Run();
	}

	/**
	 * This autonomous (along with the chooser code above) shows how to select between different autonomous modes
	 * using the dashboard. The sendable chooser code works with the Java SmartDashboard. If you prefer the LabVIEW
	 * Dashboard, remove all of the chooser code and uncomment the GetString code to get the auto name from the text box
	 * below the Gyro
	 *
	 * You can add additional auto modes by adding additional commands to the chooser code above (like the commented example)
	 * or additional comparisons to the if-else structure below with additional strings & commands.
	 */
	void AutonomousInit()
	{
		/* std::string autoSelected = SmartDashboard::GetString("Auto Selector", "Default");
		if(autoSelected == "My Auto") {
			autonomousCommand.reset(new MyAutoCommand());
		} else {
			autonomousCommand.reset(new ExampleCommand());
		} */

		autonomousCommand.reset((Command *)chooser->GetSelected());

		if (autonomousCommand != NULL)
			autonomousCommand->Start();
	}

	void AutonomousPeriodic()
	{
		Scheduler::GetInstance()->Run();
	}

	void TeleopInit()
	{
		// This makes sure that the autonomous stops running when
		// teleop starts running. If you want the autonomous to
		// continue until interrupted by another command, remove
		// this line or comment it out.
		if (autonomousCommand != NULL)
			autonomousCommand->Cancel();
	}

	void TeleopPeriodic()
	{
		Scheduler::GetInstance()->Run();
		// Call Teleop run here. Access Teleop through library
	}

	void TestPeriodic()
	{
		LiveWindow::GetInstance()->Run();
	}
};

START_ROBOT_CLASS(Robot)

<commit_msg>Call teleop run<commit_after>#include "WPILib.h"
#include "Commands/Command.h"
#include "Commands/ExampleCommand.h"
#include "CommandBase.h"
#include "Resources.h"

class Robot: public IterativeRobot
{
private:
	std::unique_ptr<Command> autonomousCommand;
	SendableChooser *chooser;
	Data *library;

	void RobotInit()
	{
		CommandBase::init();
		chooser = new SendableChooser();
		chooser->AddDefault("Default Auto", new ExampleCommand());
		//chooser->AddObject("My Auto", new MyAutoCommand());
		SmartDashboard::PutData("Auto Modes", chooser);
		library = &conjure::getLibrary();
	}

	/**
     * This function is called once each time the robot enters Disabled mode.
     * You can use it to reset any subsystem information you want to clear when
	 * the robot is disabled.
     */
	void DisabledInit()
	{
	}

	void DisabledPeriodic()
	{
		Scheduler::GetInstance()->Run();
	}

	/**
	 * This autonomous (along with the chooser code above) shows how to select between different autonomous modes
	 * using the dashboard. The sendable chooser code works with the Java SmartDashboard. If you prefer the LabVIEW
	 * Dashboard, remove all of the chooser code and uncomment the GetString code to get the auto name from the text box
	 * below the Gyro
	 *
	 * You can add additional auto modes by adding additional commands to the chooser code above (like the commented example)
	 * or additional comparisons to the if-else structure below with additional strings & commands.
	 */
	void AutonomousInit()
	{
		/* std::string autoSelected = SmartDashboard::GetString("Auto Selector", "Default");
		if(autoSelected == "My Auto") {
			autonomousCommand.reset(new MyAutoCommand());
		} else {
			autonomousCommand.reset(new ExampleCommand());
		} */

		autonomousCommand.reset((Command *)chooser->GetSelected());

		if (autonomousCommand != NULL)
			autonomousCommand->Start();
	}

	void AutonomousPeriodic()
	{
		Scheduler::GetInstance()->Run();
	}

	void TeleopInit()
	{
		// This makes sure that the autonomous stops running when
		// teleop starts running. If you want the autonomous to
		// continue until interrupted by another command, remove
		// this line or comment it out.
		if (autonomousCommand != NULL)
			autonomousCommand->Cancel();
	}

	void TeleopPeriodic()
	{
		Scheduler::GetInstance()->Run();
		// Call Teleop run here.
		library->getTele().run();
	}

	void TestPeriodic()
	{
		LiveWindow::GetInstance()->Run();
	}
};

START_ROBOT_CLASS(Robot)

<|endoftext|>


<commit_before>#include <iostream>
#include <sys/time.h>
#include "bmt.hpp"
#include <cassert>
#include <cstdio>
#include <vector>
#include <numeric>
#include <unistd.h>
#include <algorithm>

int getTimeDiff ( const struct timeval& aStart,
    const struct timeval& aEnd ) {

  return (aEnd.tv_sec - aStart.tv_sec) * 1000000  +
    (aEnd.tv_usec - aStart.tv_usec ) ;
}

int printHelpMessage ( char **argv ) {

  printf("%s -t [type] -o [operation_type] -s [start] -e [end] \n", argv[0] ) ;
  printf("type -> o : odbc  / g : gpec precompiler \n") ;
  printf("operation_type -> i : insert / s : select / d : delete / u : update\n" ) ;
  return 0 ;
}

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

  struct timeval sStartTime, sEndTime ;
  std::vector <int> sStore;

  int param_opt ;

  char sOperation;
  char sType;
  int  sStart_arg = 0;
  int  sEnd_arg   = 0;
  int  sCheck = 0;
  StandardRunner *sRunner = NULL ;

  while ( (param_opt = getopt (argc, argv , "t:o:s:e:h" ) ) != -1 )  {
    switch ( param_opt ) {
      case 't' :
        sType = optarg [0]  ;
        sCheck ++;
        break;
      case 'o' :
        sOperation = optarg[0];
        sCheck ++;
        break;

      case 's' :
        sStart_arg = atoi (optarg);
        sCheck ++;
        break;

      case 'e' :
        sEnd_arg = atoi (optarg);
        sCheck ++;
        break;

      case 'h' :
        sCheck = 0;
        break;
    }
  }

  if ( sCheck != 4 ) {
    printHelpMessage (argv ) ;
    exit (0);
  }

  switch ( sType ) {
     case 'g' :
       sRunner = new GPECRunner ( "test", "test", "" ) ;
     break;
     case 'o' :
       sRunner = new ODBCRunner ( "test", "test", "" ) ;
     break;
     default :
       printf("Invalid Type !!  [o : odbc] / [g : gpec] \n") ;
       exit ( -1 ) ;
  }

  for ( int i = sStart_arg ; i < sEnd_arg + 1 ; ++i ) {

    gettimeofday (&sStartTime, NULL ) ;

    switch ( sOperation ) {
      case 'i' :

        assert ( sRunner->doInsert ( i , i + 1 ) == 0 )  ;
        break;

      case 's' :

        assert ( sRunner->doSelect ( i , i + 1 ) == 0 )  ;
        break;

      case 'd' :

        assert ( sRunner->doDelete ( i , i + 1 ) == 0 )  ;
        break;

      case 'u' :

        assert ( sRunner->doUpdate ( i , i + 1 ) == 0 )  ;
        break;
    }

    gettimeofday (&sEndTime, NULL ) ;

    int us = getTimeDiff ( sStartTime, sEndTime ) ;

    sStore.push_back ( us ) ;
  }

  std::sort ( sStore.begin(), sStore.end());

  int sum = std::accumulate(sStore.begin(), sStore.end(), 0);
  int mean = sum / sStore.size();

  printf ("Min : %d Max : %d Mean : %d ", sStore[0] , sStore[sEnd_arg - sStart_arg - 1], mean );
  double tps = (double)(sEnd_arg - sStart_arg)  / ( (double)sum / 1000000 ) ;
  printf ("TPS : %lf\n", tps ) ;

  delete sRunner;

  return 0;
}

<commit_msg>fix printing result data<commit_after>#include <iostream>
#include <sys/time.h>
#include "bmt.hpp"
#include <cassert>
#include <cstdio>
#include <vector>
#include <numeric>
#include <unistd.h>
#include <algorithm>

int getTimeDiff ( const struct timeval& aStart,
    const struct timeval& aEnd ) {

  return (aEnd.tv_sec - aStart.tv_sec) * 1000000  +
    (aEnd.tv_usec - aStart.tv_usec ) ;
}

int printHelpMessage ( char **argv ) {

  printf("%s -t [type] -o [operation_type] -s [start] -e [end] \n", argv[0] ) ;
  printf("type -> o : odbc  / g : gpec precompiler \n") ;
  printf("operation_type -> i : insert / s : select / d : delete / u : update\n" ) ;
  return 0 ;
}

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

  struct timeval sStartTime, sEndTime ;
  std::vector <int> sStore;

  int param_opt ;

  char sOperation;
  char sType;
  int  sStart_arg = 0;
  int  sEnd_arg   = 0;
  int  sCheck = 0;
  StandardRunner *sRunner = NULL ;

  while ( (param_opt = getopt (argc, argv , "t:o:s:e:h" ) ) != -1 )  {
    switch ( param_opt ) {
      case 't' :
        sType = optarg [0]  ;
        sCheck ++;
        break;
      case 'o' :
        sOperation = optarg[0];
        sCheck ++;
        break;

      case 's' :
        sStart_arg = atoi (optarg);
        sCheck ++;
        break;

      case 'e' :
        sEnd_arg = atoi (optarg);
        sCheck ++;
        break;

      case 'h' :
        sCheck = 0;
        break;
    }
  }

  if ( sCheck != 4 ) {
    printHelpMessage (argv ) ;
    exit (0);
  }

  switch ( sType ) {
     case 'g' :
       sRunner = new GPECRunner ( "test", "test", "" ) ;
     break;
     case 'o' :
       sRunner = new ODBCRunner ( "test", "test", "" ) ;
     break;
     default :
       printf("Invalid Type !!  [o : odbc] / [g : gpec] \n") ;
       exit ( -1 ) ;
  }

  for ( int i = sStart_arg ; i < sEnd_arg + 1 ; ++i ) {

    gettimeofday (&sStartTime, NULL ) ;

    switch ( sOperation ) {
      case 'i' :

        assert ( sRunner->doInsert ( i , i + 1 ) == 0 )  ;
        break;

      case 's' :

        assert ( sRunner->doSelect ( i , i + 1 ) == 0 )  ;
        break;

      case 'd' :

        assert ( sRunner->doDelete ( i , i + 1 ) == 0 )  ;
        break;

      case 'u' :

        assert ( sRunner->doUpdate ( i , i + 1 ) == 0 )  ;
        break;
    }

    gettimeofday (&sEndTime, NULL ) ;

    int us = getTimeDiff ( sStartTime, sEndTime ) ;

    sStore.push_back ( us ) ;
  }

  std::sort ( sStore.begin(), sStore.end());

  int sum = std::accumulate(sStore.begin(), sStore.end(), 0);
  int mean = sum / sStore.size();

  int p99 = sStore.size() - (sStore.size() / 100) + 1;
  int p999 = sStore.size() - (sStore.size() / 1000) + 1;

  printf ("Min latency: [%d] Max latency: [%d] Avg Latency : [%d] 99 percent latency : [%d] 99.9 percent latency : [%d]  ", sStore[0] , sStore[sEnd_arg - sStart_arg - 1], mean, sStore[p99] , sStore[p999]  );
  double tps = (double)(sEnd_arg - sStart_arg)  / ( (double)sum / 1000000 ) ;
  printf ("TPS : %lf\n", tps ) ;

  delete sRunner;

  return 0;
}

<|endoftext|>


<commit_before>#pragma once
namespace std          {
namespace experimental {
namespace parallel     {
inline namespace v1    {

class dynamic_policy
{
    private:
        union
        {
            sequential_execution_policy seq_;
            parallel_execution_policy   par_;
        };
        enum class policy_type
        {
            SEQ, PAR
        } policy_;

    public:
        dynamic_policy(const sequential_execution_policy& seq) : seq_(seq), policy_(policy_type::SEQ) {}
        dynamic_policy(const   parallel_execution_policy& par) : par_(par), policy_(policy_type::PAR) {}

        bool is_seq() const { return policy_ == policy_type::SEQ; }
        bool is_par() const { return policy_ == policy_type::PAR; }

        template<class ExecutionPolicy>
        typename enable_if<is_execution_policy<ExecutionPolicy>::value, ExecutionPolicy*>::type
        get()  __NOEXCEPT
        {
            ExecutionPolicy* dummy = nullptr;
            return get_helper(*dummy);
        }
        template<class ExecutionPolicy>
        typename enable_if<is_execution_policy<ExecutionPolicy>::value, const ExecutionPolicy*>::type
        get()  const __NOEXCEPT
        {
            ExecutionPolicy* dummy = nullptr;
            return get_helper(dummy);
        }

        // sequential_execution_policy  get_helper
        //
        sequential_execution_policy* get_helper(sequential_execution_policy*) __NOEXCEPT
        {
            return is_seq() ? &seq_ : nullptr;
        }
        const sequential_execution_policy* get_helper(sequential_execution_policy*) const __NOEXCEPT
        {
            return is_seq() ? &seq_ : nullptr;
        }

        // parallel_execution_policy  get_helper
        //
        parallel_execution_policy* get_helper(parallel_execution_policy*) __NOEXCEPT
        {
            return is_par() ? &par_ : nullptr;
        }
        const parallel_execution_policy* get_helper(parallel_execution_policy*) const __NOEXCEPT
        {
            return is_par() ? &par_ : nullptr;
        }

        // type information
        //
        const type_info& type() const __NOEXCEPT
        {
            if (is_seq()) return typeid(sequential_execution_policy);
            if (is_par()) return typeid(  parallel_execution_policy);
            return typeid(nullptr);
        }

        // algorithm dispatch
        //
        template<class Functor, class... Args>
        auto dispatch(Functor&& f, Args&&... args) const -> decltype(f(seq_, std::forward<Args>(args)...))
        {
            if (is_seq()) return f(seq_, std::forward<Args>(args)...);
            if (is_par()) return f(par_, std::forward<Args>(args)...);
            return f(seq_, args...);
        }
};

class execution_policy
{
    private:
        dynamic_policy policy_;
    public:
        // 2.7.1, execution_policy construct/assign
        template<class ExecutionPolicy>
        execution_policy(const ExecutionPolicy& policy,
                         typename enable_if<is_execution_policy<ExecutionPolicy>::value>::type * = 0) : policy_(policy)
        {}

        template<class ExecutionPolicy>
        typename enable_if<is_execution_policy<ExecutionPolicy>::value,execution_policy&>::type
        operator=(const ExecutionPolicy& policy)
        {
            policy_ = policy;
            return *this;
        }

        // 2.7.2, execution_policy object access
        const type_info& type() const __NOEXCEPT
        {
            return policy_.type();
        }

        template<class ExecutionPolicy>
        ExecutionPolicy* get() __NOEXCEPT
        {
            return policy_.get<ExecutionPolicy>();
        }
        template<class ExecutionPolicy>
        const ExecutionPolicy* get() const __NOEXCEPT
        {
            return policy_.get<ExecutionPolicy>();
        }

        // algorithm dispatch
        //
        template<class Functor, class... Args>
        friend void dispatch(Functor&& f, const execution_policy &exec, Args&&... args)
        {
            exec.policy_.dispatch(std::forward<Functor>(f), std::forward<Args>(args)...);
        }

};

}
}
}
}

<commit_msg>rename dynamic_policy -> dynamic_execution_policy<commit_after>#pragma once
namespace std          {
namespace experimental {
namespace parallel     {
inline namespace v1    {

class dynamic_execution_policy
{
    private:
        union
        {
            sequential_execution_policy seq_;
            parallel_execution_policy   par_;
        };
        enum class policy_type
        {
            SEQ, PAR
        } policy_;

    public:
        dynamic_execution_policy(const sequential_execution_policy& seq) : seq_(seq), policy_(policy_type::SEQ) {}
        dynamic_execution_policy(const   parallel_execution_policy& par) : par_(par), policy_(policy_type::PAR) {}

        bool is_seq() const { return policy_ == policy_type::SEQ; }
        bool is_par() const { return policy_ == policy_type::PAR; }

        template<class ExecutionPolicy>
        typename enable_if<is_execution_policy<ExecutionPolicy>::value, ExecutionPolicy*>::type
        get()  __NOEXCEPT
        {
            ExecutionPolicy* dummy = nullptr;
            return get_helper(*dummy);
        }
        template<class ExecutionPolicy>
        typename enable_if<is_execution_policy<ExecutionPolicy>::value, const ExecutionPolicy*>::type
        get()  const __NOEXCEPT
        {
            ExecutionPolicy* dummy = nullptr;
            return get_helper(dummy);
        }

        // sequential_execution_policy  get_helper
        //
        sequential_execution_policy* get_helper(sequential_execution_policy*) __NOEXCEPT
        {
            return is_seq() ? &seq_ : nullptr;
        }
        const sequential_execution_policy* get_helper(sequential_execution_policy*) const __NOEXCEPT
        {
            return is_seq() ? &seq_ : nullptr;
        }

        // parallel_execution_policy  get_helper
        //
        parallel_execution_policy* get_helper(parallel_execution_policy*) __NOEXCEPT
        {
            return is_par() ? &par_ : nullptr;
        }
        const parallel_execution_policy* get_helper(parallel_execution_policy*) const __NOEXCEPT
        {
            return is_par() ? &par_ : nullptr;
        }

        // type information
        //
        const type_info& type() const __NOEXCEPT
        {
            if (is_seq()) return typeid(sequential_execution_policy);
            if (is_par()) return typeid(  parallel_execution_policy);
            return typeid(nullptr);
        }

        // algorithm dispatch
        //
        template<class Functor, class... Args>
        auto dispatch(Functor&& f, Args&&... args) const -> decltype(f(seq_, std::forward<Args>(args)...))
        {
            if (is_seq()) return f(seq_, std::forward<Args>(args)...);
            if (is_par()) return f(par_, std::forward<Args>(args)...);
            return f(seq_, args...);
        }
};

class execution_policy
{
    private:
        dynamic_execution_policy policy_;
    public:
        // 2.7.1, execution_policy construct/assign
        template<class ExecutionPolicy>
        execution_policy(const ExecutionPolicy& policy,
                         typename enable_if<is_execution_policy<ExecutionPolicy>::value>::type * = 0) : policy_(policy)
        {}

        template<class ExecutionPolicy>
        typename enable_if<is_execution_policy<ExecutionPolicy>::value,execution_policy&>::type
        operator=(const ExecutionPolicy& policy)
        {
            policy_ = policy;
            return *this;
        }

        // 2.7.2, execution_policy object access
        const type_info& type() const __NOEXCEPT
        {
            return policy_.type();
        }

        template<class ExecutionPolicy>
        ExecutionPolicy* get() __NOEXCEPT
        {
            return policy_.get<ExecutionPolicy>();
        }
        template<class ExecutionPolicy>
        const ExecutionPolicy* get() const __NOEXCEPT
        {
            return policy_.get<ExecutionPolicy>();
        }

        // algorithm dispatch
        //
        template<class Functor, class... Args>
        friend void dispatch(Functor&& f, const execution_policy &exec, Args&&... args)
        {
            exec.policy_.dispatch(std::forward<Functor>(f), std::forward<Args>(args)...);
        }

};

}
}
}
}

<|endoftext|>


<commit_before>/*
 * ROCMetric.cpp
 *
 *  Created on: 28.02.2015
 *      Author: Kolja Esders (kolja.esders@student.kit.edu)
 */

#include "ROCMetric.h"

namespace NetworKit {

std::pair<std::vector<double>, std::vector<double>> ROCMetric::generatePoints() {
  std::pair<std::vector<double>, std::vector<double>> points;
  points.first.reserve(thresholds.size());
  points.second.reserve(thresholds.size());
  for (index i = 0; i < thresholds.size(); ++i) {
    double falsePositiveRatio = 1.0 * falsePositives.at(i) / numNegatives;
    if (!points.first.empty() && points.first.back() == falsePositiveRatio) {
      points.second.pop_back();
    } else {
      points.first.push_back(falsePositiveRatio);
    }
    points.second.push_back(1.0 * truePositives.at(i) / numPositives);
  }
  return points;
}

} // namespace NetworKit<commit_msg>Handling special case for ROC<commit_after>/*
 * ROCMetric.cpp
 *
 *  Created on: 28.02.2015
 *      Author: Kolja Esders (kolja.esders@student.kit.edu)
 */

#include "ROCMetric.h"

namespace NetworKit {

std::pair<std::vector<double>, std::vector<double>> ROCMetric::generatePoints() {
  if (numPositives == 0) {
    throw std::logic_error("ROC metric is not defined for #positives == 0.");
  } else if (numNegatives == 0) {
    throw std::logic_error("ROC metric is not defined for #negatives == 0.");
  }
  std::pair<std::vector<double>, std::vector<double>> points;
  points.first.reserve(thresholds.size());
  points.second.reserve(thresholds.size());
  for (index i = 0; i < thresholds.size(); ++i) {
    double falsePositiveRatio = 1.0 * falsePositives.at(i) / numNegatives;
    if (!points.first.empty() && points.first.back() == falsePositiveRatio) {
      points.second.pop_back();
    } else {
      points.first.push_back(falsePositiveRatio);
    }
    points.second.push_back(1.0 * truePositives.at(i) / numPositives);
  }
  return points;
}

} // namespace NetworKit<|endoftext|>


<commit_before>/*  This file is part of kdepim.
    Copyright (C) 2005,2007 Will Stephenson <wstephenson@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    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
    Library General Public License for more details.

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

    As a special exception, permission is given to link this library
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "networkstatuscommon.h"

QDataStream & operator<< ( QDataStream & s, const NetworkStatus::Properties p )
{
  s << p.name;
	s << (int)p.status;
	s << p.service;
	return s;
}

QDataStream & operator>> ( QDataStream & s, NetworkStatus::Properties &p )
{
	int status;
	s >> p.name;
	s >> status;
	p.status = (NetworkStatus::Status)status;
	s >> p.service;
	return s;
}

namespace NetworkStatus
{
  QString toString( NetworkStatus::Status st )
  {
    QString str;
    switch ( st ) {
      case NetworkStatus::NoNetworks:
        str = "NoNetworks";
        break;
      case NetworkStatus::Unreachable:
        str = "Unreachable";
        break;
      case NetworkStatus::OfflineDisconnected:
        str = "OfflineDisconnected";
        break;
      case NetworkStatus::OfflineFailed:
        str = "OfflineFailed";
        break;
      case NetworkStatus::ShuttingDown:
        str = "ShuttingDown";
        break;
      case NetworkStatus::Offline:
        str = "Offline";
        break;
      case NetworkStatus::Establishing:
        str = "Establishing";
        break;
      case NetworkStatus::Online:
        str = "Online";
        break;
    }
    return str;
  }
} // namespace NetworkStatus
<commit_msg>redundant file<commit_after><|endoftext|>