<commit_before>// crbarker@google.com
//
// Implements JoystickNavigator.

#include "joystick_navigator.h"

//#define DEBUG

#include <time.h>
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <geometry_msgs/Pose.h>
#include <geometry_msgs/PoseStamped.h>

#include <algorithm>
#include <cmath>

#include "slinky_nav/SlinkyPose.h"

static const double kPi = 3.141592653589793;
static const double kPoleLat = 90.0 - 0.000001;
static const double kEarthRadius = 6371000;
static const timespec kExpectedInterval = {0, 33333333};  // 30 Hz

JoystickNavigator::JoystickNavigator()
    : under_joy_control_(false),
      kiosk_pub_(NULL),
      display_pub_(NULL) {
  // The sensitivities and gutter are hard-coded here.
  // In this case, linear_sensitivity_ refers to linear scaling
  // (vs. quadratic scaling) not linear motion (vs. angular).
  linear_sensitivity_.linear.x = 0.0;  // longitude
  linear_sensitivity_.linear.y = 0.0;  // latitude
  linear_sensitivity_.linear.z = 0.0;  // altitude
  linear_sensitivity_.angular.x = 0.0;  // pitch
  linear_sensitivity_.angular.y = 0.0;  // roll
  linear_sensitivity_.angular.z = 0.0;  // heading

  quadratic_sensitivity_.linear.x = 0.00000048;  // longitude
  quadratic_sensitivity_.linear.y = 0.00000048;  // latitude
  quadratic_sensitivity_.linear.z = 0.072;  // altitude
  quadratic_sensitivity_.angular.x = 2.2;  // pitch
  quadratic_sensitivity_.angular.y = 0.0;  // roll
  quadratic_sensitivity_.angular.z = 2.2;  // heading

  // If all joystick inputs are all less than the gutter, the input
  // is ignored, and it's assumed that we're under touch/mouse control.
  gutter_.linear.x = 0.001;
  gutter_.linear.y = 0.001;
  gutter_.linear.z = 0.001;
  gutter_.angular.x = 0.001;
  gutter_.angular.y = 0.001;
  gutter_.angular.z = 0.001;
}

void JoystickNavigator::Init(
    ros::Publisher *kiosk_pub, ros::Publisher *display_pub) {

  kiosk_pub_ = kiosk_pub;
  display_pub_ = display_pub;
  clock_gettime(CLOCK_REALTIME, &last_joy_time_);
}

void JoystickNavigator::ProcessCameraMoved(
    const slinky_nav::SlinkyPose& slinky_pose) {
  // Allow touchscreen takeover.
  if (!under_joy_control_ &&
        !EqualPoses(slinky_pose.current_pose, last_camera_pose_)) {
    PublishPose(display_pub_, slinky_pose.current_pose);
  }

  last_camera_pose_ = slinky_pose.current_pose;
  pose_minimums_ = slinky_pose.pose_minimums;
  pose_maximums_ = slinky_pose.pose_maximums;
}

bool JoystickNavigator::EqualPoses(
    const geometry_msgs::Pose& left, const geometry_msgs::Pose& right) {
  return (
    left.position.x == right.position.x &&
    left.position.y == right.position.y &&
    left.position.z == right.position.z &&
    left.orientation.x == right.orientation.x &&
    left.orientation.y == right.orientation.y &&
    left.orientation.z == right.orientation.z
  );
}

void JoystickNavigator::ProcessJoy(const geometry_msgs::Twist& normalized_joy) {
  // The joystick sensitivities are tuned for a nominal input frequency.
  // However, inputs can come faster/slower than that, so we apply further
  // scaling.
  timespec current_time;
  clock_gettime(CLOCK_REALTIME, &current_time);
  timespec diff_time = DiffTimespec(last_joy_time_, current_time);
  last_joy_time_ = current_time;
  double interval_scale = DivTimespec(diff_time, kExpectedInterval);

  // If the entire normalized_joy is at steady state then we exit early.
  if (IsWithinGutter(normalized_joy)) {
    // This breadcrumb tells us to base future navigation on the last received
    // camera pose, not our requested pose.
    under_joy_control_ = false;
    return;
  }
  // Otherwise, we don't gutter any inputs. If we're moving the camera at all,
  // we'll move it based on all inputs, no matter how tiny.

  // If we've been under control of the joystick since the last call, we start
  // from the last pose the joystick requested (preventing stutter in case
  // the camera response gets delayed). However, if this is the first time
  // we're moving since the joystick was in the gutter, we'll start from
  // the last reported camera position.
  geometry_msgs::Pose& starting_pose = last_requested_pose_;
  if (!under_joy_control_) {
    starting_pose = last_camera_pose_;
    under_joy_control_ = true;
  }

  geometry_msgs::Pose ending_pose = starting_pose;
  geometry_msgs::Twist scaled_joy;
  Scale(normalized_joy, interval_scale, &scaled_joy);

  // Altitude:  Adjusts camera altitude per joystick linear Z axis.
  // Altitude is computed first, since it affects scaling of other inputs.
  ending_pose.position.z =
      Clamp(starting_pose.position.z +
          (starting_pose.position.z * scaled_joy.linear.z),
          pose_minimums_.position.z, pose_maximums_.position.z);

  // Heading:  Adjusts compass heading per joystick angular Z axis.
  // This is computed early because it affects the direction of translations.
  // [0, 360), with wrapping.
  ending_pose.orientation.z =
      fmod(starting_pose.orientation.z + 360 - scaled_joy.angular.z, 360);
  ending_pose.orientation.z =
      Clamp(ending_pose.orientation.z,
            pose_minimums_.orientation.z,
            pose_maximums_.orientation.z);

  // Tilt:  Adjusts tilt per joystick angular X axis.
  // TODO(crbarker): clamp the tilt intelligently so we never omit earth.
  ending_pose.orientation.x =
      Clamp(starting_pose.orientation.x + scaled_joy.angular.x,
            pose_minimums_.orientation.x,
            pose_maximums_.orientation.x);

#ifdef DEBUG
  ROS_INFO("JOYSTICK curr lon:%lf, lat:%lf, alt:%lf, hdg:%lf, tlt:%lf",
           ending_pose.position.x,
           ending_pose.position.y,
           ending_pose.position.z,
           ending_pose.orientation.z,
           ending_pose.orientation.x);
  ROS_INFO("JOYSTICK scaled linear x:%lf, y:%lf",
           scaled_joy.linear.x,
           scaled_joy.linear.y
  );
#endif
  // Translate:  Translates the camera per joystick linear X/Y axes.
  // Translation speed is dependent on altitude and direction is dependent
  // on heading.
  // Latitude (-90, 90)
  // Longitude [-180, 180), with wrapping as we pass the meridian.
  double heading_radians = ending_pose.orientation.z * kPi / 180;
  double cos_heading = cos(heading_radians);
  double sin_heading = sin(heading_radians);
  double delta_lat =
      (cos_heading * scaled_joy.linear.y) -
      (sin_heading * scaled_joy.linear.x);
  double delta_lon =
      (cos_heading * scaled_joy.linear.x) +
      (sin_heading * scaled_joy.linear.y);

#ifdef DEBUG
  ROS_INFO("JOYSTICK hr:%lf, cos:%lf, sin:%lf, dlat:%lf, dlon:%lf",
           heading_radians,
           cos_heading, sin_heading,
           delta_lat, delta_lon
  );
#endif
  // The further we are from the ground, the more we should translate x and y.
  double alt_scale = ending_pose.position.z;

  double proposed_position_y = starting_pose.position.y + (delta_lat * alt_scale);
  if ( abs(proposed_position_y) > kPoleLat) {
    ending_pose.orientation.z = fmod(ending_pose.orientation.z + 180, 360);
  }

  ending_pose.position.y =
      Clamp(starting_pose.position.y + (delta_lat * alt_scale),
            kPoleLat * -1.0,
            kPoleLat);
  ending_pose.position.y =
      Clamp(ending_pose.position.y,
            pose_minimums_.position.y,
            pose_maximums_.position.y);

#ifdef DEBUG
  ROS_INFO("JOYSTICK ENDING POSE alt_scale:%lf, yold:%lf, ynew:%lf",
           alt_scale,
           ending_pose.position.y,
           ending_pose.position.y +(delta_lat * alt_scale)
  );
#endif

  ending_pose.position.x =
      fmod((starting_pose.position.x + (delta_lon * alt_scale)) + 540, 360) -
      180;
  ending_pose.position.x =
      Clamp(ending_pose.position.x,
            pose_minimums_.position.x,
            pose_maximums_.position.x);

  last_requested_pose_ = ending_pose;

  PublishPose(kiosk_pub_, ending_pose);
  PublishPose(display_pub_, ending_pose);
}

void JoystickNavigator::PublishPose(
    ros::Publisher *pub, const geometry_msgs::Pose &pose) {
  geometry_msgs::PoseStamped pose_msg;
  pose_msg.pose = pose;
  pose_msg.header.stamp = ros::Time::now();
  pub->publish(pose_msg);
}

double JoystickNavigator::Quadratic(double v) {
  return std::abs(v) * v;
}

double JoystickNavigator::Clamp(double v, double min, double max) {
  return std::max(std::min(v, max), min);
}

timespec JoystickNavigator::DiffTimespec(timespec start, timespec end) {
  timespec diff;
  if ((end.tv_nsec - start.tv_nsec) < 0) {
    diff.tv_sec = end.tv_sec - start.tv_sec - 1;
    diff.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
  } else {
    diff.tv_sec = end.tv_sec - start.tv_sec;
    diff.tv_nsec = end.tv_nsec - start.tv_nsec;
  }
  return diff;
}

double JoystickNavigator::DivTimespec(timespec num, timespec denom) {
  double lnum = num.tv_sec * 1000000000 + num.tv_nsec;
  double ldenom = denom.tv_sec * 1000000000 + denom.tv_nsec;
  return lnum / ldenom;
}

// Compares the 'normal' and returns true if anything is outside the gutter.
bool JoystickNavigator::IsWithinGutter(const geometry_msgs::Twist& normal) {
  return (std::abs(normal.linear.x) < gutter_.linear.x) &&
      (std::abs(normal.linear.y) < gutter_.linear.y) &&
      (std::abs(normal.linear.z) < gutter_.linear.z) &&
      (std::abs(normal.angular.x) < gutter_.angular.x) &&
      (std::abs(normal.angular.y) < gutter_.angular.y) &&
      (std::abs(normal.angular.z) < gutter_.angular.z);
}

// Multiplies the 'normal' by linear_sensitivity_, and multiplies the quadratic
// scaled 'normal' by quadratic_sensitivity_.  Then scales the whole thing by
// 'interval_scale.'
void JoystickNavigator::Scale(
    const geometry_msgs::Twist& normal,
    double interval_scale,
    geometry_msgs::Twist* result) {

#ifdef DEBUG
  ROS_INFO("SCALING nlx:%lf, nly:%lf, lsx:%lf, lsy:%lf, is:%lf",
           normal.linear.x, normal.linear.y,
           linear_sensitivity_.linear.x, linear_sensitivity_.linear.y,
           interval_scale
  );
#endif

  result->linear.x = (normal.linear.x * linear_sensitivity_.linear.x +
      Quadratic(normal.linear.x) * quadratic_sensitivity_.linear.x) *
      interval_scale;
  result->linear.y = (normal.linear.y * linear_sensitivity_.linear.y +
      Quadratic(normal.linear.y) * quadratic_sensitivity_.linear.y) *
      interval_scale;
  result->linear.z = (normal.linear.z * linear_sensitivity_.linear.z +
      Quadratic(normal.linear.z) * quadratic_sensitivity_.linear.z) *
      interval_scale;
  result->angular.x = (normal.angular.x * linear_sensitivity_.angular.x +
      Quadratic(normal.angular.x) * quadratic_sensitivity_.angular.x) *
      interval_scale;
  result->angular.y = (normal.angular.y * linear_sensitivity_.angular.y +
      Quadratic(normal.angular.y) * quadratic_sensitivity_.angular.y) *
      interval_scale;
  result->angular.z = (normal.angular.z * linear_sensitivity_.angular.z +
      Quadratic(normal.angular.z) * quadratic_sensitivity_.angular.z) *
      interval_scale;
}
<commit_msg>More SpaceNav movement sensitivity tweakage<commit_after>// crbarker@google.com
//
// Implements JoystickNavigator.

#include "joystick_navigator.h"

//#define DEBUG

#include <time.h>
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <geometry_msgs/Pose.h>
#include <geometry_msgs/PoseStamped.h>

#include <algorithm>
#include <cmath>

#include "slinky_nav/SlinkyPose.h"

