<commit_before>/*
 * Copyright 2016 Google Inc.
 *
 * 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 <cstdio>
#include <cstdlib>
#include <exception>
#include <memory>
#include <string>
#include <sstream>
#include <string.h>
#include "png.h"
#include "guetzli/jpeg_data.h"
#include "guetzli/jpeg_data_reader.h"
#include "guetzli/processor.h"
#include "guetzli/quality.h"
#include "guetzli/stats.h"

namespace {

constexpr int kDefaultJPEGQuality = 95;

// An upper estimate of memory usage of Guetzli. The bound is
// max(kLowerMemusaeMB * 1<<20, pixel_count * kBytesPerPixel)
constexpr int kBytesPerPixel = 300;
constexpr int kLowestMemusageMB = 100; // in MB

constexpr int kDefaultMemlimitMB = 6000; // in MB

inline uint8_t BlendOnBlack(const uint8_t val, const uint8_t alpha) {
  return (static_cast<int>(val) * static_cast<int>(alpha) + 128) / 255;
}

bool ReadPNG(const std::string& data, int* xsize, int* ysize,
             std::vector<uint8_t>* rgb) {
  png_structp png_ptr =
      png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (!png_ptr) {
    return false;
  }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    png_destroy_read_struct(&png_ptr, nullptr, nullptr);
    return false;
  }

  if (setjmp(png_jmpbuf(png_ptr)) != 0) {
    // Ok we are here because of the setjmp.
    png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
    return false;
  }

  std::istringstream memstream(data, std::ios::in | std::ios::binary);
  png_set_read_fn(png_ptr, static_cast<void*>(&memstream), [](png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead) {
    std::istringstream& memstream = *static_cast<std::istringstream*>(png_get_io_ptr(png_ptr));

    memstream.read(reinterpret_cast<char*>(outBytes), byteCountToRead);

    if (memstream.eof()) png_error(png_ptr, "unexpected end of data");
    if (memstream.fail()) png_error(png_ptr, "read from memory error");
  });

  // The png_transforms flags are as follows:
  // packing == convert 1,2,4 bit images,
  // strip == 16 -> 8 bits / channel,
  // shift == use sBIT dynamics, and
  // expand == palettes -> rgb, grayscale -> 8 bit images, tRNS -> alpha.
  const unsigned int png_transforms =
      PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_16;

  png_read_png(png_ptr, info_ptr, png_transforms, nullptr);

  png_bytep* row_pointers = png_get_rows(png_ptr, info_ptr);

  *xsize = png_get_image_width(png_ptr, info_ptr);
  *ysize = png_get_image_height(png_ptr, info_ptr);
  rgb->resize(3 * (*xsize) * (*ysize));

  const int components = png_get_channels(png_ptr, info_ptr);
  switch (components) {
    case 1: {
      // GRAYSCALE
      for (int y = 0; y < *ysize; ++y) {
        const uint8_t* row_in = row_pointers[y];
        uint8_t* row_out = &(*rgb)[3 * y * (*xsize)];
        for (int x = 0; x < *xsize; ++x) {
          const uint8_t gray = row_in[x];
          row_out[3 * x + 0] = gray;
          row_out[3 * x + 1] = gray;
          row_out[3 * x + 2] = gray;
        }
      }
      break;
    }
    case 2: {
      // GRAYSCALE + ALPHA
      for (int y = 0; y < *ysize; ++y) {
        const uint8_t* row_in = row_pointers[y];
        uint8_t* row_out = &(*rgb)[3 * y * (*xsize)];
        for (int x = 0; x < *xsize; ++x) {
          const uint8_t gray = BlendOnBlack(row_in[2 * x], row_in[2 * x + 1]);
          row_out[3 * x + 0] = gray;
          row_out[3 * x + 1] = gray;
          row_out[3 * x + 2] = gray;
        }
      }
      break;
    }
    case 3: {
      // RGB
      for (int y = 0; y < *ysize; ++y) {
        const uint8_t* row_in = row_pointers[y];
        uint8_t* row_out = &(*rgb)[3 * y * (*xsize)];
        memcpy(row_out, row_in, 3 * (*xsize));
      }
      break;
    }
    case 4: {
      // RGBA
      for (int y = 0; y < *ysize; ++y) {
        const uint8_t* row_in = row_pointers[y];
        uint8_t* row_out = &(*rgb)[3 * y * (*xsize)];
        for (int x = 0; x < *xsize; ++x) {
          const uint8_t alpha = row_in[4 * x + 3];
          row_out[3 * x + 0] = BlendOnBlack(row_in[4 * x + 0], alpha);
          row_out[3 * x + 1] = BlendOnBlack(row_in[4 * x + 1], alpha);
          row_out[3 * x + 2] = BlendOnBlack(row_in[4 * x + 2], alpha);
        }
      }
      break;
    }
    default:
      png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
      return false;
  }
  png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
  return true;
}

std::string ReadFileOrDie(const char* filename) {
  bool read_from_stdin = strncmp(filename, "-", 2) == 0;

  FILE* f = read_from_stdin ? stdin : fopen(filename, "rb");
  if (!f) {
    perror("Can't open input file");
    exit(1);
  }

  std::string result;
  off_t buffer_size = 8192;

  if (fseek(f, 0, SEEK_END) == 0) {
    buffer_size = ftell(f);
    if (fseek(f, 0, SEEK_SET) != 0) {
      perror("fseek");
      exit(1);
    }
  } else if (ferror(f)) {
    perror("fseek");
    exit(1);
  }

  std::unique_ptr<char[]> buf(new char[buffer_size]);
  while (!feof(f)) {
    size_t read_bytes = fread(buf.get(), sizeof(char), buffer_size, f);
    if (ferror(f)) {
      perror("fread");
      exit(1);
    }
    result.append(buf.get(), read_bytes);
  }

  fclose(f);
  return result;
}

void WriteFileOrDie(const char* filename, const std::string& contents) {
  bool write_to_stdout = strncmp(filename, "-", 2) == 0;

  FILE* f = write_to_stdout ? stdout : fopen(filename, "wb");
  if (!f) {
    perror("Can't open output file for writing");
    exit(1);
  }
  if (fwrite(contents.data(), 1, contents.size(), f) != contents.size()) {
    perror("fwrite");
    exit(1);
  }
  if (fclose(f) < 0) {
    perror("fclose");
    exit(1);
  }
}

void TerminateHandler() {
  fprintf(stderr, "Unhandled exception. Most likely insufficient memory available.\n"
          "Make sure that there is 300MB/MPix of memory available.\n");
  exit(1);
}

void Usage() {
  fprintf(stderr,
      "Guetzli JPEG compressor. Usage: \n"
      "guetzli [flags] input_filename output_filename\n"
      "\n"
      "Flags:\n"
      "  --verbose    - Print a verbose trace of all attempts to standard output.\n"
      "  --quality Q  - Visual quality to aim for, expressed as a JPEG quality value.\n"
      "                 Default value is %d.\n"
      "  --memlimit M - Memory limit in MB. Guetzli will fail if unable to stay under\n"
      "                 the limit. Default limit is %d MB.\n"
      "  --nomemlimit - Do not limit memory usage.\n", kDefaultJPEGQuality, kDefaultMemlimitMB);
  exit(1);
}

}  // namespace

int main(int argc, char** argv) {
  std::set_terminate(TerminateHandler);

  int verbose = 0;
  int quality = kDefaultJPEGQuality;
  int memlimit_mb = kDefaultMemlimitMB;

  int opt_idx = 1;
  for(;opt_idx < argc;opt_idx++) {
    if (strnlen(argv[opt_idx], 2) < 2 || argv[opt_idx][0] != '-' || argv[opt_idx][1] != '-')
      break;
    if (!strcmp(argv[opt_idx], "--verbose")) {
      verbose = 1;
    } else if (!strcmp(argv[opt_idx], "--quality")) {
      opt_idx++;
      if (opt_idx >= argc)
        Usage();
      quality = atoi(argv[opt_idx]);
    } else if (!strcmp(argv[opt_idx], "--memlimit")) {
      opt_idx++;
      if (opt_idx >= argc)
        Usage();
      memlimit_mb = atoi(argv[opt_idx]);
    } else if (!strcmp(argv[opt_idx], "--nomemlimit")) {
      memlimit_mb = -1;
    } else if (!strcmp(argv[opt_idx], "--")) {
      opt_idx++;
      break;
    } else {
      fprintf(stderr, "Unknown commandline flag: %s\n", argv[opt_idx]);
      Usage();
    }
  }

  if (argc - opt_idx != 2) {
    Usage();
  }

  std::string in_data = ReadFileOrDie(argv[opt_idx]);
  std::string out_data;

  guetzli::Params params;
  params.butteraugli_target =
      guetzli::ButteraugliScoreForQuality(quality);

  guetzli::ProcessStats stats;

  if (verbose) {
    stats.debug_output_file = stderr;
  }

  static const unsigned char kPNGMagicBytes[] = {
      0x89, 'P', 'N', 'G', '\r', '\n', 0x1a, '\n',
  };
  if (in_data.size() >= 8 &&
      memcmp(in_data.data(), kPNGMagicBytes, sizeof(kPNGMagicBytes)) == 0) {
    int xsize, ysize;
    std::vector<uint8_t> rgb;
    if (!ReadPNG(in_data, &xsize, &ysize, &rgb)) {
      fprintf(stderr, "Error reading PNG data from input file\n");
      return 1;
    }
    double pixels = static_cast<double>(xsize) * ysize;
    if (memlimit_mb != -1
        && (pixels * kBytesPerPixel / (1 << 20) > memlimit_mb
            || memlimit_mb < kLowestMemusageMB)) {
      fprintf(stderr, "Memory limit would be exceeded. Failing.\n");
      return 1;
    }
    if (!guetzli::Process(params, &stats, rgb, xsize, ysize, &out_data)) {
      fprintf(stderr, "Guetzli processing failed\n");
      return 1;
    }
  } else {
    guetzli::JPEGData jpg_header;
    if (!guetzli::ReadJpeg(in_data, guetzli::JPEG_READ_HEADER, &jpg_header)) {
      fprintf(stderr, "Error reading JPG data from input file\n");
      return 1;
    }
    double pixels = static_cast<double>(jpg_header.width) * jpg_header.height;
    if (memlimit_mb != -1
        && (pixels * kBytesPerPixel / (1 << 20) > memlimit_mb
            || memlimit_mb < kLowestMemusageMB)) {
      fprintf(stderr, "Memory limit would be exceeded. Failing.\n");
      return 1;
    }
    if (!guetzli::Process(params, &stats, in_data, &out_data)) {
      fprintf(stderr, "Guetzli processing failed\n");
      return 1;
    }
  }

  WriteFileOrDie(argv[opt_idx + 1], out_data);
  return 0;
}
<commit_msg>Update the memory usage estimate to 200 bytes / pixel.<commit_after>/*
 * Copyright 2016 Google Inc.
 *
 * 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 <cstdio>
#include <cstdlib>
#include <exception>
#include <memory>
#include <string>
#include <sstream>
#include <string.h>
#include "png.h"
#include "guetzli/jpeg_data.h"
#include "guetzli/jpeg_data_reader.h"
#include "guetzli/processor.h"
#include "guetzli/quality.h"
#include "guetzli/stats.h"

namespace {

constexpr int kDefaultJPEGQuality = 95;

// An upper estimate of memory usage of Guetzli. The bound is
// max(kLowerMemusaeMB * 1<<20, pixel_count * kBytesPerPixel)
constexpr int kBytesPerPixel = 200;
constexpr int kLowestMemusageMB = 100; // in MB

constexpr int kDefaultMemlimitMB = 6000; // in MB

inline uint8_t BlendOnBlack(const uint8_t val, const uint8_t alpha) {
  return (static_cast<int>(val) * static_cast<int>(alpha) + 128) / 255;
}

bool ReadPNG(const std::string& data, int* xsize, int* ysize,
             std::vector<uint8_t>* rgb) {
  png_structp png_ptr =
      png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (!png_ptr) {
    return false;
  }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    png_destroy_read_struct(&png_ptr, nullptr, nullptr);
    return false;
  }

  if (setjmp(png_jmpbuf(png_ptr)) != 0) {
    // Ok we are here because of the setjmp.
    png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
    return false;
  }

  std::istringstream memstream(data, std::ios::in | std::ios::binary);
  png_set_read_fn(png_ptr, static_cast<void*>(&memstream), [](png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead) {
    std::istringstream& memstream = *static_cast<std::istringstream*>(png_get_io_ptr(png_ptr));

    memstream.read(reinterpret_cast<char*>(outBytes), byteCountToRead);

    if (memstream.eof()) png_error(png_ptr, "unexpected end of data");
    if (memstream.fail()) png_error(png_ptr, "read from memory error");
  });

  // The png_transforms flags are as follows:
  // packing == convert 1,2,4 bit images,
  // strip == 16 -> 8 bits / channel,
  // shift == use sBIT dynamics, and
  // expand == palettes -> rgb, grayscale -> 8 bit images, tRNS -> alpha.
  const unsigned int png_transforms =
      PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_STRIP_16;

  png_read_png(png_ptr, info_ptr, png_transforms, nullptr);

  png_bytep* row_pointers = png_get_rows(png_ptr, info_ptr);

  *xsize = png_get_image_width(png_ptr, info_ptr);
  *ysize = png_get_image_height(png_ptr, info_ptr);
  rgb->resize(3 * (*xsize) * (*ysize));

  const int components = png_get_channels(png_ptr, info_ptr);
  switch (components) {
    case 1: {
      // GRAYSCALE
      for (int y = 0; y < *ysize; ++y) {
        const uint8_t* row_in = row_pointers[y];
        uint8_t* row_out = &(*rgb)[3 * y * (*xsize)];
        for (int x = 0; x < *xsize; ++x) {
          const uint8_t gray = row_in[x];
          row_out[3 * x + 0] = gray;
          row_out[3 * x + 1] = gray;
          row_out[3 * x + 2] = gray;
        }
      }
      break;
    }
    case 2: {
      // GRAYSCALE + ALPHA
      for (int y = 0; y < *ysize; ++y) {
        const uint8_t* row_in = row_pointers[y];
        uint8_t* row_out = &(*rgb)[3 * y * (*xsize)];
        for (int x = 0; x < *xsize; ++x) {
          const uint8_t gray = BlendOnBlack(row_in[2 * x], row_in[2 * x + 1]);
          row_out[3 * x + 0] = gray;
          row_out[3 * x + 1] = gray;
          row_out[3 * x + 2] = gray;
        }
      }
      break;
    }
    case 3: {
      // RGB
      for (int y = 0; y < *ysize; ++y) {
        const uint8_t* row_in = row_pointers[y];
        uint8_t* row_out = &(*rgb)[3 * y * (*xsize)];
        memcpy(row_out, row_in, 3 * (*xsize));
      }
      break;
    }
    case 4: {
      // RGBA
      for (int y = 0; y < *ysize; ++y) {
        const uint8_t* row_in = row_pointers[y];
        uint8_t* row_out = &(*rgb)[3 * y * (*xsize)];
        for (int x = 0; x < *xsize; ++x) {
          const uint8_t alpha = row_in[4 * x + 3];
          row_out[3 * x + 0] = BlendOnBlack(row_in[4 * x + 0], alpha);
          row_out[3 * x + 1] = BlendOnBlack(row_in[4 * x + 1], alpha);
          row_out[3 * x + 2] = BlendOnBlack(row_in[4 * x + 2], alpha);
        }
      }
      break;
    }
    default:
      png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
      return false;
  }
  png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
  return true;
}

std::string ReadFileOrDie(const char* filename) {
  bool read_from_stdin = strncmp(filename, "-", 2) == 0;

  FILE* f = read_from_stdin ? stdin : fopen(filename, "rb");
  if (!f) {
    perror("Can't open input file");
    exit(1);
  }

  std::string result;
  off_t buffer_size = 8192;

  if (fseek(f, 0, SEEK_END) == 0) {
    buffer_size = ftell(f);
    if (fseek(f, 0, SEEK_SET) != 0) {
      perror("fseek");
      exit(1);
    }
  } else if (ferror(f)) {
    perror("fseek");
    exit(1);
  }

  std::unique_ptr<char[]> buf(new char[buffer_size]);
  while (!feof(f)) {
    size_t read_bytes = fread(buf.get(), sizeof(char), buffer_size, f);
    if (ferror(f)) {
      perror("fread");
      exit(1);
    }
    result.append(buf.get(), read_bytes);
  }

  fclose(f);
  return result;
}

void WriteFileOrDie(const char* filename, const std::string& contents) {
  bool write_to_stdout = strncmp(filename, "-", 2) == 0;

  FILE* f = write_to_stdout ? stdout : fopen(filename, "wb");
  if (!f) {
    perror("Can't open output file for writing");
    exit(1);
  }
  if (fwrite(contents.data(), 1, contents.size(), f) != contents.size()) {
    perror("fwrite");
    exit(1);
  }
  if (fclose(f) < 0) {
    perror("fclose");
    exit(1);
  }
}

void TerminateHandler() {
  fprintf(stderr, "Unhandled exception. Most likely insufficient memory available.\n"
          "Make sure that there is 300MB/MPix of memory available.\n");
  exit(1);
}

void Usage() {
  fprintf(stderr,
      "Guetzli JPEG compressor. Usage: \n"
      "guetzli [flags] input_filename output_filename\n"
      "\n"
      "Flags:\n"
      "  --verbose    - Print a verbose trace of all attempts to standard output.\n"
      "  --quality Q  - Visual quality to aim for, expressed as a JPEG quality value.\n"
      "                 Default value is %d.\n"
      "  --memlimit M - Memory limit in MB. Guetzli will fail if unable to stay under\n"
      "                 the limit. Default limit is %d MB.\n"
      "  --nomemlimit - Do not limit memory usage.\n", kDefaultJPEGQuality, kDefaultMemlimitMB);
  exit(1);
}

}  // namespace

int main(int argc, char** argv) {
  std::set_terminate(TerminateHandler);

  int verbose = 0;
  int quality = kDefaultJPEGQuality;
  int memlimit_mb = kDefaultMemlimitMB;

  int opt_idx = 1;
  for(;opt_idx < argc;opt_idx++) {
    if (strnlen(argv[opt_idx], 2) < 2 || argv[opt_idx][0] != '-' || argv[opt_idx][1] != '-')
      break;
    if (!strcmp(argv[opt_idx], "--verbose")) {
      verbose = 1;
    } else if (!strcmp(argv[opt_idx], "--quality")) {
      opt_idx++;
      if (opt_idx >= argc)
        Usage();
      quality = atoi(argv[opt_idx]);
    } else if (!strcmp(argv[opt_idx], "--memlimit")) {
      opt_idx++;
      if (opt_idx >= argc)
        Usage();
      memlimit_mb = atoi(argv[opt_idx]);
    } else if (!strcmp(argv[opt_idx], "--nomemlimit")) {
      memlimit_mb = -1;
    } else if (!strcmp(argv[opt_idx], "--")) {
      opt_idx++;
      break;
    } else {
      fprintf(stderr, "Unknown commandline flag: %s\n", argv[opt_idx]);
      Usage();
    }
  }

  if (argc - opt_idx != 2) {
    Usage();
  }

  std::string in_data = ReadFileOrDie(argv[opt_idx]);
  std::string out_data;

  guetzli::Params params;
  params.butteraugli_target =
      guetzli::ButteraugliScoreForQuality(quality);

  guetzli::ProcessStats stats;

  if (verbose) {
    stats.debug_output_file = stderr;
  }

  static const unsigned char kPNGMagicBytes[] = {
      0x89, 'P', 'N', 'G', '\r', '\n', 0x1a, '\n',
  };
  if (in_data.size() >= 8 &&
      memcmp(in_data.data(), kPNGMagicBytes, sizeof(kPNGMagicBytes)) == 0) {
    int xsize, ysize;
    std::vector<uint8_t> rgb;
    if (!ReadPNG(in_data, &xsize, &ysize, &rgb)) {
      fprintf(stderr, "Error reading PNG data from input file\n");
      return 1;
    }
    double pixels = static_cast<double>(xsize) * ysize;
    if (memlimit_mb != -1
        && (pixels * kBytesPerPixel / (1 << 20) > memlimit_mb
            || memlimit_mb < kLowestMemusageMB)) {
      fprintf(stderr, "Memory limit would be exceeded. Failing.\n");
      return 1;
    }
    if (!guetzli::Process(params, &stats, rgb, xsize, ysize, &out_data)) {
      fprintf(stderr, "Guetzli processing failed\n");
      return 1;
    }
  } else {
    guetzli::JPEGData jpg_header;
    if (!guetzli::ReadJpeg(in_data, guetzli::JPEG_READ_HEADER, &jpg_header)) {
      fprintf(stderr, "Error reading JPG data from input file\n");
      return 1;
    }
    double pixels = static_cast<double>(jpg_header.width) * jpg_header.height;
    if (memlimit_mb != -1
        && (pixels * kBytesPerPixel / (1 << 20) > memlimit_mb
            || memlimit_mb < kLowestMemusageMB)) {
      fprintf(stderr, "Memory limit would be exceeded. Failing.\n");
      return 1;
    }
    if (!guetzli::Process(params, &stats, in_data, &out_data)) {
      fprintf(stderr, "Guetzli processing failed\n");
      return 1;
    }
  }

  WriteFileOrDie(argv[opt_idx + 1], out_data);
  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2011-2012 Gregory Banks
 *
 * 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 "np/spiegel/common.hxx"
#include "state.hxx"
#include "compile_unit.hxx"
#include "walker.hxx"
#include "enumerations.hxx"

namespace np { namespace spiegel { namespace dwarf {
using namespace std;
using namespace np::util;

bool
compile_unit_t::read_header(reader_t &r)
{
    reader_ = r;	    // sample offset of start of header

    np::spiegel::offset_t length;
    uint16_t version;
    bool is64 = false;
    if (!r.read_u32(length))
	return false;
    if (length == 0xffffffff)
    {
	/* An all-1 length marks the 64-bit format
	 * introduced in the DWARF3 standard */
