<commit_before>// Copyright 2020 Global Phasing Ltd.
//
// merge multi-record (unmerged) data - I and sigma(I)

#include <cmath>              // for sqrt
#include <cstdio>
#include <algorithm>          // for sort
#include <iostream>
#include <tuple>              // for tie
#ifndef GEMMI_ALL_IN_ONE
# define GEMMI_WRITE_IMPLEMENTATION 1
#endif
#include <gemmi/gz.hpp>       // for MaybeGzipped
#include <gemmi/gzread.hpp>
#include <gemmi/mtz2cif.hpp>  // for MtzToCif
#include <gemmi/ofstream.hpp> // for Ofstream
#include <gemmi/refln.hpp>
#define GEMMI_PROG merge
#include "options.h"

enum OptionIndex { BlockName=4, Compare };

static const option::Descriptor Usage[] = {
  { NoOp, 0, "", "", Arg::None,
    "Usage:\n  " EXE_NAME " [options] INPUT_FILE OUTPUT_FILE"
    "\n  " EXE_NAME " --compare [options] UNMERGED_FILE MERGED_FILE"
    "\nOptions:"},
  CommonUsage[Help],
  CommonUsage[Version],
  CommonUsage[Verbose],
  { BlockName, 0, "b", "block", Arg::Required,
    "  -b NAME, --block=NAME  \toutput mmCIF block name: data_NAME (default: merged)." },
  { Compare, 0, "", "compare", Arg::None, "" },
  { NoOp, 0, "", "", Arg::None,
    "The input file can be either SF-mmCIF with _diffrn_refln or MTZ.\n"
    "The output file can be either SF-mmCIF or MTZ."
  },
  { 0, 0, 0, 0, 0, 0 }
};

struct Intensity {
  gemmi::Miller hkl;
  bool plus;  // I(+) if true, I(-) otherwise
  double value;
  double sigma;

  bool operator<(const Intensity& o) {
    return std::tie(hkl[0], hkl[1], hkl[2]) < std::tie(o.hkl[0], o.hkl[1], o.hkl[2]);
  }
};

struct Intensities {
  std::vector<Intensity> data;
  const gemmi::SpaceGroup* spacegroup = nullptr;
  gemmi::UnitCell unit_cell;
  double wavelength;

  template<typename DataProxy>
  void read(const DataProxy& proxy, size_t value_idx, size_t sigma_idx) {
    unit_cell = proxy.unit_cell();
    spacegroup = proxy.spacegroup();
    for (size_t i = 0; i < proxy.size(); i += proxy.stride()) {
      Intensity intensity;
      intensity.hkl = proxy.get_hkl(i);
      intensity.value = proxy.get_num(i + value_idx);
      intensity.sigma = proxy.get_num(i + sigma_idx);
      // XDS marks rejected reflections with negative sigma
      if (!std::isnan(intensity.value) && intensity.sigma >= 0)
        data.push_back(intensity);
    }
  }

  std::string spacegroup_str() const { return spacegroup ? spacegroup->xhm() : "none"; }

  void remove_systematic_absences() {
    if (!spacegroup)
      return;
    gemmi::GroupOps gops = spacegroup->operations();
    gemmi::vector_remove_if(data, [&](Intensity& x) {
        return gops.is_systematically_absent(x.hkl);
    });
  }

  void sort() { std::sort(data.begin(), data.end()); }
};

[[noreturn]]
inline void exit_message(const char* msg, const char* path=nullptr) {
  if (path)
    std::fprintf(stderr, "%s: %s\n", msg, path);
  else
    std::fprintf(stderr, "%s\n", msg);
  std::exit(1);
}

static
Intensities read_intensities(bool merged, const char* input_path,
                             const char* block_name, bool verbose) {
  Intensities intensities;
  try {
    if (gemmi::giends_with(input_path, ".mtz")) {
      gemmi::Mtz mtz;
      if (verbose)
        mtz.warnings = stderr;
      mtz.read_input(gemmi::MaybeGzipped(input_path), /*with_data=*/true);
      if (merged && !mtz.batches.empty())
        exit_message("The second file should be merged.");
      if (!merged && mtz.batches.empty() && !mtz.column_with_label("M/ISYM"))
        exit_message("The input mtz file should be unmerged.");
      const std::string value_label = merged ? "IMEAN" : "I";
      const std::string sigma_label = "SIG" + value_label;
      const gemmi::Mtz::Column& col = mtz.get_column_with_label(value_label);
      size_t sigma_idx = mtz.get_column_with_label(sigma_label).idx;
      size_t value_idx = col.idx;
      intensities.wavelength = mtz.dataset(col.dataset_id).wavelength;
      intensities.read(gemmi::MtzDataProxy{mtz}, value_idx, sigma_idx);
    } else {
      auto rblocks = gemmi::as_refln_blocks(gemmi::read_cif_gz(input_path).blocks);
      const std::string value_label = merged ? "intensity_meas" : "intensity_net";
      const std::string sigma_label = "intensity_sigma";
      for (gemmi::ReflnBlock& rb : rblocks) {
        if (block_name && rb.block.name != block_name)
          continue;
        rb.use_unmerged(!merged);
        if (rb.default_loop) {
          size_t value_idx = rb.get_column_index(value_label);
          size_t sigma_idx = rb.get_column_index(sigma_label);
          if (verbose)
            std::fprintf(stderr, "Taking data from %s ...\n", rb.block.name.c_str());
          intensities.wavelength = rb.wavelength;
          intensities.read(gemmi::ReflnDataProxy(rb), value_idx, sigma_idx);
          if (!intensities.spacegroup)
            exit_message("Unknown space group", input_path);
          if (!merged) {
            gemmi::GroupOps gops = intensities.spacegroup->operations();
            gemmi::ReciprocalAsu asu(intensities.spacegroup);
            for (Intensity& intensity : intensities.data)
              intensity.hkl = asu.to_asu(intensity.hkl, gops);
          }
          break;
        }
      }
      if (intensities.data.empty())
        exit_message("Unmerged data not found in", input_path);
    }
  } catch (std::runtime_error& e) {
    std::fprintf(stderr, "ERROR while reading %s: %s\n", input_path, e.what());
    std::exit(1);
  }
  return intensities;
}

static
void merge_intensities_in_place(Intensities& intensities) {
  intensities.sort();
  std::vector<Intensity>::iterator out = intensities.data.begin();
  double sum_wI = 0.;
  double sum_w = 0.;
  for (auto in = intensities.data.begin(); in != intensities.data.end(); ++in) {
    if (out->hkl != in->hkl) {
      out->value = sum_wI / sum_w;
      out->sigma = 1.0 / std::sqrt(sum_w);
      sum_wI = sum_w = 0.;
      ++out;
      if (out != in)
        out->hkl = in->hkl;
    }
    double w = 1. / (in->sigma * in->sigma);
    sum_wI += w * in->value;
    sum_w += w;
  }
  out->value = sum_wI / sum_w;
  out->sigma = 1.0 / std::sqrt(sum_w);
  intensities.data.erase(++out, intensities.data.end());
}

static
void write_merged_intensities(const Intensities& intensities, const char* output_path) {
  gemmi::Mtz mtz;
  mtz.cell = intensities.unit_cell;
  mtz.spacegroup = intensities.spacegroup;
  mtz.add_dataset("HKL_base");
  mtz.add_column("H", 'H');
  mtz.add_column("K", 'H');
  mtz.add_column("L", 'H');
  mtz.add_dataset("unknown").wavelength = intensities.wavelength;
  mtz.add_column("IMEAN", 'J');
  mtz.add_column("SIGIMEAN", 'Q');
  mtz.nreflections = (int) intensities.data.size();
  mtz.data.resize(intensities.data.size() * mtz.columns.size());
  for (size_t i = 0; i != intensities.data.size(); ++i) {
    size_t offset = i * mtz.columns.size();
    mtz.set_hkl(offset, intensities.data[i].hkl);
    mtz.data[offset + 3] = (float) intensities.data[i].value;
    mtz.data[offset + 4] = (float) intensities.data[i].sigma;
  }
  try {
    if (gemmi::giends_with(output_path, ".mtz")) {
      mtz.write_to_file(output_path);
    } else {
      gemmi::MtzToCif mtz_to_cif;
      mtz_to_cif.with_comments = false;
      mtz_to_cif.block_name = "merged";
      gemmi::Ofstream os(output_path, /*dash=*/&std::cout);
      mtz_to_cif.write_cif(mtz, os.ref());
    }
  } catch (std::runtime_error& e) {
    std::fprintf(stderr, "ERROR while writing %s: %s\n", output_path, e.what());
    std::exit(1);
  }
}

static
void compare_intensities(Intensities& intensities, Intensities& ref) {
  if (intensities.spacegroup == ref.spacegroup)
    printf("Space group: %s\n", intensities.spacegroup_str().c_str());
  else
    printf("Space groups: %s   %s\n", intensities.spacegroup_str().c_str(),
           ref.spacegroup_str().c_str());
  printf("Reflections: %zu  %zu\n", intensities.data.size(), ref.data.size());
  intensities.remove_systematic_absences();
  ref.remove_systematic_absences();
  printf("Excluding sys. absences: %zu  %zu\n",
         intensities.data.size(), ref.data.size());
  const gemmi::UnitCell& cell = intensities.unit_cell;
  ref.sort();
  auto a = intensities.data.begin();
  gemmi::Correlation vc, sc;
  for (const Intensity& r : ref.data) {
    if (r.hkl != a->hkl) {
      while (*a < r && ++a != intensities.data.end()) {
      }
      if (a == intensities.data.end())
        break;
      if (r.hkl != a->hkl)
        continue;
    }
    vc.add_point(r.value, a->value);
    sc.add_point(r.sigma, a->sigma);
    ++a;
    if (a == intensities.data.end())
      break;
  }
  printf("Common reflections: %d\n", vc.n);
  double min_a_1_d2 = INFINITY;
  double max_a_1_d2 = 0;
  double min_r_1_d2 = INFINITY;
  double max_r_1_d2 = 0;
  for (const Intensity& x : intensities.data) {
    double a_1_d2 = cell.calculate_1_d2(x.hkl);
    if (a_1_d2 < min_a_1_d2)
      min_a_1_d2 = a_1_d2;
    if (a_1_d2 > max_a_1_d2)
      max_a_1_d2 = a_1_d2;
  }
  for (const Intensity& x : ref.data) {
    double r_1_d2 = cell.calculate_1_d2(x.hkl);
    if (r_1_d2 < min_r_1_d2)
      min_r_1_d2 = r_1_d2;
    if (r_1_d2 > max_r_1_d2)
      max_r_1_d2 = r_1_d2;
  }
  printf("Resolution: %g-%g    %g-%g\n",
         1/std::sqrt(min_a_1_d2), 1/std::sqrt(max_a_1_d2),
         1/std::sqrt(min_r_1_d2), 1/std::sqrt(max_r_1_d2));
  printf("Value CC: %.9g%% (slope: %g)\n", 100 * vc.coefficient(), vc.slope());
  printf("Sigma CC: %.9g%% (slope: %g)\n", 100 * sc.coefficient(), sc.slope());
}

int GEMMI_MAIN(int argc, char **argv) {
  OptParser p(EXE_NAME);
  p.simple_parse(argc, argv, Usage);
  p.require_positional_args(2);
  bool verbose = p.options[Verbose];
  const char* input_path = p.nonOption(0);
  const char* output_path = p.nonOption(1);
  if (verbose)
    std::fprintf(stderr, "Reading %s ...\n", input_path);
  const char* block_name = nullptr;
  if (p.options[BlockName])
    block_name = p.options[BlockName].arg;
  Intensities intensities = read_intensities(false, input_path, block_name, verbose);
  if (verbose)
    std::fprintf(stderr, "Merging observations (%zu total) ...\n", intensities.data.size());
  merge_intensities_in_place(intensities);
  if (p.options[Compare]) {
    if (verbose)
      std::fprintf(stderr, "Reading merged reflections from %s ...\n", output_path);
    Intensities ref = read_intensities(true, input_path, nullptr, verbose);
    compare_intensities(intensities, ref);
  } else {
    if (verbose)
      std::fprintf(stderr, "Writing %zu reflections to %s ...\n",
                   intensities.data.size(), output_path);
    write_merged_intensities(intensities, output_path);
  }
  return 0;
}

// vim:sw=2:ts=2:et:path^=../include,../third_party
<commit_msg>fix build<commit_after>// Copyright 2020 Global Phasing Ltd.
//
// merge multi-record (unmerged) data - I and sigma(I)

