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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef __otbOGRVectorDataIO_txx
#define __otbOGRVectorDataIO_txx

#include "otbOGRVectorDataIO.h"

#include "ogrsf_frmts.h"

#include "itksys/SystemTools.hxx"

#include "itkByteSwapper.h"
#include "otbMacro.h"
#include "otbSystem.h"
#include "otbDataNode.h"
#include "otbMetaDataKey.h"
#include "itkTimeProbe.h"
#include "otbVectorDataKeywordlist.h"
#include "otbOGRIOHelper.h"

namespace otb
{

OGRVectorDataIO
::OGRVectorDataIO() :
  m_DataSource(NULL)
{
  // OGR factory registration
  OGRRegisterAll();
}

OGRVectorDataIO::~OGRVectorDataIO()
{
  if (m_DataSource != NULL)
    {
    OGRDataSource::DestroyDataSource(m_DataSource);
    }
}

bool
OGRVectorDataIO::CanReadFile(const char* filename) const
{
  OGRDataSource * poDS = OGRSFDriverRegistrar::Open(filename, FALSE);
  if (poDS == NULL)
    {
    return false;
    }
//     std::cout << poDS->GetDriver()->GetName() << std::endl;
  OGRDataSource::DestroyDataSource(poDS);
  return true;
}

// Used to print information about this object

void
OGRVectorDataIO::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

// Read vector data

void
OGRVectorDataIO
::Read(itk::DataObject* datag)
{
  VectorDataPointerType data = dynamic_cast<VectorDataType*>(datag);
  // Destroy previous opened data source
  if (m_DataSource != NULL)
    {
    OGRDataSource::DestroyDataSource(m_DataSource);
    }

  m_DataSource = OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), FALSE);

  if (m_DataSource == NULL)
    {
    itkExceptionMacro(<< "Failed to open data file " << this->m_FileName);
    }

  otbMsgDebugMacro(<< "Driver to read: OGR");
  otbMsgDebugMacro(<< "Reading  file: " << this->m_FileName);

  // Reading layers
  otbMsgDevMacro(<< "Number of layers: " << m_DataSource->GetLayerCount());

  // Retrieving root node
  DataTreePointerType tree = data->GetDataTree();
  DataNodePointerType root = tree->GetRoot()->Get();

  OGRSpatialReference * oSRS = NULL;
  //We take the assumption that the spatial reference is common to all layers
  oSRS = m_DataSource->GetLayer(0)->GetSpatialRef();

  if (oSRS != NULL)
    {
    char * projectionRefChar;
    oSRS->exportToWkt(&projectionRefChar);
    std::string projectionRef = projectionRefChar;
    CPLFree(projectionRefChar);
    itk::MetaDataDictionary& dict = data->GetMetaDataDictionary();
    itk::EncapsulateMetaData<std::string>(dict, MetaDataKey::ProjectionRefKey, projectionRef);
    }
  else
    {
    otbMsgDevMacro(<< "Can't retrieve the OGRSpatialReference from the shapefile");
    }

  std::string projectionRefWkt = data->GetProjectionRef();

  bool projectionInformationAvailable = !projectionRefWkt.empty();

  if (projectionInformationAvailable)
    {
    otbMsgDevMacro(<< "Projection information : " << projectionRefWkt);
    }
  else
    {
    otbMsgDevMacro(<< "Projection information unavailable: assuming WGS84");
    }

  // For each layer
  for (int layerIndex = 0; layerIndex < m_DataSource->GetLayerCount(); ++layerIndex)
    {
    /** retrieving layer and property */
    OGRLayer * layer = m_DataSource->GetLayer(layerIndex);
    otbMsgDevMacro(<< "Number of features: " << layer->GetFeatureCount());

    OGRFeatureDefn * dfn = layer->GetLayerDefn();

    /** Create the document node */
    DataNodePointerType document = DataNodeType::New();
    document->SetNodeType(DOCUMENT);
    document->SetNodeId(dfn->GetName());

    /** Retrieving the fields types */
//     OGRFieldDefn * field;
//     for (int fieldIndex = 0; fieldIndex<dfn->GetFieldCount(); ++fieldIndex)
//     {
//       field  = dfn->GetFieldDefn(fieldIndex);
//       document->SetField(field->GetNameRef(), OGRFieldDefn::GetFieldTypeName(field->GetType()));
//       // std::cout<<"Document "<<document->GetNodeId()<<": Adding field "<<field->GetNameRef()<<" "<<OGRFieldDefn::GetFieldTypeName(field->GetType())<<std::endl;
//     }

    /** Adding the layer to the data tree */
    tree->Add(document, root);

    /// This is not good but we do not have the choice if we want to
    /// get a hook on the internal structure
    InternalTreeNodeType * documentPtr = const_cast<InternalTreeNodeType *>(tree->GetNode(document));

    /** IO class helper to convert ogr layer*/

    OGRIOHelper::Pointer OGRConversion = OGRIOHelper::New();
    OGRConversion->ConvertOGRLayerToDataTreeNode(layer, documentPtr);

    } // end For each layer

  OGRDataSource::DestroyDataSource(m_DataSource);
  m_DataSource = NULL;
}

bool OGRVectorDataIO::CanWriteFile(const char* filename) const
{

  std::string lFileName(filename);
  if (System::IsADirName(lFileName) == true)
    {
    return false;
    }

  return (this->GetOGRDriverName(filename) != "NOT-FOUND");
}

void OGRVectorDataIO::Write(const itk::DataObject* datag, char ** papszOptions)
{
  itk::TimeProbe chrono;
  chrono.Start();

  VectorDataConstPointerType data = dynamic_cast<const VectorDataType*>(datag);

  //Find first the OGR driver
  OGRSFDriver * ogrDriver =
    OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(this->GetOGRDriverName(this->m_FileName).data());

  if (ogrDriver == NULL)
    {
    itkExceptionMacro(<< "No OGR driver found to write file " << this->m_FileName);
    }

  // free an existing previous data source, if any
  if (m_DataSource != NULL)
    {
    OGRDataSource::DestroyDataSource(m_DataSource);
    }

  // Erase the dataSource if already exist
  //TODO investigate the possibility of giving the option OVERWRITE=YES to the CreateDataSource method
  OGRDataSource * poDS = OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), TRUE);
  if (poDS != NULL)
    {
    //Erase the data if possible
    if (poDS->GetDriver()->TestCapability(ODrCDeleteDataSource))
      {
      //Delete datasource
      poDS->GetDriver()->DeleteDataSource(this->m_FileName.c_str());
      }
    }
  OGRDataSource::DestroyDataSource(poDS);

  // m_DataSource = OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), TRUE);
  m_DataSource = ogrDriver->CreateDataSource(this->m_FileName.c_str(), papszOptions);

  // check the created data source
  if (m_DataSource == NULL)
    {
    itkExceptionMacro(
      << "Failed to create OGR data source for file " << this->m_FileName <<
      ". Since OGR can not overwrite existing file, be sure that this file does not already exist");
    }

  // Retrieve data required for georeferencing

  std::string projectionRefWkt = data->GetProjectionRef();
  bool        projectionInformationAvailable = !projectionRefWkt.empty();

  if (projectionInformationAvailable)
    {
    otbMsgDevMacro(<< "Projection information : " << projectionRefWkt);
    }
  else
    {
    otbMsgDevMacro(<< "Projection information unavailable");
    }

  //TODO georeference here from OGRSpatialReference http://www.gdal.org/ogr/classOGRDataSource.html
  OGRSpatialReference * oSRS = NULL;
  if (projectionInformationAvailable)
    {
    oSRS = static_cast<OGRSpatialReference *>(OSRNewSpatialReference(projectionRefWkt.c_str()));
    }

  // Retrieving root node
  DataTreeConstPointerType tree = data->GetDataTree();
  if (tree->GetRoot() == NULL)
    {
    itkExceptionMacro(<< "Data tree is empty: Root == NULL");
    }
  DataNodePointerType root = tree->GetRoot()->Get();

  unsigned int layerKept;
  OGRLayer *   ogrCurrentLayer = NULL;
//   OGRFeatureVectorType ogrFeatures;
  OGRGeometryCollection * ogrCollection = NULL;
  // OGRGeometry * ogrCurrentGeometry = NULL;

  // Get the input tree root
  InternalTreeNodeType * inputRoot = const_cast<InternalTreeNodeType *>(tree->GetRoot());

  //Refactoring SHPIO Manuel
  OGRIOHelper::Pointer IOConversion = OGRIOHelper::New();
  layerKept = IOConversion->ProcessNodeWrite(inputRoot, m_DataSource, ogrCollection, ogrCurrentLayer, oSRS);

  otbMsgDevMacro( << "layerKept " << layerKept );

  OGRDataSource::DestroyDataSource(m_DataSource);
  m_DataSource = NULL;

  if (oSRS != NULL)
    {
    OSRRelease(oSRS);
    }

  chrono.Stop();
  otbMsgDevMacro( << "OGRVectorDataIO: file saved in " << chrono.GetMeanTime() << " seconds. (" << layerKept <<
  " elements)" );

  otbMsgDevMacro(<< " OGRVectorDataIO::Write()  ");
}

std::string
OGRVectorDataIO::GetOGRDriverName(std::string name) const
{
  std::string extension;
  std::string driverOGR;

  std::string upperName;
  upperName = name;
  std::transform(name.begin(), name.end(), upperName.begin(), (int (*)(int))toupper);

  //Test of PostGIS connection string
  if (upperName.substr(0, 3) == "PG:")
    {
    driverOGR = "PostgreSQL";
    }
  else
    {
    extension = System::GetExtension(upperName);
    if (extension == "SHP") driverOGR = "ESRI Shapefile";
    else if ((extension == "TAB")) driverOGR = "MapInfo File";
    else if (extension == "GML") driverOGR = "GML";
    else if (extension == "GPX") driverOGR = "GPX";
    else if (extension == "SQLITE") driverOGR = "SQLite";
//    else if (extension=="KML")
//      driverOGR="KML";
    else driverOGR = "NOT-FOUND";
    }
  //std::cout << name << " " << driverOGR <<" "<<upperName<< " "<< upperName.substr(0, 3) << std::endl;
  return driverOGR;
}

} // end namespace otb

#endif
<commit_msg>ENH: enable kml writing using OGR<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef __otbOGRVectorDataIO_txx
#define __otbOGRVectorDataIO_txx

#include "otbOGRVectorDataIO.h"

#include "ogrsf_frmts.h"

#include "itksys/SystemTools.hxx"

#include "itkByteSwapper.h"
#include "otbMacro.h"
#include "otbSystem.h"
#include "otbDataNode.h"
#include "otbMetaDataKey.h"
#include "itkTimeProbe.h"
#include "otbVectorDataKeywordlist.h"
#include "otbOGRIOHelper.h"

namespace otb
{

OGRVectorDataIO
::OGRVectorDataIO() :
  m_DataSource(NULL)
{
  // OGR factory registration
  OGRRegisterAll();
}

OGRVectorDataIO::~OGRVectorDataIO()
{
  if (m_DataSource != NULL)
    {
    OGRDataSource::DestroyDataSource(m_DataSource);
    }
}

bool
OGRVectorDataIO::CanReadFile(const char* filename) const
{
  OGRDataSource * poDS = OGRSFDriverRegistrar::Open(filename, FALSE);
  if (poDS == NULL)
    {
    return false;
    }
//     std::cout << poDS->GetDriver()->GetName() << std::endl;
  OGRDataSource::DestroyDataSource(poDS);
  return true;
}

// Used to print information about this object

void
OGRVectorDataIO::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os, indent);
}

// Read vector data

