<commit_before>/**
 * @file llspeakingindicatormanager.cpp
 * @author Mike Antipov
 * @brief Implementation of SpeackerIndicatorManager class to process registered LLSpeackerIndicator
 * depend on avatars are in the same voice channel.
 *
 * $LicenseInfo:firstyear=2010&license=viewergpl$
 *
 * Copyright (c) 2010, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"
#include "llspeakingindicatormanager.h"

#include "llagentdata.h"
#include "llvoicechannel.h"
#include "llvoiceclient.h"

/**
 * This class intended to control visibility of avatar speaking indicators depend on whether avatars
 * are in the same voice channel.
 *
 * Speaking indicator should be visible for avatars in the same voice channel. See EXT-3976.
 *
 * It stores passed instances of LLOutputMonitorCtrl in a multimap by avatar LLUUID.
 * It observes changing of voice channel and changing of participant list in voice channel.
 * When voice channel or voice participant list is changed it updates visibility of an appropriate
 * speaking indicator.
 *
 * Several indicators can be registered for the same avatar.
 */
class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, LLVoiceClientParticipantObserver
{
	LOG_CLASS(SpeakingIndicatorManager);
public:

	/**
	 * Stores passed speaking indicator to control its visibility.
	 *
	 * Registered indicator is set visible if an appropriate avatar is in the same voice channel with Agent.
	 * It ignores instances of Agent's indicator.
	 *
	 * @param speaker_id LLUUID of an avatar whose speaking indicator is registered.
	 * @param speaking_indicator instance of the speaking indicator to be registered.
	 */
	void registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator);

	/**
	 * Removes passed speaking indicator from observing.
	 *
	 * @param speaker_id LLUUID of an avatar whose speaking indicator should be unregistered.
	 * @param speaking_indicator instance of the speaking indicator to be unregistered.
	 */
	void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);

private:
	typedef std::set<LLUUID> speaker_ids_t;
	typedef std::multimap<LLUUID, LLSpeakingIndicator*> speaking_indicators_mmap_t;
	typedef speaking_indicators_mmap_t::value_type speaking_indicator_value_t;
	typedef speaking_indicators_mmap_t::const_iterator indicator_const_iterator;
	typedef std::pair<indicator_const_iterator, indicator_const_iterator> indicator_range_t;

	friend class LLSingleton<SpeakingIndicatorManager>;
	SpeakingIndicatorManager();
	~SpeakingIndicatorManager();

	/**
	 * Callback to determine when voice channel is changed.
	 *
	 * It switches all registered speaking indicators off.
	 * To reduce overheads only switched on indicators are processed.
	 */
	void sOnCurrentChannelChanged(const LLUUID& session_id);

	/**
	 * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
	 *
	 * Switches off indicators had been switched on and switches on indicators of current participants list.
	 * There is only a few indicators in lists should be switched off/on.
	 * So, method does not calculate difference between these list it only switches off already
	 * switched on indicators and switches on indicators of voice channel participants
	 */
	void onChange();

	/**
	 * Changes state of indicators specified by LLUUIDs
	 *
	 * @param speakers_uuids - avatars' LLUUIDs whose speaking indicators should be switched
	 * @param switch_on - if TRUE specified indicator will be switched on, off otherwise.
	 */
	void switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on);

	/**
	 * Multimap with all registered speaking indicators
	 */
	speaking_indicators_mmap_t mSpeakingIndicators;

	/**
	 * LUUIDs of avatar for which we have speaking indicators switched on.
	 *
	 * Is used to switch off all previously ON indicators when voice participant list is changed.
	 *
	 * @see onChange()
	 */
	speaker_ids_t mSwitchedIndicatorsOn;
};

//////////////////////////////////////////////////////////////////////////
// PUBLIC SECTION
//////////////////////////////////////////////////////////////////////////
void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator)
{
	if (speaker_id == gAgentID) return;

	LL_DEBUGS("SpeakingIndicator") << "Registering indicator: " << speaker_id << LL_ENDL;
	speaking_indicator_value_t value_type(speaker_id, speaking_indicator);
	mSpeakingIndicators.insert(value_type);

	speaker_ids_t speakers_uuids;
	BOOL is_in_same_voice = LLVoiceClient::getInstance()->findParticipantByID(speaker_id) != NULL;

	speakers_uuids.insert(speaker_id);
	switchSpeakerIndicators(speakers_uuids, is_in_same_voice);
}

void SpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator)
{
	speaking_indicators_mmap_t::iterator it;
	it = mSpeakingIndicators.find(speaker_id);
	for (;it != mSpeakingIndicators.end(); ++it)
	{
		if (it->second == speaking_indicator)
		{
			mSpeakingIndicators.erase(it);
			break;
		}
	}
}

//////////////////////////////////////////////////////////////////////////
// PRIVATE SECTION
//////////////////////////////////////////////////////////////////////////
SpeakingIndicatorManager::SpeakingIndicatorManager()
{
	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&SpeakingIndicatorManager::sOnCurrentChannelChanged, this, _1));
	LLVoiceClient::getInstance()->addObserver(this);
}

SpeakingIndicatorManager::~SpeakingIndicatorManager()
{
	// Don't use LLVoiceClient::getInstance() here without check
	// singleton MAY have already been destroyed.
	if(LLVoiceClient::instanceExists())
	{
		LLVoiceClient::getInstance()->removeObserver(this);
	}
}

void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
{
	switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE);
	mSwitchedIndicatorsOn.clear();
}

void SpeakingIndicatorManager::onChange()
{
	LL_DEBUGS("SpeakingIndicator") << "Voice participant list was changed, updating indicators" << LL_ENDL;

	speaker_ids_t speakers_uuids;
	LLVoiceClient::getInstance()->getParticipantsUUIDSet(speakers_uuids);

	LL_DEBUGS("SpeakingIndicator") << "Switching all OFF, count: " << mSwitchedIndicatorsOn.size() << LL_ENDL;
	// switch all indicators off
	switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE);
	mSwitchedIndicatorsOn.clear();

	LL_DEBUGS("SpeakingIndicator") << "Switching all ON, count: " << speakers_uuids.size() << LL_ENDL;
	// then switch current voice participants indicators on
	switchSpeakerIndicators(speakers_uuids, TRUE);
}

void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on)
{
	speaker_ids_t::const_iterator it_uuid = speakers_uuids.begin();
	for (; it_uuid != speakers_uuids.end(); ++it_uuid)
	{
		LL_DEBUGS("SpeakingIndicator") << "Looking for indicator: " << *it_uuid << LL_ENDL;
		indicator_range_t it_range = mSpeakingIndicators.equal_range(*it_uuid);
		indicator_const_iterator it_indicator = it_range.first;
		bool was_found = false;
		for (; it_indicator != it_range.second; ++it_indicator)
		{
			was_found = true;
			LLSpeakingIndicator* indicator = (*it_indicator).second;
			indicator->switchIndicator(switch_on);
		}

		if (was_found)
		{
			LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators where found" << LL_ENDL;

			if (switch_on)
			{
				// store switched on indicator to be able switch it off
				mSwitchedIndicatorsOn.insert(*it_uuid);
			}
		}
		else
		{
			LL_WARNS("SpeakingIndicator") << "indicator was not found among registered: " << *it_uuid << LL_ENDL;
		}
	}
}

/************************************************************************/
/*         LLSpeakingIndicatorManager namespace implementation          */
/************************************************************************/

void LLSpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator)
{
	SpeakingIndicatorManager::instance().registerSpeakingIndicator(speaker_id, speaking_indicator);
}

void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator)
{
	SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator);
}

// EOF

<commit_msg>Related to EXT-3976 (Voice chat speaking indicators should only display when users are in the same voice channel) -- cleanup: remove logging of unnecessary warning messages if there are no any registered speaking indicators for voice participant<commit_after>/**
 * @file llspeakingindicatormanager.cpp
 * @author Mike Antipov
 * @brief Implementation of SpeackerIndicatorManager class to process registered LLSpeackerIndicator
 * depend on avatars are in the same voice channel.
 *
 * $LicenseInfo:firstyear=2010&license=viewergpl$
 *
 * Copyright (c) 2010, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"
#include "llspeakingindicatormanager.h"

#include "llagentdata.h"
#include "llvoicechannel.h"
#include "llvoiceclient.h"

/**
 * This class intended to control visibility of avatar speaking indicators depend on whether avatars
 * are in the same voice channel.
 *
 * Speaking indicator should be visible for avatars in the same voice channel. See EXT-3976.
 *
 * It stores passed instances of LLOutputMonitorCtrl in a multimap by avatar LLUUID.
 * It observes changing of voice channel and changing of participant list in voice channel.
 * When voice channel or voice participant list is changed it updates visibility of an appropriate
 * speaking indicator.
 *
 * Several indicators can be registered for the same avatar.
 */
class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, LLVoiceClientParticipantObserver
{
	LOG_CLASS(SpeakingIndicatorManager);
public:

	/**
	 * Stores passed speaking indicator to control its visibility.
	 *
	 * Registered indicator is set visible if an appropriate avatar is in the same voice channel with Agent.
	 * It ignores instances of Agent's indicator.
	 *
	 * @param speaker_id LLUUID of an avatar whose speaking indicator is registered.
	 * @param speaking_indicator instance of the speaking indicator to be registered.
	 */
	void registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator);

	/**
	 * Removes passed speaking indicator from observing.
	 *
	 * @param speaker_id LLUUID of an avatar whose speaking indicator should be unregistered.
	 * @param speaking_indicator instance of the speaking indicator to be unregistered.
	 */
	void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);