#include <cmath>              // for sqrt
#include <cstdio>
#include <algorithm>          // for sort
#include <iostream>
#include <tuple>              // for tie
#ifndef GEMMI_ALL_IN_ONE
# define GEMMI_WRITE_IMPLEMENTATION 1
#endif
#include <gemmi/gz.hpp>       // for MaybeGzipped
#include <gemmi/gzread.hpp>
#include <gemmi/mtz2cif.hpp>  // for MtzToCif
#include <gemmi/ofstream.hpp> // for Ofstream
#include <gemmi/refln.hpp>
#define GEMMI_PROG merge
#include "options.h"

enum OptionIndex { BlockName=4, Compare };

static const option::Descriptor Usage[] = {
  { NoOp, 0, "", "", Arg::None,
    "Usage:\n  " EXE_NAME " [options] INPUT_FILE OUTPUT_FILE"
    "\n  " EXE_NAME " --compare [options] UNMERGED_FILE MERGED_FILE"
    "\nOptions:"},
  CommonUsage[Help],
  CommonUsage[Version],
  CommonUsage[Verbose],
  { BlockName, 0, "b", "block", Arg::Required,
    "  -b NAME, --block=NAME  \toutput mmCIF block name: data_NAME (default: merged)." },
  { Compare, 0, "", "compare", Arg::None, "" },
  { NoOp, 0, "", "", Arg::None,
    "The input file can be either SF-mmCIF with _diffrn_refln or MTZ.\n"
    "The output file can be either SF-mmCIF or MTZ."
  },
  { 0, 0, 0, 0, 0, 0 }
};

struct Intensity {
  gemmi::Miller hkl;
  bool plus;  // I(+) if true, I(-) otherwise
  double value;
  double sigma;

  bool operator<(const Intensity& o) const {
    return std::tie(hkl[0], hkl[1], hkl[2]) < std::tie(o.hkl[0], o.hkl[1], o.hkl[2]);
  }
};

struct Intensities {
  std::vector<Intensity> data;
  const gemmi::SpaceGroup* spacegroup = nullptr;
  gemmi::UnitCell unit_cell;
  double wavelength;

  template<typename DataProxy>
  void read(const DataProxy& proxy, size_t value_idx, size_t sigma_idx) {
    unit_cell = proxy.unit_cell();
    spacegroup = proxy.spacegroup();
    for (size_t i = 0; i < proxy.size(); i += proxy.stride()) {
      Intensity intensity;
      intensity.hkl = proxy.get_hkl(i);
      intensity.value = proxy.get_num(i + value_idx);
      intensity.sigma = proxy.get_num(i + sigma_idx);
      // XDS marks rejected reflections with negative sigma
      if (!std::isnan(intensity.value) && intensity.sigma >= 0)
        data.push_back(intensity);
    }
  }

  std::string spacegroup_str() const { return spacegroup ? spacegroup->xhm() : "none"; }

  void remove_systematic_absences() {
    if (!spacegroup)
      return;
    gemmi::GroupOps gops = spacegroup->operations();
    gemmi::vector_remove_if(data, [&](Intensity& x) {
        return gops.is_systematically_absent(x.hkl);
    });
  }

  void sort() { std::sort(data.begin(), data.end()); }
};

[[noreturn]]
inline void exit_message(const char* msg, const char* path=nullptr) {
  if (path)
    std::fprintf(stderr, "%s: %s\n", msg, path);
  else
    std::fprintf(stderr, "%s\n", msg);
  std::exit(1);
}

static
Intensities read_intensities(bool merged, const char* input_path,
                             const char* block_name, bool verbose) {
  Intensities intensities;
  try {
    if (gemmi::giends_with(input_path, ".mtz")) {
      gemmi::Mtz mtz;
      if (verbose)
        mtz.warnings = stderr;
      mtz.read_input(gemmi::MaybeGzipped(input_path), /*with_data=*/true);
      if (merged && !mtz.batches.empty())
        exit_message("The second file should be merged.");
      if (!merged && mtz.batches.empty() && !mtz.column_with_label("M/ISYM"))
        exit_message("The input mtz file should be unmerged.");
      const std::string value_label = merged ? "IMEAN" : "I";
      const std::string sigma_label = "SIG" + value_label;
      const gemmi::Mtz::Column& col = mtz.get_column_with_label(value_label);
      size_t sigma_idx = mtz.get_column_with_label(sigma_label).idx;
      size_t value_idx = col.idx;
      intensities.wavelength = mtz.dataset(col.dataset_id).wavelength;
      intensities.read(gemmi::MtzDataProxy{mtz}, value_idx, sigma_idx);
    } else {
      auto rblocks = gemmi::as_refln_blocks(gemmi::read_cif_gz(input_path).blocks);
      const std::string value_label = merged ? "intensity_meas" : "intensity_net";
      const std::string sigma_label = "intensity_sigma";
      for (gemmi::ReflnBlock& rb : rblocks) {
        if (block_name && rb.block.name != block_name)
          continue;
        rb.use_unmerged(!merged);
        if (rb.default_loop) {
          size_t value_idx = rb.get_column_index(value_label);
          size_t sigma_idx = rb.get_column_index(sigma_label);
          if (verbose)
            std::fprintf(stderr, "Taking data from %s ...\n", rb.block.name.c_str());
          intensities.wavelength = rb.wavelength;
          intensities.read(gemmi::ReflnDataProxy(rb), value_idx, sigma_idx);
          if (!intensities.spacegroup)
            exit_message("Unknown space group", input_path);
          if (!merged) {
            gemmi::GroupOps gops = intensities.spacegroup->operations();
            gemmi::ReciprocalAsu asu(intensities.spacegroup);
            for (Intensity& intensity : intensities.data)
              intensity.hkl = asu.to_asu(intensity.hkl, gops);
          }
          break;
        }
      }
      if (intensities.data.empty())
        exit_message("Unmerged data not found in", input_path);
    }
  } catch (std::runtime_error& e) {
    std::fprintf(stderr, "ERROR while reading %s: %s\n", input_path, e.what());
    std::exit(1);
  }
  return intensities;
}

static
void merge_intensities_in_place(Intensities& intensities) {
  intensities.sort();
  std::vector<Intensity>::iterator out = intensities.data.begin();
  double sum_wI = 0.;
  double sum_w = 0.;
  for (auto in = intensities.data.begin(); in != intensities.data.end(); ++in) {
    if (out->hkl != in->hkl) {
      out->value = sum_wI / sum_w;
      out->sigma = 1.0 / std::sqrt(sum_w);
      sum_wI = sum_w = 0.;
      ++out;
      if (out != in)
        out->hkl = in->hkl;
    }
    double w = 1. / (in->sigma * in->sigma);
    sum_wI += w * in->value;
    sum_w += w;
  }
  out->value = sum_wI / sum_w;
  out->sigma = 1.0 / std::sqrt(sum_w);
  intensities.data.erase(++out, intensities.data.end());
}

static
void write_merged_intensities(const Intensities& intensities, const char* output_path) {
  gemmi::Mtz mtz;
  mtz.cell = intensities.unit_cell;
  mtz.spacegroup = intensities.spacegroup;
  mtz.add_dataset("HKL_base");
  mtz.add_column("H", 'H');
  mtz.add_column("K", 'H');
  mtz.add_column("L", 'H');
  mtz.add_dataset("unknown").wavelength = intensities.wavelength;
  mtz.add_column("IMEAN", 'J');
  mtz.add_column("SIGIMEAN", 'Q');
  mtz.nreflections = (int) intensities.data.size();
  mtz.data.resize(intensities.data.size() * mtz.columns.size());
  for (size_t i = 0; i != intensities.data.size(); ++i) {
    size_t offset = i * mtz.columns.size();
    mtz.set_hkl(offset, intensities.data[i].hkl);
    mtz.data[offset + 3] = (float) intensities.data[i].value;
    mtz.data[offset + 4] = (float) intensities.data[i].sigma;
  }
  try {
    if (gemmi::giends_with(output_path, ".mtz")) {
      mtz.write_to_file(output_path);
    } else {
      gemmi::MtzToCif mtz_to_cif;
      mtz_to_cif.with_comments = false;
      mtz_to_cif.block_name = "merged";
      gemmi::Ofstream os(output_path, /*dash=*/&std::cout);
      mtz_to_cif.write_cif(mtz, os.ref());
    }
  } catch (std::runtime_error& e) {
    std::fprintf(stderr, "ERROR while writing %s: %s\n", output_path, e.what());
    std::exit(1);
  }
}

static
void compare_intensities(Intensities& intensities, Intensities& ref) {
  if (intensities.spacegroup == ref.spacegroup)
    printf("Space group: %s\n", intensities.spacegroup_str().c_str());
  else
    printf("Space groups: %s   %s\n", intensities.spacegroup_str().c_str(),
           ref.spacegroup_str().c_str());
  printf("Reflections: %zu  %zu\n", intensities.data.size(), ref.data.size());
  intensities.remove_systematic_absences();
  ref.remove_systematic_absences();
  printf("Excluding sys. absences: %zu  %zu\n",
         intensities.data.size(), ref.data.size());
  const gemmi::UnitCell& cell = intensities.unit_cell;
  ref.sort();
  auto a = intensities.data.begin();
  gemmi::Correlation vc, sc;
  for (const Intensity& r : ref.data) {
    if (r.hkl != a->hkl) {
      while (*a < r && ++a != intensities.data.end()) {
      }
      if (a == intensities.data.end())
        break;
      if (r.hkl != a->hkl)
        continue;
    }
    vc.add_point(r.value, a->value);
    sc.add_point(r.sigma, a->sigma);
    ++a;
    if (a == intensities.data.end())
      break;
  }
  printf("Common reflections: %d\n", vc.n);
  double min_a_1_d2 = INFINITY;
  double max_a_1_d2 = 0;
  double min_r_1_d2 = INFINITY;
  double max_r_1_d2 = 0;
  for (const Intensity& x : intensities.data) {
    double a_1_d2 = cell.calculate_1_d2(x.hkl);
    if (a_1_d2 < min_a_1_d2)
      min_a_1_d2 = a_1_d2;
    if (a_1_d2 > max_a_1_d2)
      max_a_1_d2 = a_1_d2;
  }
  for (const Intensity& x : ref.data) {
    double r_1_d2 = cell.calculate_1_d2(x.hkl);
    if (r_1_d2 < min_r_1_d2)
      min_r_1_d2 = r_1_d2;
    if (r_1_d2 > max_r_1_d2)
      max_r_1_d2 = r_1_d2;
  }
  printf("Resolution: %g-%g    %g-%g\n",
         1/std::sqrt(min_a_1_d2), 1/std::sqrt(max_a_1_d2),
         1/std::sqrt(min_r_1_d2), 1/std::sqrt(max_r_1_d2));
  printf("Value CC: %.9g%% (slope: %g)\n", 100 * vc.coefficient(), vc.slope());
  printf("Sigma CC: %.9g%% (slope: %g)\n", 100 * sc.coefficient(), sc.slope());
}

int GEMMI_MAIN(int argc, char **argv) {
  OptParser p(EXE_NAME);
  p.simple_parse(argc, argv, Usage);
  p.require_positional_args(2);
  bool verbose = p.options[Verbose];
  const char* input_path = p.nonOption(0);
  const char* output_path = p.nonOption(1);
  if (verbose)
    std::fprintf(stderr, "Reading %s ...\n", input_path);
  const char* block_name = nullptr;
  if (p.options[BlockName])
    block_name = p.options[BlockName].arg;
  Intensities intensities = read_intensities(false, input_path, block_name, verbose);
  if (verbose)
    std::fprintf(stderr, "Merging observations (%zu total) ...\n", intensities.data.size());
  merge_intensities_in_place(intensities);
  if (p.options[Compare]) {
    if (verbose)
      std::fprintf(stderr, "Reading merged reflections from %s ...\n", output_path);
    Intensities ref = read_intensities(true, input_path, nullptr, verbose);
    compare_intensities(intensities, ref);
  } else {
    if (verbose)
      std::fprintf(stderr, "Writing %zu reflections to %s ...\n",
                   intensities.data.size(), output_path);
    write_merged_intensities(intensities, output_path);
  }
  return 0;
}

// vim:sw=2:ts=2:et:path^=../include,../third_party
<|endoftext|>