void
OGRVectorDataIO
::Read(itk::DataObject* datag)
{
  VectorDataPointerType data = dynamic_cast<VectorDataType*>(datag);
  // Destroy previous opened data source
  if (m_DataSource != NULL)
    {
    OGRDataSource::DestroyDataSource(m_DataSource);
    }

  m_DataSource = OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), FALSE);

  if (m_DataSource == NULL)
    {
    itkExceptionMacro(<< "Failed to open data file " << this->m_FileName);
    }

  otbMsgDebugMacro(<< "Driver to read: OGR");
  otbMsgDebugMacro(<< "Reading  file: " << this->m_FileName);

  // Reading layers
  otbMsgDevMacro(<< "Number of layers: " << m_DataSource->GetLayerCount());

  // Retrieving root node
  DataTreePointerType tree = data->GetDataTree();
  DataNodePointerType root = tree->GetRoot()->Get();

  OGRSpatialReference * oSRS = NULL;
  //We take the assumption that the spatial reference is common to all layers
  oSRS = m_DataSource->GetLayer(0)->GetSpatialRef();

  if (oSRS != NULL)
    {
    char * projectionRefChar;
    oSRS->exportToWkt(&projectionRefChar);
    std::string projectionRef = projectionRefChar;
    CPLFree(projectionRefChar);
    itk::MetaDataDictionary& dict = data->GetMetaDataDictionary();
    itk::EncapsulateMetaData<std::string>(dict, MetaDataKey::ProjectionRefKey, projectionRef);
    }
  else
    {
    otbMsgDevMacro(<< "Can't retrieve the OGRSpatialReference from the shapefile");
    }

  std::string projectionRefWkt = data->GetProjectionRef();

  bool projectionInformationAvailable = !projectionRefWkt.empty();

  if (projectionInformationAvailable)
    {
    otbMsgDevMacro(<< "Projection information : " << projectionRefWkt);
    }
  else
    {
    otbMsgDevMacro(<< "Projection information unavailable: assuming WGS84");
    }

  // For each layer
  for (int layerIndex = 0; layerIndex < m_DataSource->GetLayerCount(); ++layerIndex)
    {
    /** retrieving layer and property */
    OGRLayer * layer = m_DataSource->GetLayer(layerIndex);
    otbMsgDevMacro(<< "Number of features: " << layer->GetFeatureCount());

    OGRFeatureDefn * dfn = layer->GetLayerDefn();

    /** Create the document node */
    DataNodePointerType document = DataNodeType::New();
    document->SetNodeType(DOCUMENT);
    document->SetNodeId(dfn->GetName());

    /** Retrieving the fields types */
//     OGRFieldDefn * field;
//     for (int fieldIndex = 0; fieldIndex<dfn->GetFieldCount(); ++fieldIndex)
//     {
//       field  = dfn->GetFieldDefn(fieldIndex);
//       document->SetField(field->GetNameRef(), OGRFieldDefn::GetFieldTypeName(field->GetType()));
//       // std::cout<<"Document "<<document->GetNodeId()<<": Adding field "<<field->GetNameRef()<<" "<<OGRFieldDefn::GetFieldTypeName(field->GetType())<<std::endl;
//     }

    /** Adding the layer to the data tree */
    tree->Add(document, root);

    /// This is not good but we do not have the choice if we want to
    /// get a hook on the internal structure
    InternalTreeNodeType * documentPtr = const_cast<InternalTreeNodeType *>(tree->GetNode(document));

    /** IO class helper to convert ogr layer*/

    OGRIOHelper::Pointer OGRConversion = OGRIOHelper::New();
    OGRConversion->ConvertOGRLayerToDataTreeNode(layer, documentPtr);

    } // end For each layer

  OGRDataSource::DestroyDataSource(m_DataSource);
  m_DataSource = NULL;
}

bool OGRVectorDataIO::CanWriteFile(const char* filename) const
{

  std::string lFileName(filename);
  if (System::IsADirName(lFileName) == true)
    {
    return false;
    }

  return (this->GetOGRDriverName(filename) != "NOT-FOUND");
}

void OGRVectorDataIO::Write(const itk::DataObject* datag, char ** papszOptions)
{
  itk::TimeProbe chrono;
  chrono.Start();

  VectorDataConstPointerType data = dynamic_cast<const VectorDataType*>(datag);

  //Find first the OGR driver
  OGRSFDriver * ogrDriver =
    OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(this->GetOGRDriverName(this->m_FileName).data());

  if (ogrDriver == NULL)
    {
    itkExceptionMacro(<< "No OGR driver found to write file " << this->m_FileName);
    }

  // free an existing previous data source, if any
  if (m_DataSource != NULL)
    {
    OGRDataSource::DestroyDataSource(m_DataSource);
    }

  // Erase the dataSource if already exist
  //TODO investigate the possibility of giving the option OVERWRITE=YES to the CreateDataSource method
  OGRDataSource * poDS = OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), TRUE);
  if (poDS != NULL)
    {
    //Erase the data if possible
    if (poDS->GetDriver()->TestCapability(ODrCDeleteDataSource))
      {
      //Delete datasource
      poDS->GetDriver()->DeleteDataSource(this->m_FileName.c_str());
      }
    }
  OGRDataSource::DestroyDataSource(poDS);

  // m_DataSource = OGRSFDriverRegistrar::Open(this->m_FileName.c_str(), TRUE);
  m_DataSource = ogrDriver->CreateDataSource(this->m_FileName.c_str(), papszOptions);

  // check the created data source
  if (m_DataSource == NULL)
    {
    itkExceptionMacro(
      << "Failed to create OGR data source for file " << this->m_FileName <<
      ". Since OGR can not overwrite existing file, be sure that this file does not already exist");
    }

  // Retrieve data required for georeferencing

  std::string projectionRefWkt = data->GetProjectionRef();
  bool        projectionInformationAvailable = !projectionRefWkt.empty();

  if (projectionInformationAvailable)
    {
    otbMsgDevMacro(<< "Projection information : " << projectionRefWkt);
    }
  else
    {
    otbMsgDevMacro(<< "Projection information unavailable");
    }

  //TODO georeference here from OGRSpatialReference http://www.gdal.org/ogr/classOGRDataSource.html
  OGRSpatialReference * oSRS = NULL;
  if (projectionInformationAvailable)
    {
    oSRS = static_cast<OGRSpatialReference *>(OSRNewSpatialReference(projectionRefWkt.c_str()));
    }

  // Retrieving root node
  DataTreeConstPointerType tree = data->GetDataTree();
  if (tree->GetRoot() == NULL)
    {
    itkExceptionMacro(<< "Data tree is empty: Root == NULL");
    }
  DataNodePointerType root = tree->GetRoot()->Get();

  unsigned int layerKept;
  OGRLayer *   ogrCurrentLayer = NULL;
//   OGRFeatureVectorType ogrFeatures;
  OGRGeometryCollection * ogrCollection = NULL;
  // OGRGeometry * ogrCurrentGeometry = NULL;

  // Get the input tree root
  InternalTreeNodeType * inputRoot = const_cast<InternalTreeNodeType *>(tree->GetRoot());

  //Refactoring SHPIO Manuel
  OGRIOHelper::Pointer IOConversion = OGRIOHelper::New();
  layerKept = IOConversion->ProcessNodeWrite(inputRoot, m_DataSource, ogrCollection, ogrCurrentLayer, oSRS);

  otbMsgDevMacro( << "layerKept " << layerKept );

  OGRDataSource::DestroyDataSource(m_DataSource);
  m_DataSource = NULL;

  if (oSRS != NULL)
    {
    OSRRelease(oSRS);
    }

  chrono.Stop();
  otbMsgDevMacro( << "OGRVectorDataIO: file saved in " << chrono.GetMeanTime() << " seconds. (" << layerKept <<
  " elements)" );

  otbMsgDevMacro(<< " OGRVectorDataIO::Write()  ");
}

std::string
OGRVectorDataIO::GetOGRDriverName(std::string name) const
{
  std::string extension;
  std::string driverOGR;

  std::string upperName;
  upperName = name;
  std::transform(name.begin(), name.end(), upperName.begin(), (int (*)(int))toupper);

  //Test of PostGIS connection string
  if (upperName.substr(0, 3) == "PG:")
    {
    driverOGR = "PostgreSQL";
    }
  else
    {
    extension = System::GetExtension(upperName);
    if (extension == "SHP") driverOGR = "ESRI Shapefile";
    else if ((extension == "TAB")) driverOGR = "MapInfo File";
    else if (extension == "GML") driverOGR = "GML";
    else if (extension == "GPX") driverOGR = "GPX";
    else if (extension == "SQLITE") driverOGR = "SQLite";
     else if (extension=="KML") driverOGR="KML";
    else driverOGR = "NOT-FOUND";
    }
  //std::cout << name << " " << driverOGR <<" "<<upperName<< " "<< upperName.substr(0, 3) << std::endl;
  return driverOGR;
}

} // end namespace otb

#endif
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file DebuggingStateWrapper.cpp
 * @author Yann yann@ethdev.com
 * @date 2014
 * Used to translate c++ type (u256, bytes, ...) into friendly value (to be used by QML).
 */

#include <tuple>
#include <QDebug>
#include <QPointer>
#include <QQmlEngine>
#include <QVariantList>
#include <libevmcore/Instruction.h>
#include <libethcore/CommonJS.h>
#include <libdevcrypto/Common.h>
#include <libevmcore/Instruction.h>
#include <libdevcore/Common.h>
#include "DebuggingStateWrapper.h"
#include "QBigInt.h"
using namespace dev;
using namespace dev::eth;
using namespace dev::mix;

namespace
{
	static QVariantList memDumpToList(bytes const& _bytes, unsigned _width)
	{
		QVariantList dumpList;
		for (unsigned i = 0; i < _bytes.size(); i += _width)
		{
			std::stringstream ret;

			for (unsigned j = i; j < i + _width; ++j)
				if (j < _bytes.size())
					if (_bytes[j] >= 32 && _bytes[j] < 127)
						ret << (char)_bytes[j];
					else
						ret << '?';
				else
					ret << ' ';
			QString strPart = QString::fromStdString(ret.str());

			ret.clear();
			ret.str(std::string());

			for (unsigned j = i; j < i + _width && j < _bytes.size(); ++j)
				ret << std::setfill('0') << std::setw(2) << std::hex << (unsigned)_bytes[j] << " ";
			QString hexPart = QString::fromStdString(ret.str());

			QStringList line = { strPart, hexPart };
			dumpList.push_back(line);
		}
		return dumpList;
	}
}

QCode* QMachineState::getHumanReadableCode(QObject* _owner, const Address& _address, const bytes& _code, QHash<int, int>& o_codeMap)
{
	QVariantList codeStr;
	for (unsigned i = 0; i <= _code.size(); ++i)
	{
		byte b = i < _code.size() ? _code[i] : 0;
		try
		{
			QString s = QString::fromStdString(instructionInfo((Instruction)b).name);
			std::ostringstream out;
			out << std::hex << std::setw(4) << std::setfill('0') << i;
			int offset = i;
			if (b >= (byte)Instruction::PUSH1 && b <= (byte)Instruction::PUSH32)
			{
				unsigned bc = getPushNumber((Instruction)b);
				s = "PUSH 0x" + QString::fromStdString(toHex(bytesConstRef(&_code[i + 1], bc)));
				i += bc;
			}
			o_codeMap[offset] = codeStr.size();
			codeStr.append(QVariant::fromValue(new QInstruction(_owner, QString::fromStdString(out.str()) + "  "  + s)));
		}
		catch (...)
		{
			qDebug() << QString("Unhandled exception!") << endl <<
					 QString::fromStdString(boost::current_exception_diagnostic_information());
			break;	// probably hit data segment
		}
	}
	return new QCode(_owner, QString::fromStdString(toString(_address)), std::move(codeStr));
}

QBigInt* QMachineState::gasCost()
{
	return new QBigInt(m_state.gasCost);
}

