<commit_before>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>

    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 "FreeTypeFont.h"

#include <algorithm>
#include <ft2build.h>
#include FT_FREETYPE_H
#include <Utility/Unicode.h>

#include "Extensions.h"
#include "Image.h"
#include "TextureTools/Atlas.h"
#include "TextureTools/DistanceField.h"

namespace Magnum { namespace Text {

namespace {

class FreeTypeLayouter: public AbstractLayouter {
    public:
        explicit FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text);

        std::tuple<Rectangle, Rectangle, Vector2> renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override;

    private:
        FreeTypeFont& font;
        std::vector<FT_UInt> glyphs;
        const Float size;
};

}

FreeTypeFontRenderer::FreeTypeFontRenderer() {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Init_FreeType(&_library) == 0);
}

FreeTypeFontRenderer::~FreeTypeFontRenderer() {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_FreeType(_library) == 0);
}

FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): _size(size) {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &_ftFont) == 0);

    finishConstruction();
}

FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): _size(size) {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Memory_Face(renderer.library(), data, dataSize, 0, &_ftFont) == 0);

    finishConstruction();
}

void FreeTypeFont::finishConstruction() {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, _size*64, 100, 100) == 0);

    #ifndef MAGNUM_TARGET_GLES
    MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg);
    #else
    MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::EXT::texture_rg);
    #endif

    /* Set up the texture */
    _texture.setWrapping(Texture2D::Wrapping::ClampToEdge)
        ->setMinificationFilter(Texture2D::Filter::Linear)
        ->setMagnificationFilter(Texture2D::Filter::Linear);
}

void FreeTypeFont::prerenderInternal(const std::string& characters, const Vector2i& atlasSize, const Int radius, Texture2D* output) {
    glyphs.clear();

    /** @bug Crash when atlas is too small */

    /* Get glyph codes from characters */
    std::vector<FT_UInt> charIndices;
    charIndices.reserve(characters.size()+1);
    charIndices.push_back(0);
    for(std::size_t i = 0; i != characters.size(); ) {
        UnsignedInt codepoint;
        std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(characters, i);
        charIndices.push_back(FT_Get_Char_Index(_ftFont, codepoint));
    }

    /* Remove duplicates (e.g. uppercase and lowercase mapped to same glyph) */
    std::sort(charIndices.begin(), charIndices.end());
    charIndices.erase(std::unique(charIndices.begin(), charIndices.end()), charIndices.end());

    /* Sizes of all characters */
    const Vector2i padding = Vector2i(radius);
    std::vector<Vector2i> charSizes;
    charSizes.reserve(charIndices.size());
    for(FT_UInt c: charIndices) {
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(_ftFont, c, FT_LOAD_DEFAULT) == 0);
        charSizes.push_back(Vector2i(_ftFont->glyph->metrics.width, _ftFont->glyph->metrics.height)/64);
    }

    /* Create texture atlas */
    const std::vector<Rectanglei> charPositions = TextureTools::atlas(atlasSize, charSizes, padding);

    /* Render all characters to the atlas and create character map */
    glyphs.reserve(charPositions.size());
    unsigned char* pixmap = new unsigned char[atlasSize.product()]();
    Image2D image(atlasSize, Image2D::Format::Red, Image2D::Type::UnsignedByte, pixmap);
    for(std::size_t i = 0; i != charPositions.size(); ++i) {
        /* Load and render glyph */
        /** @todo B&W only if radius != 0 */
        FT_GlyphSlot glyph = _ftFont->glyph;
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(_ftFont, charIndices[i], FT_LOAD_DEFAULT) == 0);
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) == 0);

        /* Copy rendered bitmap to texture image */
        const FT_Bitmap& bitmap = glyph->bitmap;
        CORRADE_INTERNAL_ASSERT(std::abs(bitmap.width-charPositions[i].width()) <= 2);
        CORRADE_INTERNAL_ASSERT(std::abs(bitmap.rows-charPositions[i].height()) <= 2);
        for(Int yin = 0, yout = charPositions[i].bottom(), ymax = bitmap.rows; yin != ymax; ++yin, ++yout)
            for(Int xin = 0, xout = charPositions[i].left(), xmax = bitmap.width; xin != xmax; ++xin, ++xout)
                pixmap[yout*atlasSize.x() + xout] = bitmap.buffer[(bitmap.rows-yin-1)*bitmap.width + xin];

        /* Save character texture position and texture coordinates for given character index */
        CORRADE_INTERNAL_ASSERT_OUTPUT(glyphs.insert({charIndices[i], std::make_tuple(
            Rectangle::fromSize((Vector2(glyph->bitmap_left, glyph->bitmap_top-charPositions[i].height()) - Vector2(radius))/_size,
                                Vector2(charPositions[i].size() + 2*padding)/_size),
            Rectangle(Vector2(charPositions[i].bottomLeft() - padding)/atlasSize,
                      Vector2(charPositions[i].topRight() + padding)/atlasSize)
        )}).second);
    }

    /* Set texture data */
    #ifndef MAGNUM_TARGET_GLES
    output->setImage(0, Texture2D::InternalFormat::R8, &image);
    #else
    output->setImage(0, Texture2D::InternalFormat::Red, &image);
    #endif
}

void FreeTypeFont::prerender(const std::string& characters, const Vector2i& atlasSize) {
    prerenderInternal(characters, atlasSize, 0, &_texture);
}

void FreeTypeFont::prerenderDistanceField(const std::string& characters, const Vector2i& sourceAtlasSize, const Vector2i& atlasSize, Int radius) {
    MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_storage);

    /* Render input texture */
    Texture2D input;
    input.setWrapping(Texture2D::Wrapping::ClampToEdge)
        ->setMinificationFilter(Texture2D::Filter::Linear)
        ->setMagnificationFilter(Texture2D::Filter::Linear);
    prerenderInternal(characters, sourceAtlasSize, radius, &input);

    /* Create distance field from input texture */
    _texture.setStorage(1, Texture2D::InternalFormat::R8, atlasSize);
    TextureTools::distanceField(&input, &_texture, Rectanglei::fromSize({}, atlasSize), radius);
}

FreeTypeFont::~FreeTypeFont() {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_Face(_ftFont) == 0);
}

const std::tuple<Rectangle, Rectangle>& FreeTypeFont::operator[](char32_t character) const {
    auto it = glyphs.find(character);

    if(it == glyphs.end())
        return glyphs.at(0);
    return it->second;
}

AbstractLayouter* FreeTypeFont::layout(const Float size, const std::string& text) {
    return new FreeTypeLayouter(*this, size, text);
}

namespace {

FreeTypeLayouter::FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text): font(font), size(size) {
    /* Get glyph codes from characters */
    glyphs.reserve(text.size());
    _glyphCount = text.size();
    for(std::size_t i = 0; i != text.size(); ) {
        UnsignedInt codepoint;
        std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(text, i);
        glyphs.push_back(FT_Get_Char_Index(font.font(), codepoint));
    }
}

std::tuple<Rectangle, Rectangle, Vector2> FreeTypeLayouter::renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) {
    /* Position of the texture in the resulting glyph, texture coordinates */
    Rectangle texturePosition, textureCoordinates;
    std::tie(texturePosition, textureCoordinates) = font[glyphs[i]];

    /* Load glyph */
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(font.font(), glyphs[i], FT_LOAD_DEFAULT) == 0);
    const FT_GlyphSlot  slot = font.font()->glyph;
    Vector2 offset = Vector2(0, 0); /** @todo really? */
    Vector2 advance = Vector2(slot->advance.x, slot->advance.y)/(64*font.size());

    /* Absolute quad position, composed from cursor position, glyph offset
        and texture position, denormalized to requested text size */
    Rectangle quadPosition = Rectangle::fromSize(
        (cursorPosition + offset + Vector2(texturePosition.left(), texturePosition.bottom()))*size,
        texturePosition.size()*size);

    return std::make_tuple(quadPosition, textureCoordinates, advance);
}

}

}}
<commit_msg>Text: properly compute glyph count in FreeTypeFont layouter.<commit_after>/*
    This file is part of Magnum.

    Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>

    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 "FreeTypeFont.h"

#include <algorithm>
#include <ft2build.h>
#include FT_FREETYPE_H
#include <Utility/Unicode.h>

#include "Extensions.h"
#include "Image.h"
#include "TextureTools/Atlas.h"
#include "TextureTools/DistanceField.h"

namespace Magnum { namespace Text {

namespace {

class FreeTypeLayouter: public AbstractLayouter {
    public:
        explicit FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text);

        std::tuple<Rectangle, Rectangle, Vector2> renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) override;

    private:
        FreeTypeFont& font;
        std::vector<FT_UInt> glyphs;
        const Float size;
};

}

FreeTypeFontRenderer::FreeTypeFontRenderer() {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Init_FreeType(&_library) == 0);
}

FreeTypeFontRenderer::~FreeTypeFontRenderer() {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_FreeType(_library) == 0);
}

FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const std::string& fontFile, Float size): _size(size) {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Face(renderer.library(), fontFile.c_str(), 0, &_ftFont) == 0);

    finishConstruction();
}

FreeTypeFont::FreeTypeFont(FreeTypeFontRenderer& renderer, const unsigned char* data, std::size_t dataSize, Float size): _size(size) {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_New_Memory_Face(renderer.library(), data, dataSize, 0, &_ftFont) == 0);

    finishConstruction();
}

void FreeTypeFont::finishConstruction() {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Set_Char_Size(_ftFont, 0, _size*64, 100, 100) == 0);

    #ifndef MAGNUM_TARGET_GLES
    MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg);
    #else
    MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::EXT::texture_rg);
    #endif

    /* Set up the texture */
    _texture.setWrapping(Texture2D::Wrapping::ClampToEdge)
        ->setMinificationFilter(Texture2D::Filter::Linear)
        ->setMagnificationFilter(Texture2D::Filter::Linear);
}

