<commit_before>// ==========================================================================
//                                  ANISE
// ==========================================================================
// Copyright (c) 2006-2014, Knut Reinert, FU Berlin
// 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 Knut Reinert or the FU Berlin 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 KNUT REINERT OR THE FU BERLIN 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: Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>
// ==========================================================================

#include "file_name_tokens.h"

char const * GLOBAL_STATE_TOKEN = "global_state";
char const * GLOBAL_STATE_EXT = ".txt";

// Token and extension for site state files.
char const * SITE_STATE_TOKEN = "site_state";
char const * SITE_STATE_EXT = ".txt";

// Token and extension for orphans FASTQ file.
char const * ORPHANS_TOKEN = "orphans";
char const * ORPHANS_EXT = ".fq";

// Token and extension for orphans active map.
char const * ORPHANS_ACTIVE_TOKEN = "orphans_active";
char const * ORPHANS_ACTIVE_EXT = ".bin";

// Token and extension for reads SAM files.
char const * READS_TOKEN = "reads";
char const * READS_EXT = ".sam";

// Token and extension for orphans active map.
char const * SCAFFOLD_SEQS_TOKEN = "scaffold_seqs";
char const * SCAFFOLD_SEQS_EXT = ".fa";

// Token and extension for time log.
char const * TIME_LOG_TOKEN = "time_log";
char const * TIME_LOG_EXT = ".tsv";
<commit_msg>Using compressed file for orphans.<commit_after>// ==========================================================================
//                                  ANISE
// ==========================================================================
// Copyright (c) 2006-2014, Knut Reinert, FU Berlin
// 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 Knut Reinert or the FU Berlin 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 KNUT REINERT OR THE FU BERLIN 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: Manuel Holtgrewe <manuel.holtgrewe@fu-berlin.de>
// ==========================================================================

#include "file_name_tokens.h"

char const * GLOBAL_STATE_TOKEN = "global_state";
char const * GLOBAL_STATE_EXT = ".txt";

// Token and extension for site state files.
char const * SITE_STATE_TOKEN = "site_state";
char const * SITE_STATE_EXT = ".txt";

// Token and extension for orphans FASTQ file.
char const * ORPHANS_TOKEN = "orphans";
char const * ORPHANS_EXT = ".fq.gz";

// Token and extension for orphans active map.
char const * ORPHANS_ACTIVE_TOKEN = "orphans_active";
char const * ORPHANS_ACTIVE_EXT = ".bin";

// Token and extension for reads SAM files.
char const * READS_TOKEN = "reads";
char const * READS_EXT = ".sam";

// Token and extension for orphans active map.
char const * SCAFFOLD_SEQS_TOKEN = "scaffold_seqs";
char const * SCAFFOLD_SEQS_EXT = ".fa";

// Token and extension for time log.
char const * TIME_LOG_TOKEN = "time_log";
char const * TIME_LOG_EXT = ".tsv";
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/desktop_capture/win/cursor.h"

#include <algorithm>

#include "webrtc/modules/desktop_capture/win/scoped_gdi_object.h"
#include "webrtc/modules/desktop_capture/desktop_frame.h"
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
#include "webrtc/system_wrappers/interface/compile_assert.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/typedefs.h"

namespace webrtc {

namespace {

#if defined(WEBRTC_ARCH_LITTLE_ENDIAN)

#define RGBA(r, g, b, a) \
    ((((a) << 24) & 0xff000000) | \
    (((b) << 16) & 0xff0000) | \
    (((g) << 8) & 0xff00) | \
    ((r) & 0xff))

#else  // !defined(WEBRTC_ARCH_LITTLE_ENDIAN)

#define RGBA(r, g, b, a) \
    ((((r) << 24) & 0xff000000) | \
    (((g) << 16) & 0xff0000) | \
    (((b) << 8) & 0xff00) | \
    ((a) & 0xff))

#endif  // !defined(WEBRTC_ARCH_LITTLE_ENDIAN)

const int kBytesPerPixel = DesktopFrame::kBytesPerPixel;

// Pixel colors used when generating cursor outlines.
const uint32_t kPixelRgbaBlack = RGBA(0, 0, 0, 0xff);
const uint32_t kPixelRgbaWhite = RGBA(0xff, 0xff, 0xff, 0xff);
const uint32_t kPixelRgbaTransparent = RGBA(0, 0, 0, 0);

const uint32_t kPixelRgbWhite = RGB(0xff, 0xff, 0xff);
const uint32_t kPixelRgbBlack = RGB(0, 0, 0);

// Expands the cursor shape to add a white outline for visibility against
// dark backgrounds.
void AddCursorOutline(int width, int height, uint32_t* data) {
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      // If this is a transparent pixel (bgr == 0 and alpha = 0), check the
      // neighbor pixels to see if this should be changed to an outline pixel.
      if (*data == kPixelRgbaTransparent) {
        // Change to white pixel if any neighbors (top, bottom, left, right)
        // are black.
        if ((y > 0 && data[-width] == kPixelRgbaBlack) ||
            (y < height - 1 && data[width] == kPixelRgbaBlack) ||
            (x > 0 && data[-1] == kPixelRgbaBlack) ||
            (x < width - 1 && data[1] == kPixelRgbaBlack)) {
          *data = kPixelRgbaWhite;
        }
      }
      data++;
    }
  }
}

// Premultiplies RGB components of a pixel by its alpha component.
uint32_t AlphaMul(uint32_t pixel) {
  COMPILE_ASSERT(sizeof(uint32_t) == kBytesPerPixel);

  RGBQUAD from = *reinterpret_cast<RGBQUAD*>(&pixel);
  RGBQUAD to = {
    (static_cast<uint16_t>(from.rgbBlue) * from.rgbReserved) / 0xff,
    (static_cast<uint16_t>(from.rgbGreen) * from.rgbReserved) / 0xff,
    (static_cast<uint16_t>(from.rgbRed) * from.rgbReserved) / 0xff,
    from.rgbReserved
  };

  return *reinterpret_cast<uint32_t*>(&to);
}

// Scans a 32bpp bitmap looking for any pixels with non-zero alpha component.
// |*has_alpha| is set to true if non-zero alpha is found. |stride| is expressed
// in pixels.
bool HasAlphaChannel(const uint32_t* data, int stride, int width, int height,
                     bool* has_alpha) {
  const RGBQUAD* plane = reinterpret_cast<const RGBQUAD*>(data);
  for (int y = 0; y < height; ++y) {
    for (int x = 0; x < width; ++x) {
      if (plane->rgbReserved != 0) {
        *has_alpha = true;
        return true;
      }
      plane += 1;
    }
    plane += stride - width;
  }

  *has_alpha = false;
  return true;
}

}  // namespace

MouseCursorShape* CreateMouseCursorShapeFromCursor(HDC dc, HCURSOR cursor) {
  ICONINFO iinfo;
  if (!GetIconInfo(cursor, &iinfo)) {
    LOG_F(LS_ERROR) << "Unable to get cursor icon info. Error = "
                    << GetLastError();
    return NULL;
  }

  int hotspot_x = iinfo.xHotspot;
  int hotspot_y = iinfo.yHotspot;

  // Make sure the bitmaps will be freed.
  win::ScopedBitmap scoped_mask(iinfo.hbmMask);
  win::ScopedBitmap scoped_color(iinfo.hbmColor);
  bool is_color = iinfo.hbmColor != NULL;

  // Get |scoped_mask| dimensions.
  BITMAP bitmap_info;
  if (!GetObject(scoped_mask, sizeof(bitmap_info), &bitmap_info)) {
    LOG_F(LS_ERROR) << "Unable to get bitmap info. Error = "
                    << GetLastError();
    return NULL;
  }

  int width = bitmap_info.bmWidth;
  int height = bitmap_info.bmHeight;
  scoped_array<uint32_t> mask_data(new uint32_t[width * height]);

  // Get pixel data from |scoped_mask| converting it to 32bpp along the way.
  // GetDIBits() sets the alpha component of every pixel to 0.
  BITMAPV5HEADER bmi = {0};
  bmi.bV5Size = sizeof(bmi);
  bmi.bV5Width = width;
  bmi.bV5Height = -height;  // request a top-down bitmap.
  bmi.bV5Planes = 1;
  bmi.bV5BitCount = kBytesPerPixel * 8;
  bmi.bV5Compression = BI_RGB;
  bmi.bV5AlphaMask = 0xff000000;
  bmi.bV5CSType = LCS_WINDOWS_COLOR_SPACE;
  bmi.bV5Intent = LCS_GM_BUSINESS;
  if (!GetDIBits(dc,
                 scoped_mask,
                 0,
                 height,
                 mask_data.get(),
                 reinterpret_cast<BITMAPINFO*>(&bmi),
                 DIB_RGB_COLORS)) {
    LOG_F(LS_ERROR) << "Unable to get bitmap bits. Error = "
                    << GetLastError();
    return NULL;
  }

  uint32_t* mask_plane = mask_data.get();

  scoped_array<uint32_t> color_data;
  uint32_t* color_plane = NULL;
  int color_stride = 0;
  bool has_alpha = false;

  if (is_color) {
    // Get the pixels from the color bitmap.
    color_data.reset(new uint32_t[width * height]);
    if (!GetDIBits(dc,
                   scoped_color,
                   0,
                   height,
                   color_data.get(),
                   reinterpret_cast<BITMAPINFO*>(&bmi),
                   DIB_RGB_COLORS)) {
      LOG_F(LS_ERROR) << "Unable to get bitmap bits. Error = "
                      << GetLastError();
      return NULL;
    }

    color_plane = color_data.get();
    color_stride = width;

    // GetDIBits() does not provide any indication whether the bitmap has alpha
    // channel, so we use HasAlphaChannel() below to find it out.
    if (!HasAlphaChannel(color_plane, color_stride, width, height, &has_alpha))
      return NULL;
  } else {
    // For non-color cursors, the mask contains both an AND and an XOR mask and
    // the height includes both. Thus, the width is correct, but we need to
    // divide by 2 to get the correct mask height.
    height /= 2;

    // The XOR mask becomes the color bitmap.
    color_plane = mask_plane + (width * height);
    color_stride = width;
  }

  // Reconstruct transparency from the mask if the color image does not has
  // alpha channel.
  if (!has_alpha) {
    bool add_outline = false;
    uint32_t* color = color_plane;
    uint32_t* dst = color_plane;
    uint32_t* mask = mask_plane;
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        // The two bitmaps combine as follows:
        //  mask  color   Windows Result   Our result    RGB   Alpha
        //   0     00      Black            Black         00    ff
        //   0     ff      White            White         ff    ff
        //   1     00      Screen           Transparent   00    00
        //   1     ff      Reverse-screen   Black         00    ff
        //
        // Since we don't support XOR cursors, we replace the "Reverse Screen"
        // with black. In this case, we also add an outline around the cursor
        // so that it is visible against a dark background.
        if (*mask == kPixelRgbWhite) {
          if (*color != 0) {
            add_outline = true;
            *dst = kPixelRgbaBlack;
          } else {
            *dst = kPixelRgbaTransparent;
          }
        } else {
          *dst = kPixelRgbaBlack ^ *color;
        }

        ++color;
        ++dst;
        ++mask;
      }
    }
    if (add_outline) {
      AddCursorOutline(width, height, color_plane);
    }
  }

  scoped_ptr<MouseCursorShape> result(new MouseCursorShape());
  result->data.assign(reinterpret_cast<char*>(color_plane),
                      height * width * kBytesPerPixel);
  result->size.set(width, height);
  result->hotspot.set(hotspot_x, hotspot_y);
  return result.release();
}

}  // namespace webrtc
<commit_msg>Pre-multiply images for MouseCursorShape.<commit_after>/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/desktop_capture/win/cursor.h"

#include <algorithm>

#include "webrtc/modules/desktop_capture/win/scoped_gdi_object.h"
#include "webrtc/modules/desktop_capture/desktop_frame.h"
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
#include "webrtc/system_wrappers/interface/compile_assert.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
#include "webrtc/typedefs.h"

