<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkVolumeMapper.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkVolumeMapper.h"

// Construct a vtkVolumeMapper with empty scalar input and clipping off.
vtkVolumeMapper::vtkVolumeMapper()
{
  this->ScalarInput = NULL;
  this->RGBTextureInput = NULL;
  this->Clipping = 0;
  this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = -1.0;
  this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = 1.0;
  this->Center[0] = this->Center[1] = this->Center[2] = 0.0;
}

vtkVolumeMapper::~vtkVolumeMapper()
{
  this->SetScalarInput((vtkStructuredPoints *)NULL);
}

void vtkVolumeMapper::Update()
{
  if ( this->ScalarInput )
    {
    this->ScalarInput->Update();
    }
}

// Get the bounds of the ScalarInput
float *vtkVolumeMapper::GetBounds()
{
  static float bounds[] = {-1.0,1.0, -1.0,1.0, -1.0,1.0};

  if ( ! this->ScalarInput )
    {
    return bounds;
    }
  else
    {
    this->ScalarInput->Update();
    this->ScalarInput->GetBounds(this->Bounds);
    return this->Bounds;
    }
}

// Get the bounds for this Prop as (Xmin,Xmax,Ymin,Ymax,Zmin,Zmax).
void vtkVolumeMapper::GetBounds(float bounds[6])
{
  this->GetBounds();
  for (int i=0; i<6; i++)
    {
    bounds[i] = this->Bounds[i];
    }
}

float *vtkVolumeMapper::GetCenter()
{
  this->GetBounds();
  for (int i=0; i<3; i++)
    {
    this->Center[i] = (this->Bounds[2*i+1] + this->Bounds[2*i]) / 2.0;
    }
  return this->Center;
}

float vtkVolumeMapper::GetLength()
{
  double diff, l=0.0;
  int i;

  this->GetBounds();
  for (i=0; i<3; i++)
    {
    diff = this->Bounds[2*i+1] - this->Bounds[2*i];
    l += diff * diff;
    }

  return (float)sqrt(l);
}

void vtkVolumeMapper::SetRGBTextureInput( vtkStructuredPoints *rgbTexture )
{
  vtkPointData    *pd;
  vtkScalars      *scalars;

  if ( rgbTexture && rgbTexture != this->RGBTextureInput )
    {
    rgbTexture->Update();
    pd = rgbTexture->GetPointData();
    if ( !pd )
      {
      vtkErrorMacro( << "No PointData in texture!" );
      return;
      }
    scalars = pd->GetScalars();
    if ( !scalars )
      {
      vtkErrorMacro( << "No scalars in texture!" );
      return;
      }
    if ( scalars->GetDataType() != VTK_UNSIGNED_CHAR )
      {
      vtkErrorMacro( << "Scalars in texture must be unsigned char!" );
      return;
      }
    if ( scalars->GetNumberOfComponents() != 3 )
      {
      vtkErrorMacro( << "Scalars must have 3 components (r, g, and b)" );
      return;
      }
    this->RGBTextureInput = rgbTexture;
    this->Modified();
    }
}

// Print the vtkVolumeMapper
void vtkVolumeMapper::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkObject::PrintSelf(os,indent);

  if ( this->ScalarInput )
    {
    os << indent << "ScalarInput: (" << this->ScalarInput << ")\n";
    }
  else
    {
    os << indent << "ScalarInput: (none)\n";
    }

  if ( this->RGBTextureInput )
    {
    os << indent << "RGBTextureInput: (" << this->RGBTextureInput << ")\n";
    }
  else
    {
    os << indent << "RGBTextureInput: (none)\n";
    }

  os << indent << "Clipping: " << (this->Clipping ? "On\n" : "Off\n");
  os << indent << "Build Time: " <<this->BuildTime.GetMTime() << "\n";
}

<commit_msg>ERR: Fixed printself defect (printing the right superclass now)<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkVolumeMapper.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkVolumeMapper.h"

// Construct a vtkVolumeMapper with empty scalar input and clipping off.
vtkVolumeMapper::vtkVolumeMapper()
{
  this->ScalarInput = NULL;
  this->RGBTextureInput = NULL;
  this->Clipping = 0;
  this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = -1.0;
  this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = 1.0;
  this->Center[0] = this->Center[1] = this->Center[2] = 0.0;
}

vtkVolumeMapper::~vtkVolumeMapper()
{
  this->SetScalarInput((vtkStructuredPoints *)NULL);
}

void vtkVolumeMapper::Update()
{
  if ( this->ScalarInput )
    {
    this->ScalarInput->Update();
    }
}

// Get the bounds of the ScalarInput
float *vtkVolumeMapper::GetBounds()
{
  static float bounds[] = {-1.0,1.0, -1.0,1.0, -1.0,1.0};

  if ( ! this->ScalarInput )
    {
    return bounds;
    }
  else
    {
    this->ScalarInput->Update();
    this->ScalarInput->GetBounds(this->Bounds);
    return this->Bounds;
    }
}

// Get the bounds for this Prop as (Xmin,Xmax,Ymin,Ymax,Zmin,Zmax).
void vtkVolumeMapper::GetBounds(float bounds[6])
{
  this->GetBounds();
  for (int i=0; i<6; i++)
    {
    bounds[i] = this->Bounds[i];
    }
}

float *vtkVolumeMapper::GetCenter()
{
  this->GetBounds();
  for (int i=0; i<3; i++)
    {
    this->Center[i] = (this->Bounds[2*i+1] + this->Bounds[2*i]) / 2.0;
    }
  return this->Center;
}

float vtkVolumeMapper::GetLength()
{
  double diff, l=0.0;
  int i;

  this->GetBounds();
  for (i=0; i<3; i++)
    {
    diff = this->Bounds[2*i+1] - this->Bounds[2*i];
    l += diff * diff;
    }

  return (float)sqrt(l);
}

void vtkVolumeMapper::SetRGBTextureInput( vtkStructuredPoints *rgbTexture )
{
  vtkPointData    *pd;
  vtkScalars      *scalars;

  if ( rgbTexture && rgbTexture != this->RGBTextureInput )
    {
    rgbTexture->Update();
    pd = rgbTexture->GetPointData();
    if ( !pd )
      {
      vtkErrorMacro( << "No PointData in texture!" );
      return;
      }
    scalars = pd->GetScalars();
    if ( !scalars )
      {
      vtkErrorMacro( << "No scalars in texture!" );
      return;
      }
    if ( scalars->GetDataType() != VTK_UNSIGNED_CHAR )
      {
      vtkErrorMacro( << "Scalars in texture must be unsigned char!" );
      return;
      }
    if ( scalars->GetNumberOfComponents() != 3 )
      {
      vtkErrorMacro( << "Scalars must have 3 components (r, g, and b)" );
      return;
      }
    this->RGBTextureInput = rgbTexture;
    this->Modified();
    }
}

// Print the vtkVolumeMapper
void vtkVolumeMapper::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkProcessObject::PrintSelf(os,indent);

  if ( this->ScalarInput )
    {
    os << indent << "ScalarInput: (" << this->ScalarInput << ")\n";
    }
  else
    {
    os << indent << "ScalarInput: (none)\n";
    }

  if ( this->RGBTextureInput )
    {
    os << indent << "RGBTextureInput: (" << this->RGBTextureInput << ")\n";
    }
  else
    {
    os << indent << "RGBTextureInput: (none)\n";
    }

  os << indent << "Clipping: " << (this->Clipping ? "On\n" : "Off\n");
  os << indent << "Build Time: " <<this->BuildTime.GetMTime() << "\n";
}

<|endoftext|>


<commit_before>// Copyright (c) 2014-2017 The Helium Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "governance-votedb.h"

CGovernanceObjectVoteFile::CGovernanceObjectVoteFile()
    : nMemoryVotes(0),
      listVotes(),
      mapVoteIndex()
{}

CGovernanceObjectVoteFile::CGovernanceObjectVoteFile(const CGovernanceObjectVoteFile& other)
    : nMemoryVotes(other.nMemoryVotes),
      listVotes(other.listVotes),
      mapVoteIndex()
{
    RebuildIndex();
}

void CGovernanceObjectVoteFile::AddVote(const CGovernanceVote& vote)
{
    listVotes.push_front(vote);
    mapVoteIndex[vote.GetHash()] = listVotes.begin();
    ++nMemoryVotes;
}

bool CGovernanceObjectVoteFile::HasVote(const uint256& nHash) const
{
    vote_m_cit it = mapVoteIndex.find(nHash);
    if(it == mapVoteIndex.end()) {
        return false;
    }
    return true;
}

bool CGovernanceObjectVoteFile::GetVote(const uint256& nHash, CGovernanceVote& vote) const
{
    vote_m_cit it = mapVoteIndex.find(nHash);
    if(it == mapVoteIndex.end()) {
        return false;
    }
    vote = *(it->second);
    return true;
}

std::vector<CGovernanceVote> CGovernanceObjectVoteFile::GetVotes() const
{
    std::vector<CGovernanceVote> vecResult;
    for(vote_l_cit it = listVotes.begin(); it != listVotes.end(); ++it) {
        vecResult.push_back(*it);
    }
    return vecResult;
}

void CGovernanceObjectVoteFile::RemoveVotesFromMasternode(const CTxIn& vinMasternode)
{
    vote_l_it it = listVotes.begin();
    while(it != listVotes.end()) {
        if(it->GetVinMasternode() == vinMasternode) {
            --nMemoryVotes;
            mapVoteIndex.erase(it->GetHash());
            listVotes.erase(it++);
        }
        else {
            ++it;
        }
    }
}

CGovernanceObjectVoteFile& CGovernanceObjectVoteFile::operator=(const CGovernanceObjectVoteFile& other)
{
    nMemoryVotes = other.nMemoryVotes;
    listVotes = other.listVotes;
    RebuildIndex();
    return *this;
}

void CGovernanceObjectVoteFile::RebuildIndex()
{
    mapVoteIndex.clear();
    nMemoryVotes = 0;
    vote_l_it it = listVotes.begin();
    while(it != listVotes.end()) {
        CGovernanceVote& vote = *it;
        uint256 nHash = vote.GetHash();
        if(mapVoteIndex.find(nHash) == mapVoteIndex.end()) {
            mapVoteIndex[nHash] = it;
            ++nMemoryVotes;
            ++it;
        }
        else {
            listVotes.erase(it++);
        }
    }
}
<commit_msg>Update governance-votedb.cpp<commit_after>// Copyright (c) 2014-2017 The Helium Core developers
// Copyright (c) 2014-2017 The DASH Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "governance-votedb.h"

CGovernanceObjectVoteFile::CGovernanceObjectVoteFile()
    : nMemoryVotes(0),
      listVotes(),
      mapVoteIndex()
{}

CGovernanceObjectVoteFile::CGovernanceObjectVoteFile(const CGovernanceObjectVoteFile& other)
    : nMemoryVotes(other.nMemoryVotes),
      listVotes(other.listVotes),
      mapVoteIndex()
{
    RebuildIndex();
}

void CGovernanceObjectVoteFile::AddVote(const CGovernanceVote& vote)
{
    listVotes.push_front(vote);
    mapVoteIndex[vote.GetHash()] = listVotes.begin();
    ++nMemoryVotes;
}

bool CGovernanceObjectVoteFile::HasVote(const uint256& nHash) const
{
    vote_m_cit it = mapVoteIndex.find(nHash);
    if(it == mapVoteIndex.end()) {
        return false;
    }
    return true;
}

bool CGovernanceObjectVoteFile::GetVote(const uint256& nHash, CGovernanceVote& vote) const
{
    vote_m_cit it = mapVoteIndex.find(nHash);
    if(it == mapVoteIndex.end()) {
        return false;
    }
    vote = *(it->second);
    return true;
}

