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

Copyright (c) 2000-2009 Torus Knot Software Ltd

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

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

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

#include "OgreGLSLESLinkProgram.h"
#include "OgreGLSLESExtSupport.h"
#include "OgreGLSLESGpuProgram.h"
#include "OgreGLSLESProgram.h"
#include "OgreGLSLESLinkProgramManager.h"
#include "OgreStringVector.h"
#include "OgreLogManager.h"
#include "OgreGpuProgramManager.h"
#include "OgreStringConverter.h"

namespace Ogre {

	//-----------------------------------------------------------------------
	GLSLESLinkProgram::GLSLESLinkProgram(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram)
        : mVertexProgram(vertexProgram)
		, mFragmentProgram(fragmentProgram)
		, mUniformRefsBuilt(false)
        , mLinked(false)
		, mTriedToLinkAndFailed(false)
	{
		// init CustomAttributesIndexs
		for(size_t i = 0 ; i < VES_COUNT; i++)
			for(size_t j = 0 ; j < OGRE_MAX_TEXTURE_COORD_SETS; j++)
		{
			mCustomAttributesIndexs[i][j] = NULL_CUSTOM_ATTRIBUTES_INDEX;
		}

        if (!mVertexProgram && !mFragmentProgram)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Attempted to create a shader program without both a vertex and fragment program.",
                        "GLSLESLinkProgram::GLSLESLinkProgram");
        }
	}

	//-----------------------------------------------------------------------
	GLSLESLinkProgram::~GLSLESLinkProgram(void)
	{
		glDeleteProgram(mGLHandle);
        GL_CHECK_ERROR;
	}

	//-----------------------------------------------------------------------
	Ogre::String GLSLESLinkProgram::getCombinedName()
	{
		String name;
		if (mVertexProgram)
		{
			name += "Vertex Program:" ;
			name += mVertexProgram->getName();
		}
		if (mFragmentProgram)
		{
			name += " Fragment Program:" ;
			name += mFragmentProgram->getName();
		}
		return name;
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::activate(void)
	{
		if (!mLinked && !mTriedToLinkAndFailed)
		{
			if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() &&
				GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) )
			{
				getMicrocodeFromCache();
			}
			else
			{
				compileAndLink();
			}

			buildGLUniformReferences();
		}

		if (mLinked)
		{
            GL_CHECK_ERROR
            glUseProgram( mGLHandle );
            GL_CHECK_ERROR
		}
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::getMicrocodeFromCache(void)
	{
		GpuProgramManager::Microcode cacheMicrocode =
			GpuProgramManager::getSingleton().getMicrocodeFromCache(getCombinedName());

		// add to the microcode to the cache
		String name;
		name = getCombinedName();

		// buffer size
		GLint binaryLength = cacheMicrocode->size() - sizeof(GLenum);

		// turns out we need this param when loading
		GLenum binaryFormat = 0;

		cacheMicrocode->seek(0);

		// get size of binary
		cacheMicrocode->read(&binaryFormat, sizeof(GLenum));

#if GL_OES_get_program_binary
		// load binary
		glProgramBinaryOES( mGLHandle,
							binaryFormat,
							cacheMicrocode->getPtr(),
							binaryLength
			);
#endif
		GLint   success = 0;
		glGetProgramiv(mGLHandle, GL_LINK_STATUS, &success);
		if (!success)
		{
			//
			// Something must have changed since the program binaries
			// were cached away.  Fallback to source shader loading path,
			// and then retrieve and cache new program binaries once again.
			//
			compileAndLink();
		}

	}

	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::compileAndLink()
	{

        glGetError(); // Clean up the error. Otherwise will flood log.
        mGLHandle = glCreateProgram();
        GL_CHECK_ERROR

		// compile and attach Vertex Program
		if (!mVertexProgram->getGLSLProgram()->compile(true))
		{
			// todo error
			return;
		}
        mVertexProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);
        setSkeletalAnimationIncluded(mVertexProgram->isSkeletalAnimationIncluded());

		// compile and attach Fragment Program
		if (!mFragmentProgram->getGLSLProgram()->compile(true))
		{
			// todo error
			return;
		}
        mFragmentProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);

		// the link
		glLinkProgram( mGLHandle );
		GL_CHECK_ERROR
			glGetProgramiv( mGLHandle, GL_LINK_STATUS, &mLinked );
		GL_CHECK_ERROR

		mTriedToLinkAndFailed = !mLinked;

		logObjectInfo( getCombinedName() + String("GLSL link result : "), mGLHandle );
		if(mLinked)
		{
			if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() )
			{
				// add to the microcode to the cache
				String name;
				name = getCombinedName();

				// get buffer size
				GLint binaryLength = 0;
#if GL_OES_get_program_binary
				glGetProgramiv(mGLHandle, GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength);
#endif

				// turns out we need this param when loading
				GLenum binaryFormat = 0;

				// get the buffer
				GpuProgramManager::Microcode newMicrocode(OGRE_NEW MemoryDataStream(name,  binaryLength + sizeof(GLenum)));
				newMicrocode->seek(0);

#if GL_OES_get_program_binary
				// get binary
				glGetProgramBinaryOES(mGLHandle, binaryLength, NULL, (GLenum *)newMicrocode->getPtr(), newMicrocode->getPtr() + sizeof(GLenum));
#endif

				GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode);
			}
		}
	}
	//-----------------------------------------------------------------------
	const char * getAttributeSemanticString(VertexElementSemantic semantic)
	{
		switch(semantic)
		{
			case VES_POSITION:
				return "vertex";
			case VES_BLEND_WEIGHTS:
				return "blendWeights";
			case VES_NORMAL:
				return "normal";
			case VES_DIFFUSE:
				return "colour";
			case VES_SPECULAR:
				return "secondary_colour";
			case VES_BLEND_INDICES:
				return "blendIndices";
			case VES_TANGENT:
				return "tangent";
			case VES_BINORMAL:
				return "binormal";
			case VES_TEXTURE_COORDINATES:
				return "uv";
			default:
				assert(false && "Missing attribute!");
				return 0;
		};

	}
	//-----------------------------------------------------------------------
	GLuint GLSLESLinkProgram::getAttributeIndex(VertexElementSemantic semantic, uint index)
	{
		GLuint res = mCustomAttributesIndexs[semantic-1][index];
		if (res != NULL_CUSTOM_ATTRIBUTES_INDEX)
		{
			const char * attString = getAttributeSemanticString(semantic);
			GLint attrib = glGetAttribLocation(mGLHandle, attString);

			// sadly position is a special case
			if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX && semantic == VES_POSITION)
			{
				attrib = glGetAttribLocation(mGLHandle, "position");
			}

			// for uv and other case the index is a part of the name
			if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX)
			{
				String attStringWithSemantic = String(attString) + StringConverter::toString(index);
				attrib = glGetAttribLocation(mGLHandle, attStringWithSemantic.c_str());
			}

			// update mCustomAttributesIndexs with the index we found (or didn't found)
			mCustomAttributesIndexs[semantic-1][index] = attrib;
			res = attrib;
		}
		return res;
	}
	//-----------------------------------------------------------------------
	bool GLSLESLinkProgram::isAttributeValid(VertexElementSemantic semantic, uint index)
	{
		return getAttributeIndex(semantic, index) != -1;
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::buildGLUniformReferences(void)
	{
		if (!mUniformRefsBuilt)
		{
			const GpuConstantDefinitionMap* vertParams = 0;
			const GpuConstantDefinitionMap* fragParams = 0;
			if (mVertexProgram)
			{
				vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map);
			}
			if (mFragmentProgram)
			{
				fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map);
			}

			GLSLESLinkProgramManager::getSingleton().extractUniforms(
				mGLHandle, vertParams, fragParams, mGLUniformReferences);

			mUniformRefsBuilt = true;
		}
	}

	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params,
		uint16 mask, GpuProgramType fromProgType)
	{
		// Iterate through uniform reference list and update uniform values
		GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin();
		GLUniformReferenceIterator endUniform = mGLUniformReferences.end();

		for (;currentUniform != endUniform; ++currentUniform)
		{
			// Only pull values from buffer it's supposed to be in (vertex or fragment)
			// This method will be called twice, once for vertex program params,
			// and once for fragment program params.
			if (fromProgType == currentUniform->mSourceProgType)
			{
				const GpuConstantDefinition* def = currentUniform->mConstantDef;
				if (def->variability & mask)
				{
					GLsizei glArraySize = (GLsizei)def->arraySize;

					// Get the index in the parameter real list
					switch (def->constType)
					{
					case GCT_FLOAT1:
						glUniform1fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT2:
						glUniform2fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT3:
						glUniform3fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT4:
						glUniform4fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_2X2:
						glUniformMatrix2fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_3X3:
						glUniformMatrix3fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_4X4:
						glUniformMatrix4fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_INT1:
						glUniform1iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT2:
						glUniform2iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT3:
						glUniform3iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT4:
						glUniform4iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_SAMPLER1D:
					case GCT_SAMPLER1DSHADOW:
					case GCT_SAMPLER2D:
					case GCT_SAMPLER2DSHADOW:
					case GCT_SAMPLER3D:
					case GCT_SAMPLERCUBE:
						// Samplers handled like 1-element ints
						glUniform1iv(currentUniform->mLocation, 1,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_2X3:
					case GCT_MATRIX_2X4:
					case GCT_MATRIX_3X2:
					case GCT_MATRIX_3X4:
					case GCT_MATRIX_4X2:
					case GCT_MATRIX_4X3:
                    case GCT_UNKNOWN:
                        break;

					} // End switch
                    GL_CHECK_ERROR;
				} // Variability & mask
			} // fromProgType == currentUniform->mSourceProgType

  		} // End for
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::updatePassIterationUniforms(GpuProgramParametersSharedPtr params)
	{
		if (params->hasPassIterationNumber())
		{
			size_t index = params->getPassIterationNumberIndex();

			GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin();
			GLUniformReferenceIterator endUniform = mGLUniformReferences.end();

			// Need to find the uniform that matches the multi pass entry
			for (;currentUniform != endUniform; ++currentUniform)
			{
				// Get the index in the parameter real list
				if (index == currentUniform->mConstantDef->physicalIndex)
				{
					glUniform1fv(currentUniform->mLocation, 1, params->getFloatPointer(index));
                    GL_CHECK_ERROR;
					// There will only be one multipass entry
					return;
				}
			}
		}
    }
} // namespace Ogre
<commit_msg>GLES2 render system: Fixed a bug with program binary cache - glCreateProgram should be also called before a program is loaded from the cache.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

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

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

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

#include "OgreGLSLESLinkProgram.h"
#include "OgreGLSLESExtSupport.h"
#include "OgreGLSLESGpuProgram.h"
#include "OgreGLSLESProgram.h"
#include "OgreGLSLESLinkProgramManager.h"
#include "OgreStringVector.h"
#include "OgreLogManager.h"
#include "OgreGpuProgramManager.h"
#include "OgreStringConverter.h"

namespace Ogre {

	//-----------------------------------------------------------------------
	GLSLESLinkProgram::GLSLESLinkProgram(GLSLESGpuProgram* vertexProgram, GLSLESGpuProgram* fragmentProgram)
        : mVertexProgram(vertexProgram)
		, mFragmentProgram(fragmentProgram)
		, mUniformRefsBuilt(false)
        , mLinked(false)
		, mTriedToLinkAndFailed(false)
	{
		// init CustomAttributesIndexs
		for(size_t i = 0 ; i < VES_COUNT; i++)
			for(size_t j = 0 ; j < OGRE_MAX_TEXTURE_COORD_SETS; j++)
		{
			mCustomAttributesIndexs[i][j] = NULL_CUSTOM_ATTRIBUTES_INDEX;
		}

        if (!mVertexProgram && !mFragmentProgram)
        {
            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR,
                        "Attempted to create a shader program without both a vertex and fragment program.",
                        "GLSLESLinkProgram::GLSLESLinkProgram");
        }
	}

	//-----------------------------------------------------------------------
	GLSLESLinkProgram::~GLSLESLinkProgram(void)
	{
		glDeleteProgram(mGLHandle);
        GL_CHECK_ERROR;
	}

	//-----------------------------------------------------------------------
	Ogre::String GLSLESLinkProgram::getCombinedName()
	{
		String name;
		if (mVertexProgram)
		{
			name += "Vertex Program:" ;
			name += mVertexProgram->getName();
		}
		if (mFragmentProgram)
		{
			name += " Fragment Program:" ;
			name += mFragmentProgram->getName();
		}
		return name;
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::activate(void)
	{
		if (!mLinked && !mTriedToLinkAndFailed)
		{
			glGetError(); // Clean up the error. Otherwise will flood log.
			mGLHandle = glCreateProgram();
			GL_CHECK_ERROR

			if ( GpuProgramManager::getSingleton().canGetCompiledShaderBuffer() &&
				GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(getCombinedName()) )
			{
				getMicrocodeFromCache();
			}
			else
			{
				compileAndLink();
			}

			buildGLUniformReferences();
		}

		if (mLinked)
		{
            GL_CHECK_ERROR
            glUseProgram( mGLHandle );
            GL_CHECK_ERROR
		}
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::getMicrocodeFromCache(void)
	{
		GpuProgramManager::Microcode cacheMicrocode =
			GpuProgramManager::getSingleton().getMicrocodeFromCache(getCombinedName());

		// add to the microcode to the cache
		String name;
		name = getCombinedName();

		// buffer size
		GLint binaryLength = cacheMicrocode->size() - sizeof(GLenum);

		// turns out we need this param when loading
		GLenum binaryFormat = 0;

		cacheMicrocode->seek(0);

		// get size of binary
		cacheMicrocode->read(&binaryFormat, sizeof(GLenum));

#if GL_OES_get_program_binary
		// load binary
		glProgramBinaryOES( mGLHandle,
							binaryFormat,
							cacheMicrocode->getPtr(),
							binaryLength
			);
#endif
		GLint   success = 0;
		glGetProgramiv(mGLHandle, GL_LINK_STATUS, &success);
		if (!success)
		{
			//
			// Something must have changed since the program binaries
			// were cached away.  Fallback to source shader loading path,
			// and then retrieve and cache new program binaries once again.
			//
			compileAndLink();
		}

	}

	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::compileAndLink()
	{
		// compile and attach Vertex Program
		if (!mVertexProgram->getGLSLProgram()->compile(true))
		{
			// todo error
			return;
		}
        mVertexProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);
        setSkeletalAnimationIncluded(mVertexProgram->isSkeletalAnimationIncluded());

		// compile and attach Fragment Program
		if (!mFragmentProgram->getGLSLProgram()->compile(true))
		{
			// todo error
			return;
		}
        mFragmentProgram->getGLSLProgram()->attachToProgramObject(mGLHandle);

		// the link
		glLinkProgram( mGLHandle );
		GL_CHECK_ERROR
			glGetProgramiv( mGLHandle, GL_LINK_STATUS, &mLinked );
		GL_CHECK_ERROR

		mTriedToLinkAndFailed = !mLinked;

		logObjectInfo( getCombinedName() + String("GLSL link result : "), mGLHandle );
		if(mLinked)
		{
			if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache() )
			{
				// add to the microcode to the cache
				String name;
				name = getCombinedName();

				// get buffer size
				GLint binaryLength = 0;
#if GL_OES_get_program_binary
				glGetProgramiv(mGLHandle, GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength);
#endif

				// turns out we need this param when loading
				GLenum binaryFormat = 0;

				// get the buffer
				GpuProgramManager::Microcode newMicrocode(OGRE_NEW MemoryDataStream(name,  binaryLength + sizeof(GLenum)));
				newMicrocode->seek(0);

#if GL_OES_get_program_binary
				// get binary
				glGetProgramBinaryOES(mGLHandle, binaryLength, NULL, (GLenum *)newMicrocode->getPtr(), newMicrocode->getPtr() + sizeof(GLenum));
#endif

				GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode);
			}
		}
	}
	//-----------------------------------------------------------------------
	const char * getAttributeSemanticString(VertexElementSemantic semantic)
	{
		switch(semantic)
		{
			case VES_POSITION:
				return "vertex";
			case VES_BLEND_WEIGHTS:
				return "blendWeights";
			case VES_NORMAL:
				return "normal";
			case VES_DIFFUSE:
				return "colour";
			case VES_SPECULAR:
				return "secondary_colour";
			case VES_BLEND_INDICES:
				return "blendIndices";
			case VES_TANGENT:
				return "tangent";
			case VES_BINORMAL:
				return "binormal";
			case VES_TEXTURE_COORDINATES:
				return "uv";
			default:
				assert(false && "Missing attribute!");
				return 0;
		};

	}
	//-----------------------------------------------------------------------
	GLuint GLSLESLinkProgram::getAttributeIndex(VertexElementSemantic semantic, uint index)
	{
		GLuint res = mCustomAttributesIndexs[semantic-1][index];
		if (res != NULL_CUSTOM_ATTRIBUTES_INDEX)
		{
			const char * attString = getAttributeSemanticString(semantic);
			GLint attrib = glGetAttribLocation(mGLHandle, attString);

			// sadly position is a special case
			if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX && semantic == VES_POSITION)
			{
				attrib = glGetAttribLocation(mGLHandle, "position");
			}

			// for uv and other case the index is a part of the name
			if (attrib == NOT_FOUND_CUSTOM_ATTRIBUTES_INDEX)
			{
				String attStringWithSemantic = String(attString) + StringConverter::toString(index);
				attrib = glGetAttribLocation(mGLHandle, attStringWithSemantic.c_str());
			}

			// update mCustomAttributesIndexs with the index we found (or didn't found)
			mCustomAttributesIndexs[semantic-1][index] = attrib;
			res = attrib;
		}
		return res;
	}
	//-----------------------------------------------------------------------
	bool GLSLESLinkProgram::isAttributeValid(VertexElementSemantic semantic, uint index)
	{
		return getAttributeIndex(semantic, index) != -1;
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::buildGLUniformReferences(void)
	{
		if (!mUniformRefsBuilt)
		{
			const GpuConstantDefinitionMap* vertParams = 0;
			const GpuConstantDefinitionMap* fragParams = 0;
			if (mVertexProgram)
			{
				vertParams = &(mVertexProgram->getGLSLProgram()->getConstantDefinitions().map);
			}
			if (mFragmentProgram)
			{
				fragParams = &(mFragmentProgram->getGLSLProgram()->getConstantDefinitions().map);
			}

			GLSLESLinkProgramManager::getSingleton().extractUniforms(
				mGLHandle, vertParams, fragParams, mGLUniformReferences);

			mUniformRefsBuilt = true;
		}
	}

	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::updateUniforms(GpuProgramParametersSharedPtr params,
		uint16 mask, GpuProgramType fromProgType)
	{
		// Iterate through uniform reference list and update uniform values
		GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin();
		GLUniformReferenceIterator endUniform = mGLUniformReferences.end();

		for (;currentUniform != endUniform; ++currentUniform)
		{
			// Only pull values from buffer it's supposed to be in (vertex or fragment)
			// This method will be called twice, once for vertex program params,
			// and once for fragment program params.
			if (fromProgType == currentUniform->mSourceProgType)
			{
				const GpuConstantDefinition* def = currentUniform->mConstantDef;
				if (def->variability & mask)
				{
					GLsizei glArraySize = (GLsizei)def->arraySize;

					// Get the index in the parameter real list
					switch (def->constType)
					{
					case GCT_FLOAT1:
						glUniform1fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT2:
						glUniform2fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT3:
						glUniform3fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_FLOAT4:
						glUniform4fv(currentUniform->mLocation, glArraySize,
							params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_2X2:
						glUniformMatrix2fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_3X3:
						glUniformMatrix3fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_4X4:
						glUniformMatrix4fv(currentUniform->mLocation, glArraySize,
							GL_FALSE, params->getFloatPointer(def->physicalIndex));
						break;
					case GCT_INT1:
						glUniform1iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT2:
						glUniform2iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT3:
						glUniform3iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_INT4:
						glUniform4iv(currentUniform->mLocation, glArraySize,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_SAMPLER1D:
					case GCT_SAMPLER1DSHADOW:
					case GCT_SAMPLER2D:
					case GCT_SAMPLER2DSHADOW:
					case GCT_SAMPLER3D:
					case GCT_SAMPLERCUBE:
						// Samplers handled like 1-element ints
						glUniform1iv(currentUniform->mLocation, 1,
							(GLint*)params->getIntPointer(def->physicalIndex));
						break;
					case GCT_MATRIX_2X3:
					case GCT_MATRIX_2X4:
					case GCT_MATRIX_3X2:
					case GCT_MATRIX_3X4:
					case GCT_MATRIX_4X2:
					case GCT_MATRIX_4X3:
                    case GCT_UNKNOWN:
                        break;

					} // End switch
                    GL_CHECK_ERROR;
				} // Variability & mask
			} // fromProgType == currentUniform->mSourceProgType

  		} // End for
	}
	//-----------------------------------------------------------------------
	void GLSLESLinkProgram::updatePassIterationUniforms(GpuProgramParametersSharedPtr params)
	{
		if (params->hasPassIterationNumber())
		{
			size_t index = params->getPassIterationNumberIndex();

			GLUniformReferenceIterator currentUniform = mGLUniformReferences.begin();
			GLUniformReferenceIterator endUniform = mGLUniformReferences.end();

			// Need to find the uniform that matches the multi pass entry
			for (;currentUniform != endUniform; ++currentUniform)
			{
				// Get the index in the parameter real list
				if (index == currentUniform->mConstantDef->physicalIndex)
				{
					glUniform1fv(currentUniform->mLocation, 1, params->getFloatPointer(index));
                    GL_CHECK_ERROR;
					// There will only be one multipass entry
					return;
				}
			}
		}
    }
} // namespace Ogre
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/site_instance.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_details.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "content/common/notification_type.h"
#include "net/base/net_util.h"
#include "net/test/test_server.h"

class RenderViewHostManagerTest : public InProcessBrowserTest {
 public:
  RenderViewHostManagerTest() {
    EnableDOMAutomation();
  }

  static bool GetFilePathWithHostAndPortReplacement(
      const std::string& original_file_path,
      const net::HostPortPair& host_port_pair,
      std::string* replacement_path) {
    std::vector<net::TestServer::StringPair> replacement_text;
    replacement_text.push_back(
        make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
    return net::TestServer::GetFilePathWithReplacements(
        original_file_path, replacement_text, replacement_path);
  }
};

// Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
// and target=_blank should create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       SwapProcessWithRelNoreferrerAndTargetBlank) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a rel=noreferrer + target=blank link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefTargetBlankLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the tab to open.
  if (browser()->tab_count() < 2)
    ui_test_utils::WaitForNewTab(browser());

  // Opens in new tab.
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(1, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Wait for the cross-site transition in the new tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());
  EXPECT_FALSE(browser()->GetSelectedTabContents()->render_manager()->
                   pending_render_view_host());

  // Should have a new SiteInstance.
  scoped_refptr<SiteInstance> noref_blank_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_NE(orig_site_instance, noref_blank_site_instance);
}

// Test for crbug.com/24447.  Following a cross-site link with just
// target=_blank should not create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DontSwapProcessWithOnlyTargetBlank) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a target=blank link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickTargetBlankLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the tab to open.
  if (browser()->tab_count() < 2)
    ui_test_utils::WaitForNewTab(browser());

  // Opens in new tab.
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(1, browser()->selected_index());

  // Wait for the cross-site transition in the new tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> blank_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, blank_site_instance);
}

// Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
// and no target=_blank should not create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DontSwapProcessWithOnlyRelNoreferrer) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a rel=noreferrer link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the cross-site transition in the current tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());

  // Opens in same tab.
  EXPECT_EQ(1, browser()->tab_count());
  EXPECT_EQ(0, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> noref_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, noref_site_instance);
}