private:
	typedef std::set<LLUUID> speaker_ids_t;
	typedef std::multimap<LLUUID, LLSpeakingIndicator*> speaking_indicators_mmap_t;
	typedef speaking_indicators_mmap_t::value_type speaking_indicator_value_t;
	typedef speaking_indicators_mmap_t::const_iterator indicator_const_iterator;
	typedef std::pair<indicator_const_iterator, indicator_const_iterator> indicator_range_t;

	friend class LLSingleton<SpeakingIndicatorManager>;
	SpeakingIndicatorManager();
	~SpeakingIndicatorManager();

	/**
	 * Callback to determine when voice channel is changed.
	 *
	 * It switches all registered speaking indicators off.
	 * To reduce overheads only switched on indicators are processed.
	 */
	void sOnCurrentChannelChanged(const LLUUID& session_id);

	/**
	 * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
	 *
	 * Switches off indicators had been switched on and switches on indicators of current participants list.
	 * There is only a few indicators in lists should be switched off/on.
	 * So, method does not calculate difference between these list it only switches off already
	 * switched on indicators and switches on indicators of voice channel participants
	 */
	void onChange();

	/**
	 * Changes state of indicators specified by LLUUIDs
	 *
	 * @param speakers_uuids - avatars' LLUUIDs whose speaking indicators should be switched
	 * @param switch_on - if TRUE specified indicator will be switched on, off otherwise.
	 */
	void switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on);

	/**
	 * Multimap with all registered speaking indicators
	 */
	speaking_indicators_mmap_t mSpeakingIndicators;

	/**
	 * LUUIDs of avatar for which we have speaking indicators switched on.
	 *
	 * Is used to switch off all previously ON indicators when voice participant list is changed.
	 *
	 * @see onChange()
	 */
	speaker_ids_t mSwitchedIndicatorsOn;
};

//////////////////////////////////////////////////////////////////////////
// PUBLIC SECTION
//////////////////////////////////////////////////////////////////////////
void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator)
{
	if (speaker_id == gAgentID) return;

	LL_DEBUGS("SpeakingIndicator") << "Registering indicator: " << speaker_id << LL_ENDL;
	speaking_indicator_value_t value_type(speaker_id, speaking_indicator);
	mSpeakingIndicators.insert(value_type);

	speaker_ids_t speakers_uuids;
	BOOL is_in_same_voice = LLVoiceClient::getInstance()->findParticipantByID(speaker_id) != NULL;

	speakers_uuids.insert(speaker_id);
	switchSpeakerIndicators(speakers_uuids, is_in_same_voice);
}

void SpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator)
{
	speaking_indicators_mmap_t::iterator it;
	it = mSpeakingIndicators.find(speaker_id);
	for (;it != mSpeakingIndicators.end(); ++it)
	{
		if (it->second == speaking_indicator)
		{
			mSpeakingIndicators.erase(it);
			break;
		}
	}
}

//////////////////////////////////////////////////////////////////////////
// PRIVATE SECTION
//////////////////////////////////////////////////////////////////////////
SpeakingIndicatorManager::SpeakingIndicatorManager()
{
	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&SpeakingIndicatorManager::sOnCurrentChannelChanged, this, _1));
	LLVoiceClient::getInstance()->addObserver(this);
}

SpeakingIndicatorManager::~SpeakingIndicatorManager()
{
	// Don't use LLVoiceClient::getInstance() here without check
	// singleton MAY have already been destroyed.
	if(LLVoiceClient::instanceExists())
	{
		LLVoiceClient::getInstance()->removeObserver(this);
	}
}

void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
{
	switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE);
	mSwitchedIndicatorsOn.clear();
}

void SpeakingIndicatorManager::onChange()
{
	LL_DEBUGS("SpeakingIndicator") << "Voice participant list was changed, updating indicators" << LL_ENDL;

	speaker_ids_t speakers_uuids;
	LLVoiceClient::getInstance()->getParticipantsUUIDSet(speakers_uuids);

	LL_DEBUGS("SpeakingIndicator") << "Switching all OFF, count: " << mSwitchedIndicatorsOn.size() << LL_ENDL;
	// switch all indicators off
	switchSpeakerIndicators(mSwitchedIndicatorsOn, FALSE);
	mSwitchedIndicatorsOn.clear();

	LL_DEBUGS("SpeakingIndicator") << "Switching all ON, count: " << speakers_uuids.size() << LL_ENDL;
	// then switch current voice participants indicators on
	switchSpeakerIndicators(speakers_uuids, TRUE);
}

void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& speakers_uuids, BOOL switch_on)
{
	speaker_ids_t::const_iterator it_uuid = speakers_uuids.begin();
	for (; it_uuid != speakers_uuids.end(); ++it_uuid)
	{
		LL_DEBUGS("SpeakingIndicator") << "Looking for indicator: " << *it_uuid << LL_ENDL;
		indicator_range_t it_range = mSpeakingIndicators.equal_range(*it_uuid);
		indicator_const_iterator it_indicator = it_range.first;
		bool was_found = false;
		for (; it_indicator != it_range.second; ++it_indicator)
		{
			was_found = true;
			LLSpeakingIndicator* indicator = (*it_indicator).second;
			indicator->switchIndicator(switch_on);
		}

		if (was_found)
		{
			LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators where found" << LL_ENDL;

			if (switch_on)
			{
				// store switched on indicator to be able switch it off
				mSwitchedIndicatorsOn.insert(*it_uuid);
			}
		}
	}
}

/************************************************************************/
/*         LLSpeakingIndicatorManager namespace implementation          */
/************************************************************************/

void LLSpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_id, LLSpeakingIndicator* const speaking_indicator)
{
	SpeakingIndicatorManager::instance().registerSpeakingIndicator(speaker_id, speaking_indicator);
}

void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator)
{
	SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator);
}

// EOF

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: thread.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 08:47:30 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CPPU_THREADPOOL_THREAD_HXX
#define _CPPU_THREADPOOL_THREAD_HXX

#include <list>

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#include <osl/thread.h>

#include "jobqueue.hxx"

namespace cppu_threadpool {

    class JobQueue;

    //-----------------------------------------
    // private thread class for the threadpool
    // independent from vos
    //-----------------------------------------
    class ORequestThread
    {
    public:
        ORequestThread( JobQueue * ,
                        const ::rtl::ByteSequence &aThreadId,
                        sal_Bool bAsynchron );
        ~ORequestThread();

        void setTask( JobQueue * , const ::rtl::ByteSequence & aThreadId , sal_Bool bAsynchron );

        sal_Bool create();
        void join();
        void onTerminated();
        void run();
        inline void setDeleteSelf( sal_Bool b )
            { m_bDeleteSelf = b; }

    private:
        oslThread m_thread;
        JobQueue *m_pQueue;
        ::rtl::ByteSequence m_aThreadId;
        sal_Bool m_bAsynchron;
        sal_Bool m_bDeleteSelf;
    };

    class ThreadAdmin
    {
    public:
        ~ThreadAdmin ();
        static ThreadAdmin *getInstance();
        void add( ORequestThread * );
        void remove( ORequestThread * );
        void join();

    private:
        ::osl::Mutex m_mutex;
        ::std::list< ORequestThread * > m_lst;
    };

} // end cppu_threadpool

#endif

<commit_msg>INTEGRATION: CWS sb49 (1.4.40); FILE MERGED 2006/03/22 10:14:06 sb 1.4.40.1: #i63397# Keep objects alive long enough so that threads still running while atexit handlers are processed do not access dead objects.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: thread.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2006-04-19 13:49:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CPPU_THREADPOOL_THREAD_HXX
#define _CPPU_THREADPOOL_THREAD_HXX

#include <list>

#ifndef _RTL_REF_HXX_
#include "rtl/ref.hxx"
#endif
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#include <osl/thread.h>

#include "jobqueue.hxx"

namespace cppu_threadpool {

    class JobQueue;
    class ThreadPool;

    //-----------------------------------------
    // private thread class for the threadpool
    // independent from vos
    //-----------------------------------------
    class ORequestThread
    {
    public:
        ORequestThread( rtl::Reference< ThreadPool > const & threadPool,
                        JobQueue * pQueue,
                        const ::rtl::ByteSequence &aThreadId,
                        sal_Bool bAsynchron );
        ~ORequestThread();

        void setTask( JobQueue * , const ::rtl::ByteSequence & aThreadId , sal_Bool bAsynchron );

        sal_Bool create();
        void join();
        void onTerminated();
        void run();
        inline void setDeleteSelf( sal_Bool b )
            { m_bDeleteSelf = b; }

    private:
        oslThread m_thread;
        rtl::Reference< ThreadPool > m_threadPool;
        JobQueue *m_pQueue;
        ::rtl::ByteSequence m_aThreadId;
        sal_Bool m_bAsynchron;
        sal_Bool m_bDeleteSelf;
    };

    class ThreadAdmin
    {
    public:
        ~ThreadAdmin ();
        static ThreadAdmin *getInstance();
        void add( ORequestThread * );
        void remove( ORequestThread * );
        void join();

    private:
        ::osl::Mutex m_mutex;
        ::std::list< ORequestThread * > m_lst;
    };

} // end cppu_threadpool

#endif

<|endoftext|>


<commit_before>/*RF implementation: setting up the transceiver AX5042
 * It uses the SPI library
 *
 * The circuit:
 * - Pins 2, 7, 20, 26 of AX5042 connected to 2,5V Power Supply
 * - Pins
 * - Pin 16 (MISO)of AX5042 connected to MISO (digital pin 50)
 * - Pin 17 (MOSI)of AX5042 connected to MOSI (digital pin 51)
 * - Pin 15 (CLK) of AX5042 connected to SCK (digital pin 52)
 * - Pin 14 (SEL) of AX5042 connected to SS (digital pin 49)
 *
 * All the programming has be done following the AX5042 Programming Manual
*/

#include "comms.h"

const int chip_select_pin = 49;

