<commit_before>#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <algorithm>
#include "time.h"

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#include "atlstr.h"

using namespace std;

using namespace System;

void compareAndSwap(int* first, int* second);

void mergeSort(int* numbers, int size);

void printMergeIndicies(int size);

void printArray(int *numbers, int length);

DWORD WINAPI workerFunction(LPVOID lpParam);

BOOL setConsoleFontSize(int size);

struct MergeData
{
	int* first;
	int* second;
};

int main()
{
	setConsoleFontSize(32);

	int size;
	cout << "Please, enter length of the array" << endl;
	cin >> size;
	srand(time(0));

	int* numbers = new int[size];
	for (int i = 0; i < size; i++)
	{
		numbers[i] = rand() % 100 + 1;
	}

	cout << "Generated array: ";
	printArray(numbers, size);

	cout << "Compared indicies step by step:" << endl;
	printMergeIndicies(size);

	mergeSort(numbers, size);

	cout << "Sorted array: ";
	printArray(numbers, size);

	delete[] numbers;

	return 0;
}

void mergeSort(int* numbers, int size)
{
	HANDLE* hThreadArray = new HANDLE[size / 2];
	MergeData* dataArray = new MergeData[size / 2];

	for (int phase = 1; phase < size; phase *= 2)
	{
		for (int comparatorSize = phase; comparatorSize > 0; comparatorSize /= 2)
		{
			int index = 0;
			for (int startIndexInBlock = comparatorSize % phase;
				startIndexInBlock + comparatorSize < size;
				startIndexInBlock += comparatorSize * 2)
			{
				for (int comparatorInBlockIndex = 0;
					comparatorInBlockIndex < comparatorSize && (startIndexInBlock + comparatorInBlockIndex + comparatorSize) < size;
					comparatorInBlockIndex++)
				{
					int firstIndexBlock = (startIndexInBlock + comparatorInBlockIndex) / (phase * 2);
					int secondIndexBlock = (startIndexInBlock + comparatorInBlockIndex + comparatorSize) / (phase * 2);
					//compare only items from the same block
					if (firstIndexBlock == secondIndexBlock)
					{
						dataArray[index].first = numbers + startIndexInBlock + comparatorInBlockIndex;
						dataArray[index].second = dataArray[index].first + comparatorSize;
						hThreadArray[index] = CreateThread(0, 0, workerFunction, dataArray + index, 0, 0);
						index++;
					}
				}
			}

			WaitForMultipleObjects(index, hThreadArray, TRUE, INFINITE);
			for (int i = 0; i < index; i++)
			{
				CloseHandle(hThreadArray[i]);
			}
		}
	}

	delete[] hThreadArray;
	delete[] dataArray;
}

void compareAndSwap(int* first, int* second)
{
	if (first[0] > second[0])
	{
		int temp = first[0];
		first[0] = second[0];
		second[0] = temp;
	}
}

DWORD WINAPI workerFunction(LPVOID lpParam)
{
	MergeData* data = (MergeData*)lpParam;
	compareAndSwap(data->first, data->second);
	return 0;
}

void printMergeIndicies(int size)
{
	for (int phase = 1; phase < size; phase *= 2)
	{
		for (int comparatorSize = phase; comparatorSize > 0; comparatorSize /= 2)
		{
			int index = 0;
			for (int startIndexInBlock = comparatorSize % phase;
				startIndexInBlock + comparatorSize < size;
				startIndexInBlock += comparatorSize * 2)
			{
				for (int comparatorInBlockIndex = 0;
					comparatorInBlockIndex < comparatorSize && (startIndexInBlock + comparatorInBlockIndex + comparatorSize) < size;
					comparatorInBlockIndex++)
				{
					int firstIndexBlock = (startIndexInBlock + comparatorInBlockIndex) / (phase * 2);
					int secondIndexBlock = (startIndexInBlock + comparatorInBlockIndex + comparatorSize) / (phase * 2);
					//compare only items from the same block
					if (firstIndexBlock == secondIndexBlock)
					{
						cout << "[" << startIndexInBlock + comparatorInBlockIndex << "-"
							<< startIndexInBlock + comparatorInBlockIndex + comparatorSize << "]";
					}
				}
			}
			cout << endl;
		}
	}
}

void printArray(int *numbers, int length)
{
	cout << "[";
	for (int i = 0; i < length - 1; i++)
	{
		cout << numbers[i] << ", ";
	}
	cout << numbers[length - 1] << "]" << endl;
}

BOOL setConsoleFontSize(int size) {
	HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_FONT_INFOEX info{ sizeof(CONSOLE_FONT_INFOEX) };
	if (!GetCurrentConsoleFontEx(output, false, &info))
		return false;
	info.dwFontSize.Y = size;
	info.dwFontSize.X = (int)(size / 1.5);
	return SetCurrentConsoleFontEx(output, false, &info);
}

/*

void bucketSort(int* a, int n)
{
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
int p = sysInfo.dwNumberOfProcessors;

}

*/<commit_msg>5th homework<commit_after>#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <algorithm>
#include "time.h"

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <strsafe.h>
#include "atlstr.h"

using namespace std;

using namespace System;

void compareAndSwap(int* first, int* second);

void mergeSort(int* numbers, int size);

void printMergeIndicies(int size);

void printArray(int *numbers, int length);

DWORD WINAPI workerFunction(LPVOID lpParam);

BOOL setConsoleFontSize(int size);

struct MergeData
{
	int* first;
	int* second;
};

int main()
{
	setConsoleFontSize(32);

	int size;
	cout << "Please, enter length of the array" << endl;
	cin >> size;
	srand(time(0));

	int* numbers = new int[size];
	for (int i = 0; i < size; i++)
	{
		numbers[i] = rand() % 100 + 1;
	}

	cout << "Generated array: ";
	printArray(numbers, size);

	cout << "Compared indicies step by step:" << endl;
	printMergeIndicies(size);

	mergeSort(numbers, size);

	cout << "Sorted array: ";
	printArray(numbers, size);

	delete[] numbers;

	return 0;
}

void mergeSort(int* numbers, int size)
{
	HANDLE* hThreadArray = new HANDLE[size / 2];
	MergeData* dataArray = new MergeData[size / 2];

	for (int phase = 1; phase < size; phase *= 2)
	{
		for (int comparatorSize = phase; comparatorSize > 0; comparatorSize /= 2)
		{
			int index = 0;
			for (int startIndexInBlock = comparatorSize % phase;
				startIndexInBlock + comparatorSize < size;
				startIndexInBlock += comparatorSize * 2)
			{
				for (int comparatorInBlockIndex = 0;
					comparatorInBlockIndex < comparatorSize && (startIndexInBlock + comparatorInBlockIndex + comparatorSize) < size;
					comparatorInBlockIndex++)
				{
					int firstIndexBlock = (startIndexInBlock + comparatorInBlockIndex) / (phase * 2);
					int secondIndexBlock = (startIndexInBlock + comparatorInBlockIndex + comparatorSize) / (phase * 2);
					//compare only items from the same block
					if (firstIndexBlock == secondIndexBlock)
					{
						dataArray[index].first = numbers + startIndexInBlock + comparatorInBlockIndex;
						dataArray[index].second = dataArray[index].first + comparatorSize;
						hThreadArray[index] = CreateThread(0, 0, workerFunction, dataArray + index, 0, 0);
						index++;
					}
				}
			}

			WaitForMultipleObjects(index, hThreadArray, TRUE, INFINITE);
			for (int i = 0; i < index; i++)
			{
				CloseHandle(hThreadArray[i]);
			}
		}
	}

	delete[] hThreadArray;
	delete[] dataArray;
}

void compareAndSwap(int* first, int* second)
{
	if (first[0] > second[0])
	{
		int temp = first[0];
		first[0] = second[0];
		second[0] = temp;
	}
}

DWORD WINAPI workerFunction(LPVOID lpParam)
{
	MergeData* data = (MergeData*)lpParam;
	compareAndSwap(data->first, data->second);
	return 0;
}

void printMergeIndicies(int size)
{
	for (int phase = 1; phase < size; phase *= 2)
	{
		for (int comparatorSize = phase; comparatorSize > 0; comparatorSize /= 2)
		{
			int index = 0;
			for (int startIndexInBlock = comparatorSize % phase;
				startIndexInBlock + comparatorSize < size;
				startIndexInBlock += comparatorSize * 2)
			{
				for (int comparatorInBlockIndex = 0;
					comparatorInBlockIndex < comparatorSize && (startIndexInBlock + comparatorInBlockIndex + comparatorSize) < size;
					comparatorInBlockIndex++)
				{
					int firstIndexBlock = (startIndexInBlock + comparatorInBlockIndex) / (phase * 2);
					int secondIndexBlock = (startIndexInBlock + comparatorInBlockIndex + comparatorSize) / (phase * 2);
					//compare only items from the same block
					if (firstIndexBlock == secondIndexBlock)
					{
						cout << "[" << startIndexInBlock + comparatorInBlockIndex << "-"
							<< startIndexInBlock + comparatorInBlockIndex + comparatorSize << "]";
					}
				}
			}
			cout << endl;
		}
	}
}

void printArray(int *numbers, int length)
{
	cout << "[";
	for (int i = 0; i < length - 1; i++)
	{
		cout << numbers[i] << ", ";
	}
	cout << numbers[length - 1] << "]" << endl;
}

BOOL setConsoleFontSize(int size) {
	HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_FONT_INFOEX info{ sizeof(CONSOLE_FONT_INFOEX) };
	if (!GetCurrentConsoleFontEx(output, false, &info))
		return false;
	info.dwFontSize.Y = size;
	info.dwFontSize.X = (int)(size / 1.5);
	return SetCurrentConsoleFontEx(output, false, &info);
}<|endoftext|>


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

#include "OrbitClientServices/ProcessClient.h"

#include <memory>
#include <vector>

#include "OrbitBase/Logging.h"
#include "grpcpp/grpcpp.h"
#include "outcome.hpp"
#include "services.grpc.pb.h"
#include "symbol.pb.h"

namespace {

using orbit_grpc_protos::GetDebugInfoFileRequest;
using orbit_grpc_protos::GetDebugInfoFileResponse;
using orbit_grpc_protos::GetModuleListRequest;
using orbit_grpc_protos::GetModuleListResponse;
using orbit_grpc_protos::GetProcessListRequest;
using orbit_grpc_protos::GetProcessListResponse;
using orbit_grpc_protos::GetProcessMemoryRequest;
using orbit_grpc_protos::GetProcessMemoryResponse;
using orbit_grpc_protos::ModuleInfo;
using orbit_grpc_protos::ProcessInfo;
using orbit_grpc_protos::ProcessService;

constexpr uint64_t kGrpcDefaultTimeoutMilliseconds = 1000;

std::unique_ptr<grpc::ClientContext> CreateContext(
    uint64_t timeout_milliseconds = kGrpcDefaultTimeoutMilliseconds) {
  auto context = std::make_unique<grpc::ClientContext>();
  std::chrono::time_point deadline =
      std::chrono::system_clock::now() + std::chrono::milliseconds(timeout_milliseconds);
  context->set_deadline(deadline);

  return context;
}

}  // namespace

ErrorMessageOr<std::vector<orbit_grpc_protos::ProcessInfo>> ProcessClient::GetProcessList() {
  GetProcessListRequest request;
  GetProcessListResponse response;
  std::unique_ptr<grpc::ClientContext> context = CreateContext();

  grpc::Status status = process_service_->GetProcessList(context.get(), request, &response);
  if (!status.ok()) {
    ERROR("gRPC call to GetProcessList failed: %s (error_code=%d)", status.error_message(),
          status.error_code());
    return ErrorMessage(status.error_message());
  }

  const auto& processes = response.processes();

  return std::vector<ProcessInfo>(processes.begin(), processes.end());
}

