<commit_before>#include "ovasCPluginExternalStimulations.h"

#include <boost/interprocess/ipc/message_queue.hpp>

#include <vector>
#include <ctime>
#include <iostream>

#include <openvibe/ovITimeArithmetics.h>

#define boolean OpenViBE::boolean

using namespace OpenViBE;
using namespace OpenViBE::Kernel;
using namespace OpenViBEAcquisitionServer;
using namespace OpenViBEAcquisitionServerPlugins;
using namespace std;

CPluginExternalStimulations::CPluginExternalStimulations(const IKernelContext& rKernelContext) :
	IAcquisitionServerPlugin(rKernelContext),
	m_bIsExternalStimulationsEnabled(false)
{
	m_rKernelContext.getLogManager() << LogLevel_Info << "Loading plugin: Software Tagging\n";

	m_oProperties.name = "Software Tagging";

	addSetting<boolean>("Enable External Stimulations", true);
	addSetting<OpenViBE::CString>("External Stimulation Queue Name", "openvibeExternalStimulations");

}

CPluginExternalStimulations::~CPluginExternalStimulations()
{
}

// Hooks

void CPluginExternalStimulations::startHook()
{
	m_bIsExternalStimulationsEnabled = getSetting<boolean>("Enable External Stimulations");

	if (m_bIsExternalStimulationsEnabled)
	{
		m_sExternalStimulationsQueueName = getSetting<OpenViBE::CString>("External Stimulation Queue Name");
		ftime(&m_CTStartTime);
		m_bIsESThreadRunning = true;
		m_ESthreadPtr.reset(new boost::thread( boost::bind(&CPluginExternalStimulations::readExternalStimulations , this )));
		m_rKernelContext.getLogManager() << LogLevel_Info << "Software tagging activated...\n";
	}
	m_vExternalStimulations.clear();

	m_iDebugExternalStimulationsSent=0;
	m_iDebugCurrentReadIPCStimulations = 0;
	m_iDebugStimulationsLost = 0;
	m_iDebugStimulationsReceivedEarlier = 0;
	m_iDebugStimulationsReceivedLate = 0;
	m_iDebugStimulationsReceivedWrongSize = 0;
	m_iDebugStimulationsBuffered = 0;

}

void CPluginExternalStimulations::loopHook(CStimulationSet &stimulationSet, uint64 start, uint64 end)
{
	if (m_bIsExternalStimulationsEnabled)
	{
		//m_rKernelContext.getLogManager() << LogLevel_Error << "Checking for external stimulations:" << p << "\n";
		addExternalStimulations(&stimulationSet,m_rKernelContext.getLogManager(),start,end);
	}

}

void CPluginExternalStimulations::stopHook()
{
	if (m_bIsExternalStimulationsEnabled)
	{
		m_bIsESThreadRunning = false;
		m_ESthreadPtr->join();
	}

	//software tagging diagnosting
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Total external ones received through IPC: " << m_iDebugCurrentReadIPCStimulations << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Sent to Designer: " << m_iDebugExternalStimulationsSent << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Lost because of invalid timestamp: " << m_iDebugStimulationsLost << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Stimulations that came earlier: " << m_iDebugStimulationsReceivedEarlier << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Stimulations that came later: " << 	m_iDebugStimulationsReceivedLate << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Stimulations that had wrong size: " << 	m_iDebugStimulationsReceivedWrongSize << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Buffered: " << 	m_iDebugStimulationsBuffered << "\n";

	int processed=0;
	vector<SExternalStimulation>::iterator cii;
	for(cii=m_vExternalStimulations.begin(); cii!=m_vExternalStimulations.end(); cii++)
	{
		if (cii->isProcessed)
			processed++;
	}
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  processed: " << processed << "\n";
	//end software tagging diagnosting
}

void CPluginExternalStimulations::acceptNewConnectionHook()
{
	m_vExternalStimulations.clear();
}

// Plugin specific methods

void CPluginExternalStimulations::readExternalStimulations()
{
	using namespace boost::interprocess;

	//std::cout << "Creating External Stimulations thread" << std::endl;
	//std::cout << "Queue Name : " << m_sExternalStimulationsQueueName << std::endl;
	//char mq_name[255];
	//std::strcpy(mq_name, m_sExternalStimulationsQueueName.toASCIIString());
	const int chunk_length=3;
	const int pause_time=5;

	unsigned int priority;
	size_t recvd_size;

	uint64 chunk[chunk_length];

	while (m_bIsESThreadRunning)
	{
		bool success = false;
		try
		{
			//Open a message queue.
			message_queue mq
					(open_only  //only open
					 ,m_sExternalStimulationsQueueName.toASCIIString()    //name
					 //,mq_name    //name
					 );

			success = mq.try_receive(&chunk, sizeof(chunk), recvd_size, priority);
		}
		catch(interprocess_exception & /* ex */)
		{
			//m_bIsESThreadRunning = false;
			//m_rKernelContext.getLogManager() << LogLevel_Error << "Problem with message queue in external stimulations:" << ex.what() << "\n";
			boost::this_thread::sleep(boost::posix_time::milliseconds(pause_time));
			continue;
		}

		if (!success)
		{
			boost::this_thread::sleep(boost::posix_time::milliseconds(pause_time));
			continue;
		}

		m_iDebugCurrentReadIPCStimulations++;

		if(recvd_size != sizeof(chunk))
		{
			//m_rKernelContext.getLogManager() << LogLevel_Error << "Problem with type of received data when reqding external stimulation!\n";
			m_iDebugStimulationsReceivedWrongSize++;
		}
		else
		{
			//m_rKernelContext.getLogManager() << LogLevel_Warning << "received\n";

			SExternalStimulation stim;

			stim.identifier = chunk[1];
			uint64 received_time = chunk[2];

			//1. calculate time
			uint64 ct_start_time_ms = (m_CTStartTime.time * 1000 + m_CTStartTime.millitm);

			int64 time_test = received_time - ct_start_time_ms;

			if (time_test<0)
			{
				m_iDebugStimulationsLost++;
				//m_rKernelContext.getLogManager() << LogLevel_Warning <<  "AS: external stimulation time is invalid, probably stimulation is before reference point, total invalid so far: " << m_i32FlashesLost << "\n";
				boost::this_thread::sleep(boost::posix_time::milliseconds(pause_time));
				continue; //we skip this stimulation
			}
			//2. Convert to OpenVibe time
			uint64 ct_event_time = received_time - ct_start_time_ms;

			float64 time = (float64)ct_event_time / (float64)1000;

			uint64 ov_time = ITimeArithmetics::secondsToTime(time);
			stim.timestamp = ov_time;

			stim.alreadyCountedAsEarlier = false;

			//3. Store, the main thread will process it
			{
				//lock
				boost::mutex::scoped_lock lock(m_es_mutex);

				m_vExternalStimulations.push_back(stim);
				m_iDebugStimulationsBuffered++;
				m_esAvailable.notify_one();
				//unlock
			}

			boost::this_thread::sleep(boost::posix_time::milliseconds(pause_time));

		}
	}
}

void CPluginExternalStimulations::addExternalStimulations(OpenViBE::CStimulationSet* ss, OpenViBE::Kernel::ILogManager& logm,uint64 start,uint64 end)
{
	uint64 duration_ms = 40;
	{
		//lock
		boost::mutex::scoped_lock lock(m_es_mutex);

		vector<SExternalStimulation>::iterator cii;

		for(cii=m_vExternalStimulations.begin(); cii!=m_vExternalStimulations.end(); cii++)
		{
			if (cii->isProcessed==true) continue;

			// if time matches current chunk being processed - send it
			if (cii->timestamp >= start && cii->timestamp < end)
			{
				//flashes_in_this_time_chunk++;
				//logm << LogLevel_Error << "Stimulation added." << "\n";
				ss->appendStimulation(cii->identifier, cii->timestamp, duration_ms);
				m_iDebugExternalStimulationsSent++;
				//m_vExternalStimulations.erase(cii);
				cii->isProcessed = true;
			}
			else
				//the stimulation is coming too late - after the current block being processed
				//we correct the timestamp to the current block and we send it
				if (cii->timestamp < start)
				{
					m_iDebugStimulationsReceivedLate++;
					ss->appendStimulation(cii->identifier, start, duration_ms);
					m_iDebugExternalStimulationsSent++;
					//m_vExternalStimulations.erase(cii);
					cii->isProcessed = true;
				}
				else //stim.timestamp > end - coming before the currently processed block, so we still can put in the right place
				{
					//save the stimulation for later
					if (!cii->alreadyCountedAsEarlier)
					{
						m_iDebugStimulationsReceivedEarlier++;
						cii->alreadyCountedAsEarlier = true;
					}
					continue;
				}
		}

		m_esAvailable.notify_one();
		//unlock
	}
}

boolean CPluginExternalStimulations::setExternalStimulationsEnabled(boolean bActive)
{
	m_bIsExternalStimulationsEnabled=bActive;
	return true;
}

boolean CPluginExternalStimulations::isExternalStimulationsEnabled(void)
{
	return m_bIsExternalStimulationsEnabled;
}
<commit_msg>contrib/plugins/external-stimulations: * fixed bug #135, settings in external stimulations are now loaded from the configuration manager<commit_after>#include "ovasCPluginExternalStimulations.h"

#include <boost/interprocess/ipc/message_queue.hpp>

#include <vector>
#include <ctime>
#include <iostream>

#include <openvibe/ovITimeArithmetics.h>

#define boolean OpenViBE::boolean

using namespace OpenViBE;
using namespace OpenViBE::Kernel;
using namespace OpenViBEAcquisitionServer;
using namespace OpenViBEAcquisitionServerPlugins;
using namespace std;

CPluginExternalStimulations::CPluginExternalStimulations(const IKernelContext& rKernelContext) :
	IAcquisitionServerPlugin(rKernelContext),
	m_bIsExternalStimulationsEnabled(false)
{
	m_rKernelContext.getLogManager() << LogLevel_Info << "Loading plugin: Software Tagging\n";

	m_oProperties.name = "Software Tagging";

    IConfigurationManager& l_pConfigurationManager = m_rKernelContext.getConfigurationManager();

    addSetting<boolean>("Enable External Stimulations", l_pConfigurationManager.expandAsBoolean("${AcquisitionServer_ExternalStimulations}", false));
    addSetting<OpenViBE::CString>("External Stimulation Queue Name", l_pConfigurationManager.expand("${AcquisitionServer_ExternalStimulationsQueueName}"));

}

CPluginExternalStimulations::~CPluginExternalStimulations()
{
}

// Hooks

