<commit_before>#include "powerup.hpp"

#define SEARCH_RADIUS 5

int Powerup::vertex_type( Vertex& v ) {
	int num_neighbors = map->getNumActors();
	for ( int i = 0; i < num_neighbors; i++ ) {
		int a, b;
		map->getActorPosition( i, a, b );
		Vertex temp( a, b );
		if( temp == v ) {
			return map->getActorType( i );
		}
	}
	return 0;
}

Powerup::Powerup( int type ): Actor( type ) {}

Powerup* Powerup::duplicate() {
	return new Powerup( getType() );
}

const char*  Powerup::getActorId() {
	return "simplehero";
}

const char* Powerup::getNetId() {
	return "hammesa";
}

bool Powerup::visited( const Vertex& v ) const {
	return v_set.find( v ) != v_set.end();
}

int Powerup::selectNeighbor( GraphMap* map, int cur_x, int cur_y ) {
	this->map = map;
	v_set.clear();
	rank_nodes( cur_x, cur_y );

	return 0;
}

void Powerup::rank_nodes( int x, int y ) {
	queue< Vertex > q;
	Vertex temp( x, y );
	dist[temp] = 0;

	q.push( Vertex( x, y ) );

	vector< Vertex > enemies;
	vector< Vertex > eatables;

	bool stop = false;
	while( !q.empty() && enemies.size() < SEARCH_RADIUS && !stop ) {
		Vertex popped = q.front();
		q.pop();

		v_set.insert( popped );
		if( vertex_type( popped ) & ACTOR_ENEMY ) {
			enemies.push_back( popped );
		}

		if( vertex_type( popped ) & ACTOR_EATABLE ) {
			eatables.push_back( popped );
		}

		int num_neighbors = map->getNumNeighbors( popped.x, popped. y )
		for ( int i = 0; i < num_neighbors; i++ ) {
			int a, b;
			map->getNeighbor( popped.x, popped.y, i, a, b );
			Vertex temp( a, b );

			if( !visited( temp ) ) {
				dist[temp] = dist[popped] + 1;
				if( dist[temp] > SEARCH_RADIUS ) {
					stop = true;
					break;
				}

				q.push( temp );
			}
		}
	}

}

<commit_msg>added const<commit_after>#include "powerup.hpp"

#define SEARCH_RADIUS 5

int Powerup::vertex_type( const Vertex& v ) const {
	int num_neighbors = map->getNumActors();
	for ( int i = 0; i < num_neighbors; i++ ) {
		int a, b;
		map->getActorPosition( i, a, b );
		Vertex temp( a, b );
		if( temp == v ) {
			return map->getActorType( i );
		}
	}
	return 0;
}

Powerup::Powerup( int type ): Actor( type ) {}

Powerup* Powerup::duplicate() {
	return new Powerup( getType() );
}

const char*  Powerup::getActorId() {
	return "simplehero";
}

const char* Powerup::getNetId() {
	return "hammesa";
}

bool Powerup::visited( const Vertex& v ) const {
	return v_set.find( v ) != v_set.end();
}

int Powerup::selectNeighbor( GraphMap* map, int cur_x, int cur_y ) {
	this->map = map;
	v_set.clear();
	rank_nodes( cur_x, cur_y );

	return 0;
}

void Powerup::rank_nodes( int x, int y ) {
	queue< Vertex > q;
	Vertex temp( x, y );
	dist[temp] = 0;

	q.push( Vertex( x, y ) );

	vector< Vertex > enemies;
	vector< Vertex > eatables;

	bool stop = false;
	while( !q.empty() && enemies.size() < SEARCH_RADIUS && !stop ) {
		Vertex popped = q.front();
		q.pop();

		v_set.insert( popped );
		if( vertex_type( popped ) & ACTOR_ENEMY ) {
			enemies.push_back( popped );
		}

		if( vertex_type( popped ) & ACTOR_EATABLE ) {
			eatables.push_back( popped );
		}

		int num_neighbors = map->getNumNeighbors( popped.x, popped. y );
		for ( int i = 0; i < num_neighbors; i++ ) {
			int a, b;
			map->getNeighbor( popped.x, popped.y, i, a, b );
			Vertex temp( a, b );

			if( !visited( temp ) ) {
				dist[temp] = dist[popped] + 1;
				if( dist[temp] > SEARCH_RADIUS ) {
					stop = true;
					break;
				}

				q.push( temp );
			}
		}
	}
}

<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <babylon/asio/asio.h>
#include <babylon/misc/string_tools.h>
#include <babylon/core/filesystem.h>
#include <babylon/babylon_common.h>

#include <thread>
#include <iostream>

std::string assets_folder = BABYLON::babylon_repo_folder() + std::string("/assets/");

std::string textUrl = std::string("file:/") + assets_folder + "/fonts/fa-regular-400.ttf";
std::string binaryUrl = std::string("file:/") + assets_folder
  + "/glTF-Sample-Models/2.0/AntiqueCamera/glTF/camera_camera_Normal.png";
std::string nonExistingFileUrl = "file:/non_existing_file";

std::vector<std::string> textFilesUrls = {
  textUrl, nonExistingFileUrl, textUrl, textUrl, nonExistingFileUrl, textUrl, nonExistingFileUrl
};

std::vector<std::string> binaryFilesUrls  = {
  binaryUrl, nonExistingFileUrl, binaryUrl, binaryUrl, nonExistingFileUrl, binaryUrl, nonExistingFileUrl
};

void SampleApplicationLoop()
{
  auto mainThreadId = std::this_thread::get_id();

  int nb_success_text = 0;
  int nb_success_binary = 0;
  int nb_error = 0;
  int nb_calls_to_progress = 0;

  // Sample callbacks that will be called *synchronously*
  auto onSuccessText = [&nb_success_text, mainThreadId](const std::string& /*textContent*/) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_success_text;
  };
  auto onSuccessBinary = [&nb_success_binary, mainThreadId](const BABYLON::ArrayBuffer& /*data*/) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_success_binary;
  };
  auto onError = [&nb_error, mainThreadId](const std::string& message) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_error;
    std::cout << "onError: "<< message << "\n";
  };
  auto onProgress = [&nb_calls_to_progress, mainThreadId](bool /*lengthComputable*/, size_t /*loaded*/, size_t /*total*/) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_calls_to_progress;
  };

  // Sample application main loop
  bool applicationShallExit = false;
  while(!applicationShallExit)
  {
    if (!textFilesUrls.empty())
    {
      std::string url = textFilesUrls.back();
      textFilesUrls.pop_back();
      BABYLON::asio::LoadAssetAsync_Text(url, onSuccessText, onError, onProgress);
    }
    if (!binaryFilesUrls.empty())
    {
      std::string url = binaryFilesUrls.back();
      binaryFilesUrls.pop_back();
      BABYLON::asio::LoadAssetAsync_Binary(url, onSuccessBinary, onError, onProgress);
    }

    applicationShallExit =
      textFilesUrls.empty() && binaryFilesUrls.empty() && ! BABYLON::asio::HasRemainingTasks();

    // Remember to call asio::HeartBeat_Sync() in your application main loop:
    // if there are pending callbacks, this will call the first one *synchronously*
    BABYLON::asio::HeartBeat_Sync();
  };

  EXPECT_EQ(nb_success_text, 4);
  EXPECT_EQ(nb_success_binary, 4);
  EXPECT_EQ(nb_error, 6);
  EXPECT_GT(nb_calls_to_progress, 10);
//  printf("nb_success_text=%i, nb_success_binary=%i, nb_error=%i nb_calls_to_progress=%i\n",
//    nb_success_text, nb_success_binary, nb_error, nb_calls_to_progress);
}

TEST(async_requests, SampleApplicationLoop)
{
#ifndef _WIN32
  std::cout << "isFile(" <<  textUrl.substr(6) << ") => " << BABYLON::Filesystem::isFile(textUrl.substr(6)) << "\n";
  std::cout << "isFile(" <<  binaryUrl.substr(6) << ") => " << BABYLON::Filesystem::isFile(binaryUrl.substr(6)) << "\n";
  SampleApplicationLoop();
  BABYLON::asio::Service_Stop();
#endif // _WIN32
}

TEST(async_requests, LoadText)
{
#if 0 // This code works, but features no real google test call
  std::cout << "\n";
  auto onSuccessText = [](const std::string& textContent) {
    std::cout << "\n==>\n" << textContent << "\n<==\n";
  };
  auto onError = [](const std::string& message) {
    std::cout << "Error:" << message << "!!!\n";
  };
  auto onProgress = [](bool lengthComputable, size_t loaded, size_t total) {
    std::cout << "onProgress " << loaded << " / " << total << " lengthComputable: " << lengthComputable << "\n";
  };

  BABYLON::asio::LoadUrlAsync_Text(textUrl, onSuccessText, onError, onProgress);
  BABYLON::asio::Service_WaitAll_Sync();
#endif
}
<commit_msg>fix asio_test<commit_after>#include <gtest/gtest.h>
#include <babylon/asio/asio.h>
#include <babylon/misc/string_tools.h>
#include <babylon/core/filesystem.h>
#include <babylon/babylon_common.h>

#include <thread>
#include <iostream>

std::string textUrl = "fonts/fa-regular-400.ttf";
std::string binaryUrl = "glTF-Sample-Models/2.0/AntiqueCamera/glTF/camera_camera_Normal.png";
std::string nonExistingFileUrl = "non_existing_file";

std::vector<std::string> textFilesUrls = {
  textUrl, nonExistingFileUrl, textUrl, textUrl, nonExistingFileUrl, textUrl, nonExistingFileUrl
};

std::vector<std::string> binaryFilesUrls  = {
  binaryUrl, nonExistingFileUrl, binaryUrl, binaryUrl, nonExistingFileUrl, binaryUrl, nonExistingFileUrl
};

void SampleApplicationLoop()
{
  auto mainThreadId = std::this_thread::get_id();

  int nb_success_text = 0;
  int nb_success_binary = 0;
  int nb_error = 0;
  int nb_calls_to_progress = 0;

  // Sample callbacks that will be called *synchronously*
  auto onSuccessText = [&nb_success_text, mainThreadId](const std::string& /*textContent*/) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_success_text;
  };
  auto onSuccessBinary = [&nb_success_binary, mainThreadId](const BABYLON::ArrayBuffer& /*data*/) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_success_binary;
  };
  auto onError = [&nb_error, mainThreadId](const std::string& message) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_error;
    std::cout << "onError: "<< message << "\n";
  };
  auto onProgress = [&nb_calls_to_progress, mainThreadId](bool /*lengthComputable*/, size_t /*loaded*/, size_t /*total*/) {
    auto thisThreadId = std::this_thread::get_id();
    EXPECT_EQ(thisThreadId, mainThreadId);
    ++nb_calls_to_progress;
  };

  // Sample application main loop
  bool applicationShallExit = false;
  while(!applicationShallExit)
  {
    if (!textFilesUrls.empty())
    {
      std::string url = textFilesUrls.back();
      textFilesUrls.pop_back();
      BABYLON::asio::LoadAssetAsync_Text(url, onSuccessText, onError, onProgress);
    }
    if (!binaryFilesUrls.empty())
    {
      std::string url = binaryFilesUrls.back();
      binaryFilesUrls.pop_back();
      BABYLON::asio::LoadAssetAsync_Binary(url, onSuccessBinary, onError, onProgress);
    }

    applicationShallExit =
      textFilesUrls.empty() && binaryFilesUrls.empty() && ! BABYLON::asio::HasRemainingTasks();

    // Remember to call asio::HeartBeat_Sync() in your application main loop:
    // if there are pending callbacks, this will call the first one *synchronously*
    BABYLON::asio::HeartBeat_Sync();
  };

  EXPECT_EQ(nb_success_text, 4);
  EXPECT_EQ(nb_success_binary, 4);
  EXPECT_EQ(nb_error, 6);
  EXPECT_GT(nb_calls_to_progress, 10);
