<commit_before>// Copyright (c) 2009 Stef Busking
// Distributed under the terms of the MIT License.

#include "GLTextureManager.h"

#include <sstream>

#ifndef NDEBUG
#include <iostream>
#endif

#include <cassert>

// ----------------------------------------------------------------------------
GLTextureManager *GLTextureManager::New()
{
	if (GLEW_VERSION_1_3)
	{
#ifndef NDEBUG
		std::cout
			<< "GLTextureManager: Using OpenGL 1.3 or higher"
			<< std::endl;
#endif
		return new GLTextureManager();
	}
	else if (GLEW_ARB_multitexture)
	{
		// TODO: add ARB fallback
#ifndef NDEBUG
		std::cerr
			<< "GLTextureManager: Falling back to ARB (not implemented!)"
			<< std::endl;
#endif
		return 0;
	}
	else
	{
#ifndef NDEBUG
		std::cerr
			<< "GLTextureManager: Multitexturing not supported!"
			<< std::endl;
#endif
		return 0;
	}
}

// ----------------------------------------------------------------------------
GLTextureManager::GLTextureManager() : currentProgram(0)
{
	// Get maximum number of texture units
	// NOTE: this seems to be the right parameter, but I'm not 100% sure...
	// GL_MAX_TEXTURE_UNITS is stuck at 4 on nvidia, however
	// GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS might be used as well.
	glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);

	// Initialize current bindings
	currentBinding.resize(maxTextureUnits, 0);
}

// ----------------------------------------------------------------------------
GLTextureManager::~GLTextureManager()
{
	// Make sure our textures are no longer bound
	Unbind();

	// Delete all managed textures
	std::map<std::string, GLTexture*>::iterator it = textures.begin();
	while (it != textures.end())
	{
		//const string name = it->first;
		GLTexture *tex = it->second;
		assert(tex);
		++it;
		delete tex;
	}
}

// ----------------------------------------------------------------------------
// Add a new sampler with the given name and texture, optionally add to store
GLTextureManager::SamplerId GLTextureManager::AddTexture(
	const std::string &name, GLTexture *tex, bool takeOwnership)
{
	// Do we already have a sampler with this name?
	SamplerId sampler = GetSampler(name);
	if (sampler == BAD_SAMPLER_ID)
	{
		// Find an unused SamplerId to register a new sampler
		if (!unusedSamplers.empty())
		{
			sampler = unusedSamplers.front();
			unusedSamplers.pop();
		}
		else
		{
			// No unused SamplerIds, add a new one
			sampler = samplers.size();
			samplers.push_back(0);
		}

		samplersByName[name] = sampler;
	}

	// If the sampler already has a texture and we own it, delete it
	GLTexture *samplerTex = samplers[sampler];
	if (samplerTex)
	{
		GLTexture *oldTex = GetTexture(name);
		// TODO: the sampler and store can be different if it was swapped out
		//assert(oldTex == samplers[sampler]);
		// For now, we DO NOT assume ownership of swapped in textures here;
		// the destructor won't either unless the SwapTexture TODO is fixed!

		// AddTexture however is a true replace operation, and therefore
		// deletes the old texture from the store.
		if (oldTex != tex) delete oldTex;
	}

	// Assign this texture to the sampler
	samplers[sampler] = tex;

	if (takeOwnership)
	{
		// Add the texture to the list
		textures[name] = tex;
	}

	return sampler;
}

// ----------------------------------------------------------------------------
// Get the sampler with the given name
GLTextureManager::SamplerId GLTextureManager::GetSampler(
	const std::string &name)
{
	std::map<std::string, SamplerId>::iterator sit = samplersByName.find(name);
	if (sit != samplersByName.end())
	{
		return sit->second;
	}
	else
	{
		return BAD_SAMPLER_ID;
	}
}

// ----------------------------------------------------------------------------
// Swap the texture assigned to the given sampler, returns the old texture
GLTexture *GLTextureManager::SwapTexture(SamplerId sampler, GLTexture *tex)
{
	assert(sampler >= 0
		&& static_cast<unsigned int>(sampler) < samplers.size());

	// Replace the texture on this sampler
	GLTexture *oldTex = samplers[sampler];
	samplers[sampler] = tex;

	// TODO: we should replace the stored copy as well (if we own this texture)
	// however, this operation should be as fast as possible, and we don't
	// know if tex is owned by us without knowing its name (see AddTexture)
	return oldTex;
}

// ----------------------------------------------------------------------------
// Unregister the given name as a sampler
void GLTextureManager::RemoveSampler(const std::string &name)
{
	// Find the sampler
	SamplerId sampler = GetSampler(name);
	if (sampler != BAD_SAMPLER_ID)
	{
		// TODO: invalidate any programs in cache that use this sampler?

		unusedSamplers.push(sampler);
		samplers[sampler] = 0;
		samplersByName.erase(name);
	}
}

// ----------------------------------------------------------------------------
// Specify that the given unit is managed elsewhere, but should be registered
// on programs using the given name
bool GLTextureManager::AddReservedSlot(const std::string &name, int unit)
{
	assert(0 <= unit && unit < maxTextureUnits);

	// Register reserved slot
	reserved[name] = unit;

	// Is any texture bound here?
	if (currentBinding[unit])
	{
		glActiveTexture(GL_TEXTURE0 + unit);
		currentBinding[unit]->UnbindCurrent();
		currentBinding[unit] = 0;
		glActiveTexture(GL_TEXTURE0);
	}

	// TODO: some more error checking could be useful (aliasing...)

	return true;
}

// ----------------------------------------------------------------------------
// Get a texture from the store
GLTexture *GLTextureManager::GetTexture(const std::string &name)
{
	// Do we know this texture?
	std::map<std::string, GLTexture*>::iterator texit =
		textures.find(name);

	if (texit == textures.end()) return 0;

	return texit->second;
}

// ----------------------------------------------------------------------------
// Get a texture from the store
const GLTexture *GLTextureManager::GetTexture(const std::string &name) const
{
	// Do we know this texture?
	std::map<std::string, GLTexture*>::const_iterator texit =
		textures.find(name);

	if (texit == textures.end()) return 0;

	return texit->second;
}

// ----------------------------------------------------------------------------
// Remove and return a texture from the store, or delete a reserved slot
GLTexture *GLTextureManager::RemoveTexture(const std::string &name)
{
	// Is this a reserved slot?
	std::map<std::string, int>::iterator rit = reserved.find(name);
	if (rit != reserved.end())
	{
		// Remove the reserved slot
		reserved.erase(name);
		return 0;
	}
	else
	{
		GLTexture *tex = GetTexture(name);
		// Ignore invalid removals
		if (!tex) return 0;

		// If this texture is currently bound, unbind it
		for (int unit = 0; unit < maxTextureUnits; ++unit)
		{
			if (currentBinding[unit] == tex)
			{
				glActiveTexture(GL_TEXTURE0 + unit);
				tex->UnbindCurrent();
				currentBinding[unit] = 0;
			}
		}
		glActiveTexture(GL_TEXTURE0);

		// Remove the texture from the store
		textures.erase(name);
		return tex;
	}
}

// ----------------------------------------------------------------------------
// Delete a texture from the store, or delete a reserved slot
void GLTextureManager::DeleteTexture(const std::string &name)
{
	GLTexture *tex = RemoveTexture(name);
	if (tex)
	{
#ifndef NDEBUG
		/*
		std::cout
			<< "GLTextureManager: Deleting texture '"
			<< name << "'" << std::endl;
		*/
#endif
		delete tex;
	}
}

// ----------------------------------------------------------------------------
// Reset all assignments, except reserved slots
void GLTextureManager::BeginNewPass()
{
	// Essentially, this means we simply unregister all programs
	std::map<GLProgram*, SamplerBindings>::iterator it = bindings.begin();
	while (it != bindings.end())
	{
		GLProgram *prog = it->first;
		++it;
		UnregisterProgram(prog);
	}
	currentProgram = 0;
}

// ----------------------------------------------------------------------------
// Bind all textures required by the currently active program
void GLTextureManager::Bind()
{
	// Make sure we have a current program
	if (!currentProgram) return;
	SamplerBindings &binding = bindings[currentProgram];

	for (int unit = 0; unit < maxTextureUnits; ++unit)
	{
		SamplerId samplerId = binding[unit];
		// Ignore unused / reserved units
		if (samplerId >= 0)
		{
			// Get the texture
			GLTexture *tex = samplers[samplerId];
			// This could be NULL due to programmer error
			// (removing a sampler without resetting programs that use it)
			//assert(tex);

			// Check if anything is bound to this unit
			GLTexture *oldTex = currentBinding[unit];
			if (oldTex == tex) continue;

			// Set up texture in OpenGL
			glActiveTexture(GL_TEXTURE0 + unit);
			if (oldTex) oldTex->UnbindCurrent();
			if (tex) tex->BindToCurrent();

			// Update current binding
			currentBinding[unit] = tex;
		}
	}
	glActiveTexture(GL_TEXTURE0);
}

// ----------------------------------------------------------------------------
// Unbind all currently bound textures
void GLTextureManager::Unbind()
{
	for (int unit = 0; unit < maxTextureUnits; ++unit)
	{
		GLTexture *tex = currentBinding[unit];
		if (tex)
		{
			glActiveTexture(GL_TEXTURE0 + unit);
			tex->UnbindCurrent();
			currentBinding[unit] = 0;
		}
	}
	glActiveTexture(GL_TEXTURE0);
}