/*Setting up the transceiver*/
void configure() {
pinMode(chip_select_pin, OUTPUT);
    SPI.begin();
    write_register(AGCTARGET, 0x0E);
    write_register(PLLRNG, (read_register(PLLRNG) | 0x01));
    write_register(RXMISC, ((read_register(RXMISC) | 0x01)& 0xFD)//write 01 in the last 2 bits
    configure_PLLLOOP(BANDSEL);
    configure_FREQ(FCARRIER);
    configure_TXPWR();
    configure_IFFREQ(FXTAL);
    configure_FSKDEV(BITRATE);
    configure_TXRATE(BITRATE);
    configure_CICDEC(BITRATE);
    configure_MODULATION(MODdefault);
    uint32_t fskmul = configure_FSKMUL(BITRATE,TMGCORRFRAC);
    uint32_t datarate = configure_DATARATE(BITRATE);
    //we need the values of fskmul and datarate for TMGGAIN config
    configure_TMGGAIN(fskmul,datarate,TMGCORRFRAC);
    configure_AGCATTACK(BITRATE);
    configure_AGCDECAY(BITRATE);
    configure_PHASEGAIN();
    configure_FREQGAIN();
    configure_FREQGAIN2();
    configure_AMPLGAIN();
    configure_AMPLGAIN();

    /*LACKS ENCODING PROGRAMMING*/

    int fabort = 0; /* '1' to abort packet*/
    byte frmmode = 010; /*HDLC*/
    frmmode = frmmode  << 1;
    byte crcmode = 001; /*CRC-16*/
    crcmode = crcmode <<4;
    byte framing = crcmode |frmmode | fabort;
    write_register(FRAMING, framing);

    write_register(IFMODE, 0x00); /*Frame Mode*/

    /*IRQ and DCLK control the switches: '00' OFF, '01' Rx, '10' Tx*/
    byte irq_txenz = 11011111;
    byte dclkz= 10111111;
    byte pincfg1 = read_register(PINCFG1);
    pincfg1 = pincfg1 & dclkz & irq_txenz;
    write_register(PINCFG1, pincfg1);

    byte pincfg2 = 01110110;
    write_register(PINCFG2, pincfg2);
}

void tx(char *data,int data_size){
    write_register(PWRMODE, 0x60);
    delay (3);
    uint8_t freq0;
    uint32_t freq = FCARRIER/FXTAL*2^24 + 1/2;
    freq0 = freq >> 24;
    write_register(FREQ3, freq0);
    freq0 = freq >> 16;
    write_register(FREQ2, freq0);
    freq0 = freq >> 8;
    write_register(FREQ1, freq0);
    freq0 = freq;
    write_register(FREQ0, freq0);

    /*LACKS ENCODING*/

    write_register(PWRMODE, 0x6C);
    delay (0.05);
    auto_ranging();
    write_register(PWRMODE, 0x6D);
    delay (0.05);
    hdlc_tx(data, data_size);
    write_register(PWRMODE, 0x00);

}

char *rx(){
    write_register(PWRMODE, 0x60);
    delay (3);
    int fcarrier=433;
    int fxtal=16.3;
    uint8_t freq0;
    uint32_t freq = fcarrier/fxtal*2^24 + 1/2;
    freq0 = freq >> 24;
    write_register(FREQ3, freq0);
    freq0 = freq >> 16;
    write_register(FREQ2, freq0);
    freq0 = freq >> 8;
    write_register(FREQ1, freq0);
    freq0 = freq;
    write_register(FREQ0, freq0);

    /*LACKS ENCODING*/

    write_register(PWRMODE, 0x68);
    delay (0.05);
    auto_ranging();
    write_register(PWRMODE, 0x69);
    delay (0.05);
    char *data = hdlc_rx();
    write_register(PWRMODE, 0x00);
    return data;
  }

/*It has to be especified the value of each case when the protocol
  would be written*/
void change_x(int parameter, int value) {
    switch(parameter) {
          case FREQUENCY:
              uint8_t freq0;
              uint32_t freq = value/FXTAL*2^24 + 1/2;
              freq0 = freq >> 24;
              write_register(FREQ3, freq0);
              freq0 = freq >> 16;
              write_register(FREQ2, freq0);
              freq0 = freq >> 8;
              write_register(FREQ1, freq0);
              freq0 = freq;
              write_register(FREQ0, freq0);
              break;
          case BITRATE:
              int fdev=H/2*value;
              uint8_t fsk0;
              uint32_t fsk = fdev/FXTAL*2^24 + 1/2;
              fsk0 = fsk >> 16;
              write_register(FSKDEV2, fsk0);
              fsk0 = fsk >> 8;
              write_register(FSKDEV1, fsk0);
              fsk0 = fsk;
             write_register(FSKDEV0, fsk0);
             break;
      }
  }

/*Read a register*/
unsigned int read_register(byte this_register) {
    unsigned int result = 0;   // result to return
    byte reading = 0b01111111;
    byte data_to_send = reading & this_register;
    Serial.println(this_register, BIN);
    digitalWrite(chip_select_pin, LOW);
    SPI.transfer(data_to_send);
    result = SPI.transfer(0x00);
    digitalWrite(chip_select_pin, HIGH);
    return (result);
}

/*Function to write a determinated value in a determinated Register*/
void write_register(byte this_register, byte this_value) {
    byte writing = 0b10000000;
    byte data_to_send = writing | this_register;
    digitalWrite(chip_select_pin, LOW);
    SPI.transfer(data_to_send);
    SPI.transfer(this_value);
    digitalWrite(chip_select_pin, HIGH);
}

/*Auto range needed after initialize or setting chip in SYNTHRX or SYNTHTX*/
void auto_ranging(){
    write_register(PLLRANGING,0x08);
}

/*------------------CONFIGURATION FUNCTIONS---------------------*/
/*This function configures register PLLLOOP*/
void configure_PLLLOOP(int band){
    bandsel = band << 8;
    byte pllloop = bandsel | 0b00001111;
    write_register(PLLLOOP, pllloop);
}

/*The parameter "freq" is supposed to be in Hz.
 *This function configures registers FREQ3, FREQ2,
 *FREQ1, FREQ0*/
void configure_FREQ(int freq){
    uint8_t freq0;
    uint32_t freq = freq/FXTAL*2^24 + 1/2;
    freq0 = freq >> 24;
    write_register(FREQ3, freq0);
    freq0 = freq >> 16;
    write_register(FREQ2, freq0);
    freq0 = freq >> 8;
    write_register(FREQ1, freq0);
    freq0 = freq;
    write_register(FREQ0, freq0);
}

/*This function configures register TXPWR*/
void configure_TXPWR(){
    write_register(TXPWR, 0x0F);
}

/*This function configures register IFFREQHI, IFFREQLO*/
void configure_IFFREQ(){
    int fif=1;
    uint8_t iffreq0;
    uint32_t iffreq = fif/FXTAL*2^17 + 1/2;
    iffreq0 = iffreq >> 8;
    write_register(IFFREQHI, iffreq0);
    iffreq0 = iffreq;
    write_register(IFFREQLO, iffreq0)
}

/*This function configures registers FSKDEV2, FSKDEV1,
*FSKDEV0*/
void configure_FSKDEV(int bitrate){
    int fdev=H/2*bitrate;
    uint8_t fsk0;
    uint32_t fsk = fdev/FXTAL*2^24 + 1/2;
    fsk0 = fsk >> 16;
    write_register(FSKDEV2, fsk0);
    fsk0 = fsk >> 8;
    write_register(FSKDEV1, fsk0);
    fsk0 = fsk;
    write_register(FSKDEV0, fsk0);
}

/*This function configures registers TXRATEHI, TXRATEMID,
*TXRATELO*/
void configure_TXRATE(int bitrate){
    uint8_t txr0;
    uint32_t txr = bitrate/FXTAL*2^24 + 1/2;
    txr0 = txr >> 16;
    write_register(TXRATEHI, txr0);
    txr0 = txr >> 8;
    write_register(TXRATEMID, txr0);
    txr0 = txr;
    write_register(TXRATELO, txr0);
}

/*This function configures registers CICDECHI, CICDECLO*/
void configure_CICDEC(int bitrate){
    uint8_t cicdec0;
    uint32_t cicdec = 1.5*FXTAL/(8*1.2*(1+H)*bitrate);
    cicdec0 = cicdec >> 8;
    write_register(CICDECHI, cicdec0);
    cicdec0 = cicdec;
    write_register(CICDECLO, cicdec0);
    }

/*This function configures register MODULATION*/
void configure_MODULATION(String modulation){
    uint8_t modValue = getModulationReg(modulation);
    write_register(MODULATION, modValue);
}

/*This function configures register FSKMUL*/
uint32_t configure_FSKMUL(int bitrate, int tmgcorrfrac, String modulationValue){
    unsigned int = fskmul;
    if(getModulationReg(modulationValue) < 8){
        fskmul = 1;
    }else{
        unsigned int comprovacion = FXTAL/(4*bitrate*cicdec);
        if(tmgcorrfrac >= comprovacion){
            fskmul = 1/(4*bitrate*cicdec/FXTAL+1/tmgcorrfrac);
        }
	}
    write_register(FSKMUL,fskmul);
    return fskmul;
}

/*This function configures register DATARATE*/
uint32_t configure_DATARATE(int bitrate){
    uint8_t datarate0;
    uint32_t datarate = 2^10*FXTAL/(2*169*bitrate)+1/2;
    datarate0 = datarate >> 8;
    write_register(DATARATEHI, datarate0);
    datarate0 = datarate;
    write_register(DATARATELO, datarate0);
    return datarate;
}

/*This function configures registers TMGGAINHI, TMGGAINLO*/
void configure_TMGGAIN(uint32_t fskmul,uint32_t datarate,int tmgcorrfrac){
    uint8_t tmggain0;
    uint32_t tmggain = fskmul*datarate/tmgcorrfrac + 1/2;
    tmggain0 = tmggain >> 8;
    write_register(TMGGAINHI, tmggain0);
    tmggain0 = tmggain;
    write_register(TMGGAINLO, tmggain0);
}

/*This function configures registers AGCATTACK*/
void configure_AGCATTACK(int bitrate){
    uint32_t modValue = read_register(MODULATION);
    uint32_t agcattack;
    if(modValue == 0){
        agcattack = 27 + log(bitrate/(10*FXTAL))/log(2);
    }else{
        agcattack = 27 + log(bitrate/FXTAL)/log(2);
    }
    write_register(AGCATTACK, agcattack);
}

/*This function configures registers AGCDECAY*/
void configure_AGCDECAY(int bitrate){
    uint32_t modValue = read_register(MODULATION);
    uint32_t agcdecay;
    if(modValue == 0){
        agcdecay = 27 + log(bitrate/(100*FXTAL))/log(2);
    }else{
        agcdecay = 27 + log(bitrate/(10*FXTAL))/log(2);
    }
    write_register(AGCDECAY, agcdecay);
}

/*This function configures registers PHASEGAIN*/
void configure_PHASEGAIN(){
    uint32_t modValue = read_register(MODULATION);
    if(modValue == 0){
        write_register(PHASEGAIN, 0x00);
    }else{
        write_register(PHASEGAIN, 0x03);
    }
}

/*This function configures registers FREQGAIN*/
void configure_FREQGAIN(){
    modValue = read_register(MODULATION);
    if(modValue < 7){
        write_register(FREQGAIN, 0x06);
    }else{
        write_register(FREQGAINEQ, 0x03);
    }
}

/*This function configures registers FREQGAIN2*/
void configure_FREQGAIN2(){
    write_register(FREQGAIN2, 0x06);
}

/*This function configures registers AMPLGAIN*/
void configure_AMPLGAIN(){
    write_register(AMPLGAIN, 0x06);
}

/*--------------------------------------------------------------*/

/*This function translates the String modulation into the value to be assigned
*to the register in hexadecimal*/
uint8_t getModulationReg(String modulation){
    switch (modulation){
        case "ASK":
            modValue = 0x00;
            break;
        case "PSK":
            modValue = 0x04;
            break;
        case "OQPSK":
            modValue = 0x06;
            break;
        case "MSK":
            modValue = 0x07;
            break;
        case "FSK":
            modValue = 0x0B;
            break;
        case "GFSK":
		    modValue = 0x0F;
            break;
    }
    return modValue;
}<commit_msg>Adapted transmission and reception functions<commit_after>/*RF implementation: setting up the transceiver AX5042
 * It uses the SPI library
 *
 * The circuit:
 * - Pins 2, 7, 20, 26 of AX5042 connected to 2,5V Power Supply
 * - Pins
 * - Pin 16 (MISO)of AX5042 connected to MISO (digital pin 50)
 * - Pin 17 (MOSI)of AX5042 connected to MOSI (digital pin 51)
 * - Pin 15 (CLK) of AX5042 connected to SCK (digital pin 52)
 * - Pin 14 (SEL) of AX5042 connected to SS (digital pin 49)
 *
 * All the programming has be done following the AX5042 Programming Manual
*/

#include "comms.h"

const int chip_select_pin = 49;

/*The next variables save the changes on the default ones*/
int frequency;
int bitrate;
String modulationValue;

/*Setting up the transceiver*/
void configure() {
pinMode(chip_select_pin, OUTPUT);
    SPI.begin();
    write_register(AGCTARGET, 0x0E);
    write_register(PLLRNG, (read_register(PLLRNG) | 0x01));
    write_register(RXMISC, ((read_register(RXMISC) | 0x01)& 0xFD)//write 01 in the last 2 bits
    configure_PLLLOOP(BANDSEL);
    configure_FREQ(FCARRIER);
    configure_TXPWR();
    configure_IFFREQ(FXTAL);
    configure_FSKDEV(BITRATE);
    configure_TXRATE(BITRATE);
    configure_CICDEC(BITRATE);
    configure_MODULATION(MODdefault);
    uint32_t fskmul = configure_FSKMUL(BITRATE,TMGCORRFRAC);
    uint32_t datarate = configure_DATARATE(BITRATE);
    //we need the values of fskmul and datarate for TMGGAIN config
    configure_TMGGAIN(fskmul,datarate,TMGCORRFRAC);
    configure_AGCATTACK(BITRATE);
    configure_AGCDECAY(BITRATE);
    configure_PHASEGAIN();
    configure_FREQGAIN();
    configure_FREQGAIN2();
    configure_AMPLGAIN();
    configure_AMPLGAIN();

    /*LACKS ENCODING PROGRAMMING*/

    int fabort = 0; /* '1' to abort packet*/
    byte frmmode = 010; /*HDLC*/
    frmmode = frmmode  << 1;
    byte crcmode = 001; /*CRC-16*/
    crcmode = crcmode <<4;
    byte framing = crcmode |frmmode | fabort;
    write_register(FRAMING, framing);

    write_register(IFMODE, 0x00); /*Frame Mode*/

    /*IRQ and DCLK control the switches: '00' OFF, '01' Rx, '10' Tx*/
    byte irq_txenz = 11011111;
    byte dclkz= 10111111;
    byte pincfg1 = read_register(PINCFG1);
    pincfg1 = pincfg1 & dclkz & irq_txenz;
    write_register(PINCFG1, pincfg1);

    byte pincfg2 = 01110110;
    write_register(PINCFG2, pincfg2);
}

void tx(char *data,int data_size){
    write_register(PWRMODE, 0x60);
    delay (3);
    if(frequency == NULL){
        configure_FREQ(FCARRIER);
    }else{
        configure_FREQ(frequency);
    }

    /*LACKS ENCODING*/

    write_register(PWRMODE, 0x6C);
    delay (0.05);
    auto_ranging();
    write_register(PWRMODE, 0x6D);
    delay (0.05);
    hdlc_tx(data, data_size);
    write_register(PWRMODE, 0x00);

}

char *rx(){
    write_register(PWRMODE, 0x60);
    delay (3);
    if(frequency == NULL){
        configure_FREQ(FCARRIER);
    }else{
        configure_FREQ(frequency);
	}

    /*LACKS ENCODING*/

    write_register(PWRMODE, 0x68);
    delay (0.05);
    auto_ranging();
    write_register(PWRMODE, 0x69);
    delay (0.05);
    char *data = hdlc_rx();
    write_register(PWRMODE, 0x00);
    return data;
  }

/*It has to be specified the value of each case when the protocol
  would be written*/
void change_x(int parameter, int value) {
    switch(parameter) {
          case FREQUENCY:
              uint8_t freq0;
              uint32_t freq = value/FXTAL*2^24 + 1/2;
              freq0 = freq >> 24;
              write_register(FREQ3, freq0);
              freq0 = freq >> 16;
              write_register(FREQ2, freq0);
              freq0 = freq >> 8;
              write_register(FREQ1, freq0);
              freq0 = freq;
              write_register(FREQ0, freq0);
              break;
          case BITRATE:
              int fdev=H/2*value;
              uint8_t fsk0;
              uint32_t fsk = fdev/FXTAL*2^24 + 1/2;
              fsk0 = fsk >> 16;
              write_register(FSKDEV2, fsk0);
              fsk0 = fsk >> 8;
              write_register(FSKDEV1, fsk0);
              fsk0 = fsk;
             write_register(FSKDEV0, fsk0);
             break;
      }
  }

/*Read a register*/
unsigned int read_register(byte this_register) {
    unsigned int result = 0;   // result to return
    byte reading = 0b01111111;
    byte data_to_send = reading & this_register;
    Serial.println(this_register, BIN);
    digitalWrite(chip_select_pin, LOW);
    SPI.transfer(data_to_send);
    result = SPI.transfer(0x00);
    digitalWrite(chip_select_pin, HIGH);
    return (result);
}

/*Function to write a determinated value in a determinated Register*/
void write_register(byte this_register, byte this_value) {
    byte writing = 0b10000000;
    byte data_to_send = writing | this_register;
    digitalWrite(chip_select_pin, LOW);
    SPI.transfer(data_to_send);
    SPI.transfer(this_value);
    digitalWrite(chip_select_pin, HIGH);
}

/*Auto range needed after initialize or setting chip in SYNTHRX or SYNTHTX*/
void auto_ranging(){
    write_register(PLLRANGING,0x08);
}

/*------------------CONFIGURATION FUNCTIONS---------------------*/
/*This function configures register PLLLOOP*/
void configure_PLLLOOP(int band){
    bandsel = band << 8;
    byte pllloop = bandsel | 0b00001111;
    write_register(PLLLOOP, pllloop);
}

/*The parameter "freq" is supposed to be in Hz.
 *This function configures registers FREQ3, FREQ2,
 *FREQ1, FREQ0*/
void configure_FREQ(int freq){
    uint8_t freq0;
    uint32_t freq = freq/FXTAL*2^24 + 1/2;
    freq0 = freq >> 24;
    write_register(FREQ3, freq0);
    freq0 = freq >> 16;
    write_register(FREQ2, freq0);
    freq0 = freq >> 8;
    write_register(FREQ1, freq0);
    freq0 = freq;
    write_register(FREQ0, freq0);
}

/*This function configures register TXPWR*/
void configure_TXPWR(){
    write_register(TXPWR, 0x0F);
}

/*This function configures register IFFREQHI, IFFREQLO*/
void configure_IFFREQ(){
    int fif=1;
    uint8_t iffreq0;
    uint32_t iffreq = fif/FXTAL*2^17 + 1/2;
    iffreq0 = iffreq >> 8;
    write_register(IFFREQHI, iffreq0);
    iffreq0 = iffreq;
    write_register(IFFREQLO, iffreq0)
}

/*This function configures registers FSKDEV2, FSKDEV1,
*FSKDEV0*/
void configure_FSKDEV(int bitrate){
    int fdev=H/2*bitrate;
    uint8_t fsk0;
    uint32_t fsk = fdev/FXTAL*2^24 + 1/2;
    fsk0 = fsk >> 16;
    write_register(FSKDEV2, fsk0);
    fsk0 = fsk >> 8;
    write_register(FSKDEV1, fsk0);
    fsk0 = fsk;
    write_register(FSKDEV0, fsk0);
}

/*This function configures registers TXRATEHI, TXRATEMID,
*TXRATELO*/
void configure_TXRATE(int bitrate){
    uint8_t txr0;
    uint32_t txr = bitrate/FXTAL*2^24 + 1/2;
    txr0 = txr >> 16;
    write_register(TXRATEHI, txr0);
    txr0 = txr >> 8;
    write_register(TXRATEMID, txr0);
    txr0 = txr;
    write_register(TXRATELO, txr0);
}

/*This function configures registers CICDECHI, CICDECLO*/
void configure_CICDEC(int bitrate){
    uint8_t cicdec0;
    uint32_t cicdec = 1.5*FXTAL/(8*1.2*(1+H)*bitrate);
    cicdec0 = cicdec >> 8;
    write_register(CICDECHI, cicdec0);
    cicdec0 = cicdec;
    write_register(CICDECLO, cicdec0);
    }

/*This function configures register MODULATION*/
void configure_MODULATION(String modulation){
    uint8_t modValue = getModulationReg(modulation);
    write_register(MODULATION, modValue);
}

/*This function configures register FSKMUL*/
uint32_t configure_FSKMUL(int bitrate, int tmgcorrfrac, String modulationValue){
    unsigned int = fskmul;
    if(getModulationReg(modulationValue) < 8){
        fskmul = 1;
    }else{
        unsigned int comprovacion = FXTAL/(4*bitrate*cicdec);
        if(tmgcorrfrac >= comprovacion){
            fskmul = 1/(4*bitrate*cicdec/FXTAL+1/tmgcorrfrac);
        }
	}
    write_register(FSKMUL,fskmul);
    return fskmul;
}

/*This function configures register DATARATE*/
uint32_t configure_DATARATE(int bitrate){
    uint8_t datarate0;
    uint32_t datarate = 2^10*FXTAL/(2*169*bitrate)+1/2;
    datarate0 = datarate >> 8;
    write_register(DATARATEHI, datarate0);
    datarate0 = datarate;
    write_register(DATARATELO, datarate0);
    return datarate;
}

/*This function configures registers TMGGAINHI, TMGGAINLO*/
void configure_TMGGAIN(uint32_t fskmul,uint32_t datarate,int tmgcorrfrac){
    uint8_t tmggain0;
    uint32_t tmggain = fskmul*datarate/tmgcorrfrac + 1/2;
    tmggain0 = tmggain >> 8;
    write_register(TMGGAINHI, tmggain0);
    tmggain0 = tmggain;
    write_register(TMGGAINLO, tmggain0);
}

/*This function configures registers AGCATTACK*/
void configure_AGCATTACK(int bitrate){
    uint32_t modValue = read_register(MODULATION);
    uint32_t agcattack;
    if(modValue == 0){
        agcattack = 27 + log(bitrate/(10*FXTAL))/log(2);
    }else{
        agcattack = 27 + log(bitrate/FXTAL)/log(2);
    }
    write_register(AGCATTACK, agcattack);
}

/*This function configures registers AGCDECAY*/
void configure_AGCDECAY(int bitrate){
    uint32_t modValue = read_register(MODULATION);
    uint32_t agcdecay;
    if(modValue == 0){
        agcdecay = 27 + log(bitrate/(100*FXTAL))/log(2);
    }else{
        agcdecay = 27 + log(bitrate/(10*FXTAL))/log(2);
    }
    write_register(AGCDECAY, agcdecay);
}

/*This function configures registers PHASEGAIN*/
void configure_PHASEGAIN(){
    uint32_t modValue = read_register(MODULATION);
    if(modValue == 0){
        write_register(PHASEGAIN, 0x00);
    }else{
        write_register(PHASEGAIN, 0x03);
    }
}

/*This function configures registers FREQGAIN*/
void configure_FREQGAIN(){
    modValue = read_register(MODULATION);
    if(modValue < 7){
        write_register(FREQGAIN, 0x06);
    }else{
        write_register(FREQGAINEQ, 0x03);
    }
}

/*This function configures registers FREQGAIN2*/
void configure_FREQGAIN2(){
    write_register(FREQGAIN2, 0x06);
}

/*This function configures registers AMPLGAIN*/
void configure_AMPLGAIN(){
    write_register(AMPLGAIN, 0x06);
}

/*--------------------------------------------------------------*/

/*This function translates the String modulation into the value to be assigned
*to the register in hexadecimal*/
uint8_t getModulationReg(String modulation){
    switch (modulation){
        case "ASK":
            modValue = 0x00;
            break;
        case "PSK":
            modValue = 0x04;
            break;
        case "OQPSK":
            modValue = 0x06;
            break;
        case "MSK":
            modValue = 0x07;
            break;
        case "FSK":
            modValue = 0x0B;
            break;
        case "GFSK":
		    modValue = 0x0F;
            break;
    }
    return modValue;
}<|endoftext|>


<commit_before>// LICENSE/*{{{*/
/*
  sxc - Simple Xmpp Client
  Copyright (C) 2008 Dennis Felsing, Andreas Waidler

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

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/*}}}*/

// INCLUDES/*{{{*/

#ifdef HAVE_CONFIG_H
#   include <config.hxx>
#   include <print.hxx>
#endif

#include <string>
#include <Control/Control.hxx>
#include <Control/File/Output.hxx>
#include <Control/Command/Command.hxx>
#include <libsxc/Exception/Exception.hxx>
#include <Time/Timestamp.hxx>
#include <Time/LocalDateTime.hxx>
#include <Time/IsoDateTimeFormat.hxx>

/*}}}*/

namespace Control
{
    namespace File
    {
        Output::Output(const std::string &accountName)/*{{{*/
        : _accountName(accountName)
        {
        }

/*}}}*/
        std::string Output::_createPath() const/*{{{*/
        {
            return _accountName + "/out";
        }

/*}}}*/
        std::string Output::_format(const std::string &output) const/*{{{*/
        {
            Time::LocalDateTime date = Time::LocalDateTime(Time::Timestamp());
            Time::IsoDateTimeFormat format(&date);
            return format.string() + ' ' + output;
        }

/*}}}*/
    }
}

// Use no tabs at all; four spaces indentation; max. eighty chars per line.
// vim: et ts=4 sw=4 tw=80 fo+=c fdm=marker
<commit_msg>Removed unnecessary includes.<commit_after>// LICENSE/*{{{*/
/*
  sxc - Simple Xmpp Client
  Copyright (C) 2008 Dennis Felsing, Andreas Waidler

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

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/*}}}*/

// INCLUDES/*{{{*/

#ifdef HAVE_CONFIG_H
#   include <config.hxx>
#   include <print.hxx>
#endif

#include <string>
#include <Control/File/Output.hxx>
#include <Time/Timestamp.hxx>
#include <Time/LocalDateTime.hxx>
#include <Time/IsoDateTimeFormat.hxx>

/*}}}*/

namespace Control
{
    namespace File
    {
        Output::Output(const std::string &accountName)/*{{{*/
        : _accountName(accountName)
        {
        }

/*}}}*/
        std::string Output::_createPath() const/*{{{*/
        {
            return _accountName + "/out";
        }

/*}}}*/
        std::string Output::_format(const std::string &output) const/*{{{*/
        {
            Time::LocalDateTime date = Time::LocalDateTime(Time::Timestamp());
            Time::IsoDateTimeFormat format(&date);
            return format.string() + ' ' + output;
        }

/*}}}*/
    }
}

// Use no tabs at all; four spaces indentation; max. eighty chars per line.
// vim: et ts=4 sw=4 tw=80 fo+=c fdm=marker
<|endoftext|>


<commit_before>//===-- WriteInst.cpp - Functions for writing instructions -------*- C++ -*--=//
//
// This file implements the routines for encoding instruction opcodes to a
// bytecode stream.
//
// Note that the performance of this library is not terribly important, because
// it shouldn't be used by JIT type applications... so it is not a huge focus
// at least.  :)
//
//===----------------------------------------------------------------------===//

#include "WriterInternals.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
#include "llvm/iTerminators.h"
#include <algorithm>

typedef unsigned char uchar;

// outputInstructionFormat0 - Output those wierd instructions that have a large
// number of operands or have large operands themselves...
//
// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
//
static void outputInstructionFormat0(const Instruction *I,
				     const SlotCalculator &Table,
				     unsigned Type, std::deque<uchar> &Out) {
  // Opcode must have top two bits clear...
  output_vbr(I->getOpcode() << 2, Out);          // Instruction Opcode ID
  output_vbr(Type, Out);                         // Result type

  unsigned NumArgs = I->getNumOperands();
  output_vbr(NumArgs + isa<CastInst>(I), Out);

  for (unsigned i = 0; i < NumArgs; ++i) {
    int Slot = Table.getValSlot(I->getOperand(i));
    assert(Slot >= 0 && "No slot number for value!?!?");
    output_vbr((unsigned)Slot, Out);
  }

  if (isa<CastInst>(I)) {
    int Slot = Table.getValSlot(I->getType());
    assert(Slot != -1 && "Cast return type unknown?");
    output_vbr((unsigned)Slot, Out);
  }

  align32(Out);    // We must maintain correct alignment!
}

// outputInstrVarArgsCall - Output the obsurdly annoying varargs function calls.
// This are more annoying than most because the signature of the call does not
// tell us anything about the types of the arguments in the varargs portion.
// Because of this, we encode (as type 0) all of the argument types explicitly
// before the argument value.  This really sucks, but you shouldn't be using
// varargs functions in your code! *death to printf*!
//
// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
//
static void outputInstrVarArgsCall(const Instruction *I,
				   const SlotCalculator &Table, unsigned Type,
				   std::deque<uchar> &Out) {
  assert(isa<CallInst>(I) || isa<InvokeInst>(I));
  // Opcode must have top two bits clear...
  output_vbr(I->getOpcode() << 2, Out);          // Instruction Opcode ID
  output_vbr(Type, Out);                         // Result type (varargs type)

  unsigned NumArgs = I->getNumOperands();
  output_vbr(NumArgs*2, Out);
  // TODO: Don't need to emit types for the fixed types of the varargs function
  // prototype...

  // The type for the function has already been emitted in the type field of the
  // instruction.  Just emit the slot # now.
  int Slot = Table.getValSlot(I->getOperand(0));
  assert(Slot >= 0 && "No slot number for value!?!?");
  output_vbr((unsigned)Slot, Out);

  // Output a dummy field to fill Arg#2 in the reader that is currently unused
  // for varargs calls.  This is a gross hack to make the code simpler, but we
  // aren't really doing very small bytecode for varargs calls anyways.
  // FIXME in the future: Smaller bytecode for varargs calls
  output_vbr(0, Out);

  for (unsigned i = 1; i < NumArgs; ++i) {
    // Output Arg Type ID
    Slot = Table.getValSlot(I->getOperand(i)->getType());
    assert(Slot >= 0 && "No slot number for value!?!?");
    output_vbr((unsigned)Slot, Out);

    // Output arg ID itself
    Slot = Table.getValSlot(I->getOperand(i));
    assert(Slot >= 0 && "No slot number for value!?!?");
    output_vbr((unsigned)Slot, Out);
  }
  align32(Out);    // We must maintain correct alignment!
}

// outputInstructionFormat1 - Output one operand instructions, knowing that no
// operand index is >= 2^12.
//
static void outputInstructionFormat1(const Instruction *I,
				     const SlotCalculator &Table, int *Slots,
				     unsigned Type, std::deque<uchar> &Out) {
  unsigned Opcode = I->getOpcode();      // Instruction Opcode ID

  // bits   Instruction format:
  // --------------------------
  // 01-00: Opcode type, fixed to 1.
  // 07-02: Opcode
  // 19-08: Resulting type plane
  // 31-20: Operand #1 (if set to (2^12-1), then zero operands)
  //
  unsigned Bits = 1 | (Opcode << 2) | (Type << 8) | (Slots[0] << 20);
  //  cerr << "1 " << IType << " " << Type << " " << Slots[0] << endl;
  output(Bits, Out);
}

// outputInstructionFormat2 - Output two operand instructions, knowing that no
// operand index is >= 2^8.
//
static void outputInstructionFormat2(const Instruction *I,
				     const SlotCalculator &Table, int *Slots,
				     unsigned Type, std::deque<uchar> &Out) {
  unsigned Opcode = I->getOpcode();      // Instruction Opcode ID

  // bits   Instruction format:
  // --------------------------
  // 01-00: Opcode type, fixed to 2.
  // 07-02: Opcode
  // 15-08: Resulting type plane
  // 23-16: Operand #1
  // 31-24: Operand #2
  //
  unsigned Bits = 2 | (Opcode << 2) | (Type << 8) |
                    (Slots[0] << 16) | (Slots[1] << 24);
  //  cerr << "2 " << IType << " " << Type << " " << Slots[0] << " "
  //       << Slots[1] << endl;
  output(Bits, Out);
}

// outputInstructionFormat3 - Output three operand instructions, knowing that no
// operand index is >= 2^6.
//
static void outputInstructionFormat3(const Instruction *I,
				     const SlotCalculator &Table, int *Slots,
				     unsigned Type, std::deque<uchar> &Out) {
  unsigned Opcode = I->getOpcode();      // Instruction Opcode ID

  // bits   Instruction format:
  // --------------------------
  // 01-00: Opcode type, fixed to 3.
  // 07-02: Opcode
  // 13-08: Resulting type plane
  // 19-14: Operand #1
  // 25-20: Operand #2
  // 31-26: Operand #3
  //
  unsigned Bits = 3 | (Opcode << 2) | (Type << 8) |
          (Slots[0] << 14) | (Slots[1] << 20) | (Slots[2] << 26);
  //cerr << "3 " << IType << " " << Type << " " << Slots[0] << " "
  //     << Slots[1] << " " << Slots[2] << endl;
  output(Bits, Out);
}

void BytecodeWriter::processInstruction(const Instruction *I) {
  assert(I->getOpcode() < 64 && "Opcode too big???");

  unsigned NumOperands = I->getNumOperands();
  int MaxOpSlot = 0;
  int Slots[3]; Slots[0] = (1 << 12)-1;   // Marker to signify 0 operands

  for (unsigned i = 0; i < NumOperands; ++i) {
    const Value *Def = I->getOperand(i);
    int slot = Table.getValSlot(Def);
    assert(slot != -1 && "Broken bytecode!");
    if (slot > MaxOpSlot) MaxOpSlot = slot;
    if (i < 3) Slots[i] = slot;
  }

  // Figure out which type to encode with the instruction.  Typically we want
  // the type of the first parameter, as opposed to the type of the instruction
  // (for example, with setcc, we always know it returns bool, but the type of
  // the first param is actually interesting).  But if we have no arguments
  // we take the type of the instruction itself.
  //
  const Type *Ty;
  switch (I->getOpcode()) {
  case Instruction::Malloc:
  case Instruction::Alloca:
    Ty = I->getType();  // Malloc & Alloca ALWAYS want to encode the return type
    break;
  case Instruction::Store:
    Ty = I->getOperand(1)->getType();  // Encode the pointer type...
    assert(isa<PointerType>(Ty) && "Store to nonpointer type!?!?");
    break;
  default:              // Otherwise use the default behavior...
    Ty = NumOperands ? I->getOperand(0)->getType() : I->getType();
    break;
  }

  unsigned Type;
  int Slot = Table.getValSlot(Ty);
  assert(Slot != -1 && "Type not available!!?!");
  Type = (unsigned)Slot;

  // Make sure that we take the type number into consideration.  We don't want
  // to overflow the field size for the instruction format we select.
  //
  if (Slot > MaxOpSlot) MaxOpSlot = Slot;

  // Handle the special case for cast...
  if (isa<CastInst>(I)) {
    // Cast has to encode the destination type as the second argument in the
    // packet, or else we won't know what type to cast to!
    Slots[1] = Table.getValSlot(I->getType());
    assert(Slots[1] != -1 && "Cast return type unknown?");
    if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1];
    NumOperands++;
  } else if (const CallInst *CI = dyn_cast<CallInst>(I)) {// Handle VarArg calls
    PointerType *Ty = cast<PointerType>(CI->getCalledValue()->getType());
    if (cast<FunctionType>(Ty->getElementType())->isVarArg()) {
      outputInstrVarArgsCall(I, Table, Type, Out);
      return;
    }
  } else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) { // ...  & Invokes
    PointerType *Ty = cast<PointerType>(II->getCalledValue()->getType());
    if (cast<FunctionType>(Ty->getElementType())->isVarArg()) {
      outputInstrVarArgsCall(I, Table, Type, Out);
      return;
    }
  }

  // Decide which instruction encoding to use.  This is determined primarily by
  // the number of operands, and secondarily by whether or not the max operand
  // will fit into the instruction encoding.  More operands == fewer bits per
  // operand.
  //
  switch (NumOperands) {
  case 0:
  case 1:
    if (MaxOpSlot < (1 << 12)-1) { // -1 because we use 4095 to indicate 0 ops
      outputInstructionFormat1(I, Table, Slots, Type, Out);
      return;
    }
    break;

  case 2:
    if (MaxOpSlot < (1 << 8)) {
      outputInstructionFormat2(I, Table, Slots, Type, Out);
      return;
    }
    break;

  case 3:
    if (MaxOpSlot < (1 << 6)) {
      outputInstructionFormat3(I, Table, Slots, Type, Out);
      return;
    }
    break;
  }

  // If we weren't handled before here, we either have a large number of
  // operands or a large operand index that we are refering to.
  outputInstructionFormat0(I, Table, Type, Out);
}
<commit_msg>Fix constness problem<commit_after>//===-- WriteInst.cpp - Functions for writing instructions -------*- C++ -*--=//
//
// This file implements the routines for encoding instruction opcodes to a
// bytecode stream.
//
// Note that the performance of this library is not terribly important, because
// it shouldn't be used by JIT type applications... so it is not a huge focus
// at least.  :)
//
//===----------------------------------------------------------------------===//