//  printf("nb_success_text=%i, nb_success_binary=%i, nb_error=%i nb_calls_to_progress=%i\n",
//    nb_success_text, nb_success_binary, nb_error, nb_calls_to_progress);
}

TEST(async_requests, SampleApplicationLoop)
{
#ifndef _WIN32
  std::cout << "isFile(" <<  textUrl.substr(6) << ") => " << BABYLON::Filesystem::isFile(textUrl.substr(6)) << "\n";
  std::cout << "isFile(" <<  binaryUrl.substr(6) << ") => " << BABYLON::Filesystem::isFile(binaryUrl.substr(6)) << "\n";
  SampleApplicationLoop();
  BABYLON::asio::Service_Stop();
#endif // _WIN32
}

TEST(async_requests, LoadText)
{
#if 0 // This code works, but features no real google test call
  std::cout << "\n";
  auto onSuccessText = [](const std::string& textContent) {
    std::cout << "\n==>\n" << textContent << "\n<==\n";
  };
  auto onError = [](const std::string& message) {
    std::cout << "Error:" << message << "!!!\n";
  };
  auto onProgress = [](bool lengthComputable, size_t loaded, size_t total) {
    std::cout << "onProgress " << loaded << " / " << total << " lengthComputable: " << lengthComputable << "\n";
  };

  BABYLON::asio::LoadUrlAsync_Text(textUrl, onSuccessText, onError, onProgress);
  BABYLON::asio::Service_WaitAll_Sync();
#endif
}
<|endoftext|>


<commit_before>#include "StdAfx.h"
#include "WebBrowserHelper.h"
#include <sstream>
#include <iomanip>
#include <WinInet.h>

using namespace Utilities::WebBrowser;

WebBrowserHelper::WebBrowserHelper(void)
{
}

WebBrowserHelper::~WebBrowserHelper(void)
{
}

int WebBrowserHelper::ClearCache()
{
// Pointer to a GROUPID variable
	GROUPID groupId = 0;

	// Local variables
	DWORD cacheEntryInfoBufferSizeInitial = 0;
    DWORD cacheEntryInfoBufferSize = 0;
    int *cacheEntryInfoBuffer = 0;
    INTERNET_CACHE_ENTRY_INFO *internetCacheEntry;
    HANDLE enumHandle = NULL;
    BOOL returnValue = false;

	// Delete the groups first.
    // Groups may not always exist on the system.
    // For more information, visit the following Microsoft Web site:
    // http://msdn2.microsoft.com/en-us/library/ms909365.aspx
    // By default, a URL does not belong to any group. Therefore, that cache may become
    // empty even when the CacheGroup APIs are not used because the existing URL does not belong to any group.
    enumHandle = FindFirstUrlCacheGroup(0, CACHEGROUP_SEARCH_ALL, 0, 0, &groupId, 0);

	// If there are no items in the Cache, you are finished.
	if (enumHandle != NULL && ERROR_NO_MORE_ITEMS == GetLastError())
		return 0;

	// Loop through Cache Group, and then delete entries.
	if (enumHandle != NULL)
	{
		while (groupId != NULL)
		{
			// Delete a particular Cache Group.
			returnValue = DeleteUrlCacheGroup(groupId, CACHEGROUP_FLAG_FLUSHURL_ONDELETE, 0);

			if (!returnValue && ERROR_FILE_NOT_FOUND == GetLastError())
			{
				returnValue = FindNextUrlCacheGroup(enumHandle, &groupId, 0);
			}

			if (!returnValue && (ERROR_NO_MORE_ITEMS == GetLastError() || ERROR_FILE_NOT_FOUND == GetLastError()))
			{
				break;
			}
		}
	}

	 // Start to delete URLs that do not belong to any group.
	enumHandle = FindFirstUrlCacheEntry(NULL, 0, &cacheEntryInfoBufferSizeInitial);
	if (enumHandle == NULL && ERROR_NO_MORE_ITEMS == GetLastError())
		return 0;

	cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial;
	internetCacheEntry =  (INTERNET_CACHE_ENTRY_INFO*)malloc(cacheEntryInfoBufferSize);
	enumHandle = FindFirstUrlCacheEntry(NULL, internetCacheEntry, &cacheEntryInfoBufferSizeInitial);
	if (enumHandle != NULL)
	{
		while (internetCacheEntry != NULL)
		{
			cacheEntryInfoBufferSizeInitial = cacheEntryInfoBufferSize;
			returnValue = DeleteUrlCacheEntry(internetCacheEntry->lpszSourceUrlName);

			if (!returnValue)
			{
				returnValue = FindNextUrlCacheEntry(enumHandle, internetCacheEntry, &cacheEntryInfoBufferSizeInitial);
			}

			DWORD dwError = GetLastError();
			if (!returnValue && ERROR_NO_MORE_ITEMS == dwError)
			{
				break;
			}

			if (!returnValue && cacheEntryInfoBufferSizeInitial > cacheEntryInfoBufferSize)
			{
				cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial;
				internetCacheEntry =  (INTERNET_CACHE_ENTRY_INFO*)realloc(internetCacheEntry, cacheEntryInfoBufferSize);
				returnValue = FindNextUrlCacheEntry(enumHandle, internetCacheEntry, &cacheEntryInfoBufferSizeInitial);
			}
		}
	}

	free(internetCacheEntry);
	return 0;
}

std::wstring WebBrowserHelper::hexencode(const std::wstring& input)
{
	std::wostringstream ssOut;
    ssOut << std::setbase(16);
    for(std::wstring::const_iterator i = input.begin(); i != input.end(); ++i)
    {
        if(isalnum(*i))
            ssOut << *i;
        else
            ssOut << '%' << std::setw(2) << ((unsigned int)(unsigned char)*i);
    }
    return ssOut.str();
}<commit_msg>Modify MS ClearCache procedure to fix infinite loop<commit_after>#include "StdAfx.h"
#include "WebBrowserHelper.h"
#include <sstream>
#include <iomanip>
#include <WinInet.h>

using namespace Utilities::WebBrowser;

WebBrowserHelper::WebBrowserHelper(void)
{
}

WebBrowserHelper::~WebBrowserHelper(void)
{
}

int WebBrowserHelper::ClearCache()
{
	// Pointer to a GROUPID variable
	GROUPID groupId = 0;

	// Local variables
	DWORD cacheEntryInfoBufferSizeInitial = 0;
    DWORD cacheEntryInfoBufferSize = 0;
    int *cacheEntryInfoBuffer = 0;
    INTERNET_CACHE_ENTRY_INFO *internetCacheEntry;
    HANDLE enumHandle = NULL;
    BOOL returnValue = false;

	// Delete the groups first.
    // Groups may not always exist on the system.
    // For more information, visit the following Microsoft Web site:
    // http://msdn2.microsoft.com/en-us/library/ms909365.aspx
    // By default, a URL does not belong to any group. Therefore, that cache may become
    // empty even when the CacheGroup APIs are not used because the existing URL does not belong to any group.
    enumHandle = FindFirstUrlCacheGroup(0, CACHEGROUP_SEARCH_ALL, 0, 0, &groupId, 0);

	// If there are no items in the Cache, you are finished.
	if (enumHandle != NULL && ERROR_NO_MORE_ITEMS == GetLastError())
		return 0;

	// Loop through Cache Group, and then delete entries.
	if (enumHandle != NULL)
	{
		while (1)
		{
			// Delete a particular Cache Group.
			returnValue = DeleteUrlCacheGroup(groupId, CACHEGROUP_FLAG_FLUSHURL_ONDELETE, 0);

			returnValue = FindNextUrlCacheGroup(enumHandle, &groupId, 0);

			if (!returnValue)
			{
				break;
			}
		}
	}

	 // Start to delete URLs that do not belong to any group.
	enumHandle = FindFirstUrlCacheEntry(NULL, 0, &cacheEntryInfoBufferSizeInitial);
	if (enumHandle == NULL && ERROR_NO_MORE_ITEMS == GetLastError())
		return 0;

	cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial;
	internetCacheEntry =  (INTERNET_CACHE_ENTRY_INFO*)malloc(cacheEntryInfoBufferSize);
	enumHandle = FindFirstUrlCacheEntry(NULL, internetCacheEntry, &cacheEntryInfoBufferSizeInitial);
	if (enumHandle != NULL)
	{
		while (1)
		{
			cacheEntryInfoBufferSizeInitial = cacheEntryInfoBufferSize;
			returnValue = DeleteUrlCacheEntry(internetCacheEntry->lpszSourceUrlName);

			// Allows try to get the next entry
			returnValue = FindNextUrlCacheEntry(enumHandle, internetCacheEntry, &cacheEntryInfoBufferSizeInitial);

			DWORD dwError = GetLastError();
			if (!returnValue && ERROR_NO_MORE_ITEMS == dwError)
			{
				break;
			}

			if (!returnValue && cacheEntryInfoBufferSizeInitial > cacheEntryInfoBufferSize)
			{
				cacheEntryInfoBufferSize = cacheEntryInfoBufferSizeInitial;
				internetCacheEntry =  (INTERNET_CACHE_ENTRY_INFO*)realloc(internetCacheEntry, cacheEntryInfoBufferSize);
				returnValue = FindNextUrlCacheEntry(enumHandle, internetCacheEntry, &cacheEntryInfoBufferSizeInitial);
			}
		}
	}

	free(internetCacheEntry);
	return 0;
}

std::wstring WebBrowserHelper::hexencode(const std::wstring& input)
{
	std::wostringstream ssOut;
    ssOut << std::setbase(16);
    for(std::wstring::const_iterator i = input.begin(); i != input.end(); ++i)
    {
        if(isalnum(*i))
            ssOut << *i;
        else
            ssOut << '%' << std::setw(2) << ((unsigned int)(unsigned char)*i);
    }
    return ssOut.str();
}<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkGenericDataSetTessellator.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 notice for more information.

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

#include "vtkObjectFactory.h"
#include "vtkUnstructuredGrid.h"
#include "vtkPointData.h"
#include "vtkTetra.h"
#include "vtkCellArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkIdTypeArray.h"
#include "vtkDoubleArray.h"
#include "vtkMergePoints.h"
#include "vtkGenericDataSet.h"
#include "vtkGenericCellIterator.h"
#include "vtkGenericAdaptorCell.h"