#if _NP_ADDRSIZE == 4
	fatal("The 64-bit DWARF format is not supported on 32-bit architectures");
#elif _NP_ADDRSIZE == 8
	is64 = true;
	if (!r.read_u64(length))
	    return false;
#else
#error "Unknown address size"
#endif
    }
    if (length > r.get_remains())
	fatal("Bad DWARF compilation unit length %llu", (unsigned long long)length);

    if (!r.read_u16(version))
	return false;
    if (version < MIN_DWARF_VERSION || version > MAX_DWARF_VERSION)
	fatal("Bad DWARF version %u, expecting %u-%u",
	      version, MIN_DWARF_VERSION, MAX_DWARF_VERSION);
    if (length < (unsigned)(header_length-(is64 ? 14 : 6)/*read so far*/))
	fatal("Bad DWARF compilation unit length %llu", (unsigned long long)length);

    uint8_t addrsize;
    if (!r.read_u32(abbrevs_offset_) ||
	!r.read_u8(addrsize))
	return false;
    if (addrsize != _NP_ADDRSIZE) fatal("Bad DWARF addrsize %u, expecting %u",
	      addrsize, _NP_ADDRSIZE);

#if _NP_DEBUG
    printf("DWARF compilation unit header\n");
    printf("    length %u\n", (unsigned)length);
    printf("    version %u\n", (unsigned)version);
    printf("    is64 %s\n", is64 ? "true" : "false");
    printf("    abbrevs_offset %u\n", (unsigned)abbrevs_offset_);
    printf("    addrsize %u\n", (unsigned)addrsize);
#endif

    version_ = version;
    is64_ = is64;

    length += is64 ? 12 : 4;	// account for the `length' field of the header

    // setup reader_ to point to the whole compile
    // unit but not any bytes of the next one
    reader_.set_is64(is64);
    reader_ = reader_.initial_subset(length);

    // skip the outer reader over the body
    r.skip(length - header_length);

    return true;
}

void
compile_unit_t::read_abbrevs(reader_t &r)
{
    r.seek(abbrevs_offset_);

    uint32_t code;
    /* code 0 indicates end of compile unit */
    while (r.read_uleb128(code) && code)
    {
	abbrev_t *a = new abbrev_t(code);
	if (!a->read(r))
	{
	    delete a;
	    break;
	}
	if (a->code >= abbrevs_.size())
	    abbrevs_.resize(a->code+1, 0);
	abbrevs_[a->code] = a;
    }
}

void
compile_unit_t::dump_abbrevs() const
{
    printf("Abbrevs {\n");

    vector<abbrev_t*>::const_iterator itr;
    for (itr = abbrevs_.begin() ; itr != abbrevs_.end() ; ++itr)
    {
	abbrev_t *a = *itr;
	if (!a) continue;
	printf("Code %u\n", a->code);
	printf("    tag 0x%x (%s)\n", a->tag, tagnames.to_name(a->tag));
	printf("    children %u (%s)\n",
		(unsigned)a->children,
		childvals.to_name(a->children));
	printf("    attribute specifications {\n");

	vector<abbrev_t::attr_spec_t>::iterator i;
	for (i = a->attr_specs.begin() ; i != a->attr_specs.end() ; ++i)
	{
	    printf("        name 0x%x (%s)",
		    i->name, attrnames.to_name(i->name));
	    printf(" form 0x%x (%s)\n",
		    i->form, formvals.to_name(i->form));
	}
	printf("    }\n");
    }
    printf("}\n");
}