namespace webrtc {

namespace {

#if defined(WEBRTC_ARCH_LITTLE_ENDIAN)

#define RGBA(r, g, b, a) \
    ((((a) << 24) & 0xff000000) | \
    (((b) << 16) & 0xff0000) | \
    (((g) << 8) & 0xff00) | \
    ((r) & 0xff))

#else  // !defined(WEBRTC_ARCH_LITTLE_ENDIAN)

#define RGBA(r, g, b, a) \
    ((((r) << 24) & 0xff000000) | \
    (((g) << 16) & 0xff0000) | \
    (((b) << 8) & 0xff00) | \
    ((a) & 0xff))

#endif  // !defined(WEBRTC_ARCH_LITTLE_ENDIAN)

const int kBytesPerPixel = DesktopFrame::kBytesPerPixel;

// Pixel colors used when generating cursor outlines.
const uint32_t kPixelRgbaBlack = RGBA(0, 0, 0, 0xff);
const uint32_t kPixelRgbaWhite = RGBA(0xff, 0xff, 0xff, 0xff);
const uint32_t kPixelRgbaTransparent = RGBA(0, 0, 0, 0);

const uint32_t kPixelRgbWhite = RGB(0xff, 0xff, 0xff);
const uint32_t kPixelRgbBlack = RGB(0, 0, 0);

// Expands the cursor shape to add a white outline for visibility against
// dark backgrounds.
void AddCursorOutline(int width, int height, uint32_t* data) {
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      // If this is a transparent pixel (bgr == 0 and alpha = 0), check the
      // neighbor pixels to see if this should be changed to an outline pixel.
      if (*data == kPixelRgbaTransparent) {
        // Change to white pixel if any neighbors (top, bottom, left, right)
        // are black.
        if ((y > 0 && data[-width] == kPixelRgbaBlack) ||
            (y < height - 1 && data[width] == kPixelRgbaBlack) ||
            (x > 0 && data[-1] == kPixelRgbaBlack) ||
            (x < width - 1 && data[1] == kPixelRgbaBlack)) {
          *data = kPixelRgbaWhite;
        }
      }
      data++;
    }
  }
}

// Premultiplies RGB components of the pixel data in the given image by
// the corresponding alpha components.
void AlphaMul(uint32_t* data, int width, int height) {
  COMPILE_ASSERT(sizeof(uint32_t) == kBytesPerPixel);

  for (uint32_t* data_end = data + width * height; data != data_end; ++data) {
    RGBQUAD* from = reinterpret_cast<RGBQUAD*>(data);
    RGBQUAD* to = reinterpret_cast<RGBQUAD*>(data);
    to->rgbBlue =
        (static_cast<uint16_t>(from->rgbBlue) * from->rgbReserved) / 0xff;
    to->rgbGreen =
        (static_cast<uint16_t>(from->rgbGreen) * from->rgbReserved) / 0xff;
    to->rgbRed =
        (static_cast<uint16_t>(from->rgbRed) * from->rgbReserved) / 0xff;
  }
}

// Scans a 32bpp bitmap looking for any pixels with non-zero alpha component.
// |*has_alpha| is set to true if non-zero alpha is found. |stride| is expressed
// in pixels.
bool HasAlphaChannel(const uint32_t* data, int stride, int width, int height,
                     bool* has_alpha) {
  const RGBQUAD* plane = reinterpret_cast<const RGBQUAD*>(data);
  for (int y = 0; y < height; ++y) {
    for (int x = 0; x < width; ++x) {
      if (plane->rgbReserved != 0) {
        *has_alpha = true;
        return true;
      }
      plane += 1;
    }
    plane += stride - width;
  }

  *has_alpha = false;
  return true;
}

}  // namespace

MouseCursorShape* CreateMouseCursorShapeFromCursor(HDC dc, HCURSOR cursor) {
  ICONINFO iinfo;
  if (!GetIconInfo(cursor, &iinfo)) {
    LOG_F(LS_ERROR) << "Unable to get cursor icon info. Error = "
                    << GetLastError();
    return NULL;
  }

  int hotspot_x = iinfo.xHotspot;
  int hotspot_y = iinfo.yHotspot;

  // Make sure the bitmaps will be freed.
  win::ScopedBitmap scoped_mask(iinfo.hbmMask);
  win::ScopedBitmap scoped_color(iinfo.hbmColor);
  bool is_color = iinfo.hbmColor != NULL;

  // Get |scoped_mask| dimensions.
  BITMAP bitmap_info;
  if (!GetObject(scoped_mask, sizeof(bitmap_info), &bitmap_info)) {
    LOG_F(LS_ERROR) << "Unable to get bitmap info. Error = "
                    << GetLastError();
    return NULL;
  }

  int width = bitmap_info.bmWidth;
  int height = bitmap_info.bmHeight;
  scoped_array<uint32_t> mask_data(new uint32_t[width * height]);

  // Get pixel data from |scoped_mask| converting it to 32bpp along the way.
  // GetDIBits() sets the alpha component of every pixel to 0.
  BITMAPV5HEADER bmi = {0};
  bmi.bV5Size = sizeof(bmi);
  bmi.bV5Width = width;
  bmi.bV5Height = -height;  // request a top-down bitmap.
  bmi.bV5Planes = 1;
  bmi.bV5BitCount = kBytesPerPixel * 8;
  bmi.bV5Compression = BI_RGB;
  bmi.bV5AlphaMask = 0xff000000;
  bmi.bV5CSType = LCS_WINDOWS_COLOR_SPACE;
  bmi.bV5Intent = LCS_GM_BUSINESS;
  if (!GetDIBits(dc,
                 scoped_mask,
                 0,
                 height,
                 mask_data.get(),
                 reinterpret_cast<BITMAPINFO*>(&bmi),
                 DIB_RGB_COLORS)) {
    LOG_F(LS_ERROR) << "Unable to get bitmap bits. Error = "
                    << GetLastError();
    return NULL;
  }

  uint32_t* mask_plane = mask_data.get();

  scoped_array<uint32_t> color_data;
  uint32_t* color_plane = NULL;
  int color_stride = 0;
  bool has_alpha = false;

  if (is_color) {
    // Get the pixels from the color bitmap.
    color_data.reset(new uint32_t[width * height]);
    if (!GetDIBits(dc,
                   scoped_color,
                   0,
                   height,
                   color_data.get(),
                   reinterpret_cast<BITMAPINFO*>(&bmi),
                   DIB_RGB_COLORS)) {
      LOG_F(LS_ERROR) << "Unable to get bitmap bits. Error = "
                      << GetLastError();
      return NULL;
    }

    color_plane = color_data.get();
    color_stride = width;

    // GetDIBits() does not provide any indication whether the bitmap has alpha
    // channel, so we use HasAlphaChannel() below to find it out.
    if (!HasAlphaChannel(color_plane, color_stride, width, height, &has_alpha))
      return NULL;
  } else {
    // For non-color cursors, the mask contains both an AND and an XOR mask and
    // the height includes both. Thus, the width is correct, but we need to
    // divide by 2 to get the correct mask height.
    height /= 2;

    // The XOR mask becomes the color bitmap.
    color_plane = mask_plane + (width * height);
    color_stride = width;
  }

  // Reconstruct transparency from the mask if the color image does not has
  // alpha channel.
  if (!has_alpha) {
    bool add_outline = false;
    uint32_t* color = color_plane;
    uint32_t* dst = color_plane;
    uint32_t* mask = mask_plane;
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        // The two bitmaps combine as follows:
        //  mask  color   Windows Result   Our result    RGB   Alpha
        //   0     00      Black            Black         00    ff
        //   0     ff      White            White         ff    ff
        //   1     00      Screen           Transparent   00    00
        //   1     ff      Reverse-screen   Black         00    ff
        //
        // Since we don't support XOR cursors, we replace the "Reverse Screen"
        // with black. In this case, we also add an outline around the cursor
        // so that it is visible against a dark background.
        if (*mask == kPixelRgbWhite) {
          if (*color != 0) {
            add_outline = true;
            *dst = kPixelRgbaBlack;
          } else {
            *dst = kPixelRgbaTransparent;
          }
        } else {
          *dst = kPixelRgbaBlack ^ *color;
        }

        ++color;
        ++dst;
        ++mask;
      }
    }
    if (add_outline) {
      AddCursorOutline(width, height, color_plane);
    }
  }

  // Pre-multiply the resulting pixels since MouseCursorShape uses premultiplied
  // images.
  AlphaMul(color_plane, width, height);

  scoped_ptr<MouseCursorShape> result(new MouseCursorShape());
  result->data.assign(reinterpret_cast<char*>(color_plane),
                      height * width * kBytesPerPixel);
  result->size.set(width, height);
  result->hotspot.set(hotspot_x, hotspot_y);
  return result.release();
}

}  // namespace webrtc
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <limits.h>
#include <random>

#include "transpose.h"

#define BIT(x) ((unsigned long long) 1 << x)

template <typename T>
union container {
	T native;
	unsigned char bytes[sizeof(T)];
};

template <typename T>
void
assign_bit(T *in_ptr, T *out_ptr, size_t elem_index_out, size_t sig_bit, size_t out_bit)
{
	/*
	 * Part of the transpose operation. Take the (sig_bit) bit of the (out_bit)
	 * element of (in_ptr), and move it to the (out_bit) bit of the (sig_bit)
	 * block of (out_ptr), at index elem_index_out. See README for explanation.
	 */
	container<T> in, out;
	in.native = in_ptr[out_bit];
	out.native = out_ptr[elem_index_out];

	/* Each elem has sizeof(T) "bytes". We only need one of them. */
	size_t bits_per_elem = sizeof(T)*CHAR_BIT;
	size_t in_byte_index = sig_bit/CHAR_BIT; /* Verified. */
	size_t out_byte_index = (out_bit % bits_per_elem) / CHAR_BIT; /* Verified. */
	size_t sig_bit_byte_index = sig_bit % CHAR_BIT; /* Verified. */
	size_t out_bit_byte_index = out_bit % CHAR_BIT; /* Verified. */

	out.bytes[out_byte_index] |=
		BIT(out_bit_byte_index) * !!(BIT(sig_bit_byte_index) & in.bytes[in_byte_index]);

	out_ptr[elem_index_out] = out.native;
}

template <typename T>
void
transpose(T *data_in, T *data_out, size_t len)
{
	/*
	 * Bitwise transpose elements of type T such that the n-th significant bits
	 * are stored contiguously in memory.
	 */
	size_t sig_bit, out_bit, sigbit_start, elem_index_out, bits_per_elem;
	bits_per_elem = sizeof(T)*CHAR_BIT;

	for (sig_bit=0; sig_bit<bits_per_elem; sig_bit++){
		sigbit_start = sig_bit*len/bits_per_elem;
		for (out_bit=0; out_bit<len; out_bit++){
			elem_index_out = sigbit_start + out_bit/bits_per_elem;
			assign_bit(data_in, data_out, elem_index_out, sig_bit, out_bit);
		}
	}
}

template <typename T>
void
create_test_files(size_t elems, double mean, double stddev, const char *typestr)
{
	size_t i;

	T *in = (T*) calloc(elems, sizeof(T));
	if (!in){
		printf("Could not alloc memory\n");
		exit(1);
	}
	T *out = (T*) calloc(elems, sizeof(T));
	if (!out){
		printf("Could not alloc memory\n");
		exit(1);
	}

	using namespace std;

	default_random_engine rng;
	normal_distribution<double> gaussian(mean, stddev);
	for (i=0; i<elems; i++){
		in[i] = (T) gaussian(rng)+(i*0.01);
	}

	transpose(in, out, elems);

	ofstream out_stream;
	char out_name[50];

	sprintf(out_name, "raw_%s_%.2f_pm_%.2f.bin", typestr, mean, stddev);
	out_stream.open(out_name, ios::out | ios::binary);
	out_stream.write((char*)in, elems*sizeof(T));
	out_stream.close();

	sprintf(out_name, "transposed_%s_%.2f_pm_%.2f.bin", typestr, mean, stddev);
	out_stream.open(out_name, ios::out | ios::binary);
	out_stream.write((char*)out, elems*sizeof(T));
	out_stream.close();

	free(in);
	free(out);
}