// ----------------------------------------------------------------------------
bool GLTextureManager::SetupProgram(GLProgram *prog, bool updateIfKnown)
{
	// Set current program
	currentProgram = prog;

	bool ok = true;

	// Do we know this program?
	std::map<GLProgram*, SamplerBindings>::iterator it =
		bindings.find(prog);
	if (it == bindings.end() || updateIfKnown)
	{
		// Add new (or get and clear) bindings for this program
		SamplerBindings &binding = bindings[prog];
		binding.clear();
		binding.resize(maxTextureUnits, -1);

		// For finding available texture units
		unsigned int nextFreeUnit = 0;
		std::vector<bool> inUse;
		inUse.resize(maxTextureUnits, false);
		// Mark all reserved slots
		for (std::map<std::string, int>::const_iterator rit =
			reserved.begin(); rit != reserved.end(); ++rit)
		{
			inUse[rit->second] = true;
		}

		// Get the uniforms required for this program
		std::vector<GLUniformInfo> uniforms = prog->GetActiveUniforms();
		for (std::vector<GLUniformInfo>::iterator it = uniforms.begin();
			it != uniforms.end(); ++it)
		{
			// Is this a sampler?
			if (it->type == GL_SAMPLER_1D
				|| it->type == GL_SAMPLER_2D
				|| it->type == GL_SAMPLER_3D
				|| it->type == GL_SAMPLER_CUBE
				|| it->type == GL_SAMPLER_1D_SHADOW
				|| it->type == GL_SAMPLER_2D_SHADOW
				|| it->type == GL_SAMPLER_2D_RECT_ARB
				|| it->type == GL_SAMPLER_2D_RECT_SHADOW_ARB)
			{
				// Is this a reserved texture unit?
				// TODO: how to handle reserved slots in arrays?
				std::map<std::string, int>::const_iterator rit =
					reserved.find(it->name);
				if (rit != reserved.end())
				{
					// Reserved unit, only set location in program
					prog->UseTexture(it->name, rit->second);
				}
				else
				{
					// Is this a texture array?
					for (int element = 0; element < it->size; ++element)
					{
						// Build the name for this element
						std::string name;
						if (it->size > 1)
						{
							// Some implementations return name[0],
							// others just return name...
							std::string arrayName = it->name.substr(0,
								it->name.find('['));
							std::ostringstream elementName;
							elementName << arrayName << "[" << element << "]";
							name = elementName.str();
						}
						else
						{
							name = it->name;
						}

						// Find the matching SamplerId
						SamplerId sampler = GetSampler(name);
						// If size == 1 this could be a single-element array
						if (it->size == 1 && sampler == BAD_SAMPLER_ID)
						{
							std::string arrayName = it->name.substr(0,
								it->name.find('['));
							std::ostringstream elementName;
							elementName << arrayName << "[0]";
							sampler = GetSampler(elementName.str());
						}
						if (sampler == BAD_SAMPLER_ID)
						{
#ifndef NDEBUG
							std::cerr
								<< "GLTextureManager: "
								<< "Program requires unknown sampler '"
								<< name << "'" << std::endl;
#endif
							// TODO: we might want to re-check this sampler
							// Continue for now, but inform the caller
							ok = false;
						}
						else
						{
							// Find the next free texture unit
							while (nextFreeUnit != maxTextureUnits
								&& inUse[nextFreeUnit])
							{
								++nextFreeUnit;
							}
							if (nextFreeUnit == maxTextureUnits)
							{
								// We ran out of texture units!
#ifndef NDEBUG
								std::cerr
									<< "GLProgram: "
									<< "ran out of available texture units!"
									<< std::endl;
#endif
								return false;
							}

							// Assign sampler to unit
							binding[nextFreeUnit] = sampler;
							inUse[nextFreeUnit] = true;
							// Pass the unit id to program
							prog->UseTexture(name, nextFreeUnit);
						}
					}
				}
			}
		}
	}

	return ok;
}

// ----------------------------------------------------------------------------
// Remove bindings for the given program
void GLTextureManager::UnregisterProgram(GLProgram *prog)
{
	bindings.erase(prog);
}
<commit_msg>Fixed warning in GLTextureManager::SetupProgram.<commit_after>// Copyright (c) 2009 Stef Busking
// Distributed under the terms of the MIT License.

#include "GLTextureManager.h"

#include <sstream>

#ifndef NDEBUG
#include <iostream>
#endif

#include <cassert>

// ----------------------------------------------------------------------------
GLTextureManager *GLTextureManager::New()
{
	if (GLEW_VERSION_1_3)
	{
#ifndef NDEBUG
		std::cout
			<< "GLTextureManager: Using OpenGL 1.3 or higher"
			<< std::endl;
#endif
		return new GLTextureManager();
	}
	else if (GLEW_ARB_multitexture)
	{
		// TODO: add ARB fallback
#ifndef NDEBUG
		std::cerr
			<< "GLTextureManager: Falling back to ARB (not implemented!)"
			<< std::endl;
#endif
		return 0;
	}
	else
	{
#ifndef NDEBUG
		std::cerr
			<< "GLTextureManager: Multitexturing not supported!"
			<< std::endl;
#endif
		return 0;
	}
}

// ----------------------------------------------------------------------------
GLTextureManager::GLTextureManager() : currentProgram(0)
{
	// Get maximum number of texture units
	// NOTE: this seems to be the right parameter, but I'm not 100% sure...
	// GL_MAX_TEXTURE_UNITS is stuck at 4 on nvidia, however
	// GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS might be used as well.
	glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);

	// Initialize current bindings
	currentBinding.resize(maxTextureUnits, 0);
}

// ----------------------------------------------------------------------------
GLTextureManager::~GLTextureManager()
{
	// Make sure our textures are no longer bound
	Unbind();

	// Delete all managed textures
	std::map<std::string, GLTexture*>::iterator it = textures.begin();
	while (it != textures.end())
	{
		//const string name = it->first;
		GLTexture *tex = it->second;
		assert(tex);
		++it;
		delete tex;
	}
}

// ----------------------------------------------------------------------------
// Add a new sampler with the given name and texture, optionally add to store
GLTextureManager::SamplerId GLTextureManager::AddTexture(
	const std::string &name, GLTexture *tex, bool takeOwnership)
{
	// Do we already have a sampler with this name?
	SamplerId sampler = GetSampler(name);
	if (sampler == BAD_SAMPLER_ID)
	{
		// Find an unused SamplerId to register a new sampler
		if (!unusedSamplers.empty())
		{
			sampler = unusedSamplers.front();
			unusedSamplers.pop();
		}
		else
		{
			// No unused SamplerIds, add a new one
			sampler = samplers.size();
			samplers.push_back(0);
		}

		samplersByName[name] = sampler;
	}

	// If the sampler already has a texture and we own it, delete it
	GLTexture *samplerTex = samplers[sampler];
	if (samplerTex)
	{
		GLTexture *oldTex = GetTexture(name);
		// TODO: the sampler and store can be different if it was swapped out
		//assert(oldTex == samplers[sampler]);
		// For now, we DO NOT assume ownership of swapped in textures here;
		// the destructor won't either unless the SwapTexture TODO is fixed!

		// AddTexture however is a true replace operation, and therefore
		// deletes the old texture from the store.
		if (oldTex != tex) delete oldTex;
	}

	// Assign this texture to the sampler
	samplers[sampler] = tex;

	if (takeOwnership)
	{
		// Add the texture to the list
		textures[name] = tex;
	}

	return sampler;
}

// ----------------------------------------------------------------------------
// Get the sampler with the given name
GLTextureManager::SamplerId GLTextureManager::GetSampler(
	const std::string &name)
{
	std::map<std::string, SamplerId>::iterator sit = samplersByName.find(name);
	if (sit != samplersByName.end())
	{
		return sit->second;
	}
	else
	{
		return BAD_SAMPLER_ID;
	}
}

// ----------------------------------------------------------------------------
// Swap the texture assigned to the given sampler, returns the old texture
GLTexture *GLTextureManager::SwapTexture(SamplerId sampler, GLTexture *tex)
{
	assert(sampler >= 0
		&& static_cast<unsigned int>(sampler) < samplers.size());

	// Replace the texture on this sampler
	GLTexture *oldTex = samplers[sampler];
	samplers[sampler] = tex;

	// TODO: we should replace the stored copy as well (if we own this texture)
	// however, this operation should be as fast as possible, and we don't
	// know if tex is owned by us without knowing its name (see AddTexture)
	return oldTex;
}

// ----------------------------------------------------------------------------
// Unregister the given name as a sampler
void GLTextureManager::RemoveSampler(const std::string &name)
{
	// Find the sampler
	SamplerId sampler = GetSampler(name);
	if (sampler != BAD_SAMPLER_ID)
	{
		// TODO: invalidate any programs in cache that use this sampler?

		unusedSamplers.push(sampler);
		samplers[sampler] = 0;
		samplersByName.erase(name);
	}
}

// ----------------------------------------------------------------------------
// Specify that the given unit is managed elsewhere, but should be registered
// on programs using the given name
bool GLTextureManager::AddReservedSlot(const std::string &name, int unit)
{
	assert(0 <= unit && unit < maxTextureUnits);

	// Register reserved slot
	reserved[name] = unit;

	// Is any texture bound here?
	if (currentBinding[unit])
	{
		glActiveTexture(GL_TEXTURE0 + unit);
		currentBinding[unit]->UnbindCurrent();
		currentBinding[unit] = 0;
		glActiveTexture(GL_TEXTURE0);
	}

	// TODO: some more error checking could be useful (aliasing...)

	return true;
}

// ----------------------------------------------------------------------------
// Get a texture from the store
GLTexture *GLTextureManager::GetTexture(const std::string &name)
{
	// Do we know this texture?
	std::map<std::string, GLTexture*>::iterator texit =
		textures.find(name);

	if (texit == textures.end()) return 0;

	return texit->second;
}

// ----------------------------------------------------------------------------
// Get a texture from the store
const GLTexture *GLTextureManager::GetTexture(const std::string &name) const
{
	// Do we know this texture?
	std::map<std::string, GLTexture*>::const_iterator texit =
		textures.find(name);

	if (texit == textures.end()) return 0;

	return texit->second;
}

// ----------------------------------------------------------------------------
// Remove and return a texture from the store, or delete a reserved slot
GLTexture *GLTextureManager::RemoveTexture(const std::string &name)
{
	// Is this a reserved slot?
	std::map<std::string, int>::iterator rit = reserved.find(name);
	if (rit != reserved.end())
	{
		// Remove the reserved slot
		reserved.erase(name);
		return 0;
	}
	else
	{
		GLTexture *tex = GetTexture(name);
		// Ignore invalid removals
		if (!tex) return 0;

		// If this texture is currently bound, unbind it
		for (int unit = 0; unit < maxTextureUnits; ++unit)
		{
			if (currentBinding[unit] == tex)
			{
				glActiveTexture(GL_TEXTURE0 + unit);
				tex->UnbindCurrent();
				currentBinding[unit] = 0;
			}
		}
		glActiveTexture(GL_TEXTURE0);

		// Remove the texture from the store
		textures.erase(name);
		return tex;
	}
}