const char *
compile_unit_t::get_executable() const
{
    const state_t::linkobj_t *lo = state_t::instance()->linkobjs_[loindex_];
    return lo->filename_;
}

const section_t *
compile_unit_t::get_section(uint32_t i) const
{
    const state_t::linkobj_t *lo = state_t::instance()->linkobjs_[loindex_];
    return &lo->sections_[i];
}

// close namespaces
}; }; };
<commit_msg>Fix some error messages<commit_after>/*
 * Copyright 2011-2012 Gregory Banks
 *
 * 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 "np/spiegel/common.hxx"
#include "state.hxx"
#include "compile_unit.hxx"
#include "walker.hxx"
#include "enumerations.hxx"

namespace np { namespace spiegel { namespace dwarf {
using namespace std;
using namespace np::util;

bool
compile_unit_t::read_header(reader_t &r)
{
    reader_ = r;	    // sample offset of start of header

    np::spiegel::offset_t length;
    uint16_t version;
    bool is64 = false;
    if (!r.read_u32(length))
	return false;
    if (length == 0xffffffff)
    {
	/* An all-1 length marks the 64-bit format
	 * introduced in the DWARF3 standard */
#if _NP_ADDRSIZE == 4
	fatal("The 64-bit DWARF format is not supported on 32-bit architectures");
#elif _NP_ADDRSIZE == 8
	is64 = true;
	if (!r.read_u64(length))
	    return false;
#else
#error "Unknown address size"
#endif
    }
    if (length > r.get_remains())
	fatal("Bad DWARF compile unit length %llu", (unsigned long long)length);

    if (!r.read_u16(version))
	return false;
    if (version < MIN_DWARF_VERSION || version > MAX_DWARF_VERSION)
	fatal("Bad DWARF version %u, expecting %u-%u",
	      version, MIN_DWARF_VERSION, MAX_DWARF_VERSION);
    if (length < (unsigned)(header_length-(is64 ? 14 : 6)/*read so far*/))
	fatal("Bad DWARF compile unit length %llu", (unsigned long long)length);

    uint8_t addrsize;
    if (!r.read_u32(abbrevs_offset_) ||
	!r.read_u8(addrsize))
	return false;
    if (addrsize != _NP_ADDRSIZE) fatal("Bad DWARF addrsize %u, expecting %u",
	      addrsize, _NP_ADDRSIZE);

#if _NP_DEBUG
    printf("DWARF compilation unit header\n");
    printf("    length %u\n", (unsigned)length);
    printf("    version %u\n", (unsigned)version);
    printf("    is64 %s\n", is64 ? "true" : "false");
    printf("    abbrevs_offset %u\n", (unsigned)abbrevs_offset_);
    printf("    addrsize %u\n", (unsigned)addrsize);
#endif

    version_ = version;
    is64_ = is64;

    length += is64 ? 12 : 4;	// account for the `length' field of the header

    // setup reader_ to point to the whole compile
    // unit but not any bytes of the next one
    reader_.set_is64(is64);
    reader_ = reader_.initial_subset(length);

    // skip the outer reader over the body
    r.skip(length - header_length);

    return true;
}

void
compile_unit_t::read_abbrevs(reader_t &r)
{
    r.seek(abbrevs_offset_);

    uint32_t code;
    /* code 0 indicates end of compile unit */
    while (r.read_uleb128(code) && code)
    {
	abbrev_t *a = new abbrev_t(code);
	if (!a->read(r))
	{
	    delete a;
	    break;
	}
	if (a->code >= abbrevs_.size())
	    abbrevs_.resize(a->code+1, 0);
	abbrevs_[a->code] = a;
    }
}

void
compile_unit_t::dump_abbrevs() const
{
    printf("Abbrevs {\n");

    vector<abbrev_t*>::const_iterator itr;
    for (itr = abbrevs_.begin() ; itr != abbrevs_.end() ; ++itr)
    {
	abbrev_t *a = *itr;
	if (!a) continue;
	printf("Code %u\n", a->code);
	printf("    tag 0x%x (%s)\n", a->tag, tagnames.to_name(a->tag));
	printf("    children %u (%s)\n",
		(unsigned)a->children,
		childvals.to_name(a->children));
	printf("    attribute specifications {\n");

	vector<abbrev_t::attr_spec_t>::iterator i;
	for (i = a->attr_specs.begin() ; i != a->attr_specs.end() ; ++i)
	{
	    printf("        name 0x%x (%s)",
		    i->name, attrnames.to_name(i->name));
	    printf(" form 0x%x (%s)\n",
		    i->form, formvals.to_name(i->form));
	}
	printf("    }\n");
    }
    printf("}\n");
}

const char *
compile_unit_t::get_executable() const
{
    const state_t::linkobj_t *lo = state_t::instance()->linkobjs_[loindex_];
    return lo->filename_;
}

const section_t *
compile_unit_t::get_section(uint32_t i) const
{
    const state_t::linkobj_t *lo = state_t::instance()->linkobjs_[loindex_];
    return &lo->sections_[i];
}

// close namespaces
}; }; };
<|endoftext|>


<commit_before><commit_msg>tdf#93052 Fix abundance of calc annotation styles<commit_after><|endoftext|>


<commit_before>#include "j1App.h"
#include "j1Render.h"
#include "p2Log.h"
#include "j1Camera.h"
#include "j1Player.h"
#include "j1Window.h"
#include "Color.h"
#include "GuiLabel.h"

j1Camera::j1Camera()
{
	name.create("camera");
}

j1Camera::~j1Camera()
{

}

// Called before render is available
bool j1Camera::Awake(pugi::xml_node&)
{
	//Create the ellipses
	LitleEllipse.ellipsecentre = { 0,0 };
	LitleEllipse.semimajoraxis = 320;
	LitleEllipse.semiminoraxis = 180;

	BigEllipse.ellipsecentre = { 0,0 };
	BigEllipse.semimajoraxis = 640;
	BigEllipse.semiminoraxis = 360;

	f_border_between_ellipses = BigEllipse.InsideEllipseValue({ 0,LitleEllipse.semiminoraxis});

	DebugPerformanceData_Rect = { 0,0,260,135 };

	return true;
}

// Called before the first frame
bool j1Camera::Start()
{
	//Get some useful variables
	f_Max_scale = App->win->scale;
	f_Min_scale = f_Max_scale - 0.3f;
	if (f_Min_scale < 0.8f)
		f_Min_scale = 0.8f;
	int w, h = 0;
	SDL_GetRendererOutputSize(App->render->renderer, &w, &h);
	i_Half_w = (int)(w * 0.5f);
	i_Half_h = (int)(h * 0.5f);

	//Fill up debug performance data vector
	for (int i = 0, pos = App->win->GetWindowH() - DebugPerformanceData_Rect.h + 6; i < 8; i++, pos += 15) //8, number of debug strings
		DebugPerformanceData.push_back(App->gui->CreateLabel({ 10,pos }, &std::string(""), false, AddGuiTo::none));
	DebugPerformanceData[6]->EditLabelStr(&std::string("Press F9 to toggle this window visibility."));
	DebugPerformanceData[6]->SetLabelColor(&Yellow);
	DebugPerformanceData[7]->EditLabelStr(&std::string("Press F10 to report a bug."));
	DebugPerformanceData[7]->SetLabelColor(&Yellow);

	return true;
}

// Called each loop iteration
bool j1Camera::PreUpdate()
{
	//Calculate camera centre
	/**/
	if (App->input->GetKey(SDL_SCANCODE_L) == KEY_REPEAT) App->win->scale += 0.005;
	if (App->input->GetKey(SDL_SCANCODE_K) == KEY_REPEAT) App->win->scale -= 0.005;
	/**/
	float Scale = App->win->GetScale();
	iPoint Centre = { 0,0 };
	Centre.x = (int)((((float)(App->player->Link->pos.x + App->player->Zelda->pos.x)) * 0.5f));
	Centre.y = (int)((((float)(App->player->Link->pos.y + App->player->Zelda->pos.y)) * 0.5f) );
	//Camera position
	App->render->camera.x = -Centre.x * Scale + i_Half_w;
	App->render->camera.y = -Centre.y * Scale + i_Half_h;
	//Ellipss centre
	iPoint CentrePos = { 0,0 };
	CentrePos = App->render->WorldToScreen(Centre.x, Centre.y);
	LitleEllipse.ellipsecentre = BigEllipse.ellipsecentre = { (int)(CentrePos.x), (int)(CentrePos.y) };

	//Debug Performance Data
	DebugPerformanceData_Rect.x = -App->render->camera.x;
	DebugPerformanceData_Rect.y = -App->render->camera.y + App->win->GetWindowH() - DebugPerformanceData_Rect.h;
	return true;
}

// Called each loop iteration
bool j1Camera::Update(float dt)
{
	iPoint LinkPos = { 0,0 };
	LinkPos = App->render->WorldToScreen(App->player->Link->pos.x, App->player->Link->pos.y);
	/**/
	//Is inside the little ellipse
	if (LitleEllipse.InsideEllipse(LinkPos))
		App->win->scale = f_Max_scale;
	//Is out the little ellipse
	else
	{
		//Is between the big ellipse and the little one
		if (BigEllipse.InsideEllipse(LinkPos))
		{
			//Scale between f_Max_scale and f_Min_scale
			float f_percentual_value = (((float)(BigEllipse.InsideEllipseValue(LinkPos) - f_border_between_ellipses)) / ((float)(1.0f - f_border_between_ellipses))) * 100.0f;
			float f_invert_percentual_value = 100.0f - f_percentual_value;
			if (f_invert_percentual_value < 0.0f)
				f_invert_percentual_value = 0.0f;
			else if (f_invert_percentual_value > 100.0f)
				f_invert_percentual_value = 100.0f;
			App->win->scale = (((f_Max_scale - f_Min_scale) * f_invert_percentual_value) / (100.0f)) + f_Min_scale;
		}
		//Is out the big ellipse
		else
			App->win->scale = f_Min_scale;
	}
	/**/

	//Some ellipses debug draw for testing
	/*
	//Little ellipse
	//Centre
	App->render->DrawCircle(LitleEllipse.ellipsecentre.x, LitleEllipse.ellipsecentre.y, 5, 0, 0, 255);
	//Axis
	App->render->DrawCircle(LitleEllipse.ellipsecentre.x + LitleEllipse.semimajoraxis, LitleEllipse.ellipsecentre.y, 5, 0, 0, 255);
	App->render->DrawCircle(LitleEllipse.ellipsecentre.x - LitleEllipse.semimajoraxis, LitleEllipse.ellipsecentre.y, 5, 0, 0, 255);
	App->render->DrawCircle(LitleEllipse.ellipsecentre.x, LitleEllipse.ellipsecentre.y + LitleEllipse.semiminoraxis, 5, 0, 0, 255);
	App->render->DrawCircle(LitleEllipse.ellipsecentre.x, LitleEllipse.ellipsecentre.y - LitleEllipse.semiminoraxis, 5, 0, 0, 255);

	//Big ellipse
	//Centre
	App->render->DrawCircle(BigEllipse.ellipsecentre.x, BigEllipse.ellipsecentre.y, 10, 255, 0, 0);
	//Axis
	App->render->DrawCircle(BigEllipse.ellipsecentre.x + BigEllipse.semimajoraxis, BigEllipse.ellipsecentre.y, 10, 255, 0, 0);
	App->render->DrawCircle(BigEllipse.ellipsecentre.x - BigEllipse.semimajoraxis, BigEllipse.ellipsecentre.y, 10, 255, 0, 0);
	App->render->DrawCircle(BigEllipse.ellipsecentre.x, BigEllipse.ellipsecentre.y + BigEllipse.semiminoraxis, 10, 255, 0, 0);
	App->render->DrawCircle(BigEllipse.ellipsecentre.x, BigEllipse.ellipsecentre.y - BigEllipse.semiminoraxis, 10, 255, 0, 0);
	*/

	//Debug window with perdformance data
	if (App->input->GetKey(SDL_SCANCODE_F9) == KEY_DOWN)
		f_DebugPerformanceData = !f_DebugPerformanceData;

	if (App->input->GetKey(SDL_SCANCODE_F10) == KEY_DOWN)
		ShellExecute(NULL, "open", "https://github.com/Guille1406/The-Legend-of-Zelda-Hyrule-Conquest/issues", NULL, NULL, SW_SHOWMAXIMIZED);

	if (f_DebugPerformanceData)
	{
		App->render->DrawQuad(DebugPerformanceData_Rect, Blue(0), Blue(1), Blue(2), 150, true, true, false);

		for (int i = 0; i < DebugPerformanceData.size(); i++)
		{
			switch (i)
			{
			case 0:
				static char AvFPS[25];
				sprintf_s(AvFPS, 25, "Av.FPS: %.2f", App->avg_fps);
				DebugPerformanceData[i]->EditLabelStr(&std::string(AvFPS));
				break;
			case 1:
				static char LastFrameMs[25];
				sprintf_s(LastFrameMs, 25, "Last Frame Ms: %u", App->last_frame_ms);
				DebugPerformanceData[i]->EditLabelStr(&std::string(LastFrameMs));
				break;
			case 2:
				static char Lastsecframes[25];
				sprintf_s(Lastsecframes, 25, "Last sec frames: %i", App->frames_on_last_update);
				DebugPerformanceData[i]->EditLabelStr(&std::string(Lastsecframes));
				break;
			case 3:
				static char Lastdt[25];
				sprintf_s(Lastdt, 25, "Last dt: %.3f", App->dt);
				DebugPerformanceData[i]->EditLabelStr(&std::string(Lastdt));
				break;
			case 4:
				static char Timesincestartup[100];
				sprintf_s(Timesincestartup, 100, "Time since startup: %.3f", App->seconds_since_startup);
				DebugPerformanceData[i]->EditLabelStr(&std::string(Timesincestartup));
				break;
			case 5:
				static char FrameCount[100];
				sprintf_s(FrameCount, 100, "Frame Count: %lu", App->frame_count);
				DebugPerformanceData[i]->EditLabelStr(&std::string(FrameCount));
				break;
			}
			DebugPerformanceData[i]->Draw();
		}
	}

	return true;
}