QBigInt* QMachineState::gas()
{
	return new QBigInt(m_state.gas);
}

QBigInt* QMachineState::newMemSize()
{
	return new QBigInt(m_state.newMemSize);
}

QStringList QMachineState::debugStack()
{
	QStringList stack;
	for (std::vector<u256>::reverse_iterator i = m_state.stack.rbegin(); i != m_state.stack.rend(); ++i)
		stack.append(QString::fromStdString(prettyU256(*i)));
	return stack;
}

QStringList QMachineState::debugStorage()
{
	QStringList storage;
	for (auto const& i: m_state.storage)
	{
		std::stringstream s;
		s << "@" << prettyU256(i.first) << "\t" << prettyU256(i.second);
		storage.append(QString::fromStdString(s.str()));
	}
	return storage;
}

QVariantList QMachineState::debugMemory()
{
	return memDumpToList(m_state.memory, 16);
}

QCallData* QMachineState::getDebugCallData(QObject* _owner, bytes const& _data)
{
	return new QCallData(_owner, memDumpToList(_data, 16));
}

QVariantList QMachineState::levels()
{
	QVariantList levelList;
	for (unsigned l: m_state.levels)
		levelList.push_back(l);
	return levelList;
}

QString QMachineState::instruction()
{
	return QString::fromStdString(dev::eth::instructionInfo(m_state.inst).name);
}

QString QMachineState::endOfDebug()
{
	if (m_state.gasCost > m_state.gas)
		return QObject::tr("OUT-OF-GAS");
	else if (m_state.inst == Instruction::RETURN && m_state.stack.size() >= 2)
	{
		unsigned from = (unsigned)m_state.stack.back();
		unsigned size = (unsigned)m_state.stack[m_state.stack.size() - 2];
		unsigned o = 0;
		bytes out(size, 0);
		for (; o < size && from + o < m_state.memory.size(); ++o)
			out[o] = m_state.memory[from + o];
		return QObject::tr("RETURN") + " " + QString::fromStdString(dev::memDump(out, 16, false));
	}
	else if (m_state.inst == Instruction::STOP)
		return QObject::tr("STOP");
	else if (m_state.inst == Instruction::SUICIDE && m_state.stack.size() >= 1)
		return QObject::tr("SUICIDE") + " 0x" + QString::fromStdString(toString(right160(m_state.stack.back())));
	else
		return QObject::tr("EXCEPTION");
}
<commit_msg>Add memory address in memory dump.<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum 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.

	cpp-ethereum 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 cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file DebuggingStateWrapper.cpp
 * @author Yann yann@ethdev.com
 * @date 2014
 * Used to translate c++ type (u256, bytes, ...) into friendly value (to be used by QML).
 */

#include <tuple>
#include <QDebug>
#include <QPointer>
#include <QQmlEngine>
#include <QVariantList>
#include <libevmcore/Instruction.h>
#include <libethcore/CommonJS.h>
#include <libdevcrypto/Common.h>
#include <libevmcore/Instruction.h>
#include <libdevcore/Common.h>
#include "DebuggingStateWrapper.h"
#include "QBigInt.h"
using namespace dev;
using namespace dev::eth;
using namespace dev::mix;

namespace
{
	static QVariantList memDumpToList(bytes const& _bytes, unsigned _width, bool _includeAddress = false)
	{
		QVariantList dumpList;
		for (unsigned i = 0; i < _bytes.size(); i += _width)
		{
			std::stringstream ret;
			if (_includeAddress)
			{
				ret << std::setfill('0') << std::setw(6) << std::hex << i << " ";
				ret << "   ";
			}
			for (unsigned j = i; j < i + _width; ++j)
				if (j < _bytes.size())
					if (_bytes[j] >= 32 && _bytes[j] < 127)
						ret << (char)_bytes[j];
					else
						ret << '?';
				else
					ret << ' ';
			QString strPart = QString::fromStdString(ret.str());

			ret.clear();
			ret.str(std::string());

			for (unsigned j = i; j < i + _width && j < _bytes.size(); ++j)
				ret << std::setfill('0') << std::setw(2) << std::hex << (unsigned)_bytes[j] << " ";
			QString hexPart = QString::fromStdString(ret.str());

			QStringList line = { strPart, hexPart };
			dumpList.push_back(line);
		}
		return dumpList;
	}
}

QCode* QMachineState::getHumanReadableCode(QObject* _owner, const Address& _address, const bytes& _code, QHash<int, int>& o_codeMap)
{
	QVariantList codeStr;
	for (unsigned i = 0; i <= _code.size(); ++i)
	{
		byte b = i < _code.size() ? _code[i] : 0;
		try
		{
			QString s = QString::fromStdString(instructionInfo((Instruction)b).name);
			std::ostringstream out;
			out << std::hex << std::setw(4) << std::setfill('0') << i;
			int offset = i;
			if (b >= (byte)Instruction::PUSH1 && b <= (byte)Instruction::PUSH32)
			{
				unsigned bc = getPushNumber((Instruction)b);
				s = "PUSH 0x" + QString::fromStdString(toHex(bytesConstRef(&_code[i + 1], bc)));
				i += bc;
			}
			o_codeMap[offset] = codeStr.size();
			codeStr.append(QVariant::fromValue(new QInstruction(_owner, QString::fromStdString(out.str()) + "  "  + s)));
		}
		catch (...)
		{
			qDebug() << QString("Unhandled exception!") << endl <<
					 QString::fromStdString(boost::current_exception_diagnostic_information());
			break;	// probably hit data segment
		}
	}
	return new QCode(_owner, QString::fromStdString(toString(_address)), std::move(codeStr));
}

QBigInt* QMachineState::gasCost()
{
	return new QBigInt(m_state.gasCost);
}

QBigInt* QMachineState::gas()
{
	return new QBigInt(m_state.gas);
}

QBigInt* QMachineState::newMemSize()
{
	return new QBigInt(m_state.newMemSize);
}

QStringList QMachineState::debugStack()
{
	QStringList stack;
	for (std::vector<u256>::reverse_iterator i = m_state.stack.rbegin(); i != m_state.stack.rend(); ++i)
		stack.append(QString::fromStdString(prettyU256(*i)));
	return stack;
}

QStringList QMachineState::debugStorage()
{
	QStringList storage;
	for (auto const& i: m_state.storage)
	{
		std::stringstream s;
		s << "@" << prettyU256(i.first) << "\t" << prettyU256(i.second);
		storage.append(QString::fromStdString(s.str()));
	}
	return storage;
}

QVariantList QMachineState::debugMemory()
{
	return memDumpToList(m_state.memory, 16, true);
}

QCallData* QMachineState::getDebugCallData(QObject* _owner, bytes const& _data)
{
	return new QCallData(_owner, memDumpToList(_data, 16));
}

QVariantList QMachineState::levels()
{
	QVariantList levelList;
	for (unsigned l: m_state.levels)
		levelList.push_back(l);
	return levelList;
}

QString QMachineState::instruction()
{
	return QString::fromStdString(dev::eth::instructionInfo(m_state.inst).name);
}

QString QMachineState::endOfDebug()
{
	if (m_state.gasCost > m_state.gas)
		return QObject::tr("OUT-OF-GAS");
	else if (m_state.inst == Instruction::RETURN && m_state.stack.size() >= 2)
	{
		unsigned from = (unsigned)m_state.stack.back();
		unsigned size = (unsigned)m_state.stack[m_state.stack.size() - 2];
		unsigned o = 0;
		bytes out(size, 0);
		for (; o < size && from + o < m_state.memory.size(); ++o)
			out[o] = m_state.memory[from + o];
		return QObject::tr("RETURN") + " " + QString::fromStdString(dev::memDump(out, 16, false));
	}
	else if (m_state.inst == Instruction::STOP)
		return QObject::tr("STOP");
	else if (m_state.inst == Instruction::SUICIDE && m_state.stack.size() >= 1)
		return QObject::tr("SUICIDE") + " 0x" + QString::fromStdString(toString(right160(m_state.stack.back())));
	else
		return QObject::tr("EXCEPTION");
}
<|endoftext|>


<commit_before>#include "worklist3.h"
#include <iostream>
#include <stdlib.h>

//FILE *fp;
void node::set_data(int element)
{
	data = element;
}

void node::get_data()
{
	cout << data << " -> ";
}

linklist::linklist()
{
	//exit = 1; count = 0; length = 0; choice = 0; search = 0;
	num = 0; count = 0;
	first = new node;
	first->next = NULL;
}
linklist::~linklist()
{
	while (first != NULL && first->next != NULL)
	{
		//node *q;
		will = new node;
		//delete q->info.team;
		will = first;
		first = first->next;
		delete will;
	}
	cout << "ѵ" << endl;
	cout << "Աɾ" << endl;
}
bool linklist::creat(FILE *fp)
{
	if (fp == NULL)
	{
		cout << "open error!" << endl;
		return false;
	}
	else
	{
		cout << "open success!" << endl;
	}
	int num = 1;
	char s[10];
	int element;
	while ((fgets(s, 10, fp)) != NULL)
	{
		sscanf(s, "%d", &element);
		x = new node;
		x->set_data(element);
		now = first;
		count = 0;
		while (now != NULL && count < num - 1)
		{
			now = now->next;
			count++;
		}
		x->next = now->next;
		now->next = x;
		num++;
	}
	fclose(fp);
	return true;
}

void linklist::inversion()
{
	prev = NULL;
	now = first->next;
	will = now->next;
	while (now != NULL)
	{
		will = now->next;
		now->next = prev;
		prev = now;
		now = will;
	}
	first->next = prev;
}

void linklist::printlist()
{

	now = first->next;
	while (now != NULL)
	{
		now->get_data();
		now = now->next;
	}
}<commit_msg>debug the will = new node; 防止申请新节点后指针指向其他内存单元造成内存泄漏。<commit_after>#include "worklist3.h"
#include <iostream>
#include <stdlib.h>

//FILE *fp;
void node::set_data(int element)
{
	data = element;
}

void node::get_data()
{
	cout << data << " -> ";
}

linklist::linklist()
{
	//exit = 1; count = 0; length = 0; choice = 0; search = 0;
	num = 0; count = 0;
	first = new node;
	first->next = NULL;
}
linklist::~linklist()
{
	while (first != NULL && first->next != NULL)
	{
		//node *q;
		//will = new node;
		//delete q->info.team;
		will = first;
		first = first->next;
		delete will;
	}
	cout << "ѵ" << endl;
	cout << "Աɾ" << endl;
}
bool linklist::creat(FILE *fp)
{
	if (fp == NULL)
	{
		cout << "open error!" << endl;
		return false;
	}
	else
	{
		cout << "open success!" << endl;
	}
	int num = 1;
	char s[10];
	int element;
	while ((fgets(s, 10, fp)) != NULL)
	{
		sscanf(s, "%d", &element);
		x = new node;
		x->set_data(element);
		now = first;
		count = 0;
		while (now != NULL && count < num - 1)
		{
			now = now->next;
			count++;
		}
		x->next = now->next;
		now->next = x;
		num++;
	}
	fclose(fp);
	return true;
}

void linklist::inversion()
{
	prev = NULL;
	now = first->next;
	will = now->next;
	while (now != NULL)
	{
		will = now->next;
		now->next = prev;
		prev = now;
		now = will;
	}
	first->next = prev;
}

void linklist::printlist()
{

	now = first->next;
	while (now != NULL)
	{
		now->get_data();
		now = now->next;
	}
}<|endoftext|>


<commit_before>#include "xchainer/array_repr.h"

#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include <vector>

#ifdef XCHAINER_ENABLE_CUDA
#include <cuda_runtime.h>
#endif  // XCHAINER_ENABLE_CUDA