void FreeTypeFont::prerenderInternal(const std::string& characters, const Vector2i& atlasSize, const Int radius, Texture2D* output) {
    glyphs.clear();

    /** @bug Crash when atlas is too small */

    /* Get glyph codes from characters */
    std::vector<FT_UInt> charIndices;
    charIndices.reserve(characters.size()+1);
    charIndices.push_back(0);
    for(std::size_t i = 0; i != characters.size(); ) {
        UnsignedInt codepoint;
        std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(characters, i);
        charIndices.push_back(FT_Get_Char_Index(_ftFont, codepoint));
    }

    /* Remove duplicates (e.g. uppercase and lowercase mapped to same glyph) */
    std::sort(charIndices.begin(), charIndices.end());
    charIndices.erase(std::unique(charIndices.begin(), charIndices.end()), charIndices.end());

    /* Sizes of all characters */
    const Vector2i padding = Vector2i(radius);
    std::vector<Vector2i> charSizes;
    charSizes.reserve(charIndices.size());
    for(FT_UInt c: charIndices) {
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(_ftFont, c, FT_LOAD_DEFAULT) == 0);
        charSizes.push_back(Vector2i(_ftFont->glyph->metrics.width, _ftFont->glyph->metrics.height)/64);
    }

    /* Create texture atlas */
    const std::vector<Rectanglei> charPositions = TextureTools::atlas(atlasSize, charSizes, padding);

    /* Render all characters to the atlas and create character map */
    glyphs.reserve(charPositions.size());
    unsigned char* pixmap = new unsigned char[atlasSize.product()]();
    Image2D image(atlasSize, Image2D::Format::Red, Image2D::Type::UnsignedByte, pixmap);
    for(std::size_t i = 0; i != charPositions.size(); ++i) {
        /* Load and render glyph */
        /** @todo B&W only if radius != 0 */
        FT_GlyphSlot glyph = _ftFont->glyph;
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(_ftFont, charIndices[i], FT_LOAD_DEFAULT) == 0);
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) == 0);

        /* Copy rendered bitmap to texture image */
        const FT_Bitmap& bitmap = glyph->bitmap;
        CORRADE_INTERNAL_ASSERT(std::abs(bitmap.width-charPositions[i].width()) <= 2);
        CORRADE_INTERNAL_ASSERT(std::abs(bitmap.rows-charPositions[i].height()) <= 2);
        for(Int yin = 0, yout = charPositions[i].bottom(), ymax = bitmap.rows; yin != ymax; ++yin, ++yout)
            for(Int xin = 0, xout = charPositions[i].left(), xmax = bitmap.width; xin != xmax; ++xin, ++xout)
                pixmap[yout*atlasSize.x() + xout] = bitmap.buffer[(bitmap.rows-yin-1)*bitmap.width + xin];

        /* Save character texture position and texture coordinates for given character index */
        CORRADE_INTERNAL_ASSERT_OUTPUT(glyphs.insert({charIndices[i], std::make_tuple(
            Rectangle::fromSize((Vector2(glyph->bitmap_left, glyph->bitmap_top-charPositions[i].height()) - Vector2(radius))/_size,
                                Vector2(charPositions[i].size() + 2*padding)/_size),
            Rectangle(Vector2(charPositions[i].bottomLeft() - padding)/atlasSize,
                      Vector2(charPositions[i].topRight() + padding)/atlasSize)
        )}).second);
    }

    /* Set texture data */
    #ifndef MAGNUM_TARGET_GLES
    output->setImage(0, Texture2D::InternalFormat::R8, &image);
    #else
    output->setImage(0, Texture2D::InternalFormat::Red, &image);
    #endif
}

void FreeTypeFont::prerender(const std::string& characters, const Vector2i& atlasSize) {
    prerenderInternal(characters, atlasSize, 0, &_texture);
}

void FreeTypeFont::prerenderDistanceField(const std::string& characters, const Vector2i& sourceAtlasSize, const Vector2i& atlasSize, Int radius) {
    MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_storage);

    /* Render input texture */
    Texture2D input;
    input.setWrapping(Texture2D::Wrapping::ClampToEdge)
        ->setMinificationFilter(Texture2D::Filter::Linear)
        ->setMagnificationFilter(Texture2D::Filter::Linear);
    prerenderInternal(characters, sourceAtlasSize, radius, &input);

    /* Create distance field from input texture */
    _texture.setStorage(1, Texture2D::InternalFormat::R8, atlasSize);
    TextureTools::distanceField(&input, &_texture, Rectanglei::fromSize({}, atlasSize), radius);
}

FreeTypeFont::~FreeTypeFont() {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_Face(_ftFont) == 0);
}

const std::tuple<Rectangle, Rectangle>& FreeTypeFont::operator[](char32_t character) const {
    auto it = glyphs.find(character);

    if(it == glyphs.end())
        return glyphs.at(0);
    return it->second;
}

AbstractLayouter* FreeTypeFont::layout(const Float size, const std::string& text) {
    return new FreeTypeLayouter(*this, size, text);
}

namespace {

FreeTypeLayouter::FreeTypeLayouter(FreeTypeFont& font, const Float size, const std::string& text): font(font), size(size) {
    /* Get glyph codes from characters */
    glyphs.reserve(text.size());
    for(std::size_t i = 0; i != text.size(); ) {
        UnsignedInt codepoint;
        std::tie(codepoint, i) = Corrade::Utility::Unicode::nextChar(text, i);
        glyphs.push_back(FT_Get_Char_Index(font.font(), codepoint));
    }
    _glyphCount = glyphs.size();
}

std::tuple<Rectangle, Rectangle, Vector2> FreeTypeLayouter::renderGlyph(const Vector2& cursorPosition, const UnsignedInt i) {
    /* Position of the texture in the resulting glyph, texture coordinates */
    Rectangle texturePosition, textureCoordinates;
    std::tie(texturePosition, textureCoordinates) = font[glyphs[i]];

    /* Load glyph */
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(font.font(), glyphs[i], FT_LOAD_DEFAULT) == 0);
    const FT_GlyphSlot  slot = font.font()->glyph;
    Vector2 offset = Vector2(0, 0); /** @todo really? */
    Vector2 advance = Vector2(slot->advance.x, slot->advance.y)/(64*font.size());

    /* Absolute quad position, composed from cursor position, glyph offset
        and texture position, denormalized to requested text size */
    Rectangle quadPosition = Rectangle::fromSize(
        (cursorPosition + offset + Vector2(texturePosition.left(), texturePosition.bottom()))*size,
        texturePosition.size()*size);

    return std::make_tuple(quadPosition, textureCoordinates, advance);
}

}

}}
<|endoftext|>


<commit_before><commit_msg>aw: Minor trace event name fix<commit_after><|endoftext|>


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

#include "android_webview/native/aw_settings.h"

#include "android_webview/browser/renderer_host/aw_render_view_host_ext.h"
#include "android_webview/native/aw_contents.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "jni/AwSettings_jni.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "webkit/common/user_agent/user_agent.h"
#include "webkit/common/webpreferences.h"
#include "webkit/glue/webkit_glue.h"

using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF8ToJavaString;
using base::android::ScopedJavaLocalRef;

namespace android_webview {

AwSettings::AwSettings(JNIEnv* env, jobject obj, jint web_contents)
    : WebContentsObserver(
          reinterpret_cast<content::WebContents*>(web_contents)),
      aw_settings_(env, obj) {
}

AwSettings::~AwSettings() {
  JNIEnv* env = base::android::AttachCurrentThread();
  ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
  jobject obj = scoped_obj.obj();
  if (!obj) return;
  Java_AwSettings_nativeAwSettingsGone(env, obj,
                                       reinterpret_cast<jint>(this));
}

void AwSettings::Destroy(JNIEnv* env, jobject obj) {
  delete this;
}

AwRenderViewHostExt* AwSettings::GetAwRenderViewHostExt() {
  if (!web_contents()) return NULL;
  AwContents* contents = AwContents::FromWebContents(web_contents());
  if (!contents) return NULL;
  return contents->render_view_host_ext();
}

void AwSettings::ResetScrollAndScaleState(JNIEnv* env, jobject obj) {
  AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
  if (!rvhe) return;
  rvhe->ResetScrollAndScaleState();
}

void AwSettings::UpdateEverything() {
  JNIEnv* env = base::android::AttachCurrentThread();
  CHECK(env);
  ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
  jobject obj = scoped_obj.obj();
  if (!obj) return;
  // Grab the lock and call UpdateEverythingLocked.
  Java_AwSettings_updateEverything(env, obj);
}

void AwSettings::UpdateEverythingLocked(JNIEnv* env, jobject obj) {
  UpdateInitialPageScaleLocked(env, obj);
  UpdateWebkitPreferencesLocked(env, obj);
  UpdateUserAgentLocked(env, obj);
  ResetScrollAndScaleState(env, obj);
  UpdatePreferredSizeMode();
  UpdateFormDataPreferencesLocked(env, obj);
}

void AwSettings::UpdateUserAgentLocked(JNIEnv* env, jobject obj) {
  if (!web_contents()) return;

  ScopedJavaLocalRef<jstring> str =
      Java_AwSettings_getUserAgentLocked(env, obj);
  bool ua_overidden = str.obj() != NULL;

  if (ua_overidden) {
    std::string override = base::android::ConvertJavaStringToUTF8(str);
    web_contents()->SetUserAgentOverride(override);
  }

  const content::NavigationController& controller =
      web_contents()->GetController();
  for (int i = 0; i < controller.GetEntryCount(); ++i)
    controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(ua_overidden);
}

void AwSettings::UpdateWebkitPreferencesLocked(JNIEnv* env, jobject obj) {
  if (!web_contents()) return;
  AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt();
  if (!render_view_host_ext) return;

  content::RenderViewHost* render_view_host =
      web_contents()->GetRenderViewHost();
  if (!render_view_host) return;
  WebPreferences prefs = render_view_host->GetWebkitPreferences();

  prefs.text_autosizing_enabled =
      Java_AwSettings_getTextAutosizingEnabledLocked(env, obj);

  int text_size_percent = Java_AwSettings_getTextSizePercentLocked(env, obj);
  if (prefs.text_autosizing_enabled) {
    prefs.font_scale_factor = text_size_percent / 100.0f;
    prefs.force_enable_zoom = text_size_percent >= 130;
    // Use the default zoom level value when Text Autosizer is turned on.
    render_view_host_ext->SetTextZoomLevel(0);
  } else {
    prefs.force_enable_zoom = false;
    render_view_host_ext->SetTextZoomLevel(
        WebKit::WebView::zoomFactorToZoomLevel(text_size_percent / 100.0f));
  }

  prefs.standard_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getStandardFontFamilyLocked(env, obj));