// ----------------------------------------------------------------------------
// Delete a texture from the store, or delete a reserved slot
void GLTextureManager::DeleteTexture(const std::string &name)
{
	GLTexture *tex = RemoveTexture(name);
	if (tex)
	{
#ifndef NDEBUG
		/*
		std::cout
			<< "GLTextureManager: Deleting texture '"
			<< name << "'" << std::endl;
		*/
#endif
		delete tex;
	}
}

// ----------------------------------------------------------------------------
// Reset all assignments, except reserved slots
void GLTextureManager::BeginNewPass()
{
	// Essentially, this means we simply unregister all programs
	std::map<GLProgram*, SamplerBindings>::iterator it = bindings.begin();
	while (it != bindings.end())
	{
		GLProgram *prog = it->first;
		++it;
		UnregisterProgram(prog);
	}
	currentProgram = 0;
}

// ----------------------------------------------------------------------------
// Bind all textures required by the currently active program
void GLTextureManager::Bind()
{
	// Make sure we have a current program
	if (!currentProgram) return;
	SamplerBindings &binding = bindings[currentProgram];

	for (int unit = 0; unit < maxTextureUnits; ++unit)
	{
		SamplerId samplerId = binding[unit];
		// Ignore unused / reserved units
		if (samplerId >= 0)
		{
			// Get the texture
			GLTexture *tex = samplers[samplerId];
			// This could be NULL due to programmer error
			// (removing a sampler without resetting programs that use it)
			//assert(tex);

			// Check if anything is bound to this unit
			GLTexture *oldTex = currentBinding[unit];
			if (oldTex == tex) continue;

			// Set up texture in OpenGL
			glActiveTexture(GL_TEXTURE0 + unit);
			if (oldTex) oldTex->UnbindCurrent();
			if (tex) tex->BindToCurrent();

			// Update current binding
			currentBinding[unit] = tex;
		}
	}
	glActiveTexture(GL_TEXTURE0);
}

// ----------------------------------------------------------------------------
// Unbind all currently bound textures
void GLTextureManager::Unbind()
{
	for (int unit = 0; unit < maxTextureUnits; ++unit)
	{
		GLTexture *tex = currentBinding[unit];
		if (tex)
		{
			glActiveTexture(GL_TEXTURE0 + unit);
			tex->UnbindCurrent();
			currentBinding[unit] = 0;
		}
	}
	glActiveTexture(GL_TEXTURE0);
}

// ----------------------------------------------------------------------------
bool GLTextureManager::SetupProgram(GLProgram *prog, bool updateIfKnown)
{
	// Set current program
	currentProgram = prog;

	bool ok = true;

	// Do we know this program?
	std::map<GLProgram*, SamplerBindings>::iterator it =
		bindings.find(prog);
	if (it == bindings.end() || updateIfKnown)
	{
		// Add new (or get and clear) bindings for this program
		SamplerBindings &binding = bindings[prog];
		binding.clear();
		binding.resize(maxTextureUnits, -1);

		// For finding available texture units
		int nextFreeUnit = 0;
		std::vector<bool> inUse;
		inUse.resize(maxTextureUnits, false);
		// Mark all reserved slots
		for (std::map<std::string, int>::const_iterator rit =
			reserved.begin(); rit != reserved.end(); ++rit)
		{
			inUse[rit->second] = true;
		}

		// Get the uniforms required for this program
		std::vector<GLUniformInfo> uniforms = prog->GetActiveUniforms();
		for (std::vector<GLUniformInfo>::iterator it = uniforms.begin();
			it != uniforms.end(); ++it)
		{
			// Is this a sampler?
			if (it->type == GL_SAMPLER_1D
				|| it->type == GL_SAMPLER_2D
				|| it->type == GL_SAMPLER_3D
				|| it->type == GL_SAMPLER_CUBE
				|| it->type == GL_SAMPLER_1D_SHADOW
				|| it->type == GL_SAMPLER_2D_SHADOW
				|| it->type == GL_SAMPLER_2D_RECT_ARB
				|| it->type == GL_SAMPLER_2D_RECT_SHADOW_ARB)
			{
				// Is this a reserved texture unit?
				// TODO: how to handle reserved slots in arrays?
				std::map<std::string, int>::const_iterator rit =
					reserved.find(it->name);
				if (rit != reserved.end())
				{
					// Reserved unit, only set location in program
					prog->UseTexture(it->name, rit->second);
				}
				else
				{
					// Is this a texture array?
					for (int element = 0; element < it->size; ++element)
					{
						// Build the name for this element
						std::string name;
						if (it->size > 1)
						{
							// Some implementations return name[0],
							// others just return name...
							std::string arrayName = it->name.substr(0,
								it->name.find('['));
							std::ostringstream elementName;
							elementName << arrayName << "[" << element << "]";
							name = elementName.str();
						}
						else
						{
							name = it->name;
						}

						// Find the matching SamplerId
						SamplerId sampler = GetSampler(name);
						// If size == 1 this could be a single-element array
						if (it->size == 1 && sampler == BAD_SAMPLER_ID)
						{
							std::string arrayName = it->name.substr(0,
								it->name.find('['));
							std::ostringstream elementName;
							elementName << arrayName << "[0]";
							sampler = GetSampler(elementName.str());
						}
						if (sampler == BAD_SAMPLER_ID)
						{
#ifndef NDEBUG
							std::cerr
								<< "GLTextureManager: "
								<< "Program requires unknown sampler '"
								<< name << "'" << std::endl;
#endif
							// TODO: we might want to re-check this sampler
							// Continue for now, but inform the caller
							ok = false;
						}
						else
						{
							// Find the next free texture unit
							while (nextFreeUnit != maxTextureUnits
								&& inUse[nextFreeUnit])
							{
								++nextFreeUnit;
							}
							if (nextFreeUnit == maxTextureUnits)
							{
								// We ran out of texture units!
#ifndef NDEBUG
								std::cerr
									<< "GLProgram: "
									<< "ran out of available texture units!"
									<< std::endl;
#endif
								return false;
							}

							// Assign sampler to unit
							binding[nextFreeUnit] = sampler;
							inUse[nextFreeUnit] = true;
							// Pass the unit id to program
							prog->UseTexture(name, nextFreeUnit);
						}
					}
				}
			}
		}
	}

	return ok;
}

// ----------------------------------------------------------------------------
// Remove bindings for the given program
void GLTextureManager::UnregisterProgram(GLProgram *prog)
{
	bindings.erase(prog);
}
<|endoftext|>


<commit_before>#include "plot.h"
#include "curvedata.h"
#include "signaldata.h"
#include <qwt_plot_grid.h>
#include <qwt_plot_layout.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_directpainter.h>
#include <qwt_curve_fitter.h>
#include <qwt_painter.h>
#include <qwt_scale_engine.h>
#include <qwt_scale_draw.h>
#include <qwt_plot_zoomer.h>
#include <qwt_plot_panner.h>
#include <qwt_plot_magnifier.h>
#include <qwt_text.h>

#include <qevent.h>

#include <limits>
#include <cassert>

class MyScaleDraw : public QwtScaleDraw
{
  virtual QwtText label(double value) const
  {
    return QString::number(value, 'f', 2);
  }
};

class MyZoomer: public QwtPlotZoomer
{
public:
    MyZoomer(QwtPlotCanvas *canvas):
        QwtPlotZoomer(canvas)
    {
        setTrackerMode(AlwaysOn);
    }

    virtual QwtText trackerTextF(const QPointF &pos) const
    {
        QColor bg(Qt::white);
        bg.setAlpha(200);

        QwtText text = QwtPlotZoomer::trackerTextF(pos);
        text.setBackgroundBrush( QBrush( bg ));
        return text;
    }
};

class MyMagnifier: public QwtPlotMagnifier
{
public:
    MyMagnifier(QwtPlotCanvas *canvas):
        QwtPlotMagnifier(canvas)
    {

    }

protected:

    // Normally, a value < 1.0 zooms in, a value > 1.0 zooms out.
    // This function is overloaded to invert the magnification direction.
    virtual void rescale( double factor )
    {
      factor = qAbs( factor );
      factor = (1-factor) + 1;
      this->QwtPlotMagnifier::rescale(factor);
    }

};

Plot::Plot(QWidget *parent):
  QwtPlot(parent),
  d_interval(0.0, 10.0),
  d_timerId(-1)
{
  setAutoReplot(false);

  // The backing store is important, when working with widget
  // overlays ( f.e rubberbands for zooming ).
  // Here we don't have them and the internal
  // backing store of QWidget is good enough.

  canvas()->setPaintAttribute(QwtPlotCanvas::BackingStore, false);

#if defined(Q_WS_X11)
  // Even if not recommended by TrollTech, Qt::WA_PaintOutsidePaintEvent
  // works on X11. This has a nice effect on the performance.

  canvas()->setAttribute(Qt::WA_PaintOutsidePaintEvent, true);

  // Disabling the backing store of Qt improves the performance
  // for the direct painter even more, but the canvas becomes
  // a native window of the window system, receiving paint events
  // for resize and expose operations. Those might be expensive
  // when there are many points and the backing store of
  // the canvas is disabled. So in this application
  // we better don't both backing stores.

  if ( canvas()->testPaintAttribute( QwtPlotCanvas::BackingStore ) )
  {
    canvas()->setAttribute(Qt::WA_PaintOnScreen, true);
    canvas()->setAttribute(Qt::WA_NoSystemBackground, true);
  }

#endif

  initGradient();

  plotLayout()->setAlignCanvasToScales(true);

  setAxisTitle(QwtPlot::xBottom, "Time [s]");
  setAxisScale(QwtPlot::xBottom, d_interval.minValue(), d_interval.maxValue());
  setAxisScale(QwtPlot::yLeft, -4.0, 4.0);

  setAxisScaleDraw(QwtPlot::xBottom, new MyScaleDraw);

  QwtPlotGrid *grid = new QwtPlotGrid();
  grid->setPen(QPen(Qt::gray, 0.0, Qt::DotLine));
  grid->enableX(false);
  grid->enableXMin(false);
  grid->enableY(true);
  grid->enableYMin(false);
  grid->attach(this);

  d_origin = new QwtPlotMarker();
  d_origin->setLineStyle(QwtPlotMarker::HLine);
  d_origin->setValue(d_interval.minValue() + d_interval.width() / 2.0, 0.0);
  d_origin->setLinePen(QPen(Qt::gray, 0.0, Qt::DashLine));
  d_origin->attach(this);

  QwtPlotZoomer* zoomer = new MyZoomer(canvas());
    zoomer->setMousePattern(QwtEventPattern::QwtEventPattern::MouseSelect1,
        Qt::LeftButton, Qt::ShiftModifier);
   // zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
   //     Qt::RightButton);

    QwtPlotPanner *panner = new QwtPlotPanner(canvas());
    //panner->setAxisEnabled(QwtPlot::yRight, false);
    panner->setMouseButton(Qt::LeftButton);

    // zoom in/out with the wheel
    QwtPlotMagnifier* magnifier = new MyMagnifier(canvas());
    magnifier->setMouseButton(Qt::MiddleButton);

    const QColor c(Qt::darkBlue);
    zoomer->setRubberBandPen(c);
    zoomer->setTrackerPen(c);

  this->setMinimumHeight(200);
}