#include "WriterInternals.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
#include "llvm/iTerminators.h"
#include <algorithm>

typedef unsigned char uchar;

// outputInstructionFormat0 - Output those wierd instructions that have a large
// number of operands or have large operands themselves...
//
// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
//
static void outputInstructionFormat0(const Instruction *I,
				     const SlotCalculator &Table,
				     unsigned Type, std::deque<uchar> &Out) {
  // Opcode must have top two bits clear...
  output_vbr(I->getOpcode() << 2, Out);          // Instruction Opcode ID
  output_vbr(Type, Out);                         // Result type

  unsigned NumArgs = I->getNumOperands();
  output_vbr(NumArgs + isa<CastInst>(I), Out);

  for (unsigned i = 0; i < NumArgs; ++i) {
    int Slot = Table.getValSlot(I->getOperand(i));
    assert(Slot >= 0 && "No slot number for value!?!?");
    output_vbr((unsigned)Slot, Out);
  }

  if (isa<CastInst>(I)) {
    int Slot = Table.getValSlot(I->getType());
    assert(Slot != -1 && "Cast return type unknown?");
    output_vbr((unsigned)Slot, Out);
  }

  align32(Out);    // We must maintain correct alignment!
}

// outputInstrVarArgsCall - Output the obsurdly annoying varargs function calls.
// This are more annoying than most because the signature of the call does not
// tell us anything about the types of the arguments in the varargs portion.
// Because of this, we encode (as type 0) all of the argument types explicitly
// before the argument value.  This really sucks, but you shouldn't be using
// varargs functions in your code! *death to printf*!
//
// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
//
static void outputInstrVarArgsCall(const Instruction *I,
				   const SlotCalculator &Table, unsigned Type,
				   std::deque<uchar> &Out) {
  assert(isa<CallInst>(I) || isa<InvokeInst>(I));
  // Opcode must have top two bits clear...
  output_vbr(I->getOpcode() << 2, Out);          // Instruction Opcode ID
  output_vbr(Type, Out);                         // Result type (varargs type)

  unsigned NumArgs = I->getNumOperands();
  output_vbr(NumArgs*2, Out);
  // TODO: Don't need to emit types for the fixed types of the varargs function
  // prototype...

  // The type for the function has already been emitted in the type field of the
  // instruction.  Just emit the slot # now.
  int Slot = Table.getValSlot(I->getOperand(0));
  assert(Slot >= 0 && "No slot number for value!?!?");
  output_vbr((unsigned)Slot, Out);

  // Output a dummy field to fill Arg#2 in the reader that is currently unused
  // for varargs calls.  This is a gross hack to make the code simpler, but we
  // aren't really doing very small bytecode for varargs calls anyways.
  // FIXME in the future: Smaller bytecode for varargs calls
  output_vbr(0, Out);

  for (unsigned i = 1; i < NumArgs; ++i) {
    // Output Arg Type ID
    Slot = Table.getValSlot(I->getOperand(i)->getType());
    assert(Slot >= 0 && "No slot number for value!?!?");
    output_vbr((unsigned)Slot, Out);

    // Output arg ID itself
    Slot = Table.getValSlot(I->getOperand(i));
    assert(Slot >= 0 && "No slot number for value!?!?");
    output_vbr((unsigned)Slot, Out);
  }
  align32(Out);    // We must maintain correct alignment!
}