static const double kPi = 3.141592653589793;
static const double kPoleLat = 90.0 - 0.000001;
static const double kEarthRadius = 6371000;
static const timespec kExpectedInterval = {0, 33333333};  // 30 Hz

JoystickNavigator::JoystickNavigator()
    : under_joy_control_(false),
      kiosk_pub_(NULL),
      display_pub_(NULL) {
  // The sensitivities and gutter are hard-coded here.
  // In this case, linear_sensitivity_ refers to linear scaling
  // (vs. quadratic scaling) not linear motion (vs. angular).
  linear_sensitivity_.linear.x = 0.0;  // longitude
  linear_sensitivity_.linear.y = 0.0;  // latitude
  linear_sensitivity_.linear.z = 0.0;  // altitude
  linear_sensitivity_.angular.x = 0.0;  // pitch
  linear_sensitivity_.angular.y = 0.0;  // roll
  linear_sensitivity_.angular.z = 0.0;  // heading

  quadratic_sensitivity_.linear.x = 0.00000058;  // longitude
  quadratic_sensitivity_.linear.y = 0.00000058;  // latitude
  quadratic_sensitivity_.linear.z = 0.078;  // altitude
  quadratic_sensitivity_.angular.x = 2.2;  // pitch
  quadratic_sensitivity_.angular.y = 0.0;  // roll
  quadratic_sensitivity_.angular.z = 2.2;  // heading

  // If all joystick inputs are all less than the gutter, the input
  // is ignored, and it's assumed that we're under touch/mouse control.
  gutter_.linear.x = 0.001;
  gutter_.linear.y = 0.001;
  gutter_.linear.z = 0.001;
  gutter_.angular.x = 0.001;
  gutter_.angular.y = 0.001;
  gutter_.angular.z = 0.001;
}

void JoystickNavigator::Init(
    ros::Publisher *kiosk_pub, ros::Publisher *display_pub) {

  kiosk_pub_ = kiosk_pub;
  display_pub_ = display_pub;
  clock_gettime(CLOCK_REALTIME, &last_joy_time_);
}

void JoystickNavigator::ProcessCameraMoved(
    const slinky_nav::SlinkyPose& slinky_pose) {
  // Allow touchscreen takeover.
  if (!under_joy_control_ &&
        !EqualPoses(slinky_pose.current_pose, last_camera_pose_)) {
    PublishPose(display_pub_, slinky_pose.current_pose);
  }

  last_camera_pose_ = slinky_pose.current_pose;
  pose_minimums_ = slinky_pose.pose_minimums;
  pose_maximums_ = slinky_pose.pose_maximums;
}

bool JoystickNavigator::EqualPoses(
    const geometry_msgs::Pose& left, const geometry_msgs::Pose& right) {
  return (
    left.position.x == right.position.x &&
    left.position.y == right.position.y &&
    left.position.z == right.position.z &&
    left.orientation.x == right.orientation.x &&
    left.orientation.y == right.orientation.y &&
    left.orientation.z == right.orientation.z
  );
}

void JoystickNavigator::ProcessJoy(const geometry_msgs::Twist& normalized_joy) {
  // The joystick sensitivities are tuned for a nominal input frequency.
  // However, inputs can come faster/slower than that, so we apply further
  // scaling.
  timespec current_time;
  clock_gettime(CLOCK_REALTIME, &current_time);
  timespec diff_time = DiffTimespec(last_joy_time_, current_time);
  last_joy_time_ = current_time;
  double interval_scale = DivTimespec(diff_time, kExpectedInterval);

  // If the entire normalized_joy is at steady state then we exit early.
  if (IsWithinGutter(normalized_joy)) {
    // This breadcrumb tells us to base future navigation on the last received
    // camera pose, not our requested pose.
    under_joy_control_ = false;
    return;
  }
  // Otherwise, we don't gutter any inputs. If we're moving the camera at all,
  // we'll move it based on all inputs, no matter how tiny.

  // If we've been under control of the joystick since the last call, we start
  // from the last pose the joystick requested (preventing stutter in case
  // the camera response gets delayed). However, if this is the first time
  // we're moving since the joystick was in the gutter, we'll start from
  // the last reported camera position.
  geometry_msgs::Pose& starting_pose = last_requested_pose_;
  if (!under_joy_control_) {
    starting_pose = last_camera_pose_;
    under_joy_control_ = true;
  }

  geometry_msgs::Pose ending_pose = starting_pose;
  geometry_msgs::Twist scaled_joy;
  Scale(normalized_joy, interval_scale, &scaled_joy);

  // Altitude:  Adjusts camera altitude per joystick linear Z axis.
  // Altitude is computed first, since it affects scaling of other inputs.
  ending_pose.position.z =
      Clamp(starting_pose.position.z +
          (starting_pose.position.z * scaled_joy.linear.z),
          pose_minimums_.position.z, pose_maximums_.position.z);

  // Heading:  Adjusts compass heading per joystick angular Z axis.
  // This is computed early because it affects the direction of translations.
  // [0, 360), with wrapping.
  ending_pose.orientation.z =
      fmod(starting_pose.orientation.z + 360 - scaled_joy.angular.z, 360);
  ending_pose.orientation.z =
      Clamp(ending_pose.orientation.z,
            pose_minimums_.orientation.z,
            pose_maximums_.orientation.z);

  // Tilt:  Adjusts tilt per joystick angular X axis.
  // TODO(crbarker): clamp the tilt intelligently so we never omit earth.
  ending_pose.orientation.x =
      Clamp(starting_pose.orientation.x + scaled_joy.angular.x,
            pose_minimums_.orientation.x,
            pose_maximums_.orientation.x);

#ifdef DEBUG
  ROS_INFO("JOYSTICK curr lon:%lf, lat:%lf, alt:%lf, hdg:%lf, tlt:%lf",
           ending_pose.position.x,
           ending_pose.position.y,
           ending_pose.position.z,
           ending_pose.orientation.z,
           ending_pose.orientation.x);
  ROS_INFO("JOYSTICK scaled linear x:%lf, y:%lf",
           scaled_joy.linear.x,
           scaled_joy.linear.y
  );
#endif
  // Translate:  Translates the camera per joystick linear X/Y axes.
  // Translation speed is dependent on altitude and direction is dependent
  // on heading.
  // Latitude (-90, 90)
  // Longitude [-180, 180), with wrapping as we pass the meridian.
  double heading_radians = ending_pose.orientation.z * kPi / 180;
  double cos_heading = cos(heading_radians);
  double sin_heading = sin(heading_radians);
  double delta_lat =
      (cos_heading * scaled_joy.linear.y) -
      (sin_heading * scaled_joy.linear.x);
  double delta_lon =
      (cos_heading * scaled_joy.linear.x) +
      (sin_heading * scaled_joy.linear.y);

#ifdef DEBUG
  ROS_INFO("JOYSTICK hr:%lf, cos:%lf, sin:%lf, dlat:%lf, dlon:%lf",
           heading_radians,
           cos_heading, sin_heading,
           delta_lat, delta_lon
  );
#endif
  // The further we are from the ground, the more we should translate x and y.
  double alt_scale = ending_pose.position.z;

  double proposed_position_y = starting_pose.position.y + (delta_lat * alt_scale);
  if ( abs(proposed_position_y) > kPoleLat) {
    ending_pose.orientation.z = fmod(ending_pose.orientation.z + 180, 360);
  }

  ending_pose.position.y =
      Clamp(starting_pose.position.y + (delta_lat * alt_scale),
            kPoleLat * -1.0,
            kPoleLat);
  ending_pose.position.y =
      Clamp(ending_pose.position.y,
            pose_minimums_.position.y,
            pose_maximums_.position.y);

#ifdef DEBUG
  ROS_INFO("JOYSTICK ENDING POSE alt_scale:%lf, yold:%lf, ynew:%lf",
           alt_scale,
           ending_pose.position.y,
           ending_pose.position.y +(delta_lat * alt_scale)
  );
#endif

  ending_pose.position.x =
      fmod((starting_pose.position.x + (delta_lon * alt_scale)) + 540, 360) -
      180;
  ending_pose.position.x =
      Clamp(ending_pose.position.x,
            pose_minimums_.position.x,
            pose_maximums_.position.x);

  last_requested_pose_ = ending_pose;

  PublishPose(kiosk_pub_, ending_pose);
  PublishPose(display_pub_, ending_pose);
}

void JoystickNavigator::PublishPose(
    ros::Publisher *pub, const geometry_msgs::Pose &pose) {
  geometry_msgs::PoseStamped pose_msg;
  pose_msg.pose = pose;
  pose_msg.header.stamp = ros::Time::now();
  pub->publish(pose_msg);
}

double JoystickNavigator::Quadratic(double v) {
  return std::abs(v) * v;
}

double JoystickNavigator::Clamp(double v, double min, double max) {
  return std::max(std::min(v, max), min);
}

timespec JoystickNavigator::DiffTimespec(timespec start, timespec end) {
  timespec diff;
  if ((end.tv_nsec - start.tv_nsec) < 0) {
    diff.tv_sec = end.tv_sec - start.tv_sec - 1;
    diff.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
  } else {
    diff.tv_sec = end.tv_sec - start.tv_sec;
    diff.tv_nsec = end.tv_nsec - start.tv_nsec;
  }
  return diff;
}

double JoystickNavigator::DivTimespec(timespec num, timespec denom) {
  double lnum = num.tv_sec * 1000000000 + num.tv_nsec;
  double ldenom = denom.tv_sec * 1000000000 + denom.tv_nsec;
  return lnum / ldenom;
}

// Compares the 'normal' and returns true if anything is outside the gutter.
bool JoystickNavigator::IsWithinGutter(const geometry_msgs::Twist& normal) {
  return (std::abs(normal.linear.x) < gutter_.linear.x) &&
      (std::abs(normal.linear.y) < gutter_.linear.y) &&
      (std::abs(normal.linear.z) < gutter_.linear.z) &&
      (std::abs(normal.angular.x) < gutter_.angular.x) &&
      (std::abs(normal.angular.y) < gutter_.angular.y) &&
      (std::abs(normal.angular.z) < gutter_.angular.z);
}

// Multiplies the 'normal' by linear_sensitivity_, and multiplies the quadratic
// scaled 'normal' by quadratic_sensitivity_.  Then scales the whole thing by
// 'interval_scale.'
void JoystickNavigator::Scale(
    const geometry_msgs::Twist& normal,
    double interval_scale,
    geometry_msgs::Twist* result) {

#ifdef DEBUG
  ROS_INFO("SCALING nlx:%lf, nly:%lf, lsx:%lf, lsy:%lf, is:%lf",
           normal.linear.x, normal.linear.y,
           linear_sensitivity_.linear.x, linear_sensitivity_.linear.y,
           interval_scale
  );
#endif

  result->linear.x = (normal.linear.x * linear_sensitivity_.linear.x +
      Quadratic(normal.linear.x) * quadratic_sensitivity_.linear.x) *
      interval_scale;
  result->linear.y = (normal.linear.y * linear_sensitivity_.linear.y +
      Quadratic(normal.linear.y) * quadratic_sensitivity_.linear.y) *
      interval_scale;
  result->linear.z = (normal.linear.z * linear_sensitivity_.linear.z +
      Quadratic(normal.linear.z) * quadratic_sensitivity_.linear.z) *
      interval_scale;
  result->angular.x = (normal.angular.x * linear_sensitivity_.angular.x +
      Quadratic(normal.angular.x) * quadratic_sensitivity_.angular.x) *
      interval_scale;
  result->angular.y = (normal.angular.y * linear_sensitivity_.angular.y +
      Quadratic(normal.angular.y) * quadratic_sensitivity_.angular.y) *
      interval_scale;
  result->angular.z = (normal.angular.z * linear_sensitivity_.angular.z +
      Quadratic(normal.angular.z) * quadratic_sensitivity_.angular.z) *
      interval_scale;
}
<|endoftext|>


<commit_before>/*
 *	dcblocker≈
 *	External object for Max/MSP to perform basic mathematical operations on objects in a lydbær dsp chain.
 *	Copyright © 2008 by Timothy Place
 *
 *	License: This code is licensed under the terms of the GNU LGPL
 *	http://www.gnu.org/licenses/lgpl.html
 */

#include "maxMulticore.h"

// Data Structure for this object
typedef struct DCBlockerBaer {
    t_object			obj;
	MCoreObjectPtr		lydbaer;
	TTPtr				lydbaerOutlet;
	long				attrBypass;
};
typedef DCBlockerBaer* DCBlockerBaerPtr;