Plot::~Plot()
{

}

void Plot::addSignal(SignalData* signalData, QColor color)
{
  QwtPlotCurve* d_curve = new QwtPlotCurve();
  d_curve->setStyle(QwtPlotCurve::Lines);
  d_curve->setPen(QPen(color));
#if 1
  d_curve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
#endif
#if 1
  d_curve->setPaintAttribute(QwtPlotCurve::ClipPolygons, false);
#endif
  d_curve->setData(new CurveData(signalData));
  d_curve->attach(this);

  mSignals[signalData] = d_curve;
}

void Plot::removeSignal(SignalData* signalData)
{
  if (!signalData)
  {
    return;
  }

  QwtPlotCurve* curve = mSignals.value(signalData);
  assert(curve);
  curve->detach();
  delete curve;
  mSignals.remove(signalData);
}

void Plot::setSignalVisible(SignalData* signalData, bool visible)
{
  if (!signalData)
  {
    return;
  }

  QwtPlotCurve* curve = mSignals.value(signalData);
  assert(curve);

  if (visible)
  {
    curve->attach(this);
  }
  else
  {
    curve->detach();
  }
}

void Plot::setSignalColor(SignalData* signalData, QColor color)
{
  if (!signalData)
  {
    return;
  }

  QwtPlotCurve* curve = mSignals.value(signalData);
  assert(curve);
  curve->setPen(QPen(color));
}

void Plot::initGradient()
{
  QPalette pal = canvas()->palette();

#if QT_VERSION >= 0x040400
  QLinearGradient gradient( 0.0, 0.0, 1.0, 0.0 );
  gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
  //gradient.setColorAt(0.0, QColor( 0, 49, 110 ) );
  //gradient.setColorAt(1.0, QColor( 0, 87, 174 ) );

  gradient.setColorAt(0.0, QColor( 255, 255, 255 ) );
  gradient.setColorAt(1.0, QColor( 255, 255, 255 ) );

  pal.setBrush(QPalette::Window, QBrush(gradient));
#else
  pal.setBrush(QPalette::Window, QBrush( color ));
#endif

  canvas()->setPalette(pal);
}

void Plot::start()
{
  d_timerId = startTimer(33);
}

void Plot::stop()
{
  killTimer(d_timerId);
}

void Plot::replot()
{
  // Lock the signal data objects, then plot the data and unlock.
  QList<SignalData*> signalDataList = mSignals.keys();
  foreach (SignalData* signalData, signalDataList)
  {
    signalData->lock();
  }

  QwtPlot::replot();

  foreach (SignalData* signalData, signalDataList)
  {
    signalData->unlock();
  }
}

double Plot::timeWindow()
{
  return d_interval.width();
}

void Plot::setTimeWindow(double interval)
{
  if ( interval > 0.0 && interval != d_interval.width() )
  {
    d_interval.setMinValue(d_interval.maxValue() - interval);
  }
}

void Plot::setYScale(double scale)
{
  setAxisScale(QwtPlot::yLeft, -scale, scale);
}

void Plot::timerEvent(QTimerEvent *event)
{
  if ( event->timerId() == d_timerId )
  {

    if (!mSignals.size())
    {
      return;
    }

    float maxTime = std::numeric_limits<float>::min();

    QList<SignalData*> signalDataList = mSignals.keys();
    foreach (SignalData* signalData, signalDataList)
    {
      signalData->updateValues();
      if (signalData->size())
      {
        float signalMaxTime = signalData->value(signalData->size() - 1).x();
        if (signalMaxTime > maxTime)
          {
          maxTime = signalMaxTime;
          }
      }
    }

    if (maxTime != std::numeric_limits<float>::min())
    {
      d_interval = QwtInterval(maxTime - d_interval.width(), maxTime);

      setAxisScale(QwtPlot::xBottom, d_interval.minValue(), d_interval.maxValue());

      QwtScaleEngine* engine = axisScaleEngine(QwtPlot::xBottom);
      //engine->setAttribute(QwtScaleEngine::Floating, true);
      //engine->setMargins(0,50.0);

      QwtScaleDiv scaleDiv = engine->divideScale(d_interval.minValue(), d_interval.maxValue(), 0, 0);

      QList<double> majorTicks;
      double majorStep = scaleDiv.range() / 5.0;
      for (int i = 0; i <= 5; ++i)
      {
        majorTicks << scaleDiv.lowerBound() + i*majorStep;
      }
      majorTicks.back() = scaleDiv.upperBound();

      QList<double> minorTicks;
      double minorStep = scaleDiv.range() / 25.0;
      for (int i = 0; i <= 25; ++i)
      {
        minorTicks << scaleDiv.lowerBound() + i*minorStep;
      }
      minorTicks.back() = scaleDiv.upperBound();

      scaleDiv.setTicks(QwtScaleDiv::MajorTick, majorTicks);
      scaleDiv.setTicks(QwtScaleDiv::MinorTick, minorTicks);
      setAxisScaleDiv(QwtPlot::xBottom, scaleDiv);

/*
      QwtScaleDiv scaleDiv;// = *axisScaleDiv(QwtPlot::xBottom);
      scaleDiv.setInterval(d_interval);

      QList<double> majorTicks;
      majorTicks << d_interval.minValue() << d_interval.maxValue();
      scaleDiv.setTicks(QwtScaleDiv::MajorTick, majorTicks);
      setAxisScaleDiv(QwtPlot::xBottom, scaleDiv);
*/

      //printf("update x axis interval: [%f,  %f]\n", d_interval.minValue(), d_interval.maxValue());
    }

    this->replot();
  }

  QwtPlot::timerEvent(event);
}
<commit_msg>signal_scope: replot after changing signal visibility<commit_after>#include "plot.h"
#include "curvedata.h"
#include "signaldata.h"
#include <qwt_plot_grid.h>
#include <qwt_plot_layout.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_directpainter.h>
#include <qwt_curve_fitter.h>
#include <qwt_painter.h>
#include <qwt_scale_engine.h>
#include <qwt_scale_draw.h>
#include <qwt_plot_zoomer.h>
#include <qwt_plot_panner.h>
#include <qwt_plot_magnifier.h>
#include <qwt_text.h>

#include <qevent.h>

#include <limits>
#include <cassert>

class MyScaleDraw : public QwtScaleDraw
{
  virtual QwtText label(double value) const
  {
    return QString::number(value, 'f', 2);
  }
};

class MyZoomer: public QwtPlotZoomer
{
public:
    MyZoomer(QwtPlotCanvas *canvas):
        QwtPlotZoomer(canvas)
    {
        setTrackerMode(AlwaysOn);
    }

    virtual QwtText trackerTextF(const QPointF &pos) const
    {
        QColor bg(Qt::white);
        bg.setAlpha(200);

        QwtText text = QwtPlotZoomer::trackerTextF(pos);
        text.setBackgroundBrush( QBrush( bg ));
        return text;
    }
};

class MyMagnifier: public QwtPlotMagnifier
{
public:
    MyMagnifier(QwtPlotCanvas *canvas):
        QwtPlotMagnifier(canvas)
    {

    }

protected:

    // Normally, a value < 1.0 zooms in, a value > 1.0 zooms out.
    // This function is overloaded to invert the magnification direction.
    virtual void rescale( double factor )
    {
      factor = qAbs( factor );
      factor = (1-factor) + 1;
      this->QwtPlotMagnifier::rescale(factor);
    }

};

Plot::Plot(QWidget *parent):
  QwtPlot(parent),
  d_interval(0.0, 10.0),
  d_timerId(-1)
{
  setAutoReplot(false);

  // The backing store is important, when working with widget
  // overlays ( f.e rubberbands for zooming ).
  // Here we don't have them and the internal
  // backing store of QWidget is good enough.

  canvas()->setPaintAttribute(QwtPlotCanvas::BackingStore, false);

#if defined(Q_WS_X11)
  // Even if not recommended by TrollTech, Qt::WA_PaintOutsidePaintEvent
  // works on X11. This has a nice effect on the performance.

  canvas()->setAttribute(Qt::WA_PaintOutsidePaintEvent, true);

  // Disabling the backing store of Qt improves the performance
  // for the direct painter even more, but the canvas becomes
  // a native window of the window system, receiving paint events
  // for resize and expose operations. Those might be expensive
  // when there are many points and the backing store of
  // the canvas is disabled. So in this application
  // we better don't both backing stores.

  if ( canvas()->testPaintAttribute( QwtPlotCanvas::BackingStore ) )
  {
    canvas()->setAttribute(Qt::WA_PaintOnScreen, true);
    canvas()->setAttribute(Qt::WA_NoSystemBackground, true);
  }

#endif

  initGradient();

  plotLayout()->setAlignCanvasToScales(true);

  setAxisTitle(QwtPlot::xBottom, "Time [s]");
  setAxisScale(QwtPlot::xBottom, d_interval.minValue(), d_interval.maxValue());
  setAxisScale(QwtPlot::yLeft, -4.0, 4.0);

  setAxisScaleDraw(QwtPlot::xBottom, new MyScaleDraw);

  QwtPlotGrid *grid = new QwtPlotGrid();
  grid->setPen(QPen(Qt::gray, 0.0, Qt::DotLine));
  grid->enableX(false);
  grid->enableXMin(false);
  grid->enableY(true);
  grid->enableYMin(false);
  grid->attach(this);

  d_origin = new QwtPlotMarker();
  d_origin->setLineStyle(QwtPlotMarker::HLine);
  d_origin->setValue(d_interval.minValue() + d_interval.width() / 2.0, 0.0);
  d_origin->setLinePen(QPen(Qt::gray, 0.0, Qt::DashLine));
  d_origin->attach(this);

  QwtPlotZoomer* zoomer = new MyZoomer(canvas());
    zoomer->setMousePattern(QwtEventPattern::QwtEventPattern::MouseSelect1,
        Qt::LeftButton, Qt::ShiftModifier);
   // zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
   //     Qt::RightButton);

    QwtPlotPanner *panner = new QwtPlotPanner(canvas());
    //panner->setAxisEnabled(QwtPlot::yRight, false);
    panner->setMouseButton(Qt::LeftButton);

    // zoom in/out with the wheel
    QwtPlotMagnifier* magnifier = new MyMagnifier(canvas());
    magnifier->setMouseButton(Qt::MiddleButton);

    const QColor c(Qt::darkBlue);
    zoomer->setRubberBandPen(c);
    zoomer->setTrackerPen(c);

  this->setMinimumHeight(200);
}