// Called each loop iteration
bool j1Camera::PostUpdate()
{
	return true;
}

// Called before quitting
bool j1Camera::CleanUp()
{
	LOG("Freeing camera");
	return true;
}

void j1Camera::OnGui(Gui* ui, GuiEvent event)
{

}

void j1Camera::OnConsoleCommand(const Command* command, const std::vector<std::string>& commandarguments)
{

}

void j1Camera::OnConsoleCVar(const CVar* cvar)
{

}<commit_msg>Camera Updated<commit_after>#include "j1App.h"
#include "j1Render.h"
#include "p2Log.h"
#include "j1Camera.h"
#include "j1Player.h"
#include "j1Window.h"
#include "Color.h"
#include "GuiLabel.h"

j1Camera::j1Camera()
{
	name.create("camera");
}

j1Camera::~j1Camera()
{

}

// Called before render is available
bool j1Camera::Awake(pugi::xml_node&)
{
	//Create the ellipses
	LitleEllipse.ellipsecentre = { 0,0 };
	LitleEllipse.semimajoraxis = 320;
	LitleEllipse.semiminoraxis = 180;

	BigEllipse.ellipsecentre = { 0,0 };
	BigEllipse.semimajoraxis = 640;
	BigEllipse.semiminoraxis = 360;

	f_border_between_ellipses = BigEllipse.InsideEllipseValue({ 0,LitleEllipse.semiminoraxis});

	DebugPerformanceData_Rect = { 0,0,260,135 };

	return true;
}

// Called before the first frame
bool j1Camera::Start()
{
	//Get some useful variables
	f_Max_scale = App->win->scale;
	f_Min_scale = f_Max_scale - 0.3f;
	if (f_Min_scale < 0.8f)
		f_Min_scale = 0.8f;
	int w, h = 0;
	SDL_GetRendererOutputSize(App->render->renderer, &w, &h);
	i_Half_w = (int)(w * 0.5f);
	i_Half_h = (int)(h * 0.5f);

	//Fill up debug performance data vector
	for (int i = 0, pos = App->win->GetWindowH() - DebugPerformanceData_Rect.h + 6; i < 8; i++, pos += 15) //8, number of debug strings
		DebugPerformanceData.push_back(App->gui->CreateLabel({ 10,pos }, &std::string(""), false, AddGuiTo::none));
	DebugPerformanceData[6]->EditLabelStr(&std::string("Press F9 to toggle this window visibility."));
	DebugPerformanceData[6]->SetLabelColor(&Yellow);
	DebugPerformanceData[7]->EditLabelStr(&std::string("Press F10 to report a bug."));
	DebugPerformanceData[7]->SetLabelColor(&Yellow);

	return true;
}

// Called each loop iteration
bool j1Camera::PreUpdate()
{
	//Calculate camera centre
	/**/
	if (App->input->GetKey(SDL_SCANCODE_L) == KEY_REPEAT) App->win->scale += 0.005;
	if (App->input->GetKey(SDL_SCANCODE_K) == KEY_REPEAT) App->win->scale -= 0.005;
	/**/
	float Scale = App->win->GetScale();
	iPoint Centre = { 0,0 };
	Centre.x = (int)((((float)(App->player->Link->pos.x + App->player->Zelda->pos.x)) * 0.5f));
	Centre.y = (int)((((float)(App->player->Link->pos.y + App->player->Zelda->pos.y)) * 0.5f) );
	//Camera position

	App->render->camera.x = -Centre.x * Scale + i_Half_w;
	App->render->camera.y = -Centre.y * Scale + i_Half_h;

	if (App->render->camera.x >= 0) App->render->camera.x = 0;
	if (-App->render->camera.x >= App->map->data.width * App->map->data.tile_width - App->render->camera.w / App->win->GetScale()) {
		App->render->camera.x = -1 * (App->map->data.width * App->map->data.tile_width - App->render->camera.w / App->win->GetScale());
	}

	if (App->render->camera.y >= 0) App->render->camera.y = 0;
	if (-App->render->camera.y >= App->map->data.height * App->map->data.tile_height - App->render->camera.h / App->win->GetScale()) {
		App->render->camera.y = -1 * (App->map->data.height * App->map->data.tile_height - App->render->camera.h / App->win->GetScale());
	}
	//Ellipss centre
	iPoint CentrePos = { 0,0 };
	CentrePos = App->render->WorldToScreen(Centre.x, Centre.y);
	LitleEllipse.ellipsecentre = BigEllipse.ellipsecentre = { (int)(CentrePos.x), (int)(CentrePos.y) };

	//Debug Performance Data
	DebugPerformanceData_Rect.x = -App->render->camera.x;
	DebugPerformanceData_Rect.y = -App->render->camera.y + App->win->GetWindowH() - DebugPerformanceData_Rect.h;
	return true;
}

// Called each loop iteration
bool j1Camera::Update(float dt)
{
	iPoint LinkPos = { 0,0 };
	LinkPos = App->render->WorldToScreen(App->player->Link->pos.x, App->player->Link->pos.y);
	/**/
	//Is inside the little ellipse
	if (LitleEllipse.InsideEllipse(LinkPos))
		App->win->scale = f_Max_scale;
	//Is out the little ellipse
	else
	{
		//Is between the big ellipse and the little one
		if (BigEllipse.InsideEllipse(LinkPos))
		{
			//Scale between f_Max_scale and f_Min_scale
			float f_percentual_value = (((float)(BigEllipse.InsideEllipseValue(LinkPos) - f_border_between_ellipses)) / ((float)(1.0f - f_border_between_ellipses))) * 100.0f;
			float f_invert_percentual_value = 100.0f - f_percentual_value;
			if (f_invert_percentual_value < 0.0f)
				f_invert_percentual_value = 0.0f;
			else if (f_invert_percentual_value > 100.0f)
				f_invert_percentual_value = 100.0f;
			App->win->scale = (((f_Max_scale - f_Min_scale) * f_invert_percentual_value) / (100.0f)) + f_Min_scale;
		}
		//Is out the big ellipse
		else
			App->win->scale = f_Min_scale;
	}
	/**/

	//Some ellipses debug draw for testing
	/*
	//Little ellipse
	//Centre
	App->render->DrawCircle(LitleEllipse.ellipsecentre.x, LitleEllipse.ellipsecentre.y, 5, 0, 0, 255);
	//Axis
	App->render->DrawCircle(LitleEllipse.ellipsecentre.x + LitleEllipse.semimajoraxis, LitleEllipse.ellipsecentre.y, 5, 0, 0, 255);
	App->render->DrawCircle(LitleEllipse.ellipsecentre.x - LitleEllipse.semimajoraxis, LitleEllipse.ellipsecentre.y, 5, 0, 0, 255);
	App->render->DrawCircle(LitleEllipse.ellipsecentre.x, LitleEllipse.ellipsecentre.y + LitleEllipse.semiminoraxis, 5, 0, 0, 255);
	App->render->DrawCircle(LitleEllipse.ellipsecentre.x, LitleEllipse.ellipsecentre.y - LitleEllipse.semiminoraxis, 5, 0, 0, 255);

	//Big ellipse
	//Centre
	App->render->DrawCircle(BigEllipse.ellipsecentre.x, BigEllipse.ellipsecentre.y, 10, 255, 0, 0);
	//Axis
	App->render->DrawCircle(BigEllipse.ellipsecentre.x + BigEllipse.semimajoraxis, BigEllipse.ellipsecentre.y, 10, 255, 0, 0);
	App->render->DrawCircle(BigEllipse.ellipsecentre.x - BigEllipse.semimajoraxis, BigEllipse.ellipsecentre.y, 10, 255, 0, 0);
	App->render->DrawCircle(BigEllipse.ellipsecentre.x, BigEllipse.ellipsecentre.y + BigEllipse.semiminoraxis, 10, 255, 0, 0);
	App->render->DrawCircle(BigEllipse.ellipsecentre.x, BigEllipse.ellipsecentre.y - BigEllipse.semiminoraxis, 10, 255, 0, 0);
	*/

	//Debug window with perdformance data
	if (App->input->GetKey(SDL_SCANCODE_F9) == KEY_DOWN)
		f_DebugPerformanceData = !f_DebugPerformanceData;

	if (App->input->GetKey(SDL_SCANCODE_F10) == KEY_DOWN)
		ShellExecute(NULL, "open", "https://github.com/Guille1406/The-Legend-of-Zelda-Hyrule-Conquest/issues", NULL, NULL, SW_SHOWMAXIMIZED);

	if (f_DebugPerformanceData)
	{
		App->render->DrawQuad(DebugPerformanceData_Rect, Blue(0), Blue(1), Blue(2), 150, true, true, false);

		for (int i = 0; i < DebugPerformanceData.size(); i++)
		{
			switch (i)
			{
			case 0:
				static char AvFPS[25];
				sprintf_s(AvFPS, 25, "Av.FPS: %.2f", App->avg_fps);
				DebugPerformanceData[i]->EditLabelStr(&std::string(AvFPS));
				break;
			case 1:
				static char LastFrameMs[25];
				sprintf_s(LastFrameMs, 25, "Last Frame Ms: %u", App->last_frame_ms);
				DebugPerformanceData[i]->EditLabelStr(&std::string(LastFrameMs));
				break;
			case 2:
				static char Lastsecframes[25];
				sprintf_s(Lastsecframes, 25, "Last sec frames: %i", App->frames_on_last_update);
				DebugPerformanceData[i]->EditLabelStr(&std::string(Lastsecframes));
				break;
			case 3:
				static char Lastdt[25];
				sprintf_s(Lastdt, 25, "Last dt: %.3f", App->dt);
				DebugPerformanceData[i]->EditLabelStr(&std::string(Lastdt));
				break;
			case 4:
				static char Timesincestartup[100];
				sprintf_s(Timesincestartup, 100, "Time since startup: %.3f", App->seconds_since_startup);
				DebugPerformanceData[i]->EditLabelStr(&std::string(Timesincestartup));
				break;
			case 5:
				static char FrameCount[100];
				sprintf_s(FrameCount, 100, "Frame Count: %lu", App->frame_count);
				DebugPerformanceData[i]->EditLabelStr(&std::string(FrameCount));
				break;
			}
			DebugPerformanceData[i]->Draw();
		}
	}

	return true;
}

// Called each loop iteration
bool j1Camera::PostUpdate()
{
	return true;
}

// Called before quitting
bool j1Camera::CleanUp()
{
	LOG("Freeing camera");
	return true;
}

void j1Camera::OnGui(Gui* ui, GuiEvent event)
{

}

void j1Camera::OnConsoleCommand(const Command* command, const std::vector<std::string>& commandarguments)
{

}

void j1Camera::OnConsoleCVar(const CVar* cvar)
{

}<|endoftext|>


<commit_before>#include "CRUD_Link.h"

#include "CRUD_Events.h"

// CRUD link receives messages from ServerEndpoint,
// these are basically CRUDP_Packets preprocessed by CRUDP_Protocol

// ServerEndpoint gets new input -> Bytes -> CRUDP_Protocol -> pushq(PacketEvent)
// ACE_Reactor knows to wake CRUDLink up, whenever there are new events

