<commit_before>/*
 * MCore Extensions for TTBlue
 * Creates a wrapper for TTAudioObjects that can be used to build an audio processing graph.
 * Copyright © 2008, Timothy Place
 *
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "multicore.h"
#define thisTTClass MCoreObject

MCoreObject::MCoreObject(const TTValue& arguments)
	: TTObject("multicore.object"), flags(kMCoreProcessor), alwaysProcessSidechain(false), audioSources(NULL), sidechainSources(NULL), numSources(0), numSidechainSources(0),
	audioInput(NULL), audioOutput(NULL), sidechainInput(NULL), sidechainOutput(NULL), audioObject(NULL)
{
	TTErr		err;
	TTSymbolPtr	wrappedObjectName;
	TTUInt16	initialNumChannels;

	TT_ASSERT(multicore_correct_instantiation_args, arguments.getSize() == 2);

	arguments.get(0, &wrappedObjectName);
	arguments.get(1, initialNumChannels);
	inChansToOutChansRatio[0] = 1;
	inChansToOutChansRatio[1] = 1;

	err = TTObjectInstantiate(wrappedObjectName, &audioObject, initialNumChannels);
	err = TTObjectInstantiate(kTTSym_audiosignal, &audioInput, initialNumChannels);
	err = TTObjectInstantiate(kTTSym_audiosignal, &audioOutput, initialNumChannels * TTLimitMin<TTFloat32>(inChansToOutChansRatio[1] / inChansToOutChansRatio[0], 1));

	registerMessageWithArgument(objectFreeing);	// called when one of our input source objects is deleted
}

MCoreObject::~MCoreObject()
{
	for(TTUInt16 i=0; i<numSources; i++)
		audioSources[i]->unregisterObserverForNotifications(*this);

	TTObjectRelease(&audioObject);
	TTObjectRelease(&audioInput);
	TTObjectRelease(&audioOutput);
	TTObjectRelease(&sidechainInput);
	TTObjectRelease(&sidechainOutput);
}

TTErr MCoreObject::objectFreeing(const TTValue& theObjectBeingDeleted)
{
	TTObjectPtr o = theObjectBeingDeleted;
	TTBoolean	found = NO;
	TTBoolean	oldValid = valid;
	// This is an ugly operation
	// the problem is that we don't want to traverse a linked-list in the processing chain

	valid = false;
	while(getlock())
		;

	for(TTUInt16 i=0; i<(numSources-1); i++){
		if(audioSources[i] == o)
			found = YES;
		if(found)
			audioSources[i] = audioSources[i+1];
	}

	audioSources[numSources-1] = 0;
	numSources--;

	valid = oldValid;
	return kTTErrNone;
}

TTErr MCoreObject::setAudioOutputPtr(TTAudioSignalPtr newOutputPtr)
{
	TTObjectPtr oldAudioOutput = audioOutput;

	audioOutput = (TTAudioSignalPtr)TTObjectReference(newOutputPtr);

	if(oldAudioOutput)
		TTObjectRelease(&oldAudioOutput);
	return kTTErrNone;
}

TTErr MCoreObject::setInChansToOutChansRatio(TTUInt16 numInputChannels, TTUInt16 numOutputChannels)
{
	inChansToOutChansRatio[0] = numInputChannels;
	inChansToOutChansRatio[1] = numOutputChannels;
	return kTTErrNone;
}

TTErr MCoreObject::setAlwaysProcessSidechain(TTBoolean newValue)
{
	alwaysProcessSidechain = newValue;
	return kTTErrNone;
}

TTErr MCoreObject::prepareToProcess()
{
	lock();
	if(valid){
		processStatus = kProcessNotStarted;

		for(TTUInt16 i=0; i<numSources; i++)
			audioSources[i]->prepareToProcess();
		for(TTUInt16 i=0; i<numSidechainSources; i++)
			sidechainSources[i]->prepareToProcess();

	}
	unlock();
	return kTTErrNone;
}

TTErr MCoreObject::resetSources(TTUInt16 vs)
{
	// go through all of the sources and tell them we don't want to watch them any more
	for(TTUInt16 i=0; i<numSources; i++)
		audioSources[i]->unregisterObserverForNotifications(*this);

	if(audioSources && numSources)
		free(audioSources);
	audioSources = NULL;
	numSources = 0;

	if(sidechainSources && numSidechainSources)
		free(sidechainSources);
	sidechainSources = NULL;
	numSidechainSources = 0;

	// Generators will not receive an 'addSource' call,
	// so we set them with the 'default' vector size provided by the global reset
	if(flags & kMCoreGenerator){
		audioOutput->allocWithVectorSize(vs);
	}

	return kTTErrNone;
}

TTErr MCoreObject::addSource(MCoreObjectPtr anObject, TTUInt16 sourceOutletNumber, TTUInt16 anInletNumber)
{
	if(anInletNumber){		// A sidechain source
		numSidechainSources++;
		if(numSidechainSources == 1){
			sidechainSources = (MCoreObjectPtr*)malloc(sizeof(MCoreObjectPtr) * numSidechainSources);
			sidechainOutletIndices = (TTUInt16*)malloc(sizeof(TTUInt16) * numSources);
		}
		else{
			sidechainSources = (MCoreObjectPtr*)realloc(sidechainSources, sizeof(MCoreObjectPtr) * numSidechainSources);
			sidechainOutletIndices = (TTUInt16*)realloc(sidechainOutletIndices, sizeof(TTUInt16) * numSources);
		}
		sidechainSources[numSidechainSources-1] = anObject;
		sidechainOutletIndices[numSidechainSources-1] = sourceOutletNumber;

		if(!sidechainInput)
			TTObjectInstantiate(kTTSym_audiosignal, &sidechainInput, 1);
		if(!sidechainOutput)
			TTObjectInstantiate(kTTSym_audiosignal, &sidechainOutput, TTLimitMin<TTFloat32>(inChansToOutChansRatio[1] / inChansToOutChansRatio[0], 1));
	}
	else{					// A normal audio source
		numSources++;
		if(numSources == 1){
			audioSources = (MCoreObjectPtr*)malloc(sizeof(MCoreObjectPtr) * numSources);
			audioSourceOutletIndices = (TTUInt16*)malloc(sizeof(TTUInt16) * numSources);
		}
		else{
			audioSources = (MCoreObjectPtr*)realloc(audioSources, sizeof(MCoreObjectPtr) * numSources);
			audioSourceOutletIndices = (TTUInt16*)realloc(audioSourceOutletIndices, sizeof(TTUInt16) * numSources);
		}
		audioSources[numSources-1] = anObject;
		audioSourceOutletIndices[numSources-1] = sourceOutletNumber;
	}

	// tell the source that is passed in that we want to watch it
	anObject->registerObserverForNotifications(*this);

	return kTTErrNone;
}

TTUInt16 MCoreObject::initAudioSignal(TTAudioSignalPtr aSignal, MCoreObjectPtr aSource)
{
	TTUInt16	numChannels;
	TTUInt16	sourceProducesNumChannels;

	numChannels = aSignal->getNumChannels();
	sourceProducesNumChannels = aSource->audioOutput->getNumChannels();

	// currently we only up-size a signal, but perhaps we should also down-size them as appropriate?
	if(sourceProducesNumChannels > numChannels)
		aSignal->setmaxNumChannels(sourceProducesNumChannels);

	aSignal->setnumChannels(sourceProducesNumChannels);
	return sourceProducesNumChannels;
}

TTErr MCoreObject::init()
{
	TTUInt16	sourceProducesNumChannels;
	TTUInt16	sidechainSourceProducesNumChannels;
	TTUInt16	weDeliverNumChannels;

	lock();

	// init objects higher up in the chain first
	for(TTUInt16 i=0; i<numSources; i++)
		audioSources[i]->init();
	for(TTUInt16 i=0; i<numSidechainSources; i++)
		sidechainSources[i]->init();

	// What follows is a bit ugly (including code duplication) and should be reviewed:
	// The sidechain situation makes this even more complex...
	// For now we make the dubious assumption that sidechains are going to follow along
	// and be set up just like the normal audio inputs.

	if(numSources && audioSources){
		// match our source's vector size and number of channels
		sourceProducesNumChannels = initAudioSignal(audioInput, audioSources[0]);

		// while it make sense to always match the input of this object to the output of the previous object (as above)
		// we might want to have a different number of outputs here -- how should we handle that?
		// for now we are just matching them more or less...
		weDeliverNumChannels = sourceProducesNumChannels * TTLimitMin<TTFloat32>(inChansToOutChansRatio[1] / inChansToOutChansRatio[0], 1);
		audioOutput->setmaxNumChannels(weDeliverNumChannels);
		audioOutput->setnumChannels(weDeliverNumChannels);

		// for generators, these are already alloc'd in the reset method
		audioInput->allocWithVectorSize(audioSources[0]->audioOutput->getVectorSize());
		audioOutput->allocWithVectorSize(audioSources[0]->audioOutput->getVectorSize());

		if(numSidechainSources){
			sidechainSourceProducesNumChannels = initAudioSignal(sidechainInput, sidechainSources[0]);
			sidechainInput->allocWithVectorSize(sidechainSources[0]->audioOutput->getVectorSize());
		}
		if(alwaysProcessSidechain){
			if(!sidechainOutput)
				TTObjectInstantiate(kTTSym_audiosignal, &sidechainOutput, sourceProducesNumChannels * TTLimitMin<TTFloat32>(inChansToOutChansRatio[1] / inChansToOutChansRatio[0], 1));
			sidechainOutput->allocWithVectorSize(audioSources[0]->audioOutput->getVectorSize());
		}
	}
	else{
		sourceProducesNumChannels = 0;
		weDeliverNumChannels = getNumOutputChannels();
	}

	// Even more ambiguous, what do we do for the acual audio object?
	// For now we are setting it to the higher of the two options to be safe.
	// (and we are not taking sidechains into account at all
	if(weDeliverNumChannels > sourceProducesNumChannels)
		audioObject->setMaxNumChannels(weDeliverNumChannels);
	else
		audioObject->setMaxNumChannels(sourceProducesNumChannels);

	unlock();
	return kTTErrNone;
}

TTErr MCoreObject::getAudioOutput(TTAudioSignalPtr& returnedSignal, TTBoolean getSidechain)
{
	TTAudioSignalPtr	pulledInput = NULL;
	TTAudioSignalPtr	pulledSidechainInput = NULL;
	TTErr				err;

	lock();
	switch(processStatus){

		// we have not processed anything yet, so let's get started
		case kProcessNotStarted:
			processStatus = kProcessingCurrently;

			// zero the samples
			audioInput->clear();

			// sum the sources
			for(TTUInt16 i=0; i<numSources; i++){
				// if there is a non-zero source outlet index, that means we are supposed to request the sidechain signal
				err = audioSources[i]->getAudioOutput(pulledInput, audioSourceOutletIndices[i]);
				if(!err)
					(*audioInput) += (*pulledInput);
			}

			if(numSidechainSources){
				sidechainInput->clear();	// zero the samples

				// sum the sidechain sources
				for(TTUInt16 i=0; i<numSidechainSources; i++){
					err = sidechainSources[i]->getAudioOutput(pulledSidechainInput);
					if(!err)
						(*sidechainInput) += (*pulledSidechainInput);
				}

				audioObject->process(audioInput, sidechainInput, audioOutput);		// a processor with sidechain input
			}
			else if(alwaysProcessSidechain){
				audioObject->process(audioInput, audioInput, audioOutput, sidechainOutput);		// a processor with sidechain output
			}
			else if(numSources){
				audioObject->process(audioInput, audioOutput);		// a processor
			}
			else{
				audioObject->process(audioOutput);					// a generator (or no input)
			}

			// return
			if(getSidechain)
				returnedSignal = sidechainOutput;
			else
				returnedSignal = audioOutput;

			processStatus = kProcessComplete;
			break;

		// we already processed everything that needs to be processed, so just set the pointer
		case kProcessComplete:
			if(getSidechain)
				returnedSignal = sidechainOutput;
			else
				returnedSignal = audioOutput;
			break;

		// to prevent feedback / infinite loops, we just hand back the last calculated output here
		case kProcessingCurrently:
			if(getSidechain)
				returnedSignal = sidechainOutput;
			else
				returnedSignal = audioOutput;
			break;

		// we should never get here
		default:
			unlock();
			return kTTErrGeneric;
	}
	unlock();
	return kTTErrNone;
}

<commit_msg>validity checking before sending notifications to observers -- this resolves some crashing problems -- would like to come back some time and review exactly how everything is happening though...<commit_after>/*
 * MCore Extensions for TTBlue
 * Creates a wrapper for TTAudioObjects that can be used to build an audio processing graph.
 * Copyright © 2008, Timothy Place
 *
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html
 */

#include "multicore.h"
#define thisTTClass MCoreObject

