<commit_before>// Copyright 2014 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 "base/prefs/pref_service.h"
#include "chrome/browser/browsing_data/browsing_data_remover_test_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/webui/options/options_ui_browsertest.h"
#include "chrome/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"

namespace options {

class ClearBrowserDataBrowserTest : public OptionsUIBrowserTest {
 protected:
  void ClickElement(const std::string& selector) {
    bool element_enabled = false;
    ASSERT_NO_FATAL_FAILURE(GetElementEnabledState(selector, &element_enabled));
    ASSERT_TRUE(element_enabled);
    ASSERT_TRUE(content::ExecuteScript(
        GetSettingsFrame(),
        "document.querySelector('" + selector + "').click();"));
  }

  bool IsElementEnabled(const std::string& selector) {
    bool element_enabled = false;
    GetElementEnabledState(selector, &element_enabled);
    return element_enabled;
  }

  bool IsElementInFocus(const std::string& selector) {
    bool element_in_focus = false;
    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
        GetSettingsFrame(),
        "window.domAutomationController.send(document.querySelector('" +
            selector + "') == document.activeElement);",
        &element_in_focus));
    return element_in_focus;
  }

 private:
  void GetElementEnabledState(
      const std::string& selector,
      bool* enabled) {
    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
        GetSettingsFrame(),
        "window.domAutomationController.send(!document.querySelector('" +
            selector + "').disabled);",
        enabled));
  }
};

IN_PROC_BROWSER_TEST_F(ClearBrowserDataBrowserTest,
                       CommitButtonDisabledWhileDeletionInProgress) {
  const char kTimePeriodSelectorId[] = "#clear-browser-data-time-period";
  const char kCommitButtonId[] = "#clear-browser-data-commit";
  BrowsingDataRemoverCompletionInhibitor completion_inhibitor;

  // Navigate to the Clear Browsing Data dialog to ensure that the commit button
  // is initially enabled, usable, and gets disabled after having been pressed.
  // Furthermore, verify that the time period combo-box gets the initial focus.
  NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage);
  EXPECT_TRUE(IsElementInFocus(kTimePeriodSelectorId));
  ASSERT_NO_FATAL_FAILURE(ClickElement(kCommitButtonId));
  EXPECT_FALSE(IsElementEnabled(kCommitButtonId));

  completion_inhibitor.BlockUntilNearCompletion();

  // Simulate a reload while the previous removal is still running, and verify
  // that the button is still disabled.
  NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage);
  EXPECT_FALSE(IsElementEnabled(kCommitButtonId));

  completion_inhibitor.ContinueToCompletion();

  // However, the button should be enabled again once the process has finished.
  NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage);
  EXPECT_TRUE(IsElementEnabled(kCommitButtonId));
}

IN_PROC_BROWSER_TEST_F(ClearBrowserDataBrowserTest,
                       CommitButtonDisabledWhenNoDataTypesSelected) {
  const char kCommitButtonId[] = "#clear-browser-data-commit";
  const char* kDataTypes[] = {"browser.clear_data.browsing_history",
                              "browser.clear_data.download_history",
                              "browser.clear_data.cache",
                              "browser.clear_data.cookies",
                              "browser.clear_data.passwords",
                              "browser.clear_data.form_data",
                              "browser.clear_data.hosted_apps_data",
                              "browser.clear_data.content_licenses"};

  PrefService* prefs = browser()->profile()->GetPrefs();
  for (size_t i = 0; i < arraysize(kDataTypes); ++i) {
    prefs->SetBoolean(kDataTypes[i], false);
  }

  // Navigate to the Clear Browsing Data dialog to ensure that the commit button
  // is disabled if clearing is not requested for any of the data types.
  NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage);
  EXPECT_FALSE(IsElementEnabled(kCommitButtonId));

  // However, expect the commit button to be re-enabled if any of the data types
  // gets selected to be cleared.
  for (size_t i = 0; i < arraysize(kDataTypes); ++i) {
    prefs->SetBoolean(kDataTypes[i], true);
    EXPECT_TRUE(IsElementEnabled(kCommitButtonId));
    prefs->SetBoolean(kDataTypes[i], false);
  }
}

}  // namespace options
<commit_msg>DisabledClearBrowserDataBrowserTest.CommitButtonDisabledWhileDeletionInProgress.<commit_after>// Copyright 2014 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 "base/prefs/pref_service.h"
#include "chrome/browser/browsing_data/browsing_data_remover_test_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/webui/options/options_ui_browsertest.h"
#include "chrome/common/url_constants.h"
#include "content/public/test/browser_test_utils.h"

namespace options {

class ClearBrowserDataBrowserTest : public OptionsUIBrowserTest {
 protected:
  void ClickElement(const std::string& selector) {
    bool element_enabled = false;
    ASSERT_NO_FATAL_FAILURE(GetElementEnabledState(selector, &element_enabled));
    ASSERT_TRUE(element_enabled);
    ASSERT_TRUE(content::ExecuteScript(
        GetSettingsFrame(),
        "document.querySelector('" + selector + "').click();"));
  }

  bool IsElementEnabled(const std::string& selector) {
    bool element_enabled = false;
    GetElementEnabledState(selector, &element_enabled);
    return element_enabled;
  }

  bool IsElementInFocus(const std::string& selector) {
    bool element_in_focus = false;
    EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
        GetSettingsFrame(),
        "window.domAutomationController.send(document.querySelector('" +
            selector + "') == document.activeElement);",
        &element_in_focus));
    return element_in_focus;
  }

 private:
  void GetElementEnabledState(
      const std::string& selector,
      bool* enabled) {
    ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
        GetSettingsFrame(),
        "window.domAutomationController.send(!document.querySelector('" +
            selector + "').disabled);",
        enabled));
  }
};

// Fails flakily. http://crbug.com/379574
IN_PROC_BROWSER_TEST_F(ClearBrowserDataBrowserTest,
                       DISABLED_CommitButtonDisabledWhileDeletionInProgress) {
  const char kTimePeriodSelectorId[] = "#clear-browser-data-time-period";
  const char kCommitButtonId[] = "#clear-browser-data-commit";
  BrowsingDataRemoverCompletionInhibitor completion_inhibitor;

  // Navigate to the Clear Browsing Data dialog to ensure that the commit button
  // is initially enabled, usable, and gets disabled after having been pressed.
  // Furthermore, verify that the time period combo-box gets the initial focus.
  NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage);
  EXPECT_TRUE(IsElementInFocus(kTimePeriodSelectorId));
  ASSERT_NO_FATAL_FAILURE(ClickElement(kCommitButtonId));
  EXPECT_FALSE(IsElementEnabled(kCommitButtonId));

  completion_inhibitor.BlockUntilNearCompletion();

  // Simulate a reload while the previous removal is still running, and verify
  // that the button is still disabled.
  NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage);
  EXPECT_FALSE(IsElementEnabled(kCommitButtonId));

  completion_inhibitor.ContinueToCompletion();

  // However, the button should be enabled again once the process has finished.
  NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage);
  EXPECT_TRUE(IsElementEnabled(kCommitButtonId));
}

IN_PROC_BROWSER_TEST_F(ClearBrowserDataBrowserTest,
                       CommitButtonDisabledWhenNoDataTypesSelected) {
  const char kCommitButtonId[] = "#clear-browser-data-commit";
  const char* kDataTypes[] = {"browser.clear_data.browsing_history",
                              "browser.clear_data.download_history",
                              "browser.clear_data.cache",
                              "browser.clear_data.cookies",
                              "browser.clear_data.passwords",
                              "browser.clear_data.form_data",
                              "browser.clear_data.hosted_apps_data",
                              "browser.clear_data.content_licenses"};

  PrefService* prefs = browser()->profile()->GetPrefs();
  for (size_t i = 0; i < arraysize(kDataTypes); ++i) {
    prefs->SetBoolean(kDataTypes[i], false);
  }

  // Navigate to the Clear Browsing Data dialog to ensure that the commit button
  // is disabled if clearing is not requested for any of the data types.
  NavigateToSettingsSubpage(chrome::kClearBrowserDataSubPage);
  EXPECT_FALSE(IsElementEnabled(kCommitButtonId));

  // However, expect the commit button to be re-enabled if any of the data types
  // gets selected to be cleared.
  for (size_t i = 0; i < arraysize(kDataTypes); ++i) {
    prefs->SetBoolean(kDataTypes[i], true);
    EXPECT_TRUE(IsElementEnabled(kCommitButtonId));
    prefs->SetBoolean(kDataTypes[i], false);
  }
}

}  // namespace options
<|endoftext|>


<commit_before>#include <common/buffer.h>
#include <common/endian.h>

#include <xcodec/xcodec.h>
#include <xcodec/xcodec_cache.h>
#include <xcodec/xcodec_decoder.h>
#include <xcodec/xcodec_encoder.h>
#include <xcodec/xcodec_hash.h>

XCodecDecoder::XCodecDecoder(XCodecCache *cache)
: log_("/xcodec/decoder"),
  cache_(cache),
  window_()
{ }

XCodecDecoder::~XCodecDecoder()
{ }

/*
 * XXX These comments are out-of-date.
 *
 * Decode an XCodec-encoded stream.  Returns false if there was an
 * inconsistency, error or unrecoverable condition in the stream.
 * Returns true if we were able to process the stream entirely or
 * expect to be able to finish processing it once more data arrives.
 * The input buffer is cleared of anything we can parse right now.
 *
 * Since some events later in the stream (i.e. ASK or LEARN) may need
 * to be processed before some earlier in the stream (i.e. REF), we
 * parse the stream into a list of actions to take, performing them
 * as we go if possible, otherwise queueing them to occur until the
 * action that is blocking the stream has been satisfied or the stream
 * has been closed.
 *
 * XXX For now we will ASK in every stream where an unknown hash has
 * occurred and expect a LEARN in all of them.  In the future, it is
 * desirable to optimize this.  Especially once we start putting an
 * instance UUID in the HELLO message and can tell which streams
 * share an originator.
 */
bool
XCodecDecoder::decode(Buffer *output, Buffer *input, std::set<uint64_t>& unknown_hashes)
{
	while (!input->empty()) {
		unsigned off;
		if (!input->find(XCODEC_MAGIC, &off)) {
			output->append(input);
			input->clear();

			break;
		}

		if (off != 0) {
			output->append(input, off);
			input->skip(off);
		}
		ASSERT(!input->empty());

		/*
		 * Need the following byte at least.
		 */
		if (input->length() == 1)
			break;

		uint8_t op;
		input->extract(&op, sizeof XCODEC_MAGIC);

		switch (op) {
		case XCODEC_OP_ESCAPE:
			output->append(XCODEC_MAGIC);
			input->skip(sizeof XCODEC_MAGIC + sizeof op);
			break;
		case XCODEC_OP_EXTRACT:
			if (input->length() < sizeof XCODEC_MAGIC + sizeof op + XCODEC_SEGMENT_LENGTH)
				goto done;
			else {
				input->skip(sizeof XCODEC_MAGIC + sizeof op);

				BufferSegment *seg;
				input->copyout(&seg, XCODEC_SEGMENT_LENGTH);
				input->skip(XCODEC_SEGMENT_LENGTH);

				uint64_t hash = XCodecHash::hash(seg->data());
				BufferSegment *oseg = cache_->lookup(hash);
				if (oseg != NULL) {
					if (oseg->equal(seg)) {
						seg->unref();
						seg = oseg;
					} else {
						ERROR(log_) << "Collision in <EXTRACT>.";
						seg->unref();
						return (false);
					}
				} else {
					cache_->enter(hash, seg);
				}

				window_.declare(hash, seg);
				output->append(seg);
				seg->unref();
			}
			break;
		case XCODEC_OP_REF:
			if (input->length() < sizeof XCODEC_MAGIC + sizeof op + sizeof (uint64_t))
				goto done;
			else {
				uint64_t behash;
				input->extract(&behash, sizeof XCODEC_MAGIC + sizeof op);
				input->skip(sizeof XCODEC_MAGIC + sizeof op + sizeof behash);
				uint64_t hash = BigEndian::decode(behash);

				BufferSegment *oseg = cache_->lookup(hash);
				if (oseg == NULL) {
					if (unknown_hashes.find(hash) == unknown_hashes.end()) {
						DEBUG(log_) << "Sending <ASK>, waiting for <LEARN>.";
						unknown_hashes.insert(hash);
					} else {
						DEBUG(log_) << "Already sent <ASK>, waiting for <LEARN>.";
					}

					return (true);
				} else {
					window_.declare(hash, oseg);
					output->append(oseg);
					oseg->unref();
				}
			}
			break;
		case XCODEC_OP_BACKREF:
			if (input->length() < sizeof XCODEC_MAGIC + sizeof op + sizeof (uint8_t))
				goto done;
			else {
				uint8_t idx;
				input->moveout(&idx, sizeof XCODEC_MAGIC + sizeof op, sizeof idx);

				BufferSegment *oseg = window_.dereference(idx);
				if (oseg == NULL) {
					ERROR(log_) << "Index not present in <BACKREF> window: " << (unsigned)idx;
					return (false);
				}

				output->append(oseg);
				oseg->unref();
			}
			break;
		default:
			ERROR(log_) << "Unsupported XCodec opcode " << (unsigned)op << ".";
			return (false);
		}
	}
done:	return (true);
}
<commit_msg>Don't skip a reference if we're sending an ASK for it.  If we do that, we can decode a subsequent reference, but the backref window will be wrong.<commit_after>#include <common/buffer.h>
#include <common/endian.h>