std::vector<CGovernanceVote> CGovernanceObjectVoteFile::GetVotes() const
{
    std::vector<CGovernanceVote> vecResult;
    for(vote_l_cit it = listVotes.begin(); it != listVotes.end(); ++it) {
        vecResult.push_back(*it);
    }
    return vecResult;
}

void CGovernanceObjectVoteFile::RemoveVotesFromMasternode(const CTxIn& vinMasternode)
{
    vote_l_it it = listVotes.begin();
    while(it != listVotes.end()) {
        if(it->GetVinMasternode() == vinMasternode) {
            --nMemoryVotes;
            mapVoteIndex.erase(it->GetHash());
            listVotes.erase(it++);
        }
        else {
            ++it;
        }
    }
}

CGovernanceObjectVoteFile& CGovernanceObjectVoteFile::operator=(const CGovernanceObjectVoteFile& other)
{
    nMemoryVotes = other.nMemoryVotes;
    listVotes = other.listVotes;
    RebuildIndex();
    return *this;
}

void CGovernanceObjectVoteFile::RebuildIndex()
{
    mapVoteIndex.clear();
    nMemoryVotes = 0;
    vote_l_it it = listVotes.begin();
    while(it != listVotes.end()) {
        CGovernanceVote& vote = *it;
        uint256 nHash = vote.GetHash();
        if(mapVoteIndex.find(nHash) == mapVoteIndex.end()) {
            mapVoteIndex[nHash] = it;
            ++nMemoryVotes;
            ++it;
        }
        else {
            listVotes.erase(it++);
        }
    }
}
<|endoftext|>


<commit_before>/**
 * Kryvos File Encryptor - Encrypts and decrypts files.
 * Copyright (C) 2014 Andrew Dolby
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contact : andrewdolby@gmail.com
 */

#include "gui/FileListFrame.hpp"
#include "gui/Delegate.hpp"
#include "utility/make_unique.h"
#include <QtWidgets/QScroller>
#include <QtWidgets/QTableView>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QVBoxLayout>
#include <QtGui/QStandardItemModel>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtCore/QStringRef>
#include <QtCore/QStringBuilder>
#include <QtCore/QString>

class FileListFrame::FileListFramePrivate {
 public:
  /*!
   * \brief FileListFramePrivate Constructs the FileListFrame private
   * implementation.
   */
  explicit FileListFramePrivate();

  /*!
   * \brief addFileToModel Adds a file to the file list model.
   * \param filePath String containing the file path.
   */
  void addFileToModel(const QString& filePath);

  std::unique_ptr<QStandardItemModel> fileListModel;
  QTableView* fileListView;
};

FileListFrame::FileListFrame(QWidget* parent) :
  QFrame{parent}, pimpl{make_unique<FileListFramePrivate>()}
{
  // File list
  pimpl->fileListModel->setHeaderData(0, Qt::Horizontal, tr("Files"));
  pimpl->fileListModel->setHeaderData(1, Qt::Horizontal, tr("Progress"));
  pimpl->fileListModel->setHeaderData(2, Qt::Horizontal, tr("Remove file"));

  const QStringList headerList = {tr("Files"), tr("Progress"),
                                  tr("Remove file")};
  pimpl->fileListModel->setHorizontalHeaderLabels(headerList);

  pimpl->fileListView = new QTableView{this};
  pimpl->fileListView->setModel(pimpl->fileListModel.get());

  QHeaderView* header = pimpl->fileListView->horizontalHeader();
  header->setStretchLastSection(false);
  header->hide();

  pimpl->fileListView->verticalHeader()->hide();
  pimpl->fileListView->setShowGrid(false);

  // Custom delegate paints progress bar and file close button for each file
  auto delegate = new Delegate{this};
  pimpl->fileListView->setItemDelegate(delegate);

  pimpl->fileListView->setHorizontalScrollMode(QAbstractItemView::
                                                ScrollPerPixel);

  // Attach a scroller to the file list
  QScroller::grabGesture(pimpl->fileListView,
                         QScroller::TouchGesture);

  // Disable overshoot; it makes interacting with small widgets harder
  QScroller* scroller = QScroller::scroller(pimpl->fileListView);

  QScrollerProperties properties = scroller->scrollerProperties();

  QVariant overshootPolicy = QVariant::fromValue
                              <QScrollerProperties::OvershootPolicy>
                              (QScrollerProperties::OvershootAlwaysOff);

  properties.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy,
                             overshootPolicy);
  properties.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy,
                             overshootPolicy);

  scroller->setScrollerProperties(properties);

  auto fileListLayout = new QVBoxLayout{this};
  fileListLayout->addWidget(pimpl->fileListView);
  fileListLayout->setContentsMargins(0, 0, 0, 0);
  fileListLayout->setSpacing(0);

  connect(delegate, &Delegate::removeRow,
          this, &FileListFrame::removeFileFromModel);
}

FileListFrame::~FileListFrame() {}

QStandardItem* FileListFrame::item(int row) const
{
  Q_ASSERT(pimpl);
  Q_ASSERT(pimpl->fileListModel);

  return pimpl->fileListModel->item(row, 0);
}

int FileListFrame::rowCount() const
{
  Q_ASSERT(pimpl);
  Q_ASSERT(pimpl->fileListModel);

  return pimpl->fileListModel->rowCount();
}

void FileListFrame::clear()
{
  Q_ASSERT(pimpl);
  Q_ASSERT(pimpl->fileListModel);

  pimpl->fileListModel->clear();
}

void FileListFrame::addFileToModel(const QString& path)
{
  QFileInfo file{path};
  QDir directory{file.dir()};

  if (file.exists() && file.isFile())
  { // If the file exists, add it to the model
    QString fileName;
    if (directory.isRoot())
    {
      fileName = file.absoluteFilePath();
    }
    else
    {
      fileName = directory.rootPath() % QLatin1String{"..."} %
                 "/" % directory.dirName() % "/" % file.fileName();
    }

    auto pathItem = new QStandardItem{fileName};
    pathItem->setDragEnabled(false);
    pathItem->setDropEnabled(false);
    pathItem->setEditable(false);
    pathItem->setSelectable(false);
    pathItem->setToolTip(path);
    QVariant pathVariant = QVariant::fromValue(path);
    pathItem->setData(pathVariant);

    auto progressItem = new QStandardItem{};
    progressItem->setDragEnabled(false);
    progressItem->setDropEnabled(false);
    progressItem->setEditable(false);
    progressItem->setSelectable(false);

    auto closeFileItem = new QStandardItem{};
    closeFileItem->setDragEnabled(false);
    closeFileItem->setDropEnabled(false);
    closeFileItem->setEditable(false);
    closeFileItem->setSelectable(false);

    const QList<QStandardItem*> items = {pathItem, progressItem, closeFileItem};

    // Search to see if this item is already in the model
    auto addNewItem = true;

    const auto rowCount = pimpl->fileListModel->rowCount();
    for (auto row = 0; row < rowCount; ++row)
    {
      auto testItem = pimpl->fileListModel->item(row, 0);

      if (testItem->data().toString() == pathItem->data().toString())
      {
        addNewItem = false;
      }
    }

    if (addNewItem)
    { // Add the item to the model if it's new
      pimpl->fileListModel->appendRow(items);
      QHeaderView* header = pimpl->fileListView->horizontalHeader();
      header->setSectionResizeMode(0, QHeaderView::ResizeToContents);
      header->setResizeContentsPrecision(0);
      header->resizeSection(1, 130);
    }
  } // End if file exists and is a file
}

void FileListFrame::removeFileFromModel(const QModelIndex& index)
{
  Q_ASSERT(pimpl);
  Q_ASSERT(pimpl->fileListModel);

  auto testItem = pimpl->fileListModel->item(index.row(), 0);

  // Signal that this file shouldn't be encrypted or decrypted
  emit stopFile(testItem->data().toString());

  // Remove row from model
  pimpl->fileListModel->removeRow(index.row());
}

void FileListFrame::updateProgress(const QString& path, qint64 percent)
{
  Q_ASSERT(pimpl);
  Q_ASSERT(pimpl->fileListModel);

  QFileInfo file{path};
  QDir directory{file.dir()};

  QString fileName;

  if (directory.isRoot())
  {
    fileName = file.absoluteFilePath();
  }
  else
  {
    fileName = directory.rootPath() % QLatin1String{"..."} %
               "/" % directory.dirName() % "/" % file.fileName();
  }

  const QList<QStandardItem*> items = pimpl->fileListModel->findItems(fileName);

  if (items.size() > 0)
  {
    auto item = items[0];

    if (item != nullptr)
    {
      const auto index = item->row();

      auto progressItem = pimpl->fileListModel->item(index, 1);

      if (progressItem != nullptr)
      {
        progressItem->setData(percent, Qt::DisplayRole);
      }
    }
  }
}

FileListFrame::FileListFramePrivate::FileListFramePrivate() :
  fileListModel{make_unique<QStandardItemModel>()}, fileListView{nullptr}
{}
<commit_msg>Improve FileListFrame<commit_after>/**
 * Kryvos File Encryptor - Encrypts and decrypts files.
 * Copyright (C) 2014 Andrew Dolby
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contact : andrewdolby@gmail.com
 */

#include "gui/FileListFrame.hpp"
#include "gui/Delegate.hpp"
#include "utility/make_unique.h"
#include <QtWidgets/QScroller>
#include <QtWidgets/QTableView>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QVBoxLayout>
#include <QtGui/QStandardItemModel>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtCore/QStringRef>
#include <QtCore/QStringBuilder>
#include <QtCore/QString>

class FileListFrame::FileListFramePrivate {
 public:
  /*!
   * \brief FileListFramePrivate Constructs the FileListFrame private
   * implementation.
   */
  explicit FileListFramePrivate();

  /*!
   * \brief addFileToModel Adds a file to the file list model.
   * \param filePath String containing the file path.
   */
  void addFileToModel(const QString& filePath);

  std::unique_ptr<QStandardItemModel> fileListModel;
  QTableView* fileListView;
};

FileListFrame::FileListFrame(QWidget* parent) :
  QFrame{parent}, pimpl{make_unique<FileListFramePrivate>()}
{
  // File list header
  const QStringList headerList = {tr("Files"), tr("Progress"),
                                  tr("Remove file")};
  pimpl->fileListModel->setHorizontalHeaderLabels(headerList);

  pimpl->fileListView = new QTableView{this};
  pimpl->fileListView->setModel(pimpl->fileListModel.get());

  QHeaderView* header = pimpl->fileListView->horizontalHeader();
  header->setStretchLastSection(false);
  header->hide();

  pimpl->fileListView->verticalHeader()->hide();
  pimpl->fileListView->setShowGrid(false);

  // Custom delegate paints progress bar and file close button for each file
  auto delegate = new Delegate{this};
  pimpl->fileListView->setItemDelegate(delegate);

  pimpl->fileListView->setHorizontalScrollMode(QAbstractItemView::
                                                ScrollPerPixel);

  // Attach a scroller to the file list
  QScroller::grabGesture(pimpl->fileListView,
                         QScroller::TouchGesture);

  // Disable overshoot; it makes interacting with small widgets harder
  auto scroller = QScroller::scroller(pimpl->fileListView);

  QScrollerProperties properties = scroller->scrollerProperties();

  QVariant overshootPolicy = QVariant::fromValue
                              <QScrollerProperties::OvershootPolicy>
                              (QScrollerProperties::OvershootAlwaysOff);

  properties.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy,
                             overshootPolicy);
  properties.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy,
                             overshootPolicy);

  scroller->setScrollerProperties(properties);

  auto fileListLayout = new QVBoxLayout{this};
  fileListLayout->addWidget(pimpl->fileListView);
  fileListLayout->setContentsMargins(0, 0, 0, 0);
  fileListLayout->setSpacing(0);

  connect(delegate, &Delegate::removeRow,
          this, &FileListFrame::removeFileFromModel);
}

FileListFrame::~FileListFrame() {}