vtkCxxRevisionMacro(vtkGenericDataSetTessellator, "1.2");
vtkStandardNewMacro(vtkGenericDataSetTessellator);

//----------------------------------------------------------------------------
//
vtkGenericDataSetTessellator::vtkGenericDataSetTessellator()
{
}

//----------------------------------------------------------------------------
vtkGenericDataSetTessellator::~vtkGenericDataSetTessellator()
{
}

//----------------------------------------------------------------------------
//
void vtkGenericDataSetTessellator::Execute()
{
  vtkDebugMacro(<< "Executing vtkGenericDataSetTessellator...");

  vtkGenericDataSet *input = this->GetInput();
  vtkUnstructuredGrid *output = this->GetOutput();
  vtkIdType numPts = input->GetNumberOfPoints();
  vtkIdType numCells = input->GetNumberOfCells();
  vtkPointData *outputPD = output->GetPointData();
  vtkCellData *outputCD = output->GetCellData();
  vtkGenericAdaptorCell *cell;
  vtkIdType numInserted=0, numNew, i;
  vtkIdType npts, *pts;

  // Copy original points and point data
  vtkPoints *newPts = vtkPoints::New();
  newPts->Allocate(2*numPts,numPts);

  // loop over region
  vtkUnsignedCharArray *types = vtkUnsignedCharArray::New();
  types->Allocate(numCells);
  vtkIdTypeArray *locs = vtkIdTypeArray::New();
  locs->Allocate(numCells);
  vtkCellArray *conn = vtkCellArray::New();
  conn->Allocate(numCells);

  vtkGenericCellIterator *cellIt = input->NewCellIterator();
  for(cellIt->Begin(); !cellIt->IsAtEnd(); cellIt->Next())
    {
    cell = cellIt->GetCell();
    cell->Tessellate(input->GetAttributes(), input->GetTessellator(),
                     newPts, conn, outputPD, outputCD);

    numNew = conn->GetNumberOfCells() - numInserted;
    numInserted = conn->GetNumberOfCells();

    for (i=0; i < numNew; i++)
      {
      locs->InsertNextValue(conn->GetTraversalLocation());
      conn->GetNextCell(npts,pts); //side effect updates traversal location
      switch (cell->GetDimension())
        {
        case 1:
          types->InsertNextValue(VTK_LINE);
          break;
        case 2:
          types->InsertNextValue(VTK_TRIANGLE);
          break;
        case 3:
          types->InsertNextValue(VTK_TETRA);
          break;
        default:
          vtkErrorMacro(<<"Bad mojo in data set tessellation");
        } //switch
      } //insert each new cell
    } //for all cells
  cellIt->Delete();

  // Send to the output
  output->SetPoints(newPts);
  output->SetCells(types, locs, conn);

  vtkDebugMacro(<<"Subdivided " << numCells << " cells to produce "
                << conn->GetNumberOfCells() << "new cells");

  newPts->Delete();
  types->Delete();
  locs->Delete();
  conn->Delete();

  output->Squeeze();
}

//----------------------------------------------------------------------------
void vtkGenericDataSetTessellator::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<commit_msg>ERR:Handle progress events and abort<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGenericDataSetTessellator.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm 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 notice for more information.

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

#include "vtkObjectFactory.h"
#include "vtkUnstructuredGrid.h"
#include "vtkPointData.h"
#include "vtkTetra.h"
#include "vtkCellArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkIdTypeArray.h"
#include "vtkDoubleArray.h"
#include "vtkMergePoints.h"
#include "vtkGenericDataSet.h"
#include "vtkGenericCellIterator.h"
#include "vtkGenericAdaptorCell.h"

vtkCxxRevisionMacro(vtkGenericDataSetTessellator, "1.3");
vtkStandardNewMacro(vtkGenericDataSetTessellator);

//----------------------------------------------------------------------------
//
vtkGenericDataSetTessellator::vtkGenericDataSetTessellator()
{
}

//----------------------------------------------------------------------------
vtkGenericDataSetTessellator::~vtkGenericDataSetTessellator()
{
}

//----------------------------------------------------------------------------
//
void vtkGenericDataSetTessellator::Execute()
{
  vtkDebugMacro(<< "Executing vtkGenericDataSetTessellator...");

  vtkGenericDataSet *input = this->GetInput();
  vtkUnstructuredGrid *output = this->GetOutput();
  vtkIdType numPts = input->GetNumberOfPoints();
  vtkIdType numCells = input->GetNumberOfCells();
  vtkPointData *outputPD = output->GetPointData();
  vtkCellData *outputCD = output->GetCellData();
  vtkGenericAdaptorCell *cell;
  vtkIdType numInserted=0, numNew, i;
  vtkIdType npts, *pts;
  int abortExecute=0;

  // Copy original points and point data
  vtkPoints *newPts = vtkPoints::New();
  newPts->Allocate(2*numPts,numPts);

  // loop over region
  vtkUnsignedCharArray *types = vtkUnsignedCharArray::New();
  types->Allocate(numCells);
  vtkIdTypeArray *locs = vtkIdTypeArray::New();
  locs->Allocate(numCells);
  vtkCellArray *conn = vtkCellArray::New();
  conn->Allocate(numCells);

  vtkGenericCellIterator *cellIt = input->NewCellIterator();
  vtkIdType updateTime = numCells/20 + 1;  // update roughly every 5%
  vtkIdType count = 0;
  for(cellIt->Begin(); !cellIt->IsAtEnd() && !abortExecute; cellIt->Next(), count++)
    {
    if ( !(count % updateTime) )
      {
      this->UpdateProgress((double)count / numCells);
      abortExecute = this->GetAbortExecute();
      }

    cell = cellIt->GetCell();
    cell->Tessellate(input->GetAttributes(), input->GetTessellator(),
                     newPts, conn, outputPD, outputCD);

    numNew = conn->GetNumberOfCells() - numInserted;
    numInserted = conn->GetNumberOfCells();

    for (i=0; i < numNew; i++)
      {
      locs->InsertNextValue(conn->GetTraversalLocation());
      conn->GetNextCell(npts,pts); //side effect updates traversal location
      switch (cell->GetDimension())
        {
        case 1:
          types->InsertNextValue(VTK_LINE);
          break;
        case 2:
          types->InsertNextValue(VTK_TRIANGLE);
          break;
        case 3:
          types->InsertNextValue(VTK_TETRA);
          break;
        default:
          vtkErrorMacro(<<"Bad mojo in data set tessellation");
        } //switch
      } //insert each new cell
    } //for all cells
  cellIt->Delete();

  // Send to the output
  output->SetPoints(newPts);
  output->SetCells(types, locs, conn);

  vtkDebugMacro(<<"Subdivided " << numCells << " cells to produce "
                << conn->GetNumberOfCells() << "new cells");

  newPts->Delete();
  types->Delete();
  locs->Delete();
  conn->Delete();

  output->Squeeze();
}

//----------------------------------------------------------------------------
void vtkGenericDataSetTessellator::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}
<|endoftext|>


<commit_before>/// @file SNIIS_Linux.cpp
/// Linux implementation of input

#include "SNIIS_Linux.h"
#include "SNIIS_Intern.h"

#if SNIIS_SYSTEM_LINUX
using namespace SNIIS;
#include "../Traumklassen/TraumBasis.h"

#include <cstring>
#include <sstream>
#include <fcntl.h>
#include <linux/input.h>

static bool IsBitSet( const uint8_t* bits, size_t i) { return (bits[i/8] & (1<<(i&7))) != 0; }