template <typename T>
void
create_test_files_from_arr(T *arr, size_t elems)
{
	T *out = (T*) calloc(elems, sizeof(T));
	if (!out){
		printf("Could not alloc memory\n");
		exit(1);
	}

	using namespace std;

	transpose(arr, out, elems);

	ofstream out_stream;
	char out_name[50];

	out_stream.open("raw_from_dat.bin", ios::out | ios::binary);
	out_stream.write((char*)arr, elems*sizeof(T));
	out_stream.close();

	out_stream.open("transposed_from_dat.bin", ios::out | ios::binary);
	out_stream.write((char*)out, elems*sizeof(T));
	out_stream.close();

	free(out);
}

void
_register_types(void)
{
	/* Hack to prevent execution of any called functions */
	int j = 1;
	if (j)
		exit(1);

	float *f;
	int *i;
	double *d;
	long *l;
	const char *str;

	create_test_files_from_arr(f, (size_t) 0);
	create_test_files_from_arr(i, (size_t) 0);
	create_test_files_from_arr(d, (size_t) 0);
	create_test_files_from_arr(l, (size_t) 0);

	create_test_files<int>(size_t (0), 0.0, 0.0, str);
	create_test_files<float>(size_t (0), 0.0, 0.0, str);
	create_test_files<double>(size_t (0), 0.0, 0.0, str);
	create_test_files<long>(size_t (0), 0.0, 0.0, str);
}
<commit_msg>Remove trend in default transpose test data<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <limits.h>
#include <random>

#include "transpose.h"

#define BIT(x) ((unsigned long long) 1 << x)

template <typename T>
union container {
	T native;
	unsigned char bytes[sizeof(T)];
};

template <typename T>
void
assign_bit(T *in_ptr, T *out_ptr, size_t elem_index_out, size_t sig_bit, size_t out_bit)
{
	/*
	 * Part of the transpose operation. Take the (sig_bit) bit of the (out_bit)
	 * element of (in_ptr), and move it to the (out_bit) bit of the (sig_bit)
	 * block of (out_ptr), at index elem_index_out. See README for explanation.
	 */
	container<T> in, out;
	in.native = in_ptr[out_bit];
	out.native = out_ptr[elem_index_out];

	/* Each elem has sizeof(T) "bytes". We only need one of them. */
	size_t bits_per_elem = sizeof(T)*CHAR_BIT;
	size_t in_byte_index = sig_bit/CHAR_BIT; /* Verified. */
	size_t out_byte_index = (out_bit % bits_per_elem) / CHAR_BIT; /* Verified. */
	size_t sig_bit_byte_index = sig_bit % CHAR_BIT; /* Verified. */
	size_t out_bit_byte_index = out_bit % CHAR_BIT; /* Verified. */

	out.bytes[out_byte_index] |=
		BIT(out_bit_byte_index) * !!(BIT(sig_bit_byte_index) & in.bytes[in_byte_index]);

	out_ptr[elem_index_out] = out.native;
}

template <typename T>
void
transpose(T *data_in, T *data_out, size_t len)
{
	/*
	 * Bitwise transpose elements of type T such that the n-th significant bits
	 * are stored contiguously in memory.
	 */
	size_t sig_bit, out_bit, sigbit_start, elem_index_out, bits_per_elem;
	bits_per_elem = sizeof(T)*CHAR_BIT;

	for (sig_bit=0; sig_bit<bits_per_elem; sig_bit++){
		sigbit_start = sig_bit*len/bits_per_elem;
		for (out_bit=0; out_bit<len; out_bit++){
			elem_index_out = sigbit_start + out_bit/bits_per_elem;
			assign_bit(data_in, data_out, elem_index_out, sig_bit, out_bit);
		}
	}
}

template <typename T>
void
create_test_files(size_t elems, double mean, double stddev, const char *typestr)
{
	size_t i;

	T *in = (T*) calloc(elems, sizeof(T));
	if (!in){
		printf("Could not alloc memory\n");
		exit(1);
	}
	T *out = (T*) calloc(elems, sizeof(T));
	if (!out){
		printf("Could not alloc memory\n");
		exit(1);
	}

	using namespace std;

	default_random_engine rng;
	normal_distribution<double> gaussian(mean, stddev);
	for (i=0; i<elems; i++){
		in[i] = (T) gaussian(rng);
	}

	transpose(in, out, elems);

	ofstream out_stream;
	char out_name[50];

	sprintf(out_name, "raw_%s_%.2f_pm_%.2f.bin", typestr, mean, stddev);
	out_stream.open(out_name, ios::out | ios::binary);
	out_stream.write((char*)in, elems*sizeof(T));
	out_stream.close();

	sprintf(out_name, "transposed_%s_%.2f_pm_%.2f.bin", typestr, mean, stddev);
	out_stream.open(out_name, ios::out | ios::binary);
	out_stream.write((char*)out, elems*sizeof(T));
	out_stream.close();

	free(in);
	free(out);
}

template <typename T>
void
create_test_files_from_arr(T *arr, size_t elems)
{
	T *out = (T*) calloc(elems, sizeof(T));
	if (!out){
		printf("Could not alloc memory\n");
		exit(1);
	}

	using namespace std;

	transpose(arr, out, elems);

	ofstream out_stream;
	char out_name[50];

	out_stream.open("raw_from_dat.bin", ios::out | ios::binary);
	out_stream.write((char*)arr, elems*sizeof(T));
	out_stream.close();

	out_stream.open("transposed_from_dat.bin", ios::out | ios::binary);
	out_stream.write((char*)out, elems*sizeof(T));
	out_stream.close();

	free(out);
}

void
_register_types(void)
{
	/* Hack to prevent execution of any called functions */
	int j = 1;
	if (j)
		exit(1);

	float *f;
	int *i;
	double *d;
	long *l;
	const char *str;

	create_test_files_from_arr(f, (size_t) 0);
	create_test_files_from_arr(i, (size_t) 0);
	create_test_files_from_arr(d, (size_t) 0);
	create_test_files_from_arr(l, (size_t) 0);

	create_test_files<int>(size_t (0), 0.0, 0.0, str);
	create_test_files<float>(size_t (0), 0.0, 0.0, str);
	create_test_files<double>(size_t (0), 0.0, 0.0, str);
	create_test_files<long>(size_t (0), 0.0, 0.0, str);
}
<|endoftext|>


<commit_before>//===- Printer.cpp - Code for printing data structure graphs nicely -------===//
//
// This file implements the 'dot' graph printer.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DataStructure.h"
#include "llvm/Analysis/DSGraph.h"
#include "llvm/Analysis/DSGraphTraits.h"
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
#include "Support/CommandLine.h"
#include "Support/GraphWriter.h"
#include "Support/Statistic.h"
#include <fstream>
#include <sstream>

// OnlyPrintMain - The DataStructure printer exposes this option to allow
// printing of only the graph for "main".
//
namespace {
  cl::opt<bool> OnlyPrintMain("only-print-main-ds", cl::ReallyHidden);
  Statistic<> MaxGraphSize   ("dsnode", "Maximum graph size");
  Statistic<> NumFoldedNodes ("dsnode", "Number of folded nodes (in final graph)");
}

void DSNode::dump() const { print(std::cerr, 0); }

static std::string getCaption(const DSNode *N, const DSGraph *G) {
  std::stringstream OS;
  Module *M = 0;
  // Get the module from ONE of the functions in the graph it is available.
  if (G && !G->getReturnNodes().empty())
    M = G->getReturnNodes().begin()->first->getParent();

  if (N->isNodeCompletelyFolded())
    OS << "FOLDED";
  else {
    WriteTypeSymbolic(OS, N->getType(), M);
    if (N->isArray())
      OS << " array";
  }
  if (unsigned NodeType = N->getNodeFlags()) {
    OS << ": ";
    if (NodeType & DSNode::AllocaNode ) OS << "S";
    if (NodeType & DSNode::HeapNode   ) OS << "H";
    if (NodeType & DSNode::GlobalNode ) OS << "G";
    if (NodeType & DSNode::UnknownNode) OS << "U";
    if (NodeType & DSNode::Incomplete ) OS << "I";
    if (NodeType & DSNode::Modified   ) OS << "M";
    if (NodeType & DSNode::Read       ) OS << "R";
#ifndef NDEBUG
    if (NodeType & DSNode::DEAD       ) OS << "<dead>";
#endif
    OS << "\n";
  }

  for (unsigned i = 0, e = N->getGlobals().size(); i != e; ++i) {
    WriteAsOperand(OS, N->getGlobals()[i], false, true, M);
    OS << "\n";
  }

  return OS.str();
}

template<>
struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
  static std::string getGraphName(const DSGraph *G) {
    switch (G->getReturnNodes().size()) {
    case 0: return "Global graph";
    case 1: return "Function " + G->getReturnNodes().begin()->first->getName();
    default:
      std::string Return = "Functions: ";
      for (DSGraph::ReturnNodesTy::const_iterator I=G->getReturnNodes().begin();
           I != G->getReturnNodes().end(); ++I)
        Return += I->first->getName() + " ";
      return Return;
    }
  }

  static const char *getGraphProperties(const DSGraph *G) {
    return "\tsize=\"10,7.5\";\n"
           "\trotate=\"90\";\n";
  }

  static std::string getNodeLabel(const DSNode *Node, const DSGraph *Graph) {
    return getCaption(Node, Graph);
  }

  static std::string getNodeAttributes(const DSNode *N) {
    return "shape=Mrecord";//fontname=Courier";
  }

  /// addCustomGraphFeatures - Use this graph writing hook to emit call nodes
  /// and the return node.
  ///
  static void addCustomGraphFeatures(const DSGraph *G,
                                     GraphWriter<const DSGraph*> &GW) {
    Module *CurMod = 0;
    if (!G->getReturnNodes().empty())
      CurMod = G->getReturnNodes().begin()->first->getParent();

    // Add scalar nodes to the graph...
    const DSGraph::ScalarMapTy &VM = G->getScalarMap();
    for (DSGraph::ScalarMapTy::const_iterator I = VM.begin(); I != VM.end();++I)
      if (!isa<GlobalValue>(I->first)) {
        std::stringstream OS;
        WriteAsOperand(OS, I->first, false, true, CurMod);
        GW.emitSimpleNode(I->first, "", OS.str());

        // Add edge from return node to real destination
        int EdgeDest = I->second.getOffset() >> DS::PointerShift;
        if (EdgeDest == 0) EdgeDest = -1;
        GW.emitEdge(I->first, -1, I->second.getNode(),
                    EdgeDest, "arrowtail=tee,color=gray63");
      }

    // Output the returned value pointer...
    const DSGraph::ReturnNodesTy &RetNodes = G->getReturnNodes();
    for (DSGraph::ReturnNodesTy::const_iterator I = RetNodes.begin(),
           E = RetNodes.end(); I != E; ++I)
      if (I->second.getNode()) {
        std::string Label;
        if (RetNodes.size() == 1)
          Label = "returning";
        else
          Label = I->first->getName() + " ret node";
        // Output the return node...
        GW.emitSimpleNode((void*)1, "plaintext=circle", Label);

        // Add edge from return node to real destination
        int RetEdgeDest = I->second.getOffset() >> DS::PointerShift;;
        if (RetEdgeDest == 0) RetEdgeDest = -1;
        GW.emitEdge((void*)1, -1, I->second.getNode(),
                    RetEdgeDest, "arrowtail=tee,color=gray63");
      }

    // Output all of the call nodes...
    const std::vector<DSCallSite> &FCs =
      G->shouldPrintAuxCalls() ? G->getAuxFunctionCalls()
      : G->getFunctionCalls();
    for (unsigned i = 0, e = FCs.size(); i != e; ++i) {
      const DSCallSite &Call = FCs[i];
      std::vector<std::string> EdgeSourceCaptions(Call.getNumPtrArgs()+2);
      EdgeSourceCaptions[0] = "r";
      if (Call.isDirectCall())
        EdgeSourceCaptions[1] = Call.getCalleeFunc()->getName();
      else
        EdgeSourceCaptions[1] = "f";

      GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2,
                        &EdgeSourceCaptions);

      if (DSNode *N = Call.getRetVal().getNode()) {
        int EdgeDest = Call.getRetVal().getOffset() >> DS::PointerShift;
        if (EdgeDest == 0) EdgeDest = -1;
        GW.emitEdge(&Call, 0, N, EdgeDest, "color=gray63,tailclip=false");
      }

      // Print out the callee...
      if (Call.isIndirectCall()) {
        DSNode *N = Call.getCalleeNode();
        assert(N && "Null call site callee node!");
        GW.emitEdge(&Call, 1, N, -1, "color=gray63,tailclip=false");
      }

      for (unsigned j = 0, e = Call.getNumPtrArgs(); j != e; ++j)
        if (DSNode *N = Call.getPtrArg(j).getNode()) {
          int EdgeDest = Call.getPtrArg(j).getOffset() >> DS::PointerShift;
          if (EdgeDest == 0) EdgeDest = -1;
          GW.emitEdge(&Call, j+2, N, EdgeDest, "color=gray63,tailclip=false");
        }
    }
  }
};