#include "xchainer/array.h"
#include "xchainer/array_node.h"
#include "xchainer/backend.h"
#ifdef XCHAINER_ENABLE_CUDA
#include "xchainer/cuda/cuda_runtime.h"
#endif  // XCHAINER_ENABLE_CUDA
#include "xchainer/dtype.h"
#include "xchainer/shape.h"

namespace xchainer {

namespace {

int GetNDigits(int64_t value) {
    int digits = 0;
    while (value != 0) {
        value /= 10;
        ++digits;
    }
    return digits;
}

void PrintNTimes(std::ostream& os, char c, int n) {
    while (n-- > 0) {
        os << c;
    }
}

class IntFormatter {
public:
    void Scan(int64_t value) {
        int digits = 0;
        if (value < 0) {
            ++digits;
            value = -value;
        }
        digits += GetNDigits(value);
        if (max_digits_ < digits) {
            max_digits_ = digits;
        }
    }

    void Print(std::ostream& os, int64_t value) const { os << std::setw(max_digits_) << std::right << value; }

private:
    int max_digits_ = 1;
};

class FloatFormatter {
public:
    void Scan(double value) {
        int b_digits = 0;
        if (value < 0) {
            has_minus_ = true;
            ++b_digits;
            value = -value;
        }
        if (std::isinf(value) || std::isnan(value)) {
            b_digits += 3;
            if (digits_before_point_ < b_digits) {
                digits_before_point_ = b_digits;
            }
            return;
        }
        if (value >= 100'000'000) {
            int e_digits = GetNDigits(static_cast<int64_t>(std::log10(value)));
            if (digits_after_e_ < e_digits) {
                digits_after_e_ = e_digits;
            }
        }
        if (digits_after_e_ > 0) {
            return;
        }

        const auto int_frac_parts = IntFracPartsToPrint(value);

        b_digits += GetNDigits(int_frac_parts.first);
        if (digits_before_point_ < b_digits) {
            digits_before_point_ = b_digits;
        }

        const int a_digits = GetNDigits(int_frac_parts.second) - 1;
        if (digits_after_point_ < a_digits) {
            digits_after_point_ = a_digits;
        }
    }

    void Print(std::ostream& os, double value) {
        if (digits_after_e_ > 0) {
            int width = 12 + (has_minus_ ? 1 : 0) + digits_after_e_;
            if (has_minus_ && !std::signbit(value)) {
                os << ' ';
                --width;
            }
            os << std::scientific << std::left << std::setw(width) << std::setprecision(8) << value;
        } else {
            if (std::isinf(value) || std::isnan(value)) {
                os << std::right << std::setw(digits_before_point_ + digits_after_point_ + 1) << value;
                return;
            }
            const auto int_frac_parts = IntFracPartsToPrint(value);
            const int a_digits = GetNDigits(int_frac_parts.second) - 1;
            os << std::fixed << std::right << std::setw(digits_before_point_ + a_digits + 1) << std::setprecision(a_digits)
               << std::showpoint << value;
            PrintNTimes(os, ' ', digits_after_point_ - a_digits);
        }
    }

private:
    // Returns the integral part and fractional part as integers.
    // Note that the fractional part is prefixed by 1 so that the information of preceeding zeros is not missed.
    static std::pair<int64_t, int64_t> IntFracPartsToPrint(double value) {
        double int_part;
        const double frac_part = std::modf(value, &int_part);

        auto shifted_frac_part = static_cast<int64_t>((std::abs(frac_part) + 1) * 100'000'000);
        while ((shifted_frac_part % 10) == 0) {
            shifted_frac_part /= 10;
        }

        return {static_cast<int64_t>(int_part), shifted_frac_part};
    }

    int digits_before_point_ = 1;
    int digits_after_point_ = 0;
    int digits_after_e_ = 0;
    bool has_minus_ = false;
};

class BoolFormatter {
public:
    void Scan(bool value) { (void)value; /* unused */ }

    void Print(std::ostream& os, bool value) const {
        os << (value ? " True" : "False");  // NOLINTER
    }
};

template <typename T>
using Formatter = std::conditional_t<std::is_same<T, bool>::value, BoolFormatter,
                                     std::conditional_t<std::is_floating_point<T>::value, FloatFormatter, IntFormatter>>;

struct ArrayReprImpl {
    template <typename T, typename Visitor>
    void VisitElements(const Array& array, Visitor&& visitor) const {
        // TODO(niboshi): Contiguousness is assumed.
        // TODO(niboshi): Replace with Indxer class.
        auto shape = array.shape();
        std::vector<int64_t> indexer;
        std::copy(shape.cbegin(), shape.cend(), std::back_inserter(indexer));
        std::shared_ptr<const T> data = std::static_pointer_cast<const T>(array.data());

// TODO(hvy): Only synchronize devices when it is really needed
#ifdef XCHAINER_ENABLE_CUDA
        cuda::CheckError(cudaDeviceSynchronize());
#endif  // XCHAINER_ENABLE_CUDA

        for (int64_t i = 0; i < array.GetTotalSize(); ++i) {
            // Increment indexer
            for (int j = shape.ndim() - 1; j >= 0; --j) {
                indexer[j]++;
                if (indexer[j] >= shape[j]) {
                    indexer[j] = 0;
                } else {
                    break;
                }
            }

            visitor(data.get()[i], &indexer[0]);
        }
    }

    template <typename T>
    void operator()(const Array& array, std::ostream& os) const {
        Formatter<T> formatter;

        // Let formatter scan all elements to print.
        VisitElements<T>(array, [&formatter](T value, const int64_t* index) {
            (void)index;  // unused
            formatter.Scan(value);
        });

        // Print values using the formatter.
        const int8_t ndim = array.ndim();
        int cur_line_size = 0;
        VisitElements<T>(array, [ndim, &cur_line_size, &formatter, &os](T value, const int64_t* index) {
            int8_t trailing_zeros = 0;
            if (ndim > 0) {
                for (auto it = index + ndim; --it >= index;) {
                    if (*it == 0) {
                        ++trailing_zeros;
                    } else {
                        break;
                    }
                }
            }
            if (trailing_zeros == ndim) {
                // This is the first iteration, so print the header
                os << "array(";
                PrintNTimes(os, '[', ndim);
            } else if (trailing_zeros > 0) {
                PrintNTimes(os, ']', trailing_zeros);
                os << ',';
                PrintNTimes(os, '\n', trailing_zeros);
                PrintNTimes(os, ' ', 6 + ndim - trailing_zeros);
                PrintNTimes(os, '[', trailing_zeros);
                cur_line_size = 0;
            } else {
                if (cur_line_size == 10) {
                    os << ",\n";
                    PrintNTimes(os, ' ', 6 + ndim);
                    cur_line_size = 0;
                } else {
                    os << ", ";
                }
            }
            formatter.Print(os, value);
            ++cur_line_size;
        });

        if (array.GetTotalSize() == 0) {
            // In case of an empty Array, print the header here
            os << "array([]";
        } else {
            PrintNTimes(os, ']', ndim);
        }

        // Print the footer
        os << ", shape=" << array.shape();
        os << ", dtype=" << array.dtype();
        os << ", device='" << array.device().name() << "'";
        const std::vector<std::shared_ptr<ArrayNode>>& nodes = array.nodes();
        if (!nodes.empty()) {
            os << ", graph_ids=[";
            for (size_t i = 0; i < nodes.size(); ++i) {
                if (i > 0) {
                    os << ", ";
                }
                os << '\'' << nodes[i]->graph_id() << '\'';
            }
            os << ']';
        }
        os << ')';
    }
};

}  // namespace

std::ostream& operator<<(std::ostream& os, const Array& array) {
    // TODO(hvy): We need to determine the output specification of this function, whether or not to align with Python repr specification,
    // and also whether this functionality should be defined in C++ layer or Python layer.
    VisitDtype(array.dtype(), [&](auto pt) { ArrayReprImpl{}.operator()<typename decltype(pt)::type>(array, os); });
    return os;
}

std::string ArrayRepr(const Array& array) {
    std::ostringstream os;
    os << array;
    return os.str();
}

}  // namespace xchainer
<commit_msg>Remove CUDA code from array_repr.cc<commit_after>#include "xchainer/array_repr.h"

#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include <vector>

#include "xchainer/array.h"
#include "xchainer/array_node.h"
#include "xchainer/backend.h"
#include "xchainer/dtype.h"
#include "xchainer/shape.h"

namespace xchainer {

namespace {

int GetNDigits(int64_t value) {
    int digits = 0;
    while (value != 0) {
        value /= 10;
        ++digits;
    }
    return digits;
}

void PrintNTimes(std::ostream& os, char c, int n) {
    while (n-- > 0) {
        os << c;
    }
}

class IntFormatter {
public:
    void Scan(int64_t value) {
        int digits = 0;
        if (value < 0) {
            ++digits;
            value = -value;
        }
        digits += GetNDigits(value);
        if (max_digits_ < digits) {
            max_digits_ = digits;
        }
    }

    void Print(std::ostream& os, int64_t value) const { os << std::setw(max_digits_) << std::right << value; }

private:
    int max_digits_ = 1;
};

class FloatFormatter {
public:
    void Scan(double value) {
        int b_digits = 0;
        if (value < 0) {
            has_minus_ = true;
            ++b_digits;
            value = -value;
        }
        if (std::isinf(value) || std::isnan(value)) {
            b_digits += 3;
            if (digits_before_point_ < b_digits) {
                digits_before_point_ = b_digits;
            }
            return;
        }
        if (value >= 100'000'000) {
            int e_digits = GetNDigits(static_cast<int64_t>(std::log10(value)));
            if (digits_after_e_ < e_digits) {
                digits_after_e_ = e_digits;
            }
        }
        if (digits_after_e_ > 0) {
            return;
        }

        const auto int_frac_parts = IntFracPartsToPrint(value);

        b_digits += GetNDigits(int_frac_parts.first);
        if (digits_before_point_ < b_digits) {
            digits_before_point_ = b_digits;
        }

        const int a_digits = GetNDigits(int_frac_parts.second) - 1;
        if (digits_after_point_ < a_digits) {
            digits_after_point_ = a_digits;
        }
    }

    void Print(std::ostream& os, double value) {
        if (digits_after_e_ > 0) {
            int width = 12 + (has_minus_ ? 1 : 0) + digits_after_e_;
            if (has_minus_ && !std::signbit(value)) {
                os << ' ';
                --width;
            }
            os << std::scientific << std::left << std::setw(width) << std::setprecision(8) << value;
        } else {
            if (std::isinf(value) || std::isnan(value)) {
                os << std::right << std::setw(digits_before_point_ + digits_after_point_ + 1) << value;
                return;
            }
            const auto int_frac_parts = IntFracPartsToPrint(value);
            const int a_digits = GetNDigits(int_frac_parts.second) - 1;
            os << std::fixed << std::right << std::setw(digits_before_point_ + a_digits + 1) << std::setprecision(a_digits)
               << std::showpoint << value;
            PrintNTimes(os, ' ', digits_after_point_ - a_digits);
        }
    }

private:
    // Returns the integral part and fractional part as integers.
    // Note that the fractional part is prefixed by 1 so that the information of preceeding zeros is not missed.
    static std::pair<int64_t, int64_t> IntFracPartsToPrint(double value) {
        double int_part;
        const double frac_part = std::modf(value, &int_part);

        auto shifted_frac_part = static_cast<int64_t>((std::abs(frac_part) + 1) * 100'000'000);
        while ((shifted_frac_part % 10) == 0) {
            shifted_frac_part /= 10;
        }

        return {static_cast<int64_t>(int_part), shifted_frac_part};
    }

    int digits_before_point_ = 1;
    int digits_after_point_ = 0;
    int digits_after_e_ = 0;
    bool has_minus_ = false;
};

class BoolFormatter {
public:
    void Scan(bool value) { (void)value; /* unused */ }