  prefs.fixed_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getFixedFontFamilyLocked(env, obj));

  prefs.sans_serif_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getSansSerifFontFamilyLocked(env, obj));

  prefs.serif_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getSerifFontFamilyLocked(env, obj));

  prefs.cursive_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getCursiveFontFamilyLocked(env, obj));

  prefs.fantasy_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getFantasyFontFamilyLocked(env, obj));

  prefs.default_encoding = ConvertJavaStringToUTF8(
      Java_AwSettings_getDefaultTextEncodingLocked(env, obj));

  prefs.minimum_font_size = Java_AwSettings_getMinimumFontSizeLocked(env, obj);

  prefs.minimum_logical_font_size =
      Java_AwSettings_getMinimumLogicalFontSizeLocked(env, obj);

  prefs.default_font_size = Java_AwSettings_getDefaultFontSizeLocked(env, obj);

  prefs.default_fixed_font_size =
      Java_AwSettings_getDefaultFixedFontSizeLocked(env, obj);

  // Blink's LoadsImagesAutomatically and ImagesEnabled must be
  // set cris-cross to Android's. See
  // https://code.google.com/p/chromium/issues/detail?id=224317#c26
  prefs.loads_images_automatically =
      Java_AwSettings_getImagesEnabledLocked(env, obj);
  prefs.images_enabled =
      Java_AwSettings_getLoadsImagesAutomaticallyLocked(env, obj);

  prefs.javascript_enabled =
      Java_AwSettings_getJavaScriptEnabledLocked(env, obj);

  prefs.allow_universal_access_from_file_urls =
      Java_AwSettings_getAllowUniversalAccessFromFileURLsLocked(env, obj);

  prefs.allow_file_access_from_file_urls =
      Java_AwSettings_getAllowFileAccessFromFileURLsLocked(env, obj);

  prefs.javascript_can_open_windows_automatically =
      Java_AwSettings_getJavaScriptCanOpenWindowsAutomaticallyLocked(env, obj);

  prefs.supports_multiple_windows =
      Java_AwSettings_getSupportMultipleWindowsLocked(env, obj);

  prefs.plugins_enabled = !Java_AwSettings_getPluginsDisabledLocked(env, obj);

  prefs.application_cache_enabled =
      Java_AwSettings_getAppCacheEnabledLocked(env, obj);

  prefs.local_storage_enabled =
      Java_AwSettings_getDomStorageEnabledLocked(env, obj);

  prefs.databases_enabled = Java_AwSettings_getDatabaseEnabledLocked(env, obj);

  prefs.double_tap_to_zoom_enabled = prefs.use_wide_viewport =
      Java_AwSettings_getUseWideViewportLocked(env, obj);

  prefs.initialize_at_minimum_page_scale =
      Java_AwSettings_getLoadWithOverviewModeLocked(env, obj);

  prefs.user_gesture_required_for_media_playback =
      Java_AwSettings_getMediaPlaybackRequiresUserGestureLocked(env, obj);

  ScopedJavaLocalRef<jstring> url =
      Java_AwSettings_getDefaultVideoPosterURLLocked(env, obj);
  prefs.default_video_poster_url = url.obj() ?
      GURL(ConvertJavaStringToUTF8(url)) : GURL();

  prefs.support_deprecated_target_density_dpi =
      Java_AwSettings_getSupportDeprecatedTargetDensityDPILocked(env, obj);

  // TODO(primiano): deferred image decoding seems to cause increased memory
  // usage in WebView chromium after http://crrev.com/19838002  (at least on
  // some tests, for instance +18MB on moz and moz2). Thus, deferred image
  // decoding is being disabled until the root of the problem is found.
  // See http://crbug.com/262957 .
  prefs.deferred_image_decoding_enabled = false;

  render_view_host->UpdateWebkitPreferences(prefs);
}

void AwSettings::UpdateInitialPageScaleLocked(JNIEnv* env, jobject obj) {
  AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
  if (!rvhe) return;

  float initial_page_scale_percent =
      Java_AwSettings_getInitialPageScalePercentLocked(env, obj);
  if (initial_page_scale_percent == 0) {
    rvhe->SetInitialPageScale(-1);
  } else {
    float dip_scale = static_cast<float>(
        Java_AwSettings_getDIPScaleLocked(env, obj));
    rvhe->SetInitialPageScale(initial_page_scale_percent / dip_scale / 100.0f);
  }
}

void AwSettings::UpdatePreferredSizeMode() {
  if (web_contents()->GetRenderViewHost()) {
    web_contents()->GetRenderViewHost()->EnablePreferredSizeMode();
  }
}

void AwSettings::UpdateFormDataPreferencesLocked(JNIEnv* env, jobject obj) {
  if (!web_contents()) return;
  AwContents* contents = AwContents::FromWebContents(web_contents());
  if (!contents) return;

  contents->SetSaveFormData(Java_AwSettings_getSaveFormDataLocked(env, obj));
}

void AwSettings::RenderViewCreated(content::RenderViewHost* render_view_host) {
  // A single WebContents can normally have 0 to many RenderViewHost instances
  // associated with it.
  // This is important since there is only one RenderViewHostExt instance per
  // WebContents (and not one RVHExt per RVH, as you might expect) and updating
  // settings via RVHExt only ever updates the 'current' RVH.
  // In android_webview we don't swap out the RVH on cross-site navigations, so
  // we shouldn't have to deal with the multiple RVH per WebContents case. That
  // in turn means that the newly created RVH is always the 'current' RVH
  // (since we only ever go from 0 to 1 RVH instances) and hence the DCHECK.
  DCHECK(web_contents()->GetRenderViewHost() == render_view_host);

  UpdateEverything();
}

void AwSettings::WebContentsDestroyed(content::WebContents* web_contents) {
  delete this;
}

static jint Init(JNIEnv* env,
                 jobject obj,
                 jint web_contents) {
  AwSettings* settings = new AwSettings(env, obj, web_contents);
  return reinterpret_cast<jint>(settings);
}

static jstring GetDefaultUserAgent(JNIEnv* env, jclass clazz) {
  return base::android::ConvertUTF8ToJavaString(
      env, content::GetUserAgent(GURL())).Release();
}

bool RegisterAwSettings(JNIEnv* env) {
  return RegisterNativesImpl(env) >= 0;
}

}  // namespace android_webview
<commit_msg>Remove extra-whitespace in aw_settings.cc.<commit_after>// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "android_webview/native/aw_settings.h"

#include "android_webview/browser/renderer_host/aw_render_view_host_ext.h"
#include "android_webview/native/aw_contents.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "jni/AwSettings_jni.h"
#include "third_party/WebKit/public/web/WebView.h"
#include "webkit/common/user_agent/user_agent.h"
#include "webkit/common/webpreferences.h"
#include "webkit/glue/webkit_glue.h"

using base::android::ConvertJavaStringToUTF16;
using base::android::ConvertUTF8ToJavaString;
using base::android::ScopedJavaLocalRef;

namespace android_webview {

AwSettings::AwSettings(JNIEnv* env, jobject obj, jint web_contents)
    : WebContentsObserver(
          reinterpret_cast<content::WebContents*>(web_contents)),
      aw_settings_(env, obj) {
}

AwSettings::~AwSettings() {
  JNIEnv* env = base::android::AttachCurrentThread();
  ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
  jobject obj = scoped_obj.obj();
  if (!obj) return;
  Java_AwSettings_nativeAwSettingsGone(env, obj,
                                       reinterpret_cast<jint>(this));
}

void AwSettings::Destroy(JNIEnv* env, jobject obj) {
  delete this;
}

AwRenderViewHostExt* AwSettings::GetAwRenderViewHostExt() {
  if (!web_contents()) return NULL;
  AwContents* contents = AwContents::FromWebContents(web_contents());
  if (!contents) return NULL;
  return contents->render_view_host_ext();
}

void AwSettings::ResetScrollAndScaleState(JNIEnv* env, jobject obj) {
  AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
  if (!rvhe) return;
  rvhe->ResetScrollAndScaleState();
}

void AwSettings::UpdateEverything() {
  JNIEnv* env = base::android::AttachCurrentThread();
  CHECK(env);
  ScopedJavaLocalRef<jobject> scoped_obj = aw_settings_.get(env);
  jobject obj = scoped_obj.obj();
  if (!obj) return;
  // Grab the lock and call UpdateEverythingLocked.
  Java_AwSettings_updateEverything(env, obj);
}

void AwSettings::UpdateEverythingLocked(JNIEnv* env, jobject obj) {
  UpdateInitialPageScaleLocked(env, obj);
  UpdateWebkitPreferencesLocked(env, obj);
  UpdateUserAgentLocked(env, obj);
  ResetScrollAndScaleState(env, obj);
  UpdatePreferredSizeMode();
  UpdateFormDataPreferencesLocked(env, obj);
}

void AwSettings::UpdateUserAgentLocked(JNIEnv* env, jobject obj) {
  if (!web_contents()) return;

  ScopedJavaLocalRef<jstring> str =
      Java_AwSettings_getUserAgentLocked(env, obj);
  bool ua_overidden = str.obj() != NULL;

  if (ua_overidden) {
    std::string override = base::android::ConvertJavaStringToUTF8(str);
    web_contents()->SetUserAgentOverride(override);
  }

  const content::NavigationController& controller =
      web_contents()->GetController();
  for (int i = 0; i < controller.GetEntryCount(); ++i)
    controller.GetEntryAtIndex(i)->SetIsOverridingUserAgent(ua_overidden);
}

void AwSettings::UpdateWebkitPreferencesLocked(JNIEnv* env, jobject obj) {
  if (!web_contents()) return;
  AwRenderViewHostExt* render_view_host_ext = GetAwRenderViewHostExt();
  if (!render_view_host_ext) return;

  content::RenderViewHost* render_view_host =
      web_contents()->GetRenderViewHost();
  if (!render_view_host) return;
  WebPreferences prefs = render_view_host->GetWebkitPreferences();

  prefs.text_autosizing_enabled =
      Java_AwSettings_getTextAutosizingEnabledLocked(env, obj);

  int text_size_percent = Java_AwSettings_getTextSizePercentLocked(env, obj);
  if (prefs.text_autosizing_enabled) {
    prefs.font_scale_factor = text_size_percent / 100.0f;
    prefs.force_enable_zoom = text_size_percent >= 130;
    // Use the default zoom level value when Text Autosizer is turned on.
    render_view_host_ext->SetTextZoomLevel(0);
  } else {
    prefs.force_enable_zoom = false;
    render_view_host_ext->SetTextZoomLevel(
        WebKit::WebView::zoomFactorToZoomLevel(text_size_percent / 100.0f));
  }

  prefs.standard_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getStandardFontFamilyLocked(env, obj));