QStandardItem* FileListFrame::item(int row) const
{
  Q_ASSERT(pimpl);
  Q_ASSERT(pimpl->fileListModel);

  return pimpl->fileListModel->item(row, 0);
}

int FileListFrame::rowCount() const
{
  Q_ASSERT(pimpl);
  Q_ASSERT(pimpl->fileListModel);

  return pimpl->fileListModel->rowCount();
}

void FileListFrame::clear()
{
  Q_ASSERT(pimpl);
  Q_ASSERT(pimpl->fileListModel);

  pimpl->fileListModel->clear();
}

void FileListFrame::addFileToModel(const QString& path)
{
  QFileInfo fileInfo{path};
  QDir directory{fileInfo.dir()};

  if (fileInfo.exists() && fileInfo.isFile())
  { // If the file exists, add it to the model
    QString fileName;

    if (directory.isRoot())
    {
      fileName = fileInfo.absoluteFilePath();
    }
    else
    {
      fileName = directory.rootPath() % QLatin1String{"..."} %
                 QLatin1String{"/"} % directory.dirName() % QLatin1String{"/"} %
                 fileInfo.fileName();
    }

    auto pathItem = new QStandardItem{fileName};
    pathItem->setDragEnabled(false);
    pathItem->setDropEnabled(false);
    pathItem->setEditable(false);
    pathItem->setSelectable(false);
    pathItem->setToolTip(path);
    QVariant pathVariant = QVariant::fromValue(path);
    pathItem->setData(pathVariant);

    auto progressItem = new QStandardItem{};
    progressItem->setDragEnabled(false);
    progressItem->setDropEnabled(false);
    progressItem->setEditable(false);
    progressItem->setSelectable(false);

    auto closeFileItem = new QStandardItem{};
    closeFileItem->setDragEnabled(false);
    closeFileItem->setDropEnabled(false);
    closeFileItem->setEditable(false);
    closeFileItem->setSelectable(false);

    const QList<QStandardItem*> items = {pathItem, progressItem, closeFileItem};

    // Search to see if this item is already in the model
    auto addNewItem = true;

    const auto rowCount = pimpl->fileListModel->rowCount();
    for (auto row = 0; row < rowCount; ++row)
    {
      auto testItem = pimpl->fileListModel->item(row, 0);

      if (testItem->data().toString() == pathItem->data().toString())
      {
        addNewItem = false;
      }
    }

    if (addNewItem)
    { // Add the item to the model if it's new
      pimpl->fileListModel->appendRow(items);
      QHeaderView* header = pimpl->fileListView->horizontalHeader();
      header->setSectionResizeMode(0, QHeaderView::ResizeToContents);
      header->setResizeContentsPrecision(0);
      header->resizeSection(1, 130);
    }
  } // End if file exists and is a file
}

void FileListFrame::removeFileFromModel(const QModelIndex& index)
{
  Q_ASSERT(pimpl);
  Q_ASSERT(pimpl->fileListModel);

  auto testItem = pimpl->fileListModel->item(index.row(), 0);

  // Signal that this file shouldn't be encrypted or decrypted
  emit stopFile(testItem->data().toString());

  // Remove row from model
  pimpl->fileListModel->removeRow(index.row());
}

void FileListFrame::updateProgress(const QString& path, qint64 percent)
{
  Q_ASSERT(pimpl);
  Q_ASSERT(pimpl->fileListModel);

  QFileInfo fileInfo{path};
  QDir directory{fileInfo.dir()};

  QString fileName;

  if (directory.isRoot())
  {
    fileName = fileInfo.absoluteFilePath();
  }
  else
  {
    fileName = directory.rootPath() % QLatin1String{"..."} %
               QLatin1String{"/"} % directory.dirName() % QLatin1String{"/"} %
               fileInfo.fileName();
  }

  const auto items = pimpl->fileListModel->findItems(fileName);

  if (items.size() > 0)
  {
    auto item = items[0];

    if (item != nullptr)
    {
      const auto index = item->row();

      auto progressItem = pimpl->fileListModel->item(index, 1);

      if (progressItem != nullptr)
      {
        progressItem->setData(percent, Qt::DisplayRole);
      }
    }
  }
}

FileListFrame::FileListFramePrivate::FileListFramePrivate() :
  fileListModel{make_unique<QStandardItemModel>()}, fileListView{nullptr}
{}
<|endoftext|>


<commit_before>#ifndef AMGCL_ADAPTER_EPETRA_HPP
#define AMGCL_ADAPTER_EPETRA_HPP

/*
The MIT License

Copyright (c) 2012-2014 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
\file    amgcl/adapter/epetra.hpp
\author  Denis Demidov <dennis.demidov@gmail.com>
\brief   Adapt Epetra_CrsMatrix from Trilinos.
\ingroup adapters
*/

#include <vector>

#include <Epetra_CrsMatrix.h>
#include <Epetra_Vector.h>
#include <Epetra_Import.h>

#include <amgcl/backend/interface.hpp>

namespace amgcl {
namespace backend {

/// Adapts Epetra_CrsMatrix
class epetra_map {
    public:
        epetra_map(const Epetra_CrsMatrix &A)
            : A(A), order(A.ColMap())
        {
            const Epetra_Map& row_map = A.RowMap();
            const Epetra_Map& col_map = A.ColMap();

            double entries_before;
            double local_entries = row_map.NumMyElements();
            A.Comm().ScanSum(&local_entries, &entries_before, 1);
            entries_before -= local_entries;

            Epetra_Vector perm(row_map);
            for(int i = 0, j = entries_before; i < local_entries; ++i, ++j)
                perm[i] = j;

            Epetra_Import importer = Epetra_Import(col_map, row_map);

            order.Import(perm, importer, Insert);
        }

        size_t rows() const {
            return A.NumMyRows();
        }

        size_t cols() const {
            return A.NumGlobalCols();
        }

        size_t nonzeros() const {
            return A.NumMyNonzeros();
        }

        class row_iterator {
            public:
                typedef int    col_type;
                typedef double val_type;

                row_iterator(
                        const Epetra_CrsMatrix &A,
                        const Epetra_Vector    &order,
                        int row
                        ) : A(A), order(order)
                {
                    int nnz;
                    A.ExtractMyRowView(row, nnz, m_val, m_col);
                    m_end = m_col + nnz;
                }

                operator bool() const {
                    return m_col != m_end;
                }

                row_iterator& operator++() {
                    ++m_col;
                    ++m_val;
                    return *this;
                }

                col_type col() const {
                    return order[*m_col];
                }

                val_type value() const {
                    return *m_val;
                }

            private:
                const Epetra_CrsMatrix &A;
                const Epetra_Vector    ℴ

                col_type * m_col;
                col_type * m_end;
                val_type * m_val;
        };

        row_iterator row_begin(int row) const {
            return row_iterator(A, order, row);
        }
    private:
        const Epetra_CrsMatrix &A;
        Epetra_Vector order;
};

/// Adapts Epetra_CrsMatrix
inline epetra_map map(const Epetra_CrsMatrix &A) {
    return epetra_map(A);
}

//---------------------------------------------------------------------------
// Specialization of matrix interface
//---------------------------------------------------------------------------
template <>
struct value_type < epetra_map > {
    typedef double type;
};

template <>
struct rows_impl < epetra_map > {
    static size_t get(const epetra_map &A) {
        return A.rows();
    }
};

template <>
struct cols_impl < epetra_map > {
    static size_t get(const epetra_map &A) {
        return A.cols();
    }
};

template <>
struct nonzeros_impl < epetra_map > {
    static size_t get(const epetra_map &A) {
        return A.nonzeros();
    }
};

template <>
struct row_iterator < epetra_map > {
    typedef epetra_map::row_iterator type;
};

template <>
struct row_begin_impl< epetra_map >
{
    static typename row_iterator< epetra_map >::type
    get(const epetra_map &A, size_t row) {
        return A.row_begin(row);
    }
};

} // namespace backend
} // namespace amgcl

#endif
<commit_msg>No need to keep reference to matrix in epetra_map::row_iterator<commit_after>#ifndef AMGCL_ADAPTER_EPETRA_HPP
#define AMGCL_ADAPTER_EPETRA_HPP

/*
The MIT License

Copyright (c) 2012-2014 Denis Demidov <dennis.demidov@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
\file    amgcl/adapter/epetra.hpp
\author  Denis Demidov <dennis.demidov@gmail.com>
\brief   Adapt Epetra_CrsMatrix from Trilinos.
\ingroup adapters
*/

#include <vector>

#include <Epetra_CrsMatrix.h>
#include <Epetra_Vector.h>
#include <Epetra_Import.h>

#include <amgcl/backend/interface.hpp>

namespace amgcl {
namespace backend {

/// Adapts Epetra_CrsMatrix
class epetra_map {
    public:
        epetra_map(const Epetra_CrsMatrix &A)
            : A(A), order(A.ColMap())
        {
            const Epetra_Map& row_map = A.RowMap();
            const Epetra_Map& col_map = A.ColMap();

            double entries_before;
            double local_entries = row_map.NumMyElements();
            A.Comm().ScanSum(&local_entries, &entries_before, 1);
            entries_before -= local_entries;

            Epetra_Vector perm(row_map);
            for(int i = 0, j = entries_before; i < local_entries; ++i, ++j)
                perm[i] = j;

            Epetra_Import importer = Epetra_Import(col_map, row_map);

            order.Import(perm, importer, Insert);
        }

        size_t rows() const {
            return A.NumMyRows();
        }

        size_t cols() const {
            return A.NumGlobalCols();
        }

        size_t nonzeros() const {
            return A.NumMyNonzeros();
        }

        class row_iterator {
            public:
                typedef int    col_type;
                typedef double val_type;

                row_iterator(
                        const Epetra_CrsMatrix &A,
                        const Epetra_Vector    &order,
                        int row
                        ) : order(order)
                {
                    int nnz;
                    A.ExtractMyRowView(row, nnz, m_val, m_col);
                    m_end = m_col + nnz;
                }

                operator bool() const {
                    return m_col != m_end;
                }

                row_iterator& operator++() {
                    ++m_col;
                    ++m_val;
                    return *this;
                }

                col_type col() const {
                    return order[*m_col];
                }

                val_type value() const {
                    return *m_val;
                }

            private:
                const Epetra_Vector ℴ

                col_type * m_col;
                col_type * m_end;
                val_type * m_val;
        };

        row_iterator row_begin(int row) const {
            return row_iterator(A, order, row);
        }
    private:
        const Epetra_CrsMatrix &A;
        Epetra_Vector order;
};

/// Adapts Epetra_CrsMatrix
inline epetra_map map(const Epetra_CrsMatrix &A) {
    return epetra_map(A);
}

//---------------------------------------------------------------------------
// Specialization of matrix interface
//---------------------------------------------------------------------------
template <>
struct value_type < epetra_map > {
    typedef double type;
};

template <>
struct rows_impl < epetra_map > {
    static size_t get(const epetra_map &A) {
        return A.rows();
    }
};

template <>
struct cols_impl < epetra_map > {
    static size_t get(const epetra_map &A) {
        return A.cols();
    }
};

template <>
struct nonzeros_impl < epetra_map > {
    static size_t get(const epetra_map &A) {
        return A.nonzeros();
    }
};

template <>
struct row_iterator < epetra_map > {
    typedef epetra_map::row_iterator type;
};

template <>
struct row_begin_impl< epetra_map >
{
    static typename row_iterator< epetra_map >::type
    get(const epetra_map &A, size_t row) {
        return A.row_begin(row);
    }
};

} // namespace backend
} // namespace amgcl

#endif
<|endoftext|>