ErrorMessageOr<std::vector<ModuleInfo>> ProcessClient::LoadModuleList(int32_t pid) {
  GetModuleListRequest request;
  GetModuleListResponse response;
  request.set_process_id(pid);

  std::unique_ptr<grpc::ClientContext> context = CreateContext();
  grpc::Status status = process_service_->GetModuleList(context.get(), request, &response);

  if (!status.ok()) {
    ERROR("Grpc call failed: code=%d, message=%s", status.error_code(), status.error_message());
    return ErrorMessage(status.error_message());
  }

  const auto& modules = response.modules();

  return std::vector<ModuleInfo>(modules.begin(), modules.end());
}

ErrorMessageOr<std::string> ProcessClient::FindDebugInfoFile(const std::string& module_path) {
  GetDebugInfoFileRequest request;
  GetDebugInfoFileResponse response;

  request.set_module_path(module_path);

  std::unique_ptr<grpc::ClientContext> context = CreateContext();

  grpc::Status status = process_service_->GetDebugInfoFile(context.get(), request, &response);
  if (!status.ok()) {
    ERROR("gRPC call to GetDebugInfoFile failed: %s", status.error_message());
    return ErrorMessage(status.error_message());
  }

  return response.debug_info_file_path();
}

ErrorMessageOr<std::string> ProcessClient::LoadProcessMemory(int32_t pid, uint64_t address,
                                                             uint64_t size) {
  GetProcessMemoryRequest request;
  request.set_pid(pid);
  request.set_address(address);
  request.set_size(size);

  GetProcessMemoryResponse response;

  std::unique_ptr<grpc::ClientContext> context = CreateContext();

  grpc::Status status = process_service_->GetProcessMemory(context.get(), request, &response);
  if (!status.ok()) {
    ERROR("gRPC call to GetProcessMemory failed: %s", status.error_message());
    return ErrorMessage(status.error_message());
  }

  return std::move(*response.mutable_memory());
}<commit_msg>Increase deadline for grpc communication when requesting process information. (#1459)<commit_after>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "OrbitClientServices/ProcessClient.h"

#include <memory>
#include <vector>

#include "OrbitBase/Logging.h"
#include "grpcpp/grpcpp.h"
#include "outcome.hpp"
#include "services.grpc.pb.h"
#include "symbol.pb.h"

namespace {

using orbit_grpc_protos::GetDebugInfoFileRequest;
using orbit_grpc_protos::GetDebugInfoFileResponse;
using orbit_grpc_protos::GetModuleListRequest;
using orbit_grpc_protos::GetModuleListResponse;
using orbit_grpc_protos::GetProcessListRequest;
using orbit_grpc_protos::GetProcessListResponse;
using orbit_grpc_protos::GetProcessMemoryRequest;
using orbit_grpc_protos::GetProcessMemoryResponse;
using orbit_grpc_protos::ModuleInfo;
using orbit_grpc_protos::ProcessInfo;
using orbit_grpc_protos::ProcessService;

constexpr uint64_t kGrpcDefaultTimeoutMilliseconds = 3000;

std::unique_ptr<grpc::ClientContext> CreateContext(
    uint64_t timeout_milliseconds = kGrpcDefaultTimeoutMilliseconds) {
  auto context = std::make_unique<grpc::ClientContext>();
  std::chrono::time_point deadline =
      std::chrono::system_clock::now() + std::chrono::milliseconds(timeout_milliseconds);
  context->set_deadline(deadline);

  return context;
}

}  // namespace

ErrorMessageOr<std::vector<orbit_grpc_protos::ProcessInfo>> ProcessClient::GetProcessList() {
  GetProcessListRequest request;
  GetProcessListResponse response;
  std::unique_ptr<grpc::ClientContext> context = CreateContext();

  grpc::Status status = process_service_->GetProcessList(context.get(), request, &response);
  if (!status.ok()) {
    ERROR("gRPC call to GetProcessList failed: %s (error_code=%d)", status.error_message(),
          status.error_code());
    return ErrorMessage(status.error_message());
  }

  const auto& processes = response.processes();

  return std::vector<ProcessInfo>(processes.begin(), processes.end());
}

ErrorMessageOr<std::vector<ModuleInfo>> ProcessClient::LoadModuleList(int32_t pid) {
  GetModuleListRequest request;
  GetModuleListResponse response;
  request.set_process_id(pid);

  std::unique_ptr<grpc::ClientContext> context = CreateContext();
  grpc::Status status = process_service_->GetModuleList(context.get(), request, &response);

  if (!status.ok()) {
    ERROR("Grpc call failed: code=%d, message=%s", status.error_code(), status.error_message());
    return ErrorMessage(status.error_message());
  }

  const auto& modules = response.modules();

  return std::vector<ModuleInfo>(modules.begin(), modules.end());
}

ErrorMessageOr<std::string> ProcessClient::FindDebugInfoFile(const std::string& module_path) {
  GetDebugInfoFileRequest request;
  GetDebugInfoFileResponse response;

  request.set_module_path(module_path);

  std::unique_ptr<grpc::ClientContext> context = CreateContext();

  grpc::Status status = process_service_->GetDebugInfoFile(context.get(), request, &response);
  if (!status.ok()) {
    ERROR("gRPC call to GetDebugInfoFile failed: %s", status.error_message());
    return ErrorMessage(status.error_message());
  }

  return response.debug_info_file_path();
}

ErrorMessageOr<std::string> ProcessClient::LoadProcessMemory(int32_t pid, uint64_t address,
                                                             uint64_t size) {
  GetProcessMemoryRequest request;
  request.set_pid(pid);
  request.set_address(address);
  request.set_size(size);

  GetProcessMemoryResponse response;

  std::unique_ptr<grpc::ClientContext> context = CreateContext();

  grpc::Status status = process_service_->GetProcessMemory(context.get(), request, &response);
  if (!status.ok()) {
    ERROR("gRPC call to GetProcessMemory failed: %s", status.error_message());
    return ErrorMessage(status.error_message());
  }

  return std::move(*response.mutable_memory());
}<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of dirtsand.                                             *
 *                                                                            *
 * dirtsand 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.                                        *
 *                                                                            *
 * dirtsand 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 dirtsand.  If not, see <http://www.gnu.org/licenses/>.          *
 ******************************************************************************/

#include "NetMsgObject.h"
#include "errors.h"
#include <zlib.h>

void MOUL::NetMsgStream::read(DS::Stream* stream)
{
    uint32_t uncompressedSize = stream->read<uint32_t>();
    m_compression = static_cast<Compression>(stream->read<uint8_t>());
    uint32_t size = stream->read<uint32_t>();
    uint8_t* buffer = new uint8_t[size];
    stream->readBytes(buffer, size);

    if (m_compression == e_CompressZlib) {
        DS_PASSERT(size >= 2);

        uint8_t* zbuf = new uint8_t[uncompressedSize];
        uLongf zlength = uncompressedSize - 2;
        memcpy(zbuf, buffer, 2);
        int result = uncompress(zbuf + 2, &zlength, buffer + 2, size - 2);
        if (result != Z_OK) {
            delete[] zbuf;
            delete[] buffer;
            DS_PASSERT(0);
        }
        m_stream.steal(zbuf, uncompressedSize);
        delete[] buffer;
    } else {
        m_stream.steal(buffer, size);
    }
}

void MOUL::NetMsgStream::write(DS::Stream* stream)
{
    stream->write<uint32_t>(m_compression == e_CompressZlib ? m_stream.size() : 0);
    stream->write<uint8_t>(m_compression);

    if (m_compression == e_CompressZlib) {
        DS_PASSERT(m_stream.size() >= 2);

        uLongf zlength = compressBound(m_stream.size() - 2);
        uint8_t* zbuf = new uint8_t[zlength + 2];
        memcpy(zbuf, m_stream.buffer(), 2);
        int result = compress(zbuf + 2, &zlength, m_stream.buffer() + 2, m_stream.size() - 2);
        if (result != Z_OK) {
            delete[] zbuf;
            DS_PASSERT(0);
        }
        stream->write<uint32_t>(zlength + 2);
        stream->writeBytes(zbuf, zlength + 2);
        delete[] zbuf;
    } else {
        stream->write<uint32_t>(m_stream.size());
        stream->writeBytes(m_stream.buffer(), m_stream.size());
    }
}

void MOUL::NetMsgObject::read(DS::Stream* stream)
{
    NetMessage::read(stream);
    m_object.read(stream);
}

void MOUL::NetMsgObject::write(DS::Stream* stream)
{
    NetMessage::write(stream);
    m_object.write(stream);
}
<commit_msg>Always write the uncompressed size<commit_after>/******************************************************************************
 * This file is part of dirtsand.                                             *
 *                                                                            *
 * dirtsand 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.                                        *
 *                                                                            *
 * dirtsand 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 dirtsand.  If not, see <http://www.gnu.org/licenses/>.          *
 ******************************************************************************/

#include "NetMsgObject.h"
#include "errors.h"
#include <zlib.h>

void MOUL::NetMsgStream::read(DS::Stream* stream)
{
    uint32_t uncompressedSize = stream->read<uint32_t>();
    m_compression = static_cast<Compression>(stream->read<uint8_t>());
    uint32_t size = stream->read<uint32_t>();
    uint8_t* buffer = new uint8_t[size];
    stream->readBytes(buffer, size);

    if (m_compression == e_CompressZlib) {
        DS_PASSERT(size >= 2);

        uint8_t* zbuf = new uint8_t[uncompressedSize];
        uLongf zlength = uncompressedSize - 2;
        memcpy(zbuf, buffer, 2);
        int result = uncompress(zbuf + 2, &zlength, buffer + 2, size - 2);
        if (result != Z_OK) {
            delete[] zbuf;
            delete[] buffer;
            DS_PASSERT(0);
        }
        m_stream.steal(zbuf, uncompressedSize);
        delete[] buffer;
    } else {
        m_stream.steal(buffer, size);
    }
}

void MOUL::NetMsgStream::write(DS::Stream* stream)
{
    stream->write<uint32_t>(m_stream.size());
    stream->write<uint8_t>(m_compression);

    if (m_compression == e_CompressZlib) {
        DS_PASSERT(m_stream.size() >= 2);

        uLongf zlength = compressBound(m_stream.size() - 2);
        uint8_t* zbuf = new uint8_t[zlength + 2];
        memcpy(zbuf, m_stream.buffer(), 2);
        int result = compress(zbuf + 2, &zlength, m_stream.buffer() + 2, m_stream.size() - 2);
        if (result != Z_OK) {
            delete[] zbuf;
            DS_PASSERT(0);
        }
        stream->write<uint32_t>(zlength + 2);
        stream->writeBytes(zbuf, zlength + 2);
        delete[] zbuf;
    } else {
        stream->write<uint32_t>(m_stream.size());
        stream->writeBytes(m_stream.buffer(), m_stream.size());
    }
}

void MOUL::NetMsgObject::read(DS::Stream* stream)
{
    NetMessage::read(stream);
    m_object.read(stream);
}

void MOUL::NetMsgObject::write(DS::Stream* stream)
{
    NetMessage::write(stream);
    m_object.write(stream);
}
<|endoftext|>


<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file JPetTask.cpp
 */

#include "../JPetParamManager/JPetParamManager.h"
#include "./JPetTask.h"

JPetTask::JPetTask(const char* name, const char* description):
  fName(name, description),
  fEvent(0),
  fParamManager(0),
  fStatistics(0),
  fAuxilliaryData(0)
{
}

void JPetTask::init(const JPetOptionsInterface&)
{
}

//void JPetTask::init(const JPetTaskInterface::Options&)
//{
//}

void JPetTask::exec()
{
  // do something with event
}

std::unique_ptr<JPetOptionsInterface> JPetTask::terminate()
{
  std::unique_ptr<JPetOptionsInterface> p(new JPetOptionsInterface);
  return p;
}

//void JPetTask::terminate()
//{
//}

void JPetTask::setEvent(TObject* ev)
{
  fEvent = ev;
}

void JPetTask::setParamManager(JPetParamManager* paramManager)
{
  fParamManager = paramManager;
}

const JPetParamBank& JPetTask::getParamBank()
{
  DEBUG("JPetTask");
  assert(fParamManager);
  return fParamManager->getParamBank();
}

void JPetTask::setStatistics(JPetStatistics* statistics)
{
  assert(statistics);
  fStatistics = statistics;
}

JPetAuxilliaryData& JPetTask::getAuxilliaryData()
{
  assert(fAuxilliaryData);
  return *fAuxilliaryData;
}

void JPetTask::setAuxilliaryData(JPetAuxilliaryData* auxData)
{
  assert(auxData);
  fAuxilliaryData = auxData;
}

JPetStatistics& JPetTask::getStatistics()
{
  assert(fStatistics);
  return *fStatistics;
}

<commit_msg>Remove one assert from JPetTask<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  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.
 *
 *  @file JPetTask.cpp
 */

#include "../JPetParamManager/JPetParamManager.h"
#include "./JPetTask.h"

JPetTask::JPetTask(const char* name, const char* description):
  fName(name, description),
  fEvent(0),
  fParamManager(0),
  fStatistics(0),
  fAuxilliaryData(0)
{
}

void JPetTask::init(const JPetOptionsInterface&)
{
}

//void JPetTask::init(const JPetTaskInterface::Options&)
//{
//}

void JPetTask::exec()
{
  // do something with event
}

std::unique_ptr<JPetOptionsInterface> JPetTask::terminate()
{
  std::unique_ptr<JPetOptionsInterface> p(new JPetOptionsInterface);
  return p;
}

//void JPetTask::terminate()
//{
//}

void JPetTask::setEvent(TObject* ev)
{
  fEvent = ev;
}

void JPetTask::setParamManager(JPetParamManager* paramManager)
{
  fParamManager = paramManager;
}

const JPetParamBank& JPetTask::getParamBank()
{
  DEBUG("JPetTask");
  assert(fParamManager);
  return fParamManager->getParamBank();
}

void JPetTask::setStatistics(JPetStatistics* statistics)
{
  assert(statistics);
  fStatistics = statistics;
}

JPetAuxilliaryData& JPetTask::getAuxilliaryData()
{
  assert(fAuxilliaryData);
  return *fAuxilliaryData;
}

void JPetTask::setAuxilliaryData(JPetAuxilliaryData* auxData)
{
  assert(auxData);
  fAuxilliaryData = auxData;
}

JPetStatistics& JPetTask::getStatistics()
{
  assert(fStatistics);
  return *fStatistics;
}

<|endoftext|>


<commit_before>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 1999 Brent A. Fulgham <bfulgham@debian.org>
 * Copyright (C) 1999, 2000 Stefan Seefeld <stefan@berlin-consortium.org
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#ifndef _Profiler_hh
#define _Profiler_hh

#include <Prague/Sys/ntree.hh>
#include <Prague/Sys/Thread.hh>
#include <ctime>
#include <iostream>
#include <string>
#include <iomanip.h>

namespace Prague
{

class Profiler
{
  struct CheckPoint
  {
    CheckPoint(const string &s) : name(s), count(0), start(0), stop(0), elapsed(0) {}
    CheckPoint(CheckPoint *cp)
      : name(cp->name),
	count(cp->count),
	start(cp->start),
	stop(cp->stop),
	elapsed(cp->elapsed)
    {}
    void indent(ostream &os, unsigned short ind) { while (ind--) os.put(' ');}
    void output(ostream &os, unsigned short ind);
    string name;
    long count;
    clock_t start;
    clock_t stop;
    double elapsed;
  };
  typedef ntree<CheckPoint *> table_t;
  typedef ntree<CheckPoint *>::node item_t;
  typedef ntree<CheckPoint *>::node::child_iterator child_iterator;
  typedef ntree<CheckPoint *>::node::const_child_iterator const_child_iterator;
  typedef ntree<CheckPoint *>::node::up_iterator up_iterator;
  struct Guard
  {
    Guard()
      {
	Profiler::table = new table_t(0);
	Profiler::current = &Profiler::table->root();
      }
    ~Guard()
      {
	Profiler::clean(*Profiler::current);
	delete Profiler::table;
      }
  };
  friend struct Guard;
public:
  Profiler(const string &name)
    {
#ifdef profile
      MutexGuard guard(mutex);
      child_iterator i = lookup(name);
      current = &*i;
      current->value->count++;
      current->value->start = clock();
#endif /* profile */
    }
  ~Profiler()
    {
#ifdef profile
      MutexGuard guard(mutex);
      current->value->stop = clock();
      current->value->elapsed += (current->value->stop - current->value->start);
      up_iterator i = current->up_begin();
      current = &*++i;
#endif /* profile */
    }
  static void dump(ostream &);
private:
  static child_iterator lookup(const string &name)
    {
      for (child_iterator i = current->child_begin(); i != current->child_end(); i++)
	if ((*i).value->name == name) return i;
      return current->push_back(new CheckPoint(name));
    }
  static void dump(ostream &, const item_t &, unsigned short);
  static void clean(const item_t &root)
    {
      for (const_child_iterator i = root.child_begin(); i != root.child_end(); i++)
	clean(*i);
      delete root.value;
    }
  static Guard    guard;
  static table_t *table;
  static item_t  *current;
  static Mutex    mutex;
};

};

#endif /* _Profiler_hh */
<commit_msg>Bug fix: Create named root node.<commit_after>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 1999 Brent A. Fulgham <bfulgham@debian.org>
 * Copyright (C) 1999, 2000 Stefan Seefeld <stefan@berlin-consortium.org
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#ifndef _Profiler_hh
#define _Profiler_hh

#include <Prague/Sys/ntree.hh>
#include <Prague/Sys/Thread.hh>
#include <ctime>
#include <iostream>
#include <string>
#include <iomanip.h>

namespace Prague
{

class Profiler
{
  struct CheckPoint
  {
    CheckPoint(const string &s) : name(s), count(0), start(0), stop(0), elapsed(0) {}
    CheckPoint(CheckPoint *cp)
      : name(cp->name),
	count(cp->count),
	start(cp->start),
	stop(cp->stop),
	elapsed(cp->elapsed)
    {}
    void indent(ostream &os, unsigned short ind) { while (ind--) os.put(' ');}
    void output(ostream &os, unsigned short ind);
    string name;
    long count;
    clock_t start;
    clock_t stop;
    double elapsed;
  };
  typedef ntree<CheckPoint *> table_t;
  typedef ntree<CheckPoint *>::node item_t;
  typedef ntree<CheckPoint *>::node::child_iterator child_iterator;
  typedef ntree<CheckPoint *>::node::const_child_iterator const_child_iterator;
  typedef ntree<CheckPoint *>::node::up_iterator up_iterator;
  struct Guard
  {
    Guard()
      {
	Profiler::table = new table_t(new CheckPoint("RootEntry"));
	Profiler::current = &table->root();
      }
    ~Guard()
      {
	Profiler::clean(*Profiler::current);
	delete Profiler::table;
      }
  };
  friend struct Guard;
public:
  Profiler(const string &name)
    {
#ifdef profile
      MutexGuard guard(mutex);
      child_iterator i = lookup(name);
      current = &*i;
      current->value->count++;
      current->value->start = clock();
#endif /* profile */
    }
  ~Profiler()
    {
#ifdef profile
      MutexGuard guard(mutex);
      current->value->stop = clock();
      current->value->elapsed += (current->value->stop - current->value->start);
      up_iterator i = current->up_begin();
      current = &*++i;
#endif /* profile */
    }
  static void dump(ostream &);
private:
  static child_iterator lookup(const string &name)
    {
      for (child_iterator i = current->child_begin(); i != current->child_end(); i++)
	if ((*i).value->name == name) return i;
      return current->push_back(new CheckPoint(name));
    }
  static void dump(ostream &, const item_t &, unsigned short);
  static void clean(const item_t &root)
    {
      for (const_child_iterator i = root.child_begin(); i != root.child_end(); i++)
	clean(*i);
      delete root.value;
    }
  static Guard    guard;
  static table_t *table;
  static item_t  *current;
  static Mutex    mutex;
};

};

#endif /* _Profiler_hh */
<|endoftext|>


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

#include <termbox.h>

#include "components/screen_butler.hpp"

namespace butler {

screen_butler::screen_butler(vector<bookwyrm::item> &items)
    : items_(items), viewing_details_(false)
{
    /* Create the default menu screen and focus on it. */
    index_ = std::make_shared<screen::multiselect_menu>(items_);
    focused_ = index_;
    screens_.insert(index_);
}

void screen_butler::update_screens()
{
    tb_clear();

    if (!bookwyrm_fits()) {
        int x = 0, y = 0;
        for (const uint32_t &ch : "The terminal is too small. I can't fit!")
            tb_change_cell(x++, y, ch, 0, 0);

        tb_present();
        return;
    }

    for (auto &screen : screens_)
        screen->update();

    tb_present();
}

void screen_butler::resize_screens()
{
    for (auto &screen : screens_)
        screen->on_resize();

    update_screens();
}

void screen_butler::display()
{
    /*
     * Let the source threads free.
     * This doesn't feel like the best place to have this,
     * but we do need to have a release in scope if we
     * ever want the threads to run.
     * TODO: find out if there is a better place for this.
     */
    py::gil_scoped_release nogil;

    struct tb_event ev;
    while (tb_poll_event(&ev)) {
        if (ev.type == TB_EVENT_RESIZE) {
            resize_screens();
        } else if (ev.type == TB_EVENT_KEY) {
            /* When the terminal is too small, only allow quitting. */
            if (!bookwyrm_fits()) {
                if (ev.key == TB_KEY_ESC)
                    return;

                continue;
            }

            if (ev.key == TB_KEY_ESC)
                return;

            if (meta_action(ev.key, ev.ch) || focused_->action(ev.key, ev.ch))
                update_screens();
        }
    }
}

bool screen_butler::meta_action(const uint16_t &key, const uint32_t &ch)
{
    switch (ch) {
        case 'l':
            return open_details();
        case 'h':
            return close_details();
    }

    switch (key) {
        case TB_KEY_CTRL_L:
            update_screens();
            return true;
        case TB_KEY_ARROW_RIGHT:
            return open_details();
        case TB_KEY_ARROW_LEFT:
            return close_details();
    }

    return false;
}

bool screen_butler::open_details()
{
    if (viewing_details_) return false;

    /* How much space will the detail menu take up? */
    int height;
    std::tie(index_scrollback_, height) = index_->compress();

    details_ = std::make_shared<screen::item_details>(index_->selected_item(), height);
    focused_ = details_;
    screens_.insert(details_);

    viewing_details_ = true;
    return true;
}

bool screen_butler::close_details()
{
    if (!viewing_details_) return false;

    focused_ = index_;
    screens_.erase(details_);

    /* Give back the space the detail menu too up to the index menu. */
    index_->decompress(index_scrollback_);
    index_scrollback_ = -1;

    viewing_details_ = false;
    return true;
}

/* ns butler */
}

namespace tui {

std::shared_ptr<butler::screen_butler> make_with(butler::script_butler &butler, vector<py::module> &sources)
{
    auto tui = std::make_shared<butler::screen_butler>(butler.results());
    butler.set_screens(tui);
    butler.async_search(sources); // Watch out, it's hot!
    return tui;
}

/* ns tui */
}

<commit_msg>butler/scree: simplify display()<commit_after>/*
 * Copyright (C) 2017 Tmplt <tmplt@dragons.rocks>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <termbox.h>

#include "components/screen_butler.hpp"

namespace butler {

screen_butler::screen_butler(vector<bookwyrm::item> &items)
    : items_(items), viewing_details_(false)
{
    /* Create the default menu screen and focus on it. */
    index_ = std::make_shared<screen::multiselect_menu>(items_);
    focused_ = index_;
    screens_.insert(index_);
}