// outputInstructionFormat1 - Output one operand instructions, knowing that no
// operand index is >= 2^12.
//
static void outputInstructionFormat1(const Instruction *I,
				     const SlotCalculator &Table, int *Slots,
				     unsigned Type, std::deque<uchar> &Out) {
  unsigned Opcode = I->getOpcode();      // Instruction Opcode ID

  // bits   Instruction format:
  // --------------------------
  // 01-00: Opcode type, fixed to 1.
  // 07-02: Opcode
  // 19-08: Resulting type plane
  // 31-20: Operand #1 (if set to (2^12-1), then zero operands)
  //
  unsigned Bits = 1 | (Opcode << 2) | (Type << 8) | (Slots[0] << 20);
  //  cerr << "1 " << IType << " " << Type << " " << Slots[0] << endl;
  output(Bits, Out);
}

// outputInstructionFormat2 - Output two operand instructions, knowing that no
// operand index is >= 2^8.
//
static void outputInstructionFormat2(const Instruction *I,
				     const SlotCalculator &Table, int *Slots,
				     unsigned Type, std::deque<uchar> &Out) {
  unsigned Opcode = I->getOpcode();      // Instruction Opcode ID

  // bits   Instruction format:
  // --------------------------
  // 01-00: Opcode type, fixed to 2.
  // 07-02: Opcode
  // 15-08: Resulting type plane
  // 23-16: Operand #1
  // 31-24: Operand #2
  //
  unsigned Bits = 2 | (Opcode << 2) | (Type << 8) |
                    (Slots[0] << 16) | (Slots[1] << 24);
  //  cerr << "2 " << IType << " " << Type << " " << Slots[0] << " "
  //       << Slots[1] << endl;
  output(Bits, Out);
}