  prefs.fixed_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getFixedFontFamilyLocked(env, obj));

  prefs.sans_serif_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getSansSerifFontFamilyLocked(env, obj));

  prefs.serif_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getSerifFontFamilyLocked(env, obj));

  prefs.cursive_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getCursiveFontFamilyLocked(env, obj));

  prefs.fantasy_font_family_map[webkit_glue::kCommonScript] =
      ConvertJavaStringToUTF16(
          Java_AwSettings_getFantasyFontFamilyLocked(env, obj));

  prefs.default_encoding = ConvertJavaStringToUTF8(
      Java_AwSettings_getDefaultTextEncodingLocked(env, obj));

  prefs.minimum_font_size = Java_AwSettings_getMinimumFontSizeLocked(env, obj);

  prefs.minimum_logical_font_size =
      Java_AwSettings_getMinimumLogicalFontSizeLocked(env, obj);

  prefs.default_font_size = Java_AwSettings_getDefaultFontSizeLocked(env, obj);

  prefs.default_fixed_font_size =
      Java_AwSettings_getDefaultFixedFontSizeLocked(env, obj);

  // Blink's LoadsImagesAutomatically and ImagesEnabled must be
  // set cris-cross to Android's. See
  // https://code.google.com/p/chromium/issues/detail?id=224317#c26
  prefs.loads_images_automatically =
      Java_AwSettings_getImagesEnabledLocked(env, obj);
  prefs.images_enabled =
      Java_AwSettings_getLoadsImagesAutomaticallyLocked(env, obj);

  prefs.javascript_enabled =
      Java_AwSettings_getJavaScriptEnabledLocked(env, obj);

  prefs.allow_universal_access_from_file_urls =
      Java_AwSettings_getAllowUniversalAccessFromFileURLsLocked(env, obj);

  prefs.allow_file_access_from_file_urls =
      Java_AwSettings_getAllowFileAccessFromFileURLsLocked(env, obj);

  prefs.javascript_can_open_windows_automatically =
      Java_AwSettings_getJavaScriptCanOpenWindowsAutomaticallyLocked(env, obj);

  prefs.supports_multiple_windows =
      Java_AwSettings_getSupportMultipleWindowsLocked(env, obj);

  prefs.plugins_enabled = !Java_AwSettings_getPluginsDisabledLocked(env, obj);

  prefs.application_cache_enabled =
      Java_AwSettings_getAppCacheEnabledLocked(env, obj);

  prefs.local_storage_enabled =
      Java_AwSettings_getDomStorageEnabledLocked(env, obj);

  prefs.databases_enabled = Java_AwSettings_getDatabaseEnabledLocked(env, obj);

  prefs.double_tap_to_zoom_enabled = prefs.use_wide_viewport =
      Java_AwSettings_getUseWideViewportLocked(env, obj);

  prefs.initialize_at_minimum_page_scale =
      Java_AwSettings_getLoadWithOverviewModeLocked(env, obj);

  prefs.user_gesture_required_for_media_playback =
      Java_AwSettings_getMediaPlaybackRequiresUserGestureLocked(env, obj);

  ScopedJavaLocalRef<jstring> url =
      Java_AwSettings_getDefaultVideoPosterURLLocked(env, obj);
  prefs.default_video_poster_url = url.obj() ?
      GURL(ConvertJavaStringToUTF8(url)) : GURL();

  prefs.support_deprecated_target_density_dpi =
      Java_AwSettings_getSupportDeprecatedTargetDensityDPILocked(env, obj);

  // TODO(primiano): deferred image decoding seems to cause increased memory
  // usage in WebView chromium after http://crrev.com/19838002  (at least on
  // some tests, for instance +18MB on moz and moz2). Thus, deferred image
  // decoding is being disabled until the root of the problem is found.
  // See http://crbug.com/262957 .
  prefs.deferred_image_decoding_enabled = false;

  render_view_host->UpdateWebkitPreferences(prefs);
}

void AwSettings::UpdateInitialPageScaleLocked(JNIEnv* env, jobject obj) {
  AwRenderViewHostExt* rvhe = GetAwRenderViewHostExt();
  if (!rvhe) return;

  float initial_page_scale_percent =
      Java_AwSettings_getInitialPageScalePercentLocked(env, obj);
  if (initial_page_scale_percent == 0) {
    rvhe->SetInitialPageScale(-1);
  } else {
    float dip_scale = static_cast<float>(
        Java_AwSettings_getDIPScaleLocked(env, obj));
    rvhe->SetInitialPageScale(initial_page_scale_percent / dip_scale / 100.0f);
  }
}

void AwSettings::UpdatePreferredSizeMode() {
  if (web_contents()->GetRenderViewHost()) {
    web_contents()->GetRenderViewHost()->EnablePreferredSizeMode();
  }
}

void AwSettings::UpdateFormDataPreferencesLocked(JNIEnv* env, jobject obj) {
  if (!web_contents()) return;
  AwContents* contents = AwContents::FromWebContents(web_contents());
  if (!contents) return;

  contents->SetSaveFormData(Java_AwSettings_getSaveFormDataLocked(env, obj));
}

void AwSettings::RenderViewCreated(content::RenderViewHost* render_view_host) {
  // A single WebContents can normally have 0 to many RenderViewHost instances
  // associated with it.
  // This is important since there is only one RenderViewHostExt instance per
  // WebContents (and not one RVHExt per RVH, as you might expect) and updating
  // settings via RVHExt only ever updates the 'current' RVH.
  // In android_webview we don't swap out the RVH on cross-site navigations, so
  // we shouldn't have to deal with the multiple RVH per WebContents case. That
  // in turn means that the newly created RVH is always the 'current' RVH
  // (since we only ever go from 0 to 1 RVH instances) and hence the DCHECK.
  DCHECK(web_contents()->GetRenderViewHost() == render_view_host);

  UpdateEverything();
}

void AwSettings::WebContentsDestroyed(content::WebContents* web_contents) {
  delete this;
}

static jint Init(JNIEnv* env,
                 jobject obj,
                 jint web_contents) {
  AwSettings* settings = new AwSettings(env, obj, web_contents);
  return reinterpret_cast<jint>(settings);
}

static jstring GetDefaultUserAgent(JNIEnv* env, jclass clazz) {
  return base::android::ConvertUTF8ToJavaString(
      env, content::GetUserAgent(GURL())).Release();
}

bool RegisterAwSettings(JNIEnv* env) {
  return RegisterNativesImpl(env) >= 0;
}

}  // namespace android_webview
<|endoftext|>


<commit_before>//
// protobuf_broker.cpp
// Projectname: amos-ss16-proj5
//
// Created on 28.05.2016.
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

#include <vector>
#include <string>
#include <limits>
#include <memory>
#include <iostream>

#include <arpa/inet.h>

#include "caf/all.hpp"
#include "caf/io/all.hpp"

CAF_PUSH_WARNINGS
#include "message.pb.h"
CAF_POP_WARNINGS

using namespace std;
using namespace caf;
using namespace caf::io;

void print_on_exit(const actor& hdl, const std::string& name) {
  hdl->attach_functor([=](abstract_actor* ptr, uint32_t reason) {
    aout(ptr) << name << " exited with reason " << reason << endl;
  });
}

/*
  **************************
  Client's behavior -- sends a warning after kickoff and quits
  after the warning has been acknowledged by the server
  **************************
*/
behavior sendWarning(event_based_actor* self) {
  auto count = make_shared<size_t>(0);
  return {
    on(atom("kickoff"), arg_match) >> [=](const actor& pong) {
      self->send(pong, atom("warning"), 1);
      self->become (
        on(atom("ack"), arg_match) >> [=](int value) -> void {
          self->quit();
          return;
        }
      );
    }
  };
}

/*
  **************************
  Server's behavior -- gets the client's warning from the protobuf broker
  and responds with an "ack" message
  **************************
*/
behavior ackMessage() {
  return {
    on(atom("warning"), arg_match) >> [](int value) {
      return make_message(atom("ack"), value);
    }
  };
}

/*
  **************************
  Protobuf broker implementation
  Works as a communication handling middleman for the server/client actors above
  Deserizalizes/serializes messages
  **************************
*/
void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) {
  // monitor buddy to quit broker if buddy is done
  self->monitor(buddy);
  auto write = [=](const org::libcppa::WarnOrAck& p) {
    string buf = p.SerializeAsString();
    int32_t s = htonl(static_cast<int32_t>(buf.size()));
    self->write(hdl, sizeof(int32_t), &s);
    self->write(hdl, buf.size(), buf.data());
    self->flush(hdl);
  };
  // message handler
  message_handler default_bhvr = {
    [=](const connection_closed_msg&) {
      aout(self) << "connection closed" << endl;
      self->send_exit(buddy, exit_reason::remote_link_unreachable);
      self->quit(exit_reason::remote_link_unreachable);
    },
    on(atom("warning"), arg_match) >> [=](int i) {
      aout(self) << "Send: warning " << i << endl;
      org::libcppa::WarnOrAck p;
      p.mutable_warn()->set_id(i);
      write(p);
    },
    on(atom("ack"), arg_match) >> [=](int i) {
      aout(self) << "Send: ack " << i << endl;
      org::libcppa::WarnOrAck p;
      p.mutable_ack()->set_id(i);
      write(p);
    },
    [=](const down_msg& dm) {
      if (dm.source == buddy) {
        aout(self) << "our buddy is down" << endl;
        self->quit(dm.reason);
      }
    },
    others >> [=] {
      cout << "unexpected: " << to_string(self->current_message()) << endl;
    }
  };
  auto await_protobuf_data = message_handler {
    [=](const new_data_msg& msg) {
      org::libcppa::WarnOrAck p;
      p.ParseFromArray(msg.buf.data(), static_cast<int>(msg.buf.size()));
      if (p.has_warn()) {
        aout(self) << "Received: warning " << p.warn().id() << endl;
        self->send(buddy, atom("warning"), p.warn().id());
      }
      else if (p.has_ack()) {
        aout(self) << "Received: ack " << p.ack().id() << endl;
        self->send(buddy, atom("ack"), p.ack().id());
      }
      else {
        self->quit(exit_reason::user_shutdown);
        cerr << "neither Warning nor ACK!" << endl;
      }
      // receive next length prefix
      self->configure_read(hdl, receive_policy::exactly(sizeof(int32_t)));
      self->unbecome();
    }
  }.or_else(default_bhvr);
  auto await_length_prefix = message_handler {
    [=](const new_data_msg& msg) {
      int32_t num_bytes;
      memcpy(&num_bytes, msg.buf.data(), sizeof(int32_t));
      num_bytes = htonl(num_bytes);
      if (num_bytes < 0 || num_bytes > (1024 * 1024)) {
        aout(self) << "someone is trying something nasty" << endl;
        self->quit(exit_reason::user_shutdown);
        return;
      }
      // receive protobuf data
      auto nb = static_cast<size_t>(num_bytes);
      self->configure_read(hdl, receive_policy::exactly(nb));
      self->become(keep_behavior, await_protobuf_data);
    }
  }.or_else(default_bhvr);
  // initial setup
  self->configure_read(hdl, receive_policy::exactly(sizeof(int32_t)));
  self->become(await_length_prefix);
}

/*
 **************************
 Helper method for the server to handle connections;
 Starts the server broker with the received message handle if a client connects
 **************************
*/
behavior server(broker* self, actor buddy) {
  aout(self) << "server is running" << endl;
  return {
    [=](const new_connection_msg& msg) {
      aout(self) << "server accepted new connection" << endl;
      auto io_actor = self->fork(protobuf_io, msg.handle, buddy);
      print_on_exit(io_actor, "protobuf_io");
      // only accept 1 connection in our example
      self->quit();
    },
    others >> [=] {
      cout << "unexpected: " << to_string(self->current_message()) << endl;
    },
    after(std::chrono::seconds(60)) >> [=] {
      aout(self) << "received nothing within 60 seconds..." << endl;
      self->send_exit(buddy, exit_reason::remote_link_unreachable);
      self->quit();
    }
  };
}