void screen_butler::update_screens()
{
    tb_clear();

    if (!bookwyrm_fits()) {
        int x = 0, y = 0;
        for (const uint32_t &&ch : "The terminal is too small. I can't fit!")
            tb_change_cell(x++, y, ch, 0, 0);
    } else {
        for (auto &screen : screens_)
           screen->update();
    }

    tb_present();
}

void screen_butler::resize_screens()
{
    for (auto &screen : screens_)
        screen->on_resize();

    update_screens();
}

void screen_butler::display()
{
    /*
     * Let the source threads free.
     * This doesn't feel like the best place to have this,
     * but we do need to have a release in scope if we
     * ever want the threads to run.
     * TODO: find out if there is a better place for this.
     */
    py::gil_scoped_release nogil;

    struct tb_event ev;
    while (tb_poll_event(&ev)) {
        if (ev.type == TB_EVENT_RESIZE) {
            resize_screens();
        } else if (ev.type == TB_EVENT_KEY) {
            if (ev.key == TB_KEY_ESC)
                return;

            /* When the terminal is too small, only allow quitting. */
            if (!bookwyrm_fits())
                continue;

            if (meta_action(ev.key, ev.ch) || focused_->action(ev.key, ev.ch))
                update_screens();
        }
    }
}

bool screen_butler::meta_action(const uint16_t &key, const uint32_t &ch)
{
    switch (ch) {
        case 'l':
            return open_details();
        case 'h':
            return close_details();
    }

    switch (key) {
        case TB_KEY_CTRL_L:
            /* Update the screens, done display(). */
            return true;
        case TB_KEY_ARROW_RIGHT:
            return open_details();
        case TB_KEY_ARROW_LEFT:
            return close_details();
    }

    return false;
}

