<commit_before>/*
 * Samplebuffer.cpp
 *
 *  Created on: Dec 4, 2013
 *      Author: gwue
 */

#include "Soundbuffer.hpp"

Soundbuffer::Soundbuffer(unsigned int samplerate)
{
	int err;

	// Always offer chunks of the same size to ALSA
	this->alsaSamples = ALSACHARS / this->getFrameSize();
	this->sane = true;
	this->running = true;
	this->playing = false;
	this->writeoffset = 0;
	this->readoffset = ALSACHARS;
	for (int i = 0; i < SOUNDBUFFERSIZE; i++)
	{
		this->buffer[i] = 0;
	}

	snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;

	snd_pcm_open(&(this->pcm_handle), "plughw:0,0", stream, 0);

	if ((err = snd_pcm_open(&(this->pcm_handle), "plughw:0,0", stream, 0)) < 0)
	{
		fprintf(stderr, "cannot open audio device (%s)\n", snd_strerror(err));
		this->sane = false;
	}

	if ((err = snd_pcm_hw_params_malloc(&this->hw_params)) < 0)
	{
		fprintf(stderr,
				"cannot allocate record hardware parameter structure (%s)\n",
				snd_strerror(err));
		this->sane = false;
	}

	if ((err = snd_pcm_hw_params_any(this->pcm_handle, this->hw_params)) < 0)
	{
		fprintf(stderr, "cannot initialize hardware parameter structure (%s)\n",
				snd_strerror(err));
		this->sane = false;
	}
	if ((err = snd_pcm_hw_params_set_access(this->pcm_handle, this->hw_params,
			SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
	{
		fprintf(stderr, "cannot set access type (%s)\n", snd_strerror(err));
		this->sane = false;
	}
	//TODO only one format supported right now. should be made selectable in the future
	// Currently, it is set to Unsigned Integer 32 Bit, Little Endian.
	// If you change this here, every function that operates on sound data would need to be adjusted accordingly!
	if ((err = snd_pcm_hw_params_set_format(this->pcm_handle, this->hw_params,
			SND_PCM_FORMAT_S32_LE)) < 0)
	{
		fprintf(stderr, "cannot set sample format (%s)\n", snd_strerror(err));
		this->sane = false;
	}
	if ((err = snd_pcm_hw_params_set_buffer_size(this->pcm_handle,
			this->hw_params, 2048)) < 0)
	{
		fprintf(stderr, "cannot set buffer size (%s)\n", snd_strerror(err));
		this->sane = false;
	}

	//TODO Handling for unsupported sampling rates
	unsigned int exact_rate = samplerate;
	if ((err = snd_pcm_hw_params_set_rate_near(this->pcm_handle,
			this->hw_params, &exact_rate, 0)) < 0)
	{
		fprintf(stderr, "cannot set sample rate (%s)\n", snd_strerror(err));
		this->sane = false;
	}
	if (samplerate != exact_rate)
	{
		printf("Rate %i not supported, set to %i \n", samplerate, exact_rate);
	}

	// TODO For now, only one channel. Increase this to two channels in the future
	if ((err = snd_pcm_hw_params_set_channels(this->pcm_handle, this->hw_params,
			1)) < 0)
	{
		fprintf(stderr, "cannot set channel count (%s)\n", snd_strerror(err));
		this->sane = false;
	}
	if ((err = snd_pcm_hw_params(this->pcm_handle, this->hw_params)) < 0)
	{
		fprintf(stderr, "cannot set parameters (%s)\n", snd_strerror(err));
		this->sane = false;
	}
	if ((err = snd_pcm_prepare(this->pcm_handle)) < 0)
	{
		fprintf(stderr, "cannot prepare audio interface for use (%s)\n",
				snd_strerror(err));
		this->sane = false;
	}

	// If no errors occured we can create our playback thread
	//TODO uncomment this
//	if (this->sane)
	{
		this->bufferThread = boost::thread(&Soundbuffer::run, this);
	}
}

void Soundbuffer::run()
{
	int nframes;
	int err = 0;
	snd_pcm_prepare(this->pcm_handle);

	while (this->running)
	{
		// Wait for the playback to start
		if (!this->playing)
		{
			usleep(50000);
		}
		else
		{
			nframes = 0;

			// Wait for the audio device to become ready (or timeout after a second)
			if ((err = snd_pcm_wait(this->pcm_handle, 1000)) < 0)
			{
				fprintf(stderr, "poll failed (%s)\n", snd_strerror(err));
				this->running = 0;
			}

			// Ask the audio device how many frames it can accept
			if ((nframes = snd_pcm_avail_update(this->pcm_handle)) < 0)
			{
				fprintf(stderr, "unknown ALSA avail update return value (%s)\n",
						snd_strerror(nframes));
				this->running = 0;
			}

			// Only write to the soundcard if alsa requested enough frames
			if (nframes >= this->alsaSamples)
			{
				this->mutex.lock();
				char* frames = this->getNextFrames();

				if ((err = snd_pcm_writei(this->pcm_handle, frames,
						this->alsaSamples)) < 0)
				{
					fprintf(stderr, "write to audio interface failed (%s)\n",
							snd_strerror(err));
					this->running = 0;
				}
				this->mutex.unlock();

			}
		}
	}
}

Soundbuffer::~Soundbuffer()
{
}

char* Soundbuffer::getNextFrames()
{
	char* buffer_ptr = this->buffer + this->readoffset;

	// Advance readbuffer by ALSACHUNKS
	int nextReadOffset = this->readoffset + ALSACHARS;
	if (nextReadOffset >= SOUNDBUFFERSIZE)
	{
		nextReadOffset = 0;
	}
	if (nextReadOffset == this->writeoffset)
	{
		std::cerr
				<< "Buffer has run dry! This should not happen! Will now play previous samples again!"
				<< std::endl;
	}
	else
	{
		this->readoffset = nextReadOffset;
	}
	return buffer_ptr;
}

void Soundbuffer::startPlayback()
{
	this->playing = true;
}

void Soundbuffer::stopThread()
{
	this->running = false;
	this->bufferThread.join();
}

void Soundbuffer::testPlayback()
{
	printf("Starting test playback!\n");
	int err;
	int nframes = 0;
	char sine[SOUNDBUFFERSIZE];
	double phase = 0;

	for (double freq = 27.5; freq < 4187; freq *=
			1.0594630943592952645618252949463)
	{
		printf("Freq: %f\n", freq);
		for (int i = 0; i < 50; i++)
		{
			if ((err = snd_pcm_wait(this->pcm_handle, 1000)) < 0)
			{
				fprintf(stderr, "poll failed (%s)\n", strerror(err));
				return;
			}
			if ((nframes = snd_pcm_avail_update(this->pcm_handle)) < 0)
			{
				fprintf(stderr, "unknown ALSA avail update return value (%d)\n",
						nframes);
				return;
			}
			if (nframes > SOUNDBUFFERSIZE / 4)
			{
				nframes = SOUNDBUFFERSIZE / 4;
			}
			for (int j = 0; j < nframes; j++)
			{
				((int*) sine)[j] = (int) (sin(phase) * INT_MAX);

				phase += (2 * M_PI / 44100.0) * freq;

				if (phase > M_PI * 2)
				{
					phase -= M_PI * 2;
				}
			}

			if ((err = snd_pcm_writei(this->pcm_handle, sine, nframes)) < 0)
			{
				fprintf(stderr, "write to audio interface failed (%s)\n",
						snd_strerror(err));
				return;
			}
		}
	}

	printf("Stopping test playback!\n");
}

void Soundbuffer::fillbuffer(char* data, int size)
{
	if ((size & (size - 1)) != 0)
	{
		std::cerr << "You need to fill the buffer with array sizes x^2"
				<< std::endl;
		return;
	}
	if (size >= SOUNDBUFFERSIZE)
	{
		std::cerr << "Too many samples. Might be at most "
				<< SOUNDBUFFERSIZE / 2 << std::endl;
		return;
	}

	while (!this->canAcceptData(size))
	{
		usleep(100);
	}

	this->mutex.lock();
	for (int i = 0; i < size; i++)
	{
		this->buffer[this->writeoffset] = data[i];
		this->writeoffset++;
		if (this->writeoffset >= SOUNDBUFFERSIZE)
		{
			this->writeoffset = 0;
		}
	}
	this->mutex.unlock();

}

bool Soundbuffer::canAcceptData(int size)
{
	int free;

	this->mutex.lock();
	if (this->writeoffset > this->readoffset)
	{
		free = this->readoffset + (SOUNDBUFFERSIZE - this->writeoffset);
	}
	else if (this->writeoffset < this->readoffset)
	{
		free = this->readoffset - this->writeoffset;
	}
	else
	{
		//write and readoffset equal ---> buffer is full
		free = 0;
	}
	this->mutex.unlock();

	if (free >= size)
	{
		return true;
	}
	else
	{
		return false;
	}
}

int Soundbuffer::getFrameSize()
{
	return 4;
}
<commit_msg>why exactly did i open the audio device twice?<commit_after>/*
 * Samplebuffer.cpp
 *
 *  Created on: Dec 4, 2013
 *      Author: gwue
 */

#include "Soundbuffer.hpp"

Soundbuffer::Soundbuffer(unsigned int samplerate)
{
	int err;

	// Always offer chunks of the same size to ALSA
	this->alsaSamples = ALSACHARS / this->getFrameSize();
	this->sane = true;
	this->running = true;
	this->playing = false;
	this->writeoffset = 0;
	this->readoffset = ALSACHARS;
	for (int i = 0; i < SOUNDBUFFERSIZE; i++)
	{
		this->buffer[i] = 0;
	}

	snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;

	if ((err = snd_pcm_open(&(this->pcm_handle), "plughw:0,0", stream, 0)) < 0)
	{
		fprintf(stderr, "cannot open audio device (%s)\n", snd_strerror(err));
		this->sane = false;
	}

	if ((err = snd_pcm_hw_params_malloc(&this->hw_params)) < 0)
	{
		fprintf(stderr,
				"cannot allocate record hardware parameter structure (%s)\n",
				snd_strerror(err));
		this->sane = false;
	}

	if ((err = snd_pcm_hw_params_any(this->pcm_handle, this->hw_params)) < 0)
	{
		fprintf(stderr, "cannot initialize hardware parameter structure (%s)\n",
				snd_strerror(err));
		this->sane = false;
	}
	if ((err = snd_pcm_hw_params_set_access(this->pcm_handle, this->hw_params,
			SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
	{
		fprintf(stderr, "cannot set access type (%s)\n", snd_strerror(err));
		this->sane = false;
	}
	//TODO only one format supported right now. should be made selectable in the future
	// Currently, it is set to Unsigned Integer 32 Bit, Little Endian.
	// If you change this here, every function that operates on sound data would need to be adjusted accordingly!
	if ((err = snd_pcm_hw_params_set_format(this->pcm_handle, this->hw_params,
			SND_PCM_FORMAT_S32_LE)) < 0)
	{
		fprintf(stderr, "cannot set sample format (%s)\n", snd_strerror(err));
		this->sane = false;
	}
	if ((err = snd_pcm_hw_params_set_buffer_size(this->pcm_handle,
			this->hw_params, 2048)) < 0)
	{
		fprintf(stderr, "cannot set buffer size (%s)\n", snd_strerror(err));
		this->sane = false;
	}

	//TODO Handling for unsupported sampling rates
	unsigned int exact_rate = samplerate;
	if ((err = snd_pcm_hw_params_set_rate_near(this->pcm_handle,
			this->hw_params, &exact_rate, 0)) < 0)
	{
		fprintf(stderr, "cannot set sample rate (%s)\n", snd_strerror(err));
		this->sane = false;
	}
	if (samplerate != exact_rate)
	{
		printf("Rate %i not supported, set to %i \n", samplerate, exact_rate);
	}

	// TODO For now, only one channel. Increase this to two channels in the future
	if ((err = snd_pcm_hw_params_set_channels(this->pcm_handle, this->hw_params,
			1)) < 0)
	{
		fprintf(stderr, "cannot set channel count (%s)\n", snd_strerror(err));
		this->sane = false;
	}
	if ((err = snd_pcm_hw_params(this->pcm_handle, this->hw_params)) < 0)
	{
		fprintf(stderr, "cannot set parameters (%s)\n", snd_strerror(err));
		this->sane = false;
	}
	if ((err = snd_pcm_prepare(this->pcm_handle)) < 0)
	{
		fprintf(stderr, "cannot prepare audio interface for use (%s)\n",
				snd_strerror(err));
		this->sane = false;
	}

	// If no errors occured we can create our playback thread
	//TODO uncomment this
//	if (this->sane)
	{
		this->bufferThread = boost::thread(&Soundbuffer::run, this);
	}
}

void Soundbuffer::run()
{
	int nframes;
	int err = 0;
	snd_pcm_prepare(this->pcm_handle);

	while (this->running)
	{
		// Wait for the playback to start
		if (!this->playing)
		{
			usleep(50000);
		}
		else
		{
			nframes = 0;

			// Wait for the audio device to become ready (or timeout after a second)
			if ((err = snd_pcm_wait(this->pcm_handle, 1000)) < 0)
			{
				fprintf(stderr, "poll failed (%s)\n", snd_strerror(err));
				this->running = 0;
			}

			// Ask the audio device how many frames it can accept
			if ((nframes = snd_pcm_avail_update(this->pcm_handle)) < 0)
			{
				fprintf(stderr, "unknown ALSA avail update return value (%s)\n",
						snd_strerror(nframes));
				this->running = 0;
			}

			// Only write to the soundcard if alsa requested enough frames
			if (nframes >= this->alsaSamples)
			{
				this->mutex.lock();
				char* frames = this->getNextFrames();

				if ((err = snd_pcm_writei(this->pcm_handle, frames,
						this->alsaSamples)) < 0)
				{
					fprintf(stderr, "write to audio interface failed (%s)\n",
							snd_strerror(err));
					this->running = 0;
				}
				this->mutex.unlock();

			}
		}
	}
}

Soundbuffer::~Soundbuffer()
{
}

char* Soundbuffer::getNextFrames()
{
	char* buffer_ptr = this->buffer + this->readoffset;

	// Advance readbuffer by ALSACHUNKS
	int nextReadOffset = this->readoffset + ALSACHARS;
	if (nextReadOffset >= SOUNDBUFFERSIZE)
	{
		nextReadOffset = 0;
	}
	if (nextReadOffset == this->writeoffset)
	{
		std::cerr
				<< "Buffer has run dry! This should not happen! Will now play previous samples again!"
				<< std::endl;
	}
	else
	{
		this->readoffset = nextReadOffset;
	}
	return buffer_ptr;
}

void Soundbuffer::startPlayback()
{
	this->playing = true;
}

void Soundbuffer::stopThread()
{
	this->running = false;
	this->bufferThread.join();
}

void Soundbuffer::testPlayback()
{
	printf("Starting test playback!\n");
	int err;
	int nframes = 0;
	char sine[SOUNDBUFFERSIZE];
	double phase = 0;

	for (double freq = 27.5; freq < 4187; freq *=
			1.0594630943592952645618252949463)
	{
		printf("Freq: %f\n", freq);
		for (int i = 0; i < 50; i++)
		{
			if ((err = snd_pcm_wait(this->pcm_handle, 1000)) < 0)
			{
				fprintf(stderr, "poll failed (%s)\n", strerror(err));
				return;
			}
			if ((nframes = snd_pcm_avail_update(this->pcm_handle)) < 0)
			{
				fprintf(stderr, "unknown ALSA avail update return value (%d)\n",
						nframes);
				return;
			}
			if (nframes > SOUNDBUFFERSIZE / 4)
			{
				nframes = SOUNDBUFFERSIZE / 4;
			}
			for (int j = 0; j < nframes; j++)
			{
				((int*) sine)[j] = (int) (sin(phase) * INT_MAX);

				phase += (2 * M_PI / 44100.0) * freq;

				if (phase > M_PI * 2)
				{
					phase -= M_PI * 2;
				}
			}

			if ((err = snd_pcm_writei(this->pcm_handle, sine, nframes)) < 0)
			{
				fprintf(stderr, "write to audio interface failed (%s)\n",
						snd_strerror(err));
				return;
			}
		}
	}

	printf("Stopping test playback!\n");
}

void Soundbuffer::fillbuffer(char* data, int size)
{
	if ((size & (size - 1)) != 0)
	{
		std::cerr << "You need to fill the buffer with array sizes x^2"
				<< std::endl;
		return;
	}
	if (size >= SOUNDBUFFERSIZE)
	{
		std::cerr << "Too many samples. Might be at most "
				<< SOUNDBUFFERSIZE / 2 << std::endl;
		return;
	}

	while (!this->canAcceptData(size))
	{
		usleep(100);
	}

	this->mutex.lock();
	for (int i = 0; i < size; i++)
	{
		this->buffer[this->writeoffset] = data[i];
		this->writeoffset++;
		if (this->writeoffset >= SOUNDBUFFERSIZE)
		{
			this->writeoffset = 0;
		}
	}
	this->mutex.unlock();

}

bool Soundbuffer::canAcceptData(int size)
{
	int free;

	this->mutex.lock();
	if (this->writeoffset > this->readoffset)
	{
		free = this->readoffset + (SOUNDBUFFERSIZE - this->writeoffset);
	}
	else if (this->writeoffset < this->readoffset)
	{
		free = this->readoffset - this->writeoffset;
	}
	else
	{
		//write and readoffset equal ---> buffer is full
		free = 0;
	}
	this->mutex.unlock();

	if (free >= size)
	{
		return true;
	}
	else
	{
		return false;
	}
}

int Soundbuffer::getFrameSize()
{
	return 4;
}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2014 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreShaderSubRenderState.h"
#include "OgreException.h"

namespace Ogre {
namespace RTShader {

//-----------------------------------------------------------------------
SubRenderState::SubRenderState()
{

}

//-----------------------------------------------------------------------
SubRenderState::~SubRenderState()
{
    if (mOtherAccessor.isNull() == false)
    {
        mOtherAccessor->removeSubRenderStateInstance(this);
    }
}

//-----------------------------------------------------------------------
SubRenderStateFactory::~SubRenderStateFactory()
{
    assert(mSubRenderStateList.empty() &&
        "SubRenderStateFactory::~SubRenderStateFactory -> Sub render states still exists !!!");
}

//-----------------------------------------------------------------------
SubRenderState* SubRenderStateFactory::createInstance()
{
    SubRenderState* subRenderState = createInstanceImpl();

    mSubRenderStateList.insert(subRenderState);

    return subRenderState;
}

//-----------------------------------------------------------------------
SubRenderState* SubRenderStateFactory::createOrRetrieveInstance(SGScriptTranslator* translator)
{
    //check if we already create a SRS
    SubRenderState* subRenderState = translator->getGeneratedSubRenderState(getType());
    if (subRenderState == NULL)
    {
        //create a new sub render state
        subRenderState = SubRenderStateFactory::createInstance();
    }
    return subRenderState;
}

//-----------------------------------------------------------------------
void SubRenderStateFactory::destroyInstance(SubRenderState* subRenderState)
{
    SubRenderStateSetIterator it = mSubRenderStateList.find(subRenderState);

    if (it != mSubRenderStateList.end())
    {
        OGRE_DELETE *it;
        mSubRenderStateList.erase(it);
    }
}

//-----------------------------------------------------------------------
void SubRenderStateFactory::destroyAllInstances()
{
    SubRenderStateSetIterator it;

    for (it = mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it)
    {
        OGRE_DELETE *it;
    }
    mSubRenderStateList.clear();

}

//-----------------------------------------------------------------------
SubRenderState& SubRenderState::operator=(const SubRenderState& rhs)
{
    if (getType() != rhs.getType())
    {
        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
            "Can not copy sub render states of different types !!",
            "SubRenderState::operator=");
    }

    copyFrom(rhs);

    SubRenderStateAccessorPtr rhsAccessor = rhs.getAccessor();

    rhsAccessor->addSubRenderStateInstance(this);
    mOtherAccessor = rhsAccessor;

    return *this;
}

//-----------------------------------------------------------------------
bool SubRenderState::createCpuSubPrograms(ProgramSet* programSet)
{
    bool result;

    // Resolve parameters.
    result = resolveParameters(programSet);
    if (false == result)
        return false;

    // Resolve dependencies.
    result = resolveDependencies(programSet);
    if (false == result)
        return false;

    // Add function invocations.
    result = addFunctionInvocations(programSet);
    if (false == result)
        return false;

    return true;
}

//-----------------------------------------------------------------------
bool SubRenderState::resolveParameters(ProgramSet* programSet)
{
    return true;
}

//-----------------------------------------------------------------------
bool SubRenderState::resolveDependencies(ProgramSet* programSet)
{
    return true;
}

//-----------------------------------------------------------------------
bool SubRenderState::addFunctionInvocations( ProgramSet* programSet )
{
    return true;
}

//-----------------------------------------------------------------------
SubRenderStateAccessorPtr SubRenderState::getAccessor()
{
    if (mThisAccessor.isNull())
    {
        SubRenderStateAccessor* accessor = OGRE_NEW_T(SubRenderStateAccessor, MEMCATEGORY_GENERAL)(this);

        mThisAccessor.bind(accessor, SPFM_DELETE_T);
    }

    return mThisAccessor;
}

//-----------------------------------------------------------------------
SubRenderStateAccessorPtr SubRenderState::getAccessor() const
{
    if (mThisAccessor.isNull())
    {
        SubRenderStateAccessor* accessor = OGRE_NEW_T(SubRenderStateAccessor, MEMCATEGORY_GENERAL)(this);

        mThisAccessor.bind(accessor, SPFM_DELETE_T);
    }

    return mThisAccessor;
}

}
}

<commit_msg>replace plain assert with OgreAssert<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org

Copyright (c) 2000-2014 Torus Knot Software Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreShaderSubRenderState.h"
#include "OgreException.h"

namespace Ogre {
namespace RTShader {

//-----------------------------------------------------------------------
SubRenderState::SubRenderState()
{

}

//-----------------------------------------------------------------------
SubRenderState::~SubRenderState()
{
    if (mOtherAccessor.isNull() == false)
    {
        mOtherAccessor->removeSubRenderStateInstance(this);
    }
}

//-----------------------------------------------------------------------
SubRenderStateFactory::~SubRenderStateFactory()
{
    OgreAssert(mSubRenderStateList.empty(),
        "SubRenderStateFactory::~SubRenderStateFactory -> Sub render states still exists !!!");
}

//-----------------------------------------------------------------------
SubRenderState* SubRenderStateFactory::createInstance()
{
    SubRenderState* subRenderState = createInstanceImpl();

    mSubRenderStateList.insert(subRenderState);

    return subRenderState;
}

//-----------------------------------------------------------------------
SubRenderState* SubRenderStateFactory::createOrRetrieveInstance(SGScriptTranslator* translator)
{
    //check if we already create a SRS
    SubRenderState* subRenderState = translator->getGeneratedSubRenderState(getType());
    if (subRenderState == NULL)
    {
        //create a new sub render state
        subRenderState = SubRenderStateFactory::createInstance();
    }
    return subRenderState;
}

//-----------------------------------------------------------------------
void SubRenderStateFactory::destroyInstance(SubRenderState* subRenderState)
{
    SubRenderStateSetIterator it = mSubRenderStateList.find(subRenderState);

    if (it != mSubRenderStateList.end())
    {
        OGRE_DELETE *it;
        mSubRenderStateList.erase(it);
    }
}

//-----------------------------------------------------------------------
void SubRenderStateFactory::destroyAllInstances()
{
    SubRenderStateSetIterator it;

    for (it = mSubRenderStateList.begin(); it != mSubRenderStateList.end(); ++it)
    {
        OGRE_DELETE *it;
    }
    mSubRenderStateList.clear();

}

//-----------------------------------------------------------------------
SubRenderState& SubRenderState::operator=(const SubRenderState& rhs)
{
    if (getType() != rhs.getType())
    {
        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
            "Can not copy sub render states of different types !!",
            "SubRenderState::operator=");
    }

    copyFrom(rhs);

    SubRenderStateAccessorPtr rhsAccessor = rhs.getAccessor();

    rhsAccessor->addSubRenderStateInstance(this);
    mOtherAccessor = rhsAccessor;

    return *this;
}

//-----------------------------------------------------------------------
bool SubRenderState::createCpuSubPrograms(ProgramSet* programSet)
{
    bool result;

    // Resolve parameters.
    result = resolveParameters(programSet);
    if (false == result)
        return false;

    // Resolve dependencies.
    result = resolveDependencies(programSet);
    if (false == result)
        return false;

    // Add function invocations.
    result = addFunctionInvocations(programSet);
    if (false == result)
        return false;

    return true;
}

//-----------------------------------------------------------------------
bool SubRenderState::resolveParameters(ProgramSet* programSet)
{
    return true;
}

//-----------------------------------------------------------------------
bool SubRenderState::resolveDependencies(ProgramSet* programSet)
{
    return true;
}

//-----------------------------------------------------------------------
bool SubRenderState::addFunctionInvocations( ProgramSet* programSet )
{
    return true;
}

//-----------------------------------------------------------------------
SubRenderStateAccessorPtr SubRenderState::getAccessor()
{
    if (mThisAccessor.isNull())
    {
        SubRenderStateAccessor* accessor = OGRE_NEW_T(SubRenderStateAccessor, MEMCATEGORY_GENERAL)(this);

        mThisAccessor.bind(accessor, SPFM_DELETE_T);
    }

    return mThisAccessor;
}

//-----------------------------------------------------------------------
SubRenderStateAccessorPtr SubRenderState::getAccessor() const
{
    if (mThisAccessor.isNull())
    {
        SubRenderStateAccessor* accessor = OGRE_NEW_T(SubRenderStateAccessor, MEMCATEGORY_GENERAL)(this);

        mThisAccessor.bind(accessor, SPFM_DELETE_T);
    }

    return mThisAccessor;
}

}
}

<|endoftext|>


<commit_before>
#include "ioFrogs.h"

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <IPStack.h>
#include <Countdown.h>
#include <MQTTClient.h>
#include <MQTTSender.h>

#include <DHT.h>
#include <Adafruit_TSL2591.h>

#include <TemperatureSensor.h>
#include <HumiditySensor.h>
#include <LuminositySensor.h>

#include <TemperatureLogger.h>
#include <HumidityLogger.h>
#include <LuminosityLogger.h>

#include <MQTTTemperatureListener.h>
#include <MQTTLuminosityListener.h>
#include <MQTTHumidityListener.h>

EthernetClient c;
IPStack * ipstack;
MQTT::Client<IPStack, Countdown>* client;

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x76, 0xEC }; // replace with your device's MAC

DHT * dht;
DHTTemperatureSensorAdapter* temperatureSensor;
DHTHumiditySensorAdapter* humiditySensor;

Adafruit_TSL2591* tsl;
TSL2591LuminositySensorAdapter* luminositySensor;

MQTTTemperatureListener* mqttTempListener;
MQTTHumidityListener* mqttHumListener;
MQTTLuminosityListener* mqttLuminosityListener;

TemperatureLogger* tempListener;
HumidityLogger* humListener;
LuminosityLogger* luminosityListener;

void connect() {
	char hostname[] = "192.168.1.4";
	int port = 1883;

	Serial.print("Connecting to ");
	Serial.print(hostname);
	Serial.print(":");
	Serial.println(port);

	int rc = ipstack->connect(hostname, port);
	if (rc != 1) {
		Serial.print("rc from TCP connect is ");
		Serial.println(rc);
	}

	Serial.println("MQTT connecting");
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	data.MQTTVersion = 3;
	data.clientID.cstring = (char*) "arduino-sample";
	rc = client->connect(data);
	if (rc != 0) {
		Serial.print("rc from MQTT connect is ");
		Serial.println(rc);
	}
	Serial.println("MQTT connected");
}

void setup() {
	Serial.begin(9600);

	dht = new DHT(2, DHT22);
	dht->begin();

	tsl = new Adafruit_TSL2591(2591);
	tsl->begin();

	temperatureSensor = new DHTTemperatureSensorAdapter(dht);
	tempListener = new TemperatureLogger();
	temperatureSensor->attach(tempListener);

	humiditySensor = new DHTHumiditySensorAdapter(dht);
	humListener = new HumidityLogger();
	humiditySensor->attach(humListener);

	luminositySensor = new TSL2591LuminositySensorAdapter(tsl);
	luminosityListener = new LuminosityLogger();
	luminositySensor->attach(luminosityListener);

	/**/
	Ethernet.begin(mac);
	ipstack = new IPStack(c);
	client = new MQTT::Client<IPStack, Countdown>(*ipstack);

	connect();

	/**/
	mqttTempListener = new MQTTTemperatureListener(client);
	temperatureSensor->attach(mqttTempListener);

	/**/
	mqttHumListener = new MQTTHumidityListener(client);
	humiditySensor->attach(mqttHumListener);
	/**/
	mqttLuminosityListener = new MQTTLuminosityListener(client);
	luminositySensor->attach(mqttLuminosityListener);
	/**/
}

void loop() {
	if (!client->isConnected())
		connect();
	temperatureSensor->update(millis());
	humiditySensor->update(millis());
	luminositySensor->update(millis());
	delay(1000);
}

<commit_msg>refactoring du programme principal<commit_after>
#include "ioFrogs.h"

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <IPStack.h>
#include <Countdown.h>
#include <MQTTClient.h>
#include <MQTTSender.h>

#include <DHT.h>
#include <Adafruit_TSL2591.h>

#include <TemperatureSensor.h>
#include <HumiditySensor.h>
#include <LuminositySensor.h>

#include <TemperatureLogger.h>
#include <HumidityLogger.h>
#include <LuminosityLogger.h>

#include <MQTTTemperatureListener.h>
#include <MQTTLuminosityListener.h>
#include <MQTTHumidityListener.h>

EthernetClient* ethernetClient;
IPStack* ipstack;
MQTT::Client<IPStack, Countdown>* mqttClient;

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0x76, 0xEC }; // replace with your device's MAC

DHT * dht;
DHTTemperatureSensorAdapter* temperatureSensor;
DHTHumiditySensorAdapter* humiditySensor;

Adafruit_TSL2591* tsl;
TSL2591LuminositySensorAdapter* luminositySensor;

MQTTTemperatureListener* mqttTempListener;
MQTTHumidityListener* mqttHumListener;
MQTTLuminosityListener* mqttLuminosityListener;

TemperatureLogger* tempListener;
HumidityLogger* humListener;
LuminosityLogger* luminosityListener;

void connectToServer() {
	char hostname[] = "192.168.1.4";
	int port = 1883;

	Serial.print("Connecting to ");
	Serial.print(hostname);
	Serial.print(":");
	Serial.print(port);
	Serial.print("...");

	int rc = ipstack->connect(hostname, port);
	if (rc != 1) {
		Serial.print("rc from TCP connect is ");
		Serial.println(rc);
	}
	Serial.println("OK");
}

void connectToMQTT(){
	Serial.print("MQTT connecting...");
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	data.MQTTVersion = 3;
	data.clientID.cstring = (char*) "terrarium";
	int rc = mqttClient->connect(data);
	if (rc != 0) {
		Serial.print("rc from MQTT connect is ");
		Serial.println(rc);
	}
	Serial.println("OK");
}

void connect(){
	connectToServer();
	connectToMQTT();
}

void MQTTListenersAttachment() {
	Serial.println("MQTT Listener attachment...");
	mqttTempListener = new MQTTTemperatureListener(mqttClient);
	temperatureSensor->attach(mqttTempListener);
	mqttHumListener = new MQTTHumidityListener(mqttClient);
	humiditySensor->attach(mqttHumListener);
	mqttLuminosityListener = new MQTTLuminosityListener(mqttClient);
	luminositySensor->attach(mqttLuminosityListener);
	Serial.println("OK");
}

void loggersAttachment() {
	Serial.print("Loggers attachment...");
	tempListener = new TemperatureLogger();
	temperatureSensor->attach(tempListener);
	humListener = new HumidityLogger();
	humiditySensor->attach(humListener);
	luminosityListener = new LuminosityLogger();
	luminositySensor->attach(luminosityListener);
	Serial.println("OK");
}

void initializeSensorAdapters() {
	Serial.print("Sensor Adapter Initialisation...");
	temperatureSensor = new DHTTemperatureSensorAdapter(dht);
	humiditySensor = new DHTHumiditySensorAdapter(dht);
	luminositySensor = new TSL2591LuminositySensorAdapter(tsl);
	Serial.println("OK");
}

void initializeLuminositySensor() {
	Serial.print("TSL2591 Initialisation...");
	tsl = new Adafruit_TSL2591(2591);
	tsl->begin();
	Serial.println("OK");
}

void initializeTemperatureHumiditySensor() {
	/**/
	Serial.print("DHT Initialisation...");
	dht = new DHT(2, DHT11);
	dht->begin();
	Serial.println("OK");
}

void initializeNetwork() {
	/**/
	Serial.print("Etherner Shield Initialisation...");
	Ethernet.begin(mac);
	ethernetClient = new EthernetClient();
	ipstack = new IPStack(*ethernetClient);
	mqttClient = new MQTT::Client<IPStack, Countdown>(*ipstack);
	Serial.println("OK\n");
}

void setup() {
	Serial.begin(9600);
	Serial.println("=== Internet Of Frogs ===");
	Serial.println("By Carole Lai Tong and geeks from LAB");
	Serial.println("Sponsorised by W4");
	Serial.println("");

	initializeTemperatureHumiditySensor();
	initializeLuminositySensor();
	initializeSensorAdapters();
	loggersAttachment();

	initializeNetwork();
	connect();
	MQTTListenersAttachment();
	Serial.println("=========================");
}

void loop() {
	if (!mqttClient->isConnected())
		connect();

	temperatureSensor->update(millis());
	humiditySensor->update(millis());
	luminositySensor->update(millis());
	delay(1000);
}

<|endoftext|>


<commit_before>// Day18.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

constexpr size_t Rows = 40;

typedef std::vector<bool> Row;
typedef std::array <Row, Rows> Board;

Board PopulateBoard(const std::string & Input, size_t & SafeTiles);

int main()
{
	std::string Line = GetFileLines("Input.txt")[0];

	size_t SafeTiles;
	Board Floor = PopulateBoard(Line, SafeTiles);

	std::cout << "Safe Tiles: " << SafeTiles << std::endl;

	system("pause");

    return 0;
}

Row FillRow(const std::string & Input, size_t & SafeTiles)
{
	Row NewRow;
	NewRow.reserve(Input.size());

	for (char Field : Input)
	{
		bool IsSafeTile = (Field == '.');
		NewRow.push_back(IsSafeTile);

		SafeTiles += IsSafeTile ? 1  : 0;
	}

	return NewRow;
}

bool IsSafe(const Row & PreviousRow, size_t Index)
{
	bool Left = (Index > 0) ? PreviousRow[Index - 1] : true;
	bool Right = (Index < (PreviousRow.size() - 1)) ? PreviousRow[Index + 1] : true;

	return (Left == Right);
}

Row ComputeRow(const Row & PreviousRow, size_t & SafeTiles)
{
	Row NewRow;
	NewRow.reserve(PreviousRow.size());

	for (size_t i = 0; i < PreviousRow.size(); i++)
	{
		bool IsSafeTile = IsSafe(PreviousRow, i);
		NewRow.push_back(IsSafeTile);

		SafeTiles += IsSafeTile ? 1 : 0;
	}

	return NewRow;
}

Board PopulateBoard(const std::string & Input, size_t & SafeTiles)
{
	SafeTiles = 0;
	Board Floor;

	Floor[0] = FillRow(Input, SafeTiles);

	for (size_t i = 1; i < Rows; i++)
	{
		Floor[i] = ComputeRow(Floor[i - 1], SafeTiles);
	}

	return Floor;
}<commit_msg>Day18 part two<commit_after>// Day18.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

constexpr size_t PartOne = 40;
constexpr size_t PartTwo = 400000;

typedef std::vector<bool> Row;

size_t ComputeRow(const std::string & Input, size_t RowCount);

int main()
{
	std::string Line = GetFileLines("Input.txt")[0];

	std::cout << PartOne << ": " << ComputeRow(Line, PartOne) << std::endl;
	std::cout << PartOne << ": " << ComputeRow(Line, PartTwo) << std::endl;

	system("pause");

    return 0;
}

Row FillRow(const std::string & Input, size_t & SafeTiles)
{
	Row NewRow;
	NewRow.reserve(Input.size());

	for (char Field : Input)
	{
		bool IsSafeTile = (Field == '.');
		NewRow.push_back(IsSafeTile);

		SafeTiles += IsSafeTile ? 1  : 0;
	}

	return NewRow;
}

bool IsSafe(const Row & PreviousRow, size_t Index)
{
	bool Left = (Index > 0) ? PreviousRow[Index - 1] : true;
	bool Right = (Index < (PreviousRow.size() - 1)) ? PreviousRow[Index + 1] : true;

	return (Left == Right);
}

Row ComputeRow(const Row & PreviousRow, size_t & SafeTiles)
{
	Row NewRow;
	NewRow.reserve(PreviousRow.size());

	for (size_t i = 0; i < PreviousRow.size(); i++)
	{
		bool IsSafeTile = IsSafe(PreviousRow, i);
		NewRow.push_back(IsSafeTile);

		SafeTiles += IsSafeTile ? 1 : 0;
	}

	return NewRow;
}

size_t ComputeRow(const std::string & Input, size_t RowCount)
{
	size_t SafeTiles = 0;
	Row CurrentRow = FillRow(Input, SafeTiles);

	for (size_t i = 1; i < RowCount; i++)
	{
		Row NextRow = ComputeRow(CurrentRow, SafeTiles);
		std::swap(CurrentRow, NextRow);
	}

	return SafeTiles;
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLTextFrameContext.hxx,v $
 *
 *  $Revision: 1.24 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 16:08:25 $
 *
 *  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 _XMLTEXTFRAMECONTEXT_HXX
#define _XMLTEXTFRAMECONTEXT_HXX

#ifndef _COM_SUN_STAR_TEXT_TEXTCONTENTANCHORTYPE_HPP
#include <com/sun/star/text/TextContentAnchorType.hpp>
#endif

#ifndef _XMLOFF_XMLICTXT_HXX
#include <xmloff/xmlictxt.hxx>
#endif

namespace com { namespace sun { namespace star {
    namespace text { class XTextCursor; class XTextContent; }
} } }

class SvXMLAttributeList;
class XMLTextFrameContextHyperlink_Impl;

class XMLTextFrameContext : public SvXMLImportContext
{
    ::com::sun::star::uno::Reference<
        ::com::sun::star::xml::sax::XAttributeList > m_xAttrList;

    SvXMLImportContextRef m_xImplContext;
    SvXMLImportContextRef m_xReplImplContext;
    SvXMLAttributeList *m_pAttrList;

    XMLTextFrameContextHyperlink_Impl   *m_pHyperlink;
    ::rtl::OUString m_sDesc;

    ::com::sun::star::text::TextContentAnchorType   m_eDefaultAnchorType;

    // --> OD 2006-03-10 #i51726#
    // The <draw:name> can longer be used to distinguish Writer graphic/text box
    // objects and Draw graphic/text box objects.
    // The new distinguish attribute is the parent style of the automatic style
    // of the object. All Draw objects have an automatic style without a parent style.
    sal_Bool m_HasAutomaticStyleWithoutParentStyle;
    // <--
    sal_Bool m_bSupportsReplacement;

    sal_Bool CreateIfNotThere();
    sal_Bool CreateIfNotThere( ::com::sun::star::uno::Reference <
        ::com::sun::star::beans::XPropertySet >& rPropSet );

public:

    TYPEINFO();

    XMLTextFrameContext( SvXMLImport& rImport,
            sal_uInt16 nPrfx,
            const ::rtl::OUString& rLName,
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
            ::com::sun::star::text::TextContentAnchorType eDfltAnchorType );
    virtual ~XMLTextFrameContext();

    virtual void EndElement();

    SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                const ::rtl::OUString& rLocalName,
                 const ::com::sun::star::uno::Reference<
                    ::com::sun::star::xml::sax::XAttributeList > & xAttrList );

    void SetHyperlink( const ::rtl::OUString& rHRef,
                       const ::rtl::OUString& rName,
                       const ::rtl::OUString& rTargetFrameName,
                       sal_Bool bMap );

    ::com::sun::star::text::TextContentAnchorType GetAnchorType() const;

    ::com::sun::star::uno::Reference <
        ::com::sun::star::text::XTextContent > GetTextContent() const;
    // --> OD 2004-08-24 #i33242#
    ::com::sun::star::uno::Reference <
        ::com::sun::star::drawing::XShape > GetShape() const;
    // <--
};

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.24.162); FILE MERGED 2008/04/01 13:05:30 thb 1.24.162.2: #i85898# Stripping all external header guards 2008/03/31 16:28:37 rt 1.24.162.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: XMLTextFrameContext.hxx,v $
 * $Revision: 1.25 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _XMLTEXTFRAMECONTEXT_HXX
#define _XMLTEXTFRAMECONTEXT_HXX

#ifndef _COM_SUN_STAR_TEXT_TEXTCONTENTANCHORTYPE_HPP
#include <com/sun/star/text/TextContentAnchorType.hpp>
#endif
#include <xmloff/xmlictxt.hxx>

namespace com { namespace sun { namespace star {
    namespace text { class XTextCursor; class XTextContent; }
} } }

class SvXMLAttributeList;
class XMLTextFrameContextHyperlink_Impl;

class XMLTextFrameContext : public SvXMLImportContext
{
    ::com::sun::star::uno::Reference<
        ::com::sun::star::xml::sax::XAttributeList > m_xAttrList;

    SvXMLImportContextRef m_xImplContext;
    SvXMLImportContextRef m_xReplImplContext;
    SvXMLAttributeList *m_pAttrList;

    XMLTextFrameContextHyperlink_Impl   *m_pHyperlink;
    ::rtl::OUString m_sDesc;

    ::com::sun::star::text::TextContentAnchorType   m_eDefaultAnchorType;

    // --> OD 2006-03-10 #i51726#
    // The <draw:name> can longer be used to distinguish Writer graphic/text box
    // objects and Draw graphic/text box objects.
    // The new distinguish attribute is the parent style of the automatic style
    // of the object. All Draw objects have an automatic style without a parent style.
    sal_Bool m_HasAutomaticStyleWithoutParentStyle;
    // <--
    sal_Bool m_bSupportsReplacement;

    sal_Bool CreateIfNotThere();
    sal_Bool CreateIfNotThere( ::com::sun::star::uno::Reference <
        ::com::sun::star::beans::XPropertySet >& rPropSet );

public:

    TYPEINFO();

    XMLTextFrameContext( SvXMLImport& rImport,
            sal_uInt16 nPrfx,
            const ::rtl::OUString& rLName,
            const ::com::sun::star::uno::Reference<
                ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
            ::com::sun::star::text::TextContentAnchorType eDfltAnchorType );
    virtual ~XMLTextFrameContext();

    virtual void EndElement();

    SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
                const ::rtl::OUString& rLocalName,
                 const ::com::sun::star::uno::Reference<
                    ::com::sun::star::xml::sax::XAttributeList > & xAttrList );

    void SetHyperlink( const ::rtl::OUString& rHRef,
                       const ::rtl::OUString& rName,
                       const ::rtl::OUString& rTargetFrameName,
                       sal_Bool bMap );

    ::com::sun::star::text::TextContentAnchorType GetAnchorType() const;

    ::com::sun::star::uno::Reference <
        ::com::sun::star::text::XTextContent > GetTextContent() const;
    // --> OD 2004-08-24 #i33242#
    ::com::sun::star::uno::Reference <
        ::com::sun::star::drawing::XShape > GetShape() const;
    // <--
};