void CPluginExternalStimulations::startHook()
{
	m_bIsExternalStimulationsEnabled = getSetting<boolean>("Enable External Stimulations");

	if (m_bIsExternalStimulationsEnabled)
	{
		m_sExternalStimulationsQueueName = getSetting<OpenViBE::CString>("External Stimulation Queue Name");
		ftime(&m_CTStartTime);
		m_bIsESThreadRunning = true;
		m_ESthreadPtr.reset(new boost::thread( boost::bind(&CPluginExternalStimulations::readExternalStimulations , this )));
		m_rKernelContext.getLogManager() << LogLevel_Info << "Software tagging activated...\n";
	}
	m_vExternalStimulations.clear();

	m_iDebugExternalStimulationsSent=0;
	m_iDebugCurrentReadIPCStimulations = 0;
	m_iDebugStimulationsLost = 0;
	m_iDebugStimulationsReceivedEarlier = 0;
	m_iDebugStimulationsReceivedLate = 0;
	m_iDebugStimulationsReceivedWrongSize = 0;
	m_iDebugStimulationsBuffered = 0;

}

void CPluginExternalStimulations::loopHook(CStimulationSet &stimulationSet, uint64 start, uint64 end)
{
	if (m_bIsExternalStimulationsEnabled)
	{
		//m_rKernelContext.getLogManager() << LogLevel_Error << "Checking for external stimulations:" << p << "\n";
		addExternalStimulations(&stimulationSet,m_rKernelContext.getLogManager(),start,end);
	}

}

void CPluginExternalStimulations::stopHook()
{
	if (m_bIsExternalStimulationsEnabled)
	{
		m_bIsESThreadRunning = false;
		m_ESthreadPtr->join();
	}

	//software tagging diagnosting
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Total external ones received through IPC: " << m_iDebugCurrentReadIPCStimulations << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Sent to Designer: " << m_iDebugExternalStimulationsSent << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Lost because of invalid timestamp: " << m_iDebugStimulationsLost << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Stimulations that came earlier: " << m_iDebugStimulationsReceivedEarlier << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Stimulations that came later: " << 	m_iDebugStimulationsReceivedLate << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Stimulations that had wrong size: " << 	m_iDebugStimulationsReceivedWrongSize << "\n";
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  Buffered: " << 	m_iDebugStimulationsBuffered << "\n";

	int processed=0;
	vector<SExternalStimulation>::iterator cii;
	for(cii=m_vExternalStimulations.begin(); cii!=m_vExternalStimulations.end(); cii++)
	{
		if (cii->isProcessed)
			processed++;
	}
	m_rKernelContext.getLogManager() << LogLevel_Debug << "  processed: " << processed << "\n";
	//end software tagging diagnosting
}

void CPluginExternalStimulations::acceptNewConnectionHook()
{
	m_vExternalStimulations.clear();
}

// Plugin specific methods

void CPluginExternalStimulations::readExternalStimulations()
{
	using namespace boost::interprocess;

	//std::cout << "Creating External Stimulations thread" << std::endl;
	//std::cout << "Queue Name : " << m_sExternalStimulationsQueueName << std::endl;
	//char mq_name[255];
	//std::strcpy(mq_name, m_sExternalStimulationsQueueName.toASCIIString());
	const int chunk_length=3;
	const int pause_time=5;

	unsigned int priority;
	size_t recvd_size;

	uint64 chunk[chunk_length];

	while (m_bIsESThreadRunning)
	{
		bool success = false;
		try
		{
			//Open a message queue.
			message_queue mq
					(open_only  //only open
					 ,m_sExternalStimulationsQueueName.toASCIIString()    //name
					 //,mq_name    //name
					 );

			success = mq.try_receive(&chunk, sizeof(chunk), recvd_size, priority);
		}
		catch(interprocess_exception & /* ex */)
		{
			//m_bIsESThreadRunning = false;
			//m_rKernelContext.getLogManager() << LogLevel_Error << "Problem with message queue in external stimulations:" << ex.what() << "\n";
			boost::this_thread::sleep(boost::posix_time::milliseconds(pause_time));
			continue;
		}

		if (!success)
		{
			boost::this_thread::sleep(boost::posix_time::milliseconds(pause_time));
			continue;
		}

		m_iDebugCurrentReadIPCStimulations++;

		if(recvd_size != sizeof(chunk))
		{
			//m_rKernelContext.getLogManager() << LogLevel_Error << "Problem with type of received data when reqding external stimulation!\n";
			m_iDebugStimulationsReceivedWrongSize++;
		}
		else
		{
			//m_rKernelContext.getLogManager() << LogLevel_Warning << "received\n";

			SExternalStimulation stim;

			stim.identifier = chunk[1];
			uint64 received_time = chunk[2];

			//1. calculate time
			uint64 ct_start_time_ms = (m_CTStartTime.time * 1000 + m_CTStartTime.millitm);

			int64 time_test = received_time - ct_start_time_ms;

			if (time_test<0)
			{
				m_iDebugStimulationsLost++;
				//m_rKernelContext.getLogManager() << LogLevel_Warning <<  "AS: external stimulation time is invalid, probably stimulation is before reference point, total invalid so far: " << m_i32FlashesLost << "\n";
				boost::this_thread::sleep(boost::posix_time::milliseconds(pause_time));
				continue; //we skip this stimulation
			}
			//2. Convert to OpenVibe time
			uint64 ct_event_time = received_time - ct_start_time_ms;

			float64 time = (float64)ct_event_time / (float64)1000;

			uint64 ov_time = ITimeArithmetics::secondsToTime(time);
			stim.timestamp = ov_time;

			stim.alreadyCountedAsEarlier = false;

			//3. Store, the main thread will process it
			{
				//lock
				boost::mutex::scoped_lock lock(m_es_mutex);

				m_vExternalStimulations.push_back(stim);
				m_iDebugStimulationsBuffered++;
				m_esAvailable.notify_one();
				//unlock
			}

			boost::this_thread::sleep(boost::posix_time::milliseconds(pause_time));

		}
	}
}

void CPluginExternalStimulations::addExternalStimulations(OpenViBE::CStimulationSet* ss, OpenViBE::Kernel::ILogManager& logm,uint64 start,uint64 end)
{
	uint64 duration_ms = 40;
	{
		//lock
		boost::mutex::scoped_lock lock(m_es_mutex);

		vector<SExternalStimulation>::iterator cii;

		for(cii=m_vExternalStimulations.begin(); cii!=m_vExternalStimulations.end(); cii++)
		{
			if (cii->isProcessed==true) continue;

			// if time matches current chunk being processed - send it
			if (cii->timestamp >= start && cii->timestamp < end)
			{
				//flashes_in_this_time_chunk++;
				//logm << LogLevel_Error << "Stimulation added." << "\n";
				ss->appendStimulation(cii->identifier, cii->timestamp, duration_ms);
				m_iDebugExternalStimulationsSent++;
				//m_vExternalStimulations.erase(cii);
				cii->isProcessed = true;
			}
			else
				//the stimulation is coming too late - after the current block being processed
				//we correct the timestamp to the current block and we send it
				if (cii->timestamp < start)
				{
					m_iDebugStimulationsReceivedLate++;
					ss->appendStimulation(cii->identifier, start, duration_ms);
					m_iDebugExternalStimulationsSent++;
					//m_vExternalStimulations.erase(cii);
					cii->isProcessed = true;
				}
				else //stim.timestamp > end - coming before the currently processed block, so we still can put in the right place
				{
					//save the stimulation for later
					if (!cii->alreadyCountedAsEarlier)
					{
						m_iDebugStimulationsReceivedEarlier++;
						cii->alreadyCountedAsEarlier = true;
					}
					continue;
				}
		}

		m_esAvailable.notify_one();
		//unlock
	}
}

boolean CPluginExternalStimulations::setExternalStimulationsEnabled(boolean bActive)
{
	m_bIsExternalStimulationsEnabled=bActive;
	return true;
}

boolean CPluginExternalStimulations::isExternalStimulationsEnabled(void)
{
	return m_bIsExternalStimulationsEnabled;
}
<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 *
 * logger.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/logging/logger.cpp
 *
 *-------------------------------------------------------------------------
 */

#include "backend/logging/logger.h"

namespace peloton {
namespace logging {

/**
 * @brief Run logging_MainLoop to receive log record and flush
 */
void Logger::logging_MainLoop(void){
  proxy->logging_MainLoop();
}

/**
 * @brief Run logging_MainLoop to receive log record and flush
 */
void Logger::log(LogRecord record){
  proxy->log(record);
}

/**
 * @brief Run logging_MainLoop to receive log record and flush
 */
void Logger::flush(void){
  proxy->flush();
}

}  // namespace logging
}  // namespace peloton

<commit_msg>Minor refactoring<commit_after>/*-------------------------------------------------------------------------
 *
 * logger.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/logging/logger.cpp
 *
 *-------------------------------------------------------------------------
 */

#include "backend/logging/logger.h"

namespace peloton {
namespace logging {

/**
 * @brief Run logging_MainLoop
 */
void Logger::logging_MainLoop(void){
  proxy->logging_MainLoop();
}

/**
 * @brief Run log
 * @param record
 */
void Logger::log(LogRecord record){
  proxy->log(record);
}

/**
 * @brief Run flush
 */
void Logger::flush(void){
  proxy->flush();
}

}  // namespace logging
}  // namespace peloton

<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////////
//                                                                         	//
//   Ludic Game Library                                                    	//
//   Copyright (C)2014 - Michell Stuttgart Faria                          	//
//                       Paulo Vicente Gomes dos Santos				        //
//                       Alfredo José de Paula Barbosa                      //
//                                                                         	//
//   Ludic is a FREE SOFTWARE released under the BSD License.              	//
//                                                                         	//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "ludic.hpp"

namespace Ludic {

/**
 * @file AllegroStarter.hpp
 * @author Michell Stuttgart
 * @date 01/09/14
 * @class AllegroStarter
 * @brief Class responsible for initializing the basic modules
 * of the Allegro, Allegro_Image, Allegro_Font, Allegro_Audio
 * and Allegro_Primitives.
 * It is called automatically by Ludic Library
 * in early in the program. This is a class for the exclusive
 * use of the library.
 */
class AllegroStarter {

private:

	static AllegroStarter instance;

	/**
	* @brief Default Constructor.
	*/
	AllegroStarter();

public:

	/**
	 * @brief Default Destructor
	 */
	virtual ~AllegroStarter();

};

} /* sgl namespace */
<commit_msg>Doxygen comment updated<commit_after>//////////////////////////////////////////////////////////////////////////////
//                                                                         	//
//   Ludic Game Library                                                    	//
//   Copyright (C)2014 - Michell Stuttgart Faria                          	//
//                       Paulo Vicente Gomes dos Santos				        //
//                       Alfredo José de Paula Barbosa                      //
//                                                                         	//
//   Ludic is a FREE SOFTWARE released under the BSD License.              	//
//                                                                         	//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "ludic.hpp"

namespace Ludic {

/**
 * @file AllegroStarter.hpp
 * @author Michell Stuttgart
 * @date 01/09/14
 * @class AllegroStarter
 * @brief Class responsible for initializing the basic modules of the Allegro.
 *
 * The basic modules are: Allegro_Image, Allegro_Font, Allegro_Audio
 * and Allegro_Primitives.
 * It is called automatically by Ludic Library
 * in early in the program. This is a class for the exclusive
 * use of the library.
 */
class AllegroStarter {

private:

	static AllegroStarter instance;

	/**
	* @brief Default Constructor.
	*/
	AllegroStarter();

public:

	/**
	 * @brief Default Destructor
	 */
	virtual ~AllegroStarter();

};

} /* sgl namespace */
<|endoftext|>


<commit_before>/***************************************************************************//**
 * FILE : timekeeper.hpp
 */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is libZinc.
 *
 * The Initial Developer of the Original Code is
 * Auckland Uniservices Ltd, Auckland, New Zealand.
 * Portions created by the Initial Developer are Copyright (C) 2012
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */
#ifndef __ZN_TIME_KEEPER_HPP__
#define __ZN_TIME_KEEPER_HPP__

#include "zinc/timekeeper.h"
#include "zinc/timenotifier.hpp"

namespace zinc
{

class TimeKeeper
{
protected:
	Cmiss_time_keeper_id id;

public:

	TimeKeeper() : id(0)
	{   }

	// takes ownership of C handle, responsibility for destroying it
	explicit TimeKeeper(Cmiss_time_keeper_id in_time_keeper_id) :
		id(in_time_keeper_id)
	{  }

	TimeKeeper(const TimeKeeper& timeKeeper) :
		id(Cmiss_time_keeper_access(timeKeeper.id))
	{  }

	TimeKeeper& operator=(const TimeKeeper& timeKeeper)
	{
		Cmiss_time_keeper_id temp_id = Cmiss_time_keeper_access(timeKeeper.id);
		if (0 != id)
		{
			Cmiss_time_keeper_destroy(&id);
		}
		id = temp_id;
		return *this;
	}

	~TimeKeeper()
	{
		if (0 != id)
		{
			Cmiss_time_keeper_destroy(&id);
		}
	}

	bool isValid()
	{
		return (0 != id);
	}

	Cmiss_time_keeper_id getId()
	{
		return id;
	}

	enum Attribute
	{
		ATTRIBUTE_INVALID = CMISS_TIME_KEEPER_ATTRIBUTE_INVALID,
		ATTRIBUTE_TIME = CMISS_TIME_KEEPER_ATTRIBUTE_TIME,
		ATTRIBUTE_MINIMUM_TIME = CMISS_TIME_KEEPER_ATTRIBUTE_MINIMUM_TIME,
		ATTRIBUTE_MAXIMUM_TIME = CMISS_TIME_KEEPER_ATTRIBUTE_MAXIMUM_TIME,
		ATTRIBUTE_SPEED = CMISS_TIME_KEEPER_ATTRIBUTE_SPEED
	};

	int getAttributeReal(Attribute attribute)
	{
		return Cmiss_time_keeper_get_attribute_real(id,
			static_cast<Cmiss_time_keeper_attribute>(attribute));
	}

	int setAttributeReal(Attribute attribute, double value)
	{
		return Cmiss_time_keeper_set_attribute_real(id,
			static_cast<Cmiss_time_keeper_attribute>(attribute), value);
	}

	TimeNotifier createNotifierRegular(double updateFrequency, double timeOffset)
	{
		return TimeNotifier(Cmiss_time_keeper_create_notifier_regular(
			id, updateFrequency, timeOffset));
	}

	int addTimeNotifier(TimeNotifier timeNotifier)
	{
		return Cmiss_time_keeper_add_time_notifier(id, timeNotifier.getId());
	}

	int removeTimeNotifier(TimeNotifier timeNotifier)
	{
		return Cmiss_time_keeper_remove_time_notifier(id, timeNotifier.getId());
	}

};

}  // namespace zinc

#endif /* __ZN_TIME_KEEPER_HPP__ */
<commit_msg>Removing CMISS_TIME_KEEPER_ATTRIBUTE_SPEED from the C++ API.  https://tracker.physiomeproject.org/show_bug.cgi?id=3528<commit_after>/***************************************************************************//**
 * FILE : timekeeper.hpp
 */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is libZinc.
 *
 * The Initial Developer of the Original Code is
 * Auckland Uniservices Ltd, Auckland, New Zealand.
 * Portions created by the Initial Developer are Copyright (C) 2012
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */
#ifndef __ZN_TIME_KEEPER_HPP__
#define __ZN_TIME_KEEPER_HPP__

#include "zinc/timekeeper.h"
#include "zinc/timenotifier.hpp"

namespace zinc
{

class TimeKeeper
{
protected:
	Cmiss_time_keeper_id id;

public:

	TimeKeeper() : id(0)
	{   }

	// takes ownership of C handle, responsibility for destroying it
	explicit TimeKeeper(Cmiss_time_keeper_id in_time_keeper_id) :
		id(in_time_keeper_id)
	{  }

	TimeKeeper(const TimeKeeper& timeKeeper) :
		id(Cmiss_time_keeper_access(timeKeeper.id))
	{  }

	TimeKeeper& operator=(const TimeKeeper& timeKeeper)
	{
		Cmiss_time_keeper_id temp_id = Cmiss_time_keeper_access(timeKeeper.id);
		if (0 != id)
		{
			Cmiss_time_keeper_destroy(&id);
		}
		id = temp_id;
		return *this;
	}

	~TimeKeeper()
	{
		if (0 != id)
		{
			Cmiss_time_keeper_destroy(&id);
		}
	}

	bool isValid()
	{
		return (0 != id);
	}

	Cmiss_time_keeper_id getId()
	{
		return id;
	}

	enum Attribute
	{
		ATTRIBUTE_INVALID = CMISS_TIME_KEEPER_ATTRIBUTE_INVALID,
		ATTRIBUTE_TIME = CMISS_TIME_KEEPER_ATTRIBUTE_TIME,
		ATTRIBUTE_MINIMUM_TIME = CMISS_TIME_KEEPER_ATTRIBUTE_MINIMUM_TIME,
		ATTRIBUTE_MAXIMUM_TIME = CMISS_TIME_KEEPER_ATTRIBUTE_MAXIMUM_TIME
	};

	int getAttributeReal(Attribute attribute)
	{
		return Cmiss_time_keeper_get_attribute_real(id,
			static_cast<Cmiss_time_keeper_attribute>(attribute));
	}

	int setAttributeReal(Attribute attribute, double value)
	{
		return Cmiss_time_keeper_set_attribute_real(id,
			static_cast<Cmiss_time_keeper_attribute>(attribute), value);
	}

	TimeNotifier createNotifierRegular(double updateFrequency, double timeOffset)
	{
		return TimeNotifier(Cmiss_time_keeper_create_notifier_regular(
			id, updateFrequency, timeOffset));
	}

	int addTimeNotifier(TimeNotifier timeNotifier)
	{
		return Cmiss_time_keeper_add_time_notifier(id, timeNotifier.getId());
	}

	int removeTimeNotifier(TimeNotifier timeNotifier)
	{
		return Cmiss_time_keeper_remove_time_notifier(id, timeNotifier.getId());
	}

};

}  // namespace zinc

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


<commit_before>/*
 *  SliderWithLabel.cpp
 *  iPhoneEmptyExample
 *
 *  Created by hansi on 29.01.11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 * ------------------------------
 *  PLEASE READ BEFORE YOU CODE:
 *
 *  This is a simple container thingie.
 *  You can use it exactly like an OF main app, there are only small differences in how touch events work.
 *  1. If you don't want an event to propagate to other containers just do a "return true;" at then end.
 *  2. A container will only be notified of events that happen within it's bounds
 *  3. If you do a "return true" at the end of touchDown() your container will be remembered and will then
 *     receive all moved(), doubleTap() and touchUp() events, even if they happen outside the container.
 *  4. The coordinates touch.x and touch.y are modified to match the drawing coordinate system, so 0/0 is at the
 *     left top corner of your container, not top left corner of your application.
 */

#include "MUI.h"

mui::SliderWithLabel::SliderWithLabel( float x_, float y_, float width_, float height_, float min_, float max_, float value_, int decimalPlaces_ ) : Container( x_, y_, width_, height_ ), decimalPlaces(decimalPlaces_), oldValue(-9999) {
	slider = new Slider( 0, 0, width_ - 40, height_, min_, max_, value_ );
	label = new Label( ofToString(max_), width_ - 35, 0, 35, height_ );
	label->width = label->boundingBox.width + 5;
	ofColor col;
	col.r = col.g = col.b = 0;
	label->fg = col;
	label->horizontalAlign = Right;
	defaultValue = value_;

	add( slider );
	add( label );
}

//--------------------------------------------------------------
void mui::SliderWithLabel::update(){
	slider->width = width - 5 - label->width;
	slider->height = height;
	label->x = width - label->width;
	if( oldValue != slider->value ){
		label->text = ofToString( slider->value, decimalPlaces );
		label->commit();
		oldValue = slider->value;
	}
}

//--------------------------------------------------------------
void mui::SliderWithLabel::draw(){
}

