<commit_before>#include "Atm_controller.hpp"

const char Atm_controller::relOps[8] = "0=!<>-+";

Atm_controller& Atm_controller::begin( bool initialState /* = false */ ) {
  // clang-format off
  const static state_t state_table[] PROGMEM = {
    /*              ON_ENTER    ON_LOOP  ON_EXIT  EVT_ON  EVT_OFF  EVT_TOGGLE EVT_INPUT ELSE */
    /* OFF     */    ACT_OFF,        -1,      -1,     ON,      -1,         ON,      OFF,  -1,
    /* ON      */     ACT_ON,        -1,      -1,     -1,     OFF,        OFF,       ON,  -1,
  };
  // clang-format on
  Machine::begin( state_table, ELSE );
  _last_state = -1;
  state( initialState ? ON : OFF );
  _indicator = -1;
  return *this;
}

Atm_controller& Atm_controller::indicator( int led, bool activeLow /* = false */ ) {
  _indicator = led;
  _indicatorActiveLow = activeLow;
  pinMode( _indicator, OUTPUT );
  return *this;
}

Atm_controller& Atm_controller::onFlip( bool status, atm_cb_push_t callback, int idx /* = 0 */ ) {
  _connector[status ? 0 : 1].set( callback, idx );
  return *this;
}

Atm_controller& Atm_controller::onFlip( bool status, Machine& machine, int evt /* = 0 */ ) {
  _connector[status ? 0 : 1].set( &machine, evt );
  return *this;
}

Atm_controller& Atm_controller::onInput( bool status, atm_cb_push_t callback, int idx /* = 0 */ ) {
  _connector[status ? 2 : 3].set( callback, idx );
  return *this;
}

Atm_controller& Atm_controller::onInput( bool status, Machine& machine, int event /* = 0 */ ) {
  _connector[status ? 2 : 3].set( &machine, event );
  return *this;
}

Atm_controller& Atm_controller::IF( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_AND, machine, relOp, match );
}

Atm_controller& Atm_controller::IF( atm_cb_pull_t callback, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_AND, callback, relOp, match );
}

Atm_controller& Atm_controller::AND( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_AND, machine, relOp, match );
}

Atm_controller& Atm_controller::AND( atm_cb_pull_t callback, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_AND, callback, relOp, match );
}

Atm_controller& Atm_controller::OR( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_OR, machine, relOp, match );
}

Atm_controller& Atm_controller::OR( atm_cb_pull_t callback, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_OR, callback, relOp, match );
}

Atm_controller& Atm_controller::XOR( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_XOR, machine, relOp, match );
}

Atm_controller& Atm_controller::XOR( atm_cb_pull_t callback, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_XOR, callback, relOp, match );
}

Atm_controller& Atm_controller::OP( char logOp, Machine& machine, char relOp, int match ) {
  for ( uint8_t i = 0; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
    if ( _operand[i].mode() == atm_connector::MODE_NULL ) {  // Pick the first free slot
      _operand[i].set( &machine, match, logOp, (int)( strchr( relOps, relOp ) - relOps ) );
      break;
    }
  }
  return *this;
}

Atm_controller& Atm_controller::OP( char logOp, atm_cb_pull_t callback, char relOp, int match ) {
  for ( uint8_t i = 0; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
    if ( _operand[i].mode() == atm_connector::MODE_NULL ) {  // Pick the first free slot
      _operand[i].set( callback, match, logOp, (int)( strchr( relOps, relOp ) - relOps ) );
      break;
    }
  }
  return *this;
}

bool Atm_controller::eval_one( uint8_t idx ) {
  switch ( _operand[idx].relOp() ) {
    case atm_connector::REL_EQ:
      return _operand[idx].pull() == _operand[idx].event;
    case atm_connector::REL_NEQ:
      return _operand[idx].pull() != _operand[idx].event;
    case atm_connector::REL_LT:
      return _operand[idx].pull() < _operand[idx].event;
    case atm_connector::REL_GT:
      return _operand[idx].pull() > _operand[idx].event;
    case atm_connector::REL_LTE:
      return _operand[idx].pull() <= _operand[idx].event;
    case atm_connector::REL_GTE:
      return _operand[idx].pull() >= _operand[idx].event;
  }
  return false;
}

bool Atm_controller::eval_all() {
  bool r = eval_one( 0 );
  for ( uint8_t i = 1; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
    if ( _operand[i].mode() ) {
      switch ( _operand[i].logOp() ) {
        case atm_connector::LOG_AND:
          r = r && eval_one( i );
          break;
        case atm_connector::LOG_OR:
          r = r || eval_one( i );
          break;
        case atm_connector::LOG_XOR:
          r = !r != !eval_one( i );
          break;
      }
    }
  }
  return r;
}

int Atm_controller::event( int id ) {
  switch ( id ) {
    case EVT_ON:
      return eval_all();
    case EVT_OFF:
      return !eval_all();
  }
  return 0;
}

void Atm_controller::action( int id ) {
  switch ( id ) {
    case ACT_OFF:
      _connector[_last_state == current ? 3 : 1].push();
      if ( _indicator > -1 ) digitalWrite( _indicator, !LOW != !_indicatorActiveLow );
      _last_state = current;
      return;
    case ACT_ON:
      if ( _last_state != -1 ) _connector[( _last_state == current ) ? 2 : 0].push();
      if ( _indicator > -1 ) digitalWrite( _indicator, !HIGH != !_indicatorActiveLow );
      _last_state = current;
      return;
  }
}

Atm_controller& Atm_controller::trace( Stream& stream ) {
  Machine::setTrace( &stream, atm_serial_debug::trace, "CONTROLLER\0EVT_ON\0EVT_OFF\0EVT_TOGGLE\0EVT_INPUT\0ELSE\0OFF\0ON" );
  return *this;
}
<commit_msg>Changed eval_one()<commit_after>#include "Atm_controller.hpp"

const char Atm_controller::relOps[8] = "0=!<>-+";

Atm_controller& Atm_controller::begin( bool initialState /* = false */ ) {
  // clang-format off
  const static state_t state_table[] PROGMEM = {
    /*              ON_ENTER    ON_LOOP  ON_EXIT  EVT_ON  EVT_OFF  EVT_TOGGLE EVT_INPUT ELSE */
    /* OFF     */    ACT_OFF,        -1,      -1,     ON,      -1,         ON,      OFF,  -1,
    /* ON      */     ACT_ON,        -1,      -1,     -1,     OFF,        OFF,       ON,  -1,
  };
  // clang-format on
  Machine::begin( state_table, ELSE );
  _last_state = -1;
  state( initialState ? ON : OFF );
  _indicator = -1;
  return *this;
}

Atm_controller& Atm_controller::indicator( int led, bool activeLow /* = false */ ) {
  _indicator = led;
  _indicatorActiveLow = activeLow;
  pinMode( _indicator, OUTPUT );
  return *this;
}

Atm_controller& Atm_controller::onFlip( bool status, atm_cb_push_t callback, int idx /* = 0 */ ) {
  _connector[status ? 0 : 1].set( callback, idx );
  return *this;
}

Atm_controller& Atm_controller::onFlip( bool status, Machine& machine, int event /* = 0 */ ) {
  _connector[status ? 0 : 1].set( &machine, event );
  return *this;
}

Atm_controller& Atm_controller::onInput( bool status, atm_cb_push_t callback, int idx /* = 0 */ ) {
  _connector[status ? 2 : 3].set( callback, idx );
  return *this;
}

Atm_controller& Atm_controller::onInput( bool status, Machine& machine, int event /* = 0 */ ) {
  _connector[status ? 2 : 3].set( &machine, event );
  return *this;
}

Atm_controller& Atm_controller::IF( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_AND, machine, relOp, match );
}

Atm_controller& Atm_controller::IF( atm_cb_pull_t callback, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_AND, callback, relOp, match );
}

Atm_controller& Atm_controller::AND( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_AND, machine, relOp, match );
}

Atm_controller& Atm_controller::AND( atm_cb_pull_t callback, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_AND, callback, relOp, match );
}

Atm_controller& Atm_controller::OR( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_OR, machine, relOp, match );
}

Atm_controller& Atm_controller::OR( atm_cb_pull_t callback, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_OR, callback, relOp, match );
}

Atm_controller& Atm_controller::XOR( Machine& machine, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_XOR, machine, relOp, match );
}

Atm_controller& Atm_controller::XOR( atm_cb_pull_t callback, char relOp /* = '>' */, int match /* = 0 */ ) {
  return OP( atm_connector::LOG_XOR, callback, relOp, match );
}

Atm_controller& Atm_controller::OP( char logOp, Machine& machine, char relOp, int match ) {
  for ( uint8_t i = 0; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
    if ( _operand[i].mode() == atm_connector::MODE_NULL ) {  // Pick the first free slot
      _operand[i].set( &machine, match, logOp, (int)( strchr( relOps, relOp ) - relOps ) );
      break;
    }
  }
  return *this;
}

Atm_controller& Atm_controller::OP( char logOp, atm_cb_pull_t callback, char relOp, int match ) {
  for ( uint8_t i = 0; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
    if ( _operand[i].mode() == atm_connector::MODE_NULL ) {  // Pick the first free slot
      _operand[i].set( callback, match, logOp, (int)( strchr( relOps, relOp ) - relOps ) );
      break;
    }
  }
  return *this;
}

bool Atm_controller::eval_one( atm_connector& connector ) {
  switch ( connector.relOp() ) {
    case connector.REL_EQ:
      return connector.pull() == connector.event;
    case connector.REL_NEQ:
      return connector.pull() != connector.event;
    case connector.REL_LT:
      return connector.pull() < connector.event;
    case connector.REL_GT:
      return connector.pull() > connector.event;
    case connector.REL_LTE:
      return connector.pull() <= connector.event;
    case connector.REL_GTE:
      return connector.pull() >= connector.event;
  }
  return false;
}

bool Atm_controller::eval_all() {
  bool r = eval_one( _operand[0] );
  for ( uint8_t i = 1; i < ATM_CONDITION_OPERAND_MAX; i++ ) {
    if ( _operand[i].mode() ) {
      switch ( _operand[i].logOp() ) {
        case atm_connector::LOG_AND:
          r = r && eval_one( _operand[i] );
          break;
        case atm_connector::LOG_OR:
          r = r || eval_one( _operand[i] );
          break;
        case atm_connector::LOG_XOR:
          r = !r != !eval_one( _operand[i] );
          break;
      }
    }
  }
  return r;
}

int Atm_controller::event( int id ) {
  switch ( id ) {
    case EVT_ON:
      return eval_all();
    case EVT_OFF:
      return !eval_all();
  }
  return 0;
}

void Atm_controller::action( int id ) {
  switch ( id ) {
    case ACT_OFF:
      _connector[_last_state == current ? 3 : 1].push();
      if ( _indicator > -1 ) digitalWrite( _indicator, !LOW != !_indicatorActiveLow );
      _last_state = current;
      return;
    case ACT_ON:
      if ( _last_state != -1 ) _connector[( _last_state == current ) ? 2 : 0].push();
      if ( _indicator > -1 ) digitalWrite( _indicator, !HIGH != !_indicatorActiveLow );
      _last_state = current;
      return;
  }
}