optional<uint16_t> as_u16(const std::string& str) {
  return static_cast<uint16_t>(stoul(str));
}

void startClient (uint16_t port, const string& host) {
	cout << "run in client mode" << endl;
	// spawn the actor that sends warnings
	auto client_actor = spawn(sendWarning);
	// spawn a broker to serialize and recognize messages
	auto io_actor = spawn_io_client(protobuf_io, host, port, client_actor);
	print_on_exit(io_actor, "protobuf_io");
	print_on_exit(client_actor, "exit warning");
	// Start the warning message actor by using a kickoff message event sent directly from main
	send_as(io_actor, client_actor, atom("kickoff"), io_actor);
	await_all_actors_done();
  	shutdown();
}

void startServer (uint16_t port) {
	cout << "run in server mode" << endl;
	// spawn the actor that acks messages
	auto serv_actor = spawn(ackMessage);
	// spawn an IO server to handle communication and work with the broker later (uses the behavior server helper)
	auto sever_actor = spawn_io_server(server, port, serv_actor);
	print_on_exit(sever_actor, "server");
	print_on_exit(serv_actor, "exit ack");
	await_all_actors_done();
	shutdown();
}

int main(int argc, char** argv) {
	// Parsing arguments
	message_builder{argv + 1, argv + argc}.apply({
	  on("-s", as_u16) >> [&](uint16_t port) {
		// We are a server
		startServer(port);
	  },
	  on("-c", val<string>, as_u16) >> [&](const string& host, uint16_t port) {
      		// We are a client
		startClient(port, host);
    	  },
    	  others >> [] {
      		cerr << "use with eihter '-s PORT' as server or "
          	"'-c HOST PORT' as client"
           	<< endl;
    }
  });
}
<commit_msg>Still with a bug<commit_after>//
// protobuf_broker.cpp
// Projectname: amos-ss16-proj5
//
// Created on 28.05.2016.
// Copyright (c) 2016 de.fau.cs.osr.amos2016.gruppe5
//
// This file is part of the AMOS Project 2016 @ FAU
// (Friedrich-Alexander University Erlangen-Nürnberg)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

#include "protobuf_broker.h"

void print_on_exit(const actor& hdl, const std::string& name) {
  hdl->attach_functor([=](abstract_actor* ptr, uint32_t reason) {
    aout(ptr) << name << " exited with reason " << reason << endl;
  });
}

/*
  **************************
  Client's behavior -- sends a warning after kickoff and quits
  after the warning has been acknowledged by the server
  **************************
*/
behavior sendWarning(event_based_actor* self) {
  auto count = make_shared<size_t>(0);
  return {
    on(atom("kickoff"), arg_match) >> [=](const actor& pong) {
      self->send(pong, atom("warning"), 1);
      self->become (
        on(atom("ack"), arg_match) >> [=](int value) -> void {
          self->quit();
          return;
        }
      );
    }
  };
}

/*
  **************************
  Server's behavior -- gets the client's warning from the protobuf broker
  and responds with an "ack" message
  **************************
*/
behavior ackMessage() {
  return {
    on(atom("warning"), arg_match) >> [](int value) {
      return make_message(atom("ack"), value);
    }
  };
}

/*
  **************************
  Protobuf broker implementation
  Works as a communication handling middleman for the server/client actors above
  Deserizalizes/serializes messages
  **************************
*/
void protobuf_io(broker* self, connection_handle hdl, const actor& buddy) {
  // monitor buddy to quit broker if buddy is done
  self->monitor(buddy);
  auto write = [=](const org::libcppa::WarnOrAck& p) {
    string buf = p.SerializeAsString();
    int32_t s = htonl(static_cast<int32_t>(buf.size()));
    self->write(hdl, sizeof(int32_t), &s);
    self->write(hdl, buf.size(), buf.data());
    self->flush(hdl);
  };
  // message handler
  message_handler default_bhvr = {
    [=](const connection_closed_msg&) {
      aout(self) << "connection closed" << endl;
      self->send_exit(buddy, exit_reason::remote_link_unreachable);
      self->quit(exit_reason::remote_link_unreachable);
    },
    on(atom("warning"), arg_match) >> [=](int i) {
      aout(self) << "Send: warning " << i << endl;
      org::libcppa::WarnOrAck p;
      p.mutable_warn()->set_id(i);
      write(p);
    },
    on(atom("ack"), arg_match) >> [=](int i) {
      aout(self) << "Send: ack " << i << endl;
      org::libcppa::WarnOrAck p;
      p.mutable_ack()->set_id(i);
      write(p);
    },
    [=](const down_msg& dm) {
      if (dm.source == buddy) {
        aout(self) << "our buddy is down" << endl;
        self->quit(dm.reason);
      }
    },
    others >> [=] {
      cout << "unexpected: " << to_string(self->current_message()) << endl;
    }
  };
  auto await_protobuf_data = message_handler {
    [=](const new_data_msg& msg) {
      org::libcppa::WarnOrAck p;
      p.ParseFromArray(msg.buf.data(), static_cast<int>(msg.buf.size()));
      if (p.has_warn()) {
        aout(self) << "Received: warning " << p.warn().id() << endl;
        self->send(buddy, atom("warning"), p.warn().id());
      }
      else if (p.has_ack()) {
        aout(self) << "Received: ack " << p.ack().id() << endl;
        self->send(buddy, atom("ack"), p.ack().id());
      }
      else {
        self->quit(exit_reason::user_shutdown);
        cerr << "neither Warning nor ACK!" << endl;
      }
      // receive next length prefix
      self->configure_read(hdl, receive_policy::exactly(sizeof(int32_t)));
      self->unbecome();
    }
  }.or_else(default_bhvr);
  auto await_length_prefix = message_handler {
    [=](const new_data_msg& msg) {
      int32_t num_bytes;
      memcpy(&num_bytes, msg.buf.data(), sizeof(int32_t));
      num_bytes = htonl(num_bytes);
      if (num_bytes < 0 || num_bytes > (1024 * 1024)) {
        aout(self) << "someone is trying something nasty" << endl;
        self->quit(exit_reason::user_shutdown);
        return;
      }
      // receive protobuf data
      auto nb = static_cast<size_t>(num_bytes);
      self->configure_read(hdl, receive_policy::exactly(nb));
      self->become(keep_behavior, await_protobuf_data);
    }
  }.or_else(default_bhvr);
  // initial setup
  self->configure_read(hdl, receive_policy::exactly(sizeof(int32_t)));
  self->become(await_length_prefix);
}

/*
 **************************
 Helper method for the server to handle connections;
 Starts the server broker with the received message handle if a client connects
 **************************
*/
behavior server(broker* self, actor buddy) {
  aout(self) << "server is running" << endl;
  return {
    [=](const new_connection_msg& msg) {
      aout(self) << "server accepted new connection" << endl;
      auto io_actor = self->fork(protobuf_io, msg.handle, buddy);
      print_on_exit(io_actor, "protobuf_io");
      // only accept 1 connection in our example
      self->quit();
    },
    others >> [=] {
      cout << "unexpected: " << to_string(self->current_message()) << endl;
    },
    after(std::chrono::seconds(60)) >> [=] {
      aout(self) << "received nothing within 60 seconds..." << endl;
      self->send_exit(buddy, exit_reason::remote_link_unreachable);
      self->quit();
    }
  };
}

optional<uint16_t> as_u16(const std::string& str) {
  return static_cast<uint16_t>(stoul(str));
}

void startClient (uint16_t port, const string& host) {
	cout << "run in client mode" << endl;
	// spawn the actor that sends warnings
	auto client_actor = spawn(sendWarning);
	// spawn a broker to serialize and recognize messages
	auto io_actor = spawn_io_client(protobuf_io, host, port, client_actor);
	print_on_exit(io_actor, "protobuf_io");
	print_on_exit(client_actor, "exit warning");
	// Start the warning message actor by using a kickoff message event sent directly from main
	send_as(io_actor, client_actor, atom("kickoff"), io_actor);
	await_all_actors_done();
  	shutdown();
}

void startServer (uint16_t port) {
	cout << "run in server mode" << endl;
	// spawn the actor that acks messages
	auto serv_actor = spawn(ackMessage);
	// spawn an IO server to handle communication and work with the broker later (uses the behavior server helper)
	auto sever_actor = spawn_io_server(server, port, serv_actor);
	print_on_exit(sever_actor, "server");
	print_on_exit(serv_actor, "exit ack");
	await_all_actors_done();
	shutdown();
}

int main(int argc, char** argv) {
	// Parsing arguments
	message_builder{argv + 1, argv + argc}.apply({
	  on("-s", as_u16) >> [&](uint16_t port) {
		// We are a server
		startServer(port);
	  },
	  on("-c", val<string>, as_u16) >> [&](const string& host, uint16_t port) {
      		// We are a client
		startClient(port, host);
    	  },
    	  others >> [] {
      		cerr << "use with eihter '-s PORT' as server or "
          	"'-c HOST PORT' as client"
           	<< endl;
    }
  });
}
<|endoftext|>


<commit_before>/* Copyright (c) 2014, Chris Berger, Jesse Freitas, Severin Ibarluzea,
Kiana McNellis, Kienan Knight-Boehm, Sam Seng

All rights reserved.
This code is licensed using the BSD "3-Clause" license. Please refer to
"LICENSE.md" for the full license.
*/
#include <stdlib.h>
#include <string>
#include <iostream>
#include <sstream>

#include "../modules/modules.h"
#include "TestCase.h"

#include "../sampleConfig/HW1/config.h"

using std::ifstream;
using std::ofstream;
using std::string;
using std::cout;
using std::endl;
using std::cerr;

int execute(const string& cmd);
string to_string(int i);

int main(int argc, char* argv[]) {
	cout << "Running User Code..." << endl;

	// Make sure arguments are entered correctly
	if (argc != 1) {
		//Pass in the current working directory to run the programs
		cout << "Incorrect # of arguments:" << argc << endl;
		cout << "Usage : " << endl
				<< "     ./runner" << endl;
		return 2;
	}
	if(compile_command != ""){
		int compile = execute(compile_command + " 2>.compile_out.txt");
		if(compile){
			cerr << "COMPILATION FAILED" << endl;
			exit(1);
		}
	}
	int n = 0;
	if(readmeTestCase != NULL)
		n++;
	if(compilationTestCase != NULL)
		n++;

	// Run each test case and create output files
	for (unsigned int i = 0 + n; i < num_testcases; i++) {
		cout << testcases[i].command() << std::endl;

		if(testcases[i].recompile()){
			int recomp = execute(testcases[i].compile_cmd() + " 2>.compile_out_" + to_string(i) + ".txt");
			if(recomp){
				cerr << "Recompilation in test case " << testcases[i].title() << " failed; No points will be awarded." << std::endl;
				continue;
			}
		}

		string cmd = testcases[i].command();
		if (cmd != "") {
			int exit_no = execute(cmd + " 1>test" + to_string(i+1-n)
							+ "_cout.txt 2>test" + to_string(i+1-n)
							+ "_cerr.txt");
		}

		// Recompile the original in case the executable was overwritten
		if(testcases[i].recompile() && compile_command != ""){
			execute(compile_command);
		}
	}

	return 0;
}