//--------------------------------------------------------------
void mui::SliderWithLabel::drawBackground(){
}<commit_msg>fixed layout bug in sliderwithlabel (width of decimal places wasn't calculated correctly)<commit_after>/*
 *  SliderWithLabel.cpp
 *  iPhoneEmptyExample
 *
 *  Created by hansi on 29.01.11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 * ------------------------------
 *  PLEASE READ BEFORE YOU CODE:
 *
 *  This is a simple container thingie.
 *  You can use it exactly like an OF main app, there are only small differences in how touch events work.
 *  1. If you don't want an event to propagate to other containers just do a "return true;" at then end.
 *  2. A container will only be notified of events that happen within it's bounds
 *  3. If you do a "return true" at the end of touchDown() your container will be remembered and will then
 *     receive all moved(), doubleTap() and touchUp() events, even if they happen outside the container.
 *  4. The coordinates touch.x and touch.y are modified to match the drawing coordinate system, so 0/0 is at the
 *     left top corner of your container, not top left corner of your application.
 */

#include "MUI.h"

mui::SliderWithLabel::SliderWithLabel( float x_, float y_, float width_, float height_, float min_, float max_, float value_, int decimalPlaces_ ) : Container( x_, y_, width_, height_ ), decimalPlaces(decimalPlaces_), oldValue(-9999) {
	slider = new Slider( 0, 0, width_ - 40, height_, min_, max_, value_ );
	label = new Label( ofToString(max_,decimalPlaces), width_ - 35, 0, 35, height_ );
	label->width = label->boundingBox.width + 5;
	ofColor col;
	col.r = col.g = col.b = 0;
	label->fg = col;
	label->horizontalAlign = Right;
	defaultValue = value_;

	add( slider );
	add( label );
}

//--------------------------------------------------------------
void mui::SliderWithLabel::update(){
	slider->width = width - 5 - label->width;
	slider->height = height;
	label->x = width - label->width;
	if( oldValue != slider->value ){
		label->text = ofToString( slider->value, decimalPlaces );
		label->commit();
		oldValue = slider->value;
	}
}

//--------------------------------------------------------------
void mui::SliderWithLabel::draw(){
}

//--------------------------------------------------------------
void mui::SliderWithLabel::drawBackground(){
}<|endoftext|>


<commit_before>#if defined(WINVER)
#include <windows.h>
#endif

#ifdef __DJGPP__
#else
const long UCLOCKS_PER_SEC = 1000;

long uclock();

#endif

#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <functional>
#include <unordered_map>
#include <memory>
#include <utility>
#include <map>
#include <algorithm>
#include <chrono>

#ifdef __EMSCRIPTEN__
#include <emscripten/html5.h>
#include <emscripten/emscripten.h>
#endif

enum class ESoundDriver {
    kNone, kPcSpeaker, kOpl2Lpt, kAdlib, kTandy, kCovox
};

ESoundDriver soundDriver = ESoundDriver::kNone;
void initOPL2(int port);
void playTune(const std::string &);

///game interface
void init();
void loopTick(long ms);
void shutdown();
bool  isPlaying();
///
#ifdef __EMSCRIPTEN__
void emscriptenLoopTick() {
    loopTick(50);
}
#endif

#ifdef __APPLE__
int main(int argc, char **argv) {
#else

#if defined(WINVER)

namespace odb {
    LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{

        HINSTANCE hInst;

        WNDCLASSEX WndCls;
        static char szAppName[] = "DungeonsOfNoudar95";
        MSG Msg;

        hInst = hInstance;
        WndCls.cbSize = sizeof(WndCls);
        WndCls.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
        WndCls.lpfnWndProc = odb::WindProcedure;
        WndCls.cbClsExtra = 0;
        WndCls.cbWndExtra = 0;
        WndCls.hInstance = hInst;
        WndCls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        WndCls.hCursor = LoadCursor(NULL, IDC_ARROW);
        WndCls.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
        WndCls.lpszMenuName = NULL;
        WndCls.lpszClassName = szAppName;
        WndCls.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
        RegisterClassEx(&WndCls);

        CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                       szAppName,
                       "Dungeons of Noudar 95",
                       WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       320,
                       240,
                       NULL,
                       NULL,
                       hInstance,
                       NULL);

#else

int main(int argc, char **argv) {
    puts("Dungeons of Noudar 3D startup.\nCopyright 2016-2020 Brotherhood of 13h.");

    if (argc >= 2) {
        if (!std::strcmp(argv[1], "opl2lpt")) {
            soundDriver = ESoundDriver::kOpl2Lpt;
            initOPL2(-1);
            playTune("t200i101o1a");
        } else if (!std::strcmp(argv[1], "adlib")) {
            soundDriver = ESoundDriver::kAdlib;
            initOPL2(0x0388);
            playTune("t200i101o1a");
        } else if (!std::strcmp(argv[1], "pcspeaker")) {
            soundDriver = ESoundDriver::kPcSpeaker;
        }
    }
#endif

#endif

    init();

#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop(emscriptenLoopTick, 20, 1);
#else
    clock_t diff = 0;

    while (isPlaying()) {
        clock_t t0 = 0;
        clock_t t1 = 0;

        t0 = uclock();

        loopTick(diff);

        t1 = uclock();

        diff = (1000 * (t1 - t0)) / UCLOCKS_PER_SEC;

        if (diff == 0) {
            diff = 1;
        }
    }
#endif

    shutdown();

    return 0;
}
<commit_msg>Add a very simply sound driver selection menu to DOS versions startup<commit_after>#if defined(WINVER)
#include <windows.h>
#endif

#ifdef __DJGPP__
#include <conio.h>
#include <dpmi.h>
#include <go32.h>
#include <pc.h>
#include <bios.h>
#else
const long UCLOCKS_PER_SEC = 1000;

long uclock();

#endif

#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <functional>
#include <unordered_map>
#include <memory>
#include <utility>
#include <map>
#include <algorithm>
#include <chrono>

#ifdef __EMSCRIPTEN__
#include <emscripten/html5.h>
#include <emscripten/emscripten.h>
#endif

enum class ESoundDriver {
    kNone, kPcSpeaker, kOpl2Lpt, kAdlib, kTandy, kCovox
};

ESoundDriver soundDriver = ESoundDriver::kNone;
void initOPL2(int port);
void playTune(const std::string &);

///game interface
void init();
void loopTick(long ms);
void shutdown();
bool  isPlaying();
///
#ifdef __EMSCRIPTEN__
void emscriptenLoopTick() {
    loopTick(50);
}
#endif

#ifdef __APPLE__
int main(int argc, char **argv) {
#else

#if defined(WINVER)

namespace odb {
    LRESULT CALLBACK WindProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)
{

        HINSTANCE hInst;

        WNDCLASSEX WndCls;
        static char szAppName[] = "DungeonsOfNoudar95";
        MSG Msg;

        hInst = hInstance;
        WndCls.cbSize = sizeof(WndCls);
        WndCls.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
        WndCls.lpfnWndProc = odb::WindProcedure;
        WndCls.cbClsExtra = 0;
        WndCls.cbWndExtra = 0;
        WndCls.hInstance = hInst;
        WndCls.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        WndCls.hCursor = LoadCursor(NULL, IDC_ARROW);
        WndCls.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
        WndCls.lpszMenuName = NULL;
        WndCls.lpszClassName = szAppName;
        WndCls.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
        RegisterClassEx(&WndCls);

        CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                       szAppName,
                       "Dungeons of Noudar 95",
                       WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                       CW_USEDEFAULT,
                       CW_USEDEFAULT,
                       320,
                       240,
                       NULL,
                       NULL,
                       hInstance,
                       NULL);

#else

int main(int argc, char **argv) {
    puts("\n\nDungeons of Noudar 3D startup.\nCopyright 2016-2022 Brotherhood of 13h.");

    if (argc >= 2) {
        if (!std::strcmp(argv[1], "opl2lpt")) {
            soundDriver = ESoundDriver::kOpl2Lpt;
            initOPL2(-1);
            playTune("t200i101o1a");
        } else if (!std::strcmp(argv[1], "adlib")) {
            soundDriver = ESoundDriver::kAdlib;
            initOPL2(0x0388);
            playTune("t200i101o1a");
        } else if (!std::strcmp(argv[1], "pcspeaker")) {
            soundDriver = ESoundDriver::kPcSpeaker;
        }
    } else {
        puts("\n\nPlease select a sound driver:");
        puts("1 - PC Speaker");
        puts("2 - Adlib");
        puts("3 - OPL2LPT on LPT1");
        puts("4 - No sound");
        puts("5 - Quit");

        uint8_t selection = getch();

        switch( selection ) {
            case '1':
                soundDriver = ESoundDriver::kPcSpeaker;
                break;

            case '2':
                soundDriver = ESoundDriver::kAdlib;
                initOPL2(0x0388);
                playTune("t200i101o1a");
                break;

            case '3':
                soundDriver = ESoundDriver::kOpl2Lpt;
                initOPL2(-1);
                playTune("t200i101o1a");
                break;

            case '4':
                break;
            case '5':
                exit(0);
                return 0;
        }
    }
#endif

#endif

    init();

#ifdef __EMSCRIPTEN__
    emscripten_set_main_loop(emscriptenLoopTick, 20, 1);
#else
    clock_t diff = 0;

    while (isPlaying()) {
        clock_t t0 = 0;
        clock_t t1 = 0;

        t0 = uclock();

        loopTick(diff);

        t1 = uclock();

        diff = (1000 * (t1 - t0)) / UCLOCKS_PER_SEC;

        if (diff == 0) {
            diff = 1;
        }
    }
#endif

    shutdown();

    return 0;
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <stego-crypt-lib/stego-crypt-lib.hh>

TEST(StegStub, oneEqualsone) {
  int one = 1;
  EXPECT_EQ(1, one);
}

TEST(BmpTests, Validation) {
  std::ifstream ifs("test/stego-crypt/test.bmp", std::ios::binary);
  std::ostringstream ost;
  ost << ifs.rdbuf();
  std::string bmp(ost.str());
  EXPECT_EQ(true, is_bmp_valid(bmp));
}

TEST(BmpTests, Open) {
  bmp_t bmp = open_bmp("test/stego-crypt/test.bmp");
  EXPECT_EQ(true, is_bmp_valid(bmp));
}

TEST(BmpTests, BitsPerPixel) {
  bmp_t bmp = open_bmp("test/stego-crypt/test.bmp");
  EXPECT_EQ(8, bmp_bits_per_pixel(bmp));
}

TEST(BmpTests, ImageOffset) {
  bmp_t bmp = open_bmp("test/stego-crypt/test.bmp");
  unsigned offset = bmp_image_offset(bmp);
  // test.bmp is 8-bit and is 512*512
  EXPECT_EQ(512*512, bmp.size() - offset);
}
<commit_msg>Wrote failing tests for bmp height and width<commit_after>#include <gtest/gtest.h>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <stego-crypt-lib/stego-crypt-lib.hh>

TEST(StegStub, oneEqualsone) {
  int one = 1;
  EXPECT_EQ(1, one);
}

TEST(BmpTests, Validation) {
  std::ifstream ifs("test/stego-crypt/test.bmp", std::ios::binary);
  std::ostringstream ost;
  ost << ifs.rdbuf();
  std::string bmp(ost.str());
  EXPECT_EQ(true, is_bmp_valid(bmp));
}

TEST(BmpTests, Open) {
  bmp_t bmp = open_bmp("test/stego-crypt/test.bmp");
  EXPECT_EQ(true, is_bmp_valid(bmp));
}

TEST(BmpTests, BitsPerPixel) {
  bmp_t bmp = open_bmp("test/stego-crypt/test.bmp");
  EXPECT_EQ(8, bmp_bits_per_pixel(bmp));
}

TEST(BmpTests, Dimensions) {
  bmp_t bmp = open_bmp("test/stego-crypt/test.bmp");
  EXPECT_EQ(512, bmp_width(bmp));
  EXPECT_EQ(512, bmp_height(bmp));
}

TEST(BmpTests, ImageOffset) {
  bmp_t bmp = open_bmp("test/stego-crypt/test.bmp");
  unsigned offset = bmp_image_offset(bmp);
  // test.bmp is 8-bit and is 512*512
  EXPECT_EQ(512*512, bmp.size() - offset);
}
<|endoftext|>


<commit_before>/* +---------------------------------------------------------------------------+
   |                 The Mobile Robot Programming Toolkit (MRPT)               |
   |                                                                           |
   |                          http://www.mrpt.org/                             |
   |                                                                           |
   | Copyright (c) 2005-2013, Individual contributors, see AUTHORS file        |
   | Copyright (c) 2005-2013, MAPIR group, University of Malaga                |
   | Copyright (c) 2012-2013, University of Almeria                            |
   | All rights reserved.                                                      |
   |                                                                           |
   | Redistribution and use in source and binary forms, with or without        |
   | modification, are permitted provided that the following conditions are    |
   | met:                                                                      |
   |    * Redistributions of source code must retain the above copyright       |
   |      notice, this list of conditions and the following disclaimer.        |
   |    * Redistributions in binary form must reproduce the above copyright    |
   |      notice, this list of conditions and the following disclaimer in the  |
   |      documentation and/or other materials provided with the distribution. |
   |    * Neither the name of the copyright holders nor the                    |
   |      names of its contributors may be used to endorse or promote products |
   |      derived from this software without specific prior written permission.|
   |                                                                           |
   | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       |
   | 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
   | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR|
   | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE |
   | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL|
   | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR|
   |  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)       |
   | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,       |
   | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN  |
   | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           |
   | POSSIBILITY OF SUCH DAMAGE.                                               |
   +---------------------------------------------------------------------------+ */

#include <mrpt/hwdrivers/CSickLaserSerial.h>
#include <mrpt/gui.h>
#include <mrpt/maps.h>

using namespace mrpt;
using namespace mrpt::utils;
using namespace mrpt::slam;
using namespace mrpt::gui;
using namespace mrpt::opengl;
using namespace mrpt::hwdrivers;
using namespace std;

string SERIAL_NAME;	// Name of the serial port to open

// ------------------------------------------------------
//				Test_PLS
// ------------------------------------------------------
void TestPLS()
{
	CSickLaserSerial	laser;

	cout << "SICK LMS thru serial port test application." << endl << endl;

	if (SERIAL_NAME.empty())
	{
        cout << "Enter the serial port name (e.g. COM1, ttyS0, ttyUSB0, ttyACM0): ";
        getline(cin,SERIAL_NAME);
	}
	else
	{
        cout << "Using serial port: " << SERIAL_NAME << endl;
	}

	laser.setSerialPort(SERIAL_NAME);

#if 1
	laser.setBaudRate(500000);
	//laser.setBaudRate(38400);
	laser.setScanFOV(180);
	laser.setScanResolution(50);  // 25=0.25deg, 50=0.5deg, 100=1deg
	//laser.setMillimeterMode(true);
#endif

#if MRPT_HAS_WXWIDGETS
	CDisplayWindowPlots		win("Laser scans");
#endif

	// Load config:
	//laser.loadConfig( CConfigFile( "./LASER_SCAN_TEST.ini") ,"PLS#1" );

	cout << "Trying to initialize the laser..." << endl;
	laser.initialize(); // This will raise an exception on error
	cout << "Initialized OK!" << endl;

	while (!mrpt::system::os::kbhit())
	{
		bool						thereIsObservation,hardError;
		CObservation2DRangeScan		obs;

		try
		{
			laser.doProcessSimple( thereIsObservation, obs, hardError );
		}
		catch (std::exception &e)
		{
			cerr << e.what() << endl;
			hardError = true;
		}

		if (hardError)
			printf("[TEST] Hardware error=true!!\n");

		if (thereIsObservation)
		{
			printf("[TEST] Observation received (%u ranges over %.02fdeg, mid=%.03f)!!\n",
				(unsigned int)obs.scan.size(),
				RAD2DEG(obs.aperture),
				obs.scan[obs.scan.size()/2]);

			obs.sensorPose = CPose3D(0,0,0);
			mrpt::slam::CSimplePointsMap		theMap;
			theMap.insertionOptions.minDistBetweenLaserPoints	= 0;
			theMap.insertObservation( &obs );

#if MRPT_HAS_WXWIDGETS
			vector_float	xs,ys,zs;
			theMap.getAllPoints(xs,ys,zs);
			win.plot(xs,ys,".b3");
			win.axis_equal();
#endif
		}
		mrpt::system::sleep(15);
	};

	laser.turnOff();
}

int main(int argc, char **argv)
{
	try
	{
	    if (argc>1)
        {
            SERIAL_NAME = string(argv[1]);
        }

		TestPLS();
		return 0;

	} catch (std::exception &e)
	{
		std::cout << "EXCEPCION: " << e.what() << std::endl;
		return -1;
	}
	catch (...)
	{
		printf("Another exception!!");
		return -1;
	}

}

<commit_msg>SICK laser example: more common parameters by default<commit_after>/* +---------------------------------------------------------------------------+
   |                 The Mobile Robot Programming Toolkit (MRPT)               |
   |                                                                           |
   |                          http://www.mrpt.org/                             |
   |                                                                           |
   | Copyright (c) 2005-2013, Individual contributors, see AUTHORS file        |
   | Copyright (c) 2005-2013, MAPIR group, University of Malaga                |
   | Copyright (c) 2012-2013, University of Almeria                            |
   | All rights reserved.                                                      |
   |                                                                           |
   | Redistribution and use in source and binary forms, with or without        |
   | modification, are permitted provided that the following conditions are    |
   | met:                                                                      |
   |    * Redistributions of source code must retain the above copyright       |
   |      notice, this list of conditions and the following disclaimer.        |
   |    * Redistributions in binary form must reproduce the above copyright    |
   |      notice, this list of conditions and the following disclaimer in the  |
   |      documentation and/or other materials provided with the distribution. |
   |    * Neither the name of the copyright holders nor the                    |
   |      names of its contributors may be used to endorse or promote products |
   |      derived from this software without specific prior written permission.|
   |                                                                           |
   | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       |
   | 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
   | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR|
   | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE |
   | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL|
   | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR|
   |  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)       |
   | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,       |
   | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN  |
   | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           |
   | POSSIBILITY OF SUCH DAMAGE.                                               |
   +---------------------------------------------------------------------------+ */

#include <mrpt/hwdrivers/CSickLaserSerial.h>
#include <mrpt/gui.h>
#include <mrpt/maps.h>

using namespace mrpt;
using namespace mrpt::utils;
using namespace mrpt::slam;
using namespace mrpt::gui;
using namespace mrpt::opengl;
using namespace mrpt::hwdrivers;
using namespace std;

string SERIAL_NAME;	// Name of the serial port to open

// ------------------------------------------------------
//				Test_PLS
// ------------------------------------------------------
void TestPLS()
{
	CSickLaserSerial	laser;

	cout << "SICK LMS thru serial port test application." << endl << endl;

	if (SERIAL_NAME.empty())
	{
        cout << "Enter the serial port name (e.g. COM1, ttyS0, ttyUSB0, ttyACM0): ";
        getline(cin,SERIAL_NAME);
	}
	else
	{
        cout << "Using serial port: " << SERIAL_NAME << endl;
	}

	laser.setSerialPort(SERIAL_NAME);

#if 1
	//laser.setBaudRate(500000);
	laser.setBaudRate(9600);
	laser.setScanFOV(180);
	laser.setScanResolution(50);  // 25=0.25deg, 50=0.5deg, 100=1deg
	//laser.setMillimeterMode(true);
#endif

#if MRPT_HAS_WXWIDGETS
	CDisplayWindowPlots		win("Laser scans");
#endif

	// Load config:
	//laser.loadConfig( CConfigFile( "./LASER_SCAN_TEST.ini") ,"PLS#1" );

	cout << "Trying to initialize the laser..." << endl;
	laser.initialize(); // This will raise an exception on error
	cout << "Initialized OK!" << endl;

	while (!mrpt::system::os::kbhit())
	{
		bool						thereIsObservation,hardError;
		CObservation2DRangeScan		obs;

		try
		{
			laser.doProcessSimple( thereIsObservation, obs, hardError );
		}
		catch (std::exception &e)
		{
			cerr << e.what() << endl;
			hardError = true;
		}

		if (hardError)
			printf("[TEST] Hardware error=true!!\n");

		if (thereIsObservation)
		{
			printf("[TEST] Observation received (%u ranges over %.02fdeg, mid=%.03f)!!\n",
				(unsigned int)obs.scan.size(),
				RAD2DEG(obs.aperture),
				obs.scan[obs.scan.size()/2]);

			obs.sensorPose = CPose3D(0,0,0);
			mrpt::slam::CSimplePointsMap		theMap;
			theMap.insertionOptions.minDistBetweenLaserPoints	= 0;
			theMap.insertObservation( &obs );

#if MRPT_HAS_WXWIDGETS
			vector_float	xs,ys,zs;
			theMap.getAllPoints(xs,ys,zs);
			win.plot(xs,ys,".b3");
			win.axis_equal();
#endif
		}
		mrpt::system::sleep(15);
	};

	laser.turnOff();
}

int main(int argc, char **argv)
{
	try
	{
	    if (argc>1)
        {
            SERIAL_NAME = string(argv[1]);
        }

		TestPLS();
		return 0;

	} catch (std::exception &e)
	{
		std::cout << "EXCEPCION: " << e.what() << std::endl;
		return -1;
	}
	catch (...)
	{
		printf("Another exception!!");
		return -1;
	}

}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/

#include <math.h>
#include <stdlib.h>
#include <string.h>

#include "third_party/googletest/src/include/gtest/gtest.h"

#include "./av1_rtcd.h"
#include "./aom_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "av1/common/blockd.h"
#include "av1/common/scan.h"
#include "aom/aom_integer.h"
#include "av1/common/av1_inv_txfm.h"

using libaom_test::ACMRandom;

namespace {
const double PI = 3.141592653589793238462643383279502884;
const double kInvSqrt2 = 0.707106781186547524400844362104;

void reference_idct_1d(const double *in, double *out, int size) {
  for (int n = 0; n < size; ++n) {
    out[n] = 0;
    for (int k = 0; k < size; ++k) {
      if (k == 0)
        out[n] += kInvSqrt2 * in[k] * cos(PI * (2 * n + 1) * k / (2 * size));
      else
        out[n] += in[k] * cos(PI * (2 * n + 1) * k / (2 * size));
    }
  }
}

typedef void (*IdctFuncRef)(const double *in, double *out, int size);
typedef void (*IdctFunc)(const tran_low_t *in, tran_low_t *out);

class TransTestBase {
 public:
  virtual ~TransTestBase() {}

 protected:
  void RunInvAccuracyCheck() {
    tran_low_t *input = new tran_low_t[txfm_size_];
    tran_low_t *output = new tran_low_t[txfm_size_];
    double *ref_input = new double[txfm_size_];
    double *ref_output = new double[txfm_size_];

    ACMRandom rnd(ACMRandom::DeterministicSeed());
    const int count_test_block = 5000;
    for (int ti = 0; ti < count_test_block; ++ti) {
      for (int ni = 0; ni < txfm_size_; ++ni) {
        input[ni] = rnd.Rand8() - rnd.Rand8();
        ref_input[ni] = static_cast<double>(input[ni]);
      }

      fwd_txfm_(input, output);
      fwd_txfm_ref_(ref_input, ref_output, txfm_size_);

      for (int ni = 0; ni < txfm_size_; ++ni) {
        EXPECT_LE(
            abs(output[ni] - static_cast<tran_low_t>(round(ref_output[ni]))),
            max_error_);
      }
    }

    delete[] input;
    delete[] output;
    delete[] ref_input;
    delete[] ref_output;
  }

  double max_error_;
  int txfm_size_;
  IdctFunc fwd_txfm_;
  IdctFuncRef fwd_txfm_ref_;
};

typedef std::tr1::tuple<IdctFunc, IdctFuncRef, int, int> IdctParam;
class AV1InvTxfm : public TransTestBase,
                   public ::testing::TestWithParam<IdctParam> {
 public:
  virtual void SetUp() {
    fwd_txfm_ = GET_PARAM(0);
    fwd_txfm_ref_ = GET_PARAM(1);
    txfm_size_ = GET_PARAM(2);
    max_error_ = GET_PARAM(3);
  }
  virtual void TearDown() {}
};

TEST_P(AV1InvTxfm, RunInvAccuracyCheck) { RunInvAccuracyCheck(); }

INSTANTIATE_TEST_CASE_P(
    C, AV1InvTxfm,
    ::testing::Values(IdctParam(&av1_idct4_c, &reference_idct_1d, 4, 1),
                      IdctParam(&av1_idct8_c, &reference_idct_1d, 8, 2),
                      IdctParam(&av1_idct16_c, &reference_idct_1d, 16, 4),
                      IdctParam(&av1_idct32_c, &reference_idct_1d, 32, 6)));

typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, InvTxfmFunc, TX_SIZE, int>
    PartialInvTxfmParam;
const int kMaxNumCoeffs = 1024;
class AV1PartialIDctTest
    : public ::testing::TestWithParam<PartialInvTxfmParam> {
 public:
  virtual ~AV1PartialIDctTest() {}
  virtual void SetUp() {
    ftxfm_ = GET_PARAM(0);
    full_itxfm_ = GET_PARAM(1);
    partial_itxfm_ = GET_PARAM(2);
    tx_size_ = GET_PARAM(3);
    last_nonzero_ = GET_PARAM(4);
  }

  virtual void TearDown() { libaom_test::ClearSystemState(); }

 protected:
  int last_nonzero_;
  TX_SIZE tx_size_;
  FwdTxfmFunc ftxfm_;
  InvTxfmFunc full_itxfm_;
  InvTxfmFunc partial_itxfm_;
};

TEST_P(AV1PartialIDctTest, RunQuantCheck) {
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  int size;
  switch (tx_size_) {
    case TX_4X4: size = 4; break;
    case TX_8X8: size = 8; break;
    case TX_16X16: size = 16; break;
    case TX_32X32: size = 32; break;
    default: FAIL() << "Wrong Size!"; break;
  }
  DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);

  const int count_test_block = 1000;
  const int block_size = size * size;

  DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]);

  int max_error = 0;
  for (int i = 0; i < count_test_block; ++i) {
    // clear out destination buffer
    memset(dst1, 0, sizeof(*dst1) * block_size);
    memset(dst2, 0, sizeof(*dst2) * block_size);
    memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
    memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);

    ACMRandom rnd(ACMRandom::DeterministicSeed());

    for (int i = 0; i < count_test_block; ++i) {
      // Initialize a test block with input range [-255, 255].
      if (i == 0) {
        for (int j = 0; j < block_size; ++j) input_extreme_block[j] = 255;
      } else if (i == 1) {
        for (int j = 0; j < block_size; ++j) input_extreme_block[j] = -255;
      } else {
        for (int j = 0; j < block_size; ++j) {
          input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255;
        }
      }

      ftxfm_(input_extreme_block, output_ref_block, size);

      // quantization with maximum allowed step sizes
      test_coef_block1[0] = (output_ref_block[0] / 1336) * 1336;
      for (int j = 1; j < last_nonzero_; ++j)
        test_coef_block1[av1_default_scan_orders[tx_size_].scan[j]] =
            (output_ref_block[j] / 1828) * 1828;
    }

    ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
    ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block1, dst2, size));

    for (int j = 0; j < block_size; ++j) {
      const int diff = dst1[j] - dst2[j];
      const int error = diff * diff;
      if (max_error < error) max_error = error;
    }
  }

  EXPECT_EQ(0, max_error)
      << "Error: partial inverse transform produces different results";
}