Plot::~Plot()
{

}

void Plot::addSignal(SignalData* signalData, QColor color)
{
  QwtPlotCurve* d_curve = new QwtPlotCurve();
  d_curve->setStyle(QwtPlotCurve::Lines);
  d_curve->setPen(QPen(color));
#if 1
  d_curve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
#endif
#if 1
  d_curve->setPaintAttribute(QwtPlotCurve::ClipPolygons, false);
#endif
  d_curve->setData(new CurveData(signalData));
  d_curve->attach(this);

  mSignals[signalData] = d_curve;
}

void Plot::removeSignal(SignalData* signalData)
{
  if (!signalData)
  {
    return;
  }

  QwtPlotCurve* curve = mSignals.value(signalData);
  assert(curve);
  curve->detach();
  delete curve;
  mSignals.remove(signalData);
}

void Plot::setSignalVisible(SignalData* signalData, bool visible)
{
  if (!signalData)
  {
    return;
  }

  QwtPlotCurve* curve = mSignals.value(signalData);
  assert(curve);

  if (visible)
  {
    curve->attach(this);
  }
  else
  {
    curve->detach();
  }

  this->replot();
}

void Plot::setSignalColor(SignalData* signalData, QColor color)
{
  if (!signalData)
  {
    return;
  }

  QwtPlotCurve* curve = mSignals.value(signalData);
  assert(curve);
  curve->setPen(QPen(color));
}

void Plot::initGradient()
{
  QPalette pal = canvas()->palette();

#if QT_VERSION >= 0x040400
  QLinearGradient gradient( 0.0, 0.0, 1.0, 0.0 );
  gradient.setCoordinateMode( QGradient::StretchToDeviceMode );
  //gradient.setColorAt(0.0, QColor( 0, 49, 110 ) );
  //gradient.setColorAt(1.0, QColor( 0, 87, 174 ) );

  gradient.setColorAt(0.0, QColor( 255, 255, 255 ) );
  gradient.setColorAt(1.0, QColor( 255, 255, 255 ) );

  pal.setBrush(QPalette::Window, QBrush(gradient));
#else
  pal.setBrush(QPalette::Window, QBrush( color ));
#endif

  canvas()->setPalette(pal);
}

void Plot::start()
{
  d_timerId = startTimer(33);
}

void Plot::stop()
{
  killTimer(d_timerId);
}

void Plot::replot()
{
  // Lock the signal data objects, then plot the data and unlock.
  QList<SignalData*> signalDataList = mSignals.keys();
  foreach (SignalData* signalData, signalDataList)
  {
    signalData->lock();
  }

  QwtPlot::replot();

  foreach (SignalData* signalData, signalDataList)
  {
    signalData->unlock();
  }
}

double Plot::timeWindow()
{
  return d_interval.width();
}

void Plot::setTimeWindow(double interval)
{
  if ( interval > 0.0 && interval != d_interval.width() )
  {
    d_interval.setMinValue(d_interval.maxValue() - interval);
  }
}

void Plot::setYScale(double scale)
{
  setAxisScale(QwtPlot::yLeft, -scale, scale);
}

void Plot::timerEvent(QTimerEvent *event)
{
  if ( event->timerId() == d_timerId )
  {

    if (!mSignals.size())
    {
      return;
    }

    float maxTime = std::numeric_limits<float>::min();

    QList<SignalData*> signalDataList = mSignals.keys();
    foreach (SignalData* signalData, signalDataList)
    {
      signalData->updateValues();
      if (signalData->size())
      {
        float signalMaxTime = signalData->value(signalData->size() - 1).x();
        if (signalMaxTime > maxTime)
          {
          maxTime = signalMaxTime;
          }
      }
    }

    if (maxTime != std::numeric_limits<float>::min())
    {
      d_interval = QwtInterval(maxTime - d_interval.width(), maxTime);

      setAxisScale(QwtPlot::xBottom, d_interval.minValue(), d_interval.maxValue());

      QwtScaleEngine* engine = axisScaleEngine(QwtPlot::xBottom);
      //engine->setAttribute(QwtScaleEngine::Floating, true);
      //engine->setMargins(0,50.0);

      QwtScaleDiv scaleDiv = engine->divideScale(d_interval.minValue(), d_interval.maxValue(), 0, 0);

      QList<double> majorTicks;
      double majorStep = scaleDiv.range() / 5.0;
      for (int i = 0; i <= 5; ++i)
      {
        majorTicks << scaleDiv.lowerBound() + i*majorStep;
      }
      majorTicks.back() = scaleDiv.upperBound();

      QList<double> minorTicks;
      double minorStep = scaleDiv.range() / 25.0;
      for (int i = 0; i <= 25; ++i)
      {
        minorTicks << scaleDiv.lowerBound() + i*minorStep;
      }
      minorTicks.back() = scaleDiv.upperBound();

      scaleDiv.setTicks(QwtScaleDiv::MajorTick, majorTicks);
      scaleDiv.setTicks(QwtScaleDiv::MinorTick, minorTicks);
      setAxisScaleDiv(QwtPlot::xBottom, scaleDiv);

/*
      QwtScaleDiv scaleDiv;// = *axisScaleDiv(QwtPlot::xBottom);
      scaleDiv.setInterval(d_interval);

      QList<double> majorTicks;
      majorTicks << d_interval.minValue() << d_interval.maxValue();
      scaleDiv.setTicks(QwtScaleDiv::MajorTick, majorTicks);
      setAxisScaleDiv(QwtPlot::xBottom, scaleDiv);
*/

      //printf("update x axis interval: [%f,  %f]\n", d_interval.minValue(), d_interval.maxValue());
    }

    this->replot();
  }

  QwtPlot::timerEvent(event);
}
<|endoftext|>


<commit_before>#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "automata.h"

DFA dfa;
NDFA ndfa;
set<string> tokens, final;

struct enumstate {
  string name;
  enumstate() { name = string(); incremento(); }
  string& operator++() { incremento(); return name; }
  string operator++(int) { string tmp(name); incremento(); return tmp; }
  void incremento() {
    int i;
    do {
      for (i = 0; i < (int) name.length(); i++)
        if (name[i] < 'Z') { name[i]++; break; }
        else name[i] = 'A';
      if (i == (int) name.length()) name.append("A");
    }
    while (!name.compare(S) || !name.compare(X) ||
           ndfa.find(name) != ndfa.end());
  }
};

void debugprint() {
  for (NDFA::iterator src = ndfa.begin(); src != ndfa.end(); src++) {
    printf("%s ", (src -> first).c_str());
    for (ntransition::iterator tgt = (src -> second).begin(); tgt != (src -> second).end(); tgt++)
      for (int i = 0; i < (int) (tgt -> second).size(); i++)
        printf("(%c, %s)", tgt -> first, (tgt -> second)[i].c_str());
    printf("\n");
  }
}

void debugd() {
  for (DFA::iterator src = dfa.begin(); src != dfa.end(); src++) {
    printf("%s ", (src -> first).c_str());
    for (dtransition::iterator tgt = (src -> second).begin(); tgt != (src -> second).end(); tgt++)
        printf("(%c, %s)", tgt -> first, (tgt -> second).c_str());
    printf("\n");
  }
}

int readgrammar() {
  int i, top;
  string src, tgt;
  enumstate state;
  map<string, string> states;
  char s[MAX], word[MAX], flag, term;
  states[S] = S; states[X] = X;
  while (fgets(s, MAX, stdin) != NULL && strlen(s) > 1) {
    s[strlen(s) - 1] = '|';
    for (top = i = 0; s[i] != ':'; i++) {
      if (s[i] == '<' || s[i] == '>' || s[i] == ' ') continue;
      word[top++] = s[i];
    }
    word[top] = '\0';
    //    for (j = i + 1; word[j] != '='; j++);
    //    if (j - i != 2) return 0;
    //    i = j + 1;
    i += 2;
    src = string(word);
    printf("%s ::= ", states[src].c_str());
    if (states.find(src) == states.end()) states[src] = state++;
    while (s[++i] != '\0') {
      for (top = flag = 0; s[i] != '|'; i++) {
        if (s[i] == ' ') continue;
        if (s[i] == '<') flag = 1;
        else if (s[i] == '>') flag = 0;
        else if (!flag) term = s[i];
        else word[top++] = s[i];
      }
      word[top] = '\0';
      tgt = string(word);
      if (states.find(tgt) == states.end()) states[tgt] = state++;
      ndfa[states[src]][term].push_back(states[tgt]);
      printf("%c%s%s", term, states[tgt].c_str(), s[i + 1] == '\0' ? "\n" : " | ");
    }
    printf("\n");
  }
  src = states[""]; final.insert(src); //scr is a final state
  printf("final state: %s\n", src.c_str());
  for (i = 33; i < 127; i++)
    ndfa[src][(char) i].push_back(X);
  return 1;
}

int readtokens(int N) {
  int i;
  char word[MAX];
  enumstate current;
  while (N--) {
    if (fgets(word, MAX, stdin) == NULL || word[0] == '\n') return 0;
    word[strlen(word) - 1] = '\0';
    // map.insert().second returns true or false if
    // successfully inserted that key or it was
    // already there (and thus did nothing), respectively
    if (!tokens.insert(string(word)).second) continue;
    printf("%s\n", word);
    ndfa[S][word[0]].push_back(current.name);
    for (i = 1; word[i] != '\0'; i++)
      ndfa[current++][word[i]].push_back(current.name);
    printf("readtokens X: %s\n", current.name.c_str());
    for (i = 33; i < 127; i++)
      ndfa[current.name][(char) i].push_back(X);
    final.insert(current.name);
    current++;
  }
  return 1;
}