bool screen_butler::open_details()
{
    if (viewing_details_) return false;

    /* How much space will the detail menu take up? */
    int height;
    std::tie(index_scrollback_, height) = index_->compress();

    details_ = std::make_shared<screen::item_details>(index_->selected_item(), height);
    focused_ = details_;
    screens_.insert(details_);

    viewing_details_ = true;
    return true;
}

bool screen_butler::close_details()
{
    if (!viewing_details_) return false;

    focused_ = index_;
    screens_.erase(details_);

    /* Give back the space the detail menu too up to the index menu. */
    index_->decompress(index_scrollback_);
    index_scrollback_ = -1;

    viewing_details_ = false;
    return true;
}

/* ns butler */
}

namespace tui {

std::shared_ptr<butler::screen_butler> make_with(butler::script_butler &butler, vector<py::module> &sources)
{
    auto tui = std::make_shared<butler::screen_butler>(butler.results());
    butler.set_screens(tui);
    butler.async_search(sources); // Watch out, it's hot!
    return tui;
}

/* ns tui */
}

<|endoftext|>


<commit_before>#ifndef CAN_EMULATOR

#include "usbutil.h"
#include "canread.h"
#include "serialutil.h"
#include "signals.h"
#include "log.h"
#include "cJSON.h"
#include "listener.h"
#include <stdint.h>
#include <stdlib.h>

extern SerialDevice SERIAL_DEVICE;
extern UsbDevice USB_DEVICE;
extern Listener listener;

/* Forward declarations */

void receiveCan(CanBus*);
void initializeAllCan();
bool receiveWriteRequest(uint8_t*);

void setup() {
    initializeLogging();
#ifndef NO_UART
    initializeSerial(&SERIAL_DEVICE);
#endif
    initializeUsb(&USB_DEVICE);
    initializeAllCan();
}

void loop() {
    for(int i = 0; i < getCanBusCount(); i++) {
        receiveCan(&getCanBuses()[i]);
    }
    processListenerQueues(&listener);
    readFromHost(&USB_DEVICE, &receiveWriteRequest);
#ifndef NO_UART
    readFromSerial(&SERIAL_DEVICE, &receiveWriteRequest);
#endif
    for(int i = 0; i < getCanBusCount(); i++) {
        processCanWriteQueue(&getCanBuses()[i]);
    }
}

void initializeAllCan() {
    for(int i = 0; i < getCanBusCount(); i++) {
        initializeCan(&(getCanBuses()[i]));
    }
}

void receiveRawWriteRequest(cJSON* idObject, cJSON* root) {
    uint32_t id = idObject->valueint;
    cJSON* dataObject = cJSON_GetObjectItem(root, "data");
    if(dataObject == NULL) {
        debug("Raw write request missing data\r\n", id);
        return;
    }

    char* dataString = dataObject->valuestring;
    char* end;
    unsigned long long data = __builtin_bswap64(strtoull(dataString, &end, 16));
    CanMessage message = {id, data};
    QUEUE_PUSH(CanMessage, &getCanBuses()[0].sendQueue, message);
}

/* The binary format handled by this function is as follows:
 *
 * A leading '{' followed by a 4 byte message ID, then a '|' separator and
 * finally 8 bytes of data and a trailing '}'. E.g.:
 *
 * {<4 byte ID>|<8 bytes of data>}
 */
void receiveBinaryWriteRequest(uint8_t* message) {
    const int BINARY_CAN_WRITE_PACKET_LENGTH = 15;
    if(message[0] != '{' || message[5] != '|' || message[14] != '}') {
        debug("Received a corrupted CAN message: ");
        for(int i = 0; i <= BINARY_CAN_WRITE_PACKET_LENGTH; i++) {
            debug("%02x ", message[i] );
        }
        debug("\r\n");
        return;
    }

    CanMessage outgoing = {0, 0};
    memcpy((uint8_t*)&outgoing.id, &message[1], 4);
    for(int i = 0; i < 8; i++) {
        ((uint8_t*)&(outgoing.data))[i] = message[i + 6];
    }
    QUEUE_PUSH(CanMessage, &getCanBuses()[0].sendQueue, outgoing);
}

void receiveTranslatedWriteRequest(cJSON* nameObject, cJSON* root) {
    char* name = nameObject->valuestring;
    cJSON* value = cJSON_GetObjectItem(root, "value");
    if(value == NULL) {
        debug("Write request for %s missing value\r\n", name);
        return;
    }

    // Optional, may be null
    cJSON* event = cJSON_GetObjectItem(root, "event");

    CanSignal* signal = lookupSignal(name, getSignals(),
            getSignalCount(), true);
    CanCommand* command = lookupCommand(name, getCommands(), getCommandCount());
    if(signal != NULL) {
        sendCanSignal(signal, value, getSignals(), getSignalCount());
    } else if(command != NULL) {
        command->handler(name, value, event, getSignals(), getSignalCount());
    } else {
        debug("Writing not allowed for signal with name %s\r\n", name);
    }
}

bool receiveJsonWriteRequest(uint8_t* message) {
    cJSON *root = cJSON_Parse((char*)message);
    bool foundMessage = false;
    if(root != NULL) {
        foundMessage = true;
        cJSON* nameObject = cJSON_GetObjectItem(root, "name");
        if(nameObject == NULL) {
            cJSON* idObject = cJSON_GetObjectItem(root, "id");
            if(idObject == NULL) {
                debug("Write request is malformed, "
                        "missing name or id: %s\r\n", message);
            } else {
                receiveRawWriteRequest(idObject, root);
            }
        } else {
            receiveTranslatedWriteRequest(nameObject, root);
        }
        cJSON_Delete(root);
    } else {
        debug("No valid JSON in incoming buffer yet -- "
                "if it's valid, may be out of memory\r\n");
    }
    return foundMessage;
}

bool receiveWriteRequest(uint8_t* message) {
#ifdef TRANSMITTER
    receiveBinaryWriteRequest(message);
    return true;
#else
    return receiveJsonWriteRequest(message);
#endif
}

/*
 * Check to see if a packet has been received. If so, read the packet and print
 * the packet payload to the serial monitor.
 */
void receiveCan(CanBus* bus) {
    // TODO what happens if we process until the queue is empty?
    if(!QUEUE_EMPTY(CanMessage, &bus->receiveQueue)) {
        CanMessage message = QUEUE_POP(CanMessage, &bus->receiveQueue);
        decodeCanMessage(message.id, message.data);
    }
}

void reset() {
    initializeAllCan();
}

#endif // CAN_EMULATOR
<commit_msg>Only require value in write message if no command handler found.<commit_after>#ifndef CAN_EMULATOR

#include "usbutil.h"
#include "canread.h"
#include "serialutil.h"
#include "signals.h"
#include "log.h"
#include "cJSON.h"
#include "listener.h"
#include <stdint.h>
#include <stdlib.h>

extern SerialDevice SERIAL_DEVICE;
extern UsbDevice USB_DEVICE;
extern Listener listener;

/* Forward declarations */

void receiveCan(CanBus*);
void initializeAllCan();
bool receiveWriteRequest(uint8_t*);

void setup() {
    initializeLogging();
#ifndef NO_UART
    initializeSerial(&SERIAL_DEVICE);
#endif
    initializeUsb(&USB_DEVICE);
    initializeAllCan();
}

void loop() {
    for(int i = 0; i < getCanBusCount(); i++) {
        receiveCan(&getCanBuses()[i]);
    }
    processListenerQueues(&listener);
    readFromHost(&USB_DEVICE, &receiveWriteRequest);
#ifndef NO_UART
    readFromSerial(&SERIAL_DEVICE, &receiveWriteRequest);
#endif
    for(int i = 0; i < getCanBusCount(); i++) {
        processCanWriteQueue(&getCanBuses()[i]);
    }
}

void initializeAllCan() {
    for(int i = 0; i < getCanBusCount(); i++) {
        initializeCan(&(getCanBuses()[i]));
    }
}

void receiveRawWriteRequest(cJSON* idObject, cJSON* root) {
    uint32_t id = idObject->valueint;
    cJSON* dataObject = cJSON_GetObjectItem(root, "data");
    if(dataObject == NULL) {
        debug("Raw write request missing data\r\n", id);
        return;
    }

    char* dataString = dataObject->valuestring;
    char* end;
    unsigned long long data = __builtin_bswap64(strtoull(dataString, &end, 16));
    CanMessage message = {id, data};
    QUEUE_PUSH(CanMessage, &getCanBuses()[0].sendQueue, message);
}

/* The binary format handled by this function is as follows:
 *
 * A leading '{' followed by a 4 byte message ID, then a '|' separator and
 * finally 8 bytes of data and a trailing '}'. E.g.:
 *
 * {<4 byte ID>|<8 bytes of data>}
 */
void receiveBinaryWriteRequest(uint8_t* message) {
    const int BINARY_CAN_WRITE_PACKET_LENGTH = 15;
    if(message[0] != '{' || message[5] != '|' || message[14] != '}') {
        debug("Received a corrupted CAN message: ");
        for(int i = 0; i <= BINARY_CAN_WRITE_PACKET_LENGTH; i++) {
            debug("%02x ", message[i] );
        }
        debug("\r\n");
        return;
    }

    CanMessage outgoing = {0, 0};
    memcpy((uint8_t*)&outgoing.id, &message[1], 4);
    for(int i = 0; i < 8; i++) {
        ((uint8_t*)&(outgoing.data))[i] = message[i + 6];
    }
    QUEUE_PUSH(CanMessage, &getCanBuses()[0].sendQueue, outgoing);
}

void receiveTranslatedWriteRequest(cJSON* nameObject, cJSON* root) {
    char* name = nameObject->valuestring;
    cJSON* value = cJSON_GetObjectItem(root, "value");

    // Optional, may be null
    cJSON* event = cJSON_GetObjectItem(root, "event");

    CanSignal* signal = lookupSignal(name, getSignals(), getSignalCount(),
            true);
    CanCommand* command = lookupCommand(name, getCommands(), getCommandCount());
    if(signal != NULL) {
        if(value == NULL) {
            debug("Write request for %s missing value\r\n", name);
            return;
        }
        sendCanSignal(signal, value, getSignals(), getSignalCount());
    } else if(command != NULL) {
        command->handler(name, value, event, getSignals(), getSignalCount());
    } else {
        debug("Writing not allowed for signal with name %s\r\n", name);
    }
}