TEST_P(AV1PartialIDctTest, ResultsMatch) {
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  int size;
  switch (tx_size_) {
    case TX_4X4: size = 4; break;
    case TX_8X8: size = 8; break;
    case TX_16X16: size = 16; break;
    case TX_32X32: size = 32; break;
    default: FAIL() << "Wrong Size!"; break;
  }
  DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);
  const int count_test_block = 1000;
  const int max_coeff = 32766 / 4;
  const int block_size = size * size;
  int max_error = 0;
  for (int i = 0; i < count_test_block; ++i) {
    // clear out destination buffer
    memset(dst1, 0, sizeof(*dst1) * block_size);
    memset(dst2, 0, sizeof(*dst2) * block_size);
    memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
    memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);
    int max_energy_leftover = max_coeff * max_coeff;
    for (int j = 0; j < last_nonzero_; ++j) {
      int16_t coef = static_cast<int16_t>(sqrt(1.0 * max_energy_leftover) *
                                          (rnd.Rand16() - 32768) / 65536);
      max_energy_leftover -= coef * coef;
      if (max_energy_leftover < 0) {
        max_energy_leftover = 0;
        coef = 0;
      }
      test_coef_block1[av1_default_scan_orders[tx_size_].scan[j]] = coef;
    }

    memcpy(test_coef_block2, test_coef_block1,
           sizeof(*test_coef_block2) * block_size);

    ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
    ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block2, dst2, size));

    for (int j = 0; j < block_size; ++j) {
      const int diff = dst1[j] - dst2[j];
      const int error = diff * diff;
      if (max_error < error) max_error = error;
    }
  }

  EXPECT_EQ(0, max_error)
      << "Error: partial inverse transform produces different results";
}
using std::tr1::make_tuple;