Atm_controller& Atm_controller::trace( Stream& stream ) {
  Machine::setTrace( &stream, atm_serial_debug::trace, "CONTROLLER\0EVT_ON\0EVT_OFF\0EVT_TOGGLE\0EVT_INPUT\0ELSE\0OFF\0ON" );
  return *this;
}
<|endoftext|>


<commit_before>#include "BenchmarkStack.h"
#include "StackAllocator.h"
#include <iostream>		// cout cin ...
#include <stdlib.h>     /* srand, rand */

BenchmarkStack::BenchmarkStack(const int runtime)
	: Benchmark(runtime) {
}

BenchmarkResults BenchmarkStack::allocation() {
	std::cout << "STACK ALLOCATION" << std::endl;
	setStartTimer();

	StackAllocator stackAllocator(1e10);

	int operations = 0;
	while(!outOfTime()){
		stackAllocator.Allocate(sizeof(int), alignof(int));			// 4  -> 4
		stackAllocator.Allocate(sizeof(bool), alignof(bool));		// 1  -> 5
																	// 3  -> 8
		stackAllocator.Allocate(sizeof(foo), alignof(foo));			// 16 -> 24

		++operations;
	}

	BenchmarkResults results = buildResults(operations, m_runtime, 0, 0);

	printResults(results);
	stackAllocator.Reset();
	return results;
}

BenchmarkResults BenchmarkStack::freeing() {
	std::cout << "STACK FREEING" << std::endl;

	setStartTimer();

	StackAllocator stackAllocator(1e10);

	std::size_t operations = 0;
	double elapsedTime = 0;
	while(elapsedTime < (m_runtime * 1e3)){
		if (operations % 2 == 0){
			stackAllocator.Allocate(sizeof(int), alignof(int));			// 4  -> 4
			stackAllocator.Allocate(sizeof(bool), alignof(bool));		// 1  -> 5
																	// 3  -> 8
			stackAllocator.Allocate(sizeof(foo), alignof(foo));			// 16 -> 24
		}else {
			timespec before_free, after_free;
			setTimer(before_free);
			stackAllocator.Free(sizeof(foo));
			stackAllocator.Free(sizeof(bool));
			stackAllocator.Free(sizeof(int));
			setTimer(after_free);
			elapsedTime += calculateElapsedTime(before_free, after_free);
		}
		++operations;
	}

	BenchmarkResults results = buildResults(operations/2, m_runtime, 0, 0);

	printResults(results);
	stackAllocator.Reset();
	return results;}

BenchmarkResults BenchmarkStack::read() {
	std::cout << "STACK READ" << std::endl;

	StackAllocator stackAllocator(1e10);

	std::size_t operations = 0;
	double elapsedTime = 0;
	while(elapsedTime < (m_runtime * 1e3)){
		int * i = (int *) stackAllocator.Allocate(sizeof(int), alignof(int));			// 4  -> 4
		bool * b = (bool *) stackAllocator.Allocate(sizeof(bool), alignof(bool));		// 1  -> 5
																	// 3  -> 8
		foo * f = (foo *) stackAllocator.Allocate(sizeof(foo), alignof(foo));			// 16 -> 24

		timespec before_read, after_read;
		setTimer(before_read);
		int i_value = *i;
		bool b_value = *b;
		foo f_value = *f;
		setTimer(after_read);

		elapsedTime += calculateElapsedTime(before_read, after_read);

		++operations;
	}

	BenchmarkResults results = buildResults(operations, m_runtime, 0, 0);

	printResults(results);
	stackAllocator.Reset();
	return results;
}

BenchmarkResults BenchmarkStack::write() {
	std::cout << "STACK WITE" << std::endl;
	srand (0);

	StackAllocator stackAllocator(1e10);

	std::size_t operations = 0;
	double elapsedTime = 0;
	while(elapsedTime < (m_runtime * 1e3)){
		int * i = (int *) stackAllocator.Allocate(sizeof(int), alignof(int));			// 4  -> 4
		bool * b = (bool *) stackAllocator.Allocate(sizeof(bool), alignof(bool));		// 1  -> 5
																	// 3  -> 8
		foo * f = (foo *) stackAllocator.Allocate(sizeof(foo), alignof(foo));			// 16 -> 24

		int randomN = rand();
		timespec before_write, after_write;
		setTimer(before_write);
		*i =  randomN % 100;
		*b = randomN % 2;
		*f = foo();
		setTimer(after_write);

		elapsedTime += calculateElapsedTime(before_write, after_write);

		++operations;
	}

	BenchmarkResults results = buildResults(operations, m_runtime, 0, 0);

	printResults(results);
	stackAllocator.Reset();
	return results;

}

BenchmarkResults BenchmarkStack::all() {
	return buildResults(0, 0, 0, 0);
}<commit_msg>Added all benchmark.<commit_after>#include "BenchmarkStack.h"
#include "StackAllocator.h"
#include <iostream>		// cout cin ...
#include <stdlib.h>     /* srand, rand */

BenchmarkStack::BenchmarkStack(const int runtime)
	: Benchmark(runtime) {
}

BenchmarkResults BenchmarkStack::allocation() {
	std::cout << "STACK ALLOCATION" << std::endl;
	setStartTimer();

	StackAllocator stackAllocator(1e10);

	int operations = 0;
	while(!outOfTime()){
		stackAllocator.Allocate(sizeof(int), alignof(int));			// 4  -> 4
		stackAllocator.Allocate(sizeof(bool), alignof(bool));		// 1  -> 5
																	// 3  -> 8
		stackAllocator.Allocate(sizeof(foo), alignof(foo));			// 16 -> 24

		++operations;
	}

	BenchmarkResults results = buildResults(operations, m_runtime, 0, 0);

	printResults(results);
	stackAllocator.Reset();
	return results;
}

BenchmarkResults BenchmarkStack::freeing() {
	std::cout << "STACK FREEING" << std::endl;

	timespec before, after;
	setTimer(before);
	StackAllocator stackAllocator(1e10);
	setTimer(after);
	double elapsedTime = calculateElapsedTime(before, after);

	std::size_t operations = 0;
	while(elapsedTime < (m_runtime * 1e3)){
		if (operations % 2 == 0){
			stackAllocator.Allocate(sizeof(int), alignof(int));			// 4  -> 4
			stackAllocator.Allocate(sizeof(bool), alignof(bool));		// 1  -> 5
																	// 3  -> 8
			stackAllocator.Allocate(sizeof(foo), alignof(foo));			// 16 -> 24
		}else {
			setTimer(before);
			stackAllocator.Free(sizeof(foo));
			stackAllocator.Free(sizeof(bool));
			stackAllocator.Free(sizeof(int));
			setTimer(after);
			elapsedTime += calculateElapsedTime(before, after);
		}
		++operations;
	}

	BenchmarkResults results = buildResults(operations/2, m_runtime, 0, 0);

	printResults(results);
	stackAllocator.Reset();
	return results;}

BenchmarkResults BenchmarkStack::read() {
	std::cout << "STACK READ" << std::endl;

	timespec before, after;
	setTimer(before);
	StackAllocator stackAllocator(1e10);
	setTimer(after);
	double elapsedTime = calculateElapsedTime(before, after);

	std::size_t operations = 0;
	while(elapsedTime < (m_runtime * 1e3)){
		int * i = (int *) stackAllocator.Allocate(sizeof(int), alignof(int));			// 4  -> 4
		bool * b = (bool *) stackAllocator.Allocate(sizeof(bool), alignof(bool));		// 1  -> 5
																	// 3  -> 8
		foo * f = (foo *) stackAllocator.Allocate(sizeof(foo), alignof(foo));			// 16 -> 24

		setTimer(before);
		int i_value = *i;
		bool b_value = *b;
		foo f_value = *f;
		setTimer(after);

		elapsedTime += calculateElapsedTime(before, after);

		++operations;
	}

	BenchmarkResults results = buildResults(operations, m_runtime, 0, 0);

	printResults(results);
	stackAllocator.Reset();
	return results;
}

BenchmarkResults BenchmarkStack::write() {
	std::cout << "STACK WRITE" << std::endl;
	srand (0);

	timespec before, after;
	setTimer(before);
	StackAllocator stackAllocator(1e10);
	setTimer(after);
	double elapsedTime = calculateElapsedTime(before, after);

	std::size_t operations = 0;
	while(elapsedTime < (m_runtime * 1e3)){
		int * i = (int *) stackAllocator.Allocate(sizeof(int), alignof(int));			// 4  -> 4
		bool * b = (bool *) stackAllocator.Allocate(sizeof(bool), alignof(bool));		// 1  -> 5
																	// 3  -> 8
		foo * f = (foo *) stackAllocator.Allocate(sizeof(foo), alignof(foo));			// 16 -> 24

		int randomN = rand();
		setTimer(before);
		*i =  randomN % 100;
		*b = randomN % 2;
		*f = foo();
		setTimer(after);

		elapsedTime += calculateElapsedTime(before, after);

		++operations;
	}

	BenchmarkResults results = buildResults(operations, m_runtime, 0, 0);

	printResults(results);
	stackAllocator.Reset();
	return results;
}

BenchmarkResults BenchmarkStack::all() {
	std::cout << "STACK ALL" << std::endl;
	setStartTimer();
	StackAllocator stackAllocator(1e10);

	std::size_t operations = 0;
	int * i;
	bool * b;
	foo * f;
	while(!outOfTime()){
		if (operations % 2 == 0){
			i = (int *) stackAllocator.Allocate(sizeof(int), alignof(int));			// 4  -> 4
			b = (bool *) stackAllocator.Allocate(sizeof(bool), alignof(bool));		// 1  -> 5													// 3  -> 8
			f = (foo *) stackAllocator.Allocate(sizeof(foo), alignof(foo));			// 16 -> 24
		}else {
			*i = *i + 1;
			*b = !b;
			*f = foo();

			stackAllocator.Free(sizeof(foo));
			stackAllocator.Free(sizeof(bool));
			stackAllocator.Free(sizeof(int));
		}

		++operations;
	}

	BenchmarkResults results = buildResults(operations, m_runtime, 0, 0);

	printResults(results);
	stackAllocator.Reset();
	return results;}<|endoftext|>