bool receiveJsonWriteRequest(uint8_t* message) {
    cJSON *root = cJSON_Parse((char*)message);
    bool foundMessage = false;
    if(root != NULL) {
        foundMessage = true;
        cJSON* nameObject = cJSON_GetObjectItem(root, "name");
        if(nameObject == NULL) {
            cJSON* idObject = cJSON_GetObjectItem(root, "id");
            if(idObject == NULL) {
                debug("Write request is malformed, "
                        "missing name or id: %s\r\n", message);
            } else {
                receiveRawWriteRequest(idObject, root);
            }
        } else {
            receiveTranslatedWriteRequest(nameObject, root);
        }
        cJSON_Delete(root);
    } else {
        debug("No valid JSON in incoming buffer yet -- "
                "if it's valid, may be out of memory\r\n");
    }
    return foundMessage;
}

bool receiveWriteRequest(uint8_t* message) {
#ifdef TRANSMITTER
    receiveBinaryWriteRequest(message);
    return true;
#else
    return receiveJsonWriteRequest(message);
#endif
}

/*
 * Check to see if a packet has been received. If so, read the packet and print
 * the packet payload to the serial monitor.
 */
void receiveCan(CanBus* bus) {
    // TODO what happens if we process until the queue is empty?
    if(!QUEUE_EMPTY(CanMessage, &bus->receiveQueue)) {
        CanMessage message = QUEUE_POP(CanMessage, &bus->receiveQueue);
        decodeCanMessage(message.id, message.data);
    }
}

void reset() {
    initializeAllCan();
}

#endif // CAN_EMULATOR
<|endoftext|>


<commit_before>// Copyright (c) 2015, Baidu.com, Inc. All Rights Reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: yanshiguang02@baidu.com

#include "file_cache.h"

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "common/logging.h"

namespace bfs {

struct FileEntity {
    int32_t fd;
    std::string file_name;
};

static void DeleteEntry(const common::Slice& key, void* value) {
    FileEntity* file = reinterpret_cast<FileEntity*>(value);
    close(file->fd);
    LOG(INFO, "FileCache Close file %s", file->file_name.c_str());
    delete file;
}

FileCache::FileCache(int32_t cache_size)
    : _cache(common::NewLRUCache(cache_size)) {
}

FileCache::~FileCache() {
    delete _cache;
}

common::Cache::Handle* FileCache::FindFile(const std::string& file_path) {
    common::Slice key(file_path);
    common::Cache::Handle* handle = _cache->Lookup(key);
    handle = _cache->Lookup(key);
    if (handle == NULL) {
        int fd = open(file_path.c_str(), O_RDONLY);
        if (fd < 0) {
            return NULL;
        }
        FileEntity* file = new FileEntity;
        file->fd = fd;
        file->file_name = file_path;
        handle = _cache->Insert(key, file, 1, &DeleteEntry);
    }
    return handle;
}
int32_t FileCache::ReadFile(const std::string& file_path, char* buf,
                            int32_t len, int64_t offset) {
    common::Cache::Handle* handle = FindFile(file_path);
    int32_t fd = (reinterpret_cast<FileEntity*>(_cache->Value(handle)))->fd;
    int32_t ret = pread(fd, buf, len, offset);
    _cache->Release(handle);
    return ret;
}

} // namespace bfs
/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
<commit_msg>Smallfix<commit_after>// Copyright (c) 2015, Baidu.com, Inc. All Rights Reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: yanshiguang02@baidu.com

#include "file_cache.h"

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "common/logging.h"

namespace bfs {

struct FileEntity {
    int32_t fd;
    std::string file_name;
};

static void DeleteEntry(const common::Slice& key, void* value) {
    FileEntity* file = reinterpret_cast<FileEntity*>(value);
    close(file->fd);
    LOG(INFO, "FileCache Close file %s", file->file_name.c_str());
    delete file;
}

FileCache::FileCache(int32_t cache_size)
    : _cache(common::NewLRUCache(cache_size)) {
}

FileCache::~FileCache() {
    delete _cache;
}

common::Cache::Handle* FileCache::FindFile(const std::string& file_path) {
    common::Slice key(file_path);
    common::Cache::Handle* handle = _cache->Lookup(key);
    if (handle == NULL) {
        int fd = open(file_path.c_str(), O_RDONLY);
        if (fd < 0) {
            return NULL;
        }
        FileEntity* file = new FileEntity;
        file->fd = fd;
        file->file_name = file_path;
        handle = _cache->Insert(key, file, 1, &DeleteEntry);
    }
    return handle;
}
int32_t FileCache::ReadFile(const std::string& file_path, char* buf,
                            int32_t len, int64_t offset) {
    common::Cache::Handle* handle = FindFile(file_path);
    int32_t fd = (reinterpret_cast<FileEntity*>(_cache->Value(handle)))->fd;
    int32_t ret = pread(fd, buf, len, offset);
    _cache->Release(handle);
    return ret;
}

} // namespace bfs
/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
<|endoftext|>


<commit_before>#include <fstream>

#include <chdl/chdl.h>
#include <chdl/cassign.h>

#include "config.h"
#include "interfaces.h"
#include "harpinst.h"

using namespace std;
using namespace chdl;

// Types and functions for barrier implementation
typedef ag<STP("valid"), node,
        ag<STP("pc"), bvec<N>,
        ag<STP("id"), bvec<WW>,
        ag<STP("active"), bvec<L> > > > > barrier_warp_t;

typedef ag<STP("valid"), node,
        ag<STP("arrived"), bvec<WW>,
        ag<STP("warps"), vec<W, barrier_warp_t> > > > barrier_t;

// Replace the idx-th entry of in with val. Optionally replace all entries.
template <unsigned N, typename T>
  void Replace(vec<N, T> out, vec<N, T> in,
               bvec<CLOG2(N)> idx, const T &val, node all=Lit(0));

void Funcunit_bar(func_splitter_t &out, reg_func_t &in);

void Funcunit_bar(func_splitter_t &out, reg_func_t &in) {
  HIERARCHY_ENTER();

  // The state machine that controls this unit. We're OK with introducing some
  // 1-cycle delays, so there is no pipelining.
  enum { ST_IDLE, ST_WRITE, ST_RELEASE, ST_CLEAR, N_STATES } state_t;
  const unsigned SS(CLOG2(N_STATES));
  bvec<SS> next_state, state(Reg(next_state));
  bvec<N_STATES> state_1h(Zext<N_STATES>(Decoder(state)));

  harpinst<N, RR, RR> inst(_(_(in, "contents"), "ir"));
  bvec<L> active(_(_(_(in, "contents"), "warp"), "active")),
          pmask(_(_(_(in, "contents"), "pval"), "pmask"));

  vec<L, bvec<N> > n_v(_(_(_(in,"contents"),"rval"),"val1")),
                   id_v(_(_(_(in,"contents"),"rval"),"val0"));

  bvec<LL> lane_sel(Lsb(active & pmask));
  node arrive(_(in, "valid") && OrN(active & pmask));

  bvec<CLOG2(BARRIERS)> id(Latch(
    !arrive, Zext<CLOG2(BARRIERS)>(Mux(lane_sel, id_v))
  ));
  bvec<CLOG2(W + 1)> n(Latch(
    !arrive, Zext<CLOG2(W+1)>(Mux(lane_sel, n_v))
  ));

  TAP(arrive);
  TAP(lane_sel);
  TAP(id);
  TAP(n);
  TAP(state);

  node wr(state_1h[ST_WRITE] || state_1h[ST_CLEAR]), filled, all_released;
  barrier_t d, q(Syncmem(id, Flatten(d), wr));

  Cassign(next_state).
    IF(state_1h[ST_IDLE] && arrive, Lit<SS>(ST_WRITE)).
    IF(state_1h[ST_WRITE] && filled, Lit<SS>(ST_RELEASE)).
    IF(state_1h[ST_WRITE] && !filled, Lit<SS>(ST_IDLE)).
    IF(state_1h[ST_RELEASE] && all_released, Lit<SS>(ST_CLEAR)).
    IF(state_1h[ST_CLEAR], Lit<SS>(ST_IDLE)).
    ELSE(state);
  TAP(d); TAP(q);

  filled = (n == Lit<CLOG2(W + 1)>(1)) ||
           _(q, "arrived") == Zext<WW>(n - Lit<CLOG2(W + 1)>(1));

  TAP(filled);

  // Valid bit is cleared for clear, set for write.
  _(d, "valid") = state_1h[ST_WRITE];
  bvec<WW> idx;
  Cassign(idx).
    IF(_(q, "valid"), _(q, "arrived")).
    ELSE(Lit<WW>(0));
  _(d, "arrived") = Mux(state_1h[ST_CLEAR], idx + Lit<WW>(1), Lit<WW>(0));

  // In release mode, maintain a counter that increments every time we send
  // another warp back out into the pipeline to join its friends.
  node release(state_1h[ST_RELEASE] && _(out, "ready")),
       reset_release_ctr(!state_1h[ST_RELEASE]);
  bvec<CLOG2(W + 1)> next_release_ctr, release_ctr(Reg(next_release_ctr));
  Cassign(next_release_ctr).
    IF(reset_release_ctr, Lit<CLOG2(W + 1)>(0)).
    IF(release, release_ctr + Lit<CLOG2(W + 1)>(1)).
    ELSE(release_ctr);
  all_released = (next_release_ctr == n);

  TAP(release);
  TAP(release_ctr);
  TAP(all_released);

  barrier_warp_t w;
  Replace(_(d, "warps"), _(q, "warps"), idx, w, state_1h[ST_CLEAR]);
  _(w, "pc") = Latch(!arrive, _(_(_(in, "contents"), "warp"), "pc"));
  _(w, "id") = Latch(!arrive, _(_(_(in, "contents"), "warp"), "id"));
  _(w, "active") = Latch(!arrive, _(_(_(in, "contents"), "warp"), "active"));
  _(w, "valid") = state_1h[ST_WRITE];

  // Never writes anything back.
  _(_(_(out, "contents"), "rwb"), "mask") = Lit<L>(0);

  _(in, "ready") = state_1h[ST_IDLE];
  _(out, "valid") = state_1h[ST_RELEASE];

  barrier_warp_t rw(Mux(Zext<WW>(release_ctr), _(q, "warps")));
  _(_(_(out, "contents"), "warp"), "id") = _(rw, "id");
  _(_(_(out, "contents"), "warp"), "active") = _(rw, "active");
  _(_(_(out, "contents"), "warp"), "pc") = _(rw, "pc");

  HIERARCHY_EXIT();
}

template <unsigned N, typename T>
  void Replace(vec<N, T> out, vec<N, T> in,
               bvec<CLOG2(N)> idx, const T &val, node all)
{
  for (unsigned i = 0; i < N; ++i)
    Cassign(out[i]).
      IF(all || idx == Lit<CLOG2(N)>(i), val).
      ELSE(in[i]);
}
<commit_msg>Can only arrive at barrier when it's ready.<commit_after>#include <fstream>

#include <chdl/chdl.h>
#include <chdl/cassign.h>

#include "config.h"
#include "interfaces.h"
#include "harpinst.h"

using namespace std;
using namespace chdl;

// Types and functions for barrier implementation
typedef ag<STP("valid"), node,
        ag<STP("pc"), bvec<N>,
        ag<STP("id"), bvec<WW>,
        ag<STP("active"), bvec<L> > > > > barrier_warp_t;

typedef ag<STP("valid"), node,
        ag<STP("arrived"), bvec<WW>,
        ag<STP("warps"), vec<W, barrier_warp_t> > > > barrier_t;

// Replace the idx-th entry of in with val. Optionally replace all entries.
template <unsigned N, typename T>
  void Replace(vec<N, T> out, vec<N, T> in,
               bvec<CLOG2(N)> idx, const T &val, node all=Lit(0));