<commit_before>//============================================================================
// Name        : idli.cpp
// Author      : srini
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
using namespace std;
#include <idli.h>
int main(int argc, const char** argv ) {
	database data;
	itemInfo item ;
	unsigned int choice, rfout,temp_weight;
	string s;
	cout<<"Enter \n1 to add new item\n2 to remove item\n3 to return the item\n4 to display contents recorded\n0 to exit"<<endl;

	do
	{
		cin>>choice;
		switch(choice)
		{
		case 0:
			break;
		case 1:
			cout<<"Enter details:"<<endl;
			item.getbarcode();
			item.getrfid();
			item.getweight();
			data.add(item);
			break;
		case 2:
			cout<<"which Grocery do u want to take out"<<endl;
			cin>>rfout;
			data.find(rfout);
			break;

		case 3:
			cout<<"which Grocery do u want to put in"<<endl;
			cin>>rfout;
			cout<<"what is the weight now"<<endl;
			cin>>temp_weight;
			data.update(rfout,temp_weight);
			break;
		case 4:
			for (data.it=data.mymap.begin(); data.it!=data.mymap.end(); ++data.it)
				data.it->second.display();
			break;

		default:
			cout<<"Invalid choice !"<< endl;
			cout<<"Enter \n1 to add new item\n2 to remove item\n3 to return the item\n4 to display contents recorded\n0 to exit"<<endl;
		}
	}while(choice);
cout << "program terminated" << endl;
	return 0;
}
<commit_msg>Update idli.cpp<commit_after>//============================================================================
// Name        : idli.cpp
// Author      : srini
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
using namespace std;
#include <idli.h>
int main(int argc, const char** argv ) {
	database data;
	itemInfo item ;
	unsigned int choice, rfout,temp_weight;
	string s;
	cout<<"Enter \n1 to add new item\n2 to remove item\n3 to return the item\n4 to display contents recorded\n0 to exit"<<endl;

	do
	{
		cin>>choice;
		switch(choice)
		{
		case 0:
			break;
		case 1:
			cout<<"Enter details:"<<endl;
			item.getbarcode();
			item.getrfid();
			item.getweight();
			data.add(item);
			break;
		case 2:
			cout<<"which Grocery do u want to take out"<<endl;
			cin>>rfout;
			data.find(rfout);
			break;

		case 3:
			cout<<"which Grocery do u want to put in"<<endl;
			cin>>rfout;
			cout<<"what is the weight now"<<endl;
			cin>>temp_weight;
			data.update(rfout,temp_weight);
			break;
		case 4:
				map<string, itemInfo> :: iterator it;
			for (it=data.mymap.begin(); it!=data.mymap.end(); ++it)
				it->second.display();
			break;

		default:
			cout<<"Invalid choice !"<< endl;
			cout<<"Enter \n1 to add new item\n2 to remove item\n3 to return the item\n4 to display contents recorded\n0 to exit"<<endl;
		}
	}while(choice);
cout << "program terminated" << endl;
	return 0;
}
<|endoftext|>


<commit_before>#include "HybridAutomaton.h"
//#include "MilestoneFactory.h"

#include "CSpaceMilestone.h"
#include "OpSpaceMilestone.h"

#include <Windows.h>

#include <ctime>
#include <iostream>

HybridAutomaton::HybridAutomaton() :
MDP(),
start_node_id_(NULL)
{
}

HybridAutomaton::~HybridAutomaton()
{
}

Milestone* HybridAutomaton::getStartNode() const
{
	return start_node_id_;
}

void HybridAutomaton::setStartNode(Milestone* nodeID)
{
	start_node_id_ = nodeID;
}

Milestone* HybridAutomaton::getMilestoneByName(const std::string& name) const
{
	for(unsigned int i=0; i<this->nodeList.size(); i++)
	{
        Milestone* ms=(Milestone*)nodeList[i];
		if(ms->getName() == name)
		{
			return ms;
		}
	}
	return NULL;
}

MotionBehaviour* HybridAutomaton::getNextMotionBehaviour(const Milestone* currentMs, LocalDecisionCriterion* criterion)
{
	std::vector<MDPEdge*> edges = getSortedOutgoingEdges(currentMs);
	if(edges.size() > 0 )
	{
		if(!criterion)
		{
			return (MotionBehaviour*)(edges[0]);
		}
		else
		{
			for(int i = 0; i < edges.size(); i++)
			{
				if(criterion->isConnected(currentMs, (Milestone*)edges[i]->getChild()))
				{
					return (MotionBehaviour*)(edges[i]);
				}
			}
		}
	}
	return NULL;
}

std::string HybridAutomaton::toStringXML() const
{
	// If the HybridAutomaton is empty, return the corresponding string
	if(nodeNumber==0 && edgeNumber==0)
		return std::string("Empty HybridAutomaton");

	// Create the base document
	TiXmlDocument document;
	// Add the declaration
	TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
	// Create the first (and only) root element and link it to the base document
	TiXmlElement * hyb = new TiXmlElement("HybridAutomaton");
	document.LinkEndChild(hyb);

	// Every new no-empty HybridAutomaton gets a new name
	static int name_counter = 0;
	std::string name_str;
	std::stringstream name_ss;
	name_ss << name_counter;
	name_str = name_ss.str();
	std::string name_complete = std::string("HS") + name_str;
	name_counter++;

	hyb->SetAttribute("Name", name_complete.c_str());

	if(start_node_id_ < 0)
		throw std::string("[HybridAutomaton::toStringXML] ERROR: Start node is non-valid.");

	hyb->SetAttribute("InitialMilestone", start_node_id_->getName().c_str());

	// Add the data of the nodes-milestones
	for(unsigned int i = 0; i<nodeNumber ; i++){
        Milestone* ms=(Milestone*)nodeList.at(i);
		if(ms!=NULL){
			TiXmlElement * mst_element = ms->toElementXML();
			hyb->LinkEndChild(mst_element);
		}
	}

	// Add the data of the edges-motionbehaviours
	for(unsigned int i = 0; i<nodeNumber ; i++){
		for(unsigned int j = 0; j<nodeNumber ; j++){
            MotionBehaviour* mb=(MotionBehaviour*)adjacencyMatrix.at(i).at(j);
			if( mb != NULL){
				TiXmlElement * mb_element = mb->toElementXML();
				hyb->LinkEndChild(mb_element);
			}
		}
	}

	// Declare a printer
	TiXmlPrinter printer;
	// Attach it to the document you want to convert in to a std::string
	document.Accept(&printer);
	// Create a std::string and copy your document data in to the string
	std::string ret_val = printer.CStr();

	//TODO: Memory leaks?
	return ret_val;
}

ostream& operator<<(ostream & out, const HybridAutomaton & hybrid_system){
	out << hybrid_system.toStringXML();
	return out;
}<commit_msg>public node access method for graph<commit_after>#include "HybridAutomaton.h"
//#include "MilestoneFactory.h"

#include "CSpaceMilestone.h"
#include "OpSpaceMilestone.h"

#include <Windows.h>

#include <ctime>
#include <iostream>

HybridAutomaton::HybridAutomaton() :
MDP(),
start_node_id_(NULL)
{
}

HybridAutomaton::~HybridAutomaton()
{
}

Milestone* HybridAutomaton::getStartNode() const
{
	return start_node_id_;
}

void HybridAutomaton::setStartNode(Milestone* nodeID)
{
	start_node_id_ = nodeID;
}

Milestone* HybridAutomaton::getMilestoneByName(const std::string& name) const
{
	for(unsigned int i=0; i<this->nodeList.size(); i++)
	{
        Milestone* ms=(Milestone*)nodeList[i];
		if(ms->getName() == name)
		{
			return ms;
		}
	}
	return NULL;
}

MotionBehaviour* HybridAutomaton::getNextMotionBehaviour(const Milestone* currentMs, LocalDecisionCriterion* criterion)
{
	std::vector<const MDPEdge*> edges = getSortedOutgoingEdges(currentMs);
	if(edges.size() > 0 )
	{
		if(!criterion)
		{
			return (MotionBehaviour*)(edges[0]);
		}
		else
		{
			for(unsigned int i = 0; i < edges.size(); i++)
			{
				if(criterion->isConnected(currentMs, (Milestone*)edges[i]->getChild()))
				{
					return (MotionBehaviour*)(edges[i]);
				}
			}
		}
	}
	return NULL;
}

std::string HybridAutomaton::toStringXML() const
{
	// If the HybridAutomaton is empty, return the corresponding string
	if(nodeNumber==0 && edgeNumber==0)
		return std::string("Empty HybridAutomaton");

	// Create the base document
	TiXmlDocument document;
	// Add the declaration
	TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" );
	// Create the first (and only) root element and link it to the base document
	TiXmlElement * hyb = new TiXmlElement("HybridAutomaton");
	document.LinkEndChild(hyb);

	// Every new no-empty HybridAutomaton gets a new name
	static int name_counter = 0;
	std::string name_str;
	std::stringstream name_ss;
	name_ss << name_counter;
	name_str = name_ss.str();
	std::string name_complete = std::string("HS") + name_str;
	name_counter++;

	hyb->SetAttribute("Name", name_complete.c_str());

	if(start_node_id_ < 0)
		throw std::string("[HybridAutomaton::toStringXML] ERROR: Start node is non-valid.");

	hyb->SetAttribute("InitialMilestone", start_node_id_->getName().c_str());

	// Add the data of the nodes-milestones
	for(unsigned int i = 0; i<nodeNumber ; i++){
        Milestone* ms=(Milestone*)nodeList.at(i);
		if(ms!=NULL){
			TiXmlElement * mst_element = ms->toElementXML();
			hyb->LinkEndChild(mst_element);
		}
	}

	// Add the data of the edges-motionbehaviours
	for(unsigned int i = 0; i<nodeNumber ; i++){
		for(unsigned int j = 0; j<nodeNumber ; j++){
            MotionBehaviour* mb=(MotionBehaviour*)adjacencyMatrix.at(i).at(j);
			if( mb != NULL){
				TiXmlElement * mb_element = mb->toElementXML();
				hyb->LinkEndChild(mb_element);
			}
		}
	}

	// Declare a printer
	TiXmlPrinter printer;
	// Attach it to the document you want to convert in to a std::string
	document.Accept(&printer);
	// Create a std::string and copy your document data in to the string
	std::string ret_val = printer.CStr();

	//TODO: Memory leaks?
	return ret_val;
}

ostream& operator<<(ostream & out, const HybridAutomaton & hybrid_system){
	out << hybrid_system.toStringXML();
	return out;
}<|endoftext|>


<commit_before>/*
 * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
 * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
 */

#include "bx_p.h"
#include <bx/mutex.h>

#if BX_CONFIG_SUPPORTS_THREADING

#if BX_CRT_NONE
#elif  BX_PLATFORM_ANDROID \
	|| BX_PLATFORM_LINUX   \
	|| BX_PLATFORM_IOS     \
	|| BX_PLATFORM_OSX     \
	|| BX_PLATFORM_PS4     \
	|| BX_PLATFORM_RPI
#	include <pthread.h>
#elif  BX_PLATFORM_WINDOWS \
	|| BX_PLATFORM_WINRT   \
	|| BX_PLATFORM_XBOXONE
#	include <windows.h>
#	include <errno.h>
#endif // BX_PLATFORM_

namespace bx
{
#if BX_CRT_NONE
	Mutex::Mutex()
	{
		BX_STATIC_ASSERT(sizeof(pthread_mutex_t) <= sizeof(m_internal) );
	}

	Mutex::~Mutex()
	{
	}

	void Mutex::lock()
	{
	}

	void Mutex::unlock()
	{
	}

#else

#	if BX_PLATFORM_WINDOWS \
	|| BX_PLATFORM_XBOXONE \
	|| BX_PLATFORM_WINRT
	typedef CRITICAL_SECTION pthread_mutex_t;
	typedef unsigned pthread_mutexattr_t;

	inline int pthread_mutex_lock(pthread_mutex_t* _mutex)
	{
		EnterCriticalSection(_mutex);
		return 0;
	}

	inline int pthread_mutex_unlock(pthread_mutex_t* _mutex)
	{
		LeaveCriticalSection(_mutex);
		return 0;
	}

	inline int pthread_mutex_trylock(pthread_mutex_t* _mutex)
	{
		return TryEnterCriticalSection(_mutex) ? 0 : EBUSY;
	}

	inline int pthread_mutex_init(pthread_mutex_t* _mutex, pthread_mutexattr_t* /*_attr*/)
	{
#		if BX_PLATFORM_WINRT
		InitializeCriticalSectionEx(_mutex, 4000, 0);   // docs recommend 4000 spincount as sane default
#		else
		InitializeCriticalSection(_mutex);
#		endif // BX_PLATFORM_
		return 0;
	}