void debugf() {
  printf("\n\nEstados finais:\n");
  for (set<string>::iterator i = final.begin(); i != final.end(); i++)
    printf("%s\n", i -> c_str());
}

void makedet() {
  int i, j, k;
  set<string> done;
  vector<string> states;
  states.push_back("S|"); done.insert("S|");
  for (i = 0; i < (int) states.size(); i++) {
    j = 0;
    string src;
    vector< set<string> > trans(312);
    while (j < (int) states[i].length()) {
      k = j;
      // searching for the first '|' in order to
      // find the 'src' state to look at its transitions
      // 'j' stops 1 position after that '|'
      while (states[i][j++] != '|');
      src = states[i].substr(k, j - k - 1);
      if (final.find(src) != final.end()) continue;
      for (ntransition::iterator t = ndfa[src].begin(); t != ndfa[src].end(); t++) {
        string tgt;
        for (k = 0; k < (int) (t -> second).size(); k++)
          tgt.append((t -> second)[k]).append("|");
        trans[(int) t -> first].insert(tgt);
      }
    }
    for (j = 0; j < 312; j++) {
      string tr;
      if (trans[j].size() == 0) continue;
      for (set<string>::iterator s = trans[j].begin(); s != trans[j].end(); s++)
        tr.append(*s);
      dfa[states[i]][(char) j] = tr;
      if (done.find(tr) == done.end()) {
        states.push_back(tr);
        done.insert(tr);
      }
    }
  }
  // for (auto fs: final) {
  // for (set<string>::iterator fs = final.begin(); fs != final.end(); fs++) {
  //   printf("+++++++++++++++= %s\n", fs -> c_str());
  //   for (auto s: dfa) {
  //     printf("%s\n", s.first.c_str());
  //   }
  // }
}

int minimize(string u) {
  int i; bool flag = false, tmp;
  for (i = 33; i < 127; i++, flag |= !tmp)
    if ((tmp = !minimize(dfa[u][(char) i]))) dfa[u][(char) i] = X;
  if (final.find(u) != final.end() || flag) return 1;
  dfa.erase(u);
  return 0;
}
<commit_msg>Now updating final states after determinization<commit_after>#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "automata.h"

DFA dfa;
NDFA ndfa;
set<string> tokens, final;

struct enumstate {
  string name;
  enumstate() { name = string(); incremento(); }
  string& operator++() { incremento(); return name; }
  string operator++(int) { string tmp(name); incremento(); return tmp; }
  void incremento() {
    int i;
    do {
      for (i = 0; i < (int) name.length(); i++)
        if (name[i] < 'Z') { name[i]++; break; }
        else name[i] = 'A';
      if (i == (int) name.length()) name.append("A");
    }
    while (!name.compare(S) || !name.compare(X) ||
           ndfa.find(name) != ndfa.end());
  }
};

void debugprint() {
  for (NDFA::iterator src = ndfa.begin(); src != ndfa.end(); src++) {
    printf("%s ", (src -> first).c_str());
    for (ntransition::iterator tgt = (src -> second).begin(); tgt != (src -> second).end(); tgt++)
      for (int i = 0; i < (int) (tgt -> second).size(); i++)
        printf("(%c, %s)", tgt -> first, (tgt -> second)[i].c_str());
    printf("\n");
  }
}

void debugd() {
  for (DFA::iterator src = dfa.begin(); src != dfa.end(); src++) {
    printf("%s ", (src -> first).c_str());
    for (dtransition::iterator tgt = (src -> second).begin(); tgt != (src -> second).end(); tgt++)
        printf("(%c, %s)", tgt -> first, (tgt -> second).c_str());
    printf("\n");
  }
}

int readgrammar() {
  int i, top;
  string src, tgt;
  enumstate state;
  map<string, string> states;
  char s[MAX], word[MAX], flag, term;
  states[S] = S; states[X] = X;
  while (fgets(s, MAX, stdin) != NULL && strlen(s) > 1) {
    s[strlen(s) - 1] = '|';
    for (top = i = 0; s[i] != ':'; i++) {
      if (s[i] == '<' || s[i] == '>' || s[i] == ' ') continue;
      word[top++] = s[i];
    }
    word[top] = '\0';
    //    for (j = i + 1; word[j] != '='; j++);
    //    if (j - i != 2) return 0;
    //    i = j + 1;
    i += 2;
    src = string(word);
    printf("%s ::= ", states[src].c_str());
    if (states.find(src) == states.end()) states[src] = state++;
    while (s[++i] != '\0') {
      for (top = flag = 0; s[i] != '|'; i++) {
        if (s[i] == ' ') continue;
        if (s[i] == '<') flag = 1;
        else if (s[i] == '>') flag = 0;
        else if (!flag) term = s[i];
        else word[top++] = s[i];
      }
      word[top] = '\0';
      tgt = string(word);
      if (states.find(tgt) == states.end()) states[tgt] = state++;
      ndfa[states[src]][term].push_back(states[tgt]);
      printf("%c%s%s", term, states[tgt].c_str(), s[i + 1] == '\0' ? "\n" : " | ");
    }
    printf("\n");
  }
  src = states[""]; final.insert(src); //scr is a final state
  printf("final state: %s\n", src.c_str());
  for (i = 33; i < 127; i++)
    ndfa[src][(char) i].push_back(X);
  return 1;
}

int readtokens(int N) {
  int i;
  char word[MAX];
  enumstate current;
  while (N--) {
    if (fgets(word, MAX, stdin) == NULL || word[0] == '\n') return 0;
    word[strlen(word) - 1] = '\0';
    // map.insert().second returns true or false if
    // successfully inserted that key or it was
    // already there (and thus did nothing), respectively
    if (!tokens.insert(string(word)).second) continue;
    printf("%s\n", word);
    ndfa[S][word[0]].push_back(current.name);
    for (i = 1; word[i] != '\0'; i++)
      ndfa[current++][word[i]].push_back(current.name);
    printf("readtokens X: %s\n", current.name.c_str());
    for (i = 33; i < 127; i++)
      ndfa[current.name][(char) i].push_back(X);
    final.insert(current.name);
    current++;
  }
  return 1;
}

void debugf() {
  printf("\n\nEstados finais:\n");
  for (set<string>::iterator i = final.begin(); i != final.end(); i++)
    printf("%s\n", i -> c_str());
}

void makedet() {
  int i, j, k;
  set<string> done;
  vector<string> states;
  states.push_back("S|"); done.insert("S|");
  for (i = 0; i < (int) states.size(); i++) {
    j = 0;
    string src;
    vector< set<string> > trans(312);
    while (j < (int) states[i].length()) {
      k = j;
      // searching for the first '|' in order to
      // find the 'src' state to look at its transitions
      // 'j' stops 1 position after that '|'
      while (states[i][j++] != '|');
      src = states[i].substr(k, j - k - 1);
      if (final.find(src) != final.end()) continue;
      for (ntransition::iterator t = ndfa[src].begin(); t != ndfa[src].end(); t++) {
        string tgt;
        for (k = 0; k < (int) (t -> second).size(); k++)
          tgt.append((t -> second)[k]).append("|");
        trans[(int) t -> first].insert(tgt);
      }
    }
    for (j = 0; j < 312; j++) {
      string tr;
      if (trans[j].size() == 0) continue;
      for (set<string>::iterator s = trans[j].begin(); s != trans[j].end(); s++)
        tr.append(*s);
      dfa[states[i]][(char) j] = tr;
      if (done.find(tr) == done.end()) {
        states.push_back(tr);
        done.insert(tr);
      }
    }
  }
  done.clear();
  for (auto fs: final) {
    for (auto s: dfa)
      if (s.first.find(fs))
        done.insert(s.first);
    final.erase(fs);
  }
  for (auto s: done) final.insert(s);
}

int minimize(string u) {
  int i;
  bool flag = false, tmp;
  for (i = 33; i < 127; i++, flag |= !tmp)
    if ((tmp = !minimize(dfa[u][(char) i]))) dfa[u][(char) i] = X;
  if (final.find(u) != final.end() || flag) return 1;
  dfa.erase(u);
  return 0;
}
<|endoftext|>


<commit_before>/*
 * File:   SDFLoader.cpp
 * Author: Benedikt Vogler
 *
 * Created on 8. Juli 2014, 18:52
 */

#include <algorithm>
#include "SDFloader.hpp"
#include "Camera.hpp"
#include "Box.hpp"
#include "Sphere.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include "Material.hpp"
#include "LightPoint.hpp"

using namespace std;

SDFLoader::SDFLoader() {
}

SDFLoader::SDFLoader(const SDFLoader& orig) {
}

SDFLoader::~SDFLoader() {
}

/**
 * Loads a scene file and reacts to the commands in it
 * @param scenefile the string to the file
 * @return
 */