void Funcunit_bar(func_splitter_t &out, reg_func_t &in);

void Funcunit_bar(func_splitter_t &out, reg_func_t &in) {
  HIERARCHY_ENTER();

  // The state machine that controls this unit. We're OK with introducing some
  // 1-cycle delays, so there is no pipelining.
  enum { ST_IDLE, ST_WRITE, ST_RELEASE, ST_CLEAR, N_STATES } state_t;
  const unsigned SS(CLOG2(N_STATES));
  bvec<SS> next_state, state(Reg(next_state));
  bvec<N_STATES> state_1h(Zext<N_STATES>(Decoder(state)));

  harpinst<N, RR, RR> inst(_(_(in, "contents"), "ir"));
  bvec<L> active(_(_(_(in, "contents"), "warp"), "active")),
          pmask(_(_(_(in, "contents"), "pval"), "pmask"));

  vec<L, bvec<N> > n_v(_(_(_(in,"contents"),"rval"),"val1")),
                   id_v(_(_(_(in,"contents"),"rval"),"val0"));

  bvec<LL> lane_sel(Lsb(active & pmask));
  node arrive(_(in, "ready") && _(in, "valid") && OrN(active & pmask));

  bvec<CLOG2(BARRIERS)> id(Latch(
    !arrive, Zext<CLOG2(BARRIERS)>(Mux(lane_sel, id_v))
  ));
  bvec<CLOG2(W + 1)> n(Latch(
    !arrive, Zext<CLOG2(W+1)>(Mux(lane_sel, n_v))
  ));

  TAP(arrive);
  TAP(lane_sel);
  TAP(id);
  TAP(n);
  TAP(state);

  node wr(state_1h[ST_WRITE] || state_1h[ST_CLEAR]), filled, all_released;
  barrier_t d, q(Syncmem(id, Flatten(d), wr));

  Cassign(next_state).
    IF(state_1h[ST_IDLE] && arrive, Lit<SS>(ST_WRITE)).
    IF(state_1h[ST_WRITE] && filled, Lit<SS>(ST_RELEASE)).
    IF(state_1h[ST_WRITE] && !filled, Lit<SS>(ST_IDLE)).
    IF(state_1h[ST_RELEASE] && all_released, Lit<SS>(ST_CLEAR)).
    IF(state_1h[ST_CLEAR], Lit<SS>(ST_IDLE)).
    ELSE(state);
  TAP(d); TAP(q);

  filled = (n == Lit<CLOG2(W + 1)>(1)) ||
           _(q, "arrived") == Zext<WW>(n - Lit<CLOG2(W + 1)>(1));

  TAP(filled);

  // Valid bit is cleared for clear, set for write.
  _(d, "valid") = state_1h[ST_WRITE];
  bvec<WW> idx;
  Cassign(idx).
    IF(_(q, "valid"), _(q, "arrived")).
    ELSE(Lit<WW>(0));
  _(d, "arrived") = Mux(state_1h[ST_CLEAR], idx + Lit<WW>(1), Lit<WW>(0));

  // In release mode, maintain a counter that increments every time we send
  // another warp back out into the pipeline to join its friends.
  node release(state_1h[ST_RELEASE] && _(out, "ready")),
       reset_release_ctr(!state_1h[ST_RELEASE]);
  bvec<CLOG2(W + 1)> next_release_ctr, release_ctr(Reg(next_release_ctr));
  Cassign(next_release_ctr).
    IF(reset_release_ctr, Lit<CLOG2(W + 1)>(0)).
    IF(release, release_ctr + Lit<CLOG2(W + 1)>(1)).
    ELSE(release_ctr);
  all_released = (next_release_ctr == n);

  TAP(release);
  TAP(release_ctr);
  TAP(all_released);

  barrier_warp_t w;
  Replace(_(d, "warps"), _(q, "warps"), idx, w, state_1h[ST_CLEAR]);
  _(w, "pc") = Latch(!arrive, _(_(_(in, "contents"), "warp"), "pc"));
  _(w, "id") = Latch(!arrive, _(_(_(in, "contents"), "warp"), "id"));
  _(w, "active") = Latch(!arrive, _(_(_(in, "contents"), "warp"), "active"));
  _(w, "valid") = state_1h[ST_WRITE];

  // Never writes anything back.
  _(_(_(out, "contents"), "rwb"), "mask") = Lit<L>(0);

  _(in, "ready") = state_1h[ST_IDLE];
  _(out, "valid") = state_1h[ST_RELEASE];

  barrier_warp_t rw(Mux(Zext<WW>(release_ctr), _(q, "warps")));
  _(_(_(out, "contents"), "warp"), "id") = _(rw, "id");
  _(_(_(out, "contents"), "warp"), "active") = _(rw, "active");
  _(_(_(out, "contents"), "warp"), "pc") = _(rw, "pc");

  HIERARCHY_EXIT();
}

template <unsigned N, typename T>
  void Replace(vec<N, T> out, vec<N, T> in,
               bvec<CLOG2(N)> idx, const T &val, node all)
{
  for (unsigned i = 0; i < N; ++i)
    Cassign(out[i]).
      IF(all || idx == Lit<CLOG2(N)>(i), val).
      ELSE(in[i]);
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/core/SkMatrixImageFilter.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkRect.h"
#include "include/effects/SkImageFilters.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkSamplingPriv.h"
#include "src/core/SkSpecialImage.h"
#include "src/core/SkSpecialSurface.h"
#include "src/core/SkWriteBuffer.h"

SkMatrixImageFilter::SkMatrixImageFilter(const SkMatrix& transform,
                                         const SkSamplingOptions& sampling,
                                         sk_sp<SkImageFilter> input)
    : INHERITED(&input, 1, nullptr)
    , fTransform(transform)
    , fSampling(sampling) {
}

sk_sp<SkImageFilter> SkMatrixImageFilter::Make(const SkMatrix& transform,
                                               const SkSamplingOptions& sampling,
                                               sk_sp<SkImageFilter> input) {
    return sk_sp<SkImageFilter>(new SkMatrixImageFilter(transform,
                                                        sampling,
                                                        std::move(input)));
}

sk_sp<SkImageFilter> SkImageFilters::MatrixTransform(
        const SkMatrix& transform, const SkSamplingOptions& sampling, sk_sp<SkImageFilter> input) {
    return SkMatrixImageFilter::Make(transform, sampling, std::move(input));
}

#ifdef SK_SUPPORT_LEGACY_MATRIX_IMAGEFILTER
sk_sp<SkImageFilter> SkImageFilters::MatrixTransform(
        const SkMatrix& transform, SkFilterQuality filterQuality, sk_sp<SkImageFilter> input) {
    auto sampling = SkSamplingOptions(filterQuality,
                                      SkSamplingOptions::kMedium_asMipmapLinear);
    return SkMatrixImageFilter::Make(transform, sampling, std::move(input));
}
#endif

sk_sp<SkFlattenable> SkMatrixImageFilter::CreateProc(SkReadBuffer& buffer) {
    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
    SkMatrix matrix;
    buffer.readMatrix(&matrix);

    auto sampling = [&]() {
        if (buffer.isVersionLT(SkPicturePriv::kMatrixImageFilterSampling_Version)) {
            return SkSamplingOptions(buffer.read32LE(kLast_SkFilterQuality),
                                     SkSamplingOptions::kMedium_asMipmapLinear);
        } else {
            return SkSamplingPriv::Read(buffer);
        }
    }();
    return Make(matrix, sampling, common.getInput(0));
}

void SkMatrixImageFilter::flatten(SkWriteBuffer& buffer) const {
    this->INHERITED::flatten(buffer);
    buffer.writeMatrix(fTransform);
    SkSamplingPriv::Write(buffer, fSampling);
}

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

sk_sp<SkSpecialImage> SkMatrixImageFilter::onFilterImage(const Context& ctx,
                                                         SkIPoint* offset) const {

    SkIPoint inputOffset = SkIPoint::Make(0, 0);
    sk_sp<SkSpecialImage> input(this->filterInput(0, ctx, &inputOffset));
    if (!input) {
        return nullptr;
    }

    SkMatrix matrix;
    if (!ctx.ctm().invert(&matrix)) {
        return nullptr;
    }
    matrix.postConcat(fTransform);
    matrix.postConcat(ctx.ctm());

    const SkIRect srcBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(),
                                                input->width(), input->height());
    const SkRect srcRect = SkRect::Make(srcBounds);

    SkRect dstRect;
    matrix.mapRect(&dstRect, srcRect);
    SkIRect dstBounds;
    dstRect.roundOut(&dstBounds);

    sk_sp<SkSpecialSurface> surf(ctx.makeSurface(dstBounds.size()));
    if (!surf) {
        return nullptr;
    }

    SkCanvas* canvas = surf->getCanvas();
    SkASSERT(canvas);

    canvas->clear(0x0);

    canvas->translate(-SkIntToScalar(dstBounds.x()), -SkIntToScalar(dstBounds.y()));
    canvas->concat(matrix);

    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setBlendMode(SkBlendMode::kSrc);

    input->draw(canvas, srcRect.x(), srcRect.y(), fSampling, &paint);

    offset->fX = dstBounds.fLeft;
    offset->fY = dstBounds.fTop;
    return surf->makeImageSnapshot();
}

SkRect SkMatrixImageFilter::computeFastBounds(const SkRect& src) const {
    SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
    SkRect dst;
    fTransform.mapRect(&dst, bounds);
    return dst;
}