// outputInstructionFormat3 - Output three operand instructions, knowing that no
// operand index is >= 2^6.
//
static void outputInstructionFormat3(const Instruction *I,
				     const SlotCalculator &Table, int *Slots,
				     unsigned Type, std::deque<uchar> &Out) {
  unsigned Opcode = I->getOpcode();      // Instruction Opcode ID

  // bits   Instruction format:
  // --------------------------
  // 01-00: Opcode type, fixed to 3.
  // 07-02: Opcode
  // 13-08: Resulting type plane
  // 19-14: Operand #1
  // 25-20: Operand #2
  // 31-26: Operand #3
  //
  unsigned Bits = 3 | (Opcode << 2) | (Type << 8) |
          (Slots[0] << 14) | (Slots[1] << 20) | (Slots[2] << 26);
  //cerr << "3 " << IType << " " << Type << " " << Slots[0] << " "
  //     << Slots[1] << " " << Slots[2] << endl;
  output(Bits, Out);
}

void BytecodeWriter::processInstruction(const Instruction *I) {
  assert(I->getOpcode() < 64 && "Opcode too big???");

  unsigned NumOperands = I->getNumOperands();
  int MaxOpSlot = 0;
  int Slots[3]; Slots[0] = (1 << 12)-1;   // Marker to signify 0 operands

  for (unsigned i = 0; i < NumOperands; ++i) {
    const Value *Def = I->getOperand(i);
    int slot = Table.getValSlot(Def);
    assert(slot != -1 && "Broken bytecode!");
    if (slot > MaxOpSlot) MaxOpSlot = slot;
    if (i < 3) Slots[i] = slot;
  }

  // Figure out which type to encode with the instruction.  Typically we want
  // the type of the first parameter, as opposed to the type of the instruction
  // (for example, with setcc, we always know it returns bool, but the type of
  // the first param is actually interesting).  But if we have no arguments
  // we take the type of the instruction itself.
  //
  const Type *Ty;
  switch (I->getOpcode()) {
  case Instruction::Malloc:
  case Instruction::Alloca:
    Ty = I->getType();  // Malloc & Alloca ALWAYS want to encode the return type
    break;
  case Instruction::Store:
    Ty = I->getOperand(1)->getType();  // Encode the pointer type...
    assert(isa<PointerType>(Ty) && "Store to nonpointer type!?!?");
    break;
  default:              // Otherwise use the default behavior...
    Ty = NumOperands ? I->getOperand(0)->getType() : I->getType();
    break;
  }

  unsigned Type;
  int Slot = Table.getValSlot(Ty);
  assert(Slot != -1 && "Type not available!!?!");
  Type = (unsigned)Slot;

  // Make sure that we take the type number into consideration.  We don't want
  // to overflow the field size for the instruction format we select.
  //
  if (Slot > MaxOpSlot) MaxOpSlot = Slot;

  // Handle the special case for cast...
  if (isa<CastInst>(I)) {
    // Cast has to encode the destination type as the second argument in the
    // packet, or else we won't know what type to cast to!
    Slots[1] = Table.getValSlot(I->getType());
    assert(Slots[1] != -1 && "Cast return type unknown?");
    if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1];
    NumOperands++;
  } else if (const CallInst *CI = dyn_cast<CallInst>(I)) {// Handle VarArg calls
    const PointerType *Ty = cast<PointerType>(CI->getCalledValue()->getType());
    if (cast<FunctionType>(Ty->getElementType())->isVarArg()) {
      outputInstrVarArgsCall(I, Table, Type, Out);
      return;
    }
  } else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) { // ...  & Invokes
    const PointerType *Ty = cast<PointerType>(II->getCalledValue()->getType());
    if (cast<FunctionType>(Ty->getElementType())->isVarArg()) {
      outputInstrVarArgsCall(I, Table, Type, Out);
      return;
    }
  }

  // Decide which instruction encoding to use.  This is determined primarily by
  // the number of operands, and secondarily by whether or not the max operand
  // will fit into the instruction encoding.  More operands == fewer bits per
  // operand.
  //
  switch (NumOperands) {
  case 0:
  case 1:
    if (MaxOpSlot < (1 << 12)-1) { // -1 because we use 4095 to indicate 0 ops
      outputInstructionFormat1(I, Table, Slots, Type, Out);
      return;
    }
    break;

  case 2:
    if (MaxOpSlot < (1 << 8)) {
      outputInstructionFormat2(I, Table, Slots, Type, Out);
      return;
    }
    break;

  case 3:
    if (MaxOpSlot < (1 << 6)) {
      outputInstructionFormat3(I, Table, Slots, Type, Out);
      return;
    }
    break;
  }

  // If we weren't handled before here, we either have a large number of
  // operands or a large operand index that we are refering to.
  outputInstructionFormat0(I, Table, Type, Out);
}
<|endoftext|>