// Prototypes for methods
DCBlockerBaerPtr	dcBlockerBaerNew(SymbolPtr msg, AtomCount argc, AtomPtr argv);
void				dcBlockerBaerFree(DCBlockerBaerPtr x);
void				dcBlockerBaerAssist(DCBlockerBaerPtr x, void* b, long msg, long arg, char* dst);
void				dcBlockerBaerClear(DCBlockerBaerPtr x);
TTErr				dcBlockerBaerReset(DCBlockerBaerPtr x, long vectorSize);
TTErr				dcBlockerBaerSetup(DCBlockerBaerPtr x);
TTErr				dcBlockerBaerObject(DCBlockerBaerPtr x, MCoreObjectPtr audioSourceObject, long sourceOutletNumber);
MaxErr				dcBlockerBaerSetBypass(DCBlockerBaerPtr x, void *attr, AtomCount argc, AtomPtr argv);

// Globals
static ClassPtr sDCBlockerBaerClass;

/************************************************************************************/
// Main() Function

int main(void)
{
	ClassPtr c;

	MCoreInit();
	common_symbols_init();

	c = class_new("dcblocker≈", (method)dcBlockerBaerNew, (method)dcBlockerBaerFree, sizeof(DCBlockerBaer), (method)0L, A_GIMME, 0);

	class_addmethod(c, (method)dcBlockerBaerClear,		"clear",			0);
	class_addmethod(c, (method)dcBlockerBaerReset,		"multicore.reset",	A_CANT, 0);
	class_addmethod(c, (method)dcBlockerBaerSetup,		"multicore.setup",	A_CANT, 0);
	class_addmethod(c, (method)dcBlockerBaerObject,		"multicore.signal",	A_OBJ, A_LONG, 0);
 	class_addmethod(c, (method)dcBlockerBaerAssist,		"assist",			A_CANT, 0);
    class_addmethod(c, (method)object_obex_dumpout,		"dumpout",			A_CANT, 0);

	CLASS_ATTR_LONG(c,		"bypass",	0,		DCBlockerBaer,	attrBypass);
	CLASS_ATTR_STYLE(c,		"bypass",	0,		"onoff");
	CLASS_ATTR_ACCESSORS(c,	"bypass",	NULL,	dcBlockerBaerSetBypass);

	class_register(_sym_box, c);
	sDCBlockerBaerClass = c;
	return 0;
}

/************************************************************************************/
// Object Creation Method

DCBlockerBaerPtr dcBlockerBaerNew(SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
    DCBlockerBaerPtr	x;
	TTValue				v;
	TTErr				err;

    x = (DCBlockerBaerPtr)object_alloc(sDCBlockerBaerClass);
    if(x){
    	object_obex_store((void *)x, _sym_dumpout, (ObjectPtr)outlet_new(x, NULL));
		x->lydbaerOutlet = outlet_new(x, "multicore.signal");

		// TODO: we need to update objects to work with the correct number of channels when the network is configured
		// Either that, or when we pull we just up the number of channels if when we need to ???
		v.setSize(2);
		v.set(0, TT("dcblocker"));
		v.set(1, 1);
		err = TTObjectInstantiate(TT("multicore.object"), (TTObjectPtr*)&x->lydbaer, v);

		if(!x->lydbaer->audioObject){
			object_error(ObjectPtr(x), "cannot load TTBlue object");
			return NULL;
		}

		attr_args_process(x, argc, argv);
	}
	return x;
}

// Memory Deallocation
void dcBlockerBaerFree(DCBlockerBaerPtr x)
{
	if(x->lydbaer)
		TTObjectRelease((TTObjectPtr*)&x->lydbaer);
}

/************************************************************************************/
// Methods bound to input/inlets

// Method for Assistance Messages
void dcBlockerBaerAssist(DCBlockerBaerPtr x, void* b, long msg, long arg, char* dst)
{
	if(msg==1)			// Inlets
		strcpy(dst, "multichannel input and control messages");
	else if(msg==2){	// Outlets
		if(arg == 0)
			strcpy(dst, "multichannel output");
		else
			strcpy(dst, "dumpout");
	}
}

void dcBlockerBaerClear(DCBlockerBaerPtr x)
{
	x->lydbaer->audioObject->sendMessage(TT("clear"));
}

// METHODS SPECIFIC TO LYDBAER EXTERNALS

TTErr dcBlockerBaerReset(DCBlockerBaerPtr x, long vectorSize)
{
	return x->lydbaer->resetSources(vectorSize);
}

TTErr dcBlockerBaerSetup(DCBlockerBaerPtr x)
{
	Atom a[2];

	atom_setobj(a+0, ObjectPtr(x->lydbaer));
	atom_setlong(a+1, 0);
	outlet_anything(x->lydbaerOutlet, gensym("multicore.signal"), 2, a);
	return kTTErrNone;
}

TTErr dcBlockerBaerObject(DCBlockerBaerPtr x, MCoreObjectPtr audioSourceObject, long sourceOutletNumber)
{
	return x->lydbaer->addSource(audioSourceObject, sourceOutletNumber);
}

// ATTRIBUTE SETTERS

MaxErr dcBlockerBaerSetBypass(DCBlockerBaerPtr x, void *attr, AtomCount argc, AtomPtr argv)
{
	if(argc){
		x->attrBypass = atom_getlong(argv);
		x->lydbaer->audioObject->setAttributeValue(kTTSym_bypass, x->attrBypass);
	}
	return MAX_ERR_NONE;
}

<commit_msg>fix for dcblock extern instantiation<commit_after>/*
 *	dcblocker≈
 *	External object for Max/MSP to perform basic mathematical operations on objects in a lydbær dsp chain.
 *	Copyright © 2008 by Timothy Place
 *
 *	License: This code is licensed under the terms of the GNU LGPL
 *	http://www.gnu.org/licenses/lgpl.html
 */

#include "maxMulticore.h"

// Data Structure for this object
typedef struct DCBlockerBaer {
    t_object			obj;
	MCoreObjectPtr		lydbaer;
	TTPtr				lydbaerOutlet;
	long				attrBypass;
};
typedef DCBlockerBaer* DCBlockerBaerPtr;

// Prototypes for methods
DCBlockerBaerPtr	dcBlockerBaerNew(SymbolPtr msg, AtomCount argc, AtomPtr argv);
void				dcBlockerBaerFree(DCBlockerBaerPtr x);
void				dcBlockerBaerAssist(DCBlockerBaerPtr x, void* b, long msg, long arg, char* dst);
void				dcBlockerBaerClear(DCBlockerBaerPtr x);
TTErr				dcBlockerBaerReset(DCBlockerBaerPtr x, long vectorSize);
TTErr				dcBlockerBaerSetup(DCBlockerBaerPtr x);
TTErr				dcBlockerBaerObject(DCBlockerBaerPtr x, MCoreObjectPtr audioSourceObject, long sourceOutletNumber);
MaxErr				dcBlockerBaerSetBypass(DCBlockerBaerPtr x, void *attr, AtomCount argc, AtomPtr argv);

// Globals
static ClassPtr sDCBlockerBaerClass;

/************************************************************************************/
// Main() Function

int main(void)
{
	ClassPtr c;

	MCoreInit();
	common_symbols_init();

	c = class_new("dcblocker≈", (method)dcBlockerBaerNew, (method)dcBlockerBaerFree, sizeof(DCBlockerBaer), (method)0L, A_GIMME, 0);

	class_addmethod(c, (method)dcBlockerBaerClear,		"clear",			0);
	class_addmethod(c, (method)dcBlockerBaerReset,		"multicore.reset",	A_CANT, 0);
	class_addmethod(c, (method)dcBlockerBaerSetup,		"multicore.setup",	A_CANT, 0);
	class_addmethod(c, (method)dcBlockerBaerObject,		"multicore.signal",	A_OBJ, A_LONG, 0);
 	class_addmethod(c, (method)dcBlockerBaerAssist,		"assist",			A_CANT, 0);
    class_addmethod(c, (method)object_obex_dumpout,		"dumpout",			A_CANT, 0);

	CLASS_ATTR_LONG(c,		"bypass",	0,		DCBlockerBaer,	attrBypass);
	CLASS_ATTR_STYLE(c,		"bypass",	0,		"onoff");
	CLASS_ATTR_ACCESSORS(c,	"bypass",	NULL,	dcBlockerBaerSetBypass);

	class_register(_sym_box, c);
	sDCBlockerBaerClass = c;
	return 0;
}

/************************************************************************************/
// Object Creation Method

DCBlockerBaerPtr dcBlockerBaerNew(SymbolPtr msg, AtomCount argc, AtomPtr argv)
{
    DCBlockerBaerPtr	x;
	TTValue				v;
	TTErr				err;

    x = (DCBlockerBaerPtr)object_alloc(sDCBlockerBaerClass);
    if(x){
    	object_obex_store((void *)x, _sym_dumpout, (ObjectPtr)outlet_new(x, NULL));
		x->lydbaerOutlet = outlet_new(x, "multicore.signal");

		// TODO: we need to update objects to work with the correct number of channels when the network is configured
		// Either that, or when we pull we just up the number of channels if when we need to ???
		v.setSize(2);
		v.set(0, TT("dcblock"));
		v.set(1, 1);
		err = TTObjectInstantiate(TT("multicore.object"), (TTObjectPtr*)&x->lydbaer, v);

		if(!x->lydbaer->audioObject){
			object_error(ObjectPtr(x), "cannot load TTBlue object");
			return NULL;
		}

		attr_args_process(x, argc, argv);
	}
	return x;
}

// Memory Deallocation
void dcBlockerBaerFree(DCBlockerBaerPtr x)
{
	if(x->lydbaer)
		TTObjectRelease((TTObjectPtr*)&x->lydbaer);
}

/************************************************************************************/
// Methods bound to input/inlets

// Method for Assistance Messages
void dcBlockerBaerAssist(DCBlockerBaerPtr x, void* b, long msg, long arg, char* dst)
{
	if(msg==1)			// Inlets
		strcpy(dst, "multichannel input and control messages");
	else if(msg==2){	// Outlets
		if(arg == 0)
			strcpy(dst, "multichannel output");
		else
			strcpy(dst, "dumpout");
	}
}

void dcBlockerBaerClear(DCBlockerBaerPtr x)
{
	x->lydbaer->audioObject->sendMessage(TT("clear"));
}

// METHODS SPECIFIC TO LYDBAER EXTERNALS

TTErr dcBlockerBaerReset(DCBlockerBaerPtr x, long vectorSize)
{
	return x->lydbaer->resetSources(vectorSize);
}

TTErr dcBlockerBaerSetup(DCBlockerBaerPtr x)
{
	Atom a[2];

	atom_setobj(a+0, ObjectPtr(x->lydbaer));
	atom_setlong(a+1, 0);
	outlet_anything(x->lydbaerOutlet, gensym("multicore.signal"), 2, a);
	return kTTErrNone;
}

TTErr dcBlockerBaerObject(DCBlockerBaerPtr x, MCoreObjectPtr audioSourceObject, long sourceOutletNumber)
{
	return x->lydbaer->addSource(audioSourceObject, sourceOutletNumber);
}

// ATTRIBUTE SETTERS

MaxErr dcBlockerBaerSetBypass(DCBlockerBaerPtr x, void *attr, AtomCount argc, AtomPtr argv)
{
	if(argc){
		x->attrBypass = atom_getlong(argv);
		x->lydbaer->audioObject->setAttributeValue(kTTSym_bypass, x->attrBypass);
	}
	return MAX_ERR_NONE;
}

<|endoftext|>


<commit_before><commit_msg>extensions: clean up some code I saw while tracking down a bug<commit_after><|endoftext|>


<commit_before>// Copyright Benoit Blanchon 2014-2015
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson

#pragma once

#include "JsonSubscriptBase.hpp"

namespace ArduinoJson {

template <typename TKey>
class JsonObjectSubscript
    : public JsonSubscriptBase<JsonObjectSubscript<TKey> > {
 public:
  FORCE_INLINE JsonObjectSubscript(JsonObject& object, TKey key)
      : _object(object), _key(key) {}

  using JsonSubscriptBase<JsonObjectSubscript<TKey> >::operator=;

  FORCE_INLINE bool success() const { return _object.containsKey(_key); }

  FORCE_INLINE operator JsonVariant() const { return _object.get(_key); }

  template <typename TValue>
  FORCE_INLINE TValue as() const {
    return _object.get<TValue>(_key);
  }

  template <typename TValue>
  FORCE_INLINE TValue is() const {
    return _object.is<TValue>(_key);
  }

  template <typename TValue>
  FORCE_INLINE bool set(TValue value) {
    return _object.set(_key, value);
  }

  FORCE_INLINE JsonVariant get() { return _object.get(_key); }

  void writeTo(Internals::JsonWriter& writer) const {
    _object.get(_key).writeTo(writer);
  }

 private:
  JsonObject& _object;
  TKey _key;
};

#ifdef ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream& operator<<(
    std::ostream& os, const JsonObjectSubscript<const String&>& source) {
  return source.printTo(os);
}