INSTANTIATE_TEST_CASE_P(
    C, AV1PartialIDctTest,
    ::testing::Values(make_tuple(&aom_fdct32x32_c, &av1_idct32x32_1024_add_c,
                                 &av1_idct32x32_34_add_c, TX_32X32, 34),
                      make_tuple(&aom_fdct32x32_c, &av1_idct32x32_1024_add_c,
                                 &av1_idct32x32_1_add_c, TX_32X32, 1),
                      make_tuple(&aom_fdct16x16_c, &av1_idct16x16_256_add_c,
                                 &av1_idct16x16_10_add_c, TX_16X16, 10),
                      make_tuple(&aom_fdct16x16_c, &av1_idct16x16_256_add_c,
                                 &av1_idct16x16_1_add_c, TX_16X16, 1),
                      make_tuple(&aom_fdct8x8_c, &av1_idct8x8_64_add_c,
                                 &av1_idct8x8_12_add_c, TX_8X8, 12),
                      make_tuple(&aom_fdct8x8_c, &av1_idct8x8_64_add_c,
                                 &av1_idct8x8_1_add_c, TX_8X8, 1),
                      make_tuple(&aom_fdct4x4_c, &av1_idct4x4_16_add_c,
                                 &av1_idct4x4_1_add_c, TX_4X4, 1)));
}  // namespace
<commit_msg>av1_inv_txfm_test: fix decode-only build<commit_after>/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/

#include <math.h>
#include <stdlib.h>
#include <string.h>

#include "third_party/googletest/src/include/gtest/gtest.h"

#include "./av1_rtcd.h"
#include "./aom_dsp_rtcd.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "av1/common/blockd.h"
#include "av1/common/scan.h"
#include "aom/aom_integer.h"
#include "av1/common/av1_inv_txfm.h"

using libaom_test::ACMRandom;

namespace {
const double PI = 3.141592653589793238462643383279502884;
const double kInvSqrt2 = 0.707106781186547524400844362104;

void reference_idct_1d(const double *in, double *out, int size) {
  for (int n = 0; n < size; ++n) {
    out[n] = 0;
    for (int k = 0; k < size; ++k) {
      if (k == 0)
        out[n] += kInvSqrt2 * in[k] * cos(PI * (2 * n + 1) * k / (2 * size));
      else
        out[n] += in[k] * cos(PI * (2 * n + 1) * k / (2 * size));
    }
  }
}

typedef void (*IdctFuncRef)(const double *in, double *out, int size);
typedef void (*IdctFunc)(const tran_low_t *in, tran_low_t *out);

class TransTestBase {
 public:
  virtual ~TransTestBase() {}

 protected:
  void RunInvAccuracyCheck() {
    tran_low_t *input = new tran_low_t[txfm_size_];
    tran_low_t *output = new tran_low_t[txfm_size_];
    double *ref_input = new double[txfm_size_];
    double *ref_output = new double[txfm_size_];

    ACMRandom rnd(ACMRandom::DeterministicSeed());
    const int count_test_block = 5000;
    for (int ti = 0; ti < count_test_block; ++ti) {
      for (int ni = 0; ni < txfm_size_; ++ni) {
        input[ni] = rnd.Rand8() - rnd.Rand8();
        ref_input[ni] = static_cast<double>(input[ni]);
      }

      fwd_txfm_(input, output);
      fwd_txfm_ref_(ref_input, ref_output, txfm_size_);

      for (int ni = 0; ni < txfm_size_; ++ni) {
        EXPECT_LE(
            abs(output[ni] - static_cast<tran_low_t>(round(ref_output[ni]))),
            max_error_);
      }
    }

    delete[] input;
    delete[] output;
    delete[] ref_input;
    delete[] ref_output;
  }

  double max_error_;
  int txfm_size_;
  IdctFunc fwd_txfm_;
  IdctFuncRef fwd_txfm_ref_;
};

typedef std::tr1::tuple<IdctFunc, IdctFuncRef, int, int> IdctParam;
class AV1InvTxfm : public TransTestBase,
                   public ::testing::TestWithParam<IdctParam> {
 public:
  virtual void SetUp() {
    fwd_txfm_ = GET_PARAM(0);
    fwd_txfm_ref_ = GET_PARAM(1);
    txfm_size_ = GET_PARAM(2);
    max_error_ = GET_PARAM(3);
  }
  virtual void TearDown() {}
};

TEST_P(AV1InvTxfm, RunInvAccuracyCheck) { RunInvAccuracyCheck(); }

INSTANTIATE_TEST_CASE_P(
    C, AV1InvTxfm,
    ::testing::Values(IdctParam(&av1_idct4_c, &reference_idct_1d, 4, 1),
                      IdctParam(&av1_idct8_c, &reference_idct_1d, 8, 2),
                      IdctParam(&av1_idct16_c, &reference_idct_1d, 16, 4),
                      IdctParam(&av1_idct32_c, &reference_idct_1d, 32, 6)));

#if CONFIG_AV1_ENCODER
typedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride);
typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride);
typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, InvTxfmFunc, TX_SIZE, int>
    PartialInvTxfmParam;
const int kMaxNumCoeffs = 1024;
class AV1PartialIDctTest
    : public ::testing::TestWithParam<PartialInvTxfmParam> {
 public:
  virtual ~AV1PartialIDctTest() {}
  virtual void SetUp() {
    ftxfm_ = GET_PARAM(0);
    full_itxfm_ = GET_PARAM(1);
    partial_itxfm_ = GET_PARAM(2);
    tx_size_ = GET_PARAM(3);
    last_nonzero_ = GET_PARAM(4);
  }

  virtual void TearDown() { libaom_test::ClearSystemState(); }

 protected:
  int last_nonzero_;
  TX_SIZE tx_size_;
  FwdTxfmFunc ftxfm_;
  InvTxfmFunc full_itxfm_;
  InvTxfmFunc partial_itxfm_;
};