MCoreObject::MCoreObject(const TTValue& arguments)
	: TTObject("multicore.object"), flags(kMCoreProcessor), alwaysProcessSidechain(false), audioSources(NULL), sidechainSources(NULL), numSources(0), numSidechainSources(0),
	audioInput(NULL), audioOutput(NULL), sidechainInput(NULL), sidechainOutput(NULL), audioObject(NULL)
{
	TTErr		err;
	TTSymbolPtr	wrappedObjectName;
	TTUInt16	initialNumChannels;

	TT_ASSERT(multicore_correct_instantiation_args, arguments.getSize() == 2);

	arguments.get(0, &wrappedObjectName);
	arguments.get(1, initialNumChannels);
	inChansToOutChansRatio[0] = 1;
	inChansToOutChansRatio[1] = 1;

	err = TTObjectInstantiate(wrappedObjectName, &audioObject, initialNumChannels);
	err = TTObjectInstantiate(kTTSym_audiosignal, &audioInput, initialNumChannels);
	err = TTObjectInstantiate(kTTSym_audiosignal, &audioOutput, initialNumChannels * TTLimitMin<TTFloat32>(inChansToOutChansRatio[1] / inChansToOutChansRatio[0], 1));

	registerMessageWithArgument(objectFreeing);	// called when one of our input source objects is deleted
}

MCoreObject::~MCoreObject()
{
	for(TTUInt16 i=0; i<numSources; i++){
		if(audioSources[i]->valid)
			audioSources[i]->unregisterObserverForNotifications(*this);
	}
	TTObjectRelease(&audioObject);
	TTObjectRelease(&audioInput);
	TTObjectRelease(&audioOutput);
	TTObjectRelease(&sidechainInput);
	TTObjectRelease(&sidechainOutput);
}

TTErr MCoreObject::objectFreeing(const TTValue& theObjectBeingDeleted)
{
	TTObjectPtr o = theObjectBeingDeleted;
	TTBoolean	found = NO;
	TTBoolean	oldValid = valid;
	// This is an ugly operation
	// the problem is that we don't want to traverse a linked-list in the processing chain

	valid = false;
	while(getlock())
		;

	for(TTUInt16 i=0; i<(numSources-1); i++){
		if(audioSources[i] == o)
			found = YES;
		if(found)
			audioSources[i] = audioSources[i+1];
	}

	audioSources[numSources-1] = 0;
	numSources--;

	valid = oldValid;
	return kTTErrNone;
}

TTErr MCoreObject::setAudioOutputPtr(TTAudioSignalPtr newOutputPtr)
{
	TTObjectPtr oldAudioOutput = audioOutput;

	audioOutput = (TTAudioSignalPtr)TTObjectReference(newOutputPtr);

	if(oldAudioOutput)
		TTObjectRelease(&oldAudioOutput);
	return kTTErrNone;
}

TTErr MCoreObject::setInChansToOutChansRatio(TTUInt16 numInputChannels, TTUInt16 numOutputChannels)
{
	inChansToOutChansRatio[0] = numInputChannels;
	inChansToOutChansRatio[1] = numOutputChannels;
	return kTTErrNone;
}

TTErr MCoreObject::setAlwaysProcessSidechain(TTBoolean newValue)
{
	alwaysProcessSidechain = newValue;
	return kTTErrNone;
}

TTErr MCoreObject::prepareToProcess()
{
	lock();
	if(valid){
		processStatus = kProcessNotStarted;

		for(TTUInt16 i=0; i<numSources; i++)
			audioSources[i]->prepareToProcess();
		for(TTUInt16 i=0; i<numSidechainSources; i++)
			sidechainSources[i]->prepareToProcess();

	}
	unlock();
	return kTTErrNone;
}

TTErr MCoreObject::resetSources(TTUInt16 vs)
{
	// go through all of the sources and tell them we don't want to watch them any more
	for(TTUInt16 i=0; i<numSources; i++)
		audioSources[i]->unregisterObserverForNotifications(*this);

	if(audioSources && numSources)
		free(audioSources);
	audioSources = NULL;
	numSources = 0;

	if(sidechainSources && numSidechainSources)
		free(sidechainSources);
	sidechainSources = NULL;
	numSidechainSources = 0;

	// Generators will not receive an 'addSource' call,
	// so we set them with the 'default' vector size provided by the global reset
	if(flags & kMCoreGenerator){
		audioOutput->allocWithVectorSize(vs);
	}

	return kTTErrNone;
}

TTErr MCoreObject::addSource(MCoreObjectPtr anObject, TTUInt16 sourceOutletNumber, TTUInt16 anInletNumber)
{
	if(anInletNumber){		// A sidechain source
		numSidechainSources++;
		if(numSidechainSources == 1){
			sidechainSources = (MCoreObjectPtr*)malloc(sizeof(MCoreObjectPtr) * numSidechainSources);
			sidechainOutletIndices = (TTUInt16*)malloc(sizeof(TTUInt16) * numSources);
		}
		else{
			sidechainSources = (MCoreObjectPtr*)realloc(sidechainSources, sizeof(MCoreObjectPtr) * numSidechainSources);
			sidechainOutletIndices = (TTUInt16*)realloc(sidechainOutletIndices, sizeof(TTUInt16) * numSources);
		}
		sidechainSources[numSidechainSources-1] = anObject;
		sidechainOutletIndices[numSidechainSources-1] = sourceOutletNumber;

		if(!sidechainInput)
			TTObjectInstantiate(kTTSym_audiosignal, &sidechainInput, 1);
		if(!sidechainOutput)
			TTObjectInstantiate(kTTSym_audiosignal, &sidechainOutput, TTLimitMin<TTFloat32>(inChansToOutChansRatio[1] / inChansToOutChansRatio[0], 1));
	}
	else{					// A normal audio source
		numSources++;
		if(numSources == 1){
			audioSources = (MCoreObjectPtr*)malloc(sizeof(MCoreObjectPtr) * numSources);
			audioSourceOutletIndices = (TTUInt16*)malloc(sizeof(TTUInt16) * numSources);
		}
		else{
			audioSources = (MCoreObjectPtr*)realloc(audioSources, sizeof(MCoreObjectPtr) * numSources);
			audioSourceOutletIndices = (TTUInt16*)realloc(audioSourceOutletIndices, sizeof(TTUInt16) * numSources);
		}
		audioSources[numSources-1] = anObject;
		audioSourceOutletIndices[numSources-1] = sourceOutletNumber;
	}

	// tell the source that is passed in that we want to watch it
	anObject->registerObserverForNotifications(*this);

	return kTTErrNone;
}

TTUInt16 MCoreObject::initAudioSignal(TTAudioSignalPtr aSignal, MCoreObjectPtr aSource)
{
	TTUInt16	numChannels;
	TTUInt16	sourceProducesNumChannels;

	numChannels = aSignal->getNumChannels();
	sourceProducesNumChannels = aSource->audioOutput->getNumChannels();

	// currently we only up-size a signal, but perhaps we should also down-size them as appropriate?
	if(sourceProducesNumChannels > numChannels)
		aSignal->setmaxNumChannels(sourceProducesNumChannels);

	aSignal->setnumChannels(sourceProducesNumChannels);
	return sourceProducesNumChannels;
}

TTErr MCoreObject::init()
{
	TTUInt16	sourceProducesNumChannels;
	TTUInt16	sidechainSourceProducesNumChannels;
	TTUInt16	weDeliverNumChannels;

	lock();

	// init objects higher up in the chain first
	for(TTUInt16 i=0; i<numSources; i++)
		audioSources[i]->init();
	for(TTUInt16 i=0; i<numSidechainSources; i++)
		sidechainSources[i]->init();

	// What follows is a bit ugly (including code duplication) and should be reviewed:
	// The sidechain situation makes this even more complex...
	// For now we make the dubious assumption that sidechains are going to follow along
	// and be set up just like the normal audio inputs.

	if(numSources && audioSources){
		// match our source's vector size and number of channels
		sourceProducesNumChannels = initAudioSignal(audioInput, audioSources[0]);

		// while it make sense to always match the input of this object to the output of the previous object (as above)
		// we might want to have a different number of outputs here -- how should we handle that?
		// for now we are just matching them more or less...
		weDeliverNumChannels = sourceProducesNumChannels * TTLimitMin<TTFloat32>(inChansToOutChansRatio[1] / inChansToOutChansRatio[0], 1);
		audioOutput->setmaxNumChannels(weDeliverNumChannels);
		audioOutput->setnumChannels(weDeliverNumChannels);

		// for generators, these are already alloc'd in the reset method
		audioInput->allocWithVectorSize(audioSources[0]->audioOutput->getVectorSize());
		audioOutput->allocWithVectorSize(audioSources[0]->audioOutput->getVectorSize());

		if(numSidechainSources){
			sidechainSourceProducesNumChannels = initAudioSignal(sidechainInput, sidechainSources[0]);
			sidechainInput->allocWithVectorSize(sidechainSources[0]->audioOutput->getVectorSize());
		}
		if(alwaysProcessSidechain){
			if(!sidechainOutput)
				TTObjectInstantiate(kTTSym_audiosignal, &sidechainOutput, sourceProducesNumChannels * TTLimitMin<TTFloat32>(inChansToOutChansRatio[1] / inChansToOutChansRatio[0], 1));
			sidechainOutput->allocWithVectorSize(audioSources[0]->audioOutput->getVectorSize());
		}
	}
	else{
		sourceProducesNumChannels = 0;
		weDeliverNumChannels = getNumOutputChannels();
	}

	// Even more ambiguous, what do we do for the acual audio object?
	// For now we are setting it to the higher of the two options to be safe.
	// (and we are not taking sidechains into account at all
	if(weDeliverNumChannels > sourceProducesNumChannels)
		audioObject->setMaxNumChannels(weDeliverNumChannels);
	else
		audioObject->setMaxNumChannels(sourceProducesNumChannels);

	unlock();
	return kTTErrNone;
}

TTErr MCoreObject::getAudioOutput(TTAudioSignalPtr& returnedSignal, TTBoolean getSidechain)
{
	TTAudioSignalPtr	pulledInput = NULL;
	TTAudioSignalPtr	pulledSidechainInput = NULL;
	TTErr				err;

	lock();
	switch(processStatus){

		// we have not processed anything yet, so let's get started
		case kProcessNotStarted:
			processStatus = kProcessingCurrently;

			// zero the samples
			audioInput->clear();

			// sum the sources
			for(TTUInt16 i=0; i<numSources; i++){
				// if there is a non-zero source outlet index, that means we are supposed to request the sidechain signal
				err = audioSources[i]->getAudioOutput(pulledInput, audioSourceOutletIndices[i]);
				if(!err)
					(*audioInput) += (*pulledInput);
			}

			if(numSidechainSources){
				sidechainInput->clear();	// zero the samples

				// sum the sidechain sources
				for(TTUInt16 i=0; i<numSidechainSources; i++){
					err = sidechainSources[i]->getAudioOutput(pulledSidechainInput);
					if(!err)
						(*sidechainInput) += (*pulledSidechainInput);
				}

				audioObject->process(audioInput, sidechainInput, audioOutput);		// a processor with sidechain input
			}
			else if(alwaysProcessSidechain){
				audioObject->process(audioInput, audioInput, audioOutput, sidechainOutput);		// a processor with sidechain output
			}
			else if(numSources){
				audioObject->process(audioInput, audioOutput);		// a processor
			}
			else{
				audioObject->process(audioOutput);					// a generator (or no input)
			}

			// return
			if(getSidechain)
				returnedSignal = sidechainOutput;
			else
				returnedSignal = audioOutput;

			processStatus = kProcessComplete;
			break;

		// we already processed everything that needs to be processed, so just set the pointer
		case kProcessComplete:
			if(getSidechain)
				returnedSignal = sidechainOutput;
			else
				returnedSignal = audioOutput;
			break;

		// to prevent feedback / infinite loops, we just hand back the last calculated output here
		case kProcessingCurrently:
			if(getSidechain)
				returnedSignal = sidechainOutput;
			else
				returnedSignal = audioOutput;
			break;

		// we should never get here
		default:
			unlock();
			return kTTErrGeneric;
	}
	unlock();
	return kTTErrNone;
}

<|endoftext|>