#include <xcodec/xcodec.h>
#include <xcodec/xcodec_cache.h>
#include <xcodec/xcodec_decoder.h>
#include <xcodec/xcodec_encoder.h>
#include <xcodec/xcodec_hash.h>

XCodecDecoder::XCodecDecoder(XCodecCache *cache)
: log_("/xcodec/decoder"),
  cache_(cache),
  window_()
{ }

XCodecDecoder::~XCodecDecoder()
{ }

/*
 * XXX These comments are out-of-date.
 *
 * Decode an XCodec-encoded stream.  Returns false if there was an
 * inconsistency, error or unrecoverable condition in the stream.
 * Returns true if we were able to process the stream entirely or
 * expect to be able to finish processing it once more data arrives.
 * The input buffer is cleared of anything we can parse right now.
 *
 * Since some events later in the stream (i.e. ASK or LEARN) may need
 * to be processed before some earlier in the stream (i.e. REF), we
 * parse the stream into a list of actions to take, performing them
 * as we go if possible, otherwise queueing them to occur until the
 * action that is blocking the stream has been satisfied or the stream
 * has been closed.
 *
 * XXX For now we will ASK in every stream where an unknown hash has
 * occurred and expect a LEARN in all of them.  In the future, it is
 * desirable to optimize this.  Especially once we start putting an
 * instance UUID in the HELLO message and can tell which streams
 * share an originator.
 */
bool
XCodecDecoder::decode(Buffer *output, Buffer *input, std::set<uint64_t>& unknown_hashes)
{
	while (!input->empty()) {
		unsigned off;
		if (!input->find(XCODEC_MAGIC, &off)) {
			output->append(input);
			input->clear();

			break;
		}

		if (off != 0) {
			output->append(input, off);
			input->skip(off);
		}
		ASSERT(!input->empty());

		/*
		 * Need the following byte at least.
		 */
		if (input->length() == 1)
			break;

		uint8_t op;
		input->extract(&op, sizeof XCODEC_MAGIC);

		switch (op) {
		case XCODEC_OP_ESCAPE:
			output->append(XCODEC_MAGIC);
			input->skip(sizeof XCODEC_MAGIC + sizeof op);
			break;
		case XCODEC_OP_EXTRACT:
			if (input->length() < sizeof XCODEC_MAGIC + sizeof op + XCODEC_SEGMENT_LENGTH)
				goto done;
			else {
				input->skip(sizeof XCODEC_MAGIC + sizeof op);

				BufferSegment *seg;
				input->copyout(&seg, XCODEC_SEGMENT_LENGTH);
				input->skip(XCODEC_SEGMENT_LENGTH);

				uint64_t hash = XCodecHash::hash(seg->data());
				BufferSegment *oseg = cache_->lookup(hash);
				if (oseg != NULL) {
					if (oseg->equal(seg)) {
						seg->unref();
						seg = oseg;
					} else {
						ERROR(log_) << "Collision in <EXTRACT>.";
						seg->unref();
						return (false);
					}
				} else {
					cache_->enter(hash, seg);
				}

				window_.declare(hash, seg);
				output->append(seg);
				seg->unref();
			}
			break;
		case XCODEC_OP_REF:
			if (input->length() < sizeof XCODEC_MAGIC + sizeof op + sizeof (uint64_t))
				goto done;
			else {
				uint64_t behash;
				input->extract(&behash, sizeof XCODEC_MAGIC + sizeof op);
				uint64_t hash = BigEndian::decode(behash);

				BufferSegment *oseg = cache_->lookup(hash);
				if (oseg == NULL) {
					if (unknown_hashes.find(hash) == unknown_hashes.end()) {
						DEBUG(log_) << "Sending <ASK>, waiting for <LEARN>.";
						unknown_hashes.insert(hash);
					} else {
						DEBUG(log_) << "Already sent <ASK>, waiting for <LEARN>.";
					}

					return (true);
				}

				input->skip(sizeof XCODEC_MAGIC + sizeof op + sizeof behash);

				window_.declare(hash, oseg);
				output->append(oseg);
				oseg->unref();
			}
			break;
		case XCODEC_OP_BACKREF:
			if (input->length() < sizeof XCODEC_MAGIC + sizeof op + sizeof (uint8_t))
				goto done;
			else {
				uint8_t idx;
				input->moveout(&idx, sizeof XCODEC_MAGIC + sizeof op, sizeof idx);

				BufferSegment *oseg = window_.dereference(idx);
				if (oseg == NULL) {
					ERROR(log_) << "Index not present in <BACKREF> window: " << (unsigned)idx;
					return (false);
				}

				output->append(oseg);
				oseg->unref();
			}
			break;
		default:
			ERROR(log_) << "Unsupported XCodec opcode " << (unsigned)op << ".";
			return (false);
		}
	}
done:	return (true);
}
<|endoftext|>


<commit_before>/**
 *
 *  @file State.cpp
 * Definitions for the class State, that manages the independent variables of temperature, mass density,
 * and species mass/mole fraction that define the thermodynamic state (see \ref phases and
 * class \link Cantera::State State\endlink).
 *
 */

/*
 *  $Author$
 *  $Date$
 *  $Revision$
 *
 *  Copyright 2003-2004 California Institute of Technology
 *  See file License.txt for licensing information
 *
 */

#include "utilities.h"
#include "ctexceptions.h"
#include "stringUtils.h"
#include "State.h"

//#ifdef DARWIN
//#include <Accelerate.h>
//#endif

using namespace std;

namespace Cantera {

  State::State() : m_kk(0), m_temp(0.0), m_dens(0.001), m_mmw(0.0) {}

  State::~State() {}

  State::State(const State& right) :
    m_kk(0),
    m_temp(0.0),
    m_dens(0.001),
    m_mmw(0.0) {
    /*
     * Call the assignment operator.
     */
    *this = operator=(right);
  }

  /*
   * Assignment operator for the State Class
   */
  State& State::operator=(const State& right) {
    /*
     * Check for self assignment.
     */
    if (this == &right) return *this;
    /*
     * We do a straight assignment operator on all of the
     * data. The vectors are copied.
     */
    m_kk             = right.m_kk;
    m_temp           = right.m_temp;
    m_dens           = right.m_dens;
    m_mmw            = right.m_mmw;
    m_ym             = right.m_ym;
    m_y              = right.m_y;
    m_molwts         = right.m_molwts;
    m_rmolwts        = right.m_rmolwts;
    /*
     * Return the reference to the current object
     */
    return *this;
  }

    doublereal State::moleFraction(int k) const {
        if (k >= 0 && k < m_kk) {
            return m_ym[k] * m_mmw;
        }
        else {
            throw CanteraError("State:moleFraction",
                "illegal species index number");
        }
    }

    void State::setMoleFractions(const doublereal* x) {
        doublereal sum = 0.0, norm = 0.0;
        sum = dot(x, x + m_kk, m_molwts.begin());
        doublereal rsum = 1.0/sum;
        transform(x, x + m_kk, m_ym.begin(), timesConstant<double>(rsum));
        transform(m_ym.begin(), m_ym.begin() + m_kk, m_molwts.begin(),
            m_y.begin(), multiplies<double>());
        norm = accumulate(x, x + m_kk, 0.0);
        //for (k = 0; k != m_kk; ++k) {
        //    m_ym[k] = x[k] / sum;
        //    m_y[k]  = m_molwts[k]*m_ym[k];
        //    norm += x[k];
        //}
        m_mmw = sum/norm;
    }

    void State::setMoleFractions_NoNorm(const doublereal* x) {
        m_mmw = dot(x, x + m_kk, m_molwts.begin());
        doublereal rmmw = 1.0/m_mmw;
        transform(x, x + m_kk, m_ym.begin(), timesConstant<double>(rmmw));
        transform(m_y.begin(), m_y.begin() + m_kk, m_molwts.begin(),
            m_y.begin(), multiplies<double>());
    }

    doublereal State::massFraction(int k) const {
        if (k >= 0 && k < m_kk) {
            return m_y[k];
        }
        else {
            throw CanteraError("State:massFraction",
                "illegal species index number");
        }
    }

    doublereal State::concentration(int k) const {
        if (k >= 0 && k < m_kk) {
            return m_y[k] * m_dens * m_rmolwts[k] ;
        }
        else {
            throw CanteraError("State:massFraction",
                "illegal species index number");
        }
    }

    void State::setMassFractions(const doublereal* y) {
        doublereal norm = 0.0, sum = 0.0;
        //cblas_dcopy(m_kk, y, 1, m_y.begin(), 1);
        norm = accumulate(y, y + m_kk, 0.0);
        copy(y, y + m_kk, m_y.begin());
        scale(y, y + m_kk, m_y.begin(), 1.0/norm);
        //        for (k = 0; k != m_kk; ++k) {
        //    norm += y[k];
        //    m_y[k] = y[k];
        //}

        //scale(m_kk, 1.0/norm, m_y.begin());
        transform(m_y.begin(), m_y.begin() + m_kk, m_rmolwts.begin(),
            m_ym.begin(), multiplies<double>());
        sum = accumulate(m_ym.begin(), m_ym.begin() + m_kk, 0.0);
        //        for (k = 0; k != m_kk; ++k) {
        //    m_ym[k] = m_y[k] * m_rmolwts[k];
        //    sum += m_ym[k];
        //}
        m_mmw = 1.0/sum;
    }

    void State::setMassFractions_NoNorm(const doublereal* y) {
        doublereal sum = 0.0;
        copy(y, y + m_kk, m_y.begin());
        transform(m_y.begin(), m_y.end(), m_rmolwts.begin(), m_ym.begin(),
            multiplies<double>());
        sum = accumulate(m_ym.begin(), m_ym.end(), 0.0);
        //for (k = 0; k != m_kk; ++k) {
        //    m_y[k] = y[k];
        //    m_ym[k] = m_y[k] * m_rmolwts[k];
        //    sum += m_ym[k];
        //}
        m_mmw = 1.0/sum;
    }

    doublereal State::sum_xlogx() const {
        return m_mmw* Cantera::sum_xlogx(m_ym.begin(), m_ym.end()) + log(m_mmw);
    }

    doublereal State::sum_xlogQ(doublereal* Q) const {
        return m_mmw * Cantera::sum_xlogQ(m_ym.begin(), m_ym.end(), Q);
    }

    void State::setConcentrations(const doublereal* c) {
        int k;
        doublereal sum = 0.0, norm = 0.0;
        for (k = 0; k != m_kk; ++k) {
            sum += c[k]*m_molwts[k];
            norm += c[k];
        }
        m_mmw = sum/norm;
        setDensity(sum);
        doublereal rsum = 1.0/sum;
        for (k = 0; k != m_kk; ++k) {
            m_ym[k] = c[k] * rsum;
            m_y[k] =  m_ym[k] * m_molwts[k];
        }
    }

    void State::getConcentrations(doublereal* c) const {
        scale(m_ym.begin(), m_ym.end(), c, m_dens);
    }

    doublereal State::mean_Y(const doublereal* Q) const {
        return dot(m_y.begin(), m_y.end(), Q);
    }