    void Print(std::ostream& os, bool value) const {
        os << (value ? " True" : "False");  // NOLINTER
    }
};

template <typename T>
using Formatter = std::conditional_t<std::is_same<T, bool>::value, BoolFormatter,
                                     std::conditional_t<std::is_floating_point<T>::value, FloatFormatter, IntFormatter>>;

struct ArrayReprImpl {
    template <typename T, typename Visitor>
    void VisitElements(const Array& array, Visitor&& visitor) const {
        // TODO(niboshi): Contiguousness is assumed.
        // TODO(niboshi): Replace with Indxer class.
        auto shape = array.shape();
        std::vector<int64_t> indexer;
        std::copy(shape.cbegin(), shape.cend(), std::back_inserter(indexer));
        std::shared_ptr<const T> data = std::static_pointer_cast<const T>(array.data());

        array.device().Synchronize();

        for (int64_t i = 0; i < array.GetTotalSize(); ++i) {
            // Increment indexer
            for (int j = shape.ndim() - 1; j >= 0; --j) {
                indexer[j]++;
                if (indexer[j] >= shape[j]) {
                    indexer[j] = 0;
                } else {
                    break;
                }
            }

            visitor(data.get()[i], &indexer[0]);
        }
    }

    template <typename T>
    void operator()(const Array& array, std::ostream& os) const {
        Formatter<T> formatter;

        // Let formatter scan all elements to print.
        VisitElements<T>(array, [&formatter](T value, const int64_t* index) {
            (void)index;  // unused
            formatter.Scan(value);
        });

        // Print values using the formatter.
        const int8_t ndim = array.ndim();
        int cur_line_size = 0;
        VisitElements<T>(array, [ndim, &cur_line_size, &formatter, &os](T value, const int64_t* index) {
            int8_t trailing_zeros = 0;
            if (ndim > 0) {
                for (auto it = index + ndim; --it >= index;) {
                    if (*it == 0) {
                        ++trailing_zeros;
                    } else {
                        break;
                    }
                }
            }
            if (trailing_zeros == ndim) {
                // This is the first iteration, so print the header
                os << "array(";
                PrintNTimes(os, '[', ndim);
            } else if (trailing_zeros > 0) {
                PrintNTimes(os, ']', trailing_zeros);
                os << ',';
                PrintNTimes(os, '\n', trailing_zeros);
                PrintNTimes(os, ' ', 6 + ndim - trailing_zeros);
                PrintNTimes(os, '[', trailing_zeros);
                cur_line_size = 0;
            } else {
                if (cur_line_size == 10) {
                    os << ",\n";
                    PrintNTimes(os, ' ', 6 + ndim);
                    cur_line_size = 0;
                } else {
                    os << ", ";
                }
            }
            formatter.Print(os, value);
            ++cur_line_size;
        });

        if (array.GetTotalSize() == 0) {
            // In case of an empty Array, print the header here
            os << "array([]";
        } else {
            PrintNTimes(os, ']', ndim);
        }

        // Print the footer
        os << ", shape=" << array.shape();
        os << ", dtype=" << array.dtype();
        os << ", device='" << array.device().name() << "'";
        const std::vector<std::shared_ptr<ArrayNode>>& nodes = array.nodes();
        if (!nodes.empty()) {
            os << ", graph_ids=[";
            for (size_t i = 0; i < nodes.size(); ++i) {
                if (i > 0) {
                    os << ", ";
                }
                os << '\'' << nodes[i]->graph_id() << '\'';
            }
            os << ']';
        }
        os << ')';
    }
};

}  // namespace

std::ostream& operator<<(std::ostream& os, const Array& array) {
    // TODO(hvy): We need to determine the output specification of this function, whether or not to align with Python repr specification,
    // and also whether this functionality should be defined in C++ layer or Python layer.
    VisitDtype(array.dtype(), [&](auto pt) { ArrayReprImpl{}.operator()<typename decltype(pt)::type>(array, os); });
    return os;
}

std::string ArrayRepr(const Array& array) {
    std::ostringstream os;
    os << array;
    return os.str();
}

}  // namespace xchainer
<|endoftext|>


<commit_before>/** ---------------------------------------------------------------------------
 * @file: shader.cpp
 *
 * Copyright (c) 2017 Yann Herklotz Grave <ymherklotz@gmail.com>
 * MIT License, see LICENSE file for more details.
 * ----------------------------------------------------------------------------
 */

#include "shader.h"

#include <fstream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

using std::runtime_error;

namespace yage
{

Shader::Shader(const std::string &vertex_path, const std::string &fragment_path)
{
    std::string vertex_source, fragment_source;
    std::ifstream vertex_file, fragment_file;

    vertex_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    fragment_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);

    try {
        vertex_file.open(vertex_path);
        fragment_file.open(fragment_path);

        std::ostringstream vertex_stream, fragment_stream;
        vertex_stream << vertex_file.rdbuf();
        fragment_stream << fragment_file.rdbuf();

        vertex_file.close();
        fragment_file.close();

        vertex_source   = vertex_stream.str();
        fragment_source = fragment_stream.str();
    } catch (std::ifstream::failure e) {
        throw runtime_error("File could not be opened: " +
                            std::string(e.what()));
    }

    const char *vertex_source_c   = vertex_source.c_str();
    const char *fragment_source_c = fragment_source.c_str();

    GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, &vertex_source_c, NULL);
    glCompileShader(vertex_shader);
    errorCheck(vertex_shader, "vertex");

    GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, &fragment_source_c, NULL);
    glCompileShader(fragment_shader);
    errorCheck(fragment_shader, "fragment");

    program_id_ = glCreateProgram();
    glAttachShader(program_id_, vertex_shader);
    glAttachShader(program_id_, fragment_shader);
    glLinkProgram(program_id_);
    errorCheck(program_id_, "program");

    glDetachShader(program_id_, vertex_shader);
    glDetachShader(program_id_, fragment_shader);

    glDeleteShader(vertex_shader);
    glDeleteShader(fragment_shader);
}

Shader::~Shader()
{
    /// cleans up all the shaders and the program
    if (program_id_ != 0) {
        glDeleteProgram(program_id_);
    }
}

void Shader::use() const
{
    glUseProgram(program_id_);
}

void Shader::setUniform(const std::string &name, int value) const
{
    glUniform1i(getUniformLocation(name), static_cast<GLint>(value));
}

void Shader::setUniform(const std::string &name, float value) const
{
    glUniform1f(getUniformLocation(name), static_cast<GLfloat>(value));
}

void Shader::setUniform(const std::string &name, const glm::mat4 &matrix) const
{
    glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &(matrix[0][0]));
}

GLint Shader::getUniformLocation(const std::string &uniform_name) const
{
    GLint location = glGetUniformLocation(program_id_, uniform_name.c_str());
    if (location == GL_INVALID_INDEX) {
        throw std::runtime_error("'" + uniform_name + "' not found");
    }
    return location;
}

void Shader::errorCheck(GLuint shader, const std::string &shader_type) const
{
    int success;
    char info_log[1024];
    if (shader_type != std::string("program")) {
        glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
        if (!success) {
            glGetShaderInfoLog(shader, 1024, NULL, info_log);
            throw runtime_error(shader_type +
                                " failed to compile: " + std::string(info_log));
        }
    } else {
        glGetProgramiv(shader, GL_LINK_STATUS, &success);
        if (!success) {
            glGetProgramInfoLog(shader, 1024, NULL, info_log);
            throw runtime_error(shader_type +
                                " failed to link: " + std::string(info_log));
        }
    }
}

} // namespace yage
<commit_msg>[Bug fix] Changed int to unsigned.<commit_after>/** ---------------------------------------------------------------------------
 * @file: shader.cpp
 *
 * Copyright (c) 2017 Yann Herklotz Grave <ymherklotz@gmail.com>
 * MIT License, see LICENSE file for more details.
 * ----------------------------------------------------------------------------
 */

#include "shader.h"

#include <fstream>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

using std::runtime_error;

namespace yage
{

Shader::Shader(const std::string &vertex_path, const std::string &fragment_path)
{
    std::string vertex_source, fragment_source;
    std::ifstream vertex_file, fragment_file;

    vertex_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    fragment_file.exceptions(std::ifstream::failbit | std::ifstream::badbit);

    try {
        vertex_file.open(vertex_path);
        fragment_file.open(fragment_path);

        std::ostringstream vertex_stream, fragment_stream;
        vertex_stream << vertex_file.rdbuf();
        fragment_stream << fragment_file.rdbuf();

        vertex_file.close();
        fragment_file.close();

        vertex_source   = vertex_stream.str();
        fragment_source = fragment_stream.str();
    } catch (std::ifstream::failure e) {
        throw runtime_error("File could not be opened: " +
                            std::string(e.what()));
    }

    const char *vertex_source_c   = vertex_source.c_str();
    const char *fragment_source_c = fragment_source.c_str();

    GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, &vertex_source_c, NULL);
    glCompileShader(vertex_shader);
    errorCheck(vertex_shader, "vertex");

    GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, &fragment_source_c, NULL);
    glCompileShader(fragment_shader);
    errorCheck(fragment_shader, "fragment");

    program_id_ = glCreateProgram();
    glAttachShader(program_id_, vertex_shader);
    glAttachShader(program_id_, fragment_shader);
    glLinkProgram(program_id_);
    errorCheck(program_id_, "program");

    glDetachShader(program_id_, vertex_shader);
    glDetachShader(program_id_, fragment_shader);

    glDeleteShader(vertex_shader);
    glDeleteShader(fragment_shader);
}

Shader::~Shader()
{
    /// cleans up all the shaders and the program
    if (program_id_ != 0) {
        glDeleteProgram(program_id_);
    }
}

void Shader::use() const
{
    glUseProgram(program_id_);
}

void Shader::setUniform(const std::string &name, int value) const
{
    glUniform1i(getUniformLocation(name), static_cast<GLint>(value));
}

void Shader::setUniform(const std::string &name, float value) const
{
    glUniform1f(getUniformLocation(name), static_cast<GLfloat>(value));
}

void Shader::setUniform(const std::string &name, const glm::mat4 &matrix) const
{
    glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &(matrix[0][0]));
}

GLint Shader::getUniformLocation(const std::string &uniform_name) const
{
    GLuint location = glGetUniformLocation(program_id_, uniform_name.c_str());
    if (location == GL_INVALID_INDEX) {
        throw std::runtime_error("'" + uniform_name + "' not found");
    }
    return location;
}

void Shader::errorCheck(GLuint shader, const std::string &shader_type) const
{
    int success;
    char info_log[1024];
    if (shader_type != std::string("program")) {
        glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
        if (!success) {
            glGetShaderInfoLog(shader, 1024, NULL, info_log);
            throw runtime_error(shader_type +
                                " failed to compile: " + std::string(info_log));
        }
    } else {
        glGetProgramiv(shader, GL_LINK_STATUS, &success);
        if (!success) {
            glGetProgramInfoLog(shader, 1024, NULL, info_log);
            throw runtime_error(shader_type +
                                " failed to link: " + std::string(info_log));
        }
    }
}

} // namespace yage
<|endoftext|>