///
/// \brief CRUDLink::event_for_packet - convert incoming packet into higher level events and push them to our target()
/// \param pak_ev - received packet
///
void CRUDLink::event_for_packet(PacketEvent * pak_ev)
{
    CrudP_Packet *pak=pak_ev->m_pkt;
    // switch this to while, maybe many events are coming from single packet ?
    CRUDLink_Event *res = factory().EventFromStream(*pak->GetStream());
    if(!res)
    {
        ACE_ERROR((LM_ERROR, ACE_TEXT ("%p EventFromStream returned NULL\n")));
        return;
    }
    res->serializefrom(*pak->GetStream());
    res->src(this);
    res->seq_number = pak->GetSequenceNumber();
    target()->putq(res);
    if(pak->GetStream()->GetReadableBits()>1)
        ACE_DEBUG((LM_WARNING,ACE_TEXT("(%P|%t) leftover bits in packet: %s\n"),res->info()));
}
///
/// \brief CRUDLink::packets_for_event - convert event to 1-n packets and push them to our net_layer()
/// \param ev - an event that we've received from our downstream.
///
void CRUDLink::packets_for_event(SEGSEvent *ev)
{
    lCrudP_Packet packets;
    CRUDLink_Event *c_ev =static_cast<CRUDLink_Event *>(ev);
    CrudP_Packet *res   = new CrudP_Packet;
    ACE_ASSERT(res);
    ACE_DEBUG((LM_WARNING,ACE_TEXT("(%P|%t) packets_for_event %s\n"),ev->info()));

    c_ev->serializeto(*res->GetStream()); // serialize packet into res packet
    // create one or more properly formated CrudP_Packets in the protocol object
    m_protocol.SendPacket(res);
    size_t cnt=m_protocol.GetUnsentPackets(packets);
    // wrap all packets as PacketEvents and put them on link queue
    while(cnt--)
    {
        net_layer()->putq(new PacketEvent(this,*packets.begin(),peer_addr()));
        packets.pop_front();
    }
    connection_sent_packet(); // data was sent, update
}
int CRUDLink::open (void *p)
{
    if (EventProcessor::open (p) == -1)
        return -1;
    m_notifier.reactor(reactor());  // notify reactor with write event,
    msg_queue()->notification_strategy (&m_notifier);   // whenever there is a new event on msg_queue()
    connection_update(); // record first activity time.
    connection_sent_packet();
    return 0;
}
int CRUDLink::handle_output( ACE_HANDLE )
{
    SEGSEvent *ev;
    ACE_Time_Value nowait (ACE_OS::gettimeofday ());
    while (-1 != getq(ev, &nowait))
    {
        switch(ev->type())
        {
            case SEGS_EventTypes::evFinish:
                ev->release();
                return -1;
            case SEGS_EventTypes::evConnect:
                m_peer_addr=static_cast<ConnectEvent *>(ev)->src_addr;
                connection_update();
                break;
            case SEGS_EventTypes::evDisconnect:
                putq(new SEGSEvent(SEGS_EventTypes::evFinish)); // close the link
                break;
            case CRUD_EventTypes::evPacket: // CRUDP_Protocol has posted a pre-parsed packet to us
                event_for_packet(static_cast<PacketEvent *>(ev));
                connection_update(); // we've received some bytes -> connection update
                break;
            default:
                packets_for_event(static_cast<CRUDLink_Event *>(ev));
                break;
        }
        ev->release();
        //TODO: check how getq works when nowait is before now() ??
        //nowait = ACE_OS::gettimeofday();
        //TODO: consider breaking out of this loop after processing N messages ?
    }
    // Now if our message queue is empty, we will wait unitl m_notifier awakens us.
    if (msg_queue()->is_empty ()) // we don't want to be woken up
        reactor()->cancel_wakeup(this, ACE_Event_Handler::WRITE_MASK);
    else // unless there is something to send still
        reactor()->schedule_wakeup(this, ACE_Event_Handler::WRITE_MASK);
    return 0;
}
///
/// \brief CRUDLink::received_block - convert incoming bytes to PacketEvent's
/// \param bytes - raw data to convert into packets.
///
void CRUDLink::received_block( BitStream &bytes )
{
    size_t recv_count=0; // count of proper packets
    // Fill the protocol with 'raw' bit stream
    m_protocol.ReceivedBlock(bytes);
    // now try to get actual packets
    CrudP_Packet *pkt = m_protocol.RecvPacket(false);
    while(pkt)
    {
        putq(new PacketEvent(net_layer(),pkt,peer_addr()));
        ++recv_count;
        pkt=m_protocol.RecvPacket(false);
    }
    if(recv_count>0)
        connection_update(); //update the last time we've seen packets on this link
}

<commit_msg>fix a missed field rename<commit_after>#include "CRUD_Link.h"

#include "CRUD_Events.h"

// CRUD link receives messages from ServerEndpoint,
// these are basically CRUDP_Packets preprocessed by CRUDP_Protocol

// ServerEndpoint gets new input -> Bytes -> CRUDP_Protocol -> pushq(PacketEvent)
// ACE_Reactor knows to wake CRUDLink up, whenever there are new events

///
/// \brief CRUDLink::event_for_packet - convert incoming packet into higher level events and push them to our target()
/// \param pak_ev - received packet
///
void CRUDLink::event_for_packet(PacketEvent * pak_ev)
{
    CrudP_Packet *pak=pak_ev->m_pkt;
    // switch this to while, maybe many events are coming from single packet ?
    CRUDLink_Event *res = factory().EventFromStream(*pak->GetStream());
    if(!res)
    {
        ACE_ERROR((LM_ERROR, ACE_TEXT ("%p EventFromStream returned NULL\n")));
        return;
    }
    res->serializefrom(*pak->GetStream());
    res->src(this);
    res->m_seq_number = pak->GetSequenceNumber();
    target()->putq(res);
    if(pak->GetStream()->GetReadableBits()>1)
        ACE_DEBUG((LM_WARNING,ACE_TEXT("(%P|%t) leftover bits in packet: %s\n"),res->info()));
}
///
/// \brief CRUDLink::packets_for_event - convert event to 1-n packets and push them to our net_layer()
/// \param ev - an event that we've received from our downstream.
///
void CRUDLink::packets_for_event(SEGSEvent *ev)
{
    lCrudP_Packet packets;
    CRUDLink_Event *c_ev =static_cast<CRUDLink_Event *>(ev);
    CrudP_Packet *res   = new CrudP_Packet;
    ACE_ASSERT(res);
    ACE_DEBUG((LM_WARNING,ACE_TEXT("(%P|%t) packets_for_event %s\n"),ev->info()));

    c_ev->serializeto(*res->GetStream()); // serialize packet into res packet
    // create one or more properly formated CrudP_Packets in the protocol object
    m_protocol.SendPacket(res);
    size_t cnt=m_protocol.GetUnsentPackets(packets);
    // wrap all packets as PacketEvents and put them on link queue
    while(cnt--)
    {
        net_layer()->putq(new PacketEvent(this,*packets.begin(),peer_addr()));
        packets.pop_front();
    }
    connection_sent_packet(); // data was sent, update
}
int CRUDLink::open (void *p)
{
    if (EventProcessor::open (p) == -1)
        return -1;
    m_notifier.reactor(reactor());  // notify reactor with write event,
    msg_queue()->notification_strategy (&m_notifier);   // whenever there is a new event on msg_queue()
    connection_update(); // record first activity time.
    connection_sent_packet();
    return 0;
}
int CRUDLink::handle_output( ACE_HANDLE )
{
    SEGSEvent *ev;
    ACE_Time_Value nowait (ACE_OS::gettimeofday ());
    while (-1 != getq(ev, &nowait))
    {
        switch(ev->type())
        {
            case SEGS_EventTypes::evFinish:
                ev->release();
                return -1;
            case SEGS_EventTypes::evConnect:
                m_peer_addr=static_cast<ConnectEvent *>(ev)->src_addr;
                connection_update();
                break;
            case SEGS_EventTypes::evDisconnect:
                putq(new SEGSEvent(SEGS_EventTypes::evFinish)); // close the link
                break;
            case CRUD_EventTypes::evPacket: // CRUDP_Protocol has posted a pre-parsed packet to us
                event_for_packet(static_cast<PacketEvent *>(ev));
                connection_update(); // we've received some bytes -> connection update
                break;
            default:
                packets_for_event(static_cast<CRUDLink_Event *>(ev));
                break;
        }
        ev->release();
        //TODO: check how getq works when nowait is before now() ??
        //nowait = ACE_OS::gettimeofday();
        //TODO: consider breaking out of this loop after processing N messages ?
    }
    // Now if our message queue is empty, we will wait unitl m_notifier awakens us.
    if (msg_queue()->is_empty ()) // we don't want to be woken up
        reactor()->cancel_wakeup(this, ACE_Event_Handler::WRITE_MASK);
    else // unless there is something to send still
        reactor()->schedule_wakeup(this, ACE_Event_Handler::WRITE_MASK);
    return 0;
}
///
/// \brief CRUDLink::received_block - convert incoming bytes to PacketEvent's
/// \param bytes - raw data to convert into packets.
///
void CRUDLink::received_block( BitStream &bytes )
{
    size_t recv_count=0; // count of proper packets
    // Fill the protocol with 'raw' bit stream
    m_protocol.ReceivedBlock(bytes);
    // now try to get actual packets
    CrudP_Packet *pkt = m_protocol.RecvPacket(false);
    while(pkt)
    {
        putq(new PacketEvent(net_layer(),pkt,peer_addr()));
        ++recv_count;
        pkt=m_protocol.RecvPacket(false);
    }
    if(recv_count>0)
        connection_update(); //update the last time we've seen packets on this link
}

<|endoftext|>


<commit_before>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2012, Willow Garage, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Willow Garage nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

/* Author: Ioan Sucan */

#include <moveit/move_group_interface/move_group.h>
#include <moveit/py_bindings_tools/roscpp_initializer.h>
#include <moveit/py_bindings_tools/py_conversions.h>
#include <eigen_conversions/eigen_msg.h>

#include <boost/function.hpp>
#include <boost/python.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/stl_iterator.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>

#include <boost/shared_ptr.hpp>
#include <Python.h>
#include <ros/ros.h>
#include <boost/thread.hpp>

namespace bp = boost::python;