	inline int pthread_mutex_destroy(pthread_mutex_t* _mutex)
	{
		DeleteCriticalSection(_mutex);
		return 0;
	}
#	endif // BX_PLATFORM_

	Mutex::Mutex()
	{
		BX_STATIC_ASSERT(sizeof(pthread_mutex_t) <= sizeof(m_internal) );

		pthread_mutexattr_t attr;

#	if BX_PLATFORM_WINDOWS \
	|| BX_PLATFORM_XBOXONE \
	|| BX_PLATFORM_WINRT
#	else
		pthread_mutexattr_init(&attr);
		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
#	endif // BX_PLATFORM_

		pthread_mutex_t* handle = (pthread_mutex_t*)m_internal;
		pthread_mutex_init(handle, &attr);
	}

	Mutex::~Mutex()
	{
		pthread_mutex_t* handle = (pthread_mutex_t*)m_internal;
		pthread_mutex_destroy(handle);
	}

	void Mutex::lock()
	{
		pthread_mutex_t* handle = (pthread_mutex_t*)m_internal;
		pthread_mutex_lock(handle);
	}

	void Mutex::unlock()
	{
		pthread_mutex_t* handle = (pthread_mutex_t*)m_internal;
		pthread_mutex_unlock(handle);
	}
#endif // BX_CRT_NONE

} // namespace bx

#endif // BX_MUTEX_H_HEADER_GUARD
<commit_msg>crtnone: Added mutex.<commit_after>/*
 * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
 * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
 */

#include "bx_p.h"
#include <bx/mutex.h>

#if BX_CONFIG_SUPPORTS_THREADING

#if BX_CRT_NONE
#	include <bx/cpu.h>
#	include "crt0.h"
#elif  BX_PLATFORM_ANDROID \
	|| BX_PLATFORM_LINUX   \
	|| BX_PLATFORM_IOS     \
	|| BX_PLATFORM_OSX     \
	|| BX_PLATFORM_PS4     \
	|| BX_PLATFORM_RPI
#	include <pthread.h>
#elif  BX_PLATFORM_WINDOWS \
	|| BX_PLATFORM_WINRT   \
	|| BX_PLATFORM_XBOXONE
#	include <windows.h>
#	include <errno.h>
#endif // BX_PLATFORM_

namespace bx
{
#if BX_CRT_NONE
	struct State
	{
		enum Enum
		{
			Unlocked,
			Locked,
			Contested,
		};
	};

	Mutex::Mutex()
	{
		BX_STATIC_ASSERT(sizeof(int32_t) <= sizeof(m_internal) );

		uint32_t* futex = (uint32_t*)m_internal;
		*futex = State::Unlocked;
	}

	Mutex::~Mutex()
	{
	}

	void Mutex::lock()
	{
		uint32_t* futex = (uint32_t*)m_internal;

		if (State::Unlocked == bx::atomicCompareAndSwap<uint32_t>(futex, State::Unlocked, State::Locked) )
		{
			return;
		}

		while (State::Unlocked != bx::atomicCompareAndSwap<uint32_t>(futex, State::Locked, State::Contested) )
		{
			crt0::futexWait(futex, State::Contested);
		}
	}

	void Mutex::unlock()
	{
		uint32_t* futex = (uint32_t*)m_internal;

		if (State::Contested == bx::atomicCompareAndSwap<uint32_t>(futex, State::Locked, State::Unlocked) )
		{
			crt0::futexWake(futex, State::Locked);
		}
	}

#else

#	if BX_PLATFORM_WINDOWS \
	|| BX_PLATFORM_XBOXONE \
	|| BX_PLATFORM_WINRT
	typedef CRITICAL_SECTION pthread_mutex_t;
	typedef unsigned pthread_mutexattr_t;

	inline int pthread_mutex_lock(pthread_mutex_t* _mutex)
	{
		EnterCriticalSection(_mutex);
		return 0;
	}

	inline int pthread_mutex_unlock(pthread_mutex_t* _mutex)
	{
		LeaveCriticalSection(_mutex);
		return 0;
	}

	inline int pthread_mutex_trylock(pthread_mutex_t* _mutex)
	{
		return TryEnterCriticalSection(_mutex) ? 0 : EBUSY;
	}

	inline int pthread_mutex_init(pthread_mutex_t* _mutex, pthread_mutexattr_t* /*_attr*/)
	{
#		if BX_PLATFORM_WINRT
		InitializeCriticalSectionEx(_mutex, 4000, 0);   // docs recommend 4000 spincount as sane default
#		else
		InitializeCriticalSection(_mutex);
#		endif // BX_PLATFORM_
		return 0;
	}

	inline int pthread_mutex_destroy(pthread_mutex_t* _mutex)
	{
		DeleteCriticalSection(_mutex);
		return 0;
	}
#	endif // BX_PLATFORM_

	Mutex::Mutex()
	{
		BX_STATIC_ASSERT(sizeof(pthread_mutex_t) <= sizeof(m_internal) );

		pthread_mutexattr_t attr;

#	if BX_PLATFORM_WINDOWS \
	|| BX_PLATFORM_XBOXONE \
	|| BX_PLATFORM_WINRT
#	else
		pthread_mutexattr_init(&attr);
		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
#	endif // BX_PLATFORM_

		pthread_mutex_t* handle = (pthread_mutex_t*)m_internal;
		pthread_mutex_init(handle, &attr);
	}

	Mutex::~Mutex()
	{
		pthread_mutex_t* handle = (pthread_mutex_t*)m_internal;
		pthread_mutex_destroy(handle);
	}

	void Mutex::lock()
	{
		pthread_mutex_t* handle = (pthread_mutex_t*)m_internal;
		pthread_mutex_lock(handle);
	}

	void Mutex::unlock()
	{
		pthread_mutex_t* handle = (pthread_mutex_t*)m_internal;
		pthread_mutex_unlock(handle);
	}
#endif // BX_CRT_NONE

} // namespace bx

#endif // BX_MUTEX_H_HEADER_GUARD
<|endoftext|>


<commit_before>#include <fnmatch.h>
#include <boost/algorithm/string/predicate.hpp>
#include <chrono>
#include <functional>
#include <netinet/tcp.h>

#include "buffer.hh"
#include "logging.hh"
#include "task.hh"
#include "http/http_message.hh"
#include "uri/uri.hh"
#include "net.hh"

namespace ten {

//! simple http server
class http_server : public netsock_server {
public:
    //! wrapper around an http request/response
    struct request {
        request(http_request &req_, netsock &sock_)
            : req(req_), resp(404), sock(sock_),
            start(std::chrono::monotonic_clock::now()),
            resp_sent(false) {}

        //! compose a uri from the request uri
        uri get_uri(std::string host="") {
            if (host.empty()) {
                host = req.get("Host");
                // TODO: transform to preserve passed in host
                if (boost::starts_with(req.uri, "http://")) {
                    return req.uri;
                }
            }

            if (host.empty()) {
                // just make up a host
                host = "localhost";
            }
            uri tmp;
            tmp.host = host;
            tmp.scheme = "http";
            tmp.path = req.uri.c_str();
            return tmp.compose();
        }

        //! send response to this request
        ssize_t send_response() {
            if (resp_sent) return 0;
            resp_sent = true;
            std::string data;
            // TODO: Content-Length might be another good one to add here
            // but only if Transfer-Encoding isn't chunked?
            // HTTP/1.1 requires Date, so lets add it
            if (resp.get("Date").empty()) {
                char buf[128];
                struct tm tm;
                time_t now = std::chrono::system_clock::to_time_t(procnow());
                strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S GMT", gmtime_r(&now, &tm));
                resp.set("Date", buf);
            }
            std::string conn = req.get("Connection");
            if (!conn.empty() && resp.get("Connection").empty()) {
                // obey clients wishes if we have none of our own
                resp.set("Connection", conn);
            }
            if (req.http_version == "HTTP/1.0" && req.get("Connection").empty()) {
                resp.set("Connection", "close");
            }
            data = resp.data();
            if (!resp.body.empty()) {
                data += resp.body;
            }
            ssize_t nw = sock.send(data.data(), data.size());
            return nw;
        }

        //! the ip of the host making the request
        //! might use the X-Forwarded-For header
        std::string agent_ip(bool use_xff=false) const {
            if (use_xff) {
                std::string xffs = req.get("X-Forwarded-For");
                const char *xff = xffs.c_str();
                if (xff) {
                    // pick the first addr
                    int i;
                    for (i=0; *xff && i<256 && !isdigit((unsigned char)*xff); i++, xff++) {}
                    if (*xff && i < 256) {
                        // now, find the end
                        const char *e = xff;
                        for (i = 0; *e && i<256 && (isdigit((unsigned char)*e) || *e == '.'); i++, e++) {}
                        if (i < 256 && e >= xff + 7 ) {
                            return std::string(xff, e - xff);
                        }
                    }
                }
            }
            address addr;
            if (sock.getpeername(addr)) {
                char buf[INET6_ADDRSTRLEN];
                return addr.ntop(buf, sizeof(buf));
            }
            return "";
        }

        ~request() {
            if (!resp_sent) {
                // ensure a response is sent
                resp = http_response(404, Headers("Content-Length", 0));
                send_response();
            }

            if (resp.get("Connection") == "close") {
                sock.close();
            }
        }

        http_request &req;
        http_response resp;
        netsock &sock;
        std::chrono::high_resolution_clock::time_point start;
        bool resp_sent;
    };

    typedef std::function<void (request &)> callback_type;
    struct route {
        std::string pattern;
        callback_type callback;
        int fnmatch_flags;

        route(const std::string &pattern_,
                const callback_type &callback_,
                int fnmatch_flags_=0)
            : pattern(pattern_), callback(callback_), fnmatch_flags(fnmatch_flags_) {}
    };

public:
    http_server(size_t stacksize_=default_stacksize, unsigned timeout_ms_=0)
        : netsock_server("http", stacksize_, timeout_ms_),
        _routes(std::make_shared<std::vector<route> >())
    {
    }

    //! add a callback for a uri with an fnmatch pattern
    void add_route(const std::string &pattern,
            const callback_type &callback,
            int fnmatch_flags = 0)
    {
      _routes->push_back(route(pattern, callback, fnmatch_flags));
    }

    //! set logging function, called after every request
    void set_log_callback(const callback_type &f) {
        _log_func = f;
    }

private:
    std::shared_ptr<std::vector<route> > _routes;
    callback_type _log_func;

    void on_shutdown() {
        // release any memory held by bound callbacks
        // this shared ptr madness is for threaded shutdown
        auto rr = _routes;
        rr->clear();
    }

    void on_connection(netsock &s) {
        // TODO: tuneable buffer sizes
        buffer buf(4*1024);
        http_parser parser;

        // TODO: might want to enable this later after
        // we know this will be a long-lived connection
        // otherwise the overhead of the syscall hurts concurrency
        //s.s.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1);

        http_request req;
        for (;;) {
            req.parser_init(&parser);
            bool got_headers = false;
            for (;;) {
                buf.reserve(4*1024);
                ssize_t nr = -1;
                if (buf.size() == 0) {
                    nr = s.recv(buf.back(), buf.available(), timeout_ms);
                    if (nr < 0) return;
                    buf.commit(nr);
                }
                size_t nparse = buf.size();
                req.parse(&parser, buf.front(), nparse);
                buf.remove(nparse);
                if (req.complete) {
                    // handle request
                    handle_request(req, s);
                    break;
                }
                if (nr == 0) return;
                if (!got_headers && !req.method.empty()) {
                    got_headers = true;
                    if (req.get("Expect") == "100-continue") {
                        http_response cont_resp(100);
                        std::string data = cont_resp.data();
                        ssize_t nw = s.send(data.data(), data.size());
                        (void)nw;
                    }
                }
            }
        }
    }

    void handle_request(http_request &req, netsock &s) {
        request r(req, s);
        std::string path = req.path();
        DVLOG(5) << "path: " << path;
        // not super efficient, but good enough
        for (auto i= _routes->cbegin(); i!= _routes->cend(); i++) {
            DVLOG(5) << "matching pattern: " << i->pattern;
            if (fnmatch(i->pattern.c_str(), path.c_str(), i->fnmatch_flags) == 0) {
                try {
                    i->callback(r);
                } catch (std::exception &e) {
                    r.resp = http_response(500,
                            Headers("Connection", "close"));
                    std::string msg = e.what();
                    msg += "\n";
                    r.resp.set_body(msg);
                    r.send_response();
                }
                break;
            }
        }
        if (_log_func) {
            _log_func(r);
        }
    }
};

} // end namespace ten