<commit_before>/* -*- mode: c++; c-basic-offset:4 -*-
    systemtrayicon.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Kleopatra 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, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "systemtrayicon.h"

#include <KIcon>
#include <KLocale>
#include <KAboutApplicationDialog>
#include <KAboutData>
#include <KComponentData>

#include <QMenu>
#include <QAction>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QLabel>
#include <QDialog>
#include <QDialogButtonBox>
#include <QPushButton>

#include <QCoreApplication>
#include <QProcess>
#include <QPointer>

#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>

#include <cassert>

using namespace boost;

class SystemTrayIcon::Private {
    friend class ::SystemTrayIcon;
    SystemTrayIcon * const q;
public:
    explicit Private( SystemTrayIcon * qq );
    ~Private();

private:
    void slotOpenCertificateManager() {
        emit q->activated( QSystemTrayIcon::Trigger );
    }
    void slotAbout() {
        if ( !aboutDialog ) {
            aboutDialog = new KAboutApplicationDialog( KGlobal::mainComponent().aboutData() );
            aboutDialog->setAttribute( Qt::WA_DeleteOnClose );
        }

        if ( aboutDialog->isVisible() )
            aboutDialog->raise();
        else
            aboutDialog->show();

    }
    void slotCheckConfiguration();

private:
    QMenu menu;
    QAction openCertificateManagerAction;
    QAction aboutAction;
    QAction checkConfigAction;
    QAction quitAction;

    QPointer<KAboutApplicationDialog> aboutDialog;
};

SystemTrayIcon::Private::Private( SystemTrayIcon * qq )
    : q( qq ),
      menu(),
      openCertificateManagerAction( i18n("&Open Certificate Manager..."), q ),
      aboutAction( i18n("&About %1...", KGlobal::mainComponent().aboutData()->programName() ), q ),
      checkConfigAction( i18n("&Check GnuPG Config..."), q ),
      quitAction( i18n("&Shutdown Kleopatra"), q ),
      aboutDialog()
{
    KDAB_SET_OBJECT_NAME( menu );
    KDAB_SET_OBJECT_NAME( openCertificateManagerAction );
    KDAB_SET_OBJECT_NAME( aboutAction );
    KDAB_SET_OBJECT_NAME( checkConfigAction );
    KDAB_SET_OBJECT_NAME( quitAction );

    connect( &openCertificateManagerAction, SIGNAL(triggered()), q, SLOT(slotOpenCertificateManager()) );
    connect( &aboutAction, SIGNAL(triggered()), q, SLOT(slotAbout()) );
    connect( &quitAction, SIGNAL(triggered()), QCoreApplication::instance(), SLOT(quit()) );
    connect( &checkConfigAction, SIGNAL(triggered()), q, SLOT(slotCheckConfiguration()) );

    menu.addAction( &openCertificateManagerAction );
    menu.addAction( &aboutAction );
    menu.addSeparator();
    menu.addAction( &checkConfigAction );
    menu.addSeparator();
    menu.addAction( &quitAction );

    q->setContextMenu( &menu );
}

SystemTrayIcon::Private::~Private() {}

SystemTrayIcon::SystemTrayIcon( QObject * p )
    : QSystemTrayIcon( KIcon( "gpg" ), p ), d( new Private( this ) )
{

}

SystemTrayIcon::~SystemTrayIcon() {}

void SystemTrayIcon::Private::slotCheckConfiguration() {
    assert( checkConfigAction.isEnabled() );
    if ( !checkConfigAction.isEnabled() )
        return;

    checkConfigAction.setEnabled( false );
    const shared_ptr<QAction> enabler( &checkConfigAction, bind( &QAction::setEnabled, _1, true ) );

    // 1. start process
    QProcess process;
    process.setProcessChannelMode( QProcess::MergedChannels );
    process.start( "gpgconf", QStringList() << "--check-config", QIODevice::ReadOnly );

    // 2. show dialog:
    QDialog dlg;
    QVBoxLayout vlay( &dlg );
    QLabel label( i18n("This is the result of the GnuPG config check:" ), &dlg );
    QTextEdit textEdit( &dlg );
    QDialogButtonBox box( QDialogButtonBox::Close, Qt::Horizontal, &dlg );

    textEdit.setReadOnly( true );
    textEdit.setWordWrapMode( QTextOption::NoWrap );

    vlay.addWidget( &label );
    vlay.addWidget( &textEdit, 1 );
    vlay.addWidget( &box );

    dlg.show();

    connect( box.button( QDialogButtonBox::Close ), SIGNAL(clicked()), &dlg, SLOT(reject()) );
    connect( &dlg, SIGNAL(finished(int)), &process, SLOT(terminate()) );

    // 3. wait for either dialog close or process exit
    QEventLoop loop;
    connect( &process, SIGNAL(finished(int,QProcess::ExitStatus)), &loop, SLOT(quit()) );
    connect( &dlg, SIGNAL(finished(int)), &loop, SLOT(quit()) );

    const QPointer<QObject> Q( q );
    loop.exec();

    // safety exit:
    if ( !Q )
        return;

    // check whether it was the dialog that was closed, and return in
    // that case:
    if ( !dlg.isVisible() )
        return;

    if ( process.error() != QProcess::UnknownError )
        textEdit.setPlainText( QString::fromUtf8( process.readAll() ) + '\n' + process.errorString() );
    else
        textEdit.setPlainText( QString::fromUtf8( process.readAll() ) );

    // wait for dialog close:
    assert( dlg.isVisible() );
    loop.exec();
}

#include "moc_systemtrayicon.cpp"

<commit_msg>use kleopatra icon for the systray<commit_after>/* -*- mode: c++; c-basic-offset:4 -*-
    systemtrayicon.cpp

    This file is part of Kleopatra, the KDE keymanager
    Copyright (c) 2007 Klarälvdalens Datakonsult AB

    Kleopatra is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Kleopatra 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, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "systemtrayicon.h"

#include <KIcon>
#include <KLocale>
#include <KAboutApplicationDialog>
#include <KAboutData>
#include <KComponentData>

#include <QMenu>
#include <QAction>
#include <QVBoxLayout>
#include <QTextEdit>
#include <QLabel>
#include <QDialog>
#include <QDialogButtonBox>
#include <QPushButton>

#include <QCoreApplication>
#include <QProcess>
#include <QPointer>

#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>

#include <cassert>

using namespace boost;

class SystemTrayIcon::Private {
    friend class ::SystemTrayIcon;
    SystemTrayIcon * const q;
public:
    explicit Private( SystemTrayIcon * qq );
    ~Private();

private:
    void slotOpenCertificateManager() {
        emit q->activated( QSystemTrayIcon::Trigger );
    }
    void slotAbout() {
        if ( !aboutDialog ) {
            aboutDialog = new KAboutApplicationDialog( KGlobal::mainComponent().aboutData() );
            aboutDialog->setAttribute( Qt::WA_DeleteOnClose );
        }

        if ( aboutDialog->isVisible() )
            aboutDialog->raise();
        else
            aboutDialog->show();

    }
    void slotCheckConfiguration();

private:
    QMenu menu;
    QAction openCertificateManagerAction;
    QAction aboutAction;
    QAction checkConfigAction;
    QAction quitAction;

    QPointer<KAboutApplicationDialog> aboutDialog;
};

SystemTrayIcon::Private::Private( SystemTrayIcon * qq )
    : q( qq ),
      menu(),
      openCertificateManagerAction( i18n("&Open Certificate Manager..."), q ),
      aboutAction( i18n("&About %1...", KGlobal::mainComponent().aboutData()->programName() ), q ),
      checkConfigAction( i18n("&Check GnuPG Config..."), q ),
      quitAction( i18n("&Shutdown Kleopatra"), q ),
      aboutDialog()
{
    KDAB_SET_OBJECT_NAME( menu );
    KDAB_SET_OBJECT_NAME( openCertificateManagerAction );
    KDAB_SET_OBJECT_NAME( aboutAction );
    KDAB_SET_OBJECT_NAME( checkConfigAction );
    KDAB_SET_OBJECT_NAME( quitAction );

    connect( &openCertificateManagerAction, SIGNAL(triggered()), q, SLOT(slotOpenCertificateManager()) );
    connect( &aboutAction, SIGNAL(triggered()), q, SLOT(slotAbout()) );
    connect( &quitAction, SIGNAL(triggered()), QCoreApplication::instance(), SLOT(quit()) );
    connect( &checkConfigAction, SIGNAL(triggered()), q, SLOT(slotCheckConfiguration()) );

    menu.addAction( &openCertificateManagerAction );
    menu.addAction( &aboutAction );
    menu.addSeparator();
    menu.addAction( &checkConfigAction );
    menu.addSeparator();
    menu.addAction( &quitAction );

    q->setContextMenu( &menu );
}

SystemTrayIcon::Private::~Private() {}

SystemTrayIcon::SystemTrayIcon( QObject * p )
    : QSystemTrayIcon( KIcon( "kleopatra" ), p ), d( new Private( this ) )
{

}

SystemTrayIcon::~SystemTrayIcon() {}

void SystemTrayIcon::Private::slotCheckConfiguration() {
    assert( checkConfigAction.isEnabled() );
    if ( !checkConfigAction.isEnabled() )
        return;

    checkConfigAction.setEnabled( false );
    const shared_ptr<QAction> enabler( &checkConfigAction, bind( &QAction::setEnabled, _1, true ) );

    // 1. start process
    QProcess process;
    process.setProcessChannelMode( QProcess::MergedChannels );
    process.start( "gpgconf", QStringList() << "--check-config", QIODevice::ReadOnly );

    // 2. show dialog:
    QDialog dlg;
    QVBoxLayout vlay( &dlg );
    QLabel label( i18n("This is the result of the GnuPG config check:" ), &dlg );
    QTextEdit textEdit( &dlg );
    QDialogButtonBox box( QDialogButtonBox::Close, Qt::Horizontal, &dlg );

    textEdit.setReadOnly( true );
    textEdit.setWordWrapMode( QTextOption::NoWrap );

    vlay.addWidget( &label );
    vlay.addWidget( &textEdit, 1 );
    vlay.addWidget( &box );

    dlg.show();

    connect( box.button( QDialogButtonBox::Close ), SIGNAL(clicked()), &dlg, SLOT(reject()) );
    connect( &dlg, SIGNAL(finished(int)), &process, SLOT(terminate()) );

    // 3. wait for either dialog close or process exit
    QEventLoop loop;
    connect( &process, SIGNAL(finished(int,QProcess::ExitStatus)), &loop, SLOT(quit()) );
    connect( &dlg, SIGNAL(finished(int)), &loop, SLOT(quit()) );

    const QPointer<QObject> Q( q );
    loop.exec();

    // safety exit:
    if ( !Q )
        return;

    // check whether it was the dialog that was closed, and return in
    // that case:
    if ( !dlg.isVisible() )
        return;

    if ( process.error() != QProcess::UnknownError )
        textEdit.setPlainText( QString::fromUtf8( process.readAll() ) + '\n' + process.errorString() );
    else
        textEdit.setPlainText( QString::fromUtf8( process.readAll() ) );

    // wait for dialog close:
    assert( dlg.isVisible() );
    loop.exec();
}

#include "moc_systemtrayicon.cpp"

<|endoftext|>


<commit_before>/*
Copyright (c) 2015,
Dan Bethell, Johannes Saam, Vahan Sosoyan.
All rights reserved. See Copyright.txt for more details.
 */

#include "Client.h"
#include <boost/lexical_cast.hpp>
#include <stdexcept>
#include <iostream>

using namespace aton;
using boost::asio::ip::tcp;

Client::Client( std::string hostname, int port ) :
                mHost( hostname ),
                mPort( port ),
                mImageId( -1 ),
                mSocket( mIoService )
{
}

void Client::connect( std::string hostname, int port )
{
    bool result = true;
    tcp::resolver resolver(mIoService);
    tcp::resolver::query query( hostname.c_str(), boost::lexical_cast<std::string>(port).c_str() );
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    tcp::resolver::iterator end;
    boost::system::error_code error = boost::asio::error::host_not_found;
    while (error && endpoint_iterator != end)
    {
        mSocket.close();
        mSocket.connect(*endpoint_iterator++, error);
    }
    if (error)
        throw boost::system::system_error(error);
}

void Client::disconnect()
{
    mSocket.close();
}

Client::~Client()
{
    disconnect();
}