<commit_before>/*
 * @file fspanelcontactsets.cpp
 * @brief Contact sets UI
 *
 * (C) 2013 Cinder Roxley @ Second Life <cinder.roxley@phoenixviewer.com>
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include "llviewerprecompiledheaders.h"

#include "llnotificationsutil.h"

#include "fspanelcontactsets.h"
#include "fscontactsfloater.h"
#include "llavataractions.h"
#include "llcallingcard.h"
#include "llfloateravatarpicker.h"
#include "llfloaterreg.h"
#include "llslurl.h"
#include "lltrans.h"

#include <boost/foreach.hpp>

static LLRegisterPanelClassWrapper<FSPanelContactSets> t_panel_contact_sets("contact_sets_panel");

FSPanelContactSets::FSPanelContactSets() : LLPanel()
, mContactSetCombo(NULL)
, mAvatarList(NULL)
{
	mContactSetChangedConnection = LGGContactSets::getInstance()->setContactSetChangeCallback(boost::bind(&FSPanelContactSets::updateSets, this, _1));
}

FSPanelContactSets::~FSPanelContactSets()
{
	if (mContactSetChangedConnection.connected())
		mContactSetChangedConnection.disconnect();
}

BOOL FSPanelContactSets::postBuild()
{
	childSetAction("add_set_btn",			boost::bind(&FSPanelContactSets::onClickAddSet,			this));
	childSetAction("remove_set_btn",		boost::bind(&FSPanelContactSets::onClickRemoveSet,		this));
	childSetAction("config_btn",			boost::bind(&FSPanelContactSets::onClickConfigureSet,	this));
	childSetAction("add_btn",				boost::bind(&FSPanelContactSets::onClickAddAvatar,		this));
	childSetAction("remove_btn",			boost::bind(&FSPanelContactSets::onClickRemoveAvatar,	this));
	childSetAction("profile_btn",			boost::bind(&FSPanelContactSets::onClickOpenProfile,	this));
	childSetAction("start_im_btn",			boost::bind(&FSPanelContactSets::onClickStartIM,		this));
	childSetAction("offer_teleport_btn",	boost::bind(&FSPanelContactSets::onClickOfferTeleport,	this));

	mContactSetCombo = getChild<LLComboBox>("combo_sets");
	if (mContactSetCombo)
	{
		mContactSetCombo->setCommitCallback(boost::bind(&FSPanelContactSets::refreshSetList, this));
		refreshContactSets();
	}

	mAvatarList = getChild<LLAvatarList>("contact_list");
	if (mAvatarList)
	{
		mAvatarList->setCommitCallback(boost::bind(&FSPanelContactSets::onSelectAvatar, this));
		mAvatarList->setNoItemsCommentText(getString("empty_list"));
		generateAvatarList(mContactSetCombo->getSimple());
	}

	return TRUE;
}

void FSPanelContactSets::onSelectAvatar()
{
	mAvatarSelections.clear();
	mAvatarList->getSelectedUUIDs(mAvatarSelections);
	resetControls();
}

void FSPanelContactSets::generateAvatarList(const std::string& contact_set)
{
	if (!mAvatarList) return;

	uuid_vec_t& avatars = mAvatarList->getIDs();
	avatars.clear();
	if (contact_set == getString("no_sets"))
	{

	}
	//else if (contact_set == "Friends")
	//{
	//	LLAvatarTracker::buddy_map_t buddies;
	//	LLAvatarTracker::instance().copyBuddyList(buddies);
	//	LLAvatarTracker::buddy_map_t::const_iterator buddy = buddies.begin();
	//	for (; buddy != buddies.end(); ++buddy)
	//	{
	//		avatars.push_back(buddy->first);
	//	}
	//}
	else
	{
		LGGContactSets::ContactSetGroup* group = LGGContactSets::getInstance()->getGroup(contact_set);	// UGLY!
		BOOST_FOREACH(const LLUUID id, group->mFriends)
		{
			avatars.push_back(id);
		}
	}
	mAvatarList->setDirty();
	resetControls();
}

void FSPanelContactSets::resetControls()
{
	bool has_sets = (!LGGContactSets::getInstance()->getAllGroups().empty());
	bool has_selection = mAvatarSelections.size();
	childSetEnabled("remove_set_btn", has_sets);
	childSetEnabled("config_btn", has_sets);
	childSetEnabled("add_btn", has_sets);
	childSetEnabled("remove_btn", (has_sets && has_selection));
	childSetEnabled("profile_btn", has_selection);
	childSetEnabled("start_im_btn", has_selection);
	childSetEnabled("offer_teleport_btn", has_selection);	// Should probably check if they're online...
}

void FSPanelContactSets::updateSets(LGGContactSets::EContactSetUpdate type)
{
	switch (type)
	{
		case LGGContactSets::UPDATED_LISTS:
			refreshContactSets();
			break;
		case LGGContactSets::UPDATED_MEMBERS:
			refreshSetList();
			break;
	}
}

void FSPanelContactSets::refreshContactSets()
{
	if (!mContactSetCombo) return;

	mContactSetCombo->clearRows();
	std::vector<std::string> contact_sets = LGGContactSets::getInstance()->getAllGroups();
	if (!contact_sets.empty())
	{
		BOOST_FOREACH(const std::string& set_name, contact_sets)
		{
			mContactSetCombo->add(set_name);
		}
	}
	else
	{
		mContactSetCombo->add(getString("no_sets"), LLSD("No Set"));
	}
	// This only gets enabled for testing.
	//mContactSetCombo->add(LLTrans::getString("InvFolder Friends"), LLSD("Friends"), ADD_TOP);
	resetControls();
}

void FSPanelContactSets::refreshSetList()
{
	generateAvatarList(mContactSetCombo->getSimple());
	resetControls();
}

void FSPanelContactSets::onClickAddAvatar()
{
	LLFloater* root_floater = gFloaterView->getParentFloater(this);
	LLFloater* avatar_picker = LLFloaterAvatarPicker::show(boost::bind(&FSPanelContactSets::handlePickerCallback, this, _1, mContactSetCombo->getSimple()),
														   TRUE, TRUE, TRUE, root_floater->getName());
	if (root_floater && avatar_picker)
		root_floater->addDependentFloater(avatar_picker);
}

void FSPanelContactSets::handlePickerCallback(const uuid_vec_t& ids, const std::string& set)
{
	if (ids.empty() || !mContactSetCombo) return;

	BOOST_FOREACH(const LLUUID& id, ids)
	{
		if (!LLAvatarTracker::instance().isBuddy(id))
			LGGContactSets::getInstance()->addNonFriendToList(id);
		LGGContactSets::getInstance()->addFriendToGroup(id, set);
	}
}

void FSPanelContactSets::onClickRemoveAvatar()
{
	if (!(mAvatarList && mContactSetCombo)) return;

	std::string set = mContactSetCombo->getSimple();
	BOOST_FOREACH(const LLUUID& id, mAvatarSelections)
	{
		LGGContactSets::getInstance()->removeFriendFromGroup(id, set);
		if (!LLAvatarTracker::instance().isBuddy(id) && LGGContactSets::getInstance()->getFriendGroups(id).size() > 1)
			LGGContactSets::getInstance()->removeNonFriendFromList(id);
	}
}

void FSPanelContactSets::onClickAddSet()
{
	LLNotificationsUtil::add("AddNewContactSet", LLSD(), LLSD(), &handleAddContactSetCallback);
}

void FSPanelContactSets::onClickRemoveSet()
{
	LLSD payload, args;
	std::string set = mContactSetCombo->getSimple();
	args["SET_NAME"] = set;
	payload["contact_set"] = set;
	LLNotificationsUtil::add("RemoveContactSet", args, payload, &handleRemoveContactSetCallback);
}

void FSPanelContactSets::onClickConfigureSet()
{
	LLFloater* root_floater = gFloaterView->getParentFloater(this);
	LLFloater* config_floater = LLFloaterReg::showInstance("fs_contact_set_config", LLSD(mContactSetCombo->getSimple()));
	if (root_floater && config_floater)
		root_floater->addDependentFloater(config_floater);
}

void FSPanelContactSets::onClickOpenProfile()
{
	BOOST_FOREACH(const LLUUID& id, mAvatarSelections)
	{
		LLAvatarActions::showProfile(id);
	}
}

void FSPanelContactSets::onClickStartIM()
{
	if ( mAvatarSelections.size() == 1 )
	{
		LLAvatarActions::startIM(mAvatarSelections[0]);
	}
	else if ( mAvatarSelections.size() > 1 )
	{
		LLAvatarActions::startConference(mAvatarSelections);
	}
}

void FSPanelContactSets::onClickOfferTeleport()
{
	LLAvatarActions::offerTeleport(mAvatarSelections);
}

////////////////////
// Static methods //
////////////////////

// static
bool FSPanelContactSets::handleAddContactSetCallback(const LLSD& notification, const LLSD& response)
{
	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
	if (option == 0)
	{
		std::string set_name = response["message"].asString();
		LGGContactSets::getInstance()->addGroup(set_name);
	}
	return false;
}

// static
bool FSPanelContactSets::handleRemoveContactSetCallback(const LLSD& notification, const LLSD& response)
{
	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
	if (option == 0)
	{
		LGGContactSets::getInstance()->deleteGroup(notification["payload"]["contact_set"].asString());
	}
	return false;
}
<commit_msg>Refresh the list when we refresh the contact sets<commit_after>/*
 * @file fspanelcontactsets.cpp
 * @brief Contact sets UI
 *
 * (C) 2013 Cinder Roxley @ Second Life <cinder.roxley@phoenixviewer.com>
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include "llviewerprecompiledheaders.h"

#include "llnotificationsutil.h"

#include "fspanelcontactsets.h"
#include "fscontactsfloater.h"
#include "llavataractions.h"
#include "llcallingcard.h"
#include "llfloateravatarpicker.h"
#include "llfloaterreg.h"
#include "llslurl.h"
#include "lltrans.h"

#include <boost/foreach.hpp>

static LLRegisterPanelClassWrapper<FSPanelContactSets> t_panel_contact_sets("contact_sets_panel");

FSPanelContactSets::FSPanelContactSets() : LLPanel()
, mContactSetCombo(NULL)
, mAvatarList(NULL)
{
	mContactSetChangedConnection = LGGContactSets::getInstance()->setContactSetChangeCallback(boost::bind(&FSPanelContactSets::updateSets, this, _1));
}

FSPanelContactSets::~FSPanelContactSets()
{
	if (mContactSetChangedConnection.connected())
		mContactSetChangedConnection.disconnect();
}

BOOL FSPanelContactSets::postBuild()
{
	childSetAction("add_set_btn",			boost::bind(&FSPanelContactSets::onClickAddSet,			this));
	childSetAction("remove_set_btn",		boost::bind(&FSPanelContactSets::onClickRemoveSet,		this));
	childSetAction("config_btn",			boost::bind(&FSPanelContactSets::onClickConfigureSet,	this));
	childSetAction("add_btn",				boost::bind(&FSPanelContactSets::onClickAddAvatar,		this));
	childSetAction("remove_btn",			boost::bind(&FSPanelContactSets::onClickRemoveAvatar,	this));
	childSetAction("profile_btn",			boost::bind(&FSPanelContactSets::onClickOpenProfile,	this));
	childSetAction("start_im_btn",			boost::bind(&FSPanelContactSets::onClickStartIM,		this));
	childSetAction("offer_teleport_btn",	boost::bind(&FSPanelContactSets::onClickOfferTeleport,	this));

	mContactSetCombo = getChild<LLComboBox>("combo_sets");
	if (mContactSetCombo)
	{
		mContactSetCombo->setCommitCallback(boost::bind(&FSPanelContactSets::refreshSetList, this));
		refreshContactSets();
	}

	mAvatarList = getChild<LLAvatarList>("contact_list");
	if (mAvatarList)
	{
		mAvatarList->setCommitCallback(boost::bind(&FSPanelContactSets::onSelectAvatar, this));
		mAvatarList->setNoItemsCommentText(getString("empty_list"));
		generateAvatarList(mContactSetCombo->getSimple());
	}

	return TRUE;
}

void FSPanelContactSets::onSelectAvatar()
{
	mAvatarSelections.clear();
	mAvatarList->getSelectedUUIDs(mAvatarSelections);
	resetControls();
}

void FSPanelContactSets::generateAvatarList(const std::string& contact_set)
{
	if (!mAvatarList) return;

	uuid_vec_t& avatars = mAvatarList->getIDs();
	avatars.clear();
	if (contact_set == getString("no_sets"))
	{

	}
	//else if (contact_set == "Friends")
	//{
	//	LLAvatarTracker::buddy_map_t buddies;
	//	LLAvatarTracker::instance().copyBuddyList(buddies);
	//	LLAvatarTracker::buddy_map_t::const_iterator buddy = buddies.begin();
	//	for (; buddy != buddies.end(); ++buddy)
	//	{
	//		avatars.push_back(buddy->first);
	//	}
	//}
	else
	{
		LGGContactSets::ContactSetGroup* group = LGGContactSets::getInstance()->getGroup(contact_set);	// UGLY!
		BOOST_FOREACH(const LLUUID id, group->mFriends)
		{
			avatars.push_back(id);
		}
	}
	mAvatarList->setDirty();
	resetControls();
}

void FSPanelContactSets::resetControls()
{
	bool has_sets = (!LGGContactSets::getInstance()->getAllGroups().empty());
	bool has_selection = mAvatarSelections.size();
	childSetEnabled("remove_set_btn", has_sets);
	childSetEnabled("config_btn", has_sets);
	childSetEnabled("add_btn", has_sets);
	childSetEnabled("remove_btn", (has_sets && has_selection));
	childSetEnabled("profile_btn", has_selection);
	childSetEnabled("start_im_btn", has_selection);
	childSetEnabled("offer_teleport_btn", has_selection);	// Should probably check if they're online...
}

void FSPanelContactSets::updateSets(LGGContactSets::EContactSetUpdate type)
{
	switch (type)
	{
		case LGGContactSets::UPDATED_LISTS:
			refreshContactSets();
		case LGGContactSets::UPDATED_MEMBERS:
			refreshSetList();
			break;
	}
}

void FSPanelContactSets::refreshContactSets()
{
	if (!mContactSetCombo) return;

	mContactSetCombo->clearRows();
	std::vector<std::string> contact_sets = LGGContactSets::getInstance()->getAllGroups();
	if (!contact_sets.empty())
	{
		BOOST_FOREACH(const std::string& set_name, contact_sets)
		{
			mContactSetCombo->add(set_name);
		}
	}
	else
	{
		mContactSetCombo->add(getString("no_sets"), LLSD("No Set"));
	}
	// This only gets enabled for testing.
	//mContactSetCombo->add(LLTrans::getString("InvFolder Friends"), LLSD("Friends"), ADD_TOP);
	resetControls();
}

void FSPanelContactSets::refreshSetList()
{
	generateAvatarList(mContactSetCombo->getSimple());
	resetControls();
}

void FSPanelContactSets::onClickAddAvatar()
{
	LLFloater* root_floater = gFloaterView->getParentFloater(this);
	LLFloater* avatar_picker = LLFloaterAvatarPicker::show(boost::bind(&FSPanelContactSets::handlePickerCallback, this, _1, mContactSetCombo->getSimple()),
														   TRUE, TRUE, TRUE, root_floater->getName());
	if (root_floater && avatar_picker)
		root_floater->addDependentFloater(avatar_picker);
}

void FSPanelContactSets::handlePickerCallback(const uuid_vec_t& ids, const std::string& set)
{
	if (ids.empty() || !mContactSetCombo) return;

	BOOST_FOREACH(const LLUUID& id, ids)
	{
		if (!LLAvatarTracker::instance().isBuddy(id))
			LGGContactSets::getInstance()->addNonFriendToList(id);
		LGGContactSets::getInstance()->addFriendToGroup(id, set);
	}
}

void FSPanelContactSets::onClickRemoveAvatar()
{
	if (!(mAvatarList && mContactSetCombo)) return;

	std::string set = mContactSetCombo->getSimple();
	BOOST_FOREACH(const LLUUID& id, mAvatarSelections)
	{
		LGGContactSets::getInstance()->removeFriendFromGroup(id, set);
		if (!LLAvatarTracker::instance().isBuddy(id) && LGGContactSets::getInstance()->getFriendGroups(id).size() > 1)
			LGGContactSets::getInstance()->removeNonFriendFromList(id);
	}
}

void FSPanelContactSets::onClickAddSet()
{
	LLNotificationsUtil::add("AddNewContactSet", LLSD(), LLSD(), &handleAddContactSetCallback);
}

void FSPanelContactSets::onClickRemoveSet()
{
	LLSD payload, args;
	std::string set = mContactSetCombo->getSimple();
	args["SET_NAME"] = set;
	payload["contact_set"] = set;
	LLNotificationsUtil::add("RemoveContactSet", args, payload, &handleRemoveContactSetCallback);
}

void FSPanelContactSets::onClickConfigureSet()
{
	LLFloater* root_floater = gFloaterView->getParentFloater(this);
	LLFloater* config_floater = LLFloaterReg::showInstance("fs_contact_set_config", LLSD(mContactSetCombo->getSimple()));
	if (root_floater && config_floater)
		root_floater->addDependentFloater(config_floater);
}

void FSPanelContactSets::onClickOpenProfile()
{
	BOOST_FOREACH(const LLUUID& id, mAvatarSelections)
	{
		LLAvatarActions::showProfile(id);
	}
}

void FSPanelContactSets::onClickStartIM()
{
	if ( mAvatarSelections.size() == 1 )
	{
		LLAvatarActions::startIM(mAvatarSelections[0]);
	}
	else if ( mAvatarSelections.size() > 1 )
	{
		LLAvatarActions::startConference(mAvatarSelections);
	}
}

void FSPanelContactSets::onClickOfferTeleport()
{
	LLAvatarActions::offerTeleport(mAvatarSelections);
}

////////////////////
// Static methods //
////////////////////

// static
bool FSPanelContactSets::handleAddContactSetCallback(const LLSD& notification, const LLSD& response)
{
	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
	if (option == 0)
	{
		std::string set_name = response["message"].asString();
		LGGContactSets::getInstance()->addGroup(set_name);
	}
	return false;
}

// static
bool FSPanelContactSets::handleRemoveContactSetCallback(const LLSD& notification, const LLSD& response)
{
	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
	if (option == 0)
	{
		LGGContactSets::getInstance()->deleteGroup(notification["payload"]["contact_set"].asString());
	}
	return false;
}
<|endoftext|>


<commit_before>//===--- Heap.cpp - Swift Language Heap Logic -----------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Implementations of the Swift heap
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Heap.h"
#include "Private.h"
#include <stdio.h>
#include <stdlib.h>
#include <cassert>
#include <pthread.h>

using namespace swift;

__attribute__((visibility("hidden")))
malloc_zone_t _swift_zone = {
  NULL, // ignore -- for CF
  NULL, // ignore -- for CF
  _swift_zone_size,
  _swift_zone_malloc,
  _swift_zone_calloc,
  _swift_zone_valloc,
  _swift_zone_free,
  _swift_zone_realloc,
  _swift_zone_destroy,
  "SwiftZone", // name
  NULL, // optional batch malloc
  NULL, // optional batch free
  NULL, // FIXME -- struct malloc_introspection_t *
  0, // version
  NULL, // XXX -- add support for memalign and free_definite_size?
  NULL, // XXX -- add support for memalign and free_definite_size?
  NULL, // XXX -- add support for pressure_relief?
};

extern "C" pthread_key_t _swift_alloc_offset = -1;

__attribute__((constructor))
static void registerZone() {
  assert(sizeof(pthread_key_t) == sizeof(long));
  malloc_zone_register(&_swift_zone);
  pthread_key_t key, prev_key;
  int r = pthread_key_create(&key, NULL);
  assert(r == 0);
  (void)r;
  prev_key = key;
  _swift_alloc_offset = key;
  for (unsigned i = 0; i < 64; i++) {
    int r = pthread_key_create(&key, NULL);
    assert(r == 0);
    (void)r;
    assert(key == prev_key + 1);
    prev_key = key;
  }
}

size_t swift::_swift_zone_size(malloc_zone_t *zone, const void *pointer) {
  return malloc_size(pointer);
}

void *swift::_swift_zone_malloc(malloc_zone_t *zone, size_t size) {
  return malloc(size);
}

void *swift::_swift_zone_calloc(malloc_zone_t *zone,
                                size_t count, size_t size) {
  return calloc(count, size);
}

void *swift::_swift_zone_valloc(malloc_zone_t *zone, size_t size) {
  return valloc(size);
}

void swift::_swift_zone_free(malloc_zone_t *zone, void *pointer) {
  return free(pointer);
}

void *swift::_swift_zone_realloc(malloc_zone_t *zone,
                                 void *pointer, size_t size) {
  return realloc(pointer, size);
}

void swift::_swift_zone_destroy(malloc_zone_t *zone) {
  // nobody should ever destroy this zone
  abort();
}

// Plain old memory allocation

__attribute__((noinline,used))
static void *
_swift_alloc_slow(AllocIndex idx, uintptr_t flags)
{
  size_t sz;

  idx++;

  // we could do a table based lookup if we think it worthwhile
#ifdef __LP64__
  if        (idx <= 16) { sz =  idx       << 3;
  } else if (idx <= 24) { sz = (idx -  8) << 4;
  } else if (idx <= 32) { sz = (idx - 16) << 5;
  } else if (idx <= 40) { sz = (idx - 24) << 6;
  } else if (idx <= 48) { sz = (idx - 32) << 7;
  } else if (idx <= 56) { sz = (idx - 40) << 8;
#else
  if        (idx <= 16) { sz =  idx       << 2;
  } else if (idx <= 24) { sz = (idx -  8) << 3;
  } else if (idx <= 32) { sz = (idx - 16) << 4;
  } else if (idx <= 40) { sz = (idx - 24) << 5;
  } else if (idx <= 48) { sz = (idx - 32) << 6;
  } else if (idx <= 56) { sz = (idx - 40) << 7;
  } else if (idx <= 64) { sz = (idx - 48) << 8;
#endif
  } else {
    __builtin_trap();
  }

  void *r;
  do {
    if (flags & SWIFT_RAWALLOC) {
      r = _swift_zone.malloc(NULL, sz);
    } else {
      r = _swift_zone.calloc(NULL, 1, sz);
    }
  } while (!r && !(flags & SWIFT_TRYALLOC));

  return r;
}

extern "C" LLVM_LIBRARY_VISIBILITY
void _swift_refillThreadAllocCache(AllocIndex idx, uintptr_t flags) {
  void *tmp = _swift_alloc_slow(idx, flags);
  if (!tmp) {
    return;
  }
  assert(flags & SWIFT_RAWALLOC);
  swift_rawDealloc(tmp, idx);
}

void *swift::swift_slowAlloc(size_t size, uintptr_t flags) {
  size_t idx = SIZE_MAX;
  if (size == 0) idx = 0;
  --size;
  // we could do a table based lookup if we think it worthwhile
#ifdef __LP64__
  if      (size <   0x80) idx = (size >> 3) +  0x0;
  else if (size <  0x100) idx = (size >> 4) +  0x8;
  else if (size <  0x200) idx = (size >> 5) + 0x10;
  else if (size <  0x400) idx = (size >> 6) + 0x18;
  else if (size <  0x800) idx = (size >> 7) + 0x20;
  else if (size < 0x1000) idx = (size >> 8) + 0x28;
#else
  if      (size <   0x40) idx = (size >> 2) +  0x0;
  else if (size <   0x80) idx = (size >> 3) +  0x8;
  else if (size <  0x100) idx = (size >> 4) + 0x10;
  else if (size <  0x200) idx = (size >> 5) + 0x18;
  else if (size <  0x400) idx = (size >> 6) + 0x20;
  else if (size <  0x800) idx = (size >> 7) + 0x28;
  else if (size < 0x1000) idx = (size >> 8) + 0x30;
#endif

  void *r;
  if (idx != SIZE_MAX) {
    assert(flags & SWIFT_RAWALLOC);
    r = swift_tryRawAlloc(idx);
    if (r) return r;
  }

  do {
    if (flags & SWIFT_RAWALLOC) {
      r = _swift_zone.malloc(NULL, size);
    } else {
      r = _swift_zone.calloc(NULL, 1, size);
    }
  } while (!r && !(flags & SWIFT_TRYALLOC));

  return r;
}

// These are implemented in FastEntryPoints.s on some platforms.
#ifndef SWIFT_HAVE_FAST_ENTRY_POINTS

#if __has_include(<os/tsd.h>)
// OS X and iOS internal version

#include <os/tsd.h>

struct AllocCacheEntry {
  struct AllocCacheEntry *next;
};

static AllocCacheEntry *
getAllocCacheEntry(unsigned long idx) {
  assert(idx < ALLOC_CACHE_COUNT);
  return (AllocCacheEntry *)_os_tsd_get_direct(idx + _swift_alloc_offset);
}

static void
setAllocCacheEntry(unsigned long idx, AllocCacheEntry *entry) {
  assert(idx < ALLOC_CACHE_COUNT);
  _os_tsd_set_direct(idx + _swift_alloc_offset, entry);
}

static AllocCacheEntry *
getRawAllocCacheEntry(unsigned long idx) {
  assert(idx < ALLOC_CACHE_COUNT);
  return (AllocCacheEntry *)_os_tsd_get_direct(idx + _swift_alloc_offset);
}

static void
setRawAllocCacheEntry(unsigned long idx, AllocCacheEntry *entry) {
  assert(idx < ALLOC_CACHE_COUNT);
  _os_tsd_set_direct(idx + _swift_alloc_offset, entry);
}

void *swift::swift_rawAlloc(AllocIndex idx) {
  AllocCacheEntry *r = getRawAllocCacheEntry(idx);
  if (r) {
    setRawAllocCacheEntry(idx, r->next);
    return r;
  }
  return _swift_alloc_slow(idx, SWIFT_RAWALLOC);
}

void *swift::swift_tryRawAlloc(AllocIndex idx) {
  AllocCacheEntry *r = getRawAllocCacheEntry(idx);
  if (r) {
    setRawAllocCacheEntry(idx, r->next);
    return r;
  }
  return _swift_alloc_slow(idx, SWIFT_TRYALLOC|SWIFT_RAWALLOC);
}

void swift::swift_rawDealloc(void *ptr, AllocIndex idx) {
  auto cur = static_cast<AllocCacheEntry *>(ptr);
  AllocCacheEntry *prev = getRawAllocCacheEntry(idx);
  cur->next = prev;
  setRawAllocCacheEntry(idx, cur);
}

#else

# error no thread-local cache implementation for this platform

#endif

// !SWIFT_HAVE_FAST_ENTRY_POINTS
#endif

void swift::swift_slowDealloc(void *ptr, size_t bytes) {
  if (bytes == 0) {
    bytes = malloc_size(ptr);
  }

  bytes--;

  AllocIndex idx;
#ifdef __LP64__
  if        (bytes < 0x80)   { idx = (bytes >> 3);
  } else if (bytes < 0x100)  { idx = (bytes >> 4) + 0x8;
  } else if (bytes < 0x200)  { idx = (bytes >> 5) + 0x10;
  } else if (bytes < 0x400)  { idx = (bytes >> 6) + 0x18;
  } else if (bytes < 0x800)  { idx = (bytes >> 7) + 0x20;
  } else if (bytes < 0x1000) { idx = (bytes >> 8) + 0x28;
#else
  if        (bytes < 0x40)   { idx = (bytes >> 2);
  } else if (bytes < 0x80)   { idx = (bytes >> 3) + 0x8;
  } else if (bytes < 0x100)  { idx = (bytes >> 4) + 0x10;
  } else if (bytes < 0x200)  { idx = (bytes >> 5) + 0x18;
  } else if (bytes < 0x400)  { idx = (bytes >> 6) + 0x20;
  } else if (bytes < 0x800)  { idx = (bytes >> 7) + 0x28;
  } else if (bytes < 0x1000) { idx = (bytes >> 8) + 0x30;
#endif
  } else { return free(ptr);
  }

  swift_rawDealloc(ptr, idx);
}

void swift::swift_slowRawDealloc(void *ptr, size_t bytes) {
  AllocIndex idx;

  if (bytes == 0) {
    // the caller either doesn't know the size
    // or the caller really does think the size is zero
    // in any case, punt!
    return free(ptr);
  }

  bytes--;

#ifdef __LP64__
  if        (bytes < 0x80)   { idx = (bytes >> 3);
  } else if (bytes < 0x100)  { idx = (bytes >> 4) + 0x8;
  } else if (bytes < 0x200)  { idx = (bytes >> 5) + 0x10;
  } else if (bytes < 0x400)  { idx = (bytes >> 6) + 0x18;
  } else if (bytes < 0x800)  { idx = (bytes >> 7) + 0x20;
  } else if (bytes < 0x1000) { idx = (bytes >> 8) + 0x28;
#else
  if        (bytes < 0x40)   { idx = (bytes >> 2);
  } else if (bytes < 0x80)   { idx = (bytes >> 3) + 0x8;
  } else if (bytes < 0x100)  { idx = (bytes >> 4) + 0x10;
  } else if (bytes < 0x200)  { idx = (bytes >> 5) + 0x18;
  } else if (bytes < 0x400)  { idx = (bytes >> 6) + 0x20;
  } else if (bytes < 0x800)  { idx = (bytes >> 7) + 0x28;
  } else if (bytes < 0x1000) { idx = (bytes >> 8) + 0x30;
#endif
  } else { return free(ptr);
  }

  swift_rawDealloc(ptr, idx);
}
<commit_msg>stdlib: do not forward malloc_size()<commit_after>//===--- Heap.cpp - Swift Language Heap Logic -----------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Implementations of the Swift heap
//
//===----------------------------------------------------------------------===//

#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Heap.h"
#include "Private.h"
#include <stdio.h>
#include <stdlib.h>
#include <cassert>
#include <pthread.h>

using namespace swift;

__attribute__((visibility("hidden")))
malloc_zone_t _swift_zone = {
  NULL, // ignore -- for CF
  NULL, // ignore -- for CF
  _swift_zone_size,
  _swift_zone_malloc,
  _swift_zone_calloc,
  _swift_zone_valloc,
  _swift_zone_free,
  _swift_zone_realloc,
  _swift_zone_destroy,
  "SwiftZone", // name
  NULL, // optional batch malloc
  NULL, // optional batch free
  NULL, // FIXME -- struct malloc_introspection_t *
  0, // version
  NULL, // XXX -- add support for memalign and free_definite_size?
  NULL, // XXX -- add support for memalign and free_definite_size?
  NULL, // XXX -- add support for pressure_relief?
};

extern "C" pthread_key_t _swift_alloc_offset = -1;

__attribute__((constructor))
static void registerZone() {
  assert(sizeof(pthread_key_t) == sizeof(long));
  malloc_zone_register(&_swift_zone);
  pthread_key_t key, prev_key;
  int r = pthread_key_create(&key, NULL);
  assert(r == 0);
  (void)r;
  prev_key = key;
  _swift_alloc_offset = key;
  for (unsigned i = 0; i < 64; i++) {
    int r = pthread_key_create(&key, NULL);
    assert(r == 0);
    (void)r;
    assert(key == prev_key + 1);
    prev_key = key;
  }
}

size_t swift::_swift_zone_size(malloc_zone_t *zone, const void *pointer) {
  return 0;
}

void *swift::_swift_zone_malloc(malloc_zone_t *zone, size_t size) {
  return malloc(size);
}

void *swift::_swift_zone_calloc(malloc_zone_t *zone,
                                size_t count, size_t size) {
  return calloc(count, size);
}

void *swift::_swift_zone_valloc(malloc_zone_t *zone, size_t size) {
  return valloc(size);
}

void swift::_swift_zone_free(malloc_zone_t *zone, void *pointer) {
  return free(pointer);
}

void *swift::_swift_zone_realloc(malloc_zone_t *zone,
                                 void *pointer, size_t size) {
  return realloc(pointer, size);
}

void swift::_swift_zone_destroy(malloc_zone_t *zone) {
  // nobody should ever destroy this zone
  abort();
}

// Plain old memory allocation

__attribute__((noinline,used))
static void *
_swift_alloc_slow(AllocIndex idx, uintptr_t flags)
{
  size_t sz;

  idx++;

  // we could do a table based lookup if we think it worthwhile
#ifdef __LP64__
  if        (idx <= 16) { sz =  idx       << 3;
  } else if (idx <= 24) { sz = (idx -  8) << 4;
  } else if (idx <= 32) { sz = (idx - 16) << 5;
  } else if (idx <= 40) { sz = (idx - 24) << 6;
  } else if (idx <= 48) { sz = (idx - 32) << 7;
  } else if (idx <= 56) { sz = (idx - 40) << 8;
#else
  if        (idx <= 16) { sz =  idx       << 2;
  } else if (idx <= 24) { sz = (idx -  8) << 3;
  } else if (idx <= 32) { sz = (idx - 16) << 4;
  } else if (idx <= 40) { sz = (idx - 24) << 5;
  } else if (idx <= 48) { sz = (idx - 32) << 6;
  } else if (idx <= 56) { sz = (idx - 40) << 7;
  } else if (idx <= 64) { sz = (idx - 48) << 8;
#endif
  } else {
    __builtin_trap();
  }

  void *r;
  do {
    if (flags & SWIFT_RAWALLOC) {
      r = _swift_zone.malloc(NULL, sz);
    } else {
      r = _swift_zone.calloc(NULL, 1, sz);
    }
  } while (!r && !(flags & SWIFT_TRYALLOC));

  return r;
}

extern "C" LLVM_LIBRARY_VISIBILITY
void _swift_refillThreadAllocCache(AllocIndex idx, uintptr_t flags) {
  void *tmp = _swift_alloc_slow(idx, flags);
  if (!tmp) {
    return;
  }
  assert(flags & SWIFT_RAWALLOC);
  swift_rawDealloc(tmp, idx);
}

void *swift::swift_slowAlloc(size_t size, uintptr_t flags) {
  size_t idx = SIZE_MAX;
  if (size == 0) idx = 0;
  --size;
  // we could do a table based lookup if we think it worthwhile
#ifdef __LP64__
  if      (size <   0x80) idx = (size >> 3) +  0x0;
  else if (size <  0x100) idx = (size >> 4) +  0x8;
  else if (size <  0x200) idx = (size >> 5) + 0x10;
  else if (size <  0x400) idx = (size >> 6) + 0x18;
  else if (size <  0x800) idx = (size >> 7) + 0x20;
  else if (size < 0x1000) idx = (size >> 8) + 0x28;
#else
  if      (size <   0x40) idx = (size >> 2) +  0x0;
  else if (size <   0x80) idx = (size >> 3) +  0x8;
  else if (size <  0x100) idx = (size >> 4) + 0x10;
  else if (size <  0x200) idx = (size >> 5) + 0x18;
  else if (size <  0x400) idx = (size >> 6) + 0x20;
  else if (size <  0x800) idx = (size >> 7) + 0x28;
  else if (size < 0x1000) idx = (size >> 8) + 0x30;
#endif

  void *r;
  if (idx != SIZE_MAX) {
    assert(flags & SWIFT_RAWALLOC);
    r = swift_tryRawAlloc(idx);
    if (r) return r;
  }

  do {
    if (flags & SWIFT_RAWALLOC) {
      r = _swift_zone.malloc(NULL, size);
    } else {
      r = _swift_zone.calloc(NULL, 1, size);
    }
  } while (!r && !(flags & SWIFT_TRYALLOC));

  return r;
}

// These are implemented in FastEntryPoints.s on some platforms.
#ifndef SWIFT_HAVE_FAST_ENTRY_POINTS

#if __has_include(<os/tsd.h>)
// OS X and iOS internal version

#include <os/tsd.h>

struct AllocCacheEntry {
  struct AllocCacheEntry *next;
};

static AllocCacheEntry *
getAllocCacheEntry(unsigned long idx) {
  assert(idx < ALLOC_CACHE_COUNT);
  return (AllocCacheEntry *)_os_tsd_get_direct(idx + _swift_alloc_offset);
}

static void
setAllocCacheEntry(unsigned long idx, AllocCacheEntry *entry) {
  assert(idx < ALLOC_CACHE_COUNT);
  _os_tsd_set_direct(idx + _swift_alloc_offset, entry);
}

static AllocCacheEntry *
getRawAllocCacheEntry(unsigned long idx) {
  assert(idx < ALLOC_CACHE_COUNT);
  return (AllocCacheEntry *)_os_tsd_get_direct(idx + _swift_alloc_offset);
}

static void
setRawAllocCacheEntry(unsigned long idx, AllocCacheEntry *entry) {
  assert(idx < ALLOC_CACHE_COUNT);
  _os_tsd_set_direct(idx + _swift_alloc_offset, entry);
}

void *swift::swift_rawAlloc(AllocIndex idx) {
  AllocCacheEntry *r = getRawAllocCacheEntry(idx);
  if (r) {
    setRawAllocCacheEntry(idx, r->next);
    return r;
  }
  return _swift_alloc_slow(idx, SWIFT_RAWALLOC);
}

void *swift::swift_tryRawAlloc(AllocIndex idx) {
  AllocCacheEntry *r = getRawAllocCacheEntry(idx);
  if (r) {
    setRawAllocCacheEntry(idx, r->next);
    return r;
  }
  return _swift_alloc_slow(idx, SWIFT_TRYALLOC|SWIFT_RAWALLOC);
}

void swift::swift_rawDealloc(void *ptr, AllocIndex idx) {
  auto cur = static_cast<AllocCacheEntry *>(ptr);
  AllocCacheEntry *prev = getRawAllocCacheEntry(idx);
  cur->next = prev;
  setRawAllocCacheEntry(idx, cur);
}

#else

# error no thread-local cache implementation for this platform

#endif

// !SWIFT_HAVE_FAST_ENTRY_POINTS
#endif

void swift::swift_slowDealloc(void *ptr, size_t bytes) {
  if (bytes == 0) {
    bytes = malloc_size(ptr);
  }

  bytes--;

  AllocIndex idx;
#ifdef __LP64__
  if        (bytes < 0x80)   { idx = (bytes >> 3);
  } else if (bytes < 0x100)  { idx = (bytes >> 4) + 0x8;
  } else if (bytes < 0x200)  { idx = (bytes >> 5) + 0x10;
  } else if (bytes < 0x400)  { idx = (bytes >> 6) + 0x18;
  } else if (bytes < 0x800)  { idx = (bytes >> 7) + 0x20;
  } else if (bytes < 0x1000) { idx = (bytes >> 8) + 0x28;
#else
  if        (bytes < 0x40)   { idx = (bytes >> 2);
  } else if (bytes < 0x80)   { idx = (bytes >> 3) + 0x8;
  } else if (bytes < 0x100)  { idx = (bytes >> 4) + 0x10;
  } else if (bytes < 0x200)  { idx = (bytes >> 5) + 0x18;
  } else if (bytes < 0x400)  { idx = (bytes >> 6) + 0x20;
  } else if (bytes < 0x800)  { idx = (bytes >> 7) + 0x28;
  } else if (bytes < 0x1000) { idx = (bytes >> 8) + 0x30;
#endif
  } else { return free(ptr);
  }

  swift_rawDealloc(ptr, idx);
}

void swift::swift_slowRawDealloc(void *ptr, size_t bytes) {
  AllocIndex idx;

  if (bytes == 0) {
    // the caller either doesn't know the size
    // or the caller really does think the size is zero
    // in any case, punt!
    return free(ptr);
  }

  bytes--;

#ifdef __LP64__
  if        (bytes < 0x80)   { idx = (bytes >> 3);
  } else if (bytes < 0x100)  { idx = (bytes >> 4) + 0x8;
  } else if (bytes < 0x200)  { idx = (bytes >> 5) + 0x10;
  } else if (bytes < 0x400)  { idx = (bytes >> 6) + 0x18;
  } else if (bytes < 0x800)  { idx = (bytes >> 7) + 0x20;
  } else if (bytes < 0x1000) { idx = (bytes >> 8) + 0x28;
#else
  if        (bytes < 0x40)   { idx = (bytes >> 2);
  } else if (bytes < 0x80)   { idx = (bytes >> 3) + 0x8;
  } else if (bytes < 0x100)  { idx = (bytes >> 4) + 0x10;
  } else if (bytes < 0x200)  { idx = (bytes >> 5) + 0x18;
  } else if (bytes < 0x400)  { idx = (bytes >> 6) + 0x20;
  } else if (bytes < 0x800)  { idx = (bytes >> 7) + 0x28;
  } else if (bytes < 0x1000) { idx = (bytes >> 8) + 0x30;
#endif
  } else { return free(ptr);
  }

  swift_rawDealloc(ptr, idx);
}
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QFileDialog>
#include <QMessageBox>

#include "src/xmlio.hpp"
#include "src/exceptions.hpp"
#include "addsemestredialog.h"
#include "src/dossier.hpp"
#include "choosedossierdialog.h"

#define UVM UvManager::getInstance()

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ioPolicy = 0;
    QMainWindow::showMaximized();
}

MainWindow::~MainWindow() {
    delete ui;
    UvManager::freeInstance();
    FormationManager::freeInstance();
    CategorieUVManager::freeInstance();
    DossierManager::freeInstance();
    NoteUVManager::freeInstance();
}

//! Fonction de chargement du ficher contenant les uvs
void MainWindow::loadFile() {

    QString filename = QFileDialog::getOpenFileName(this, "Ouvrir le fichier");
    if (filename.isNull()) { return; }

    ioPolicy = new XmlIo();
    ioPolicy->setIdentifier(filename);

    try {
        ioPolicy->load();
    } catch(const Exception& e) {
        delete ioPolicy;
        ioPolicy = 0;
        QMessageBox error(this);
        error.setText(e.getinfo());
        error.exec();
        return;
    }

    ui->uvDisplay->refresh();
    ui->noteDisplay->refresh();
    ui->categorieDisplay->refresh();
    ui->formationDisplay->refresh();
}

//! Fonction de sauvegarde du fichier
void MainWindow::saveFile() {
    if (ioPolicy != 0) {
        ioPolicy->save();
    } else {
        QMessageBox error(this);
        error.setText("Aucune donnée chargée");
        error.exec();
        return;
    }
}

void MainWindow::completeDossier() {
    ChooseDossierDialog *dialog = new ChooseDossierDialog(this);
    dialog->exec();
    delete dialog;
}
<commit_msg>Maj des display<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QFileDialog>
#include <QMessageBox>

#include "src/xmlio.hpp"
#include "src/exceptions.hpp"
#include "addsemestredialog.h"
#include "src/dossier.hpp"
#include "choosedossierdialog.h"

#define UVM UvManager::getInstance()

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ioPolicy = 0;
    QMainWindow::showMaximized();
}

MainWindow::~MainWindow() {
    delete ui;
    UvManager::freeInstance();
    FormationManager::freeInstance();
    CategorieUVManager::freeInstance();
    DossierManager::freeInstance();
    NoteUVManager::freeInstance();
}

//! Fonction de chargement du ficher contenant les uvs
void MainWindow::loadFile() {

    QString filename = QFileDialog::getOpenFileName(this, "Ouvrir le fichier");
    if (filename.isNull()) { return; }

    ioPolicy = new XmlIo();
    ioPolicy->setIdentifier(filename);

    try {
        ioPolicy->load();
    } catch(const Exception& e) {
        delete ioPolicy;
        ioPolicy = 0;
        QMessageBox error(this);
        error.setText(e.getinfo());
        error.exec();
        return;
    }

    ui->uvDisplay->refresh();
    ui->noteDisplay->refresh();
    ui->categorieDisplay->refresh();
    ui->formationDisplay->refresh();
    ui->dossierDisplay->refresh();
}

//! Fonction de sauvegarde du fichier
void MainWindow::saveFile() {
    if (ioPolicy != 0) {
        ioPolicy->save();
    } else {
        QMessageBox error(this);
        error.setText("Aucune donnée chargée");
        error.exec();
        return;
    }
}

void MainWindow::completeDossier() {
    ChooseDossierDialog *dialog = new ChooseDossierDialog(this);
    dialog->exec();
    delete dialog;
    ui->dossierDisplay->refresh();
}
<|endoftext|>


<commit_before>#include <qapplication.h>
#include "mitkVolumeDataVtkMapper3D.h"
#include "DataTreeNode.h"
#include "mitkFloatProperty.h"
#include "mitkBoolProperty.h"
#include "mitkColorProperty.h"
#include "mitkOpenGLRenderer.h"
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkVolumeRayCastMapper.h>
#include <vtkVolume.h>
#include <vtkVolumeProperty.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkVolumeRayCastCompositeFunction.h>
#include <vtkFiniteDifferenceGradientEstimator.h>
#include <vtkRenderWindow.h>
#include <vtkCallbackCommand.h>
// extern QApplication* qApp;

const mitk::Image* mitk::VolumeDataVtkMapper3D::GetInput()
{
if (this->GetNumberOfInputs() < 1)
{
return 0;
}

return static_cast<const mitk::Image*> ( GetData() );
}

void mitk::VolumeDataVtkMapper3D::GenerateData()
{

}

void mitk::VolumeDataVtkMapper3D::GenerateOutputInformation()
{
}

mitk::VolumeDataVtkMapper3D::VolumeDataVtkMapper3D()
{
  m_VtkVolumeMapper = vtkVolumeRayCastMapper::New();
  vtkVolumeRayCastCompositeFunction* compositeFunction = vtkVolumeRayCastCompositeFunction::New();
  m_VtkVolumeMapper->SetVolumeRayCastFunction(compositeFunction);
  vtkFiniteDifferenceGradientEstimator* gradientEstimator =
	vtkFiniteDifferenceGradientEstimator::New();
  m_VtkVolumeMapper->SetGradientEstimator(gradientEstimator);
  gradientEstimator->Delete();
  m_Volume = vtkVolume::New();
  m_Volume->SetMapper( m_VtkVolumeMapper );
  m_Prop3D = m_Volume;
  m_Prop3D->Register(NULL);

}

mitk::VolumeDataVtkMapper3D::~VolumeDataVtkMapper3D()
{

}
void mitk::VolumeDataVtkMapper3D::AbortCallback(vtkObject *caller, unsigned long eid, void *clientdata, void *calldata) {
  // std::cout << "abort test called" << std::endl;
  vtkRenderWindow* renWin = dynamic_cast<vtkRenderWindow*>(caller);
  assert(renWin);
  // FIXME: qApp->hasPendingEvents is always true, renWin->GetEventPending is
  // always false. So aborting the render doesn't work this way.

  // if (
  //   qApp->hasPendingEvents()
  // )
  // {
  // std::cout << "setting abort render" << std::endl;
  //   renWin->SetAbortRender(1);
  // }
}

void mitk::VolumeDataVtkMapper3D::Update(mitk::BaseRenderer* renderer)
{
 if(IsVisible(renderer)==false)
  {
//  FIXME: don't understand this
    if (m_Prop3D) {
      std::cout << "visibility off" <<std::endl;
      m_Prop3D->VisibilityOff();
    }
    return;
  }
  if (m_Prop3D) {
    m_Prop3D->VisibilityOn();
  }
  const mitk::Image* img = (GetInput());
  if (img == NULL) {
    itkWarningMacro("Image == NULL")
  } else {
    vtkVolumeProperty* volumeProperty = vtkVolumeProperty::New();
    vtkPiecewiseFunction *opacityTransferFunction, *gradientTransferFunction;
    vtkColorTransferFunction* colorTransferFunction;

    opacityTransferFunction  = vtkPiecewiseFunction::New();
    colorTransferFunction    = vtkColorTransferFunction::New();
    mitk::LevelWindow levelWindow;
    int lw_min,lw_max;
    if (GetLevelWindow(levelWindow,renderer)) {
      lw_min = (int)levelWindow.GetMin();
      lw_max = (int)levelWindow.GetMax();
    } else {
      lw_min = 0;
      lw_max = 255;
    }

    opacityTransferFunction->AddPoint( lw_min, 0.0 );
    opacityTransferFunction->AddPoint( lw_max, 0.9 );
    opacityTransferFunction->ClampingOff();

    colorTransferFunction->AddRGBPoint( lw_min, 1.0, 1.0, 1.0 );
    colorTransferFunction->AddRGBPoint( lw_max, 1.0, 1.0, 1.0 );
    colorTransferFunction->ClampingOff();

    volumeProperty->SetColor( colorTransferFunction );
    volumeProperty->SetScalarOpacity( opacityTransferFunction );
    volumeProperty->ShadeOn();
    volumeProperty->SetDiffuse(0.7);
    volumeProperty->SetAmbient(0.01);

    m_Volume = vtkVolume::New();
    // FIXME: const_cast; maybe GetVtkImageData can be made const by using volatile
    m_VtkVolumeMapper->SetInput(const_cast<mitk::Image*>(img)->GetVtkImageData());
    m_Volume->SetMapper( m_VtkVolumeMapper );
    m_Volume->SetProperty(volumeProperty);

    m_Prop3D = m_Volume;

    // now add an AbortCheckEvent callback for cancelling the rendering
    mitk::OpenGLRenderer* openGlRenderer = dynamic_cast<mitk::OpenGLRenderer*>(renderer);
    assert(openGlRenderer);
    vtkCallbackCommand* cbc = vtkCallbackCommand::New();
    cbc->SetCallback(mitk::VolumeDataVtkMapper3D::AbortCallback);
    vtkRenderWindow* vtkRendWin;
    vtkRendWin = (vtkRenderWindow*)openGlRenderer->GetVtkRenderWindow();
    vtkRendWin->AddObserver(vtkCommand::AbortCheckEvent,cbc);

    StandardUpdate();
  }
}

void mitk::VolumeDataVtkMapper3D::Update()
{
}

void mitk::VolumeDataVtkMapper3D::ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer)
{

}
<commit_msg>now looking for 'volumerendering' property<commit_after>#include <qapplication.h>
#include "mitkVolumeDataVtkMapper3D.h"
#include "DataTreeNode.h"
#include "mitkFloatProperty.h"
#include "mitkBoolProperty.h"
#include "mitkColorProperty.h"
#include "mitkOpenGLRenderer.h"
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkVolumeRayCastMapper.h>
#include <vtkVolume.h>
#include <vtkVolumeProperty.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkVolumeRayCastCompositeFunction.h>
#include <vtkFiniteDifferenceGradientEstimator.h>
#include <vtkRenderWindow.h>
#include <vtkCallbackCommand.h>
// extern QApplication* qApp;

const mitk::Image* mitk::VolumeDataVtkMapper3D::GetInput()
{
if (this->GetNumberOfInputs() < 1)
{
return 0;
}

return static_cast<const mitk::Image*> ( GetData() );
}

void mitk::VolumeDataVtkMapper3D::GenerateData()
{

}

void mitk::VolumeDataVtkMapper3D::GenerateOutputInformation()
{
}

mitk::VolumeDataVtkMapper3D::VolumeDataVtkMapper3D()
{
  m_VtkVolumeMapper = vtkVolumeRayCastMapper::New();
  vtkVolumeRayCastCompositeFunction* compositeFunction = vtkVolumeRayCastCompositeFunction::New();
  m_VtkVolumeMapper->SetVolumeRayCastFunction(compositeFunction);
  vtkFiniteDifferenceGradientEstimator* gradientEstimator =
	vtkFiniteDifferenceGradientEstimator::New();
  m_VtkVolumeMapper->SetGradientEstimator(gradientEstimator);
  gradientEstimator->Delete();
  m_Volume = vtkVolume::New();
  m_Volume->SetMapper( m_VtkVolumeMapper );
  m_Prop3D = m_Volume;
  m_Prop3D->Register(NULL);

}

mitk::VolumeDataVtkMapper3D::~VolumeDataVtkMapper3D()
{

}
void mitk::VolumeDataVtkMapper3D::AbortCallback(vtkObject *caller, unsigned long eid, void *clientdata, void *calldata) {
  // std::cout << "abort test called" << std::endl;
  vtkRenderWindow* renWin = dynamic_cast<vtkRenderWindow*>(caller);
  assert(renWin);
  // FIXME: qApp->hasPendingEvents is always true, renWin->GetEventPending is
  // always false. So aborting the render doesn't work this way.

  // if (
  //   qApp->hasPendingEvents()
  // )
  // {
  // std::cout << "setting abort render" << std::endl;
  //   renWin->SetAbortRender(1);
  // }
}

void mitk::VolumeDataVtkMapper3D::Update(mitk::BaseRenderer* renderer)
{

 if(IsVisible(renderer)==false ||
    GetDataTreeNode() == NULL ||
    dynamic_cast<mitk::BoolProperty*>(GetDataTreeNode()->GetProperty("volumerendering",renderer).GetPointer())==NULL ||
    dynamic_cast<mitk::BoolProperty*>(GetDataTreeNode()->GetProperty("volumerendering",renderer).GetPointer())->GetBool() == false
  )
  {
//  FIXME: don't understand this
    if (m_Prop3D) {
      std::cout << "visibility off" <<std::endl;

      m_Prop3D->VisibilityOff();
    }
    return;
  }
  if (m_Prop3D) {
    m_Prop3D->VisibilityOn();
  }
  const mitk::Image* img = (GetInput());
  if (img == NULL) {
    itkWarningMacro("Image == NULL")
  } else {
    vtkVolumeProperty* volumeProperty = vtkVolumeProperty::New();
    vtkPiecewiseFunction *opacityTransferFunction, *gradientTransferFunction;
    vtkColorTransferFunction* colorTransferFunction;

    opacityTransferFunction  = vtkPiecewiseFunction::New();
    colorTransferFunction    = vtkColorTransferFunction::New();
    mitk::LevelWindow levelWindow;
    int lw_min,lw_max;
    if (GetLevelWindow(levelWindow,renderer)) {
      lw_min = (int)levelWindow.GetMin();
      lw_max = (int)levelWindow.GetMax();
    } else {
      lw_min = 0;
      lw_max = 255;
    }

    opacityTransferFunction->AddPoint( lw_min, 0.0 );
    opacityTransferFunction->AddPoint( lw_max, 0.9 );
    opacityTransferFunction->ClampingOff();

    colorTransferFunction->AddRGBPoint( lw_min, 1.0, 1.0, 1.0 );
    colorTransferFunction->AddRGBPoint( lw_max, 1.0, 1.0, 1.0 );
    colorTransferFunction->ClampingOff();

    volumeProperty->SetColor( colorTransferFunction );
    volumeProperty->SetScalarOpacity( opacityTransferFunction );
    volumeProperty->ShadeOn();
    volumeProperty->SetDiffuse(0.7);
    volumeProperty->SetAmbient(0.01);

    m_Volume = vtkVolume::New();
    // FIXME: const_cast; maybe GetVtkImageData can be made const by using volatile
    m_VtkVolumeMapper->SetInput(const_cast<mitk::Image*>(img)->GetVtkImageData());
    m_Volume->SetMapper( m_VtkVolumeMapper );
    m_Volume->SetProperty(volumeProperty);

    m_Prop3D = m_Volume;

    // now add an AbortCheckEvent callback for cancelling the rendering
    mitk::OpenGLRenderer* openGlRenderer = dynamic_cast<mitk::OpenGLRenderer*>(renderer);
    assert(openGlRenderer);
    vtkCallbackCommand* cbc = vtkCallbackCommand::New();
    cbc->SetCallback(mitk::VolumeDataVtkMapper3D::AbortCallback);
    vtkRenderWindow* vtkRendWin;
    vtkRendWin = (vtkRenderWindow*)openGlRenderer->GetVtkRenderWindow();
    vtkRendWin->AddObserver(vtkCommand::AbortCheckEvent,cbc);

    StandardUpdate();
  }
}

void mitk::VolumeDataVtkMapper3D::Update()
{
}

void mitk::VolumeDataVtkMapper3D::ApplyProperties(vtkActor* actor, mitk::BaseRenderer* renderer)
{

}
<|endoftext|>


<commit_before>#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iterator>
#include <locale>
#include <locale.h>
#include <string>
#include <vector>
#include <simstring/simstring.h>

#include "optparse.h"

class option
{
public:
    enum {
        MODE_INTERACTIVE,
        MODE_BUILD,
        MODE_HELP,
    };

    enum {
        QT_EXACT,
        QT_DICE,
        QT_COSINE,
        QT_JACCARD,
        QT_OVERLAP,
    };

    enum {
        CC_CHAR = 0,    // char
        CC_WCHAR,       // wchar_t
    };

    int mode;
    int code;
    std::string name;

    int ngram_size;
    bool be;
    int query_type;
    double threshold;
    bool echo_back;
    bool quiet;

public:
    option() :
        mode(MODE_INTERACTIVE),
        code(CC_CHAR),
        name(""),
        ngram_size(3),
        be(false),
        query_type(QT_COSINE),
        threshold(0.7),
        echo_back(false),
        quiet(false)
    {
    }
};

class option_parser :
    public option,
    public optparse
{
    BEGIN_OPTION_MAP_INLINE()
        ON_OPTION(SHORTOPT('b') || LONGOPT("build"))
            mode = MODE_BUILD;

        ON_OPTION_WITH_ARG(SHORTOPT('d') || LONGOPT("database"))
            name = arg;

        ON_OPTION(SHORTOPT('w') || LONGOPT("wchar"))
            code = CC_WCHAR;

        ON_OPTION(SHORTOPT('m') || LONGOPT("mark"))
            be = true;

        ON_OPTION_WITH_ARG(SHORTOPT('s') || LONGOPT("similarity"))
            if (std::strcmp(arg, "exact") == 0) {
                query_type = QT_EXACT;
            } else if (std::strcmp(arg, "dice") == 0) {
                query_type = QT_DICE;
            } else if (std::strcmp(arg, "cosine") == 0) {
                query_type = QT_COSINE;
            } else if (std::strcmp(arg, "jaccard") == 0) {
                query_type = QT_JACCARD;
            } else if (std::strcmp(arg, "overlap") == 0) {
                query_type = QT_OVERLAP;
            }

        ON_OPTION_WITH_ARG(SHORTOPT('t') || LONGOPT("threshold"))
            threshold = std::atof(arg);

        ON_OPTION(SHORTOPT('e') || LONGOPT("echo"))
            echo_back = true;

        ON_OPTION(SHORTOPT('q') || LONGOPT("quiet"))
            quiet = true;

        ON_OPTION_WITH_ARG(SHORTOPT('n') || LONGOPT("ngram"))
            ngram_size = std::atoi(arg);

        ON_OPTION(SHORTOPT('h') || LONGOPT("help"))
            mode = MODE_HELP;

    END_OPTION_MAP()
};

int usage(std::ostream& os, const char *argv0)
{
    os << "USAGE: " << argv0 << " [OPTIONS]" << std::endl;
    os << std::endl;
    return 0;
}

template <class char_type, class istream_type>
int build(option& opt, istream_type& is)
{
    typedef std::basic_string<char_type> string_type;
    typedef simstring::ngram_generator ngram_generator_type;
    typedef simstring::writer_base<string_type, ngram_generator_type> writer_type;

    int n = 0;
    clock_t clk;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    // Show parameters for database construction.
    os << "Constructing the database" << std::endl;
    os << "Database name: " << opt.name << std::endl;
    os << "N-gram length: " << opt.ngram_size << std::endl;
    os << "Char type: " << typeid(char_type).name() << std::endl;
    os.flush();

    // Open the database for construction.
    clk = std::clock();
    ngram_generator_type gen(opt.ngram_size, opt.be);
    writer_type db(gen, opt.name);
    if (db.fail()) {
        es << "ERROR: " << db.error() << std::endl;
        return 1;
    }

    // Insert every string from STDIN into the database.
    for (;;) {
        // Read a line.
        string_type line;
        std::getline(is, line);
        if (is.eof()) {
            break;
        }

        // Insert the string.
        if (!db.insert(line)) {
            es << "ERROR: " << db.error() << std::endl;
            return 1;
        }

        // Progress report.
        if (!opt.quiet && ++n % 10000 == 0) {
            os << "Number of strings: " << n << std::endl;
            os.flush();
        }
    }
    os << "Number of strings: " << n << std::endl;
    os << std::endl;
    os.flush();

    // Finalize the database.
    os << "Flushing the database" << std::endl;
    if (!db.close()) {
        es << "ERROR: " << db.error() << std::endl;
        return 1;
    }
    os << std::endl;

    // Report the elaped time for construction.
    os << "Seconds required: "
        << (std::clock() - clk) / (double)CLOCKS_PER_SEC << std::endl;
    os << std::endl;
    os.flush();

    return 0;
}

template <class char_type, class istream_type, class ostream_type>
int interactive(option& opt, istream_type& is, ostream_type& os)
{
    typedef std::basic_string<char_type> string_type;
    typedef std::vector<string_type> strings_type;
    typedef simstring::ngram_generator ngram_generator_type;
    typedef simstring::reader_base<string_type> reader_type;
    typedef simstring::query::exact<string_type, ngram_generator_type> query_exact_type;
    typedef simstring::query::cosine<string_type, ngram_generator_type> query_cosine_type;
    typedef simstring::query::dice<string_type, ngram_generator_type> query_dice_type;
    typedef simstring::query::jaccard<string_type, ngram_generator_type> query_jaccard_type;
    typedef simstring::query::overlap<string_type, ngram_generator_type> query_overlap_type;

    reader_type db;
    std::ostream& es = std::cerr;

    db.open(opt.name);

    ngram_generator_type gen(opt.ngram_size, opt.be);

    for (;;) {
        // Read a line.
        string_type line;
        std::getline(is, line);
        if (is.eof()) {
            os << std::endl;
            break;
        }

        // The line is a query.
        strings_type xstrs;
        clock_t clk = std::clock();

        // Issue a query.
        switch (opt.query_type) {
        case option::QT_EXACT:
            db.retrieve(
                query_exact_type(gen, line),
                std::back_inserter(xstrs)
                );
            break;
        case option::QT_DICE:
            db.retrieve(
                query_dice_type(gen, line, opt.threshold),
                std::back_inserter(xstrs)
                );
            break;
        case option::QT_COSINE:
            db.retrieve(
                query_cosine_type(gen, line, opt.threshold),
                std::back_inserter(xstrs)
                );
            break;
        case option::QT_JACCARD:
            db.retrieve(
                query_jaccard_type(gen, line, opt.threshold),
                std::back_inserter(xstrs)
                );
            break;
        case option::QT_OVERLAP:
            db.retrieve(
                query_overlap_type(gen, line, opt.threshold),
                std::back_inserter(xstrs)
                );
            break;
        }

        // Output the query string if necessary.
        if (opt.echo_back) {
            os << line << std::endl;
        }

        // Output the retrieved strings.
        typename strings_type::const_iterator it;
        for (it = xstrs.begin();it != xstrs.end();++it) {
            os << os.widen('\t') << *it << std::endl;
        }
        os.flush();

        if (!opt.quiet) {
            es << xstrs.size() << " strings retrieved (" <<
                (std::clock() - clk) / (double)CLOCKS_PER_SEC <<
                " sec)" << std::endl;
        }
    }

    return 0;
}

int main(int argc, char *argv[])
{
    option_parser opt;
    std::istream& is = std::cin;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    // Show the copyright information.
    os << SIMSTRING_NAME " ";
    os << SIMSTRING_MAJOR_VERSION << "." << SIMSTRING_MINOR_VERSION << " ";
    os << SIMSTRING_COPYRIGHT << std::endl;
    os << std::endl;

    // Parse the command-line options.
    try {
        int arg_used = opt.parse(argv, argc);
    } catch (const optparse::unrecognized_option& e) {
        es << "ERROR: unrecognized option: " << e.what() << std::endl;
        return 1;
    } catch (const optparse::invalid_value& e) {
        es << "ERROR: " << e.what() << std::endl;
        return 1;
    }

    // Change the locale of wcin and wcout if necessary.
    if (opt.code == option::CC_WCHAR) {
        std::ios_base::sync_with_stdio(false);
        std::locale::global(std::locale(""));
        std::wcout.imbue(std::locale(""));
        std::wcin.imbue(std::locale(""));
    }

    // Branches for the processing mode.
    switch (opt.mode) {
    case option::MODE_HELP:
        return usage(os, argv[0]);
    case option::MODE_BUILD:
        if (opt.code == option::CC_CHAR) {
            return build<char>(opt, std::cin);
        } else if (opt.code == option::CC_WCHAR) {
            return build<wchar_t>(opt, std::wcin);
        }
        break;
    case option::MODE_INTERACTIVE:
        if (opt.code == option::CC_CHAR) {
            return interactive<char>(opt, std::cin, std::cout);
        } else if (opt.code == option::CC_WCHAR) {
            return interactive<wchar_t>(opt, std::wcin, std::wcout);
        }
        break;
    }

    return 1;
}
<commit_msg>Output the copyright message to STDERR<commit_after>#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iterator>
#include <locale>
#include <locale.h>
#include <string>
#include <vector>
#include <simstring/simstring.h>

#include "optparse.h"

class option
{
public:
    enum {
        MODE_INTERACTIVE,
        MODE_BUILD,
        MODE_HELP,
    };

    enum {
        QT_EXACT,
        QT_DICE,
        QT_COSINE,
        QT_JACCARD,
        QT_OVERLAP,
    };

    enum {
        CC_CHAR = 0,    // char
        CC_WCHAR,       // wchar_t
    };

    int mode;
    int code;
    std::string name;

    int ngram_size;
    bool be;
    int query_type;
    double threshold;
    bool echo_back;
    bool quiet;

public:
    option() :
        mode(MODE_INTERACTIVE),
        code(CC_CHAR),
        name(""),
        ngram_size(3),
        be(false),
        query_type(QT_COSINE),
        threshold(0.7),
        echo_back(false),
        quiet(false)
    {
    }
};

class option_parser :
    public option,
    public optparse
{
    BEGIN_OPTION_MAP_INLINE()
        ON_OPTION(SHORTOPT('b') || LONGOPT("build"))
            mode = MODE_BUILD;

        ON_OPTION_WITH_ARG(SHORTOPT('d') || LONGOPT("database"))
            name = arg;

        ON_OPTION(SHORTOPT('w') || LONGOPT("wchar"))
            code = CC_WCHAR;

        ON_OPTION(SHORTOPT('m') || LONGOPT("mark"))
            be = true;

        ON_OPTION_WITH_ARG(SHORTOPT('s') || LONGOPT("similarity"))
            if (std::strcmp(arg, "exact") == 0) {
                query_type = QT_EXACT;
            } else if (std::strcmp(arg, "dice") == 0) {
                query_type = QT_DICE;
            } else if (std::strcmp(arg, "cosine") == 0) {
                query_type = QT_COSINE;
            } else if (std::strcmp(arg, "jaccard") == 0) {
                query_type = QT_JACCARD;
            } else if (std::strcmp(arg, "overlap") == 0) {
                query_type = QT_OVERLAP;
            }

        ON_OPTION_WITH_ARG(SHORTOPT('t') || LONGOPT("threshold"))
            threshold = std::atof(arg);

        ON_OPTION(SHORTOPT('e') || LONGOPT("echo"))
            echo_back = true;

        ON_OPTION(SHORTOPT('q') || LONGOPT("quiet"))
            quiet = true;

        ON_OPTION_WITH_ARG(SHORTOPT('n') || LONGOPT("ngram"))
            ngram_size = std::atoi(arg);

        ON_OPTION(SHORTOPT('h') || LONGOPT("help"))
            mode = MODE_HELP;

    END_OPTION_MAP()
};

int usage(std::ostream& os, const char *argv0)
{
    os << "USAGE: " << argv0 << " [OPTIONS]" << std::endl;
    os << std::endl;
    return 0;
}

template <class char_type, class istream_type>
int build(option& opt, istream_type& is)
{
    typedef std::basic_string<char_type> string_type;
    typedef simstring::ngram_generator ngram_generator_type;
    typedef simstring::writer_base<string_type, ngram_generator_type> writer_type;

    int n = 0;
    clock_t clk;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    // Show parameters for database construction.
    os << "Constructing the database" << std::endl;
    os << "Database name: " << opt.name << std::endl;
    os << "N-gram length: " << opt.ngram_size << std::endl;
    os << "Char type: " << typeid(char_type).name() << std::endl;
    os.flush();

    // Open the database for construction.
    clk = std::clock();
    ngram_generator_type gen(opt.ngram_size, opt.be);
    writer_type db(gen, opt.name);
    if (db.fail()) {
        es << "ERROR: " << db.error() << std::endl;
        return 1;
    }

    // Insert every string from STDIN into the database.
    for (;;) {
        // Read a line.
        string_type line;
        std::getline(is, line);
        if (is.eof()) {
            break;
        }

        // Insert the string.
        if (!db.insert(line)) {
            es << "ERROR: " << db.error() << std::endl;
            return 1;
        }

        // Progress report.
        if (!opt.quiet && ++n % 10000 == 0) {
            os << "Number of strings: " << n << std::endl;
            os.flush();
        }
    }
    os << "Number of strings: " << n << std::endl;
    os << std::endl;
    os.flush();

    // Finalize the database.
    os << "Flushing the database" << std::endl;
    if (!db.close()) {
        es << "ERROR: " << db.error() << std::endl;
        return 1;
    }
    os << std::endl;

    // Report the elaped time for construction.
    os << "Seconds required: "
        << (std::clock() - clk) / (double)CLOCKS_PER_SEC << std::endl;
    os << std::endl;
    os.flush();

    return 0;
}

template <class char_type, class istream_type, class ostream_type>
int interactive(option& opt, istream_type& is, ostream_type& os)
{
    typedef std::basic_string<char_type> string_type;
    typedef std::vector<string_type> strings_type;
    typedef simstring::ngram_generator ngram_generator_type;
    typedef simstring::reader_base<string_type> reader_type;
    typedef simstring::query::exact<string_type, ngram_generator_type> query_exact_type;
    typedef simstring::query::cosine<string_type, ngram_generator_type> query_cosine_type;
    typedef simstring::query::dice<string_type, ngram_generator_type> query_dice_type;
    typedef simstring::query::jaccard<string_type, ngram_generator_type> query_jaccard_type;
    typedef simstring::query::overlap<string_type, ngram_generator_type> query_overlap_type;

    reader_type db;
    std::ostream& es = std::cerr;

    db.open(opt.name);

    ngram_generator_type gen(opt.ngram_size, opt.be);

    for (;;) {
        // Read a line.
        string_type line;
        std::getline(is, line);
        if (is.eof()) {
            os << std::endl;
            break;
        }

        // The line is a query.
        strings_type xstrs;
        clock_t clk = std::clock();

        // Issue a query.
        switch (opt.query_type) {
        case option::QT_EXACT:
            db.retrieve(
                query_exact_type(gen, line),
                std::back_inserter(xstrs)
                );
            break;
        case option::QT_DICE:
            db.retrieve(
                query_dice_type(gen, line, opt.threshold),
                std::back_inserter(xstrs)
                );
            break;
        case option::QT_COSINE:
            db.retrieve(
                query_cosine_type(gen, line, opt.threshold),
                std::back_inserter(xstrs)
                );
            break;
        case option::QT_JACCARD:
            db.retrieve(
                query_jaccard_type(gen, line, opt.threshold),
                std::back_inserter(xstrs)
                );
            break;
        case option::QT_OVERLAP:
            db.retrieve(
                query_overlap_type(gen, line, opt.threshold),
                std::back_inserter(xstrs)
                );
            break;
        }

        // Output the query string if necessary.
        if (opt.echo_back) {
            os << line << std::endl;
        }

        // Output the retrieved strings.
        typename strings_type::const_iterator it;
        for (it = xstrs.begin();it != xstrs.end();++it) {
            os << os.widen('\t') << *it << std::endl;
        }
        os.flush();

        if (!opt.quiet) {
            es << xstrs.size() << " strings retrieved (" <<
                (std::clock() - clk) / (double)CLOCKS_PER_SEC <<
                " sec)" << std::endl;
        }
    }

    return 0;
}

int main(int argc, char *argv[])
{
    option_parser opt;
    std::istream& is = std::cin;
    std::ostream& os = std::cout;
    std::ostream& es = std::cerr;

    // Show the copyright information.
    es << SIMSTRING_NAME " ";
    es << SIMSTRING_MAJOR_VERSION << "." << SIMSTRING_MINOR_VERSION << " ";
    es << SIMSTRING_COPYRIGHT << std::endl;
    es << std::endl;

    // Parse the command-line options.
    try {
        int arg_used = opt.parse(argv, argc);
    } catch (const optparse::unrecognized_option& e) {
        es << "ERROR: unrecognized option: " << e.what() << std::endl;
        return 1;
    } catch (const optparse::invalid_value& e) {
        es << "ERROR: " << e.what() << std::endl;
        return 1;
    }

    // Change the locale of wcin and wcout if necessary.
    if (opt.code == option::CC_WCHAR) {
        std::ios_base::sync_with_stdio(false);
        std::locale::global(std::locale(""));
        std::wcout.imbue(std::locale(""));
        std::wcin.imbue(std::locale(""));
    }

    // Branches for the processing mode.
    switch (opt.mode) {
    case option::MODE_HELP:
        return usage(os, argv[0]);
    case option::MODE_BUILD:
        if (opt.code == option::CC_CHAR) {
            return build<char>(opt, std::cin);
        } else if (opt.code == option::CC_WCHAR) {
            return build<wchar_t>(opt, std::wcin);
        }
        break;
    case option::MODE_INTERACTIVE:
        if (opt.code == option::CC_CHAR) {
            return interactive<char>(opt, std::cin, std::cout);
        } else if (opt.code == option::CC_WCHAR) {
            return interactive<wchar_t>(opt, std::wcin, std::wcout);
        }
        break;
    }

    return 1;
}
<|endoftext|>


<commit_before>#include "Input.h"
#include <libndls.h>

#define INPUT WalrusRPG::Input

using WalrusRPG::Input::Key;
using WalrusRPG::Input::KeyState;

struct InputMap
{
    Key key;
    t_key key_code;
};

static KeyState key_states[Key::K_SIZE] = {KeyState::KS_RELEASED};
static InputMap key_map[] = {
    {Key::K_A, KEY_NSPIRE_CTRL},     {Key::K_B, KEY_NSPIRE_SHIFT},
    {Key::K_L, KEY_NSPIRE_TAB},      {Key::K_R, KEY_NSPIRE_MENU},

    {Key::K_UP, KEY_NSPIRE_8},       {Key::K_DOWN, KEY_NSPIRE_5},
    {Key::K_LEFT, KEY_NSPIRE_4},     {Key::K_RIGHT, KEY_NSPIRE_6},

    {Key::K_START, KEY_NSPIRE_HOME}, {Key::K_SELECT, KEY_NSPIRE_ESC},
};

KeyState INPUT::key_get_state(Key key)
{
        return key_states[key];
}

void INPUT::key_poll()
{
    for (unsigned i = 0; i < K_SIZE; i++)
    {
        bool current_key_state = isKeyPressed(key_map[i].key_code);
        KeyState previous_key_state = key_states[i];

        KeyState resulting_key_state = KS_RELEASED;
        if (current_key_state)
        {
            if (previous_key_state == KS_RELEASED ||
                previous_key_state == KS_JUST_RELEASED)
                resulting_key_state = KS_JUST_PRESSED;
            else if (previous_key_state == KS_JUST_PRESSED ||
                     previous_key_state == KS_PRESSED)
                resulting_key_state = KS_PRESSED;
        }
        else
        {
            if (previous_key_state == KS_PRESSED || previous_key_state == KS_JUST_PRESSED)
                resulting_key_state = KS_JUST_RELEASED;
            else if (previous_key_state == KS_JUST_RELEASED ||
                     previous_key_state == KS_RELEASED)
                resulting_key_state = KS_RELEASED;
        }
        key_states[i] = resulting_key_state;
    }
}

bool INPUT::key_pressed(Key key)
{
    return key_states[key] == KS_JUST_PRESSED;
}
bool INPUT::key_released(Key key)
{
    return key_states[key] == KS_JUST_RELEASED;
}
bool INPUT::key_down(Key key)
{
    return key_states[key] == KS_JUST_PRESSED || key_states[key] == KS_PRESSED;
}
bool INPUT::key_up(Key key)
{
    return key_states[key] == KS_JUST_RELEASED || key_states[key] == KS_RELEASED;
}
<commit_msg>Home doesn't work on my CX CAS. :/<commit_after>#include "Input.h"
#include <libndls.h>

#define INPUT WalrusRPG::Input

using WalrusRPG::Input::Key;
using WalrusRPG::Input::KeyState;

struct InputMap
{
    Key key;
    t_key key_code;
};

static KeyState key_states[Key::K_SIZE] = {KeyState::KS_RELEASED};
static InputMap key_map[] = {
    {Key::K_A, KEY_NSPIRE_CTRL},     {Key::K_B, KEY_NSPIRE_SHIFT},
    {Key::K_L, KEY_NSPIRE_TAB},      {Key::K_R, KEY_NSPIRE_MENU},

    {Key::K_UP, KEY_NSPIRE_8},       {Key::K_DOWN, KEY_NSPIRE_5},
    {Key::K_LEFT, KEY_NSPIRE_4},     {Key::K_RIGHT, KEY_NSPIRE_6},

    {Key::K_START, KEY_NSPIRE_DOC}, {Key::K_SELECT, KEY_NSPIRE_ESC},
};

KeyState INPUT::key_get_state(Key key)
{
        return key_states[key];
}

void INPUT::key_poll()
{
    for (unsigned i = 0; i < K_SIZE; i++)
    {
        bool current_key_state = isKeyPressed(key_map[i].key_code);
        KeyState previous_key_state = key_states[i];

        KeyState resulting_key_state = KS_RELEASED;
        if (current_key_state)
        {
            if (previous_key_state == KS_RELEASED ||
                previous_key_state == KS_JUST_RELEASED)
                resulting_key_state = KS_JUST_PRESSED;
            else if (previous_key_state == KS_JUST_PRESSED ||
                     previous_key_state == KS_PRESSED)
                resulting_key_state = KS_PRESSED;
        }
        else
        {
            if (previous_key_state == KS_PRESSED || previous_key_state == KS_JUST_PRESSED)
                resulting_key_state = KS_JUST_RELEASED;
            else if (previous_key_state == KS_JUST_RELEASED ||
                     previous_key_state == KS_RELEASED)
                resulting_key_state = KS_RELEASED;
        }
        key_states[i] = resulting_key_state;
    }
}

bool INPUT::key_pressed(Key key)
{
    return key_states[key] == KS_JUST_PRESSED;
}
bool INPUT::key_released(Key key)
{
    return key_states[key] == KS_JUST_RELEASED;
}
bool INPUT::key_down(Key key)
{
    return key_states[key] == KS_JUST_PRESSED || key_states[key] == KS_PRESSED;
}
bool INPUT::key_up(Key key)
{
    return key_states[key] == KS_JUST_RELEASED || key_states[key] == KS_RELEASED;
}
<|endoftext|>


<commit_before>// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)

// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the internal cross-platform support utilities.

#include <gmock/internal/gmock-port.h>
#include <gtest/gtest.h>

// This file intentionally contains no test at this moment.
<commit_msg>Adds a dummy test to gmock-port.test.cc.<commit_after>// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vladl@google.com (Vlad Losev)

// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the internal cross-platform support utilities.

#include <gmock/internal/gmock-port.h>
#include <gtest/gtest.h>

// This file intentionally contains no tests at this moment.

// Putting a dummy test here makes references to symbols in the gtest
// library and avoids 'undefined symbol' linker errors in gmock_main.
TEST(DummyTest, Dummy) {}
<|endoftext|>