inline std::ostream& operator<<(
    std::ostream& os, const JsonObjectSubscript<const char*>& source) {
  return source.printTo(os);
}
#endif
}
<commit_msg>Return type bool<commit_after>// Copyright Benoit Blanchon 2014-2015
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson

#pragma once

#include "JsonSubscriptBase.hpp"

namespace ArduinoJson {

template <typename TKey>
class JsonObjectSubscript
    : public JsonSubscriptBase<JsonObjectSubscript<TKey> > {
 public:
  FORCE_INLINE JsonObjectSubscript(JsonObject& object, TKey key)
      : _object(object), _key(key) {}

  using JsonSubscriptBase<JsonObjectSubscript<TKey> >::operator=;

  FORCE_INLINE bool success() const { return _object.containsKey(_key); }

  FORCE_INLINE operator JsonVariant() const { return _object.get(_key); }

  template <typename TValue>
  FORCE_INLINE TValue as() const {
    return _object.get<TValue>(_key);
  }

  template <typename TValue>
  FORCE_INLINE bool is() const {
    return _object.is<TValue>(_key);
  }

  template <typename TValue>
  FORCE_INLINE bool set(TValue value) {
    return _object.set(_key, value);
  }

  FORCE_INLINE JsonVariant get() { return _object.get(_key); }

  void writeTo(Internals::JsonWriter& writer) const {
    _object.get(_key).writeTo(writer);
  }

 private:
  JsonObject& _object;
  TKey _key;
};

#ifdef ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream& operator<<(
    std::ostream& os, const JsonObjectSubscript<const String&>& source) {
  return source.printTo(os);
}

inline std::ostream& operator<<(
    std::ostream& os, const JsonObjectSubscript<const char*>& source) {
  return source.printTo(os);
}
#endif
}
<|endoftext|>


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

#include "src/envoy/http/authn/peer_authenticator.h"
#include "common/http/utility.h"
#include "src/envoy/utils/utils.h"

using istio::authn::Payload;

namespace iaapi = istio::authentication::v1alpha1;

namespace Envoy {
namespace Http {
namespace Istio {
namespace AuthN {

PeerAuthenticator::PeerAuthenticator(FilterContext* filter_context,
                                     const iaapi::Policy& policy)
    : AuthenticatorBase(filter_context), policy_(policy) {}

bool PeerAuthenticator::run(Payload* payload) {
  bool success = false;

  if (policy_.peers_size() == 0) {
    ENVOY_LOG(debug, "No method defined. Skip source authentication.");
    success = true;
  } else {
    for (const auto& method : policy_.peers()) {
      switch (method.params_case()) {
        case iaapi::PeerAuthenticationMethod::ParamsCase::kMtls:
          success = validateX509(method.mtls(), payload);
          break;
        case iaapi::PeerAuthenticationMethod::ParamsCase::kJwt:
          success = validateJwt(method.jwt(), payload);
          break;
        default:
          ENVOY_LOG(error, "Unknown peer authentication param {}",
                    method.DebugString());
          success = false;
          break;
      }

      if (success) {
        break;
      }
    }
  }

  if (success) {
    filter_context()->setPeerResult(payload);
  }

  return success;
}

}  // namespace AuthN
}  // namespace Istio
}  // namespace Http
}  // namespace Envoy
<commit_msg>No setPeerResult() when peer is empty (#1461)<commit_after>/* Copyright 2018 Istio Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/envoy/http/authn/peer_authenticator.h"
#include "common/http/utility.h"
#include "src/envoy/utils/utils.h"

using istio::authn::Payload;

namespace iaapi = istio::authentication::v1alpha1;

namespace Envoy {
namespace Http {
namespace Istio {
namespace AuthN {

PeerAuthenticator::PeerAuthenticator(FilterContext* filter_context,
                                     const iaapi::Policy& policy)
    : AuthenticatorBase(filter_context), policy_(policy) {}

bool PeerAuthenticator::run(Payload* payload) {
  bool success = false;

  if (policy_.peers_size() == 0) {
    ENVOY_LOG(debug, "No method defined. Skip source authentication.");
    success = true;
    return success;
  }
  for (const auto& method : policy_.peers()) {
    switch (method.params_case()) {
      case iaapi::PeerAuthenticationMethod::ParamsCase::kMtls:
        success = validateX509(method.mtls(), payload);
        break;
      case iaapi::PeerAuthenticationMethod::ParamsCase::kJwt:
        success = validateJwt(method.jwt(), payload);
        break;
      default:
        ENVOY_LOG(error, "Unknown peer authentication param {}",
                  method.DebugString());
        success = false;
        break;
    }

    if (success) {
      break;
    }
  }

  if (success) {
    filter_context()->setPeerResult(payload);
  }

  return success;
}

}  // namespace AuthN
}  // namespace Istio
}  // namespace Http
}  // namespace Envoy
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/webui/print_preview_handler.h"

#include "base/threading/thread.h"
#include "base/values.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/browser_thread.h"
#include "printing/backend/print_backend.h"

class EnumeratePrintersTaskProxy
    : public base::RefCountedThreadSafe<EnumeratePrintersTaskProxy> {
 public:
  EnumeratePrintersTaskProxy(const base::WeakPtr<PrintPreviewHandler>& handler,
                             printing::PrintBackend* print_backend)
      : handler_(handler),
        print_backend_(print_backend) {
  }

  void EnumeratePrinters() {
    ListValue* printers = new ListValue;

    printing::PrinterList printer_list;
    print_backend_->EnumeratePrinters(&printer_list);
    for (printing::PrinterList::iterator index = printer_list.begin();
         index != printer_list.end(); ++index) {
      printers->Append(new StringValue(index->printer_name));
    }

    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this,
                          &EnumeratePrintersTaskProxy::SendPrinterList,
                          printers));
  }

  void SendPrinterList(ListValue* printers) {
    if (handler_)
      handler_->SendPrinterList(*printers);
    delete printers;
  }

 private:
  base::WeakPtr<PrintPreviewHandler> handler_;

  scoped_refptr<printing::PrintBackend> print_backend_;

  DISALLOW_COPY_AND_ASSIGN(EnumeratePrintersTaskProxy);
};

PrintPreviewHandler::PrintPreviewHandler()
    : print_backend_(printing::PrintBackend::CreateInstance(NULL)) {
}

PrintPreviewHandler::~PrintPreviewHandler() {
}

void PrintPreviewHandler::RegisterMessages() {
  web_ui_->RegisterMessageCallback("getPrinters",
      NewCallback(this, &PrintPreviewHandler::HandleGetPrinters));
  web_ui_->RegisterMessageCallback("print",
      NewCallback(this, &PrintPreviewHandler::HandlePrint));
}

void PrintPreviewHandler::HandleGetPrinters(const ListValue*) {
  scoped_refptr<EnumeratePrintersTaskProxy> task =
      new EnumeratePrintersTaskProxy(AsWeakPtr(), print_backend_.get());
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(task.get(),
                        &EnumeratePrintersTaskProxy::EnumeratePrinters));
}

void PrintPreviewHandler::HandlePrint(const ListValue*) {
  web_ui_->GetRenderViewHost()->PrintForPrintPreview();
}

void PrintPreviewHandler::SendPrinterList(const ListValue& printers) {
  web_ui_->CallJavascriptFunction(L"setPrinters", printers);
}
<commit_msg>Print Preview: Make sure EnumeratePrintersTaskProxy gets deleted on the right thread.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/webui/print_preview_handler.h"

#include "base/threading/thread.h"
#include "base/values.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/browser_thread.h"
#include "printing/backend/print_backend.h"

class EnumeratePrintersTaskProxy
    : public base::RefCountedThreadSafe<EnumeratePrintersTaskProxy,
                                        BrowserThread::DeleteOnUIThread> {
 public:
  EnumeratePrintersTaskProxy(const base::WeakPtr<PrintPreviewHandler>& handler,
                             printing::PrintBackend* print_backend)
      : handler_(handler),
        print_backend_(print_backend) {
  }

  void EnumeratePrinters() {
    ListValue* printers = new ListValue;

    printing::PrinterList printer_list;
    print_backend_->EnumeratePrinters(&printer_list);
    for (printing::PrinterList::iterator index = printer_list.begin();
         index != printer_list.end(); ++index) {
      printers->Append(new StringValue(index->printer_name));
    }

    BrowserThread::PostTask(
        BrowserThread::UI, FROM_HERE,
        NewRunnableMethod(this,
                          &EnumeratePrintersTaskProxy::SendPrinterList,
                          printers));
  }

  void SendPrinterList(ListValue* printers) {
    if (handler_)
      handler_->SendPrinterList(*printers);
    delete printers;
  }

 private:
  friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
  friend class DeleteTask<EnumeratePrintersTaskProxy>;

  ~EnumeratePrintersTaskProxy() {}

  base::WeakPtr<PrintPreviewHandler> handler_;

  scoped_refptr<printing::PrintBackend> print_backend_;

  DISALLOW_COPY_AND_ASSIGN(EnumeratePrintersTaskProxy);
};

PrintPreviewHandler::PrintPreviewHandler()
    : print_backend_(printing::PrintBackend::CreateInstance(NULL)) {
}

PrintPreviewHandler::~PrintPreviewHandler() {
}

void PrintPreviewHandler::RegisterMessages() {
  web_ui_->RegisterMessageCallback("getPrinters",
      NewCallback(this, &PrintPreviewHandler::HandleGetPrinters));
  web_ui_->RegisterMessageCallback("print",
      NewCallback(this, &PrintPreviewHandler::HandlePrint));
}

void PrintPreviewHandler::HandleGetPrinters(const ListValue*) {
  scoped_refptr<EnumeratePrintersTaskProxy> task =
      new EnumeratePrintersTaskProxy(AsWeakPtr(), print_backend_.get());
  BrowserThread::PostTask(
      BrowserThread::FILE, FROM_HERE,
      NewRunnableMethod(task.get(),
                        &EnumeratePrintersTaskProxy::EnumeratePrinters));
}

void PrintPreviewHandler::HandlePrint(const ListValue*) {
  web_ui_->GetRenderViewHost()->PrintForPrintPreview();
}

void PrintPreviewHandler::SendPrinterList(const ListValue& printers) {
  web_ui_->CallJavascriptFunction(L"setPrinters", printers);
}
<|endoftext|>


<commit_before><commit_msg>Wrong exception message.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/installer/util/chrome_frame_operations.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/channel_info.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/master_preferences.h"
#include "chrome/installer/util/master_preferences_constants.h"
#include "chrome/installer/util/util_constants.h"