// --------------------------------------------------------------------------------------------------------------------
// Constructor
LinuxInput::LinuxInput( Window wnd)
{
  mWindow = wnd;
  mDisplay = nullptr;

  mDisplay = XOpenDisplay( nullptr);
  if( !mDisplay )
    throw std::runtime_error( "Failed to open XDisplay");

  int event = 0, error = 0;
  int major = 2, minor = 0;
  bool isAvailable = (XQueryExtension( mDisplay, "XInputExtension", &mXiOpcode, &event, &error) != False
               && XIQueryVersion( mDisplay, &major, &minor) != BadRequest);
  if( !isAvailable )
    throw std::runtime_error( "Failed to get XInputExtension");

  // Register for events
  XIEventMask evmask;
  uint8_t mask[] = { 0, 0, 0, 0 };
  XISetMask( mask, XI_HierarchyChanged);
  XISetMask( mask, XI_RawMotion);
  XISetMask( mask, XI_RawButtonPress);
  XISetMask( mask, XI_RawButtonRelease);
  XISetMask( mask, XI_RawKeyPress);
  XISetMask( mask, XI_RawKeyRelease);

  evmask.deviceid = XIAllDevices;
  evmask.mask_len = sizeof( mask);
  evmask.mask = mask;
  auto selwnd = DefaultRootWindow( mDisplay);
  if( XISelectEvents( mDisplay, selwnd, &evmask, 1) != 0 )
    throw std::runtime_error( "Failed to register for XInput2 events");

  int deviceCount = 0;
  XIDeviceInfo* devices = XIQueryDevice( mDisplay, XIAllDevices, &deviceCount);
  for( int i = 0; i < deviceCount; i++ )
  {
    /* We only look at "slave" devices. "Master" pointers are the logical
     * cursors, "slave" pointers are the hardware that back them.
     * "Floating slaves" are hardware that don't back a cursor.
     */

    switch( devices[i].use )
    {
      case XISlavePointer:
      case XIFloatingSlave:
      {
        Traum::Konsole.Log( "Mouse %d (id %d) - \"%s\"", mNumMice, mDevices.size(), devices[i].name);

        // a mouse. probably. Ignore some common pffft cases
        if( strstr(devices[i].name, "XTEST") != nullptr )
          break;

        try {
          auto m = new LinuxMouse( this, mDevices.size(), devices[i]);
          InputSystemHelper::AddDevice( m);
          mMiceById[devices[i].deviceid] = m;
        } catch( std::exception& e)
        {
          // TODO: invent logging
          Traum::Konsole.Log( "Exception: %s", e.what());
        }
        break;
      }

      case XISlaveKeyboard:
      {
        Traum::Konsole.Log( "Keyboard %d (id %d) - \"%s\"", mNumKeyboards, mDevices.size(), devices[i].name);
        // a keyboard
        if( strstr(devices[i].name, "XTEST") != nullptr )
          break;

        try {
          auto k = new LinuxKeyboard( this, mDevices.size(), devices[i]);
          InputSystemHelper::AddDevice( k);
          mKeyboardsById[devices[i].deviceid] = k;
        } catch( std::exception& e)
        {
          // TODO: invent logging
          Traum::Konsole.Log( "Exception: %s", e.what());
        }
        break;
      }

      default:
        // pffft.
        break;
    }
  }

  XIFreeDeviceInfo( devices);

  // use a completely different API for controllers, because XInput would be perfectly capable of supporting
  // those, too, but refuses to do so. It enumerates my USB headset as a keyboard, but it does not expose
  // my XBox controller. Sometimes I wish to look into the coders' minds and learn what possessed them when
  // designing x separate APIs for the same purpose, but each with a different set of flaws.
	for( size_t a = 0; a < 64; ++a )
	{
		std::stringstream eventPath;
		eventPath << "/dev/input/event" << a;
		int fd = open( eventPath.str().c_str(), O_RDWR |O_NONBLOCK );
		if( fd == -1 )
			continue;

    char tmp[256] = "Unknown";
    if( ioctl( fd, EVIOCGNAME( sizeof( tmp)), tmp) < 0)
      throw std::runtime_error( "Could not read device name");

    Traum::Konsole.Log( "Controller %d (id %d) - \"%s\"", mNumJoysticks, mDevices.size(), &tmp[0]);

    // check if it's a controller. If we're started with root privileges, we'd get mice and keyboards here, too,
    // but we can't rely on it, so we sort those out and only use it for controllers.
    // (Side note: mice and keyboards are root-only because you'd otherwise be able to write a keylogger with it.
    // It will take a few years until someone will notice that on SteamOS you enter your credit card credentials
    // and passwords with a controller. Then it's a viable approach to also spy on the controller, so they'll
    // probably make the controllers root-only, too, and this whole mess finally ends up
    // in the "Linux Hall Of Self-Digged Graves" where it belongs. Sorry for the rant.)
    uint8_t ev_bits[(EV_MAX+7)/8];
    memset( ev_bits, 0, sizeof(ev_bits) );

    //Read "all" (hence 0) components of the device
    if( ioctl( fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1 )
      throw std::runtime_error( "Could not read device events features");

    if( IsBitSet( ev_bits, EV_KEY) )
    {
      uint8_t key_bits[(KEY_MAX+7)/8];
      memset( key_bits, 0, sizeof(key_bits) );

      if( ioctl( fd, EVIOCGBIT( EV_KEY, sizeof(key_bits)), key_bits) == -1 )
        throw std::runtime_error( "Could not read device buttons features");

      bool isController = false;
      for( size_t b = 0; b < KEY_MAX; b++ )
      {
        if( IsBitSet( key_bits, b) )
        {
          // Check to ensure we find at least one joy only button
          if( (b >= BTN_JOYSTICK && b < BTN_GAMEPAD) || (b >= BTN_GAMEPAD && b < BTN_DIGI) || (b >= BTN_WHEEL && b < KEY_OK) )
            isController = true;
        }
      }

      if( isController )
      {
        try {
          auto j = new LinuxJoystick( this, mDevices.size(), fd);
          InputSystemHelper::AddDevice( j);
        } catch( std::exception& e)
        {
          // TODO: invent logging
          Traum::Konsole.Log( "Exception: %s", e.what());
        }
      } else
      {
        close( fd);
      }
    }
	}
}

// --------------------------------------------------------------------------------------------------------------------
// Destructor
LinuxInput::~LinuxInput()
{
  for( auto d : mDevices )
    delete d;

  if( mDisplay != nullptr )
    XCloseDisplay( mDisplay);
}

// --------------------------------------------------------------------------------------------------------------------
// Updates the inputs, to be called before handling system messages
void LinuxInput::Update()
{
  // Basis work
  InputSystem::Update();

  // begin updating all devices
  for( auto d : mDevices )
  {
    if( auto mouse = dynamic_cast<LinuxMouse*> (d) )
      mouse->StartUpdate();
    else if( auto keyboard = dynamic_cast<LinuxKeyboard*> (d) )
      keyboard->StartUpdate();
    else if( auto joy = dynamic_cast<LinuxJoystick*> (d) )
      joy->StartUpdate();
  }

  // process XEvents
  XEvent event;
	while( XPending( mDisplay) > 0 )
	{
		XNextEvent( mDisplay, &event);

    if( event.xcookie.type != GenericEvent )
      continue;
    else if( event.xcookie.extension != mXiOpcode )
      continue;
    else if( !XGetEventData( mDisplay, &event.xcookie) )
      continue;

    switch( event.xcookie.evtype )
    {
      case XI_RawMotion:
      case XI_RawButtonPress:
      case XI_RawButtonRelease:
      {
        auto rawev = *((const XIRawEvent *) event.xcookie.data);
        auto mit = mMiceById.find( rawev.deviceid);
        if( mit == mMiceById.end() )
          break;
        mit->second->HandleEvent( rawev);
        break;
      }

      case XI_RawKeyPress:
      case XI_RawKeyRelease:
      {
        auto rawev = *((const XIRawEvent *) event.xcookie.data);
        auto kit = mKeyboardsById.find( rawev.deviceid);
        if( kit == mKeyboardsById.end() )
          break;
        kit->second->HandleEvent( rawev);
        break;
      }
    }

    XFreeEventData( mDisplay, &event.xcookie);
  }

  // update postprocessing
  for( auto d : mDevices )
  {
    if( auto mouse = dynamic_cast<LinuxMouse*> (d) )
      mouse->EndUpdate();
  }
}

// --------------------------------------------------------------------------------------------------------------------
// Notifies the input system that the application has lost/gained focus.
void LinuxInput::InternSetFocus( bool pHasFocus)
{
  for( auto d : mDevices )
  {
    if( auto k = dynamic_cast<LinuxKeyboard*> (d) )
      k->SetFocus( mHasFocus);
    else if( auto m = dynamic_cast<LinuxMouse*> (d) )
      m->SetFocus( mHasFocus);
    else if( auto j = dynamic_cast<LinuxJoystick*> (d) )
      j->SetFocus( mHasFocus);
  }
}

// --------------------------------------------------------------------------------------------------------------------
void LinuxInput::InternSetMouseGrab( bool enabled)
{
  // The Linux XInput2 API is nice to already provide mouse acceleration and all, so all that mouse coordinate cheating
  // is simply not necessary. Just grab the mouse and be happy
  if( enabled )
  {
    XGrabPointer( mDisplay, mWindow, True, 0, GrabModeAsync, GrabModeAsync, mWindow, None, CurrentTime);
  } else
  {
    XUngrabPointer( mDisplay, CurrentTime);
  }
}

// --------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Initializes the input system with the given InitArgs. When successful, gInstance is not Null.
bool InputSystem::Initialize(void* pInitArg)
{
  if( gInstance )
    throw std::runtime_error( "Input already initialized");

  try
  {
    gInstance = new LinuxInput( (Window) pInitArg);
  } catch( std::exception& )
  {
    // nope
    gInstance = nullptr;
    return false;
  }

  return true;
}

// --------------------------------------------------------------------------------------------------------------------
// Destroys the input system. After returning gInstance is Null again
void InputSystem::Shutdown()
{
  delete gInstance;
  gInstance = nullptr;
}

#endif // SNIIS_SYSTEM_LINUX
<commit_msg>- improved guessing the device type on Linux<commit_after>/// @file SNIIS_Linux.cpp
/// Linux implementation of input

#include "SNIIS_Linux.h"
#include "SNIIS_Intern.h"

#if SNIIS_SYSTEM_LINUX
using namespace SNIIS;
#include "../Traumklassen/TraumBasis.h"

#include <cstring>
#include <sstream>
#include <fcntl.h>
#include <linux/input.h>

static bool IsBitSet( const uint8_t* bits, size_t i) { return (bits[i/8] & (1<<(i&7))) != 0; }

// --------------------------------------------------------------------------------------------------------------------
// Constructor
LinuxInput::LinuxInput( Window wnd)
{
  mWindow = wnd;
  mDisplay = nullptr;

  mDisplay = XOpenDisplay( nullptr);
  if( !mDisplay )
    throw std::runtime_error( "Failed to open XDisplay");

  int event = 0, error = 0;
  int major = 2, minor = 0;
  bool isAvailable = (XQueryExtension( mDisplay, "XInputExtension", &mXiOpcode, &event, &error) != False
               && XIQueryVersion( mDisplay, &major, &minor) != BadRequest);
  if( !isAvailable )
    throw std::runtime_error( "Failed to get XInputExtension");

  // Register for events
  XIEventMask evmask;
  uint8_t mask[] = { 0, 0, 0, 0 };
  XISetMask( mask, XI_HierarchyChanged);
  XISetMask( mask, XI_RawMotion);
  XISetMask( mask, XI_RawButtonPress);
  XISetMask( mask, XI_RawButtonRelease);
  XISetMask( mask, XI_RawKeyPress);
  XISetMask( mask, XI_RawKeyRelease);

  evmask.deviceid = XIAllDevices;
  evmask.mask_len = sizeof( mask);
  evmask.mask = mask;
  auto selwnd = DefaultRootWindow( mDisplay);
  if( XISelectEvents( mDisplay, selwnd, &evmask, 1) != 0 )
    throw std::runtime_error( "Failed to register for XInput2 events");

  int deviceCount = 0;
  XIDeviceInfo* devices = XIQueryDevice( mDisplay, XIAllDevices, &deviceCount);
  for( int i = 0; i < deviceCount; i++ )
  {
    /* We only look at "slave" devices. "Master" pointers are the logical
     * cursors, "slave" pointers are the hardware that back them.
     * "Floating slaves" are hardware that don't back a cursor.
     */

    switch( devices[i].use )
    {
      case XISlavePointer:
      {
        Traum::Konsole.Log( "Mouse %d (id %d) - \"%s\"", mNumMice, mDevices.size(), devices[i].name);

        // a mouse. probably. Ignore some common pffft cases
        if( strstr(devices[i].name, "XTEST") != nullptr )
          break;

        try {
          auto m = new LinuxMouse( this, mDevices.size(), devices[i]);
          InputSystemHelper::AddDevice( m);
          mMiceById[devices[i].deviceid] = m;
        } catch( std::exception& e)
        {
          // TODO: invent logging
          Traum::Konsole.Log( "Exception: %s", e.what());
        }
        break;
      }

      case XISlaveKeyboard:
      {
        Traum::Konsole.Log( "Keyboard %d (id %d) - \"%s\"", mNumKeyboards, mDevices.size(), devices[i].name);
        // a keyboard
        if( strstr(devices[i].name, "XTEST") != nullptr )
          break;

        try {
          auto k = new LinuxKeyboard( this, mDevices.size(), devices[i]);
          InputSystemHelper::AddDevice( k);
          mKeyboardsById[devices[i].deviceid] = k;
        } catch( std::exception& e)
        {
          // TODO: invent logging
          Traum::Konsole.Log( "Exception: %s", e.what());
        }
        break;
      }

      case XIFloatingSlave:
      {
        // Look through the controls of this device - if we find two absolute axes at 0 and 1, it might be a mouse.
        // Otherwise register it as a keyboard.
        const auto& dev = devices[i];
        bool isAxisPresent[2] = { false, false };
        for( int a = 0; a < dev.num_classes; ++a )
        {
          auto cl = dev.classes[a];
          if( cl->type != XIValuatorClass )
            continue;

          auto vcl = reinterpret_cast<const XIValuatorClassInfo*> (cl);
          if( vcl->number < 2 && vcl->mode == XIModeAbsolute )
            isAxisPresent[vcl->number] = true;
        }

        try {
          if( isAxisPresent[0] && isAxisPresent[1] )
          {
            Traum::Konsole.Log( "Floating slave \"%s\", seems to be mouse %d (id %d)", devices[i].name, mNumMice, mDevices.size());
            auto m = new LinuxMouse( this, mDevices.size(), dev);
            InputSystemHelper::AddDevice( m);
            mMiceById[dev.deviceid] = m;
          } else
          {
            Traum::Konsole.Log( "Floating slave \"%s\", seems to be keyboard %d (id %d)", devices[i].name, mNumKeyboards, mDevices.size());
            auto k = new LinuxKeyboard( this, mDevices.size(), dev);
            InputSystemHelper::AddDevice( k);
            mKeyboardsById[dev.deviceid] = k;
          }
        } catch( std::exception& e)
        {
          // TODO: invent logging
          Traum::Konsole.Log( "Exception: %s", e.what());
        }
        break;
      }

      default:
        // pffft.
        Traum::Konsole.Log( "Unknown device classs %d, ignoring.", devices[i].use);
        break;
    }
  }

  XIFreeDeviceInfo( devices);

  // use a completely different API for controllers, because XInput would be perfectly capable of supporting
  // those, too, but refuses to do so. It enumerates my USB headset as a keyboard, but it does not expose
  // my XBox controller. Sometimes I wish to look into the coders' minds and learn what possessed them when
  // designing x separate APIs for the same purpose, but each with a different set of flaws.
	for( size_t a = 0; a < 64; ++a )
	{
		std::stringstream eventPath;
		eventPath << "/dev/input/event" << a;
		int fd = open( eventPath.str().c_str(), O_RDWR |O_NONBLOCK );
		if( fd == -1 )
			continue;

    char tmp[256] = "Unknown";
    if( ioctl( fd, EVIOCGNAME( sizeof( tmp)), tmp) < 0)
      throw std::runtime_error( "Could not read device name");

    Traum::Konsole.Log( "Controller %d (id %d) - \"%s\"", mNumJoysticks, mDevices.size(), &tmp[0]);

    // check if it's a controller. If we're started with root privileges, we'd get mice and keyboards here, too,
    // but we can't rely on it, so we sort those out and only use it for controllers.
    // (Side note: mice and keyboards are root-only because you'd otherwise be able to write a keylogger with it.
    // It will take a few years until someone will notice that on SteamOS you enter your credit card credentials
    // and passwords with a controller. Then it's a viable approach to also spy on the controller, so they'll
    // probably make the controllers root-only, too, and this whole mess finally ends up
    // in the "Linux Hall Of Self-Digged Graves" where it belongs. Sorry for the rant.)
    uint8_t ev_bits[(EV_MAX+7)/8];
    memset( ev_bits, 0, sizeof(ev_bits) );

    //Read "all" (hence 0) components of the device
    if( ioctl( fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1 )
      throw std::runtime_error( "Could not read device events features");

    if( IsBitSet( ev_bits, EV_KEY) )
    {
      uint8_t key_bits[(KEY_MAX+7)/8];
      memset( key_bits, 0, sizeof(key_bits) );

      if( ioctl( fd, EVIOCGBIT( EV_KEY, sizeof(key_bits)), key_bits) == -1 )
        throw std::runtime_error( "Could not read device buttons features");

      bool isController = false;
      for( size_t b = 0; b < KEY_MAX; b++ )
      {
        if( IsBitSet( key_bits, b) )
        {
          // Check to ensure we find at least one joy only button
          if( (b >= BTN_JOYSTICK && b < BTN_GAMEPAD) || (b >= BTN_GAMEPAD && b < BTN_DIGI) || (b >= BTN_WHEEL && b < KEY_OK) )
            isController = true;
        }
      }

      if( isController )
      {
        try {
          auto j = new LinuxJoystick( this, mDevices.size(), fd);
          InputSystemHelper::AddDevice( j);
        } catch( std::exception& e)
        {
          // TODO: invent logging
          Traum::Konsole.Log( "Exception: %s", e.what());
        }
      } else
      {
        close( fd);
      }
    }
	}
}

// --------------------------------------------------------------------------------------------------------------------
// Destructor
LinuxInput::~LinuxInput()
{
  for( auto d : mDevices )
    delete d;

  if( mDisplay != nullptr )
    XCloseDisplay( mDisplay);
}

// --------------------------------------------------------------------------------------------------------------------
// Updates the inputs, to be called before handling system messages
void LinuxInput::Update()
{
  // Basis work
  InputSystem::Update();

  // begin updating all devices
  for( auto d : mDevices )
  {
    if( auto mouse = dynamic_cast<LinuxMouse*> (d) )
      mouse->StartUpdate();
    else if( auto keyboard = dynamic_cast<LinuxKeyboard*> (d) )
      keyboard->StartUpdate();
    else if( auto joy = dynamic_cast<LinuxJoystick*> (d) )
      joy->StartUpdate();
  }

  // process XEvents
  XEvent event;
	while( XPending( mDisplay) > 0 )
	{
		XNextEvent( mDisplay, &event);

    if( event.xcookie.type != GenericEvent )
      continue;
    else if( event.xcookie.extension != mXiOpcode )
      continue;
    else if( !XGetEventData( mDisplay, &event.xcookie) )
      continue;

    switch( event.xcookie.evtype )
    {
      case XI_RawMotion:
      case XI_RawButtonPress:
      case XI_RawButtonRelease:
      {
        auto rawev = *((const XIRawEvent *) event.xcookie.data);
        auto mit = mMiceById.find( rawev.deviceid);
        if( mit == mMiceById.end() )
          break;
        mit->second->HandleEvent( rawev);
        break;
      }

      case XI_RawKeyPress:
      case XI_RawKeyRelease:
      {
        auto rawev = *((const XIRawEvent *) event.xcookie.data);
        auto kit = mKeyboardsById.find( rawev.deviceid);
        if( kit == mKeyboardsById.end() )
          break;
        kit->second->HandleEvent( rawev);
        break;
      }
    }

    XFreeEventData( mDisplay, &event.xcookie);
  }

  // update postprocessing
  for( auto d : mDevices )
  {
    if( auto mouse = dynamic_cast<LinuxMouse*> (d) )
      mouse->EndUpdate();
  }
}

// --------------------------------------------------------------------------------------------------------------------
// Notifies the input system that the application has lost/gained focus.
void LinuxInput::InternSetFocus( bool pHasFocus)
{
  for( auto d : mDevices )
  {
    if( auto k = dynamic_cast<LinuxKeyboard*> (d) )
      k->SetFocus( mHasFocus);
    else if( auto m = dynamic_cast<LinuxMouse*> (d) )
      m->SetFocus( mHasFocus);
    else if( auto j = dynamic_cast<LinuxJoystick*> (d) )
      j->SetFocus( mHasFocus);
  }
}

// --------------------------------------------------------------------------------------------------------------------
void LinuxInput::InternSetMouseGrab( bool enabled)
{
  // The Linux XInput2 API is nice to already provide mouse acceleration and all, so all that mouse coordinate cheating
  // is simply not necessary. Just grab the mouse and be happy
  if( enabled )
  {
    XGrabPointer( mDisplay, mWindow, True, 0, GrabModeAsync, GrabModeAsync, mWindow, None, CurrentTime);
  } else
  {
    XUngrabPointer( mDisplay, CurrentTime);
  }
}

// --------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------
// Initializes the input system with the given InitArgs. When successful, gInstance is not Null.
bool InputSystem::Initialize(void* pInitArg)
{
  if( gInstance )
    throw std::runtime_error( "Input already initialized");

  try
  {
    gInstance = new LinuxInput( (Window) pInitArg);
  } catch( std::exception& )
  {
    // nope
    gInstance = nullptr;
    return false;
  }

  return true;
}

// --------------------------------------------------------------------------------------------------------------------
// Destroys the input system. After returning gInstance is Null again
void InputSystem::Shutdown()
{
  delete gInstance;
  gInstance = nullptr;
}

#endif // SNIIS_SYSTEM_LINUX
<|endoftext|>


<commit_before>#include "process.h"
#include <stdexcept>
#include <set>
#include <fstream>
#include <sstream>
#include <cstring>

#if defined(__linux__)
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
namespace scpak
{
    const char pathsep = '/';

    void createDirectory(const char *path)
    {
        int result = mkdir(path, 0777);
        if (result == -1)
            throw std::runtime_error("failed to create directory: " + std::string(path));
    }

    bool directoryExists(const char *path)
    {
        return access(path, F_OK) == 0;
    }

    int getFileSize(const char *path)
    {
        unsigned long filesize = -1;
        struct stat statbuf;
        if (stat(path, &statbuf) < 0)
            throw std::runtime_error("failed to get stat: " + std::string(path));
        filesize = statbuf.st_size;
        return static_cast<int>(filesize);
    }
}
#elif defined(MSV_VER)
# include <io.h>
namespace scpak
{
    const char pathsep = '\\';

    void createDirectory(const char *path)
    {
        int result = _mkdir(path);
        if (result == -1)
            throw std::runtime_error("failed to create directory: " + std::string(path));
    }
    bool directoryExists(const char *path)
    {
        return _access(path, 0) == 0;
    }
}
#endif

namespace scpak
{
    void unpack(const PakFile &pak, const std::string &dirPath)
    {
        std::string dirPathSafe = dirPath;
        if (*dirPathSafe.rbegin() != pathsep)
            dirPathSafe += pathsep;
        // find all the directories we possibly need to create
        std::set<std::string> directoriesToCreate;
        directoriesToCreate.insert(dirPath);
        for (const PakItem &item : pak.contents())
        {
            std::string filePath = dirPathSafe + item.name;
            std::size_t pend = filePath.rfind(pathsep);
            if (pend == std::string::npos)
                continue;
            std::size_t p = 0;
            while (p != pend)
            {
                p = filePath.find(pathsep, p+1);
                directoriesToCreate.insert(filePath.substr(0, p));
            }
        }
        // create directories if necessary
        for (const std::string &dir : directoriesToCreate)
            if (!directoryExists(dir.c_str()))
                createDirectory(dir.c_str());
        // unpack contents
        for (const PakItem &item : pak.contents())
        {
            if (std::strcmp(item.type, "System.String") == 0)
            {
                std::ofstream fout(dirPathSafe + item.name + ".txt", std::ios::binary);
                std::stringstream ss(reinterpret_cast<char*>(item.data));
                BinaryReader reader(&ss);
                std::string value = reader.readString();
                fout.write(value.data(), value.length());
                fout.close();
            }
            else if (std::strcmp(item.type, "System.Xml.Linq.XElement") == 0)
            {
                std::ofstream fout(dirPathSafe + item.name + ".xml", std::ios::binary);
                std::stringstream ss(reinterpret_cast<char*>(item.data));
                BinaryReader reader(&ss);
                std::string value = reader.readString();
                fout.write(value.data(), value.length());
                fout.close();
            }
            else
            {
                // just write out raw data
                std::ofstream fout(dirPathSafe + item.name, std::ios::binary);
                fout.write(reinterpret_cast<char*>(item.data), item.length);
                fout.close();
            }
        }
        // write pakinfo.txt - we need to repack it later
        std::ofstream fout(dirPathSafe + "pakinfo.txt");
        for (const PakItem &item : pak.contents())
            fout << item.name << ':' << item.type << std::endl;
        fout.close();
    }

    PakFile pack(const std::string &dirPath)
    {
        PakFile pak;
        std::vector<PakItem> contents = pak.contents();
        std::string dirPathSafe = dirPath;
        if (*dirPathSafe.rbegin() != pathsep)
            dirPathSafe += pathsep;
        std::ifstream fPakInfo(dirPathSafe + "pakinfo.txt");
        std::string line;
        int lineNumber = 1;
        while(std::getline(fPakInfo, line))
        {
            std::size_t p = line.find(':');
            if (p == std::string::npos)
            {
                std::stringstream ss;
                ss << "cannot parse pakinfo.txt, line " << lineNumber;
                throw std::runtime_error(ss.str());
            }
            std::string name = line.substr(0, p);
            std::string type = line.substr(p+1, std::string::npos);
            PakItem item;
            item.name = new char[name.length()+1];
            strcpy(item.name, name.c_str());
            item.type = new char[type.length()+1];
            strcpy(item.type, type.c_str());
            if (type == "System.String")
            {
                std::string filePath = dirPathSafe + name + ".txt";
                int fileSize = getFileSize(filePath.c_str());
                std::ifstream file(filePath, std::ios::binary);
                item.data = new byte[fileSize+5];
                std::stringstream ss(reinterpret_cast<char*>(item.data));
                BinaryWriter writer(&ss);
                writer.write7BitEncodedInt(fileSize);
                item.length = fileSize + ss.tellp();
                file.read(reinterpret_cast<char*>(item.data+ss.tellp()), fileSize);
                file.close();
            }
            else if (type == "System.Xml.Linq.XElement")
            {
                std::string filePath = dirPathSafe + name + ".xml";
                int fileSize = getFileSize(filePath.c_str());
                std::ifstream file(filePath, std::ios::binary);
                item.data = new byte[fileSize+5];
                std::stringstream ss(reinterpret_cast<char*>(item.data));
                BinaryWriter writer(&ss);
                writer.write7BitEncodedInt(fileSize);
                item.length = fileSize + ss.tellp();
                file.read(reinterpret_cast<char*>(item.data+ss.tellp()), fileSize);
                file.close();
            }
            else
            {
                std::string filePath = dirPathSafe + name;
                int fileSize = getFileSize(filePath.c_str());
                std::ifstream file(filePath, std::ios::binary);
                item.data = new byte[fileSize];
                item.length = fileSize;
                file.read(reinterpret_cast<char*>(item.data), fileSize);
                file.close();
            }
            pak.addItem(std::move(item));
            ++lineNumber;
        }
        fPakInfo.close();
        return pak;
    }
}

<commit_msg>port to win32<commit_after>#include "process.h"
#include <stdexcept>
#include <set>
#include <fstream>
#include <sstream>
#include <cstring>

#if defined(__linux__)
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
namespace scpak
{
    const char pathsep = '/';

    void createDirectory(const char *path)
    {
        int result = mkdir(path, 0777);
        if (result == -1)
            throw std::runtime_error("failed to create directory: " + std::string(path));
    }

    bool directoryExists(const char *path)
    {
        return access(path, F_OK) == 0;
    }

    int getFileSize(const char *path)
    {
        unsigned long filesize = -1;
        struct stat statbuf;
        if (stat(path, &statbuf) < 0)
            throw std::runtime_error("failed to get call stat: " + std::string(path));
        filesize = statbuf.st_size;
        return static_cast<int>(filesize);
    }
}
#elif defined(_WIN32)
# include <windows.h>
namespace scpak
{
    const char pathsep = '\\';

    void createDirectory(const char *path)
    {
		int result = CreateDirectoryA(path, NULL);
        if (result == 0)
            throw std::runtime_error("failed to get file size: " + std::string(path));
    }

    bool directoryExists(const char *path)
    {
		WIN32_FIND_DATA FindFileData;
		HANDLE hFind;
		hFind = FindFirstFileA(path, &FindFileData);
		if (hFind == INVALID_HANDLE_VALUE)
			return false;
		else
		{
			FindClose(hFind);
			return true;
		}
    }

	int getFileSize(const char *path)
	{
		WIN32_FIND_DATA fileInfo;
		HANDLE hFind;
		hFind = FindFirstFileA(path, &fileInfo);
		if (hFind == INVALID_HANDLE_VALUE)
			throw std::runtime_error("failed get file size: " + std::string(path));
		int size = fileInfo.nFileSizeLow;
		FindClose(hFind);
		return size;
	}
}
#endif

namespace scpak
{
    void unpack(const PakFile &pak, const std::string &dirPath)
    {
        std::string dirPathSafe = dirPath;
        if (*dirPathSafe.rbegin() != pathsep)
            dirPathSafe += pathsep;
        // find all the directories we possibly need to create
        std::set<std::string> directoriesToCreate;
        directoriesToCreate.insert(dirPath);
        for (const PakItem &item : pak.contents())
        {
            std::string filePath = dirPathSafe + item.name;
            std::size_t pend = filePath.rfind(pathsep);
            if (pend == std::string::npos)
                continue;
            std::size_t p = 0;
            while (p != pend)
            {
                p = filePath.find(pathsep, p+1);
                directoriesToCreate.insert(filePath.substr(0, p));
            }
        }
        // create directories if necessary
        for (const std::string &dir : directoriesToCreate)
            if (!directoryExists(dir.c_str()))
                createDirectory(dir.c_str());
        // unpack contents
        for (const PakItem &item : pak.contents())
        {
            if (std::strcmp(item.type, "System.String") == 0)
            {
                std::ofstream fout(dirPathSafe + item.name + ".txt", std::ios::binary);
                std::stringstream ss(reinterpret_cast<char*>(item.data));
                BinaryReader reader(&ss);
                std::string value = reader.readString();
                fout.write(value.data(), value.length());
                fout.close();
            }
            else if (std::strcmp(item.type, "System.Xml.Linq.XElement") == 0)
            {
                std::ofstream fout(dirPathSafe + item.name + ".xml", std::ios::binary);
                std::stringstream ss(reinterpret_cast<char*>(item.data));
                BinaryReader reader(&ss);
                std::string value = reader.readString();
                fout.write(value.data(), value.length());
                fout.close();
            }
            else
            {
                // just write out raw data
                std::ofstream fout(dirPathSafe + item.name, std::ios::binary);
                fout.write(reinterpret_cast<char*>(item.data), item.length);
                fout.close();
            }
        }
        // write pakinfo.txt - we need to repack it later
        std::ofstream fout(dirPathSafe + "pakinfo.txt");
        for (const PakItem &item : pak.contents())
            fout << item.name << ':' << item.type << std::endl;
        fout.close();
    }

    PakFile pack(const std::string &dirPath)
    {
        PakFile pak;
        std::vector<PakItem> contents = pak.contents();
        std::string dirPathSafe = dirPath;
        if (*dirPathSafe.rbegin() != pathsep)
            dirPathSafe += pathsep;
        std::ifstream fPakInfo(dirPathSafe + "pakinfo.txt");
        std::string line;
        int lineNumber = 1;
        while(std::getline(fPakInfo, line))
        {
            std::size_t p = line.find(':');
            if (p == std::string::npos)
            {
                std::stringstream ss;
                ss << "cannot parse pakinfo.txt, line " << lineNumber;
                throw std::runtime_error(ss.str());
            }
            std::string name = line.substr(0, p);
            std::string type = line.substr(p+1, std::string::npos);
            PakItem item;
            item.name = new char[name.length()+1];
            strcpy(item.name, name.c_str());
            item.type = new char[type.length()+1];
            strcpy(item.type, type.c_str());
            if (type == "System.String")
            {
                std::string filePath = dirPathSafe + name + ".txt";
                int fileSize = getFileSize(filePath.c_str());
                std::ifstream file(filePath, std::ios::binary);
                item.data = new byte[fileSize+5];
                std::stringstream ss(reinterpret_cast<char*>(item.data));
                BinaryWriter writer(&ss);
                writer.write7BitEncodedInt(fileSize);
                item.length = fileSize + ss.tellp();
                file.read(reinterpret_cast<char*>(item.data+ss.tellp()), fileSize);
                file.close();
            }
            else if (type == "System.Xml.Linq.XElement")
            {
                std::string filePath = dirPathSafe + name + ".xml";
                int fileSize = getFileSize(filePath.c_str());
                std::ifstream file(filePath, std::ios::binary);
                item.data = new byte[fileSize+5];
                std::stringstream ss(reinterpret_cast<char*>(item.data));
                BinaryWriter writer(&ss);
                writer.write7BitEncodedInt(fileSize);
                item.length = fileSize + ss.tellp();
                file.read(reinterpret_cast<char*>(item.data+ss.tellp()), fileSize);
                file.close();
            }
            else
            {
                std::string filePath = dirPathSafe + name;
                int fileSize = getFileSize(filePath.c_str());
                std::ifstream file(filePath, std::ios::binary);
                item.data = new byte[fileSize];
                item.length = fileSize;
                file.read(reinterpret_cast<char*>(item.data), fileSize);
                file.close();
            }
            pak.addItem(std::move(item));
            ++lineNumber;
        }
        fPakInfo.close();
        return pak;
    }
}

<|endoftext|>


<commit_before>/**
 * A set of network utility functions.
 *
 * @date                    December 13, 2014
 * @author                  Joeri HERMANS
 * @version                 0.1
 *
 * Copyright 2014 Joeri HERMANS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// BEGIN Includes. ///////////////////////////////////////////////////

// System dependencies.
#include <cassert>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <iostream>
#include <poll.h>
#include <netdb.h>
#include <errno.h>

// System dependencies.
#include <ias/network/util.h>

// END Includes. /////////////////////////////////////////////////////

int connect( const std::string & address, const std::size_t port ) {
    struct addrinfo hints;
    struct addrinfo * results;
    std::string portString;
    int result;
    int fd;

    // Checking the precondition.
    assert( !address.empty() && port > 0 );

    result = -1;
    memset(&hints,0,sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    portString = std::to_string(port);
    getaddrinfo(address.c_str(),portString.c_str(),&hints,&results);
    if( results != nullptr ) {
        fd = socket(results->ai_family,results->ai_socktype,results->ai_protocol);
        if( fd >= 0 ) {
            if( connect(fd,results->ai_addr,results->ai_addrlen) == 0 )
                result = fd;
            else
                close(fd);
        }
        freeaddrinfo(results);
    }

    return ( result );
}

bool enableKeepAlive( const int fd ) {
    static const int optval = 1;
    bool s;

    s = (setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,&optval,sizeof optval) >= 0);

    return ( s );
}
<commit_msg>Add implementation of the disableNagle prototype. Add preconditions.<commit_after>/**
 * A set of network utility functions.
 *
 * @date                    December 13, 2014
 * @author                  Joeri HERMANS
 * @version                 0.1
 *
 * Copyright 2014 Joeri HERMANS
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// BEGIN Includes. ///////////////////////////////////////////////////

// System dependencies.
#include <cassert>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <iostream>
#include <poll.h>
#include <netdb.h>
#include <errno.h>

// System dependencies.
#include <ias/network/util.h>

// END Includes. /////////////////////////////////////////////////////

int connect( const std::string & address, const std::size_t port ) {
    struct addrinfo hints;
    struct addrinfo * results;
    std::string portString;
    int result;
    int fd;

    // Checking the precondition.
    assert( !address.empty() && port > 0 );

    result = -1;
    memset(&hints,0,sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    portString = std::to_string(port);
    getaddrinfo(address.c_str(),portString.c_str(),&hints,&results);
    if( results != nullptr ) {
        fd = socket(results->ai_family,results->ai_socktype,results->ai_protocol);
        if( fd >= 0 ) {
            if( connect(fd,results->ai_addr,results->ai_addrlen) == 0 )
                result = fd;
            else
                close(fd);
        }
        freeaddrinfo(results);
    }

    return ( result );
}

bool enableKeepAlive( const int fd ) {
    static const int optval = 1;
    bool s;

    s = (setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,&optval,sizeof optval) >= 0);

    return ( s );
}

bool disableNagle( const int fd ) {
    static const int optval = 1;
    bool s;

    s = (setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,&optval,sizeof optval) >= 0);

    return (s);
}
<|endoftext|>


<commit_before>//#####################################################################
// Class Rotation
//#####################################################################
#include <other/core/python/from_python.h>
#include <other/core/array/convert.h>
#include <other/core/vector/Matrix.h>
#include <other/core/vector/Rotation.h>
#include <other/core/python/numpy.h>
#include <other/core/python/wrap.h>
namespace other{

typedef real T;

#ifdef OTHER_PYTHON

namespace {
template<class TV> struct NumpyDescr<Rotation<TV>>{static PyArray_Descr* d;static PyArray_Descr* descr(){OTHER_ASSERT(d);Py_INCREF(d);return d;}};
template<class TV> struct NumpyArrayType<Rotation<TV>>{static PyTypeObject* t;static PyTypeObject* type(){OTHER_ASSERT(t);Py_INCREF(t);return t;}};
template<class TV> struct NumpyIsStatic<Rotation<TV>>:public mpl::true_{};
template<class TV> struct NumpyRank<Rotation<TV>>:public mpl::int_<0>{};

template<class TV> PyArray_Descr* NumpyDescr<Rotation<TV>>::d;
template<class TV> PyTypeObject* NumpyArrayType<Rotation<TV>>::t;
}

static void set_rotation_types(PyObject* t2d,PyObject* t3d) {
  OTHER_ASSERT(PyType_Check(t2d));
  OTHER_ASSERT(PyType_Check(t3d));
  PyObject* d2d = PyObject_GetAttrString(t2d,"dtype");
  if (!d2d) throw_python_error();
  PyObject* d3d = PyObject_GetAttrString(t3d,"dtype");
  if (!d3d) throw_python_error();
  OTHER_ASSERT(PyArray_DescrCheck(d2d));
  OTHER_ASSERT(PyArray_DescrCheck(d3d));
  Py_INCREF(t2d);
  Py_INCREF(t3d);
  Py_INCREF(d2d);
  Py_INCREF(d3d);
  NumpyArrayType<Rotation<Vector<real,2>>>::t = (PyTypeObject*)t2d;
  NumpyArrayType<Rotation<Vector<real,3>>>::t = (PyTypeObject*)t3d;
  NumpyDescr<Rotation<Vector<real,2>>>::d = (PyArray_Descr*)d2d;
  NumpyDescr<Rotation<Vector<real,3>>>::d = (PyArray_Descr*)d3d;
}

template<class TV> PyObject* to_python(const Rotation<TV>& q) {
  return to_numpy(q);
}

template<class TV> bool rotations_check(PyObject* object) {
  return PyArray_Check(object) && PyArray_EquivTypes(PyArray_DESCR((PyArrayObject*)object),NumpyDescr<Rotation<TV>>::d);
}

template<class TV> Rotation<TV> FromPython<Rotation<TV>>::convert(PyObject* object) {
  if (!rotations_check<TV>(object))
    throw_array_conversion_error(object,0,0,NumpyDescr<Rotation<TV>>::d);
  return from_numpy<Rotation<TV>>(object);
}

#define INSTANTIATE(T,d) \
    template OTHER_CORE_EXPORT PyObject* to_python<Vector<T,d>>(const Rotation<Vector<T,d>>&); \
    template OTHER_CORE_EXPORT Rotation<Vector<T,d>> FromPython<Rotation<Vector<T,d>>>::convert(PyObject*); \
    template OTHER_CORE_EXPORT bool rotations_check<Vector<T,d>>(PyObject*); \
    ARRAY_CONVERSIONS(1,Rotation<Vector<T,d>>)
INSTANTIATE(real,2)
INSTANTIATE(real,3)

template<class TV> static Rotation<TV> rotation_test(const Rotation<TV>& r) {
    return r*r;
}

template<class TV> static Array<Rotation<TV>> rotation_array_test(Array<const Rotation<TV>> r) {
    Array<Rotation<TV>> rr(r.size());
    for (int i=0;i<r.size();i++)
        rr[i] = sqr(r[i]);
    return rr;
}

static PyObject* rotation_from_matrix(NdArray<const real> A) {
  OTHER_ASSERT(A.rank()>=2);
  const int r = A.rank();
  if (A.shape[r-1]==2 && A.shape[r-2]==2) {
    NdArray<Rotation<Vector<T,2>>> rs(A.shape.slice_own(0,r-2),false);
    for (const int i : range(rs.flat.size()))
      rs.flat[i] = Rotation<Vector<T,2>>(Matrix<real,2>(A.flat.slice(4*i,4*(i+1)).reshape(2,2)));
    return to_python(rs);
  } else if (A.shape[r-1]==3 && A.shape[r-2]==3) {
    NdArray<Rotation<Vector<T,3>>> rs(A.shape.slice_own(0,r-2),false);
    for (const int i : range(rs.flat.size()))
      rs.flat[i] = Rotation<Vector<T,3>>(Matrix<real,3>(A.flat.slice(9*i,9*(i+1)).reshape(3,3)));
    return to_python(rs);
  } else
    throw TypeError(format("expected 2x2 or 3x3 matrices, got shape %s",str(A.shape)));
}

#endif
}
using namespace other;

void wrap_rotation() {
#ifdef OTHER_PYTHON
  using namespace python;
  function("_set_rotation_types",set_rotation_types);
  function("rotation_test_2d",rotation_test<Vector<real,2>>);
  function("rotation_test_3d",rotation_test<Vector<real,3>>);
  function("rotation_array_test_2d",rotation_array_test<Vector<real,2>>);
  function("rotation_array_test_3d",rotation_array_test<Vector<real,3>>);
  OTHER_FUNCTION(rotation_from_matrix);
#endif
}
<commit_msg>Remove an unnecessary semicolon<commit_after>//#####################################################################
// Class Rotation
//#####################################################################
#include <other/core/python/from_python.h>
#include <other/core/array/convert.h>
#include <other/core/vector/Matrix.h>
#include <other/core/vector/Rotation.h>
#include <other/core/python/numpy.h>
#include <other/core/python/wrap.h>
namespace other{

typedef real T;

#ifdef OTHER_PYTHON

namespace {
template<class TV> struct NumpyDescr<Rotation<TV>>{static PyArray_Descr* d;static PyArray_Descr* descr(){OTHER_ASSERT(d);Py_INCREF(d);return d;}};
template<class TV> struct NumpyArrayType<Rotation<TV>>{static PyTypeObject* t;static PyTypeObject* type(){OTHER_ASSERT(t);Py_INCREF(t);return t;}};
template<class TV> struct NumpyIsStatic<Rotation<TV>>:public mpl::true_{};
template<class TV> struct NumpyRank<Rotation<TV>>:public mpl::int_<0>{};

template<class TV> PyArray_Descr* NumpyDescr<Rotation<TV>>::d;
template<class TV> PyTypeObject* NumpyArrayType<Rotation<TV>>::t;
}

static void set_rotation_types(PyObject* t2d,PyObject* t3d) {
  OTHER_ASSERT(PyType_Check(t2d));
  OTHER_ASSERT(PyType_Check(t3d));
  PyObject* d2d = PyObject_GetAttrString(t2d,"dtype");
  if (!d2d) throw_python_error();
  PyObject* d3d = PyObject_GetAttrString(t3d,"dtype");
  if (!d3d) throw_python_error();
  OTHER_ASSERT(PyArray_DescrCheck(d2d));
  OTHER_ASSERT(PyArray_DescrCheck(d3d));
  Py_INCREF(t2d);
  Py_INCREF(t3d);
  Py_INCREF(d2d);
  Py_INCREF(d3d);
  NumpyArrayType<Rotation<Vector<real,2>>>::t = (PyTypeObject*)t2d;
  NumpyArrayType<Rotation<Vector<real,3>>>::t = (PyTypeObject*)t3d;
  NumpyDescr<Rotation<Vector<real,2>>>::d = (PyArray_Descr*)d2d;
  NumpyDescr<Rotation<Vector<real,3>>>::d = (PyArray_Descr*)d3d;
}

template<class TV> PyObject* to_python(const Rotation<TV>& q) {
  return to_numpy(q);
}

template<class TV> bool rotations_check(PyObject* object) {
  return PyArray_Check(object) && PyArray_EquivTypes(PyArray_DESCR((PyArrayObject*)object),NumpyDescr<Rotation<TV>>::d);
}

template<class TV> Rotation<TV> FromPython<Rotation<TV>>::convert(PyObject* object) {
  if (!rotations_check<TV>(object))
    throw_array_conversion_error(object,0,0,NumpyDescr<Rotation<TV>>::d);
  return from_numpy<Rotation<TV>>(object);
}

#define INSTANTIATE(T,d) \
    template OTHER_CORE_EXPORT PyObject* to_python<Vector<T,d>>(const Rotation<Vector<T,d>>&); \
    template OTHER_CORE_EXPORT Rotation<Vector<T,d>> FromPython<Rotation<Vector<T,d>>>::convert(PyObject*); \
    template OTHER_CORE_EXPORT bool rotations_check<Vector<T,d>>(PyObject*); \
    ARRAY_CONVERSIONS(1,Rotation<Vector<T,d>>)
INSTANTIATE(real,2)
INSTANTIATE(real,3)

template<class TV> static Rotation<TV> rotation_test(const Rotation<TV>& r) {
    return r*r;
}

template<class TV> static Array<Rotation<TV>> rotation_array_test(Array<const Rotation<TV>> r) {
    Array<Rotation<TV>> rr(r.size());
    for (int i=0;i<r.size();i++)
        rr[i] = sqr(r[i]);
    return rr;
}

static PyObject* rotation_from_matrix(NdArray<const real> A) {
  OTHER_ASSERT(A.rank()>=2);
  const int r = A.rank();
  if (A.shape[r-1]==2 && A.shape[r-2]==2) {
    NdArray<Rotation<Vector<T,2>>> rs(A.shape.slice_own(0,r-2),false);
    for (const int i : range(rs.flat.size()))
      rs.flat[i] = Rotation<Vector<T,2>>(Matrix<real,2>(A.flat.slice(4*i,4*(i+1)).reshape(2,2)));
    return to_python(rs);
  } else if (A.shape[r-1]==3 && A.shape[r-2]==3) {
    NdArray<Rotation<Vector<T,3>>> rs(A.shape.slice_own(0,r-2),false);
    for (const int i : range(rs.flat.size()))
      rs.flat[i] = Rotation<Vector<T,3>>(Matrix<real,3>(A.flat.slice(9*i,9*(i+1)).reshape(3,3)));
    return to_python(rs);
  } else
    throw TypeError(format("expected 2x2 or 3x3 matrices, got shape %s",str(A.shape)));
}

#endif
}
using namespace other;

void wrap_rotation() {
#ifdef OTHER_PYTHON
  using namespace python;
  function("_set_rotation_types",set_rotation_types);
  function("rotation_test_2d",rotation_test<Vector<real,2>>);
  function("rotation_test_3d",rotation_test<Vector<real,3>>);
  function("rotation_array_test_2d",rotation_array_test<Vector<real,2>>);
  function("rotation_array_test_3d",rotation_array_test<Vector<real,3>>);
  OTHER_FUNCTION(rotation_from_matrix)
#endif
}
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
// This software is in the public domain, furnished "as is", without technical
// support, and with no warranty, express or implied, as to its usefulness for
// any purpose.
//
// array.hpp
// An STL-like structure that resides in video memory.
//
// Author: Scott D. Zuyderduyn, Ph.D. (scott.zuyderduyn@utoronto.ca)
//----------------------------------------------------------------------------

#pragma once
#ifndef ECUDA_ARRAY_HPP
#define ECUDA_ARRAY_HPP

#include <cstddef>
#include <limits>
#include <vector>
#include "iterators.hpp"
//#include <estd/iterators.hpp>
#include "global.hpp"
#include "memory.hpp"

namespace ecuda {

template<typename T>
class array {

public:
	typedef T value_type;
	typedef std::size_t size_type;
	typedef std::ptrdiff_t difference_type;
	typedef value_type& reference;
	typedef const value_type& const_reference;
	typedef value_type* pointer;
	typedef const value_type* const_pointer;

	typedef ecuda::RandomAccessIterator< array<T> > iterator;
	typedef const ecuda::RandomAccessIterator< const array<T> > const_iterator;
/*
public:
	struct DevicePayload {
		size_type n;
		device_ptr<T> deviceMemory;
	};
*/
private:
	size_type n;
	device_ptr<T> deviceMemory; // video card memory

public:
	__host__ __device__ array( const size_type n=0, const_reference value = T() ) : n(n) {
		#ifndef __CUDA_ARCH__
		if( n ) {
			CUDA_CALL( cudaMalloc( deviceMemory.alloc_ptr(), n*sizeof(T) ) );
			std::vector<T> v( n, value );
			CUDA_CALL( cudaMemcpy( deviceMemory.get(), &v[0], n*sizeof(T), cudaMemcpyHostToDevice ) );
		}
		#endif
	}
	__host__ array( const array<T>& src ) : n(src.n) {
		if( n ) {
			CUDA_CALL( cudaMalloc( deviceMemory.alloc_ptr(), n*sizeof(T) ) );
			CUDA_CALL( cudaMemcpy( deviceMemory.get(), src.deviceMemory.get(), n*sizeof(T), cudaMemcpyDeviceToDevice ) );
		}
	}
	__host__ array( const std::vector<T>& src ) : n(src.size()) {
		if( n ) {
			CUDA_CALL( cudaMalloc( deviceMemory.alloc_ptr(), n*sizeof(T) ) );
			CUDA_CALL( cudaMemcpy( deviceMemory.get(), &src[0], n*sizeof(T), cudaMemcpyHostToDevice ) );
		}
	}
	/*
	__host__ array( const T* sourcePtr, const size_type n=0 ) : n(n) {
		if( n ) {
			CUDA_CALL( cudaMalloc( deviceMemory.alloc_ptr(), n*sizeof(T) ) );
			CUDA_CALL( cudaMemcpy( deviceMemory.get(), sourcePtr, n*sizeof(T), cudaMemcpyHostToDevice ) );
		}
	}
	*/

	//__device__ array( const DevicePayload& devicePayload ) : n(devicePayload.n), deviceMemory(devicePayload.deviceMemory) {}

	__host__ __device__ virtual ~array() {}

	__device__ reference at( size_type index ) { return deviceMemory[index]; }
	__device__ reference operator[]( size_type index ) { return deviceMemory[index]; }
	__device__ const_reference at( size_type index ) const { return deviceMemory[index]; }
	__device__ const_reference operator[]( size_type index ) const { return deviceMemory[index]; }

	__device__ reference front() { return *deviceMemory; }
	__device__ reference back() { return operator[]( size()-1 ); }
	__device__ const_reference front() const { return *deviceMemory; }
	__device__ const_reference back() const { return operator[]( size()-1 ); }

	__host__ __device__ size_type size() const { return n; }

	__device__ iterator begin() { return iterator(*this); }
	__device__ iterator end() { return iterator(*this,size()); }
	__device__ const_iterator begin() const { return const_iterator(*this); }
	__device__ const_iterator end() const { return const_iterator(*this,size()); }

	__host__ const array<T>& operator>>( std::vector<T>& vector ) const {
		vector.resize( n );
std::cerr << "copy destination = " << deviceMemory.get() << std::endl;
std::cerr << "copying device contents of size " << n << " [" << (n*sizeof(T)) << "] to host vector" << std::endl;
		CUDA_CALL( cudaMemcpy( &vector[0], deviceMemory.get(), n*sizeof(T), cudaMemcpyDeviceToHost ) );
for( size_t i = 0; i < n; ++i ) std::cerr << "IN SITU [" << i << "]=" << vector[i] << std::endl;
		return *this;
	}

	__device__ array<T>& operator=( const array<T>& other ) {
		n = other.n;
		deviceMemory = other.deviceMemory;
		return *this;
	}

	/*
	DevicePayload passToDevice() {
		DevicePayload payload;
		payload.n = n;
		payload.deviceMemory = deviceMemory;
		return payload;
	}
	*/

};

} // namespace ecuda