Scene SDFLoader::load(std::string const& scenefile) {
    cout << "Loading file: " << scenefile << endl;
    Scene scene = Scene();

    std::map<std::string, Material> mMap;
    std::map<std::string, LightPoint> lMap;
    std::map<std::string, RenderObject*> roMap;

    string line;
    ifstream file(scenefile);
    stringstream ss;
    //file.open(scenefile, ios::in);
    if (file.is_open()) {
        while (getline (file,line)){//get line
            ss = stringstream(line);//fill the line into stringstream
            string tmpString;
            ss >> tmpString;
            //is first string define?
            if (tmpString=="define"){
                cout << "defininig: ";

                ss >> tmpString;
                if (tmpString=="material"){
                    cout << "a material: "<<endl;
                    //extract name
                    string name;
                    ss>>name;

                    //extract color
                    float red, green, blue;
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color ca(red, green, blue);
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color cd(red, green, blue);
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color cs(red, green, blue);
                    float m;
                    ss >> m;
                    Material mat(ca, cd, cs,m, name);
                    cout << "Material specs: "<<endl<<mat;
                    mMap[name]=mat;
                } else if (tmpString=="camera"){
                    string cameraname;
                    ss >> cameraname;
                    int fovX;
                    ss >> fovX;
                    scene.camera = Camera(cameraname,fovX);
                    cout << "camera: "<<cameraname<<"("<<fovX<<")"<<endl;
                } else if (tmpString=="light"){
                    string type;
                    ss>>type;

                    if (type=="diffuse") {
                        string name;
                        ss >> name;

                        glm::vec3 pos;
                        ss >> pos.x;
                        ss >> pos.y;
                        ss >> pos.z;

                        float red, green, blue;
                        ss >> red;
                        ss >> green;
                        ss >> blue;
                        Color diff(red, green, blue);

                        LightPoint light = LightPoint(name, pos, diff);
                        cout << "light point: "<<name<<"("<<pos.x<<","<<pos.y<<","<<pos.z<<","<<diff<<")"<<endl;
                        lMap[name] = light;
                    }else if (type=="ambient") {
                        string lightname;
                        ss >> lightname;//name get's ignored

                        float red, green, blue;
                        ss >> red;
                        ss >> green;
                        ss >> blue;
                        Color amb(red, green, blue);

                        scene.amb = amb;
                        cout << "ambient light "<<amb<<endl;
                    } else {
                        cout << "type not supported yet."<<endl;
                    }
                } else if (tmpString=="shape"){
                    string classname;
                    ss >> classname;
                    cout << "Shape \""<< classname << "\"."<<endl;
                    transform(classname.begin(), classname.end(),classname.begin(), ::toupper);

                    string name;
                    ss >> name;

                    RenderObject* rObject = nullptr;
                    if (classname=="BOX"){
                        int edge1x, edge1y, edge1z;
                        ss>> edge1x;
                        ss>> edge1y;
                        ss>> edge1z;

                        int edge2x, edge2y, edge2z;
                        ss>> edge2x;
                        ss>> edge2y;
                        ss>> edge2z;

                        string materialString;
                        ss>>materialString;
                        Material material = mMap[materialString];

                        rObject = new Box(
                                name,
                                glm::vec3(edge1x, edge1y, edge1z),
                                glm::vec3(edge2x, edge2y, edge2z),
                                material
                                );
                    }else if (classname=="SPHERE") {
                        int posX, posY, posZ;
                        ss>> posX;
                        ss>> posY;
                        ss>> posZ;
                        float radius;
                        ss>>radius;

                        string materialString;
                        ss>>materialString;
                        Material material = mMap[materialString];

                        rObject = new Sphere(
                                name,
                                glm::vec3(posX, posY, posZ),
                                radius,
                                material
                                );
                    }else cout << "ERROR: Shape \""<< classname << "\" not defined."<<endl;

                    if (rObject != nullptr)
                        roMap[name] = rObject;
                } else
                    cout << "object to define not implemented:"<<ss.str() <<endl;
            } else if (tmpString=="render"){
                ss >> scene.camname;
                ss >> scene.outputFile;
                ss >> scene.resX;
                ss >> scene.resY;
                //set default if not set
                if (scene.resX<=0) scene.resX=100;
                if (scene.resY<=0) scene.resY=100;
                cout << "Scene should be rendered from "<< scene.camname << " at resolution "<<scene.resX<<"x"<< scene.resY<< " to "<<scene.outputFile<<endl;
            } else if (tmpString=="#"){
                cout << line << endl;//just print comment lines
            } else
                cout << "Line not supported:"<<line <<endl;
        }
        file.close();
    }else cout << "Unable to open file";

    //save collected data in scene
    scene.materials = mMap;
    scene.renderObjects = roMap;
    scene.lights = lMap;
    return scene;
}<commit_msg>changed default size<commit_after>/*
 * File:   SDFLoader.cpp
 * Author: Benedikt Vogler
 *
 * Created on 8. Juli 2014, 18:52
 */

#include <algorithm>
#include "SDFloader.hpp"
#include "Camera.hpp"
#include "Box.hpp"
#include "Sphere.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include "Material.hpp"
#include "LightPoint.hpp"

using namespace std;

SDFLoader::SDFLoader() {
}

SDFLoader::SDFLoader(const SDFLoader& orig) {
}

SDFLoader::~SDFLoader() {
}

/**
 * Loads a scene file and reacts to the commands in it
 * @param scenefile the string to the file
 * @return
 */
Scene SDFLoader::load(std::string const& scenefile) {
    cout << "Loading file: " << scenefile << endl;
    Scene scene = Scene();

    std::map<std::string, Material> mMap;
    std::map<std::string, LightPoint> lMap;
    std::map<std::string, RenderObject*> roMap;

    string line;
    ifstream file(scenefile);
    stringstream ss;
    //file.open(scenefile, ios::in);
    if (file.is_open()) {
        while (getline (file,line)){//get line
            ss = stringstream(line);//fill the line into stringstream
            string tmpString;
            ss >> tmpString;
            //is first string define?
            if (tmpString=="define"){
                cout << "defininig: ";

                ss >> tmpString;
                if (tmpString=="material"){
                    cout << "a material: "<<endl;
                    //extract name
                    string name;
                    ss>>name;

                    //extract color
                    float red, green, blue;
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color ca(red, green, blue);
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color cd(red, green, blue);
                    ss >> red;
                    ss >> green;
                    ss >> blue;
                    Color cs(red, green, blue);
                    float m;
                    ss >> m;
                    Material mat(ca, cd, cs,m, name);
                    cout << "Material specs: "<<endl<<mat;
                    mMap[name]=mat;
                } else if (tmpString=="camera"){
                    string cameraname;
                    ss >> cameraname;
                    int fovX;
                    ss >> fovX;
                    scene.camera = Camera(cameraname,fovX);
                    cout << "camera: "<<cameraname<<"("<<fovX<<")"<<endl;
                } else if (tmpString=="light"){
                    string type;
                    ss>>type;

                    if (type=="diffuse") {
                        string name;
                        ss >> name;

                        glm::vec3 pos;
                        ss >> pos.x;
                        ss >> pos.y;
                        ss >> pos.z;

                        float red, green, blue;
                        ss >> red;
                        ss >> green;
                        ss >> blue;
                        Color diff(red, green, blue);

                        LightPoint light = LightPoint(name, pos, diff);
                        cout << "light point: "<<name<<"("<<pos.x<<","<<pos.y<<","<<pos.z<<","<<diff<<")"<<endl;
                        lMap[name] = light;
                    }else if (type=="ambient") {
                        string lightname;
                        ss >> lightname;//name get's ignored

                        float red, green, blue;
                        ss >> red;
                        ss >> green;
                        ss >> blue;
                        Color amb(red, green, blue);

                        scene.amb = amb;
                        cout << "ambient light "<<amb<<endl;
                    } else {
                        cout << "type not supported yet."<<endl;
                    }
                } else if (tmpString=="shape"){
                    string classname;
                    ss >> classname;
                    cout << "Shape \""<< classname << "\"."<<endl;
                    transform(classname.begin(), classname.end(),classname.begin(), ::toupper);

                    string name;
                    ss >> name;

                    RenderObject* rObject = nullptr;
                    if (classname=="BOX"){
                        int edge1x, edge1y, edge1z;
                        ss>> edge1x;
                        ss>> edge1y;
                        ss>> edge1z;

                        int edge2x, edge2y, edge2z;
                        ss>> edge2x;
                        ss>> edge2y;
                        ss>> edge2z;

                        string materialString;
                        ss>>materialString;
                        Material material = mMap[materialString];

                        rObject = new Box(
                                name,
                                glm::vec3(edge1x, edge1y, edge1z),
                                glm::vec3(edge2x, edge2y, edge2z),
                                material
                                );
                    }else if (classname=="SPHERE") {
                        int posX, posY, posZ;
                        ss>> posX;
                        ss>> posY;
                        ss>> posZ;
                        float radius;
                        ss>>radius;

                        string materialString;
                        ss>>materialString;
                        Material material = mMap[materialString];

                        rObject = new Sphere(
                                name,
                                glm::vec3(posX, posY, posZ),
                                radius,
                                material
                                );
                    }else cout << "ERROR: Shape \""<< classname << "\" not defined."<<endl;

                    if (rObject != nullptr)
                        roMap[name] = rObject;
                } else
                    cout << "object to define not implemented:"<<ss.str() <<endl;
            } else if (tmpString=="render"){
                ss >> scene.camname;
                ss >> scene.outputFile;
                ss >> scene.resX;
                ss >> scene.resY;
                //set default if not set
                if (scene.resX<=0) scene.resX=480;
                if (scene.resY<=0) scene.resY=320;
                cout << "Scene should be rendered from "<< scene.camname << " at resolution "<<scene.resX<<"x"<< scene.resY<< " to "<<scene.outputFile<<endl;
            } else if (tmpString=="#"){
                cout << line << endl;//just print comment lines
            } else
                cout << "Line not supported:"<<line <<endl;
        }
        file.close();
    }else cout << "Unable to open file";

    //save collected data in scene
    scene.materials = mMap;
    scene.renderObjects = roMap;
    scene.lights = lMap;
    return scene;
}<|endoftext|>


<commit_before>#include "Game.hpp"

Game::Game()
{
}

Game::~Game()
{
	Destroy();
}

bool Game::Initialize(Score * score)
{
	scoreHandler = score;
	enemyDirection = true;
	finished = false;
	victory = false;
	return true;
}

bool Game::Destroy()
{
	player.Shutdown();

	enemies.clear();
	walls.clear();
	bullets.clear();

	return true;
}

int Game::RenderGame(sf::RenderWindow * window, const sf::Time &frameTime)
{
	FinishGameCheck(window, frameTime);

	if (!finished)
	{
		//InputCheck(frameTime.asSeconds());

		for (int i = 0; i < bullets.size(); ++i)
		{
			if (bullets.at(i).IsAlive())
			{
				if (bullets.at(i).GetPosY() < -1)
				{
					bullets.at(i).Kill();
					continue;
				}

				if (CheckCollision(bullets.at(i), player))
				{
					player.Kill();
				}

				for (int j = 0; j < enemies.size(); ++j)
				{
					if (enemies.at(j).IsAlive())
					{
						if (CheckCollision(bullets.at(i), enemies.at(j)))
						{
							scoreHandler->ChangeScore(enemies.at(j).GetPoints());
							enemies.at(j).Kill();
							bullets.at(i).Kill();
							break;
						}
					}
				}

				for (int j = 0; j < walls.size(); ++j)
				{
					if (walls.at(j).IsAlive())
					{
						if (CheckCollision(bullets.at(i), walls.at(j)))
						{
							walls.at(j).Kill();
							bullets.at(i).Kill();
							break;
						}
					}
				}
			}
		}

		aiMove(frameTime);
		enemyFire();

		window->draw(*player.GetModel());
		for (int i = 0; i < bullets.size(); ++i)
		{
			if (bullets.at(i).IsAlive())
			{
				bullets.at(i).Move(100 * frameTime.asSeconds());
				window->draw(*bullets.at(i).GetModel());
			}
		}
		for (int i = 0; i < enemies.size(); ++i)
		{
			if (enemies.at(i).IsAlive())
			{
				if ((enemies.at(i).GetPosX() < 0 || enemies.at(i).GetPosX() > 800) && !enemyDescent)
				{
					enemyDirection = !enemyDirection;
					enemyDescent = true;

					if (enemies.at(i).GetPosX() < 0)
					{
						boundaryCompensation = -enemies.at(i).GetPosX();
					}
					else
					{
						boundaryCompensation = 800 - enemies.at(i).GetPosX();
					}
				}
				window->draw(*enemies.at(i).GetModel());
			}
		}

		for (int i = 0; i < walls.size(); ++i)
		{
			if (walls.at(i).IsAlive())
			{
				window->draw(*walls.at(i).GetModel());
			}
		}

		window->draw(scoreHandler->GetTotalScore());
		window->draw(scoreHandler->GetHighScore());
	}
	else
	{
		if (victory)
		{
			if (scoreHandler->winScore(window))
			{
				scoreHandler->SaveScore();
				return 1;
			}

		}
		else
		{
			if (scoreHandler->loseScore(window))
			{
				scoreHandler->SaveScore();
				return 1;
			}
		}

	}

	return 0;
}