TEST_P(AV1PartialIDctTest, RunQuantCheck) {
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  int size;
  switch (tx_size_) {
    case TX_4X4: size = 4; break;
    case TX_8X8: size = 8; break;
    case TX_16X16: size = 16; break;
    case TX_32X32: size = 32; break;
    default: FAIL() << "Wrong Size!"; break;
  }
  DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);

  const int count_test_block = 1000;
  const int block_size = size * size;

  DECLARE_ALIGNED(16, int16_t, input_extreme_block[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kMaxNumCoeffs]);

  int max_error = 0;
  for (int i = 0; i < count_test_block; ++i) {
    // clear out destination buffer
    memset(dst1, 0, sizeof(*dst1) * block_size);
    memset(dst2, 0, sizeof(*dst2) * block_size);
    memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
    memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);

    ACMRandom rnd(ACMRandom::DeterministicSeed());

    for (int i = 0; i < count_test_block; ++i) {
      // Initialize a test block with input range [-255, 255].
      if (i == 0) {
        for (int j = 0; j < block_size; ++j) input_extreme_block[j] = 255;
      } else if (i == 1) {
        for (int j = 0; j < block_size; ++j) input_extreme_block[j] = -255;
      } else {
        for (int j = 0; j < block_size; ++j) {
          input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255;
        }
      }

      ftxfm_(input_extreme_block, output_ref_block, size);

      // quantization with maximum allowed step sizes
      test_coef_block1[0] = (output_ref_block[0] / 1336) * 1336;
      for (int j = 1; j < last_nonzero_; ++j)
        test_coef_block1[av1_default_scan_orders[tx_size_].scan[j]] =
            (output_ref_block[j] / 1828) * 1828;
    }

    ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
    ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block1, dst2, size));

    for (int j = 0; j < block_size; ++j) {
      const int diff = dst1[j] - dst2[j];
      const int error = diff * diff;
      if (max_error < error) max_error = error;
    }
  }

  EXPECT_EQ(0, max_error)
      << "Error: partial inverse transform produces different results";
}

TEST_P(AV1PartialIDctTest, ResultsMatch) {
  ACMRandom rnd(ACMRandom::DeterministicSeed());
  int size;
  switch (tx_size_) {
    case TX_4X4: size = 4; break;
    case TX_8X8: size = 8; break;
    case TX_16X16: size = 16; break;
    case TX_32X32: size = 32; break;
    default: FAIL() << "Wrong Size!"; break;
  }
  DECLARE_ALIGNED(16, tran_low_t, test_coef_block1[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, tran_low_t, test_coef_block2[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, uint8_t, dst1[kMaxNumCoeffs]);
  DECLARE_ALIGNED(16, uint8_t, dst2[kMaxNumCoeffs]);
  const int count_test_block = 1000;
  const int max_coeff = 32766 / 4;
  const int block_size = size * size;
  int max_error = 0;
  for (int i = 0; i < count_test_block; ++i) {
    // clear out destination buffer
    memset(dst1, 0, sizeof(*dst1) * block_size);
    memset(dst2, 0, sizeof(*dst2) * block_size);
    memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
    memset(test_coef_block2, 0, sizeof(*test_coef_block2) * block_size);
    int max_energy_leftover = max_coeff * max_coeff;
    for (int j = 0; j < last_nonzero_; ++j) {
      int16_t coef = static_cast<int16_t>(sqrt(1.0 * max_energy_leftover) *
                                          (rnd.Rand16() - 32768) / 65536);
      max_energy_leftover -= coef * coef;
      if (max_energy_leftover < 0) {
        max_energy_leftover = 0;
        coef = 0;
      }
      test_coef_block1[av1_default_scan_orders[tx_size_].scan[j]] = coef;
    }

    memcpy(test_coef_block2, test_coef_block1,
           sizeof(*test_coef_block2) * block_size);

    ASM_REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
    ASM_REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block2, dst2, size));

    for (int j = 0; j < block_size; ++j) {
      const int diff = dst1[j] - dst2[j];
      const int error = diff * diff;
      if (max_error < error) max_error = error;
    }
  }

  EXPECT_EQ(0, max_error)
      << "Error: partial inverse transform produces different results";
}
using std::tr1::make_tuple;

INSTANTIATE_TEST_CASE_P(
    C, AV1PartialIDctTest,
    ::testing::Values(make_tuple(&aom_fdct32x32_c, &av1_idct32x32_1024_add_c,
                                 &av1_idct32x32_34_add_c, TX_32X32, 34),
                      make_tuple(&aom_fdct32x32_c, &av1_idct32x32_1024_add_c,
                                 &av1_idct32x32_1_add_c, TX_32X32, 1),
                      make_tuple(&aom_fdct16x16_c, &av1_idct16x16_256_add_c,
                                 &av1_idct16x16_10_add_c, TX_16X16, 10),
                      make_tuple(&aom_fdct16x16_c, &av1_idct16x16_256_add_c,
                                 &av1_idct16x16_1_add_c, TX_16X16, 1),
                      make_tuple(&aom_fdct8x8_c, &av1_idct8x8_64_add_c,
                                 &av1_idct8x8_12_add_c, TX_8X8, 12),
                      make_tuple(&aom_fdct8x8_c, &av1_idct8x8_64_add_c,
                                 &av1_idct8x8_1_add_c, TX_8X8, 1),
                      make_tuple(&aom_fdct4x4_c, &av1_idct4x4_16_add_c,
                                 &av1_idct4x4_1_add_c, TX_4X4, 1)));
#endif  // CONFIG_AV1_ENCODER
}  // namespace
<|endoftext|>


<commit_before><commit_msg>找出缺失的数<commit_after><|endoftext|>


<commit_before>//
//  main.cpp
//  simulate
//
//  Created by Lucy Li on 3/16/20.
//  Copyright © 2020 Lucy M Li. All rights reserved.
//

#include <iostream>

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    return 0;
}
<commit_msg>remove extraneous file<commit_after><|endoftext|>


<commit_before>
//Implementation of the parallel statement execution manager

#include "parContextManager.h"

StatementContext::StatementContext() {
  //Do nothing
}

StatementContext::StatementContext(StatementContext&& sc) {
  this->int_future_id_map = std::move(sc.int_future_id_map);
  this->float_future_id_map = std::move(sc.float_future_id_map);
  this->intptr_future_id_map = std::move(sc.intptr_future_id_map);
  this->floatptr_future_id_map = std::move(sc.floatptr_future_id_map);
  this->void_future_id_map = std::move(sc.void_future_id_map);
}

/*=================================StatementContext=================================*/
void StatementContext::addIntFuture(std::future<int64_t>& f, const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  assert(int_future_id_map.count(id)==0 && "Statement id already exists");
  int_future_id_map.insert(std::pair<int64_t,std::future<int64_t>>(id,std::move(f)));
}

void StatementContext::addFloatFuture(std::future<double>& f, const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  assert(float_future_id_map.count(id)==0 && "Statement id already exists");
  float_future_id_map.insert(std::pair<int64_t,std::future<double>>(id,std::move(f)));
}

void StatementContext::addIntptrFuture(std::future<int64_t*>& f, const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  assert(intptr_future_id_map.count(id)==0 && "Statement id already exists");
  intptr_future_id_map.insert(std::pair<int64_t,std::future<int64_t*>>(id,std::move(f)));
}

void StatementContext::addFloatptrFuture(std::future<double*>& f, const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  assert(floatptr_future_id_map.count(id)==0 && "Statement id already exists");
  floatptr_future_id_map.insert(std::pair<int64_t,std::future<double*>>(id,std::move(f)));
}

void StatementContext::addVoidFuture(std::future<void>& f, const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  assert(void_future_id_map.count(id)==0 && "Statement id already exists");
  void_future_id_map.insert(std::pair<int64_t,std::future<void>>(id,std::move(f)));
}

std::future<int64_t> StatementContext::getIntFuture(const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  auto f = std::move(int_future_id_map.at(id));
  int_future_id_map.erase(id);
  return f;
}

std::future<double> StatementContext::getFloatFuture(const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  auto f = std::move(float_future_id_map.at(id));
  float_future_id_map.erase(id);
  return f;
}

std::future<int64_t*> StatementContext::getIntptrFuture(const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  auto f = std::move(intptr_future_id_map.at(id));
  intptr_future_id_map.erase(id);
  return f;
}

std::future<double*> StatementContext::getFloatptrFuture(const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  auto f = std::move(floatptr_future_id_map.at(id));
  floatptr_future_id_map.erase(id);
  return f;
}

std::future<void> StatementContext::getVoidFuture(const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  auto f = std::move(void_future_id_map.at(id));
  void_future_id_map.erase(id);
  return f;
}

/*=================================ParContextManager=================================*/
ParContextManager::ParContextManager() {
  set_max_threads();
  thread_count = 0;
  next_cid = 0;
}

int64_t ParContextManager::make_context() {
  std::lock_guard<std::mutex> section_monitor(mutex);
  int64_t cid = next_cid++;
  context_map.insert(std::pair<int64_t,StatementContext>(cid,std::move(StatementContext())));
  return cid;
}

void ParContextManager::destroy_context(const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  assert(context_map.count(cid)==1);
  context_map.erase(cid);
}

void ParContextManager::sched_int(int64_t (*statement)(void),const int64_t id,const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  std::future<int64_t> promise;
  if (thread_count >= max_threads) {
    promise = std::async(std::launch::deferred,statement);
  } else {
    promise = std::async(std::launch::async,statement);
    thread_count++;
  }
  context_map.at(cid).addIntFuture(promise,id);
}

void ParContextManager::sched_float(double (*statement)(void),const int64_t id,const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  std::future<double> promise;
  if (thread_count >= max_threads) {
    promise = std::async(std::launch::deferred,statement);
  } else {
    promise = std::async(std::launch::async,statement);
    thread_count++;
  }
  context_map.at(cid).addFloatFuture(promise,id);
}

void ParContextManager::sched_intptr(int64_t* (*statement)(void),int64_t id,const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  std::future<int64_t*> promise;
  if (thread_count >= max_threads) {
    promise = std::async(std::launch::deferred,statement);
  } else {
    promise = std::async(std::launch::async,statement);
    thread_count++;
  }
  context_map.at(cid).addIntptrFuture(promise,id);
}

void ParContextManager::sched_floatptr(double* (*statement)(void),int64_t id,const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  std::future<double*> promise;
  if (thread_count >= max_threads) {
    promise = std::async(std::launch::deferred,statement);
  } else {
    promise = std::async(std::launch::async,statement);
    thread_count++;
  }
  context_map.at(cid).addFloatptrFuture(promise,id);
}

void ParContextManager::sched_void(void (*statement)(void),int64_t id,const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  std::future<void> promise;
  if (thread_count >= max_threads) {
    promise = std::async(std::launch::deferred,statement);
  } else {
    promise = std::async(std::launch::async,statement);
    thread_count++;
  }
  context_map.at(cid).addVoidFuture(promise,id);
}