#endif
<|endoftext|>


<commit_before>
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

#if !defined(CLI_BUILD)
#include "HackerRank.h"
#endif

typedef vector< vector<bool> > AdjacencyMatrix;

// for each leaf node return 1 as the weight of the edge that leads to it
// for non-leaf nodes, return sum of all the outcoming edges
// if an node returns an even number, that means that edge that leads to that node
// has even weight, that means there's even number of nodes on each side of that edge
// thus it splits the tree in two even components
// so if the weight is even, increas the count of edges to be removed by 1

int TraceGraph(const AdjacencyMatrix &graph, int vertex, vector<bool> &visited, int *count) {
    // Mark as visited
    visited[vertex] = true;

    // Use 1 as default (will be the value for leaf nodes)
    int weight = 1;

    // Walk adjacent vertices
    for (int i = 0; i < graph.size(); i++) {
        if (visited[i]) { continue; }
        if (graph[vertex][i]) {
            // Trace each edge from this node
            int w = TraceGraph(graph, i, visited, count);
            // Check if that edge leads to another even tree
            if (w % 2 == 0) {
                *count += 1;
            }
            // Count total nodes, including current one
            weight += w;
        }
    }

    return weight;
}

int CountComponents(const AdjacencyMatrix &graph) {
    // pick any vertex to start from and do a DFS search to put proper weights on the edges (aka count things)
    // assume that input has no gaps in vertex indeces and pick 0 as starting vertex

    vector<bool> visited(graph.size());
    int count = 0;
    TraceGraph(graph, 0, visited, &count);
    return count;
}