    void State::getMoleFractions(doublereal* x) const {
        scale(m_ym.begin(), m_ym.end(), x, m_mmw);
    }

    void State::getMassFractions(doublereal* y) const {
        copy(m_y.begin(), m_y.end(), y);
    }

    void State::init(const array_fp& mw) {
        m_kk = mw.size();
        m_molwts.resize(m_kk);
        m_rmolwts.resize(m_kk);
        m_y.resize(m_kk, 0.0);
        m_ym.resize(m_kk, 0.0);
        copy(mw.begin(), mw.end(), m_molwts.begin());
        for (int k = 0; k < m_kk; k++) {
            if (m_molwts[k] < 0.0) {
                throw CanteraError("State::init",
                    "negative molecular weight for species number "+int2str(k));
                }
            /*
             * Some surface phases may define species representing
             * empty sites that have zero molecular weight. Give them
             * a very small molecular weight to avoid dividing by
             * zero.
             */
            if (m_molwts[k] < Tiny) m_molwts[k] = Tiny;
            m_rmolwts[k] = 1.0/m_molwts[k];
        }

        /*
         * Now that we have resized the State object, let's fill it with
         * a valid mass fraction vector that sums to one. The State object
         * should never have a mass fraction vector that doesn't sum to one.
         * We will assume that species 0 has a mass fraction of 1.0 and
         * mass fraction of all other species is 0.0.
         */
        m_y[0] = 1.0;
        m_ym[0] = m_y[0] * m_rmolwts[0];
        m_mmw = 1.0 / m_ym[0];
    }

}
<commit_msg>Fixed an error in the function setMoleFractions_NoNorm(). The error was introduced in v. 1.2 of this file on 5/4/07, and lead to bad values for output mass fractions.<commit_after>/**
 *  @file State.cpp
 * Definitions for the class State, that manages the independent variables of temperature, mass density,
 * and species mass/mole fraction that define the thermodynamic state (see \ref phases and
 * class \link Cantera::State State\endlink).
 */

/*
 *  $Author$
 *  $Date$
 *  $Revision$
 *
 *  Copyright 2003-2004 California Institute of Technology
 *  See file License.txt for licensing information
 *
 */

#include "utilities.h"
#include "ctexceptions.h"
#include "stringUtils.h"
#include "State.h"

//#ifdef DARWIN
//#include <Accelerate.h>
//#endif

using namespace std;

namespace Cantera {

  State::State() : m_kk(0), m_temp(0.0), m_dens(0.001), m_mmw(0.0) {}

  State::~State() {}

  State::State(const State& right) :
    m_kk(0),
    m_temp(0.0),
    m_dens(0.001),
    m_mmw(0.0) {
    /*
     * Call the assignment operator.
     */
    *this = operator=(right);
  }

  /*
   * Assignment operator for the State Class
   */
  State& State::operator=(const State& right) {
    /*
     * Check for self assignment.
     */
    if (this == &right) return *this;
    /*
     * We do a straight assignment operator on all of the
     * data. The vectors are copied.
     */
    m_kk             = right.m_kk;
    m_temp           = right.m_temp;
    m_dens           = right.m_dens;
    m_mmw            = right.m_mmw;
    m_ym             = right.m_ym;
    m_y              = right.m_y;
    m_molwts         = right.m_molwts;
    m_rmolwts        = right.m_rmolwts;
    /*
     * Return the reference to the current object
     */
    return *this;
  }

    doublereal State::moleFraction(int k) const {
        if (k >= 0 && k < m_kk) {
            return m_ym[k] * m_mmw;
        }
        else {
            throw CanteraError("State:moleFraction",
                "illegal species index number");
        }
    }

    void State::setMoleFractions(const doublereal* x) {
        doublereal sum = 0.0, norm = 0.0;
        sum = dot(x, x + m_kk, m_molwts.begin());
        doublereal rsum = 1.0/sum;
        transform(x, x + m_kk, m_ym.begin(), timesConstant<double>(rsum));
        transform(m_ym.begin(), m_ym.begin() + m_kk, m_molwts.begin(),
            m_y.begin(), multiplies<double>());
        norm = accumulate(x, x + m_kk, 0.0);
        //for (k = 0; k != m_kk; ++k) {
        //    m_ym[k] = x[k] / sum;
        //    m_y[k]  = m_molwts[k]*m_ym[k];
        //    norm += x[k];
        //}
        m_mmw = sum/norm;
    }

    void State::setMoleFractions_NoNorm(const doublereal* x) {
        m_mmw = dot(x, x + m_kk, m_molwts.begin());
        doublereal rmmw = 1.0/m_mmw;
        transform(x, x + m_kk, m_ym.begin(), timesConstant<double>(rmmw));
        transform(m_ym.begin(), m_ym.begin() + m_kk, m_molwts.begin(),
            m_y.begin(), multiplies<double>());
    }

    doublereal State::massFraction(int k) const {
        if (k >= 0 && k < m_kk) {
            return m_y[k];
        }
        else {
            throw CanteraError("State:massFraction",
                "illegal species index number");
        }
    }

    doublereal State::concentration(int k) const {
        if (k >= 0 && k < m_kk) {
            return m_y[k] * m_dens * m_rmolwts[k] ;
        }
        else {
            throw CanteraError("State:massFraction",
                "illegal species index number");
        }
    }

    void State::setMassFractions(const doublereal* y) {
        doublereal norm = 0.0, sum = 0.0;
        //cblas_dcopy(m_kk, y, 1, m_y.begin(), 1);
        norm = accumulate(y, y + m_kk, 0.0);
        copy(y, y + m_kk, m_y.begin());
        scale(y, y + m_kk, m_y.begin(), 1.0/norm);
        //        for (k = 0; k != m_kk; ++k) {
        //    norm += y[k];
        //    m_y[k] = y[k];
        //}

        //scale(m_kk, 1.0/norm, m_y.begin());
        transform(m_y.begin(), m_y.begin() + m_kk, m_rmolwts.begin(),
            m_ym.begin(), multiplies<double>());
        sum = accumulate(m_ym.begin(), m_ym.begin() + m_kk, 0.0);
        //        for (k = 0; k != m_kk; ++k) {
        //    m_ym[k] = m_y[k] * m_rmolwts[k];
        //    sum += m_ym[k];
        //}
        m_mmw = 1.0/sum;
    }

    void State::setMassFractions_NoNorm(const doublereal* y) {
        doublereal sum = 0.0;
        copy(y, y + m_kk, m_y.begin());
        transform(m_y.begin(), m_y.end(), m_rmolwts.begin(), m_ym.begin(),
            multiplies<double>());
        sum = accumulate(m_ym.begin(), m_ym.end(), 0.0);
        //for (k = 0; k != m_kk; ++k) {
        //    m_y[k] = y[k];
        //    m_ym[k] = m_y[k] * m_rmolwts[k];
        //    sum += m_ym[k];
        //}
        m_mmw = 1.0/sum;
    }

    doublereal State::sum_xlogx() const {
        return m_mmw* Cantera::sum_xlogx(m_ym.begin(), m_ym.end()) + log(m_mmw);
    }

    doublereal State::sum_xlogQ(doublereal* Q) const {
        return m_mmw * Cantera::sum_xlogQ(m_ym.begin(), m_ym.end(), Q);
    }

    void State::setConcentrations(const doublereal* c) {
        int k;
        doublereal sum = 0.0, norm = 0.0;
        for (k = 0; k != m_kk; ++k) {
            sum += c[k]*m_molwts[k];
            norm += c[k];
        }
        m_mmw = sum/norm;
        setDensity(sum);
        doublereal rsum = 1.0/sum;
        for (k = 0; k != m_kk; ++k) {
            m_ym[k] = c[k] * rsum;
            m_y[k] =  m_ym[k] * m_molwts[k];
        }
    }

    void State::getConcentrations(doublereal* c) const {
        scale(m_ym.begin(), m_ym.end(), c, m_dens);
    }

    doublereal State::mean_Y(const doublereal* Q) const {
        return dot(m_y.begin(), m_y.end(), Q);
    }

    void State::getMoleFractions(doublereal* x) const {
        scale(m_ym.begin(), m_ym.end(), x, m_mmw);
    }

    void State::getMassFractions(doublereal* y) const {
        copy(m_y.begin(), m_y.end(), y);
    }

    void State::init(const array_fp& mw) {
        m_kk = mw.size();
        m_molwts.resize(m_kk);
        m_rmolwts.resize(m_kk);
        m_y.resize(m_kk, 0.0);
        m_ym.resize(m_kk, 0.0);
        copy(mw.begin(), mw.end(), m_molwts.begin());
        for (int k = 0; k < m_kk; k++) {
            if (m_molwts[k] < 0.0) {
                throw CanteraError("State::init",
                    "negative molecular weight for species number "+int2str(k));
                }
            /*
             * Some surface phases may define species representing
             * empty sites that have zero molecular weight. Give them
             * a very small molecular weight to avoid dividing by
             * zero.
             */
            if (m_molwts[k] < Tiny) m_molwts[k] = Tiny;
            m_rmolwts[k] = 1.0/m_molwts[k];
        }

        /*
         * Now that we have resized the State object, let's fill it with
         * a valid mass fraction vector that sums to one. The State object
         * should never have a mass fraction vector that doesn't sum to one.
         * We will assume that species 0 has a mass fraction of 1.0 and
         * mass fraction of all other species is 0.0.
         */
        m_y[0] = 1.0;
        m_ym[0] = m_y[0] * m_rmolwts[0];
        m_mmw = 1.0 / m_ym[0];
    }

}
<|endoftext|>


<commit_before>// Original Work Copyright (c) 2010 Amit J Patel, Modified Work Copyright (c) 2016 Jay M Stevens

#include "PolygonalMapGeneratorPrivatePCH.h"
#include "DrawDebugHelpers.h"
#include "Maps/MapDataHelper.h"
#include "PolygonalMapHeightmap.h"

FMapData UPolygonalMapHeightmap::MakeMapPoint(FVector2D PixelPosition, TArray<FMapData> MapData, UBiomeManager* BiomeManager)
{
	TArray<FMapData> closestPoints;
	// Iterate over the entire mapData array to find how many points we need to average
		for (int i = 0; i < MapData.Num(); i++)
		{
			if (closestPoints.Num() == 0)
			{
				closestPoints.Add(MapData[i]);
				continue;
			}
			float distance = FVector2D::DistSquared(PixelPosition, MapData[i].Point);

			// This will hold the index of first point we find that's further away than our point
			int addPointIndex = -1;
			for (int j = 0; j < closestPoints.Num(); j++)
			{
				// Get the distance of this point
				float pointDist = FVector2D::DistSquared(PixelPosition, closestPoints[j].Point);
				if (distance < pointDist)
				{
					addPointIndex = j;
					break;
				}
			}

			// If we found a point that's further away than our point, place it in the array and move everything else down
			if (addPointIndex >= 0)
			{
				FMapData last = MapData[i];
				for (int j = addPointIndex; j < closestPoints.Num(); j++)
				{
					FMapData temp = closestPoints[j];
					closestPoints[j] = last;
					last = temp;
				}
				// If we are below the number of points we need to add, then add the furthest point to the end
				if (closestPoints.Num() < NumberOfPointsToAverage)
				{
					closestPoints.Add(last);
				}
			}
			else if (closestPoints.Num() < NumberOfPointsToAverage)
			{
				closestPoints.Add(MapData[i]);
			}
		}

	// Cache the distances
	TArray<float> closestPointDistances;
	float totalDistance = 0.0f;
	for (int i = 0; i < closestPoints.Num(); i++)
	{
		float distance = FVector2D::DistSquared(PixelPosition, closestPoints[i].Point);
		totalDistance += distance;
		closestPointDistances.Add(distance);
	}

	float inversePercentageTotal = 0.0f;

	for (int i = 0; i < closestPoints.Num(); i++)
	{
		// Get the total percentage that this point contributed to the overall distance
		float percentageOfDistance = closestPointDistances[i] / totalDistance;

		// Take the inverse of the distance percentage -- points which are closer get a larger weight
		float inversePercentage = 1.0f - percentageOfDistance;

		// We re-add the inverse percentage to the array so we can make sure it all totals up to 1
		closestPointDistances[i] = inversePercentage;
		inversePercentageTotal += inversePercentage;
	}

	// Now gather the weighted distance for each point
	TArray<TPair<FMapData, float>> pointWeights;
	for (int i = 0; i < closestPoints.Num(); i++)
	{
		TPair<FMapData, float> weight;
		weight.Key = closestPoints[i];
		weight.Value = closestPointDistances[i] / inversePercentageTotal;
		pointWeights.Add(weight);
	}

	/*float isBorder = 0.0f;
	float isWater = 0.0f;
	float isOcean = 0.0f;
	float isCoast = 0.0f;
	float isRiver = 0.0f;*/

	float elevation = 0.0f;
	float moisture = 0.0f;

	TMap<FName, float> tagWeights;

	for (int i = 0; i < pointWeights.Num(); i++)
	{
		FMapData curPoint = pointWeights[i].Key;
		float weight = pointWeights[i].Value;

		/*if (UMapDataHelper::IsBorder(curPoint))
		{
			isBorder += weight;
		}
		if (curPoint.bIsCoast)
		{
			isCoast += weight;
		}
		if (curPoint.bIsOcean)
		{
			isOcean += weight;
		}
		if (curPoint.bIsRiver)
		{
			isRiver += weight;
		}
		if (curPoint.bIsWater)
		{
			isWater += weight;
		}*/

		elevation += (curPoint.Elevation * weight);
		moisture += (curPoint.Moisture * weight);

		for (int j = 0; j < curPoint.Tags.Num(); j++)
		{
			FName tag = curPoint.Tags[j];
			float currentTagWeight = tagWeights.FindOrAdd(tag);
			currentTagWeight += weight;
			tagWeights[tag] = currentTagWeight;
		}
	}

	FMapData pixelData;

	pixelData.Point = PixelPosition;
	/*pixelData.bIsBorder = isBorder >= 0.5f;
	pixelData.bIsCoast = isCoast >= 0.5f;
	pixelData.bIsOcean = isOcean >= 0.5f;
	pixelData.bIsRiver = isRiver >= 0.5f;
	pixelData.bIsWater = isWater >= 0.5f;*/

	for (auto& elem : tagWeights)
	{
		if (elem.Value >= 0.1f)
		{
			pixelData.Tags.Add(elem.Key);
		}
	}

	pixelData.Elevation = elevation;
	pixelData.Moisture = moisture;
	pixelData.Biome = BiomeManager->DetermineBiome(pixelData);
	return pixelData;
}