void Client::openImage( Data &header )
{
    // connect to port!
    connect(mHost, mPort);

    // send image header message with image desc information
    int key = 0;
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&key), sizeof(int)) );

    // read our imageid
    boost::asio::read( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&mImageId), sizeof(int)) );

    // send our width & height
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&header.mWidth), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&header.mHeight), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&header.mRArea), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&header.mVersion), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&header.mCurrentFrame), sizeof(float)) );
}

void Client::sendPixels( Data &data )
{
    if ( mImageId<0 )
    {
        throw std::runtime_error( "Could not send data - image id is not valid!" );
    }

    // send data for image_id
    int key = 1;
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&key), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&mImageId), sizeof(int)) );

    // get size of the aov name in bytes
    size_t aov_size = strlen(data.mAovName)+1;

    // send pixel data
    int num_samples = data.mWidth * data.mHeight * data.mSpp;
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mX), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mY), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mWidth), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mHeight), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mRArea), sizeof(long long)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mVersion), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mCurrentFrame), sizeof(float)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mSpp), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mRam), sizeof(long long)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mTime), sizeof(int)) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&aov_size), sizeof(size_t)) );
    boost::asio::write( mSocket, boost::asio::buffer(data.mAovName, aov_size) );
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mpData[0]), sizeof(float)*num_samples) );
}

void Client::closeImage( )
{
    // send image complete message for image_id
    int key = 2;
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&key), sizeof(int)) );

    // tell the server which image we're closing
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&mImageId), sizeof(int)) );

    // disconnect from port!
    disconnect();
}

void Client::quit()
{
    connect(mHost, mPort);
    int key = 9;
    boost::asio::write( mSocket, boost::asio::buffer(reinterpret_cast<char*>(&key), sizeof(int)) );
    disconnect();
}
<commit_msg>Polish<commit_after>/*
Copyright (c) 2015,
Dan Bethell, Johannes Saam, Vahan Sosoyan.
All rights reserved. See Copyright.txt for more details.
 */

#include "Client.h"
#include <boost/lexical_cast.hpp>
#include <stdexcept>
#include <iostream>

using namespace aton;
using boost::asio::ip::tcp;

Client::Client(std::string hostname, int port) :
               mHost(hostname),
               mPort(port),
               mImageId(-1),
               mSocket(mIoService)
{
}

void Client::connect(std::string hostname, int port)
{
    bool result = true;
    tcp::resolver resolver(mIoService);
    tcp::resolver::query query(hostname.c_str(), boost::lexical_cast<std::string>(port).c_str());
    tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
    tcp::resolver::iterator end;
    boost::system::error_code error = boost::asio::error::host_not_found;
    while (error && endpoint_iterator != end)
    {
        mSocket.close();
        mSocket.connect(*endpoint_iterator++, error);
    }
    if (error)
        throw boost::system::system_error(error);
}

void Client::disconnect()
{
    mSocket.close();
}

Client::~Client()
{
    disconnect();
}

void Client::openImage(Data& header)
{
    // connect to port!
    connect(mHost, mPort);

    // send image header message with image desc information
    int key = 0;
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&key), sizeof(int)));

    // read our imageid
    boost::asio::read(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&mImageId), sizeof(int)));

    // send our width & height
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&header.mWidth), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&header.mHeight), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&header.mRArea), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&header.mVersion), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&header.mCurrentFrame), sizeof(float)));
}

void Client::sendPixels(Data& data)
{
    if (mImageId < 0)
    {
        throw std::runtime_error("Could not send data - image id is not valid!");
    }

    // send data for image_id
    int key = 1;
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&key), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&mImageId), sizeof(int)));

    // get size of the aov name in bytes
    size_t aov_size = strlen(data.mAovName)+1;

    // send pixel data
    int num_samples = data.mWidth * data.mHeight * data.mSpp;
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mX), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mY), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mWidth), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mHeight), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mRArea), sizeof(long long)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mVersion), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mCurrentFrame), sizeof(float)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mSpp), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mRam), sizeof(long long)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mTime), sizeof(int)));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&aov_size), sizeof(size_t)));
    boost::asio::write(mSocket, boost::asio::buffer(data.mAovName, aov_size));
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&data.mpData[0]), sizeof(float)*num_samples));
}

void Client::closeImage()
{
    // send image complete message for image_id
    int key = 2;
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&key), sizeof(int)));

    // tell the server which image we're closing
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&mImageId), sizeof(int)));

    // disconnect from port!
    disconnect();
}

void Client::quit()
{
    connect(mHost, mPort);
    int key = 9;
    boost::asio::write(mSocket, boost::asio::buffer(reinterpret_cast<char*>(&key), sizeof(int)));
    disconnect();
}
<|endoftext|>


<commit_before>/* Copyright (c) 2017 Wenova - Rise of Conquerors. All rights reserved.
 *
 * This work is licensed under the terms of the MIT license.
 * For a copy, see <https://opensource.org/licenses/MIT>.
 */
/**
 * @file Config.cpp
 * Implements class Config methods.
 */

#include "Config.h"

int Config::width;
int Config::height;
int Config::fullscreen;

/**
 * Will write current screen configurations to res/config_file.dat.
 */
void Config::init() {
    LOG(INFO) << "Starting CharacterSelectState init";

    std::fstream config_file(CONFIGURATION_FILE_PATH);

    if (not config_file.is_open()) {
        LOG(FATAL) << "File couldn't be open";
    }
    assert(config_file.is_open());

    config_file >> width >> height >> fullscreen;

    LOG(INFO) << "Ending CharacterSelectState init";
}

/**
 * Accessor to width private attribute.
 *
 * @returns Game's windows width. Unit: px, [0,]
 */
int Config::get_width() {
    LOG(INFO) << "Starting CharacterSelectState get_width";

    int return_value = width;

    std::string log_message = "Ending CharacterSelectState get_width returning value: " + std::to_string(return_value);
    LOG(INFO) << log_message;

    return return_value;
}

/**
 * Accessor to height private attribute.
 * @returns  Game's windows height. Unit: px, [0,]
 */
int Config::get_height() {
    LOG(INFO) << "Starting CharacterSelectState get_height";

    int return_value = height;

    std::string log_message = "Ending CharacterSelectState get_height returning value: " + std::to_string(return_value);
    LOG(INFO) << log_message;

    return return_value;
}

/**
 * Get fullscreen current status.
 *
 * @returns 0 for no, 1 for yes [0,1]
 */
int Config::is_fullscreen() {
    LOG(INFO) << "Starting CharacterSelectState is_fullscreen";

    int return_value = fullscreen;

    std::string log_message = "Ending CharacterSelectState is_fullscreen returning value: " + std::to_string(return_value);
    LOG(INFO) << log_message;

    return return_value;
}

/**
 * Writes to file res/config_file.dat screen information.
 *
 * @param cwidth Unit: px, [0,]
 * @param cheight Unit: px, [0,]
 * @param cfullscreen [0,1]
 */
void Config::update_information(int cwidth, int cheight, int cfullscreen) {
    std::string log_message = "Starting CharacterSelectState update_information, cwidth: ";
    log_message += std::to_string(cwidth) += ", cheight: ";
    log_message += std::to_string(cheight) + ", cfullscreen: " + std::to_string(cfullscreen);

    LOG(INFO) << log_message;

    width = cwidth;
    height = cheight;
    fullscreen = cfullscreen;

    std::ofstream config_file(CONFIGURATION_FILE_PATH, std::ios::trunc);

    if (not config_file.is_open()) {
        LOG(FATAL) << "File couldn't be open";
    }
    assert(config_file.is_open());

    config_file << width << " " << height << " " << fullscreen << std::endl;
    config_file.close();

    LOG(INFO) << "Ending CharacterSelectState update_information";
}
<commit_msg>Apply check return technique to Config<commit_after>/* Copyright (c) 2017 Wenova - Rise of Conquerors. All rights reserved.
 *
 * This work is licensed under the terms of the MIT license.
 * For a copy, see <https://opensource.org/licenses/MIT>.
 */
/**
 * @file Config.cpp
 * Implements class Config methods.
 */

#include "Config.h"

int Config::width;
int Config::height;
int Config::fullscreen;

/**
 * Will write current screen configurations to res/config_file.dat.
 */
void Config::init() {
    LOG(INFO) << "Starting CharacterSelectState init";

    std::fstream config_file(CONFIGURATION_FILE_PATH);

    if (not config_file.is_open()) {
        LOG(FATAL) << "File couldn't be open";
    }
    assert(config_file.is_open());

    config_file >> width >> height >> fullscreen;

    LOG(INFO) << "Ending CharacterSelectState init";
}

/**
 * Accessor to width private attribute.
 *
 * @returns Game's windows width. Unit: px, [0,]
 */
int Config::get_width() {
    LOG(INFO) << "Starting CharacterSelectState get_width";

    int return_value = width;

    std::string log_message = "Ending CharacterSelectState get_width returning value: " + std::to_string(return_value);
    LOG(INFO) << log_message;

    if (width <= 0) {
        LOG(WARNING) << "Width is being returned with suspicious values";
    }

    return return_value;
}

/**
 * Accessor to height private attribute.
 * @returns  Game's windows height. Unit: px, [0,]
 */
int Config::get_height() {
    LOG(INFO) << "Starting CharacterSelectState get_height";

    int return_value = height;

    std::string log_message = "Ending CharacterSelectState get_height returning value: " + std::to_string(return_value);
    LOG(INFO) << log_message;

    if (height <= 0) {
        LOG(WARNING) << "Height is being returned with suspicious values";
    }

    return return_value;
}

/**
 * Get fullscreen current status.
 *
 * @returns 0 for no, 1 for yes [0,1]
 */
int Config::is_fullscreen() {
    LOG(INFO) << "Starting CharacterSelectState is_fullscreen";

    int return_value = fullscreen;

    std::string log_message = "Ending CharacterSelectState is_fullscreen returning value: " + std::to_string(return_value);
    LOG(INFO) << log_message;

    return return_value;
}

/**
 * Writes to file res/config_file.dat screen information.
 *
 * @param cwidth Unit: px, [0,]
 * @param cheight Unit: px, [0,]
 * @param cfullscreen [0,1]
 */
void Config::update_information(int cwidth, int cheight, int cfullscreen) {
    std::string log_message = "Starting CharacterSelectState update_information, cwidth: ";
    log_message += std::to_string(cwidth) += ", cheight: ";
    log_message += std::to_string(cheight) + ", cfullscreen: " + std::to_string(cfullscreen);

    LOG(INFO) << log_message;

    width = cwidth;
    height = cheight;
    fullscreen = cfullscreen;

    std::ofstream config_file(CONFIGURATION_FILE_PATH, std::ios::trunc);

    if (not config_file.is_open()) {
        LOG(FATAL) << "File couldn't be open";
    }
    assert(config_file.is_open());

    config_file << width << " " << height << " " << fullscreen << std::endl;
    config_file.close();

    LOG(INFO) << "Ending CharacterSelectState update_information";
}
<|endoftext|>


<commit_before>#include "DG_Job.h"
#include <SDL.h>
#include <atomic>
#include "DG_Windows.h"

namespace DG
{
	static const u32 JOB_COUNT = 4096;
	static const u32 JOB_MASK = JOB_COUNT - 1u;

	thread_local u32 LocalJobBufferIndex = 0;
	thread_local Job LocalJobBuffer[JOB_COUNT];
	thread_local Job* LocalJobQueue[JOB_COUNT];
	thread_local JobSystem::JobWorkQueue LocalQueue(LocalJobQueue, JOB_COUNT);

	bool g_JobQueueShutdownRequested = false;

	static JobSystem::JobWorkQueue* _queues[64];
	static SDL_mutex* _mutex = SDL_CreateMutex();
	static SDL_cond* _cond = SDL_CreateCond();
	static s32 _workerCount = 0;
	JobSystem::JobWorkQueue::JobWorkQueue(Job** queue, u32 size)
		: _jobs(queue), _size(size)
	{
	}