void evenTreeCpp() {

    int n, m;
    cin >> n >> m;
    // cout << n << m << endl;

    // Adjacency matrix, aka graph representation
    AdjacencyMatrix graph(n);
    for (int i = 0; i < n; i++) {
        graph[i] = vector<bool>(n);
    }

    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;

        graph[u - 1][v - 1] = true;
        graph[v - 1][u - 1] = true;
    }

    cout << CountComponents(graph) << endl;
}

#ifdef CLI_BUILD
int main() {
    evenTreeCpp();
    return 0;
}
#endif
<commit_msg>Minor refactoring<commit_after>
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

#if !defined(CLI_BUILD)
#include "HackerRank.h"
#endif

typedef vector< vector<bool> > AdjacencyMatrix;

// for each leaf node return 1 as the weight of the edge that leads to it
// for non-leaf nodes, return sum of all the outcoming edges
// if an node returns an even number, that means that edge that leads to that node
// has even weight, that means there's even number of nodes on each side of that edge
// thus it splits the tree in two even components
// so if the weight is even, increas the count of edges to be removed by 1

int TraceGraph(const AdjacencyMatrix &graph, int vertex, vector<bool> &visited, int *count) {
    // Mark as visited
    visited[vertex] = true;

    // Use 1 as default (will be the value for leaf nodes)
    int weight = 1;

    // Walk adjacent vertices
    for (int i = 0; i < graph.size(); i++) {
        if (visited[i]) { continue; }
        if (graph[vertex][i]) {
            // Trace each edge from this node
            int w = TraceGraph(graph, i, visited, count);
            // Check if that edge leads to another even tree
            if (w % 2 == 0) {
                *count += 1;
            }
            // Count total nodes, including current one
            weight += w;
        }
    }

    return weight;
}