namespace move_group_interface
{

class MoveGroupWrapper : protected moveit_py_bindings_tools::ROScppInitializer,
                         public MoveGroup
{
public:

  // ROSInitializer is constructed first, and ensures ros::init() was called, if needed
  MoveGroupWrapper(const std::string &group_name) : moveit_py_bindings_tools::ROScppInitializer(),
                                                    MoveGroup(group_name, boost::shared_ptr<tf::Transformer>(), ros::Duration(5, 0))
  {
  }

  void setJointValueTargetPerJointPythonList(const std::string &joint, bp::list &values)
  {
    setJointValueTarget(joint, moveit_py_bindings_tools::doubleFromList(values));
  }

  void setJointValueTargetPythonList(bp::list &values)
  {
    setJointValueTarget(moveit_py_bindings_tools::doubleFromList(values));
  }

  void setJointValueTargetPythonDict(bp::dict &values)
  {
    bp::list k = values.keys();
    int l = bp::len(k);
    std::map<std::string, double> v;
    for (int i = 0; i < l ; ++i)
      v[bp::extract<std::string>(k[i])] = bp::extract<double>(values[k[i]]);
    setJointValueTarget(v);
  }

  void rememberJointValuesFromPythonList(const std::string &string, bp::list &values)
  {
    rememberJointValues(string, moveit_py_bindings_tools::doubleFromList(values));
  }

  bp::list getJointsList(void)
  {
    return moveit_py_bindings_tools::listFromString(getJoints());
  }

  bp::list getCurrentJointValuesList(void)
  {
    return moveit_py_bindings_tools::listFromDouble(getCurrentJointValues());
  }

  bp::list getRandomJointValuesList(void)
  {
    return moveit_py_bindings_tools::listFromDouble(getRandomJointValues());
  }

  bp::dict getRememberedJointValuesPython(void) const
  {
    const std::map<std::string, std::vector<double> > &rv = getRememberedJointValues();
    bp::dict d;
    for (std::map<std::string, std::vector<double> >::const_iterator it = rv.begin() ; it != rv.end() ; ++it)
      d[it->first] = moveit_py_bindings_tools::listFromDouble(it->second);
    return d;
  }

  bp::list getCurrentPosePython(const std::string &end_effector_link)
  {
    geometry_msgs::PoseStamped pose = getCurrentPose(end_effector_link);
    std::vector<double> v(6);
    v[0] = pose.pose.position.x;
    v[1] = pose.pose.position.y;
    v[2] = pose.pose.position.z;
    Eigen::Quaterniond q;
    tf::quaternionMsgToEigen(pose.pose.orientation, q);
    Eigen::Vector3d r = Eigen::Matrix3d(q).eulerAngles(0, 1, 2); // XYZ
    v[3] = r(0);
    v[4] = r(1);
    v[5] = r(2);
    return moveit_py_bindings_tools::listFromDouble(v);
  }

  bp::list getKnownConstraintsList(void) const
  {
    return moveit_py_bindings_tools::listFromString(getKnownConstraints());
  }

  void setPoseTargetPython(bp::list &pose, const std::string &end_effector_link)
  {
    std::vector<double> v = moveit_py_bindings_tools::doubleFromList(pose);
    if (v.size() == 6)
    {
      setPositionTarget(v[0], v[1], v[2], end_effector_link);
      setOrientationTarget(v[3], v[4], v[5], end_effector_link);
    }
    else
      if (v.size() == 7)
      {
        setPositionTarget(v[0], v[1], v[2], end_effector_link);
        setOrientationTarget(v[3], v[4], v[5], v[6], end_effector_link);
      }
      else
        ROS_ERROR("Pose description expected to consist of either 6 or 7 values");
  }

  const char* getEndEffectorLinkCStr(void) const
  {
    return getEndEffectorLink().c_str();
  }

  const char* getPoseReferenceFrameCStr(void) const
  {
    return getPoseReferenceFrame().c_str();
  }

  const char* getNameCStr(void) const
  {
    return getName().c_str();
  }

  bp::dict getPlanPythonDict(void)
  {
    MoveGroup::Plan plan;
    MoveGroup::plan(plan);
    bp::list joint_names = moveit_py_bindings_tools::listFromString(plan.trajectory_.joint_trajectory.joint_names);
    bp::dict plan_dict, joint_trajectory, multi_dof_joint_trajectory;
    joint_trajectory["joint_names"] = joint_names;
    multi_dof_joint_trajectory["joint_names"] = joint_names;
    bp::list joint_traj_points, multi_dof_traj_points, poses;
    bp::dict joint_traj_point, multi_dof_traj_point, pose, position, orientation;

    for (std::vector<trajectory_msgs::JointTrajectoryPoint>::const_iterator it = plan.trajectory_.joint_trajectory.points.begin() ; it != plan.trajectory_.joint_trajectory.points.end() ; ++it)
    {
      joint_traj_point["positions"] = moveit_py_bindings_tools::listFromDouble(it->positions);
      joint_traj_point["velocities"] = moveit_py_bindings_tools::listFromDouble(it->velocities);
      joint_traj_point["accelerations"] = moveit_py_bindings_tools::listFromDouble(it->accelerations);
      joint_traj_points.append(joint_traj_point);
    }

    joint_trajectory["points"] = joint_traj_points;

    bp::list frame_ids = moveit_py_bindings_tools::listFromString(plan.trajectory_.multi_dof_joint_trajectory.frame_ids);
    bp::list child_frame_ids = moveit_py_bindings_tools::listFromString(plan.trajectory_.multi_dof_joint_trajectory.child_frame_ids);
    multi_dof_joint_trajectory["frame_ids"] = frame_ids;
    multi_dof_joint_trajectory["child_frame_ids"] = child_frame_ids;

    for (std::vector<moveit_msgs::MultiDOFJointTrajectoryPoint>::const_iterator it = plan.trajectory_.multi_dof_joint_trajectory.points.begin() ; it != plan.trajectory_.multi_dof_joint_trajectory.points.end() ; ++it)
    {
      for (std::vector<geometry_msgs::Pose>::const_iterator itr = it->poses.begin() ; itr != it->poses.end() ; ++itr)
      {
        position["x"] = itr->position.x;
        position["y"] = itr->position.y;
        position["z"] = itr->position.z;
        pose["position"] = position;

        orientation["x"] = itr->orientation.x;
        orientation["y"] = itr->orientation.y;
        orientation["z"] = itr->orientation.z;
        orientation["w"] = itr->orientation.w;
        pose["orientation"] = orientation;
        poses.append(pose);
      }
      multi_dof_traj_point["poses"] = poses;
      multi_dof_traj_points.append(multi_dof_traj_point);
    }

    multi_dof_joint_trajectory["points"] = multi_dof_traj_points;

    plan_dict["joint_trajectory"] = joint_trajectory;
    plan_dict["multi_dof_joint_trajectory"] = multi_dof_joint_trajectory;
    return plan_dict;
  }

};

void wrap_move_group_interface()
{
  bp::class_<MoveGroupWrapper> MoveGroupClass("MoveGroup", bp::init<std::string>());

  MoveGroupClass.def("async_move", &MoveGroupWrapper::asyncMove);
  MoveGroupClass.def("move", &MoveGroupWrapper::move);
  MoveGroupClass.def("execute", &MoveGroupWrapper::execute);
  MoveGroupClass.def("stop", &MoveGroupWrapper::stop);

  MoveGroupClass.def("get_name", &MoveGroupWrapper::getNameCStr);
  MoveGroupClass.def("get_joints", &MoveGroupWrapper::getJointsList);
  MoveGroupClass.def("allow_looking", &MoveGroupWrapper::allowLooking);
  MoveGroupClass.def("allow_replanning", &MoveGroupWrapper::allowReplanning);

  MoveGroupClass.def("set_pose_reference_frame", &MoveGroupWrapper::setPoseReferenceFrame);

  MoveGroupClass.def("set_pose_reference_frame", &MoveGroupWrapper::setPoseReferenceFrame);
  MoveGroupClass.def("set_end_effector_link", &MoveGroupWrapper::setEndEffectorLink);
  MoveGroupClass.def("get_end_effector_link", &MoveGroupWrapper::getEndEffectorLinkCStr);
  MoveGroupClass.def("get_pose_reference_frame", &MoveGroupWrapper::getPoseReferenceFrameCStr);

  void (MoveGroupWrapper::*setPoseTarget_1)(const geometry_msgs::PoseStamped &, const std::string&) = &MoveGroupWrapper::setPoseTarget;
  MoveGroupClass.def("set_pose_target", setPoseTarget_1);

  void (MoveGroupWrapper::*setPoseTarget_2)(const geometry_msgs::Pose &, const std::string&) = &MoveGroupWrapper::setPoseTarget;
  MoveGroupClass.def("set_pose_target", setPoseTarget_2);

  MoveGroupClass.def("set_pose_target", &MoveGroupWrapper::setPoseTargetPython);

  MoveGroupClass.def("set_position_target", &MoveGroupWrapper::setPositionTarget);

  void (MoveGroupWrapper::*setOrientationTarget_1)(double, double, double, const std::string&) = &MoveGroupWrapper::setOrientationTarget;
  MoveGroupClass.def("set_orientation_target", setOrientationTarget_1);

  void (MoveGroupWrapper::*setOrientationTarget_2)(double, double, double, double, const std::string&) = &MoveGroupWrapper::setOrientationTarget;
  MoveGroupClass.def("set_orientation_target", setOrientationTarget_2);

  MoveGroupClass.def("get_current_pose", &MoveGroupWrapper::getCurrentPosePython);

  MoveGroupClass.def("clear_pose_target", &MoveGroupWrapper::clearPoseTarget);
  MoveGroupClass.def("clear_pose_targets", &MoveGroupWrapper::clearPoseTargets);

  MoveGroupClass.def("set_joint_value_target", &MoveGroupWrapper::setJointValueTargetPythonList);
  MoveGroupClass.def("set_joint_value_target", &MoveGroupWrapper::setJointValueTargetPythonDict);
  MoveGroupClass.def("set_joint_value_target", &MoveGroupWrapper::setJointValueTargetPerJointPythonList);
  void (MoveGroupWrapper::*setJointValueTarget_4)(const std::string&, double) = &MoveGroupWrapper::setJointValueTarget;
  MoveGroupClass.def("set_joint_value_target", setJointValueTarget_4);

  void (MoveGroupWrapper::*setJointValueTarget_5)(const sensor_msgs::JointState &) = &MoveGroupWrapper::setJointValueTarget;
  MoveGroupClass.def("set_joint_value_target", setJointValueTarget_5);

  MoveGroupClass.def("set_named_target", &MoveGroupWrapper::setNamedTarget);
  MoveGroupClass.def("set_random_target", &MoveGroupWrapper::setRandomTarget);

  void (MoveGroupWrapper::*rememberJointValues_2)(const std::string&) = &MoveGroupWrapper::rememberJointValues;
  MoveGroupClass.def("remember_joint_values", rememberJointValues_2);

  MoveGroupClass.def("remember_joint_values",  &MoveGroupWrapper::rememberJointValuesFromPythonList);

  MoveGroupClass.def("get_current_joint_values",  &MoveGroupWrapper::getCurrentJointValuesList);
  MoveGroupClass.def("get_random_joint_values",  &MoveGroupWrapper::getRandomJointValuesList);
  MoveGroupClass.def("get_remembered_joint_values",  &MoveGroupWrapper::getRememberedJointValuesPython);

  MoveGroupClass.def("forget_joint_values", &MoveGroupWrapper::forgetJointValues);

  MoveGroupClass.def("get_goal_tolerance", &MoveGroupWrapper::getGoalTolerance);
  MoveGroupClass.def("set_goal_tolerance", &MoveGroupWrapper::setGoalTolerance);

  MoveGroupClass.def("set_path_constraints", &MoveGroupWrapper::setPathConstraints);
  MoveGroupClass.def("clear_path_constraints", &MoveGroupWrapper::clearPathConstraints);
  MoveGroupClass.def("get_known_constraints", &MoveGroupWrapper::getKnownConstraintsList);
  MoveGroupClass.def("set_constraints_database", &MoveGroupWrapper::setConstraintsDatabase);
  MoveGroupClass.def("set_workspace", &MoveGroupWrapper::setWorkspace);
  MoveGroupClass.def("set_planning_time", &MoveGroupWrapper::setPlanningTime);
  MoveGroupClass.def("get_plan", &MoveGroupWrapper::getPlanPythonDict);
}

}

BOOST_PYTHON_MODULE(_moveit_move_group_interface)
{
  using namespace move_group_interface;
  wrap_move_group_interface();
}
<commit_msg>fix #39 to some extent<commit_after>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2012, Willow Garage, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Willow Garage nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

/* Author: Ioan Sucan */

#include <moveit/move_group_interface/move_group.h>
#include <moveit/py_bindings_tools/roscpp_initializer.h>
#include <moveit/py_bindings_tools/py_conversions.h>
#include <eigen_conversions/eigen_msg.h>

#include <boost/function.hpp>
#include <boost/python.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/stl_iterator.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>

#include <boost/shared_ptr.hpp>
#include <Python.h>
#include <ros/ros.h>
#include <boost/thread.hpp>

namespace bp = boost::python;