void UPolygonalMapHeightmap::CreateHeightmap(UPolygonMap* PolygonMap, UBiomeManager* BiomeManager, int32 Size)
{
	if (PolygonMap == NULL)
	{
		return;
	}
	HeightmapSize = Size;
	TArray<FMapData> graph = PolygonMap->GetAllMapData();
	for (int x = 0; x < HeightmapSize; x++)
	{
		for (int y = 0; y < HeightmapSize; y++)
		{
			FVector2D point = FVector2D(x, y);
			HeightmapData.Add(MakeMapPoint(point,graph, BiomeManager));
		}
	}
}

TArray<FMapData> UPolygonalMapHeightmap::GetMapData()
{
	return HeightmapData;
}

FMapData UPolygonalMapHeightmap::GetMapPoint(int32 x, int32 y)
{
	int32 index = x + (y * HeightmapSize);
	if (index < 0 || HeightmapData.Num() <= index)
	{
		UE_LOG(LogWorldGen, Warning, TEXT("Tried to fetch a pixel at %d, %d, but no pixel was found."), x, y);
		return FMapData();
	}
	else
	{
		return HeightmapData[index];
	}
}

void UPolygonalMapHeightmap::DrawDebugPixelGrid(UWorld* world, float PixelSize)
{
	if (world == NULL)
	{
		UE_LOG(LogWorldGen, Error, TEXT("World was null!"));
		return;
	}

	float elevationScale = 3100.0f;
	FVector offset = FVector(0.0f, 0.0f, 0.0f);

	for (int32 x = 0; x < HeightmapSize; x++)
	{
		for (int32 y = 0; y < HeightmapSize; y++)
		{
			FMapData mapData = GetMapPoint(x,y);

			FColor color = FColor(255, 255, 255);
			if (UMapDataHelper::IsOcean(mapData))
			{
				color = FColor(0, 0, 255);
			}
			else if (UMapDataHelper::IsCoast(mapData))
			{
				color = FColor(255, 255, 0);
			}
			else if (UMapDataHelper::IsWater(mapData))
			{
				color = FColor(0, 255, 255);
			}

			FVector v0 = offset + FVector(mapData.Point.X * PixelSize, mapData.Point.Y * PixelSize, mapData.Elevation * elevationScale);
			FVector v1 = FVector(v0.X, v0.Y + PixelSize, v0.Z);
			FVector v2 = FVector(v0.X + PixelSize, v0.Y, v0.Z);
			FVector v3 = FVector(v2.X, v1.Y, v0.Z);
			DrawDebugSphere(world, v0, 100, 4, color, true);
			DrawDebugLine(world, v0, v1, color, true);
			DrawDebugLine(world, v0, v2, color, true);
		}
	}
}<commit_msg>Adjusted heightmap tag weight value to something more reasonable.<commit_after>// Original Work Copyright (c) 2010 Amit J Patel, Modified Work Copyright (c) 2016 Jay M Stevens

#include "PolygonalMapGeneratorPrivatePCH.h"
#include "DrawDebugHelpers.h"
#include "Maps/MapDataHelper.h"
#include "PolygonalMapHeightmap.h"

FMapData UPolygonalMapHeightmap::MakeMapPoint(FVector2D PixelPosition, TArray<FMapData> MapData, UBiomeManager* BiomeManager)
{
	TArray<FMapData> closestPoints;
	// Iterate over the entire mapData array to find how many points we need to average
		for (int i = 0; i < MapData.Num(); i++)
		{
			if (closestPoints.Num() == 0)
			{
				closestPoints.Add(MapData[i]);
				continue;
			}
			float distance = FVector2D::DistSquared(PixelPosition, MapData[i].Point);

			// This will hold the index of first point we find that's further away than our point
			int addPointIndex = -1;
			for (int j = 0; j < closestPoints.Num(); j++)
			{
				// Get the distance of this point
				float pointDist = FVector2D::DistSquared(PixelPosition, closestPoints[j].Point);
				if (distance < pointDist)
				{
					addPointIndex = j;
					break;
				}
			}

			// If we found a point that's further away than our point, place it in the array and move everything else down
			if (addPointIndex >= 0)
			{
				FMapData last = MapData[i];
				for (int j = addPointIndex; j < closestPoints.Num(); j++)
				{
					FMapData temp = closestPoints[j];
					closestPoints[j] = last;
					last = temp;
				}
				// If we are below the number of points we need to add, then add the furthest point to the end
				if (closestPoints.Num() < NumberOfPointsToAverage)
				{
					closestPoints.Add(last);
				}
			}
			else if (closestPoints.Num() < NumberOfPointsToAverage)
			{
				closestPoints.Add(MapData[i]);
			}
		}

	// Cache the distances
	TArray<float> closestPointDistances;
	float totalDistance = 0.0f;
	for (int i = 0; i < closestPoints.Num(); i++)
	{
		float distance = FVector2D::DistSquared(PixelPosition, closestPoints[i].Point);
		totalDistance += distance;
		closestPointDistances.Add(distance);
	}

	float inversePercentageTotal = 0.0f;

	for (int i = 0; i < closestPoints.Num(); i++)
	{
		// Get the total percentage that this point contributed to the overall distance
		float percentageOfDistance = closestPointDistances[i] / totalDistance;

		// Take the inverse of the distance percentage -- points which are closer get a larger weight
		float inversePercentage = 1.0f - percentageOfDistance;

		// We re-add the inverse percentage to the array so we can make sure it all totals up to 1
		closestPointDistances[i] = inversePercentage;
		inversePercentageTotal += inversePercentage;
	}

	// Now gather the weighted distance for each point
	TArray<TPair<FMapData, float>> pointWeights;
	for (int i = 0; i < closestPoints.Num(); i++)
	{
		TPair<FMapData, float> weight;
		weight.Key = closestPoints[i];
		weight.Value = closestPointDistances[i] / inversePercentageTotal;
		pointWeights.Add(weight);
	}

	/*float isBorder = 0.0f;
	float isWater = 0.0f;
	float isOcean = 0.0f;
	float isCoast = 0.0f;
	float isRiver = 0.0f;*/

	float elevation = 0.0f;
	float moisture = 0.0f;

	TMap<FName, float> tagWeights;

	for (int i = 0; i < pointWeights.Num(); i++)
	{
		FMapData curPoint = pointWeights[i].Key;
		float weight = pointWeights[i].Value;

		/*if (UMapDataHelper::IsBorder(curPoint))
		{
			isBorder += weight;
		}
		if (curPoint.bIsCoast)
		{
			isCoast += weight;
		}
		if (curPoint.bIsOcean)
		{
			isOcean += weight;
		}
		if (curPoint.bIsRiver)
		{
			isRiver += weight;
		}
		if (curPoint.bIsWater)
		{
			isWater += weight;
		}*/

		elevation += (curPoint.Elevation * weight);
		moisture += (curPoint.Moisture * weight);

		for (int j = 0; j < curPoint.Tags.Num(); j++)
		{
			FName tag = curPoint.Tags[j];
			float currentTagWeight = tagWeights.FindOrAdd(tag);
			currentTagWeight += weight;
			tagWeights[tag] = currentTagWeight;
		}
	}

	FMapData pixelData;

	pixelData.Point = PixelPosition;
	/*pixelData.bIsBorder = isBorder >= 0.5f;
	pixelData.bIsCoast = isCoast >= 0.5f;
	pixelData.bIsOcean = isOcean >= 0.5f;
	pixelData.bIsRiver = isRiver >= 0.5f;
	pixelData.bIsWater = isWater >= 0.5f;*/

	for (auto& elem : tagWeights)
	{
		if (elem.Value >= 0.5f)
		{
			pixelData.Tags.Add(elem.Key);
		}
	}

	pixelData.Elevation = elevation;
	pixelData.Moisture = moisture;
	pixelData.Biome = BiomeManager->DetermineBiome(pixelData);
	return pixelData;
}

void UPolygonalMapHeightmap::CreateHeightmap(UPolygonMap* PolygonMap, UBiomeManager* BiomeManager, int32 Size)
{
	if (PolygonMap == NULL)
	{
		return;
	}
	HeightmapSize = Size;
	TArray<FMapData> graph = PolygonMap->GetAllMapData();
	for (int x = 0; x < HeightmapSize; x++)
	{
		for (int y = 0; y < HeightmapSize; y++)
		{
			FVector2D point = FVector2D(x, y);
			HeightmapData.Add(MakeMapPoint(point,graph, BiomeManager));
		}
	}
}

TArray<FMapData> UPolygonalMapHeightmap::GetMapData()
{
	return HeightmapData;
}

FMapData UPolygonalMapHeightmap::GetMapPoint(int32 x, int32 y)
{
	int32 index = x + (y * HeightmapSize);
	if (index < 0 || HeightmapData.Num() <= index)
	{
		UE_LOG(LogWorldGen, Warning, TEXT("Tried to fetch a pixel at %d, %d, but no pixel was found."), x, y);
		return FMapData();
	}
	else
	{
		return HeightmapData[index];
	}
}

void UPolygonalMapHeightmap::DrawDebugPixelGrid(UWorld* world, float PixelSize)
{
	if (world == NULL)
	{
		UE_LOG(LogWorldGen, Error, TEXT("World was null!"));
		return;
	}

	float elevationScale = 3100.0f;
	FVector offset = FVector(0.0f, 0.0f, 0.0f);

	for (int32 x = 0; x < HeightmapSize; x++)
	{
		for (int32 y = 0; y < HeightmapSize; y++)
		{
			FMapData mapData = GetMapPoint(x,y);

			FColor color = FColor(255, 255, 255);
			if (UMapDataHelper::IsOcean(mapData))
			{
				color = FColor(0, 0, 255);
			}
			else if (UMapDataHelper::IsCoast(mapData))
			{
				color = FColor(255, 255, 0);
			}
			else if (UMapDataHelper::IsWater(mapData))
			{
				color = FColor(0, 255, 255);
			}

			FVector v0 = offset + FVector(mapData.Point.X * PixelSize, mapData.Point.Y * PixelSize, mapData.Elevation * elevationScale);
			FVector v1 = FVector(v0.X, v0.Y + PixelSize, v0.Z);
			FVector v2 = FVector(v0.X + PixelSize, v0.Y, v0.Z);
			FVector v3 = FVector(v2.X, v1.Y, v0.Z);
			DrawDebugSphere(world, v0, 100, 4, color, true);
			DrawDebugLine(world, v0, v1, color, true);
			DrawDebugLine(world, v0, v2, color, true);
		}
	}
}<|endoftext|>