int CountEdges(const AdjacencyMatrix &graph) {
    // pick any vertex to start from and do a DFS search to put proper weights on the edges (aka count things)
    // assume that input has no gaps in vertex indeces and pick 0 as starting vertex

    vector<bool> visited(graph.size());
    int count = 0;
    TraceGraph(graph, 0, visited, &count);
    return count;
}

void evenTreeCpp() {

    int n, m;
    cin >> n >> m;
    // cout << n << m << endl;

    // Adjacency matrix, aka graph representation
    AdjacencyMatrix graph(n);
    for (int i = 0; i < n; i++) {
        graph[i] = vector<bool>(n);
    }

    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;

        graph[u - 1][v - 1] = true;
        graph[v - 1][u - 1] = true;
    }

    cout << CountEdges(graph) << endl;
}

#ifdef CLI_BUILD
int main() {
    evenTreeCpp();
    return 0;
}
#endif
<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/micro/all_ops_resolver.h"
#include "tensorflow/lite/micro/benchmarks/micro_benchmark.h"
#include "tensorflow/lite/micro/examples/person_detection/model_settings.h"
#include "tensorflow/lite/micro/examples/person_detection/no_person_image_data.h"
#include "tensorflow/lite/micro/examples/person_detection/person_detect_model_data.h"
#include "tensorflow/lite/micro/examples/person_detection/person_image_data.h"
#include "tensorflow/lite/micro/micro_error_reporter.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/micro/micro_utils.h"
#include "tensorflow/lite/schema/schema_generated.h"