<commit_msg>use std::chrono<commit_after>#include <fnmatch.h>
#include <boost/algorithm/string/predicate.hpp>
#include <chrono>
#include <functional>
#include <netinet/tcp.h>

#include "buffer.hh"
#include "logging.hh"
#include "task.hh"
#include "http/http_message.hh"
#include "uri/uri.hh"
#include "net.hh"

namespace ten {

using namespace std::chrono;

//! simple http server
class http_server : public netsock_server {
public:
    //! wrapper around an http request/response
    struct request {
        request(http_request &req_, netsock &sock_)
            : req(req_), resp(404), sock(sock_),
            start(monotonic_clock::now()),
            resp_sent(false) {}

        //! compose a uri from the request uri
        uri get_uri(std::string host="") {
            if (host.empty()) {
                host = req.get("Host");
                // TODO: transform to preserve passed in host
                if (boost::starts_with(req.uri, "http://")) {
                    return req.uri;
                }
            }

            if (host.empty()) {
                // just make up a host
                host = "localhost";
            }
            uri tmp;
            tmp.host = host;
            tmp.scheme = "http";
            tmp.path = req.uri.c_str();
            return tmp.compose();
        }

        //! send response to this request
        ssize_t send_response() {
            if (resp_sent) return 0;
            resp_sent = true;
            std::string data;
            // TODO: Content-Length might be another good one to add here
            // but only if Transfer-Encoding isn't chunked?
            // HTTP/1.1 requires Date, so lets add it
            if (resp.get("Date").empty()) {
                char buf[128];
                struct tm tm;
                time_t now = system_clock::to_time_t(procnow());
                strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S GMT", gmtime_r(&now, &tm));
                resp.set("Date", buf);
            }
            std::string conn = req.get("Connection");
            if (!conn.empty() && resp.get("Connection").empty()) {
                // obey clients wishes if we have none of our own
                resp.set("Connection", conn);
            }
            if (req.http_version == "HTTP/1.0" && req.get("Connection").empty()) {
                resp.set("Connection", "close");
            }
            data = resp.data();
            if (!resp.body.empty()) {
                data += resp.body;
            }
            ssize_t nw = sock.send(data.data(), data.size());
            return nw;
        }

        //! the ip of the host making the request
        //! might use the X-Forwarded-For header
        std::string agent_ip(bool use_xff=false) const {
            if (use_xff) {
                std::string xffs = req.get("X-Forwarded-For");
                const char *xff = xffs.c_str();
                if (xff) {
                    // pick the first addr
                    int i;
                    for (i=0; *xff && i<256 && !isdigit((unsigned char)*xff); i++, xff++) {}
                    if (*xff && i < 256) {
                        // now, find the end
                        const char *e = xff;
                        for (i = 0; *e && i<256 && (isdigit((unsigned char)*e) || *e == '.'); i++, e++) {}
                        if (i < 256 && e >= xff + 7 ) {
                            return std::string(xff, e - xff);
                        }
                    }
                }
            }
            address addr;
            if (sock.getpeername(addr)) {
                char buf[INET6_ADDRSTRLEN];
                return addr.ntop(buf, sizeof(buf));
            }
            return "";
        }

        ~request() {
            if (!resp_sent) {
                // ensure a response is sent
                resp = http_response(404, Headers("Content-Length", 0));
                send_response();
            }

            if (resp.get("Connection") == "close") {
                sock.close();
            }
        }

        http_request &req;
        http_response resp;
        netsock &sock;
        high_resolution_clock::time_point start;
        bool resp_sent;
    };

    typedef std::function<void (request &)> callback_type;
    struct route {
        std::string pattern;
        callback_type callback;
        int fnmatch_flags;

        route(const std::string &pattern_,
                const callback_type &callback_,
                int fnmatch_flags_=0)
            : pattern(pattern_), callback(callback_), fnmatch_flags(fnmatch_flags_) {}
    };

public:
    http_server(size_t stacksize_=default_stacksize, unsigned timeout_ms_=0)
        : netsock_server("http", stacksize_, timeout_ms_),
        _routes(std::make_shared<std::vector<route> >())
    {
    }

    //! add a callback for a uri with an fnmatch pattern
    void add_route(const std::string &pattern,
            const callback_type &callback,
            int fnmatch_flags = 0)
    {
      _routes->push_back(route(pattern, callback, fnmatch_flags));
    }

    //! set logging function, called after every request
    void set_log_callback(const callback_type &f) {
        _log_func = f;
    }

private:
    std::shared_ptr<std::vector<route> > _routes;
    callback_type _log_func;

    void on_shutdown() {
        // release any memory held by bound callbacks
        // this shared ptr madness is for threaded shutdown
        auto rr = _routes;
        rr->clear();
    }

    void on_connection(netsock &s) {
        // TODO: tuneable buffer sizes
        buffer buf(4*1024);
        http_parser parser;

        // TODO: might want to enable this later after
        // we know this will be a long-lived connection
        // otherwise the overhead of the syscall hurts concurrency
        //s.s.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1);

        http_request req;
        for (;;) {
            req.parser_init(&parser);
            bool got_headers = false;
            for (;;) {
                buf.reserve(4*1024);
                ssize_t nr = -1;
                if (buf.size() == 0) {
                    nr = s.recv(buf.back(), buf.available(), timeout_ms);
                    if (nr < 0) return;
                    buf.commit(nr);
                }
                size_t nparse = buf.size();
                req.parse(&parser, buf.front(), nparse);
                buf.remove(nparse);
                if (req.complete) {
                    // handle request
                    handle_request(req, s);
                    break;
                }
                if (nr == 0) return;
                if (!got_headers && !req.method.empty()) {
                    got_headers = true;
                    if (req.get("Expect") == "100-continue") {
                        http_response cont_resp(100);
                        std::string data = cont_resp.data();
                        ssize_t nw = s.send(data.data(), data.size());
                        (void)nw;
                    }
                }
            }
        }
    }

    void handle_request(http_request &req, netsock &s) {
        request r(req, s);
        std::string path = req.path();
        DVLOG(5) << "path: " << path;
        // not super efficient, but good enough
        for (auto i= _routes->cbegin(); i!= _routes->cend(); i++) {
            DVLOG(5) << "matching pattern: " << i->pattern;
            if (fnmatch(i->pattern.c_str(), path.c_str(), i->fnmatch_flags) == 0) {
                try {
                    i->callback(r);
                } catch (std::exception &e) {
                    r.resp = http_response(500,
                            Headers("Connection", "close"));
                    std::string msg = e.what();
                    msg += "\n";
                    r.resp.set_body(msg);
                    r.send_response();
                }
                break;
            }
        }
        if (_log_func) {
            _log_func(r);
        }
    }
};

} // end namespace ten

<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>
#include <sstream>

#include "analyzer.h"
#include "ast.h"
#include "compiler.h"
#include "debuginfo.h"
#include "disassembler.h"
#include "lexer.h"
#include "parser.h"
#include "pt_dump.h"
#include "support.h"

extern void compile_cli(CompilerSupport *support, const ast::Program *);
extern void compile_cpp(CompilerSupport *support, const ast::Program *);
extern void compile_js(CompilerSupport *support, const ast::Program *);
extern void compile_jvm(CompilerSupport *support, const ast::Program *);

struct {
    std::string name;
    CompileProc proc;
} Targets[] = {
    {"cli", compile_cli},
    {"cpp", compile_cpp},
    {"js", compile_js},
    {"jvm", compile_jvm},
};

int main(int argc, char *argv[])
{
    bool ignore_errors = false;
    bool listing = false;
    std::string output;
    bool quiet = false;
    bool error_json = false;
    std::string target;
    CompileProc target_proc = nullptr;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s filename.neon\n", argv[0]);
        exit(1);
    }

    int a = 1;
    while (a < argc && argv[a][0] == '-' && argv[a][1] != '\0') {
        std::string arg = argv[a];
        if (arg == "-i") {
            ignore_errors = true;
        } else if (arg == "-d") {
            listing = true;
        } else if (arg == "--json") {
            error_json = true;
        } else if (arg == "-o") {
            a++;
            if (a >= argc) {
                std::cerr << "Missing output name\n";
                exit(1);
            }
            output = argv[a];
        } else if (arg == "-q") {
            quiet = true;
        } else if (arg == "-t") {
            a++;
            if (a < argc) {
                target = argv[a];
                size_t i = 0;
                while (i < sizeof(Targets)/sizeof(Targets[0]) && target != Targets[i].name) {
                    i++;
                }
                if (i < sizeof(Targets)/sizeof(Targets[0])) {
                    target_proc = Targets[i].proc;
                } else {
                    std::cerr << "Unknown target: " << target << "\n";
                    exit(1);
                }
            }
        } else {
            fprintf(stderr, "Unknown option: %s\n", arg.c_str());
            exit(1);
        }
        a++;
    }

    while (a < argc) {
        std::string name = argv[a];
        std::string source_path;

        std::stringstream buf;
        if (name == "-") {
            if (not quiet) {
                std::cout << "Compiling stdin (no output file)";
            }
            buf << std::cin.rdbuf();
        } else {
            auto i = name.find_last_of("/:\\");
            if (i != std::string::npos) {
                source_path = name.substr(0, i+1);
            }
            if (not quiet) {
                std::cout << "Compiling " << name;
            }
            std::ifstream inf(name);
            buf << inf.rdbuf();
        }
        if (not quiet) {
            if (not target.empty()) {
                std::cout << " for target " << target;
            }
            std::cout << "...\n";
        }

        CompilerSupport compiler_support(source_path, target_proc);

        const std::string objname = output.empty() ? std::string(argv[a]) + "x" : output;
        if (target_proc == nullptr) {
            remove(objname.c_str());
        }
        try {
            auto tokens = tokenize(name, buf.str());
            auto parsetree = parse(*tokens);
            auto ast = analyze(&compiler_support, parsetree.get());
            DebugInfo debug(name, buf.str());
            if (target_proc == nullptr) {
                auto bytecode = compile(ast, &debug);
                if (listing) {
                    disassemble(bytecode, std::cerr, &debug);
                }
                if (name != "-") {
                    std::ofstream outf(objname, std::ios::binary);
                    outf.write(reinterpret_cast<const std::ofstream::char_type *>(bytecode.data()), bytecode.size());
                }
            } else {
                target_proc(&compiler_support, ast);
            }

        } catch (CompilerError *error) {
            if (error_json) {
                error->write_json(std::cerr);
            } else {
                error->write(std::cerr);
            }
            if (not ignore_errors) {
                exit(1);
            }
        }

        a++;
    }
}
<commit_msg>Detect missing input file in neonc<commit_after>#include <fstream>
#include <iostream>
#include <sstream>

#include "analyzer.h"
#include "ast.h"
#include "compiler.h"
#include "debuginfo.h"
#include "disassembler.h"
#include "lexer.h"
#include "parser.h"
#include "pt_dump.h"
#include "support.h"

extern void compile_cli(CompilerSupport *support, const ast::Program *);
extern void compile_cpp(CompilerSupport *support, const ast::Program *);
extern void compile_js(CompilerSupport *support, const ast::Program *);
extern void compile_jvm(CompilerSupport *support, const ast::Program *);

struct {
    std::string name;
    CompileProc proc;
} Targets[] = {
    {"cli", compile_cli},
    {"cpp", compile_cpp},
    {"js", compile_js},
    {"jvm", compile_jvm},
};