// Test for crbug.com/14505. This tests that chrome:// urls are still functional
// after download of a file while viewing another chrome://.
// Hangs flakily in Win, http://crbug.com/45040, and started hanging on Linux,
// Mac and ChromeOS, http://crbug.com/77762.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DISABLED_ChromeURLAfterDownload) {
  GURL downloads_url("chrome://downloads");
  GURL extensions_url("chrome://extensions");
  FilePath zip_download;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &zip_download));
  zip_download = zip_download.AppendASCII("zip").AppendASCII("test.zip");
  GURL zip_url = net::FilePathToFileURL(zip_download);

  ui_test_utils::NavigateToURL(browser(), downloads_url);
  ui_test_utils::NavigateToURL(browser(), zip_url);
  ui_test_utils::WaitForDownloadCount(
      browser()->profile()->GetDownloadManager(), 1);
  ui_test_utils::NavigateToURL(browser(), extensions_url);

  TabContents *contents = browser()->GetSelectedTabContents();
  ASSERT_TRUE(contents);
  bool webui_responded = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      contents->render_view_host(),
      L"",
      L"window.domAutomationController.send(window.webui_responded_);",
      &webui_responded));
  EXPECT_TRUE(webui_responded);
}

class BrowserClosedObserver : public NotificationObserver {
 public:
  explicit BrowserClosedObserver(Browser* browser) {
    registrar_.Add(this, NotificationType::BROWSER_CLOSED,
        Source<Browser>(browser));
    ui_test_utils::RunMessageLoop();
  }