<commit_before>/*
    This file is part of KAddressBook.
    Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

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

#include <qlabel.h>
#include <qlayout.h>
#include <qlistbox.h>
#include <qpushbutton.h>
#include <qtoolbutton.h>

#include <kcombobox.h>
#include <kdebug.h>
#include <kdialog.h>
#include <kiconloader.h>
#include <klocale.h>

#include "viewconfigurefieldspage.h"

class FieldItem : public QListBoxText
{
  public:
    FieldItem( QListBox *parent, KABC::Field *field )
      : QListBoxText( parent, field->label() ), mField( field ) {}

    FieldItem( QListBox *parent, KABC::Field *field, int index )
      : QListBoxText( parent, field->label(), parent->item( index ) ),
        mField( field ) {}

    KABC::Field *field() { return mField; }

  private:
    KABC::Field *mField;
};

ViewConfigureFieldsPage::ViewConfigureFieldsPage( KABC::AddressBook *ab,
                                                  QWidget *parent,
                                                  const char *name )
  : QWidget( parent, name ), mAddressBook( ab )
{
  initGUI();
}

void ViewConfigureFieldsPage::restoreSettings( KConfig *config )
{
  KABC::Field::List fields = KABC::Field::restoreFields( config, "KABCFields" );

  if ( fields.isEmpty() )
    fields = KABC::Field::defaultFields();

  KABC::Field::List::ConstIterator it;
  for( it = fields.begin(); it != fields.end(); ++it )
    new FieldItem( mSelectedBox, *it );

  slotShowFields( mCategoryCombo->currentItem() );
}

void ViewConfigureFieldsPage::saveSettings( KConfig *config )
{
  KABC::Field::List fields;

  for( uint i = 0; i < mSelectedBox->count(); ++i ) {
    FieldItem *fieldItem = static_cast<FieldItem *>( mSelectedBox->item( i ) );
    fields.append( fieldItem->field() );
  }

  KABC::Field::saveFields( config, "KABCFields", fields );
}

void ViewConfigureFieldsPage::slotShowFields( int index )
{
  int currentPos = mUnSelectedBox->currentItem();
  mUnSelectedBox->clear();

  int category;
  if ( index == 0 ) category = KABC::Field::All;
  else category = 1 << ( index - 1 );

  KABC::Field::List allFields = mAddressBook->fields( category );

  KABC::Field::List::ConstIterator it;
  for ( it = allFields.begin(); it != allFields.end(); ++it ) {
    QListBoxItem *item = mSelectedBox->firstItem();
    while( item ) {
      FieldItem *fieldItem = static_cast<FieldItem *>( item );
      if ( (*it)->equals( fieldItem->field() ) )
        break;
      item = item->next();
    }

    if ( !item )
      new FieldItem( mUnSelectedBox, *it );
  }

  mUnSelectedBox->sort();
  mUnSelectedBox->setCurrentItem( currentPos );
}

void ViewConfigureFieldsPage::slotSelect()
{
  // insert selected items in the unselected list to the selected list,
  // directoy under the current item if selected, or at the bottonm if
  // nothing is selected in the selected list
  int where = mSelectedBox->currentItem();
  if ( !(where > -1 && mSelectedBox->item( where )->isSelected()) )
    where = mSelectedBox->count() - 1;

  for ( uint i = 0; i < mUnSelectedBox->count(); ++i )
    if ( mUnSelectedBox->isSelected( mUnSelectedBox->item( i ) ) ) {
      FieldItem *fieldItem = static_cast<FieldItem *>( mUnSelectedBox->item( i ) );
      new FieldItem( mSelectedBox, fieldItem->field(), where );
      where++;
    }

  slotShowFields( mCategoryCombo->currentItem() );
}

void ViewConfigureFieldsPage::slotUnSelect()
{
  for ( uint i = 0; i < mSelectedBox->count(); ++i )
    if ( mSelectedBox->isSelected( mSelectedBox->item( i ) ) ) {
      mSelectedBox->removeItem( i );
      --i;
    }

  slotShowFields( mCategoryCombo->currentItem() );
}

void ViewConfigureFieldsPage::slotButtonsEnabled()
{
  bool state = false;
  // add button: enabled if any items are selected in the unselected list
  for( uint i = 0; i < mUnSelectedBox->count(); ++i )
    if ( mUnSelectedBox->item( i )->isSelected() ) {
      state = true;
      break;
    }
  mAddButton->setEnabled( state );

  int j = mSelectedBox->currentItem();
  state = ( j > -1 && mSelectedBox->isSelected( j ) );

  // up button: enabled if there is a current item > 0 and that is selected
  mUpButton->setEnabled( ( j > 0 && state ) );

  // down button: enabled if there is a current item < count - 2 and that is selected
  mDownButton->setEnabled( ( j > -1 && j < (int)mSelectedBox->count() - 1 && state ) );

  // remove button: enabled if any items are selected in the selected list
  state = false;
  for ( uint i = 0; i < mSelectedBox->count(); ++i )
    if ( mSelectedBox->item( i )->isSelected() ) {
      state = true;
      break;
    }
  mRemoveButton->setEnabled( state );
}

void ViewConfigureFieldsPage::slotMoveUp()
{
  int i = mSelectedBox->currentItem();
  if ( i > 0 ) {
    QListBoxItem *item = mSelectedBox->item( i );
    mSelectedBox->takeItem( item );
    mSelectedBox->insertItem( item, i - 1 );
    mSelectedBox->setCurrentItem( item );
    mSelectedBox->setSelected( i - 1, true );
  }
}

void ViewConfigureFieldsPage::slotMoveDown()
{
  int i = mSelectedBox->currentItem();
  if ( i > -1 && i < (int)mSelectedBox->count() - 1 ) {
    QListBoxItem *item = mSelectedBox->item( i );
    mSelectedBox->takeItem( item );
    mSelectedBox->insertItem( item, i + 1 );
    mSelectedBox->setCurrentItem( item );
    mSelectedBox->setSelected( i + 1, true );
  }
}

void ViewConfigureFieldsPage::initGUI()
{
  setCaption( i18n("Select Fields to Display") );

  QGridLayout *gl = new QGridLayout( this , 6, 4, 0, KDialog::spacingHint() );

  mCategoryCombo = new KComboBox( false, this );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::All ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::Frequent ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::Address ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::Email ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::Personal ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::Organization ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::CustomCategory ) );
  connect( mCategoryCombo, SIGNAL( activated(int) ), SLOT( slotShowFields(int) ) );
  gl->addWidget( mCategoryCombo, 0, 0 );

  QLabel *label = new QLabel( i18n( "&Selected fields:" ), this );
  gl->addWidget( label, 0, 2 );

  mUnSelectedBox = new QListBox( this );
  mUnSelectedBox->setSelectionMode( QListBox::Extended );
  mUnSelectedBox->setMinimumHeight( 100 );
  gl->addWidget( mUnSelectedBox, 1, 0 );

  mSelectedBox = new QListBox( this );
  mSelectedBox->setSelectionMode( QListBox::Extended );
  label->setBuddy( mSelectedBox );
  gl->addWidget( mSelectedBox, 1, 2 );

  QBoxLayout *vb1 = new QBoxLayout( QBoxLayout::TopToBottom, KDialog::spacingHint() );
  vb1->addStretch();

  mAddButton = new QToolButton( this );
  mAddButton->setIconSet( SmallIconSet( "1rightarrow" ) );
  connect( mAddButton, SIGNAL( clicked() ), SLOT( slotSelect() ) );
  vb1->addWidget( mAddButton );

  mRemoveButton = new QToolButton( this );
  mRemoveButton->setIconSet( SmallIconSet( "1leftarrow" ) );
  connect( mRemoveButton, SIGNAL( clicked() ), SLOT( slotUnSelect() ) );
  vb1->addWidget( mRemoveButton );

  vb1->addStretch();
  gl->addLayout( vb1, 1, 1 );

  QBoxLayout *vb2 = new QBoxLayout( QBoxLayout::TopToBottom, KDialog::spacingHint() );
  vb2->addStretch();

  mUpButton = new QToolButton( this );
  mUpButton->setIconSet( SmallIconSet( "1uparrow" ) );
  connect( mUpButton, SIGNAL( clicked() ), SLOT( slotMoveUp() ) );
  vb2->addWidget( mUpButton );

  mDownButton = new QToolButton( this );
  mDownButton->setIconSet( SmallIconSet( "1downarrow" ) );
  connect( mDownButton, SIGNAL( clicked() ), SLOT( slotMoveDown() ) );
  vb2->addWidget( mDownButton );

  vb2->addStretch();
  gl->addLayout( vb2, 1, 3 );

  QSize sizeHint = mUnSelectedBox->sizeHint();

  // make sure we fill the list with all items, so that we can
  // get the maxItemWidth we need to not truncate the view
  slotShowFields( 0 );

  sizeHint = sizeHint.expandedTo( mSelectedBox->sizeHint() );
  sizeHint.setWidth( mUnSelectedBox->maxItemWidth() );
  mUnSelectedBox->setMinimumSize( sizeHint );
  mSelectedBox->setMinimumSize( sizeHint );

  gl->activate();

  connect( mUnSelectedBox, SIGNAL( selectionChanged() ), SLOT( slotButtonsEnabled() ) );
  connect( mSelectedBox, SIGNAL( selectionChanged() ), SLOT( slotButtonsEnabled() ) );
  connect( mSelectedBox, SIGNAL( currentChanged( QListBoxItem * ) ), SLOT( slotButtonsEnabled() ) );

  slotButtonsEnabled();
}

#include "viewconfigurefieldspage.moc"
<commit_msg>Fix reverseLayout<commit_after>/*
    This file is part of KAddressBook.
    Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

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

#include <qlabel.h>
#include <qlayout.h>
#include <qlistbox.h>
#include <qpushbutton.h>
#include <qtoolbutton.h>
#include <qapplication.h>

#include <kcombobox.h>
#include <kdebug.h>
#include <kdialog.h>
#include <kiconloader.h>
#include <klocale.h>

#include "viewconfigurefieldspage.h"

class FieldItem : public QListBoxText
{
  public:
    FieldItem( QListBox *parent, KABC::Field *field )
      : QListBoxText( parent, field->label() ), mField( field ) {}

    FieldItem( QListBox *parent, KABC::Field *field, int index )
      : QListBoxText( parent, field->label(), parent->item( index ) ),
        mField( field ) {}

    KABC::Field *field() { return mField; }

  private:
    KABC::Field *mField;
};

ViewConfigureFieldsPage::ViewConfigureFieldsPage( KABC::AddressBook *ab,
                                                  QWidget *parent,
                                                  const char *name )
  : QWidget( parent, name ), mAddressBook( ab )
{
  initGUI();
}

void ViewConfigureFieldsPage::restoreSettings( KConfig *config )
{
  KABC::Field::List fields = KABC::Field::restoreFields( config, "KABCFields" );

  if ( fields.isEmpty() )
    fields = KABC::Field::defaultFields();

  KABC::Field::List::ConstIterator it;
  for( it = fields.begin(); it != fields.end(); ++it )
    new FieldItem( mSelectedBox, *it );

  slotShowFields( mCategoryCombo->currentItem() );
}

void ViewConfigureFieldsPage::saveSettings( KConfig *config )
{
  KABC::Field::List fields;

  for( uint i = 0; i < mSelectedBox->count(); ++i ) {
    FieldItem *fieldItem = static_cast<FieldItem *>( mSelectedBox->item( i ) );
    fields.append( fieldItem->field() );
  }

  KABC::Field::saveFields( config, "KABCFields", fields );
}

void ViewConfigureFieldsPage::slotShowFields( int index )
{
  int currentPos = mUnSelectedBox->currentItem();
  mUnSelectedBox->clear();

  int category;
  if ( index == 0 ) category = KABC::Field::All;
  else category = 1 << ( index - 1 );

  KABC::Field::List allFields = mAddressBook->fields( category );

  KABC::Field::List::ConstIterator it;
  for ( it = allFields.begin(); it != allFields.end(); ++it ) {
    QListBoxItem *item = mSelectedBox->firstItem();
    while( item ) {
      FieldItem *fieldItem = static_cast<FieldItem *>( item );
      if ( (*it)->equals( fieldItem->field() ) )
        break;
      item = item->next();
    }

    if ( !item )
      new FieldItem( mUnSelectedBox, *it );
  }

  mUnSelectedBox->sort();
  mUnSelectedBox->setCurrentItem( currentPos );
}

void ViewConfigureFieldsPage::slotSelect()
{
  // insert selected items in the unselected list to the selected list,
  // directoy under the current item if selected, or at the bottonm if
  // nothing is selected in the selected list
  int where = mSelectedBox->currentItem();
  if ( !(where > -1 && mSelectedBox->item( where )->isSelected()) )
    where = mSelectedBox->count() - 1;

  for ( uint i = 0; i < mUnSelectedBox->count(); ++i )
    if ( mUnSelectedBox->isSelected( mUnSelectedBox->item( i ) ) ) {
      FieldItem *fieldItem = static_cast<FieldItem *>( mUnSelectedBox->item( i ) );
      new FieldItem( mSelectedBox, fieldItem->field(), where );
      where++;
    }

  slotShowFields( mCategoryCombo->currentItem() );
}

void ViewConfigureFieldsPage::slotUnSelect()
{
  for ( uint i = 0; i < mSelectedBox->count(); ++i )
    if ( mSelectedBox->isSelected( mSelectedBox->item( i ) ) ) {
      mSelectedBox->removeItem( i );
      --i;
    }

  slotShowFields( mCategoryCombo->currentItem() );
}

void ViewConfigureFieldsPage::slotButtonsEnabled()
{
  bool state = false;
  // add button: enabled if any items are selected in the unselected list
  for( uint i = 0; i < mUnSelectedBox->count(); ++i )
    if ( mUnSelectedBox->item( i )->isSelected() ) {
      state = true;
      break;
    }
  mAddButton->setEnabled( state );

  int j = mSelectedBox->currentItem();
  state = ( j > -1 && mSelectedBox->isSelected( j ) );

  // up button: enabled if there is a current item > 0 and that is selected
  mUpButton->setEnabled( ( j > 0 && state ) );

  // down button: enabled if there is a current item < count - 2 and that is selected
  mDownButton->setEnabled( ( j > -1 && j < (int)mSelectedBox->count() - 1 && state ) );

  // remove button: enabled if any items are selected in the selected list
  state = false;
  for ( uint i = 0; i < mSelectedBox->count(); ++i )
    if ( mSelectedBox->item( i )->isSelected() ) {
      state = true;
      break;
    }
  mRemoveButton->setEnabled( state );
}

void ViewConfigureFieldsPage::slotMoveUp()
{
  int i = mSelectedBox->currentItem();
  if ( i > 0 ) {
    QListBoxItem *item = mSelectedBox->item( i );
    mSelectedBox->takeItem( item );
    mSelectedBox->insertItem( item, i - 1 );
    mSelectedBox->setCurrentItem( item );
    mSelectedBox->setSelected( i - 1, true );
  }
}

void ViewConfigureFieldsPage::slotMoveDown()
{
  int i = mSelectedBox->currentItem();
  if ( i > -1 && i < (int)mSelectedBox->count() - 1 ) {
    QListBoxItem *item = mSelectedBox->item( i );
    mSelectedBox->takeItem( item );
    mSelectedBox->insertItem( item, i + 1 );
    mSelectedBox->setCurrentItem( item );
    mSelectedBox->setSelected( i + 1, true );
  }
}

void ViewConfigureFieldsPage::initGUI()
{
  setCaption( i18n("Select Fields to Display") );

  QGridLayout *gl = new QGridLayout( this , 6, 4, 0, KDialog::spacingHint() );

  mCategoryCombo = new KComboBox( false, this );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::All ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::Frequent ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::Address ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::Email ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::Personal ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::Organization ) );
  mCategoryCombo->insertItem( KABC::Field::categoryLabel( KABC::Field::CustomCategory ) );
  connect( mCategoryCombo, SIGNAL( activated(int) ), SLOT( slotShowFields(int) ) );
  gl->addWidget( mCategoryCombo, 0, 0 );

  QLabel *label = new QLabel( i18n( "&Selected fields:" ), this );
  gl->addWidget( label, 0, 2 );

  mUnSelectedBox = new QListBox( this );
  mUnSelectedBox->setSelectionMode( QListBox::Extended );
  mUnSelectedBox->setMinimumHeight( 100 );
  gl->addWidget( mUnSelectedBox, 1, 0 );

  mSelectedBox = new QListBox( this );
  mSelectedBox->setSelectionMode( QListBox::Extended );
  label->setBuddy( mSelectedBox );
  gl->addWidget( mSelectedBox, 1, 2 );

  QBoxLayout *vb1 = new QBoxLayout( QBoxLayout::TopToBottom, KDialog::spacingHint() );
  vb1->addStretch();

  mAddButton = new QToolButton( this );
  mAddButton->setIconSet( QApplication::reverseLayout() ? SmallIconSet( "1leftarrow" ) : SmallIconSet( "1rightarrow" ) );
  connect( mAddButton, SIGNAL( clicked() ), SLOT( slotSelect() ) );
  vb1->addWidget( mAddButton );

  mRemoveButton = new QToolButton( this );
  mRemoveButton->setIconSet( QApplication::reverseLayout() ? SmallIconSet( "1rightarrow" ) : SmallIconSet( "1leftarrow" ) );
  connect( mRemoveButton, SIGNAL( clicked() ), SLOT( slotUnSelect() ) );
  vb1->addWidget( mRemoveButton );

  vb1->addStretch();
  gl->addLayout( vb1, 1, 1 );

  QBoxLayout *vb2 = new QBoxLayout( QBoxLayout::TopToBottom, KDialog::spacingHint() );
  vb2->addStretch();

  mUpButton = new QToolButton( this );
  mUpButton->setIconSet( SmallIconSet( "1uparrow" ) );
  connect( mUpButton, SIGNAL( clicked() ), SLOT( slotMoveUp() ) );
  vb2->addWidget( mUpButton );

  mDownButton = new QToolButton( this );
  mDownButton->setIconSet( SmallIconSet( "1downarrow" ) );
  connect( mDownButton, SIGNAL( clicked() ), SLOT( slotMoveDown() ) );
  vb2->addWidget( mDownButton );

  vb2->addStretch();
  gl->addLayout( vb2, 1, 3 );

  QSize sizeHint = mUnSelectedBox->sizeHint();

  // make sure we fill the list with all items, so that we can
  // get the maxItemWidth we need to not truncate the view
  slotShowFields( 0 );

  sizeHint = sizeHint.expandedTo( mSelectedBox->sizeHint() );
  sizeHint.setWidth( mUnSelectedBox->maxItemWidth() );
  mUnSelectedBox->setMinimumSize( sizeHint );
  mSelectedBox->setMinimumSize( sizeHint );

  gl->activate();

  connect( mUnSelectedBox, SIGNAL( selectionChanged() ), SLOT( slotButtonsEnabled() ) );
  connect( mSelectedBox, SIGNAL( selectionChanged() ), SLOT( slotButtonsEnabled() ) );
  connect( mSelectedBox, SIGNAL( currentChanged( QListBoxItem * ) ), SLOT( slotButtonsEnabled() ) );

  slotButtonsEnabled();
}

#include "viewconfigurefieldspage.moc"
<|endoftext|>


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

/* constructor / destructor */