namespace installer {

// Remove ready-mode if not multi-install.
void ChromeFrameOperations::NormalizeOptions(
    std::set<std::wstring>* options) const {
  std::set<std::wstring>::iterator ready_mode(options->find(kOptionReadyMode));
  if (ready_mode != options->end() &&
      options->find(kOptionMultiInstall) == options->end()) {
    LOG(WARNING) << "--ready-mode option does not apply when --multi-install "
                    "is not also specified; ignoring.";
    options->erase(ready_mode);
  }
}

void ChromeFrameOperations::ReadOptions(
    const MasterPreferences& prefs,
    std::set<std::wstring>* options) const {
  DCHECK(options);

  static const struct PrefToOption {
    const char* pref_name;
    const wchar_t* option_name;
  } map[] = {
    { master_preferences::kCeee, kOptionCeee },
    { master_preferences::kChromeFrameReadyMode, kOptionReadyMode },
    { master_preferences::kMultiInstall, kOptionMultiInstall }
  };

  bool pref_value;

  for (const PrefToOption* scan = &map[0], *end = &map[arraysize(map)];
       scan != end; ++scan) {
    if (prefs.GetBool(scan->pref_name, &pref_value) && pref_value)
      options->insert(scan->option_name);
  }

  NormalizeOptions(options);
}

void ChromeFrameOperations::ReadOptions(
    const CommandLine& uninstall_command,
    std::set<std::wstring>* options) const {
  DCHECK(options);

  static const struct FlagToOption {
    const char* flag_name;
    const wchar_t* option_name;
  } map[] = {
    { switches::kCeee, kOptionCeee },
    { switches::kChromeFrameReadyMode, kOptionReadyMode },
    { switches::kMultiInstall, kOptionMultiInstall }
  };

  for (const FlagToOption* scan = &map[0], *end = &map[arraysize(map)];
       scan != end; ++scan) {
    if (uninstall_command.HasSwitch(scan->flag_name))
      options->insert(scan->option_name);
  }

  NormalizeOptions(options);
}

void ChromeFrameOperations::AddKeyFiles(
    const std::set<std::wstring>& options,
    std::vector<FilePath>* key_files) const {
  DCHECK(key_files);
  key_files->push_back(FilePath(installer::kChromeFrameDll));
  if (options.find(kOptionCeee) != options.end()) {
    key_files->push_back(FilePath(installer::kCeeeIeDll));
    key_files->push_back(FilePath(installer::kCeeeBrokerExe));
  }
}

void ChromeFrameOperations::AddComDllList(
    const std::set<std::wstring>& options,
    std::vector<FilePath>* com_dll_list) const {
  DCHECK(com_dll_list);
  std::vector<FilePath> dll_list;
  com_dll_list->push_back(FilePath(installer::kChromeFrameDll));
  if (options.find(kOptionCeee) != options.end()) {
    com_dll_list->push_back(FilePath(installer::kCeeeInstallHelperDll));
    com_dll_list->push_back(FilePath(installer::kCeeeIeDll));
  }
}

void ChromeFrameOperations::AppendProductFlags(
    const std::set<std::wstring>& options,
    CommandLine* uninstall_command) const {
  DCHECK(uninstall_command);
  uninstall_command->AppendSwitch(switches::kChromeFrame);

  if (options.find(kOptionCeee) != options.end())
    uninstall_command->AppendSwitch(switches::kCeee);

  if (options.find(kOptionMultiInstall) != options.end()) {
    if (!uninstall_command->HasSwitch(switches::kMultiInstall))
      uninstall_command->AppendSwitch(switches::kMultiInstall);

    // ready-mode is only supported in multi-installs of Chrome Frame.
    if (options.find(kOptionReadyMode) != options.end())
      uninstall_command->AppendSwitch(switches::kChromeFrameReadyMode);
  }
}

bool ChromeFrameOperations::SetChannelFlags(
    const std::set<std::wstring>& options,
    bool set,
    ChannelInfo* channel_info) const {
#if defined(GOOGLE_CHROME_BUILD)
  DCHECK(channel_info);
  bool modified = channel_info->SetChromeFrame(set);

  // Always remove the options if we're called to remove flags or if the
  // corresponding option isn't set.
  modified |= channel_info->SetCeee(
      set && options.find(kOptionCeee) != options.end());

  modified |= channel_info->SetReadyMode(
      set && options.find(kOptionReadyMode) != options.end());

  return modified;
#else
  return false;
#endif
}

bool ChromeFrameOperations::ShouldCreateUninstallEntry(
    const std::set<std::wstring>& options) const {
  return options.find(kOptionReadyMode) == options.end();
}

}  // namespace installer
<commit_msg>Add chrome_frame_helper.exe to the set of key files for Chrome Frame as that could be in use while npchrome_frame.dll isn't.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/installer/util/chrome_frame_operations.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/channel_info.h"
#include "chrome/installer/util/helper.h"
#include "chrome/installer/util/master_preferences.h"
#include "chrome/installer/util/master_preferences_constants.h"
#include "chrome/installer/util/util_constants.h"

namespace installer {

// Remove ready-mode if not multi-install.
void ChromeFrameOperations::NormalizeOptions(
    std::set<std::wstring>* options) const {
  std::set<std::wstring>::iterator ready_mode(options->find(kOptionReadyMode));
  if (ready_mode != options->end() &&
      options->find(kOptionMultiInstall) == options->end()) {
    LOG(WARNING) << "--ready-mode option does not apply when --multi-install "
                    "is not also specified; ignoring.";
    options->erase(ready_mode);
  }
}

void ChromeFrameOperations::ReadOptions(
    const MasterPreferences& prefs,
    std::set<std::wstring>* options) const {
  DCHECK(options);

  static const struct PrefToOption {
    const char* pref_name;
    const wchar_t* option_name;
  } map[] = {
    { master_preferences::kCeee, kOptionCeee },
    { master_preferences::kChromeFrameReadyMode, kOptionReadyMode },
    { master_preferences::kMultiInstall, kOptionMultiInstall }
  };

  bool pref_value;

  for (const PrefToOption* scan = &map[0], *end = &map[arraysize(map)];
       scan != end; ++scan) {
    if (prefs.GetBool(scan->pref_name, &pref_value) && pref_value)
      options->insert(scan->option_name);
  }

  NormalizeOptions(options);
}

void ChromeFrameOperations::ReadOptions(
    const CommandLine& uninstall_command,
    std::set<std::wstring>* options) const {
  DCHECK(options);

  static const struct FlagToOption {
    const char* flag_name;
    const wchar_t* option_name;
  } map[] = {
    { switches::kCeee, kOptionCeee },
    { switches::kChromeFrameReadyMode, kOptionReadyMode },
    { switches::kMultiInstall, kOptionMultiInstall }
  };

  for (const FlagToOption* scan = &map[0], *end = &map[arraysize(map)];
       scan != end; ++scan) {
    if (uninstall_command.HasSwitch(scan->flag_name))
      options->insert(scan->option_name);
  }

  NormalizeOptions(options);
}

void ChromeFrameOperations::AddKeyFiles(
    const std::set<std::wstring>& options,
    std::vector<FilePath>* key_files) const {
  DCHECK(key_files);
  key_files->push_back(FilePath(installer::kChromeFrameDll));
  key_files->push_back(FilePath(installer::kChromeFrameHelperExe));
  if (options.find(kOptionCeee) != options.end()) {
    key_files->push_back(FilePath(installer::kCeeeIeDll));
    key_files->push_back(FilePath(installer::kCeeeBrokerExe));
  }
}

void ChromeFrameOperations::AddComDllList(
    const std::set<std::wstring>& options,
    std::vector<FilePath>* com_dll_list) const {
  DCHECK(com_dll_list);
  std::vector<FilePath> dll_list;
  com_dll_list->push_back(FilePath(installer::kChromeFrameDll));
  if (options.find(kOptionCeee) != options.end()) {
    com_dll_list->push_back(FilePath(installer::kCeeeInstallHelperDll));
    com_dll_list->push_back(FilePath(installer::kCeeeIeDll));
  }
}

void ChromeFrameOperations::AppendProductFlags(
    const std::set<std::wstring>& options,
    CommandLine* uninstall_command) const {
  DCHECK(uninstall_command);
  uninstall_command->AppendSwitch(switches::kChromeFrame);

  if (options.find(kOptionCeee) != options.end())
    uninstall_command->AppendSwitch(switches::kCeee);

  if (options.find(kOptionMultiInstall) != options.end()) {
    if (!uninstall_command->HasSwitch(switches::kMultiInstall))
      uninstall_command->AppendSwitch(switches::kMultiInstall);

    // ready-mode is only supported in multi-installs of Chrome Frame.
    if (options.find(kOptionReadyMode) != options.end())
      uninstall_command->AppendSwitch(switches::kChromeFrameReadyMode);
  }
}

bool ChromeFrameOperations::SetChannelFlags(
    const std::set<std::wstring>& options,
    bool set,
    ChannelInfo* channel_info) const {
#if defined(GOOGLE_CHROME_BUILD)
  DCHECK(channel_info);
  bool modified = channel_info->SetChromeFrame(set);

  // Always remove the options if we're called to remove flags or if the
  // corresponding option isn't set.
  modified |= channel_info->SetCeee(
      set && options.find(kOptionCeee) != options.end());

  modified |= channel_info->SetReadyMode(
      set && options.find(kOptionReadyMode) != options.end());

  return modified;
#else
  return false;
#endif
}

bool ChromeFrameOperations::ShouldCreateUninstallEntry(
    const std::set<std::wstring>& options) const {
  return options.find(kOptionReadyMode) == options.end();
}

}  // namespace installer
<|endoftext|>


<commit_before>#ifndef ALEPH_GEOMETRY_DISTANCES_HAMMING_HH__
#define ALEPH_GEOMETRY_DISTANCES_MANHATTAN_HH__

#include <cstddef>
#include <cmath>

#include <iterator>
#include <string>

namespace aleph
{

namespace geometry
{

namespace distances
{

/**
  Hamming distance ($L_1$ distance) functor The functor is templated in order
  to handle arbitrary ranges. Its interface is general, but the \c accum_dist
  function is specifically meant to be used with FLANN.

  @see FLANN project page (http://www.cs.ubc.ca/research/flann)
  @see FLANN repository   (https://github.com/mariusmuja/flann)
*/

template <class T> class Hamming
{
public:

  // Flag telling FLANN that this functor can be used for calculating distances
  // within kd trees.
  using is_kdtree_distance = bool;

  // Required for FLANN usage
  using ElementType = T;
  using ResultType  = T;

  /**
    Given two ranges of double values, which are assumed to represent two
    vectors, calculates the distance between them.

    @param a             Iterator describing first vector
    @param b             Iterator describing second vector
    @param size          Size of vectors a and b

    @param worstDistance If set to a value greater than zero, calculations will
    stop once the value has been reached. Else, the value of this variable is
    ignored. This variable is provided in order to remain compatible with the
    interface of FLANN.

    @returns Hamming distance between the two input vectors.
  */

  template <typename Iterator1, typename Iterator2>
  ResultType operator()( Iterator1 a,
                         Iterator2 b,
                         std::size_t size,
                         ElementType worstDistance = -1.0 ) const
  {
    // Fixes warnings about unused parameters. This parameter is
    // provided for compatibility reasons with FLANN only.
    (void) worstDistance;

    ElementType result = ElementType();

    bool diff0  = false;
    bool diff1  = false;
    bool diff2  = false;
    bool diff3  = false;

    using DifferenceType1
      = typename std::iterator_traits<Iterator1>::difference_type;

    Iterator1 last      = std::next( a, DifferenceType1( size ) );
    Iterator1 lastGroup = std::prev( last, 3 );

    while( a < lastGroup )
    {
      diff0 = a[0] != b[0];
      diff1 = a[1] != b[1];
      diff2 = a[2] != b[2];
      diff3 = a[3] != b[3];

      result +=   static_cast<ElementType>( diff0 )
                + static_cast<ElementType>( diff1 )
                + static_cast<ElementType>( diff2 )
                + static_cast<ElementType>( diff3 );

      a += 4;
      b += 4;

      if( worstDistance > 0 && result > worstDistance )
        return result;
    }

    while( a < last )
    {
      diff0  = *a++ != *b++;
      result = result + static_cast<ElementType>( diff0 );
    }

    return result;
  }

  /**
    Partial distance calculation, used by FLANN for fast kd-tree calculations.
    This function exploits that the Hamming distance can be evaluated
    component-wise.

    @param a First component
    @param b Second component

    @returns Partial distance between those two components
  */

  template <typename U, typename V>
  ResultType accum_dist( const U& a,
                         const V& b,
                         int __attribute__((unused)) ) const
  {
    return std::abs( a - b );
  }

  /** @returns Name of functor */
  static std::string name()
  {
    return "Hamming distance";
  }
};

} // namespace distances

} // namespace geometry

} // namespace aleph

#endif
<commit_msg>Fixed incorrect include guard<commit_after>#ifndef ALEPH_GEOMETRY_DISTANCES_HAMMING_HH__
#define ALEPH_GEOMETRY_DISTANCES_HAMMING_HH__

#include <cstddef>
#include <cmath>

#include <iterator>
#include <string>