#endif
<commit_msg>working array<commit_after>//----------------------------------------------------------------------------
// This software is in the public domain, furnished "as is", without technical
// support, and with no warranty, express or implied, as to its usefulness for
// any purpose.
//
// array.hpp
// An STL-like structure that resides in video memory.
//
// Author: Scott D. Zuyderduyn, Ph.D. (scott.zuyderduyn@utoronto.ca)
//----------------------------------------------------------------------------

#pragma once
#ifndef ECUDA_ARRAY_HPP
#define ECUDA_ARRAY_HPP

#include <cstddef>
#include <limits>
#include <vector>
#include "iterators.hpp"
//#include <estd/iterators.hpp>
#include "global.hpp"
#include "memory.hpp"

namespace ecuda {

template<typename T>
class array {

public:
	typedef T value_type;
	typedef std::size_t size_type;
	typedef std::ptrdiff_t difference_type;
	typedef value_type& reference;
	typedef const value_type& const_reference;
	typedef value_type* pointer;
	typedef const value_type* const_pointer;

	typedef ecuda::RandomAccessIterator< array<T> > iterator;
	typedef const ecuda::RandomAccessIterator< const array<T> > const_iterator;
/*
public:
	struct DevicePayload {
		size_type n;
		device_ptr<T> deviceMemory;
	};
*/
private:
	size_type n;
	device_ptr<T> deviceMemory; // video card memory

public:
	__host__ __device__ array( const size_type n=0, const_reference value = T() ) : n(n) {
		#ifndef __CUDA_ARCH__
		if( n ) {
			CUDA_CALL( cudaMalloc( deviceMemory.alloc_ptr(), n*sizeof(T) ) );
			std::vector<T> v( n, value );
			CUDA_CALL( cudaMemcpy( deviceMemory.get(), &v[0], n*sizeof(T), cudaMemcpyHostToDevice ) );
		}
		#endif
	}
	__host__ array( const array<T>& src ) : n(src.n), deviceMemory(src.deviceMemory) {
		std::cerr << "performing inplace copy" << std::endl;
/*
		if( n ) {
			CUDA_CALL( cudaMalloc( deviceMemory.alloc_ptr(), n*sizeof(T) ) );
			CUDA_CALL( cudaMemcpy( deviceMemory.get(), src.deviceMemory.get(), n*sizeof(T), cudaMemcpyDeviceToDevice ) );
		}
*/
	}
	__host__ array( const std::vector<T>& src ) : n(src.size()) {
		if( n ) {
			CUDA_CALL( cudaMalloc( deviceMemory.alloc_ptr(), n*sizeof(T) ) );
			CUDA_CALL( cudaMemcpy( deviceMemory.get(), &src[0], n*sizeof(T), cudaMemcpyHostToDevice ) );
		}
	}
	/*
	__host__ array( const T* sourcePtr, const size_type n=0 ) : n(n) {
		if( n ) {
			CUDA_CALL( cudaMalloc( deviceMemory.alloc_ptr(), n*sizeof(T) ) );
			CUDA_CALL( cudaMemcpy( deviceMemory.get(), sourcePtr, n*sizeof(T), cudaMemcpyHostToDevice ) );
		}
	}
	*/