  // NotificationObserver
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    switch (type.value) {
      case NotificationType::BROWSER_CLOSED:
        MessageLoopForUI::current()->Quit();
        break;
      default:
        NOTREACHED();
        break;
    }
  }

 private:
  NotificationRegistrar registrar_;
};

// Test for crbug.com/12745. This tests that if a download is initiated from
// a chrome:// page that has registered and onunload handler, the browser
// will be able to close.
// TODO(rafaelw): The fix for 12745 has now also been reverted. Another fix
// must be found before this can be re-enabled.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DISABLED_BrowserCloseAfterDownload) {
  GURL downloads_url("chrome://downloads");
  FilePath zip_download;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &zip_download));
  zip_download = zip_download.AppendASCII("zip").AppendASCII("test.zip");
  ASSERT_TRUE(file_util::PathExists(zip_download));
  GURL zip_url = net::FilePathToFileURL(zip_download);

  ui_test_utils::NavigateToURL(browser(), downloads_url);
  TabContents *contents = browser()->GetSelectedTabContents();
  ASSERT_TRUE(contents);
  bool result = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      contents->render_view_host(),
      L"",
      L"window.onunload = function() { var do_nothing = 0; }; "
      L"window.domAutomationController.send(true);",
      &result));
  EXPECT_TRUE(result);
  ui_test_utils::NavigateToURL(browser(), zip_url);

  ui_test_utils::WaitForDownloadCount(
    browser()->profile()->GetDownloadManager(), 1);

  browser()->CloseWindow();
  BrowserClosedObserver wait_for_close(browser());
}

// Test for crbug.com/76666.  A cross-site navigation that fails with a 204
// error should not make us ignore future renderer-initiated navigations.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, ClickLinkAfter204Error) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  // The links will point to the HTTPS server.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Load a cross-site page that fails with a 204 error.
  ui_test_utils::NavigateToURL(browser(), https_server.GetURL("nocontent"));

  // We should still be looking at the normal page.
  scoped_refptr<SiteInstance> post_nav_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, post_nav_site_instance);
  EXPECT_EQ("/files/click-noreferrer-links.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Renderer-initiated navigations should work.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the cross-site transition in the current tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());

  // Opens in same tab.
  EXPECT_EQ(1, browser()->tab_count());
  EXPECT_EQ(0, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> noref_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, noref_site_instance);
}
<commit_msg>Re-enable, attempt to fix ChromeURLAfterDownload browsertest<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/site_instance.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_details.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "content/common/notification_type.h"
#include "net/base/net_util.h"
#include "net/test/test_server.h"