<commit_before>/*
 * Author: Brendan Le Foll <brendan.le.foll@intel.com>
 * Copyright (c) 2014 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "math.h"
#include "hmc5883l.h"

#define MAX_BUFFER_LENGTH 6
#define HMC5883L_I2C_ADDR 0x1E

//configuration registers
#define HMC5883L_CONF_REG_A 0x00
#define HMC5883L_CONF_REG_B 0x01

//mode register
#define HMC5883L_MODE_REG 0x02

//data register
#define HMC5883L_X_MSB_REG 0
#define HMC5883L_X_LSB_REG 1
#define HMC5883L_Z_MSB_REG 2
#define HMC5883L_Z_LSB_REG 3
#define HMC5883L_Y_MSB_REG 4
#define HMC5883L_Y_LSB_REG 5
#define DATA_REG_SIZE 6

//status register
#define HMC5883L_STATUS_REG 0x09

//ID registers
#define HMC5883L_ID_A_REG 0x0A
#define HMC5883L_ID_B_REG 0x0B
#define HMC5883L_ID_C_REG 0x0C

#define HMC5883L_CONT_MODE 0x00
#define HMC5883L_DATA_REG 0x03

//scales
#define GA_0_88_REG 0x00 << 5
#define GA_1_3_REG 0x01 << 5
#define GA_1_9_REG 0x02 << 5
#define GA_2_5_REG 0x03 << 5
#define GA_4_0_REG 0x04 << 5
#define GA_4_7_REG 0x05 << 5
#define GA_5_6_REG 0x06 << 5
#define GA_8_1_REG 0x07 << 5

//digital resolutions
#define SCALE_0_73_MG 0.73
#define SCALE_0_92_MG 0.92
#define SCALE_1_22_MG 1.22
#define SCALE_1_52_MG 1.52
#define SCALE_2_27_MG 2.27
#define SCALE_2_56_MG 2.56
#define SCALE_3_03_MG 3.03
#define SCALE_4_35_MG 4.35

using namespace upm;

Hmc5883l::Hmc5883l(int bus)
{
    m_i2c = mraa_i2c_init(bus);

    mraa_i2c_address(m_i2c, HMC5883L_I2C_ADDR);
    m_rx_tx_buf[0] = HMC5883L_CONF_REG_B;
    m_rx_tx_buf[1] = GA_1_3_REG;
    mraa_i2c_write(m_i2c, m_rx_tx_buf, 2);

    mraa_i2c_address(m_i2c, HMC5883L_I2C_ADDR);
    m_rx_tx_buf[0] = HMC5883L_MODE_REG;
    m_rx_tx_buf[1] = HMC5883L_CONT_MODE;
    mraa_i2c_write(m_i2c, m_rx_tx_buf, 2);

    Hmc5883l::update();
}

int
Hmc5883l::update(void)
{
    mraa_i2c_address(m_i2c, HMC5883L_I2C_ADDR);
    mraa_i2c_write_byte(m_i2c, HMC5883L_DATA_REG);

    mraa_i2c_address(m_i2c, HMC5883L_I2C_ADDR);
    mraa_i2c_read(m_i2c, m_rx_tx_buf, DATA_REG_SIZE);

    // x
    m_coor[0] = (m_rx_tx_buf[HMC5883L_X_MSB_REG] << 8 ) | m_rx_tx_buf[HMC5883L_X_LSB_REG];
    // z
    m_coor[2] = (m_rx_tx_buf[HMC5883L_Z_MSB_REG] << 8 ) | m_rx_tx_buf[HMC5883L_Z_LSB_REG];
    // y
    m_coor[1] = (m_rx_tx_buf[HMC5883L_Y_MSB_REG] << 8 ) | m_rx_tx_buf[HMC5883L_Y_LSB_REG];

    return MRAA_SUCCESS;
}

float
Hmc5883l::direction(void)
{
    return atan2(m_coor[1] * SCALE_0_92_MG, m_coor[0] * SCALE_0_92_MG);
}

float
Hmc5883l::heading(void)
{
    return Hmc5883l::direction() * 180/M_PI;
}

int*
Hmc5883l::coordinates(void)
{
    return &m_coor[0];
}
<commit_msg>hmc5883l: fixed type cast in update()<commit_after>/*
 * Author: Brendan Le Foll <brendan.le.foll@intel.com>
 * Copyright (c) 2014 Intel Corporation.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "math.h"
#include "hmc5883l.h"

#define MAX_BUFFER_LENGTH 6
#define HMC5883L_I2C_ADDR 0x1E

//configuration registers
#define HMC5883L_CONF_REG_A 0x00
#define HMC5883L_CONF_REG_B 0x01

//mode register
#define HMC5883L_MODE_REG 0x02

//data register
#define HMC5883L_X_MSB_REG 0
#define HMC5883L_X_LSB_REG 1
#define HMC5883L_Z_MSB_REG 2
#define HMC5883L_Z_LSB_REG 3
#define HMC5883L_Y_MSB_REG 4
#define HMC5883L_Y_LSB_REG 5
#define DATA_REG_SIZE 6

//status register
#define HMC5883L_STATUS_REG 0x09

//ID registers
#define HMC5883L_ID_A_REG 0x0A
#define HMC5883L_ID_B_REG 0x0B
#define HMC5883L_ID_C_REG 0x0C

#define HMC5883L_CONT_MODE 0x00
#define HMC5883L_DATA_REG 0x03

//scales
#define GA_0_88_REG 0x00 << 5
#define GA_1_3_REG 0x01 << 5
#define GA_1_9_REG 0x02 << 5
#define GA_2_5_REG 0x03 << 5
#define GA_4_0_REG 0x04 << 5
#define GA_4_7_REG 0x05 << 5
#define GA_5_6_REG 0x06 << 5
#define GA_8_1_REG 0x07 << 5

//digital resolutions
#define SCALE_0_73_MG 0.73
#define SCALE_0_92_MG 0.92
#define SCALE_1_22_MG 1.22
#define SCALE_1_52_MG 1.52
#define SCALE_2_27_MG 2.27
#define SCALE_2_56_MG 2.56
#define SCALE_3_03_MG 3.03
#define SCALE_4_35_MG 4.35

using namespace upm;

Hmc5883l::Hmc5883l(int bus)
{
    m_i2c = mraa_i2c_init(bus);

    mraa_i2c_address(m_i2c, HMC5883L_I2C_ADDR);
    m_rx_tx_buf[0] = HMC5883L_CONF_REG_B;
    m_rx_tx_buf[1] = GA_1_3_REG;
    mraa_i2c_write(m_i2c, m_rx_tx_buf, 2);

    mraa_i2c_address(m_i2c, HMC5883L_I2C_ADDR);
    m_rx_tx_buf[0] = HMC5883L_MODE_REG;
    m_rx_tx_buf[1] = HMC5883L_CONT_MODE;
    mraa_i2c_write(m_i2c, m_rx_tx_buf, 2);

    Hmc5883l::update();
}

int
Hmc5883l::update(void)
{
    mraa_i2c_address(m_i2c, HMC5883L_I2C_ADDR);
    mraa_i2c_write_byte(m_i2c, HMC5883L_DATA_REG);

    mraa_i2c_address(m_i2c, HMC5883L_I2C_ADDR);
    mraa_i2c_read(m_i2c, m_rx_tx_buf, DATA_REG_SIZE);

    // x
    m_coor[0] = (int16_t)((m_rx_tx_buf[HMC5883L_X_MSB_REG] << 8 ) | m_rx_tx_buf[HMC5883L_X_LSB_REG]);
    // z
    m_coor[2] = (int16_t)((m_rx_tx_buf[HMC5883L_Z_MSB_REG] << 8 ) | m_rx_tx_buf[HMC5883L_Z_LSB_REG]);
    // y
    m_coor[1] = (int16_t)((m_rx_tx_buf[HMC5883L_Y_MSB_REG] << 8 ) | m_rx_tx_buf[HMC5883L_Y_LSB_REG]);

    return MRAA_SUCCESS;
}

float
Hmc5883l::direction(void)
{
    return atan2(m_coor[1] * SCALE_0_92_MG, m_coor[0] * SCALE_0_92_MG);
}

float
Hmc5883l::heading(void)
{
    return Hmc5883l::direction() * 180/M_PI;
}

int*
Hmc5883l::coordinates(void)
{
    return &m_coor[0];
}
<|endoftext|>


<commit_before>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include <iostream>
#include <vector>

#include "tensorflow/cc/framework/grad_op_registry.h"
#include "tensorflow/cc/framework/gradients.h"
#include "tensorflow/cc/ops/functional_ops.h"

namespace tensorflow {
namespace ops {
namespace {

Status PartitionedCallGrad(const Scope& scope, const Operation& op,
                           const std::vector<Output>& grad_inputs,
                           std::vector<Output>* grad_outputs) {
  NameAttrList f;
  TF_RETURN_IF_ERROR(GetNodeAttr(op.node()->attrs(), "f", &f));
  for (const auto& attr : op.node()->attrs()) {
    (*f.mutable_attr())[attr.first] = attr.second;
  }

  std::vector<Output> func_inputs;
  std::vector<DataType> input_dtypes;

  for (int32_t i = 0; i < op.num_inputs(); i++) {
    func_inputs.push_back(op.input(i));
    input_dtypes.push_back(op.input_type(i));
  }

  func_inputs.insert(std::end(func_inputs), std::begin(grad_inputs),
                     std::end(grad_inputs));

  auto grad = SymbolicGradient(scope, func_inputs, input_dtypes, f);
  for (int32_t i = 0; i < op.num_inputs(); i++) {
    grad_outputs->push_back(grad[i]);
  }

  return scope.status();
}

REGISTER_GRADIENT_OP("PartitionedCall", PartitionedCallGrad);
REGISTER_GRADIENT_OP("StatefulPartitionedCall", PartitionedCallGrad);

}  // anonymous namespace
}  // namespace ops
}  // namespace tensorflow
<commit_msg>[tensorflow/cc/gradients/functional_grad.cc] Add calls to `reserve()` before populating vectors<commit_after>/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include <iostream>
#include <vector>

#include "tensorflow/cc/framework/grad_op_registry.h"
#include "tensorflow/cc/framework/gradients.h"
#include "tensorflow/cc/ops/functional_ops.h"

namespace tensorflow {
namespace ops {
namespace {

Status PartitionedCallGrad(const Scope& scope, const Operation& op,
                           const std::vector<Output>& grad_inputs,
                           std::vector<Output>* grad_outputs) {
  NameAttrList f;
  TF_RETURN_IF_ERROR(GetNodeAttr(op.node()->attrs(), "f", &f));
  for (const auto& attr : op.node()->attrs()) {
    (*f.mutable_attr())[attr.first] = attr.second;
  }

  std::vector<Output> func_inputs;
  std::vector<DataType> input_dtypes;
  const auto num_inputs = op.num_inputs();
  func_inputs.reserve(num_inputs);
  input_dtypes.reserve(num_inputs);

  for (int32_t i = 0; i < num_inputs; i++) {
    func_inputs.push_back(op.input(i));
    input_dtypes.push_back(op.input_type(i));
  }

  func_inputs.insert(std::end(func_inputs), std::begin(grad_inputs),
                     std::end(grad_inputs));

  auto grad = SymbolicGradient(scope, func_inputs, input_dtypes, f);
  for (int32_t i = 0; i < op.num_inputs(); i++) {
    grad_outputs->push_back(grad[i]);
  }

  return scope.status();
}

REGISTER_GRADIENT_OP("PartitionedCall", PartitionedCallGrad);
REGISTER_GRADIENT_OP("StatefulPartitionedCall", PartitionedCallGrad);

}  // anonymous namespace
}  // namespace ops
}  // namespace tensorflow
<|endoftext|>


<commit_before>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/cc/training/coordinator.h"

#include "tensorflow/cc/training/queue_runner.h"
#include "tensorflow/core/lib/core/blocking_counter.h"
#include "tensorflow/core/lib/core/error_codes.pb.h"
#include "tensorflow/core/lib/core/notification.h"
#include "tensorflow/core/lib/core/status_test_util.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/test.h"
#include "tensorflow/core/public/session.h"

namespace tensorflow {
namespace {

using error::Code;

void WaitForStopThread(Coordinator* coord, bool* stopped, Notification* done) {
  coord->WaitForStop();
  *stopped = true;
  done->Notify();
}

TEST(CoordinatorTest, TestStopAndWaitOnStop) {
  Coordinator coord;
  EXPECT_EQ(coord.ShouldStop(), false);

  bool stopped = false;
  Notification done;
  Env::Default()->SchedClosure(
      std::bind(&WaitForStopThread, &coord, &stopped, &done));
  Env::Default()->SleepForMicroseconds(10000000);
  EXPECT_EQ(stopped, false);

  TF_EXPECT_OK(coord.RequestStop());
  done.WaitForNotification();
  EXPECT_EQ(stopped, true);
  EXPECT_EQ(coord.ShouldStop(), true);
}

class MockQueueRunner : public RunnerInterface {
 public:
  MockQueueRunner(Coordinator* coord) {
    coord_ = coord;
    join_counter_ = nullptr;
    thread_pool_.reset(new thread::ThreadPool(Env::Default(), "test-pool", 10));
    stopped_ = false;
  }

  MockQueueRunner(Coordinator* coord, int* join_counter)
      : MockQueueRunner(coord) {
    join_counter_ = join_counter;
  }

  void StartCounting(std::atomic<int>* counter, int until) {
    thread_pool_->Schedule(
        std::bind(&MockQueueRunner::CountThread, this, counter, until));
  }

  void StartSettingStatus(const Status& status, BlockingCounter* counter) {
    thread_pool_->Schedule(
        std::bind(&MockQueueRunner::SetStatusThread, this, status, counter));
  }

  Status Join() {
    if (join_counter_ != nullptr) {
      (*join_counter_)++;
    }
    thread_pool_.reset();
    return status_;
  }

  Status GetStatus() { return status_; }

  void SetStatus(const Status& status) { status_ = status; }

  bool IsRunning() const override { return !stopped_; };

  void Stop() { stopped_ = true; }

 private:
  void CountThread(std::atomic<int>* counter, int until) {
    while (!coord_->ShouldStop() && counter->load() < until) {
      (*counter)++;
      Env::Default()->SleepForMicroseconds(100000);
    }
    coord_->RequestStop().IgnoreError();
  }
  void SetStatusThread(const Status& status, BlockingCounter* counter) {
    Env::Default()->SleepForMicroseconds(100000);
    SetStatus(status);
    counter->DecrementCount();
  }
  std::unique_ptr<thread::ThreadPool> thread_pool_;
  Status status_;
  Coordinator* coord_;
  int* join_counter_;
  bool stopped_;
};

TEST(CoordinatorTest, TestRealStop) {
  std::atomic<int> counter(0);
  Coordinator coord;

  std::unique_ptr<MockQueueRunner> qr1(new MockQueueRunner(&coord));
  qr1->StartCounting(&counter, 100);
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr1)));

  std::unique_ptr<MockQueueRunner> qr2(new MockQueueRunner(&coord));
  qr2->StartCounting(&counter, 100);
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr2)));

  // Wait until the counting has started
  while (counter.load() == 0)
    ;
  TF_EXPECT_OK(coord.RequestStop());

  int temp_counter = counter.load();
  Env::Default()->SleepForMicroseconds(10000000);
  EXPECT_EQ(temp_counter, counter.load());
  TF_EXPECT_OK(coord.Join());
}

TEST(CoordinatorTest, TestRequestStop) {
  Coordinator coord;
  std::atomic<int> counter(0);
  std::unique_ptr<MockQueueRunner> qr;
  for (int i = 0; i < 10; i++) {
    qr.reset(new MockQueueRunner(&coord));
    qr->StartCounting(&counter, 10);
    TF_ASSERT_OK(coord.RegisterRunner(std::move(qr)));
  }

  coord.WaitForStop();
  EXPECT_EQ(coord.ShouldStop(), true);
  EXPECT_EQ(counter.load(), 10);
  TF_EXPECT_OK(coord.Join());
}

TEST(CoordinatorTest, TestJoin) {
  Coordinator coord;
  int join_counter = 0;
  std::unique_ptr<MockQueueRunner> qr1(
      new MockQueueRunner(&coord, &join_counter));
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr1)));
  std::unique_ptr<MockQueueRunner> qr2(
      new MockQueueRunner(&coord, &join_counter));
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr2)));

  TF_EXPECT_OK(coord.RequestStop());
  TF_EXPECT_OK(coord.Join());
  EXPECT_EQ(join_counter, 2);
}

TEST(CoordinatorTest, StatusReporting) {
  Coordinator coord({Code::CANCELLED, Code::OUT_OF_RANGE});
  BlockingCounter counter(3);

  std::unique_ptr<MockQueueRunner> qr1(new MockQueueRunner(&coord));
  qr1->StartSettingStatus(Status(Code::CANCELLED, ""), &counter);
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr1)));

  std::unique_ptr<MockQueueRunner> qr2(new MockQueueRunner(&coord));
  qr2->StartSettingStatus(Status(Code::INVALID_ARGUMENT, ""), &counter);
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr2)));

  std::unique_ptr<MockQueueRunner> qr3(new MockQueueRunner(&coord));
  qr3->StartSettingStatus(Status(Code::OUT_OF_RANGE, ""), &counter);
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr3)));

  counter.Wait();
  TF_EXPECT_OK(coord.RequestStop());
  EXPECT_EQ(coord.Join().code(), Code::INVALID_ARGUMENT);
}

TEST(CoordinatorTest, JoinWithoutStop) {
  Coordinator coord;
  std::unique_ptr<MockQueueRunner> qr(new MockQueueRunner(&coord));
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr)));

  EXPECT_EQ(coord.Join().code(), Code::FAILED_PRECONDITION);
}

TEST(CoordinatorTest, AllRunnersStopped) {
  Coordinator coord;
  MockQueueRunner* qr = new MockQueueRunner(&coord);
  TF_ASSERT_OK(coord.RegisterRunner(std::unique_ptr<RunnerInterface>(qr)));

  EXPECT_FALSE(coord.AllRunnersStopped());
  qr->Stop();
  EXPECT_TRUE(coord.AllRunnersStopped());
}

}  // namespace
}  // namespace tensorflow
<commit_msg>Remove race in coordinator_test so it passes on tsan.  Reduce sleep intervals so it runs faster (11s on tsan instead of ~30s). Change: 147893428<commit_after>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/cc/training/coordinator.h"

#include "tensorflow/cc/training/queue_runner.h"
#include "tensorflow/core/lib/core/blocking_counter.h"
#include "tensorflow/core/lib/core/error_codes.pb.h"
#include "tensorflow/core/lib/core/notification.h"
#include "tensorflow/core/lib/core/status_test_util.h"
#include "tensorflow/core/platform/env.h"
#include "tensorflow/core/platform/test.h"
#include "tensorflow/core/public/session.h"

namespace tensorflow {
namespace {

using error::Code;

void WaitForStopThread(Coordinator* coord, Notification* about_to_wait,
                       Notification* done) {
  about_to_wait->Notify();
  coord->WaitForStop();
  done->Notify();
}

TEST(CoordinatorTest, TestStopAndWaitOnStop) {
  Coordinator coord;
  EXPECT_EQ(coord.ShouldStop(), false);

  Notification about_to_wait;
  Notification done;
  Env::Default()->SchedClosure(
      std::bind(&WaitForStopThread, &coord, &about_to_wait, &done));
  about_to_wait.WaitForNotification();
  Env::Default()->SleepForMicroseconds(1000 * 1000);
  EXPECT_FALSE(done.HasBeenNotified());

  TF_EXPECT_OK(coord.RequestStop());
  done.WaitForNotification();
  EXPECT_TRUE(coord.ShouldStop());
}

class MockQueueRunner : public RunnerInterface {
 public:
  MockQueueRunner(Coordinator* coord) {
    coord_ = coord;
    join_counter_ = nullptr;
    thread_pool_.reset(new thread::ThreadPool(Env::Default(), "test-pool", 10));
    stopped_ = false;
  }

  MockQueueRunner(Coordinator* coord, int* join_counter)
      : MockQueueRunner(coord) {
    join_counter_ = join_counter;
  }

  void StartCounting(std::atomic<int>* counter, int until,
                     Notification* start = nullptr) {
    thread_pool_->Schedule(
        std::bind(&MockQueueRunner::CountThread, this, counter, until, start));
  }

  void StartSettingStatus(const Status& status, BlockingCounter* counter,
                          Notification* start) {
    thread_pool_->Schedule(std::bind(&MockQueueRunner::SetStatusThread, this,
                                     status, counter, start));
  }

  Status Join() {
    if (join_counter_ != nullptr) {
      (*join_counter_)++;
    }
    thread_pool_.reset();
    return status_;
  }

  Status GetStatus() { return status_; }

  void SetStatus(const Status& status) { status_ = status; }

  bool IsRunning() const override { return !stopped_; };

  void Stop() { stopped_ = true; }

 private:
  void CountThread(std::atomic<int>* counter, int until, Notification* start) {
    if (start != nullptr) start->WaitForNotification();
    while (!coord_->ShouldStop() && counter->load() < until) {
      (*counter)++;
      Env::Default()->SleepForMicroseconds(10 * 1000);
    }
    coord_->RequestStop().IgnoreError();
  }
  void SetStatusThread(const Status& status, BlockingCounter* counter,
                       Notification* start) {
    start->WaitForNotification();
    SetStatus(status);
    counter->DecrementCount();
  }
  std::unique_ptr<thread::ThreadPool> thread_pool_;
  Status status_;
  Coordinator* coord_;
  int* join_counter_;
  bool stopped_;
};

TEST(CoordinatorTest, TestRealStop) {
  std::atomic<int> counter(0);
  Coordinator coord;

  std::unique_ptr<MockQueueRunner> qr1(new MockQueueRunner(&coord));
  qr1->StartCounting(&counter, 100);
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr1)));

  std::unique_ptr<MockQueueRunner> qr2(new MockQueueRunner(&coord));
  qr2->StartCounting(&counter, 100);
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr2)));

  // Wait until the counting has started
  while (counter.load() == 0)
    ;
  TF_EXPECT_OK(coord.RequestStop());

  int temp_counter = counter.load();
  Env::Default()->SleepForMicroseconds(1000 * 1000);
  EXPECT_EQ(temp_counter, counter.load());
  TF_EXPECT_OK(coord.Join());
}

TEST(CoordinatorTest, TestRequestStop) {
  Coordinator coord;
  std::atomic<int> counter(0);
  Notification start;
  std::unique_ptr<MockQueueRunner> qr;
  for (int i = 0; i < 10; i++) {
    qr.reset(new MockQueueRunner(&coord));
    qr->StartCounting(&counter, 10, &start);
    TF_ASSERT_OK(coord.RegisterRunner(std::move(qr)));
  }
  start.Notify();

  coord.WaitForStop();
  EXPECT_EQ(coord.ShouldStop(), true);
  EXPECT_EQ(counter.load(), 10);
  TF_EXPECT_OK(coord.Join());
}

TEST(CoordinatorTest, TestJoin) {
  Coordinator coord;
  int join_counter = 0;
  std::unique_ptr<MockQueueRunner> qr1(
      new MockQueueRunner(&coord, &join_counter));
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr1)));
  std::unique_ptr<MockQueueRunner> qr2(
      new MockQueueRunner(&coord, &join_counter));
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr2)));

  TF_EXPECT_OK(coord.RequestStop());
  TF_EXPECT_OK(coord.Join());
  EXPECT_EQ(join_counter, 2);
}

TEST(CoordinatorTest, StatusReporting) {
  Coordinator coord({Code::CANCELLED, Code::OUT_OF_RANGE});
  Notification start;
  BlockingCounter counter(3);

  std::unique_ptr<MockQueueRunner> qr1(new MockQueueRunner(&coord));
  qr1->StartSettingStatus(Status(Code::CANCELLED, ""), &counter, &start);
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr1)));

  std::unique_ptr<MockQueueRunner> qr2(new MockQueueRunner(&coord));
  qr2->StartSettingStatus(Status(Code::INVALID_ARGUMENT, ""), &counter, &start);
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr2)));

  std::unique_ptr<MockQueueRunner> qr3(new MockQueueRunner(&coord));
  qr3->StartSettingStatus(Status(Code::OUT_OF_RANGE, ""), &counter, &start);
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr3)));

  start.Notify();
  counter.Wait();
  TF_EXPECT_OK(coord.RequestStop());
  EXPECT_EQ(coord.Join().code(), Code::INVALID_ARGUMENT);
}

TEST(CoordinatorTest, JoinWithoutStop) {
  Coordinator coord;
  std::unique_ptr<MockQueueRunner> qr(new MockQueueRunner(&coord));
  TF_ASSERT_OK(coord.RegisterRunner(std::move(qr)));

  EXPECT_EQ(coord.Join().code(), Code::FAILED_PRECONDITION);
}

TEST(CoordinatorTest, AllRunnersStopped) {
  Coordinator coord;
  MockQueueRunner* qr = new MockQueueRunner(&coord);
  TF_ASSERT_OK(coord.RegisterRunner(std::unique_ptr<RunnerInterface>(qr)));

  EXPECT_FALSE(coord.AllRunnersStopped());
  qr->Stop();
  EXPECT_TRUE(coord.AllRunnersStopped());
}

}  // namespace
}  // namespace tensorflow
<|endoftext|>


<commit_before>#include <xzero/http/HttpResponse.h>
#include <xzero/http/HttpRequest.h>
#include <xzero/http/HttpChannel.h>

namespace xzero {

HttpResponse::HttpResponse(HttpChannel* channel,
                           std::unique_ptr<HttpOutput>&& output)
    : channel_(channel),
      output_(std::move(output)),
      version_(HttpVersion::UNKNOWN),
      status_(HttpStatus::Undefined),
      contentType_(),
      contentLength_(static_cast<size_t>(-1)),
      headers_(),
      committed_(false) {
  //.
}

void HttpResponse::recycle() {
  output_->recycle();
  version_ = HttpVersion::UNKNOWN;
  status_ = HttpStatus::Undefined;
  reason_.clear();
  contentType_.clear();
  contentLength_ = static_cast<size_t>(-1);
  headers_.reset();
  committed_ = false;
}

void HttpResponse::setCommitted(bool value) {
  assert(isCommitted() == false && "Cannot be modified after commit.");
  committed_ = value;
}

HttpVersion HttpResponse::version() const noexcept {
  return version_;
}

void HttpResponse::setVersion(HttpVersion version) {
  assert(isCommitted() == false && "Cannot be modified after commit.");
  version_ = version;
}

void HttpResponse::setStatus(HttpStatus status) {
  assert(isCommitted() == false && "Cannot be modified after commit.");
  status_ = status;
}

void HttpResponse::setContentType(const std::string& value) {
  assert(isCommitted() == false && "Cannot be modified after commit.");
  //TODO
}

void HttpResponse::setContentLength(size_t size) {
  assert(isCommitted() == false && "Cannot be modified after commit.");
  contentLength_ = size;
}

void HttpResponse::addHeader(const std::string& name,
                             const std::string& value) {
  assert(isCommitted() == false && "Cannot be modified after commit.");
  headers_.push_back(name, value);
}

void HttpResponse::setHeader(const std::string& name,
                             const std::string& value) {
  assert(isCommitted() == false && "Cannot be modified after commit.");
  headers_.overwrite(name, value);
}

void HttpResponse::removeHeader(const std::string& name) {
  assert(isCommitted() == false && "Cannot be modified after commit.");
  headers_.remove(name);
}

const std::string& HttpResponse::getHeader(const std::string& name) const {
  return headers_.get(name);
}

void HttpResponse::send100Continue() {
  channel_->send100Continue();
}

void HttpResponse::completed() {
  output_->completed();
}

}  // namespace xzero
<commit_msg>prefer runtime exception over assert()<commit_after>#include <xzero/http/HttpResponse.h>
#include <xzero/http/HttpRequest.h>
#include <xzero/http/HttpChannel.h>

namespace xzero {

HttpResponse::HttpResponse(HttpChannel* channel,
                           std::unique_ptr<HttpOutput>&& output)
    : channel_(channel),
      output_(std::move(output)),
      version_(HttpVersion::UNKNOWN),
      status_(HttpStatus::Undefined),
      contentType_(),
      contentLength_(static_cast<size_t>(-1)),
      headers_(),
      committed_(false) {
  //.
}

void HttpResponse::recycle() {
  output_->recycle();
  version_ = HttpVersion::UNKNOWN;
  status_ = HttpStatus::Undefined;
  reason_.clear();
  contentType_.clear();
  contentLength_ = static_cast<size_t>(-1);
  headers_.reset();
  committed_ = false;
}

void HttpResponse::setCommitted(bool value) {
  if (isCommitted())
    throw std::runtime_error("Invalid State. Cannot be modified after commit.");

  committed_ = value;
}

HttpVersion HttpResponse::version() const noexcept {
  return version_;
}

void HttpResponse::setVersion(HttpVersion version) {
  if (isCommitted())
    throw std::runtime_error("Invalid State. Cannot be modified after commit.");

  version_ = version;
}

void HttpResponse::setStatus(HttpStatus status) {
  if (isCommitted())
    throw std::runtime_error("Invalid State. Cannot be modified after commit.");

  status_ = status;
}

void HttpResponse::setContentType(const std::string& value) {
  if (isCommitted())
    throw std::runtime_error("Invalid State. Cannot be modified after commit.");

  //TODO
}

void HttpResponse::setContentLength(size_t size) {
  if (isCommitted())
    throw std::runtime_error("Invalid State. Cannot be modified after commit.");

  contentLength_ = size;
}

void HttpResponse::addHeader(const std::string& name,
                             const std::string& value) {
  if (isCommitted())
    throw std::runtime_error("Invalid State. Cannot be modified after commit.");

  headers_.push_back(name, value);
}

void HttpResponse::setHeader(const std::string& name,
                             const std::string& value) {
  if (isCommitted())
    throw std::runtime_error("Invalid State. Cannot be modified after commit.");

  headers_.overwrite(name, value);
}

void HttpResponse::removeHeader(const std::string& name) {
  if (isCommitted())
    throw std::runtime_error("Invalid State. Cannot be modified after commit.");

  headers_.remove(name);
}

const std::string& HttpResponse::getHeader(const std::string& name) const {
  return headers_.get(name);
}

void HttpResponse::send100Continue() {
  channel_->send100Continue();
}

void HttpResponse::completed() {
  output_->completed();
}

}  // namespace xzero
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

#include "ifmap/ifmap_update.h"

#include "ifmap/ifmap_node.h"

IFMapObjectPtr::IFMapObjectPtr()
    : type(NIL) {
      u.ptr = NULL;
}

IFMapObjectPtr::IFMapObjectPtr(IFMapNode *node)
    : type(NODE) {
      u.node = node;
}

IFMapObjectPtr::IFMapObjectPtr(IFMapLink *link)
    : type(LINK) {
      u.link = link;
}

IFMapUpdate::IFMapUpdate(IFMapNode *node, bool positive)
    : IFMapListEntry(positive ? UPDATE : DELETE),
      data_(node) {
}

IFMapUpdate::IFMapUpdate(IFMapLink *link, bool positive)
    : IFMapListEntry(positive ? UPDATE : DELETE),
      data_(link) {
}

std::string IFMapUpdate::ToString() {
    std::string first;
    if (data().type == IFMapObjectPtr::NODE) {
        IFMapNode *node = data().u.node;
        first = node->ToString();
    } else if (data().type == IFMapObjectPtr::LINK) {
        IFMapLink *link = data().u.link;
        first = link->ToString();
    }
    return first + ":" + TypeToString();
}

void IFMapUpdate::AdvertiseReset(const BitSet &set) {
    advertise_.Reset(set);
}
void IFMapUpdate::AdvertiseOr(const BitSet &set) {
    advertise_ |= set;
}
void IFMapUpdate::SetAdvertise(const BitSet &set) {
    advertise_ = set;
}

IFMapMarker::IFMapMarker()
    : IFMapListEntry(MARKER) {
}

IFMapState::IFMapState() : sig_(kInvalidSig) {
}

IFMapState::~IFMapState() {
    assert(update_list_.empty());
}

IFMapUpdate *IFMapState::GetUpdate(IFMapListEntry::EntryType type) {
    for (UpdateList::iterator iter = update_list_.begin();
         iter != update_list_.end(); ++iter) {
        IFMapUpdate *update = iter.operator->();
        if (update->type == type) {
            return update;
        }
    }
    return NULL;
}

void IFMapState::Insert(IFMapUpdate *update) {
    update_list_.push_front(*update);
}

void IFMapState::Remove(IFMapUpdate *update) {
    update_list_.erase(update_list_.s_iterator_to(*update));
}

IFMapNodeState::IFMapNodeState() {
}

bool IFMapNodeState::HasDependents() const {
    return !dependents_.empty();
}

IFMapLinkState::IFMapLinkState(IFMapLink *link)
    : left_(link), right_(link) {
}

void IFMapLinkState::SetDependency(IFMapNodeState *first,
                                   IFMapNodeState *second) {
    left_.reset(first);
    right_.reset(second);
}

void IFMapLinkState::RemoveDependency() {
    left_.clear();
    right_.clear();
}

bool IFMapLinkState::HasDependency() const {
    return left_.get() != NULL;
}

<commit_msg>Minor change in ToString of IFMapUpdate<commit_after>/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

#include "ifmap/ifmap_update.h"

#include "ifmap/ifmap_node.h"

IFMapObjectPtr::IFMapObjectPtr()
    : type(NIL) {
      u.ptr = NULL;
}

IFMapObjectPtr::IFMapObjectPtr(IFMapNode *node)
    : type(NODE) {
      u.node = node;
}

IFMapObjectPtr::IFMapObjectPtr(IFMapLink *link)
    : type(LINK) {
      u.link = link;
}

IFMapUpdate::IFMapUpdate(IFMapNode *node, bool positive)
    : IFMapListEntry(positive ? UPDATE : DELETE),
      data_(node) {
}

IFMapUpdate::IFMapUpdate(IFMapLink *link, bool positive)
    : IFMapListEntry(positive ? UPDATE : DELETE),
      data_(link) {
}

std::string IFMapUpdate::ToString() {
    std::string first;
    if (data().type == IFMapObjectPtr::NODE) {
        IFMapNode *node = data().u.node;
        first = node->ToString();
    } else if (data().type == IFMapObjectPtr::LINK) {
        IFMapLink *link = data().u.link;
        first = link->ToString();
    }
    return TypeToString() + " of " + first;
}

void IFMapUpdate::AdvertiseReset(const BitSet &set) {
    advertise_.Reset(set);
}
void IFMapUpdate::AdvertiseOr(const BitSet &set) {
    advertise_ |= set;
}
void IFMapUpdate::SetAdvertise(const BitSet &set) {
    advertise_ = set;
}

IFMapMarker::IFMapMarker()
    : IFMapListEntry(MARKER) {
}

IFMapState::IFMapState() : sig_(kInvalidSig) {
}

IFMapState::~IFMapState() {
    assert(update_list_.empty());
}

IFMapUpdate *IFMapState::GetUpdate(IFMapListEntry::EntryType type) {
    for (UpdateList::iterator iter = update_list_.begin();
         iter != update_list_.end(); ++iter) {
        IFMapUpdate *update = iter.operator->();
        if (update->type == type) {
            return update;
        }
    }
    return NULL;
}

void IFMapState::Insert(IFMapUpdate *update) {
    update_list_.push_front(*update);
}

void IFMapState::Remove(IFMapUpdate *update) {
    update_list_.erase(update_list_.s_iterator_to(*update));
}

IFMapNodeState::IFMapNodeState() {
}

bool IFMapNodeState::HasDependents() const {
    return !dependents_.empty();
}

IFMapLinkState::IFMapLinkState(IFMapLink *link)
    : left_(link), right_(link) {
}

void IFMapLinkState::SetDependency(IFMapNodeState *first,
                                   IFMapNodeState *second) {
    left_.reset(first);
    right_.reset(second);
}

void IFMapLinkState::RemoveDependency() {
    left_.clear();
    right_.clear();
}

bool IFMapLinkState::HasDependency() const {
    return left_.get() != NULL;
}

<|endoftext|>


<commit_before>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBitmapCache.h"
#include "SkImage_Gpu.h"
#include "GrContext.h"
#include "GrDrawContext.h"
#include "effects/GrYUVtoRGBEffect.h"
#include "SkCanvas.h"
#include "SkGpuDevice.h"
#include "SkPixelRef.h"

SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrTexture* tex,
                         int sampleCountForNewSurfaces, SkSurface::Budgeted budgeted)
    : INHERITED(w, h, uniqueID, NULL)
    , fTexture(SkRef(tex))
    , fSampleCountForNewSurfaces(sampleCountForNewSurfaces)
    , fAlphaType(at)
    , fBudgeted(budgeted)
    {}

SkImage_Gpu::~SkImage_Gpu() {
    if (fAddedRasterVersionToCache.load()) {
        SkNotifyBitmapGenIDIsStale(this->uniqueID());
    }
}

SkSurface* SkImage_Gpu::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) const {
    GrTexture* tex = this->getTexture();
    SkASSERT(tex);
    GrContext* ctx = tex->getContext();
    if (!ctx) {
        // the texture may have been abandoned, so we have to check
        return NULL;
    }
    // TODO: Change signature of onNewSurface to take a budgeted param.
    const SkSurface::Budgeted budgeted = SkSurface::kNo_Budgeted;
    return SkSurface::NewRenderTarget(ctx, budgeted, info, fSampleCountForNewSurfaces, &props);
}

extern void SkTextureImageApplyBudgetedDecision(SkImage* image) {
    if (as_IB(image)->getTexture()) {
        ((SkImage_Gpu*)image)->applyBudgetDecision();
    }
}

SkShader* SkImage_Gpu::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
                                   const SkMatrix* localMatrix) const {
    SkBitmap bm;
    GrWrapTextureInBitmap(fTexture, this->width(), this->height(), this->isOpaque(), &bm);
    return SkShader::CreateBitmapShader(bm, tileX, tileY, localMatrix);
}

bool SkImage_Gpu::getROPixels(SkBitmap* dst) const {
    if (SkBitmapCache::Find(this->uniqueID(), dst)) {
        SkASSERT(dst->getGenerationID() == this->uniqueID());
        SkASSERT(dst->isImmutable());
        SkASSERT(dst->getPixels());
        return true;
    }

    SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
    if (!dst->tryAllocPixels(SkImageInfo::MakeN32(this->width(), this->height(), at))) {
        return false;
    }
    if (!fTexture->readPixels(0, 0, dst->width(), dst->height(), kSkia8888_GrPixelConfig,
                              dst->getPixels(), dst->rowBytes())) {
        return false;
    }

    dst->pixelRef()->setImmutableWithID(this->uniqueID());
    SkBitmapCache::Add(this->uniqueID(), *dst);
    fAddedRasterVersionToCache.store(true);
    return true;
}

bool SkImage_Gpu::isOpaque() const {
    return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaque_SkAlphaType;
}

static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) {
    switch (info.colorType()) {
        case kRGBA_8888_SkColorType:
        case kBGRA_8888_SkColorType:
            break;
        default:
            return; // nothing to do
    }

    // SkColor is not necesarily RGBA or BGRA, but it is one of them on little-endian,
    // and in either case, the alpha-byte is always in the same place, so we can safely call
    // SkPreMultiplyColor()
    //
    SkColor* row = (SkColor*)pixels;
    for (int y = 0; y < info.height(); ++y) {
        for (int x = 0; x < info.width(); ++x) {
            row[x] = SkPreMultiplyColor(row[x]);
        }
    }
}

bool SkImage_Gpu::onReadPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
                               int srcX, int srcY) const {
    GrPixelConfig config = SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType(),
                                                     info.profileType());
    uint32_t flags = 0;
    if (kUnpremul_SkAlphaType == info.alphaType() && kPremul_SkAlphaType == fAlphaType) {
        // let the GPU perform this transformation for us
        flags = GrContext::kUnpremul_PixelOpsFlag;
    }
    if (!fTexture->readPixels(srcX, srcY, info.width(), info.height(), config,
                              pixels, rowBytes, flags)) {
        return false;
    }
    // do we have to manually fix-up the alpha channel?
    //      src         dst
    //      unpremul    premul      fix manually
    //      premul      unpremul    done by kUnpremul_PixelOpsFlag
    // all other combos need to change.
    //
    // Should this be handled by Ganesh? todo:?
    //
    if (kPremul_SkAlphaType == info.alphaType() && kUnpremul_SkAlphaType == fAlphaType) {
        apply_premul(info, pixels, rowBytes);
    }
    return true;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

static SkImage* new_wrapped_texture_common(GrContext* ctx, const GrBackendTextureDesc& desc,
                                           SkAlphaType at, GrWrapOwnership ownership,
                                           SkImage::TextureReleaseProc releaseProc,
                                           SkImage::ReleaseContext releaseCtx) {
    if (desc.fWidth <= 0 || desc.fHeight <= 0) {
        return NULL;
    }
    SkAutoTUnref<GrTexture> tex(ctx->textureProvider()->wrapBackendTexture(desc, ownership));
    if (!tex) {
        return NULL;
    }
    if (releaseProc) {
        tex->setRelease(releaseProc, releaseCtx);
    }

    const SkSurface::Budgeted budgeted = SkSurface::kNo_Budgeted;
    return SkNEW_ARGS(SkImage_Gpu,
                      (desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, at, tex, 0, budgeted));

}

SkImage* SkImage::NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc, SkAlphaType at,
                                 TextureReleaseProc releaseP, ReleaseContext releaseC) {
    return new_wrapped_texture_common(ctx, desc, at, kBorrow_GrWrapOwnership, releaseP, releaseC);
}

SkImage* SkImage::NewFromAdoptedTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
                                        SkAlphaType at) {
    return new_wrapped_texture_common(ctx, desc, at, kAdopt_GrWrapOwnership, NULL, NULL);
}

SkImage* SkImage::NewFromTextureCopy(GrContext* ctx, const GrBackendTextureDesc& desc,
                                     SkAlphaType at) {
    if (desc.fWidth <= 0 || desc.fHeight <= 0) {
        return NULL;
    }

    SkAutoTUnref<GrTexture> src(ctx->textureProvider()->wrapBackendTexture(
        desc, kBorrow_GrWrapOwnership));
    if (!src) {
        return NULL;
    }

    const bool isBudgeted = true;
    SkAutoTUnref<GrTexture> dst(GrDeepCopyTexture(src, isBudgeted));
    if (!dst) {
        return NULL;
    }

    const SkSurface::Budgeted budgeted = SkSurface::kYes_Budgeted;
    const int sampleCount = 0;  // todo: make this an explicit parameter to newSurface()?
    return SkNEW_ARGS(SkImage_Gpu, (desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
                                    at, dst, sampleCount, budgeted));
}

SkImage* SkImage::NewFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace colorSpace,
                                         const GrBackendObject yuvTextureHandles[3],
                                         const SkISize yuvSizes[3],
                                         GrSurfaceOrigin origin) {
    const SkSurface::Budgeted budgeted = SkSurface::kYes_Budgeted;

    if (yuvSizes[0].fWidth <= 0 || yuvSizes[0].fHeight <= 0 ||
        yuvSizes[1].fWidth <= 0 || yuvSizes[1].fHeight <= 0 ||
        yuvSizes[2].fWidth <= 0 || yuvSizes[2].fHeight <= 0) {
        return NULL;
    }
    static const GrPixelConfig kConfig = kAlpha_8_GrPixelConfig;
    GrBackendTextureDesc yDesc;
    yDesc.fConfig = kConfig;
    yDesc.fOrigin = origin;
    yDesc.fSampleCnt = 0;
    yDesc.fTextureHandle = yuvTextureHandles[0];
    yDesc.fWidth = yuvSizes[0].fWidth;
    yDesc.fHeight = yuvSizes[0].fHeight;

    GrBackendTextureDesc uDesc;
    uDesc.fConfig = kConfig;
    uDesc.fOrigin = origin;
    uDesc.fSampleCnt = 0;
    uDesc.fTextureHandle = yuvTextureHandles[1];
    uDesc.fWidth = yuvSizes[1].fWidth;
    uDesc.fHeight = yuvSizes[1].fHeight;

    GrBackendTextureDesc vDesc;
    vDesc.fConfig = kConfig;
    vDesc.fOrigin = origin;
    vDesc.fSampleCnt = 0;
    vDesc.fTextureHandle = yuvTextureHandles[2];
    vDesc.fWidth = yuvSizes[2].fWidth;
    vDesc.fHeight = yuvSizes[2].fHeight;

    SkAutoTUnref<GrTexture> yTex(ctx->textureProvider()->wrapBackendTexture(
        yDesc, kBorrow_GrWrapOwnership));
    SkAutoTUnref<GrTexture> uTex(ctx->textureProvider()->wrapBackendTexture(
        uDesc, kBorrow_GrWrapOwnership));
    SkAutoTUnref<GrTexture> vTex(ctx->textureProvider()->wrapBackendTexture(
        vDesc, kBorrow_GrWrapOwnership));
    if (!yTex || !uTex || !vTex) {
        return NULL;
    }

    GrSurfaceDesc dstDesc;
    // Needs to be a render target in order to draw to it for the yuv->rgb conversion.
    dstDesc.fFlags = kRenderTarget_GrSurfaceFlag;
    dstDesc.fOrigin = origin;
    dstDesc.fWidth = yuvSizes[0].fWidth;
    dstDesc.fHeight = yuvSizes[0].fHeight;
    dstDesc.fConfig = kRGBA_8888_GrPixelConfig;
    dstDesc.fSampleCnt = 0;

    SkAutoTUnref<GrTexture> dst(ctx->textureProvider()->createTexture(dstDesc, true));
    if (!dst) {
        return NULL;
    }

    GrPaint paint;
    paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
    paint.addColorProcessor(GrYUVtoRGBEffect::Create(paint.getProcessorDataManager(), yTex, uTex,
                                                     vTex, yuvSizes, colorSpace))->unref();

    const SkRect rect = SkRect::MakeWH(SkIntToScalar(dstDesc.fWidth),
                                       SkIntToScalar(dstDesc.fHeight));
    GrDrawContext* drawContext = ctx->drawContext();
    drawContext->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, SkMatrix::I(), rect);
    ctx->flushSurfaceWrites(dst);
    return SkNEW_ARGS(SkImage_Gpu, (dstDesc.fWidth, dstDesc.fHeight, kNeedNewImageUniqueID,
                                    kOpaque_SkAlphaType, dst, 0, budgeted));
}

///////////////////////////////////////////////////////////////////////////////////////////////////

GrTexture* GrDeepCopyTexture(GrTexture* src, bool budgeted) {
    GrContext* ctx = src->getContext();

    GrSurfaceDesc desc = src->desc();
    GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, NULL, 0);
    if (!dst) {
        return NULL;
    }

    const SkIRect srcR = SkIRect::MakeWH(desc.fWidth, desc.fHeight);
    const SkIPoint dstP = SkIPoint::Make(0, 0);
    ctx->copySurface(dst, src, srcR, dstP, GrContext::kFlushWrites_PixelOp);
    return dst;
}

<commit_msg>init atomic bool in SkImage_Gpu<commit_after>/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBitmapCache.h"
#include "SkImage_Gpu.h"
#include "GrContext.h"
#include "GrDrawContext.h"
#include "effects/GrYUVtoRGBEffect.h"
#include "SkCanvas.h"
#include "SkGpuDevice.h"
#include "SkPixelRef.h"

SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrTexture* tex,
                         int sampleCountForNewSurfaces, SkSurface::Budgeted budgeted)
    : INHERITED(w, h, uniqueID, NULL)
    , fTexture(SkRef(tex))
    , fSampleCountForNewSurfaces(sampleCountForNewSurfaces)
    , fAlphaType(at)
    , fBudgeted(budgeted)
    , fAddedRasterVersionToCache(false)
    {}

SkImage_Gpu::~SkImage_Gpu() {
    if (fAddedRasterVersionToCache.load()) {
        SkNotifyBitmapGenIDIsStale(this->uniqueID());
    }
}

SkSurface* SkImage_Gpu::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props) const {
    GrTexture* tex = this->getTexture();
    SkASSERT(tex);
    GrContext* ctx = tex->getContext();
    if (!ctx) {
        // the texture may have been abandoned, so we have to check
        return NULL;
    }
    // TODO: Change signature of onNewSurface to take a budgeted param.
    const SkSurface::Budgeted budgeted = SkSurface::kNo_Budgeted;
    return SkSurface::NewRenderTarget(ctx, budgeted, info, fSampleCountForNewSurfaces, &props);
}

extern void SkTextureImageApplyBudgetedDecision(SkImage* image) {
    if (as_IB(image)->getTexture()) {
        ((SkImage_Gpu*)image)->applyBudgetDecision();
    }
}

SkShader* SkImage_Gpu::onNewShader(SkShader::TileMode tileX, SkShader::TileMode tileY,
                                   const SkMatrix* localMatrix) const {
    SkBitmap bm;
    GrWrapTextureInBitmap(fTexture, this->width(), this->height(), this->isOpaque(), &bm);
    return SkShader::CreateBitmapShader(bm, tileX, tileY, localMatrix);
}

bool SkImage_Gpu::getROPixels(SkBitmap* dst) const {
    if (SkBitmapCache::Find(this->uniqueID(), dst)) {
        SkASSERT(dst->getGenerationID() == this->uniqueID());
        SkASSERT(dst->isImmutable());
        SkASSERT(dst->getPixels());
        return true;
    }

    SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
    if (!dst->tryAllocPixels(SkImageInfo::MakeN32(this->width(), this->height(), at))) {
        return false;
    }
    if (!fTexture->readPixels(0, 0, dst->width(), dst->height(), kSkia8888_GrPixelConfig,
                              dst->getPixels(), dst->rowBytes())) {
        return false;
    }

    dst->pixelRef()->setImmutableWithID(this->uniqueID());
    SkBitmapCache::Add(this->uniqueID(), *dst);
    fAddedRasterVersionToCache.store(true);
    return true;
}

bool SkImage_Gpu::isOpaque() const {
    return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaque_SkAlphaType;
}

static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes) {
    switch (info.colorType()) {
        case kRGBA_8888_SkColorType:
        case kBGRA_8888_SkColorType:
            break;
        default:
            return; // nothing to do
    }

    // SkColor is not necesarily RGBA or BGRA, but it is one of them on little-endian,
    // and in either case, the alpha-byte is always in the same place, so we can safely call
    // SkPreMultiplyColor()
    //
    SkColor* row = (SkColor*)pixels;
    for (int y = 0; y < info.height(); ++y) {
        for (int x = 0; x < info.width(); ++x) {
            row[x] = SkPreMultiplyColor(row[x]);
        }
    }
}

bool SkImage_Gpu::onReadPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
                               int srcX, int srcY) const {
    GrPixelConfig config = SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType(),
                                                     info.profileType());
    uint32_t flags = 0;
    if (kUnpremul_SkAlphaType == info.alphaType() && kPremul_SkAlphaType == fAlphaType) {
        // let the GPU perform this transformation for us
        flags = GrContext::kUnpremul_PixelOpsFlag;
    }
    if (!fTexture->readPixels(srcX, srcY, info.width(), info.height(), config,
                              pixels, rowBytes, flags)) {
        return false;
    }
    // do we have to manually fix-up the alpha channel?
    //      src         dst
    //      unpremul    premul      fix manually
    //      premul      unpremul    done by kUnpremul_PixelOpsFlag
    // all other combos need to change.
    //
    // Should this be handled by Ganesh? todo:?
    //
    if (kPremul_SkAlphaType == info.alphaType() && kUnpremul_SkAlphaType == fAlphaType) {
        apply_premul(info, pixels, rowBytes);
    }
    return true;
}

///////////////////////////////////////////////////////////////////////////////////////////////////

static SkImage* new_wrapped_texture_common(GrContext* ctx, const GrBackendTextureDesc& desc,
                                           SkAlphaType at, GrWrapOwnership ownership,
                                           SkImage::TextureReleaseProc releaseProc,
                                           SkImage::ReleaseContext releaseCtx) {
    if (desc.fWidth <= 0 || desc.fHeight <= 0) {
        return NULL;
    }
    SkAutoTUnref<GrTexture> tex(ctx->textureProvider()->wrapBackendTexture(desc, ownership));
    if (!tex) {
        return NULL;
    }
    if (releaseProc) {
        tex->setRelease(releaseProc, releaseCtx);
    }

    const SkSurface::Budgeted budgeted = SkSurface::kNo_Budgeted;
    return SkNEW_ARGS(SkImage_Gpu,
                      (desc.fWidth, desc.fHeight, kNeedNewImageUniqueID, at, tex, 0, budgeted));

}

SkImage* SkImage::NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc, SkAlphaType at,
                                 TextureReleaseProc releaseP, ReleaseContext releaseC) {
    return new_wrapped_texture_common(ctx, desc, at, kBorrow_GrWrapOwnership, releaseP, releaseC);
}

SkImage* SkImage::NewFromAdoptedTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
                                        SkAlphaType at) {
    return new_wrapped_texture_common(ctx, desc, at, kAdopt_GrWrapOwnership, NULL, NULL);
}

SkImage* SkImage::NewFromTextureCopy(GrContext* ctx, const GrBackendTextureDesc& desc,
                                     SkAlphaType at) {
    if (desc.fWidth <= 0 || desc.fHeight <= 0) {
        return NULL;
    }

    SkAutoTUnref<GrTexture> src(ctx->textureProvider()->wrapBackendTexture(
        desc, kBorrow_GrWrapOwnership));
    if (!src) {
        return NULL;
    }

    const bool isBudgeted = true;
    SkAutoTUnref<GrTexture> dst(GrDeepCopyTexture(src, isBudgeted));
    if (!dst) {
        return NULL;
    }

    const SkSurface::Budgeted budgeted = SkSurface::kYes_Budgeted;
    const int sampleCount = 0;  // todo: make this an explicit parameter to newSurface()?
    return SkNEW_ARGS(SkImage_Gpu, (desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
                                    at, dst, sampleCount, budgeted));
}

SkImage* SkImage::NewFromYUVTexturesCopy(GrContext* ctx , SkYUVColorSpace colorSpace,
                                         const GrBackendObject yuvTextureHandles[3],
                                         const SkISize yuvSizes[3],
                                         GrSurfaceOrigin origin) {
    const SkSurface::Budgeted budgeted = SkSurface::kYes_Budgeted;

    if (yuvSizes[0].fWidth <= 0 || yuvSizes[0].fHeight <= 0 ||
        yuvSizes[1].fWidth <= 0 || yuvSizes[1].fHeight <= 0 ||
        yuvSizes[2].fWidth <= 0 || yuvSizes[2].fHeight <= 0) {
        return NULL;
    }
    static const GrPixelConfig kConfig = kAlpha_8_GrPixelConfig;
    GrBackendTextureDesc yDesc;
    yDesc.fConfig = kConfig;
    yDesc.fOrigin = origin;
    yDesc.fSampleCnt = 0;
    yDesc.fTextureHandle = yuvTextureHandles[0];
    yDesc.fWidth = yuvSizes[0].fWidth;
    yDesc.fHeight = yuvSizes[0].fHeight;

    GrBackendTextureDesc uDesc;
    uDesc.fConfig = kConfig;
    uDesc.fOrigin = origin;
    uDesc.fSampleCnt = 0;
    uDesc.fTextureHandle = yuvTextureHandles[1];
    uDesc.fWidth = yuvSizes[1].fWidth;
    uDesc.fHeight = yuvSizes[1].fHeight;

    GrBackendTextureDesc vDesc;
    vDesc.fConfig = kConfig;
    vDesc.fOrigin = origin;
    vDesc.fSampleCnt = 0;
    vDesc.fTextureHandle = yuvTextureHandles[2];
    vDesc.fWidth = yuvSizes[2].fWidth;
    vDesc.fHeight = yuvSizes[2].fHeight;

    SkAutoTUnref<GrTexture> yTex(ctx->textureProvider()->wrapBackendTexture(
        yDesc, kBorrow_GrWrapOwnership));
    SkAutoTUnref<GrTexture> uTex(ctx->textureProvider()->wrapBackendTexture(
        uDesc, kBorrow_GrWrapOwnership));
    SkAutoTUnref<GrTexture> vTex(ctx->textureProvider()->wrapBackendTexture(
        vDesc, kBorrow_GrWrapOwnership));
    if (!yTex || !uTex || !vTex) {
        return NULL;
    }

    GrSurfaceDesc dstDesc;
    // Needs to be a render target in order to draw to it for the yuv->rgb conversion.
    dstDesc.fFlags = kRenderTarget_GrSurfaceFlag;
    dstDesc.fOrigin = origin;
    dstDesc.fWidth = yuvSizes[0].fWidth;
    dstDesc.fHeight = yuvSizes[0].fHeight;
    dstDesc.fConfig = kRGBA_8888_GrPixelConfig;
    dstDesc.fSampleCnt = 0;

    SkAutoTUnref<GrTexture> dst(ctx->textureProvider()->createTexture(dstDesc, true));
    if (!dst) {
        return NULL;
    }

    GrPaint paint;
    paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
    paint.addColorProcessor(GrYUVtoRGBEffect::Create(paint.getProcessorDataManager(), yTex, uTex,
                                                     vTex, yuvSizes, colorSpace))->unref();

    const SkRect rect = SkRect::MakeWH(SkIntToScalar(dstDesc.fWidth),
                                       SkIntToScalar(dstDesc.fHeight));
    GrDrawContext* drawContext = ctx->drawContext();
    drawContext->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, SkMatrix::I(), rect);
    ctx->flushSurfaceWrites(dst);
    return SkNEW_ARGS(SkImage_Gpu, (dstDesc.fWidth, dstDesc.fHeight, kNeedNewImageUniqueID,
                                    kOpaque_SkAlphaType, dst, 0, budgeted));
}

///////////////////////////////////////////////////////////////////////////////////////////////////

GrTexture* GrDeepCopyTexture(GrTexture* src, bool budgeted) {
    GrContext* ctx = src->getContext();

    GrSurfaceDesc desc = src->desc();
    GrTexture* dst = ctx->textureProvider()->createTexture(desc, budgeted, NULL, 0);
    if (!dst) {
        return NULL;
    }

    const SkIRect srcR = SkIRect::MakeWH(desc.fWidth, desc.fHeight);
    const SkIPoint dstP = SkIPoint::Make(0, 0);
    ctx->copySurface(dst, src, srcR, dstP, GrContext::kFlushWrites_PixelOp);
    return dst;
}

<|endoftext|>