int main(int argc, char *argv[])
{
    bool ignore_errors = false;
    bool listing = false;
    std::string output;
    bool quiet = false;
    bool error_json = false;
    std::string target;
    CompileProc target_proc = nullptr;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s filename.neon\n", argv[0]);
        exit(1);
    }

    int a = 1;
    while (a < argc && argv[a][0] == '-' && argv[a][1] != '\0') {
        std::string arg = argv[a];
        if (arg == "-i") {
            ignore_errors = true;
        } else if (arg == "-d") {
            listing = true;
        } else if (arg == "--json") {
            error_json = true;
        } else if (arg == "-o") {
            a++;
            if (a >= argc) {
                std::cerr << "Missing output name\n";
                exit(1);
            }
            output = argv[a];
        } else if (arg == "-q") {
            quiet = true;
        } else if (arg == "-t") {
            a++;
            if (a < argc) {
                target = argv[a];
                size_t i = 0;
                while (i < sizeof(Targets)/sizeof(Targets[0]) && target != Targets[i].name) {
                    i++;
                }
                if (i < sizeof(Targets)/sizeof(Targets[0])) {
                    target_proc = Targets[i].proc;
                } else {
                    std::cerr << "Unknown target: " << target << "\n";
                    exit(1);
                }
            }
        } else {
            fprintf(stderr, "Unknown option: %s\n", arg.c_str());
            exit(1);
        }
        a++;
    }

    while (a < argc) {
        std::string name = argv[a];
        std::string source_path;

        std::stringstream buf;
        if (name == "-") {
            if (not quiet) {
                std::cout << "Compiling stdin (no output file)";
            }
            buf << std::cin.rdbuf();
        } else {
            auto i = name.find_last_of("/:\\");
            if (i != std::string::npos) {
                source_path = name.substr(0, i+1);
            }
            std::ifstream inf(name);
            if (not inf) {
                std::cerr << "Source file not found: " << name << "\n";
                exit(1);
            }
            buf << inf.rdbuf();
            if (not quiet) {
                std::cout << "Compiling " << name;
            }
        }
        if (not quiet) {
            if (not target.empty()) {
                std::cout << " for target " << target;
            }
            std::cout << "...\n";
        }

        CompilerSupport compiler_support(source_path, target_proc);

        const std::string objname = output.empty() ? std::string(argv[a]) + "x" : output;
        if (target_proc == nullptr) {
            remove(objname.c_str());
        }
        try {
            auto tokens = tokenize(name, buf.str());
            auto parsetree = parse(*tokens);
            auto ast = analyze(&compiler_support, parsetree.get());
            DebugInfo debug(name, buf.str());
            if (target_proc == nullptr) {
                auto bytecode = compile(ast, &debug);
                if (listing) {
                    disassemble(bytecode, std::cerr, &debug);
                }
                if (name != "-") {
                    std::ofstream outf(objname, std::ios::binary);
                    outf.write(reinterpret_cast<const std::ofstream::char_type *>(bytecode.data()), bytecode.size());
                }
            } else {
                target_proc(&compiler_support, ast);
            }

        } catch (CompilerError *error) {
            if (error_json) {
                error->write_json(std::cerr);
            } else {
                error->write(std::cerr);
            }
            if (not ignore_errors) {
                exit(1);
            }
        }

        a++;
    }
}
<|endoftext|>


<commit_before>/*******************************************************************************
**
** Filename   : templatemanagementdialog.cpp
** Created on : 05 June, 2005
** Copyright  : (c) 2005 Till Adam <adam@kde.org>
**
*******************************************************************************/

/*******************************************************************************
**
**   This program is free software; you can redistribute it and/or modify
**   it under the terms of the GNU General Public License as published by
**   the Free Software Foundation; either version 2 of the License, or
**   (at your option) any later version.
**
**   It is distributed in the hope that it will be useful, but
**   WITHOUT ANY WARRANTY; without even the implied warranty of
**   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
**   General Public License for more details.
**
**   You should have received a copy of the GNU General Public License
**   along with this program; if not, write to the Free Software
**   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**   In addition, as a special exception, the copyright holders give
**   permission to link the code of this program with any edition of
**   the Qt library by Trolltech AS, Norway (or with modified versions
**   of Qt that use the same license as Qt), and distribute linked
**   combinations including the two.  You must obey the GNU General
**   Public License in all respects for all of the code used other than
**   Qt.  If you modify this file, you may extend this exception to
**   your version of the file, but you are not obligated to do so.  If
**   you do not wish to do so, delete this exception statement from
**   your version.
**
*******************************************************************************/
#include "templatemanagementdialog.h"

#include <QStringList>
#include <QTimer>

#include <kpushbutton.h>
#include <kinputdialog.h>
#include <klocale.h>
#include <kmessagebox.h>

TemplateManagementDialog::TemplateManagementDialog(QWidget *parent, const QStringList &templates )
    :KDialog( parent, i18n("Manage Templates"), Ok|Cancel ),
      m_templates( templates ), m_newTemplate( QString() ), m_changed( false )
{
  setObjectName( "template_management_dialog" );
  QWidget *widget = new QWidget( this );
  widget->setObjectName( "template_management_dialog_base" );
  m_base.setupUi( widget );
  setMainWidget( widget );
  connect( m_base.m_buttonAdd, SIGNAL( clicked() ),
           SLOT( slotAddTemplate() ) );
  connect( m_base.m_buttonDelete, SIGNAL( clicked() ),
           SLOT( slotDeleteTemplate() ) );
  m_base.m_listBox->insertStringList( m_templates );
  connect( m_base.m_listBox, SIGNAL( selectionChanged( Q3ListBoxItem * ) ),
           SLOT( slotUpdateDeleteButton( Q3ListBoxItem * ) ) );
  connect( m_base.m_buttonApply, SIGNAL( clicked() ),
           SLOT( slotApplyTemplate() ) );
  connect( this, SIGNAL( okClicked() ), SLOT( slotOk() ) );

}

void TemplateManagementDialog::slotAddTemplate()
{
  bool ok;
  bool duplicate = false;
  const QString newTemplate = KInputDialog::getText( i18n("Template Name"),
                                       i18n("Please enter a name for the new template:"),
                                       i18n("New Template"), &ok );
  if ( newTemplate.isEmpty() || !ok ) return;
  if ( m_templates.contains( newTemplate ) ) {
    int rc = KMessageBox::warningContinueCancel( this, i18n("A template with that name already exists, do you want to overwrite it?."), i18n("Duplicate Template Name"), i18n("Overwrite"));
    if ( rc == KMessageBox::Cancel ) {
      QTimer::singleShot(0, this, SLOT( slotAddTemplate() ) );
      return;
    }
    duplicate = true;
  }
  if ( !duplicate ) {
    m_templates.append( newTemplate );
    m_base.m_listBox->clear();
    m_base.m_listBox->insertStringList( m_templates );
  }
  m_newTemplate = newTemplate;
  m_changed = true;
  // From this point on we need to keep the original event around until the user has
  // closed the dialog, applying a template would make little sense
  m_base.m_buttonApply->setEnabled( false );
  // neither does adding it again
  m_base.m_buttonAdd->setEnabled( false );
}

void TemplateManagementDialog::slotDeleteTemplate()
{
  Q3ListBoxItem *const item = m_base.m_listBox->selectedItem();
  if ( !item ) return; // can't happen (TM)
  int current = m_base.m_listBox->index(item);
  m_templates.removeAll( item->text() );
  m_base.m_listBox->removeItem( m_base.m_listBox->currentItem() );
  m_changed = true;
  m_base.m_listBox->setSelected(qMax(current -1, 0), true);
}

void TemplateManagementDialog::slotUpdateDeleteButton( Q3ListBoxItem *item )
{
  m_base.m_buttonDelete->setEnabled( item != 0 );
}

void TemplateManagementDialog::slotApplyTemplate()
{
  // Once the user has applied the current template to the event, it makes no sense to add it again
  m_base.m_buttonAdd->setEnabled( false );
  const QString &cur = m_base.m_listBox->currentText();
  if ( !cur.isEmpty() && cur != m_newTemplate )
    emit loadTemplate( cur );
}

void TemplateManagementDialog::slotOk()
{
  // failure is not an option *cough*
  if ( !m_newTemplate.isEmpty() )
    emit saveTemplate( m_newTemplate );
  if ( m_changed )
    emit templatesChanged( m_templates );
}

#include "templatemanagementdialog.moc"
<commit_msg>Minor fix<commit_after>/*******************************************************************************
**
** Filename   : templatemanagementdialog.cpp
** Created on : 05 June, 2005
** Copyright  : (c) 2005 Till Adam <adam@kde.org>
**
*******************************************************************************/

/*******************************************************************************
**
**   This program is free software; you can redistribute it and/or modify
**   it under the terms of the GNU General Public License as published by
**   the Free Software Foundation; either version 2 of the License, or
**   (at your option) any later version.
**
**   It is distributed in the hope that it will be useful, but
**   WITHOUT ANY WARRANTY; without even the implied warranty of
**   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
**   General Public License for more details.
**
**   You should have received a copy of the GNU General Public License
**   along with this program; if not, write to the Free Software
**   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**   In addition, as a special exception, the copyright holders give
**   permission to link the code of this program with any edition of
**   the Qt library by Trolltech AS, Norway (or with modified versions
**   of Qt that use the same license as Qt), and distribute linked
**   combinations including the two.  You must obey the GNU General
**   Public License in all respects for all of the code used other than
**   Qt.  If you modify this file, you may extend this exception to
**   your version of the file, but you are not obligated to do so.  If
**   you do not wish to do so, delete this exception statement from
**   your version.
**
*******************************************************************************/
#include "templatemanagementdialog.h"

#include <QStringList>
#include <QTimer>

#include <kpushbutton.h>
#include <kinputdialog.h>
#include <klocale.h>
#include <kmessagebox.h>

TemplateManagementDialog::TemplateManagementDialog(QWidget *parent, const QStringList &templates )
    :KDialog( parent),
      m_templates( templates ), m_newTemplate( QString() ), m_changed( false )
{
  setCaption( i18n("Manage Templates") );
  setButtons(  Ok|Cancel );
  setObjectName( "template_management_dialog" );
  QWidget *widget = new QWidget( this );
  widget->setObjectName( "template_management_dialog_base" );
  m_base.setupUi( widget );
  setMainWidget( widget );
  connect( m_base.m_buttonAdd, SIGNAL( clicked() ),
           SLOT( slotAddTemplate() ) );
  connect( m_base.m_buttonDelete, SIGNAL( clicked() ),
           SLOT( slotDeleteTemplate() ) );
  m_base.m_listBox->insertStringList( m_templates );
  connect( m_base.m_listBox, SIGNAL( selectionChanged( Q3ListBoxItem * ) ),
           SLOT( slotUpdateDeleteButton( Q3ListBoxItem * ) ) );
  connect( m_base.m_buttonApply, SIGNAL( clicked() ),
           SLOT( slotApplyTemplate() ) );
  connect( this, SIGNAL( okClicked() ), SLOT( slotOk() ) );

}

void TemplateManagementDialog::slotAddTemplate()
{
  bool ok;
  bool duplicate = false;
  const QString newTemplate = KInputDialog::getText( i18n("Template Name"),
                                       i18n("Please enter a name for the new template:"),
                                       i18n("New Template"), &ok );
  if ( newTemplate.isEmpty() || !ok ) return;
  if ( m_templates.contains( newTemplate ) ) {
    int rc = KMessageBox::warningContinueCancel( this, i18n("A template with that name already exists, do you want to overwrite it?."), i18n("Duplicate Template Name"), i18n("Overwrite"));
    if ( rc == KMessageBox::Cancel ) {
      QTimer::singleShot(0, this, SLOT( slotAddTemplate() ) );
      return;
    }
    duplicate = true;
  }
  if ( !duplicate ) {
    m_templates.append( newTemplate );
    m_base.m_listBox->clear();
    m_base.m_listBox->insertStringList( m_templates );
  }
  m_newTemplate = newTemplate;
  m_changed = true;
  // From this point on we need to keep the original event around until the user has
  // closed the dialog, applying a template would make little sense
  m_base.m_buttonApply->setEnabled( false );
  // neither does adding it again
  m_base.m_buttonAdd->setEnabled( false );
}

void TemplateManagementDialog::slotDeleteTemplate()
{
  Q3ListBoxItem *const item = m_base.m_listBox->selectedItem();
  if ( !item ) return; // can't happen (TM)
  int current = m_base.m_listBox->index(item);
  m_templates.removeAll( item->text() );
  m_base.m_listBox->removeItem( m_base.m_listBox->currentItem() );
  m_changed = true;
  m_base.m_listBox->setSelected(qMax(current -1, 0), true);
}

void TemplateManagementDialog::slotUpdateDeleteButton( Q3ListBoxItem *item )
{
  m_base.m_buttonDelete->setEnabled( item != 0 );
}

void TemplateManagementDialog::slotApplyTemplate()
{
  // Once the user has applied the current template to the event, it makes no sense to add it again
  m_base.m_buttonAdd->setEnabled( false );
  const QString &cur = m_base.m_listBox->currentText();
  if ( !cur.isEmpty() && cur != m_newTemplate )
    emit loadTemplate( cur );
}