namespace aleph
{

namespace geometry
{

namespace distances
{

/**
  Hamming distance ($L_1$ distance) functor The functor is templated in order
  to handle arbitrary ranges. Its interface is general, but the \c accum_dist
  function is specifically meant to be used with FLANN.

  @see FLANN project page (http://www.cs.ubc.ca/research/flann)
  @see FLANN repository   (https://github.com/mariusmuja/flann)
*/

template <class T> class Hamming
{
public:

  // Flag telling FLANN that this functor can be used for calculating distances
  // within kd trees.
  using is_kdtree_distance = bool;

  // Required for FLANN usage
  using ElementType = T;
  using ResultType  = T;

  /**
    Given two ranges of double values, which are assumed to represent two
    vectors, calculates the distance between them.

    @param a             Iterator describing first vector
    @param b             Iterator describing second vector
    @param size          Size of vectors a and b

    @param worstDistance If set to a value greater than zero, calculations will
    stop once the value has been reached. Else, the value of this variable is
    ignored. This variable is provided in order to remain compatible with the
    interface of FLANN.

    @returns Hamming distance between the two input vectors.
  */

  template <typename Iterator1, typename Iterator2>
  ResultType operator()( Iterator1 a,
                         Iterator2 b,
                         std::size_t size,
                         ElementType worstDistance = -1.0 ) const
  {
    // Fixes warnings about unused parameters. This parameter is
    // provided for compatibility reasons with FLANN only.
    (void) worstDistance;

    ElementType result = ElementType();

    bool diff0  = false;
    bool diff1  = false;
    bool diff2  = false;
    bool diff3  = false;

    using DifferenceType1
      = typename std::iterator_traits<Iterator1>::difference_type;

    Iterator1 last      = std::next( a, DifferenceType1( size ) );
    Iterator1 lastGroup = std::prev( last, 3 );

    while( a < lastGroup )
    {
      diff0 = a[0] != b[0];
      diff1 = a[1] != b[1];
      diff2 = a[2] != b[2];
      diff3 = a[3] != b[3];

      result +=   static_cast<ElementType>( diff0 )
                + static_cast<ElementType>( diff1 )
                + static_cast<ElementType>( diff2 )
                + static_cast<ElementType>( diff3 );

      a += 4;
      b += 4;

      if( worstDistance > 0 && result > worstDistance )
        return result;
    }

    while( a < last )
    {
      diff0  = *a++ != *b++;
      result = result + static_cast<ElementType>( diff0 );
    }

    return result;
  }

  /**
    Partial distance calculation, used by FLANN for fast kd-tree calculations.
    This function exploits that the Hamming distance can be evaluated
    component-wise.

    @param a First component
    @param b Second component

    @returns Partial distance between those two components
  */

  template <typename U, typename V>
  ResultType accum_dist( const U& a,
                         const V& b,
                         int __attribute__((unused)) ) const
  {
    return std::abs( a - b );
  }

  /** @returns Name of functor */
  static std::string name()
  {
    return "Hamming distance";
  }
};

} // namespace distances

} // namespace geometry

} // namespace aleph

#endif
<|endoftext|>


<commit_before>#include "framework/builder/framework_builder.h"

#include <deal.II/base/conditional_ostream.h>
#include <deal.II/base/mpi.h>
#include <sstream>

#include "utility/reporter/mpi.h"
#include "utility/reporter/colors.h"

// Convergence classes
#include "convergence/final_checker_or_n.h"
#include "convergence/moments/single_moment_checker_l1_norm.h"
#include "convergence/parameters/single_parameter_checker.h"
#include "convergence/reporter/mpi.h"

// Domain classes
#include "domain/definition.h"
#include "domain/finite_element/finite_element_gaussian.h"
#include "domain/mesh/mesh_cartesian.h"

// Formulation classes
#include "formulation/angular/self_adjoint_angular_flux.h"
#include "formulation/scalar/diffusion.h"
#include "formulation/stamper.h"
#include "formulation/updater/saaf_updater.h"
#include "formulation/updater/diffusion_updater.h"

// Material classes
#include "material/material_protobuf.h"

// Solver classes
#include "solver/group/single_group_solver.h"
#include "solver/gmres.h"

// Iteration classes
#include "iteration/initializer/initialize_fixed_terms_once.h"

// Quadrature classes & factories
#include "quadrature/quadrature_generator_i.h"
#include "quadrature/factory/quadrature_factories.h"
#include "quadrature/utility/quadrature_utilities.h"