class RenderViewHostManagerTest : public InProcessBrowserTest {
 public:
  RenderViewHostManagerTest() {
    EnableDOMAutomation();
  }

  static bool GetFilePathWithHostAndPortReplacement(
      const std::string& original_file_path,
      const net::HostPortPair& host_port_pair,
      std::string* replacement_path) {
    std::vector<net::TestServer::StringPair> replacement_text;
    replacement_text.push_back(
        make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
    return net::TestServer::GetFilePathWithReplacements(
        original_file_path, replacement_text, replacement_path);
  }
};

// Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
// and target=_blank should create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       SwapProcessWithRelNoreferrerAndTargetBlank) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a rel=noreferrer + target=blank link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefTargetBlankLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the tab to open.
  if (browser()->tab_count() < 2)
    ui_test_utils::WaitForNewTab(browser());

  // Opens in new tab.
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(1, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Wait for the cross-site transition in the new tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());
  EXPECT_FALSE(browser()->GetSelectedTabContents()->render_manager()->
                   pending_render_view_host());

  // Should have a new SiteInstance.
  scoped_refptr<SiteInstance> noref_blank_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_NE(orig_site_instance, noref_blank_site_instance);
}

// Test for crbug.com/24447.  Following a cross-site link with just
// target=_blank should not create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DontSwapProcessWithOnlyTargetBlank) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a target=blank link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickTargetBlankLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the tab to open.
  if (browser()->tab_count() < 2)
    ui_test_utils::WaitForNewTab(browser());

  // Opens in new tab.
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(1, browser()->selected_index());

  // Wait for the cross-site transition in the new tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> blank_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, blank_site_instance);
}

// Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
// and no target=_blank should not create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DontSwapProcessWithOnlyRelNoreferrer) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a rel=noreferrer link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the cross-site transition in the current tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());

  // Opens in same tab.
  EXPECT_EQ(1, browser()->tab_count());
  EXPECT_EQ(0, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> noref_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, noref_site_instance);
}

// Test for crbug.com/14505. This tests that chrome:// urls are still functional
// after download of a file while viewing another chrome://.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       ChromeURLAfterDownload) {
  GURL flags_url("chrome://flags");
  GURL extensions_url("chrome://extensions");
  FilePath zip_download;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &zip_download));
  zip_download = zip_download.AppendASCII("zip").AppendASCII("test.zip");
  GURL zip_url = net::FilePathToFileURL(zip_download);

  ui_test_utils::NavigateToURL(browser(), flags_url);
  ui_test_utils::NavigateToURL(browser(), zip_url);
  ui_test_utils::WaitForDownloadCount(
      browser()->profile()->GetDownloadManager(), 1);
  ui_test_utils::NavigateToURL(browser(), extensions_url);

  TabContents *contents = browser()->GetSelectedTabContents();
  ASSERT_TRUE(contents);
  bool webui_responded = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      contents->render_view_host(),
      L"",
      L"window.domAutomationController.send(window.webui_responded_);",
      &webui_responded));
  EXPECT_TRUE(webui_responded);
}

class BrowserClosedObserver : public NotificationObserver {
 public:
  explicit BrowserClosedObserver(Browser* browser) {
    registrar_.Add(this, NotificationType::BROWSER_CLOSED,
        Source<Browser>(browser));
    ui_test_utils::RunMessageLoop();
  }

  // NotificationObserver
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    switch (type.value) {
      case NotificationType::BROWSER_CLOSED:
        MessageLoopForUI::current()->Quit();
        break;
      default:
        NOTREACHED();
        break;
    }
  }

 private:
  NotificationRegistrar registrar_;
};

// Test for crbug.com/12745. This tests that if a download is initiated from
// a chrome:// page that has registered and onunload handler, the browser
// will be able to close.
// TODO(rafaelw): The fix for 12745 has now also been reverted. Another fix
// must be found before this can be re-enabled.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DISABLED_BrowserCloseAfterDownload) {
  GURL downloads_url("chrome://downloads");
  FilePath zip_download;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &zip_download));
  zip_download = zip_download.AppendASCII("zip").AppendASCII("test.zip");
  ASSERT_TRUE(file_util::PathExists(zip_download));
  GURL zip_url = net::FilePathToFileURL(zip_download);

  ui_test_utils::NavigateToURL(browser(), downloads_url);
  TabContents *contents = browser()->GetSelectedTabContents();
  ASSERT_TRUE(contents);
  bool result = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      contents->render_view_host(),
      L"",
      L"window.onunload = function() { var do_nothing = 0; }; "
      L"window.domAutomationController.send(true);",
      &result));
  EXPECT_TRUE(result);
  ui_test_utils::NavigateToURL(browser(), zip_url);

  ui_test_utils::WaitForDownloadCount(
    browser()->profile()->GetDownloadManager(), 1);

  browser()->CloseWindow();
  BrowserClosedObserver wait_for_close(browser());
}

// Test for crbug.com/76666.  A cross-site navigation that fails with a 204
// error should not make us ignore future renderer-initiated navigations.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, ClickLinkAfter204Error) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  // The links will point to the HTTPS server.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Load a cross-site page that fails with a 204 error.
  ui_test_utils::NavigateToURL(browser(), https_server.GetURL("nocontent"));

  // We should still be looking at the normal page.
  scoped_refptr<SiteInstance> post_nav_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, post_nav_site_instance);
  EXPECT_EQ("/files/click-noreferrer-links.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Renderer-initiated navigations should work.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the cross-site transition in the current tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());

  // Opens in same tab.
  EXPECT_EQ(1, browser()->tab_count());
  EXPECT_EQ(0, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> noref_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, noref_site_instance);
}
<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013 - 2016, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "SurgSim/Blocks/KnotIdentificationBehavior.h"
#include "SurgSim/Framework/BasicSceneElement.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Scene.h"

#define MAKE_VEC(vec) std::vector<int>(vec, vec + sizeof(vec) / sizeof(int))

namespace SurgSim
{
namespace Blocks
{
class MockKnotIdentificationBehavior : public KnotIdentificationBehavior
{
public:
	explicit MockKnotIdentificationBehavior(const std::string& name) : KnotIdentificationBehavior(name) {}

	bool tryReidmeisterMove1(std::vector<int>* gaussCode, std::vector<int>* erased)
	{
		return KnotIdentificationBehavior::tryReidmeisterMove1(gaussCode, erased);
	}

	bool tryReidmeisterMove2(std::vector<int>* gaussCode, std::vector<int>* erased)
	{
		return KnotIdentificationBehavior::tryReidmeisterMove2(gaussCode, erased);
	}

	void clearReidmeisterMove3()
	{
		m_lastReidmeister3Code.clear();
	}

	bool tryReidmeisterMove3(std::vector<int>* gaussCode)
	{
		return KnotIdentificationBehavior::tryReidmeisterMove3(gaussCode);
	}

	void adjustGaussCodeForErasedCrossings(std::vector<int>* gaussCode, std::vector<int>* erased)
	{
		return KnotIdentificationBehavior::adjustGaussCodeForErasedCrossings(gaussCode, erased);
	}

	std::string identifyKnot(const std::vector<int>& gaussCode)
	{
		KnotIdentificationBehavior::identifyKnot(gaussCode);
		return KnotIdentificationBehavior::getKnotName();
	}
};

class KnotIdentificationBehaviorTest : public testing::Test
{
public:
	KnotIdentificationBehaviorTest() : testing::Test(), mockKnotIdentificationBehavior3("Test3")
	{

	}

	void SetUp()
	{

	}

	void testReidmeisterMove1(std::vector<int> gaussCodeBefore, std::vector<int> gaussCodeAfter,
							  std::vector<int> erased = std::vector<int>())
	{
		MockKnotIdentificationBehavior mockKnotIdentificationBehavior("Test ReidmeisterMove1");
		std::vector<int> erasedCalculated;
		bool expectedReturn = gaussCodeBefore != gaussCodeAfter;
		bool actualReturn = mockKnotIdentificationBehavior.tryReidmeisterMove1(&gaussCodeBefore, &erasedCalculated);
		EXPECT_EQ(expectedReturn, actualReturn);
		EXPECT_TRUE(gaussCodeBefore == gaussCodeAfter);
		std::sort(erased.begin(), erased.end(), std::greater<int>());
		std::sort(erasedCalculated.begin(), erasedCalculated.end(), std::greater<int>());
		EXPECT_TRUE(erased == erasedCalculated);
	}

	void testReidmeisterMove2(std::vector<int> gaussCodeBefore, std::vector<int> gaussCodeAfter,
							  std::vector<int> erased = std::vector<int>())
	{
		MockKnotIdentificationBehavior mockKnotIdentificationBehavior("Test ReidmeisterMove2");
		std::vector<int> erasedCalculated;
		bool expectedReturn = gaussCodeBefore != gaussCodeAfter;
		bool actualReturn = mockKnotIdentificationBehavior.tryReidmeisterMove2(&gaussCodeBefore, &erasedCalculated);
		EXPECT_EQ(expectedReturn, actualReturn);
		EXPECT_TRUE(gaussCodeBefore == gaussCodeAfter);
		std::sort(erased.begin(), erased.end(), std::greater<int>());
		std::sort(erasedCalculated.begin(), erasedCalculated.end(), std::greater<int>());
		EXPECT_TRUE(erased == erasedCalculated);
	}