<commit_before>#include "instrumentation_factories.h"

#include <complex>
#include <vector>

#include <deal.II/base/conditional_ostream.h>

#include "convergence/status.h"
#include "instrumentation/basic_instrument.h"
#include "instrumentation/instrument.h"
#include "instrumentation/converter/convergence_to_string.h"
#include "instrumentation/converter/int_vector_complex_pair_to_string.h"
#include "instrumentation/converter/int_double_pair_to_string.h"
#include "instrumentation/converter/string_color_pair_to_string.h"
#include "instrumentation/outstream/to_conditional_ostream.h"
#include "instrumentation/outstream/to_ostream.h"
#include "utility/colors.h"

namespace bart {

namespace instrumentation {

namespace factory {

template<typename InputType>
std::unique_ptr<InstrumentType<InputType>> MakeBasicInstrument(std::unique_ptr<
    OutstreamType<InputType>> outstream_ptr_) {
  using ReturnType = instrumentation::BasicInstrument<InputType>;
  return std::make_unique<ReturnType>(std::move(outstream_ptr_));
}

// MAKE CONVERTER ==============================================================

template <>
std::unique_ptr<ConverterType<convergence::Status, std::string>>
MakeConverter<convergence::Status, std::string>() {
  using ReturnType = instrumentation::converter::ConvergenceToString;
  return std::make_unique<ReturnType>();
}

template <>
auto MakeConverter<std::pair<int, std::vector<std::complex<double>>>, std::string, int> (const int precision)
-> std::unique_ptr<ConverterType<std::pair<int, std::vector<std::complex<double>>>, std::string>>{
    using ReturnType = instrumentation::converter::IntVectorComplexPairToString;
    auto return_ptr = std::make_unique<ReturnType>();
    return_ptr->set_precision(precision);
    return return_ptr;
}

template <>
std::unique_ptr<ConverterType<std::pair<int, double>, std::string>>
MakeConverter<std::pair<int, double>, std::string, int>(const int precision) {
  using ReturnType = instrumentation::converter::IntDoublePairToString;
  auto return_ptr = std::make_unique<ReturnType>();
  return_ptr->set_precision(precision);
  return return_ptr;
}

template <>
std::unique_ptr<ConverterType<std::pair<std::string, utility::Color>, std::string>>
MakeConverter<std::pair<std::string, utility::Color>, std::string>() {
  using ReturnType = instrumentation::converter::StringColorPairToString;
  auto return_ptr = std::make_unique<ReturnType>();
  return return_ptr;
}

// MAKE INSTRUMENT =============================================================

template <typename InputType, typename OutputType>
std::unique_ptr<InstrumentType<InputType>> MakeInstrument(
    std::unique_ptr<ConverterType<InputType, OutputType>> converter_ptr_,
    std::unique_ptr<OutstreamType<OutputType>> outstream_ptr_) {
  using ReturnType = instrumentation::Instrument<InputType, OutputType>;
  return std::make_unique<ReturnType>(std::move(converter_ptr_),
                                      std::move(outstream_ptr_));
}

// MAKE OUTSTREAM ==============================================================

template <>
std::unique_ptr<OutstreamType<std::string>>
MakeOutstream<std::string, std::unique_ptr<dealii::ConditionalOStream>>(
    std::unique_ptr<dealii::ConditionalOStream> conditional_ostream_ptr) {
  using ReturnType = instrumentation::outstream::ToConditionalOstream;
  return std::make_unique<ReturnType>(std::move(conditional_ostream_ptr));
}

template <>
std::unique_ptr<OutstreamType<std::string>>
MakeOutstream<std::string, std::unique_ptr<std::ostream>>(
    std::unique_ptr<std::ostream> ostream_ptr) {
  using ReturnType = instrumentation::outstream::ToOstream;
  return std::make_unique<ReturnType>(std::move(ostream_ptr));
}

template std::unique_ptr<InstrumentType<convergence::Status>> MakeInstrument(std::unique_ptr<ConverterType<convergence::Status, std::string>>, std::unique_ptr<OutstreamType<std::string>>);
template std::unique_ptr<InstrumentType<std::pair<int, double>>> MakeInstrument(std::unique_ptr<ConverterType<std::pair<int, double>, std::string>>, std::unique_ptr<OutstreamType<std::string>>);
template std::unique_ptr<InstrumentType<std::pair<std::string, utility::Color>>> MakeInstrument(std::unique_ptr<ConverterType<std::pair<std::string, utility::Color>, std::string>>, std::unique_ptr<OutstreamType<std::string>>);
template std::unique_ptr<InstrumentType<std::string>> MakeBasicInstrument(std::unique_ptr<OutstreamType<std::string>>);

} // namespace factory

} // namespace instrumentation

} // namespace bart
<commit_msg>Added some aliases to make converter factory functions easier to read.<commit_after>#include "instrumentation_factories.h"