	//__device__ array( const DevicePayload& devicePayload ) : n(devicePayload.n), deviceMemory(devicePayload.deviceMemory) {}

	__host__ __device__ virtual ~array() {}

	__device__ reference at( size_type index ) { return deviceMemory[index]; }
	__device__ reference operator[]( size_type index ) { return deviceMemory[index]; }
	__device__ const_reference at( size_type index ) const { return deviceMemory[index]; }
	__device__ const_reference operator[]( size_type index ) const { return deviceMemory[index]; }

	__device__ reference front() { return *deviceMemory; }
	__device__ reference back() { return operator[]( size()-1 ); }
	__device__ const_reference front() const { return *deviceMemory; }
	__device__ const_reference back() const { return operator[]( size()-1 ); }

	__host__ __device__ size_type size() const { return n; }

	__device__ iterator begin() { return iterator(*this); }
	__device__ iterator end() { return iterator(*this,size()); }
	__device__ const_iterator begin() const { return const_iterator(*this); }
	__device__ const_iterator end() const { return const_iterator(*this,size()); }

	__host__ const array<T>& operator>>( std::vector<T>& vector ) const {
		vector.resize( n );
std::cerr << "copy destination = " << deviceMemory.get() << std::endl;
std::cerr << "copying device contents of size " << n << " [" << (n*sizeof(T)) << "] to host vector" << std::endl;
		CUDA_CALL( cudaMemcpy( &vector[0], deviceMemory.get(), n*sizeof(T), cudaMemcpyDeviceToHost ) );
for( size_t i = 0; i < n; ++i ) std::cerr << "IN SITU [" << i << "]=" << vector[i] << std::endl;
		return *this;
	}

	__device__ array<T>& operator=( const array<T>& other ) {
		n = other.n;
		deviceMemory = other.deviceMemory;
		return *this;
	}

	/*
	DevicePayload passToDevice() {
		DevicePayload payload;
		payload.n = n;
		payload.deviceMemory = deviceMemory;
		return payload;
	}
	*/

};

} // namespace ecuda

#endif
<|endoftext|>