// Executes command (from shell) and returns error code (0 = success)
int execute(const string& cmd) {
	return system(cmd.c_str());
}

string to_string(int i) {
	std::ostringstream tmp;
	tmp << i;
	return tmp.str();
}
<commit_msg>typo in compiliation test case name<commit_after>/* Copyright (c) 2014, Chris Berger, Jesse Freitas, Severin Ibarluzea,
Kiana McNellis, Kienan Knight-Boehm, Sam Seng

All rights reserved.
This code is licensed using the BSD "3-Clause" license. Please refer to
"LICENSE.md" for the full license.
*/
#include <stdlib.h>
#include <string>
#include <iostream>
#include <sstream>

#include "../modules/modules.h"
#include "TestCase.h"

#include "../sampleConfig/HW1/config.h"

using std::ifstream;
using std::ofstream;
using std::string;
using std::cout;
using std::endl;
using std::cerr;

int execute(const string& cmd);
string to_string(int i);

int main(int argc, char* argv[]) {
	cout << "Running User Code..." << endl;

	// Make sure arguments are entered correctly
	if (argc != 1) {
		//Pass in the current working directory to run the programs
		cout << "Incorrect # of arguments:" << argc << endl;
		cout << "Usage : " << endl
				<< "     ./runner" << endl;
		return 2;
	}
	if(compile_command != ""){
		int compile = execute(compile_command + " 2>.compile_out.txt");
		if(compile){
			cerr << "COMPILATION FAILED" << endl;
			exit(1);
		}
	}
	int n = 0;
	if(readmeTestCase != NULL)
		n++;
	if(compileTestCase != NULL)
		n++;

	// Run each test case and create output files
	for (unsigned int i = 0 + n; i < num_testcases; i++) {
		cout << testcases[i].command() << std::endl;

		if(testcases[i].recompile()){
			int recomp = execute(testcases[i].compile_cmd() + " 2>.compile_out_" + to_string(i) + ".txt");
			if(recomp){
				cerr << "Recompilation in test case " << testcases[i].title() << " failed; No points will be awarded." << std::endl;
				continue;
			}
		}

		string cmd = testcases[i].command();
		if (cmd != "") {
			int exit_no = execute(cmd + " 1>test" + to_string(i+1-n)
							+ "_cout.txt 2>test" + to_string(i+1-n)
							+ "_cerr.txt");
		}

		// Recompile the original in case the executable was overwritten
		if(testcases[i].recompile() && compile_command != ""){
			execute(compile_command);
		}
	}

	return 0;
}

// Executes command (from shell) and returns error code (0 = success)
int execute(const string& cmd) {
	return system(cmd.c_str());
}

