<commit_before>#include "Simulator.h"
#include "DistanceCalculator.h"
#include <chrono>
#include <thread>
extern DistanceCalculator gDistanceCalculator;

Simulator::Simulator() :ThreadedClass("Simulator")
{
	self.fieldCoords = cv::Point(-100, 100);
	self.polarMetricCoords = cv::Point(0,0);
	// distribute balls uniformly
	for (int i = 0; i < NUMBER_OF_BALLS; i++) {
		balls[i].fieldCoords.x = ((i % 3) - 1) * 100;
		balls[i].fieldCoords.y = (i / 3 - 1.5) * 110;
		balls[i].id = i;
	}
	Start();
}
void Simulator::UpdateGatePos(){

	// angles are wrong
	double a1 = gDistanceCalculator.angleBetween(self.fieldCoords, blueGate.fieldCoords) + self.getAngle();
	double a2 = gDistanceCalculator.angleBetween(self.fieldCoords, yellowGate.fieldCoords) + self.getAngle();

	double d1 = gDistanceCalculator.getDistanceInverted(self.fieldCoords, blueGate.fieldCoords);
	double d2 = gDistanceCalculator.getDistanceInverted(self.fieldCoords, yellowGate.fieldCoords);
	// draw gates
	frame_blank.copyTo(frame);
	double x1 = d1*sin(a1 / 180 * CV_PI);
	double y1 = d1*cos(a1 / 180 * CV_PI);
	double x2 = d2*sin(a2 / 180 * CV_PI);
	double y2 = d2*cos(a2 / 180 * CV_PI);

	cv::Scalar color(236, 137, 48);
	cv::Scalar color2(61, 255, 244);
	cv::circle(frame, cv::Point(x1, y1) + cv::Point(frame.size() / 2), 38, color, -1);
	cv::circle(frame, cv::Point(x2, y2) + cv::Point(frame.size() / 2), 38, color2, -1);

	// balls
	for (int i = 0; i < NUMBER_OF_BALLS; i++){
		double a = gDistanceCalculator.angleBetween(self.fieldCoords, balls[i].fieldCoords) + self.getAngle();
		double d = gDistanceCalculator.getDistanceInverted(self.fieldCoords, balls[i].fieldCoords);
		double x = d*sin(a / 180 * CV_PI);
		double y = d*cos(a / 180 * CV_PI);
		cv::Scalar color(48, 154, 236);
		cv::circle(frame, cv::Point(x, y) + cv::Point(frame.size() / 2), 12, color, -1);
	}

	{
		std::lock_guard<std::mutex> lock(mutex);
		frame.copyTo(frame_copy);
	}

}

void Simulator::UpdateRobotPos(){
	UpdateGatePos();
}

Simulator::~Simulator()
{
	WaitForStop();
}

cv::Mat & Simulator::Capture(bool bFullFrame){
	return frame_copy;
}

cv::Size Simulator::GetFrameSize(bool bFullFrame){
	return frame.size();
}

double Simulator::GetFPS(){
	return 0;
}

cv::Mat & Simulator::GetLastFrame(bool bFullFrame){
	return frame;
}

void Simulator::TogglePlay(){
}

void Simulator::Drive(double fowardSpeed, double direction, double angularSpeed){
	self.polarMetricCoords.y += angularSpeed;
	self.fieldCoords.x += fowardSpeed * sin((direction - self.getAngle()) / 180 * CV_PI);
	self.fieldCoords.y += fowardSpeed * cos((direction - self.getAngle()) / 180 * CV_PI);
}

const Speed & Simulator::GetActualSpeed(){
	return actualSpeed;
}

const Speed & Simulator::GetTargetSpeed(){
	return targetSpeed;
}

void Simulator::Init(){
}

std::string Simulator::GetDebugInfo() {
	return "simulating wheels";
}

void Simulator::Run(){
	while (!stop_thread){
		UpdateRobotPos();
		std::this_thread::sleep_for(std::chrono::milliseconds(50));
	}
}<commit_msg>angles fixed<commit_after>#include "Simulator.h"
#include "DistanceCalculator.h"
#include <chrono>
#include <thread>
extern DistanceCalculator gDistanceCalculator;

Simulator::Simulator() :ThreadedClass("Simulator")
{
	self.fieldCoords = cv::Point(-100, 100);
	self.polarMetricCoords = cv::Point(0,0);
	// distribute balls uniformly
	for (int i = 0; i < NUMBER_OF_BALLS; i++) {
		balls[i].fieldCoords.x = ((i % 3) - 1) * 100;
		balls[i].fieldCoords.y = (i / 3 - 1.5) * 110;
		balls[i].id = i;
	}
	Start();
}
void Simulator::UpdateGatePos(){

	double a1 = gDistanceCalculator.angleBetween(cv::Point(0, 1), self.fieldCoords- blueGate.fieldCoords) + self.getAngle();
	double a2 = gDistanceCalculator.angleBetween(cv::Point(0, 1), self.fieldCoords - yellowGate.fieldCoords) + self.getAngle();

	double d1 = gDistanceCalculator.getDistanceInverted(self.fieldCoords, blueGate.fieldCoords);
	double d2 = gDistanceCalculator.getDistanceInverted(self.fieldCoords, yellowGate.fieldCoords);
	// draw gates
	frame_blank.copyTo(frame);
	double x1 = d1*sin(a1 / 180 * CV_PI);
	double y1 = d1*cos(a1 / 180 * CV_PI);
	double x2 = d2*sin(a2 / 180 * CV_PI);
	double y2 = d2*cos(a2 / 180 * CV_PI);

	cv::Scalar color(236, 137, 48);
	cv::Scalar color2(61, 255, 244);
	cv::circle(frame, cv::Point(x1, y1) + cv::Point(frame.size() / 2), 38, color, -1);
	cv::circle(frame, cv::Point(x2, y2) + cv::Point(frame.size() / 2), 38, color2, -1);

	// balls
	for (int i = 0; i < NUMBER_OF_BALLS; i++){
		double a = gDistanceCalculator.angleBetween(cv::Point(0, 1), self.fieldCoords - balls[i].fieldCoords) + self.getAngle();
		double d = gDistanceCalculator.getDistanceInverted(self.fieldCoords, balls[i].fieldCoords);
		double x = d*sin(a / 180 * CV_PI);
		double y = d*cos(a / 180 * CV_PI);
		cv::Scalar color(48, 154, 236);
		cv::circle(frame, cv::Point(x, y) + cv::Point(frame.size() / 2), 12, color, -1);
	}

	{
		std::lock_guard<std::mutex> lock(mutex);
		frame.copyTo(frame_copy);
	}

}

void Simulator::UpdateRobotPos(){
	UpdateGatePos();
}

Simulator::~Simulator()
{
	WaitForStop();
}

cv::Mat & Simulator::Capture(bool bFullFrame){
	return frame_copy;
}

cv::Size Simulator::GetFrameSize(bool bFullFrame){
	return frame.size();
}

double Simulator::GetFPS(){
	return 0;
}

cv::Mat & Simulator::GetLastFrame(bool bFullFrame){
	return frame;
}

void Simulator::TogglePlay(){
}

void Simulator::Drive(double fowardSpeed, double direction, double angularSpeed){
	self.polarMetricCoords.y += angularSpeed;
	self.fieldCoords.x += fowardSpeed * sin((direction - self.getAngle()) / 180 * CV_PI);
	self.fieldCoords.y += fowardSpeed * cos((direction - self.getAngle()) / 180 * CV_PI);
}

const Speed & Simulator::GetActualSpeed(){
	return actualSpeed;
}

const Speed & Simulator::GetTargetSpeed(){
	return targetSpeed;
}

void Simulator::Init(){
}

std::string Simulator::GetDebugInfo() {
	return "simulating wheels";
}

void Simulator::Run(){
	while (!stop_thread){
		UpdateRobotPos();
		std::this_thread::sleep_for(std::chrono::milliseconds(50));
	}
}<|endoftext|>


<commit_before>#include <stdafx.h>

#include <playfab/PlayFabCurlHttpPlugin.h>
#include <playfab/PlayFabSettings.h>
#include <curl/curl.h>

#include <stdexcept>

namespace PlayFab
{
    PlayFabCurlHttpPlugin::PlayFabCurlHttpPlugin()
    {
        activeRequestCount = 0;
        threadRunning = true;
        workerThread = std::thread(&PlayFabCurlHttpPlugin::WorkerThread, this);
    };

    PlayFabCurlHttpPlugin::~PlayFabCurlHttpPlugin()
    {
        threadRunning = false;
        try
        {
            workerThread.join();
        }
        catch (...)
        {
        }
    }

    void PlayFabCurlHttpPlugin::WorkerThread()
    {
        size_t queueSize;

        while (this->threadRunning)
        {
            try
            {
                std::unique_ptr<CallRequestContainerBase> requestContainer = nullptr;

                { // LOCK httpRequestMutex
                    std::unique_lock<std::mutex> lock(this->httpRequestMutex);

                    queueSize = this->pendingRequests.size();
                    if (queueSize != 0)
                    {
                        requestContainer = std::move(this->pendingRequests[0]);
                        this->pendingRequests.pop_front();
                    }
                } // UNLOCK httpRequestMutex

                if (queueSize == 0)
                {
                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
                    continue;
                }

                if (requestContainer != nullptr)
                {
                    CallRequestContainer* requestContainerPtr = dynamic_cast<CallRequestContainer*>(requestContainer.get());
                    if (requestContainerPtr != nullptr)
                    {
                        requestContainer.release();
                        ExecuteRequest(std::unique_ptr<CallRequestContainer>(requestContainerPtr));
                    }
                }
            }
            catch (const std::exception& ex)
            {
                PlayFabPluginManager::GetInstance().HandleException(ex);
            }
            catch (...)
            {

            }
        }
    }

    void PlayFabCurlHttpPlugin::HandleCallback(std::unique_ptr<CallRequestContainer> requestContainer)
    {
        CallRequestContainer& reqContainer = *requestContainer;
        reqContainer.finished = true;
        if (PlayFabSettings::threadedCallbacks)
        {
            HandleResults(std::move(requestContainer));
        }

        if (!PlayFabSettings::threadedCallbacks)
        {
            { // LOCK httpRequestMutex
                std::unique_lock<std::mutex> lock(httpRequestMutex);
                pendingResults.push_back(std::unique_ptr<CallRequestContainerBase>(static_cast<CallRequestContainerBase*>(requestContainer.release())));
            } // UNLOCK httpRequestMutex
        }
    }

    size_t PlayFabCurlHttpPlugin::CurlReceiveData(char* buffer, size_t blockSize, size_t blockCount, void* userData)
    {
        CallRequestContainer* reqContainer = reinterpret_cast<CallRequestContainer*>(userData);
        reqContainer->responseString.append(buffer, blockSize * blockCount);

        return (blockSize * blockCount);
    }

    void PlayFabCurlHttpPlugin::MakePostRequest(std::unique_ptr<CallRequestContainerBase> requestContainer)
    {
        { // LOCK httpRequestMutex
            std::unique_lock<std::mutex> lock(httpRequestMutex);
            pendingRequests.push_back(std::move(requestContainer));
            activeRequestCount++;
        } // UNLOCK httpRequestMutex
    }

    void PlayFabCurlHttpPlugin::ExecuteRequest(std::unique_ptr<CallRequestContainer> requestContainer)
    {
        CallRequestContainer& reqContainer = *requestContainer;

        // Set up curl handle
        CURL* curlHandle = curl_easy_init();
        curl_easy_reset(curlHandle);
        curl_easy_setopt(curlHandle, CURLOPT_NOSIGNAL, true);
        std::string urlString = reqContainer.GetFullUrl();
        curl_easy_setopt(curlHandle, CURLOPT_URL, urlString.c_str());

        // Set up headers
        curl_slist* curlHttpHeaders = nullptr;
        curlHttpHeaders = curl_slist_append(curlHttpHeaders, "Accept: application/json");
        curlHttpHeaders = curl_slist_append(curlHttpHeaders, "Content-Type: application/json; charset=utf-8");
        curlHttpHeaders = curl_slist_append(curlHttpHeaders, ("X-PlayFabSDK: " + PlayFabSettings::versionString).c_str());
        curlHttpHeaders = curl_slist_append(curlHttpHeaders, "X-ReportErrorAsSuccess: true");

        auto headers = reqContainer.GetHeaders();

        if (headers.size() > 0)
        {
            for (auto const &obj : headers)
            {
                if (obj.first.length() != 0 && obj.second.length() != 0) // no empty keys or values in headers
                {
                    std::string header = obj.first + ": " + obj.second;
                    curlHttpHeaders = curl_slist_append(curlHttpHeaders, header.c_str());
                }
            }
        }

        curl_easy_setopt(curlHandle, CURLOPT_HTTPHEADER, curlHttpHeaders);

        // Set up post & payload
        std::string payload = reqContainer.GetRequestBody();
        curl_easy_setopt(curlHandle, CURLOPT_POST, nullptr);
        curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDS, payload.c_str());