namespace move_group_interface
{

class MoveGroupWrapper : protected moveit_py_bindings_tools::ROScppInitializer,
                         public MoveGroup
{
public:

  // ROSInitializer is constructed first, and ensures ros::init() was called, if needed
  MoveGroupWrapper(const std::string &group_name) : moveit_py_bindings_tools::ROScppInitializer(),
                                                    MoveGroup(group_name, boost::shared_ptr<tf::Transformer>(), ros::Duration(5, 0))
  {
  }

  void setJointValueTargetPerJointPythonList(const std::string &joint, bp::list &values)
  {
    setJointValueTarget(joint, moveit_py_bindings_tools::doubleFromList(values));
  }

  void setJointValueTargetPythonList(bp::list &values)
  {
    setJointValueTarget(moveit_py_bindings_tools::doubleFromList(values));
  }

  void setJointValueTargetPythonDict(bp::dict &values)
  {
    bp::list k = values.keys();
    int l = bp::len(k);
    std::map<std::string, double> v;
    for (int i = 0; i < l ; ++i)
      v[bp::extract<std::string>(k[i])] = bp::extract<double>(values[k[i]]);
    setJointValueTarget(v);
  }

  void rememberJointValuesFromPythonList(const std::string &string, bp::list &values)
  {
    rememberJointValues(string, moveit_py_bindings_tools::doubleFromList(values));
  }

  bp::list getJointsList(void)
  {
    return moveit_py_bindings_tools::listFromString(getJoints());
  }

  bp::list getCurrentJointValuesList(void)
  {
    return moveit_py_bindings_tools::listFromDouble(getCurrentJointValues());
  }

  bp::list getRandomJointValuesList(void)
  {
    return moveit_py_bindings_tools::listFromDouble(getRandomJointValues());
  }

  bp::dict getRememberedJointValuesPython(void) const
  {
    const std::map<std::string, std::vector<double> > &rv = getRememberedJointValues();
    bp::dict d;
    for (std::map<std::string, std::vector<double> >::const_iterator it = rv.begin() ; it != rv.end() ; ++it)
      d[it->first] = moveit_py_bindings_tools::listFromDouble(it->second);
    return d;
  }

  bp::list getCurrentPosePython(const std::string &end_effector_link = "")
  {
    geometry_msgs::PoseStamped pose = getCurrentPose(end_effector_link);
    std::vector<double> v(6);
    v[0] = pose.pose.position.x;
    v[1] = pose.pose.position.y;
    v[2] = pose.pose.position.z;
    Eigen::Quaterniond q;
    tf::quaternionMsgToEigen(pose.pose.orientation, q);
    Eigen::Vector3d r = Eigen::Matrix3d(q).eulerAngles(0, 1, 2); // XYZ
    v[3] = r(0);
    v[4] = r(1);
    v[5] = r(2);
    return moveit_py_bindings_tools::listFromDouble(v);
  }

  bp::list getKnownConstraintsList(void) const
  {
    return moveit_py_bindings_tools::listFromString(getKnownConstraints());
  }

  void convertToArrayOfPoses(bp::list &poses, std::vector<geometry_msgs::Pose> &msg)
  {
    int l = bp::len(poses);
    for (int i = 0; i < l ; ++i)
    {
      bp::list pose = bp::extract<bp::list>(poses[i]);
      std::vector<double> v = moveit_py_bindings_tools::doubleFromList(pose);
      if (v.size() == 6 || v.size() == 7)
      {
        Eigen::Affine3d p = v.size() == 6 ?
          Eigen::Affine3d(Eigen::AngleAxisd(v[3], Eigen::Vector3d::UnitX())
                          * Eigen::AngleAxisd(v[4], Eigen::Vector3d::UnitY())
                          * Eigen::AngleAxisd(v[5], Eigen::Vector3d::UnitZ())) :
          Eigen::Affine3d(Eigen::Quaterniond(v[6], v[3], v[4], v[5]));
        p.translation() = Eigen::Vector3d(v[0], v[1], v[2]);
        geometry_msgs::Pose pm;
        tf::poseEigenToMsg(p, pm);
        msg.push_back(pm);
      }
      else
        ROS_WARN("Incorrect number of values for a pose: %u", (unsigned int)v.size());
    }
  }

  void setPoseTargetsPython(bp::list &poses, const std::string &end_effector_link = "")
  {
    std::vector<geometry_msgs::Pose> msg;
    convertToArrayOfPoses(poses, msg);
    setPoseTargets(msg, end_effector_link);
  }

  void followConstraintsPython(bp::list &poses, const std::string &end_effector_link = "")
  {
    std::vector<geometry_msgs::Pose> msg;
    convertToArrayOfPoses(poses, msg);
    followConstraints(msg, 1e-3, 1e-2, end_effector_link);
  }

  void setPoseTargetPython(bp::list &pose, const std::string &end_effector_link = "")
  {
    std::vector<double> v = moveit_py_bindings_tools::doubleFromList(pose);
    if (v.size() == 6)
    {
      setPositionTarget(v[0], v[1], v[2], end_effector_link);
      setOrientationTarget(v[3], v[4], v[5], end_effector_link);
    }
    else
      if (v.size() == 7)
      {
        setPositionTarget(v[0], v[1], v[2], end_effector_link);
        setOrientationTarget(v[3], v[4], v[5], v[6], end_effector_link);
      }
      else
        ROS_ERROR("Pose description expected to consist of either 6 or 7 values");
  }

  const char* getEndEffectorLinkCStr(void) const
  {
    return getEndEffectorLink().c_str();
  }

  const char* getPoseReferenceFrameCStr(void) const
  {
    return getPoseReferenceFrame().c_str();
  }

  const char* getNameCStr(void) const
  {
    return getName().c_str();
  }

  bp::dict getPlanPythonDict(void)
  {
    MoveGroup::Plan plan;
    MoveGroup::plan(plan);
    bp::list joint_names = moveit_py_bindings_tools::listFromString(plan.trajectory_.joint_trajectory.joint_names);
    bp::dict plan_dict, joint_trajectory, multi_dof_joint_trajectory;
    joint_trajectory["joint_names"] = joint_names;
    multi_dof_joint_trajectory["joint_names"] = joint_names;
    bp::list joint_traj_points, multi_dof_traj_points, poses;
    bp::dict joint_traj_point, multi_dof_traj_point, pose, position, orientation;

    for (std::vector<trajectory_msgs::JointTrajectoryPoint>::const_iterator it = plan.trajectory_.joint_trajectory.points.begin() ;
         it != plan.trajectory_.joint_trajectory.points.end() ; ++it)
    {
      joint_traj_point["positions"] = moveit_py_bindings_tools::listFromDouble(it->positions);
      joint_traj_point["velocities"] = moveit_py_bindings_tools::listFromDouble(it->velocities);
      joint_traj_point["accelerations"] = moveit_py_bindings_tools::listFromDouble(it->accelerations);
      joint_traj_points.append(joint_traj_point);
    }

    joint_trajectory["points"] = joint_traj_points;

    bp::list frame_ids = moveit_py_bindings_tools::listFromString(plan.trajectory_.multi_dof_joint_trajectory.frame_ids);
    bp::list child_frame_ids = moveit_py_bindings_tools::listFromString(plan.trajectory_.multi_dof_joint_trajectory.child_frame_ids);
    multi_dof_joint_trajectory["frame_ids"] = frame_ids;
    multi_dof_joint_trajectory["child_frame_ids"] = child_frame_ids;

    for (std::vector<moveit_msgs::MultiDOFJointTrajectoryPoint>::const_iterator it = plan.trajectory_.multi_dof_joint_trajectory.points.begin() ;
         it != plan.trajectory_.multi_dof_joint_trajectory.points.end() ; ++it)
    {
      for (std::vector<geometry_msgs::Pose>::const_iterator itr = it->poses.begin() ; itr != it->poses.end() ; ++itr)
      {
        position["x"] = itr->position.x;
        position["y"] = itr->position.y;
        position["z"] = itr->position.z;
        pose["position"] = position;

        orientation["x"] = itr->orientation.x;
        orientation["y"] = itr->orientation.y;
        orientation["z"] = itr->orientation.z;
        orientation["w"] = itr->orientation.w;
        pose["orientation"] = orientation;
        poses.append(pose);
      }
      multi_dof_traj_point["poses"] = poses;
      multi_dof_traj_points.append(multi_dof_traj_point);
    }

    multi_dof_joint_trajectory["points"] = multi_dof_traj_points;

    plan_dict["joint_trajectory"] = joint_trajectory;
    plan_dict["multi_dof_joint_trajectory"] = multi_dof_joint_trajectory;
    return plan_dict;
  }

};

void wrap_move_group_interface()
{
  bp::class_<MoveGroupWrapper> MoveGroupClass("MoveGroup", bp::init<std::string>());

  MoveGroupClass.def("async_move", &MoveGroupWrapper::asyncMove);
  MoveGroupClass.def("move", &MoveGroupWrapper::move);
  MoveGroupClass.def("execute", &MoveGroupWrapper::execute);
  MoveGroupClass.def("stop", &MoveGroupWrapper::stop);

  MoveGroupClass.def("get_name", &MoveGroupWrapper::getNameCStr);
  MoveGroupClass.def("get_joints", &MoveGroupWrapper::getJointsList);
  MoveGroupClass.def("allow_looking", &MoveGroupWrapper::allowLooking);
  MoveGroupClass.def("allow_replanning", &MoveGroupWrapper::allowReplanning);

  MoveGroupClass.def("set_pose_reference_frame", &MoveGroupWrapper::setPoseReferenceFrame);

  MoveGroupClass.def("set_pose_reference_frame", &MoveGroupWrapper::setPoseReferenceFrame);
  MoveGroupClass.def("set_end_effector_link", &MoveGroupWrapper::setEndEffectorLink);
  MoveGroupClass.def("get_end_effector_link", &MoveGroupWrapper::getEndEffectorLinkCStr);
  MoveGroupClass.def("get_pose_reference_frame", &MoveGroupWrapper::getPoseReferenceFrameCStr);

  void (MoveGroupWrapper::*setPoseTarget_1)(const geometry_msgs::PoseStamped &, const std::string&) = &MoveGroupWrapper::setPoseTarget;
  MoveGroupClass.def("set_pose_target", setPoseTarget_1);

  void (MoveGroupWrapper::*setPoseTarget_2)(const geometry_msgs::Pose &, const std::string&) = &MoveGroupWrapper::setPoseTarget;
  MoveGroupClass.def("set_pose_target", setPoseTarget_2);

  MoveGroupClass.def("set_pose_target", &MoveGroupWrapper::setPoseTargetPython);

  MoveGroupClass.def("set_pose_targets", &MoveGroupWrapper::setPoseTargetsPython);

  MoveGroupClass.def("set_position_target", &MoveGroupWrapper::setPositionTarget);

  void (MoveGroupWrapper::*setOrientationTarget_1)(double, double, double, const std::string&) = &MoveGroupWrapper::setOrientationTarget;
  MoveGroupClass.def("set_orientation_target", setOrientationTarget_1);

  void (MoveGroupWrapper::*setOrientationTarget_2)(double, double, double, double, const std::string&) = &MoveGroupWrapper::setOrientationTarget;
  MoveGroupClass.def("set_orientation_target", setOrientationTarget_2);

  MoveGroupClass.def("get_current_pose", &MoveGroupWrapper::getCurrentPosePython);

  MoveGroupClass.def("clear_pose_target", &MoveGroupWrapper::clearPoseTarget);
  MoveGroupClass.def("clear_pose_targets", &MoveGroupWrapper::clearPoseTargets);

  MoveGroupClass.def("set_joint_value_target", &MoveGroupWrapper::setJointValueTargetPythonList);
  MoveGroupClass.def("set_joint_value_target", &MoveGroupWrapper::setJointValueTargetPythonDict);
  MoveGroupClass.def("set_joint_value_target", &MoveGroupWrapper::setJointValueTargetPerJointPythonList);
  void (MoveGroupWrapper::*setJointValueTarget_4)(const std::string&, double) = &MoveGroupWrapper::setJointValueTarget;
  MoveGroupClass.def("set_joint_value_target", setJointValueTarget_4);

  void (MoveGroupWrapper::*setJointValueTarget_5)(const sensor_msgs::JointState &) = &MoveGroupWrapper::setJointValueTarget;
  MoveGroupClass.def("set_joint_value_target", setJointValueTarget_5);

  MoveGroupClass.def("set_named_target", &MoveGroupWrapper::setNamedTarget);
  MoveGroupClass.def("set_random_target", &MoveGroupWrapper::setRandomTarget);

  MoveGroupClass.def("follow_constraints", &MoveGroupWrapper::followConstraintsPython);

  void (MoveGroupWrapper::*rememberJointValues_2)(const std::string&) = &MoveGroupWrapper::rememberJointValues;
  MoveGroupClass.def("remember_joint_values", rememberJointValues_2);

  MoveGroupClass.def("remember_joint_values",  &MoveGroupWrapper::rememberJointValuesFromPythonList);

  MoveGroupClass.def("get_current_joint_values",  &MoveGroupWrapper::getCurrentJointValuesList);
  MoveGroupClass.def("get_random_joint_values",  &MoveGroupWrapper::getRandomJointValuesList);
  MoveGroupClass.def("get_remembered_joint_values",  &MoveGroupWrapper::getRememberedJointValuesPython);

  MoveGroupClass.def("forget_joint_values", &MoveGroupWrapper::forgetJointValues);

  MoveGroupClass.def("get_goal_tolerance", &MoveGroupWrapper::getGoalTolerance);
  MoveGroupClass.def("set_goal_tolerance", &MoveGroupWrapper::setGoalTolerance);

  MoveGroupClass.def("set_path_constraints", &MoveGroupWrapper::setPathConstraints);
  MoveGroupClass.def("clear_path_constraints", &MoveGroupWrapper::clearPathConstraints);
  MoveGroupClass.def("get_known_constraints", &MoveGroupWrapper::getKnownConstraintsList);
  MoveGroupClass.def("set_constraints_database", &MoveGroupWrapper::setConstraintsDatabase);
  MoveGroupClass.def("set_workspace", &MoveGroupWrapper::setWorkspace);
  MoveGroupClass.def("set_planning_time", &MoveGroupWrapper::setPlanningTime);
  MoveGroupClass.def("get_plan", &MoveGroupWrapper::getPlanPythonDict);
}

}

BOOST_PYTHON_MODULE(_moveit_move_group_interface)
{
  using namespace move_group_interface;
  wrap_move_group_interface();
}
<|endoftext|>


<commit_before>#ifndef FIXEDPOINTHELPERS_HPP
#define FIXEDPOINTHELPERS_HPP
#include <cmath>
#include <limits.h>

namespace FixedPointHelpers {
    constexpr double dipow_accum(double base, int exponent, double accum) {
        return exponent == 0 ? accum :
               exponent  < 0 ? dipow_accum(base, exponent + 1, accum / base):
                               dipow_accum(base, exponent - 1, accum * base);
    }

    constexpr double dipow(double base, int exponent) {
        return dipow_accum(base, exponent, 1.);
    }