void DSNode::print(std::ostream &O, const DSGraph *G) const {
  GraphWriter<const DSGraph *> W(O, G);
  W.writeNode(this);
}

void DSGraph::print(std::ostream &O) const {
  WriteGraph(O, this, "DataStructures");
}

void DSGraph::writeGraphToFile(std::ostream &O,
                               const std::string &GraphName) const {
  std::string Filename = GraphName + ".dot";
  O << "Writing '" << Filename << "'...";
  std::ofstream F(Filename.c_str());

  if (F.good()) {
    print(F);
    unsigned NumCalls = shouldPrintAuxCalls() ?
      getAuxFunctionCalls().size() : getFunctionCalls().size();
    O << " [" << getGraphSize() << "+" << NumCalls << "]\n";
  } else {
    O << "  error opening file for writing!\n";
  }
}

/// viewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
/// then cleanup.  For use from the debugger.
///
void DSGraph::viewGraph() const {
  std::ofstream F("/tmp/tempgraph.dot");
  if (!F.good()) {
    std::cerr << "Error opening '/tmp/tempgraph.dot' for temporary graph!\n";
    return;
  }
  print(F);
  F.close();
  if (system("dot -Tps /tmp/tempgraph.dot > /tmp/tempgraph.ps"))
    std::cerr << "Error running dot: 'dot' not in path?\n";
  system("gv /tmp/tempgraph.ps");
  system("rm /tmp/tempgraph.dot /tmp/tempgraph.ps");
}

template <typename Collection>
static void printCollection(const Collection &C, std::ostream &O,
                            const Module *M, const std::string &Prefix) {
  if (M == 0) {
    O << "Null Module pointer, cannot continue!\n";
    return;
  }

  unsigned TotalNumNodes = 0, TotalCallNodes = 0;
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
    if (C.hasGraph(*I)) {
      DSGraph &Gr = C.getDSGraph((Function&)*I);
      TotalNumNodes += Gr.getGraphSize();
      unsigned NumCalls = Gr.shouldPrintAuxCalls() ?
        Gr.getAuxFunctionCalls().size() : Gr.getFunctionCalls().size();

      TotalCallNodes += NumCalls;
      if (I->getName() == "main" || !OnlyPrintMain)
        Gr.writeGraphToFile(O, Prefix+I->getName());
      else {
        O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... ["
          << Gr.getGraphSize() << "+" << NumCalls << "]\n";
      }

      if (MaxGraphSize < Gr.getNodes().size())
        MaxGraphSize = Gr.getNodes().size();
      for (unsigned i = 0, e = Gr.getNodes().size(); i != e; ++i)
        if (Gr.getNodes()[i]->isNodeCompletelyFolded())
          ++NumFoldedNodes;
    }

  DSGraph &GG = C.getGlobalsGraph();
  TotalNumNodes  += GG.getGraphSize();
  TotalCallNodes += GG.getFunctionCalls().size();
  if (!OnlyPrintMain) {
    GG.writeGraphToFile(O, Prefix+"GlobalsGraph");
  } else {
    O << "Skipped Writing '" << Prefix << "GlobalsGraph.dot'... ["
      << GG.getGraphSize() << "+" << GG.getFunctionCalls().size() << "]\n";
  }

  O << "\nGraphs contain [" << TotalNumNodes << "+" << TotalCallNodes
    << "] nodes total" << std::endl;
}

// print - Print out the analysis results...
void LocalDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "ds.");
}

void BUDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "bu.");
}

void TDDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "td.");
}
<commit_msg>Use the getFunctionNames method<commit_after>//===- Printer.cpp - Code for printing data structure graphs nicely -------===//
//
// This file implements the 'dot' graph printer.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/DataStructure.h"
#include "llvm/Analysis/DSGraph.h"
#include "llvm/Analysis/DSGraphTraits.h"
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
#include "Support/CommandLine.h"
#include "Support/GraphWriter.h"
#include "Support/Statistic.h"
#include <fstream>
#include <sstream>

// OnlyPrintMain - The DataStructure printer exposes this option to allow
// printing of only the graph for "main".
//
namespace {
  cl::opt<bool> OnlyPrintMain("only-print-main-ds", cl::ReallyHidden);
  Statistic<> MaxGraphSize   ("dsnode", "Maximum graph size");
  Statistic<> NumFoldedNodes ("dsnode", "Number of folded nodes (in final graph)");
}

void DSNode::dump() const { print(std::cerr, 0); }

static std::string getCaption(const DSNode *N, const DSGraph *G) {
  std::stringstream OS;
  Module *M = 0;
  // Get the module from ONE of the functions in the graph it is available.
  if (G && !G->getReturnNodes().empty())
    M = G->getReturnNodes().begin()->first->getParent();

  if (N->isNodeCompletelyFolded())
    OS << "FOLDED";
  else {
    WriteTypeSymbolic(OS, N->getType(), M);
    if (N->isArray())
      OS << " array";
  }
  if (unsigned NodeType = N->getNodeFlags()) {
    OS << ": ";
    if (NodeType & DSNode::AllocaNode ) OS << "S";
    if (NodeType & DSNode::HeapNode   ) OS << "H";
    if (NodeType & DSNode::GlobalNode ) OS << "G";
    if (NodeType & DSNode::UnknownNode) OS << "U";
    if (NodeType & DSNode::Incomplete ) OS << "I";
    if (NodeType & DSNode::Modified   ) OS << "M";
    if (NodeType & DSNode::Read       ) OS << "R";
#ifndef NDEBUG
    if (NodeType & DSNode::DEAD       ) OS << "<dead>";
#endif
    OS << "\n";
  }

  for (unsigned i = 0, e = N->getGlobals().size(); i != e; ++i) {
    WriteAsOperand(OS, N->getGlobals()[i], false, true, M);
    OS << "\n";
  }

  return OS.str();
}

template<>
struct DOTGraphTraits<const DSGraph*> : public DefaultDOTGraphTraits {
  static std::string getGraphName(const DSGraph *G) {
    switch (G->getReturnNodes().size()) {
    case 0: return G->getFunctionNames();
    case 1: return "Function " + G->getFunctionNames();
    default: return "Functions: " + G->getFunctionNames();
    }
  }

  static const char *getGraphProperties(const DSGraph *G) {
    return "\tsize=\"10,7.5\";\n"
           "\trotate=\"90\";\n";
  }

  static std::string getNodeLabel(const DSNode *Node, const DSGraph *Graph) {
    return getCaption(Node, Graph);
  }

  static std::string getNodeAttributes(const DSNode *N) {
    return "shape=Mrecord";//fontname=Courier";
  }

  /// addCustomGraphFeatures - Use this graph writing hook to emit call nodes
  /// and the return node.
  ///
  static void addCustomGraphFeatures(const DSGraph *G,
                                     GraphWriter<const DSGraph*> &GW) {
    Module *CurMod = 0;
    if (!G->getReturnNodes().empty())
      CurMod = G->getReturnNodes().begin()->first->getParent();

    // Add scalar nodes to the graph...
    const DSGraph::ScalarMapTy &VM = G->getScalarMap();
    for (DSGraph::ScalarMapTy::const_iterator I = VM.begin(); I != VM.end();++I)
      if (!isa<GlobalValue>(I->first)) {
        std::stringstream OS;
        WriteAsOperand(OS, I->first, false, true, CurMod);
        GW.emitSimpleNode(I->first, "", OS.str());

        // Add edge from return node to real destination
        int EdgeDest = I->second.getOffset() >> DS::PointerShift;
        if (EdgeDest == 0) EdgeDest = -1;
        GW.emitEdge(I->first, -1, I->second.getNode(),
                    EdgeDest, "arrowtail=tee,color=gray63");
      }

    // Output the returned value pointer...
    const DSGraph::ReturnNodesTy &RetNodes = G->getReturnNodes();
    for (DSGraph::ReturnNodesTy::const_iterator I = RetNodes.begin(),
           E = RetNodes.end(); I != E; ++I)
      if (I->second.getNode()) {
        std::string Label;
        if (RetNodes.size() == 1)
          Label = "returning";
        else
          Label = I->first->getName() + " ret node";
        // Output the return node...
        GW.emitSimpleNode((void*)1, "plaintext=circle", Label);

        // Add edge from return node to real destination
        int RetEdgeDest = I->second.getOffset() >> DS::PointerShift;;
        if (RetEdgeDest == 0) RetEdgeDest = -1;
        GW.emitEdge((void*)1, -1, I->second.getNode(),
                    RetEdgeDest, "arrowtail=tee,color=gray63");
      }

    // Output all of the call nodes...
    const std::vector<DSCallSite> &FCs =
      G->shouldPrintAuxCalls() ? G->getAuxFunctionCalls()
      : G->getFunctionCalls();
    for (unsigned i = 0, e = FCs.size(); i != e; ++i) {
      const DSCallSite &Call = FCs[i];
      std::vector<std::string> EdgeSourceCaptions(Call.getNumPtrArgs()+2);
      EdgeSourceCaptions[0] = "r";
      if (Call.isDirectCall())
        EdgeSourceCaptions[1] = Call.getCalleeFunc()->getName();
      else
        EdgeSourceCaptions[1] = "f";

      GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2,
                        &EdgeSourceCaptions);

      if (DSNode *N = Call.getRetVal().getNode()) {
        int EdgeDest = Call.getRetVal().getOffset() >> DS::PointerShift;
        if (EdgeDest == 0) EdgeDest = -1;
        GW.emitEdge(&Call, 0, N, EdgeDest, "color=gray63,tailclip=false");
      }

      // Print out the callee...
      if (Call.isIndirectCall()) {
        DSNode *N = Call.getCalleeNode();
        assert(N && "Null call site callee node!");
        GW.emitEdge(&Call, 1, N, -1, "color=gray63,tailclip=false");
      }

      for (unsigned j = 0, e = Call.getNumPtrArgs(); j != e; ++j)
        if (DSNode *N = Call.getPtrArg(j).getNode()) {
          int EdgeDest = Call.getPtrArg(j).getOffset() >> DS::PointerShift;
          if (EdgeDest == 0) EdgeDest = -1;
          GW.emitEdge(&Call, j+2, N, EdgeDest, "color=gray63,tailclip=false");
        }
    }
  }
};