	void testReidmeisterMove3(std::vector<int> gaussCodeBefore, std::vector<int> gaussCodeAfter, bool expectedReturn)
	{
		bool actualReturn = mockKnotIdentificationBehavior3.tryReidmeisterMove3(&gaussCodeBefore);
		EXPECT_EQ(expectedReturn, actualReturn);
		EXPECT_TRUE(gaussCodeBefore == gaussCodeAfter);
	}

	void clearReidmeisterMove3()
	{
		mockKnotIdentificationBehavior3.clearReidmeisterMove3();
	}

	void testAdjustGaussCodeForErasedCrossings(std::vector<int> gaussCodeBefore, std::vector<int> gaussCodeAfter,
		std::vector<int> erased)
	{
		MockKnotIdentificationBehavior mockKnotIdentificationBehavior("Test AdjustGaussCodeForErasedCrossings");
		mockKnotIdentificationBehavior.adjustGaussCodeForErasedCrossings(&gaussCodeBefore, &erased);
		EXPECT_TRUE(gaussCodeBefore == gaussCodeAfter);
	}

	void testIdentifyKnot(std::vector<int> gaussCode, std::string expected)
	{
		MockKnotIdentificationBehavior mockKnotIdentificationBehavior("Test IdentifyKnot");
		auto actual = mockKnotIdentificationBehavior.identifyKnot(gaussCode);
		EXPECT_TRUE(expected == actual);
	}