namespace bart {

namespace framework {

namespace builder {

template<int dim>
void FrameworkBuilder<dim>::BuildFramework(std::string name,
                                           ParametersType& prm) {
  // Framework parameters
  int n_angles = 1; // Set to default value of 1 for scalar solve

  reporter_ptr_->Report("Building Framework: ");
  reporter_ptr_->Report(name + "\n", utility::reporter::Color::Green);

  auto finite_element_ptr = Shared(BuildFiniteElement(prm));
  auto cross_sections_ptr = Shared(BuildCrossSections(prm));

  auto domain_ptr = Shared(BuildDomain(prm, finite_element_ptr,
                                       ReadMappingFile(prm.MaterialMapFilename())));
  reporter_ptr_->Report("\tSetting up domain\n");
  domain_ptr->SetUpMesh().SetUpDOF();

  std::shared_ptr<QuadratureSetType> quadrature_set_ptr = nullptr;
  std::shared_ptr<FixedUpdaterType> fixed_updater_ptr = nullptr;
  if (prm.TransportModel() == problem::EquationType::kSelfAdjointAngularFlux) {
    quadrature_set_ptr = BuildQuadratureSet(prm);
    n_angles = quadrature_set_ptr->size();
    auto stamper_ptr = BuildStamper(domain_ptr);
    auto saaf_formulation_ptr = BuildSAAFFormulation(finite_element_ptr,
                                                     cross_sections_ptr,
                                                     quadrature_set_ptr);
    fixed_updater_ptr = Shared(BuildFixedUpdater(
        std::move(saaf_formulation_ptr),
        std::move(stamper_ptr),
        quadrature_set_ptr));
  } else if (prm.TransportModel() == problem::EquationType::kDiffusion) {
    auto diffusion_formulation_ptr = BuildDiffusionFormulation(
        finite_element_ptr,
        cross_sections_ptr);
    auto stamper_ptr = BuildStamper(domain_ptr);
    fixed_updater_ptr = Shared(BuildFixedUpdater(
        std::move(diffusion_formulation_ptr),
        std::move(stamper_ptr)));
  }
}

template<int dim>
auto FrameworkBuilder<dim>::BuildConvergenceReporter()
-> std::unique_ptr<ReporterType> {
  using Reporter = bart::convergence::reporter::MpiNoisy;

  std::unique_ptr<ReporterType> return_ptr = nullptr;

  int this_process = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
  auto pout_ptr = std::make_unique<dealii::ConditionalOStream>(std::cout, this_process == 0);
  return_ptr = std::make_unique<Reporter>(std::move(pout_ptr));

  return std::move(return_ptr);
}

template<int dim>
auto FrameworkBuilder<dim>::BuildCrossSections(
    const problem::ParametersI& problem_parameters)
    -> std::unique_ptr<CrossSectionType> {
  reporter_ptr_->Report("\tBuilding Cross-sections: ");
  std::unique_ptr<CrossSectionType> return_ptr = nullptr;
  // Default implementation using protocol buffers
  try {
    MaterialProtobuf materials(problem_parameters.MaterialFilenames(),
                               problem_parameters.IsEigenvalueProblem(),
                               problem_parameters.DoNDA(),
                               problem_parameters.NEnergyGroups(),
                               problem_parameters.NumberOfMaterials());
    return_ptr = std::move(std::make_unique<CrossSectionType>(materials));
    reporter_ptr_->Report("Built (default) Cross-sections using protobuf\n",
                          utility::reporter::Color::Green);
  } catch (...) {
    reporter_ptr_->Report("Error building (default) Cross-sections using protobuf\n",
                          utility::reporter::Color::Red);
    throw;
  }
  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildDiffusionFormulation(
    const std::shared_ptr<FiniteElementType>& finite_element_ptr,
    const std::shared_ptr<data::CrossSections>& cross_sections_ptr,
    const formulation::DiffusionFormulationImpl implementation)
-> std::unique_ptr<DiffusionFormulationType> {
  reporter_ptr_->Report("\tBuilding Diffusion Formulation\n");
  std::unique_ptr<DiffusionFormulationType> return_ptr = nullptr;

  if (implementation == formulation::DiffusionFormulationImpl::kDefault) {
    using ReturnType = formulation::scalar::Diffusion<dim>;
    return_ptr = std::move(std::make_unique<ReturnType>(
        finite_element_ptr, cross_sections_ptr));
  }

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildDomain(
    ParametersType problem_parameters,
    const std::shared_ptr<FiniteElementType>& finite_element_ptr,
    std::string material_mapping)
-> std::unique_ptr<DomainType>{
  std::unique_ptr<DomainType> return_ptr = nullptr;
  reporter_ptr_->Report("\tBuilding Mesh: ");
  auto mesh_ptr = std::make_unique<domain::mesh::MeshCartesian<dim>>(
      problem_parameters.SpatialMax(),
      problem_parameters.NCells(),
      material_mapping);
  reporter_ptr_->Report("Built: " + mesh_ptr->description() + "\n",
                        utility::reporter::Color::Green);
  reporter_ptr_->Report("\tBuilding Domain: ");
  return_ptr = std::move(std::make_unique<domain::Definition<dim>>(
      std::move(mesh_ptr),
      finite_element_ptr));
  reporter_ptr_->Report("Built (default) Domain\n", Color::Green);
  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildFiniteElement(ParametersType problem_parameters)
-> std::unique_ptr<FiniteElementType>{
  std::unique_ptr<FiniteElementType> return_ptr = nullptr;

  using FiniteElementGaussianType = domain::finite_element::FiniteElementGaussian<dim>;

  reporter_ptr_->Report("\tBuilding Finite Element: ");

  try {
    return_ptr = std::move(std::make_unique<FiniteElementGaussianType>(
        problem::DiscretizationType::kContinuousFEM,
        problem_parameters.FEPolynomialDegree()));

    reporter_ptr_->Report("Built: " + return_ptr->description() + "\n",
                          utility::reporter::Color::Green);
  } catch (...) {
    reporter_ptr_->Report("Error");
    throw;
  }
  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildFixedUpdater(
    std::unique_ptr<DiffusionFormulationType> formulation_ptr,
    std::unique_ptr<StamperType> stamper_ptr)
-> std::unique_ptr<FixedUpdaterType> {
  reporter_ptr_->Report("\tBuilding Diffusion Formulation updater\n");
  std::unique_ptr<FixedUpdaterType> return_ptr = nullptr;

  using ReturnType = formulation::updater::DiffusionUpdater<dim>;
  return_ptr = std::move(std::make_unique<ReturnType>(
      std::move(formulation_ptr),
      std::move(stamper_ptr)));

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildFixedUpdater(
    std::unique_ptr<SAAFFormulationType> formulation_ptr,
    std::unique_ptr<StamperType> stamper_ptr,
    const std::shared_ptr<QuadratureSetType>& quadrature_set_ptr)
-> std::unique_ptr<FixedUpdaterType> {
  reporter_ptr_->Report("\tBuilding SAAF Formulation updater\n");
  std::unique_ptr<FixedUpdaterType> return_ptr = nullptr;

  using ReturnType = formulation::updater::SAAFUpdater<dim>;
  return_ptr = std::move(std::make_unique<ReturnType>(
      std::move(formulation_ptr),
      std::move(stamper_ptr),
      quadrature_set_ptr));

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildInitializer(
    const std::shared_ptr<formulation::updater::FixedUpdaterI>& updater_ptr,
    const int total_groups,
    const int total_angles) -> std::unique_ptr<InitializerType> {
  std::unique_ptr<InitializerType> return_ptr = nullptr;

  using InitializeOnceType = iteration::initializer::InitializeFixedTermsOnce;

  return_ptr = std::move(std::make_unique<InitializeOnceType>(
      updater_ptr, total_groups, total_angles));

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildMomentConvergenceChecker(
    double max_delta, int max_iterations)
-> std::unique_ptr<MomentConvergenceCheckerType>{
  //TODO(Josh): Add option for using other than L1Norm

  using CheckerType = convergence::moments::SingleMomentCheckerL1Norm;
  using FinalCheckerType = convergence::FinalCheckerOrN<
      system::moments::MomentVector,
      convergence::moments::SingleMomentCheckerI>;

  auto single_checker_ptr = std::make_unique<CheckerType>(max_delta);
  auto return_ptr = std::make_unique<FinalCheckerType>(
      std::move(single_checker_ptr));

  return_ptr->SetMaxIterations(max_iterations);

  return std::move(return_ptr);
}

template<int dim>
auto FrameworkBuilder<dim>::BuildParameterConvergenceChecker(
    double max_delta, int max_iterations)
-> std::unique_ptr<ParameterConvergenceCheckerType>{

  using CheckerType = convergence::parameters::SingleParameterChecker;
  using FinalCheckerType = convergence::FinalCheckerOrN<double, CheckerType>;

  auto single_checker_ptr = std::make_unique<CheckerType>(max_delta);
  auto return_ptr = std::make_unique<FinalCheckerType>(
      std::move(single_checker_ptr));

  return_ptr->SetMaxIterations(max_iterations);

  return std::move(return_ptr);
}

template<int dim>
auto FrameworkBuilder<dim>::BuildQuadratureSet(ParametersType problem_parameters)
-> std::shared_ptr<QuadratureSetType> {
  reporter_ptr_->Report("\tBuilding quadrature set\n");
  using QuadratureGeneratorType = quadrature::QuadratureGeneratorI<dim>;

  std::shared_ptr<QuadratureSetType> return_ptr = nullptr;
  std::shared_ptr<QuadratureGeneratorType > quadrature_generator_ptr = nullptr;

  const int order_value = problem_parameters.AngularQuadOrder();
  switch (problem_parameters.AngularQuad()) {
    default: {
      if (dim == 3) {
        quadrature_generator_ptr =
            quadrature::factory::MakeAngularQuadratureGeneratorPtr<dim>(
                quadrature::Order(order_value),
                quadrature::AngularQuadratureSetType::kLevelSymmetricGaussian);
      } else {
        AssertThrow(false,
                    dealii::ExcMessage("No supported quadratures for this dimension "
                                       "and transport model"))
      }
    }
  }

  return_ptr = quadrature::factory::MakeQuadratureSetPtr<dim>();

  auto quadrature_points = quadrature::utility::GenerateAllPositiveX<dim>(
      quadrature_generator_ptr->GenerateSet());

  quadrature::factory::FillQuadratureSet<dim>(return_ptr.get(),
                                              quadrature_points);

  return std::move(return_ptr);
}

template <int dim>
auto FrameworkBuilder<dim>::BuildSAAFFormulation(
    const std::shared_ptr<FiniteElementType>& finite_element_ptr,
    const std::shared_ptr<data::CrossSections>& cross_sections_ptr,
    const std::shared_ptr<QuadratureSetType>& quadrature_set_ptr,
    const formulation::SAAFFormulationImpl implementation)
-> std::unique_ptr<SAAFFormulationType> {
  reporter_ptr_->Report("\tBuilding SAAF Formulation\n");
  std::unique_ptr<SAAFFormulationType> return_ptr;

  if (implementation == formulation::SAAFFormulationImpl::kDefault) {
    using ReturnType = formulation::angular::SelfAdjointAngularFlux<dim>;

    return_ptr = std::move(std::make_unique<ReturnType>(finite_element_ptr,
                                                        cross_sections_ptr,
                                                        quadrature_set_ptr));
  }

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildSingleGroupSolver(
    const int max_iterations,
    const double convergence_tolerance)
-> std::unique_ptr<SingleGroupSolverType> {
  std::unique_ptr<SingleGroupSolverType> return_ptr = nullptr;

  auto linear_solver_ptr = std::make_unique<solver::GMRES>(max_iterations,
                                                           convergence_tolerance);

  return_ptr = std::move(std::make_unique<solver::group::SingleGroupSolver>(
          std::move(linear_solver_ptr)));

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildStamper(
    const std::shared_ptr<DomainType>& domain_ptr)
-> std::unique_ptr<StamperType> {
  reporter_ptr_->Report("\tBuilding Stamper\n");
  std::unique_ptr<StamperType> return_ptr = nullptr;

  return_ptr = std::move(
      std::make_unique<formulation::Stamper<dim>>(domain_ptr));

  return return_ptr;
}
template<int dim>
std::string FrameworkBuilder<dim>::ReadMappingFile(std::string filename) {
  reporter_ptr_->Report("\tReading mapping file: ");

  std::ifstream mapping_file(filename);
  if (mapping_file.is_open()) {
    reporter_ptr_->Report(filename + '\n', Color::Green);

    return std::string(
        (std::istreambuf_iterator<char>(mapping_file)),
        std::istreambuf_iterator<char>());
  } else {
    reporter_ptr_->Report("Error reading " + filename + "\n", Color::Red);
    AssertThrow(false,
                dealii::ExcMessage("Failed to open material mapping file"))
  }
}

template class FrameworkBuilder<1>;
template class FrameworkBuilder<2>;
template class FrameworkBuilder<3>;

} // namespace builder

} // namespace framework

} // namespace bart
<commit_msg>added initializer instantiation<commit_after>#include "framework/builder/framework_builder.h"

#include <deal.II/base/conditional_ostream.h>
#include <deal.II/base/mpi.h>
#include <sstream>

#include "utility/reporter/mpi.h"
#include "utility/reporter/colors.h"

// Convergence classes
#include "convergence/final_checker_or_n.h"
#include "convergence/moments/single_moment_checker_l1_norm.h"
#include "convergence/parameters/single_parameter_checker.h"
#include "convergence/reporter/mpi.h"

// Domain classes
#include "domain/definition.h"
#include "domain/finite_element/finite_element_gaussian.h"
#include "domain/mesh/mesh_cartesian.h"

// Formulation classes
#include "formulation/angular/self_adjoint_angular_flux.h"
#include "formulation/scalar/diffusion.h"
#include "formulation/stamper.h"
#include "formulation/updater/saaf_updater.h"
#include "formulation/updater/diffusion_updater.h"

// Material classes
#include "material/material_protobuf.h"

// Solver classes
#include "solver/group/single_group_solver.h"
#include "solver/gmres.h"

// Iteration classes
#include "iteration/initializer/initialize_fixed_terms_once.h"

// Quadrature classes & factories
#include "quadrature/quadrature_generator_i.h"
#include "quadrature/factory/quadrature_factories.h"
#include "quadrature/utility/quadrature_utilities.h"

namespace bart {

namespace framework {

namespace builder {

template<int dim>
void FrameworkBuilder<dim>::BuildFramework(std::string name,
                                           ParametersType& prm) {
  // Framework parameters
  int n_angles = 1; // Set to default value of 1 for scalar solve
  const int n_groups = prm.NEnergyGroups();

  reporter_ptr_->Report("Building Framework: ");
  reporter_ptr_->Report(name + "\n", utility::reporter::Color::Green);

  auto finite_element_ptr = Shared(BuildFiniteElement(prm));
  auto cross_sections_ptr = Shared(BuildCrossSections(prm));

  auto domain_ptr = Shared(BuildDomain(prm, finite_element_ptr,
                                       ReadMappingFile(prm.MaterialMapFilename())));
  reporter_ptr_->Report("\tSetting up domain\n");
  domain_ptr->SetUpMesh().SetUpDOF();

  std::shared_ptr<QuadratureSetType> quadrature_set_ptr = nullptr;
  std::shared_ptr<FixedUpdaterType> fixed_updater_ptr = nullptr;
  if (prm.TransportModel() == problem::EquationType::kSelfAdjointAngularFlux) {
    quadrature_set_ptr = BuildQuadratureSet(prm);
    n_angles = quadrature_set_ptr->size();
    auto stamper_ptr = BuildStamper(domain_ptr);
    auto saaf_formulation_ptr = BuildSAAFFormulation(finite_element_ptr,
                                                     cross_sections_ptr,
                                                     quadrature_set_ptr);
    fixed_updater_ptr = Shared(BuildFixedUpdater(
        std::move(saaf_formulation_ptr),
        std::move(stamper_ptr),
        quadrature_set_ptr));
  } else if (prm.TransportModel() == problem::EquationType::kDiffusion) {
    auto diffusion_formulation_ptr = BuildDiffusionFormulation(
        finite_element_ptr,
        cross_sections_ptr);
    auto stamper_ptr = BuildStamper(domain_ptr);
    fixed_updater_ptr = Shared(BuildFixedUpdater(
        std::move(diffusion_formulation_ptr),
        std::move(stamper_ptr)));
  }

  auto initializer_ptr = BuildInitializer(fixed_updater_ptr, n_groups, n_angles);

}

template<int dim>
auto FrameworkBuilder<dim>::BuildConvergenceReporter()
-> std::unique_ptr<ReporterType> {
  using Reporter = bart::convergence::reporter::MpiNoisy;

  std::unique_ptr<ReporterType> return_ptr = nullptr;

  int this_process = dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
  auto pout_ptr = std::make_unique<dealii::ConditionalOStream>(std::cout, this_process == 0);
  return_ptr = std::make_unique<Reporter>(std::move(pout_ptr));

  return std::move(return_ptr);
}

template<int dim>
auto FrameworkBuilder<dim>::BuildCrossSections(
    const problem::ParametersI& problem_parameters)
    -> std::unique_ptr<CrossSectionType> {
  reporter_ptr_->Report("\tBuilding Cross-sections: ");
  std::unique_ptr<CrossSectionType> return_ptr = nullptr;
  // Default implementation using protocol buffers
  try {
    MaterialProtobuf materials(problem_parameters.MaterialFilenames(),
                               problem_parameters.IsEigenvalueProblem(),
                               problem_parameters.DoNDA(),
                               problem_parameters.NEnergyGroups(),
                               problem_parameters.NumberOfMaterials());
    return_ptr = std::move(std::make_unique<CrossSectionType>(materials));
    reporter_ptr_->Report("Built (default) Cross-sections using protobuf\n",
                          utility::reporter::Color::Green);
  } catch (...) {
    reporter_ptr_->Report("Error building (default) Cross-sections using protobuf\n",
                          utility::reporter::Color::Red);
    throw;
  }
  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildDiffusionFormulation(
    const std::shared_ptr<FiniteElementType>& finite_element_ptr,
    const std::shared_ptr<data::CrossSections>& cross_sections_ptr,
    const formulation::DiffusionFormulationImpl implementation)
-> std::unique_ptr<DiffusionFormulationType> {
  reporter_ptr_->Report("\tBuilding Diffusion Formulation\n");
  std::unique_ptr<DiffusionFormulationType> return_ptr = nullptr;

  if (implementation == formulation::DiffusionFormulationImpl::kDefault) {
    using ReturnType = formulation::scalar::Diffusion<dim>;
    return_ptr = std::move(std::make_unique<ReturnType>(
        finite_element_ptr, cross_sections_ptr));
  }

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildDomain(
    ParametersType problem_parameters,
    const std::shared_ptr<FiniteElementType>& finite_element_ptr,
    std::string material_mapping)
-> std::unique_ptr<DomainType>{
  std::unique_ptr<DomainType> return_ptr = nullptr;
  reporter_ptr_->Report("\tBuilding Mesh: ");
  auto mesh_ptr = std::make_unique<domain::mesh::MeshCartesian<dim>>(
      problem_parameters.SpatialMax(),
      problem_parameters.NCells(),
      material_mapping);
  reporter_ptr_->Report("Built: " + mesh_ptr->description() + "\n",
                        utility::reporter::Color::Green);
  reporter_ptr_->Report("\tBuilding Domain: ");
  return_ptr = std::move(std::make_unique<domain::Definition<dim>>(
      std::move(mesh_ptr),
      finite_element_ptr));
  reporter_ptr_->Report("Built (default) Domain\n", Color::Green);
  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildFiniteElement(ParametersType problem_parameters)
-> std::unique_ptr<FiniteElementType>{
  std::unique_ptr<FiniteElementType> return_ptr = nullptr;

  using FiniteElementGaussianType = domain::finite_element::FiniteElementGaussian<dim>;

  reporter_ptr_->Report("\tBuilding Finite Element: ");

  try {
    return_ptr = std::move(std::make_unique<FiniteElementGaussianType>(
        problem::DiscretizationType::kContinuousFEM,
        problem_parameters.FEPolynomialDegree()));

    reporter_ptr_->Report("Built: " + return_ptr->description() + "\n",
                          utility::reporter::Color::Green);
  } catch (...) {
    reporter_ptr_->Report("Error");
    throw;
  }
  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildFixedUpdater(
    std::unique_ptr<DiffusionFormulationType> formulation_ptr,
    std::unique_ptr<StamperType> stamper_ptr)
-> std::unique_ptr<FixedUpdaterType> {
  reporter_ptr_->Report("\tBuilding Diffusion Formulation updater\n");
  std::unique_ptr<FixedUpdaterType> return_ptr = nullptr;

  using ReturnType = formulation::updater::DiffusionUpdater<dim>;
  return_ptr = std::move(std::make_unique<ReturnType>(
      std::move(formulation_ptr),
      std::move(stamper_ptr)));

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildFixedUpdater(
    std::unique_ptr<SAAFFormulationType> formulation_ptr,
    std::unique_ptr<StamperType> stamper_ptr,
    const std::shared_ptr<QuadratureSetType>& quadrature_set_ptr)
-> std::unique_ptr<FixedUpdaterType> {
  reporter_ptr_->Report("\tBuilding SAAF Formulation updater\n");
  std::unique_ptr<FixedUpdaterType> return_ptr = nullptr;

  using ReturnType = formulation::updater::SAAFUpdater<dim>;
  return_ptr = std::move(std::make_unique<ReturnType>(
      std::move(formulation_ptr),
      std::move(stamper_ptr),
      quadrature_set_ptr));

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildInitializer(
    const std::shared_ptr<formulation::updater::FixedUpdaterI>& updater_ptr,
    const int total_groups,
    const int total_angles) -> std::unique_ptr<InitializerType> {
  reporter_ptr_->Report("\tBuilding Initializer\n");
  std::unique_ptr<InitializerType> return_ptr = nullptr;

  using InitializeOnceType = iteration::initializer::InitializeFixedTermsOnce;

  return_ptr = std::move(std::make_unique<InitializeOnceType>(
      updater_ptr, total_groups, total_angles));

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildMomentConvergenceChecker(
    double max_delta, int max_iterations)
-> std::unique_ptr<MomentConvergenceCheckerType>{
  //TODO(Josh): Add option for using other than L1Norm

  using CheckerType = convergence::moments::SingleMomentCheckerL1Norm;
  using FinalCheckerType = convergence::FinalCheckerOrN<
      system::moments::MomentVector,
      convergence::moments::SingleMomentCheckerI>;

  auto single_checker_ptr = std::make_unique<CheckerType>(max_delta);
  auto return_ptr = std::make_unique<FinalCheckerType>(
      std::move(single_checker_ptr));

  return_ptr->SetMaxIterations(max_iterations);

  return std::move(return_ptr);
}

template<int dim>
auto FrameworkBuilder<dim>::BuildParameterConvergenceChecker(
    double max_delta, int max_iterations)
-> std::unique_ptr<ParameterConvergenceCheckerType>{

  using CheckerType = convergence::parameters::SingleParameterChecker;
  using FinalCheckerType = convergence::FinalCheckerOrN<double, CheckerType>;

  auto single_checker_ptr = std::make_unique<CheckerType>(max_delta);
  auto return_ptr = std::make_unique<FinalCheckerType>(
      std::move(single_checker_ptr));

  return_ptr->SetMaxIterations(max_iterations);

  return std::move(return_ptr);
}

template<int dim>
auto FrameworkBuilder<dim>::BuildQuadratureSet(ParametersType problem_parameters)
-> std::shared_ptr<QuadratureSetType> {
  reporter_ptr_->Report("\tBuilding quadrature set\n");
  using QuadratureGeneratorType = quadrature::QuadratureGeneratorI<dim>;

  std::shared_ptr<QuadratureSetType> return_ptr = nullptr;
  std::shared_ptr<QuadratureGeneratorType > quadrature_generator_ptr = nullptr;

  const int order_value = problem_parameters.AngularQuadOrder();
  switch (problem_parameters.AngularQuad()) {
    default: {
      if (dim == 3) {
        quadrature_generator_ptr =
            quadrature::factory::MakeAngularQuadratureGeneratorPtr<dim>(
                quadrature::Order(order_value),
                quadrature::AngularQuadratureSetType::kLevelSymmetricGaussian);
      } else {
        AssertThrow(false,
                    dealii::ExcMessage("No supported quadratures for this dimension "
                                       "and transport model"))
      }
    }
  }

  return_ptr = quadrature::factory::MakeQuadratureSetPtr<dim>();

  auto quadrature_points = quadrature::utility::GenerateAllPositiveX<dim>(
      quadrature_generator_ptr->GenerateSet());

  quadrature::factory::FillQuadratureSet<dim>(return_ptr.get(),
                                              quadrature_points);

  return std::move(return_ptr);
}

template <int dim>
auto FrameworkBuilder<dim>::BuildSAAFFormulation(
    const std::shared_ptr<FiniteElementType>& finite_element_ptr,
    const std::shared_ptr<data::CrossSections>& cross_sections_ptr,
    const std::shared_ptr<QuadratureSetType>& quadrature_set_ptr,
    const formulation::SAAFFormulationImpl implementation)
-> std::unique_ptr<SAAFFormulationType> {
  reporter_ptr_->Report("\tBuilding SAAF Formulation\n");
  std::unique_ptr<SAAFFormulationType> return_ptr;

  if (implementation == formulation::SAAFFormulationImpl::kDefault) {
    using ReturnType = formulation::angular::SelfAdjointAngularFlux<dim>;

    return_ptr = std::move(std::make_unique<ReturnType>(finite_element_ptr,
                                                        cross_sections_ptr,
                                                        quadrature_set_ptr));
  }

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildSingleGroupSolver(
    const int max_iterations,
    const double convergence_tolerance)
-> std::unique_ptr<SingleGroupSolverType> {
  std::unique_ptr<SingleGroupSolverType> return_ptr = nullptr;

  auto linear_solver_ptr = std::make_unique<solver::GMRES>(max_iterations,
                                                           convergence_tolerance);

  return_ptr = std::move(std::make_unique<solver::group::SingleGroupSolver>(
          std::move(linear_solver_ptr)));

  return return_ptr;
}

template<int dim>
auto FrameworkBuilder<dim>::BuildStamper(
    const std::shared_ptr<DomainType>& domain_ptr)
-> std::unique_ptr<StamperType> {
  reporter_ptr_->Report("\tBuilding Stamper\n");
  std::unique_ptr<StamperType> return_ptr = nullptr;

  return_ptr = std::move(
      std::make_unique<formulation::Stamper<dim>>(domain_ptr));

  return return_ptr;
}
template<int dim>
std::string FrameworkBuilder<dim>::ReadMappingFile(std::string filename) {
  reporter_ptr_->Report("\tReading mapping file: ");

  std::ifstream mapping_file(filename);
  if (mapping_file.is_open()) {
    reporter_ptr_->Report(filename + '\n', Color::Green);

    return std::string(
        (std::istreambuf_iterator<char>(mapping_file)),
        std::istreambuf_iterator<char>());
  } else {
    reporter_ptr_->Report("Error reading " + filename + "\n", Color::Red);
    AssertThrow(false,
                dealii::ExcMessage("Failed to open material mapping file"))
  }
}

template class FrameworkBuilder<1>;
template class FrameworkBuilder<2>;
template class FrameworkBuilder<3>;

} // namespace builder

} // namespace framework

} // namespace bart
<|endoftext|>


<commit_before>/**
 * \file
 * \brief Main code block.
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * 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/.
 *
 * \date 2014-07-29
 */

#include "distortos/scheduler/ThreadControlBlock.hpp"
#include "distortos/scheduler/schedulerInstance.hpp"
#include "distortos/scheduler/Scheduler.hpp"

#include <random>

#include <cstdint>
#include <cmath>

namespace
{

/*---------------------------------------------------------------------------------------------------------------------+
| local functions
+---------------------------------------------------------------------------------------------------------------------*/

/**
 * \brief Test thread
 */

void * test1(void *)
{
	volatile uint32_t i = 0;
	volatile double d;
	std::default_random_engine generator;
	std::uniform_real_distribution<> distribution {0, M_PI};

	while (1)
	{
		++i;
		d = distribution(generator);
		d = sin(cos(d *  M_PI / 180.0) * M_PI / 180.0);
	}

	return nullptr;
}

/**
 * \brief Test thread
 */

void * test2(void *)
{
	volatile uint32_t i = 0;
	volatile double d;
	std::default_random_engine generator;
	std::uniform_real_distribution<> distribution {0, M_PI};

	while (1)
	{
		++i;
		d = distribution(generator);
		d = tan(1 / (tan(d *  M_PI / 180.0) * M_PI / 180.0));
	}

	return nullptr;
}

/**
 * \brief Test thread
 */

void * test3(void *)
{
	volatile uint32_t i = 0;
	volatile double d;
	std::default_random_engine generator;
	std::uniform_real_distribution<> distribution {0, M_PI};

	while (1)
	{
		++i;
		d = distribution(generator);
		d = log10(d * 11);
	}

	return nullptr;
}

/**
 * \brief Test thread
 */

void * test4(void *)
{
	volatile uint32_t i = 0;
	volatile double d;
	std::default_random_engine generator;
	std::uniform_real_distribution<> distribution {0, M_PI};

	while (1)
	{
		++i;
		d = distribution(generator);
		d = log2(d * 3);
	}

	return nullptr;
}

/*---------------------------------------------------------------------------------------------------------------------+
| local objects
+---------------------------------------------------------------------------------------------------------------------*/

/// stack for thread1
uint64_t stack1[128];

/// stack for thread2
uint64_t stack2[128];

/// stack for thread3
uint64_t stack3[128];

/// stack for thread4
uint64_t stack4[128];

/// TCB with thread1
distortos::scheduler::ThreadControlBlock tcb1 {stack1, sizeof(stack1), test1, nullptr};

/// TCB with thread2
distortos::scheduler::ThreadControlBlock tcb2 {stack2, sizeof(stack2), test2, nullptr};

/// TCB with thread3
distortos::scheduler::ThreadControlBlock tcb3 {stack3, sizeof(stack3), test3, nullptr};

/// TCB with thread4
distortos::scheduler::ThreadControlBlock tcb4 {stack4, sizeof(stack4), test4, nullptr};

}	// namespace

/*---------------------------------------------------------------------------------------------------------------------+
| global functions
+---------------------------------------------------------------------------------------------------------------------*/

/**
 * \brief main code block
 */

int main()
{
	distortos::scheduler::schedulerInstance.threadControlBlockList.emplace_back(tcb1);
	distortos::scheduler::schedulerInstance.threadControlBlockList.emplace_back(tcb2);
	distortos::scheduler::schedulerInstance.threadControlBlockList.emplace_back(tcb3);
	distortos::scheduler::schedulerInstance.threadControlBlockList.emplace_back(tcb4);

	distortos::scheduler::schedulerInstance.start();

	return 0;
}
<commit_msg>main: use Scheduler::add() instead of direct manipulations of the list<commit_after>/**
 * \file
 * \brief Main code block.
 *
 * \author Copyright (C) 2014 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * 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/.
 *
 * \date 2014-07-29
 */

#include "distortos/scheduler/ThreadControlBlock.hpp"
#include "distortos/scheduler/schedulerInstance.hpp"
#include "distortos/scheduler/Scheduler.hpp"

#include <random>

#include <cstdint>
#include <cmath>

namespace
{

/*---------------------------------------------------------------------------------------------------------------------+
| local functions
+---------------------------------------------------------------------------------------------------------------------*/

/**
 * \brief Test thread
 */

void * test1(void *)
{
	volatile uint32_t i = 0;
	volatile double d;
	std::default_random_engine generator;
	std::uniform_real_distribution<> distribution {0, M_PI};

	while (1)
	{
		++i;
		d = distribution(generator);
		d = sin(cos(d *  M_PI / 180.0) * M_PI / 180.0);
	}

	return nullptr;
}

/**
 * \brief Test thread
 */

void * test2(void *)
{
	volatile uint32_t i = 0;
	volatile double d;
	std::default_random_engine generator;
	std::uniform_real_distribution<> distribution {0, M_PI};

	while (1)
	{
		++i;
		d = distribution(generator);
		d = tan(1 / (tan(d *  M_PI / 180.0) * M_PI / 180.0));
	}

	return nullptr;
}

/**
 * \brief Test thread
 */

void * test3(void *)
{
	volatile uint32_t i = 0;
	volatile double d;
	std::default_random_engine generator;
	std::uniform_real_distribution<> distribution {0, M_PI};

	while (1)
	{
		++i;
		d = distribution(generator);
		d = log10(d * 11);
	}

	return nullptr;
}

/**
 * \brief Test thread
 */

void * test4(void *)
{
	volatile uint32_t i = 0;
	volatile double d;
	std::default_random_engine generator;
	std::uniform_real_distribution<> distribution {0, M_PI};

	while (1)
	{
		++i;
		d = distribution(generator);
		d = log2(d * 3);
	}

	return nullptr;
}

/*---------------------------------------------------------------------------------------------------------------------+
| local objects
+---------------------------------------------------------------------------------------------------------------------*/

/// stack for thread1
uint64_t stack1[128];

/// stack for thread2
uint64_t stack2[128];

/// stack for thread3
uint64_t stack3[128];

/// stack for thread4
uint64_t stack4[128];

/// TCB with thread1
distortos::scheduler::ThreadControlBlock tcb1 {stack1, sizeof(stack1), test1, nullptr};

/// TCB with thread2
distortos::scheduler::ThreadControlBlock tcb2 {stack2, sizeof(stack2), test2, nullptr};

/// TCB with thread3
distortos::scheduler::ThreadControlBlock tcb3 {stack3, sizeof(stack3), test3, nullptr};

/// TCB with thread4
distortos::scheduler::ThreadControlBlock tcb4 {stack4, sizeof(stack4), test4, nullptr};

}	// namespace

/*---------------------------------------------------------------------------------------------------------------------+
| global functions
+---------------------------------------------------------------------------------------------------------------------*/

/**
 * \brief main code block
 */

int main()
{
	distortos::scheduler::schedulerInstance.add(tcb1);
	distortos::scheduler::schedulerInstance.add(tcb2);
	distortos::scheduler::schedulerInstance.add(tcb3);
	distortos::scheduler::schedulerInstance.add(tcb4);

	distortos::scheduler::schedulerInstance.start();

	return 0;
}
<|endoftext|>