	Job* JobSystem::JobWorkQueue::GetJob()
	{
		Job* job = Pop();
		if (!job)
		{
			// Steal Job
			u32 index = rand() % _workerCount;
			JobWorkQueue* queueToStealFrom = _queues[index];
			if (&LocalQueue != queueToStealFrom)
			{
				job = queueToStealFrom->Steal();
			}
		}
		return job;
	}

	void JobSystem::JobWorkQueue::Push(Job* job)
	{
		s32 t = _top;
		_jobs[t & JOB_MASK] = job;

		SDL_CompilerBarrier();

		_top = t + 1;
	}

	Job* JobSystem::JobWorkQueue::Pop()
	{
		s32 t = _top - 1;
		_top = t;

		MemoryBarrier(); // Can't find a SDL equivalent

		s32 b = SDL_AtomicGet(&_bottom);

		// Empty queue
		if (b > t)
		{
			_top = b;
			return nullptr;
		}

		// not empty
		Job* job = _jobs[t & JOB_MASK];

		// Not Last Item
		if (b != t)
			return job;

		// Check if a steal operation got there before us
		if (!SDL_AtomicCAS(&_bottom, b, b + 1))
			job = nullptr; // Someone stole the job

		_top = b + 1;
		return job;
	}

	Job* JobSystem::JobWorkQueue::Steal()
	{
		long b = SDL_AtomicGet(&_bottom);

		SDL_CompilerBarrier();

		long t = _top;
		if (b < t)
		{
			// non-empty queue
			Job* job = _jobs[b & JOB_MASK];
			if (SDL_AtomicCAS(&_bottom, b, b + 1))
			{
				return job;
			}
		}
		return nullptr;
	}

	void JobSystem::Finish(Job* job)
	{
		const s32 unfinishedJobs = SDL_AtomicAdd(&job->unfinishedJobs, -1);
		if (unfinishedJobs == 1)
		{
			if (job->parent)
			{
				Finish(job->parent);
			}
		}
	}

	Job* JobSystem::CreateJob(JobFunction function)
	{
		u32 index = LocalJobBufferIndex & JOB_MASK;
		++LocalJobBufferIndex;
		Job& job = LocalJobBuffer[index];
		Assert(SDL_AtomicGet(&job.unfinishedJobs) == 0);
		job.function = function;
		job.parent = nullptr;
		SDL_AtomicSet(&job.unfinishedJobs, 1);
		SDL_memset(&job.data, 0, ArrayCount(job.data));

		return &job;
	}

	Job* JobSystem::CreateJobAsChild(Job* parent, JobFunction function)
	{
		SDL_AtomicAdd(&parent->unfinishedJobs, 1);

		u32 index = LocalJobBufferIndex & JOB_MASK;
		++LocalJobBufferIndex;
		Job& job = LocalJobBuffer[index];

		Assert(SDL_AtomicGet(&job.unfinishedJobs) == 0);

		job.function = function;
		job.parent = parent;
		SDL_AtomicSet(&job.unfinishedJobs, 1);
		SDL_memset(&job.data, 0, ArrayCount(job.data));

		return &job;
	}

	void JobSystem::Wait(Job* job)
	{
		// wait until the job has completed. in the meantime, work on any other job.
		while (SDL_AtomicGet(&job->unfinishedJobs) != 0)
		{
			Job* jobToBeDone = LocalQueue.GetJob();
			if (jobToBeDone)
			{
				jobToBeDone->function(jobToBeDone, jobToBeDone->data);
				Finish(jobToBeDone);
			}
		}
	}

	void JobSystem::Run(Job* job)
	{
		LocalQueue.Push(job);
		SDL_LockMutex(_mutex);
		SDL_CondBroadcast(_cond);
		SDL_UnlockMutex(_mutex);
	}

	void JobSystem::CreateAndRegisterWorker()
	{
		SDL_CreateThread(JobQueueWorkerFunction, "Worker", nullptr);
	}

	bool JobSystem::RegisterWorker()
	{
		SDL_LockMutex(_mutex);

		if (_workerCount >= ArrayCount(_queues))
		{
			Assert(false);
			return false;
		}
		_queues[_workerCount++] = &LocalQueue;
		SDL_UnlockMutex(_mutex);
		return true;
	}

	int JobSystem::JobQueueWorkerFunction(void* data)
	{
		if (!RegisterWorker())
			return -1;
		while (!g_JobQueueShutdownRequested)
		{
			Job* job = LocalQueue.GetJob();
			if (job)
			{
				job->function(job, job->data);
				Finish(job);
			}
			else
			{
				SDL_LockMutex(_mutex);
				SDL_CondWait(_cond, _mutex);
				SDL_UnlockMutex(_mutex);
			}
		}
		return 0;
	}
}
<commit_msg>Cond speedup by counting jobs<commit_after>#include "DG_Job.h"
#include <SDL.h>
#include <atomic>
#include "DG_Windows.h"

namespace DG
{
	static const u32 JOB_COUNT = 4096;
	static const u32 JOB_MASK = JOB_COUNT - 1u;

	thread_local u32 LocalJobBufferIndex = 0;
	thread_local Job LocalJobBuffer[JOB_COUNT];
	thread_local Job* LocalJobQueue[JOB_COUNT];
	thread_local JobSystem::JobWorkQueue LocalQueue(LocalJobQueue, JOB_COUNT);

	bool g_JobQueueShutdownRequested = false;

	static JobSystem::JobWorkQueue* _queues[64];
	static SDL_mutex* _mutex = SDL_CreateMutex();
	static SDL_cond* _cond = SDL_CreateCond();
	static s32 _workerCount = 0;
	static SDL_atomic_t _jobCount;
	JobSystem::JobWorkQueue::JobWorkQueue(Job** queue, u32 size)
		: _jobs(queue), _size(size)
	{
	}

	Job* JobSystem::JobWorkQueue::GetJob()
	{
		Job* job = Pop();
		if (!job)
		{
			// Steal Job
			u32 index = rand() % _workerCount;
			JobWorkQueue* queueToStealFrom = _queues[index];
			if (&LocalQueue != queueToStealFrom)
			{
				job = queueToStealFrom->Steal();
			}
		}
		return job;
	}

	void JobSystem::JobWorkQueue::Push(Job* job)
	{
		s32 t = _top;
		_jobs[t & JOB_MASK] = job;

		SDL_CompilerBarrier();

		_top = t + 1;
	}

	Job* JobSystem::JobWorkQueue::Pop()
	{
		s32 t = _top - 1;
		_top = t;

		MemoryBarrier(); // Can't find a SDL equivalent

		s32 b = SDL_AtomicGet(&_bottom);

		// Empty queue
		if (b > t)
		{
			_top = b;
			return nullptr;
		}

		// not empty
		Job* job = _jobs[t & JOB_MASK];

		// Not Last Item
		if (b != t)
			return job;

		// Check if a steal operation got there before us
		if (!SDL_AtomicCAS(&_bottom, b, b + 1))
			job = nullptr; // Someone stole the job

		_top = b + 1;
		return job;
	}

	Job* JobSystem::JobWorkQueue::Steal()
	{
		long b = SDL_AtomicGet(&_bottom);

		SDL_CompilerBarrier();

		long t = _top;
		if (b < t)
		{
			// non-empty queue
			Job* job = _jobs[b & JOB_MASK];
			if (SDL_AtomicCAS(&_bottom, b, b + 1))
			{
				return job;
			}
		}
		return nullptr;
	}

	void JobSystem::Finish(Job* job)
	{
		const s32 unfinishedJobs = SDL_AtomicAdd(&job->unfinishedJobs, -1);
		if (unfinishedJobs == 1)
		{
			if (job->parent)
			{
				Finish(job->parent);
			}
			SDL_AtomicAdd(&_jobCount, -1);
		}
	}

	Job* JobSystem::CreateJob(JobFunction function)
	{
		u32 index = LocalJobBufferIndex & JOB_MASK;
		++LocalJobBufferIndex;
		Job& job = LocalJobBuffer[index];
		Assert(SDL_AtomicGet(&job.unfinishedJobs) == 0);
		job.function = function;
		job.parent = nullptr;
		SDL_AtomicSet(&job.unfinishedJobs, 1);
		SDL_memset(&job.data, 0, ArrayCount(job.data));

		return &job;
	}

	Job* JobSystem::CreateJobAsChild(Job* parent, JobFunction function)
	{
		SDL_AtomicAdd(&parent->unfinishedJobs, 1);

		u32 index = LocalJobBufferIndex & JOB_MASK;
		++LocalJobBufferIndex;
		Job& job = LocalJobBuffer[index];

		Assert(SDL_AtomicGet(&job.unfinishedJobs) == 0);

		job.function = function;
		job.parent = parent;
		SDL_AtomicSet(&job.unfinishedJobs, 1);
		SDL_memset(&job.data, 0, ArrayCount(job.data));

		return &job;
	}

	void JobSystem::Wait(Job* job)
	{
		// wait until the job has completed. in the meantime, work on any other job.
		while (SDL_AtomicGet(&job->unfinishedJobs) != 0)
		{
			Job* jobToBeDone = LocalQueue.GetJob();
			if (jobToBeDone)
			{
				jobToBeDone->function(jobToBeDone, jobToBeDone->data);
				Finish(jobToBeDone);
			}
		}
	}

	void JobSystem::Run(Job* job)
	{
		LocalQueue.Push(job);
		s32 prev = SDL_AtomicAdd(&_jobCount, 1);
		if (prev == 0)
		{
			SDL_LockMutex(_mutex);
			SDL_CondBroadcast(_cond);
			SDL_UnlockMutex(_mutex);
		}
	}

	void JobSystem::CreateAndRegisterWorker()
	{
		SDL_CreateThread(JobQueueWorkerFunction, "Worker", nullptr);
	}

	bool JobSystem::RegisterWorker()
	{
		SDL_LockMutex(_mutex);

		if (_workerCount >= ArrayCount(_queues))
		{
			Assert(false);
			return false;
		}
		_queues[_workerCount++] = &LocalQueue;
		SDL_UnlockMutex(_mutex);
		return true;
	}

	int JobSystem::JobQueueWorkerFunction(void* data)
	{
		if (!RegisterWorker())
			return -1;
		while (!g_JobQueueShutdownRequested)
		{
			Job* job = LocalQueue.GetJob();
			if (job)
			{
				job->function(job, job->data);
				Finish(job);
			}
			if (SDL_AtomicGet(&_jobCount) == 0)
			{
				SDL_LockMutex(_mutex);
				SDL_CondWait(_cond, _mutex);
				SDL_UnlockMutex(_mutex);
			}
		}
		return 0;
	}
}
<|endoftext|>


<commit_before>#include "Entity.hpp"

Entity::Entity()
{

}

void Entity::setVelocity(sf::Vector2f velocity)
{
    m_velocity = velocity;
}

void Entity::setVelocity(float velX, float velY)
{
    m_velocity.x = velX;
    m_velocity.y = velY;
}

sf::Vector2f Entity::getVelocity()
{
    return m_velocity;
}

void Entity::updateCurrent(float dt)
{
    // Move is the same as setPosition(getPosition() + offset) of the sf::Transformable class
    move(m_velocity * dt);
}
<commit_msg>Syntax xhanges<commit_after>#include "Entity.hpp"

Entity::Entity()
{

}

void Entity::setVelocity(sf::Vector2f velocity)
{
    m_velocity = { velocity };
}

void Entity::setVelocity(float velX, float velY)
{
    m_velocity.x = { velX };
    m_velocity.y = { velY };
}

sf::Vector2f Entity::getVelocity()
{
    return m_velocity;
}

void Entity::updateCurrent(float dt)
{
    // Move is the same as setPosition(getPosition() + offset) of the sf::Transformable class
    move(m_velocity * dt);
}
<|endoftext|>