	MockKnotIdentificationBehavior mockKnotIdentificationBehavior3;
};

TEST_F(KnotIdentificationBehaviorTest, ReidmeisterMove1)
{
	{
		int input[] = {1, -2, 3, -1, 2, -3};
		int expected[] = {1, -2, 3, -1, 2, -3};
		testReidmeisterMove1(MAKE_VEC(input), MAKE_VEC(expected));
	}
	{
		int input[] = {1, -2, 3, -3, -1, 2};
		int expected[] = {1, -2, -1, 2};
		int erased[] = {3};
		testReidmeisterMove1(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {3, 1, -2, -1, 2, -3};
		int expected[] = {1, -2, -1, 2};
		int erased[] = {3};
		testReidmeisterMove1(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {3, 1, 4, -4, -2, 6, -6, -1, -5, 5, 2, -3};
		int expected[] = {1, -2, -1, 2};
		int erased[] = {3, 4, 5, 6};
		testReidmeisterMove1(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {3, 1, 4, -4, -2, 6, 7, -6, -7, -1, -5, 5, 2, -3};
		int expected[] = {1, -2, 6, 7, -6, -7, -1, 2};
		int erased[] = {3, 4, 5};
		testReidmeisterMove1(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
}

TEST_F(KnotIdentificationBehaviorTest, ReidmeisterMove2)
{
	{
		int input[] = {3, 1, -2, -1, 2, -3, 4, 5, -4, -5};
		int expected[] = {3, 1, -2, -1, 2, -3};
		int erased[] = {4, 5};
		testReidmeisterMove2(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {-5, 3, 1, -2, -1, 2, -3, 4, 5, -4};
		int expected[] = {3, 1, -2, -1, 2, -3};
		int erased[] = {4, 5};
		testReidmeisterMove2(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {3, 1, -2, 7, 6, -1, 2, -3, 4, 5, -7, -6, -4, -5};
		int expected[] = {3, 1, -2, -1, 2, -3, 4, 5, -4, -5};
		int erased[] = {6, 7};
		testReidmeisterMove2(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
}

TEST_F(KnotIdentificationBehaviorTest, ReidmeisterMove3)
{
	{
		int input[] = {-1, -3, -2, 1, 2, 3};
		int expected[] = {-1, -3, 3, -2, 1, 2};
		clearReidmeisterMove3();
		testReidmeisterMove3(MAKE_VEC(input), MAKE_VEC(expected), true);
		int expected2[] = {2, -3, -2, 3, 1, -1};
		testReidmeisterMove3(MAKE_VEC(expected), MAKE_VEC(expected2), true);
		int expected3[] = {3, -1, -3, 1, 2, -2};
		testReidmeisterMove3(MAKE_VEC(expected2), MAKE_VEC(expected3), true);
		int expected4[] = {-2, -1, 1, -3, 2, 3};
		testReidmeisterMove3(MAKE_VEC(expected3), MAKE_VEC(expected4), true);
		testReidmeisterMove3(MAKE_VEC(expected4), MAKE_VEC(input), false);
	}
	{
		int input[] = {3, 1, -4, -2, -1, -5, 2, -3, 4, 5};
		int expected[] = {3, 1, -4, -3, -2, -5, -1, 2, 4, 5};
		clearReidmeisterMove3();
		testReidmeisterMove3(MAKE_VEC(input), MAKE_VEC(expected), true);
	}
}

TEST_F(KnotIdentificationBehaviorTest, AdjustGaussCodeForErasedCrossings)
{
	{
		int input[] = {3, -4, 5, -3, 4, -5};
		int expected[] = {1, -2, 3, -1, 2, -3};
		int erased[] = {1, 2};
		testAdjustGaussCodeForErasedCrossings(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {1, -4, 5, -1, 4, -5};
		int expected[] = {1, -2, 3, -1, 2, -3};
		int erased[] = {2, 3};
		testAdjustGaussCodeForErasedCrossings(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
}

TEST_F(KnotIdentificationBehaviorTest, IdentityKnot)
{
	{
		testIdentifyKnot(std::vector<int>(), "No Knot");
	}
	{
		int input[] = {1, -4, 5, -1, 4, -5};
		testIdentifyKnot(MAKE_VEC(input), "Unknown Knot");
	}
	{
		int input[] = {1, -2, 3, -1, 2, -3};
		testIdentifyKnot(MAKE_VEC(input), "Trefoil Knot");
	}
	{
		int input[] = {-1, 2, -3, 1, -2, 3};
		testIdentifyKnot(MAKE_VEC(input), "Trefoil Knot");
	}
	{
		int input[] = {-3, 1, -2, 3, -1, 2};
		testIdentifyKnot(MAKE_VEC(input), "Trefoil Knot");
	}
}
}
}
<commit_msg>Fix unit test<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013 - 2016, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "SurgSim/Blocks/KnotIdentificationBehavior.h"
#include "SurgSim/Framework/BasicSceneElement.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Scene.h"

#define MAKE_VEC(vec) std::vector<int>(vec, vec + sizeof(vec) / sizeof(int))

namespace SurgSim
{
namespace Blocks
{
class MockKnotIdentificationBehavior : public KnotIdentificationBehavior
{
public:
	explicit MockKnotIdentificationBehavior(const std::string& name) : KnotIdentificationBehavior(name) {}

	bool tryReidmeisterMove1(std::vector<int>* gaussCode, std::vector<int>* erased)
	{
		return KnotIdentificationBehavior::tryReidmeisterMove1(gaussCode, erased);
	}

	bool tryReidmeisterMove2(std::vector<int>* gaussCode, std::vector<int>* erased)
	{
		return KnotIdentificationBehavior::tryReidmeisterMove2(gaussCode, erased);
	}

	void clearReidmeisterMove3()
	{
		data.code.clear();
	}

	bool tryReidmeisterMove3(std::vector<int>* gaussCode)
	{
		return KnotIdentificationBehavior::tryReidmeisterMove3(gaussCode, &data);
	}

	void adjustGaussCodeForErasedCrossings(std::vector<int>* gaussCode, std::vector<int>* erased)
	{
		return KnotIdentificationBehavior::adjustGaussCodeForErasedCrossings(gaussCode, erased);
	}

	std::string identifyKnot(const std::vector<int>& gaussCode)
	{
		KnotIdentificationBehavior::identifyKnot(gaussCode);
		return KnotIdentificationBehavior::getKnotName();
	}

	KnotIdentificationBehavior::ReidmeisterMove3Data data;
};

class KnotIdentificationBehaviorTest : public testing::Test
{
public:
	KnotIdentificationBehaviorTest() : testing::Test(), mockKnotIdentificationBehavior3("Test3")
	{

	}

	void SetUp()
	{

	}

	void testReidmeisterMove1(std::vector<int> gaussCodeBefore, std::vector<int> gaussCodeAfter,
							  std::vector<int> erased = std::vector<int>())
	{
		MockKnotIdentificationBehavior mockKnotIdentificationBehavior("Test ReidmeisterMove1");
		std::vector<int> erasedCalculated;
		bool expectedReturn = gaussCodeBefore != gaussCodeAfter;
		bool actualReturn = mockKnotIdentificationBehavior.tryReidmeisterMove1(&gaussCodeBefore, &erasedCalculated);
		EXPECT_EQ(expectedReturn, actualReturn);
		EXPECT_TRUE(gaussCodeBefore == gaussCodeAfter);
		std::sort(erased.begin(), erased.end(), std::greater<int>());
		std::sort(erasedCalculated.begin(), erasedCalculated.end(), std::greater<int>());
		EXPECT_TRUE(erased == erasedCalculated);
	}

	void testReidmeisterMove2(std::vector<int> gaussCodeBefore, std::vector<int> gaussCodeAfter,
							  std::vector<int> erased = std::vector<int>())
	{
		MockKnotIdentificationBehavior mockKnotIdentificationBehavior("Test ReidmeisterMove2");
		std::vector<int> erasedCalculated;
		bool expectedReturn = gaussCodeBefore != gaussCodeAfter;
		bool actualReturn = mockKnotIdentificationBehavior.tryReidmeisterMove2(&gaussCodeBefore, &erasedCalculated);
		EXPECT_EQ(expectedReturn, actualReturn);
		EXPECT_TRUE(gaussCodeBefore == gaussCodeAfter);
		std::sort(erased.begin(), erased.end(), std::greater<int>());
		std::sort(erasedCalculated.begin(), erasedCalculated.end(), std::greater<int>());
		EXPECT_TRUE(erased == erasedCalculated);
	}

	void testReidmeisterMove3(std::vector<int> gaussCodeBefore, std::vector<int> gaussCodeAfter, bool expectedReturn)
	{
		bool actualReturn = mockKnotIdentificationBehavior3.tryReidmeisterMove3(&gaussCodeBefore);
		EXPECT_EQ(expectedReturn, actualReturn);
		EXPECT_TRUE(gaussCodeBefore == gaussCodeAfter);
	}

	void clearReidmeisterMove3()
	{
		mockKnotIdentificationBehavior3.clearReidmeisterMove3();
	}

	void testAdjustGaussCodeForErasedCrossings(std::vector<int> gaussCodeBefore, std::vector<int> gaussCodeAfter,
		std::vector<int> erased)
	{
		MockKnotIdentificationBehavior mockKnotIdentificationBehavior("Test AdjustGaussCodeForErasedCrossings");
		mockKnotIdentificationBehavior.adjustGaussCodeForErasedCrossings(&gaussCodeBefore, &erased);
		EXPECT_TRUE(gaussCodeBefore == gaussCodeAfter);
	}

	void testIdentifyKnot(std::vector<int> gaussCode, std::string expected)
	{
		MockKnotIdentificationBehavior mockKnotIdentificationBehavior("Test IdentifyKnot");
		auto actual = mockKnotIdentificationBehavior.identifyKnot(gaussCode);
		EXPECT_TRUE(expected == actual);
	}

	MockKnotIdentificationBehavior mockKnotIdentificationBehavior3;
};

TEST_F(KnotIdentificationBehaviorTest, ReidmeisterMove1)
{
	{
		int input[] = {1, -2, 3, -1, 2, -3};
		int expected[] = {1, -2, 3, -1, 2, -3};
		testReidmeisterMove1(MAKE_VEC(input), MAKE_VEC(expected));
	}
	{
		int input[] = {1, -2, 3, -3, -1, 2};
		int expected[] = {1, -2, -1, 2};
		int erased[] = {3};
		testReidmeisterMove1(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {3, 1, -2, -1, 2, -3};
		int expected[] = {1, -2, -1, 2};
		int erased[] = {3};
		testReidmeisterMove1(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {3, 1, 4, -4, -2, 6, -6, -1, -5, 5, 2, -3};
		int expected[] = {1, -2, -1, 2};
		int erased[] = {3, 4, 5, 6};
		testReidmeisterMove1(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {3, 1, 4, -4, -2, 6, 7, -6, -7, -1, -5, 5, 2, -3};
		int expected[] = {1, -2, 6, 7, -6, -7, -1, 2};
		int erased[] = {3, 4, 5};
		testReidmeisterMove1(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
}

TEST_F(KnotIdentificationBehaviorTest, ReidmeisterMove2)
{
	{
		int input[] = {3, 1, -2, -1, 2, -3, 4, 5, -4, -5};
		int expected[] = {3, 1, -2, -1, 2, -3};
		int erased[] = {4, 5};
		testReidmeisterMove2(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {-5, 3, 1, -2, -1, 2, -3, 4, 5, -4};
		int expected[] = {3, 1, -2, -1, 2, -3};
		int erased[] = {4, 5};
		testReidmeisterMove2(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {3, 1, -2, 7, 6, -1, 2, -3, 4, 5, -7, -6, -4, -5};
		int expected[] = {3, 1, -2, -1, 2, -3, 4, 5, -4, -5};
		int erased[] = {6, 7};
		testReidmeisterMove2(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
}

TEST_F(KnotIdentificationBehaviorTest, ReidmeisterMove3)
{
	{
		int input[] = {-1, -3, -2, 1, 2, 3};
		int expected[] = {-1, -3, 3, -2, 1, 2};
		clearReidmeisterMove3();
		testReidmeisterMove3(MAKE_VEC(input), MAKE_VEC(expected), true);
		int expected2[] = {2, -3, -2, 3, 1, -1};
		testReidmeisterMove3(MAKE_VEC(expected), MAKE_VEC(expected2), true);
		int expected3[] = {3, -1, -3, 1, 2, -2};
		testReidmeisterMove3(MAKE_VEC(expected2), MAKE_VEC(expected3), true);
		int expected4[] = {-2, -1, 1, -3, 2, 3};
		testReidmeisterMove3(MAKE_VEC(expected3), MAKE_VEC(expected4), true);
		testReidmeisterMove3(MAKE_VEC(expected4), MAKE_VEC(input), false);
	}
	{
		int input[] = {3, 1, -4, -2, -1, -5, 2, -3, 4, 5};
		int expected[] = {3, 1, -4, -3, -2, -5, -1, 2, 4, 5};
		clearReidmeisterMove3();
		testReidmeisterMove3(MAKE_VEC(input), MAKE_VEC(expected), true);
	}
}

TEST_F(KnotIdentificationBehaviorTest, AdjustGaussCodeForErasedCrossings)
{
	{
		int input[] = {3, -4, 5, -3, 4, -5};
		int expected[] = {1, -2, 3, -1, 2, -3};
		int erased[] = {1, 2};
		testAdjustGaussCodeForErasedCrossings(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
	{
		int input[] = {1, -4, 5, -1, 4, -5};
		int expected[] = {1, -2, 3, -1, 2, -3};
		int erased[] = {2, 3};
		testAdjustGaussCodeForErasedCrossings(MAKE_VEC(input), MAKE_VEC(expected), MAKE_VEC(erased));
	}
}

TEST_F(KnotIdentificationBehaviorTest, IdentityKnot)
{
	{
		testIdentifyKnot(std::vector<int>(), "No Knot");
	}
	{
		int input[] = {1, -4, 5, -1, 4, -5};
		testIdentifyKnot(MAKE_VEC(input), "Unknown Knot");
	}
	{
		int input[] = {1, -2, 3, -1, 2, -3};
		testIdentifyKnot(MAKE_VEC(input), "Trefoil Knot");
	}
	{
		int input[] = {-1, 2, -3, 1, -2, 3};
		testIdentifyKnot(MAKE_VEC(input), "Trefoil Knot");
	}
	{
		int input[] = {-3, 1, -2, 3, -1, 2};
		testIdentifyKnot(MAKE_VEC(input), "Trefoil Knot");
	}
}
}
}
<|endoftext|>


<commit_before>#include <iostream> //cout
#include <string>
#include "qmc.h"
#include <gmc.h> 	//LaGenMatComplex
#include <laslv.h>  //LUFactorizeIP, LaLUInverseIP, etc.
#include <blas3pp.h>
#include <random>   //random_device, mt19937
#include <cstdlib>	//rand, srand
#include <math.h>

using namespace std;

/* ---- WORKING ---- */
/* -- Output -- */
void print_sites(const int array[], const int array_size){
    for(int i = 0; i < array_size; i++){
        cout.width(7);
        cout << array[i];
    }
    cout << endl;
}

/* -- Generation -- */
/* Random Numbers */
int random_spin(){
    random_device rd;
    mt19937 gen(rd());
    std::uniform_int_distribution<> dist(0, 1);
    return dist(gen)*2 - 1;
}
double random_probability(){
    random_device rd;
    mt19937 gen(rd());
    std::uniform_real_distribution<> dist(0, 1);
    return dist(gen);
}
/* Structures */
void generate_lattice_array(const int array_size, int array[]){
    for(int i = 0; i < array_size; i++){
        array[i] = random_spin();
    }
}

/* -- Calculation -- */
/* Initial Parameters */
/* Weights */

/* -- Testing -- */
void test_spin_generation(){
    for(int i = 0; i < 5; i++){
        cout.width(10);
        cout << random_spin();
    }
    cout << endl;
}
void test_probability_generation(){
    for(int i = 0; i < 5; i++){
        cout.width(5);
        cout << random_probability();
    }
    cout << endl;
}
void test_lattice_array_generation(){
    int array_size = 10, array[array_size];
    generate_lattice_array(array_size, array);
    print_sites(array, array_size);
}

/* ---- TESTING ----*/
/* Output */

/* Randomisation */

/* Generation */

/* -- Calculation -- */
void initial_parameter_calculation(const double beta, const double U, double lambda, double delta_tau, int time_slices){
    delta_tau = delta_tau_calculation(U);
    lambda = lambda_calculation(U);
    time_slices = beta / lambda;
}
double lambda_calculation(const double U){
    return acoshf(exp(sqrt(0.125*U)/2));
}
double delta_tau_calculation(const double U){
    return sqrt(0.125 / U);
}

// void V_calculation(const double lattice[], const int time_size, const double U, const double lambda, const int sigma, const double delta_tau, LaGenMatComplex& V){//should be working
//     /* initialise everything */
//     double elements[time_size];
//     // double mu = 0;
//
//     /* calculate lambda sigma s_l */
//     for(int i = 0; i < time_size; i++){
//         scalar_multiplication(lattice[i], lambda / delta_tau, elements[i]);
//         elements[i].r = elements[i].r + mu - U / 2;
//     }
//     /* given a lattice */
//     array_to_diag(elements, time_size, V);
// }

/* Testing */
void test_parameter_calculation(){
    double beta = 10, U = 1, lambda, delta_tau, time_slices;
    initial_parameter_calculation(beta, U, lambda, delta_tau, time_slices);
    cout << "lambda = " << lambda << endl;
    cout << "delta tau = " << delta_tau << endl;
    cout << "time slices = " << time_slices << endl;
}

void test_sweep(){
    /* Plan */
    /* [ ] Input */
        // [ ] lattice_size - int
        // [ ] time_slices  - int
        // [ ] iterations   - int
        // [ ] lattice      - LaGenMatComplex
        // [ ] U            - double

    /* [ ] Processing */
        // [ ] generate a lattice of spins
        // [ ] sweep the lattice

    /* [ ] Output */
        // [ ] average spins
        // [ ] acceptance probabilities

    // int lattice_size = 5, time_slices = 4;
    // int matrix_size = lattice_size * time_slices;
    // int lattice_array[matrix_size];
    // generate_lattice_array(matrix_size, lattice_array);

}
void test_increasing_U(){
    /* Plan */

    /* [ ] Input */
        // [ ] matrix_size  - int
        // [ ] iterations   - int
        // [ ] lattice      - LaGenMatComplex
        // [ ] U            - double

    /* [ ] Processing */
        // [ ] for n increasing values of U
            // [ ] generate a lattice of spins
            // [ ] sweep the lattice

    /* [ ] Output */
        // [ ] acceptance probabilities
}

/* --- Main QMC Program --- */
int main(){
    test_parameter_calculation();
}
<commit_msg>generate initial parameters  - bug testing<commit_after>#include <iostream> //cout
#include <string>
#include "qmc.h"
#include <gmc.h> 	//LaGenMatComplex
#include <laslv.h>  //LUFactorizeIP, LaLUInverseIP, etc.
#include <blas3pp.h>
#include <random>   //random_device, mt19937
#include <cstdlib>	//rand, srand
#include <math.h>

using namespace std;

/* ---- WORKING ---- */
/* -- Output -- */
void print_sites(const int array[], const int array_size){
    for(int i = 0; i < array_size; i++){
        cout.width(7);
        cout << array[i];
    }
    cout << endl;
}

/* -- Generation -- */
/* Random Numbers */
int random_spin(){
    random_device rd;
    mt19937 gen(rd());
    std::uniform_int_distribution<> dist(0, 1);
    return dist(gen)*2 - 1;
}
double random_probability(){
    random_device rd;
    mt19937 gen(rd());
    std::uniform_real_distribution<> dist(0, 1);
    return dist(gen);
}
/* Structures */
void generate_lattice_array(const int array_size, int array[]){
    for(int i = 0; i < array_size; i++){
        array[i] = random_spin();
    }
}

/* -- Calculation -- */
/* Initial Parameters */
/* Weights */

/* -- Testing -- */
void test_spin_generation(){
    for(int i = 0; i < 5; i++){
        cout.width(10);
        cout << random_spin();
    }
    cout << endl;
}
void test_probability_generation(){
    for(int i = 0; i < 5; i++){
        cout.width(5);
        cout << random_probability();
    }
    cout << endl;
}
void test_lattice_array_generation(){
    int array_size = 10, array[array_size];
    generate_lattice_array(array_size, array);
    print_sites(array, array_size);
}

/* ---- TESTING ----*/
/* Output */

/* Randomisation */

/* Generation */

/* -- Calculation -- */

double lambda_calculation(const double U){
    return acoshf(exp(sqrt(0.125*U)/2));
}
double delta_tau_calculation(const double U){
    return sqrt(0.125 / U);
}
void initial_parameter_calculation(const double beta, const double U, double lambda, double delta_tau, int time_slices){
    delta_tau = delta_tau_calculation(U);
    lambda = lambda_calculation(U);
    time_slices = beta / lambda;
}

// void V_calculation(const double lattice[], const int time_size, const double U, const double lambda, const int sigma, const double delta_tau, LaGenMatComplex& V){//should be working
//     /* initialise everything */
//     double elements[time_size];
//     // double mu = 0;
//
//     /* calculate lambda sigma s_l */
//     for(int i = 0; i < time_size; i++){
//         scalar_multiplication(lattice[i], lambda / delta_tau, elements[i]);
//         elements[i].r = elements[i].r + mu - U / 2;
//     }
//     /* given a lattice */
//     array_to_diag(elements, time_size, V);
// }

/* Testing */
void test_parameter_calculation(){
    double beta = 10, U = 1, lambda, delta_tau, time_slices;
    initial_parameter_calculation(beta, U, lambda, delta_tau, time_slices);
    cout << "lambda = " << lambda << endl;
    cout << "delta tau = " << delta_tau << endl;
    cout << "time slices = " << time_slices << endl;
}

void test_sweep(){
    /* Plan */
    /* [ ] Input */
        // [ ] lattice_size - int
        // [ ] time_slices  - int
        // [ ] iterations   - int
        // [ ] lattice      - LaGenMatComplex
        // [ ] U            - double

    /* [ ] Processing */
        // [ ] generate a lattice of spins
        // [ ] sweep the lattice

    /* [ ] Output */
        // [ ] average spins
        // [ ] acceptance probabilities

    // int lattice_size = 5, time_slices = 4;
    // int matrix_size = lattice_size * time_slices;
    // int lattice_array[matrix_size];
    // generate_lattice_array(matrix_size, lattice_array);

}
void test_increasing_U(){
    /* Plan */

    /* [ ] Input */
        // [ ] matrix_size  - int
        // [ ] iterations   - int
        // [ ] lattice      - LaGenMatComplex
        // [ ] U            - double

    /* [ ] Processing */
        // [ ] for n increasing values of U
            // [ ] generate a lattice of spins
            // [ ] sweep the lattice

    /* [ ] Output */
        // [ ] acceptance probabilities
}

/* --- Main QMC Program --- */
int main(){
    test_parameter_calculation();
}
<|endoftext|>


<commit_before>#include <iostream> //cout
#include <string>
#include "qmc.h"
#include <gmd.h> 	//LaGenMatDouble
#include <laslv.h>  //LUFactorizeIP, LaLUInverseIP, etc.
#include <blas3pp.h>
#include <random>   //random_device, mt19937
#include <cstdlib>	//rand, srand
#include <math.h>

using namespace std;

/* ------ WORKING ------ */

/* -- Output -- */
void print_matrix(const LaGenMatDouble& matrix){
	cout << matrix << endl;
}
void print_matrix(const LaGenMatDouble& matrix, const string name){
	cout << name << ":" << endl << matrix << endl;
}
void print_sites(const double array[], const int array_size){
    for(int i = 0; i < array_size; i++){
        cout.width(7);
        cout << array[i];
    }
    cout << endl;
}
void print_vector(const LaVectorComplex& vector, const string name){
    cout << name << ":" << endl << vector << endl;
}
/* -- Generation -- */
// Random Numbers
int random_spin(){
    random_device rd;
    mt19937 gen(rd());
    std::uniform_int_distribution<> dist(0, 1);
    return dist(gen)*2 - 1;
}
double random_probability(){
    random_device rd;
    mt19937 gen(rd());
    std::uniform_real_distribution<> dist(0, 1);
    return dist(gen);
}
// Structures
void generate_lattice_array(double array[], const int array_size){
    for(int i = 0; i < array_size; i++){
        array[i] = random_spin();
    }
}

/* -- Calculation -- */
// Initial Parameters
void initial_parameter_calculation(const double U, const double beta, double& lambda, double& delta_tau, double& time_slices){
    delta_tau = sqrt(0.125 / U);
    lambda = acosh(exp(sqrt(0.125*U)/2));
    time_slices = beta / lambda;
}
// Weights
void generate_H(const int matrix_size, LaGenMatDouble& H){
    /* initialise everything */
    int matrix_volume = matrix_size * matrix_size, i;
    double elements[matrix_volume];

    /* generate the matrix */
    for(int row = 0; row < matrix_size; row++){
        for (int column = 0; column < matrix_size; column++) {
            i = (matrix_size * row) + column;
            if(abs(row - column) == 1 || abs(row - column) == matrix_size - 1){
                elements[i] = -1;
            }else{
                elements[i] = 0;
            }
        }
    }
    H = LaGenMatDouble(elements, matrix_size, matrix_size, false);

    /* print the matrix */
    print_matrix(H, "H");
}
void test_H(){
    /* initialise everything */
    int matrix_size = 5;
    LaGenMatDouble H;
    LaVectorComplex eigenvalues = LaVectorComplex(matrix_size);
    LaGenMatDouble eigenvectors = LaGenMatDouble::zeros(matrix_size, matrix_size);
    /* generate matrix */
    generate_H(matrix_size, H);
    print_matrix(H);
    /* calculate eigenstuff */
    LaEigSolve(H, eigenvalues, eigenvectors);
    print_vector(eigenvalues, "eigenvalues");
    // eigenvalues are 2 cos(n pi / q), where q = the matrix size
}

/* -- Testing -- */
void test_spin_generation(){
    for(int i = 0; i < 5; i++){
        cout.width(10);
        cout << random_spin();
    }
    cout << endl;
}
void test_probability_generation(){
    for(int i = 0; i < 5; i++){
        cout.width(5);
        cout << random_probability();
    }
    cout << endl;
}
void test_lattice_array_generation(){
    int array_size = 10;
    double array[array_size];
    generate_lattice_array(array, array_size);
    print_sites(array, array_size);
}
void test_parameter_calculation(){
    double beta = 10, U = 1, lambda, delta_tau, time_slices;
    initial_parameter_calculation(U, beta, lambda, delta_tau, time_slices);
    cout << "lambda = " << lambda << endl;
    cout << "delta tau = " << delta_tau << endl;
    cout << "time slices = " << time_slices << endl;
}
void test_matrix_storage(){
    /* initialise everything */
    int array_width = 5, array_size = array_width * array_width;
    double array[array_size];
    /* generate the lattice */
    for(int i = 0; i < array_size; i++){
        array[i] = i;
    }
    LaGenMatDouble matrix(array, array_width, array_width, true);
    /* test the results */
    print_matrix(matrix, "true");
    array[5] = -array[5];
        // row_ordering = false does change the matrix, so they're linked
        // row_ordering = tru does not change the matrix, so they're copied
    print_matrix(matrix, "true (changed)");

}

/* ------ TO TEST ------ */
// COMPLEX -> double
// float -> double
// LaVectorComplex -> LaGenMatDouble
// .r ->
// .i ->

void array_to_diag(const double array[], const int len, LaGenMatDouble& diag){
    diag = 0;
    for(int i = 0; i < len; i++){
        diag(i, i) = array[i];
    }
}
void V_calculation(const double time_slice[], const int time_size, const double U, const double lambda, const double sigma, const double delta_tau, LaGenMatDouble& V){//should be working
    /* initialise everything */
    double V_elements[time_size], mu = 0;
    /* V_ii = lambda sigma s_l / delta_tau + (mu - U/2) */
    for(int i = 0; i < time_size; i++){
        V_elements[i] = lambda * sigma * time_slice[i] / delta_tau + mu - U/2;
    }
    /* save to diagonal matrix */
    array_to_diag(V_elements, time_size, V);
}
void test_V_generation(){//should work

    /* initialise everything */
    int matrix_size = 5, placeholder_time_slices = 5;
    double time_slice[matrix_size], U = 1, beta = 10, lambda, sigma, delta_tau, time_slices;
    LaGenMatDouble V = LaGenMatDouble::zeros(matrix_size, matrix_size);

    /* calculate initial parameters */
    initial_parameter_calculation(U, beta, lambda, delta_tau, time_slices);

    /* generate the time_slice */
    generate_lattice_array(matrix_size, placeholder_time_slices);
    V_calculation(time_slice, matrix_size, U, lambda, sigma, delta_tau, V);

    /* print result */
    print_matrix(V, "V");
}

/* ------ Main QMC Program ------ */
int main(){
    test_parameter_calculation();
}
<commit_msg>implementing V - bug fixes<commit_after>#include <iostream> //cout
#include <string>
#include "qmc.h"
#include <gmd.h> 	//LaGenMatDouble
#include <laslv.h>  //LUFactorizeIP, LaLUInverseIP, etc.
#include <blas3pp.h>
#include <random>   //random_device, mt19937
#include <cstdlib>	//rand, srand
#include <math.h>

using namespace std;

/* ------ WORKING ------ */

/* -- Output -- */
void print_matrix(const LaGenMatDouble& matrix){
	cout << matrix << endl;
}
void print_matrix(const LaGenMatDouble& matrix, const string name){
	cout << name << ":" << endl << matrix << endl;
}
void print_sites(const double array[], const int array_size){
    for(int i = 0; i < array_size; i++){
        cout.width(7);
        cout << array[i];
    }
    cout << endl;
}
void print_vector(const LaVectorComplex& vector, const string name){
    cout << name << ":" << endl << vector << endl;
}
/* -- Generation -- */
// Random Numbers
int random_spin(){
    random_device rd;
    mt19937 gen(rd());
    std::uniform_int_distribution<> dist(0, 1);
    return dist(gen)*2 - 1;
}
double random_probability(){
    random_device rd;
    mt19937 gen(rd());
    std::uniform_real_distribution<> dist(0, 1);
    return dist(gen);
}
// Structures
void generate_lattice_array(double array[], const int array_size){
    for(int i = 0; i < array_size; i++){
        array[i] = random_spin();
    }
}

/* -- Calculation -- */
// Initial Parameters
void initial_parameter_calculation(const double U, const double beta, double& lambda, double& delta_tau, double& time_slices){
    delta_tau = sqrt(0.125 / U);
    lambda = acosh(exp(sqrt(0.125*U)/2));
    time_slices = beta / lambda;
}
// Weights
void generate_H(const int matrix_size, LaGenMatDouble& H){
    /* initialise everything */
    int matrix_volume = matrix_size * matrix_size, i;
    double elements[matrix_volume];

    /* generate the matrix */
    for(int row = 0; row < matrix_size; row++){
        for (int column = 0; column < matrix_size; column++) {
            i = (matrix_size * row) + column;
            if(abs(row - column) == 1 || abs(row - column) == matrix_size - 1){
                elements[i] = -1;
            }else{
                elements[i] = 0;
            }
        }
    }
    H = LaGenMatDouble(elements, matrix_size, matrix_size, false);

    /* print the matrix */
    print_matrix(H, "H");
}
void test_H(){
    /* initialise everything */
    int matrix_size = 5;
    LaGenMatDouble H;
    LaVectorComplex eigenvalues = LaVectorComplex(matrix_size);
    LaGenMatDouble eigenvectors = LaGenMatDouble::zeros(matrix_size, matrix_size);
    /* generate matrix */
    generate_H(matrix_size, H);
    print_matrix(H);
    /* calculate eigenstuff */
    LaEigSolve(H, eigenvalues, eigenvectors);
    print_vector(eigenvalues, "eigenvalues");
    // eigenvalues are 2 cos(n pi / q), where q = the matrix size
}

/* -- Testing -- */
void test_spin_generation(){
    for(int i = 0; i < 5; i++){
        cout.width(10);
        cout << random_spin();
    }
    cout << endl;
}
void test_probability_generation(){
    for(int i = 0; i < 5; i++){
        cout.width(5);
        cout << random_probability();
    }
    cout << endl;
}
void test_lattice_array_generation(){
    int array_size = 10;
    double array[array_size];
    generate_lattice_array(array, array_size);
    print_sites(array, array_size);
}
void test_parameter_calculation(){
    double beta = 10, U = 1, lambda, delta_tau, time_slices;
    initial_parameter_calculation(U, beta, lambda, delta_tau, time_slices);
    cout << "lambda = " << lambda << endl;
    cout << "delta tau = " << delta_tau << endl;
    cout << "time slices = " << time_slices << endl;
}
void test_matrix_storage(){
    /* initialise everything */
    int array_width = 5, array_size = array_width * array_width;
    double array[array_size];
    /* generate the lattice */
    for(int i = 0; i < array_size; i++){
        array[i] = i;
    }
    LaGenMatDouble matrix(array, array_width, array_width, true);
    /* test the results */
    print_matrix(matrix, "true");
    array[5] = -array[5];
        // row_ordering = false does change the matrix, so they're linked
        // row_ordering = tru does not change the matrix, so they're copied
    print_matrix(matrix, "true (changed)");

}

/* ------ TO TEST ------ */
// COMPLEX -> double
// float -> double
// LaVectorComplex -> LaGenMatDouble
// .r ->
// .i ->

void array_to_diag(const double array[], const int len, LaGenMatDouble& diag){
    diag = 0;
    for(int i = 0; i < len; i++){
        diag(i, i) = array[i];
    }
}
void V_calculation(const double time_slice[], const int time_size, const double U, const double lambda, const double sigma, const double delta_tau, LaGenMatDouble& V){//should be working
    /* initialise everything */
    double V_elements[time_size], mu = 0;
    /* V_ii = lambda sigma s_l / delta_tau + (mu - U/2) */
    for(int i = 0; i < time_size; i++){
        V_elements[i] = lambda * sigma * time_slice[i] / delta_tau + mu - U/2;
    }
    /* save to diagonal matrix */
    array_to_diag(V_elements, time_size, V);
}
void test_V_generation(){//should work

    /* initialise everything */
    int matrix_size = 5, placeholder_time_slices = 5;
    double time_slice[matrix_size], U = 1, beta = 10, lambda, sigma, delta_tau, time_slices;
    LaGenMatDouble V = LaGenMatDouble::zeros(matrix_size, matrix_size);

    /* calculate initial parameters */
    initial_parameter_calculation(U, beta, lambda, delta_tau, time_slices);

    /* generate the time_slice */
    generate_lattice_array(time_slice, placeholder_time_slices);
    V_calculation(time_slice, matrix_size, U, lambda, sigma, delta_tau, V);

    /* print result */
    print_matrix(V, "V");
}

/* ------ Main QMC Program ------ */
int main(){
    test_parameter_calculation();
}
<|endoftext|>