        // Process result
        // TODO: CURLOPT_ERRORBUFFER ?
        curl_easy_setopt(curlHandle, CURLOPT_TIMEOUT_MS, 10000L);
        curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, &reqContainer);
        curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, CurlReceiveData);

        // Send
        curl_easy_setopt(curlHandle, CURLOPT_SSL_VERIFYPEER, false); // TODO: Replace this with a ca-bundle ref???
        const auto res = curl_easy_perform(curlHandle);
        long curlHttpResponseCode = 0;
        curl_easy_getinfo(curlHandle, CURLINFO_RESPONSE_CODE, &curlHttpResponseCode);

        if (res != CURLE_OK)
        {
            reqContainer.errorWrapper.HttpCode = curlHttpResponseCode != 0 ? curlHttpResponseCode : 408;
            reqContainer.errorWrapper.HttpStatus = "Failed to contact server";
            reqContainer.errorWrapper.ErrorCode = PlayFabErrorConnectionTimeout;
            reqContainer.errorWrapper.ErrorName = "Failed to contact server";
            reqContainer.errorWrapper.ErrorMessage = "Failed to contact server, curl error: " + std::to_string(res);
            HandleCallback(std::move(requestContainer));
        }
        else
        {
            Json::CharReaderBuilder jsonReaderFactory;
            std::unique_ptr<Json::CharReader> jsonReader(jsonReaderFactory.newCharReader());
            JSONCPP_STRING jsonParseErrors;
            const bool parsedSuccessfully = jsonReader->parse(reqContainer.responseString.c_str(), reqContainer.responseString.c_str() + reqContainer.responseString.length(), &reqContainer.responseJson, &jsonParseErrors);

            if (parsedSuccessfully)
            {
                reqContainer.errorWrapper.HttpCode = reqContainer.responseJson.get("code", Json::Value::null).asInt();
                reqContainer.errorWrapper.HttpStatus = reqContainer.responseJson.get("status", Json::Value::null).asString();
                reqContainer.errorWrapper.Data = reqContainer.responseJson.get("data", Json::Value::null);
                reqContainer.errorWrapper.ErrorName = reqContainer.responseJson.get("error", Json::Value::null).asString();
                reqContainer.errorWrapper.ErrorCode = static_cast<PlayFabErrorCode>(reqContainer.responseJson.get("errorCode", Json::Value::null).asInt());
                reqContainer.errorWrapper.ErrorMessage = reqContainer.responseJson.get("errorMessage", Json::Value::null).asString();
                reqContainer.errorWrapper.ErrorDetails = reqContainer.responseJson.get("errorDetails", Json::Value::null);
            }
            else
            {
                reqContainer.errorWrapper.HttpCode = curlHttpResponseCode != 0 ? curlHttpResponseCode : 408;
                reqContainer.errorWrapper.HttpStatus = reqContainer.responseString;
                reqContainer.errorWrapper.ErrorCode = PlayFabErrorConnectionTimeout;
                reqContainer.errorWrapper.ErrorName = "Failed to parse PlayFab response";
                reqContainer.errorWrapper.ErrorMessage = jsonParseErrors;
            }

            HandleCallback(std::move(requestContainer));
        }

        curl_slist_free_all(curlHttpHeaders);
        curlHttpHeaders = nullptr;
        curl_easy_cleanup(curlHandle);
    }

    void PlayFabCurlHttpPlugin::HandleResults(std::unique_ptr<CallRequestContainer> requestContainer)
    {
        CallRequestContainer& reqContainer = *requestContainer;
        auto callback = reqContainer.GetCallback();
        if (callback != nullptr)
        {
            callback(
                reqContainer.responseJson.get("code", Json::Value::null).asInt(),
                reqContainer.responseString,
                std::unique_ptr<CallRequestContainerBase>(static_cast<CallRequestContainerBase*>(requestContainer.release())));
        }
    }

    size_t PlayFabCurlHttpPlugin::Update()
    {
        if (PlayFabSettings::threadedCallbacks)
        {
            throw std::runtime_error("You should not call Update() when PlayFabSettings::threadedCallbacks == true");
        }

        std::unique_ptr<CallRequestContainerBase> requestContainer = nullptr;
        { // LOCK httpRequestMutex
            std::unique_lock<std::mutex> lock(httpRequestMutex);
            if (pendingResults.empty())
            {
                return activeRequestCount;
            }

            requestContainer = std::move(this->pendingResults[0]);
            this->pendingResults.pop_front();
            activeRequestCount--;
        } // UNLOCK httpRequestMutex

        HandleResults(std::unique_ptr<CallRequestContainer>(static_cast<CallRequestContainer*>(requestContainer.release())));

        // activeRequestCount can be altered by HandleResults, so we have to re-lock and return an updated value
        { // LOCK httpRequestMutex
            std::unique_lock<std::mutex> lock(httpRequestMutex);
            return activeRequestCount;
        }
    }
}
<commit_msg>Bug fix: Curl Http plugin is disabling CURLOPT_SSL_VERIFYPEER (#553)<commit_after>#include <stdafx.h>

#include <playfab/PlayFabCurlHttpPlugin.h>
#include <playfab/PlayFabSettings.h>
#include <curl/curl.h>

#include <stdexcept>

namespace PlayFab
{
    PlayFabCurlHttpPlugin::PlayFabCurlHttpPlugin()
    {
        activeRequestCount = 0;
        threadRunning = true;
        workerThread = std::thread(&PlayFabCurlHttpPlugin::WorkerThread, this);
    };

    PlayFabCurlHttpPlugin::~PlayFabCurlHttpPlugin()
    {
        threadRunning = false;
        try
        {
            workerThread.join();
        }
        catch (...)
        {
        }
    }

    void PlayFabCurlHttpPlugin::WorkerThread()
    {
        size_t queueSize;

        while (this->threadRunning)
        {
            try
            {
                std::unique_ptr<CallRequestContainerBase> requestContainer = nullptr;

                { // LOCK httpRequestMutex
                    std::unique_lock<std::mutex> lock(this->httpRequestMutex);

                    queueSize = this->pendingRequests.size();
                    if (queueSize != 0)
                    {
                        requestContainer = std::move(this->pendingRequests[0]);
                        this->pendingRequests.pop_front();
                    }
                } // UNLOCK httpRequestMutex

                if (queueSize == 0)
                {
                    std::this_thread::sleep_for(std::chrono::milliseconds(10));
                    continue;
                }

                if (requestContainer != nullptr)
                {
                    CallRequestContainer* requestContainerPtr = dynamic_cast<CallRequestContainer*>(requestContainer.get());
                    if (requestContainerPtr != nullptr)
                    {
                        requestContainer.release();
                        ExecuteRequest(std::unique_ptr<CallRequestContainer>(requestContainerPtr));
                    }
                }
            }
            catch (const std::exception& ex)
            {
                PlayFabPluginManager::GetInstance().HandleException(ex);
            }
            catch (...)
            {

            }
        }
    }

    void PlayFabCurlHttpPlugin::HandleCallback(std::unique_ptr<CallRequestContainer> requestContainer)
    {
        CallRequestContainer& reqContainer = *requestContainer;
        reqContainer.finished = true;
        if (PlayFabSettings::threadedCallbacks)
        {
            HandleResults(std::move(requestContainer));
        }

        if (!PlayFabSettings::threadedCallbacks)
        {
            { // LOCK httpRequestMutex
                std::unique_lock<std::mutex> lock(httpRequestMutex);
                pendingResults.push_back(std::unique_ptr<CallRequestContainerBase>(static_cast<CallRequestContainerBase*>(requestContainer.release())));
            } // UNLOCK httpRequestMutex
        }
    }

    size_t PlayFabCurlHttpPlugin::CurlReceiveData(char* buffer, size_t blockSize, size_t blockCount, void* userData)
    {
        CallRequestContainer* reqContainer = reinterpret_cast<CallRequestContainer*>(userData);
        reqContainer->responseString.append(buffer, blockSize * blockCount);

        return (blockSize * blockCount);
    }

    void PlayFabCurlHttpPlugin::MakePostRequest(std::unique_ptr<CallRequestContainerBase> requestContainer)
    {
        { // LOCK httpRequestMutex
            std::unique_lock<std::mutex> lock(httpRequestMutex);
            pendingRequests.push_back(std::move(requestContainer));
            activeRequestCount++;
        } // UNLOCK httpRequestMutex
    }

    void PlayFabCurlHttpPlugin::ExecuteRequest(std::unique_ptr<CallRequestContainer> requestContainer)
    {
        CallRequestContainer& reqContainer = *requestContainer;

        // Set up curl handle
        CURL* curlHandle = curl_easy_init();
        curl_easy_reset(curlHandle);
        curl_easy_setopt(curlHandle, CURLOPT_NOSIGNAL, true);
        std::string urlString = reqContainer.GetFullUrl();
        curl_easy_setopt(curlHandle, CURLOPT_URL, urlString.c_str());

        // Set up headers
        curl_slist* curlHttpHeaders = nullptr;
        curlHttpHeaders = curl_slist_append(curlHttpHeaders, "Accept: application/json");
        curlHttpHeaders = curl_slist_append(curlHttpHeaders, "Content-Type: application/json; charset=utf-8");
        curlHttpHeaders = curl_slist_append(curlHttpHeaders, ("X-PlayFabSDK: " + PlayFabSettings::versionString).c_str());
        curlHttpHeaders = curl_slist_append(curlHttpHeaders, "X-ReportErrorAsSuccess: true");

        auto headers = reqContainer.GetHeaders();

        if (headers.size() > 0)
        {
            for (auto const &obj : headers)
            {
                if (obj.first.length() != 0 && obj.second.length() != 0) // no empty keys or values in headers
                {
                    std::string header = obj.first + ": " + obj.second;
                    curlHttpHeaders = curl_slist_append(curlHttpHeaders, header.c_str());
                }
            }
        }

        curl_easy_setopt(curlHandle, CURLOPT_HTTPHEADER, curlHttpHeaders);

        // Set up post & payload
        std::string payload = reqContainer.GetRequestBody();
        curl_easy_setopt(curlHandle, CURLOPT_POST, nullptr);
        curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDS, payload.c_str());

        // Process result
        // TODO: CURLOPT_ERRORBUFFER ?
        curl_easy_setopt(curlHandle, CURLOPT_TIMEOUT_MS, 10000L);
        curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, &reqContainer);
        curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, CurlReceiveData);

        // Send
        curl_easy_setopt(curlHandle, CURLOPT_SSL_VERIFYPEER, true);
        const auto res = curl_easy_perform(curlHandle);
        long curlHttpResponseCode = 0;
        curl_easy_getinfo(curlHandle, CURLINFO_RESPONSE_CODE, &curlHttpResponseCode);

        if (res != CURLE_OK)
        {
            reqContainer.errorWrapper.HttpCode = curlHttpResponseCode != 0 ? curlHttpResponseCode : 408;
            reqContainer.errorWrapper.HttpStatus = "Failed to contact server";
            reqContainer.errorWrapper.ErrorCode = PlayFabErrorConnectionTimeout;
            reqContainer.errorWrapper.ErrorName = "Failed to contact server";
            reqContainer.errorWrapper.ErrorMessage = "Failed to contact server, curl error: " + std::to_string(res);
            HandleCallback(std::move(requestContainer));
        }
        else
        {
            Json::CharReaderBuilder jsonReaderFactory;
            std::unique_ptr<Json::CharReader> jsonReader(jsonReaderFactory.newCharReader());
            JSONCPP_STRING jsonParseErrors;
            const bool parsedSuccessfully = jsonReader->parse(reqContainer.responseString.c_str(), reqContainer.responseString.c_str() + reqContainer.responseString.length(), &reqContainer.responseJson, &jsonParseErrors);

            if (parsedSuccessfully)
            {
                reqContainer.errorWrapper.HttpCode = reqContainer.responseJson.get("code", Json::Value::null).asInt();
                reqContainer.errorWrapper.HttpStatus = reqContainer.responseJson.get("status", Json::Value::null).asString();
                reqContainer.errorWrapper.Data = reqContainer.responseJson.get("data", Json::Value::null);
                reqContainer.errorWrapper.ErrorName = reqContainer.responseJson.get("error", Json::Value::null).asString();
                reqContainer.errorWrapper.ErrorCode = static_cast<PlayFabErrorCode>(reqContainer.responseJson.get("errorCode", Json::Value::null).asInt());
                reqContainer.errorWrapper.ErrorMessage = reqContainer.responseJson.get("errorMessage", Json::Value::null).asString();
                reqContainer.errorWrapper.ErrorDetails = reqContainer.responseJson.get("errorDetails", Json::Value::null);
            }
            else
            {
                reqContainer.errorWrapper.HttpCode = curlHttpResponseCode != 0 ? curlHttpResponseCode : 408;
                reqContainer.errorWrapper.HttpStatus = reqContainer.responseString;
                reqContainer.errorWrapper.ErrorCode = PlayFabErrorConnectionTimeout;
                reqContainer.errorWrapper.ErrorName = "Failed to parse PlayFab response";
                reqContainer.errorWrapper.ErrorMessage = jsonParseErrors;
            }

            HandleCallback(std::move(requestContainer));
        }

        curl_slist_free_all(curlHttpHeaders);
        curlHttpHeaders = nullptr;
        curl_easy_cleanup(curlHandle);
    }

    void PlayFabCurlHttpPlugin::HandleResults(std::unique_ptr<CallRequestContainer> requestContainer)
    {
        CallRequestContainer& reqContainer = *requestContainer;
        auto callback = reqContainer.GetCallback();
        if (callback != nullptr)
        {
            callback(
                reqContainer.responseJson.get("code", Json::Value::null).asInt(),
                reqContainer.responseString,
                std::unique_ptr<CallRequestContainerBase>(static_cast<CallRequestContainerBase*>(requestContainer.release())));
        }
    }

    size_t PlayFabCurlHttpPlugin::Update()
    {
        if (PlayFabSettings::threadedCallbacks)
        {
            throw std::runtime_error("You should not call Update() when PlayFabSettings::threadedCallbacks == true");
        }

        std::unique_ptr<CallRequestContainerBase> requestContainer = nullptr;
        { // LOCK httpRequestMutex
            std::unique_lock<std::mutex> lock(httpRequestMutex);
            if (pendingResults.empty())
            {
                return activeRequestCount;
            }

            requestContainer = std::move(this->pendingResults[0]);
            this->pendingResults.pop_front();
            activeRequestCount--;
        } // UNLOCK httpRequestMutex

        HandleResults(std::unique_ptr<CallRequestContainer>(static_cast<CallRequestContainer*>(requestContainer.release())));

        // activeRequestCount can be altered by HandleResults, so we have to re-lock and return an updated value
        { // LOCK httpRequestMutex
            std::unique_lock<std::mutex> lock(httpRequestMutex);
            return activeRequestCount;
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// 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.

#ifndef TEST_ARRAY_GENERATOR_HPP_
#define TEST_ARRAY_GENERATOR_HPP_

#include <climits>
#include <random>
#include <string>
#include <type_traits>

/**
 * Helper function to generate a test pattern for boolean type.
 * Alternating true (even index) and false (odd index) pattern.
 * @param C Container (vector, array, etc) to be filled
 * @param size How many elements to fill in. Must size<=container_size
 */
template<
  typename C,
  typename std::enable_if<
    std::is_same<typename C::value_type, bool>::value
  >::type * = nullptr
>
void test_vector_fill(C * container, size_t size, bool val1 = true,
  bool val2 = false)
{
  for (size_t i = 0; i < size; i++) {
    if ((i % 2) == 0) {
      (*container)[i] = val2;
    } else {
      (*container)[i] = val1;
    }
  }
}

/**
 * Helper function to generate a test pattern for integer number types.
 * The template type parameter must be an integer number type.
 * Mininum and maximum values for the type and random values in the middle.
 * @param C Container (vector, array, etc) to be filled
 * @param size How many elements to fill in. Must size<=container_size
 * @param min Minimum value in the range to fill.
 * @param max Maximum value in the range to fill.
 */
template<
  typename C,
  typename std::enable_if<
    std::is_integral<typename C::value_type>::value &&
    !std::is_same<typename C::value_type, bool>::value &&
    !std::is_same<typename C::value_type, char>::value &&
    !std::is_same<typename C::value_type, int8_t>::value &&
    !std::is_same<typename C::value_type, uint8_t>::value
  >::type * = nullptr
>
void test_vector_fill(C * container, size_t size,
  typename C::value_type min, typename C::value_type max)
{
  std::default_random_engine rand_generator;
  std::uniform_int_distribution<typename C::value_type> randnum(min, max);

  if (size > 0) {
    (*container)[0] = min;
    for (size_t i = 1; i < size - 1; i++) {
      (*container)[i] = randnum(rand_generator);
    }
    (*container)[size - 1] = max;
  }
}

/**
 * Helper function to generate a test pattern for char type and derivatives.
 * Note: this is necessary because uniform_int_distribution is not defined for
 * char type.
 * Mininum and maximum values for the type and random values in the middle.
 * @param C Container (vector, array, etc) to be filled
 * @param size How many elements to fill in. Must size<=container_size
 * @param min Minimum value in the range to fill.
 * @param max Maximum value in the range to fill.
 */
template<
  typename C,
  typename std::enable_if<
    std::is_same<typename C::value_type, char>::value ||
    std::is_same<typename C::value_type, int8_t>::value ||
    std::is_same<typename C::value_type, uint8_t>::value
  >::type * = nullptr
>
void test_vector_fill(C * container, size_t size,
  typename C::value_type min, typename C::value_type max)
{
  std::default_random_engine rand_generator;
  std::uniform_int_distribution<int> randnum(static_cast<int>(min), static_cast<int>(max));

  if (size > 0) {
    (*container)[0] = min;
    for (size_t i = 1; i < size - 1; i++) {
      (*container)[i] = static_cast<typename C::value_type>(randnum(rand_generator));
    }
    (*container)[size - 1] = max;
  }
}

/**
 * Helper function to generate a test pattern for float number types.
 * Mininum and maximum values for the type and random numbers in the middle.
 * @param C Container (vector, array, etc) to be filled
 * @param size How many elements to fill in. Must size<=container_size
 * @param min Minimum value in the range to fill.
 * @param max Maximum value in the range to fill.
 */
template<
  typename C,
  typename std::enable_if<
    std::is_floating_point<typename C::value_type>::value
  >::type * = nullptr
>
void test_vector_fill(C * container, size_t size,
  typename C::value_type min, typename C::value_type max)
{
  std::default_random_engine rand_generator;
  std::uniform_real_distribution<typename C::value_type> randnum(min, max);

  if (size > 0) {
    (*container)[0] = min;
    for (size_t i = 1; i < size - 1; i++) {
      (*container)[i] = randnum(rand_generator);
    }
    (*container)[size - 1] = max;
  }
}

/**
 * Helper function to generate a test pattern for string types.
 * Mininum and maximum values for the type and random numbers in the middle.
 * @param C Container (vector, array, etc) to be filled
 * @param size How many elements to fill in. Must size<=container_size
 * @param min Minimum value in the range to fill.
 * @param max Maximum value in the range to fill.
 * @param minlength Minimum length of the generated strings.
 * @param maxlength Maximum length of the generated strings.
 */
template<
  typename C,
  typename std::enable_if<
    std::is_same<typename C::value_type, typename std::string>::value
  >::type * = nullptr
>
void test_vector_fill(C * container, size_t size,
  int min, int max,
  int minlength, const int maxlength)
{
  std::default_random_engine rand_generator;
  std::uniform_int_distribution<int> randnum(min, max);
  std::uniform_int_distribution<int> randlen(minlength, maxlength);

  if (size > 0) {
    char * tmpstr = reinterpret_cast<char *>(malloc(maxlength));
    std::snprintf(tmpstr, minlength, "%*d", minlength, min);
    (*container)[0] = std::string(tmpstr);
    for (size_t i = 1; i < size - 1; i++) {
      int length = randlen(rand_generator);
      std::snprintf(tmpstr, length, "%*d", length, randnum(rand_generator));
      (*container)[i] = std::string(tmpstr);
    }
    std::snprintf(tmpstr, maxlength, "%*d", maxlength, max);
    (*container)[size - 1] = std::string(tmpstr);
  }
}

#endif  // TEST_ARRAY_GENERATOR_HPP_
<commit_msg>[rosidl_generator_cpp] Deterministic testing (#184)<commit_after>// Copyright 2015 Open Source Robotics Foundation, Inc.
//
// 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.

#ifndef TEST_ARRAY_GENERATOR_HPP_
#define TEST_ARRAY_GENERATOR_HPP_

#include <climits>
#include <random>
#include <string>
#include <type_traits>

/**
 * Helper function to generate a test pattern for boolean type.
 * Alternating true (even index) and false (odd index) pattern.
 * @param C Container (vector, array, etc) to be filled
 * @param size How many elements to fill in. Must size<=container_size
 */
template<
  typename C,
  typename std::enable_if<
    std::is_same<typename C::value_type, bool>::value
  >::type * = nullptr
>
void test_vector_fill(C * container, size_t size, bool val1 = true,
  bool val2 = false)
{
  for (size_t i = 0; i < size; i++) {
    if ((i % 2) == 0) {
      (*container)[i] = val2;
    } else {
      (*container)[i] = val1;
    }
  }
}

/**
 * Helper function to generate a test pattern for integer number types.
 * The template type parameter must be an integer number type.
 * Mininum and maximum values for the type and distributed values in the middle.
 * @param C Container (vector, array, etc) to be filled
 * @param size How many elements to fill in. Must size<=container_size
 * @param min Minimum value in the range to fill.
 * @param max Maximum value in the range to fill.
 */
template<
  typename C,
  typename std::enable_if<
    std::is_integral<typename C::value_type>::value &&
    !std::is_same<typename C::value_type, bool>::value
  >::type * = nullptr
>
void test_vector_fill(C * container, size_t size,
  typename C::value_type min, typename C::value_type max)
{
  if (size > 0 && min != max) {
    typename C::value_type step = (max - min) / size;
    (*container)[0] = min;
    for (size_t i = 1; i < size - 1; i++) {
      (*container)[i] = min + i * step;
    }
    (*container)[size - 1] = max;
  }
}

/**
 * Helper function to generate a test pattern for float number types.
 * Mininum and maximum values for the type and distributed values in the middle.
 * @param C Container (vector, array, etc) to be filled
 * @param size How many elements to fill in. Must size<=container_size
 * @param min Minimum value in the range to fill.
 * @param max Maximum value in the range to fill.
 */
template<
  typename C,
  typename std::enable_if<
    std::is_floating_point<typename C::value_type>::value
  >::type * = nullptr
>
void test_vector_fill(C * container, size_t size,
  typename C::value_type min, typename C::value_type max)
{
  if (size > 0 && min != max) {
    typename C::value_type step = (max - min) / size;
    (*container)[0] = min;
    for (size_t i = 1; i < size - 1; i++) {
      (*container)[i] = min + i * step;
    }
    (*container)[size - 1] = max;
  }
}

/**
 * Helper function to generate a test pattern for string types.
 * Mininum and maximum values for the type and distributed values in the middle.
 * @param C Container (vector, array, etc) to be filled
 * @param size How many elements to fill in. Must size<=container_size
 * @param min Minimum value in the range to fill.
 * @param max Maximum value in the range to fill.
 * @param minlength Minimum length of the generated strings.
 * @param maxlength Maximum length of the generated strings.
 */
template<
  typename C,
  typename std::enable_if<
    std::is_same<typename C::value_type, typename std::string>::value
  >::type * = nullptr
>
void test_vector_fill(C * container, size_t size,
  int min, int max,
  int minlength, const int maxlength)
{
  if (size > 0 && min != max && minlength != maxlength) {
    int step = (max - min) / size;
    int step_length = (maxlength - minlength) / size;
    char * tmpstr = reinterpret_cast<char *>(malloc(maxlength));
    std::snprintf(tmpstr, minlength, "%*d", minlength, min);
    (*container)[0] = std::string(tmpstr);
    for (size_t i = 1; i < size - 1; i++) {
      int value = min + i * step;
      int length = minlength + i * step_length;
      std::snprintf(tmpstr, length, "%*d", length, value);
      (*container)[i] = std::string(tmpstr);
    }
    std::snprintf(tmpstr, maxlength, "%*d", maxlength, max);
    (*container)[size - 1] = std::string(tmpstr);
  }
}

#endif  // TEST_ARRAY_GENERATOR_HPP_
<|endoftext|>


<commit_before>#ifdef WITH_BASISU

#define BASISU_NO_ITERATOR_DEBUG_LEVEL

#ifdef __clang__
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#endif

#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#pragma GCC diagnostic ignored "-Wunused-value"
#endif

#include "encoder/basisu_comp.h"

#include "gltfpack.h"

struct BasisSettings
{
	int etc1s_l;
	int etc1s_q;
	int uastc_l;
	float uastc_q;
};

static const BasisSettings kBasisSettings[10] = {
    {1, 1, 0, 1.5f},
    {1, 6, 0, 1.f},
    {1, 20, 1, 1.0f},
    {1, 50, 1, 0.75f},
    {1, 90, 1, 0.5f},
    {1, 128, 1, 0.4f},
    {1, 160, 1, 0.34f},
    {1, 192, 1, 0.29f}, // default
    {1, 224, 2, 0.26f},
    {1, 255, 2, 0.f},
};

static std::unique_ptr<basisu::job_pool> gJobPool;

void encodeInit(int jobs)
{
	using namespace basisu;

	basisu_encoder_init();

	uint32_t num_threads = jobs == 0 ? std::thread::hardware_concurrency() : jobs;

	gJobPool.reset(new job_pool(num_threads));
}

static bool encodeInternal(const char* input, const char* output, bool yflip, bool normal_map, bool linear, bool uastc, int uastc_l, float uastc_q, int etc1s_l, int etc1s_q, int zstd_l, int width, int height)
{
	using namespace basisu;

	basis_compressor_params params;

	params.m_multithreading = gJobPool->get_total_threads() > 1;
	params.m_pJob_pool = gJobPool.get();

	if (uastc)
	{
		static const uint32_t s_level_flags[TOTAL_PACK_UASTC_LEVELS] = {cPackUASTCLevelFastest, cPackUASTCLevelFaster, cPackUASTCLevelDefault, cPackUASTCLevelSlower, cPackUASTCLevelVerySlow};

		params.m_uastc = true;

		params.m_pack_uastc_flags &= ~cPackUASTCLevelMask;
		params.m_pack_uastc_flags |= s_level_flags[uastc_l];

		params.m_rdo_uastc = uastc_q > 0;
		params.m_rdo_uastc_quality_scalar = uastc_q;
		params.m_rdo_uastc_dict_size = 1024;
	}
	else
	{
		params.m_compression_level = etc1s_l;
		params.m_quality_level = etc1s_q;
		params.m_max_endpoint_clusters = 0;
		params.m_max_selector_clusters = 0;

		params.m_no_selector_rdo = normal_map;
		params.m_no_endpoint_rdo = normal_map;
	}

	params.m_perceptual = !linear;

	params.m_mip_gen = true;
	params.m_mip_srgb = !linear;

	params.m_resample_width = width;
	params.m_resample_height = height;

	params.m_y_flip = yflip;

	params.m_create_ktx2_file = true;
	params.m_ktx2_srgb_transfer_func = !linear;

	if (zstd_l)
	{
		params.m_ktx2_uastc_supercompression = basist::KTX2_SS_ZSTANDARD;
		params.m_ktx2_zstd_supercompression_level = zstd_l;
	}

	params.m_read_source_images = true;
	params.m_write_output_basis_files = true;

	params.m_source_filenames.resize(1);
	params.m_source_filenames[0] = input;

	params.m_out_filename = output;

	params.m_status_output = false;

	basis_compressor c;

	if (!c.init(params))
		return false;

	return c.process() == basis_compressor::cECSuccess;
}

static const char* encodeImage(const std::string& data, const char* mime_type, std::string& result, const ImageInfo& info, const Settings& settings)
{
	TempFile temp_input(mimeExtension(mime_type));
	TempFile temp_output(".ktx2");

	if (!writeFile(temp_input.path.c_str(), data))
		return "error writing temporary file";

	int quality = settings.texture_quality[info.kind];
	bool uastc = settings.texture_mode[info.kind] == TextureMode_UASTC;

	const BasisSettings& bs = kBasisSettings[quality - 1];

	int width = 0, height = 0;
	if (!getDimensions(data, mime_type, width, height))
		return "error parsing image header";

	adjustDimensions(width, height, settings);

	int zstd = uastc ? 9 : 0;

	if (!encodeInternal(temp_input.path.c_str(), temp_output.path.c_str(), settings.texture_flipy, info.normal_map, !info.srgb, uastc, bs.uastc_l, bs.uastc_q, bs.etc1s_l, bs.etc1s_q, zstd, width, height))
		return "error encoding image";

	if (!readFile(temp_output.path.c_str(), result))
		return "error reading temporary file";

	return nullptr;
}

void encodeImages(std::string* encoded, const cgltf_data* data, const std::vector<ImageInfo>& images, const char* input_path, const Settings& settings)
{
	assert(gJobPool);

	for (size_t i = 0; i < data->images_count; ++i)
	{
		const cgltf_image& image = data->images[i];
		ImageInfo info = images[i];

		if (settings.texture_mode[info.kind] == TextureMode_Raw)
			continue;

		gJobPool->add_job([=]() {
			std::string img_data;
			std::string mime_type;
			std::string result;

			if (!readImage(image, input_path, img_data, mime_type))
				encoded[i] = "error reading source file";
			else if (const char* error = encodeImage(img_data, mime_type.c_str(), result, info, settings))
				encoded[i] = error;
			else
				encoded[i].swap(result);
		}, nullptr); // explicitly pass token to make sure we're using thread-safe job_pool implementation
	}

	gJobPool->wait_for_all();
}
#endif
<commit_msg>gltfpack: Initialize interval_timer globals early<commit_after>#ifdef WITH_BASISU

#define BASISU_NO_ITERATOR_DEBUG_LEVEL

#ifdef __clang__
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
#endif

#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#pragma GCC diagnostic ignored "-Wunused-value"
#endif

#include "encoder/basisu_comp.h"

#include "gltfpack.h"

struct BasisSettings
{
	int etc1s_l;
	int etc1s_q;
	int uastc_l;
	float uastc_q;
};

static const BasisSettings kBasisSettings[10] = {
    {1, 1, 0, 1.5f},
    {1, 6, 0, 1.f},
    {1, 20, 1, 1.0f},
    {1, 50, 1, 0.75f},
    {1, 90, 1, 0.5f},
    {1, 128, 1, 0.4f},
    {1, 160, 1, 0.34f},
    {1, 192, 1, 0.29f}, // default
    {1, 224, 2, 0.26f},
    {1, 255, 2, 0.f},
};

static std::unique_ptr<basisu::job_pool> gJobPool;

void encodeInit(int jobs)
{
	using namespace basisu;

	basisu_encoder_init();

	uint32_t num_threads = jobs == 0 ? std::thread::hardware_concurrency() : jobs;

	gJobPool.reset(new job_pool(num_threads));

	interval_timer::init(); // make sure interval_timer globals are initialized from main thread
}

static bool encodeInternal(const char* input, const char* output, bool yflip, bool normal_map, bool linear, bool uastc, int uastc_l, float uastc_q, int etc1s_l, int etc1s_q, int zstd_l, int width, int height)
{
	using namespace basisu;

	basis_compressor_params params;

	params.m_multithreading = gJobPool->get_total_threads() > 1;
	params.m_pJob_pool = gJobPool.get();

	if (uastc)
	{
		static const uint32_t s_level_flags[TOTAL_PACK_UASTC_LEVELS] = {cPackUASTCLevelFastest, cPackUASTCLevelFaster, cPackUASTCLevelDefault, cPackUASTCLevelSlower, cPackUASTCLevelVerySlow};

		params.m_uastc = true;

		params.m_pack_uastc_flags &= ~cPackUASTCLevelMask;
		params.m_pack_uastc_flags |= s_level_flags[uastc_l];

		params.m_rdo_uastc = uastc_q > 0;
		params.m_rdo_uastc_quality_scalar = uastc_q;
		params.m_rdo_uastc_dict_size = 1024;
	}
	else
	{
		params.m_compression_level = etc1s_l;
		params.m_quality_level = etc1s_q;
		params.m_max_endpoint_clusters = 0;
		params.m_max_selector_clusters = 0;

		params.m_no_selector_rdo = normal_map;
		params.m_no_endpoint_rdo = normal_map;
	}

	params.m_perceptual = !linear;

	params.m_mip_gen = true;
	params.m_mip_srgb = !linear;

	params.m_resample_width = width;
	params.m_resample_height = height;

	params.m_y_flip = yflip;

	params.m_create_ktx2_file = true;
	params.m_ktx2_srgb_transfer_func = !linear;

	if (zstd_l)
	{
		params.m_ktx2_uastc_supercompression = basist::KTX2_SS_ZSTANDARD;
		params.m_ktx2_zstd_supercompression_level = zstd_l;
	}

	params.m_read_source_images = true;
	params.m_write_output_basis_files = true;

	params.m_source_filenames.resize(1);
	params.m_source_filenames[0] = input;

	params.m_out_filename = output;

	params.m_status_output = false;

	basis_compressor c;

	if (!c.init(params))
		return false;

	return c.process() == basis_compressor::cECSuccess;
}

static const char* encodeImage(const std::string& data, const char* mime_type, std::string& result, const ImageInfo& info, const Settings& settings)
{
	TempFile temp_input(mimeExtension(mime_type));
	TempFile temp_output(".ktx2");

	if (!writeFile(temp_input.path.c_str(), data))
		return "error writing temporary file";

	int quality = settings.texture_quality[info.kind];
	bool uastc = settings.texture_mode[info.kind] == TextureMode_UASTC;

	const BasisSettings& bs = kBasisSettings[quality - 1];

	int width = 0, height = 0;
	if (!getDimensions(data, mime_type, width, height))
		return "error parsing image header";

	adjustDimensions(width, height, settings);

	int zstd = uastc ? 9 : 0;

	if (!encodeInternal(temp_input.path.c_str(), temp_output.path.c_str(), settings.texture_flipy, info.normal_map, !info.srgb, uastc, bs.uastc_l, bs.uastc_q, bs.etc1s_l, bs.etc1s_q, zstd, width, height))
		return "error encoding image";

	if (!readFile(temp_output.path.c_str(), result))
		return "error reading temporary file";

	return nullptr;
}

void encodeImages(std::string* encoded, const cgltf_data* data, const std::vector<ImageInfo>& images, const char* input_path, const Settings& settings)
{
	assert(gJobPool);

	for (size_t i = 0; i < data->images_count; ++i)
	{
		const cgltf_image& image = data->images[i];
		ImageInfo info = images[i];

		if (settings.texture_mode[info.kind] == TextureMode_Raw)
			continue;

		gJobPool->add_job([=]() {
			std::string img_data;
			std::string mime_type;
			std::string result;

			if (!readImage(image, input_path, img_data, mime_type))
				encoded[i] = "error reading source file";
			else if (const char* error = encodeImage(img_data, mime_type.c_str(), result, info, settings))
				encoded[i] = error;
			else
				encoded[i].swap(result);
		}, nullptr); // explicitly pass token to make sure we're using thread-safe job_pool implementation
	}

	gJobPool->wait_for_all();
}
#endif
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

class ImageBlurer {
public:
  ImageBlurer();
  void blur_image(const sensor_msgs::ImageConstPtr& msg);
private:
  ros::NodeHandle nh_;
  ros::NodeHandle pnh_;
  image_transport::ImageTransport it_;
  image_transport::ImageTransport pit_;
  image_transport::Subscriber image_sub_;
  image_transport::Publisher image_pub_;
};

ImageBlurer::ImageBlurer()
  : nh_{},
    pnh_{"~"},
    it_{nh_},
    pit_{pnh_},
    image_sub_{it_.subscribe("src_image", 1, &ImageBlurer::blur_image, this)},
    image_pub_{pit_.advertise("dest_image", 1)}
{
}

void ImageBlurer::blur_image(const sensor_msgs::ImageConstPtr& msg)
{
  try {
    cv::Mat dest_image;
    cv::blur(cv_bridge::CvImagePtr{cv_bridge::toCvShare(msg, sensor_msgs::image_encodings::BGR8)}->image, dest_image, cv::Size(2, 100));
    image_pub_.publish(cv_bridge::CvImage{std_msgs::Header{}, "bgr8", dest_image}.toImageMsg());
  }
  catch (cv_bridge::Exception& e) {
    ROS_ERROR_STREAM("cv_bridge exception: " << e.what());
  }
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_blurer");
  ImageBlurer ib{};
  ros::spin();
  return 0;
}
<commit_msg>Avoid to make extra rvalue<commit_after>#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

class ImageBlurer {
public:
  ImageBlurer();
  void blur_image(const sensor_msgs::ImageConstPtr& msg);
private:
  ros::NodeHandle nh_;
  ros::NodeHandle pnh_;
  image_transport::ImageTransport it_;
  image_transport::ImageTransport pit_;
  image_transport::Subscriber image_sub_;
  image_transport::Publisher image_pub_;
};

ImageBlurer::ImageBlurer()
  : nh_{},
    pnh_{"~"},
    it_{nh_},
    pit_{pnh_},
    image_sub_{it_.subscribe("src_image", 1, &ImageBlurer::blur_image, this)},
    image_pub_{pit_.advertise("dest_image", 1)}
{
}

void ImageBlurer::blur_image(const sensor_msgs::ImageConstPtr& msg)
{
  try {
    cv::Mat dest_image;
    cv::blur(cv_bridge::toCvShare(msg, sensor_msgs::image_encodings::BGR8)->image, dest_image, cv::Size(2, 100));
    image_pub_.publish(cv_bridge::CvImage{std_msgs::Header{}, "bgr8", dest_image}.toImageMsg());
  }
  catch (cv_bridge::Exception& e) {
    ROS_ERROR_STREAM("cv_bridge exception: " << e.what());
  }
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_blurer");
  ImageBlurer ib{};
  ros::spin();
  return 0;
}
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

class ImageBlurer {
public:
  ImageBlurer();
  void blur_image(const sensor_msgs::ImageConstPtr& msg);
private:
  ros::NodeHandle nh_;
  ros::NodeHandle pnh_;
  image_transport::ImageTransport it_;
  image_transport::ImageTransport pit_;
  image_transport::Subscriber image_sub_;
  image_transport::Publisher image_pub_;
};

ImageBlurer::ImageBlurer()
  : nh_{},
    pnh_{"~"},
    it_{nh_},
    pit_{pnh_},
    image_sub_{it_.subscribe("src_image", 1, &ImageBlurer::blur_image, this)},
    image_pub_{pit_.advertise("dest_image", 1)}
{
}

void ImageBlurer::blur_image(const sensor_msgs::ImageConstPtr& msg)
{
  try {
    cv_bridge::CvImagePtr dest_ptr{cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8)};
    cv::blur(cv_bridge::CvImagePtr{cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8)}->image, dest_ptr->image, cv::Size(2, 100));
    image_pub_.publish(dest_ptr->toImageMsg());
  }
  catch (cv_bridge::Exception& e) {
    ROS_ERROR_STREAM("cv_bridge exception: " << e.what());
  }
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_blurer");
  ImageBlurer ib{};
  ros::spin();
  return 0;
}
<commit_msg>Refactor image preparing & handling<commit_after>#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

class ImageBlurer {
public:
  ImageBlurer();
  void blur_image(const sensor_msgs::ImageConstPtr& msg);
private:
  ros::NodeHandle nh_;
  ros::NodeHandle pnh_;
  image_transport::ImageTransport it_;
  image_transport::ImageTransport pit_;
  image_transport::Subscriber image_sub_;
  image_transport::Publisher image_pub_;
};

ImageBlurer::ImageBlurer()
  : nh_{},
    pnh_{"~"},
    it_{nh_},
    pit_{pnh_},
    image_sub_{it_.subscribe("src_image", 1, &ImageBlurer::blur_image, this)},
    image_pub_{pit_.advertise("dest_image", 1)}
{
}

void ImageBlurer::blur_image(const sensor_msgs::ImageConstPtr& msg)
{
  try {
    cv::Mat dest_image;
    cv::blur(cv_bridge::CvImagePtr{cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::RGB8)}->image, dest_image, cv::Size(2, 100));
    image_pub_.publish(cv_bridge::CvImage{std_msgs::Header{}, "rgb8", dest_image}.toImageMsg());
  }
  catch (cv_bridge::Exception& e) {
    ROS_ERROR_STREAM("cv_bridge exception: " << e.what());
  }
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_blurer");
  ImageBlurer ib{};
  ros::spin();
  return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: animationcommandnode.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 08:33:51 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

// must be first
#include "canvas/debug.hxx"
#include "canvas/verbosetrace.hxx"
#include "com/sun/star/presentation/EffectCommands.hpp"
#include "animationcommandnode.hxx"
#include "delayevent.hxx"
#include "tools.hxx"
#include "nodetools.hxx"

namespace presentation {
namespace internal {

void AnimationCommandNode::dispose()
{
    mxCommandNode.clear();
    BaseNode::dispose();
}

void AnimationCommandNode::activate_()
{
    namespace EffectCommands = com::sun::star::presentation::EffectCommands;

    switch( mxCommandNode->getCommand() ) {
        // the command is user defined
    case EffectCommands::CUSTOM: break;
        // the command is an ole verb.
    case EffectCommands::VERB: break;
        // the command starts playing on a media object
    case EffectCommands::PLAY: break;
        // the command toggles the pause status on a media object
    case EffectCommands::TOGGLEPAUSE: break;
        // the command stops the animation on a media object
    case EffectCommands::STOP: break;
        // the command stops all currently running sound effects
    case EffectCommands::STOPAUDIO:
        getContext().mrEventMultiplexer.notifyCommandStopAudio( getSelf() );
        break;
    }

    // deactivate ASAP:
    scheduleDeactivationEvent(
        makeEvent( boost::bind( &AnimationNode::deactivate, getSelf() ) ) );
}

bool AnimationCommandNode::hasPendingAnimation() const
{
    return false;
}

} // namespace internal
} // namespace presentation
<commit_msg>INTEGRATION: CWS presfixes09 (1.4.18); FILE MERGED 2006/10/18 19:54:29 thb 1.4.18.5: RESYNC: (1.5-1.6); FILE MERGED 2006/09/15 22:13:51 thb 1.4.18.4: RESYNC: (1.4-1.5); FILE MERGED 2006/04/03 16:19:00 thb 1.4.18.3: #i37778# Now passing down ComponentContext to all interested parties; building a second, all-exports version of the slideshow component (to facilitate unit testing also for internal classes) - this made necessary renaming ImportFailedException to ShapeLoadFailedException (because of silly i63703); applied relevant parts of #i63770# (const-correctness); reworked view handling in such a way that views are now kept in one central repository (and are not duplicated across all interested objects); moved code from namespace presentation to namespace slideshow 2006/03/24 18:23:16 thb 1.4.18.2: #i37778# Moved whole slideshow engine from namespace presentation (which conflicts with one of the UNO subnamespaces) to slideshow 2006/03/15 15:22:19 thb 1.4.18.1: #i49357# Removed external include guards from all non-export headers (and from the cxx files, anyway)<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: animationcommandnode.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-13 15:29:27 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

// must be first
#include "canvas/debug.hxx"
#include "canvas/verbosetrace.hxx"
#include "com/sun/star/presentation/EffectCommands.hpp"
#include "animationcommandnode.hxx"
#include "delayevent.hxx"
#include "tools.hxx"
#include "nodetools.hxx"

namespace slideshow {
namespace internal {

void AnimationCommandNode::dispose()
{
    mxCommandNode.clear();
    BaseNode::dispose();
}

void AnimationCommandNode::activate_()
{
    namespace EffectCommands = com::sun::star::presentation::EffectCommands;

    switch( mxCommandNode->getCommand() ) {
        // the command is user defined
    case EffectCommands::CUSTOM: break;
        // the command is an ole verb.
    case EffectCommands::VERB: break;
        // the command starts playing on a media object
    case EffectCommands::PLAY: break;
        // the command toggles the pause status on a media object
    case EffectCommands::TOGGLEPAUSE: break;
        // the command stops the animation on a media object
    case EffectCommands::STOP: break;
        // the command stops all currently running sound effects
    case EffectCommands::STOPAUDIO:
        getContext().mrEventMultiplexer.notifyCommandStopAudio( getSelf() );
        break;
    }

    // deactivate ASAP:
    scheduleDeactivationEvent(
        makeEvent( boost::bind( &AnimationNode::deactivate, getSelf() ) ) );
}

bool AnimationCommandNode::hasPendingAnimation() const
{
    return false;
}

} // namespace internal
} // namespace slideshow
<|endoftext|>


<commit_before>/** @file
 *
 * The implementation of the MultiplyElement class.
 *
 * @author Nicolas Bock <nicolas.bock@freeon.org>
 * @author Matt Challacombe <matt.challacombe@freeon.org>
 */

#include "multiplyelement.h"
#include "messages.h"
#include "logger.h"
#include "index.h"
#include <string.h>

/** The constructor.
 *
 * @param ANode The node of matrix A.
 * @param BNode The node of matrix B.
 * @param CNode The node of matrix C.
 */
MultiplyElement::MultiplyElement (int blocksize, int tier, int depth,
    CProxy_Node A, CProxy_Node B, CProxy_Node C)
{
  DEBUG("tier %d ME(%d,%d,%d) constructor\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z);

  this->blocksize = blocksize;
  this->tier = tier;
  this->depth = depth;
  this->A = A;
  this->B = B;
  this->C = C;

  if(tier < depth)
  {
    for(int i = 0; i < 2; i++) {
      for(int j = 0; j < 2; j++) {
        for(int k = 0; k < 2; k++)
        {
          nextConvolutionExists[i][j][k] = true;
        }
      }
    }
  }

  CResult = NULL;
  numberCalls = 0;
  wasMigrated = false;
}

/** The migration constructor.
 *
 * @param msg The migration message.
 */
MultiplyElement::MultiplyElement (CkMigrateMessage *msg)
{
  INFO("ME(%d,%d,%d) migration constructor\n", thisIndex.x, thisIndex.y,
      thisIndex.z);

  /* Reset the migration flag on the new PE. */
  wasMigrated = false;
}

/** The destructor.
 */
MultiplyElement::~MultiplyElement ()
{
  DEBUG("tier %d ME(%d,%d,%d) destructor\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z);

  delete[] CResult;

  if(!wasMigrated && (tier < depth))
  {
    DEBUG("tier %d ME(%d,%d,%d) destructor, pruning lower tier elements\n",
        tier, thisIndex.x, thisIndex.y, thisIndex.z);

    /* Recursively prune convolution elements. */
    for(int i = 0; i < 2; i++) {
      for(int j = 0; j < 2; j++) {
        for(int k = 0; k < 2; k++)
        {
          if(nextConvolutionExists[i][j][k])
          {
            DEBUG("tier %d ME(%d,%d,%d) destructor, pruning tier %d ME(%d,%d,%d)\n",
                tier, thisIndex.x, thisIndex.y, thisIndex.z,
                tier+1,
                (thisIndex.x << 1)+i,
                (thisIndex.y << 1)+j,
                (thisIndex.z << 1)+k);

            nextConvolution((thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                (thisIndex.z << 1)+k).ckDestroy();

            DEBUG("tier %d ME(%d,%d,%d) destructor, pruning tier %d ME(%d,%d,%d), here 2\n",
                tier, thisIndex.x, thisIndex.y, thisIndex.z,
                tier+1,
                (thisIndex.x << 1)+i,
                (thisIndex.y << 1)+j,
                (thisIndex.z << 1)+k);

            nextConvolutionExists[i][j][k] = false;

            DEBUG("tier %d ME(%d,%d,%d) destructor, pruning tier %d ME(%d,%d,%d), here 3\n",
                tier, thisIndex.x, thisIndex.y, thisIndex.z,
                tier+1,
                (thisIndex.x << 1)+i,
                (thisIndex.y << 1)+j,
                (thisIndex.z << 1)+k);
          }
        }
      }
    }
  }

  DEBUG("tier %d ME(%d,%d,%d) destructor done\n", tier, thisIndex.x,
      thisIndex.y, thisIndex.z);
}

/** The the next convolution array.
 *
 * @param nextConvolution The next convolution array.
 */
void MultiplyElement::setNextTier (CProxy_MultiplyElement nextConvolution,
    CProxy_Node nextA, CProxy_Node nextB, CkCallback &cb)
{
  DEBUG("tier %d ME(%d,%d,%d) setting nextTier\n", tier, thisIndex.x, thisIndex.y, thisIndex.z);
  this->nextConvolution = nextConvolution;
  this->nextA = nextA;
  this->nextB = nextB;
  contribute(cb);
}

/** The PUP method.
 *
 * @param p The object.
 */
void MultiplyElement::pup (PUP::er &p)
{
  CBase_MultiplyElement::pup(p);
  p|index;
  p|blocksize;
  p|numberCalls;
  p|depth;
  p|tier;
  p|A;
  p|B;
  p|C;

  for(int i = 0; i < 2; i++) {
    for(int j = 0; j < 2; j++) {
      for(int k = 0; k < 2; k++)
      {
        p|nextConvolutionExists[i][j][k];
      }
    }
  }

  if(tier < depth)
  {
    p|nextConvolution;
    p|nextA;
    p|nextB;
  }

  int numberElements = (CResult == NULL ? 0 : blocksize*blocksize);
  p|numberElements;

  if(p.isUnpacking())
  {
    INFO("tier %d ME(%d,%d,%d) pup: unpacking %d elements\n",
        tier, thisIndex.x, thisIndex.y, thisIndex.z, numberElements);
  }
  else
  {
    if(p.isSizing())
    {
      DEBUG("tier %d ME(%d,%d,%d) pup: sizing %d elements\n",
          tier, thisIndex.x, thisIndex.y, thisIndex.z, numberElements);
    }
    else
    {
      INFO("tier %d ME(%d,%d,%d) pup: packing %d elements\n",
          tier, thisIndex.x, thisIndex.y, thisIndex.z, numberElements);

      /* Set the wasMigrated flag to indicate that this instance is going to
       * get destroyed because of a migration, and not because of pruning. */
      wasMigrated = true;

      //print("packing");
    }
  }

  if(numberElements > 0)
  {
    if(p.isUnpacking())
    {
      CResult = new double[numberElements];
    }
    PUParray(p, CResult, numberElements);

    //print("unpacking");
  }
  else
  {
    if(p.isUnpacking()) { CResult = NULL; }
  }
}

/** Multiply nodes.
 *
 * @param cb The callback.
 */
void MultiplyElement::multiply (double tolerance, CkCallback &cb)
{
  DEBUG("tier %d ME(%d,%d,%d) multiply\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z);

  if(numberCalls > 0)
  {
    ABORT("tier %d ME(%d,%d,%d) this MultiplyElement has been called before\n",
        tier, thisIndex.x, thisIndex.y, thisIndex.z);
  }
  numberCalls++;

  if(tier == depth)
  {
    NodeInfoMsg *AInfo = A(thisIndex.x, thisIndex.z).info();
    NodeInfoMsg *BInfo = B(thisIndex.z, thisIndex.y).info();

    if(AInfo->norm*BInfo->norm > tolerance)
    {
      if(CResult != NULL)
      {
        ABORT("tier %d ME(%d,%d,%d) CResult is not NULL\n", tier, thisIndex.x,
            thisIndex.y, thisIndex.z);
      }

      DEBUG("tier %d ME(%d,%d,%d) multiplying blocks\n", tier, thisIndex.x,
          thisIndex.y, thisIndex.z);

      CResult = new double[blocksize*blocksize];
      memset(CResult, 0, sizeof(double)*blocksize*blocksize);

      NodeBlockMsg *ABlock = A(thisIndex.x, thisIndex.z).getBlock();
      NodeBlockMsg *BBlock = B(thisIndex.z, thisIndex.y).getBlock();

      for(int i = 0; i < blocksize; i++) {
        for(int j = 0; j < blocksize; j++) {
          for(int k = 0; k < blocksize; k++)
          {
            CResult[BLOCK_INDEX(i, j, 0, 0, blocksize)] +=
              ABlock->block[BLOCK_INDEX(i, k, 0, 0, blocksize)]
              *BBlock->block[BLOCK_INDEX(k, j, 0, 0, blocksize)];
          }
        }
      }

      INFO("tier %d ME(%d,%d,%d) sleeping\n", tier, thisIndex.x,
          thisIndex.y, thisIndex.z);
      sleep(30);
    }

    else
    {
      ABORT("tier %d ME(%d,%d,%d) skipping block product\n", tier,
          thisIndex.x, thisIndex.y, thisIndex.z);
    }

    delete AInfo;
    delete BInfo;
  }

  else
  {
    /* Get information on A and B matrices. */
    NodeInfoMsg *AInfo[2][2];
    NodeInfoMsg *BInfo[2][2];

    for(int i = 0; i < 2; i++) {
      for(int j = 0; j < 2; j++)
      {
        AInfo[i][j] = A((thisIndex.x << 1)+i, (thisIndex.z << 1)+j).info();
        BInfo[i][j] = B((thisIndex.z << 1)+i, (thisIndex.y << 1)+j).info();
      }
    }

    /* Check what products are necessary one tier down. */
    for(int i = 0; i < 2; i++) {
      for(int j = 0; j < 2; j++) {
        for(int k = 0; k < 2; k++)
        {
          if(AInfo[i][k]->norm*BInfo[k][j]->norm > tolerance)
          {
            if(!nextConvolutionExists[i][j][k])
            {
              DEBUG("tier %d ME(%d,%d,%d) adding product ME(%d,%d,%d): C(%d,%d) <- A(%d,%d)*B(%d,%d)\n",
                  tier, thisIndex.x, thisIndex.y, thisIndex.z,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j, (thisIndex.z << 1)+k,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.x << 1)+i, (thisIndex.z << 1)+k,
                  (thisIndex.z << 1)+k, (thisIndex.y << 1)+j);
              nextConvolution((thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.z << 1)+k).insert(blocksize, tier+1, depth, A, B, C);
              nextConvolutionExists[i][j][k] = true;
            }

            else
            {
              DEBUG("tier %d ME(%d,%d,%d) keeping product ME(%d,%d,%d): C(%d,%d) <- A(%d,%d)*B(%d,%d)\n",
                  tier, thisIndex.x, thisIndex.y, thisIndex.z,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j, (thisIndex.z << 1)+k,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.x << 1)+i, (thisIndex.z << 1)+k,
                  (thisIndex.z << 1)+k, (thisIndex.y << 1)+j);
            }
          }

          else
          {
            if(nextConvolutionExists[i][j][k])
            {
              DEBUG("tier %d ME(%d,%d,%d) dropping product ME(%d,%d,%d): C(%d,%d) <- A(%d,%d)*B(%d,%d)\n",
                  tier, thisIndex.x, thisIndex.y, thisIndex.z,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j, (thisIndex.z << 1)+k,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.x << 1)+i, (thisIndex.z << 1)+k,
                  (thisIndex.z << 1)+k, (thisIndex.y << 1)+j);

              nextConvolutionExists[i][j][k] = false;
              nextConvolution((thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.z << 1)+k).ckDestroy();
            }

            else
            {
              DEBUG("tier %d ME(%d,%d,%d) product already does not exist ME(%d,%d,%d): C(%d,%d) <- A(%d,%d)*B(%d,%d)\n",
                  tier, thisIndex.x, thisIndex.y, thisIndex.z,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j, (thisIndex.z << 1)+k,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.x << 1)+i, (thisIndex.z << 1)+k,
                  (thisIndex.z << 1)+k, (thisIndex.y << 1)+j);
            }
          }
        }
      }
    }

    for(int i = 0; i < 2; i++) {
      for(int j = 0; j < 2; j++)
      {
        delete AInfo[i][j];
        delete BInfo[i][j];
      }
    }
  }

  DEBUG("tier %d ME(%d,%d,%d) contribute\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z);
  contribute(cb);

#ifdef FORCED_MIGRATION
  if(CkNumPes() > 1)
  {
    INFO("tier %d ME(%d,%d,%d) requesting migration to PE %d\n",
        tier, thisIndex.x, thisIndex.y, thisIndex.z, (CkMyPe()+1)%CkNumPes());
    migrateMe((CkMyPe()+1)%CkNumPes());
  }
#endif
}

/** Push the C submatrices back into the C Matrix.
 *
 * @param cb The callback.
 */
void MultiplyElement::storeBack (CkCallback &cb)
{
#ifdef DEBUG_OUTPUT
  DEBUG("tier %d ME(%d,%d,%d) storing back\n", tier, thisIndex.x, thisIndex.y, thisIndex.z);
  printDense(blocksize, CResult);
#endif
  C(thisIndex.x, thisIndex.y).add(blocksize, CResult);
  contribute(cb);
}

/** Print a MultiplyElement.
 */
void MultiplyElement::print (std::string tag)
{
  INFO("tier %d ME(%d,%d,%d) [%s] CResult = %p\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z, tag.c_str(), CResult);
}

#include "multiplyelement.def.h"
<commit_msg>Another debug print statement.<commit_after>/** @file
 *
 * The implementation of the MultiplyElement class.
 *
 * @author Nicolas Bock <nicolas.bock@freeon.org>
 * @author Matt Challacombe <matt.challacombe@freeon.org>
 */

#include "multiplyelement.h"
#include "messages.h"
#include "logger.h"
#include "index.h"
#include <string.h>

/** The constructor.
 *
 * @param ANode The node of matrix A.
 * @param BNode The node of matrix B.
 * @param CNode The node of matrix C.
 */
MultiplyElement::MultiplyElement (int blocksize, int tier, int depth,
    CProxy_Node A, CProxy_Node B, CProxy_Node C)
{
  DEBUG("tier %d ME(%d,%d,%d) constructor\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z);

  this->blocksize = blocksize;
  this->tier = tier;
  this->depth = depth;
  this->A = A;
  this->B = B;
  this->C = C;

  if(tier < depth)
  {
    for(int i = 0; i < 2; i++) {
      for(int j = 0; j < 2; j++) {
        for(int k = 0; k < 2; k++)
        {
          nextConvolutionExists[i][j][k] = true;
        }
      }
    }
  }

  CResult = NULL;
  numberCalls = 0;
  wasMigrated = false;
}

/** The migration constructor.
 *
 * @param msg The migration message.
 */
MultiplyElement::MultiplyElement (CkMigrateMessage *msg)
{
  INFO("ME(%d,%d,%d) migration constructor\n", thisIndex.x, thisIndex.y,
      thisIndex.z);

  /* Reset the migration flag on the new PE. */
  wasMigrated = false;
}

/** The destructor.
 */
MultiplyElement::~MultiplyElement ()
{
  DEBUG("tier %d ME(%d,%d,%d) destructor\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z);

  delete[] CResult;

  if(!wasMigrated && (tier < depth))
  {
    DEBUG("tier %d ME(%d,%d,%d) destructor, pruning lower tier elements\n",
        tier, thisIndex.x, thisIndex.y, thisIndex.z);

    /* Recursively prune convolution elements. */
    for(int i = 0; i < 2; i++) {
      for(int j = 0; j < 2; j++) {
        for(int k = 0; k < 2; k++)
        {
          if(nextConvolutionExists[i][j][k])
          {
            DEBUG("tier %d ME(%d,%d,%d) destructor, pruning tier %d ME(%d,%d,%d)\n",
                tier, thisIndex.x, thisIndex.y, thisIndex.z,
                tier+1,
                (thisIndex.x << 1)+i,
                (thisIndex.y << 1)+j,
                (thisIndex.z << 1)+k);

            nextConvolution((thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                (thisIndex.z << 1)+k).ckDestroy();

            DEBUG("tier %d ME(%d,%d,%d) destructor, pruning tier %d ME(%d,%d,%d), here 2\n",
                tier, thisIndex.x, thisIndex.y, thisIndex.z,
                tier+1,
                (thisIndex.x << 1)+i,
                (thisIndex.y << 1)+j,
                (thisIndex.z << 1)+k);

            nextConvolutionExists[i][j][k] = false;

            DEBUG("tier %d ME(%d,%d,%d) destructor, pruning tier %d ME(%d,%d,%d), here 3\n",
                tier, thisIndex.x, thisIndex.y, thisIndex.z,
                tier+1,
                (thisIndex.x << 1)+i,
                (thisIndex.y << 1)+j,
                (thisIndex.z << 1)+k);
          }
        }
      }
    }
  }

  DEBUG("tier %d ME(%d,%d,%d) destructor done\n", tier, thisIndex.x,
      thisIndex.y, thisIndex.z);
}

/** The the next convolution array.
 *
 * @param nextConvolution The next convolution array.
 */
void MultiplyElement::setNextTier (CProxy_MultiplyElement nextConvolution,
    CProxy_Node nextA, CProxy_Node nextB, CkCallback &cb)
{
  DEBUG("tier %d ME(%d,%d,%d) setting nextTier\n", tier, thisIndex.x, thisIndex.y, thisIndex.z);
  this->nextConvolution = nextConvolution;
  this->nextA = nextA;
  this->nextB = nextB;
  contribute(cb);
}

/** The PUP method.
 *
 * @param p The object.
 */
void MultiplyElement::pup (PUP::er &p)
{
  CBase_MultiplyElement::pup(p);
  p|index;
  p|blocksize;
  p|numberCalls;
  p|depth;
  p|tier;
  p|A;
  p|B;
  p|C;

  for(int i = 0; i < 2; i++) {
    for(int j = 0; j < 2; j++) {
      for(int k = 0; k < 2; k++)
      {
        p|nextConvolutionExists[i][j][k];
      }
    }
  }

  if(tier < depth)
  {
    p|nextConvolution;
    p|nextA;
    p|nextB;
  }

  int numberElements = (CResult == NULL ? 0 : blocksize*blocksize);
  p|numberElements;

  if(p.isUnpacking())
  {
    INFO("tier %d ME(%d,%d,%d) pup: unpacking %d elements\n",
        tier, thisIndex.x, thisIndex.y, thisIndex.z, numberElements);
  }
  else
  {
    if(p.isSizing())
    {
      DEBUG("tier %d ME(%d,%d,%d) pup: sizing %d elements\n",
          tier, thisIndex.x, thisIndex.y, thisIndex.z, numberElements);
    }
    else
    {
      INFO("tier %d ME(%d,%d,%d) pup: packing %d elements\n",
          tier, thisIndex.x, thisIndex.y, thisIndex.z, numberElements);

      /* Set the wasMigrated flag to indicate that this instance is going to
       * get destroyed because of a migration, and not because of pruning. */
      wasMigrated = true;

      //print("packing");
    }
  }

  if(numberElements > 0)
  {
    if(p.isUnpacking())
    {
      CResult = new double[numberElements];
    }
    PUParray(p, CResult, numberElements);

    //print("unpacking");
  }
  else
  {
    if(p.isUnpacking()) { CResult = NULL; }
  }

  INFO("tier %d ME(%d,%d,%d) pup: done\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z);
}

/** Multiply nodes.
 *
 * @param cb The callback.
 */
void MultiplyElement::multiply (double tolerance, CkCallback &cb)
{
  DEBUG("tier %d ME(%d,%d,%d) multiply\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z);

  if(numberCalls > 0)
  {
    ABORT("tier %d ME(%d,%d,%d) this MultiplyElement has been called before\n",
        tier, thisIndex.x, thisIndex.y, thisIndex.z);
  }
  numberCalls++;

  if(tier == depth)
  {
    NodeInfoMsg *AInfo = A(thisIndex.x, thisIndex.z).info();
    NodeInfoMsg *BInfo = B(thisIndex.z, thisIndex.y).info();

    if(AInfo->norm*BInfo->norm > tolerance)
    {
      if(CResult != NULL)
      {
        ABORT("tier %d ME(%d,%d,%d) CResult is not NULL\n", tier, thisIndex.x,
            thisIndex.y, thisIndex.z);
      }

      DEBUG("tier %d ME(%d,%d,%d) multiplying blocks\n", tier, thisIndex.x,
          thisIndex.y, thisIndex.z);

      CResult = new double[blocksize*blocksize];
      memset(CResult, 0, sizeof(double)*blocksize*blocksize);

      NodeBlockMsg *ABlock = A(thisIndex.x, thisIndex.z).getBlock();
      NodeBlockMsg *BBlock = B(thisIndex.z, thisIndex.y).getBlock();

      for(int i = 0; i < blocksize; i++) {
        for(int j = 0; j < blocksize; j++) {
          for(int k = 0; k < blocksize; k++)
          {
            CResult[BLOCK_INDEX(i, j, 0, 0, blocksize)] +=
              ABlock->block[BLOCK_INDEX(i, k, 0, 0, blocksize)]
              *BBlock->block[BLOCK_INDEX(k, j, 0, 0, blocksize)];
          }
        }
      }

      INFO("tier %d ME(%d,%d,%d) sleeping\n", tier, thisIndex.x,
          thisIndex.y, thisIndex.z);
      sleep(30);
    }

    else
    {
      ABORT("tier %d ME(%d,%d,%d) skipping block product\n", tier,
          thisIndex.x, thisIndex.y, thisIndex.z);
    }

    delete AInfo;
    delete BInfo;
  }

  else
  {
    /* Get information on A and B matrices. */
    NodeInfoMsg *AInfo[2][2];
    NodeInfoMsg *BInfo[2][2];

    for(int i = 0; i < 2; i++) {
      for(int j = 0; j < 2; j++)
      {
        AInfo[i][j] = A((thisIndex.x << 1)+i, (thisIndex.z << 1)+j).info();
        BInfo[i][j] = B((thisIndex.z << 1)+i, (thisIndex.y << 1)+j).info();
      }
    }

    /* Check what products are necessary one tier down. */
    for(int i = 0; i < 2; i++) {
      for(int j = 0; j < 2; j++) {
        for(int k = 0; k < 2; k++)
        {
          if(AInfo[i][k]->norm*BInfo[k][j]->norm > tolerance)
          {
            if(!nextConvolutionExists[i][j][k])
            {
              DEBUG("tier %d ME(%d,%d,%d) adding product ME(%d,%d,%d): C(%d,%d) <- A(%d,%d)*B(%d,%d)\n",
                  tier, thisIndex.x, thisIndex.y, thisIndex.z,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j, (thisIndex.z << 1)+k,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.x << 1)+i, (thisIndex.z << 1)+k,
                  (thisIndex.z << 1)+k, (thisIndex.y << 1)+j);
              nextConvolution((thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.z << 1)+k).insert(blocksize, tier+1, depth, A, B, C);
              nextConvolutionExists[i][j][k] = true;
            }

            else
            {
              DEBUG("tier %d ME(%d,%d,%d) keeping product ME(%d,%d,%d): C(%d,%d) <- A(%d,%d)*B(%d,%d)\n",
                  tier, thisIndex.x, thisIndex.y, thisIndex.z,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j, (thisIndex.z << 1)+k,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.x << 1)+i, (thisIndex.z << 1)+k,
                  (thisIndex.z << 1)+k, (thisIndex.y << 1)+j);
            }
          }

          else
          {
            if(nextConvolutionExists[i][j][k])
            {
              DEBUG("tier %d ME(%d,%d,%d) dropping product ME(%d,%d,%d): C(%d,%d) <- A(%d,%d)*B(%d,%d)\n",
                  tier, thisIndex.x, thisIndex.y, thisIndex.z,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j, (thisIndex.z << 1)+k,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.x << 1)+i, (thisIndex.z << 1)+k,
                  (thisIndex.z << 1)+k, (thisIndex.y << 1)+j);

              nextConvolutionExists[i][j][k] = false;
              nextConvolution((thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.z << 1)+k).ckDestroy();
            }

            else
            {
              DEBUG("tier %d ME(%d,%d,%d) product already does not exist ME(%d,%d,%d): C(%d,%d) <- A(%d,%d)*B(%d,%d)\n",
                  tier, thisIndex.x, thisIndex.y, thisIndex.z,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j, (thisIndex.z << 1)+k,
                  (thisIndex.x << 1)+i, (thisIndex.y << 1)+j,
                  (thisIndex.x << 1)+i, (thisIndex.z << 1)+k,
                  (thisIndex.z << 1)+k, (thisIndex.y << 1)+j);
            }
          }
        }
      }
    }

    for(int i = 0; i < 2; i++) {
      for(int j = 0; j < 2; j++)
      {
        delete AInfo[i][j];
        delete BInfo[i][j];
      }
    }
  }

  DEBUG("tier %d ME(%d,%d,%d) contribute\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z);
  contribute(cb);

#ifdef FORCED_MIGRATION
  if(CkNumPes() > 1)
  {
    INFO("tier %d ME(%d,%d,%d) requesting migration to PE %d\n",
        tier, thisIndex.x, thisIndex.y, thisIndex.z, (CkMyPe()+1)%CkNumPes());
    migrateMe((CkMyPe()+1)%CkNumPes());
  }
#endif
}

/** Push the C submatrices back into the C Matrix.
 *
 * @param cb The callback.
 */
void MultiplyElement::storeBack (CkCallback &cb)
{
#ifdef DEBUG_OUTPUT
  DEBUG("tier %d ME(%d,%d,%d) storing back\n", tier, thisIndex.x, thisIndex.y, thisIndex.z);
  printDense(blocksize, CResult);
#endif
  C(thisIndex.x, thisIndex.y).add(blocksize, CResult);
  contribute(cb);
}

/** Print a MultiplyElement.
 */
void MultiplyElement::print (std::string tag)
{
  INFO("tier %d ME(%d,%d,%d) [%s] CResult = %p\n", tier, thisIndex.x, thisIndex.y,
      thisIndex.z, tag.c_str(), CResult);
}

#include "multiplyelement.def.h"
<|endoftext|>


<commit_before>#include "testApp.h"

#include "ofxSimpleGuiToo.h"

bool recording = false;
//--------------------------------------------------------------
void testApp::setup(){

	kinect.setup();

	kinect.setupGui();

	gui.loadFromXML();
	gui.setAutoSave(true);

	gui.setAlignRight(true);

	ofSetFrameRate(30);
	ofSetVerticalSync(true);
	ofEnableAlphaBlending();

	blobTracker.addListener(&blobEvents);
}

//--------------------------------------------------------------
void testApp::update(){

	bool newFrame = kinect.update();
	if(newFrame) {
		int minBlobSize = 40;
		int maxBlobSize = kinect.getHeight();

		contours.findContours(kinect.getOutline(), minBlobSize*minBlobSize, maxBlobSize*maxBlobSize, 20, false, true);

		doPersonTracking();

	}

	ofSetWindowTitle(ofToString(ofGetFrameRate(), 1));
}

void testApp::doPersonTracking() {

//	people.clear();

	// run the blob tracker
	vector<ofVec3f> blobs;
	ofVec2f dims(kinect.getWidth(), kinect.getHeight());

	// use the z coordinate.
	for(int i = 0; i < contours.blobs.size(); i++) {
		ofVec3f b = ofVec3f(contours.blobs[i].centroid.x/(float)kinect.getWidth(),
							contours.blobs[i].centroid.y/(float)kinect.getHeight(), i);
		blobs.push_back(b);
	}

	blobTracker.track(blobs);

	ofxBlobEvent e;
	while(blobEvents.getNextEvent(e)) {
		if(e.eventType==ofxBlobTracker_entered) {
			people[e.blobId] = BoundBlob();
			people[e.blobId].init(contours.blobs[(int)e.pos.z]);
			people[e.blobId].setDepth(kinect.getDepth(contours.blobs[(int)e.pos.z]));

			if(recording) {
				ofVec3f bounds(640,480, 255);

				ofVec3f f = people[e.blobId].left/bounds;
				anim.addFrame("hand_left", (const float*)&f.x);

				f = people[e.blobId].right/bounds;

				anim.addFrame("hand_right", (const float*)&f.x);

				f = people[e.blobId].top/bounds;
				anim.addFrame("top", (const float*)&f.x);

				f = people[e.blobId].bottom/bounds;
				anim.addFrame("bottom", (const float*)&f.x);
			}
		} else if(e.eventType==ofxBlobTracker_moved) {
			people[e.blobId].update(contours.blobs[(int)e.pos.z]);

			if(recording) {
				ofVec3f bounds(640,480, 255);

				ofVec3f f = people[e.blobId].left/bounds;
				anim.addFrame("hand_left", (const float*)&f.x);

				f = people[e.blobId].right/bounds;
				anim.addFrame("hand_right", (const float*)&f.x);

				f = people[e.blobId].top/bounds;
				anim.addFrame("top", (const float*)&f.x);

				f = people[e.blobId].bottom/bounds;
				anim.addFrame("bottom", (const float*)&f.x);
			}

		} else if(e.eventType==ofxBlobTracker_exited) {
			people.erase(e.blobId);
		}
	}

	/*if(contours.blobs.size()==people.size()) { // match the nearest
		for(int i = 0; i < contours.blobs.size(); i++) {
			people.push_back(BoundBlob());
			people.back().init(contours.blobs[i]);
		}
	} else if() {

	}*/
}
//--------------------------------------------------------------
void testApp::draw(){

	kinect.drawDebug();
	contours.draw();

	map<int,BoundBlob>::iterator it;
	for(it = people.begin(); it != people.end(); it++) {
		(*it).second.draw();
		ofDrawBitmapString(ofToString((*it).first), (*it).second.centroid);

	}
	gui.draw();
}

//--------------------------------------------------------------
void testApp::keyPressed(int key){
	switch(key) {

		case ' ':
			gui.toggleDraw();
			break;

		case 'f':
			ofToggleFullscreen();
			break;
		case 'b': kinect.learnBackground = true; break;

		case 'r':
			recording ^= true;
			if(!recording) { // just finished recording

				anim.save(ofToDataPath(ofGetTimestampString()+".txt"));
				anim.animations.clear();

			}
			break;
	}
}

//--------------------------------------------------------------
void testApp::keyReleased(int key){

}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){

}<commit_msg>Made kinect recorder output centroid<commit_after>#include "testApp.h"

#include "ofxSimpleGuiToo.h"

bool recording = false;
//--------------------------------------------------------------
void testApp::setup(){

	kinect.setup();

	kinect.setupGui();

	gui.loadFromXML();
	gui.setAutoSave(true);

	gui.setAlignRight(true);

	ofSetFrameRate(30);
	ofSetVerticalSync(true);
	ofEnableAlphaBlending();

	blobTracker.addListener(&blobEvents);
}

//--------------------------------------------------------------
void testApp::update(){

	bool newFrame = kinect.update();
	if(newFrame) {
		int minBlobSize = 40;
		int maxBlobSize = kinect.getHeight();

		contours.findContours(kinect.getOutline(), minBlobSize*minBlobSize, maxBlobSize*maxBlobSize, 20, false, true);

		doPersonTracking();

	}

	ofSetWindowTitle(ofToString(ofGetFrameRate(), 1));
}

void testApp::doPersonTracking() {

//	people.clear();

	// run the blob tracker
	vector<ofVec3f> blobs;
	ofVec2f dims(kinect.getWidth(), kinect.getHeight());

	// use the z coordinate.
	for(int i = 0; i < contours.blobs.size(); i++) {
		ofVec3f b = ofVec3f(contours.blobs[i].centroid.x/(float)kinect.getWidth(),
							contours.blobs[i].centroid.y/(float)kinect.getHeight(), i);
		blobs.push_back(b);
	}

	blobTracker.track(blobs);

	ofxBlobEvent e;
	while(blobEvents.getNextEvent(e)) {
		if(e.eventType==ofxBlobTracker_entered) {
			people[e.blobId] = BoundBlob();
			people[e.blobId].init(contours.blobs[(int)e.pos.z]);
			people[e.blobId].setDepth(kinect.getDepth(contours.blobs[(int)e.pos.z]));

			if(recording) {
				ofVec3f bounds(640,480, 255);

				ofVec3f f = people[e.blobId].left/bounds;
				anim.addFrame("hand_left", (const float*)&f.x);

				f = people[e.blobId].right/bounds;

				anim.addFrame("hand_right", (const float*)&f.x);

				f = people[e.blobId].top/bounds;
				anim.addFrame("top", (const float*)&f.x);

				f = people[e.blobId].bottom/bounds;
				anim.addFrame("bottom", (const float*)&f.x);

				f = people[e.blobId].centroid/bounds;
				anim.addFrame("centroid", (const float*)&f.x);
			}
		} else if(e.eventType==ofxBlobTracker_moved) {
			people[e.blobId].update(contours.blobs[(int)e.pos.z]);

			if(recording) {
				ofVec3f bounds(640,480, 255);

				ofVec3f f = people[e.blobId].left/bounds;
				anim.addFrame("hand_left", (const float*)&f.x);

				f = people[e.blobId].right/bounds;
				anim.addFrame("hand_right", (const float*)&f.x);

				f = people[e.blobId].top/bounds;
				anim.addFrame("top", (const float*)&f.x);

				f = people[e.blobId].bottom/bounds;
				anim.addFrame("bottom", (const float*)&f.x);

				f = people[e.blobId].centroid/bounds;
				anim.addFrame("centroid", (const float*)&f.x);
			}

		} else if(e.eventType==ofxBlobTracker_exited) {
			people.erase(e.blobId);
		}
	}

	/*if(contours.blobs.size()==people.size()) { // match the nearest
		for(int i = 0; i < contours.blobs.size(); i++) {
			people.push_back(BoundBlob());
			people.back().init(contours.blobs[i]);
		}
	} else if() {

	}*/
}
//--------------------------------------------------------------
void testApp::draw(){

	kinect.drawDebug();
	contours.draw();

	map<int,BoundBlob>::iterator it;
	for(it = people.begin(); it != people.end(); it++) {
		(*it).second.draw();
		ofDrawBitmapString(ofToString((*it).first), (*it).second.centroid);

	}
	gui.draw();
}

//--------------------------------------------------------------
void testApp::keyPressed(int key){
	switch(key) {

		case ' ':
			gui.toggleDraw();
			break;

		case 'f':
			ofToggleFullscreen();
			break;
		case 'b': kinect.learnBackground = true; break;

		case 'r':
			recording ^= true;
			if(!recording) { // just finished recording

				anim.save(ofToDataPath(ofGetTimestampString()+".txt"));
				anim.animations.clear();

			}
			break;
	}
}

//--------------------------------------------------------------
void testApp::keyReleased(int key){

}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){

}<|endoftext|>


<commit_before>#include <VMDE/VMDE.hpp>

namespace VM76 {
	GDrawable::GDrawable* test_obj;

	void loop() {
		for (;;) {
			::main_draw_start();

			glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glEnable(GL_BLEND);
			glEnable(GL_DEPTH_TEST);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

			// Activate Shader
			glUseProgram(main_shader->shaderProgram);

			// Setup uniforms
			GLuint model_location = glGetUniformLocation(main_shader->shaderProgram, "brightness");
			glUniform1f(model_location, VMDE->state.brightness);

			// Setup textures
			char uniform_name[16];
			for (int index = 0; index < 16; index++) if (Res::tex_unit[index]) {
				sprintf(uniform_name, "colortex%d", index);
				glActiveTexture(GL_TEXTURE0 + index);
				glBindTexture(GL_TEXTURE_2D, Res::tex_unit[index]->texture);
				glUniform1i(glGetUniformLocation(main_shader->shaderProgram, (GLchar*) uniform_name), index);
			}

			//matrix2D();
			test_obj->model = glm::translate(test_obj->model, glm::vec3(0.0001f, 0.0001f, 0.0001f));
			GDrawable::draw(test_obj, projection, view);

			::main_draw_end();
		}
	}

	static GLfloat vtx[] = {
		0.0, 0.0, 0.0,   1.0, 1.0, 1.0, 1.0,  0.0, 0.0,
		0.0, 1.0, 0.0,  1.0, 1.0, 1.0, 1.0,  0.0, 1.0,
		1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0,  1.0, 1.0,
		1.0, 0.0, 0.0,  1.0, 1.0, 1.0, 1.0,  1.0, 0.0
	};
	static GLuint itx[] = {0, 1, 3,  1, 2, 3};

	void start_game() {
		::init_engine(800, 600);

		new Res::Texture((char*)"../Media/terrain.png", 0);
		test_obj = GDrawable::create();
		test_obj->vtx_c = sizeof(vtx) / sizeof(GLfloat);
		test_obj->ind_c = sizeof(itx) / sizeof(GLuint);
		test_obj->vertices = vtx;
		test_obj->indices = itx;
		test_obj->tri_mesh_count = sizeof(itx) / sizeof(GLuint) / 3;
		GDrawable::fbind(test_obj);

		projection = glm::perspective(1.0f, float(VMDE->width) / float(VMDE->height), -1.0f, 1.0f);
		view = glm::lookAt(glm::vec3(2.0, 0.0, 2.0), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));

		loop();
	}
}

int main() {
	log("Starting game");
	VM76::start_game();
}
<commit_msg>正确地关闭程序<commit_after>#include <VMDE/VMDE.hpp>

namespace VM76 {
	GDrawable::GDrawable* test_obj = NULL;

	void loop() {
		for (;;) {
			glfwPollEvents();
			::main_draw_start();

			glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glEnable(GL_BLEND);
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

			// Activate Shader
			glUseProgram(main_shader->shaderProgram);

			// Setup uniforms
			GLuint model_location = glGetUniformLocation(main_shader->shaderProgram, "brightness");
			glUniform1f(model_location, VMDE->state.brightness);

			// Setup textures
			char uniform_name[16];
			for (int index = 0; index < 16; index++) if (Res::tex_unit[index]) {
				sprintf(uniform_name, "colortex%d", index);
				glActiveTexture(GL_TEXTURE0 + index);
				glBindTexture(GL_TEXTURE_2D, Res::tex_unit[index]->texture);
				glUniform1i(glGetUniformLocation(main_shader->shaderProgram, (GLchar*) uniform_name), index);
			}

			test_obj->model = glm::translate(test_obj->model, glm::vec3(0.0001f, 0.0001f, 0.0001f));
			test_obj->model = glm::rotate(test_obj->model, 0.01f, glm::vec3(1.0f, 1.0f, 1.0f));
			GDrawable::draw(test_obj, projection, view);

			::main_draw_end();
		}
	}

	static GLfloat vtx[] = {
		0.0, 0.0, 0.0,  1.0, 1.0, 1.0, 1.0,  0.0, 0.0,
		0.0, 1.0, 0.0,  1.0, 1.0, 1.0, 1.0,  0.0, 1.0,
		1.0, 1.0, 0.0,  1.0, 1.0, 1.0, 1.0,  1.0, 1.0,
		1.0, 0.0, 0.0,  1.0, 1.0, 1.0, 1.0,  1.0, 0.0,
		0.0, 0.0, 1.0,  1.0, 1.0, 1.0, 1.0,  0.0, 0.0,
		0.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,  0.0, 1.0,
		1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,  1.0, 1.0,
		1.0, 0.0, 1.0,  1.0, 1.0, 1.0, 1.0,  1.0, 0.0,
	};
	static GLuint itx[] = {0,1,3, 1,2,3, 4,5,7, 5,6,7};

	void start_game() {
		::init_engine(800, 600);

		new Res::Texture((char*)"../Media/terrain.png", 0);
		test_obj = GDrawable::create();
		test_obj->vtx_c = sizeof(vtx) / sizeof(GLfloat);
		test_obj->ind_c = sizeof(itx) / sizeof(GLuint);
		test_obj->vertices = vtx;
		test_obj->indices = itx;
		test_obj->tri_mesh_count = sizeof(itx) / sizeof(GLuint) / 3;
		GDrawable::fbind(test_obj);

		projection = glm::perspective(1.0f, float(VMDE->width) / float(VMDE->height), -1.0f, 1.0f);
		view = glm::lookAt(glm::vec3(2.0, 3.0, 2.0), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));

		loop();
	}

	void terminate() {
		GDrawable::dispose(test_obj);
	}
}

extern "C" {
	void client_terminate() {
		VM76::terminate();
	}
}

int main() {
	log("Starting game");
	VM76::start_game();
}
<|endoftext|>