SkIRect SkMatrixImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
                                                MapDirection dir, const SkIRect* inputRect) const {
    SkMatrix matrix;
    if (!ctm.invert(&matrix)) {
        return src;
    }
    if (kForward_MapDirection == dir) {
        matrix.postConcat(fTransform);
    } else {
        SkMatrix transformInverse;
        if (!fTransform.invert(&transformInverse)) {
            return src;
        }
        matrix.postConcat(transformInverse);
    }
    matrix.postConcat(ctm);
    SkRect floatBounds;
    matrix.mapRect(&floatBounds, SkRect::Make(src));
    SkIRect result = floatBounds.roundOut();

    if (kReverse_MapDirection == dir && SkSamplingOptions() != fSampling) {
        // When filtering we might need some pixels in the source that might be otherwise
        // clipped off.
        result.outset(1, 1);
    }

    return result;
}
<commit_msg>Pre-cache matrix type in SkMatrixImageFilter<commit_after>/*
 * Copyright 2014 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/core/SkMatrixImageFilter.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkRect.h"
#include "include/effects/SkImageFilters.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkSamplingPriv.h"
#include "src/core/SkSpecialImage.h"
#include "src/core/SkSpecialSurface.h"
#include "src/core/SkWriteBuffer.h"

SkMatrixImageFilter::SkMatrixImageFilter(const SkMatrix& transform,
                                         const SkSamplingOptions& sampling,
                                         sk_sp<SkImageFilter> input)
    : INHERITED(&input, 1, nullptr)
    , fTransform(transform)
    , fSampling(sampling) {
    // Pre-cache so future calls to fTransform.getType() are threadsafe.
    (void)fTransform.getType();
}

sk_sp<SkImageFilter> SkMatrixImageFilter::Make(const SkMatrix& transform,
                                               const SkSamplingOptions& sampling,
                                               sk_sp<SkImageFilter> input) {
    return sk_sp<SkImageFilter>(new SkMatrixImageFilter(transform,
                                                        sampling,
                                                        std::move(input)));
}

sk_sp<SkImageFilter> SkImageFilters::MatrixTransform(
        const SkMatrix& transform, const SkSamplingOptions& sampling, sk_sp<SkImageFilter> input) {
    return SkMatrixImageFilter::Make(transform, sampling, std::move(input));
}

#ifdef SK_SUPPORT_LEGACY_MATRIX_IMAGEFILTER
sk_sp<SkImageFilter> SkImageFilters::MatrixTransform(
        const SkMatrix& transform, SkFilterQuality filterQuality, sk_sp<SkImageFilter> input) {
    auto sampling = SkSamplingOptions(filterQuality,
                                      SkSamplingOptions::kMedium_asMipmapLinear);
    return SkMatrixImageFilter::Make(transform, sampling, std::move(input));
}
#endif

sk_sp<SkFlattenable> SkMatrixImageFilter::CreateProc(SkReadBuffer& buffer) {
    SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 1);
    SkMatrix matrix;
    buffer.readMatrix(&matrix);

    auto sampling = [&]() {
        if (buffer.isVersionLT(SkPicturePriv::kMatrixImageFilterSampling_Version)) {
            return SkSamplingOptions(buffer.read32LE(kLast_SkFilterQuality),
                                     SkSamplingOptions::kMedium_asMipmapLinear);
        } else {
            return SkSamplingPriv::Read(buffer);
        }
    }();
    return Make(matrix, sampling, common.getInput(0));
}

void SkMatrixImageFilter::flatten(SkWriteBuffer& buffer) const {
    this->INHERITED::flatten(buffer);
    buffer.writeMatrix(fTransform);
    SkSamplingPriv::Write(buffer, fSampling);
}

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

sk_sp<SkSpecialImage> SkMatrixImageFilter::onFilterImage(const Context& ctx,
                                                         SkIPoint* offset) const {

    SkIPoint inputOffset = SkIPoint::Make(0, 0);
    sk_sp<SkSpecialImage> input(this->filterInput(0, ctx, &inputOffset));
    if (!input) {
        return nullptr;
    }

    SkMatrix matrix;
    if (!ctx.ctm().invert(&matrix)) {
        return nullptr;
    }
    matrix.postConcat(fTransform);
    matrix.postConcat(ctx.ctm());

    const SkIRect srcBounds = SkIRect::MakeXYWH(inputOffset.x(), inputOffset.y(),
                                                input->width(), input->height());
    const SkRect srcRect = SkRect::Make(srcBounds);

    SkRect dstRect;
    matrix.mapRect(&dstRect, srcRect);
    SkIRect dstBounds;
    dstRect.roundOut(&dstBounds);

    sk_sp<SkSpecialSurface> surf(ctx.makeSurface(dstBounds.size()));
    if (!surf) {
        return nullptr;
    }

    SkCanvas* canvas = surf->getCanvas();
    SkASSERT(canvas);

    canvas->clear(0x0);

    canvas->translate(-SkIntToScalar(dstBounds.x()), -SkIntToScalar(dstBounds.y()));
    canvas->concat(matrix);

    SkPaint paint;
    paint.setAntiAlias(true);
    paint.setBlendMode(SkBlendMode::kSrc);

    input->draw(canvas, srcRect.x(), srcRect.y(), fSampling, &paint);

    offset->fX = dstBounds.fLeft;
    offset->fY = dstBounds.fTop;
    return surf->makeImageSnapshot();
}

SkRect SkMatrixImageFilter::computeFastBounds(const SkRect& src) const {
    SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
    SkRect dst;
    fTransform.mapRect(&dst, bounds);
    return dst;
}

SkIRect SkMatrixImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
                                                MapDirection dir, const SkIRect* inputRect) const {
    SkMatrix matrix;
    if (!ctm.invert(&matrix)) {
        return src;
    }
    if (kForward_MapDirection == dir) {
        matrix.postConcat(fTransform);
    } else {
        SkMatrix transformInverse;
        if (!fTransform.invert(&transformInverse)) {
            return src;
        }
        matrix.postConcat(transformInverse);
    }
    matrix.postConcat(ctm);
    SkRect floatBounds;
    matrix.mapRect(&floatBounds, SkRect::Make(src));
    SkIRect result = floatBounds.roundOut();

    if (kReverse_MapDirection == dir && SkSamplingOptions() != fSampling) {
        // When filtering we might need some pixels in the source that might be otherwise
        // clipped off.
        result.outset(1, 1);
    }

    return result;
}
<|endoftext|>


<commit_before>/**
 * @file
 * @brief Implementation of messenger
 *
 * @copyright MIT License
 */

#include "Messenger.hpp"

#include <memory>
#include <stdexcept>
#include <string>
#include <typeindex>

#include "Message.hpp"
#include "core/module/Module.hpp"
#include "core/utils/log.h"
#include "core/utils/type.h"
#include "delegates.h"

using namespace allpix;

Messenger::Messenger() = default;
#ifdef NDEBUG
Messenger::~Messenger() = default;
#else
Messenger::~Messenger() {
    assert(delegate_to_iterator_.empty());
}
#endif

// Check if the detectors match for the message and the delegate
static bool check_send(BaseMessage* message, BaseDelegate* delegate) {
    if(delegate->getDetector() != nullptr &&
       (message->getDetector() == nullptr || delegate->getDetector()->getName() != message->getDetector()->getName())) {
        return false;
    }
    return true;
}

/**
 * Messages should be bound during construction, so this function only gives useful information outside the constructor
 */
bool Messenger::hasReceiver(Module* source, const std::shared_ptr<BaseMessage>& message) {
    const BaseMessage* inst = message.get();
    std::type_index type_idx = typeid(*inst);

    // Get the name of the output message
    std::string name = source->get_configuration().get<std::string>("output");

    // Check if a normal specific listener exists
    for(auto& delegate : delegates_[type_idx][name]) {
        if(check_send(message.get(), delegate.get())) {
            return true;
        }
    }
    // Check if a normal generic listener exists
    for(auto& delegate : delegates_[type_idx]["*"]) {
        if(check_send(message.get(), delegate.get())) {
            return true;
        }
    }
    // Check if a base message specific listener exists
    for(auto& delegate : delegates_[typeid(BaseMessage)][name]) {
        if(check_send(message.get(), delegate.get())) {
            return true;
        }
    }
    // Check if a base message generic listener exists
    for(auto& delegate : delegates_[typeid(BaseMessage)]["*"]) {
        if(check_send(message.get(), delegate.get())) {
            return true;
        }
    }

    return false;
}

/**
 * Send messages to all specific listeners and also to all generic listeners (listening to all incoming messages)
 */
void Messenger::dispatch_message(Module* source, const std::shared_ptr<BaseMessage>& message, std::string name) {
    // Get the name of the output message
    if(name == "-") {
        name = source->get_configuration().get<std::string>("output");
    }

    bool send = false;

    // Send to specific listeners
    send = dispatch_message(source, message, name, name) || send;

    // Send to generic listeners
    send = dispatch_message(source, message, name, "*") || send;

    // Display a warning if the message is send to no receiver
    // FIXME: Check better if this is a real problem (or do this always only in the module)
    if(!send) {
        const BaseMessage* inst = message.get();
        LOG(WARNING) << "Dispatched message " << allpix::demangle(typeid(*inst).name()) << " from "
                     << source->getUniqueName() << " has no receivers!";
    }
}

/**
 * Messages are only dispatched to delegates listening to the exact same type and the exact same name.
 */
bool Messenger::dispatch_message(Module* source,
                                 const std::shared_ptr<BaseMessage>& message,
                                 const std::string& name,
                                 const std::string& id) {
    bool send = false;

    // Create type identifier from the typeid
    const BaseMessage* inst = message.get();
    std::type_index type_idx = typeid(*inst);

    // Send messages only to their specific listeners
    for(auto& delegate : delegates_[type_idx][id]) {
        if(check_send(message.get(), delegate.get())) {
            LOG(TRACE) << "Sending message " << allpix::demangle(type_idx.name()) << " from " << source->getUniqueName()
                       << " to " << delegate->getUniqueName();
            delegate->process(message, name);
            send = true;
        }
    }

    // Dispatch to base message listeners
    assert(typeid(BaseMessage) != typeid(*inst));
    for(auto& delegate : delegates_[typeid(BaseMessage)][id]) {
        if(check_send(message.get(), delegate.get())) {
            LOG(TRACE) << "Sending message " << allpix::demangle(type_idx.name()) << " from " << source->getUniqueName()
                       << " to generic listener " << delegate->getUniqueName();
            delegate->process(message, name);
            send = true;
        }
    }

    return send;
}

void Messenger::add_delegate(const std::type_info& message_type, Module* module, std::unique_ptr<BaseDelegate> delegate) {
    // Register generic or specific delegate depending on flag
    std::string message_name;
    if((delegate->getFlags() & MsgFlags::IGNORE_NAME) != MsgFlags::NONE) {
        message_name = "*";
    } else {
        message_name = module->get_configuration().get<std::string>("input");
    }

    // Register delegate internally
    delegates_[std::type_index(message_type)][message_name].push_back(std::move(delegate));
    auto delegate_iter = --delegates_[std::type_index(message_type)][message_name].end();
    delegate_to_iterator_.emplace(delegate_iter->get(),
                                  std::make_tuple(std::type_index(message_type), message_name, delegate_iter));

    // Add delegate to the module itself
    module->add_delegate(this, delegate_iter->get());
}

/**
 * @throws std::out_of_range If a delegate is removed which is never registered
 */
void Messenger::remove_delegate(BaseDelegate* delegate) {
    auto iter = delegate_to_iterator_.find(delegate);
    if(iter == delegate_to_iterator_.end()) {
        throw std::out_of_range("delegate not found in listeners");
    }
    delegates_[std::get<0>(iter->second)][std::get<1>(iter->second)].erase(std::get<2>(iter->second));
    delegate_to_iterator_.erase(iter);
}
<commit_msg>Messenger: remove warnings about dispatched messages without receivers.<commit_after>/**
 * @file
 * @brief Implementation of messenger
 *
 * @copyright MIT License
 */

#include "Messenger.hpp"

#include <memory>
#include <stdexcept>
#include <string>
#include <typeindex>

#include "Message.hpp"
#include "core/module/Module.hpp"
#include "core/utils/log.h"
#include "core/utils/type.h"
#include "delegates.h"

using namespace allpix;

Messenger::Messenger() = default;
#ifdef NDEBUG
Messenger::~Messenger() = default;
#else
Messenger::~Messenger() {
    assert(delegate_to_iterator_.empty());
}
#endif

// Check if the detectors match for the message and the delegate
static bool check_send(BaseMessage* message, BaseDelegate* delegate) {
    if(delegate->getDetector() != nullptr &&
       (message->getDetector() == nullptr || delegate->getDetector()->getName() != message->getDetector()->getName())) {
        return false;
    }
    return true;
}

/**
 * Messages should be bound during construction, so this function only gives useful information outside the constructor
 */
bool Messenger::hasReceiver(Module* source, const std::shared_ptr<BaseMessage>& message) {
    const BaseMessage* inst = message.get();
    std::type_index type_idx = typeid(*inst);

    // Get the name of the output message
    std::string name = source->get_configuration().get<std::string>("output");

    // Check if a normal specific listener exists
    for(auto& delegate : delegates_[type_idx][name]) {
        if(check_send(message.get(), delegate.get())) {
            return true;
        }
    }
    // Check if a normal generic listener exists
    for(auto& delegate : delegates_[type_idx]["*"]) {
        if(check_send(message.get(), delegate.get())) {
            return true;
        }
    }
    // Check if a base message specific listener exists
    for(auto& delegate : delegates_[typeid(BaseMessage)][name]) {
        if(check_send(message.get(), delegate.get())) {
            return true;
        }
    }
    // Check if a base message generic listener exists
    for(auto& delegate : delegates_[typeid(BaseMessage)]["*"]) {
        if(check_send(message.get(), delegate.get())) {
            return true;
        }
    }

    return false;
}

/**
 * Send messages to all specific listeners and also to all generic listeners (listening to all incoming messages)
 */
void Messenger::dispatch_message(Module* source, const std::shared_ptr<BaseMessage>& message, std::string name) {
    // Get the name of the output message
    if(name == "-") {
        name = source->get_configuration().get<std::string>("output");
    }

    bool send = false;

    // Send to specific listeners
    send = dispatch_message(source, message, name, name) || send;

    // Send to generic listeners
    send = dispatch_message(source, message, name, "*") || send;
}