void DSNode::print(std::ostream &O, const DSGraph *G) const {
  GraphWriter<const DSGraph *> W(O, G);
  W.writeNode(this);
}

void DSGraph::print(std::ostream &O) const {
  WriteGraph(O, this, "DataStructures");
}

void DSGraph::writeGraphToFile(std::ostream &O,
                               const std::string &GraphName) const {
  std::string Filename = GraphName + ".dot";
  O << "Writing '" << Filename << "'...";
  std::ofstream F(Filename.c_str());

  if (F.good()) {
    print(F);
    unsigned NumCalls = shouldPrintAuxCalls() ?
      getAuxFunctionCalls().size() : getFunctionCalls().size();
    O << " [" << getGraphSize() << "+" << NumCalls << "]\n";
  } else {
    O << "  error opening file for writing!\n";
  }
}

/// viewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
/// then cleanup.  For use from the debugger.
///
void DSGraph::viewGraph() const {
  std::ofstream F("/tmp/tempgraph.dot");
  if (!F.good()) {
    std::cerr << "Error opening '/tmp/tempgraph.dot' for temporary graph!\n";
    return;
  }
  print(F);
  F.close();
  if (system("dot -Tps /tmp/tempgraph.dot > /tmp/tempgraph.ps"))
    std::cerr << "Error running dot: 'dot' not in path?\n";
  system("gv /tmp/tempgraph.ps");
  system("rm /tmp/tempgraph.dot /tmp/tempgraph.ps");
}

template <typename Collection>
static void printCollection(const Collection &C, std::ostream &O,
                            const Module *M, const std::string &Prefix) {
  if (M == 0) {
    O << "Null Module pointer, cannot continue!\n";
    return;
  }

  unsigned TotalNumNodes = 0, TotalCallNodes = 0;
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
    if (C.hasGraph(*I)) {
      DSGraph &Gr = C.getDSGraph((Function&)*I);
      TotalNumNodes += Gr.getGraphSize();
      unsigned NumCalls = Gr.shouldPrintAuxCalls() ?
        Gr.getAuxFunctionCalls().size() : Gr.getFunctionCalls().size();

      TotalCallNodes += NumCalls;
      if (I->getName() == "main" || !OnlyPrintMain)
        Gr.writeGraphToFile(O, Prefix+I->getName());
      else {
        O << "Skipped Writing '" << Prefix+I->getName() << ".dot'... ["
          << Gr.getGraphSize() << "+" << NumCalls << "]\n";
      }

      if (MaxGraphSize < Gr.getNodes().size())
        MaxGraphSize = Gr.getNodes().size();
      for (unsigned i = 0, e = Gr.getNodes().size(); i != e; ++i)
        if (Gr.getNodes()[i]->isNodeCompletelyFolded())
          ++NumFoldedNodes;
    }

  DSGraph &GG = C.getGlobalsGraph();
  TotalNumNodes  += GG.getGraphSize();
  TotalCallNodes += GG.getFunctionCalls().size();
  if (!OnlyPrintMain) {
    GG.writeGraphToFile(O, Prefix+"GlobalsGraph");
  } else {
    O << "Skipped Writing '" << Prefix << "GlobalsGraph.dot'... ["
      << GG.getGraphSize() << "+" << GG.getFunctionCalls().size() << "]\n";
  }

  O << "\nGraphs contain [" << TotalNumNodes << "+" << TotalCallNodes
    << "] nodes total" << std::endl;
}

// print - Print out the analysis results...
void LocalDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "ds.");
}

void BUDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "bu.");
}

void TDDataStructures::print(std::ostream &O, const Module *M) const {
  printCollection(*this, O, M, "td.");
}
<|endoftext|>


<commit_before>#include "nuclear_burn.hpp"
#include "source/misc/vector_initialiser.hpp"
#include "safe_retrieve.hpp"
#include <fstream>

extern "C" {

  void initnet_(const char* rfile);

  void burn_step_(int* indexeos,
		  double* density,
		  double* energy,
		  double* tburn,
		  double* xn,
		  double* atomw,
		  double* atomn,
		  double* dedtmp,
		  int* matters,
		  double* dt,
		  double* qrec,
		  int* nse,
		  double* tmp_nse,
		  int* key_done,
		  char* screen_type);
}

namespace {

  pair<double,vector<double> > burn_step_wrapper(double density,
						 double energy,
						 double tburn,
						 vector<double> xn,
						 pair<double,double> az,
						 double dt)
  {
    int indexeos = 0;
    double dedtmp = 0;
    int matters = static_cast<int>(xn.size());
    double qrec = 0;
    int nse = 0;
    double tmp_nse = 1e10;
    char screen_type[80] = "default";
    int key_done = 0;
    burn_step_(&indexeos,
	       &density,
	       &energy,
	       &tburn,
	       &xn[0],
	       &az.first,
	       &az.second,
	       &dedtmp,
	       &matters,
	       &dt,
	       &qrec,
	       &nse,
	       &tmp_nse,
	       &key_done,
	       screen_type);
    if(key_done!=1){
      std::ofstream f("burn_step_error_report.txt");
      f << "density = " << density << "\n";
      f << "energy = " << energy << "\n";
      f << "temperature = " << tburn << "\n";
      f << "atomic weight = " << az.first << "\n";
      f << "atomic number = " << az.second << "\n";
      f << "dt = " << dt << "\n";
      f.close();
      assert(key_done==1);
    }
    return pair<double,vector<double> >(qrec,xn);
  }

  vector<double> serialize_tracers(const map<string,double>& tracers,
				   const vector<string>& isotope_list)
  {
    vector<double> res;
    for(size_t i=0;i<isotope_list.size();++i){
      res.push_back(safe_retrieve(tracers,isotope_list.at(i)));
    }
    return res;
  }

  map<string,double> reassemble_tracers(const vector<double>& compositions,
					const vector<string>& isotope_list)
  {
    assert(compositions.size()==isotope_list.size());
    map<string,double> res;
    for(size_t i=0;i<compositions.size();++i)
      res[isotope_list[i]] = compositions[i];
    return res;
  }
}

NuclearBurn::NuclearBurn
(const string& rfile,
 const string& ignore_label,
 const FermiTable& eos):
  t_prev_(0),
  ignore_label_(ignore_label),
  eos_(eos),
  isotope_list_(VectorInitialiser<string>("He4")
		("C12")
		("O16")
		("Ne20")
		("Mg24")
		("Si28")
		("S32")
		("Ar36")
		("Ca40")
		("Ti44")
		("Cr48")
		("Fe52")
		("Ni56")())
{
  initnet_(rfile.c_str());
}

void NuclearBurn::operator()(hdsim& sim)
{
  const double dt = sim.getTime() - t_prev_;
  vector<ComputationalCell>& cells = sim.getAllCells();
  for(size_t i=0;i<cells.size();++i){
    ComputationalCell& cell = cells[i];
    if(safe_retrieve(cell.stickers,ignore_label_))
      continue;
    const double temperature = eos_.dp2t(cell.density,
					 cell.pressure,
					 cell.tracers);
    const double energy = eos_.dp2e(cell.density,
				    cell.pressure,
				    cell.tracers);
    const pair<double,vector<double> > qrec_tracers =
      burn_step_wrapper(cell.density,energy,temperature,
			serialize_tracers(cell.tracers,
					  isotope_list_),
			eos_.calcAverageAtomicProperties(cell.tracers),
			dt);
    const double new_energy = energy + dt*qrec_tracers.first;
    cell.tracers = reassemble_tracers(qrec_tracers.second,isotope_list_);
    cell.pressure = eos_.de2p(cell.density, new_energy, cell.tracers);
  }
  sim.recalculateExtensives();
}
<commit_msg>fix bug<commit_after>#include "nuclear_burn.hpp"
#include "source/misc/vector_initialiser.hpp"
#include "safe_retrieve.hpp"
#include <fstream>

extern "C" {

  void initnet_(const char* rfile);

  void burn_step_(int* indexeos,
		  double* density,
		  double* energy,
		  double* tburn,
		  double* xn,
		  double* atomw,
		  double* atomn,
		  double* dedtmp,
		  int* matters,
		  double* dt,
		  double* qrec,
		  int* nse,
		  double* tmp_nse,
		  int* key_done,
		  char* screen_type);
}

namespace {

  pair<double,vector<double> > burn_step_wrapper(double density,
						 double energy,
						 double tburn,
						 vector<double> xn,
						 pair<double,double> az,
						 double dt)
  {
    int indexeos = 0;
    double dedtmp = 0;
    int matters = static_cast<int>(xn.size());
    double qrec = 0;
    int nse = 0;
    double tmp_nse = 1e10;
    char screen_type[80] = "default";
    int key_done = 0;
    burn_step_(&indexeos,
	       &density,
	       &energy,
	       &tburn,
	       &xn[0],
	       &az.first,
	       &az.second,
	       &dedtmp,
	       &matters,
	       &dt,
	       &qrec,
	       &nse,
	       &tmp_nse,
	       &key_done,
	       screen_type);
    if(key_done!=1){
      std::ofstream f("burn_step_error_report.txt");
      f << "density = " << density << "\n";
      f << "energy = " << energy << "\n";
      f << "temperature = " << tburn << "\n";
      f << "atomic weight = " << az.first << "\n";
      f << "atomic number = " << az.second << "\n";
      f << "dt = " << dt << "\n";
      f.close();
      assert(key_done==1);
    }
    return pair<double,vector<double> >(qrec,xn);
  }

  vector<double> serialize_tracers(const map<string,double>& tracers,
				   const vector<string>& isotope_list)
  {
    vector<double> res;
    for(size_t i=0;i<isotope_list.size();++i){
      res.push_back(safe_retrieve(tracers,isotope_list.at(i)));
    }
    return res;
  }

  map<string,double> reassemble_tracers(const vector<double>& compositions,
					const vector<string>& isotope_list)
  {
    assert(compositions.size()==isotope_list.size());
    map<string,double> res;
    for(size_t i=0;i<compositions.size();++i)
      res[isotope_list[i]] = compositions[i];
    return res;
  }
}

NuclearBurn::NuclearBurn
(const string& rfile,
 const string& ignore_label,
 const FermiTable& eos):
  t_prev_(0),
  ignore_label_(ignore_label),
  eos_(eos),
  isotope_list_(VectorInitialiser<string>("He4")
		("C12")
		("O16")
		("Ne20")
		("Mg24")
		("Si28")
		("S32")
		("Ar36")
		("Ca40")
		("Ti44")
		("Cr48")
		("Fe52")
		("Ni56")())
{
  initnet_(rfile.c_str());
}

void NuclearBurn::operator()(hdsim& sim)
{
  const double dt = sim.getTime() - t_prev_;
  t_prev_ = sim.getTime();
  vector<ComputationalCell>& cells = sim.getAllCells();
  for(size_t i=0;i<cells.size();++i){
    ComputationalCell& cell = cells[i];
    if(safe_retrieve(cell.stickers,ignore_label_))
      continue;
    const double temperature = eos_.dp2t(cell.density,
					 cell.pressure,
					 cell.tracers);
    const double energy = eos_.dp2e(cell.density,
				    cell.pressure,
				    cell.tracers);
    const pair<double,vector<double> > qrec_tracers =
      burn_step_wrapper(cell.density,energy,temperature,
			serialize_tracers(cell.tracers,
					  isotope_list_),
			eos_.calcAverageAtomicProperties(cell.tracers),
			dt);
    const double new_energy = energy + dt*qrec_tracers.first;
    cell.tracers = reassemble_tracers(qrec_tracers.second,isotope_list_);
    cell.pressure = eos_.de2p(cell.density, new_energy, cell.tracers);
  }
  sim.recalculateExtensives();
}
<|endoftext|>


<commit_before>/*
 * Gives the idc's friendly names.
 */

#define vehicle_store 24233
#define main_screen 24234
#define vehicle_list 24235
#define buy_vehicle_button 24236
#define spawn_locations_button 1803
<commit_msg>added idc definitions<commit_after>/*
 * Gives the idc's friendly names.
 */