void TemplateManagementDialog::slotOk()
{
  // failure is not an option *cough*
  if ( !m_newTemplate.isEmpty() )
    emit saveTemplate( m_newTemplate );
  if ( m_changed )
    emit templatesChanged( m_templates );
}

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


<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <cmath>
#include <limits>

#ifndef STATS_HPP
#define STATS_HPP

namespace isa {
namespace utils {

template< typename T > class Stats {
public:
	Stats();
	~Stats();

	void addElement(T element);
	inline void reset();

	inline long long unsigned int getNrElements() const;
	inline double getMean() const;
  inline double getHarmonicMean() const;
	inline double getVariance() const;
	inline double getStandardDeviation() const;
  inline double getCoefficientOfVariation() const;
  inline T getMin() const;
  inline T getMax() const;

private:
	long long unsigned int nrElements;
	double mean;
  double harmonicMean;
	double variance;
  T min;
  T max;
};

// Implementations

template< typename T > Stats< T >::Stats() : nrElements(0), mean(0.0), harmonicMean(0.0), variance(0.0), min(std::numeric_limits< T >::max()), max(std::numeric_limits< T >::min()) {}

template< typename T > Stats< T >::~Stats() {}

template< typename T > void Stats< T >::addElement(T element) {
	double oldMean = mean;

	nrElements++;

	if ( nrElements == 1 ) {
		mean = static_cast< double >(element);
    harmonicMean = static_cast< double >(1.0 / element);
    min = element;
    max = element;
		return;
	}
	mean = oldMean + ((element - oldMean) / nrElements);
  harmonicMean += static_cast< double >(1.0 / element);
	variance += (element - oldMean) * (element - mean);

  if ( element < min ) {
    min = element;
  } else if ( element > max ) {
    max = element;
  }
}

template< typename T > inline void Stats< T >::reset() {
	nrElements = 0;
	mean = 0.0;
  harmonicMean = 0.0;
	variance = 0.0;
  min = std::numeric_limits< T >::max();
  max = std::numeric_limits< T >::min();
}

template< typename T > inline long long unsigned int Stats< T >::getNrElements() const {
	return nrElements;
}

template< typename T > inline double Stats< T >::getMean() const {
	return mean;
}

template< typename T > inline double Stats< T >::getHarmonicMean() const {
  if ( nrElements > 0 ) {
    return nrElements / harmonicMean;
  } else {
    return 0.0;
  }
}

template< typename T > inline double Stats< T >::getVariance() const {
  if ( nrElements > 1 ) {
    return variance / (nrElements - 1);
  } else {
    return 0.0;
  }
}

template< typename T > inline double Stats< T >::getStandardDeviation() const {
	return std::sqrt(this->getVariance());
}

template< typename T > inline double Stats< T >::getCoefficientOfVariation() const {
  return this->getStandardDeviation() / this->getMean();
}

template< typename T > inline T Stats< T >::getMin() const {
  return min;
}

template< typename T > inline T Stats< T >::getMax() const {
  return max;
}

} // utils
} // isa

#endif

<commit_msg>Added the Root Mean Square to the computed statistical values.<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <cmath>
#include <limits>

#ifndef STATS_HPP
#define STATS_HPP

namespace isa {
namespace utils {

template< typename T > class Stats {
public:
	Stats();
	~Stats();

	void addElement(T element);
	inline void reset();

	inline long long unsigned int getNrElements() const;
	inline double getMean() const;
  inline double getHarmonicMean() const;
	inline double getVariance() const;
	inline double getStandardDeviation() const;
  inline double getCoefficientOfVariation() const;
  inline double getRootMeanSquare() const;
  inline T getMin() const;
  inline T getMax() const;

private:
	long long unsigned int nrElements;
	double mean;
  double harmonicMean;
	double variance;
  double rms;
  T min;
  T max;
};

// Implementations

template< typename T > Stats< T >::Stats() : nrElements(0), mean(0.0), harmonicMean(0.0), variance(0.0), rms(0.0), min(std::numeric_limits< T >::max()), max(std::numeric_limits< T >::min()) {}

template< typename T > Stats< T >::~Stats() {}

template< typename T > void Stats< T >::addElement(T element) {
	double oldMean = mean;

	nrElements++;

	if ( nrElements == 1 ) {
		mean = static_cast< double >(element);
    harmonicMean = static_cast< double >(1.0 / element);
    rms = static_cast< double >(element * element);
    min = element;
    max = element;
		return;
	}
	mean = oldMean + ((element - oldMean) / nrElements);
  harmonicMean += static_cast< double >(1.0 / element);
	variance += (element - oldMean) * (element - mean);
  rms += static_cast< double >(element * element);

  if ( element < min ) {
    min = element;
  } else if ( element > max ) {
    max = element;
  }
}

template< typename T > inline void Stats< T >::reset() {
	nrElements = 0;
	mean = 0.0;
  harmonicMean = 0.0;
	variance = 0.0;
  rms = 0.0;
  min = std::numeric_limits< T >::max();
  max = std::numeric_limits< T >::min();
}

template< typename T > inline long long unsigned int Stats< T >::getNrElements() const {
	return nrElements;
}

template< typename T > inline double Stats< T >::getMean() const {
	return mean;
}

template< typename T > inline double Stats< T >::getHarmonicMean() const {
  if ( nrElements > 0 ) {
    return nrElements / harmonicMean;
  } else {
    return 0.0;
  }
}

template< typename T > inline double Stats< T >::getVariance() const {
  if ( nrElements > 1 ) {
    return variance / (nrElements - 1);
  } else {
    return 0.0;
  }
}

template< typename T > inline double Stats< T >::getStandardDeviation() const {
	return std::sqrt(this->getVariance());
}

template< typename T > inline double Stats< T >::getCoefficientOfVariation() const {
  return this->getStandardDeviation() / this->getMean();
}

template< typename T > inline double Stats< T >::getRootMeanSquare() const {
  return std::sqrt(rms / nrElements);
}

template< typename T > inline T Stats< T >::getMin() const {
  return min;
}

template< typename T > inline T Stats< T >::getMax() const {
  return max;
}

} // utils
} // isa

#endif

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libetonyek project.
 *
 * 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/.
 */

#include "IWORKStylesheetBase.h"

#include "IWORKCollector.h"
#include "IWORKDictionary.h"
#include "IWORKStylesContext.h"
#include "IWORKStylesheet.h"
#include "IWORKToken.h"
#include "IWORKXMLParserState.h"

namespace libetonyek
{

IWORKStylesheetBase::IWORKStylesheetBase(IWORKXMLParserState &state)
  : IWORKXMLElementContextBase(state)
{
}

void IWORKStylesheetBase::startOfElement()
{
  assert(!getState().m_stylesheet);

  getState().m_stylesheet.reset(new IWORKStylesheet());
}

IWORKXMLContextPtr_t IWORKStylesheetBase::element(const int name)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::styles :
    return makeContext<IWORKStylesContext>(getState(), false);
  case IWORKToken::NS_URI_SF | IWORKToken::anon_styles :
    return makeContext<IWORKStylesContext>(getState(), false);
  }

  return IWORKXMLElementContextBase::element(name);
}

void IWORKStylesheetBase::endOfElement()
{
  assert(getState().m_stylesheet);

  if (getId())
    getState().getDictionary().m_stylesheets[get(getId())] = getState().m_stylesheet;
  if (isCollector())
    getCollector().collectStylesheet(getState().m_stylesheet);
  getState().m_stylesheet.reset();
}

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<commit_msg>fix build<commit_after>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libetonyek project.
 *
 * 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/.
 */

#include "IWORKStylesheetBase.h"

#include "IWORKCollector.h"
#include "IWORKDictionary.h"
#include "IWORKStylesContext.h"
#include "IWORKStylesheet.h"
#include "IWORKToken.h"
#include "IWORKXMLParserState.h"

namespace libetonyek
{

IWORKStylesheetBase::IWORKStylesheetBase(IWORKXMLParserState &state)
  : IWORKXMLElementContextBase(state)
{
}

void IWORKStylesheetBase::startOfElement()
{
  assert(!getState().m_stylesheet);

  getState().m_stylesheet.reset(new IWORKStylesheet());
}

IWORKXMLContextPtr_t IWORKStylesheetBase::element(const int name)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::styles :
    return makeContext<IWORKStylesContext>(getState(), false);
  case IWORKToken::NS_URI_SF | IWORKToken::anon_styles :
    return makeContext<IWORKStylesContext>(getState(), false);
  }

  return IWORKXMLContextPtr_t();
}

void IWORKStylesheetBase::endOfElement()
{
  assert(getState().m_stylesheet);

  if (getId())
    getState().getDictionary().m_stylesheets[get(getId())] = getState().m_stylesheet;
  if (isCollector())
    getCollector().collectStylesheet(getState().m_stylesheet);
  getState().m_stylesheet.reset();
}

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<|endoftext|>


<commit_before>/*
 (c) Gabriel L. Dunne, 2014
*/
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

  // of stuff
	ofSetVerticalSync(true);
  ofSetFrameRate(60);
  ofEnableDepthTest();

  // settings
  showHelp = false;
  editMode = true;
  camMouse = false;
  mouseDragging = false;
  nearestIndex = 0;
  normalSmoothAmt = 20;

  // set up material
  // shininess is a value between 0 - 128, 128 being the most shiny //
	material.setShininess( 120 );
	material.setSpecularColor(ofColor(255, 255, 255));
  material.setAmbientColor(ofColor(0, 0, 0));
  material.setShininess(10.0f);

  // load mesh
//	mesh.load("CircleDistortion.ply");
  mesh.load("landscape-round.ply");

  //sceneMesh.append(mesh);
  //sceneMesh.smoothNormals( normalSmoothAmt );

  // reference sphere
  sphere.setRadius( 20 );

  // set up lights
  ofSetGlobalAmbientColor(ofColor(0, 0, 0));
  ofSetSmoothLighting(true);
  sun.setup();
  sun.setDirectional();
  sun.setDiffuseColor( ofFloatColor(0.5f, 0.5f, 0.5f) );
  sun.setSpecularColor( ofFloatColor(0.3f, 0.3f, 0.3f) );

  moon.setup();
  moon.setDirectional();
  moon.setDiffuseColor( ofFloatColor(0.0f, 0.0f, 0.2f) );
  moon.setSpecularColor( ofFloatColor(0.0f, 0.0f, 0.05f) );

//  light.setAttenuation(0.5, 0, 0);
//  setAttenuation(float constant=1.f, float linear=0.f, float quadratic=0.f))

  // load camera settings
  ofxLoadCamera(cam, "cameraSettings");

  // start w/ mouse input disabled
  cam.disableMouseInput();
//  cam.setFov(5);
}

//--------------------------------------------------------------
void ofApp::update(){

  float d = 400.0f; // distance from center

  ofPoint sp;
  sp.set(400, 0, 0);
  sp.rotate( ofGetElapsedTimef() * 7 , ofVec3f(0, 0, 1));
  sun.setPosition(sp.x, sp.y, sp.z);
  sun.lookAt(ofVec3f(0,0,0));

  // move sun around
  //sun.setPosition(0, cos(ofGetElapsedTimef()) * d , sin(ofGetElapsedTimef()) * d);

  // move moon around
  //moon.rotateAround(ofGetElapsedTimef(), ofVec3f(1,0,0), ofVec3(0,0,0))
  ofPoint mp;
  mp.set(400, 0, 0);
  mp.rotate( ofGetElapsedTimef() * 7 + 180 , ofVec3f(0, 0, 1));
//  moon.setPosition(0, (cos(ofGetElapsedTimef())) * d , sin(ofGetElapsedTimef()) * d);
  moon.setPosition(mp.x, mp.y, mp.z);
  moon.lookAt(ofVec3f(0, 0, 0));
}