/**
 * Messages are only dispatched to delegates listening to the exact same type and the exact same name.
 */
bool Messenger::dispatch_message(Module* source,
                                 const std::shared_ptr<BaseMessage>& message,
                                 const std::string& name,
                                 const std::string& id) {
    bool send = false;

    // Create type identifier from the typeid
    const BaseMessage* inst = message.get();
    std::type_index type_idx = typeid(*inst);

    // Send messages only to their specific listeners
    for(auto& delegate : delegates_[type_idx][id]) {
        if(check_send(message.get(), delegate.get())) {
            LOG(TRACE) << "Sending message " << allpix::demangle(type_idx.name()) << " from " << source->getUniqueName()
                       << " to " << delegate->getUniqueName();
            delegate->process(message, name);
            send = true;
        }
    }

    // Dispatch to base message listeners
    assert(typeid(BaseMessage) != typeid(*inst));
    for(auto& delegate : delegates_[typeid(BaseMessage)][id]) {
        if(check_send(message.get(), delegate.get())) {
            LOG(TRACE) << "Sending message " << allpix::demangle(type_idx.name()) << " from " << source->getUniqueName()
                       << " to generic listener " << delegate->getUniqueName();
            delegate->process(message, name);
            send = true;
        }
    }

    return send;
}

void Messenger::add_delegate(const std::type_info& message_type, Module* module, std::unique_ptr<BaseDelegate> delegate) {
    // Register generic or specific delegate depending on flag
    std::string message_name;
    if((delegate->getFlags() & MsgFlags::IGNORE_NAME) != MsgFlags::NONE) {
        message_name = "*";
    } else {
        message_name = module->get_configuration().get<std::string>("input");
    }

    // Register delegate internally
    delegates_[std::type_index(message_type)][message_name].push_back(std::move(delegate));
    auto delegate_iter = --delegates_[std::type_index(message_type)][message_name].end();
    delegate_to_iterator_.emplace(delegate_iter->get(),
                                  std::make_tuple(std::type_index(message_type), message_name, delegate_iter));

    // Add delegate to the module itself
    module->add_delegate(this, delegate_iter->get());
}

/**
 * @throws std::out_of_range If a delegate is removed which is never registered
 */
void Messenger::remove_delegate(BaseDelegate* delegate) {
    auto iter = delegate_to_iterator_.find(delegate);
    if(iter == delegate_to_iterator_.end()) {
        throw std::out_of_range("delegate not found in listeners");
    }
    delegates_[std::get<0>(iter->second)][std::get<1>(iter->second)].erase(std::get<2>(iter->second));
    delegate_to_iterator_.erase(iter);
}
<|endoftext|>


<commit_before>#include <iostream>
#include "taulell.h"

///////////////////////////////////////////
//// Implementació de la classe taulell ///

//---- Constructora. Serveix per declarar una variable
//---- de tipus "taulell" de mida n x n inicialitzada
//---- amb les fitxes inicials d'una partida de Reversi.
//---- Pre: n >=2
taulell::taulell(nat n) {
  // crea taula de mida n x n
  taula = vector<vector<casella> >(n,vector<casella>(n,casella()));

  // inicialitza les 4 caselles centrals del taulell
  // si n és senar, les 4 caselles centrals queden una mica desplaçades amunt i a l'esquerra
  //TODO:

  int mitat = n/2;
  taula[mitat-1][mitat-1].omple(casella::BLANCA);
  taula[mitat][mitat-1].omple(casella::NEGRA);
  taula[mitat-1][mitat].omple(casella::NEGRA);
  taula[mitat][mitat].omple(casella::BLANCA);

}

//---- Diu si les coord p estan dins dels limits del taulell.
bool taulell::dins_limits(coord p) const {
  bool dins_x = p.x >= 0 || p.x < taula.size();
  bool dins_y = p.y >= 0 || p.y < taula.size();
  return dins_x && dins_y;
}

//---- Accedeix a la casella de la coord p del taulell.
casella& taulell::operator()(coord p) {
  return taula[p.x][p.y];
}

//---- Escriu a la pantalla el contingut del taulell.
void taulell::mostra() const {
  // escriu capçalera per enumerar columnes
  for (int i = 0; i <= taula.size(); i++) {
    if (i != 0) cout << i;
    for (int j = 0; j <= taula[i].size(); j++) {
      // escriu contingut amb la numeració de fila al principi
      cout << " ";
      if (i == 0)
      	if (j != 0) cout << j << endl;
      else {
    	casella c = taula[i-1][j-1];
        cout << c.mostra();
      }
    }
  }
}

//---- Escriu a la pantalla el contingut del taulell marcant amb '?'
//---- les caselles on es poden posar fitxes del color donat.
void taulell::mostra(int color) const {
  // escriu capçalera per enumerar columnes
  // ????
  // escriu contingut amb la numeració de fila al principi
  // ????
}

//---- Avalua les fitxes del taulell:
//---- num_caselles_blanques - num_caselles_negres.
int taulell::avalua() const {
  int blanques, negres;
  for (int i = 0; i < taula.size(); i++) {
    for (int j = 0; j < taula[i].size(); j++) {
      casella c = taula[i][j];
      if (c.valor() == 1) blanques++;
      else if(c.valor() == -1) negres++;
    }
  }
  return blanques - negres;
}

//---- Comprova si es pot girar desde la coordenada cini en la direcció d
//---- varies fitxes de l'adversari (al final hem de trobar el color donat).
//---- Retorna: girar (si es pot girar o no), c (coordenada final on s'ha trobat el color donat)
void taulell::es_pot_girar(coord cini, direccio d, int color, bool &girar, coord &c) const {
  // ????
}

//---- Comprova si es pot posar una fitxa de color a la coordena c:
//---- Cal comprovar si en una de les 8 direccions es poden girar fitxes
//---- de l'adversari (de color diferent al color donat).
bool taulell::mov_possible(coord c, int color) const {
  bool possible;

  return possible;
}

//---- Comprova si el color pot jugar (la fitxa de color es pot col·locar en algun lloc).
bool taulell::pot_jugar(int color) const {
  // ????
  return false;
}

//---- Retorna una cua amb les coordenades a on el color pot jugar.
//---- S'encuen per fila creixent, i per la mateixa fila per columna creixent.
queue<coord> taulell::coord_pot_jugar(int color) const {
  // ????
  return queue<coord>();
}

//---- Canvia el color de les caselles des de la casella ci
//---- fins a la casella cf en la direcció d.
void taulell::gira_fitxes(coord ci, coord cf, direccio d) {
  casella inicial = taula[ci.x][ci.y];
  casella final = taula[cf.x][cf.y];
}

//---- Col·loca la fitxa de color a la coordena c i gira les fitxes necessàries segons regles d'Otelo
void taulell::posa_fitxa(coord c, int color) {
  // ????
}
<commit_msg>refactor<commit_after>#include <iostream>
#include "taulell.h"

///////////////////////////////////////////
//// Implementació de la classe taulell ///

//---- Constructora. Serveix per declarar una variable
//---- de tipus "taulell" de mida n x n inicialitzada
//---- amb les fitxes inicials d'una partida de Reversi.
//---- Pre: n >=2
taulell::taulell(nat n) {
  // crea taula de mida n x n
  taula = vector<vector<casella> >(n,vector<casella>(n,casella()));

  // inicialitza les 4 caselles centrals del taulell
  // si n és senar, les 4 caselles centrals queden una mica desplaçades amunt i a l'esquerra
  //TODO:

  int mitat = n/2;
  taula[mitat-1][mitat-1].omple(casella::BLANCA);
  taula[mitat][mitat-1].omple(casella::NEGRA);
  taula[mitat-1][mitat].omple(casella::NEGRA);
  taula[mitat][mitat].omple(casella::BLANCA);

}

//---- Diu si les coord p estan dins dels limits del taulell.
bool taulell::dins_limits(coord p) const {
  bool dins_x = p.x >= 0 || p.x < taula.size();
  bool dins_y = p.y >= 0 || p.y < taula.size();
  return dins_x && dins_y;
}

//---- Accedeix a la casella de la coord p del taulell.
casella& taulell::operator()(coord p) {
  return taula[p.x][p.y];
}

//---- Escriu a la pantalla el contingut del taulell.
void taulell::mostra() const {
  // escriu capçalera per enumerar columnes
  for (int i = 0; i <= taula.size(); i++) {
    if (i != 0) cout << i;
    for (int j = 1; j <= taula[i].size(); j++) {
      // escriu contingut amb la numeració de fila al principi
      cout << " ";
      if (i == 0) cout << j;
      else {
    	  casella c = taula[i-1][j-1];
        cout << c.mostra();
      }
    }
  }
}

//---- Escriu a la pantalla el contingut del taulell marcant amb '?'
//---- les caselles on es poden posar fitxes del color donat.
void taulell::mostra(int color) const {
  // escriu capçalera per enumerar columnes
  // ????
  // escriu contingut amb la numeració de fila al principi
  // ????
}

//---- Avalua les fitxes del taulell:
//---- num_caselles_blanques - num_caselles_negres.
int taulell::avalua() const {
  int blanques, negres;
  for (int i = 0; i < taula.size(); i++) {
    for (int j = 0; j < taula[i].size(); j++) {
      casella c = taula[i][j];
      if (c.valor() == 1) blanques++;
      else if(c.valor() == -1) negres++;
    }
  }
  return blanques - negres;
}

//---- Comprova si es pot girar desde la coordenada cini en la direcció d
//---- varies fitxes de l'adversari (al final hem de trobar el color donat).
//---- Retorna: girar (si es pot girar o no), c (coordenada final on s'ha trobat el color donat)
void taulell::es_pot_girar(coord cini, direccio d, int color, bool &girar, coord &c) const {
  // ????
}

//---- Comprova si es pot posar una fitxa de color a la coordena c:
//---- Cal comprovar si en una de les 8 direccions es poden girar fitxes
//---- de l'adversari (de color diferent al color donat).
bool taulell::mov_possible(coord c, int color) const {
  bool possible;

  return possible;
}

//---- Comprova si el color pot jugar (la fitxa de color es pot col·locar en algun lloc).
bool taulell::pot_jugar(int color) const {
  // ????
  return false;
}

//---- Retorna una cua amb les coordenades a on el color pot jugar.
//---- S'encuen per fila creixent, i per la mateixa fila per columna creixent.
queue<coord> taulell::coord_pot_jugar(int color) const {
  // ????
  return queue<coord>();
}

//---- Canvia el color de les caselles des de la casella ci
//---- fins a la casella cf en la direcció d.
void taulell::gira_fitxes(coord ci, coord cf, direccio d) {
  casella inicial = taula[ci.x][ci.y];
  casella final = taula[cf.x][cf.y];
}

//---- Col·loca la fitxa de color a la coordena c i gira les fitxes necessàries segons regles d'Otelo
void taulell::posa_fitxa(coord c, int color) {
  // ????
}
<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <zorba/util/uri.h>
#include <zorba/zorba_string.h>

using namespace zorba;

int uri_file_decoding_test(int argc, char* argv[]) {
  String lTestString("file:///hello_world");
  String res = URIHelper::decodeFileURI(lTestString);
  if (res != "/hello_world")
    return 1;
  return 0;
}
<commit_msg>Fixed failing uri file decode test on Windows.<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <zorba/util/uri.h>
#include <zorba/util/path.h>
#include <zorba/zorba_string.h>

using namespace zorba;

int uri_file_decoding_test(int argc, char* argv[]) {
  String lTestString("file:///hello_world");
  String res = URIHelper::decodeFileURI(lTestString);
  String lSep(filesystem_path::get_directory_separator());

  if (res != lSep.append("hello_world")) {
    return 1;
  }
  return 0;
}
<|endoftext|>