<commit_before>// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by MIT license that can be found in the
// LICENSE file.

#include <string.h>

#include "rescle.h"

bool print_error(const char* message) {
  fprintf(stderr, "Fatal error: %s\n", message);
  return 1;
}

bool print_warning(const char* message) {
  fprintf(stderr, "Warning: %s\n", message);
  return 1;
}

bool parse_version_string(const wchar_t* str, unsigned short *v1, unsigned short *v2, unsigned short *v3, unsigned short *v4) {
  *v1 = *v2 = *v3 = *v4 = 0;
  if (swscanf_s(str, L"%hu.%hu.%hu.%hu", v1, v2, v3, v4) == 4)
    return true;
  if (swscanf_s(str, L"%hu.%hu.%hu", v1, v2, v3) == 3)
    return true;
  if (swscanf_s(str, L"%hu.%hu", v1, v2) == 2)
    return true;
  if (swscanf_s(str, L"%hu", v1) == 1)
    return true;

  return false;
}

int wmain(int argc, const wchar_t* argv[]) {
  bool loaded = false;
  rescle::ResourceUpdater updater;

  for (int i = 1; i < argc; ++i) {
    if (wcscmp(argv[i], L"--set-version-string") == 0 ||
        wcscmp(argv[i], L"-svs") == 0) {
      if (argc - i < 3)
        return print_error("--set-version-string requires 'Key' and 'Value'");

      const wchar_t* key = argv[++i];
      const wchar_t* value = argv[++i];
      if (!updater.SetVersionString(key, value))
        return print_error("Unable to change version string");

    } else if (wcscmp(argv[i], L"--set-file-version") == 0 ||
               wcscmp(argv[i], L"-sfv") == 0) {
      if (argc - i < 2)
        return print_error("--set-file-version requires a version string");

      unsigned short v1, v2, v3, v4;
      if (!parse_version_string(argv[++i], &v1, &v2, &v3, &v4))
        return print_error("Unable to parse version string for FileVersion");

      if (!updater.SetFileVersion(v1, v2, v3, v4))
        return print_error("Unable to change file version");

      if (!updater.SetVersionString(L"FileVersion", argv[i]))
        return print_error("Unable to change FileVersion string");

    } else if (wcscmp(argv[i], L"--set-product-version") == 0 ||
               wcscmp(argv[i], L"-spv") == 0) {
      if (argc - i < 2)
        return print_error("--set-product-version requires a version string");

      unsigned short v1, v2, v3, v4;
      if (!parse_version_string(argv[++i], &v1, &v2, &v3, &v4))
        return print_error("Unable to parse version string for ProductVersion");

      if (!updater.SetProductVersion(v1, v2, v3, v4))
        return print_error("Unable to change product version");

      if (!updater.SetVersionString(L"ProductVersion", argv[i]))
        return print_error("Unable to change ProductVersion string");

    } else if (wcscmp(argv[i], L"--set-icon") == 0 ||
               wcscmp(argv[i], L"-si") == 0) {
      if (argc - i < 2)
        return print_error("--set-icon requires path to the icon");

      if (!updater.SetIcon(argv[++i]))
        return print_error("Unable to set icon");
    } else if (wcscmp(argv[i], L"--set-requested-execution-level") == 0 ||
      wcscmp(argv[i], L"-sel") == 0) {
      if (argc - i < 2)
        return print_error("--set-requested-execution-level requires asInvoker, highestAvailable or requireAdministrator");

      if (updater.IsApplicationManifestSet())
      {
        print_warning("--set-requested-execution-level is ignored if --application-manifest is set");
      }

      if (!updater.SetExecutionLevel(argv[++i]))
        return print_error("Unable to set execution level");
    } else if (wcscmp(argv[i], L"--application-manifest") == 0 ||
      wcscmp(argv[i], L"-am") == 0) {
      if (argc - i < 2)
        return print_error("--application-manifest requires local path");

      if (updater.IsExecutionLevelSet())
      {
        print_warning("--set-requested-execution-level is ignored if --application-manifest is set");
      }

      if (!updater.SetApplicationManifest(argv[++i]))
        return print_error("Unable to set application manifest");

    } else if (wcscmp(argv[i], L"--set-resource-string") == 0 ||
      wcscmp(argv[i], L"--srs") == 0) {
      if (argc - i < 3)
        return print_error("--set-resource-string requires int 'Key' and string 'Value'");

      const wchar_t* key = argv[++i];
      unsigned int key_id = 0;
      if (swscanf_s(key, L"%d", &key_id) != 1)
        return print_error("Unable to parse id");

      const wchar_t* value = argv[++i];
      if (!updater.ChangeString(key_id, value))
        return print_error("Unable to change string");
    } else {
      if (loaded)
        return print_error("Unexpected trailing arguments");

      loaded = true;
      if (!updater.Load(argv[i]))
        return print_error("Unable to load file");

    }
  }

  if (!loaded)
    return print_error("You should specify a exe/dll file");

  if (!updater.Commit())
    return print_error("Unable to commit changes");

  return 0;
}
<commit_msg>Add missing r to short option<commit_after>// Copyright (c) 2013 GitHub, Inc. All rights reserved.
// Use of this source code is governed by MIT license that can be found in the
// LICENSE file.

#include <string.h>

#include "rescle.h"

bool print_error(const char* message) {
  fprintf(stderr, "Fatal error: %s\n", message);
  return 1;
}

bool print_warning(const char* message) {
  fprintf(stderr, "Warning: %s\n", message);
  return 1;
}

bool parse_version_string(const wchar_t* str, unsigned short *v1, unsigned short *v2, unsigned short *v3, unsigned short *v4) {
  *v1 = *v2 = *v3 = *v4 = 0;
  if (swscanf_s(str, L"%hu.%hu.%hu.%hu", v1, v2, v3, v4) == 4)
    return true;
  if (swscanf_s(str, L"%hu.%hu.%hu", v1, v2, v3) == 3)
    return true;
  if (swscanf_s(str, L"%hu.%hu", v1, v2) == 2)
    return true;
  if (swscanf_s(str, L"%hu", v1) == 1)
    return true;

  return false;
}

int wmain(int argc, const wchar_t* argv[]) {
  bool loaded = false;
  rescle::ResourceUpdater updater;

  for (int i = 1; i < argc; ++i) {
    if (wcscmp(argv[i], L"--set-version-string") == 0 ||
        wcscmp(argv[i], L"-svs") == 0) {
      if (argc - i < 3)
        return print_error("--set-version-string requires 'Key' and 'Value'");

      const wchar_t* key = argv[++i];
      const wchar_t* value = argv[++i];
      if (!updater.SetVersionString(key, value))
        return print_error("Unable to change version string");

    } else if (wcscmp(argv[i], L"--set-file-version") == 0 ||
               wcscmp(argv[i], L"-sfv") == 0) {
      if (argc - i < 2)
        return print_error("--set-file-version requires a version string");

      unsigned short v1, v2, v3, v4;
      if (!parse_version_string(argv[++i], &v1, &v2, &v3, &v4))
        return print_error("Unable to parse version string for FileVersion");

      if (!updater.SetFileVersion(v1, v2, v3, v4))
        return print_error("Unable to change file version");

      if (!updater.SetVersionString(L"FileVersion", argv[i]))
        return print_error("Unable to change FileVersion string");

    } else if (wcscmp(argv[i], L"--set-product-version") == 0 ||
               wcscmp(argv[i], L"-spv") == 0) {
      if (argc - i < 2)
        return print_error("--set-product-version requires a version string");

      unsigned short v1, v2, v3, v4;
      if (!parse_version_string(argv[++i], &v1, &v2, &v3, &v4))
        return print_error("Unable to parse version string for ProductVersion");

      if (!updater.SetProductVersion(v1, v2, v3, v4))
        return print_error("Unable to change product version");

      if (!updater.SetVersionString(L"ProductVersion", argv[i]))
        return print_error("Unable to change ProductVersion string");

    } else if (wcscmp(argv[i], L"--set-icon") == 0 ||
               wcscmp(argv[i], L"-si") == 0) {
      if (argc - i < 2)
        return print_error("--set-icon requires path to the icon");

      if (!updater.SetIcon(argv[++i]))
        return print_error("Unable to set icon");
    } else if (wcscmp(argv[i], L"--set-requested-execution-level") == 0 ||
      wcscmp(argv[i], L"-srel") == 0) {
      if (argc - i < 2)
        return print_error("--set-requested-execution-level requires asInvoker, highestAvailable or requireAdministrator");

      if (updater.IsApplicationManifestSet())
      {
        print_warning("--set-requested-execution-level is ignored if --application-manifest is set");
      }

      if (!updater.SetExecutionLevel(argv[++i]))
        return print_error("Unable to set execution level");
    } else if (wcscmp(argv[i], L"--application-manifest") == 0 ||
      wcscmp(argv[i], L"-am") == 0) {
      if (argc - i < 2)
        return print_error("--application-manifest requires local path");

      if (updater.IsExecutionLevelSet())
      {
        print_warning("--set-requested-execution-level is ignored if --application-manifest is set");
      }

      if (!updater.SetApplicationManifest(argv[++i]))
        return print_error("Unable to set application manifest");

    } else if (wcscmp(argv[i], L"--set-resource-string") == 0 ||
      wcscmp(argv[i], L"--srs") == 0) {
      if (argc - i < 3)
        return print_error("--set-resource-string requires int 'Key' and string 'Value'");

      const wchar_t* key = argv[++i];
      unsigned int key_id = 0;
      if (swscanf_s(key, L"%d", &key_id) != 1)
        return print_error("Unable to parse id");

      const wchar_t* value = argv[++i];
      if (!updater.ChangeString(key_id, value))
        return print_error("Unable to change string");
    } else {
      if (loaded)
        return print_error("Unexpected trailing arguments");

      loaded = true;
      if (!updater.Load(argv[i]))
        return print_error("Unable to load file");

    }
  }

  if (!loaded)
    return print_error("You should specify a exe/dll file");

  if (!updater.Commit())
    return print_error("Unable to commit changes");

  return 0;
}
<|endoftext|>


<commit_before>#ifndef TOPPRA_PIECEWISE_POLY_PATH_HPP
#define TOPPRA_PIECEWISE_POLY_PATH_HPP

#include <toppra/geometric_path.hpp>
#include <toppra/toppra.hpp>

namespace toppra {

/// Boundary condition
typedef struct {
    int order;
    Vector values;
} BoundaryCond;

/**
 * \brief Piecewise polynomial geometric path.
 *
 * An implementation of a piecewise polynomial geometric path.
 *
 * The coefficient vector has shape (N, P, D), where N is the number
 * segments. For each segment, the i-th row (P index) denotes the
 * power, while the j-th column is the degree of freedom. In
 * particular,
 *
 *  coeff(0) * dt ^ 3 + coeff(1) * dt ^ 2 + coeff(2) * dt + coeff(3)
 *
 *
 */
class PiecewisePolyPath : public GeometricPath {
 public:
  PiecewisePolyPath() = default;

  /**
   * \brief Construct new piecewise polynomial.
   *
   * See class docstring for details.
   *
   * @param coefficients Polynomial coefficients.
   * @param breakpoints Vector of breakpoints.
   */
  PiecewisePolyPath(const Matrices &coefficients, std::vector<value_type> breakpoints);

  /**
   * \brief Construct a new piecewise 3rd degree polynomial.
   * @param positions Vectors of path positions at given times.
   * @param times Vector of times in a strictly increasing order.
   * @param bc_type Boundary conditions at the curve start and end.
   */
  PiecewisePolyPath(const Vectors &positions, const Vector &times, const std::array<BoundaryCond, 2> &bc_type);