/*
 * Person Detection benchmark.  Evaluates runtime performance of the visual
 * wakewords person detection model.  This is the same model found in
 * exmaples/person_detection.
 */

namespace tflite {

using PersonDetectionOpResolver = tflite::AllOpsResolver;
using PersonDetectionBenchmarkRunner = MicroBenchmarkRunner<int8_t>;

// Create an area of memory to use for input, output, and intermediate arrays.
// Align arena to 16 bytes to avoid alignment warnings on certain platforms.
constexpr int kTensorArenaSize = 135 * 1024;
alignas(16) uint8_t tensor_arena[kTensorArenaSize];

uint8_t op_resolver_buffer[sizeof(PersonDetectionOpResolver)];
uint8_t benchmark_runner_buffer[sizeof(PersonDetectionBenchmarkRunner)];

// Initialize benchmark runner instance explicitly to avoid global init order
// issues on Sparkfun. Use new since static variables within a method
// are automatically surrounded by locking, which breaks bluepill and stm32f4.
PersonDetectionBenchmarkRunner* CreateBenchmarkRunner(MicroProfiler* profiler) {
  // We allocate PersonDetectionOpResolver from a global buffer
  // because the object's lifetime must exceed that of the
  // PersonDetectionBenchmarkRunner object.
  return new (benchmark_runner_buffer) PersonDetectionBenchmarkRunner(
      g_person_detect_model_data,
      new (op_resolver_buffer) PersonDetectionOpResolver(), tensor_arena,
      kTensorArenaSize, profiler);
}

void PersonDetectionNIerations(const int8_t* input, int iterations,
                               const char* tag,
                               PersonDetectionBenchmarkRunner& benchmark_runner,
                               MicroProfiler& profiler) {
  benchmark_runner.SetInput(input);
  int32_t ticks = 0;
  for (int i = 0; i < iterations; ++i) {
    profiler.ClearEvents();
    benchmark_runner.RunSingleIteration();
    ticks += profiler.GetTotalTicks();
  }
  MicroPrintf("%s took %d ticks (%d ms)", tag, ticks, TicksToMs(ticks));
}

}  // namespace tflite

int main(int argc, char** argv) {
  tflite::MicroProfiler profiler;

  uint32_t event_handle = profiler.BeginEvent("InitializeBenchmarkRunner");
  tflite::PersonDetectionBenchmarkRunner* benchmark_runner =
      CreateBenchmarkRunner(&profiler);
  profiler.EndEvent(event_handle);
  profiler.Log();
  MicroPrintf("");

  tflite::PersonDetectionNIerations(
      reinterpret_cast<const int8_t*>(g_person_data), 1,
      "WithPersonDataIterations(1)", *benchmark_runner, profiler);
  profiler.Log();
  MicroPrintf("");

  tflite::PersonDetectionNIerations(
      reinterpret_cast<const int8_t*>(g_no_person_data), 1,
      "NoPersonDataIterations(1)", *benchmark_runner, profiler);
  profiler.Log();
  MicroPrintf("");

  tflite::PersonDetectionNIerations(
      reinterpret_cast<const int8_t*>(g_person_data), 10,
      "WithPersonDataIterations(10)", *benchmark_runner, profiler);
  MicroPrintf("");

  tflite::PersonDetectionNIerations(
      reinterpret_cast<const int8_t*>(g_no_person_data), 10,
      "NoPersonDataIterations(10)", *benchmark_runner, profiler);
  MicroPrintf("");
}
<commit_msg>additional comments that I forgot to add in my last commit.<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/micro/all_ops_resolver.h"
#include "tensorflow/lite/micro/benchmarks/micro_benchmark.h"
#include "tensorflow/lite/micro/examples/person_detection/model_settings.h"
#include "tensorflow/lite/micro/examples/person_detection/no_person_image_data.h"
#include "tensorflow/lite/micro/examples/person_detection/person_detect_model_data.h"
#include "tensorflow/lite/micro/examples/person_detection/person_image_data.h"
#include "tensorflow/lite/micro/micro_error_reporter.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/micro/micro_utils.h"
#include "tensorflow/lite/schema/schema_generated.h"

/*
 * Person Detection benchmark.  Evaluates runtime performance of the visual
 * wakewords person detection model.  This is the same model found in
 * exmaples/person_detection.
 */