void Game::InputCheck(const float &frameTime)
{
	if (sf::Event::KeyPressed)
	{
		if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
		{
			finished = true;
		}

		if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
		{
			player.Move(frameTime, true);
		}
		else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
		{
			player.Move(frameTime, false);
		}

		if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && !player.IsShooting())
		{
			playerFire();
		}
		else if (!sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
		{
			player.SetShooting(false);
		}
	}
}

bool Game::CheckCollision(Object& object1, Object& object2)
{
	if (object1.GetModel()->getGlobalBounds().intersects(object2.GetModel()->getGlobalBounds()))
	{
		if (object1.GetTeam() != object2.GetTeam())
		{
			return true;
		}
	}
	return false;
}

void Game::aiMove(const sf::Time &frameTime)
{
	for (int i = 0; i < enemies.size(); ++i)
	{
		if (enemies.at(i).IsAlive())
		{
			if (!enemyDescent)
			{
				enemies.at(i).Move(frameTime.asSeconds(), enemyDirection);
			}
			else
			{
				enemies.at(i).Descend();
				enemies.at(i).Move(frameTime.asSeconds(), enemyDirection);
			}
		}
	}
	enemyDescent = false;
}

void Game::playerFire()
{
	bullets.emplace_back();
	bullets.back().Initialize(player.GetPosX() + 9, player.GetPosY(), 1);
	player.SetShooting(true);
}

void Game::enemyFire()
{
	int enemyShoot;

	for (int i = 0; i < enemies.size(); ++i)
	{
		if (enemies.at(i).IsAlive())
		{
			enemyShoot = rand() % 10000;
			if (enemyShoot == 1)
			{
				bullets.emplace_back();
				bullets.back().Initialize(enemies.at(i).GetPosX(), enemies.at(i).GetPosY(), 2);
			}
		}
	}
}

bool Game::PlaceWall(int startPosX, int startPosY)
{
	for (int i = 0; i < 5; ++i)
	{
		for (int j = 0; j < 3; ++j)
		{
			walls.emplace_back();
			walls.back().Initialize(startPosX + i * 15, startPosY + j * 15, 0);
		}
	}

	return true;
}

bool Game::CreatePlayer(int startPosX, int startPosY)
{
	player.Initialize(startPosX, startPosY, 1);
	return true;
}

bool Game::CreateEnemy(int startPosX, int startPosY)
{
	enemies.emplace_back();
	enemies.back().Initialize(startPosX, startPosY, 2);
	return true;
}

void Game::FinishGameCheck(sf::RenderWindow * window, const sf::Time &frameTime)
{
	if (!player.IsAlive())
	{
		finished = true;
	}

	bool isAnyEnemyAlive = false;
	for each(Enemy enemy in enemies) //Check if any enemy is alive
	{
		if (enemy.IsAlive())
		{
			isAnyEnemyAlive = true;
		}
	}

	if (!isAnyEnemyAlive) // Victory if all enemies are dead
	{
		victory = true;
		finished = true;
	}
}
<commit_msg>Changed for each loop slightly<commit_after>#include "Game.hpp"

Game::Game()
{
}

Game::~Game()
{
	Destroy();
}

bool Game::Initialize(Score * score)
{
	scoreHandler = score;
	enemyDirection = true;
	finished = false;
	victory = false;
	return true;
}

bool Game::Destroy()
{
	player.Shutdown();

	enemies.clear();
	walls.clear();
	bullets.clear();

	return true;
}

int Game::RenderGame(sf::RenderWindow * window, const sf::Time &frameTime)
{
	FinishGameCheck(window, frameTime);

	if (!finished)
	{
		//InputCheck(frameTime.asSeconds());

		for (int i = 0; i < bullets.size(); ++i)
		{
			if (bullets.at(i).IsAlive())
			{
				if (bullets.at(i).GetPosY() < -1)
				{
					bullets.at(i).Kill();
					continue;
				}

				if (CheckCollision(bullets.at(i), player))
				{
					player.Kill();
				}

				for (int j = 0; j < enemies.size(); ++j)
				{
					if (enemies.at(j).IsAlive())
					{
						if (CheckCollision(bullets.at(i), enemies.at(j)))
						{
							scoreHandler->ChangeScore(enemies.at(j).GetPoints());
							enemies.at(j).Kill();
							bullets.at(i).Kill();
							break;
						}
					}
				}

				for (int j = 0; j < walls.size(); ++j)
				{
					if (walls.at(j).IsAlive())
					{
						if (CheckCollision(bullets.at(i), walls.at(j)))
						{
							walls.at(j).Kill();
							bullets.at(i).Kill();
							break;
						}
					}
				}
			}
		}

		aiMove(frameTime);
		enemyFire();

		window->draw(*player.GetModel());
		for (int i = 0; i < bullets.size(); ++i)
		{
			if (bullets.at(i).IsAlive())
			{
				bullets.at(i).Move(100 * frameTime.asSeconds());
				window->draw(*bullets.at(i).GetModel());
			}
		}
		for (int i = 0; i < enemies.size(); ++i)
		{
			if (enemies.at(i).IsAlive())
			{
				if ((enemies.at(i).GetPosX() < 0 || enemies.at(i).GetPosX() > 800) && !enemyDescent)
				{
					enemyDirection = !enemyDirection;
					enemyDescent = true;

					if (enemies.at(i).GetPosX() < 0)
					{
						boundaryCompensation = -enemies.at(i).GetPosX();
					}
					else
					{
						boundaryCompensation = 800 - enemies.at(i).GetPosX();
					}
				}
				window->draw(*enemies.at(i).GetModel());
			}
		}

		for (int i = 0; i < walls.size(); ++i)
		{
			if (walls.at(i).IsAlive())
			{
				window->draw(*walls.at(i).GetModel());
			}
		}

		window->draw(scoreHandler->GetTotalScore());
		window->draw(scoreHandler->GetHighScore());
	}
	else
	{
		if (victory)
		{
			if (scoreHandler->winScore(window))
			{
				scoreHandler->SaveScore();
				return 1;
			}

		}
		else
		{
			if (scoreHandler->loseScore(window))
			{
				scoreHandler->SaveScore();
				return 1;
			}
		}

	}

	return 0;
}

void Game::InputCheck(const float &frameTime)
{
	if (sf::Event::KeyPressed)
	{
		if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
		{
			finished = true;
		}

		if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
		{
			player.Move(frameTime, true);
		}
		else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
		{
			player.Move(frameTime, false);
		}

		if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && !player.IsShooting())
		{
			playerFire();
		}
		else if (!sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
		{
			player.SetShooting(false);
		}
	}
}

bool Game::CheckCollision(Object& object1, Object& object2)
{
	if (object1.GetModel()->getGlobalBounds().intersects(object2.GetModel()->getGlobalBounds()))
	{
		if (object1.GetTeam() != object2.GetTeam())
		{
			return true;
		}
	}
	return false;
}

void Game::aiMove(const sf::Time &frameTime)
{
	for (int i = 0; i < enemies.size(); ++i)
	{
		if (enemies.at(i).IsAlive())
		{
			if (!enemyDescent)
			{
				enemies.at(i).Move(frameTime.asSeconds(), enemyDirection);
			}
			else
			{
				enemies.at(i).Descend();
				enemies.at(i).Move(frameTime.asSeconds(), enemyDirection);
			}
		}
	}
	enemyDescent = false;
}

void Game::playerFire()
{
	bullets.emplace_back();
	bullets.back().Initialize(player.GetPosX() + 9, player.GetPosY(), 1);
	player.SetShooting(true);
}

void Game::enemyFire()
{
	int enemyShoot;

	for (int i = 0; i < enemies.size(); ++i)
	{
		if (enemies.at(i).IsAlive())
		{
			enemyShoot = rand() % 10000;
			if (enemyShoot == 1)
			{
				bullets.emplace_back();
				bullets.back().Initialize(enemies.at(i).GetPosX(), enemies.at(i).GetPosY(), 2);
			}
		}
	}
}

bool Game::PlaceWall(int startPosX, int startPosY)
{
	for (int i = 0; i < 5; ++i)
	{
		for (int j = 0; j < 3; ++j)
		{
			walls.emplace_back();
			walls.back().Initialize(startPosX + i * 15, startPosY + j * 15, 0);
		}
	}

	return true;
}

bool Game::CreatePlayer(int startPosX, int startPosY)
{
	player.Initialize(startPosX, startPosY, 1);
	return true;
}

bool Game::CreateEnemy(int startPosX, int startPosY)
{
	enemies.emplace_back();
	enemies.back().Initialize(startPosX, startPosY, 2);
	return true;
}

void Game::FinishGameCheck(sf::RenderWindow * window, const sf::Time &frameTime)
{
	if (!player.IsAlive())
	{
		finished = true;
	}

	bool isAnyEnemyAlive = false;
	for (auto& enemy : enemies) //Check if any enemy is alive
	{
		if (enemy.IsAlive())
		{
			isAnyEnemyAlive = true;
		}
	}

	if (!isAnyEnemyAlive) // Victory if all enemies are dead
	{
		victory = true;
		finished = true;
	}
}
<|endoftext|>