//--------------------------------------------------------------
void ofApp::draw(){

  if (editMode) {
    // if editing, show background gradient
    ofBackgroundGradient(ofColor(80), ofColor(5));
  } else {
    // black bg
    ofBackground(ofColor(0));
  }

  // begin camera
	cam.begin();

  // enable lighting
  ofEnableLighting();
  //  ofEnableSeparateSpecularLight();
  sun.enable();
  moon.enable();
  //	light.setGlobalPosition(1000, 1000, 1000);
  //	light.lookAt(ofVec3f(0,0,0));

  // start material
  material.begin();
  ofSetColor(255);
  ofFill();

  // test sphere
  //sphere.setPosition(0, 60, 0);
  //sphere.draw();

  // draw mesh faces
  if (!editMode) {
    sceneMesh.draw();
  }

  // end material
  material.end();

  // end lighting
  ofDisableLighting();

  // draw light position
  if (editMode) {

    // draw grey lines to lights
    ofSetColor(ofColor::gray);
    ofSetLineWidth(1);
    ofLine(sun.getPosition(),  ofVec3f(0));
    ofLine(moon.getPosition(), ofVec3f(0));

    // draw lights
    ofFill();
    ofSetColor(sun.getDiffuseColor());
    sun.draw();
    ofSetColor(moon.getDiffuseColor());
    moon.draw();
  }

  // draw verts and wireframe when editing
  if (editMode) {
    // draw wireframe
    ofSetColor(ofColor::yellow);
    glLineWidth(2);

//    sceneMesh.drawWireframe();

    // ofvbo
    // ofvbomesh
    // ofxmesh
    // ofxhemesh

//    mesh.getFace(<#int faceId#>);

    // draw verts
    ofSetColor(ofColor::white);
    glPointSize(4);
    mesh.drawVertices();
  }

  // end camera
  cam.end();

  // vert selection
  if (editMode) {
    // create vec2 of the mouse for reference
    ofVec2f mouse(mouseX, mouseY);
    // if not dragging the mouse, find the nearest vert
    if (!mouseDragging) {
      // loop through all verticies in mesh and find the nearest vert position and index
      int n = mesh.getNumVertices();
      float nearestDistance = 0;
      for(int i = 0; i < n; i++) {
        ofVec3f cur = cam.worldToScreen(mesh.getVertex(i));
        float distance = cur.distance(mouse);
        if(i == 0 || distance < nearestDistance) {
          nearestDistance = distance;
          nearestVertex = cur;
          nearestIndex = i;
        }
      }
    }

    // draw a line from the nearest vertex to the mouse position
    ofSetColor(ofColor::gray);
    ofSetLineWidth(1);
    ofLine(nearestVertex, mouse);

    // draw a cirle around the nearest vertex
    ofNoFill();
    ofSetColor(ofColor::magenta);
    ofSetLineWidth(2);
    if (mouseDragging) {
      ofCircle(mouse, 4);
    } else {
      ofCircle(nearestVertex, 4);
    }
    ofSetLineWidth(1);

    // edit position of nearest vert with mousedrag
    if (!camMouse && mouseDragging) {
      mesh.setVertex(nearestIndex, cam.screenToWorld(ofVec3f(mouse.x, mouse.y, nearestVertex.z)));
    }

    // draw a label with the nearest vertex index
    ofDrawBitmapStringHighlight(ofToString(nearestIndex), mouse + ofVec2f(10, -10));
  }

  // draw info text
  if (showHelp) {
    stringstream ss;
    ss << "Framerate " << ofToString(ofGetFrameRate(),0) << "\n";
    ss << "  f : Toggle Fullscreen" << "\n";
    ss << "  h : Toggle Help Text" << "\n";
    ss << "  c : Toggle Camera Control : " << (camMouse == true ? "ON" : "OFF") << "\n";
    ss << "TAB : Toggle Mesh Edit : " << (editMode == true ? "ON" : "OFF") << "\n";
    ss << "  s : Save Scene" << "\n";
    ss << "  l : Load Scene";
    ofSetColor(ofColor::white);
    ofDrawBitmapStringHighlight(ss.str().c_str(), ofVec3f(10, 20), ofColor(45), ofColor(255));
  }
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

	switch(key) {

    // toggle fullscreen
		case 'f':
			ofToggleFullscreen();
			break;

    // toggle camera control
    case 'c':
      camMouse = !camMouse;
      camMouse ? cam.enableMouseInput() : cam.disableMouseInput();
			break;

    // saves the camera and mesh settings
    case 's':
      ofxSaveCamera(cam, "cameraSettings");
      mesh.save("mesh-tweaked.ply");
      break;

    // loads camera and mesh settings
    case 'l':
      ofxLoadCamera(cam, "cameraSettings");
      mesh.load("mesh-tweaked.ply");
      camMouse = false;
      editMode = false;
      break;

    // show help
    case 'h':
      showHelp = !showHelp;
      break;

    // toggle 'TAB' to edit verts
    case OF_KEY_TAB:
      editMode = !editMode;
      if (!editMode) {
        sceneMesh.clear();
        sceneMesh.append(mesh);
        sceneMesh.smoothNormals( normalSmoothAmt );
      }
      break;
	}
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
  mouseDragging = true;
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
  mouseDragging = false;
}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<commit_msg>A little faster<commit_after>/*
 (c) Gabriel L. Dunne, 2014
*/
#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

  // of stuff
	ofSetVerticalSync(true);
  ofSetFrameRate(60);
  ofEnableDepthTest();

  // settings
  showHelp = false;
  editMode = true;
  camMouse = false;
  mouseDragging = false;
  nearestIndex = 0;
  normalSmoothAmt = 20;

  // set up material
  // shininess is a value between 0 - 128, 128 being the most shiny //
	material.setShininess( 120 );
	material.setSpecularColor(ofColor(255, 255, 255));
  material.setAmbientColor(ofColor(0, 0, 0));
  material.setShininess(10.0f);

  // load mesh
//	mesh.load("CircleDistortion.ply");
  mesh.load("landscape-round.ply");

  //sceneMesh.append(mesh);
  //sceneMesh.smoothNormals( normalSmoothAmt );

  // reference sphere
  sphere.setRadius( 20 );

  // set up lights
  ofSetGlobalAmbientColor(ofColor(0, 0, 0));
  ofSetSmoothLighting(true);
  sun.setup();
  sun.setDirectional();
  sun.setDiffuseColor( ofFloatColor(0.5f, 0.5f, 0.5f) );
  sun.setSpecularColor( ofFloatColor(0.3f, 0.3f, 0.3f) );

  moon.setup();
  moon.setDirectional();
  moon.setDiffuseColor( ofFloatColor(0.0f, 0.0f, 0.2f) );
  moon.setSpecularColor( ofFloatColor(0.0f, 0.0f, 0.05f) );

//  light.setAttenuation(0.5, 0, 0);
//  setAttenuation(float constant=1.f, float linear=0.f, float quadratic=0.f))

  // load camera settings
  ofxLoadCamera(cam, "cameraSettings");

  // start w/ mouse input disabled
  cam.disableMouseInput();
//  cam.setFov(5);
}

//--------------------------------------------------------------
void ofApp::update(){

  float d = 400.0f; // distance from center

  ofPoint sp;
  sp.set(400, 0, 0);
  sp.rotate( ofGetElapsedTimef() * 10 , ofVec3f(0, 0, 1));
  sun.setPosition(sp.x, sp.y, sp.z);
  sun.lookAt(ofVec3f(0,0,0));

  // move sun around
  //sun.setPosition(0, cos(ofGetElapsedTimef()) * d , sin(ofGetElapsedTimef()) * d);

  // move moon around
  //moon.rotateAround(ofGetElapsedTimef(), ofVec3f(1,0,0), ofVec3(0,0,0))
  ofPoint mp;
  mp.set(400, 0, 0);
  mp.rotate( ofGetElapsedTimef() * 10 + 180 , ofVec3f(0, 0, 1));
//  moon.setPosition(0, (cos(ofGetElapsedTimef())) * d , sin(ofGetElapsedTimef()) * d);
  moon.setPosition(mp.x, mp.y, mp.z);
  moon.lookAt(ofVec3f(0, 0, 0));
}

//--------------------------------------------------------------
void ofApp::draw(){

  if (editMode) {
    // if editing, show background gradient
    ofBackgroundGradient(ofColor(80), ofColor(5));
  } else {
    // black bg
    ofBackground(ofColor(0));
  }

  // begin camera
	cam.begin();

  // enable lighting
  ofEnableLighting();
  //  ofEnableSeparateSpecularLight();
  sun.enable();
  moon.enable();
  //	light.setGlobalPosition(1000, 1000, 1000);
  //	light.lookAt(ofVec3f(0,0,0));

  // start material
  material.begin();
  ofSetColor(255);
  ofFill();

  // test sphere
  //sphere.setPosition(0, 60, 0);
  //sphere.draw();

  // draw mesh faces
  if (!editMode) {
    sceneMesh.draw();
  }

  // end material
  material.end();

  // end lighting
  ofDisableLighting();

  // draw light position
  if (editMode) {

    // draw grey lines to lights
    ofSetColor(ofColor::gray);
    ofSetLineWidth(1);
    ofLine(sun.getPosition(),  ofVec3f(0));
    ofLine(moon.getPosition(), ofVec3f(0));

    // draw lights
    ofFill();
    ofSetColor(sun.getDiffuseColor());
    sun.draw();
    ofSetColor(moon.getDiffuseColor());
    moon.draw();
  }

  // draw verts and wireframe when editing
  if (editMode) {
    // draw wireframe
    ofSetColor(ofColor::yellow);
    glLineWidth(2);

//    sceneMesh.drawWireframe();

    // ofvbo
    // ofvbomesh
    // ofxmesh
    // ofxhemesh

//    mesh.getFace(<#int faceId#>);

    // draw verts
    ofSetColor(ofColor::white);
    glPointSize(4);
    mesh.drawVertices();
  }

  // end camera
  cam.end();

  // vert selection
  if (editMode) {
    // create vec2 of the mouse for reference
    ofVec2f mouse(mouseX, mouseY);
    // if not dragging the mouse, find the nearest vert
    if (!mouseDragging) {
      // loop through all verticies in mesh and find the nearest vert position and index
      int n = mesh.getNumVertices();
      float nearestDistance = 0;
      for(int i = 0; i < n; i++) {
        ofVec3f cur = cam.worldToScreen(mesh.getVertex(i));
        float distance = cur.distance(mouse);
        if(i == 0 || distance < nearestDistance) {
          nearestDistance = distance;
          nearestVertex = cur;
          nearestIndex = i;
        }
      }
    }

    // draw a line from the nearest vertex to the mouse position
    ofSetColor(ofColor::gray);
    ofSetLineWidth(1);
    ofLine(nearestVertex, mouse);

    // draw a cirle around the nearest vertex
    ofNoFill();
    ofSetColor(ofColor::magenta);
    ofSetLineWidth(2);
    if (mouseDragging) {
      ofCircle(mouse, 4);
    } else {
      ofCircle(nearestVertex, 4);
    }
    ofSetLineWidth(1);

    // edit position of nearest vert with mousedrag
    if (!camMouse && mouseDragging) {
      mesh.setVertex(nearestIndex, cam.screenToWorld(ofVec3f(mouse.x, mouse.y, nearestVertex.z)));
    }

    // draw a label with the nearest vertex index
    ofDrawBitmapStringHighlight(ofToString(nearestIndex), mouse + ofVec2f(10, -10));
  }

  // draw info text
  if (showHelp) {
    stringstream ss;
    ss << "Framerate " << ofToString(ofGetFrameRate(),0) << "\n";
    ss << "  f : Toggle Fullscreen" << "\n";
    ss << "  h : Toggle Help Text" << "\n";
    ss << "  c : Toggle Camera Control : " << (camMouse == true ? "ON" : "OFF") << "\n";
    ss << "TAB : Toggle Mesh Edit : " << (editMode == true ? "ON" : "OFF") << "\n";
    ss << "  s : Save Scene" << "\n";
    ss << "  l : Load Scene";
    ofSetColor(ofColor::white);
    ofDrawBitmapStringHighlight(ss.str().c_str(), ofVec3f(10, 20), ofColor(45), ofColor(255));
  }
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

	switch(key) {

    // toggle fullscreen
		case 'f':
			ofToggleFullscreen();
			break;

    // toggle camera control
    case 'c':
      camMouse = !camMouse;
      camMouse ? cam.enableMouseInput() : cam.disableMouseInput();
			break;

    // saves the camera and mesh settings
    case 's':
      ofxSaveCamera(cam, "cameraSettings");
      mesh.save("mesh-tweaked.ply");
      break;

    // loads camera and mesh settings
    case 'l':
      ofxLoadCamera(cam, "cameraSettings");
      mesh.load("mesh-tweaked.ply");
      camMouse = false;
      editMode = false;
      break;

    // show help
    case 'h':
      showHelp = !showHelp;
      break;

    // toggle 'TAB' to edit verts
    case OF_KEY_TAB:
      editMode = !editMode;
      if (!editMode) {
        sceneMesh.clear();
        sceneMesh.append(mesh);
        sceneMesh.smoothNormals( normalSmoothAmt );
      }
      break;
	}
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
  mouseDragging = true;
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
  mouseDragging = false;
}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<|endoftext|>