namespace tflite {

using PersonDetectionOpResolver = tflite::AllOpsResolver;
using PersonDetectionBenchmarkRunner = MicroBenchmarkRunner<int8_t>;

// Create an area of memory to use for input, output, and intermediate arrays.
// Align arena to 16 bytes to avoid alignment warnings on certain platforms.
constexpr int kTensorArenaSize = 135 * 1024;
alignas(16) uint8_t tensor_arena[kTensorArenaSize];

uint8_t op_resolver_buffer[sizeof(PersonDetectionOpResolver)];
uint8_t benchmark_runner_buffer[sizeof(PersonDetectionBenchmarkRunner)];

// Initialize benchmark runner instance explicitly to avoid global init order
// issues on Sparkfun. Use new since static variables within a method
// are automatically surrounded by locking, which breaks bluepill and stm32f4.
PersonDetectionBenchmarkRunner* CreateBenchmarkRunner(MicroProfiler* profiler) {
  // We allocate PersonDetectionOpResolver from a global buffer
  // because the object's lifetime must exceed that of the
  // PersonDetectionBenchmarkRunner object.
  return new (benchmark_runner_buffer) PersonDetectionBenchmarkRunner(
      g_person_detect_model_data,
      new (op_resolver_buffer) PersonDetectionOpResolver(), tensor_arena,
      kTensorArenaSize, profiler);
}

void PersonDetectionNIerations(const int8_t* input, int iterations,
                               const char* tag,
                               PersonDetectionBenchmarkRunner& benchmark_runner,
                               MicroProfiler& profiler) {
  benchmark_runner.SetInput(input);
  int32_t ticks = 0;
  for (int i = 0; i < iterations; ++i) {
    profiler.ClearEvents();
    benchmark_runner.RunSingleIteration();
    ticks += profiler.GetTotalTicks();
  }
  MicroPrintf("%s took %d ticks (%d ms)", tag, ticks, TicksToMs(ticks));
}

}  // namespace tflite

int main(int argc, char** argv) {
  tflite::MicroProfiler profiler;

  uint32_t event_handle = profiler.BeginEvent("InitializeBenchmarkRunner");
  tflite::PersonDetectionBenchmarkRunner* benchmark_runner =
      CreateBenchmarkRunner(&profiler);
  profiler.EndEvent(event_handle);
  profiler.Log();
  MicroPrintf("");  // null MicroPrintf serves as a newline.

  tflite::PersonDetectionNIerations(
      reinterpret_cast<const int8_t*>(g_person_data), 1,
      "WithPersonDataIterations(1)", *benchmark_runner, profiler);
  profiler.Log();
  MicroPrintf("");  // null MicroPrintf serves as a newline.

  tflite::PersonDetectionNIerations(
      reinterpret_cast<const int8_t*>(g_no_person_data), 1,
      "NoPersonDataIterations(1)", *benchmark_runner, profiler);
  profiler.Log();
  MicroPrintf("");  // null MicroPrintf serves as a newline.

  tflite::PersonDetectionNIerations(
      reinterpret_cast<const int8_t*>(g_person_data), 10,
      "WithPersonDataIterations(10)", *benchmark_runner, profiler);
  MicroPrintf("");  // null MicroPrintf serves as a newline.

  tflite::PersonDetectionNIerations(
      reinterpret_cast<const int8_t*>(g_no_person_data), 10,
      "NoPersonDataIterations(10)", *benchmark_runner, profiler);
  MicroPrintf("");  // null MicroPrintf serves as a newline.
}
<|endoftext|>


<commit_before>// Copyright (c) 2014-2016 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "activemasternode.h"
#include "governance.h"
#include "main.h"
#include "masternode.h"
#include "masternode-payments.h"
#include "masternode-sync.h"
#include "masternodeman.h"
#include "netfulfilledman.h"
#include "spork.h"
#include "util.h"

class CMasternodeSync;
CMasternodeSync masternodeSync;

bool CMasternodeSync::IsBlockchainSynced()
{
    static bool fBlockchainSynced = false;
    static int64_t lastProcess = GetTime();

    // if the last call to this function was more than 60 minutes ago (client was in sleep mode) reset the sync process
    if(GetTime() - lastProcess > 60*60) {
        Reset();
        fBlockchainSynced = false;
    }
    lastProcess = GetTime();

    if(fBlockchainSynced) return true;
    if(!pCurrentBlockIndex || !pindexBestHeader || fImporting || fReindex) return false;

    // same as !IsInitialBlockDownload() but no cs_main needed here
    int nMaxBlockTime = std::max(pCurrentBlockIndex->GetBlockTime(), pindexBestHeader->GetBlockTime());
    fBlockchainSynced = pindexBestHeader->nHeight - pCurrentBlockIndex->nHeight < 24 * 6 &&
                        GetTime() - nMaxBlockTime < Params().MaxTipAge();

    return fBlockchainSynced;
}

void CMasternodeSync::Fail()
{
    nTimeLastFailure = GetTime();
    nRequestedMasternodeAssets = MASTERNODE_SYNC_FAILED;
}

void CMasternodeSync::Reset()
{
    nRequestedMasternodeAssets = MASTERNODE_SYNC_INITIAL;
    nRequestedMasternodeAttempt = 0;
    nTimeAssetSyncStarted = GetTime();
    nTimeLastMasternodeList = GetTime();
    nTimeLastPaymentVote = GetTime();
    nTimeLastBudgetItem = GetTime();
    nTimeLastFailure = 0;
    nCountFailures = 0;
}

std::string CMasternodeSync::GetAssetName()
{
    switch(nRequestedMasternodeAssets)
    {
        case(MASTERNODE_SYNC_INITIAL):      return "MASTERNODE_SYNC_INITIAL";
        case(MASTERNODE_SYNC_SPORKS):       return "MASTERNODE_SYNC_SPORKS";
        case(MASTERNODE_SYNC_LIST):         return "MASTERNODE_SYNC_LIST";
        case(MASTERNODE_SYNC_MNW):          return "MASTERNODE_SYNC_MNW";
        case(MASTERNODE_SYNC_GOVERNANCE):   return "MASTERNODE_SYNC_GOVERNANCE";
        case(MASTERNODE_SYNC_FAILED):       return "MASTERNODE_SYNC_FAILED";
        case MASTERNODE_SYNC_FINISHED:      return "MASTERNODE_SYNC_FINISHED";
        default:                            return "UNKNOWN";
    }
}

void CMasternodeSync::SwitchToNextAsset()
{
    switch(nRequestedMasternodeAssets)
    {
        case(MASTERNODE_SYNC_FAILED):
            throw std::runtime_error("Can't switch to next asset from failed, should use Reset() first!");
            break;
        case(MASTERNODE_SYNC_INITIAL):
            ClearFulfilledRequests();
            nRequestedMasternodeAssets = MASTERNODE_SYNC_SPORKS;
            break;
        case(MASTERNODE_SYNC_SPORKS):
            nTimeLastMasternodeList = GetTime();
            nRequestedMasternodeAssets = MASTERNODE_SYNC_LIST;
            break;
        case(MASTERNODE_SYNC_LIST):
            nTimeLastPaymentVote = GetTime();
            nRequestedMasternodeAssets = MASTERNODE_SYNC_MNW;
            break;
        case(MASTERNODE_SYNC_MNW):
            nTimeLastBudgetItem = GetTime();
            nRequestedMasternodeAssets = MASTERNODE_SYNC_GOVERNANCE;
            break;
        case(MASTERNODE_SYNC_GOVERNANCE):
            LogPrintf("CMasternodeSync::SwitchToNextAsset -- Sync has finished\n");
            nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
            uiInterface.NotifyAdditionalDataSyncProgressChanged(1);
            //try to activate our masternode if possible
            activeMasternode.ManageState();

            TRY_LOCK(cs_vNodes, lockRecv);
            if(!lockRecv) return;

            BOOST_FOREACH(CNode* pnode, vNodes) {
                netfulfilledman.AddFulfilledRequest(pnode->addr, "full-sync");
            }

            break;
    }
    nRequestedMasternodeAttempt = 0;
    nTimeAssetSyncStarted = GetTime();
}

std::string CMasternodeSync::GetSyncStatus()
{
    switch (masternodeSync.nRequestedMasternodeAssets) {
        case MASTERNODE_SYNC_INITIAL:       return _("Synchronization pending...");
        case MASTERNODE_SYNC_SPORKS:        return _("Synchronizing sporks...");
        case MASTERNODE_SYNC_LIST:          return _("Synchronizing masternodes...");
        case MASTERNODE_SYNC_MNW:           return _("Synchronizing masternode payments...");
        case MASTERNODE_SYNC_GOVERNANCE:    return _("Synchronizing governance objects...");
        case MASTERNODE_SYNC_FAILED:        return _("Synchronization failed");
        case MASTERNODE_SYNC_FINISHED:      return _("Synchronization finished");
        default:                            return "";
    }
}

void CMasternodeSync::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    if (strCommand == NetMsgType::SYNCSTATUSCOUNT) { //Sync status count

        //do not care about stats if sync process finished or failed
        if(IsSynced() || IsFailed()) return;

        int nItemID;
        int nCount;
        vRecv >> nItemID >> nCount;

        LogPrintf("CMasternodeSync::ProcessMessage -- SYNCSTATUSCOUNT -- got inventory count: nItemID=%d  nCount=%d  peer=%d\n", nItemID, nCount, pfrom->id);
    }
}

void CMasternodeSync::ClearFulfilledRequests()
{
    TRY_LOCK(cs_vNodes, lockRecv);
    if(!lockRecv) return;

    BOOST_FOREACH(CNode* pnode, vNodes)
    {
        netfulfilledman.RemoveFulfilledRequest(pnode->addr, "spork-sync");
        netfulfilledman.RemoveFulfilledRequest(pnode->addr, "masternode-list-sync");
        netfulfilledman.RemoveFulfilledRequest(pnode->addr, "masternode-payment-sync");
        netfulfilledman.RemoveFulfilledRequest(pnode->addr, "governance-sync");
        netfulfilledman.RemoveFulfilledRequest(pnode->addr, "full-sync");
    }
}

