<commit_before>#define F_CPU 1000000UL

#include <avr/sleep.h>
#include "macros.h"
#include "tasks.h"
#include "clock.h"
#include "irqs.h"
#include "adc.h"

// duration in ms for hBridge output
const uint16_t hBridgeOutDuration = 50;

// wait timeSignalWaitPeriod ms until timeSignal is no longer present
// before turning IRQ for timeSignal on again.
const uint16_t timeSignalWaitPeriod = 10;

// when displayed time is not time, we move the minute finger faster
// but we will wait this pause (in ms) between every finger movement.
const uint16_t pauseBetweenHBridgePulses = 500;

// 256 * minBatt1Voltage / 1.1 (1.1 ref voltage)
const uint8_t batt1Min = 186; // 0.8V
const uint8_t batt2Min = 186; // 0.8V
const uint8_t batt3Min = 186; // 0.8V

typedef PIN_DIP_3 PauseClockPin;

// DIP_4 is INT1 irq
typedef PIN_DIP_4 CheckBatteryVoltagePin;

// DIP_5 is INT0 irq
typedef PIN_DIP_5 TimeSignalPin;

typedef PIN_DIP_6 NoonSensorPin;

typedef PIN_DIP_13 HBridge1;
typedef PIN_DIP_14 HBridge2;

typedef PIN_DIP_28 Batt1Pin;
typedef PIN_DIP_27 Batt1OutPin;
typedef PIN_DIP_26 Batt2Pin;
typedef PIN_DIP_25 Batt2OutPin;
typedef PIN_DIP_24 Batt3Pin;
typedef PIN_DIP_23 Batt3OutPin;

uint16_t time; // in minutes from 12:00; wraps every 12*60 minutes

// we allow the displayed time to be pause (for instance during the night,
// because the clock is really loud)
uint16_t displayedTime; // in minutes from 12:00; wraps every 12*60 minutes

///////////////////////////////  Task managment  ///////////////////////////////

enum Task {
  IncMinute = 0,
  CheckBatteries = 0,
};

uint8_t tasksToRun;

void startTask(Task task) {
  tasksToRun |= _BV(task);
}

void stopTask(Task task) {
  tasksToRun &= ~(_BV(task));
}

void stopAllTasks() {
  tasksToRun = 0;
}

uint8_t isAllTasksStopped() {
  return tasksToRun = 0;
}

uint8_t isTaskStarted(Task task) {
  return tasksToRun & ~(_BV(task));
}
////////////////////////////////////////////////////////////////////////////////

/////////////////  TimerSignal -- INT0 related functionality  //////////////////

void enableTimerSignalIRQ() {
  EIMSK |= _BV(INT0);
}

void initTimerSignal() {
  // nothing to do for pin
  // pins are Hi-Z input by default

  // turn on irq
  enableTimerSignalIRQ();
  sei();
}

#define NEW_IRQ_TASK IncMinuteIrqTask
IRQ_TASK(NEW_IRQ_TASK) {
  time++;
  if (time == 12 * 60) time = 0;

  startTask(Task::IncMinute);

  // turn off IRQ until signal from real clock is no longer present
  // otherwise this IRQ will trigger too often.
  EIMSK &= ~(_BV(INT0));
};
#include "internal/register_irq_task_INT0.h"

uint8_t timerSignalPresent() {
  return GET_BIT(TimeSignalPin, PIN) == 0;
}
////////////////////////////////////////////////////////////////////////////////

/////////////////  CheckBattery -- INT1 related functionality  /////////////////

void enableCheckBatteryIRQ() {
  EIMSK |= _BV(INT1);
}

void initCheckBatteryPin() {
  // nothing to do for pin
  // pins are Hi-Z input by default

  // turn on irq
  enableCheckBatteryIRQ();
  sei();
}

#define NEW_IRQ_TASK CheckBatteryIrqTask
IRQ_TASK(NEW_IRQ_TASK) {
  startTask(Task::CheckBatteries);

  // turn off IRQ until button is no longer pressed
  // otherwise this IRQ will trigger too often.
  EIMSK &= ~(_BV(INT1));
};
#include "internal/register_irq_task_INT1.h"

uint8_t checkBatteryPressed() {
  return GET_BIT(CheckBatteryVoltagePin, PIN) == 0;
}
////////////////////////////////////////////////////////////////////////////////

////////////////////  PauseClock -- related functionality  /////////////////////

void initClockPaused() {
  // nothing to do
  // pins are Hi-Z input by default
}

uint8_t clockPaused() {
  return GET_BIT(PauseClockPin, PIN);
}
////////////////////////////////////////////////////////////////////////////////

////////////////////  NoonSensor -- related functionality  /////////////////////

void setNoonSensor(uint8_t v) {
  SET_BIT(NoonSensorPin, PORT, v);
}

void initNoonSensor() {
  SET_BIT(NoonSensorPin, DDR, 1);

  // start with noonSensor "on"
  setNoonSensor(1);
}
////////////////////////////////////////////////////////////////////////////////

struct IncMinuteTask {
  static inline uint8_t is_enabled() {
    return isTaskStarted(Task::IncMinute);
  }

  template<typename T>
  static inline T run(const T& clock) {
    // this task will be called twice for every minute increment.
    // first to turn the output on and second to turn it off again.

    // we also need to keep track if we have to send a positive or negative
    // signal.

    static uint8_t status = 0;

    const uint8_t clockP = clockPaused();

    const uint8_t hBridgeStatus = status & 0b11;

    if (hBridgeStatus == 0 || hBridgeStatus == 2) {
      if (!clockP) {
        if (hBridgeStatus == 0) SET_BIT(HBridge1, PORT, 1);
        else SET_BIT(HBridge1, PORT, 1);

        displayedTime++;
        if (displayedTime == 12 * 60) {
          displayedTime = 0;
          setNoonSensor(1);
        } else setNoonSensor(0);

      }

      status++;
      //             sleep for hbridgeOutDuration
      return ms_to_units(hBridgeOutDuration);
    }

    // status 1 or 3 → turn HBridge1 / HBridge2 off
    if (hBridgeStatus == 1) SET_BIT(HBridge1, PORT, 0);
    else SET_BIT(HBridge2, PORT, 0);

    // we have to make sure the timeSignal is no longer present, before
    // turning irq for timeSignal on again.
    if (timerSignalPresent()) return ms_to_units(timeSignalWaitPeriod);

    // only then switch to next status:
    status++;

    // mark IncMinuteTask as done:
    //             disable task in tasktracker
    // remove from taskTracker before enabling IRQ (otherwise we would have a
    // race condition
    stopTask(Task::IncMinute);

    enableTimerSignalIRQ();

    if (!clockP && displayedTime != time) {
      // reenable incMinuteTask, need to correct displayed time
      startTask(Task::IncMinute);
      return ms_to_units(pauseBetweenHBridgePulses);
    }

    return 0;
  }
};

#define NEW_TASK IncMinuteTask
#include REGISTER_TASK

struct CheckBatteriesTask {
  static inline uint8_t is_enabled() {
    return isTaskStarted(Task::CheckBatteries);
  }

  typedef Adc<_adc::Mode::SingleConversion, _adc::Ref::V1_1, Batt1Pin> Adc_Batt1;
  typedef Adc<_adc::Mode::SingleConversion, _adc::Ref::V1_1, Batt2Pin> Adc_Batt2;
  typedef Adc<_adc::Mode::SingleConversion, _adc::Ref::V1_1, Batt3Pin> Adc_Batt3;

  template<typename T>
  static inline T run(const T& clock) {
    Adc_Batt1::init();
    uint8_t batt1 = Adc_Batt1::adc_8bit();
    // don't need to turn off adc

    Adc_Batt2::init();
    uint8_t batt2 = Adc_Batt2::adc_8bit();
    // don't need to turn off adc

    Adc_Batt3::init();
    uint8_t batt3 = Adc_Batt3::adc_8bit();
    Adc_Batt3::turn_off();

    SET_BIT(Batt1OutPin, PORT, (batt1 > batt1Min));
    SET_BIT(Batt2OutPin, PORT, (batt2 > batt2Min));
    SET_BIT(Batt3OutPin, PORT, (batt3 > batt3Min));

    if (checkBatteryPressed()) return ms_to_units(200);

    // user no longer presses battery check button

    // turn off all outputs:
    SET_BIT(Batt1OutPin, PORT, 0);
    SET_BIT(Batt2OutPin, PORT, 0);
    SET_BIT(Batt3OutPin, PORT, 0);

    stopTask(Task::CheckBatteries);

    enableCheckBatteryIRQ();
    return 0;
  }
};

#define NEW_TASK CheckBatteriesTask
#include REGISTER_TASK

__attribute__ ((OS_main)) int main(void) {

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  // start with all tasks stopped
  stopAllTasks();

  displayedTime = 0;
  time = 0;

  initNoonSensor();
  initClockPaused();
  initTimerSignal();

  for (;;) {
    execTasks<uint16_t, TASK_LIST>();

    // if all tasks are done
    // power down
    // go to sleep without race conditions...
    cli();
    if (isAllTasksStopped()) {
      sleep_enable();
      sei();
      sleep_cpu();
      sleep_disable();
    }
    sei();
  }
  return 0;
}