SynthInstrument::SynthInstrument()
{
    construct();
    init();
}

SynthInstrument::~SynthInstrument()
{
    delete adsr;
    delete rOsc;
    delete arpeggiator;
    delete synthesizer;

    // when using JNI, we let SWIG invoke destructors when Java references are finalized
    // otherwise we delete and dispose the events directly from this instrument
#ifndef USE_JNI

    while ( !_audioEvents->empty() )
    {
        delete _audioEvents->back();
        _audioEvents->pop_back();
    }

    while ( !_liveAudioEvents->empty() )
    {
        delete _liveAudioEvents->back();
        _liveAudioEvents->pop_back();
    }

#endif

    while ( oscillators.size() > 0 )
        delete oscillators.back();
}

/* public methods */

void SynthInstrument::updateEvents()
{
    // SynthEvents are mapped to position relative to the measure's subdivisions
    // as such we don't require to invoke the BaseInstrument::updateEvents() method
    // to resync the offsets on a tempo change

    for ( int i = 0, l = _audioEvents->size(); i < l; ++i )
    {
        BaseSynthEvent* event = ( BaseSynthEvent* ) ( _audioEvents->at( i ) );
        event->invalidateProperties( event->position, event->length, this );
    }
    for ( int i = 0, l = _liveAudioEvents->size(); i < l; ++i )
    {
        BaseSynthEvent* event = ( BaseSynthEvent* ) ( _liveAudioEvents->at( i ) );
        event->invalidateProperties( event->position, event->length, this );
    }
    synthesizer->updateProperties();
}

bool SynthInstrument::removeEvent( BaseAudioEvent* audioEvent, bool isLiveEvent )
{
    bool removed = BaseInstrument::removeEvent( audioEvent, isLiveEvent );

    // when using JNI, we let SWIG invoke destructors when Java references are finalized
    // otherwise we delete and dispose the events directly from this instrument
#ifndef USE_JNI
    delete audioEvent;
    audioEvent = 0;
#endif
    return removed;
}

int SynthInstrument::getOscillatorAmount()
{
    return oscAmount;
}

void SynthInstrument::setOscillatorAmount( int aAmount )
{
    oscAmount = aAmount;

    if ( oscillators.size() < oscAmount )
        reserveOscillators( oscAmount );

    synthesizer->updateProperties();
}

void SynthInstrument::reserveOscillators( int aAmount )
{
    if ( oscillators.size() < aAmount )
    {
        while ( oscillators.size() < aAmount )
            oscillators.push_back( new OscillatorProperties( WaveForms::SINE, 0.0, 0, 0 ) );
    }
    else {
        while ( oscillators.size() > aAmount ) {
            delete oscillators.back();
            oscillators.pop_back();
        }
    }
}

OscillatorProperties* SynthInstrument::getOscillatorProperties( int aOscillatorNum )
{
    return oscillators.at( aOscillatorNum );
}

/* protected methods */