#define vehicle_store 24233
#define main_screen 24234
#define vehicle_list 24235
 #define vehicle_list_filter 24240
#define buy_vehicle_button 24236
#define vehicle_picture 24237
#define color_selection_text 24238
#define color_selection 24239
<|endoftext|>


<commit_before>/*
 *  This file is part of SmartLamp application.
 *
 * 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.
 *
 */

/*
 * Built for Attiny84 8Mhz, using AVR USBasp programmer.
 * VERSION 0.2
 */

#include <avr/io.h>
#include <avr/sleep.h>
#include <time.h>

#include <Arduino.h>

#include <USIWire.h>
#include <DS3232RTC.h>

// Input/output defines
#define LED_BLUE            5
#define LED_GR              3
#define LED_RED             2

#define BLU_STATE           1
#define BLU_RESET           0

#define RTC_INT_SQW        10

// Serial defines
#define SERIAL_BAUD      9600   // For at mode and for data mode (CC41, HM-10 and MLT-BT05)

// I2C defines
#define SDA                 4
#define SCL                 6

#define SLEEP_TIMEOUT   5000L   // Timeout before sleep
#define LENGTH             80   // Command buffer length

// Global variables
USIWire bus;                    // USIWire instance (I2C bus)
DS3232RTC RTC(bus);             // DS3232 RTC instance (I2C bus)

boolean data = false;
unsigned long prevMillis = 0;   // Millis counter to sleep
bool rtcInitOk = false;         // Communication OK with RTC

// Put the micro to sleep
void system_sleep() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();

  // sleeping ...
  sleep_disable(); // wake up fully
}

/*
 * Converts the date/time to standard Unix epoch format, using time.h library (avr-libc)
 *
 * Param:
 * - int16_t YYYY: year (Gregorian format: ex. 2017)
 * - int8_t MM: month
 * - int8_t DD: day of the month
 * - int8_t hh: hour
 * - int8_t mm: minute
 * - int8_t ss: second
 */
time_t tmConvert_t(int16_t YYYY, int8_t MM, int8_t DD, int8_t hh, int8_t mm, int8_t ss) {
  struct tm tm;
  tm.tm_year = YYYY - 1900 + 30;    // avr-libc time.h: years since 1900 + y2k epoch difference (2000 - 1970)
  tm.tm_mon  = MM - 1;              // avr-libc time.h: months in [0, 11]
  tm.tm_mday = DD;
  tm.tm_hour = hh;
  tm.tm_min  = mm;
  tm.tm_sec  = ss;
  return mk_gmtime(&tm);
}

void printDigits(int digits) {
  Serial.print(':');
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

/*
 * Prints the time in time_t, using the standard Unix epoch format, even if the time_t type is from
 * time.h (avr-libc) and is in Y2K epoch format.
 *
 * Param:
 *  - time_t time: time since Unix epoch
 */
void digitalClockDisplay(time_t time) {
  struct tm tm;

  gmtime_r(&time, &tm);

  // Digital clock display of the time
  Serial.print(tm.tm_hour);
  printDigits(tm.tm_min);
  printDigits(tm.tm_sec);
  Serial.print(' ');
  Serial.print(tm.tm_mday);
  Serial.print('/');
  Serial.print(tm.tm_mon + 1);              // avr-libc time.h: months in [0, 11]
  Serial.print('/');
  Serial.println(tm.tm_year + 1900 - 30);   // avr-libc time.h: years since 1900 + y2k epoch difference (2000 - 1970)
}

// PCINT Interrupt Service Routine (unused)
ISR(PCINT0_vect) {
  // Don't do anything here but we must include this
  // block of code otherwise the interrupt calls an
  // uninitialized interrupt handler.
}

void setup() {
  byte retcode;
  time_t ts;

  OSCCAL = 0x86;                    // Calibrated OSSCAL value with TinyTuner

  Serial.begin(SERIAL_BAUD);
  bus.begin();

  // Pinmode set
  pinMode(LED_BLUE, OUTPUT);
  pinMode(LED_GR, OUTPUT);
  pinMode(LED_RED, OUTPUT);
  pinMode(BLU_STATE, INPUT);
  pinMode(BLU_RESET, OUTPUT);
  pinMode(RTC_INT_SQW, INPUT);

  Serial.print(F("Initial value of OSCCAL is 0x"));
  Serial.println(OSCCAL, HEX);

  ts = tmConvert_t(2032, 10, 20, 23, 05, 00);

  if ((retcode = RTC.set(ts)) == 0)
    rtcInitOk = true;
  else {
    Serial.print(F("RTC Set error: "));
    Serial.print(retcode);
  }

  Serial.print(F("TS: "));
  Serial.println(ts);
  digitalClockDisplay(ts);

  Serial.print(F("RTC set to: "));
  Serial.println(RTC.get());
  digitalClockDisplay(RTC.get());

  ADCSRA  = 0;                      // Disable ADC to save power
  MCUCR  |= _BV(BODS);              // BOD disabled

  PCMSK0 |= _BV(PCINT0);            // Pin change mask: listen to portA bit 0 (D10)
  PCMSK0 |= _BV(PCINT2);            // Pin change mask: listen to portA bit 2 (D8)
  GIMSK  |= _BV(PCIE0);             // Enable PCINT interrupt on portA
}

void loop() {
  size_t count = 0;
  char buffer[LENGTH];

  // FIXME Wake from sleep with new CORE can't read first serial bytes....

  if (millis() - prevMillis >= SLEEP_TIMEOUT) {
    prevMillis = millis();
    Serial.println(F("Sleeping..."));
    system_sleep();
    Serial.println(F("Waking up..."));
    digitalClockDisplay(RTC.get());

    // Necessary to reset the alarm flag on RTC!
    if (RTC.alarm(ALARM_1)) {
      Serial.println(F("From alarm..."));
    }
  }

  while (Serial.available() && count < LENGTH - 1) {
    delay(2);
    char c = (char) Serial.read();

    prevMillis = millis();      // Update prevMillis to reset sleep timeout

    if (c == '\r' || c == '\n') {
      if (c == '\n') {
        data = true;
        Serial.flush();
        break;
      }
      continue;
    }

    buffer[count] = c;
    count++;
  }

  if (data) {
    buffer[count] = '\0';
    //Serial.print("COUNT = ");
    //Serial.println(count);
    Serial.println(buffer);

    count = 0;
    data = false;

    if (strcmp(buffer, "ON") == 0) {
      digitalWrite(LED_BLUE, HIGH);

      RTC.setAlarm(ALM1_MATCH_MINUTES, 00, 10, 23, 0);
      RTC.alarmInterrupt(ALARM_1, true);

//      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
//          analogWrite(LED_BLUE, fadeValue);
//          delay(100);
//        }
//      delay(1000);
//      digitalWrite(LED_BLUE, LOW);
//
//      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
//        analogWrite(LED_RED, fadeValue);
//        delay(100);
//      }
//      delay(1000);
//      digitalWrite(LED_RED, LOW);
//
//      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
//        analogWrite(LED_GR, fadeValue);
//        delay(100);
//      }
//      delay(1000);
//      digitalWrite(LED_GR, LOW);
    }

    if (strcmp(buffer, "OFF") == 0) {
      digitalWrite(LED_BLUE, LOW);
      digitalWrite(LED_RED, LOW);
      digitalWrite(LED_GR, LOW);
    }

    digitalClockDisplay(RTC.get());
  }
}
<commit_msg>Year..<commit_after>/*
 *  This file is part of SmartLamp application.
 *
 * 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.
 *
 */

/*
 * Built for Attiny84 8Mhz, using AVR USBasp programmer.
 * VERSION 0.2
 */

#include <avr/io.h>
#include <avr/sleep.h>
#include <time.h>

#include <Arduino.h>

#include <USIWire.h>
#include <DS3232RTC.h>

// Input/output defines
#define LED_BLUE            5
#define LED_GR              3
#define LED_RED             2

#define BLU_STATE           1
#define BLU_RESET           0

#define RTC_INT_SQW        10

// Serial defines
#define SERIAL_BAUD      9600   // For at mode and for data mode (CC41, HM-10 and MLT-BT05)

// I2C defines
#define SDA                 4
#define SCL                 6

#define SLEEP_TIMEOUT   5000L   // Timeout before sleep
#define LENGTH             80   // Command buffer length

// Global variables
USIWire bus;                    // USIWire instance (I2C bus)
DS3232RTC RTC(bus);             // DS3232 RTC instance (I2C bus)

boolean data = false;
unsigned long prevMillis = 0;   // Millis counter to sleep
bool rtcInitOk = false;         // Communication OK with RTC

// Put the micro to sleep
void system_sleep() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_mode();

  // sleeping ...
  sleep_disable(); // wake up fully
}

/*
 * Converts the date/time to standard Unix epoch format, using time.h library (avr-libc)
 *
 * Param:
 * - int16_t YYYY: year (Gregorian format: ex. 2017)
 * - int8_t MM: month
 * - int8_t DD: day of the month
 * - int8_t hh: hour
 * - int8_t mm: minute
 * - int8_t ss: second
 */
time_t tmConvert_t(int16_t YYYY, int8_t MM, int8_t DD, int8_t hh, int8_t mm, int8_t ss) {
  struct tm tm;
  tm.tm_year = YYYY - 1900 + 30;    // avr-libc time.h: years since 1900 + y2k epoch difference (2000 - 1970)
  tm.tm_mon  = MM - 1;              // avr-libc time.h: months in [0, 11]
  tm.tm_mday = DD;
  tm.tm_hour = hh;
  tm.tm_min  = mm;
  tm.tm_sec  = ss;
  return mk_gmtime(&tm);
}