#define USE_ONLY_DEFINED_IRQS
#include REGISTER_IRQS<commit_msg>feat/fix: fix Task enum int value<commit_after>#define F_CPU 1000000UL

#include <avr/sleep.h>
#include "macros.h"
#include "tasks.h"
#include "clock.h"
#include "irqs.h"
#include "adc.h"

// duration in ms for hBridge output
const uint16_t hBridgeOutDuration = 50;

// wait timeSignalWaitPeriod ms until timeSignal is no longer present
// before turning IRQ for timeSignal on again.
const uint16_t timeSignalWaitPeriod = 10;

// when displayed time is not time, we move the minute finger faster
// but we will wait this pause (in ms) between every finger movement.
const uint16_t pauseBetweenHBridgePulses = 500;

template <typename T>
constexpr uint8_t voltsToUnits(T volts) {
  return 256 * volts / 1.1;
}

// 256 * minBatt1Voltage / 1.1 (1.1 ref voltage)
const uint8_t batt1Min = voltsToUnits(0.8); // should be 186 units
const uint8_t batt2Min = voltsToUnits(0.8); // should be 186 units
const uint8_t batt3Min = voltsToUnits(0.8); // should be 186 units

typedef PIN_DIP_3 PauseClockPin;

// DIP_4 is INT1 irq
typedef PIN_DIP_4 CheckBatteryVoltagePin;

// DIP_5 is INT0 irq
typedef PIN_DIP_5 TimeSignalPin;

typedef PIN_DIP_6 NoonSensorPin;

typedef PIN_DIP_13 HBridge1;
typedef PIN_DIP_14 HBridge2;

typedef PIN_DIP_28 Batt1Pin;
typedef PIN_DIP_27 Batt1OutPin;
typedef PIN_DIP_26 Batt2Pin;
typedef PIN_DIP_25 Batt2OutPin;
typedef PIN_DIP_24 Batt3Pin;
typedef PIN_DIP_23 Batt3OutPin;

uint16_t time; // in minutes from 12:00; wraps every 12*60 minutes

// we allow the displayed time to be pause (for instance during the night,
// because the clock is really loud)
uint16_t displayedTime; // in minutes from 12:00; wraps every 12*60 minutes

///////////////////////////////  Task managment  ///////////////////////////////

enum Task {
  IncMinute = 0,
  CheckBatteries = 1,
  ReenableTimerSignalIrq = 2
};

uint8_t tasksToRun;

void startTask(Task task) {
  tasksToRun |= _BV(task);
}

void stopTask(Task task) {
  tasksToRun &= ~(_BV(task));
}

void stopAllTasks() {
  tasksToRun = 0;
}

uint8_t isAllTasksStopped() {
  return tasksToRun = 0;
}

uint8_t isTaskStarted(Task task) {
  return tasksToRun & ~(_BV(task));
}
////////////////////////////////////////////////////////////////////////////////

/////////////////  TimerSignal -- INT0 related functionality  //////////////////

void enableTimerSignalIRQ() {
  EIMSK |= _BV(INT0);
}

void initTimerSignal() {
  // nothing to do for pin
  // pins are Hi-Z input by default

  // turn on irq
  enableTimerSignalIRQ();
  sei();
}

#define NEW_IRQ_TASK IncMinuteIrqTask
IRQ_TASK(NEW_IRQ_TASK) {
  time++;
  if (time == 12 * 60) time = 0;

  startTask(Task::IncMinute);
  startTask(Task::ReenableTimerSignalIrq);

  // turn off IRQ until signal from real clock is no longer present
  // otherwise this IRQ will trigger too often.
  EIMSK &= ~(_BV(INT0));
};
#include "internal/register_irq_task_INT0.h"

uint8_t timerSignalPresent() {
  return GET_BIT(TimeSignalPin, PIN) == 0;
}

#define NEW_TASK ReenableTimerSignalIrqTask
struct NEW_TASK {
  static inline uint8_t is_enabled() {
    return isTaskStarted(Task::ReenableTimerSignalIrq);
  }

  template<typename T>
  static inline T run(const T& clock) {
    if (!timerSignalPresent()) {
      stopTask(Task::ReenableTimerSignalIrq);
      enableTimerSignalIRQ();
    }
    return ms_to_units(5);
  }
};
#include REGISTER_TASK
////////////////////////////////////////////////////////////////////////////////

/////////////////  CheckBattery -- INT1 related functionality  /////////////////

void enableCheckBatteryIRQ() {
  EIMSK |= _BV(INT1);
}

void initCheckBatteryPin() {
  // nothing to do for pin
  // pins are Hi-Z input by default

  // turn on irq
  enableCheckBatteryIRQ();
  sei();
}

#define NEW_IRQ_TASK CheckBatteryIrqTask
IRQ_TASK(NEW_IRQ_TASK) {
  startTask(Task::CheckBatteries);

  // turn off IRQ until button is no longer pressed
  // otherwise this IRQ will trigger too often.
  EIMSK &= ~(_BV(INT1));
};
#include "internal/register_irq_task_INT1.h"

uint8_t checkBatteryPressed() {
  return GET_BIT(CheckBatteryVoltagePin, PIN) == 0;
}
////////////////////////////////////////////////////////////////////////////////

////////////////////  PauseClock -- related functionality  /////////////////////

void initClockPaused() {
  // nothing to do
  // pins are Hi-Z input by default
}

uint8_t clockPaused() {
  return GET_BIT(PauseClockPin, PIN);
}
////////////////////////////////////////////////////////////////////////////////

////////////////////  NoonSensor -- related functionality  /////////////////////

void setNoonSensor(uint8_t v) {
  SET_BIT(NoonSensorPin, PORT, v);
}

void initNoonSensor() {
  SET_BIT(NoonSensorPin, DDR, 1);

  // start with noonSensor "on"
  setNoonSensor(1);
}
////////////////////////////////////////////////////////////////////////////////

#define NEW_TASK IncMinuteTask
struct NEW_TASK {
  static inline uint8_t is_enabled() {
    return isTaskStarted(Task::IncMinute);
  }

  template<typename T>
  static inline T run(const T& clock) {
    // this task will be called twice for every minute increment.
    // first to turn the output on and second to turn it off again.

    // we also need to keep track if we have to send a positive or negative
    // signal.

    static uint8_t status = 0;

    const uint8_t clockP = clockPaused();

    const uint8_t hBridgeStatus = status & 0b11;

    if (hBridgeStatus == 0 || hBridgeStatus == 2) {
      if (!clockP) {
        if (hBridgeStatus == 0) SET_BIT(HBridge1, PORT, 1);
        else SET_BIT(HBridge1, PORT, 1);

        displayedTime++;
        if (displayedTime == 12 * 60) {
          displayedTime = 0;
          setNoonSensor(1);
        } else setNoonSensor(0);

      }

      status++;
      //             sleep for hbridgeOutDuration
      return ms_to_units(hBridgeOutDuration);
    }

    // status 1 or 3 → turn HBridge1 / HBridge2 off
    if (hBridgeStatus == 1) SET_BIT(HBridge1, PORT, 0);
    else SET_BIT(HBridge2, PORT, 0);

    // we have to make sure the timeSignal is no longer present, before
    // turning irq for timeSignal on again.
    if (timerSignalPresent()) return ms_to_units(timeSignalWaitPeriod);

    // only then switch to next status:
    status++;

    // mark IncMinuteTask as done:
    //             disable task in tasktracker
    stopTask(Task::IncMinute);

    if (!clockP && displayedTime != time) {
      // reenable incMinuteTask, need to correct displayed time
      startTask(Task::IncMinute);
      return ms_to_units(pauseBetweenHBridgePulses);
    }

    return 0;
  }
};
#include REGISTER_TASK

#define NEW_TASK CheckBatteriesTask
struct NEW_TASK {
  static inline uint8_t is_enabled() {
    return isTaskStarted(Task::CheckBatteries);
  }

  typedef Adc<_adc::Mode::SingleConversion, _adc::Ref::V1_1, Batt1Pin> Adc_Batt1;
  typedef Adc<_adc::Mode::SingleConversion, _adc::Ref::V1_1, Batt2Pin> Adc_Batt2;
  typedef Adc<_adc::Mode::SingleConversion, _adc::Ref::V1_1, Batt3Pin> Adc_Batt3;

  template<typename T>
  static inline T run(const T& clock) {
    Adc_Batt1::init();
    uint8_t batt1 = Adc_Batt1::adc_8bit();
    // don't need to turn off adc

    Adc_Batt2::init();
    uint8_t batt2 = Adc_Batt2::adc_8bit();
    // don't need to turn off adc

    Adc_Batt3::init();
    uint8_t batt3 = Adc_Batt3::adc_8bit();
    Adc_Batt3::turn_off();

    SET_BIT(Batt1OutPin, PORT, (batt1 > batt1Min));
    SET_BIT(Batt2OutPin, PORT, (batt2 > batt2Min));
    SET_BIT(Batt3OutPin, PORT, (batt3 > batt3Min));

    if (checkBatteryPressed()) return ms_to_units(200);

    // user no longer presses battery check button

    // turn off all outputs:
    SET_BIT(Batt1OutPin, PORT, 0);
    SET_BIT(Batt2OutPin, PORT, 0);
    SET_BIT(Batt3OutPin, PORT, 0);

    stopTask(Task::CheckBatteries);

    enableCheckBatteryIRQ();
    return 0;
  }
};