  /**
   * /brief Evaluate the path at given position.
   */
  Vector eval_single(value_type, int order = 0) const override;

  /**
   * /brief Evaluate the path at given positions (vector).
   */
  Vectors eval(const Vector &, int order = 0) const override;

  /**
   * Return the starting and ending path positions.
   */
  Bound pathInterval() const override;
  void serialize(std::ostream &O) const override;
  void deserialize(std::istream &I) override;

  /**
   * \brief Construct a new Hermite polynomial.
   */
  static PiecewisePolyPath constructHermite(const Vectors &positions,
                                            const Vectors &velocities,
                                            const std::vector<value_type> times);

 protected:
  void initAsHermite(const Vectors &positions, const Vectors &velocities,
                     const std::vector<value_type> times);
  void computeCubicSplineCoefficients(const Vectors &positions, const Vector &times,
          const std::array<BoundaryCond, 2> &bc_type, Matrices &coefficients);
  void reset();
  size_t findSegmentIndex(value_type pos) const;
  void checkInputArgs();
  void checkInputArgs(const Vectors &positions, const Vector &times,
                      const std::array<BoundaryCond, 2> &bc_type);
  void computeDerivativesCoefficients();
  const Matrix &getCoefficient(size_t seg_index, int order) const;
  Matrices m_coefficients, m_coefficients_1, m_coefficients_2;
  std::vector<value_type> m_breakpoints;
  int m_degree;
};

}  // namespace toppra

#endif
<commit_msg>doc: Improve PiecewisePolyPath constructor docstring<commit_after>#ifndef TOPPRA_PIECEWISE_POLY_PATH_HPP
#define TOPPRA_PIECEWISE_POLY_PATH_HPP

#include <toppra/geometric_path.hpp>
#include <toppra/toppra.hpp>

namespace toppra {

/// Boundary condition
typedef struct {
    int order;
    Vector values;
} BoundaryCond;

/**
 * \brief Piecewise polynomial geometric path.
 *
 * An implementation of a piecewise polynomial geometric path.
 *
 * The coefficient vector has shape (N, P, D), where N is the number
 * segments. For each segment, the i-th row (P index) denotes the
 * power, while the j-th column is the degree of freedom. In
 * particular,
 *
 *  coeff(0) * dt ^ 3 + coeff(1) * dt ^ 2 + coeff(2) * dt + coeff(3)
 *
 *
 */
class PiecewisePolyPath : public GeometricPath {
 public:
  PiecewisePolyPath() = default;

  /**
   * \brief Construct new piecewise polynomial.
   *
   * See class docstring for details.
   *
   * @param coefficients Polynomial coefficients.
   * @param breakpoints Vector of breakpoints.
   */
  PiecewisePolyPath(const Matrices &coefficients, std::vector<value_type> breakpoints);

  /**
   * \brief Construct a new piecewise 3rd degree polynomial.
   * @param positions Vectors of path positions at given times.
   * @param times Vector of times in a strictly increasing order.
   * @param bc_type Boundary conditions at the curve start and end.
   */
  PiecewisePolyPath(const Vectors &positions, const Vector &times, const std::array<BoundaryCond, 2> &bc_type);

  /**
   * /brief Evaluate the path at given position.
   */
  Vector eval_single(value_type, int order = 0) const override;

  /**
   * /brief Evaluate the path at given positions (vector).
   */
  Vectors eval(const Vector &, int order = 0) const override;

  /**
   * Return the starting and ending path positions.
   */
  Bound pathInterval() const override;
  void serialize(std::ostream &O) const override;
  void deserialize(std::istream &I) override;

  /**
   * @brief Construct a piecewise Cubic Hermite polynomial.
   *
   * See https://en.wikipedia.org/wiki/Cubic_Hermite_spline for a good
   * description of this interplation scheme.
   *
   * This function is implemented based on scipy.interpolate.CubicHermiteSpline.
   *
   * Note that path generates by this function is not guaranteed to have
   * continuous acceleration, or the path second-order derivative.
   *
   * @param positions Robot joints corresponding to the given times. Must have
   * the same size as times.
   * @param velocities Robot joint velocities.
   * @param times Path positions or times. This is the independent variable.
   * @return PiecewisePolyPath
   */
  static PiecewisePolyPath constructHermite(const Vectors &positions,
                                            const Vectors &velocities,
                                            const std::vector<value_type> times);

  /**
   * @brief Construct a cubic spline.
   *
   * Interpolate the given joint positions with a spline that is twice
   * continuously differentiable. This means the position, velocity and
   * acceleration are guaranteed to be continous but not jerk.
   *
   * This method is modelled after scipy.interpolate.CubicSpline.
   *
   * @param positions Robot joints corresponding to the given times.
   * @param times Path positions or times. This is the independent variable.
   * @param bc_type Boundary condition.
   * @return PiecewisePolyPath
   */
  static PiecewisePolyPath CubicSpline(const Vectors &positions, const Vector &times, const std::array<BoundaryCond, 2> &bc_type){
    return PiecewisePolyPath(positions, times, bc_type);
  }

 protected:
  void initAsHermite(const Vectors &positions, const Vectors &velocities,
                     const std::vector<value_type> times);
  void computeCubicSplineCoefficients(const Vectors &positions, const Vector &times,
          const std::array<BoundaryCond, 2> &bc_type, Matrices &coefficients);
  void reset();
  size_t findSegmentIndex(value_type pos) const;
  void checkInputArgs();
  void checkInputArgs(const Vectors &positions, const Vector &times,
                      const std::array<BoundaryCond, 2> &bc_type);
  void computeDerivativesCoefficients();
  const Matrix &getCoefficient(size_t seg_index, int order) const;
  Matrices m_coefficients, m_coefficients_1, m_coefficients_2;
  std::vector<value_type> m_breakpoints;
  int m_degree;
};

}  // namespace toppra

#endif
<|endoftext|>


<commit_before>/**
 * This file defines the `getter` functor.
 */

#ifndef D2_DETAIL_GETTER_HPP
#define D2_DETAIL_GETTER_HPP

namespace d2 {
namespace detail {

/**
 * Functor fetching a member inside an object.
 */
template <typename Type, typename Tag>
class getter {
    typedef Type Tag::* Ptr;
    Ptr ptr_;

public:
    explicit getter(Ptr ptr) : ptr_(ptr) { }

    template <typename Sig>
    struct result;

    template <typename This>
    struct result<This(Tag&)> {
        typedef Type& type;
    };

    template <typename This>
    struct result<This(Tag const&)> {
        typedef Type const& type;
    };

    typename result<getter(Tag&)>::type operator()(Tag& t) const {
        return t.*ptr_;
    }

    typename result<getter(Tag const&)>::type operator()(Tag const& t) const {
        return t.*ptr_;
    }
};

/**
 * `getter` of a member specified at compile time.
 */
template <typename Type, typename Tag, Type Tag::* ptr>
struct fixed_getter : getter<Type, Tag> {
    fixed_getter() : getter<Type, Tag>(ptr) { }
};

/**
 * Helper function to create a `getter`.
 */
template <typename Type, typename Tag>
getter<Type, Tag> get(Type Tag::*ptr) {
    return getter<Type, Tag>(ptr);
}

} // end namespace detail
} // end namespace d2

#endif // !D2_DETAIL_GETTER_HPP
<commit_msg>Remove useless file (functionally equivalent to mem_fn).<commit_after><|endoftext|>


<commit_before>#ifndef slic3r_LOG_HPP
#define slic3r_LOG_HPP

#include <string>

namespace Slic3r {

class Log {
public:
    static void fatal_error(std::string topic, std::wstring message) {
        std::cerr << topic << ": ";
        std::wcerr << message << std::endl;
    }

    static void info(std::string topic, std::wstring message) {
        std::clog << topic << ": ";
        std::wclog << message << std::endl;
    }

    static void warn(std::string topic, std::wstring message) {
        std::cerr << topic << ": ";
        std::wcerr << message << std::endl;
    }

};

}

#endif // slic3r_LOG_HPP
<commit_msg>Added generic error message to Log; print error type to console.<commit_after>#ifndef slic3r_LOG_HPP
#define slic3r_LOG_HPP

#include <string>

namespace Slic3r {

class Log {
public:
    static void fatal_error(std::string topic, std::wstring message) {
        std::cerr << topic << " FERR" << ": ";
        std::wcerr << message << std::endl;
    }
    static void error(std::string topic, std::wstring message) {
        std::cerr << topic << "  ERR" << ": ";
        std::wcerr << message << std::endl;
    }

    static void info(std::string topic, std::wstring message) {
        std::clog << topic << " INFO" << ": ";
        std::wclog << message << std::endl;
    }

    static void warn(std::string topic, std::wstring message) {
        std::cerr << topic << " WARN" << ": ";
        std::wcerr << message << std::endl;
    }

};

}

#endif // slic3r_LOG_HPP
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 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 <vector>

#include "gtest/gtest.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/test/testsupport/metrics/video_metrics.h"
#include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
#include "webrtc/video_engine/test/auto_test/interface/vie_file_based_comparison_tests.h"
#include "webrtc/video_engine/test/auto_test/primitives/framedrop_primitives.h"
#include "webrtc/video_engine/test/libvietest/include/tb_external_transport.h"
#include "webrtc/video_engine/test/libvietest/include/vie_to_file_renderer.h"

namespace {

// The input file must be QCIF since I420 gets scaled to that in the tests
// (it is so bandwidth-heavy we have no choice). Our comparison algorithms
// wouldn't like scaling, so this will work when we compare with the original.
const int kInputWidth = 176;
const int kInputHeight = 144;

class ViEVideoVerificationTest : public testing::Test {
 protected:
  void SetUp() {
    input_file_ = webrtc::test::ResourcePath("paris_qcif", "yuv");
    local_file_renderer_ = NULL;
    remote_file_renderer_ = NULL;
  }

  void InitializeFileRenderers() {
    local_file_renderer_ = new ViEToFileRenderer();
    remote_file_renderer_ = new ViEToFileRenderer();
    SetUpLocalFileRenderer(local_file_renderer_);
    SetUpRemoteFileRenderer(remote_file_renderer_);
  }

  void SetUpLocalFileRenderer(ViEToFileRenderer* file_renderer) {
    SetUpFileRenderer(file_renderer, "-local-preview.yuv");
  }

  void SetUpRemoteFileRenderer(ViEToFileRenderer* file_renderer) {
    SetUpFileRenderer(file_renderer, "-remote.yuv");
  }

  // Must be called manually inside the tests.
  void StopRenderers() {
    local_file_renderer_->StopRendering();
    remote_file_renderer_->StopRendering();
  }

  void CompareFiles(const std::string& reference_file,
                    const std::string& test_file,
                    double* psnr_result, double *ssim_result) {
    webrtc::test::QualityMetricsResult psnr;
    int error = I420PSNRFromFiles(reference_file.c_str(), test_file.c_str(),
                                  kInputWidth, kInputHeight, &psnr);

    EXPECT_EQ(0, error) << "PSNR routine failed - output files missing?";
    *psnr_result = psnr.average;

    webrtc::test::QualityMetricsResult ssim;
    error = I420SSIMFromFiles(reference_file.c_str(), test_file.c_str(),
                              kInputWidth, kInputHeight, &ssim);
    EXPECT_EQ(0, error) << "SSIM routine failed - output files missing?";
    *ssim_result = ssim.average;

    ViETest::Log("Results: PSNR is %f (dB; 48 is max), "
                 "SSIM is %f (1 is perfect)",
                 psnr.average, ssim.average);
  }

  // Note: must call AFTER CompareFiles.
  void TearDownFileRenderers() {
    TearDownFileRenderer(local_file_renderer_);
    TearDownFileRenderer(remote_file_renderer_);
  }

  std::string input_file_;
  ViEToFileRenderer* local_file_renderer_;
  ViEToFileRenderer* remote_file_renderer_;
  ViEFileBasedComparisonTests tests_;

 private:
  void SetUpFileRenderer(ViEToFileRenderer* file_renderer,
                         const std::string& suffix) {
    std::string output_path = ViETest::GetResultOutputPath();
    std::string filename = "render_output" + suffix;

    if (!file_renderer->PrepareForRendering(output_path, filename)) {
      FAIL() << "Could not open output file " << filename <<
          " for writing.";
    }
  }