void CMasternodeSync::ProcessTick()
{
    static int nTick = 0;
    if(nTick++ % 6 != 0) return;
    if(!pCurrentBlockIndex) return;

    //the actual count of masternodes we have currently
    int nMnCount = mnodeman.CountEnabled();

    // RESET SYNCING INCASE OF FAILURE
    {
        if(IsSynced()) {
            /*
                Resync if we lose all masternodes from sleep/wake or failure to sync originally
            */
            if(nMnCount == 0) {
                Reset();
            } else {
                //if syncing is complete and we have masternodes, return
                return;
            }
        }

        //try syncing again
        if(IsFailed()) {
            if(nTimeLastFailure + (1*60) < GetTime()) { // 1 minute cooldown after failed sync
                Reset();
            }
            return;
        }
    }

    // INITIAL SYNC SETUP / LOG REPORTING
    double nSyncProgress = double(nRequestedMasternodeAttempt + (nRequestedMasternodeAssets - 1) * 8) / (8*4);
    LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d nRequestedMasternodeAttempt %d nSyncProgress %f\n", nTick, nRequestedMasternodeAssets, nRequestedMasternodeAttempt, nSyncProgress);
    uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress);

    // sporks synced but blockchain is not, wait until we're almost at a recent block to continue
    if(Params().NetworkIDString() != CBaseChainParams::REGTEST &&
            !IsBlockchainSynced() && nRequestedMasternodeAssets > MASTERNODE_SYNC_SPORKS) return;

    TRY_LOCK(cs_vNodes, lockRecv);
    if(!lockRecv) return;

    if(nRequestedMasternodeAssets == MASTERNODE_SYNC_INITIAL) {
        SwitchToNextAsset();
    }

    BOOST_FOREACH(CNode* pnode, vNodes)
    {
        // QUICK MODE (REGTEST ONLY!)
        if(Params().NetworkIDString() == CBaseChainParams::REGTEST)
        {
            if(nRequestedMasternodeAttempt <= 2) {
                pnode->PushMessage(NetMsgType::GETSPORKS); //get current network sporks
            } else if(nRequestedMasternodeAttempt < 4) {
                mnodeman.DsegUpdate(pnode);
            } else if(nRequestedMasternodeAttempt < 6) {
                int nMnCount = mnodeman.CountEnabled();
                pnode->PushMessage(NetMsgType::MASTERNODEPAYMENTSYNC, nMnCount); //sync payment votes
                uint256 n = uint256();
                pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, n); //sync masternode votes
            } else {
                nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
            }
            nRequestedMasternodeAttempt++;
            return;
        }

        // NORMAL NETWORK MODE - TESTNET/MAINNET
        {
            if(netfulfilledman.HasFulfilledRequest(pnode->addr, "full-sync")) {
                // we already fully synced from this node recently,
                // disconnect to free this connection slot for a new node
                pnode->fDisconnect = true;
                LogPrintf("CMasternodeSync::ProcessTick -- disconnecting from recently synced node %d\n", pnode->id);
                continue;
            }

            // SPORK : ALWAYS ASK FOR SPORKS AS WE SYNC (we skip this mode now)

            if(!netfulfilledman.HasFulfilledRequest(pnode->addr, "spork-sync")) {
                // only request once from each peer
                netfulfilledman.AddFulfilledRequest(pnode->addr, "spork-sync");
                // get current network sporks
                pnode->PushMessage(NetMsgType::GETSPORKS);

                // we always ask for sporks, so just skip this
                if(nRequestedMasternodeAssets == MASTERNODE_SYNC_SPORKS) SwitchToNextAsset();

                continue; // always get sporks first, switch to the next node without waiting for the next tick
            }

            // MNLIST : SYNC MASTERNODE LIST FROM OTHER CONNECTED CLIENTS

            if(nRequestedMasternodeAssets == MASTERNODE_SYNC_LIST) {
                // check for timeout first
                if(nTimeLastMasternodeList < GetTime() - MASTERNODE_SYNC_TIMEOUT_SECONDS) {
                    LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
                    if (nRequestedMasternodeAttempt == 0) {
                        LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
                        // there is no way we can continue without masternode list, fail here and try later
                        Fail();
                        return;
                    }
                    SwitchToNextAsset();
                    return;
                }

                // check for data
                // if we have enough masternodes in or list, switch to the next asset
                /* Note: Is this activing up? It's probably related to int CMasternodeMan::GetEstimatedMasternodes(int nBlock)
                   Surely doesn't work right for testnet currently */
                // try to fetch data from at least two peers though
                if(nRequestedMasternodeAttempt > 1 && nMnCount > mnodeman.GetEstimatedMasternodes(pCurrentBlockIndex->nHeight)*0.9) {
                    LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- found enough data\n", nTick, nRequestedMasternodeAssets);
                    SwitchToNextAsset();
                    return;
                }

                // only request once from each peer
                if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-list-sync")) continue;
                netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-list-sync");

                if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
                nRequestedMasternodeAttempt++;

                mnodeman.DsegUpdate(pnode);

                return; //this will cause each peer to get one request each six seconds for the various assets we need
            }

            // MNW : SYNC MASTERNODE PAYMENT VOTES FROM OTHER CONNECTED CLIENTS

            if(nRequestedMasternodeAssets == MASTERNODE_SYNC_MNW) {
                // check for timeout first
                // This might take a lot longer than MASTERNODE_SYNC_TIMEOUT_SECONDS minutes due to new blocks,
                // but that should be OK and it should timeout eventually.
                if(nTimeLastPaymentVote < GetTime() - MASTERNODE_SYNC_TIMEOUT_SECONDS) {
                    LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
                    if (nRequestedMasternodeAttempt == 0) {
                        LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
                        // probably not a good idea to proceed without winner list
                        Fail();
                        return;
                    }
                    SwitchToNextAsset();
                    return;
                }

                // check for data
                // if mnpayments already has enough blocks and votes, switch to the next asset
                // try to fetch data from at least two peers though
                if(nRequestedMasternodeAttempt > 1 && mnpayments.IsEnoughData()) {
                    LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d -- found enough data\n", nTick, nRequestedMasternodeAssets);
                    SwitchToNextAsset();
                    return;
                }

                // only request once from each peer
                if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-payment-sync")) continue;
                netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-payment-sync");

                if(pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
                nRequestedMasternodeAttempt++;

                // ask node for all payment votes it has (new nodes will only return votes for future payments)
                pnode->PushMessage(NetMsgType::MASTERNODEPAYMENTSYNC, mnpayments.GetStorageLimit());
                // ask node for missing pieces only (old nodes will not be asked)
                mnpayments.RequestLowDataPaymentBlocks(pnode);

                return; //this will cause each peer to get one request each six seconds for the various assets we need
            }

            // GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS

            if(nRequestedMasternodeAssets == MASTERNODE_SYNC_GOVERNANCE) {
                // check for timeout first
                if(nTimeLastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT_SECONDS){
                    LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
                    if(nRequestedMasternodeAttempt == 0) {
                        LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
                        // it's kind of ok to skip this for now, hopefully we'll catch up later?
                    }
                    SwitchToNextAsset();
                    return;
                }

                // check for data
                // if(nCountBudgetItemProp > 0 && nCountBudgetItemFin)
                // {
                //     if(governance.CountProposalInventoryItems() >= (nSumBudgetItemProp / nCountBudgetItemProp)*0.9)
                //     {
                //         if(governance.CountFinalizedInventoryItems() >= (nSumBudgetItemFin / nCountBudgetItemFin)*0.9)
                //         {
                //             SwitchToNextAsset();
                //             return;
                //         }
                //     }
                // }

                // only request once from each peer
                if(netfulfilledman.HasFulfilledRequest(pnode->addr, "governance-sync")) continue;
                netfulfilledman.AddFulfilledRequest(pnode->addr, "governance-sync");

                if (pnode->nVersion < MSG_GOVERNANCE_PEER_PROTO_VERSION) continue;
                nRequestedMasternodeAttempt++;

                pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, uint256()); //sync masternode votes

                return; //this will cause each peer to get one request each six seconds for the various assets we need
            }
        }
    }
}

void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindex)
{
    pCurrentBlockIndex = pindex;
}

void CMasternodeSync::AddedBudgetItem(uint256 hash)
{
    // skip this for now
    return;
}
<commit_msg>Do not switch from MASTERNODE_SYNC_SPORKS to next asset until blockchain is synced<commit_after>// Copyright (c) 2014-2016 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "activemasternode.h"
#include "governance.h"
#include "main.h"
#include "masternode.h"
#include "masternode-payments.h"
#include "masternode-sync.h"
#include "masternodeman.h"
#include "netfulfilledman.h"
#include "spork.h"
#include "util.h"

class CMasternodeSync;
CMasternodeSync masternodeSync;

bool CMasternodeSync::IsBlockchainSynced()
{
    static bool fBlockchainSynced = false;
    static int64_t lastProcess = GetTime();

    // if the last call to this function was more than 60 minutes ago (client was in sleep mode) reset the sync process
    if(GetTime() - lastProcess > 60*60) {
        Reset();
        fBlockchainSynced = false;
    }
    lastProcess = GetTime();

    if(fBlockchainSynced) return true;
    if(!pCurrentBlockIndex || !pindexBestHeader || fImporting || fReindex) return false;

    // same as !IsInitialBlockDownload() but no cs_main needed here
    int nMaxBlockTime = std::max(pCurrentBlockIndex->GetBlockTime(), pindexBestHeader->GetBlockTime());
    fBlockchainSynced = pindexBestHeader->nHeight - pCurrentBlockIndex->nHeight < 24 * 6 &&
                        GetTime() - nMaxBlockTime < Params().MaxTipAge();

    return fBlockchainSynced;
}

void CMasternodeSync::Fail()
{
    nTimeLastFailure = GetTime();
    nRequestedMasternodeAssets = MASTERNODE_SYNC_FAILED;
}

void CMasternodeSync::Reset()
{
    nRequestedMasternodeAssets = MASTERNODE_SYNC_INITIAL;
    nRequestedMasternodeAttempt = 0;
    nTimeAssetSyncStarted = GetTime();
    nTimeLastMasternodeList = GetTime();
    nTimeLastPaymentVote = GetTime();
    nTimeLastBudgetItem = GetTime();
    nTimeLastFailure = 0;
    nCountFailures = 0;
}

std::string CMasternodeSync::GetAssetName()
{
    switch(nRequestedMasternodeAssets)
    {
        case(MASTERNODE_SYNC_INITIAL):      return "MASTERNODE_SYNC_INITIAL";
        case(MASTERNODE_SYNC_SPORKS):       return "MASTERNODE_SYNC_SPORKS";
        case(MASTERNODE_SYNC_LIST):         return "MASTERNODE_SYNC_LIST";
        case(MASTERNODE_SYNC_MNW):          return "MASTERNODE_SYNC_MNW";
        case(MASTERNODE_SYNC_GOVERNANCE):   return "MASTERNODE_SYNC_GOVERNANCE";
        case(MASTERNODE_SYNC_FAILED):       return "MASTERNODE_SYNC_FAILED";
        case MASTERNODE_SYNC_FINISHED:      return "MASTERNODE_SYNC_FINISHED";
        default:                            return "UNKNOWN";
    }
}

void CMasternodeSync::SwitchToNextAsset()
{
    switch(nRequestedMasternodeAssets)
    {
        case(MASTERNODE_SYNC_FAILED):
            throw std::runtime_error("Can't switch to next asset from failed, should use Reset() first!");
            break;
        case(MASTERNODE_SYNC_INITIAL):
            ClearFulfilledRequests();
            nRequestedMasternodeAssets = MASTERNODE_SYNC_SPORKS;
            break;
        case(MASTERNODE_SYNC_SPORKS):
            nTimeLastMasternodeList = GetTime();
            nRequestedMasternodeAssets = MASTERNODE_SYNC_LIST;
            break;
        case(MASTERNODE_SYNC_LIST):
            nTimeLastPaymentVote = GetTime();
            nRequestedMasternodeAssets = MASTERNODE_SYNC_MNW;
            break;
        case(MASTERNODE_SYNC_MNW):
            nTimeLastBudgetItem = GetTime();
            nRequestedMasternodeAssets = MASTERNODE_SYNC_GOVERNANCE;
            break;
        case(MASTERNODE_SYNC_GOVERNANCE):
            LogPrintf("CMasternodeSync::SwitchToNextAsset -- Sync has finished\n");
            nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
            uiInterface.NotifyAdditionalDataSyncProgressChanged(1);
            //try to activate our masternode if possible
            activeMasternode.ManageState();

            TRY_LOCK(cs_vNodes, lockRecv);
            if(!lockRecv) return;

            BOOST_FOREACH(CNode* pnode, vNodes) {
                netfulfilledman.AddFulfilledRequest(pnode->addr, "full-sync");
            }

            break;
    }
    nRequestedMasternodeAttempt = 0;
    nTimeAssetSyncStarted = GetTime();
}