#include <complex>
#include <vector>

#include <deal.II/base/conditional_ostream.h>

#include "convergence/status.h"
#include "instrumentation/basic_instrument.h"
#include "instrumentation/instrument.h"
#include "instrumentation/converter/convergence_to_string.h"
#include "instrumentation/converter/int_vector_complex_pair_to_string.h"
#include "instrumentation/converter/int_double_pair_to_string.h"
#include "instrumentation/converter/string_color_pair_to_string.h"
#include "instrumentation/outstream/to_conditional_ostream.h"
#include "instrumentation/outstream/to_ostream.h"
#include "utility/colors.h"

namespace bart {

namespace instrumentation {

namespace factory {

template<typename InputType>
std::unique_ptr<InstrumentType<InputType>> MakeBasicInstrument(std::unique_ptr<
    OutstreamType<InputType>> outstream_ptr_) {
  using ReturnType = instrumentation::BasicInstrument<InputType>;
  return std::make_unique<ReturnType>(std::move(outstream_ptr_));
}

// MAKE CONVERTER ==============================================================

namespace  {
  // types used by converters
using IntComplexVectorPair = std::pair<int, std::vector<std::complex<double>>>;
using IntDoublePair = std::pair<int, double>;
using StringColorPair = std::pair<std::string, utility::Color>;

template <typename InputType>
using ConvertThisToStringPtr = std::unique_ptr<ConverterType<InputType, std::string>>;
} // namespace

template <>
std::unique_ptr<ConverterType<convergence::Status, std::string>>
MakeConverter<convergence::Status, std::string>() {
  using ReturnType = instrumentation::converter::ConvergenceToString;
  return std::make_unique<ReturnType>();
}

template <>
auto MakeConverter<IntComplexVectorPair, std::string, int> (const int precision)
-> ConvertThisToStringPtr<IntComplexVectorPair> {
    using ReturnType = instrumentation::converter::IntVectorComplexPairToString;
    auto return_ptr = std::make_unique<ReturnType>();
    return_ptr->set_precision(precision);
    return return_ptr;
}

template <>
ConvertThisToStringPtr<IntDoublePair>
MakeConverter<IntDoublePair, std::string, int>(const int precision) {
  using ReturnType = instrumentation::converter::IntDoublePairToString;
  auto return_ptr = std::make_unique<ReturnType>();
  return_ptr->set_precision(precision);
  return return_ptr;
}

template <>
ConvertThisToStringPtr<StringColorPair>
MakeConverter<StringColorPair, std::string>() {
  using ReturnType = instrumentation::converter::StringColorPairToString;
  auto return_ptr = std::make_unique<ReturnType>();
  return return_ptr;
}

// MAKE INSTRUMENT =============================================================

template <typename InputType, typename OutputType>
std::unique_ptr<InstrumentType<InputType>> MakeInstrument(
    std::unique_ptr<ConverterType<InputType, OutputType>> converter_ptr_,
    std::unique_ptr<OutstreamType<OutputType>> outstream_ptr_) {
  using ReturnType = instrumentation::Instrument<InputType, OutputType>;
  return std::make_unique<ReturnType>(std::move(converter_ptr_),
                                      std::move(outstream_ptr_));
}

// MAKE OUTSTREAM ==============================================================

template <>
std::unique_ptr<OutstreamType<std::string>>
MakeOutstream<std::string, std::unique_ptr<dealii::ConditionalOStream>>(
    std::unique_ptr<dealii::ConditionalOStream> conditional_ostream_ptr) {
  using ReturnType = instrumentation::outstream::ToConditionalOstream;
  return std::make_unique<ReturnType>(std::move(conditional_ostream_ptr));
}

template <>
std::unique_ptr<OutstreamType<std::string>>
MakeOutstream<std::string, std::unique_ptr<std::ostream>>(
    std::unique_ptr<std::ostream> ostream_ptr) {
  using ReturnType = instrumentation::outstream::ToOstream;
  return std::make_unique<ReturnType>(std::move(ostream_ptr));
}

template std::unique_ptr<InstrumentType<convergence::Status>> MakeInstrument(std::unique_ptr<ConverterType<convergence::Status, std::string>>, std::unique_ptr<OutstreamType<std::string>>);
template std::unique_ptr<InstrumentType<std::pair<int, double>>> MakeInstrument(std::unique_ptr<ConverterType<std::pair<int, double>, std::string>>, std::unique_ptr<OutstreamType<std::string>>);
template std::unique_ptr<InstrumentType<std::pair<std::string, utility::Color>>> MakeInstrument(std::unique_ptr<ConverterType<std::pair<std::string, utility::Color>, std::string>>, std::unique_ptr<OutstreamType<std::string>>);
template std::unique_ptr<InstrumentType<std::string>> MakeBasicInstrument(std::unique_ptr<OutstreamType<std::string>>);

} // namespace factory

} // namespace instrumentation

} // namespace bart
<|endoftext|>


<commit_before>/***************************************************************************
                          constraintactivitiesendstudentsdayform.cpp  -  description
                             -------------------
    begin                : 2008
    copyright            : (C) 2008 by Lalescu Liviu
    email                : Please see http://lalescu.ro/liviu/ for details about contacting Liviu Lalescu (in particular, you can find here the e-mail address)
 ***************************************************************************/

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

#include "constraintactivitiesendstudentsdayform.h"
#include "addconstraintactivitiesendstudentsdayform.h"
#include "modifyconstraintactivitiesendstudentsdayform.h"

#include <QListWidget>
#include <QScrollBar>
#include <QAbstractItemView>

ConstraintActivitiesEndStudentsDayForm::ConstraintActivitiesEndStudentsDayForm(QWidget* parent): ConstraintBaseDialog(parent)
{
	//: This is the title of the dialog to see the list of all constraints of this type
	setWindowTitle(QCoreApplication::translate("ConstraintActivitiesEndStudentsDayForm_template", "Constraints activities end students day"));
//	populateFilters();
	filterChanged();
}

bool ConstraintActivitiesEndStudentsDayForm::filterOk(const TimeConstraint* ctr) const
{
	if(ctr->type==CONSTRAINT_ACTIVITIES_END_STUDENTS_DAY)
		return true;
	else
		return false;
}

QDialog * ConstraintActivitiesEndStudentsDayForm::createAddDialog()
{
	return new AddConstraintActivitiesEndStudentsDayForm(this);
}

QDialog * ConstraintActivitiesEndStudentsDayForm::createModifyDialog(TimeConstraint *ctr)
{
	return new ModifyConstraintActivitiesEndStudentsDayForm(this, (ConstraintActivitiesEndStudentsDay*)ctr);
}
<commit_msg>remove unused includes<commit_after>/***************************************************************************
                          constraintactivitiesendstudentsdayform.cpp  -  description
                             -------------------
    begin                : 2008
    copyright            : (C) 2008 by Lalescu Liviu
    email                : Please see http://lalescu.ro/liviu/ for details about contacting Liviu Lalescu (in particular, you can find here the e-mail address)
 ***************************************************************************/

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

#include "constraintactivitiesendstudentsdayform.h"
#include "addconstraintactivitiesendstudentsdayform.h"
#include "modifyconstraintactivitiesendstudentsdayform.h"

ConstraintActivitiesEndStudentsDayForm::ConstraintActivitiesEndStudentsDayForm(QWidget* parent): ConstraintBaseDialog(parent)
{
	//: This is the title of the dialog to see the list of all constraints of this type
	setWindowTitle(QCoreApplication::translate("ConstraintActivitiesEndStudentsDayForm_template", "Constraints activities end students day"));
//	populateFilters();
	filterChanged();
}

bool ConstraintActivitiesEndStudentsDayForm::filterOk(const TimeConstraint* ctr) const
{
	if(ctr->type==CONSTRAINT_ACTIVITIES_END_STUDENTS_DAY)
		return true;
	else
		return false;
}

QDialog * ConstraintActivitiesEndStudentsDayForm::createAddDialog()
{
	return new AddConstraintActivitiesEndStudentsDayForm(this);
}

QDialog * ConstraintActivitiesEndStudentsDayForm::createModifyDialog(TimeConstraint *ctr)
{
	return new ModifyConstraintActivitiesEndStudentsDayForm(this, (ConstraintActivitiesEndStudentsDay*)ctr);
}
<|endoftext|>