  void TearDownFileRenderer(ViEToFileRenderer* file_renderer) {
      assert(file_renderer);
      bool test_failed = ::testing::UnitTest::GetInstance()->
          current_test_info()->result()->Failed();
      if (test_failed) {
        // Leave the files for analysis if the test failed.
        file_renderer->SaveOutputFile("failed-");
      }
      delete file_renderer;
    }
};

class ParameterizedFullStackTest : public ViEVideoVerificationTest,
                                   public ::testing::WithParamInterface<int> {
 public:
  static const int kNumFullStackInstances = 4;

 protected:
  struct TestParameters {
    NetworkParameters network;
    std::string file_name;
    int width;
    int height;
    int bitrate;
    double avg_psnr_threshold;
    double avg_ssim_threshold;
    ProtectionMethod protection_method;
    std::string test_label;
  };

  void SetUp() {
    for (int i = 0; i < kNumFullStackInstances; ++i) {
      parameter_table_[i].file_name = webrtc::test::ResourcePath("foreman_cif",
                                                                 "yuv");
      parameter_table_[i].width = 352;
      parameter_table_[i].height = 288;
    }
    int i = 0;
    parameter_table_[i].protection_method = kNack;
    // Uniform loss => Setting burst length to -1.
    parameter_table_[i].network.loss_model = kUniformLoss;
    parameter_table_[i].network.packet_loss_rate = 0;
    parameter_table_[i].network.burst_length = -1;
    parameter_table_[i].network.mean_one_way_delay = 0;
    parameter_table_[i].network.std_dev_one_way_delay = 0;
    parameter_table_[i].bitrate = 300;
    parameter_table_[i].avg_psnr_threshold = 35;
    parameter_table_[i].avg_ssim_threshold = 0.96;
    parameter_table_[i].test_label = "net_delay_0_0_plr_0";
    ++i;
    parameter_table_[i].protection_method = kNack;
    parameter_table_[i].network.loss_model = kUniformLoss;
    parameter_table_[i].network.packet_loss_rate = 5;
    parameter_table_[i].network.burst_length = -1;
    parameter_table_[i].network.mean_one_way_delay = 50;
    parameter_table_[i].network.std_dev_one_way_delay = 5;
    parameter_table_[i].bitrate = 300;
    parameter_table_[i].avg_psnr_threshold = 35;
    parameter_table_[i].avg_ssim_threshold = 0.96;
    parameter_table_[i].test_label = "net_delay_50_5_plr_5";
    ++i;
    parameter_table_[i].protection_method = kNack;
    parameter_table_[i].network.loss_model = kUniformLoss;
    parameter_table_[i].network.packet_loss_rate = 0;
    parameter_table_[i].network.burst_length = -1;
    parameter_table_[i].network.mean_one_way_delay = 100;
    parameter_table_[i].network.std_dev_one_way_delay = 10;
    parameter_table_[i].bitrate = 300;
    parameter_table_[i].avg_psnr_threshold = 35;
    parameter_table_[i].avg_ssim_threshold = 0.96;
    parameter_table_[i].test_label = "net_delay_100_10_plr_0";
    ++i;
    parameter_table_[i].protection_method = kNack;
    parameter_table_[i].network.loss_model = kGilbertElliotLoss;
    parameter_table_[i].network.packet_loss_rate = 5;
    parameter_table_[i].network.burst_length = 3;
    parameter_table_[i].network.mean_one_way_delay = 100;
    parameter_table_[i].network.std_dev_one_way_delay = 10;
    parameter_table_[i].bitrate = 300;
    // Thresholds disabled for now. This is being run mainly to get a graph.
    parameter_table_[i].avg_psnr_threshold = 0;
    parameter_table_[i].avg_ssim_threshold = 0.0;
    parameter_table_[i].test_label = "net_delay_100_10_plr_5_gilbert_elliot";

    ASSERT_EQ(kNumFullStackInstances - 1, i);
  }

  TestParameters parameter_table_[kNumFullStackInstances];
};

TEST_F(ViEVideoVerificationTest, RunsBaseStandardTestWithoutErrors) {
  // I420 is lossless, so the I420 test should obviously get perfect results -
  // the local preview and remote output files should be bit-exact. This test
  // runs on external transport to ensure we do not drop packets.
  // However, it's hard to make 100% stringent requirements on the video engine
  // since for instance the jitter buffer has non-deterministic elements. If it
  // breaks five times in a row though, you probably introduced a bug.
  const double kReasonablePsnr = webrtc::test::kMetricsPerfectPSNR - 2.0f;
  const double kReasonableSsim = 0.99f;
  const int kNumAttempts = 5;
  for (int attempt = 0; attempt < kNumAttempts; ++attempt) {
    InitializeFileRenderers();
    ASSERT_TRUE(tests_.TestCallSetup(input_file_, kInputWidth, kInputHeight,
                                     local_file_renderer_,
                                     remote_file_renderer_));
    std::string remote_file = remote_file_renderer_->GetFullOutputPath();
    std::string local_preview = local_file_renderer_->GetFullOutputPath();
    StopRenderers();

    double actual_psnr = 0;
    double actual_ssim = 0;
    CompareFiles(local_preview, remote_file, &actual_psnr, &actual_ssim);

    TearDownFileRenderers();

    if (actual_psnr > kReasonablePsnr && actual_ssim > kReasonableSsim) {
      // Test successful.
      return;
    } else {
      ViETest::Log("Retrying; attempt %d of %d.", attempt + 1, kNumAttempts);
    }
  }

  FAIL() << "Failed to achieve near-perfect PSNR and SSIM results after " <<
      kNumAttempts << " attempts.";
}

// Runs a whole stack processing with tracking of which frames are dropped
// in the encoder. Tests show that they start at the same frame, which is
// the important thing when doing frame-to-frame comparison with PSNR/SSIM.
TEST_P(ParameterizedFullStackTest, RunsFullStackWithoutErrors)  {
  // Using CIF here since it's a more common resolution than QCIF, and higher
  // resolutions shouldn't be a problem for a test using VP8.
  input_file_ = parameter_table_[GetParam()].file_name;
  FrameDropDetector detector;
  local_file_renderer_ = new ViEToFileRenderer();
  remote_file_renderer_ = new FrameDropMonitoringRemoteFileRenderer(&detector);
  SetUpLocalFileRenderer(local_file_renderer_);
  SetUpRemoteFileRenderer(remote_file_renderer_);

  // Set a low bit rate so the encoder budget will be tight, causing it to drop
  // frames every now and then.
  const int kBitRateKbps = parameter_table_[GetParam()].bitrate;
  const NetworkParameters network = parameter_table_[GetParam()].network;
  int width = parameter_table_[GetParam()].width;
  int height = parameter_table_[GetParam()].height;
  ProtectionMethod protection_method =
      parameter_table_[GetParam()].protection_method;
  ViETest::Log("Bit rate     : %5d kbps", kBitRateKbps);
  ViETest::Log("Packet loss  : %5d %%", network.packet_loss_rate);
  ViETest::Log("Network delay: mean=%dms std dev=%d ms",
               network.mean_one_way_delay, network.std_dev_one_way_delay);
  tests_.TestFullStack(input_file_, width, height, kBitRateKbps,
                       protection_method, network, local_file_renderer_,
                       remote_file_renderer_, &detector);
  const std::string reference_file = local_file_renderer_->GetFullOutputPath();
  const std::string output_file = remote_file_renderer_->GetFullOutputPath();
  StopRenderers();

  detector.CalculateResults();
  detector.PrintReport(parameter_table_[GetParam()].test_label);

  if (detector.GetNumberOfFramesDroppedAt(FrameDropDetector::kRendered) >
      detector.GetNumberOfFramesDroppedAt(FrameDropDetector::kDecoded)) {
    detector.PrintDebugDump();
  }

  ASSERT_GE(detector.GetNumberOfFramesDroppedAt(FrameDropDetector::kRendered),
      detector.GetNumberOfFramesDroppedAt(FrameDropDetector::kDecoded))
      << "The number of dropped frames on the decode and render steps are not "
      "equal. This may be because we have a major problem in the buffers of "
      "the ViEToFileRenderer?";

  // We may have dropped frames during the processing, which means the output
  // file does not contain all the frames that are present in the input file.
  // To make the quality measurement correct, we must adjust the output file to
  // that by copying the last successful frame into the place where the dropped
  // frame would be, for all dropped frames.
  const int frame_length_in_bytes = 3 * width * height / 2;
  ViETest::Log("Frame length: %d bytes", frame_length_in_bytes);
  std::vector<Frame*> all_frames = detector.GetAllFrames();
  FixOutputFileForComparison(output_file, frame_length_in_bytes, all_frames);

  // Verify all sent frames are present in the output file.
  size_t output_file_size = webrtc::test::GetFileSize(output_file);
  EXPECT_EQ(all_frames.size(), output_file_size / frame_length_in_bytes)
      << "The output file size is incorrect. It should be equal to the number "
      "of frames multiplied by the frame size. This will likely affect "
      "PSNR/SSIM calculations in a bad way.";

  TearDownFileRenderers();

  // We are running on a lower bitrate here so we need to settle for somewhat
  // lower PSNR and SSIM values.
  double actual_psnr = 0;
  double actual_ssim = 0;
  CompareFiles(reference_file, output_file, &actual_psnr, &actual_ssim);

  const double kExpectedMinimumPSNR =
      parameter_table_[GetParam()].avg_psnr_threshold;
  const double kExpectedMinimumSSIM =
      parameter_table_[GetParam()].avg_ssim_threshold;

  EXPECT_GE(actual_psnr, kExpectedMinimumPSNR);
  EXPECT_GE(actual_ssim, kExpectedMinimumSSIM);
}

INSTANTIATE_TEST_CASE_P(FullStackTests, ParameterizedFullStackTest,
    ::testing::Range(0, ParameterizedFullStackTest::kNumFullStackInstances));

}  // namespace
<commit_msg>Disable full stack PSNR/SSIM triggers on Mac and Win for now due to flakiness. Adding plots of PSNR and SSIM.<commit_after>/*
 *  Copyright (c) 2012 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 <vector>

#include "gtest/gtest.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/test/testsupport/perf_test.h"
#include "webrtc/test/testsupport/metrics/video_metrics.h"
#include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
#include "webrtc/video_engine/test/auto_test/interface/vie_file_based_comparison_tests.h"
#include "webrtc/video_engine/test/auto_test/primitives/framedrop_primitives.h"
#include "webrtc/video_engine/test/libvietest/include/tb_external_transport.h"
#include "webrtc/video_engine/test/libvietest/include/vie_to_file_renderer.h"

namespace {

// The input file must be QCIF since I420 gets scaled to that in the tests
// (it is so bandwidth-heavy we have no choice). Our comparison algorithms
// wouldn't like scaling, so this will work when we compare with the original.
const int kInputWidth = 176;
const int kInputHeight = 144;

class ViEVideoVerificationTest : public testing::Test {
 protected:
  void SetUp() {
    input_file_ = webrtc::test::ResourcePath("paris_qcif", "yuv");
    local_file_renderer_ = NULL;
    remote_file_renderer_ = NULL;
  }

  void InitializeFileRenderers() {
    local_file_renderer_ = new ViEToFileRenderer();
    remote_file_renderer_ = new ViEToFileRenderer();
    SetUpLocalFileRenderer(local_file_renderer_);
    SetUpRemoteFileRenderer(remote_file_renderer_);
  }

  void SetUpLocalFileRenderer(ViEToFileRenderer* file_renderer) {
    SetUpFileRenderer(file_renderer, "-local-preview.yuv");
  }

  void SetUpRemoteFileRenderer(ViEToFileRenderer* file_renderer) {
    SetUpFileRenderer(file_renderer, "-remote.yuv");
  }

  // Must be called manually inside the tests.
  void StopRenderers() {
    local_file_renderer_->StopRendering();
    remote_file_renderer_->StopRendering();
  }

  void CompareFiles(const std::string& reference_file,
                    const std::string& test_file,
                    double* psnr_result, double *ssim_result) {
    webrtc::test::QualityMetricsResult psnr;
    int error = I420PSNRFromFiles(reference_file.c_str(), test_file.c_str(),
                                  kInputWidth, kInputHeight, &psnr);

    EXPECT_EQ(0, error) << "PSNR routine failed - output files missing?";
    *psnr_result = psnr.average;

    webrtc::test::QualityMetricsResult ssim;
    error = I420SSIMFromFiles(reference_file.c_str(), test_file.c_str(),
                              kInputWidth, kInputHeight, &ssim);
    EXPECT_EQ(0, error) << "SSIM routine failed - output files missing?";
    *ssim_result = ssim.average;

    ViETest::Log("Results: PSNR is %f (dB; 48 is max), "
                 "SSIM is %f (1 is perfect)",
                 psnr.average, ssim.average);
  }

  // Note: must call AFTER CompareFiles.
  void TearDownFileRenderers() {
    TearDownFileRenderer(local_file_renderer_);
    TearDownFileRenderer(remote_file_renderer_);
  }

  std::string input_file_;
  ViEToFileRenderer* local_file_renderer_;
  ViEToFileRenderer* remote_file_renderer_;
  ViEFileBasedComparisonTests tests_;

 private:
  void SetUpFileRenderer(ViEToFileRenderer* file_renderer,
                         const std::string& suffix) {
    std::string output_path = ViETest::GetResultOutputPath();
    std::string filename = "render_output" + suffix;

    if (!file_renderer->PrepareForRendering(output_path, filename)) {
      FAIL() << "Could not open output file " << filename <<
          " for writing.";
    }
  }

  void TearDownFileRenderer(ViEToFileRenderer* file_renderer) {
      assert(file_renderer);
      bool test_failed = ::testing::UnitTest::GetInstance()->
          current_test_info()->result()->Failed();
      if (test_failed) {
        // Leave the files for analysis if the test failed.
        file_renderer->SaveOutputFile("failed-");
      }
      delete file_renderer;
    }
};

class ParameterizedFullStackTest : public ViEVideoVerificationTest,
                                   public ::testing::WithParamInterface<int> {
 public:
  static const int kNumFullStackInstances = 4;

 protected:
  struct TestParameters {
    NetworkParameters network;
    std::string file_name;
    int width;
    int height;
    int bitrate;
    double avg_psnr_threshold;
    double avg_ssim_threshold;
    ProtectionMethod protection_method;
    std::string test_label;
  };

  void SetUp() {
    for (int i = 0; i < kNumFullStackInstances; ++i) {
      parameter_table_[i].file_name = webrtc::test::ResourcePath("foreman_cif",
                                                                 "yuv");
      parameter_table_[i].width = 352;
      parameter_table_[i].height = 288;
    }
    int i = 0;
    parameter_table_[i].protection_method = kNack;
    // Uniform loss => Setting burst length to -1.
    parameter_table_[i].network.loss_model = kUniformLoss;
    parameter_table_[i].network.packet_loss_rate = 0;
    parameter_table_[i].network.burst_length = -1;
    parameter_table_[i].network.mean_one_way_delay = 0;
    parameter_table_[i].network.std_dev_one_way_delay = 0;
    parameter_table_[i].bitrate = 300;
    // TODO(holmer): Enable for Win and Mac when the file rendering has been
    // moved to a separate thread.
#ifdef WEBRTC_LINUX
    parameter_table_[i].avg_psnr_threshold = 35;
    parameter_table_[i].avg_ssim_threshold = 0.96;
#else
    parameter_table_[i].avg_psnr_threshold = 0;
    parameter_table_[i].avg_ssim_threshold = 0.0;
#endif
    parameter_table_[i].test_label = "net_delay_0_0_plr_0";
    ++i;
    parameter_table_[i].protection_method = kNack;
    parameter_table_[i].network.loss_model = kUniformLoss;
    parameter_table_[i].network.packet_loss_rate = 5;
    parameter_table_[i].network.burst_length = -1;
    parameter_table_[i].network.mean_one_way_delay = 50;
    parameter_table_[i].network.std_dev_one_way_delay = 5;
    parameter_table_[i].bitrate = 300;
    // TODO(holmer): Enable for Win and Mac when the file rendering has been
    // moved to a separate thread.
#ifdef WEBRTC_LINUX
    parameter_table_[i].avg_psnr_threshold = 35;
    parameter_table_[i].avg_ssim_threshold = 0.96;
#else
    parameter_table_[i].avg_psnr_threshold = 0;
    parameter_table_[i].avg_ssim_threshold = 0.0;
#endif
    parameter_table_[i].test_label = "net_delay_50_5_plr_5";
    ++i;
    parameter_table_[i].protection_method = kNack;
    parameter_table_[i].network.loss_model = kUniformLoss;
    parameter_table_[i].network.packet_loss_rate = 0;
    parameter_table_[i].network.burst_length = -1;
    parameter_table_[i].network.mean_one_way_delay = 100;
    parameter_table_[i].network.std_dev_one_way_delay = 10;
    parameter_table_[i].bitrate = 300;
    // TODO(holmer): Enable for Win and Mac when the file rendering has been
    // moved to a separate thread.
#ifdef WEBRTC_LINUX
    parameter_table_[i].avg_psnr_threshold = 35;
    parameter_table_[i].avg_ssim_threshold = 0.96;
#else
    parameter_table_[i].avg_psnr_threshold = 0;
    parameter_table_[i].avg_ssim_threshold = 0.0;
#endif
    parameter_table_[i].test_label = "net_delay_100_10_plr_0";
    ++i;
    parameter_table_[i].protection_method = kNack;
    parameter_table_[i].network.loss_model = kGilbertElliotLoss;
    parameter_table_[i].network.packet_loss_rate = 5;
    parameter_table_[i].network.burst_length = 3;
    parameter_table_[i].network.mean_one_way_delay = 100;
    parameter_table_[i].network.std_dev_one_way_delay = 10;
    parameter_table_[i].bitrate = 300;
    // Thresholds disabled for now. This is being run mainly to get a graph.
    parameter_table_[i].avg_psnr_threshold = 0;
    parameter_table_[i].avg_ssim_threshold = 0.0;
    parameter_table_[i].test_label = "net_delay_100_10_plr_5_gilbert_elliot";

    ASSERT_EQ(kNumFullStackInstances - 1, i);
  }

  TestParameters parameter_table_[kNumFullStackInstances];
};

TEST_F(ViEVideoVerificationTest, RunsBaseStandardTestWithoutErrors) {
  // I420 is lossless, so the I420 test should obviously get perfect results -
  // the local preview and remote output files should be bit-exact. This test
  // runs on external transport to ensure we do not drop packets.
  // However, it's hard to make 100% stringent requirements on the video engine
  // since for instance the jitter buffer has non-deterministic elements. If it
  // breaks five times in a row though, you probably introduced a bug.
  const double kReasonablePsnr = webrtc::test::kMetricsPerfectPSNR - 2.0f;
  const double kReasonableSsim = 0.99f;
  const int kNumAttempts = 5;
  for (int attempt = 0; attempt < kNumAttempts; ++attempt) {
    InitializeFileRenderers();
    ASSERT_TRUE(tests_.TestCallSetup(input_file_, kInputWidth, kInputHeight,
                                     local_file_renderer_,
                                     remote_file_renderer_));
    std::string remote_file = remote_file_renderer_->GetFullOutputPath();
    std::string local_preview = local_file_renderer_->GetFullOutputPath();
    StopRenderers();

    double actual_psnr = 0;
    double actual_ssim = 0;
    CompareFiles(local_preview, remote_file, &actual_psnr, &actual_ssim);

    TearDownFileRenderers();

    if (actual_psnr > kReasonablePsnr && actual_ssim > kReasonableSsim) {
      // Test successful.
      return;
    } else {
      ViETest::Log("Retrying; attempt %d of %d.", attempt + 1, kNumAttempts);
    }
  }

  FAIL() << "Failed to achieve near-perfect PSNR and SSIM results after " <<
      kNumAttempts << " attempts.";
}

// Runs a whole stack processing with tracking of which frames are dropped
// in the encoder. Tests show that they start at the same frame, which is
// the important thing when doing frame-to-frame comparison with PSNR/SSIM.
TEST_P(ParameterizedFullStackTest, RunsFullStackWithoutErrors)  {
  // Using CIF here since it's a more common resolution than QCIF, and higher
  // resolutions shouldn't be a problem for a test using VP8.
  input_file_ = parameter_table_[GetParam()].file_name;
  FrameDropDetector detector;
  local_file_renderer_ = new ViEToFileRenderer();
  remote_file_renderer_ = new FrameDropMonitoringRemoteFileRenderer(&detector);
  SetUpLocalFileRenderer(local_file_renderer_);
  SetUpRemoteFileRenderer(remote_file_renderer_);

  // Set a low bit rate so the encoder budget will be tight, causing it to drop
  // frames every now and then.
  const int kBitRateKbps = parameter_table_[GetParam()].bitrate;
  const NetworkParameters network = parameter_table_[GetParam()].network;
  int width = parameter_table_[GetParam()].width;
  int height = parameter_table_[GetParam()].height;
  ProtectionMethod protection_method =
      parameter_table_[GetParam()].protection_method;
  ViETest::Log("Bit rate     : %5d kbps", kBitRateKbps);
  ViETest::Log("Packet loss  : %5d %%", network.packet_loss_rate);
  ViETest::Log("Network delay: mean=%dms std dev=%d ms",
               network.mean_one_way_delay, network.std_dev_one_way_delay);
  tests_.TestFullStack(input_file_, width, height, kBitRateKbps,
                       protection_method, network, local_file_renderer_,
                       remote_file_renderer_, &detector);
  const std::string reference_file = local_file_renderer_->GetFullOutputPath();
  const std::string output_file = remote_file_renderer_->GetFullOutputPath();
  StopRenderers();

  detector.CalculateResults();
  detector.PrintReport(parameter_table_[GetParam()].test_label);

  if (detector.GetNumberOfFramesDroppedAt(FrameDropDetector::kRendered) >
      detector.GetNumberOfFramesDroppedAt(FrameDropDetector::kDecoded)) {
    detector.PrintDebugDump();
  }

  ASSERT_GE(detector.GetNumberOfFramesDroppedAt(FrameDropDetector::kRendered),
      detector.GetNumberOfFramesDroppedAt(FrameDropDetector::kDecoded))
      << "The number of dropped frames on the decode and render steps are not "
      "equal. This may be because we have a major problem in the buffers of "
      "the ViEToFileRenderer?";

  // We may have dropped frames during the processing, which means the output
  // file does not contain all the frames that are present in the input file.
  // To make the quality measurement correct, we must adjust the output file to
  // that by copying the last successful frame into the place where the dropped
  // frame would be, for all dropped frames.
  const int frame_length_in_bytes = 3 * width * height / 2;
  ViETest::Log("Frame length: %d bytes", frame_length_in_bytes);
  std::vector<Frame*> all_frames = detector.GetAllFrames();
  FixOutputFileForComparison(output_file, frame_length_in_bytes, all_frames);

  // Verify all sent frames are present in the output file.
  size_t output_file_size = webrtc::test::GetFileSize(output_file);
  EXPECT_EQ(all_frames.size(), output_file_size / frame_length_in_bytes)
      << "The output file size is incorrect. It should be equal to the number "
      "of frames multiplied by the frame size. This will likely affect "
      "PSNR/SSIM calculations in a bad way.";

  TearDownFileRenderers();

  // We are running on a lower bitrate here so we need to settle for somewhat
  // lower PSNR and SSIM values.
  double actual_psnr = 0;
  double actual_ssim = 0;
  CompareFiles(reference_file, output_file, &actual_psnr, &actual_ssim);

  const double kExpectedMinimumPSNR =
      parameter_table_[GetParam()].avg_psnr_threshold;
  const double kExpectedMinimumSSIM =
      parameter_table_[GetParam()].avg_ssim_threshold;

  EXPECT_GE(actual_psnr, kExpectedMinimumPSNR);
  EXPECT_GE(actual_ssim, kExpectedMinimumSSIM);
  webrtc::test::PrintResult(
      "psnr", "", parameter_table_[GetParam()].test_label,
      actual_psnr, "dB", false);
  webrtc::test::PrintResult(
      "ssim", "", parameter_table_[GetParam()].test_label,
      actual_ssim, "", false);
}

INSTANTIATE_TEST_CASE_P(FullStackTests, ParameterizedFullStackTest,
    ::testing::Range(0, ParameterizedFullStackTest::kNumFullStackInstances));

}  // namespace
<|endoftext|>