std::string CMasternodeSync::GetSyncStatus()
{
    switch (masternodeSync.nRequestedMasternodeAssets) {
        case MASTERNODE_SYNC_INITIAL:       return _("Synchronization pending...");
        case MASTERNODE_SYNC_SPORKS:        return _("Synchronizing sporks...");
        case MASTERNODE_SYNC_LIST:          return _("Synchronizing masternodes...");
        case MASTERNODE_SYNC_MNW:           return _("Synchronizing masternode payments...");
        case MASTERNODE_SYNC_GOVERNANCE:    return _("Synchronizing governance objects...");
        case MASTERNODE_SYNC_FAILED:        return _("Synchronization failed");
        case MASTERNODE_SYNC_FINISHED:      return _("Synchronization finished");
        default:                            return "";
    }
}

void CMasternodeSync::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
    if (strCommand == NetMsgType::SYNCSTATUSCOUNT) { //Sync status count

        //do not care about stats if sync process finished or failed
        if(IsSynced() || IsFailed()) return;

        int nItemID;
        int nCount;
        vRecv >> nItemID >> nCount;

        LogPrintf("CMasternodeSync::ProcessMessage -- SYNCSTATUSCOUNT -- got inventory count: nItemID=%d  nCount=%d  peer=%d\n", nItemID, nCount, pfrom->id);
    }
}

void CMasternodeSync::ClearFulfilledRequests()
{
    TRY_LOCK(cs_vNodes, lockRecv);
    if(!lockRecv) return;

    BOOST_FOREACH(CNode* pnode, vNodes)
    {
        netfulfilledman.RemoveFulfilledRequest(pnode->addr, "spork-sync");
        netfulfilledman.RemoveFulfilledRequest(pnode->addr, "masternode-list-sync");
        netfulfilledman.RemoveFulfilledRequest(pnode->addr, "masternode-payment-sync");
        netfulfilledman.RemoveFulfilledRequest(pnode->addr, "governance-sync");
        netfulfilledman.RemoveFulfilledRequest(pnode->addr, "full-sync");
    }
}

void CMasternodeSync::ProcessTick()
{
    static int nTick = 0;
    if(nTick++ % 6 != 0) return;
    if(!pCurrentBlockIndex) return;

    //the actual count of masternodes we have currently
    int nMnCount = mnodeman.CountEnabled();

    // RESET SYNCING INCASE OF FAILURE
    {
        if(IsSynced()) {
            /*
                Resync if we lose all masternodes from sleep/wake or failure to sync originally
            */
            if(nMnCount == 0) {
                Reset();
            } else {
                //if syncing is complete and we have masternodes, return
                return;
            }
        }

        //try syncing again
        if(IsFailed()) {
            if(nTimeLastFailure + (1*60) < GetTime()) { // 1 minute cooldown after failed sync
                Reset();
            }
            return;
        }
    }

    // INITIAL SYNC SETUP / LOG REPORTING
    double nSyncProgress = double(nRequestedMasternodeAttempt + (nRequestedMasternodeAssets - 1) * 8) / (8*4);
    LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d nRequestedMasternodeAttempt %d nSyncProgress %f\n", nTick, nRequestedMasternodeAssets, nRequestedMasternodeAttempt, nSyncProgress);
    uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress);

    // sporks synced but blockchain is not, wait until we're almost at a recent block to continue
    if(Params().NetworkIDString() != CBaseChainParams::REGTEST &&
            !IsBlockchainSynced() && nRequestedMasternodeAssets > MASTERNODE_SYNC_SPORKS) return;

    TRY_LOCK(cs_vNodes, lockRecv);
    if(!lockRecv) return;

    if(nRequestedMasternodeAssets == MASTERNODE_SYNC_INITIAL ||
        (nRequestedMasternodeAssets == MASTERNODE_SYNC_SPORKS && IsBlockchainSynced()))
    {
        SwitchToNextAsset();
    }

    BOOST_FOREACH(CNode* pnode, vNodes)
    {
        // QUICK MODE (REGTEST ONLY!)
        if(Params().NetworkIDString() == CBaseChainParams::REGTEST)
        {
            if(nRequestedMasternodeAttempt <= 2) {
                pnode->PushMessage(NetMsgType::GETSPORKS); //get current network sporks
            } else if(nRequestedMasternodeAttempt < 4) {
                mnodeman.DsegUpdate(pnode);
            } else if(nRequestedMasternodeAttempt < 6) {
                int nMnCount = mnodeman.CountEnabled();
                pnode->PushMessage(NetMsgType::MASTERNODEPAYMENTSYNC, nMnCount); //sync payment votes
                uint256 n = uint256();
                pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, n); //sync masternode votes
            } else {
                nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
            }
            nRequestedMasternodeAttempt++;
            return;
        }

        // NORMAL NETWORK MODE - TESTNET/MAINNET
        {
            if(netfulfilledman.HasFulfilledRequest(pnode->addr, "full-sync")) {
                // we already fully synced from this node recently,
                // disconnect to free this connection slot for a new node
                pnode->fDisconnect = true;
                LogPrintf("CMasternodeSync::ProcessTick -- disconnecting from recently synced node %d\n", pnode->id);
                continue;
            }

            // SPORK : ALWAYS ASK FOR SPORKS AS WE SYNC (we skip this mode now)

            if(!netfulfilledman.HasFulfilledRequest(pnode->addr, "spork-sync")) {
                // only request once from each peer
                netfulfilledman.AddFulfilledRequest(pnode->addr, "spork-sync");
                // get current network sporks
                pnode->PushMessage(NetMsgType::GETSPORKS);
                continue; // always get sporks first, switch to the next node without waiting for the next tick
            }

            // MNLIST : SYNC MASTERNODE LIST FROM OTHER CONNECTED CLIENTS

            if(nRequestedMasternodeAssets == MASTERNODE_SYNC_LIST) {
                // check for timeout first
                if(nTimeLastMasternodeList < GetTime() - MASTERNODE_SYNC_TIMEOUT_SECONDS) {
                    LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
                    if (nRequestedMasternodeAttempt == 0) {
                        LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
                        // there is no way we can continue without masternode list, fail here and try later
                        Fail();
                        return;
                    }
                    SwitchToNextAsset();
                    return;
                }

                // check for data
                // if we have enough masternodes in or list, switch to the next asset
                /* Note: Is this activing up? It's probably related to int CMasternodeMan::GetEstimatedMasternodes(int nBlock)
                   Surely doesn't work right for testnet currently */
                // try to fetch data from at least two peers though
                if(nRequestedMasternodeAttempt > 1 && nMnCount > mnodeman.GetEstimatedMasternodes(pCurrentBlockIndex->nHeight)*0.9) {
                    LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- found enough data\n", nTick, nRequestedMasternodeAssets);
                    SwitchToNextAsset();
                    return;
                }

                // only request once from each peer
                if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-list-sync")) continue;
                netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-list-sync");

                if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
                nRequestedMasternodeAttempt++;

                mnodeman.DsegUpdate(pnode);

                return; //this will cause each peer to get one request each six seconds for the various assets we need
            }

            // MNW : SYNC MASTERNODE PAYMENT VOTES FROM OTHER CONNECTED CLIENTS

            if(nRequestedMasternodeAssets == MASTERNODE_SYNC_MNW) {
                // check for timeout first
                // This might take a lot longer than MASTERNODE_SYNC_TIMEOUT_SECONDS minutes due to new blocks,
                // but that should be OK and it should timeout eventually.
                if(nTimeLastPaymentVote < GetTime() - MASTERNODE_SYNC_TIMEOUT_SECONDS) {
                    LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
                    if (nRequestedMasternodeAttempt == 0) {
                        LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
                        // probably not a good idea to proceed without winner list
                        Fail();
                        return;
                    }
                    SwitchToNextAsset();
                    return;
                }

                // check for data
                // if mnpayments already has enough blocks and votes, switch to the next asset
                // try to fetch data from at least two peers though
                if(nRequestedMasternodeAttempt > 1 && mnpayments.IsEnoughData()) {
                    LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d -- found enough data\n", nTick, nRequestedMasternodeAssets);
                    SwitchToNextAsset();
                    return;
                }

                // only request once from each peer
                if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-payment-sync")) continue;
                netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-payment-sync");

                if(pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
                nRequestedMasternodeAttempt++;

                // ask node for all payment votes it has (new nodes will only return votes for future payments)
                pnode->PushMessage(NetMsgType::MASTERNODEPAYMENTSYNC, mnpayments.GetStorageLimit());
                // ask node for missing pieces only (old nodes will not be asked)
                mnpayments.RequestLowDataPaymentBlocks(pnode);

                return; //this will cause each peer to get one request each six seconds for the various assets we need
            }

            // GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS

            if(nRequestedMasternodeAssets == MASTERNODE_SYNC_GOVERNANCE) {
                // check for timeout first
                if(nTimeLastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT_SECONDS){
                    LogPrintf("CMasternodeSync::Process -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
                    if(nRequestedMasternodeAttempt == 0) {
                        LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
                        // it's kind of ok to skip this for now, hopefully we'll catch up later?
                    }
                    SwitchToNextAsset();
                    return;
                }

                // check for data
                // if(nCountBudgetItemProp > 0 && nCountBudgetItemFin)
                // {
                //     if(governance.CountProposalInventoryItems() >= (nSumBudgetItemProp / nCountBudgetItemProp)*0.9)
                //     {
                //         if(governance.CountFinalizedInventoryItems() >= (nSumBudgetItemFin / nCountBudgetItemFin)*0.9)
                //         {
                //             SwitchToNextAsset();
                //             return;
                //         }
                //     }
                // }

                // only request once from each peer
                if(netfulfilledman.HasFulfilledRequest(pnode->addr, "governance-sync")) continue;
                netfulfilledman.AddFulfilledRequest(pnode->addr, "governance-sync");

                if (pnode->nVersion < MSG_GOVERNANCE_PEER_PROTO_VERSION) continue;
                nRequestedMasternodeAttempt++;

                pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, uint256()); //sync masternode votes

                return; //this will cause each peer to get one request each six seconds for the various assets we need
            }
        }
    }
}

void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindex)
{
    pCurrentBlockIndex = pindex;
}

void CMasternodeSync::AddedBudgetItem(uint256 hash)
{
    // skip this for now
    return;
}
<|endoftext|>