string to_string(int i) {
	std::ostringstream tmp;
	tmp << i;
	return tmp.str();
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2008-2017 the Urho3D project.
// 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 <EASTL/sort.h>

#include "../Core/Context.h"
#include "../Core/CoreEvents.h"
#include "../Core/Profiler.h"
#include "../Engine/Engine.h"
#include "../Graphics/Graphics.h"
#include "../Graphics/Renderer.h"
#include "../Graphics/GraphicsEvents.h"
#include "../IO/Log.h"
#include "../UI/UI.h"
#include "../SystemUI/SystemUI.h"
#include "../SystemUI/DebugHud.h"

#include "../DebugNew.h"

namespace Urho3D
{

static const char* qualityTexts[] =
{
    "Low",
    "Med",
    "High"
};

static const char* shadowQualityTexts[] =
{
    "16bit Low",
    "24bit Low",
    "16bit High",
    "24bit High"
};

static const unsigned FPS_UPDATE_INTERVAL_MS = 500;

DebugHud::DebugHud(Context* context)
    : Object(context)
{
    SubscribeToEvent(E_UPDATE, URHO3D_HANDLER(DebugHud, OnRenderDebugUI));
}

DebugHud::~DebugHud()
{
    UnsubscribeFromAllEvents();
}

void DebugHud::SetMode(DebugHudModeFlags mode)
{
    mode_ = mode;
}

void DebugHud::CycleMode()
{
    switch (mode_.AsInteger())
    {
    case DEBUGHUD_SHOW_NONE:
        SetMode(DEBUGHUD_SHOW_STATS);
        break;
    case DEBUGHUD_SHOW_STATS:
        SetMode(DEBUGHUD_SHOW_MODE);
        break;
    case DEBUGHUD_SHOW_MODE:
        SetMode(DEBUGHUD_SHOW_ALL);
        break;
    case DEBUGHUD_SHOW_ALL:
    default:
        SetMode(DEBUGHUD_SHOW_NONE);
        break;
    }
}

void DebugHud::SetUseRendererStats(bool enable)
{
    useRendererStats_ = enable;
}

void DebugHud::Toggle(DebugHudModeFlags mode)
{
    SetMode(GetMode() ^ mode);
}

void DebugHud::ToggleAll()
{
    Toggle(DEBUGHUD_SHOW_ALL);
}

void DebugHud::SetAppStats(const ea::string& label, const Variant& stats)
{
    SetAppStats(label, stats.ToString());
}

void DebugHud::SetAppStats(const ea::string& label, const ea::string& stats)
{
    appStats_[label] = stats;
}

bool DebugHud::ResetAppStats(const ea::string& label)
{
    return appStats_.erase(label);
}

void DebugHud::ClearAppStats()
{
    appStats_.clear();
}

void DebugHud::RenderUI(DebugHudModeFlags mode)
{
    if (mode == DEBUGHUD_SHOW_NONE)
        return;

    Renderer* renderer = GetSubsystem<Renderer>();
    Graphics* graphics = GetSubsystem<Graphics>();
    if (mode & DEBUGHUD_SHOW_STATS)
    {
        // Update stats regardless of them being shown.
        if (fpsTimer_.GetMSec(false) > FPS_UPDATE_INTERVAL_MS)
        {
            fps_ = static_cast<unsigned int>(Round(context_->GetSubsystem<Time>()->GetFramesPerSecond()));
            fpsTimer_.Reset();
        }

        ea::string stats;
        unsigned primitives, batches;
        if (!useRendererStats_)
        {
            primitives = graphics->GetNumPrimitives();
            batches = graphics->GetNumBatches();
        }
        else
        {
            primitives = context_->GetSubsystem<Renderer>()->GetNumPrimitives();
            batches = context_->GetSubsystem<Renderer>()->GetNumBatches();
        }

        float left_offset = ui::GetCursorPos().x;

        ui::Text("FPS %d", fps_);
        ui::SetCursorPosX(left_offset);
        ui::Text("Triangles %u", primitives);
        ui::SetCursorPosX(left_offset);
        ui::Text("Batches %u", batches);
        ui::SetCursorPosX(left_offset);
        ui::Text("Views %u", renderer->GetNumViews());
        ui::SetCursorPosX(left_offset);
        ui::Text("Lights %u", renderer->GetNumLights(true));
        ui::SetCursorPosX(left_offset);
        ui::Text("Shadowmaps %u", renderer->GetNumShadowMaps(true));
        ui::SetCursorPosX(left_offset);
        ui::Text("Occluders %u", renderer->GetNumOccluders(true));
        ui::SetCursorPosX(left_offset);

        for (auto i = appStats_.begin(); i != appStats_.end(); ++i)
        {
            ui::Text("%s %s", i->first.c_str(), i->second.c_str());
            ui::SetCursorPosX(left_offset);
        }
    }

    if (mode & DEBUGHUD_SHOW_MODE)
    {
        const ImGuiStyle& style = ui::GetStyle();
        const ImGuiContext& g = *ui::GetCurrentContext();
        ui::SetCursorPos({style.WindowPadding.x, ui::GetWindowSize().y - ui::GetStyle().WindowPadding.y - g.Font->FontSize});
        ui::Text("Tex:%s | Mat:%s | Spec:%s | Shadows:%s | Size:%i | Quality:%s | Occlusion:%s | Instancing:%s | API:%s",
            qualityTexts[renderer->GetTextureQuality()],
            qualityTexts[renderer->GetMaterialQuality()],
            renderer->GetSpecularLighting() ? "On" : "Off",
            renderer->GetDrawShadows() ? "On" : "Off",
            renderer->GetShadowMapSize(),
            shadowQualityTexts[renderer->GetShadowQuality()],
            renderer->GetMaxOccluderTriangles() > 0 ? "On" : "Off",
            renderer->GetDynamicInstancing() ? "On" : "Off",
            graphics->GetApiName().c_str());
    }
}

void DebugHud::OnRenderDebugUI(StringHash, VariantMap&)
{
    ImGuiViewport* viewport = ui::GetMainViewport();
    ui::SetNextWindowPos(viewport->Pos);
    ui::SetNextWindowSize(viewport->Size);
    ui::SetNextWindowViewport(viewport->ID);
    ui::PushStyleColor(ImGuiCol_WindowBg, 0);
    ui::PushStyleColor(ImGuiCol_Border, 0);
    unsigned flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove |
                     ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoScrollbar;
    if (ui::Begin("DebugHud", nullptr, flags))
        RenderUI(mode_);
    ui::End();
    ui::PopStyleColor(2);
}

}
<commit_msg>Fix out of range bug in DebugHUD when changing shadow quality.<commit_after>//
// Copyright (c) 2008-2017 the Urho3D project.
// 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 <EASTL/sort.h>

#include "../Core/Context.h"
#include "../Core/CoreEvents.h"
#include "../Core/Profiler.h"
#include "../Engine/Engine.h"
#include "../Graphics/Graphics.h"
#include "../Graphics/Renderer.h"
#include "../Graphics/GraphicsEvents.h"
#include "../IO/Log.h"
#include "../UI/UI.h"
#include "../SystemUI/SystemUI.h"
#include "../SystemUI/DebugHud.h"

#include "../DebugNew.h"

namespace Urho3D
{

static const char* qualityTexts[] =
{
    "Low",
    "Med",
    "High"
};

static const char* shadowQualityTexts[] =
{
    "16bit Low",
    "24bit Low",
    "16bit High",
    "24bit High",
    "VSM",
    "Blur VSM"
};

static const unsigned FPS_UPDATE_INTERVAL_MS = 500;

DebugHud::DebugHud(Context* context)
    : Object(context)
{
    SubscribeToEvent(E_UPDATE, URHO3D_HANDLER(DebugHud, OnRenderDebugUI));
}

DebugHud::~DebugHud()
{
    UnsubscribeFromAllEvents();
}

void DebugHud::SetMode(DebugHudModeFlags mode)
{
    mode_ = mode;
}

void DebugHud::CycleMode()
{
    switch (mode_.AsInteger())
    {
    case DEBUGHUD_SHOW_NONE:
        SetMode(DEBUGHUD_SHOW_STATS);
        break;
    case DEBUGHUD_SHOW_STATS:
        SetMode(DEBUGHUD_SHOW_MODE);
        break;
    case DEBUGHUD_SHOW_MODE:
        SetMode(DEBUGHUD_SHOW_ALL);
        break;
    case DEBUGHUD_SHOW_ALL:
    default:
        SetMode(DEBUGHUD_SHOW_NONE);
        break;
    }
}

void DebugHud::SetUseRendererStats(bool enable)
{
    useRendererStats_ = enable;
}

void DebugHud::Toggle(DebugHudModeFlags mode)
{
    SetMode(GetMode() ^ mode);
}

void DebugHud::ToggleAll()
{
    Toggle(DEBUGHUD_SHOW_ALL);
}

void DebugHud::SetAppStats(const ea::string& label, const Variant& stats)
{
    SetAppStats(label, stats.ToString());
}

void DebugHud::SetAppStats(const ea::string& label, const ea::string& stats)
{
    appStats_[label] = stats;
}

bool DebugHud::ResetAppStats(const ea::string& label)
{
    return appStats_.erase(label);
}

void DebugHud::ClearAppStats()
{
    appStats_.clear();
}

void DebugHud::RenderUI(DebugHudModeFlags mode)
{
    if (mode == DEBUGHUD_SHOW_NONE)
        return;

    Renderer* renderer = GetSubsystem<Renderer>();
    Graphics* graphics = GetSubsystem<Graphics>();
    if (mode & DEBUGHUD_SHOW_STATS)
    {
        // Update stats regardless of them being shown.
        if (fpsTimer_.GetMSec(false) > FPS_UPDATE_INTERVAL_MS)
        {
            fps_ = static_cast<unsigned int>(Round(context_->GetSubsystem<Time>()->GetFramesPerSecond()));
            fpsTimer_.Reset();
        }

        ea::string stats;
        unsigned primitives, batches;
        if (!useRendererStats_)
        {
            primitives = graphics->GetNumPrimitives();
            batches = graphics->GetNumBatches();
        }
        else
        {
            primitives = context_->GetSubsystem<Renderer>()->GetNumPrimitives();
            batches = context_->GetSubsystem<Renderer>()->GetNumBatches();
        }

        float left_offset = ui::GetCursorPos().x;

        ui::Text("FPS %d", fps_);
        ui::SetCursorPosX(left_offset);
        ui::Text("Triangles %u", primitives);
        ui::SetCursorPosX(left_offset);
        ui::Text("Batches %u", batches);
        ui::SetCursorPosX(left_offset);
        ui::Text("Views %u", renderer->GetNumViews());
        ui::SetCursorPosX(left_offset);
        ui::Text("Lights %u", renderer->GetNumLights(true));
        ui::SetCursorPosX(left_offset);
        ui::Text("Shadowmaps %u", renderer->GetNumShadowMaps(true));
        ui::SetCursorPosX(left_offset);
        ui::Text("Occluders %u", renderer->GetNumOccluders(true));
        ui::SetCursorPosX(left_offset);

        for (auto i = appStats_.begin(); i != appStats_.end(); ++i)
        {
            ui::Text("%s %s", i->first.c_str(), i->second.c_str());
            ui::SetCursorPosX(left_offset);
        }
    }

    if (mode & DEBUGHUD_SHOW_MODE)
    {
        const ImGuiStyle& style = ui::GetStyle();
        const ImGuiContext& g = *ui::GetCurrentContext();
        ui::SetCursorPos({style.WindowPadding.x, ui::GetWindowSize().y - ui::GetStyle().WindowPadding.y - g.Font->FontSize});
        ui::Text("Tex:%s | Mat:%s | Spec:%s | Shadows:%s | Size:%i | Quality:%s | Occlusion:%s | Instancing:%s | API:%s",
            qualityTexts[renderer->GetTextureQuality()],
            qualityTexts[renderer->GetMaterialQuality()],
            renderer->GetSpecularLighting() ? "On" : "Off",
            renderer->GetDrawShadows() ? "On" : "Off",
            renderer->GetShadowMapSize(),
            shadowQualityTexts[renderer->GetShadowQuality()],
            renderer->GetMaxOccluderTriangles() > 0 ? "On" : "Off",
            renderer->GetDynamicInstancing() ? "On" : "Off",
            graphics->GetApiName().c_str());
    }
}

void DebugHud::OnRenderDebugUI(StringHash, VariantMap&)
{
    ImGuiViewport* viewport = ui::GetMainViewport();
    ui::SetNextWindowPos(viewport->Pos);
    ui::SetNextWindowSize(viewport->Size);
    ui::SetNextWindowViewport(viewport->ID);
    ui::PushStyleColor(ImGuiCol_WindowBg, 0);
    ui::PushStyleColor(ImGuiCol_Border, 0);
    unsigned flags = ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove |
                     ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoScrollbar;
    if (ui::Begin("DebugHud", nullptr, flags))
        RenderUI(mode_);
    ui::End();
    ui::PopStyleColor(2);
}

}
<|endoftext|>


<commit_before>
/*
    pbrt source code Copyright(c) 1998-2010 Matt Pharr and Greg Humphreys.

    This file is part of pbrt.

    pbrt is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.  Note that the text contents of
    the book "Physically Based Rendering" are *not* licensed under the
    GNU GPL.

    pbrt is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 */

// cameras/perspective.cpp*
#include "stdafx.h"
#include "cameras/perspective.h"
#include "paramset.h"
#include "sampler.h"
#include "montecarlo.h"

// PerspectiveCamera Method Definitions
PerspectiveCamera:: PerspectiveCamera(const AnimatedTransform &cam2world,
        const float screenWindow[4], float sopen, float sclose,
        float lensr, float focald, float fov, Film *f)
    : ProjectiveCamera(cam2world, Perspective(fov, 1e-2f, 1000.f),
                       screenWindow, sopen, sclose, lensr, focald, f) {
    // Compute differential changes in origin for perspective camera rays
    dxCamera = RasterToCamera(Point(1,0,0)) - RasterToCamera(Point(0,0,0));
    dyCamera = RasterToCamera(Point(0,1,0)) - RasterToCamera(Point(0,0,0));
}

float PerspectiveCamera::GenerateRay(const CameraSample &sample,
                                     Ray *ray) const {
    // Generate raster and camera samples
    Point Pras(sample.imageX, sample.imageY, 0);
    Point Pcamera;
    RasterToCamera(Pras, &Pcamera);
    *ray = Ray(Point(0,0,0), Vector(Pcamera), 0.f, INFINITY);
    // Modify ray for depth of field
    if (lensRadius > 0.) {
        // Sample point on lens
        float lensU, lensV;
        ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
        lensU *= lensRadius;
        lensV *= lensRadius;

        // Compute point on plane of focus
        float ft = focalDistance / ray->d.z;
        Point Pfocus = (*ray)(ft);

        // Update ray for effect of lens
        ray->o = Point(lensU, lensV, 0.f);
        ray->d = Normalize(Pfocus - ray->o);
    }
    ray->time = Lerp(sample.time, shutterOpen, shutterClose);
    CameraToWorld(*ray, ray);
    return 1.f;
}

float PerspectiveCamera::GenerateRayDifferential(const CameraSample &sample,
                                                 RayDifferential *ray) const {
    // Generate raster and camera samples
    Point Pras(sample.imageX, sample.imageY, 0);
    Point Pcamera;
    RasterToCamera(Pras, &Pcamera);
    Vector dir = Normalize(Vector(Pcamera.x, Pcamera.y, Pcamera.z));
    *ray = RayDifferential(Point(0,0,0), dir, 0.f, INFINITY);
    // Modify ray for depth of field
    if (lensRadius > 0.) {
        // Sample point on lens
        float lensU, lensV;
        ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
        lensU *= lensRadius;
        lensV *= lensRadius;

        // Compute point on plane of focus
        float ft = focalDistance / ray->d.z;
        Point Pfocus = (*ray)(ft);

        // Update ray for effect of lens
        ray->o = Point(lensU, lensV, 0.f);
        ray->d = Normalize(Pfocus - ray->o);
    }

    // Compute offset rays for _PerspectiveCamera_ ray differentials
    ray->rxOrigin = ray->ryOrigin = ray->o;
    ray->rxDirection = Normalize(Vector(Pcamera) + dxCamera);
    ray->ryDirection = Normalize(Vector(Pcamera) + dyCamera);
    ray->time = Lerp(sample.time, shutterOpen, shutterClose);
    CameraToWorld(*ray, ray);
    ray->hasDifferentials = true;
    return 1.f;
}

PerspectiveCamera *CreatePerspectiveCamera(const ParamSet &params,
        const AnimatedTransform &cam2world, Film *film) {
    // Extract common camera parameters from _ParamSet_
    float shutteropen = params.FindOneFloat("shutteropen", 0.f);
    float shutterclose = params.FindOneFloat("shutterclose", 1.f);
    if (shutterclose < shutteropen) {
        Warning("Shutter close time [%f] < shutter open [%f].  Swapping them.",
                shutterclose, shutteropen);
        swap(shutterclose, shutteropen);
    }
    float lensradius = params.FindOneFloat("lensradius", 0.f);
    float focaldistance = params.FindOneFloat("focaldistance", 1e30f);
    float frame = params.FindOneFloat("frameaspectratio",
        float(film->xResolution)/float(film->yResolution));
    float screen[4];
    if (frame > 1.f) {
        screen[0] = -frame;
        screen[1] =  frame;
        screen[2] = -1.f;
        screen[3] =  1.f;
    }
    else {
        screen[0] = -1.f;
        screen[1] =  1.f;
        screen[2] = -1.f / frame;
        screen[3] =  1.f / frame;
    }
    int swi;
    const float *sw = params.FindFloat("screenwindow", &swi);
    if (sw && swi == 4)
        memcpy(screen, sw, 4*sizeof(float));
    float fov = params.FindOneFloat("fov", 90.);
    float halffov = params.FindOneFloat("halffov", -1.f);
    if (halffov > 0.f)
        // hack for structure synth, which exports half of the full fov
        fov = 2.f * halffov;
    return new PerspectiveCamera(cam2world, screen, shutteropen,
        shutterclose, lensradius, focaldistance, fov, film);
}
<commit_msg>Add missing Normalize() call in PerspectiveCamera::GenerateRay().  (Ke Xu)<commit_after>
/*
    pbrt source code Copyright(c) 1998-2010 Matt Pharr and Greg Humphreys.

    This file is part of pbrt.

    pbrt is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.  Note that the text contents of
    the book "Physically Based Rendering" are *not* licensed under the
    GNU GPL.

    pbrt is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 */

// cameras/perspective.cpp*
#include "stdafx.h"
#include "cameras/perspective.h"
#include "paramset.h"
#include "sampler.h"
#include "montecarlo.h"

// PerspectiveCamera Method Definitions
PerspectiveCamera:: PerspectiveCamera(const AnimatedTransform &cam2world,
        const float screenWindow[4], float sopen, float sclose,
        float lensr, float focald, float fov, Film *f)
    : ProjectiveCamera(cam2world, Perspective(fov, 1e-2f, 1000.f),
                       screenWindow, sopen, sclose, lensr, focald, f) {
    // Compute differential changes in origin for perspective camera rays
    dxCamera = RasterToCamera(Point(1,0,0)) - RasterToCamera(Point(0,0,0));
    dyCamera = RasterToCamera(Point(0,1,0)) - RasterToCamera(Point(0,0,0));
}

float PerspectiveCamera::GenerateRay(const CameraSample &sample,
                                     Ray *ray) const {
    // Generate raster and camera samples
    Point Pras(sample.imageX, sample.imageY, 0);
    Point Pcamera;
    RasterToCamera(Pras, &Pcamera);
    *ray = Ray(Point(0,0,0), Normalize(Vector(Pcamera)), 0.f, INFINITY);
    // Modify ray for depth of field
    if (lensRadius > 0.) {
        // Sample point on lens
        float lensU, lensV;
        ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
        lensU *= lensRadius;
        lensV *= lensRadius;

        // Compute point on plane of focus
        float ft = focalDistance / ray->d.z;
        Point Pfocus = (*ray)(ft);

        // Update ray for effect of lens
        ray->o = Point(lensU, lensV, 0.f);
        ray->d = Normalize(Pfocus - ray->o);
    }
    ray->time = Lerp(sample.time, shutterOpen, shutterClose);
    CameraToWorld(*ray, ray);
    return 1.f;
}

float PerspectiveCamera::GenerateRayDifferential(const CameraSample &sample,
                                                 RayDifferential *ray) const {
    // Generate raster and camera samples
    Point Pras(sample.imageX, sample.imageY, 0);
    Point Pcamera;
    RasterToCamera(Pras, &Pcamera);
    Vector dir = Normalize(Vector(Pcamera.x, Pcamera.y, Pcamera.z));
    *ray = RayDifferential(Point(0,0,0), dir, 0.f, INFINITY);
    // Modify ray for depth of field
    if (lensRadius > 0.) {
        // Sample point on lens
        float lensU, lensV;
        ConcentricSampleDisk(sample.lensU, sample.lensV, &lensU, &lensV);
        lensU *= lensRadius;
        lensV *= lensRadius;

        // Compute point on plane of focus
        float ft = focalDistance / ray->d.z;
        Point Pfocus = (*ray)(ft);

        // Update ray for effect of lens
        ray->o = Point(lensU, lensV, 0.f);
        ray->d = Normalize(Pfocus - ray->o);
    }

    // Compute offset rays for _PerspectiveCamera_ ray differentials
    ray->rxOrigin = ray->ryOrigin = ray->o;
    ray->rxDirection = Normalize(Vector(Pcamera) + dxCamera);
    ray->ryDirection = Normalize(Vector(Pcamera) + dyCamera);
    ray->time = Lerp(sample.time, shutterOpen, shutterClose);
    CameraToWorld(*ray, ray);
    ray->hasDifferentials = true;
    return 1.f;
}

PerspectiveCamera *CreatePerspectiveCamera(const ParamSet &params,
        const AnimatedTransform &cam2world, Film *film) {
    // Extract common camera parameters from _ParamSet_
    float shutteropen = params.FindOneFloat("shutteropen", 0.f);
    float shutterclose = params.FindOneFloat("shutterclose", 1.f);
    if (shutterclose < shutteropen) {
        Warning("Shutter close time [%f] < shutter open [%f].  Swapping them.",
                shutterclose, shutteropen);
        swap(shutterclose, shutteropen);
    }
    float lensradius = params.FindOneFloat("lensradius", 0.f);
    float focaldistance = params.FindOneFloat("focaldistance", 1e30f);
    float frame = params.FindOneFloat("frameaspectratio",
        float(film->xResolution)/float(film->yResolution));
    float screen[4];
    if (frame > 1.f) {
        screen[0] = -frame;
        screen[1] =  frame;
        screen[2] = -1.f;
        screen[3] =  1.f;
    }
    else {
        screen[0] = -1.f;
        screen[1] =  1.f;
        screen[2] = -1.f / frame;
        screen[3] =  1.f / frame;
    }
    int swi;
    const float *sw = params.FindFloat("screenwindow", &swi);
    if (sw && swi == 4)
        memcpy(screen, sw, 4*sizeof(float));
    float fov = params.FindOneFloat("fov", 90.);
    float halffov = params.FindOneFloat("halffov", -1.f);
    if (halffov > 0.f)
        // hack for structure synth, which exports half of the full fov
        fov = 2.f * halffov;
    return new PerspectiveCamera(cam2world, screen, shutteropen,
        shutterclose, lensradius, focaldistance, fov, film);
}
<|endoftext|>


<commit_before> // Yigit Suoglu Jul 29, 2016
// includes code detects from given threshold values and enviorement RGB values

#include "RGB_Detection.h"

void detect_rgb(unsigned short r, unsigned short g, unsigned short b, colorBit th_Val[8], bool & r_on, bool & g_on, bool & b_on)
{
	if((r > th_Val[7].r_t) & (g > th_Val[7].g_t) & (b > th_Val[7].b_t)) // RGB HIGH
	{
		r_on = g_on = b_on = 1;
		return;
	}
	if((r < th_Val[6].r_t) & (g > th_Val[6].g_t) & (b > th_Val[6].b_t)) // GB HIGH
	{
		g_on = b_on = 1;
		r_on = 0;
		return;
	}
	if((r > th_Val[5].r_t) & (g < th_Val[5].g_t) & (b > th_Val[5].b_t)) // RB HIGH
	{
		r_on = b_on = 1;
		g_on = 0;
		return;
	}
	if((r > th_Val[4].r_t) & (g > th_Val[4].g_t) & (b < th_Val[4].b_t)) // RG HIGH
	{
		r_on = g_on = 1;
		b_on = 0;
		return;
	}
	if(b > th_Val[3].b_t) // B HIGH
	{
		b_on = 1;
		r_on = g_on = 0;
		return;
	}
	if(g > th_Val[2].g_t) // G HIGH
	{
		r_on = b_on = 0;
		g_on = 1;
		return;
	}
	if(r > th_Val[1].r_t) //R HIGH
	{
		r_on = 1;
		g_on = b_on = 0;
		return;
	}
	r_on = g_on = b_on = 0; //NULL
}
<commit_msg>Improved detection<commit_after> // Yigit Suoglu Jul 29, 2016
// includes code detects from given threshold values and enviorement RGB values

#include "RGB_Detection.h"

void detect_rgb(unsigned short r, unsigned short g, unsigned short b, colorBit th_Val[8], bool & r_on, bool & g_on, bool & b_on)
{
	if((r > th_Val[7].r_t) & (g > th_Val[7].g_t) & (b > th_Val[7].b_t)) // RGB HIGH
	{
		r_on = g_on = b_on = 1;
		return;
	}
	if((r < th_Val[6].r_t) & (g > th_Val[6].g_t) & (b > th_Val[6].b_t)) // GB HIGH
	{
		g_on = b_on = 1;
		r_on = 0;
		return;
	}
	if((r > th_Val[5].r_t) & (g < th_Val[5].g_t) & (b > th_Val[5].b_t)) // RB HIGH
	{
		r_on = b_on = 1;
		g_on = 0;
		return;
	}
	if((r > th_Val[4].r_t) & (g > th_Val[4].g_t) & (b < th_Val[4].b_t)) // RG HIGH
	{
		r_on = g_on = 1;
		b_on = 0;
		return;
	}
	if((r < th_Val[3].r_t) & (g < th_Val[3].g_t) & (b > th_Val[3].b_t)) // B HIGH
	{
		b_on = 1;
		r_on = g_on = 0;
		return;
	}
	if((r < th_Val[1].r_t) & (g > th_Val[2].g_t) & (b < th_Val[2].b_t)) // G HIGH
	{
		r_on = b_on = 0;
		g_on = 1;
		return;
	}
	if((r > th_Val[1].r_t) & (g < th_Val[1].g_t) & (b < th_Val[1].b_t)) //R HIGH
	{
		r_on = 1;
		g_on = b_on = 0;
		return;
	}
	r_on = g_on = b_on = 0; //NULL
}
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
// CalcDriver.cpp
//
// functions:  main(void)
//----------------------------------------------------------------------------
#include <iostream>
#include <cstdlib>
#include "RPNCalc.h"

using namespace std;
//----------------------------------------------------------------------------
//
//	Function:	main()
//
//	Title:		Driver for RPN Calculator
//
//	Description:	This file contains function main()
//				which creates and starts a calculator
//
//	Programmer:	Paul Bladek
//
//	Date:		5/20/14
//
//	Version:	1.0
//
//	Environment:    Intel Xeon PC
//                  	Software:   MS Windows 7 for execution;
//                  	Compiles under Microsoft Visual C++.Net 2010
//
//	Calls:		CRPNCalc constructor
//
//	Returns:	EXIT_SUCCESS  = successful
//
//	History Log:
//			4/205/14  PB  completed version 1.0
//----------------------------------------------------------------------------

int main2(void) {
// int main(void) {
	using P4_RPNCALC::CRPNCalc;
	CRPNCalc myCalc;

	return EXIT_SUCCESS;
}
<commit_msg>rename main to main2 for tests<commit_after>//----------------------------------------------------------------------------
// CalcDriver.cpp
//
// functions:  main(void)
//----------------------------------------------------------------------------
#include <iostream>
#include <cstdlib>
#include "RPNCalc.h"

using namespace std;
//----------------------------------------------------------------------------
//
//	Function:	main()
//
//	Title:		Driver for RPN Calculator
//
//	Description:	This file contains function main()
//				which creates and starts a calculator
//
//	Programmer:	Paul Bladek
//
//	Date:		5/20/14
//
//	Version:	1.0
//
//	Environment:    Intel Xeon PC
//                  	Software:   MS Windows 7 for execution;
//                  	Compiles under Microsoft Visual C++.Net 2010
//
//	Calls:		CRPNCalc constructor
//
//	Returns:	EXIT_SUCCESS  = successful
//
//	History Log:
//			4/205/14  PB  completed version 1.0
//----------------------------------------------------------------------------

int main2(void) {
//int main(void) {
	using P4_RPNCALC::CRPNCalc;
	CRPNCalc myCalc;

	return EXIT_SUCCESS;
}
<|endoftext|>