void SynthInstrument::init()
{
    adsr = new ADSR();
    adsr->setAttack( 0.01 );
    adsr->setDecay ( 0.01 );

    // default values
    octave          = 4;
    keyboardOctave  = 4;
    keyboardVolume  = 0.5;

    // modules

    rOsc              = new RouteableOscillator();
    audioChannel      = new AudioChannel( 0.8 );
    synthesizer       = new Synthesizer( this, 0 );
    arpeggiator       = new Arpeggiator();
    arpeggiatorActive = false;

    // start out with a single oscillator

    setOscillatorAmount( 1 );
}
<commit_msg>update copyright year range<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2013-2018 Igor Zinken - http://www.igorski.nl
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "synthinstrument.h"
#include "../global.h"
#include "../sequencer.h"
#include <definitions/waveforms.h>
#include <events/basesynthevent.h>
#include <utilities/utils.h>
#include <cstddef>

/* constructor / destructor */

SynthInstrument::SynthInstrument()
{
    construct();
    init();
}

SynthInstrument::~SynthInstrument()
{
    delete adsr;
    delete rOsc;
    delete arpeggiator;
    delete synthesizer;

    // when using JNI, we let SWIG invoke destructors when Java references are finalized
    // otherwise we delete and dispose the events directly from this instrument
#ifndef USE_JNI

    while ( !_audioEvents->empty() )
    {
        delete _audioEvents->back();
        _audioEvents->pop_back();
    }

    while ( !_liveAudioEvents->empty() )
    {
        delete _liveAudioEvents->back();
        _liveAudioEvents->pop_back();
    }

#endif

    while ( oscillators.size() > 0 )
        delete oscillators.back();
}

/* public methods */

void SynthInstrument::updateEvents()
{
    // SynthEvents are mapped to position relative to the measure's subdivisions
    // as such we don't require to invoke the BaseInstrument::updateEvents() method
    // to resync the offsets on a tempo change

    for ( int i = 0, l = _audioEvents->size(); i < l; ++i )
    {
        BaseSynthEvent* event = ( BaseSynthEvent* ) ( _audioEvents->at( i ) );
        event->invalidateProperties( event->position, event->length, this );
    }
    for ( int i = 0, l = _liveAudioEvents->size(); i < l; ++i )
    {
        BaseSynthEvent* event = ( BaseSynthEvent* ) ( _liveAudioEvents->at( i ) );
        event->invalidateProperties( event->position, event->length, this );
    }
    synthesizer->updateProperties();
}

bool SynthInstrument::removeEvent( BaseAudioEvent* audioEvent, bool isLiveEvent )
{
    bool removed = BaseInstrument::removeEvent( audioEvent, isLiveEvent );

    // when using JNI, we let SWIG invoke destructors when Java references are finalized
    // otherwise we delete and dispose the events directly from this instrument
#ifndef USE_JNI
    delete audioEvent;
    audioEvent = 0;
#endif
    return removed;
}

int SynthInstrument::getOscillatorAmount()
{
    return oscAmount;
}

void SynthInstrument::setOscillatorAmount( int aAmount )
{
    oscAmount = aAmount;

    if ( oscillators.size() < oscAmount )
        reserveOscillators( oscAmount );

    synthesizer->updateProperties();
}

void SynthInstrument::reserveOscillators( int aAmount )
{
    if ( oscillators.size() < aAmount )
    {
        while ( oscillators.size() < aAmount )
            oscillators.push_back( new OscillatorProperties( WaveForms::SINE, 0.0, 0, 0 ) );
    }
    else {
        while ( oscillators.size() > aAmount ) {
            delete oscillators.back();
            oscillators.pop_back();
        }
    }
}

OscillatorProperties* SynthInstrument::getOscillatorProperties( int aOscillatorNum )
{
    return oscillators.at( aOscillatorNum );
}

/* protected methods */

void SynthInstrument::init()
{
    adsr = new ADSR();
    adsr->setAttack( 0.01 );
    adsr->setDecay ( 0.01 );

    // default values
    octave          = 4;
    keyboardOctave  = 4;
    keyboardVolume  = 0.5;

    // modules

    rOsc              = new RouteableOscillator();
    audioChannel      = new AudioChannel( 0.8 );
    synthesizer       = new Synthesizer( this, 0 );
    arpeggiator       = new Arpeggiator();
    arpeggiatorActive = false;

    // start out with a single oscillator

    setOscillatorAmount( 1 );
}
<|endoftext|>


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

#include <QCoreApplication>
#include <QDir>

#if defined(Q_OS_UNIX)
#  include <sys/stat.h>
#elif defined(Q_OS_WIN32)
#  include <aclapi.h>
#  include <fileapi.h>
#endif

#include <QHttpEngine/QLocalFile>

#include "qlocalfile_p.h"

QLocalFilePrivate::QLocalFilePrivate(QLocalFile *localFile)
    : QObject(localFile),
      q(localFile)
{
    // Store the file in the user's home directory and set the filename to the
    // name of the application with a "." prepended
    q->setFileName(QDir::home().absoluteFilePath("." + QCoreApplication::applicationName()));
}

bool QLocalFilePrivate::setPermission()
{
#if defined(Q_OS_UNIX)
    return chmod(q->fileName().toUtf8().constData(), S_IRUSR | S_IWUSR) == 0;
#elif defined(Q_OS_WIN32)
    // Windows uses ACLs to control file access - each file contains an ACL
    // which consists of one or more ACEs (access control entries) - so the
    // ACL for the file must contain only a single ACE, granting access to the
    // file owner (the current user)

    EXPLICIT_ACCESS_W ea;
    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS_W));
    ea.grfAccessPermissions = GENERIC_ALL;
    ea.grfAccessMode = GRANT_ACCESS;
    ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea.Trustee.ptstrName = L"CURRENT_USER";

    // Create a new ACL with a single access control entry
    PACL pACL;
    if (SetEntriesInAclW(1, &ea, NULL, &pACL) != ERROR_SUCCESS) {
        return false;
    }

    // Apply the ACL to the file
    if (SetNamedSecurityInfoW((LPWSTR)q->fileName().utf16(),
                             SE_FILE_OBJECT,
                             DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
                             NULL,
                             NULL,
                             pACL,
                             NULL) != ERROR_SUCCESS) {
        LocalFree(pACL);
        return false;
    }

    LocalFree(pACL);
    return true;
#else
    // Unsupported platform, so setPermission() must fail
    return false;
#endif
}

bool QLocalFilePrivate::setHidden()
{
#if defined(Q_OS_UNIX)
    // On Unix, anything beginning with a "." is hidden
    return true;
#elif defined(Q_OS_WIN32)
    return SetFileAttributesW((LPCWSTR)q->fileName().utf16(), FILE_ATTRIBUTE_HIDDEN) != 0;
#else
    // Unsupported platform, so setHidden() must fail
    return false;
#endif
}

QLocalFile::QLocalFile(QObject *parent)
    : QFile(parent),
      d(new QLocalFilePrivate(this))
{
}

bool QLocalFile::open()
{
    return QFile::open(QIODevice::WriteOnly) && d->setPermission() && d->setHidden();
}
<commit_msg>Fix compilation on earlier versions of MSVC++ (fixes #17).<commit_after>/*
 * Copyright (c) 2015 Nathan Osman
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <QCoreApplication>
#include <QDir>

#if defined(Q_OS_UNIX)
#  include <sys/stat.h>
#elif defined(Q_OS_WIN32)
#  include <aclapi.h>
#  include <windows.h>
#endif

#include <QHttpEngine/QLocalFile>

#include "qlocalfile_p.h"

QLocalFilePrivate::QLocalFilePrivate(QLocalFile *localFile)
    : QObject(localFile),
      q(localFile)
{
    // Store the file in the user's home directory and set the filename to the
    // name of the application with a "." prepended
    q->setFileName(QDir::home().absoluteFilePath("." + QCoreApplication::applicationName()));
}

bool QLocalFilePrivate::setPermission()
{
#if defined(Q_OS_UNIX)
    return chmod(q->fileName().toUtf8().constData(), S_IRUSR | S_IWUSR) == 0;
#elif defined(Q_OS_WIN32)
    // Windows uses ACLs to control file access - each file contains an ACL
    // which consists of one or more ACEs (access control entries) - so the
    // ACL for the file must contain only a single ACE, granting access to the
    // file owner (the current user)

    EXPLICIT_ACCESS_W ea;
    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS_W));
    ea.grfAccessPermissions = GENERIC_ALL;
    ea.grfAccessMode = GRANT_ACCESS;
    ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea.Trustee.ptstrName = L"CURRENT_USER";

    // Create a new ACL with a single access control entry
    PACL pACL;
    if (SetEntriesInAclW(1, &ea, NULL, &pACL) != ERROR_SUCCESS) {
        return false;
    }

    // Apply the ACL to the file
    if (SetNamedSecurityInfoW((LPWSTR)q->fileName().utf16(),
                             SE_FILE_OBJECT,
                             DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
                             NULL,
                             NULL,
                             pACL,
                             NULL) != ERROR_SUCCESS) {
        LocalFree(pACL);
        return false;
    }

    LocalFree(pACL);
    return true;
#else
    // Unsupported platform, so setPermission() must fail
    return false;
#endif
}

bool QLocalFilePrivate::setHidden()
{
#if defined(Q_OS_UNIX)
    // On Unix, anything beginning with a "." is hidden
    return true;
#elif defined(Q_OS_WIN32)
    return SetFileAttributesW((LPCWSTR)q->fileName().utf16(), FILE_ATTRIBUTE_HIDDEN) != 0;
#else
    // Unsupported platform, so setHidden() must fail
    return false;
#endif
}

QLocalFile::QLocalFile(QObject *parent)
    : QFile(parent),
      d(new QLocalFilePrivate(this))
{
}

bool QLocalFile::open()
{
    return QFile::open(QIODevice::WriteOnly) && d->setPermission() && d->setHidden();
}
<|endoftext|>