int64_t ParContextManager::recon_int(const int64_t original,const int64_t known,const int64_t update,
                const int64_t id,const int64_t max,const int64_t cid) {
  mutex.lock();
  std::chrono::milliseconds span(0);
  std::future<int64_t> fv = context_map.at(cid).getIntFuture(id);
  int64_t v;
  mutex.unlock();
  if (fv.wait_for(span)==std::future_status::deferred) {
    v = fv.get();
  } else {
    v = fv.get();
    mutex.lock();
    thread_count--;
    mutex.unlock();
  }
  return v;
}

double ParContextManager::recon_float(const double original,const int64_t known,const double update,
                const int64_t id,const int64_t max,const int64_t cid) {
  mutex.lock();
  std::chrono::milliseconds span(0);
  std::future<double> fv = context_map.at(cid).getFloatFuture(id);
  double v;
  mutex.unlock();
  if (fv.wait_for(span)==std::future_status::deferred) {
    v = fv.get();
  } else {
    v = fv.get();
    mutex.lock();
    thread_count--;
    mutex.unlock();
  }
  return v;
}

int64_t* ParContextManager::recon_intptr(const int64_t* original,const int64_t known,const int64_t* update,
                const int64_t id,const int64_t max,const int64_t cid) {
  mutex.lock();
  std::chrono::milliseconds span(0);
  std::future<int64_t*> fv = context_map.at(cid).getIntptrFuture(id);
  int64_t* v;
  mutex.unlock();
  if (fv.wait_for(span)==std::future_status::deferred) {
    v = fv.get();
  } else {
    v = fv.get();
    mutex.lock();
    thread_count--;
    mutex.unlock();
  }
  return v;
}

double* ParContextManager::recon_floatptr(const double* original,const int64_t known,const double* update,
                const int64_t id,const int64_t max,const int64_t cid) {
  mutex.lock();
  std::chrono::milliseconds span(0);
  std::future<double*> fv = context_map.at(cid).getFloatptrFuture(id);
  double* v;
  mutex.unlock();
  if (fv.wait_for(span)==std::future_status::deferred) {
    v = fv.get();
  } else {
    v = fv.get();
    mutex.lock();
    thread_count--;
    mutex.unlock();
  }
  return v;
}

void ParContextManager::recon_void(const int64_t id,const int64_t max,const int64_t cid) {
  mutex.lock();
  std::chrono::milliseconds span(0);
  std::future<void> fv = context_map.at(cid).getVoidFuture(id);
  mutex.unlock();
  if (fv.wait_for(span)==std::future_status::deferred) {
    fv.get();
  } else {
    fv.get();
    mutex.lock();
    thread_count--;
    mutex.unlock();
  }
}

void ParContextManager::set_max_threads() {
  unsigned long dth = std::thread::hardware_concurrency();
  printf("Detected %d compute elements.\n",(int)dth);
  if (dth < 2) max_threads = 2;
  else if (dth > 4) max_threads = 4;
  else max_threads = dth;
  printf("Setting max execution threads to: %d\n",(int)max_threads);
}

<commit_msg>Added small assertion text<commit_after>
//Implementation of the parallel statement execution manager

#include "parContextManager.h"

StatementContext::StatementContext() {
  //Do nothing
}

StatementContext::StatementContext(StatementContext&& sc) {
  this->int_future_id_map = std::move(sc.int_future_id_map);
  this->float_future_id_map = std::move(sc.float_future_id_map);
  this->intptr_future_id_map = std::move(sc.intptr_future_id_map);
  this->floatptr_future_id_map = std::move(sc.floatptr_future_id_map);
  this->void_future_id_map = std::move(sc.void_future_id_map);
}

/*=================================StatementContext=================================*/
void StatementContext::addIntFuture(std::future<int64_t>& f, const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  assert(int_future_id_map.count(id)==0 && "Statement id already exists");
  int_future_id_map.insert(std::pair<int64_t,std::future<int64_t>>(id,std::move(f)));
}

void StatementContext::addFloatFuture(std::future<double>& f, const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  assert(float_future_id_map.count(id)==0 && "Statement id already exists");
  float_future_id_map.insert(std::pair<int64_t,std::future<double>>(id,std::move(f)));
}

void StatementContext::addIntptrFuture(std::future<int64_t*>& f, const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  assert(intptr_future_id_map.count(id)==0 && "Statement id already exists");
  intptr_future_id_map.insert(std::pair<int64_t,std::future<int64_t*>>(id,std::move(f)));
}

void StatementContext::addFloatptrFuture(std::future<double*>& f, const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  assert(floatptr_future_id_map.count(id)==0 && "Statement id already exists");
  floatptr_future_id_map.insert(std::pair<int64_t,std::future<double*>>(id,std::move(f)));
}

void StatementContext::addVoidFuture(std::future<void>& f, const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  assert(void_future_id_map.count(id)==0 && "Statement id already exists");
  void_future_id_map.insert(std::pair<int64_t,std::future<void>>(id,std::move(f)));
}

std::future<int64_t> StatementContext::getIntFuture(const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  auto f = std::move(int_future_id_map.at(id));
  int_future_id_map.erase(id);
  return f;
}

std::future<double> StatementContext::getFloatFuture(const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  auto f = std::move(float_future_id_map.at(id));
  float_future_id_map.erase(id);
  return f;
}

std::future<int64_t*> StatementContext::getIntptrFuture(const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  auto f = std::move(intptr_future_id_map.at(id));
  intptr_future_id_map.erase(id);
  return f;
}

std::future<double*> StatementContext::getFloatptrFuture(const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  auto f = std::move(floatptr_future_id_map.at(id));
  floatptr_future_id_map.erase(id);
  return f;
}

std::future<void> StatementContext::getVoidFuture(const int64_t id) {
  std::lock_guard<std::mutex> section_monitor(map_mutex);
  auto f = std::move(void_future_id_map.at(id));
  void_future_id_map.erase(id);
  return f;
}

/*=================================ParContextManager=================================*/
ParContextManager::ParContextManager() {
  set_max_threads();
  thread_count = 0;
  next_cid = 0;
}

int64_t ParContextManager::make_context() {
  std::lock_guard<std::mutex> section_monitor(mutex);
  int64_t cid = next_cid++;
  context_map.insert(std::pair<int64_t,StatementContext>(cid,std::move(StatementContext())));
  return cid;
}

void ParContextManager::destroy_context(const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  assert(context_map.count(cid)==1 && "Couldnt find context to destroy");
  context_map.erase(cid);
}

void ParContextManager::sched_int(int64_t (*statement)(void),const int64_t id,const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  std::future<int64_t> promise;
  if (thread_count >= max_threads) {
    promise = std::async(std::launch::deferred,statement);
  } else {
    promise = std::async(std::launch::async,statement);
    thread_count++;
  }
  context_map.at(cid).addIntFuture(promise,id);
}

void ParContextManager::sched_float(double (*statement)(void),const int64_t id,const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  std::future<double> promise;
  if (thread_count >= max_threads) {
    promise = std::async(std::launch::deferred,statement);
  } else {
    promise = std::async(std::launch::async,statement);
    thread_count++;
  }
  context_map.at(cid).addFloatFuture(promise,id);
}

void ParContextManager::sched_intptr(int64_t* (*statement)(void),int64_t id,const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  std::future<int64_t*> promise;
  if (thread_count >= max_threads) {
    promise = std::async(std::launch::deferred,statement);
  } else {
    promise = std::async(std::launch::async,statement);
    thread_count++;
  }
  context_map.at(cid).addIntptrFuture(promise,id);
}

void ParContextManager::sched_floatptr(double* (*statement)(void),int64_t id,const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  std::future<double*> promise;
  if (thread_count >= max_threads) {
    promise = std::async(std::launch::deferred,statement);
  } else {
    promise = std::async(std::launch::async,statement);
    thread_count++;
  }
  context_map.at(cid).addFloatptrFuture(promise,id);
}

void ParContextManager::sched_void(void (*statement)(void),int64_t id,const int64_t cid) {
  std::lock_guard<std::mutex> section_monitor(mutex);
  std::future<void> promise;
  if (thread_count >= max_threads) {
    promise = std::async(std::launch::deferred,statement);
  } else {
    promise = std::async(std::launch::async,statement);
    thread_count++;
  }
  context_map.at(cid).addVoidFuture(promise,id);
}

int64_t ParContextManager::recon_int(const int64_t original,const int64_t known,const int64_t update,
                const int64_t id,const int64_t max,const int64_t cid) {
  mutex.lock();
  std::chrono::milliseconds span(0);
  std::future<int64_t> fv = context_map.at(cid).getIntFuture(id);
  int64_t v;
  mutex.unlock();
  if (fv.wait_for(span)==std::future_status::deferred) {
    v = fv.get();
  } else {
    v = fv.get();
    mutex.lock();
    thread_count--;
    mutex.unlock();
  }
  return v;
}

double ParContextManager::recon_float(const double original,const int64_t known,const double update,
                const int64_t id,const int64_t max,const int64_t cid) {
  mutex.lock();
  std::chrono::milliseconds span(0);
  std::future<double> fv = context_map.at(cid).getFloatFuture(id);
  double v;
  mutex.unlock();
  if (fv.wait_for(span)==std::future_status::deferred) {
    v = fv.get();
  } else {
    v = fv.get();
    mutex.lock();
    thread_count--;
    mutex.unlock();
  }
  return v;
}

int64_t* ParContextManager::recon_intptr(const int64_t* original,const int64_t known,const int64_t* update,
                const int64_t id,const int64_t max,const int64_t cid) {
  mutex.lock();
  std::chrono::milliseconds span(0);
  std::future<int64_t*> fv = context_map.at(cid).getIntptrFuture(id);
  int64_t* v;
  mutex.unlock();
  if (fv.wait_for(span)==std::future_status::deferred) {
    v = fv.get();
  } else {
    v = fv.get();
    mutex.lock();
    thread_count--;
    mutex.unlock();
  }
  return v;
}

double* ParContextManager::recon_floatptr(const double* original,const int64_t known,const double* update,
                const int64_t id,const int64_t max,const int64_t cid) {
  mutex.lock();
  std::chrono::milliseconds span(0);
  std::future<double*> fv = context_map.at(cid).getFloatptrFuture(id);
  double* v;
  mutex.unlock();
  if (fv.wait_for(span)==std::future_status::deferred) {
    v = fv.get();
  } else {
    v = fv.get();
    mutex.lock();
    thread_count--;
    mutex.unlock();
  }
  return v;
}

void ParContextManager::recon_void(const int64_t id,const int64_t max,const int64_t cid) {
  mutex.lock();
  std::chrono::milliseconds span(0);
  std::future<void> fv = context_map.at(cid).getVoidFuture(id);
  mutex.unlock();
  if (fv.wait_for(span)==std::future_status::deferred) {
    fv.get();
  } else {
    fv.get();
    mutex.lock();
    thread_count--;
    mutex.unlock();
  }
}

void ParContextManager::set_max_threads() {
  unsigned long dth = std::thread::hardware_concurrency();
  printf("Detected %d compute elements.\n",(int)dth);
  if (dth < 2) max_threads = 2;
  else if (dth > 4) max_threads = 4;
  else max_threads = dth;
  printf("Setting max execution threads to: %d\n",(int)max_threads);
}

<|endoftext|>