    constexpr int ilogb(double v) {
        return v < 0         ? ilogb(-v) :
               std::isnan(v) ? 0 :
               std::isinf(v) ? INT_MAX :
               v == 0        ? INT_MIN :
               v < 1         ? ilogb(v*2)-1 :
               v >= 2        ? ilogb(v/2) + 1 :
                               0;
    }
}
#endif // FIXEDPOINTHELPERS_HPP
<commit_msg>Make dipow_accum legible<commit_after>#ifndef FIXEDPOINTHELPERS_HPP
#define FIXEDPOINTHELPERS_HPP
#include <cmath>
#include <limits.h>

namespace FixedPointHelpers {
    constexpr double dipow_accum(double base, int exponent, double accum) {
        if (exponent == 0) {
            return accum;
        }
        if (exponent < 0) {
            return dipow_accum(base, exponent + 1, accum / base);
        }

        return dipow_accum(base, exponent - 1, accum * base);
    }

    constexpr double dipow(double base, int exponent) {
        return dipow_accum(base, exponent, 1.);
    }

    constexpr int ilogb(double v) {
        return v < 0         ? ilogb(-v) :
               std::isnan(v) ? 0 :
               std::isinf(v) ? INT_MAX :
               v == 0        ? INT_MIN :
               v < 1         ? ilogb(v*2)-1 :
               v >= 2        ? ilogb(v/2) + 1 :
                               0;
    }
}
#endif // FIXEDPOINTHELPERS_HPP
<|endoftext|>


<commit_before>#include "realloc.hpp"
#include <windows.h>

void *realloc(void *block, size_t size)
{
  if (block)
    return HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,block,size);
  else
    return HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
}
<commit_msg>update realloc<commit_after>#include "realloc.hpp"
#include <windows.h>

void *realloc(void *block, size_t size)
{
  if (!size)
  {
    if (block)
      HeapFree(GetProcessHeap(),0,block);
    return NULL;
  }

  if (block)
    return HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,block,size);
  else
    return HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Renderer/RenderStates.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <functional>
#include <Nazara/Renderer/Debug.hpp>

namespace Nz
{
	bool operator==(const RenderStates& lhs, const RenderStates& rhs)
	{
		#define NazaraRenderStateMember(field) if (lhs.field != rhs.field) return false
		#define NazaraRenderStateBoolMember NazaraRenderStateMember
		#define NazaraRenderStateFloatMember(field, maxDiff) if (!NumberEquals(lhs.field, rhs.field, maxDiff)) return false

		NazaraRenderStateBoolMember(blending);
		NazaraRenderStateBoolMember(colorWrite);
		NazaraRenderStateBoolMember(depthBuffer);
		NazaraRenderStateBoolMember(faceCulling);
		NazaraRenderStateBoolMember(scissorTest);
		NazaraRenderStateBoolMember(stencilTest);

		if (lhs.depthBuffer)
			NazaraRenderStateBoolMember(depthWrite);

		NazaraRenderStateMember(faceFilling);

		if (lhs.blending) //< Remember, at this time we know lhs.blending == rhs.blending
		{
			NazaraRenderStateMember(dstBlend);
			NazaraRenderStateMember(srcBlend);
		}

		if (lhs.depthBuffer)
			NazaraRenderStateMember(depthFunc);

		if (lhs.faceCulling)
			NazaraRenderStateMember(cullingSide);

		if (lhs.stencilTest)
		{
			NazaraRenderStateMember(stencilCompare.back);
			NazaraRenderStateMember(stencilCompare.front);
			NazaraRenderStateMember(stencilCompareMask.back);
			NazaraRenderStateMember(stencilCompareMask.front);
			NazaraRenderStateMember(stencilDepthFail.back);
			NazaraRenderStateMember(stencilDepthFail.front);
			NazaraRenderStateMember(stencilFail.back);
			NazaraRenderStateMember(stencilFail.front);
			NazaraRenderStateMember(stencilPass.back);
			NazaraRenderStateMember(stencilPass.front);
			NazaraRenderStateMember(stencilReference.back);
			NazaraRenderStateMember(stencilReference.front);
			NazaraRenderStateMember(stencilWriteMask.back);
			NazaraRenderStateMember(stencilWriteMask.front);
		}

		NazaraRenderStateFloatMember(lineWidth, 0.001f);
		NazaraRenderStateFloatMember(pointSize, 0.001f);

		#undef NazaraRenderStateMember
		#undef NazaraRenderStateBoolMember
		#undef NazaraRenderStateFloatMember

		return true;
	}
}

namespace std
{
	template<>
	struct hash<Nz::RenderStates>
	{
		size_t operator()(const Nz::RenderStates& pipelineInfo) const
		{
			std::size_t seed = 0;

			Nz::UInt8 parameterHash = 0;
			Nz::UInt8 parameterIndex = 0;

			#define NazaraRenderStateMember(member) Nz::HashCombine(seed, pipelineInfo.member)
			#define NazaraRenderStateBoolMember(member) parameterHash |= ((pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
			#define NazaraRenderStateBoolMemberDep(dependency, member) parameterHash |= ((pipelineInfo.dependency && pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
			#define NazaraRenderStateFloatMember(member, maxDiff) Nz::HashCombine(seed, std::floor(pipelineInfo.member / maxDiff) * maxDiff)

			NazaraRenderStateBoolMember(blending);
			NazaraRenderStateBoolMember(colorWrite);
			NazaraRenderStateBoolMember(depthBuffer);
			NazaraRenderStateBoolMember(faceCulling);
			NazaraRenderStateBoolMember(scissorTest);
			NazaraRenderStateBoolMember(stencilTest);

			NazaraRenderStateBoolMemberDep(depthBuffer, depthWrite);

			NazaraRenderStateMember(faceFilling);

			if (pipelineInfo.blending) //< Remember, at this time we know lhs.blending == rhs.blending
			{
				NazaraRenderStateMember(dstBlend);
				NazaraRenderStateMember(srcBlend);
			}

			if (pipelineInfo.depthBuffer)
				NazaraRenderStateMember(depthFunc);

			if (pipelineInfo.faceCulling)
				NazaraRenderStateMember(cullingSide);

			if (pipelineInfo.stencilTest)
			{
				NazaraRenderStateMember(stencilCompare.back);
				NazaraRenderStateMember(stencilCompare.front);
				NazaraRenderStateMember(stencilCompareMask.back);
				NazaraRenderStateMember(stencilCompareMask.front);
				NazaraRenderStateMember(stencilDepthFail.back);
				NazaraRenderStateMember(stencilDepthFail.front);
				NazaraRenderStateMember(stencilFail.back);
				NazaraRenderStateMember(stencilFail.front);
				NazaraRenderStateMember(stencilPass.back);
				NazaraRenderStateMember(stencilPass.front);
				NazaraRenderStateMember(stencilReference.back);
				NazaraRenderStateMember(stencilReference.front);
				NazaraRenderStateMember(stencilWriteMask.back);
				NazaraRenderStateMember(stencilWriteMask.front);
			}

			NazaraRenderStateFloatMember(lineWidth, 0.001f);
			NazaraRenderStateFloatMember(pointSize, 0.001f);

			#undef NazaraRenderStateMember
			#undef NazaraRenderStateBoolMember
			#undef NazaraRenderStateBoolMemberDep
			#undef NazaraRenderStateFloatMember

			Nz::HashCombine(seed, parameterHash);

			return seed;
		}
	};
}

#include <Nazara/Renderer/DebugOff.hpp>
<commit_msg>Ditto<commit_after>// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Renderer/RenderStates.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <functional>
#include <Nazara/Renderer/Debug.hpp>

namespace Nz
{
	bool operator==(const RenderStates& lhs, const RenderStates& rhs)
	{
		#define NazaraRenderStateMember(field) if (lhs.field != rhs.field) return false
		#define NazaraRenderStateBoolMember NazaraRenderStateMember
		#define NazaraRenderStateFloatMember(field, maxDiff) if (!NumberEquals(lhs.field, rhs.field, maxDiff)) return false

		NazaraRenderStateBoolMember(blending);
		NazaraRenderStateBoolMember(colorWrite);
		NazaraRenderStateBoolMember(depthBuffer);
		NazaraRenderStateBoolMember(faceCulling);
		NazaraRenderStateBoolMember(scissorTest);
		NazaraRenderStateBoolMember(stencilTest);

		if (lhs.depthBuffer)
			NazaraRenderStateBoolMember(depthWrite);

		NazaraRenderStateMember(faceFilling);

		if (lhs.blending) //< Remember, at this time we know lhs.blending == rhs.blending
		{
			NazaraRenderStateMember(dstBlend);
			NazaraRenderStateMember(srcBlend);
		}

		if (lhs.depthBuffer)
			NazaraRenderStateMember(depthFunc);

		if (lhs.faceCulling)
			NazaraRenderStateMember(cullingSide);

		if (lhs.stencilTest)
		{
			NazaraRenderStateMember(stencilCompare.back);
			NazaraRenderStateMember(stencilCompare.front);
			NazaraRenderStateMember(stencilCompareMask.back);
			NazaraRenderStateMember(stencilCompareMask.front);
			NazaraRenderStateMember(stencilDepthFail.back);
			NazaraRenderStateMember(stencilDepthFail.front);
			NazaraRenderStateMember(stencilFail.back);
			NazaraRenderStateMember(stencilFail.front);
			NazaraRenderStateMember(stencilPass.back);
			NazaraRenderStateMember(stencilPass.front);
			NazaraRenderStateMember(stencilReference.back);
			NazaraRenderStateMember(stencilReference.front);
			NazaraRenderStateMember(stencilWriteMask.back);
			NazaraRenderStateMember(stencilWriteMask.front);
		}

		NazaraRenderStateFloatMember(lineWidth, 0.001f);
		NazaraRenderStateFloatMember(pointSize, 0.001f);

		#undef NazaraRenderStateMember
		#undef NazaraRenderStateBoolMember
		#undef NazaraRenderStateFloatMember

		return true;
	}
}

namespace std
{
	template<>
	struct hash<Nz::RenderStates>
	{
		size_t operator()(const Nz::RenderStates& pipelineInfo) const
		{
			std::size_t seed = 0;

			Nz::UInt8 parameterHash = 0;
			Nz::UInt8 parameterIndex = 0;

			#define NazaraRenderStateBool(member) parameterHash |= ((pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
			#define NazaraRenderStateBoolDep(dependency, member) parameterHash |= ((pipelineInfo.dependency && pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
			#define NazaraRenderStateEnum(member) Nz::HashCombine(seed, static_cast<Nz::UInt8>(pipelineInfo.member))
			#define NazaraRenderStateFloat(member, maxDiff) Nz::HashCombine(seed, std::floor(pipelineInfo.member / maxDiff) * maxDiff)

			NazaraRenderStateBool(blending);
			NazaraRenderStateBool(colorWrite);
			NazaraRenderStateBool(depthBuffer);
			NazaraRenderStateBool(faceCulling);
			NazaraRenderStateBool(scissorTest);
			NazaraRenderStateBool(stencilTest);

			NazaraRenderStateBoolDep(depthBuffer, depthWrite);

			NazaraRenderStateEnum(faceFilling);

			if (pipelineInfo.blending) //< Remember, at this time we know lhs.blending == rhs.blending
			{
				NazaraRenderStateEnum(dstBlend);
				NazaraRenderStateEnum(srcBlend);
			}

			if (pipelineInfo.depthBuffer)
				NazaraRenderStateEnum(depthFunc);

			if (pipelineInfo.faceCulling)
				NazaraRenderStateEnum(cullingSide);

			if (pipelineInfo.stencilTest)
			{
				NazaraRenderStateEnum(stencilCompare.back);
				NazaraRenderStateEnum(stencilCompare.front);
				NazaraRenderStateEnum(stencilCompareMask.back);
				NazaraRenderStateEnum(stencilCompareMask.front);
				NazaraRenderStateEnum(stencilDepthFail.back);
				NazaraRenderStateEnum(stencilDepthFail.front);
				NazaraRenderStateEnum(stencilFail.back);
				NazaraRenderStateEnum(stencilFail.front);
				NazaraRenderStateEnum(stencilPass.back);
				NazaraRenderStateEnum(stencilPass.front);
				NazaraRenderStateEnum(stencilReference.back);
				NazaraRenderStateEnum(stencilReference.front);
				NazaraRenderStateEnum(stencilWriteMask.back);
				NazaraRenderStateEnum(stencilWriteMask.front);
			}

			NazaraRenderStateFloat(lineWidth, 0.001f);
			NazaraRenderStateFloat(pointSize, 0.001f);

			#undef NazaraRenderStateBool
			#undef NazaraRenderStateBoolDep
			#undef NazaraRenderStateEnum
			#undef NazaraRenderStateFloat

			Nz::HashCombine(seed, parameterHash);

			return seed;
		}
	};
}

#include <Nazara/Renderer/DebugOff.hpp>
<|endoftext|>