<commit_before>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright (C) 2017, James R. Barlow (https://github.com/jbarlow83/)
 */

#include <cstdlib>
#include <system_error>

#include "utils.h"

/* POSIX functions on Windows have a leading underscore
 */
#if defined(_WIN32)
#    define posix_fdopen _fdopen
#    define posix_close _close
#else
#    define posix_fdopen fdopen
#    define posix_close close
#endif

/* Convert a Python object to a filesystem encoded path
 * Use Python's os.fspath() which accepts os.PathLike (str, bytes, pathlib.Path)
 * and returns bytes encoded in the filesystem encoding.
 * Cast to a string without transcoding.
 */

py::object fspath(py::object filename)
{
    py::handle handle = PyOS_FSPath(filename.ptr());
    if (!handle)
        throw py::error_already_set();
    return py::reinterpret_steal<py::object>(handle);
}
<commit_msg>utils: remove unused macro<commit_after>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Copyright (C) 2017, James R. Barlow (https://github.com/jbarlow83/)
 */

#include <cstdlib>
#include <system_error>

#include "utils.h"

/* Convert a Python object to a filesystem encoded path
 * Use Python's os.fspath() which accepts os.PathLike (str, bytes, pathlib.Path)
 * and returns bytes encoded in the filesystem encoding.
 * Cast to a string without transcoding.
 */

py::object fspath(py::object filename)
{
    py::handle handle = PyOS_FSPath(filename.ptr());
    if (!handle)
        throw py::error_already_set();
    return py::reinterpret_steal<py::object>(handle);
}
<|endoftext|>


<commit_before>#include "ContextGDIPlus.h"

bool canvas::ContextGDIPlus::is_initialized = false;
ULONG_PTR canvas::ContextGDIPlus::m_gdiplusToken;

using namespace std;
using namespace canvas;

void
ContextGDIPlus::fill() {
  if (fillStyle.getType() == Style::LINEAR_GRADIENT) {
    const std::map<float, Color> & colors = fillStyle.getColors();
    if (!colors.empty()) {
      std::map<float, Color>::const_iterator it0 = colors.begin(), it1 = colors.end();
      it1--;
      const Color & c0 = it0->second, c1 = it1->second;
      Gdiplus::LinearGradientBrush brush(Gdiplus::RectF(fillStyle.x0, fillStyle.y0, fillStyle.x1 - fillStyle.x0, fillStyle.y1 - fillStyle.y0), Gdiplus::Color(c0.red, c0.green, c0.blue), Gdiplus::Color(c1.red, c1.green, c1.blue), Gdiplus::LinearGradientModeHorizontal);
      default_surface.g->FillPath(&brush, &current_path);
    }
  } else {
    Gdiplus::SolidBrush brush(Gdiplus::Color(fillStyle.color.red, fillStyle.color.green, fillStyle.color.blue));
    default_surface.g->FillPath(&brush, &current_path);
  }
}

void
ContextGDIPlus::arc(double x, double y, double r, double sa, double ea, bool anticlockwise) {
  double span = 0;
  if (0 && ((!anticlockwise && (ea - sa >= 2 * M_PI)) || (anticlockwise && (sa - ea >= 2 * M_PI)))) {
    // If the anticlockwise argument is false and endAngle-startAngle is equal to or greater than 2*PI, or, if the
    // anticlockwise argument is true and startAngle-endAngle is equal to or greater than 2*PI, then the arc is the whole
    // circumference of this circle.
    span = 2 * M_PI;
  } else {
    if (!anticlockwise && (ea < sa)) {
      span += 2 * M_PI;
    } else if (anticlockwise && (sa < ea)) {
      span -= 2 * M_PI;
    }

#if 0
    // this is also due to switched coordinate system
    // we would end up with a 0 span instead of 360
    if (!(qFuzzyCompare(span + (ea - sa) + 1, 1.0) && qFuzzyCompare(qAbs(span), 360.0))) {
      // mod 360
      span += (ea - sa) - (static_cast<int>((ea - sa) / 360)) * 360;
    }
#else
    span += ea - sa;
#endif
  }

#if 0
  // If the path is empty, move to where the arc will start to avoid painting a line from (0,0)
  // NOTE: QPainterPath::isEmpty() won't work here since it ignores a lone MoveToElement
  if (!m_path.elementCount())
    m_path.arcMoveTo(xs, ys, width, height, sa);
  else if (!radius) {
    m_path.lineTo(xc, yc);
    return;
  }
#endif

#if 0
  if (anticlockwise) {
    span = -M_PI / 2.0;
  } else {
    span = M_PI / 2.0;
  }
#endif

  Gdiplus::RectF rect(Gdiplus::REAL(x - r), Gdiplus::REAL(y - r), Gdiplus::REAL(2 * r), Gdiplus::REAL(2 * r));
  current_path.AddArc(rect, Gdiplus::REAL(sa * 180 / M_PI), Gdiplus::REAL(span * 180 / M_PI));
  current_path.GetLastPoint(&current_position);
}

<commit_msg>fix gradients<commit_after>#include "ContextGDIPlus.h"

bool canvas::ContextGDIPlus::is_initialized = false;
ULONG_PTR canvas::ContextGDIPlus::m_gdiplusToken;

using namespace std;
using namespace canvas;

void
ContextGDIPlus::fill() {
  if (fillStyle.getType() == Style::LINEAR_GRADIENT) {
    const std::map<float, Color> & colors = fillStyle.getColors();
    if (!colors.empty()) {
      std::map<float, Color>::const_iterator it0 = colors.begin(), it1 = colors.end();
      it1--;
      const Color & c0 = it0->second, c1 = it1->second;
      Gdiplus::LinearGradientBrush brush(Gdiplus::PointF(fillStyle.x0, fillStyle.y0),
					 Gdiplus::PointF(fillStyle.x1, fillStyle.y1),
					 Gdiplus::Color(c0.red, c0.green, c0.blue)
					 Gdiplus::Color(c1.red, c1.green, c1.blue));
      default_surface.g->FillPath(&brush, &current_path);
    }
  } else {
    Gdiplus::SolidBrush brush(Gdiplus::Color(fillStyle.color.red, fillStyle.color.green, fillStyle.color.blue));
    default_surface.g->FillPath(&brush, &current_path);
  }
}

void
ContextGDIPlus::arc(double x, double y, double r, double sa, double ea, bool anticlockwise) {
  double span = 0;
  if (0 && ((!anticlockwise && (ea - sa >= 2 * M_PI)) || (anticlockwise && (sa - ea >= 2 * M_PI)))) {
    // If the anticlockwise argument is false and endAngle-startAngle is equal to or greater than 2*PI, or, if the
    // anticlockwise argument is true and startAngle-endAngle is equal to or greater than 2*PI, then the arc is the whole
    // circumference of this circle.
    span = 2 * M_PI;
  } else {
    if (!anticlockwise && (ea < sa)) {
      span += 2 * M_PI;
    } else if (anticlockwise && (sa < ea)) {
      span -= 2 * M_PI;
    }

#if 0
    // this is also due to switched coordinate system
    // we would end up with a 0 span instead of 360
    if (!(qFuzzyCompare(span + (ea - sa) + 1, 1.0) && qFuzzyCompare(qAbs(span), 360.0))) {
      // mod 360
      span += (ea - sa) - (static_cast<int>((ea - sa) / 360)) * 360;
    }
#else
    span += ea - sa;
#endif
  }

#if 0
  // If the path is empty, move to where the arc will start to avoid painting a line from (0,0)
  // NOTE: QPainterPath::isEmpty() won't work here since it ignores a lone MoveToElement
  if (!m_path.elementCount())
    m_path.arcMoveTo(xs, ys, width, height, sa);
  else if (!radius) {
    m_path.lineTo(xc, yc);
    return;
  }
#endif

#if 0
  if (anticlockwise) {
    span = -M_PI / 2.0;
  } else {
    span = M_PI / 2.0;
  }
#endif

  Gdiplus::RectF rect(Gdiplus::REAL(x - r), Gdiplus::REAL(y - r), Gdiplus::REAL(2 * r), Gdiplus::REAL(2 * r));
  current_path.AddArc(rect, Gdiplus::REAL(sa * 180 / M_PI), Gdiplus::REAL(span * 180 / M_PI));
  current_path.GetLastPoint(&current_position);
}

<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (C) 2016 Advanced Micro Devices, Inc. All rights reserved.
 ******************************************************************************/

#include <atomic>
#include <cassert>
#include <cstddef>
#include <iostream>
#include <unordered_map>
#include <vector>

#include "rocfft.h"

#include "plan.h"
#include "repo.h"
#include "transform.h"

#include "radix_table.h"

#include "kernel_launch.h"

#include "function_pool.h"
#include "ref_cpu.h"

#include "real2complex.h"

#ifdef TMP_DEBUG
#include "rocfft_hip.h"
#endif

std::atomic<bool> fn_checked(false);

/* this function is called during creation of plan : enqueue the HIP kernels by
 * function pointers*/
void PlanPowX(ExecPlan& execPlan)
{
    for(size_t i = 0; i < execPlan.execSeq.size(); i++)
    {
        if((execPlan.execSeq[i]->scheme == CS_KERNEL_STOCKHAM)
           || (execPlan.execSeq[i]->scheme == CS_KERNEL_STOCKHAM_BLOCK_CC)
           || (execPlan.execSeq[i]->scheme == CS_KERNEL_STOCKHAM_BLOCK_RC))
        {
            execPlan.execSeq[i]->twiddles = twiddles_create(
                execPlan.execSeq[i]->length[0], execPlan.execSeq[i]->precision, false);
        }

        if(execPlan.execSeq[i]->large1D != 0)
        {
            execPlan.execSeq[i]->twiddles_large = twiddles_create(
                execPlan.execSeq[i]->large1D, execPlan.execSeq[i]->precision, true);
        }
    }
    // copy host buffer to device buffer
    for(size_t i = 0; i < execPlan.execSeq.size(); i++)
    {
        execPlan.execSeq[i]->devKernArg = kargs_create(execPlan.execSeq[i]->length,
                                                       execPlan.execSeq[i]->inStride,
                                                       execPlan.execSeq[i]->outStride,
                                                       execPlan.execSeq[i]->iDist,
                                                       execPlan.execSeq[i]->oDist);
    }

    if(!fn_checked)
    {
        fn_checked = true;
        function_pool::verify_no_null_functions();
    }

    for(size_t i = 0; i < execPlan.execSeq.size(); i++)
    {
        DevFnCall ptr = nullptr;
        GridParam gp;
        size_t    bwd, wgs, lds;

        switch(execPlan.execSeq[i]->scheme)
        {
        case CS_KERNEL_STOCKHAM:
        {
            // get working group size and number of transforms
            size_t workGroupSize;
            size_t numTransforms;
            GetWGSAndNT(execPlan.execSeq[i]->length[0], workGroupSize, numTransforms);
            ptr = (execPlan.execSeq[0]->precision == rocfft_precision_single)
                ? function_pool::get_function_single(
                    std::make_pair(execPlan.execSeq[i]->length[0], CS_KERNEL_STOCKHAM))
                : function_pool::get_function_double(
                    std::make_pair(execPlan.execSeq[i]->length[0], CS_KERNEL_STOCKHAM));
            size_t batch = execPlan.execSeq[i]->batch;
            for(size_t j = 1; j < execPlan.execSeq[i]->length.size(); j++)
                batch *= execPlan.execSeq[i]->length[j];
            gp.b_x = (batch % numTransforms) ? 1 + (batch / numTransforms)
                : (batch / numTransforms);
            gp.tpb_x = workGroupSize;
        }
        break;
        case CS_KERNEL_STOCKHAM_BLOCK_CC:
            ptr = (execPlan.execSeq[0]->precision == rocfft_precision_single)
                ? function_pool::get_function_single(
                    std::make_pair(execPlan.execSeq[i]->length[0],
                                   CS_KERNEL_STOCKHAM_BLOCK_CC)) :
                function_pool::get_function_double(
                    std::make_pair(execPlan.execSeq[i]->length[0],
                                   CS_KERNEL_STOCKHAM_BLOCK_CC));
            GetBlockComputeTable(execPlan.execSeq[i]->length[0], bwd, wgs, lds);
            gp.b_x = (execPlan.execSeq[i]->length[1]) / bwd * execPlan.execSeq[i]->batch;
            if(execPlan.execSeq[i]->length.size() == 3)
            {
                gp.b_x *= execPlan.execSeq[i]->length[2];
            }
            gp.tpb_x = wgs;
            break;
        case CS_KERNEL_STOCKHAM_BLOCK_RC:
            ptr = (execPlan.execSeq[0]->precision == rocfft_precision_single)
                ? function_pool::get_function_single(
                    std::make_pair(execPlan.execSeq[i]->length[0],
                                   CS_KERNEL_STOCKHAM_BLOCK_RC))
                : function_pool::get_function_double(
                    std::make_pair(execPlan.execSeq[i]->length[0],
                                   CS_KERNEL_STOCKHAM_BLOCK_RC));
            GetBlockComputeTable(execPlan.execSeq[i]->length[0], bwd, wgs, lds);
            gp.b_x = (execPlan.execSeq[i]->length[1]) / bwd * execPlan.execSeq[i]->batch;
            if(execPlan.execSeq[i]->length.size() == 3)
            {
                gp.b_x *= execPlan.execSeq[i]->length[2];
            }
            gp.tpb_x = wgs;
            break;
        case CS_KERNEL_TRANSPOSE:
        case CS_KERNEL_TRANSPOSE_XY_Z:
        case CS_KERNEL_TRANSPOSE_Z_XY:
            ptr      = &FN_PRFX(transpose_var2);
            gp.tpb_x = (execPlan.execSeq[0]->precision == rocfft_precision_single) ? 32 : 64;
            gp.tpb_y = (execPlan.execSeq[0]->precision == rocfft_precision_single) ? 32 : 16;
            break;
        case CS_KERNEL_COPY_R_TO_CMPLX:
            ptr      = &real2complex;
            gp.b_x   = (execPlan.execSeq[i]->length[0] - 1) / 512 + 1;
            gp.b_y   = execPlan.execSeq[i]->batch;
            gp.tpb_x = 512;
            gp.tpb_y = 1;
            break;
        case CS_KERNEL_COPY_CMPLX_TO_R:
            ptr      = &complex2real;
            gp.b_x   = (execPlan.execSeq[i]->length[0] - 1) / 512 + 1;
            gp.b_y   = execPlan.execSeq[i]->batch;
            gp.tpb_x = 512;
            gp.tpb_y = 1;
            break;
        case CS_KERNEL_COPY_HERM_TO_CMPLX:
            ptr      = &hermitian2complex;
            gp.b_x   = (execPlan.execSeq[i]->length[0] - 1) / 512 + 1;
            gp.b_y   = execPlan.execSeq[i]->batch;
            gp.tpb_x = 512;
            gp.tpb_y = 1;
            break;
        case CS_KERNEL_COPY_CMPLX_TO_HERM:
            ptr      = &complex2hermitian;
            gp.b_x   = (execPlan.execSeq[i]->length[0] - 1) / 512 + 1;
            gp.b_y   = execPlan.execSeq[i]->batch;
            gp.tpb_x = 512;
            gp.tpb_y = 1;
            break;
        case CS_KERNEL_CHIRP:
            ptr      = &FN_PRFX(chirp);
            gp.tpb_x = 64;
            break;
        case CS_KERNEL_PAD_MUL:
        case CS_KERNEL_FFT_MUL:
        case CS_KERNEL_RES_MUL:
            ptr      = &FN_PRFX(mul);
            gp.tpb_x = 64;
            break;
        default:
            std::cout << "should not be in this case" << std::endl;
            std::cout << "scheme: " << execPlan.execSeq[i]->scheme << std::endl;
        }

        execPlan.devFnCall.push_back(ptr);
        execPlan.gridParam.push_back(gp);
    }
}

void TransformPowX(const ExecPlan&       execPlan,
                   void*                 in_buffer[],
                   void*                 out_buffer[],
                   rocfft_execution_info info)
{
    assert(execPlan.execSeq.size() == execPlan.devFnCall.size());
    assert(execPlan.execSeq.size() == execPlan.gridParam.size());

    // for(size_t i=0; i<5; i++) //multiple kernels involving transpose
    for(size_t i = 0; i < execPlan.execSeq.size(); i++) // multiple kernels involving transpose
    {
        DeviceCallIn  data;
        DeviceCallOut back;

        data.node = execPlan.execSeq[i];
        if(info == nullptr) // if info is not specified, use the default 0 stream
        {
            data.rocfft_stream = 0;
        }
        else // use the specified stream
        {
            data.rocfft_stream = info->rocfft_stream;
        }
        size_t inBytes;
        if(data.node->precision == rocfft_precision_single)
        {
            inBytes = sizeof(float) * 2;
        }
        else
        {
            inBytes = sizeof(double) * 2;
        }

        switch(data.node->obIn)
        {
        case OB_USER_IN:
            data.bufIn[0] = in_buffer[0];
            break;
        case OB_USER_OUT:
            data.bufIn[0] = out_buffer[0];
            break;
        case OB_TEMP:
            data.bufIn[0] = info->workBuffer;
            break;
        case OB_TEMP_CMPLX_FOR_REAL:
            data.bufIn[0] = (void*)((char*)info->workBuffer + execPlan.tmpWorkBufSize * inBytes);
            break;
        case OB_TEMP_BLUESTEIN:
            data.bufIn[0] = (void*)((char*)info->workBuffer
                                    + (execPlan.tmpWorkBufSize + execPlan.copyWorkBufSize
                                       + data.node->iOffset)
                                          * inBytes);
            break;
        default:
            assert(false);
        }

        switch(data.node->obOut)
        {
        case OB_USER_IN:
            data.bufOut[0] = in_buffer[0];
            break;
        case OB_USER_OUT:
            data.bufOut[0] = out_buffer[0];
            break;
        case OB_TEMP:
            data.bufOut[0] = info->workBuffer;
            break;
        case OB_TEMP_CMPLX_FOR_REAL:
            data.bufOut[0] = (void*)((char*)info->workBuffer + execPlan.tmpWorkBufSize * inBytes);
            break;
        case OB_TEMP_BLUESTEIN:
            data.bufOut[0] = (void*)((char*)info->workBuffer
                                     + (execPlan.tmpWorkBufSize + execPlan.copyWorkBufSize
                                        + data.node->oOffset)
                                           * inBytes);
            break;
        default:
            assert(false);
        }

        data.gridParam = execPlan.gridParam[i];

#ifdef TMP_DEBUG
        size_t in_size       = data.node->iDist * data.node->batch;
        size_t in_size_bytes = in_size * 2 * sizeof(float);
        void*  dbg_in        = malloc(in_size_bytes);
        hipMemcpy(dbg_in, data.bufIn[0], in_size_bytes, hipMemcpyDeviceToHost);

        size_t out_size       = data.node->oDist * data.node->batch;
        size_t out_size_bytes = out_size * 2 * sizeof(float);
        void*  dbg_out        = malloc(out_size_bytes);
        memset(dbg_out, 0x40, out_size_bytes);
        if(data.node->placement != rocfft_placement_inplace)
        {
            hipMemcpy(data.bufOut[0], dbg_out, out_size_bytes, hipMemcpyHostToDevice);
        }
        printf("attempting kernel: %zu\n", i);
        fflush(stdout);
#endif

        DevFnCall fn = execPlan.devFnCall[i];
        if(fn)
        {
#ifdef REF_DEBUG
            // verify results for simple and five-stage scheme not for RC, CC scheme
            printf("\n---------------------------------------------\n");
            printf("\n\nkernel: %zu\n", i);
            fflush(stdout);
            RefLibOp refLibOp(&data);
#endif
            fn(&data, &back); // execution kernel here
#ifdef REF_DEBUG
            refLibOp.VerifyResult(&data);
#endif
        }
        else
        {
            printf("null ptr function call error\n");
        }

#ifdef TMP_DEBUG
        hipDeviceSynchronize();
        printf("executed kernel: %zu\n", i);
        fflush(stdout);
        hipMemcpy(dbg_out, data.bufOut[0], out_size_bytes, hipMemcpyDeviceToHost);
        printf("copied from device\n");

        // if(i == 0 || i == 2 || i == 4)
        {
            float2* f_in  = (float2*)dbg_in;
            float2* f_out = (float2*)dbg_out;
            // temporary print out the kernel output
            for(size_t y = 0; y < data.node->length[1]; y++)
            {
                for(size_t x = 0; x < data.node->length[0]; x++)
                {
                    printf("x=%zu, y=%zu, kernel output result = %f, %f\n",
                           x,
                           y,
                           f_out[y * data.node->length[0] + x].x,
                           f_out[y * data.node->length[0] + x].y);
                }
            }
        }

        printf("\n---------------------------------------------\n");
        free(dbg_out);
        free(dbg_in);
#endif
    }
}
<commit_msg>Apply clang-format.<commit_after>/*******************************************************************************
 * Copyright (C) 2016 Advanced Micro Devices, Inc. All rights reserved.
 ******************************************************************************/

#include <atomic>
#include <cassert>
#include <cstddef>
#include <iostream>
#include <unordered_map>
#include <vector>

#include "rocfft.h"

#include "plan.h"
#include "repo.h"
#include "transform.h"

#include "radix_table.h"

#include "kernel_launch.h"

#include "function_pool.h"
#include "ref_cpu.h"

#include "real2complex.h"

#ifdef TMP_DEBUG
#include "rocfft_hip.h"
#endif

std::atomic<bool> fn_checked(false);

/* this function is called during creation of plan : enqueue the HIP kernels by
 * function pointers*/
void PlanPowX(ExecPlan& execPlan)
{
    for(size_t i = 0; i < execPlan.execSeq.size(); i++)
    {
        if((execPlan.execSeq[i]->scheme == CS_KERNEL_STOCKHAM)
           || (execPlan.execSeq[i]->scheme == CS_KERNEL_STOCKHAM_BLOCK_CC)
           || (execPlan.execSeq[i]->scheme == CS_KERNEL_STOCKHAM_BLOCK_RC))
        {
            execPlan.execSeq[i]->twiddles = twiddles_create(
                execPlan.execSeq[i]->length[0], execPlan.execSeq[i]->precision, false);
        }

        if(execPlan.execSeq[i]->large1D != 0)
        {
            execPlan.execSeq[i]->twiddles_large = twiddles_create(
                execPlan.execSeq[i]->large1D, execPlan.execSeq[i]->precision, true);
        }
    }
    // copy host buffer to device buffer
    for(size_t i = 0; i < execPlan.execSeq.size(); i++)
    {
        execPlan.execSeq[i]->devKernArg = kargs_create(execPlan.execSeq[i]->length,
                                                       execPlan.execSeq[i]->inStride,
                                                       execPlan.execSeq[i]->outStride,
                                                       execPlan.execSeq[i]->iDist,
                                                       execPlan.execSeq[i]->oDist);
    }

    if(!fn_checked)
    {
        fn_checked = true;
        function_pool::verify_no_null_functions();
    }

    for(size_t i = 0; i < execPlan.execSeq.size(); i++)
    {
        DevFnCall ptr = nullptr;
        GridParam gp;
        size_t    bwd, wgs, lds;

        switch(execPlan.execSeq[i]->scheme)
        {
        case CS_KERNEL_STOCKHAM:
        {
            // get working group size and number of transforms
            size_t workGroupSize;
            size_t numTransforms;
            GetWGSAndNT(execPlan.execSeq[i]->length[0], workGroupSize, numTransforms);
            ptr = (execPlan.execSeq[0]->precision == rocfft_precision_single)
                      ? function_pool::get_function_single(
                          std::make_pair(execPlan.execSeq[i]->length[0], CS_KERNEL_STOCKHAM))
                      : function_pool::get_function_double(
                          std::make_pair(execPlan.execSeq[i]->length[0], CS_KERNEL_STOCKHAM));
            size_t batch = execPlan.execSeq[i]->batch;
            for(size_t j = 1; j < execPlan.execSeq[i]->length.size(); j++)
                batch *= execPlan.execSeq[i]->length[j];
            gp.b_x
                = (batch % numTransforms) ? 1 + (batch / numTransforms) : (batch / numTransforms);
            gp.tpb_x = workGroupSize;
        }
        break;
        case CS_KERNEL_STOCKHAM_BLOCK_CC:
            ptr = (execPlan.execSeq[0]->precision == rocfft_precision_single)
                      ? function_pool::get_function_single(std::make_pair(
                          execPlan.execSeq[i]->length[0], CS_KERNEL_STOCKHAM_BLOCK_CC))
                      : function_pool::get_function_double(std::make_pair(
                          execPlan.execSeq[i]->length[0], CS_KERNEL_STOCKHAM_BLOCK_CC));
            GetBlockComputeTable(execPlan.execSeq[i]->length[0], bwd, wgs, lds);
            gp.b_x = (execPlan.execSeq[i]->length[1]) / bwd * execPlan.execSeq[i]->batch;
            if(execPlan.execSeq[i]->length.size() == 3)
            {
                gp.b_x *= execPlan.execSeq[i]->length[2];
            }
            gp.tpb_x = wgs;
            break;
        case CS_KERNEL_STOCKHAM_BLOCK_RC:
            ptr = (execPlan.execSeq[0]->precision == rocfft_precision_single)
                      ? function_pool::get_function_single(std::make_pair(
                          execPlan.execSeq[i]->length[0], CS_KERNEL_STOCKHAM_BLOCK_RC))
                      : function_pool::get_function_double(std::make_pair(
                          execPlan.execSeq[i]->length[0], CS_KERNEL_STOCKHAM_BLOCK_RC));
            GetBlockComputeTable(execPlan.execSeq[i]->length[0], bwd, wgs, lds);
            gp.b_x = (execPlan.execSeq[i]->length[1]) / bwd * execPlan.execSeq[i]->batch;
            if(execPlan.execSeq[i]->length.size() == 3)
            {
                gp.b_x *= execPlan.execSeq[i]->length[2];
            }
            gp.tpb_x = wgs;
            break;
        case CS_KERNEL_TRANSPOSE:
        case CS_KERNEL_TRANSPOSE_XY_Z:
        case CS_KERNEL_TRANSPOSE_Z_XY:
            ptr      = &FN_PRFX(transpose_var2);
            gp.tpb_x = (execPlan.execSeq[0]->precision == rocfft_precision_single) ? 32 : 64;
            gp.tpb_y = (execPlan.execSeq[0]->precision == rocfft_precision_single) ? 32 : 16;
            break;
        case CS_KERNEL_COPY_R_TO_CMPLX:
            ptr      = &real2complex;
            gp.b_x   = (execPlan.execSeq[i]->length[0] - 1) / 512 + 1;
            gp.b_y   = execPlan.execSeq[i]->batch;
            gp.tpb_x = 512;
            gp.tpb_y = 1;
            break;
        case CS_KERNEL_COPY_CMPLX_TO_R:
            ptr      = &complex2real;
            gp.b_x   = (execPlan.execSeq[i]->length[0] - 1) / 512 + 1;
            gp.b_y   = execPlan.execSeq[i]->batch;
            gp.tpb_x = 512;
            gp.tpb_y = 1;
            break;
        case CS_KERNEL_COPY_HERM_TO_CMPLX:
            ptr      = &hermitian2complex;
            gp.b_x   = (execPlan.execSeq[i]->length[0] - 1) / 512 + 1;
            gp.b_y   = execPlan.execSeq[i]->batch;
            gp.tpb_x = 512;
            gp.tpb_y = 1;
            break;
        case CS_KERNEL_COPY_CMPLX_TO_HERM:
            ptr      = &complex2hermitian;
            gp.b_x   = (execPlan.execSeq[i]->length[0] - 1) / 512 + 1;
            gp.b_y   = execPlan.execSeq[i]->batch;
            gp.tpb_x = 512;
            gp.tpb_y = 1;
            break;
        case CS_KERNEL_CHIRP:
            ptr      = &FN_PRFX(chirp);
            gp.tpb_x = 64;
            break;
        case CS_KERNEL_PAD_MUL:
        case CS_KERNEL_FFT_MUL:
        case CS_KERNEL_RES_MUL:
            ptr      = &FN_PRFX(mul);
            gp.tpb_x = 64;
            break;
        default:
            std::cout << "should not be in this case" << std::endl;
            std::cout << "scheme: " << execPlan.execSeq[i]->scheme << std::endl;
        }

        execPlan.devFnCall.push_back(ptr);
        execPlan.gridParam.push_back(gp);
    }
}

void TransformPowX(const ExecPlan&       execPlan,
                   void*                 in_buffer[],
                   void*                 out_buffer[],
                   rocfft_execution_info info)
{
    assert(execPlan.execSeq.size() == execPlan.devFnCall.size());
    assert(execPlan.execSeq.size() == execPlan.gridParam.size());

    // for(size_t i=0; i<5; i++) //multiple kernels involving transpose
    for(size_t i = 0; i < execPlan.execSeq.size(); i++) // multiple kernels involving transpose
    {
        DeviceCallIn  data;
        DeviceCallOut back;

        data.node = execPlan.execSeq[i];
        if(info == nullptr) // if info is not specified, use the default 0 stream
        {
            data.rocfft_stream = 0;
        }
        else // use the specified stream
        {
            data.rocfft_stream = info->rocfft_stream;
        }
        size_t inBytes;
        if(data.node->precision == rocfft_precision_single)
        {
            inBytes = sizeof(float) * 2;
        }
        else
        {
            inBytes = sizeof(double) * 2;
        }

        switch(data.node->obIn)
        {
        case OB_USER_IN:
            data.bufIn[0] = in_buffer[0];
            break;
        case OB_USER_OUT:
            data.bufIn[0] = out_buffer[0];
            break;
        case OB_TEMP:
            data.bufIn[0] = info->workBuffer;
            break;
        case OB_TEMP_CMPLX_FOR_REAL:
            data.bufIn[0] = (void*)((char*)info->workBuffer + execPlan.tmpWorkBufSize * inBytes);
            break;
        case OB_TEMP_BLUESTEIN:
            data.bufIn[0] = (void*)((char*)info->workBuffer
                                    + (execPlan.tmpWorkBufSize + execPlan.copyWorkBufSize
                                       + data.node->iOffset)
                                          * inBytes);
            break;
        default:
            assert(false);
        }

        switch(data.node->obOut)
        {
        case OB_USER_IN:
            data.bufOut[0] = in_buffer[0];
            break;
        case OB_USER_OUT:
            data.bufOut[0] = out_buffer[0];
            break;
        case OB_TEMP:
            data.bufOut[0] = info->workBuffer;
            break;
        case OB_TEMP_CMPLX_FOR_REAL:
            data.bufOut[0] = (void*)((char*)info->workBuffer + execPlan.tmpWorkBufSize * inBytes);
            break;
        case OB_TEMP_BLUESTEIN:
            data.bufOut[0] = (void*)((char*)info->workBuffer
                                     + (execPlan.tmpWorkBufSize + execPlan.copyWorkBufSize
                                        + data.node->oOffset)
                                           * inBytes);
            break;
        default:
            assert(false);
        }

        data.gridParam = execPlan.gridParam[i];

#ifdef TMP_DEBUG
        size_t in_size       = data.node->iDist * data.node->batch;
        size_t in_size_bytes = in_size * 2 * sizeof(float);
        void*  dbg_in        = malloc(in_size_bytes);
        hipMemcpy(dbg_in, data.bufIn[0], in_size_bytes, hipMemcpyDeviceToHost);

        size_t out_size       = data.node->oDist * data.node->batch;
        size_t out_size_bytes = out_size * 2 * sizeof(float);
        void*  dbg_out        = malloc(out_size_bytes);
        memset(dbg_out, 0x40, out_size_bytes);
        if(data.node->placement != rocfft_placement_inplace)
        {
            hipMemcpy(data.bufOut[0], dbg_out, out_size_bytes, hipMemcpyHostToDevice);
        }
        printf("attempting kernel: %zu\n", i);
        fflush(stdout);
#endif

        DevFnCall fn = execPlan.devFnCall[i];
        if(fn)
        {
#ifdef REF_DEBUG
            // verify results for simple and five-stage scheme not for RC, CC scheme
            printf("\n---------------------------------------------\n");
            printf("\n\nkernel: %zu\n", i);
            fflush(stdout);
            RefLibOp refLibOp(&data);
#endif
            fn(&data, &back); // execution kernel here
#ifdef REF_DEBUG
            refLibOp.VerifyResult(&data);
#endif
        }
        else
        {
            printf("null ptr function call error\n");
        }

#ifdef TMP_DEBUG
        hipDeviceSynchronize();
        printf("executed kernel: %zu\n", i);
        fflush(stdout);
        hipMemcpy(dbg_out, data.bufOut[0], out_size_bytes, hipMemcpyDeviceToHost);
        printf("copied from device\n");

        // if(i == 0 || i == 2 || i == 4)
        {
            float2* f_in  = (float2*)dbg_in;
            float2* f_out = (float2*)dbg_out;
            // temporary print out the kernel output
            for(size_t y = 0; y < data.node->length[1]; y++)
            {
                for(size_t x = 0; x < data.node->length[0]; x++)
                {
                    printf("x=%zu, y=%zu, kernel output result = %f, %f\n",
                           x,
                           y,
                           f_out[y * data.node->length[0] + x].x,
                           f_out[y * data.node->length[0] + x].y);
                }
            }
        }

        printf("\n---------------------------------------------\n");
        free(dbg_out);
        free(dbg_in);
#endif
    }
}
<|endoftext|>