void printDigits(int digits) {
  Serial.print(':');
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

/*
 * Prints the time in time_t, using the standard Unix epoch format, even if the time_t type is from
 * time.h (avr-libc) and is in Y2K epoch format.
 *
 * Param:
 *  - time_t time: time since Unix epoch
 */
void digitalClockDisplay(time_t time) {
  struct tm tm;

  gmtime_r(&time, &tm);

  // Digital clock display of the time
  Serial.print(tm.tm_hour);
  printDigits(tm.tm_min);
  printDigits(tm.tm_sec);
  Serial.print(' ');
  Serial.print(tm.tm_mday);
  Serial.print('/');
  Serial.print(tm.tm_mon + 1);              // avr-libc time.h: months in [0, 11]
  Serial.print('/');
  Serial.println(tm.tm_year + 1900 - 30);   // avr-libc time.h: years since 1900 + y2k epoch difference (2000 - 1970)
}

// PCINT Interrupt Service Routine (unused)
ISR(PCINT0_vect) {
  // Don't do anything here but we must include this
  // block of code otherwise the interrupt calls an
  // uninitialized interrupt handler.
}

void setup() {
  byte retcode;
  time_t ts;

  OSCCAL = 0x86;                    // Calibrated OSSCAL value with TinyTuner

  Serial.begin(SERIAL_BAUD);
  bus.begin();

  // Pinmode set
  pinMode(LED_BLUE, OUTPUT);
  pinMode(LED_GR, OUTPUT);
  pinMode(LED_RED, OUTPUT);
  pinMode(BLU_STATE, INPUT);
  pinMode(BLU_RESET, OUTPUT);
  pinMode(RTC_INT_SQW, INPUT);

  Serial.print(F("Initial value of OSCCAL is 0x"));
  Serial.println(OSCCAL, HEX);

  ts = tmConvert_t(2017, 10, 20, 23, 05, 00);

  if ((retcode = RTC.set(ts)) == 0)
    rtcInitOk = true;
  else {
    Serial.print(F("RTC Set error: "));
    Serial.print(retcode);
  }

  Serial.print(F("TS: "));
  Serial.println(ts);
  digitalClockDisplay(ts);

  Serial.print(F("RTC set to: "));
  Serial.println(RTC.get());
  digitalClockDisplay(RTC.get());

  ADCSRA  = 0;                      // Disable ADC to save power
  MCUCR  |= _BV(BODS);              // BOD disabled

  PCMSK0 |= _BV(PCINT0);            // Pin change mask: listen to portA bit 0 (D10)
  PCMSK0 |= _BV(PCINT2);            // Pin change mask: listen to portA bit 2 (D8)
  GIMSK  |= _BV(PCIE0);             // Enable PCINT interrupt on portA
}

void loop() {
  size_t count = 0;
  char buffer[LENGTH];

  // FIXME Wake from sleep with new CORE can't read first serial bytes....

  if (millis() - prevMillis >= SLEEP_TIMEOUT) {
    prevMillis = millis();
    Serial.println(F("Sleeping..."));
    system_sleep();
    Serial.println(F("Waking up..."));
    digitalClockDisplay(RTC.get());

    // Necessary to reset the alarm flag on RTC!
    if (RTC.alarm(ALARM_1)) {
      Serial.println(F("From alarm..."));
    }
  }

  while (Serial.available() && count < LENGTH - 1) {
    delay(2);
    char c = (char) Serial.read();

    prevMillis = millis();      // Update prevMillis to reset sleep timeout

    if (c == '\r' || c == '\n') {
      if (c == '\n') {
        data = true;
        Serial.flush();
        break;
      }
      continue;
    }

    buffer[count] = c;
    count++;
  }

  if (data) {
    buffer[count] = '\0';
    //Serial.print("COUNT = ");
    //Serial.println(count);
    Serial.println(buffer);

    count = 0;
    data = false;

    if (strcmp(buffer, "ON") == 0) {
      digitalWrite(LED_BLUE, HIGH);

      RTC.setAlarm(ALM1_MATCH_MINUTES, 00, 10, 23, 0);
      RTC.alarmInterrupt(ALARM_1, true);

//      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
//          analogWrite(LED_BLUE, fadeValue);
//          delay(100);
//        }
//      delay(1000);
//      digitalWrite(LED_BLUE, LOW);
//
//      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
//        analogWrite(LED_RED, fadeValue);
//        delay(100);
//      }
//      delay(1000);
//      digitalWrite(LED_RED, LOW);
//
//      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
//        analogWrite(LED_GR, fadeValue);
//        delay(100);
//      }
//      delay(1000);
//      digitalWrite(LED_GR, LOW);
    }

    if (strcmp(buffer, "OFF") == 0) {
      digitalWrite(LED_BLUE, LOW);
      digitalWrite(LED_RED, LOW);
      digitalWrite(LED_GR, LOW);
    }

    digitalClockDisplay(RTC.get());
  }
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////
/// @file ai.cpp
/// @author Connor McBride
/// @brief Contains definition information for the AI class.
//////////////////////////////////////////////////////////////////////

#include "ai.h"

// @public_functions
// @constructors
AI::AI(int player_id) {
  m_player_id = player_id;

  return;
}

// @game_runners
void AI::init() {

  return;
}

bool AI::run() {
  // Spawn something
  if (!Occupied(1, 1)) {
    spawn(1, 1);
  }

  // Cycle through units
  for (Unit &u : units) {
    // If they're ours
    if (u.player_id() == PlayerID()) {
      // Move them to the right one
      if (!Occupied(u.x() + 1, u.y())) {
        move(u, u.x() + 1, u.y());
      }
    }
  }
  return true;
}

void AI::end() {
  for (Unit &u : units) {
    if (PlayerID() == u.player_id())
      std::cout << u.DebugString() << std::endl;
  }
  return;
}

// @game_state_getters
int AI::PlayerID() {
  return m_player_id;
}

int AI::TurnNumber() {
  return BaseAI::m_turn_number;
}

// @game_state_booleans
bool AI::InMapBounds(int x, int y) {
  return (x >= 0 && x < kMapWidth && y >= 0 && y < kMapHeight);
}

bool AI::Occupied(int x, int y) {
  if (m_unit_coordinate_index_map.find(Coordinate(x, y)) != m_unit_coordinate_index_map.end()) {
    return true;
  }

  return false;
}

// @game_unique
void AI::spawn(int x, int y, int type) {
  if (InMapBounds(x, y)) {
    if (!Occupied(x, y)) {
      Unit u = Unit(x, y, type, AI::m_player_id);
      units.push_back(u);
      m_unit_id_index_map[u.id()] = units.size() - 1;
      m_unit_coordinate_index_map[u.coordinate()] = units.size() - 1;
    } else {
      std::cout << "--Spawn denied at X: " << x << ", Y: " << y << " (Occupied)" << std::endl;
    }
  } else {
    std::cout << "-- Spawn denied at X: " << x << ", Y: " << y << " (Out of Map)" << std::endl;
  }
  return;
}

bool AI::move(Unit &u, int x, int y) {
  if (!Occupied(x, y)) {
    Coordinate temp_coordinate = u.coordinate();
    int index = m_unit_coordinate_index_map[temp_coordinate];
    m_unit_coordinate_index_map.erase(temp_coordinate);
    u.move(x, y);
    m_unit_coordinate_index_map[u.coordinate()] = index;
    return true;
  }
  std::cout << "Move denied X: " << x << ", Y: " << y << " (Occupied)." << std::endl;
  return false;
}

// @static_game_unique
void AI::PrintGameMap() {
  for (int j = 0; j < board.width(); j++) {
    std::cout << "==";
  }
  std::cout << std::endl;
  for (int y = board.height() - 1; y >= 0; y--) {
    for (int x = 0; x < board.width(); x++) {
      if (!Occupied(x, y)) {
        std::cout << ' ' << board.GetTileAt(x, y)->get_char();
      } else {
        std::cout << ' ' << 'x';
      }
    }
    std::cout << std::endl;
  }
  for (int j = 0; j < board.width(); j++) {
    std::cout << "==";
  }
  std::cout << std::endl;
}<commit_msg>Added formatting thing.<commit_after>//////////////////////////////////////////////////////////////////////
/// @file ai.cpp
/// @author Connor McBride
/// @brief Contains definition information for the AI class.
//////////////////////////////////////////////////////////////////////

#include "ai.h"

// @public_functions
// @constructors
AI::AI(int player_id) {
  m_player_id = player_id;

  return;
}

// @game_runners
void AI::init() {

  return;
}

bool AI::run() {
  // Spawn something
  if (!Occupied(1, 1)) {
    spawn(1, 1);
  }

  // Cycle through units
  for (Unit &u : units) {
    // If they're ours
    if (u.player_id() == PlayerID()) {
      // Move them to the right one
      if (!Occupied(u.x() + 1, u.y())) {
        move(u, u.x() + 1, u.y());
      }
    }
  }
  return true;
}

void AI::end() {
  for (Unit &u : units) {
    if (PlayerID() == u.player_id())
      std::cout << u.DebugString() << std::endl;
  }
  return;
}

// @game_state_getters
int AI::PlayerID() {
  return m_player_id;
}

int AI::TurnNumber() {
  return BaseAI::m_turn_number;
}

// @game_state_booleans
bool AI::InMapBounds(int x, int y) {
  return (x >= 0 && x < kMapWidth && y >= 0 && y < kMapHeight);
}

bool AI::Occupied(int x, int y) {
  if (m_unit_coordinate_index_map.find(Coordinate(x, y)) != m_unit_coordinate_index_map.end()) {
    return true;
  }

  return false;
}

// @game_unique
void AI::spawn(int x, int y, int type) {
  if (InMapBounds(x, y)) {
    if (!Occupied(x, y)) {
      Unit u = Unit(x, y, type, AI::m_player_id);
      units.push_back(u);
      m_unit_id_index_map[u.id()] = units.size() - 1;
      m_unit_coordinate_index_map[u.coordinate()] = units.size() - 1;
    } else {
      std::cout << "--Spawn denied at X: " << x << ", Y: " << y << " (Occupied)" << std::endl;
    }
  } else {
    std::cout << "-- Spawn denied at X: " << x << ", Y: " << y << " (Out of Map)" << std::endl;
  }
  return;
}

bool AI::move(Unit &u, int x, int y) {
  if (!Occupied(x, y)) {
    Coordinate temp_coordinate = u.coordinate();
    int index = m_unit_coordinate_index_map[temp_coordinate];
    m_unit_coordinate_index_map.erase(temp_coordinate);
    u.move(x, y);
    m_unit_coordinate_index_map[u.coordinate()] = index;
    return true;
  }
  std::cout << "--Move denied X: " << x << ", Y: " << y << " (Occupied)." << std::endl;
  return false;
}

// @static_game_unique
void AI::PrintGameMap() {
  for (int j = 0; j < board.width(); j++) {
    std::cout << "==";
  }
  std::cout << std::endl;
  for (int y = board.height() - 1; y >= 0; y--) {
    for (int x = 0; x < board.width(); x++) {
      if (!Occupied(x, y)) {
        std::cout << ' ' << board.GetTileAt(x, y)->get_char();
      } else {
        std::cout << ' ' << 'x';
      }
    }
    std::cout << std::endl;
  }
  for (int j = 0; j < board.width(); j++) {
    std::cout << "==";
  }
  std::cout << std::endl;
}<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <deque>

#include "dll_test.hpp"

#include "dll/neural/conv_layer.hpp"
#include "dll/neural/dense_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/pooling/mp_layer.hpp"
#include "dll/pooling/avgp_layer.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

TEST_CASE("unit/conv/sgd/6", "[unit][conv][dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_layer_desc<1, 28, 28, 6, 5, 5, dll::activation<dll::function::RELU>, dll::initializer<dll::initializer_type::HE>>::layer_t,
            dll::conv_layer_desc<6, 24, 24, 6, 5, 5, dll::activation<dll::function::RELU>, dll::initializer<dll::initializer_type::HE>>::layer_t,
            dll::dense_layer_desc<6 * 20 * 20, 200, dll::activation<dll::function::RELU>, dll::initializer<dll::initializer_type::HE>>::layer_t,
            dll::dense_layer_desc<200, 10, dll::activation<dll::function::SOFTMAX>>::layer_t>,
        dll::updater<dll::updater_type::MOMENTUM>, dll::trainer<dll::sgd_trainer>, dll::batch_size<20>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 1, 28, 28>>(600);
    REQUIRE(!dataset.training_images.empty());

    dll_test::mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate    = 0.001;
    dbn->initial_momentum = 0.9;
    dbn->final_momentum   = 0.9;

    FT_CHECK(50, 6e-2);
    TEST_CHECK(0.25);
}

TEST_CASE("unit/conv/sgd/7", "[unit][conv][dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_layer_desc<1, 28, 28, 6, 5, 5, dll::activation<dll::function::RELU>>::layer_t,
            dll::mp_2d_layer_desc<6, 24, 24, 2, 2>::layer_t,
            dll::conv_layer_desc<6, 12, 12, 5, 5, 5, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_layer_desc<5 * 8 * 8, 100, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_layer_desc<100, 10, dll::activation<dll::function::SOFTMAX>>::layer_t>,
        dll::updater<dll::updater_type::MOMENTUM>, dll::trainer<dll::sgd_trainer>, dll::batch_size<20>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 1, 28, 28>>(600);
    REQUIRE(!dataset.training_images.empty());

    dll_test::mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.005;

    FT_CHECK(50, 6e-2);
    TEST_CHECK(0.25);
}

TEST_CASE("unit/conv/sgd/8", "[unit][conv][dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_layer_desc<1, 28, 28, 6, 5, 5, dll::activation<dll::function::RELU>>::layer_t,
            dll::avgp_3d_layer_desc<6, 24, 24, 1, 2, 2>::layer_t,
            dll::conv_layer_desc<6, 12, 12, 6, 5, 5, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_layer_desc<6 * 8 * 8, 100, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_layer_desc<100, 10, dll::activation<dll::function::SOFTMAX>>::layer_t>,
        dll::trainer<dll::sgd_trainer>, dll::updater<dll::updater_type::ADAM>, dll::batch_size<20>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 1, 28, 28>>(1000);
    REQUIRE(!dataset.training_images.empty());

    dll_test::mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->display();

    dbn->learning_rate = 0.001;

    FT_CHECK(25, 6e-2);
    TEST_CHECK(0.25);
}
<commit_msg>Cleanup test<commit_after>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <deque>

#include "dll_test.hpp"

#include "dll/neural/conv_layer.hpp"
#include "dll/neural/dense_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/pooling/mp_layer.hpp"
#include "dll/pooling/avgp_layer.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

TEST_CASE("unit/conv/sgd/6", "[unit][conv][dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_layer_desc<1, 28, 28, 6, 5, 5, dll::activation<dll::function::RELU>, dll::initializer<dll::initializer_type::HE>>::layer_t,
            dll::conv_layer_desc<6, 24, 24, 6, 5, 5, dll::activation<dll::function::RELU>, dll::initializer<dll::initializer_type::HE>>::layer_t,
            dll::dense_layer_desc<6 * 20 * 20, 200, dll::activation<dll::function::RELU>, dll::initializer<dll::initializer_type::HE>>::layer_t,
            dll::dense_layer_desc<200, 10, dll::activation<dll::function::SOFTMAX>>::layer_t>,
        dll::updater<dll::updater_type::MOMENTUM>, dll::trainer<dll::sgd_trainer>, dll::batch_size<20>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 1, 28, 28>>(600);
    REQUIRE(!dataset.training_images.empty());

    dll_test::mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate    = 0.001;
    dbn->initial_momentum = 0.9;
    dbn->final_momentum   = 0.9;

    FT_CHECK(50, 6e-2);
    TEST_CHECK(0.25);
}

TEST_CASE("unit/conv/sgd/7", "[unit][conv][dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_layer_desc<1, 28, 28, 6, 5, 5, dll::activation<dll::function::RELU>>::layer_t,
            dll::mp_2d_layer_desc<6, 24, 24, 2, 2>::layer_t,
            dll::conv_layer_desc<6, 12, 12, 5, 5, 5, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_layer_desc<5 * 8 * 8, 100, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_layer_desc<100, 10, dll::activation<dll::function::SOFTMAX>>::layer_t>,
        dll::updater<dll::updater_type::MOMENTUM>, dll::trainer<dll::sgd_trainer>, dll::batch_size<20>>::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 1, 28, 28>>(600);
    REQUIRE(!dataset.training_images.empty());

    dll_test::mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.005;

    FT_CHECK(50, 6e-2);
    TEST_CHECK(0.25);
}

TEST_CASE("unit/conv/sgd/8", "[unit][conv][dbn][mnist][sgd]") {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_layer<1, 28, 28, 6, 5, 5, dll::relu>,
            dll::avgp_3d_layer<6, 24, 24, 1, 2, 2>,
            dll::conv_layer<6, 12, 12, 6, 5, 5, dll::relu>,
            dll::dense_layer<6 * 8 * 8, 100, dll::relu>,
            dll::dense_layer<100, 10, dll::softmax>
        >,
        dll::updater<dll::updater_type::ADAM>,
        dll::batch_size<20>
    >::dbn_t dbn_t;

    auto dataset = mnist::read_dataset_direct<std::vector, etl::fast_dyn_matrix<float, 1, 28, 28>>(1000);
    REQUIRE(!dataset.training_images.empty());

    dll_test::mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->display();

    dbn->learning_rate = 0.001;

    FT_CHECK(25, 6e-2);
    TEST_CHECK(0.25);
}
<|endoftext|>


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

namespace Urho3D
{

PreviewInspector::PreviewInspector(Context* context)
    : InspectorProvider(context)
    , view_(context, {0, 0, 200, 200})
{
    // Workaround: for some reason this overriden method of our class does not get called by SceneView constructor.
    CreateObjects();

    if (SceneTab* sceneTab = GetSubsystem<Editor>()->GetTab<SceneTab>())
        SetEffectSource(sceneTab->GetViewport()->GetRenderPath());
}

void PreviewInspector::SetModel(Model* model)
{
    auto staticModel = node_->GetOrCreateComponent<StaticModel>();

    staticModel->SetModel(model);
    auto bb = model->GetBoundingBox();
    auto scale = 1.f / Max(bb.Size().x_, Max(bb.Size().y_, bb.Size().z_)) * 0.8f;
    node_->SetScale(scale);
    node_->SetWorldPosition(node_->GetWorldPosition() - staticModel->GetWorldBoundingBox().Center());
}

void PreviewInspector::SetModel(const ea::string& resourceName)
{
    SetModel(context_->GetCache()->GetResource<Model>(resourceName));
}

void PreviewInspector::CreateObjects()
{
    view_.CreateObjects();
    node_ = view_.GetScene()->CreateChild("Preview");
    view_.GetCamera()->GetNode()->CreateComponent<Light>();
    view_.GetCamera()->GetNode()->SetPosition(Vector3::BACK * distance_);
    view_.GetCamera()->GetNode()->LookAt(Vector3::ZERO);
}

void PreviewInspector::RenderPreview()
{
    auto* input = GetSubsystem<Input>();
    auto size = static_cast<int>(ui::GetWindowWidth() - ui::GetCursorPosX());
    view_.SetSize({0, 0, size, size});
    ui::ImageItem(view_.GetTexture(), ImVec2(size, size));
    bool wasActive = mouseGrabbed_;
    mouseGrabbed_ = ui::ItemMouseActivation(MOUSEB_RIGHT) && ui::IsMouseDragging(MOUSEB_RIGHT);
    if (wasActive != mouseGrabbed_)
        input->SetMouseVisible(!mouseGrabbed_);

    if (mouseGrabbed_)
    {
        ui::SetMouseCursor(ImGuiMouseCursor_None);
        Node* node = view_.GetCamera()->GetNode();
        if (input->GetKeyPress(KEY_ESCAPE))
        {
            node->SetPosition(Vector3::BACK * distance_);
            node->LookAt(Vector3::ZERO);
        }
        else
        {
            Vector2 delta(input->GetMouseMove());
            Quaternion rotateDelta = Quaternion(delta.x_ * 0.1f, node->GetUp()) *
                Quaternion(delta.y_ * 0.1f, node->GetRight());
            node->RotateAround(Vector3::ZERO, rotateDelta, TS_WORLD);
        }
    }
}

void PreviewInspector::SetEffectSource(RenderPath* renderPath)
{
    if (renderPath == nullptr)
        return;

    view_.GetViewport()->SetRenderPath(renderPath);
    auto* light = view_.GetCamera()->GetComponent<Light>();
    for (auto& command: renderPath->commands_)
    {
        if (command.pixelShaderName_.starts_with("PBR"))
        {
            // Lights in PBR scenes need modifications, otherwise obects in material preview look very dark
            light->SetUsePhysicalValues(true);
            light->SetBrightness(5000);
            light->SetShadowCascade(CascadeParameters(10, 20, 30, 40, 10));
            return;
        }
    }

    light->SetUsePhysicalValues(false);
    light->SetBrightness(DEFAULT_BRIGHTNESS);
    light->SetShadowCascade(CascadeParameters(DEFAULT_SHADOWSPLIT, 0.0f, 0.0f, 0.0f, DEFAULT_SHADOWFADESTART));
}

}
<commit_msg>Editor: Fix artefacts in model and material previews.<commit_after>//
// Copyright (c) 2017-2020 the rbfx project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#include <Urho3D/Graphics/Viewport.h>
#include <Urho3D/Graphics/RenderPath.h>
#include <Urho3D/Graphics/Light.h>
#include <Urho3D/Graphics/Camera.h>
#include <Urho3D/Graphics/Model.h>
#include <Urho3D/Input/Input.h>
#include <Urho3D/Resource/ResourceCache.h>
#include <Urho3D/SystemUI/SystemUI.h>
#include <Urho3D/Graphics/StaticModel.h>
#include "Tabs/Scene/SceneTab.h"
#include "PreviewInspector.h"
#include "Editor.h"

namespace Urho3D
{

PreviewInspector::PreviewInspector(Context* context)
    : InspectorProvider(context)
    , view_(context, {0, 0, 200, 200})
{
    // Workaround: for some reason this overriden method of our class does not get called by SceneView constructor.
    CreateObjects();

    if (SceneTab* sceneTab = GetSubsystem<Editor>()->GetTab<SceneTab>())
        SetEffectSource(sceneTab->GetViewport()->GetRenderPath());
}

void PreviewInspector::SetModel(Model* model)
{
    auto staticModel = node_->GetOrCreateComponent<StaticModel>();

    staticModel->SetModel(model);
    auto bb = model->GetBoundingBox();
    auto scale = 1.f / Max(bb.Size().x_, Max(bb.Size().y_, bb.Size().z_)) * 0.8f;
    node_->SetScale(scale);
    node_->SetWorldPosition(node_->GetWorldPosition() - staticModel->GetWorldBoundingBox().Center());
}

void PreviewInspector::SetModel(const ea::string& resourceName)
{
    SetModel(context_->GetCache()->GetResource<Model>(resourceName));
}

void PreviewInspector::CreateObjects()
{
    view_.CreateObjects();
    node_ = view_.GetScene()->CreateChild("Preview");
    Node* node = view_.GetCamera()->GetNode();
    node->CreateComponent<Light>();
    node->SetPosition(Vector3::BACK * distance_);
    node->LookAt(Vector3::ZERO);
}

void PreviewInspector::RenderPreview()
{
    auto* input = GetSubsystem<Input>();
    float dpi = ui::GetCurrentWindow()->Viewport->DpiScale;
    float size = ui::GetWindowWidth() - ui::GetCursorPosX();
    view_.SetSize({0, 0, static_cast<int>(size * dpi), static_cast<int>(size * dpi)});
    ui::ImageItem(view_.GetTexture(), ImVec2(size, size));
    bool wasActive = mouseGrabbed_;
    mouseGrabbed_ = ui::ItemMouseActivation(MOUSEB_RIGHT) && ui::IsMouseDragging(MOUSEB_RIGHT);
    if (wasActive != mouseGrabbed_)
        input->SetMouseVisible(!mouseGrabbed_);

    if (mouseGrabbed_)
    {
        ui::SetMouseCursor(ImGuiMouseCursor_None);
        Node* node = view_.GetCamera()->GetNode();
        if (input->GetKeyPress(KEY_ESCAPE))
        {
            node->SetPosition(Vector3::BACK * distance_);
            node->LookAt(Vector3::ZERO);
        }
        else
        {
            Vector2 delta(input->GetMouseMove());
            Quaternion rotateDelta = Quaternion(delta.x_ * 0.1f, node->GetUp()) *
                Quaternion(delta.y_ * 0.1f, node->GetRight());
            node->RotateAround(Vector3::ZERO, rotateDelta, TS_WORLD);
        }
    }
}

void PreviewInspector::SetEffectSource(RenderPath* renderPath)
{
    if (renderPath == nullptr)
        return;

    view_.GetViewport()->SetRenderPath(renderPath);
    auto* light = view_.GetCamera()->GetComponent<Light>();
    for (auto& command: renderPath->commands_)
    {
        if (command.pixelShaderName_.starts_with("PBR"))
        {
            // Lights in PBR scenes need modifications, otherwise obects in material preview look very dark
            light->SetUsePhysicalValues(true);
            light->SetBrightness(5000);
            light->SetShadowCascade(CascadeParameters(10, 20, 30, 40, 10));
            return;
        }
    }

    light->SetUsePhysicalValues(false);
    light->SetBrightness(DEFAULT_BRIGHTNESS);
    light->SetShadowCascade(CascadeParameters(DEFAULT_SHADOWSPLIT, 0.0f, 0.0f, 0.0f, DEFAULT_SHADOWFADESTART));
}

}
<|endoftext|>