#include REGISTER_TASK

__attribute__ ((OS_main)) int main(void) {

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  // start with all tasks stopped
  stopAllTasks();

  displayedTime = 0;
  time = 0;

  initNoonSensor();
  initClockPaused();
  initTimerSignal();

  for (;;) {
    execTasks<uint16_t, TASK_LIST>();

    // if all tasks are done
    // power down
    // go to sleep without race conditions...
    cli();
    if (isAllTasksStopped()) {
      sleep_enable();
      sei();
      sleep_cpu();
      sleep_disable();
    }
    sei();
  }
  return 0;
}

#define USE_ONLY_DEFINED_IRQS
#include REGISTER_IRQS<|endoftext|>


<commit_before>#ifndef BITSMANIPULATION_HPP_
#define BITSMANIPULATION_HPP_

#include <iostream>
#include <limits>
#include <bitset>

void Representation()
{
    std::cout << "Representation of the numbers in binary and hex" <<
                    std::endl;

    const long long unsigned int max = std::numeric_limits<unsigned char>::max();
    for (long long unsigned int i = 0; i <= max; ++i)
    {
        std::cout << "Dec: " <<  std::dec << std::showbase << i;
        std::cout << " Bin: 0b" << std::bitset<8>(i).to_string();
        std::cout << " Oct: " << std::oct << std::showbase << i;
        std::cout << " Hex: " << std::hex << std::showbase << i << std::endl;
    }

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

void OperationAND()
{
    std::cout << "Example of AND operation" << std::endl;
    unsigned char first = 0b00111000;
    unsigned char second = 0b10101010;
    unsigned char result = first & second;

    std::cout << "First value: 0b" << std::bitset<8>(first).to_string() <<
                    std::endl;
    std::cout << "Second value: 0b" << std::bitset<8>(second).to_string() <<
                    std::endl;
    std::cout << "Result of AND operation: 0b" <<
                    std::bitset<8>(result).to_string() << std::endl;

    first = 0b11111000;
    second = 0b10101011;
    result = first & second;

    std::cout << std::endl << "With other values" << std::endl;
    std::cout << "First value: 0b" << std::bitset<8>(first).to_string() <<
                    std::endl;
    std::cout << "Second value: 0b" << std::bitset<8>(second).to_string() <<
                    std::endl;
    std::cout << "Result of AND operation: 0b" <<
                    std::bitset<8>(result).to_string() << std::endl;

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

// TODO: OR operation
// TODO: XOR operation
// TODO: bit reversing
// TODO: bit rotation
// TODO: number multiplication to 2
// TODO: number division by 2

void StartBM()
{
    Representation();
    OperationAND();
}

#endif /* BITSMANIPULATION_HPP_ */
<commit_msg>OR operation<commit_after>#ifndef BITSMANIPULATION_HPP_
#define BITSMANIPULATION_HPP_

#include <iostream>
#include <limits>
#include <bitset>

void Representation()
{
    std::cout << "Representation of the numbers in binary and hex" <<
                    std::endl;

    const long long unsigned int max = std::numeric_limits<unsigned char>::max();
    for (long long unsigned int i = 0; i <= max; ++i)
    {
        std::cout << "Dec: " <<  std::dec << std::showbase << i;
        std::cout << " Bin: 0b" << std::bitset<8>(i).to_string();
        std::cout << " Oct: " << std::oct << std::showbase << i;
        std::cout << " Hex: " << std::hex << std::showbase << i << std::endl;
    }

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

void OperationAND()
{
    std::cout << "Example of AND operation" << std::endl;
    unsigned char first = 0b00111000;
    unsigned char second = 0b10101010;
    unsigned char result = first & second;

    std::cout << "First value: 0b" << std::bitset<8>(first).to_string() <<
                    std::endl;
    std::cout << "Second value: 0b" << std::bitset<8>(second).to_string() <<
                    std::endl;
    std::cout << "Result of AND operation: 0b" <<
                    std::bitset<8>(result).to_string() << std::endl;

    first = 0b11111000;
    second = 0b10101011;
    result = first & second;

    std::cout << std::endl << "With other values" << std::endl;
    std::cout << "First value: 0b" << std::bitset<8>(first).to_string() <<
                    std::endl;
    std::cout << "Second value: 0b" << std::bitset<8>(second).to_string() <<
                    std::endl;
    std::cout << "Result of AND operation: 0b" <<
                    std::bitset<8>(result).to_string() << std::endl;

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

void OperationOR()
{
    std::cout << "Example of OR operation" << std::endl;
    unsigned char first = 0b00111000;
    unsigned char second = 0b10101010;
    unsigned char result = first | second;

    std::cout << "First value: 0b" << std::bitset<8>(first).to_string() <<
                    std::endl;
    std::cout << "Second value: 0b" << std::bitset<8>(second).to_string() <<
                    std::endl;
    std::cout << "Result of OR operation: 0b" <<
                    std::bitset<8>(result).to_string() << std::endl;

    first = 0b11111000;
    second = 0b10101011;
    result = first | second;

    std::cout << std::endl << "With other values" << std::endl;
    std::cout << "First value: 0b" << std::bitset<8>(first).to_string() <<
                    std::endl;
    std::cout << "Second value: 0b" << std::bitset<8>(second).to_string() <<
                    std::endl;
    std::cout << "Result of OR operation: 0b" <<
                    std::bitset<8>(result).to_string() << std::endl;

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

// TODO: XOR operation
// TODO: bit reversing
// TODO: bit rotation
// TODO: number multiplication to 2
// TODO: number division by 2

void StartBM()
{
    Representation();
    OperationAND();
    OperationOR();
}

#endif /* BITSMANIPULATION_HPP_ */
<|endoftext|>


<commit_before>#ifndef BITSMANIPULATION_HPP_
#define BITSMANIPULATION_HPP_

#include <iostream>
#include <limits>
#include <bitset>

void Representation()
{
    std::cout << "Representation of the numbers in binary and hex" <<
                    std::endl;

    const long long unsigned int max = std::numeric_limits<unsigned char>::max();
    for (long long unsigned int i = 0; i <= max; ++i)
    {
        std::cout << "Dec: " <<  std::dec << std::showbase << i;
        std::cout << " Bin: 0b" << std::bitset<8>(i).to_string();
        std::cout << " Oct: " << std::oct << std::showbase << i;
        std::cout << " Hex: " << std::hex << std::showbase << i << std::endl;
    }

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

void OperationAND()
{
    std::cout << "Example of AND operation" << std::endl;
    unsigned char first = 0b00111000;
    unsigned char second = 0b10101010;

    std::cout << std::bitset<8>(first).to_string() << " & " <<
                    std::bitset<8>(second).to_string() << " = " <<
                    std::bitset<8>(first & second).to_string() <<
                    std::endl;

    first = 0b11111000;
    second = 0b10101011;

    std::cout << std::bitset<8>(first).to_string() << " & " <<
                        std::bitset<8>(second).to_string() << " = " <<
                        std::bitset<8>(first & second).to_string() <<
                        std::endl;

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

void OperationOR()
{
    std::cout << "Example of OR operation" << std::endl;
    unsigned char first = 0b00111000;
    unsigned char second = 0b10101010;

    std::cout << std::bitset<8>(first).to_string() << " | " <<
                        std::bitset<8>(second).to_string() << " = " <<
                        std::bitset<8>(first | second).to_string() <<
                        std::endl;

    first = 0b11111000;
    second = 0b10101011;

    std::cout << std::bitset<8>(first).to_string() << " | " <<
                        std::bitset<8>(second).to_string() << " = " <<
                        std::bitset<8>(first | second).to_string() <<
                        std::endl;

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

void OperationXOR()
{
    std::cout << "Example of XOR operation" << std::endl;
    unsigned char first = 0b00111000;
    unsigned char second = 0b10101010;

    std::cout << std::bitset<8>(first).to_string() << " ^ " <<
                        std::bitset<8>(second).to_string() << " = " <<
                        std::bitset<8>(first ^ second).to_string() <<
                        std::endl;

    first = 0b11111000;
    second = 0b10101011;

    std::cout << std::bitset<8>(first).to_string() << " ^ " <<
                        std::bitset<8>(second).to_string() << " = " <<
                        std::bitset<8>(first ^ second).to_string() <<
                        std::endl;

    std::cout << "Byte complementation using XOR operation" << std::endl;
    first = 0b11111111;
    std::cout << std::bitset<8>(first).to_string() << " ^ " <<
                            std::bitset<8>(second).to_string() << " = " <<
                            std::bitset<8>(first ^ second).to_string() <<
                            std::endl;

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

void Reverse()
{
    std::cout << "Byte reverse operation" << std::endl;
    const unsigned char original = 0b00110010;

    unsigned char value = original;
    unsigned char result = 0;
    const int max = std::numeric_limits<unsigned char>::digits - 1;
    for (int i = 0; i < max; ++i)
    {
       if (value & 0x01)
       {
          result |= 0x01;
       }

       value = static_cast<unsigned char>(value >> 1);
       result = static_cast<unsigned char>(result << 1);
    }

    std::cout << std::bitset<8>(original).to_string() << " -> " <<
                    std::bitset<8>(result).to_string() << std::endl;

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

// TODO: bit rotation

void MultiplicationBy2()
{
    std::cout << "Multiplication by 2" << std::endl;
    unsigned char value = 0b00111000;
    unsigned char result = static_cast<unsigned char>(value << 1);

    std::cout << std::bitset<8>(value).to_string() << " << 1 = " <<
                    std::bitset<8>(result).to_string() << std::endl;

    unsigned int valueInt = static_cast<unsigned int>(value);
    unsigned int resultInt = static_cast<unsigned int>(result);
    std::cout << std::dec << valueInt << " -> " << resultInt << std::endl;

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

void DivisionBy2()
{
    std::cout << "Division by 2" << std::endl;
    unsigned char value = 0b00111000;
    unsigned char result = static_cast<unsigned char>(value >> 1);

    std::cout << std::bitset<8>(value).to_string() << " >> 1 = " <<
                    std::bitset<8>(result).to_string() << std::endl;

    unsigned int valueInt = static_cast<unsigned int>(value);
    unsigned int resultInt = static_cast<unsigned int>(result);
    std::cout << std::dec << valueInt << " -> " << resultInt << std::endl;

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

void StartBM()
{
    Representation();
    OperationAND();
    OperationOR();
    OperationXOR();
    Reverse();
    MultiplicationBy2();
    DivisionBy2();
}

#endif /* BITSMANIPULATION_HPP_ */
<commit_msg>Add bits rotation<commit_after>#ifndef BITSMANIPULATION_HPP_
#define BITSMANIPULATION_HPP_

#include <iostream>
#include <limits>
#include <bitset>

void Representation()
{
    std::cout << "Representation of the numbers in binary and hex" <<
                    std::endl;

    const long long unsigned int max = std::numeric_limits<unsigned char>::max();
    for (long long unsigned int i = 0; i <= max; ++i)
    {
        std::cout << "Dec: " <<  std::dec << std::showbase << i;
        std::cout << " Bin: 0b" << std::bitset<8>(i).to_string();
        std::cout << " Oct: " << std::oct << std::showbase << i;
        std::cout << " Hex: " << std::hex << std::showbase << i << std::endl;
    }

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

void OperationAND()
{
    std::cout << "Example of AND operation" << std::endl;
    unsigned char first = 0b00111000;
    unsigned char second = 0b10101010;

    std::cout << std::bitset<8>(first).to_string() << " & " <<
                    std::bitset<8>(second).to_string() << " = " <<
                    std::bitset<8>(first & second).to_string() <<
                    std::endl;

    first = 0b11111000;
    second = 0b10101011;

    std::cout << std::bitset<8>(first).to_string() << " & " <<
                        std::bitset<8>(second).to_string() << " = " <<
                        std::bitset<8>(first & second).to_string() <<
                        std::endl;

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

void OperationOR()
{
    std::cout << "Example of OR operation" << std::endl;
    unsigned char first = 0b00111000;
    unsigned char second = 0b10101010;

    std::cout << std::bitset<8>(first).to_string() << " | " <<
                        std::bitset<8>(second).to_string() << " = " <<
                        std::bitset<8>(first | second).to_string() <<
                        std::endl;

    first = 0b11111000;
    second = 0b10101011;

    std::cout << std::bitset<8>(first).to_string() << " | " <<
                        std::bitset<8>(second).to_string() << " = " <<
                        std::bitset<8>(first | second).to_string() <<
                        std::endl;

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

void OperationXOR()
{
    std::cout << "Example of XOR operation" << std::endl;
    unsigned char first = 0b00111000;
    unsigned char second = 0b10101010;

    std::cout << std::bitset<8>(first).to_string() << " ^ " <<
                        std::bitset<8>(second).to_string() << " = " <<
                        std::bitset<8>(first ^ second).to_string() <<
                        std::endl;

    first = 0b11111000;
    second = 0b10101011;

    std::cout << std::bitset<8>(first).to_string() << " ^ " <<
                        std::bitset<8>(second).to_string() << " = " <<
                        std::bitset<8>(first ^ second).to_string() <<
                        std::endl;

    std::cout << "Byte complementation using XOR operation" << std::endl;
    first = 0b11111111;
    std::cout << std::bitset<8>(first).to_string() << " ^ " <<
                            std::bitset<8>(second).to_string() << " = " <<
                            std::bitset<8>(first ^ second).to_string() <<
                            std::endl;

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

void Reverse()
{
    std::cout << "Byte reverse operation" << std::endl;
    const unsigned char original = 0b00110010;

    unsigned char value = original;
    unsigned char result = 0;
    const int max = std::numeric_limits<unsigned char>::digits - 1;
    for (int i = 0; i < max; ++i)
    {
       if (value & 0x01)
       {
          result |= 0x01;
       }

       value = static_cast<unsigned char>(value >> 1);
       result = static_cast<unsigned char>(result << 1);
    }

    std::cout << std::bitset<8>(original).to_string() << " -> " <<
                    std::bitset<8>(result).to_string() << std::endl;

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

void Rotation()
{
    std::cout << "Byte rotation operation" << std::endl;
    unsigned char original = 0b00110010;
    unsigned char moves = 5;
    int digits = std::numeric_limits<unsigned char>::digits;
    unsigned char result = static_cast<unsigned char>(
            (original >> moves) | (original << (digits - moves)));

    std::cout << std::bitset<8>(original).to_string() << " -> " <<
                        std::bitset<8>(result).to_string() << std::endl;

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

void MultiplicationBy2()
{
    std::cout << "Multiplication by 2" << std::endl;
    unsigned char value = 0b00111000;
    unsigned char result = static_cast<unsigned char>(value << 1);

    std::cout << std::bitset<8>(value).to_string() << " << 1 = " <<
                    std::bitset<8>(result).to_string() << std::endl;

    unsigned int valueInt = static_cast<unsigned int>(value);
    unsigned int resultInt = static_cast<unsigned int>(result);
    std::cout << std::dec << valueInt << " -> " << resultInt << std::endl;

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

void DivisionBy2()
{
    std::cout << "Division by 2" << std::endl;
    unsigned char value = 0b00111000;
    unsigned char result = static_cast<unsigned char>(value >> 1);

    std::cout << std::bitset<8>(value).to_string() << " >> 1 = " <<
                    std::bitset<8>(result).to_string() << std::endl;

    unsigned int valueInt = static_cast<unsigned int>(value);
    unsigned int resultInt = static_cast<unsigned int>(result);
    std::cout << std::dec << valueInt << " -> " << resultInt << std::endl;

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

void StartBM()
{
    Representation();
    OperationAND();
    OperationOR();
    OperationXOR();
    Reverse();
    Rotation();
    MultiplicationBy2();
    DivisionBy2();
}

#endif /* BITSMANIPULATION_HPP_ */
<|endoftext|>


<commit_before>/*
* this file is part of the oxygen gtk engine
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
* Copyright (c) 2010 Ruslan Kabatsayev <b7.10110111@gmail.com>
*
* This  library is free  software; you can  redistribute it and/or
* modify it  under  the terms  of the  GNU Lesser  General  Public
* License  as published  by the Free  Software  Foundation; either
* version 2 of the License, or(at your option ) any later version.
*
* This library is distributed  in the hope that it will be useful,
* but  WITHOUT ANY WARRANTY; without even  the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License  along  with  this library;  if not,  write to  the Free
* Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include "oxygenanimations.h"
#include "../oxygengtkutils.h"
#include "../oxygenqtsettings.h"
#include "../config.h"

#include <cassert>
#include <iostream>

namespace Oxygen
{

    //_________________________________________
    Animations::Animations( void ):
        _innerShadowsEnabled( true ),
        _hooksInitialized( false )
    {
        #if OXYGEN_DEBUG
        std::cerr << "Oxygen::Animations::Animations" << std::endl;
        #endif

        // create engines
        registerEngine( _backgroundHintEngine = new BackgroundHintEngine( this ) );
        registerEngine( _comboEngine = new ComboEngine( this ) );
        registerEngine( _comboBoxEngine = new ComboBoxEngine( this ) );
        registerEngine( _comboBoxEntryEngine = new ComboBoxEntryEngine( this ) );
        registerEngine( _dialogEngine = new DialogEngine( this ) );
        registerEngine( _flatWidgetEngine = new FlatWidgetEngine( this ) );
        registerEngine( _groupBoxEngine = new GroupBoxEngine( this ) );
        registerEngine( _groupBoxLabelEngine = new GroupBoxLabelEngine( this ) );
        registerEngine( _hoverEngine = new HoverEngine( this ) );
        registerEngine( _mainWindowEngine = new MainWindowEngine( this ) );
        registerEngine( _menuItemEngine = new MenuItemEngine( this ) );
        registerEngine( _panedEngine = new PanedEngine( this ) );
        registerEngine( _scrollBarEngine = new ScrollBarEngine( this ) );
        registerEngine( _scrolledWindowEngine = new ScrolledWindowEngine( this ) );
        registerEngine( _innerShadowEngine = new InnerShadowEngine( this ) );
        registerEngine( _tabWidgetEngine = new TabWidgetEngine( this ) );
        registerEngine( _treeViewEngine = new TreeViewEngine( this ) );
        registerEngine( _widgetSizeEngine = new WidgetSizeEngine( this ) );

        // animations specific engines
        registerEngine( _widgetStateEngine = new WidgetStateEngine( this ) );
        registerEngine( _arrowStateEngine = new ArrowStateEngine( this ) );
        registerEngine( _scrollBarStateEngine = new ScrollBarStateEngine( this ) );
        registerEngine( _tabWidgetStateEngine = new TabWidgetStateEngine( this ) );
        registerEngine( _treeViewStateEngine = new TreeViewStateEngine( this ) );
        registerEngine( _menuBarStateEngine = new MenuBarStateEngine( this ) );
        registerEngine( _menuStateEngine = new MenuStateEngine( this ) );
        registerEngine( _toolBarStateEngine = new ToolBarStateEngine( this ) );

    }

    //____________________________________________________________________________________________
    Animations::~Animations( void )
    {
        #if OXYGEN_DEBUG
        std::cerr << "Oxygen::Animations::~Animations" << std::endl;
        #endif

        // delete all engines
        for( BaseEngine::List::iterator iter = _engines.begin(); iter != _engines.end(); ++iter )
        { delete *iter; }

        // disconnect all signals from map
        for( WidgetMap::iterator iter = _allWidgets.begin(); iter != _allWidgets.end(); iter++ )
        { iter->second.disconnect(); }

        // clear hooks
        _sizeAllocationHook.disconnect();
        _realizationHook.disconnect();
        _innerShadowHook.disconnect();

    }

    //_________________________________________
    void Animations::initialize( const QtSettings& settings )
    {

        const bool animationsEnabled( settings.animationsEnabled() );

        // pass animations configuration to engines
        _widgetStateEngine->setApplicationName( settings.applicationName() );
        _widgetStateEngine->setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
        _widgetStateEngine->setDuration( settings.genericAnimationsDuration() );

        _arrowStateEngine->setApplicationName( settings.applicationName() );
        _arrowStateEngine->setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
        _arrowStateEngine->setDuration( settings.genericAnimationsDuration() );

        _scrollBarStateEngine->setApplicationName( settings.applicationName() );
        _scrollBarStateEngine->setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
        _scrollBarStateEngine->setDuration( settings.genericAnimationsDuration() );

        _tabWidgetStateEngine->setApplicationName( settings.applicationName() );
        _tabWidgetStateEngine->setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
        _tabWidgetStateEngine->setDuration( settings.genericAnimationsDuration() );

        _treeViewStateEngine->setApplicationName( settings.applicationName() );
        _treeViewStateEngine->setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
        _treeViewStateEngine->setDuration( settings.genericAnimationsDuration() );

        _menuBarStateEngine->setApplicationName( settings.applicationName() );
        _menuBarStateEngine->setAnimationsEnabled( animationsEnabled && (settings.menuBarAnimationType() != None) );
        _menuBarStateEngine->setFollowMouse( settings.menuBarAnimationType() == FollowMouse );
        _menuBarStateEngine->setDuration( settings.menuBarAnimationsDuration() );
        _menuBarStateEngine->setFollowMouseAnimationsDuration( settings.menuBarFollowMouseAnimationsDuration() );

        _menuStateEngine->setApplicationName( settings.applicationName() );
        _menuStateEngine->setEnabled( animationsEnabled && (settings.menuAnimationType() != None) );
        _menuStateEngine->setFollowMouse( settings.menuAnimationType() == FollowMouse );
        _menuStateEngine->setDuration( settings.menuAnimationsDuration() );
        _menuStateEngine->setFollowMouseAnimationsDuration( settings.menuFollowMouseAnimationsDuration() );

        // for now, only Fade animations mode is supported for toolbar animations
        _toolBarStateEngine->setApplicationName( settings.applicationName() );
        _toolBarStateEngine->setEnabled( animationsEnabled && (settings.toolBarAnimationType() != None) );
        _toolBarStateEngine->setFollowMouse(  settings.toolBarAnimationType() == FollowMouse );
        _toolBarStateEngine->setDuration( settings.genericAnimationsDuration() );
        _toolBarStateEngine->setFollowMouseAnimationsDuration( settings.toolBarAnimationsDuration() );

        // background hint engine
        _backgroundHintEngine->setUseBackgroundGradient( settings.useBackgroundGradient() );

    }

    //____________________________________________________________________________________________
    void Animations::initializeHooks( void )
    {
        if( _hooksInitialized ) return;

        // https://bugzilla.gnome.org/show_bug.cgi?id=643416
        #if ENABLE_INNER_SHADOWS_HACK
        if(!getenv("OXYGEN_DISABLE_INNER_SHADOWS_HACK"))
        { _innerShadowHook.connect( "realize", (GSignalEmissionHook)innerShadowHook, this ); }
        #endif

        _sizeAllocationHook.connect( "size-allocate", (GSignalEmissionHook)sizeAllocationHook, this );
        _realizationHook.connect( "realize", (GSignalEmissionHook)realizationHook, this );

        _hooksInitialized = true;
    }

    //____________________________________________________________________________________________
    bool Animations::registerWidget( GtkWidget* widget )
    {

        if( _allWidgets.find( widget ) != _allWidgets.end() ) return false;

        #if OXYGEN_DEBUG
        std::cerr << "Oxygen::Animations::registerWidget - " << widget << " (" << (widget ? G_OBJECT_TYPE_NAME( widget ):"0x0") << ")" << std::endl;
        #endif

        Signal destroyId;
        destroyId.connect( G_OBJECT( widget ), "destroy", G_CALLBACK( destroyNotifyEvent ), this );
        _allWidgets.insert( std::make_pair( widget, destroyId ) );
        return true;

    }

    //____________________________________________________________________________________________
    void Animations::unregisterWidget( GtkWidget* widget )
    {

        #if OXYGEN_DEBUG
        std::cerr << "Oxygen::Animations::unregisterWidget - " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl;
        #endif

        // find in map
        WidgetMap::iterator iter( _allWidgets.find( widget ) );
        assert( iter != _allWidgets.end() );

        // disconnect signal
        iter->second.disconnect();

        // erase from map
        _allWidgets.erase( widget );

        // erase from all maps
        for( BaseEngine::List::iterator iter = _engines.begin(); iter != _engines.end(); ++iter )
        { (*iter)->unregisterWidget( widget ); }

    }

    //____________________________________________________________________________________________
    void Animations::setEnabled( bool value )
    {

        for( BaseEngine::List::iterator iter = _engines.begin(); iter != _engines.end(); ++iter )
        { (*iter)->setEnabled( value ); }

    }

    //____________________________________________________________________________________________
    gboolean Animations::destroyNotifyEvent( GtkWidget* widget, gpointer data )
    {
        static_cast<Animations*>(data)->unregisterWidget( widget );
        return FALSE;
    }

    //____________________________________________________________________________________________
    gboolean Animations::sizeAllocationHook( GSignalInvocationHint*, guint, const GValue* params, gpointer data )
    {

        // get widget from params
        GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) );

        // check type
        if( !GTK_IS_WIDGET( widget ) ) return FALSE;

        // cast data
        Animations& animations( *static_cast<Animations*>(data) );

        // groupbox labels
        #if ENABLE_GROUPBOX_HACK
        if( animations.groupBoxLabelEngine().contains( widget ) )
        {
            animations.groupBoxLabelEngine().adjustSize( widget );
            return TRUE;
        }
        #endif

        #if ENABLE_COMBOBOX_LIST_RESIZE
        // comboboxes
        if( !GTK_IS_WINDOW( widget ) ) return TRUE;

        GtkWindow* window( GTK_WINDOW( widget ) );
        if( gtk_window_get_type_hint( window ) != GDK_WINDOW_TYPE_HINT_COMBO ) return TRUE;

        GtkWidget* combobox = animations.comboBoxEngine().find( widget );
        if( !combobox ) combobox = animations.comboBoxEntryEngine().find( widget );
        if( !combobox ) combobox = animations.comboEngine().find( widget );
        if( !combobox ) return true;

        int w, h;
        gtk_window_get_size( window, &w, &h );

        gint targetX, dummy, y;
        gtk_window_get_position( window, &dummy, &y );
        gdk_window_get_origin( gtk_widget_get_window( combobox ), &targetX, &dummy );

        const GtkAllocation comboAllocation( Gtk::gtk_widget_get_allocation( combobox ) );
        int uglyShadowWidth=!Gtk::gdk_default_screen_is_composited();
        gtk_window_move( window, targetX + comboAllocation.x + 3 - uglyShadowWidth, y );

        const GtkAllocation widgetAllocation( Gtk::gtk_widget_get_allocation( widget ) );
        gtk_widget_set_size_request( widget, comboAllocation.width - 6 + 2*uglyShadowWidth, widgetAllocation.height );
        #endif

        return TRUE;

    }

    //____________________________________________________________________________________________
    gboolean Animations::innerShadowHook( GSignalInvocationHint*, guint, const GValue* params, gpointer data )
    {

        #if GTK_CHECK_VERSION(2,24,2)

        // get widget from params
        GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) );

        // check type
        if( !GTK_IS_WIDGET( widget ) ) return FALSE;

        // check enabled state
        Animations& animations( *static_cast<Animations*>(data) );
        if( !animations.innerShadowsEnabled() ) return TRUE;

        // blacklist
        if( Gtk::g_object_is_a( G_OBJECT( widget ), "SwtFixed" ) ) return TRUE;
        if( Gtk::g_object_is_a( G_OBJECT( widget ), "GtkPizza" ) ) return TRUE;

        GtkWidget* parent(gtk_widget_get_parent(widget));
        if( !GTK_IS_SCROLLED_WINDOW( parent ) ) return TRUE;

        GtkWidget* child(gtk_bin_get_child(GTK_BIN(parent)));
        if(child!=widget) return TRUE;

        #if OXYGEN_DEBUG
        std::cerr
            << "Oxygen::Animations::innerShadowHook -"
            << " widget: " << widget << " (" << G_OBJECT_TYPE_NAME(widget) << ")"
            << " parent: " << parent << " (" << G_OBJECT_TYPE_NAME(parent) << ")"
            << " widget path: " << Gtk::gtk_widget_path( widget )
            << " isTreeView: " << (GTK_IS_TREE_VIEW(widget)?"true":"false")
            << " isTextView: " << (GTK_IS_TEXT_VIEW(widget)?"true":"false")
            << std::endl;
        #endif

        animations.innerShadowEngine().registerWidget( parent );
        animations.innerShadowEngine().registerChild( parent, widget );

        #endif  // Gtk version
        return TRUE;

    }

    //____________________________________________________________________________________________
    gboolean Animations::realizationHook( GSignalInvocationHint*, guint, const GValue* params, gpointer data )
    {

        // get widget from params
        GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) );

        // check type
        if( !GTK_IS_WIDGET( widget ) ) return FALSE;

        if( GTK_IS_NOTEBOOK( widget ) )
        { gtk_notebook_set_show_border( GTK_NOTEBOOK(widget), FALSE ); }

        #if ENABLE_GROUPBOX_HACK
        if( GTK_IS_LABEL( widget ) &&  GTK_IS_FRAME( gtk_widget_get_parent( widget ) ) )
        {

            GtkFrame *frame( GTK_FRAME( gtk_widget_get_parent( widget ) ) );
            if( widget == gtk_frame_get_label_widget( frame ) && !Gtk::gtk_widget_find_parent( widget, "GtkPizza" ) )
            {
                #if OXYGEN_DEBUG
                std::cout
                    << "Oxygen::Animations::realizationHook -"
                    << " widget: " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")"
                    << " parent: " << frame << " (" << G_OBJECT_TYPE_NAME( frame ) << ")"
                    << std::endl;
                #endif

                // modify alignment
                gtk_frame_set_label_align( frame, 0.5, 0.0 );
                gtk_frame_set_shadow_type( frame, GTK_SHADOW_OUT );

                // register to engine
                Animations& animations( *static_cast<Animations*>(data) );
                animations.groupBoxLabelEngine().registerWidget( widget );
                animations.groupBoxLabelEngine().adjustSize( widget );

            }

        }
        #endif

        return TRUE;

    }

}
<commit_msg>Force shadow on known scrolled windows allready in innerShadowHook CCBUG: 316995<commit_after>/*
* this file is part of the oxygen gtk engine
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
* Copyright (c) 2010 Ruslan Kabatsayev <b7.10110111@gmail.com>
*
* This  library is free  software; you can  redistribute it and/or
* modify it  under  the terms  of the  GNU Lesser  General  Public
* License  as published  by the Free  Software  Foundation; either
* version 2 of the License, or(at your option ) any later version.
*
* This library is distributed  in the hope that it will be useful,
* but  WITHOUT ANY WARRANTY; without even  the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License  along  with  this library;  if not,  write to  the Free
* Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include "oxygenanimations.h"
#include "../oxygengtkutils.h"
#include "../oxygenqtsettings.h"
#include "../config.h"

#include <cassert>
#include <iostream>

namespace Oxygen
{

    //_________________________________________
    Animations::Animations( void ):
        _innerShadowsEnabled( true ),
        _hooksInitialized( false )
    {
        #if OXYGEN_DEBUG
        std::cerr << "Oxygen::Animations::Animations" << std::endl;
        #endif

        // create engines
        registerEngine( _backgroundHintEngine = new BackgroundHintEngine( this ) );
        registerEngine( _comboEngine = new ComboEngine( this ) );
        registerEngine( _comboBoxEngine = new ComboBoxEngine( this ) );
        registerEngine( _comboBoxEntryEngine = new ComboBoxEntryEngine( this ) );
        registerEngine( _dialogEngine = new DialogEngine( this ) );
        registerEngine( _flatWidgetEngine = new FlatWidgetEngine( this ) );
        registerEngine( _groupBoxEngine = new GroupBoxEngine( this ) );
        registerEngine( _groupBoxLabelEngine = new GroupBoxLabelEngine( this ) );
        registerEngine( _hoverEngine = new HoverEngine( this ) );
        registerEngine( _mainWindowEngine = new MainWindowEngine( this ) );
        registerEngine( _menuItemEngine = new MenuItemEngine( this ) );
        registerEngine( _panedEngine = new PanedEngine( this ) );
        registerEngine( _scrollBarEngine = new ScrollBarEngine( this ) );
        registerEngine( _scrolledWindowEngine = new ScrolledWindowEngine( this ) );
        registerEngine( _innerShadowEngine = new InnerShadowEngine( this ) );
        registerEngine( _tabWidgetEngine = new TabWidgetEngine( this ) );
        registerEngine( _treeViewEngine = new TreeViewEngine( this ) );
        registerEngine( _widgetSizeEngine = new WidgetSizeEngine( this ) );

        // animations specific engines
        registerEngine( _widgetStateEngine = new WidgetStateEngine( this ) );
        registerEngine( _arrowStateEngine = new ArrowStateEngine( this ) );
        registerEngine( _scrollBarStateEngine = new ScrollBarStateEngine( this ) );
        registerEngine( _tabWidgetStateEngine = new TabWidgetStateEngine( this ) );
        registerEngine( _treeViewStateEngine = new TreeViewStateEngine( this ) );
        registerEngine( _menuBarStateEngine = new MenuBarStateEngine( this ) );
        registerEngine( _menuStateEngine = new MenuStateEngine( this ) );
        registerEngine( _toolBarStateEngine = new ToolBarStateEngine( this ) );

    }

    //____________________________________________________________________________________________
    Animations::~Animations( void )
    {
        #if OXYGEN_DEBUG
        std::cerr << "Oxygen::Animations::~Animations" << std::endl;
        #endif

        // delete all engines
        for( BaseEngine::List::iterator iter = _engines.begin(); iter != _engines.end(); ++iter )
        { delete *iter; }

        // disconnect all signals from map
        for( WidgetMap::iterator iter = _allWidgets.begin(); iter != _allWidgets.end(); iter++ )
        { iter->second.disconnect(); }

        // clear hooks
        _sizeAllocationHook.disconnect();
        _realizationHook.disconnect();
        _innerShadowHook.disconnect();

    }

    //_________________________________________
    void Animations::initialize( const QtSettings& settings )
    {

        const bool animationsEnabled( settings.animationsEnabled() );

        // pass animations configuration to engines
        _widgetStateEngine->setApplicationName( settings.applicationName() );
        _widgetStateEngine->setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
        _widgetStateEngine->setDuration( settings.genericAnimationsDuration() );

        _arrowStateEngine->setApplicationName( settings.applicationName() );
        _arrowStateEngine->setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
        _arrowStateEngine->setDuration( settings.genericAnimationsDuration() );

        _scrollBarStateEngine->setApplicationName( settings.applicationName() );
        _scrollBarStateEngine->setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
        _scrollBarStateEngine->setDuration( settings.genericAnimationsDuration() );

        _tabWidgetStateEngine->setApplicationName( settings.applicationName() );
        _tabWidgetStateEngine->setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
        _tabWidgetStateEngine->setDuration( settings.genericAnimationsDuration() );

        _treeViewStateEngine->setApplicationName( settings.applicationName() );
        _treeViewStateEngine->setEnabled( animationsEnabled && settings.genericAnimationsEnabled() );
        _treeViewStateEngine->setDuration( settings.genericAnimationsDuration() );

        _menuBarStateEngine->setApplicationName( settings.applicationName() );
        _menuBarStateEngine->setAnimationsEnabled( animationsEnabled && (settings.menuBarAnimationType() != None) );
        _menuBarStateEngine->setFollowMouse( settings.menuBarAnimationType() == FollowMouse );
        _menuBarStateEngine->setDuration( settings.menuBarAnimationsDuration() );
        _menuBarStateEngine->setFollowMouseAnimationsDuration( settings.menuBarFollowMouseAnimationsDuration() );

        _menuStateEngine->setApplicationName( settings.applicationName() );
        _menuStateEngine->setEnabled( animationsEnabled && (settings.menuAnimationType() != None) );
        _menuStateEngine->setFollowMouse( settings.menuAnimationType() == FollowMouse );
        _menuStateEngine->setDuration( settings.menuAnimationsDuration() );
        _menuStateEngine->setFollowMouseAnimationsDuration( settings.menuFollowMouseAnimationsDuration() );

        // for now, only Fade animations mode is supported for toolbar animations
        _toolBarStateEngine->setApplicationName( settings.applicationName() );
        _toolBarStateEngine->setEnabled( animationsEnabled && (settings.toolBarAnimationType() != None) );
        _toolBarStateEngine->setFollowMouse(  settings.toolBarAnimationType() == FollowMouse );
        _toolBarStateEngine->setDuration( settings.genericAnimationsDuration() );
        _toolBarStateEngine->setFollowMouseAnimationsDuration( settings.toolBarAnimationsDuration() );

        // background hint engine
        _backgroundHintEngine->setUseBackgroundGradient( settings.useBackgroundGradient() );

    }

    //____________________________________________________________________________________________
    void Animations::initializeHooks( void )
    {
        if( _hooksInitialized ) return;

        // https://bugzilla.gnome.org/show_bug.cgi?id=643416
        #if ENABLE_INNER_SHADOWS_HACK
        if(!getenv("OXYGEN_DISABLE_INNER_SHADOWS_HACK"))
        { _innerShadowHook.connect( "realize", (GSignalEmissionHook)innerShadowHook, this ); }
        #endif

        _sizeAllocationHook.connect( "size-allocate", (GSignalEmissionHook)sizeAllocationHook, this );
        _realizationHook.connect( "realize", (GSignalEmissionHook)realizationHook, this );

        _hooksInitialized = true;
    }

    //____________________________________________________________________________________________
    bool Animations::registerWidget( GtkWidget* widget )
    {

        if( _allWidgets.find( widget ) != _allWidgets.end() ) return false;

        #if OXYGEN_DEBUG
        std::cerr << "Oxygen::Animations::registerWidget - " << widget << " (" << (widget ? G_OBJECT_TYPE_NAME( widget ):"0x0") << ")" << std::endl;
        #endif

        Signal destroyId;
        destroyId.connect( G_OBJECT( widget ), "destroy", G_CALLBACK( destroyNotifyEvent ), this );
        _allWidgets.insert( std::make_pair( widget, destroyId ) );
        return true;

    }

    //____________________________________________________________________________________________
    void Animations::unregisterWidget( GtkWidget* widget )
    {

        #if OXYGEN_DEBUG
        std::cerr << "Oxygen::Animations::unregisterWidget - " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")" << std::endl;
        #endif

        // find in map
        WidgetMap::iterator iter( _allWidgets.find( widget ) );
        assert( iter != _allWidgets.end() );

        // disconnect signal
        iter->second.disconnect();

        // erase from map
        _allWidgets.erase( widget );

        // erase from all maps
        for( BaseEngine::List::iterator iter = _engines.begin(); iter != _engines.end(); ++iter )
        { (*iter)->unregisterWidget( widget ); }

    }

    //____________________________________________________________________________________________
    void Animations::setEnabled( bool value )
    {

        for( BaseEngine::List::iterator iter = _engines.begin(); iter != _engines.end(); ++iter )
        { (*iter)->setEnabled( value ); }

    }

    //____________________________________________________________________________________________
    gboolean Animations::destroyNotifyEvent( GtkWidget* widget, gpointer data )
    {
        static_cast<Animations*>(data)->unregisterWidget( widget );
        return FALSE;
    }

    //____________________________________________________________________________________________
    gboolean Animations::sizeAllocationHook( GSignalInvocationHint*, guint, const GValue* params, gpointer data )
    {

        // get widget from params
        GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) );

        // check type
        if( !GTK_IS_WIDGET( widget ) ) return FALSE;

        // cast data
        Animations& animations( *static_cast<Animations*>(data) );

        // groupbox labels
        #if ENABLE_GROUPBOX_HACK
        if( animations.groupBoxLabelEngine().contains( widget ) )
        {
            animations.groupBoxLabelEngine().adjustSize( widget );
            return TRUE;
        }
        #endif

        #if ENABLE_COMBOBOX_LIST_RESIZE
        // comboboxes
        if( !GTK_IS_WINDOW( widget ) ) return TRUE;

        GtkWindow* window( GTK_WINDOW( widget ) );
        if( gtk_window_get_type_hint( window ) != GDK_WINDOW_TYPE_HINT_COMBO ) return TRUE;

        GtkWidget* combobox = animations.comboBoxEngine().find( widget );
        if( !combobox ) combobox = animations.comboBoxEntryEngine().find( widget );
        if( !combobox ) combobox = animations.comboEngine().find( widget );
        if( !combobox ) return true;

        int w, h;
        gtk_window_get_size( window, &w, &h );

        gint targetX, dummy, y;
        gtk_window_get_position( window, &dummy, &y );
        gdk_window_get_origin( gtk_widget_get_window( combobox ), &targetX, &dummy );

        const GtkAllocation comboAllocation( Gtk::gtk_widget_get_allocation( combobox ) );
        int uglyShadowWidth=!Gtk::gdk_default_screen_is_composited();
        gtk_window_move( window, targetX + comboAllocation.x + 3 - uglyShadowWidth, y );

        const GtkAllocation widgetAllocation( Gtk::gtk_widget_get_allocation( widget ) );
        gtk_widget_set_size_request( widget, comboAllocation.width - 6 + 2*uglyShadowWidth, widgetAllocation.height );
        #endif

        return TRUE;

    }

    //____________________________________________________________________________________________
    gboolean Animations::innerShadowHook( GSignalInvocationHint*, guint, const GValue* params, gpointer data )
    {

        #if GTK_CHECK_VERSION(2,24,2)

        // get widget from params
        GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) );

        // check type
        if( !GTK_IS_WIDGET( widget ) ) return FALSE;

        // check enabled state
        Animations& animations( *static_cast<Animations*>(data) );
        if( !animations.innerShadowsEnabled() ) return TRUE;

        // blacklist
        if( Gtk::g_object_is_a( G_OBJECT( widget ), "SwtFixed" ) ) return TRUE;
        if( Gtk::g_object_is_a( G_OBJECT( widget ), "GtkPizza" ) ) return TRUE;

        GtkWidget* parent(gtk_widget_get_parent(widget));
        if( !GTK_IS_SCROLLED_WINDOW( parent ) ) return TRUE;

        GtkWidget* child(gtk_bin_get_child(GTK_BIN(parent)));
        if(child!=widget) return TRUE;

        #if OXYGEN_DEBUG
        std::cerr
            << "Oxygen::Animations::innerShadowHook -"
            << " widget: " << widget << " (" << G_OBJECT_TYPE_NAME(widget) << ")"
            << " parent: " << parent << " (" << G_OBJECT_TYPE_NAME(parent) << ")"
            << " widget path: " << Gtk::gtk_widget_path( widget )
            << " isTreeView: " << (GTK_IS_TREE_VIEW(widget)?"true":"false")
            << " isTextView: " << (GTK_IS_TEXT_VIEW(widget)?"true":"false")
            << std::endl;
        #endif

        // force shadow type on known windows
        if( Gtk::gtk_scrolled_window_force_sunken( parent ) )
        { gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW( parent ), GTK_SHADOW_IN ); }

        animations.innerShadowEngine().registerWidget( parent );
        animations.innerShadowEngine().registerChild( parent, widget );

        #endif  // Gtk version
        return TRUE;

    }

    //____________________________________________________________________________________________
    gboolean Animations::realizationHook( GSignalInvocationHint*, guint, const GValue* params, gpointer data )
    {

        // get widget from params
        GtkWidget* widget( GTK_WIDGET( g_value_get_object( params ) ) );

        // check type
        if( !GTK_IS_WIDGET( widget ) ) return FALSE;

        if( GTK_IS_NOTEBOOK( widget ) )
        { gtk_notebook_set_show_border( GTK_NOTEBOOK(widget), FALSE ); }

        #if ENABLE_GROUPBOX_HACK
        if( GTK_IS_LABEL( widget ) &&  GTK_IS_FRAME( gtk_widget_get_parent( widget ) ) )
        {

            GtkFrame *frame( GTK_FRAME( gtk_widget_get_parent( widget ) ) );
            if( widget == gtk_frame_get_label_widget( frame ) && !Gtk::gtk_widget_find_parent( widget, "GtkPizza" ) )
            {
                #if OXYGEN_DEBUG
                std::cout
                    << "Oxygen::Animations::realizationHook -"
                    << " widget: " << widget << " (" << G_OBJECT_TYPE_NAME( widget ) << ")"
                    << " parent: " << frame << " (" << G_OBJECT_TYPE_NAME( frame ) << ")"
                    << std::endl;
                #endif

                // modify alignment
                gtk_frame_set_label_align( frame, 0.5, 0.0 );
                gtk_frame_set_shadow_type( frame, GTK_SHADOW_OUT );

                // register to engine
                Animations& animations( *static_cast<Animations*>(data) );
                animations.groupBoxLabelEngine().registerWidget( widget );
                animations.groupBoxLabelEngine().adjustSize( widget );

            }

        }
        #endif

        return TRUE;

    }

}
<|endoftext|>


<commit_before>#include <chrono>
#include <getopt.h>
#include <memory>
#include "primes.hpp"
#include "snv.hpp"
#include "del.hpp"
#include "read_parsers.hh"

using namespace khmer;
using namespace read_parsers;
typedef Read Sequence;
typedef std::chrono::time_point<std::chrono::system_clock> timepoint;

typedef struct
{
    uint delsize;
    ulong interval;
    uint ksize;
    ulong limit;
    uint histmax;
    uint numtables;
    double sampling_rate;
    int seed;
    std::string muttype;
    ulong targetsize;
    std::string infile;
    std::string refrfile;
} ProgramArgs;

void print_usage(std::ostream& stream = std::cerr)
{
    stream << "Usage: snv-hist [options] seqs.fa [genome.fa]\n";
    stream << "  options:\n";
    stream << "    -h    print this help message and exit\n";
    stream << "    -i    debug output interval (default: 1000000)\n";
    stream << "    -k    k-mer length (default: 31)\n";
    stream << "    -l    limit number of positions to process\n";
    stream << "    -m    max histogram value (default: 16)\n";
    stream << "    -n    num tables (default: 4)\n";
    stream << "    -r    sampling rate (default: 1.0)\n";
    stream << "    -s    seed for random number generator (default: 42)\n";
    stream << "    -t    mutation type: snv (default), del\n";
    stream << "    -x    approx table size (default: 5e8)\n";
    stream << "    -z    deletion size (default: 5)\n";
}

void parse_args(int argc, const char **argv, ProgramArgs *args)
{
    char c;
    while ((c = getopt (argc, (char *const *)argv, "d:hi:k:l:m:n:r:s:t:x:z:")) != -1) {
        if (c == 'd') {
            args->delsize = atoi(optarg);
        }
        else if (c == 'h') {
            print_usage(std::cout);
            exit(0);
        }
        else if (c == 'i') {
            args->interval = atoi(optarg);
        }
        else if (c == 'k') {
            args->ksize = atoi(optarg);
        }
        else if (c == 'l') {
            args->limit = atoi(optarg);
        }
        else if (c == 'm') {
            args->histmax = atoi(optarg);
        }
        else if (c == 'n') {
            args->numtables = atoi(optarg);
        }
        else if (c == 'r') {
            args->sampling_rate = atof(optarg);
        }
        else if (c == 's') {
            args->seed = atoi(optarg);
        }
        else if (c == 't') {
            args->muttype = optarg;
        }
        else if (c == 'x') {
            args->targetsize = atoi(optarg);
        }
        else if (c == 'z') {
            args->delsize = atoi(optarg);
        }
        else {
            std::cerr << "Unknown option '" << c << "'\n";
            print_usage();
            exit(1);
        }
    }

    args->infile = argv[optind];
    args->refrfile = argv[optind];
    if (argc > optind + 1) {
        args->refrfile = argv[optind + 1];
    }
}

int main(int argc, const char **argv)
{
    if (argc == 1) {
        print_usage(std::cout);
        return 0;
    }

    ProgramArgs args = {5, 1000000, 31, 0, 16, 4, 1.0, 42, "snv", 500000000, "", ""};
    parse_args(argc, argv, &args);

    std::cerr << "# allocating countgraph\n";
    std::vector<uint64_t> tablesizes = get_n_primes_near_x(args.targetsize, args.numtables);
    Countgraph countgraph(args.ksize, tablesizes);

    std::cerr << "# consuming reference...";
    timepoint start = std::chrono::system_clock::now();
    unsigned int seqs_consumed = 0;
    unsigned long long kmers_consumed = 0;
    countgraph.consume_fasta(args.refrfile, seqs_consumed, kmers_consumed);
    timepoint end = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed = end - start;
    std::cerr << "consumed " << seqs_consumed << " sequence(s) and "
              << kmers_consumed << " " << args.ksize << "-mers (in " << elapsed.count() << " seconds)\n";

    std::cerr << "# querying k-mer abundance...\n\n";
    Logger logger(args.interval, std::cerr);
    std::unique_ptr<Mutator> mut = NULL;
    if(args.muttype == "snv") {
        mut.reset(new MutatorSNV(args.ksize, logger, args.histmax, args.limit));
    }
    else if(args.muttype == "del") {
        mut.reset(new MutatorDel(args.ksize, args.delsize, logger, args.histmax, args.limit));
    }
    else {
        std::cerr << "Error: unknown mutation type '" << args.muttype << "'\n";
        exit(1);
    }
    mut->set_sampling_rate(args.sampling_rate, args.seed);

    IParser *parser = IParser::get_parser(args.infile);
    Sequence seq;
    while (!parser->is_complete()) {
        try {
            seq = parser->get_next_read();
        } catch (NoMoreReadsAvailable &e) {
            break;
        }
        mut->process(seq.sequence, countgraph);
    }
    std::cout << *mut;
    delete parser;

    return 0;
}
<commit_msg>Bringing the C++ code up to date<commit_after>#include <chrono>
#include <getopt.h>
#include <memory>
#include "primes.hpp"
#include "snv.hpp"
#include "del.hpp"
#include "read_parsers.hh"

using namespace khmer;
using namespace read_parsers;
typedef Read Sequence;
typedef std::chrono::time_point<std::chrono::system_clock> timepoint;

typedef struct
{
    uint delsize;
    ulong interval;
    uint ksize;
    ulong limit;
    uint histmax;
    uint numtables;
    double sampling_rate;
    int seed;
    std::string muttype;
    ulong targetsize;
    std::string infile;
    std::string refrfile;
} ProgramArgs;

void print_usage(std::ostream& stream = std::cerr)
{
    stream << "Usage: snv-hist [options] seqs.fa [genome.fa]\n";
    stream << "  options:\n";
    stream << "    -h    print this help message and exit\n";
    stream << "    -i    debug output interval (default: 1000000)\n";
    stream << "    -k    k-mer length (default: 31)\n";
    stream << "    -l    limit number of positions to process\n";
    stream << "    -m    max histogram value (default: 16)\n";
    stream << "    -n    num tables (default: 4)\n";
    stream << "    -r    sampling rate (default: 1.0)\n";
    stream << "    -s    seed for random number generator (default: 42)\n";
    stream << "    -t    mutation type: snv (default), del\n";
    stream << "    -x    approx table size (default: 5e8)\n";
    stream << "    -z    deletion size (default: 5)\n";
}

void parse_args(int argc, const char **argv, ProgramArgs *args)
{
    char c;
    while ((c = getopt (argc, (char *const *)argv, "d:hi:k:l:m:n:r:s:t:x:z:")) != -1) {
        if (c == 'd') {
            args->delsize = atoi(optarg);
        }
        else if (c == 'h') {
            print_usage(std::cout);
            exit(0);
        }
        else if (c == 'i') {
            args->interval = atoi(optarg);
        }
        else if (c == 'k') {
            args->ksize = atoi(optarg);
        }
        else if (c == 'l') {
            args->limit = atoi(optarg);
        }
        else if (c == 'm') {
            args->histmax = atoi(optarg);
        }
        else if (c == 'n') {
            args->numtables = atoi(optarg);
        }
        else if (c == 'r') {
            args->sampling_rate = atof(optarg);
        }
        else if (c == 's') {
            args->seed = atoi(optarg);
        }
        else if (c == 't') {
            args->muttype = optarg;
        }
        else if (c == 'x') {
            args->targetsize = atoi(optarg);
        }
        else if (c == 'z') {
            args->delsize = atoi(optarg);
        }
        else {
            std::cerr << "Unknown option '" << c << "'\n";
            print_usage();
            exit(1);
        }
    }

    args->infile = argv[optind];
    args->refrfile = argv[optind];
    if (argc > optind + 1) {
        args->refrfile = argv[optind + 1];
    }
}

int main(int argc, const char **argv)
{
    if (argc == 1) {
        print_usage(std::cout);
        return 0;
    }

    ProgramArgs args = {5, 1000000, 31, 0, 16, 4, 1.0, 42, "snv", 500000000, "", ""};
    parse_args(argc, argv, &args);

    std::cerr << "# allocating countgraph\n";
    std::vector<uint64_t> tablesizes = get_n_primes_near_x(args.targetsize, args.numtables);
    Countgraph countgraph(args.ksize, tablesizes);

    std::cerr << "# consuming reference...";
    timepoint start = std::chrono::system_clock::now();
    unsigned int seqs_consumed = 0;
    unsigned long long kmers_consumed = 0;
    countgraph.consume_seqfile<FastxReader>(args.refrfile, seqs_consumed, kmers_consumed);
    timepoint end = std::chrono::system_clock::now();
    std::chrono::duration<double> elapsed = end - start;
    std::cerr << "consumed " << seqs_consumed << " sequence(s) and "
              << kmers_consumed << " " << args.ksize << "-mers (in " << elapsed.count() << " seconds)\n";

    std::cerr << "# querying k-mer abundance...\n\n";
    Logger logger(args.interval, std::cerr);
    std::unique_ptr<Mutator> mut = NULL;
    if(args.muttype == "snv") {
        mut.reset(new MutatorSNV(args.ksize, logger, args.histmax, args.limit));
    }
    else if(args.muttype == "del") {
        mut.reset(new MutatorDel(args.ksize, args.delsize, logger, args.histmax, args.limit));
    }
    else {
        std::cerr << "Error: unknown mutation type '" << args.muttype << "'\n";
        exit(1);
    }
    mut->set_sampling_rate(args.sampling_rate, args.seed);

    FastxParserPtr parser = get_parser<FastxReader>(args.infile);
    Sequence seq;
    while (!parser->is_complete()) {
        try {
            seq = parser->get_next_read();
        } catch (NoMoreReadsAvailable &e) {
            break;
        }
        mut->process(seq.sequence, countgraph);
    }
    std::cout << *mut;

    return 0;
}
<|endoftext|>