<commit_before>#include "behavior_functions.h"
#include <ctime> // to make truly random
#include <cstdlib>
#include <iostream>
#include <cmath>

bool seeded;
namespace mbmore {

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool EveryXTimestep(int curr_time, int interval) {
  // true when there is no remainder, so it is the Xth timestep
  return curr_time % interval == 0;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool EveryRandomXTimestep(int frequency, int rng_seed) {

  if (frequency == 0) {
    return false;
  }

  if (!seeded) {
    if (rng_seed == -1) {
      srand(time(0));    // seed random
    }
    else {
      srand(rng_seed);   // user-defined fixed seed
    }
    seeded = true;
  }
  double midpoint = frequency / 2;

  // The interwebs say that rand is not truly random.
  //  tRan = rand() % frequency;
  double cur_rand = rand();
  int tRan = 1 + (cur_rand*(1.0/(RAND_MAX+1.0))) * frequency;
  //  int tRan = 1 + uniform_deviate_(rand()) * frequency;
  //    std::cout << "EveryRandom: " << cur_rand/RAND_MAX << std::endl;

  if (tRan == midpoint) {
    return true;
  } else {
   return false;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Returns true for this instance with a particular likelihood of getting a
// True over all instances.

  bool XLikely(double prob, int rng_seed) {

    /*
  if (prob == 0) {
    return false;
  }
    */

  if (!seeded) {
    if (rng_seed == -1) {
      srand(time(0));    // seed random
    }
    else {
      srand(rng_seed);   // user-defined fixed seed
    }
    seeded = true;
  }

  double cur_rand = rand();
  double tRan = (cur_rand/RAND_MAX);

  if (tRan <= prob) {
    return true;
  } else {
   return false;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
bool EveryRandomXTimestep(int frequency) {
  bool time_seed = 0 ;
  return EveryRandomXTimestep(frequency, time_seed);
}
*/

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Use Box-Muller algorithm to make a random number sampled from
// a normal distribution

double RNG_NormalDist(double mean, double sigma, int rng_seed) {

  if (sigma == 0 ) {
    return mean ;
  }

  static double n2 = 0.0;
  static int n2_cached = 0;

  double result ;
  double x, y, r;
  double rand1, rand2;

  if (!seeded) {
    if (rng_seed == -1) {
      srand(time(0)); // if seeding on time
    }
    else {
      srand(rng_seed);  //use fixed seed for reproducibility
    }
    seeded = true;
  }

  do {
    rand1 = rand();
    rand2 = rand();
    x = 2.0*rand1/RAND_MAX - 1;
    y = 2.0*rand2/RAND_MAX - 1;
    r = x*x + y*y;
    //    std::cout << rand1/RAND_MAX << "  " << rand2/RAND_MAX  << std::endl;
  } while (r == 0.0 || r > 1.0);

  double d = std::sqrt(-2.0*log(r)/r);
  double n1 = x*d;
  n2 = y*d;

  /*
  if (!n2_cached) {
    n2_cached = 1;
    return n1*sigma + mean;
  }
  else {
    n2_cached = 0 ;
    return n2*sigma + mean;
  }
  */
  //  std::cout << "NormalDist: " << n1*sigma + mean  << std::endl;
  return n1*sigma + mean;

}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Randomly choose a discrete number between min and max
// (ie. integer betweeen 1 and 5)

double RNG_Integer(double min, double max, int rng_seed) {

  if (!seeded) {
    if (rng_seed == -1) {
      srand(time(0)); // if seeding on time
    }
    else {
      srand(rng_seed);  //use fixed seed for reproducibility
    }
    seeded = true;
  }

  int tRan = min + (rand()*(1.0/(RAND_MAX+1.0))) * max;

  return tRan;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
double RNG_NormalDist(double mean, double sigma) {
  bool time_seed = 0;
  return RNG_NormalDist(mean, sigma, time_seed);
}
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
// Internal function to make a better random number
double uniform_deviate_ ( int seed ){
  return seed * ( 1.0 / ( RAND_MAX + 1.0 ) );
}
*/

} // namespace mbmore<commit_msg>found a bug in EveryRandomX, it couldnt have a frequency of one<commit_after>#include "behavior_functions.h"
#include <ctime> // to make truly random
#include <cstdlib>
#include <iostream>
#include <cmath>

bool seeded;
namespace mbmore {

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool EveryXTimestep(int curr_time, int interval) {
  // true when there is no remainder, so it is the Xth timestep
  return curr_time % interval == 0;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool EveryRandomXTimestep(int frequency, int rng_seed) {
  //TODO: Doesn't work for a frequency of 1
  if (frequency == 0) {
    return false;
  }

  if (!seeded) {
    if (rng_seed == -1) {
      srand(time(0));    // seed random
    }
    else {
      srand(rng_seed);   // user-defined fixed seed
    }
    seeded = true;
  }

  // Because this relies on integer rounding, it fails for a frequency of
  // 1 because the midpoint rounds to zero.
  double midpoint;
  (frequency == 1) ? (midpoint = 1) : (midpoint = frequency / 2);

  // The interwebs say that rand is not truly random.
  //  tRan = rand() % frequency;
  double cur_rand = rand();
  int tRan = 1 + (cur_rand*(1.0/(RAND_MAX+1.0))) * frequency;
  //  int tRan = 1 + uniform_deviate_(rand()) * frequency;
  //  std::cout << "tRan: " << tRan << " midpoint " << midpoint << std::endl;

  if (tRan == midpoint) {
    return true;
  } else {
   return false;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Returns true for this instance with a particular likelihood of getting a
// True over all instances.

  bool XLikely(double prob, int rng_seed) {

    /*
  if (prob == 0) {
    return false;
  }
    */

  if (!seeded) {
    if (rng_seed == -1) {
      srand(time(0));    // seed random
    }
    else {
      srand(rng_seed);   // user-defined fixed seed
    }
    seeded = true;
  }

  double cur_rand = rand();
  double tRan = (cur_rand/RAND_MAX);

  if (tRan <= prob) {
    return true;
  } else {
   return false;
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
bool EveryRandomXTimestep(int frequency) {
  bool time_seed = 0 ;
  return EveryRandomXTimestep(frequency, time_seed);
}
*/

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Use Box-Muller algorithm to make a random number sampled from
// a normal distribution

double RNG_NormalDist(double mean, double sigma, int rng_seed) {

  if (sigma == 0 ) {
    return mean ;
  }

  static double n2 = 0.0;
  static int n2_cached = 0;

  double result ;
  double x, y, r;
  double rand1, rand2;

  if (!seeded) {
    if (rng_seed == -1) {
      srand(time(0)); // if seeding on time
    }
    else {
      srand(rng_seed);  //use fixed seed for reproducibility
    }
    seeded = true;
  }

  do {
    rand1 = rand();
    rand2 = rand();
    x = 2.0*rand1/RAND_MAX - 1;
    y = 2.0*rand2/RAND_MAX - 1;
    r = x*x + y*y;
    //    std::cout << rand1/RAND_MAX << "  " << rand2/RAND_MAX  << std::endl;
  } while (r == 0.0 || r > 1.0);

  double d = std::sqrt(-2.0*log(r)/r);
  double n1 = x*d;
  n2 = y*d;

  /*
  if (!n2_cached) {
    n2_cached = 1;
    return n1*sigma + mean;
  }
  else {
    n2_cached = 0 ;
    return n2*sigma + mean;
  }
  */
  //  std::cout << "NormalDist: " << n1*sigma + mean  << std::endl;
  return n1*sigma + mean;

}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Randomly choose a discrete number between min and max
// (ie. integer betweeen 1 and 5)

double RNG_Integer(double min, double max, int rng_seed) {

  if (!seeded) {
    if (rng_seed == -1) {
      srand(time(0)); // if seeding on time
    }
    else {
      srand(rng_seed);  //use fixed seed for reproducibility
    }
    seeded = true;
  }

  int tRan = min + (rand()*(1.0/(RAND_MAX+1.0))) * max;

  return tRan;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
double RNG_NormalDist(double mean, double sigma) {
  bool time_seed = 0;
  return RNG_NormalDist(mean, sigma, time_seed);
}
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
// Internal function to make a better random number
double uniform_deviate_ ( int seed ){
  return seed * ( 1.0 / ( RAND_MAX + 1.0 ) );
}
*/

} // namespace mbmore<|endoftext|>


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

Copyright (c) 2000-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

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

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

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreResourceManager.h"

#include "OgreException.h"
#include "OgreArchive.h"
#include "OgreArchiveManager.h"
#include "OgreStringVector.h"
#include "OgreStringConverter.h"
#include "OgreResourceGroupManager.h"

namespace Ogre {

    //-----------------------------------------------------------------------
    ResourceManager::ResourceManager()
		: mNextHandle(1), mMemoryUsage(0), mLoadOrder(0), mVerbose(true)
    {
        // Init memory limit & usage
        mMemoryBudget = std::numeric_limits<unsigned long>::max();
    }
    //-----------------------------------------------------------------------
    ResourceManager::~ResourceManager()
    {
        removeAll();
    }
	//-----------------------------------------------------------------------
    ResourcePtr ResourceManager::create(const String& name, const String& group,
		bool isManual, ManualResourceLoader* loader, const NameValuePairList* params)
	{
		// Call creation implementation
		ResourcePtr ret = ResourcePtr(
            createImpl(name, getNextHandle(), group, isManual, loader, params));
        if (params)
            ret->setParameterList(*params);

		addImpl(ret);
		// Tell resource group manager
		ResourceGroupManager::getSingleton()._notifyResourceCreated(ret);
		return ret;

	}
    //-----------------------------------------------------------------------
    ResourceManager::ResourceCreateOrRetrieveResult
	ResourceManager::createOrRetrieve(
		const String& name, const String& group,
		bool isManual, ManualResourceLoader* loader,
		const NameValuePairList* params)
	{
		// Lock for the whole get / insert
		OGRE_LOCK_AUTO_MUTEX

		ResourcePtr res = getByName(name, group);
		bool created = false;
		if (res.isNull())
		{
			created = true;
			res = create(name, group, isManual, loader, params);
		}

		return ResourceCreateOrRetrieveResult(res, created);
	}
    //-----------------------------------------------------------------------
    ResourcePtr ResourceManager::prepare(const String& name,
        const String& group, bool isManual, ManualResourceLoader* loader,
        const NameValuePairList* loadParams)
    {
        ResourcePtr r = createOrRetrieve(name,group,isManual,loader,loadParams).first;
		// ensure prepared
        r->prepare();
        return r;
    }
    //-----------------------------------------------------------------------
    ResourcePtr ResourceManager::load(const String& name,
        const String& group, bool isManual, ManualResourceLoader* loader,
        const NameValuePairList* loadParams)
    {
        ResourcePtr r = createOrRetrieve(name,group,isManual,loader,loadParams).first;
		// ensure loaded
        r->load();
        return r;
    }
    //-----------------------------------------------------------------------
	void ResourceManager::addImpl( ResourcePtr& res )
	{
		OGRE_LOCK_AUTO_MUTEX

			std::pair<ResourceMap::iterator, bool> result;
		if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup()))
		{
			result = mResources.insert( ResourceMap::value_type( res->getName(), res ) );
		}
		else
		{
			ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(res->getGroup());

			// we will create the group if it doesn't exists in our list
			if( itGroup == mResourcesWithGroup.end())
			{
				ResourceMap dummy;
				mResourcesWithGroup.insert( ResourceWithGroupMap::value_type( res->getGroup(), dummy ) );
				itGroup = mResourcesWithGroup.find(res->getGroup());
			}
			result = itGroup->second.insert( ResourceMap::value_type( res->getName(), res ) );

		}

		if (!result.second)
		{
			// Attempt to resolve the collision
			if(ResourceGroupManager::getSingleton().getLoadingListener())
			{
				if(ResourceGroupManager::getSingleton().getLoadingListener()->resourceCollision(res.get(), this))
				{
					// Try to do the addition again, no seconds attempts to resolve collisions are allowed
					std::pair<ResourceMap::iterator, bool> result;
					if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup()))
					{
						result = mResources.insert( ResourceMap::value_type( res->getName(), res ) );
					}
					else
					{
						ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(res->getGroup());
						result = itGroup->second.insert( ResourceMap::value_type( res->getName(), res ) );
					}
					if (!result.second)
					{
						OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the name " + res->getName() +
							" already exists.", "ResourceManager::add");
					}

					std::pair<ResourceHandleMap::iterator, bool> resultHandle =
						mResourcesByHandle.insert( ResourceHandleMap::value_type( res->getHandle(), res ) );
					if (!resultHandle.second)
					{
						OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the handle " +
							StringConverter::toString((long) (res->getHandle())) +
							" already exists.", "ResourceManager::add");
					}
				}
			}
		}
		else
		{
			// Insert the handle
			std::pair<ResourceHandleMap::iterator, bool> resultHandle =
				mResourcesByHandle.insert( ResourceHandleMap::value_type( res->getHandle(), res ) );
			if (!resultHandle.second)
			{
				OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the handle " +
					StringConverter::toString((long) (res->getHandle())) +
					" already exists.", "ResourceManager::add");
			}
		}
	}
	//-----------------------------------------------------------------------
	void ResourceManager::removeImpl( ResourcePtr& res )
	{
		OGRE_LOCK_AUTO_MUTEX

		if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup()))
		{
			ResourceMap::iterator nameIt = mResources.find(res->getName());
			if (nameIt != mResources.end())
			{
				mResources.erase(nameIt);
			}
		}
		else
		{
			ResourceWithGroupMap::iterator groupIt = mResourcesWithGroup.find(res->getGroup());
			if (groupIt != mResourcesWithGroup.end())
			{
				ResourceMap::iterator nameIt = groupIt->second.find(res->getName());
				if (nameIt != groupIt->second.end())
				{
					groupIt->second.erase(nameIt);
				}

				if (groupIt->second.empty())
				{
					mResourcesWithGroup.erase(groupIt);
				}
			}
		}

		ResourceHandleMap::iterator handleIt = mResourcesByHandle.find(res->getHandle());
		if (handleIt != mResourcesByHandle.end())
		{
			mResourcesByHandle.erase(handleIt);
		}
		// Tell resource group manager
		ResourceGroupManager::getSingleton()._notifyResourceRemoved(res);
	}
    //-----------------------------------------------------------------------
    void ResourceManager::setMemoryBudget( size_t bytes)
    {
        // Update limit & check usage
        mMemoryBudget = bytes;
        checkUsage();
    }
    //-----------------------------------------------------------------------
    size_t ResourceManager::getMemoryBudget(void) const
    {
        return mMemoryBudget;
    }
	//-----------------------------------------------------------------------
	void ResourceManager::unload(const String& name)
	{
		ResourcePtr res = getByName(name);

		if (!res.isNull())
		{
			// Unload resource
			res->unload();

		}
	}
	//-----------------------------------------------------------------------
	void ResourceManager::unload(ResourceHandle handle)
	{
		ResourcePtr res = getByHandle(handle);

		if (!res.isNull())
		{
			// Unload resource
			res->unload();

		}
	}
	//-----------------------------------------------------------------------
	void ResourceManager::unloadAll(bool reloadableOnly)
	{
		OGRE_LOCK_AUTO_MUTEX

		ResourceMap::iterator i, iend;
		iend = mResources.end();
		for (i = mResources.begin(); i != iend; ++i)
		{
			if (!reloadableOnly || i->second->isReloadable())
			{
				i->second->unload();
			}
		}

	}
	//-----------------------------------------------------------------------
	void ResourceManager::reloadAll(bool reloadableOnly)
	{
		OGRE_LOCK_AUTO_MUTEX

		ResourceMap::iterator i, iend;
		iend = mResources.end();
		for (i = mResources.begin(); i != iend; ++i)
		{
			if (!reloadableOnly || i->second->isReloadable())
			{
				i->second->reload();
			}
		}

	}
    //-----------------------------------------------------------------------
    void ResourceManager::unloadUnreferencedResources(bool reloadableOnly)
    {
        OGRE_LOCK_AUTO_MUTEX

        ResourceMap::iterator i, iend;
        iend = mResources.end();
        for (i = mResources.begin(); i != iend; ++i)
        {
            // A use count of 3 means that only RGM and RM have references
            // RGM has one (this one) and RM has 2 (by name and by handle)
            if (i->second.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS)
            {
                Resource* res = i->second.get();
                if (!reloadableOnly || res->isReloadable())
                {
                    res->unload();
                }
            }
        }
    }
    //-----------------------------------------------------------------------
    void ResourceManager::reloadUnreferencedResources(bool reloadableOnly)
    {
        OGRE_LOCK_AUTO_MUTEX

        ResourceMap::iterator i, iend;
        iend = mResources.end();
        for (i = mResources.begin(); i != iend; ++i)
        {
            // A use count of 3 means that only RGM and RM have references
            // RGM has one (this one) and RM has 2 (by name and by handle)
            if (i->second.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS)
            {
                Resource* res = i->second.get();
                if (!reloadableOnly || res->isReloadable())
                {
                    res->reload();
                }
            }
        }
    }
    //-----------------------------------------------------------------------
    void ResourceManager::remove(ResourcePtr& res)
    {
        removeImpl(res);
    }
	//-----------------------------------------------------------------------
	void ResourceManager::remove(const String& name)
	{
		ResourcePtr res = getByName(name);

		if (!res.isNull())
		{
			removeImpl(res);
		}
	}
	//-----------------------------------------------------------------------
	void ResourceManager::remove(ResourceHandle handle)
	{
		ResourcePtr res = getByHandle(handle);

		if (!res.isNull())
		{
			removeImpl(res);
		}
	}
	//-----------------------------------------------------------------------
	void ResourceManager::removeAll(void)
	{
		OGRE_LOCK_AUTO_MUTEX

		mResources.clear();
		mResourcesWithGroup.clear();
		mResourcesByHandle.clear();
		// Notify resource group manager
		ResourceGroupManager::getSingleton()._notifyAllResourcesRemoved(this);
	}
    //-----------------------------------------------------------------------
    ResourcePtr ResourceManager::getByName(const String& name, const String& groupName /* = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME */)
    {
		OGRE_LOCK_AUTO_MUTEX

		ResourcePtr res;

		// if not in the global pool - get it from the grouped pool
		if(!ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(groupName))
		{
			ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(groupName);

			if( itGroup != mResourcesWithGroup.end())
			{
				ResourceMap::iterator it = itGroup->second.find(name);

				if( it != itGroup->second.end())
				{
					res = it->second;
				}
			}
		}

		// if didn't find it the grouped pool - get it from the global pool
		if (res.isNull())
		{

			ResourceMap::iterator it = mResources.find(name);

			if( it != mResources.end())
			{
				res = it->second;
			}
			else
			{
				// this is the case when we need to search also in the grouped hash
				if (groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME)
				{
					ResourceWithGroupMap::iterator iter = mResourcesWithGroup.begin();
					ResourceWithGroupMap::iterator iterE = mResourcesWithGroup.end();
					for ( ; iter != iterE ; iter++ )
					{
						ResourceMap::iterator it = iter->second.find(name);

						if( it != iter->second.end())
						{
							res = it->second;
							break;
						}
					}
				}
			}
		}

		return res;

    }
    //-----------------------------------------------------------------------
    ResourcePtr ResourceManager::getByHandle(ResourceHandle handle)
    {
		OGRE_LOCK_AUTO_MUTEX

        ResourceHandleMap::iterator it = mResourcesByHandle.find(handle);
        if (it == mResourcesByHandle.end())
        {
            return ResourcePtr();
        }
        else
        {
            return it->second;
        }
    }
    //-----------------------------------------------------------------------
    ResourceHandle ResourceManager::getNextHandle(void)
    {
		OGRE_LOCK_AUTO_MUTEX

        return mNextHandle++;
    }
    //-----------------------------------------------------------------------
    void ResourceManager::checkUsage(void)
    {
        // TODO Page out here?
    }
	//-----------------------------------------------------------------------
	void ResourceManager::_notifyResourceTouched(Resource* res)
	{
		// TODO
	}
	//-----------------------------------------------------------------------
	void ResourceManager::_notifyResourceLoaded(Resource* res)
	{
		OGRE_LOCK_AUTO_MUTEX

		mMemoryUsage += res->getSize();
	}
	//-----------------------------------------------------------------------
	void ResourceManager::_notifyResourceUnloaded(Resource* res)
	{
		OGRE_LOCK_AUTO_MUTEX

		mMemoryUsage -= res->getSize();
	}
	//-----------------------------------------------------------------------

}

<commit_msg>fixed a deadlock<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-2006 Torus Knot Software Ltd
Also see acknowledgements in Readme.html

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

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

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

You may alternatively use this source under the terms of a specific version of
the OGRE Unrestricted License provided you have obtained such a license from
Torus Knot Software Ltd.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreResourceManager.h"

#include "OgreException.h"
#include "OgreArchive.h"
#include "OgreArchiveManager.h"
#include "OgreStringVector.h"
#include "OgreStringConverter.h"
#include "OgreResourceGroupManager.h"

namespace Ogre {

    //-----------------------------------------------------------------------
    ResourceManager::ResourceManager()
		: mNextHandle(1), mMemoryUsage(0), mLoadOrder(0), mVerbose(true)
    {
        // Init memory limit & usage
        mMemoryBudget = std::numeric_limits<unsigned long>::max();
    }
    //-----------------------------------------------------------------------
    ResourceManager::~ResourceManager()
    {
        removeAll();
    }
	//-----------------------------------------------------------------------
    ResourcePtr ResourceManager::create(const String& name, const String& group,
		bool isManual, ManualResourceLoader* loader, const NameValuePairList* params)
	{
		// Call creation implementation
		ResourcePtr ret = ResourcePtr(
            createImpl(name, getNextHandle(), group, isManual, loader, params));
        if (params)
            ret->setParameterList(*params);

		addImpl(ret);
		// Tell resource group manager
		ResourceGroupManager::getSingleton()._notifyResourceCreated(ret);
		return ret;

	}
    //-----------------------------------------------------------------------
    ResourceManager::ResourceCreateOrRetrieveResult
	ResourceManager::createOrRetrieve(
		const String& name, const String& group,
		bool isManual, ManualResourceLoader* loader,
		const NameValuePairList* params)
	{
		// Lock for the whole get / insert
		OGRE_LOCK_AUTO_MUTEX

		ResourcePtr res = getByName(name, group);
		bool created = false;
		if (res.isNull())
		{
			created = true;
			res = create(name, group, isManual, loader, params);
		}

		return ResourceCreateOrRetrieveResult(res, created);
	}
    //-----------------------------------------------------------------------
    ResourcePtr ResourceManager::prepare(const String& name,
        const String& group, bool isManual, ManualResourceLoader* loader,
        const NameValuePairList* loadParams)
    {
        ResourcePtr r = createOrRetrieve(name,group,isManual,loader,loadParams).first;
		// ensure prepared
        r->prepare();
        return r;
    }
    //-----------------------------------------------------------------------
    ResourcePtr ResourceManager::load(const String& name,
        const String& group, bool isManual, ManualResourceLoader* loader,
        const NameValuePairList* loadParams)
    {
        ResourcePtr r = createOrRetrieve(name,group,isManual,loader,loadParams).first;
		// ensure loaded
        r->load();
        return r;
    }
    //-----------------------------------------------------------------------
	void ResourceManager::addImpl( ResourcePtr& res )
	{
		OGRE_LOCK_AUTO_MUTEX

			std::pair<ResourceMap::iterator, bool> result;
		if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup()))
		{
			result = mResources.insert( ResourceMap::value_type( res->getName(), res ) );
		}
		else
		{
			ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(res->getGroup());

			// we will create the group if it doesn't exists in our list
			if( itGroup == mResourcesWithGroup.end())
			{
				ResourceMap dummy;
				mResourcesWithGroup.insert( ResourceWithGroupMap::value_type( res->getGroup(), dummy ) );
				itGroup = mResourcesWithGroup.find(res->getGroup());
			}
			result = itGroup->second.insert( ResourceMap::value_type( res->getName(), res ) );

		}

		if (!result.second)
		{
			// Attempt to resolve the collision
			if(ResourceGroupManager::getSingleton().getLoadingListener())
			{
				if(ResourceGroupManager::getSingleton().getLoadingListener()->resourceCollision(res.get(), this))
				{
					// Try to do the addition again, no seconds attempts to resolve collisions are allowed
					std::pair<ResourceMap::iterator, bool> result;
					if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup()))
					{
						result = mResources.insert( ResourceMap::value_type( res->getName(), res ) );
					}
					else
					{
						ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(res->getGroup());
						result = itGroup->second.insert( ResourceMap::value_type( res->getName(), res ) );
					}
					if (!result.second)
					{
						OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the name " + res->getName() +
							" already exists.", "ResourceManager::add");
					}

					std::pair<ResourceHandleMap::iterator, bool> resultHandle =
						mResourcesByHandle.insert( ResourceHandleMap::value_type( res->getHandle(), res ) );
					if (!resultHandle.second)
					{
						OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the handle " +
							StringConverter::toString((long) (res->getHandle())) +
							" already exists.", "ResourceManager::add");
					}
				}
			}
		}
		else
		{
			// Insert the handle
			std::pair<ResourceHandleMap::iterator, bool> resultHandle =
				mResourcesByHandle.insert( ResourceHandleMap::value_type( res->getHandle(), res ) );
			if (!resultHandle.second)
			{
				OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "Resource with the handle " +
					StringConverter::toString((long) (res->getHandle())) +
					" already exists.", "ResourceManager::add");
			}
		}
	}
	//-----------------------------------------------------------------------
	void ResourceManager::removeImpl( ResourcePtr& res )
	{
		OGRE_LOCK_AUTO_MUTEX

		if(ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(res->getGroup()))
		{
			ResourceMap::iterator nameIt = mResources.find(res->getName());
			if (nameIt != mResources.end())
			{
				mResources.erase(nameIt);
			}
		}
		else
		{
			ResourceWithGroupMap::iterator groupIt = mResourcesWithGroup.find(res->getGroup());
			if (groupIt != mResourcesWithGroup.end())
			{
				ResourceMap::iterator nameIt = groupIt->second.find(res->getName());
				if (nameIt != groupIt->second.end())
				{
					groupIt->second.erase(nameIt);
				}

				if (groupIt->second.empty())
				{
					mResourcesWithGroup.erase(groupIt);
				}
			}
		}

		ResourceHandleMap::iterator handleIt = mResourcesByHandle.find(res->getHandle());
		if (handleIt != mResourcesByHandle.end())
		{
			mResourcesByHandle.erase(handleIt);
		}
		// Tell resource group manager
		ResourceGroupManager::getSingleton()._notifyResourceRemoved(res);
	}
    //-----------------------------------------------------------------------
    void ResourceManager::setMemoryBudget( size_t bytes)
    {
        // Update limit & check usage
        mMemoryBudget = bytes;
        checkUsage();
    }
    //-----------------------------------------------------------------------
    size_t ResourceManager::getMemoryBudget(void) const
    {
        return mMemoryBudget;
    }
	//-----------------------------------------------------------------------
	void ResourceManager::unload(const String& name)
	{
		ResourcePtr res = getByName(name);

		if (!res.isNull())
		{
			// Unload resource
			res->unload();

		}
	}
	//-----------------------------------------------------------------------
	void ResourceManager::unload(ResourceHandle handle)
	{
		ResourcePtr res = getByHandle(handle);

		if (!res.isNull())
		{
			// Unload resource
			res->unload();

		}
	}
	//-----------------------------------------------------------------------
	void ResourceManager::unloadAll(bool reloadableOnly)
	{
		OGRE_LOCK_AUTO_MUTEX

		ResourceMap::iterator i, iend;
		iend = mResources.end();
		for (i = mResources.begin(); i != iend; ++i)
		{
			if (!reloadableOnly || i->second->isReloadable())
			{
				i->second->unload();
			}
		}

	}
	//-----------------------------------------------------------------------
	void ResourceManager::reloadAll(bool reloadableOnly)
	{
		OGRE_LOCK_AUTO_MUTEX

		ResourceMap::iterator i, iend;
		iend = mResources.end();
		for (i = mResources.begin(); i != iend; ++i)
		{
			if (!reloadableOnly || i->second->isReloadable())
			{
				i->second->reload();
			}
		}

	}
    //-----------------------------------------------------------------------
    void ResourceManager::unloadUnreferencedResources(bool reloadableOnly)
    {
        OGRE_LOCK_AUTO_MUTEX

        ResourceMap::iterator i, iend;
        iend = mResources.end();
        for (i = mResources.begin(); i != iend; ++i)
        {
            // A use count of 3 means that only RGM and RM have references
            // RGM has one (this one) and RM has 2 (by name and by handle)
            if (i->second.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS)
            {
                Resource* res = i->second.get();
                if (!reloadableOnly || res->isReloadable())
                {
                    res->unload();
                }
            }
        }
    }
    //-----------------------------------------------------------------------
    void ResourceManager::reloadUnreferencedResources(bool reloadableOnly)
    {
        OGRE_LOCK_AUTO_MUTEX

        ResourceMap::iterator i, iend;
        iend = mResources.end();
        for (i = mResources.begin(); i != iend; ++i)
        {
            // A use count of 3 means that only RGM and RM have references
            // RGM has one (this one) and RM has 2 (by name and by handle)
            if (i->second.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS)
            {
                Resource* res = i->second.get();
                if (!reloadableOnly || res->isReloadable())
                {
                    res->reload();
                }
            }
        }
    }
    //-----------------------------------------------------------------------
    void ResourceManager::remove(ResourcePtr& res)
    {
        removeImpl(res);
    }
	//-----------------------------------------------------------------------
	void ResourceManager::remove(const String& name)
	{
		ResourcePtr res = getByName(name);

		if (!res.isNull())
		{
			removeImpl(res);
		}
	}
	//-----------------------------------------------------------------------
	void ResourceManager::remove(ResourceHandle handle)
	{
		ResourcePtr res = getByHandle(handle);

		if (!res.isNull())
		{
			removeImpl(res);
		}
	}
	//-----------------------------------------------------------------------
	void ResourceManager::removeAll(void)
	{
		OGRE_LOCK_AUTO_MUTEX

		mResources.clear();
		mResourcesWithGroup.clear();
		mResourcesByHandle.clear();
		// Notify resource group manager
		ResourceGroupManager::getSingleton()._notifyAllResourcesRemoved(this);
	}
    //-----------------------------------------------------------------------
    ResourcePtr ResourceManager::getByName(const String& name, const String& groupName /* = ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME */)
    {
		ResourcePtr res;

		// if not in the global pool - get it from the grouped pool
		if(!ResourceGroupManager::getSingleton().isResourceGroupInGlobalPool(groupName))
		{
			OGRE_LOCK_AUTO_MUTEX
			ResourceWithGroupMap::iterator itGroup = mResourcesWithGroup.find(groupName);

			if( itGroup != mResourcesWithGroup.end())
			{
				ResourceMap::iterator it = itGroup->second.find(name);

				if( it != itGroup->second.end())
				{
					res = it->second;
				}
			}
		}

		// if didn't find it the grouped pool - get it from the global pool
		if (res.isNull())
		{
			OGRE_LOCK_AUTO_MUTEX

			ResourceMap::iterator it = mResources.find(name);

			if( it != mResources.end())
			{
				res = it->second;
			}
			else
			{
				// this is the case when we need to search also in the grouped hash
				if (groupName == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME)
				{
					ResourceWithGroupMap::iterator iter = mResourcesWithGroup.begin();
					ResourceWithGroupMap::iterator iterE = mResourcesWithGroup.end();
					for ( ; iter != iterE ; iter++ )
					{
						ResourceMap::iterator it = iter->second.find(name);

						if( it != iter->second.end())
						{
							res = it->second;
							break;
						}
					}
				}
			}
		}

		return res;
    }
    //-----------------------------------------------------------------------
    ResourcePtr ResourceManager::getByHandle(ResourceHandle handle)
    {
		OGRE_LOCK_AUTO_MUTEX

        ResourceHandleMap::iterator it = mResourcesByHandle.find(handle);
        if (it == mResourcesByHandle.end())
        {
            return ResourcePtr();
        }
        else
        {
            return it->second;
        }
    }
    //-----------------------------------------------------------------------
    ResourceHandle ResourceManager::getNextHandle(void)
    {
		OGRE_LOCK_AUTO_MUTEX

        return mNextHandle++;
    }
    //-----------------------------------------------------------------------
    void ResourceManager::checkUsage(void)
    {
        // TODO Page out here?
    }
	//-----------------------------------------------------------------------
	void ResourceManager::_notifyResourceTouched(Resource* res)
	{
		// TODO
	}
	//-----------------------------------------------------------------------
	void ResourceManager::_notifyResourceLoaded(Resource* res)
	{
		OGRE_LOCK_AUTO_MUTEX

		mMemoryUsage += res->getSize();
	}
	//-----------------------------------------------------------------------
	void ResourceManager::_notifyResourceUnloaded(Resource* res)
	{
		OGRE_LOCK_AUTO_MUTEX

		mMemoryUsage -= res->getSize();
	}
	//-----------------------------------------------------------------------

}

<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "OgreRenderingModule.h"
#include "Renderer.h"
#include "EC_Placeable.h"
#include "Entity.h"
#include "RexNetworkUtils.h"

#include <Ogre.h>
#include <QDebug>

using namespace OgreRenderer;

void SetShowBoundingBoxRecursive(Ogre::SceneNode* node, bool enable)
{
    if (!node)
        return;
    node->showBoundingBox(enable);
    int numChildren = node->numChildren();
    for (int i = 0; i < numChildren; ++i)
    {
        Ogre::SceneNode* childNode = dynamic_cast<Ogre::SceneNode*>(node->getChild(i));
        if (childNode)
            SetShowBoundingBoxRecursive(childNode, enable);
    }
}

EC_Placeable::EC_Placeable(IModule* module) :
    IComponent(module->GetFramework()),
    renderer_(checked_static_cast<OgreRenderingModule*>(module)->GetRenderer()),
    scene_node_(0),
    link_scene_node_(0),
    attached_(false),
    select_priority_(0),
    transform(this, "Transform"),
    drawDebug(this, "Show bounding box", false)
{
    RendererPtr renderer = renderer_.lock();
    Ogre::SceneManager* scene_mgr = renderer->GetSceneManager();
    link_scene_node_ = scene_mgr->createSceneNode();
    scene_node_ = scene_mgr->createSceneNode();
    link_scene_node_->addChild(scene_node_);

    // In case the placeable is used for camera control, set fixed yaw axis
    link_scene_node_->setFixedYawAxis(true, Ogre::Vector3::UNIT_Z);

    // Hook the transform attribute change
    connect(this, SIGNAL(OnAttributeChanged(IAttribute*, AttributeChange::Type)),
        SLOT(HandleAttributeChanged(IAttribute*, AttributeChange::Type)));

    connect(this, SIGNAL(ParentEntitySet()), SLOT(RegisterActions()));

    AttachNode();
}

EC_Placeable::~EC_Placeable()
{
    if (renderer_.expired())
        return;
    RendererPtr renderer = renderer_.lock();
    Ogre::SceneManager* scene_mgr = renderer->GetSceneManager();

    if (scene_node_ && link_scene_node_)
    {
        link_scene_node_->removeChild(scene_node_);
    }

    if (scene_node_)
    {
        scene_mgr->destroySceneNode(scene_node_);
        scene_node_ = 0;
    }

    if (link_scene_node_)
    {
        DetachNode();

        scene_mgr->destroySceneNode(link_scene_node_);
        link_scene_node_ = 0;
    }
}

void EC_Placeable::SetParent(ComponentPtr placeable)
{
    if ((placeable.get() != 0) && (!dynamic_cast<EC_Placeable*>(placeable.get())))
    {
        OgreRenderingModule::LogError("Attempted to set parent placeable which is not " + TypeNameStatic().toStdString());
        return;
    }
    DetachNode();
    parent_ = placeable;
    AttachNode();
}

Vector3df EC_Placeable::GetPosition() const
{
    const Ogre::Vector3& pos = link_scene_node_->getPosition();
    return Vector3df(pos.x, pos.y, pos.z);
}

Quaternion EC_Placeable::GetOrientation() const
{
    const Ogre::Quaternion& orientation = link_scene_node_->getOrientation();
    return Quaternion(orientation.x, orientation.y, orientation.z, orientation.w);
}

Vector3df EC_Placeable::GetScale() const
{
    const Ogre::Vector3& scale = scene_node_->getScale();
    return Vector3df(scale.x, scale.y, scale.z);
}

Vector3df EC_Placeable::GetLocalXAxis() const
{
    const Ogre::Vector3& xaxis = link_scene_node_->getOrientation().xAxis();
    return Vector3df(xaxis.x, xaxis.y, xaxis.z);
}

QVector3D EC_Placeable::GetQLocalXAxis() const
{
    Vector3df xaxis= GetLocalXAxis();
    return QVector3D(xaxis.x, xaxis.y, xaxis.z);
}

Vector3df EC_Placeable::GetLocalYAxis() const
{
    const Ogre::Vector3& yaxis = link_scene_node_->getOrientation().yAxis();
    return Vector3df(yaxis.x, yaxis.y, yaxis.z);
}

QVector3D EC_Placeable::GetQLocalYAxis() const
{
    Vector3df yaxis= GetLocalYAxis();
    return QVector3D(yaxis.x, yaxis.y, yaxis.z);
}

Vector3df EC_Placeable::GetLocalZAxis() const
{
    const Ogre::Vector3& zaxis = link_scene_node_->getOrientation().zAxis();
    return Vector3df(zaxis.x, zaxis.y, zaxis.z);
}

QVector3D EC_Placeable::GetQLocalZAxis() const
{
    Vector3df zaxis= GetLocalZAxis();
    return QVector3D(zaxis.x, zaxis.y, zaxis.z);
}

void EC_Placeable::SetPosition(const Vector3df& position)
{
   if ( !RexTypes::IsValidPositionVector(position) )
        return;
    link_scene_node_->setPosition(Ogre::Vector3(position.x, position.y, position.z));
}

void EC_Placeable::SetOrientation(const Quaternion& orientation)
{
    link_scene_node_->setOrientation(Ogre::Quaternion(orientation.w, orientation.x, orientation.y, orientation.z));
}

void EC_Placeable::LookAt(const Vector3df& look_at)
{
    // Don't rely on the stability of the lookat (since it uses previous orientation),
    // so start in identity transform
    link_scene_node_->setOrientation(Ogre::Quaternion::IDENTITY);
    link_scene_node_->lookAt(Ogre::Vector3(look_at.x, look_at.y, look_at.z), Ogre::Node::TS_WORLD);
}

void EC_Placeable::SetYaw(float radians)
{
    link_scene_node_->yaw(Ogre::Radian(radians), Ogre::Node::TS_WORLD);
}

void EC_Placeable::SetPitch(float radians)
{
    link_scene_node_->pitch(Ogre::Radian(radians));
}

void EC_Placeable::SetRoll(float radians)
{
    link_scene_node_->roll(Ogre::Radian(radians));
}

float EC_Placeable::GetYaw() const
{
    const Ogre::Quaternion& orientation = link_scene_node_->getOrientation();
    return orientation.getYaw().valueRadians();
}
float EC_Placeable::GetPitch() const
{
    const Ogre::Quaternion& orientation = link_scene_node_->getOrientation();
    return orientation.getPitch().valueRadians();
}
float EC_Placeable::GetRoll() const
{
    const Ogre::Quaternion& orientation = link_scene_node_->getOrientation();
    return orientation.getRoll().valueRadians();
}

void EC_Placeable::SetScale(const Vector3df& scale)
{
    scene_node_->setScale(Ogre::Vector3(scale.x, scale.y, scale.z));
}

void EC_Placeable::AttachNode()
{
    if (renderer_.expired())
        return;
    RendererPtr renderer = renderer_.lock();

    if (attached_)
        return;

    Ogre::SceneNode* parent_node;

    if (!parent_)
    {
        Ogre::SceneManager* scene_mgr = renderer->GetSceneManager();
        parent_node = scene_mgr->getRootSceneNode();
    }
    else
    {
        EC_Placeable* parent = checked_static_cast<EC_Placeable*>(parent_.get());
        parent_node = parent->GetLinkSceneNode();
    }

    parent_node->addChild(link_scene_node_);
    attached_ = true;
}

void EC_Placeable::DetachNode()
{
    if (renderer_.expired())
        return;
    RendererPtr renderer = renderer_.lock();

    if (!attached_)
        return;

    Ogre::SceneNode* parent_node;

    if (!parent_)
    {
        Ogre::SceneManager* scene_mgr = renderer->GetSceneManager();
        parent_node = scene_mgr->getRootSceneNode();
    }
    else
    {
        EC_Placeable* parent = checked_static_cast<EC_Placeable*>(parent_.get());
        parent_node = parent->GetLinkSceneNode();
    }

    parent_node->removeChild(link_scene_node_);
    attached_ = false;
}

//experimental QVector3D acessors
QVector3D EC_Placeable::GetQPosition() const
{
    //conversions, conversions, all around
    //.. if this works, and QVector3D is good, we should consider porting Vector3df for that
    Vector3df rexpos = GetPosition();
    return QVector3D(rexpos.x, rexpos.y, rexpos.z);
}

void EC_Placeable::SetQPosition(const QVector3D newpos)
{
    SetPosition(Vector3df(newpos.x(), newpos.y(), newpos.z()));
}

QQuaternion EC_Placeable::GetQOrientation() const
{
    Quaternion rexort = GetOrientation();
    return QQuaternion(rexort.w, rexort.x, rexort.y, rexort.z);
}

void EC_Placeable::SetQOrientation(const QQuaternion newort)
{
    SetOrientation(Quaternion(newort.x(), newort.y(), newort.z(), newort.scalar()));
}

QVector3D EC_Placeable::GetQScale() const
{
    Vector3df rexscale = GetScale();
    return QVector3D(rexscale.x, rexscale.y, rexscale.z);
}

void EC_Placeable::SetQScale(const QVector3D newscale)
{
    SetScale(Vector3df(newscale.x(), newscale.y(), newscale.z()));
}

QVector3D EC_Placeable::translate(int axis, float amount)
{
    Ogre::Matrix3 m;
    Ogre::Vector3 v;
    float x, y, z;
    x = y = z = 0.0;
    m.SetColumn(0,  link_scene_node_->getOrientation().xAxis());
    m.SetColumn(1,  link_scene_node_->getOrientation().yAxis());
    m.SetColumn(2,  link_scene_node_->getOrientation().zAxis());
    switch(axis) {
        case 0:
            x = amount;
            break;
        case 1:
            y = amount;
            break;
        case 2:
            z = amount;
            break;
        default:
            // nothing, don't translate
            break;

    }
    link_scene_node_->translate(m, Ogre::Vector3(x, y, z), Ogre::Node::TS_LOCAL);
    const Ogre::Vector3 newpos = link_scene_node_->getPosition();
    return QVector3D(newpos.x, newpos.y, newpos.z);
}

void EC_Placeable::HandleAttributeChanged(IAttribute* attribute, AttributeChange::Type change)
{
    if (attribute == &transform)
    {
        if (!link_scene_node_)
            return;

        const Transform& trans = transform.Get();
        link_scene_node_->setPosition(trans.position.x, trans.position.y, trans.position.z);
        Quaternion orientation(DEGTORAD * trans.rotation.x,
                          DEGTORAD * trans.rotation.y,
                          DEGTORAD * trans.rotation.z);
        link_scene_node_->setOrientation(Ogre::Quaternion(orientation.w, orientation.x, orientation.y, orientation.z));

        // Prevent Ogre exception from zero scale
        Vector3df scale(trans.scale.x, trans.scale.y, trans.scale.z);
        if (scale.x < 0.0000001f)
            scale.x = 0.0000001f;
        if (scale.y < 0.0000001f)
            scale.y = 0.0000001f;
        if (scale.z < 0.0000001f)
            scale.z = 0.0000001f;

        link_scene_node_->setScale(scale.x, scale.y, scale.z);
    }
    else if (attribute == &drawDebug)
    {
        SetShowBoundingBoxRecursive(link_scene_node_, drawDebug.Get());
    }
}

void EC_Placeable::Show()
{
	if (!link_scene_node_)
        return;

link_scene_node_->setVisible(true);
}

void EC_Placeable::Hide()
{
		if (!link_scene_node_)
			return;

		link_scene_node_->setVisible(false);
}

void EC_Placeable::ToggleVisibility()
{
    if (!link_scene_node_)
        return;

    link_scene_node_->flipVisibility();
}

void EC_Placeable::RegisterActions()
{
    Scene::Entity *entity = GetParentEntity();
    assert(entity);
    if (entity)
    {
        // Generic actions
        entity->ConnectAction("ShowEntity", this, SLOT(Show()));
        entity->ConnectAction("HideEntity", this, SLOT(Hide()));
        entity->ConnectAction("ToggleEntity", this, SLOT(ToggleVisibility()));

    }
}

<commit_msg>Added also assert to EC_Placeable - SetPosition(), so it breaks in debug-mode if position is invalid.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "OgreRenderingModule.h"
#include "Renderer.h"
#include "EC_Placeable.h"
#include "Entity.h"
#include "RexNetworkUtils.h"

#include <Ogre.h>
#include <QDebug>

using namespace OgreRenderer;

void SetShowBoundingBoxRecursive(Ogre::SceneNode* node, bool enable)
{
    if (!node)
        return;
    node->showBoundingBox(enable);
    int numChildren = node->numChildren();
    for (int i = 0; i < numChildren; ++i)
    {
        Ogre::SceneNode* childNode = dynamic_cast<Ogre::SceneNode*>(node->getChild(i));
        if (childNode)
            SetShowBoundingBoxRecursive(childNode, enable);
    }
}

EC_Placeable::EC_Placeable(IModule* module) :
    IComponent(module->GetFramework()),
    renderer_(checked_static_cast<OgreRenderingModule*>(module)->GetRenderer()),
    scene_node_(0),
    link_scene_node_(0),
    attached_(false),
    select_priority_(0),
    transform(this, "Transform"),
    drawDebug(this, "Show bounding box", false)
{
    RendererPtr renderer = renderer_.lock();
    Ogre::SceneManager* scene_mgr = renderer->GetSceneManager();
    link_scene_node_ = scene_mgr->createSceneNode();
    scene_node_ = scene_mgr->createSceneNode();
    link_scene_node_->addChild(scene_node_);

    // In case the placeable is used for camera control, set fixed yaw axis
    link_scene_node_->setFixedYawAxis(true, Ogre::Vector3::UNIT_Z);

    // Hook the transform attribute change
    connect(this, SIGNAL(OnAttributeChanged(IAttribute*, AttributeChange::Type)),
        SLOT(HandleAttributeChanged(IAttribute*, AttributeChange::Type)));

    connect(this, SIGNAL(ParentEntitySet()), SLOT(RegisterActions()));

    AttachNode();
}

EC_Placeable::~EC_Placeable()
{
    if (renderer_.expired())
        return;
    RendererPtr renderer = renderer_.lock();
    Ogre::SceneManager* scene_mgr = renderer->GetSceneManager();

    if (scene_node_ && link_scene_node_)
    {
        link_scene_node_->removeChild(scene_node_);
    }

    if (scene_node_)
    {
        scene_mgr->destroySceneNode(scene_node_);
        scene_node_ = 0;
    }

    if (link_scene_node_)
    {
        DetachNode();

        scene_mgr->destroySceneNode(link_scene_node_);
        link_scene_node_ = 0;
    }
}

void EC_Placeable::SetParent(ComponentPtr placeable)
{
    if ((placeable.get() != 0) && (!dynamic_cast<EC_Placeable*>(placeable.get())))
    {
        OgreRenderingModule::LogError("Attempted to set parent placeable which is not " + TypeNameStatic().toStdString());
        return;
    }
    DetachNode();
    parent_ = placeable;
    AttachNode();
}

Vector3df EC_Placeable::GetPosition() const
{
    const Ogre::Vector3& pos = link_scene_node_->getPosition();
    return Vector3df(pos.x, pos.y, pos.z);
}

Quaternion EC_Placeable::GetOrientation() const
{
    const Ogre::Quaternion& orientation = link_scene_node_->getOrientation();
    return Quaternion(orientation.x, orientation.y, orientation.z, orientation.w);
}

Vector3df EC_Placeable::GetScale() const
{
    const Ogre::Vector3& scale = scene_node_->getScale();
    return Vector3df(scale.x, scale.y, scale.z);
}

Vector3df EC_Placeable::GetLocalXAxis() const
{
    const Ogre::Vector3& xaxis = link_scene_node_->getOrientation().xAxis();
    return Vector3df(xaxis.x, xaxis.y, xaxis.z);
}

QVector3D EC_Placeable::GetQLocalXAxis() const
{
    Vector3df xaxis= GetLocalXAxis();
    return QVector3D(xaxis.x, xaxis.y, xaxis.z);
}

Vector3df EC_Placeable::GetLocalYAxis() const
{
    const Ogre::Vector3& yaxis = link_scene_node_->getOrientation().yAxis();
    return Vector3df(yaxis.x, yaxis.y, yaxis.z);
}

QVector3D EC_Placeable::GetQLocalYAxis() const
{
    Vector3df yaxis= GetLocalYAxis();
    return QVector3D(yaxis.x, yaxis.y, yaxis.z);
}

Vector3df EC_Placeable::GetLocalZAxis() const
{
    const Ogre::Vector3& zaxis = link_scene_node_->getOrientation().zAxis();
    return Vector3df(zaxis.x, zaxis.y, zaxis.z);
}

QVector3D EC_Placeable::GetQLocalZAxis() const
{
    Vector3df zaxis= GetLocalZAxis();
    return QVector3D(zaxis.x, zaxis.y, zaxis.z);
}

void EC_Placeable::SetPosition(const Vector3df& position)
{
   assert(!RexTypes::IsValidPositionVector(position));

   if ( !RexTypes::IsValidPositionVector(position) )
        return;
    link_scene_node_->setPosition(Ogre::Vector3(position.x, position.y, position.z));
}

void EC_Placeable::SetOrientation(const Quaternion& orientation)
{
    link_scene_node_->setOrientation(Ogre::Quaternion(orientation.w, orientation.x, orientation.y, orientation.z));
}

void EC_Placeable::LookAt(const Vector3df& look_at)
{
    // Don't rely on the stability of the lookat (since it uses previous orientation),
    // so start in identity transform
    link_scene_node_->setOrientation(Ogre::Quaternion::IDENTITY);
    link_scene_node_->lookAt(Ogre::Vector3(look_at.x, look_at.y, look_at.z), Ogre::Node::TS_WORLD);
}

void EC_Placeable::SetYaw(float radians)
{
    link_scene_node_->yaw(Ogre::Radian(radians), Ogre::Node::TS_WORLD);
}

void EC_Placeable::SetPitch(float radians)
{
    link_scene_node_->pitch(Ogre::Radian(radians));
}

void EC_Placeable::SetRoll(float radians)
{
    link_scene_node_->roll(Ogre::Radian(radians));
}

float EC_Placeable::GetYaw() const
{
    const Ogre::Quaternion& orientation = link_scene_node_->getOrientation();
    return orientation.getYaw().valueRadians();
}
float EC_Placeable::GetPitch() const
{
    const Ogre::Quaternion& orientation = link_scene_node_->getOrientation();
    return orientation.getPitch().valueRadians();
}
float EC_Placeable::GetRoll() const
{
    const Ogre::Quaternion& orientation = link_scene_node_->getOrientation();
    return orientation.getRoll().valueRadians();
}

void EC_Placeable::SetScale(const Vector3df& scale)
{
    scene_node_->setScale(Ogre::Vector3(scale.x, scale.y, scale.z));
}

void EC_Placeable::AttachNode()
{
    if (renderer_.expired())
        return;
    RendererPtr renderer = renderer_.lock();

    if (attached_)
        return;

    Ogre::SceneNode* parent_node;

    if (!parent_)
    {
        Ogre::SceneManager* scene_mgr = renderer->GetSceneManager();
        parent_node = scene_mgr->getRootSceneNode();
    }
    else
    {
        EC_Placeable* parent = checked_static_cast<EC_Placeable*>(parent_.get());
        parent_node = parent->GetLinkSceneNode();
    }

    parent_node->addChild(link_scene_node_);
    attached_ = true;
}

void EC_Placeable::DetachNode()
{
    if (renderer_.expired())
        return;
    RendererPtr renderer = renderer_.lock();

    if (!attached_)
        return;

    Ogre::SceneNode* parent_node;

    if (!parent_)
    {
        Ogre::SceneManager* scene_mgr = renderer->GetSceneManager();
        parent_node = scene_mgr->getRootSceneNode();
    }
    else
    {
        EC_Placeable* parent = checked_static_cast<EC_Placeable*>(parent_.get());
        parent_node = parent->GetLinkSceneNode();
    }

    parent_node->removeChild(link_scene_node_);
    attached_ = false;
}

//experimental QVector3D acessors
QVector3D EC_Placeable::GetQPosition() const
{
    //conversions, conversions, all around
    //.. if this works, and QVector3D is good, we should consider porting Vector3df for that
    Vector3df rexpos = GetPosition();
    return QVector3D(rexpos.x, rexpos.y, rexpos.z);
}

void EC_Placeable::SetQPosition(const QVector3D newpos)
{
    SetPosition(Vector3df(newpos.x(), newpos.y(), newpos.z()));
}

QQuaternion EC_Placeable::GetQOrientation() const
{
    Quaternion rexort = GetOrientation();
    return QQuaternion(rexort.w, rexort.x, rexort.y, rexort.z);
}

void EC_Placeable::SetQOrientation(const QQuaternion newort)
{
    SetOrientation(Quaternion(newort.x(), newort.y(), newort.z(), newort.scalar()));
}

QVector3D EC_Placeable::GetQScale() const
{
    Vector3df rexscale = GetScale();
    return QVector3D(rexscale.x, rexscale.y, rexscale.z);
}

void EC_Placeable::SetQScale(const QVector3D newscale)
{
    SetScale(Vector3df(newscale.x(), newscale.y(), newscale.z()));
}

QVector3D EC_Placeable::translate(int axis, float amount)
{
    Ogre::Matrix3 m;
    Ogre::Vector3 v;
    float x, y, z;
    x = y = z = 0.0;
    m.SetColumn(0,  link_scene_node_->getOrientation().xAxis());
    m.SetColumn(1,  link_scene_node_->getOrientation().yAxis());
    m.SetColumn(2,  link_scene_node_->getOrientation().zAxis());
    switch(axis) {
        case 0:
            x = amount;
            break;
        case 1:
            y = amount;
            break;
        case 2:
            z = amount;
            break;
        default:
            // nothing, don't translate
            break;

    }
    link_scene_node_->translate(m, Ogre::Vector3(x, y, z), Ogre::Node::TS_LOCAL);
    const Ogre::Vector3 newpos = link_scene_node_->getPosition();
    return QVector3D(newpos.x, newpos.y, newpos.z);
}

void EC_Placeable::HandleAttributeChanged(IAttribute* attribute, AttributeChange::Type change)
{
    if (attribute == &transform)
    {
        if (!link_scene_node_)
            return;

        const Transform& trans = transform.Get();
        link_scene_node_->setPosition(trans.position.x, trans.position.y, trans.position.z);
        Quaternion orientation(DEGTORAD * trans.rotation.x,
                          DEGTORAD * trans.rotation.y,
                          DEGTORAD * trans.rotation.z);
        link_scene_node_->setOrientation(Ogre::Quaternion(orientation.w, orientation.x, orientation.y, orientation.z));

        // Prevent Ogre exception from zero scale
        Vector3df scale(trans.scale.x, trans.scale.y, trans.scale.z);
        if (scale.x < 0.0000001f)
            scale.x = 0.0000001f;
        if (scale.y < 0.0000001f)
            scale.y = 0.0000001f;
        if (scale.z < 0.0000001f)
            scale.z = 0.0000001f;

        link_scene_node_->setScale(scale.x, scale.y, scale.z);
    }
    else if (attribute == &drawDebug)
    {
        SetShowBoundingBoxRecursive(link_scene_node_, drawDebug.Get());
    }
}

void EC_Placeable::Show()
{
	if (!link_scene_node_)
        return;

link_scene_node_->setVisible(true);
}

void EC_Placeable::Hide()
{
		if (!link_scene_node_)
			return;

		link_scene_node_->setVisible(false);
}

void EC_Placeable::ToggleVisibility()
{
    if (!link_scene_node_)
        return;

    link_scene_node_->flipVisibility();
}

void EC_Placeable::RegisterActions()
{
    Scene::Entity *entity = GetParentEntity();
    assert(entity);
    if (entity)
    {
        // Generic actions
        entity->ConnectAction("ShowEntity", this, SLOT(Show()));
        entity->ConnectAction("HideEntity", this, SLOT(Hide()));
        entity->ConnectAction("ToggleEntity", this, SLOT(ToggleVisibility()));

    }
}

<|endoftext|>


<commit_before>
#include "Config.hpp"

#include "Werk/Utility/Units.hpp"

namespace werk
{

//This runs on the background thread
void Config::execute()
{
	//Don't reload unless asked
	if (!_reloadConfig.value()) {
		return;
	}
	_reloadConfig.reset();

	//Select which values dictionary is not active
	ConfigValuesT &newValues = _values.load() == &_values1 ? _values2 : _values1;
	newValues.clear();

	//Reload all configs
	for (ConfigSource *configSource : _configSources) {
		if (!configSource->reloadConfig(newValues)) {
			_log->logRaw(LogLevel::ERROR, "Failed to load config");
		}
	}

	//Swap the configs atomically
	_values.store(&newValues);
	_changed.set();
}

//Run on whatever thread the configurables live on
void Config::reloadConfigurables()
{
	//Don't reload unless changed
	if (!_changed.value()) {
		return;
	}
	_changed.reset();

	for (Configurable *configurable : _configurables) {
		configurable->reloadConfig(*this);
	}
}

//Basic types
const char *Config::getString(const std::string &key, const char *defaultValue, const char *help) const
{
	const char *stringValue = getStringRaw(key);
	if (stringValue == nullptr) {
		_log->log(LogLevel::CONFIG, "<Config> [%s] = %s [DEFAULT]%s%s",
			key.c_str(),
			defaultValue,
			help == nullptr ? "" : " -- ",
			help == nullptr ? "" : help);
		return defaultValue;
	}

	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s%s%s",
		key.c_str(),
		stringValue,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	return stringValue;
}

bool Config::getBool(const std::string &key, bool defaultValue, const char *help) const
{
	const ConfigValuesT * const values = _values;
	auto i = values->find(key);

	if (i == values->end()) {
		_log->log(LogLevel::CONFIG, "<Config> [%s] = %s [DEFAULT]%s%s",
			key.c_str(),
			defaultValue ? "true" : "false",
			help == nullptr ? "" : " -- ",
			help == nullptr ? "" : help);
		return defaultValue;
	}

	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s%s%s",
		key.c_str(),
		i->second.c_str(),
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	return i->second == "true" || i->second == "True";
}

double Config::getDouble(const std::string &key, double defaultValue, const char *help) const
{
	const char *stringValue = getStringRaw(key);
	if (stringValue == nullptr) {
		_log->log(LogLevel::CONFIG, "<Config> [%s] = %f [DEFAULT]%s%s",
			key.c_str(),
			defaultValue,
			help == nullptr ? "" : " -- ",
			help == nullptr ? "" : help);
		return defaultValue;
	}

	double value = std::stod(stringValue);
	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s (%f)%s%s",
		key.c_str(),
		stringValue, value,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	return value;
}

int64_t Config::getInt64(const std::string &key, int64_t defaultValue, const char *help) const
{
	const char *stringValue = getStringRaw(key);
	if (stringValue == nullptr) {
		_log->log(LogLevel::CONFIG, "<Config> [%s] = %" PRIi64 " [DEFAULT]%s%s",
			key.c_str(),
			defaultValue,
			help == nullptr ? "" : " -- ",
			help == nullptr ? "" : help);
		return defaultValue;
	}

	int64_t value = std::stoll(stringValue);
	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s (%" PRIi64 ")%s%s",
		key.c_str(),
		stringValue, value,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	return value;
}

uint64_t Config::getUint64(const std::string &key, uint64_t defaultValue, const char *help) const
{
	const char *stringValue = getStringRaw(key);
	if (stringValue == nullptr) {
		_log->log(LogLevel::CONFIG, "<Config> [%s] = %" PRIu64 " [DEFAULT]%s%s",
			key.c_str(),
			defaultValue,
			help == nullptr ? "" : " -- ",
			help == nullptr ? "" : help);
		return defaultValue;
	}

	uint64_t value = std::stoull(stringValue);
	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s (%" PRIu64 ")%s%s",
		key.c_str(),
		stringValue, value,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	return value;
}

uint64_t Config::getStorageAmount(const std::string &key, uint64_t defaultValue, const char *help) const
{
	const char *stringValue = getStringRaw(key);
	if (stringValue == nullptr) {
		_log->log(LogLevel::CONFIG, "<Config> [%s] = %" PRIu64 " [DEFAULT]%s%s",
			key.c_str(),
			defaultValue,
			help == nullptr ? "" : " -- ",
			help == nullptr ? "" : help);
		return defaultValue;
	}

	uint64_t value = parseUnits(stringValue, STORAGE_UNITS);
	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s (%" PRIu64 ")%s%s",
		key.c_str(),
		stringValue, value,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	return value;
}

uint64_t Config::getTimeAmount(const std::string &key, uint64_t defaultValue, const char *help) const
{
	const char *stringValue = getStringRaw(key);
	if (stringValue == nullptr) {
		_log->log(LogLevel::CONFIG, "<Config> [%s] = %" PRIu64 " [DEFAULT]%s%s",
			key.c_str(),
			defaultValue,
			help == nullptr ? "" : " -- ",
			help == nullptr ? "" : help);
		return defaultValue;
	}

	uint64_t value = parseUnits(stringValue, TIME_UNITS);
	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s (%" PRIu64 ")%s%s",
		key.c_str(),
		stringValue, value,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	return value;
}

}
<commit_msg>Clean up config logging and add JSON output for #77<commit_after>
#include "Config.hpp"

#include "Werk/Utility/Units.hpp"

namespace werk
{

//This runs on the background thread
void Config::execute()
{
	//Don't reload unless asked
	if (!_reloadConfig.value()) {
		return;
	}
	_reloadConfig.reset();

	//Select which values dictionary is not active
	ConfigValuesT &newValues = _values.load() == &_values1 ? _values2 : _values1;
	newValues.clear();

	//Reload all configs
	for (ConfigSource *configSource : _configSources) {
		if (!configSource->reloadConfig(newValues)) {
			_log->logRaw(LogLevel::ERROR, "Failed to load config");
		}
	}

	//Swap the configs atomically
	_values.store(&newValues);
	_changed.set();
}

//Run on whatever thread the configurables live on
void Config::reloadConfigurables()
{
	//Don't reload unless changed
	if (!_changed.value()) {
		return;
	}
	_changed.reset();

	for (Configurable *configurable : _configurables) {
		configurable->reloadConfig(*this);
	}
}

//Basic types
const char *Config::getString(const std::string &key, const char *defaultValue, const char *help) const
{
	const char *stringValue = getStringRaw(key);
	const char *defaultLogValue = "";
	const char *quoteChar = "\"";
	if (nullptr == stringValue) {
		stringValue = defaultValue;
		defaultLogValue = " [DEFAULT]";
		if (nullptr == stringValue) {
			quoteChar = "";
		}
	}

	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s%s%s%s",
		key.c_str(),
		stringValue,
		defaultLogValue,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	_log->log(LogLevel::JSON, "{\"type\":\"config\",\"key\":\"%s\",\"value\":%s%s%s}",
		key.c_str(),
		quoteChar,
		nullptr == stringValue ? "null" : stringValue,
		quoteChar);
	return stringValue;
}

bool Config::getBool(const std::string &key, bool defaultValue, const char *help) const
{
	bool value = defaultValue;
	const char *defaultLogValue = " [DEFAULT]";

	const ConfigValuesT * const values = _values;
	auto i = values->find(key);
	if (i == values->end()) {
		value = i->second == "true" || i->second == "True";
		defaultLogValue = "";
	}

	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s%s%s",
		key.c_str(),
		i->second.c_str(),
		defaultLogValue,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	_log->log(LogLevel::JSON, "{\"type\":\"config\",\"key\":\"%s\",\"value\":%s}",
		key.c_str(),
		value ? "true" : "false");
	return value;
}

double Config::getDouble(const std::string &key, double defaultValue, const char *help) const
{
	double value = defaultValue;
	const char *defaultLogValue = " [DEFAULT]";

	const char *stringValue = getStringRaw(key);
	if (stringValue != nullptr) {
		value = std::stod(stringValue);
		defaultLogValue = "";
	}

	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s (%f)%s%s%s",
		key.c_str(),
		stringValue, value,
		defaultLogValue,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	_log->log(LogLevel::JSON, "{\"type\":\"config\",\"key\":\"%s\",\"value\":%f}",
		key.c_str(),
		value);
	return value;
}

int64_t Config::getInt64(const std::string &key, int64_t defaultValue, const char *help) const
{
	int64_t value = defaultValue;
	const char *defaultLogValue = " [DEFAULT]";

	const char *stringValue = getStringRaw(key);
	if (stringValue != nullptr) {
		value = std::stoll(stringValue);
		defaultLogValue = "";
	}

	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s (%" PRIi64 ")%s%s%s",
		key.c_str(),
		stringValue, value,
		defaultLogValue,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	_log->log(LogLevel::JSON, "{\"type\":\"config\",\"key\":\"%s\",\"value\":%" PRIi64 "}",
		key.c_str(),
		value);
	return value;
}

uint64_t Config::getUint64(const std::string &key, uint64_t defaultValue, const char *help) const
{
	uint64_t value = defaultValue;
	const char *defaultLogValue = " [DEFAULT]";

	const char *stringValue = getStringRaw(key);
	if (stringValue != nullptr) {
		value = std::stoull(stringValue);
		defaultLogValue = "";
	}

	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s (%" PRIu64 ")%s%s%s",
		key.c_str(),
		stringValue, value,
		defaultLogValue,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	_log->log(LogLevel::JSON, "{\"type\":\"config\",\"key\":\"%s\",\"value\":%" PRIu64 "}",
		key.c_str(),
		value);
	return value;
}

uint64_t Config::getStorageAmount(const std::string &key, uint64_t defaultValue, const char *help) const
{
	uint64_t value = defaultValue;
	const char *defaultLogValue = " [DEFAULT]";

	const char *stringValue = getStringRaw(key);
	if (stringValue != nullptr) {
		value = parseUnits(stringValue, STORAGE_UNITS);
		defaultLogValue = "";
	}

	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s (%" PRIu64 ")%s%s%s",
		key.c_str(),
		stringValue, value,
		defaultLogValue,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	_log->log(LogLevel::JSON, "{\"type\":\"config\",\"key\":\"%s\",\"value\":%" PRIu64 "}",
		key.c_str(),
		value);
	return value;
}

uint64_t Config::getTimeAmount(const std::string &key, uint64_t defaultValue, const char *help) const
{
	uint64_t value = defaultValue;
	const char *defaultLogValue = " [DEFAULT]";

	const char *stringValue = getStringRaw(key);
	if (stringValue != nullptr) {
		value = parseUnits(stringValue, TIME_UNITS);
		defaultLogValue = "";
	}

	_log->log(LogLevel::CONFIG, "<Config> [%s] = %s (%" PRIu64 ")%s%s%s",
		key.c_str(),
		stringValue, value,
		defaultLogValue,
		help == nullptr ? "" : " -- ",
		help == nullptr ? "" : help);
	_log->log(LogLevel::JSON, "{\"type\":\"config\",\"key\":\"%s\",\"value\":%" PRIu64 "}",
		key.c_str(),
		value);
	return value;
}

}
<|endoftext|>


<commit_before>#include <ncurses.h>
#include <stdint.h>
#include <iostream>
#include <unistd.h>

#include "display/Screen.h"
#include "display/Window.h"
#include "map/Level.h"
#include "map/filters/DrunkardsWalkFilter.h"

void pause_curses(Screen& screen)
{
	screen.pause();

	std::cout << "Paused ncurses..." << std::endl;

	sleep(4);

	std::cout << "Resuming..." << std::endl;

	sleep(1);
}

int main()
{
	Screen screen;

	uint32_t screen_y = screen.getHeight();
	uint32_t screen_x = screen.getWidth();

	//Create a window for our map; window (and map) are double screen size)
	uint32_t map_y = screen_y * 2;
	uint32_t map_x = screen_x * 2;
	WINDOW* map = newwin(map_y, map_x, 0, 0);
	//Generate a map
	Level cave(map_y, map_x);
	DrunkardsWalkFilter walk;
	walk.setSeed(time(NULL));
	walk.apply(cave);
	//Now put the map into our map window
	for(uint32_t x = 0; x < cave.getWidth(); x++)
	{
		for(uint32_t y = 0; y < cave.getHeight(); y++)
		{
			mvwaddch(map, x+1, y, cave[x][y].getDisplay());
		}
	}

	Window top(screen_x, 3, 0, 0);
	Window left(20, screen_y-2, 0, 2);
	//WINDOW* main = newwin(screen_y-2, screen_x-19, 2, 19);
	WINDOW* main = subwin(map, screen_y-3, screen_x-20, 3, 20);

	top.addBorder();
	left.addBorder();
	//wborder(main, '|', '|', '-', '-', '+', '+', '+', '+');

	top.add(1, 0, "Message Panel");
	left.add(1, 0, "Stat Panel");
	//mvwprintw(main, 0, 1, "Main Panel");

	//Center the map viewport
	uint32_t map_view_y = map_y/2 - (screen_y-3)/2;
	uint32_t map_view_x = map_x/2 - (screen_x-20)/2;
	uint32_t map_view_max_y = screen_y - 3;
	uint32_t map_view_max_x = screen_x - 20;
	mvderwin(main, map_view_y, map_view_x);

	//wrefresh(top);
	top.refresh();
	left.refresh();
	wrefresh(main);

	int ch;
	bool run = true;
	while(run)
	{
		ch = getch();

		switch(ch)
		{
			case KEY_UP:
				if(0 < map_view_y)
				{
					top.add(1, 1, "Up");
					map_view_y--;
				}
				break;
			case KEY_DOWN:
				if(map_view_max_y > map_view_y)
				{
					top.add(1, 1, "Down");
					map_view_y++;
				}
				break;
			case KEY_LEFT:
				if(0 < map_view_x)
				{
					top.add(1, 1, "Left");
					map_view_x--;
				}
				break;
			case KEY_RIGHT:
				if(map_view_max_x > map_view_x)
				{
					top.add(1, 1, "Right");
					map_view_x++;
				}
				break;
			case 'p':
			case 'P':
				pause_curses(screen);
				break;
			case 'q':
			case 'Q':
				run = false;
				break;
		}

		mvderwin(main, map_view_y, map_view_x);
		wrefresh(main);
		top.refresh();
	}
}
<commit_msg>The entered key is now displayed in the "stats" window for debugging.<commit_after>#include <ncurses.h>
#include <stdint.h>
#include <iostream>
#include <unistd.h>

#include "display/Screen.h"
#include "display/Window.h"
#include "map/Level.h"
#include "map/filters/DrunkardsWalkFilter.h"

void pause_curses(Screen& screen)
{
	screen.pause();

	std::cout << "Paused ncurses..." << std::endl;

	sleep(4);

	std::cout << "Resuming..." << std::endl;

	sleep(1);
}

int main()
{
	Screen screen;

	uint32_t screen_y = screen.getHeight();
	uint32_t screen_x = screen.getWidth();

	//Create a window for our map; window (and map) are double screen size)
	uint32_t map_y = screen_y * 2;
	uint32_t map_x = screen_x * 2;
	WINDOW* map = newwin(map_y, map_x, 0, 0);
	//Generate a map
	Level cave(map_y, map_x);
	DrunkardsWalkFilter walk;
	walk.setSeed(time(NULL));
	walk.apply(cave);
	//Now put the map into our map window
	for(uint32_t x = 0; x < cave.getWidth(); x++)
	{
		for(uint32_t y = 0; y < cave.getHeight(); y++)
		{
			mvwaddch(map, x+1, y, cave[x][y].getDisplay());
		}
	}

	Window top(screen_x, 3, 0, 0);
	Window left(20, screen_y-2, 0, 2);
	//WINDOW* main = newwin(screen_y-2, screen_x-19, 2, 19);
	WINDOW* main = subwin(map, screen_y-3, screen_x-20, 3, 20);

	top.addBorder();
	left.addBorder();
	//wborder(main, '|', '|', '-', '-', '+', '+', '+', '+');

	top.add(1, 0, "Message Panel");
	left.add(1, 0, "Stat Panel");
	//mvwprintw(main, 0, 1, "Main Panel");

	//Center the map viewport
	uint32_t map_view_y = map_y/2 - (screen_y-3)/2;
	uint32_t map_view_x = map_x/2 - (screen_x-20)/2;
	uint32_t map_view_max_y = screen_y - 3;
	uint32_t map_view_max_x = screen_x - 20;
	mvderwin(main, map_view_y, map_view_x);

	//wrefresh(top);
	top.refresh();
	left.refresh();
	wrefresh(main);

	int ch;
	bool run = true;
	while(run)
	{
		ch = getch();

		//Display the character in our "stats" window for now
		left.add(1, 1, ch);
		left.refresh();

		switch(ch)
		{
			case KEY_UP:
				if(0 < map_view_y)
				{
					top.add(1, 1, "Up");
					map_view_y--;
				}
				break;
			case KEY_DOWN:
				if(map_view_max_y > map_view_y)
				{
					top.add(1, 1, "Down");
					map_view_y++;
				}
				break;
			case KEY_LEFT:
				if(0 < map_view_x)
				{
					top.add(1, 1, "Left");
					map_view_x--;
				}
				break;
			case KEY_RIGHT:
				if(map_view_max_x > map_view_x)
				{
					top.add(1, 1, "Right");
					map_view_x++;
				}
				break;
			case 'p':
			case 'P':
				pause_curses(screen);
				break;
			case 'q':
			case 'Q':
				run = false;
				break;
		}

		mvderwin(main, map_view_y, map_view_x);
		wrefresh(main);
		top.refresh();
	}
}
<|endoftext|>


<commit_before>
#include "vtkCommand.h"
#include "vtkSphereSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkSmartPointer.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkTimerLog.h"

int TestManyActors(int argc, char* argv[])
{
  int numActors = 512;
  int numRenders = 100;
  bool interact = false;
  for (int i = 1; i < argc; ++i)
    {
    if (!strcmp(argv[i], "-I"))
      {
      interact = true;
      continue;
      }
    if (!strcmp(argv[i], "-T") ||
        !strcmp(argv[i], "-V") ||
        !strcmp(argv[i], "-D"))
      {
      ++i;
      continue;
      }
    if (!strcmp(argv[i], "-N"))
      {
      ++i;
      numActors = atoi(argv[i]);
      continue;
      }
    if (!strcmp(argv[i], "-R"))
      {
      ++i;
      numRenders = atoi(argv[i]);
      continue;
      }
    cerr << argv[0] << " options:" << endl;
    cerr << " -N: Number of actors" << endl;
    }
  vtkSmartPointer<vtkSphereSource> source =
    vtkSmartPointer<vtkSphereSource>::New();
  vtkSmartPointer<vtkRenderer> ren =
    vtkSmartPointer<vtkRenderer>::New();
  int side1 = static_cast<int>(
    round(pow(numActors, 1.0/3.0)));
  int side2 = static_cast<int>(
    round(sqrt(numActors/static_cast<double>(side1))));
  int side3 = static_cast<int>(
    ceil(static_cast<double>(numActors)/side1/side2));
  int actorId = 0;
  for (int i = 0; i < side1; ++i)
    {
    for (int j = 0; j < side2; ++j)
      {
      for (int k = 0; k < side3; ++k)
        {
        vtkSmartPointer<vtkPolyDataMapper> mapper =
          vtkSmartPointer<vtkPolyDataMapper>::New();
        vtkSmartPointer<vtkActor> actor =
          vtkSmartPointer<vtkActor>::New();
        mapper->SetInputConnection(source->GetOutputPort());
        actor->SetMapper(mapper);
        actor->SetPosition(i, j, k);
        ren->AddActor(actor);
        ++actorId;
        if (actorId >= numActors)
          {
          break;
          }
        }
      if (actorId >= numActors)
        {
        break;
        }
      }
    if (actorId >= numActors)
      {
      break;
      }
    }
  vtkSmartPointer<vtkRenderWindow> win =
    vtkSmartPointer<vtkRenderWindow>::New();
  vtkSmartPointer<vtkRenderWindowInteractor> iren =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
    vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
  ren->ResetCamera();
  win->AddRenderer(ren);
  win->SetInteractor(iren);
  iren->SetInteractorStyle(style);

  cerr << "number of actors: " << numActors << endl;
  cerr << "number of renders: " << numRenders << endl;

  vtkSmartPointer<vtkTimerLog> timer = vtkSmartPointer<vtkTimerLog>::New();
  timer->StartTimer();
  iren->Initialize();
  iren->SetEventPosition(100, 100);
  iren->InvokeEvent(vtkCommand::LeftButtonPressEvent, 0);
  timer->StopTimer();
  double firstRender = timer->GetElapsedTime();
  cerr << "first render time: " << firstRender << endl;

  timer->StartTimer();
  for (int i = 0; i < numRenders; ++i)
    {
    iren->SetEventPosition(100, 100 + i);
    iren->InvokeEvent(vtkCommand::MouseMoveEvent, 0);
    }
  iren->InvokeEvent(vtkCommand::LeftButtonReleaseEvent, 0);
  timer->StopTimer();
  double elapsed = timer->GetElapsedTime();
  cerr << "interactive render time: " << elapsed / numRenders << endl;
  cerr << "render time per actor: " << elapsed / numRenders / numActors << endl;

  if (interact)
    {
    iren->Start();
    }

  return 0;
}

<commit_msg>COMP: Use vtkMath for round().<commit_after>
#include "vtkActor.h"
#include "vtkCommand.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkMath.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkSphereSource.h"
#include "vtkTimerLog.h"

int TestManyActors(int argc, char* argv[])
{
  int numActors = 512;
  int numRenders = 100;
  bool interact = false;
  for (int i = 1; i < argc; ++i)
    {
    if (!strcmp(argv[i], "-I"))
      {
      interact = true;
      continue;
      }
    if (!strcmp(argv[i], "-T") ||
        !strcmp(argv[i], "-V") ||
        !strcmp(argv[i], "-D"))
      {
      ++i;
      continue;
      }
    if (!strcmp(argv[i], "-N"))
      {
      ++i;
      numActors = atoi(argv[i]);
      continue;
      }
    if (!strcmp(argv[i], "-R"))
      {
      ++i;
      numRenders = atoi(argv[i]);
      continue;
      }
    cerr << argv[0] << " options:" << endl;
    cerr << " -N: Number of actors" << endl;
    }
  vtkSmartPointer<vtkSphereSource> source =
    vtkSmartPointer<vtkSphereSource>::New();
  vtkSmartPointer<vtkRenderer> ren =
    vtkSmartPointer<vtkRenderer>::New();
  int side1 = static_cast<int>(
    vtkMath::Round(pow(numActors, 1.0/3.0)));
  int side2 = static_cast<int>(
    vtkMath::Round(sqrt(numActors/static_cast<double>(side1))));
  int side3 = static_cast<int>(
    ceil(static_cast<double>(numActors)/side1/side2));
  int actorId = 0;
  for (int i = 0; i < side1; ++i)
    {
    for (int j = 0; j < side2; ++j)
      {
      for (int k = 0; k < side3; ++k)
        {
        vtkSmartPointer<vtkPolyDataMapper> mapper =
          vtkSmartPointer<vtkPolyDataMapper>::New();
        vtkSmartPointer<vtkActor> actor =
          vtkSmartPointer<vtkActor>::New();
        mapper->SetInputConnection(source->GetOutputPort());
        actor->SetMapper(mapper);
        actor->SetPosition(i, j, k);
        ren->AddActor(actor);
        ++actorId;
        if (actorId >= numActors)
          {
          break;
          }
        }
      if (actorId >= numActors)
        {
        break;
        }
      }
    if (actorId >= numActors)
      {
      break;
      }
    }
  vtkSmartPointer<vtkRenderWindow> win =
    vtkSmartPointer<vtkRenderWindow>::New();
  vtkSmartPointer<vtkRenderWindowInteractor> iren =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
    vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
  ren->ResetCamera();
  win->AddRenderer(ren);
  win->SetInteractor(iren);
  iren->SetInteractorStyle(style);

  cerr << "number of actors: " << numActors << endl;
  cerr << "number of renders: " << numRenders << endl;

  vtkSmartPointer<vtkTimerLog> timer = vtkSmartPointer<vtkTimerLog>::New();
  timer->StartTimer();
  iren->Initialize();
  iren->SetEventPosition(100, 100);
  iren->InvokeEvent(vtkCommand::LeftButtonPressEvent, 0);
  timer->StopTimer();
  double firstRender = timer->GetElapsedTime();
  cerr << "first render time: " << firstRender << endl;

  timer->StartTimer();
  for (int i = 0; i < numRenders; ++i)
    {
    iren->SetEventPosition(100, 100 + i);
    iren->InvokeEvent(vtkCommand::MouseMoveEvent, 0);
    }
  iren->InvokeEvent(vtkCommand::LeftButtonReleaseEvent, 0);
  timer->StopTimer();
  double elapsed = timer->GetElapsedTime();
  cerr << "interactive render time: " << elapsed / numRenders << endl;
  cerr << "render time per actor: " << elapsed / numRenders / numActors << endl;

  if (interact)
    {
    iren->Start();
    }

  return 0;
}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkOpenGLClipPlanesPainter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkOpenGLClipPlanesPainter.h"

#include "vtkActor.h"
#include "vtkMatrix4x4.h"
#include "vtkObjectFactory.h"
#include "vtkPlane.h"
#include "vtkPlaneCollection.h"

#ifndef VTK_IMPLEMENT_MESA_CXX
# include "vtkOpenGL.h"
#endif

#ifndef VTK_IMPLEMENT_MESA_CXX
vtkStandardNewMacro(vtkOpenGLClipPlanesPainter);
vtkCxxRevisionMacro(vtkOpenGLClipPlanesPainter, "1.3");
#endif
//-----------------------------------------------------------------------------
vtkOpenGLClipPlanesPainter::vtkOpenGLClipPlanesPainter()
{
}

//-----------------------------------------------------------------------------
vtkOpenGLClipPlanesPainter::~vtkOpenGLClipPlanesPainter()
{
}

//-----------------------------------------------------------------------------
void vtkOpenGLClipPlanesPainter::RenderInternal(vtkRenderer* renderer,
  vtkActor* actor, unsigned long typeflags)
{
  vtkPlaneCollection *clipPlanes;
  vtkPlane *plane;
  int i, numClipPlanes;
  double planeEquation[4];

  clipPlanes = this->ClippingPlanes;

  if (clipPlanes == NULL)
    {
    numClipPlanes = 0;
    }
  else
    {
    numClipPlanes = clipPlanes->GetNumberOfItems();
    if (numClipPlanes > 6)
      {
      vtkErrorMacro(<< "OpenGL guarantees at most 6 additional clipping planes");
      }
    }

  for (i = 0; i < numClipPlanes; i++)
    {
    glEnable((GLenum)(GL_CLIP_PLANE0+i));
    }

  if ( clipPlanes )
    {
    vtkMatrix4x4 *actorMatrix = vtkMatrix4x4::New();
    actor->GetMatrix( actorMatrix );
    actorMatrix->Invert();
    // OpenGL matrices are transposed compared to VTK matrices
    actorMatrix->Transpose();

    double origin[4], normal[3], point[4];

    for (i = 0; i < numClipPlanes; i++)
      {
      plane = (vtkPlane *)clipPlanes->GetItemAsObject(i);

      plane->GetOrigin(origin);
      plane->GetNormal(normal);

      glMatrixMode(GL_MODELVIEW);
      glPushMatrix();
      glMultMatrixd(actorMatrix->Element[0]);

      planeEquation[0] = normal[0];
      planeEquation[1] = normal[1];
      planeEquation[2] = normal[2];
      planeEquation[3] = -(planeEquation[0]*origin[0]+
        planeEquation[1]*origin[1]+
        planeEquation[2]*origin[2]);
      glClipPlane((GLenum)(GL_CLIP_PLANE0+i),planeEquation);

      glPopMatrix();
      }

    actorMatrix->Delete();
    }

  this->Superclass::RenderInternal(renderer, actor, typeflags);

  for (i = 0; i < numClipPlanes; i++)
    {
    glDisable((GLenum)(GL_CLIP_PLANE0+i));
    }
}

//-----------------------------------------------------------------------------
void vtkOpenGLClipPlanesPainter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}
<commit_msg>BUG: Removed unused variable point from clipping plane transformation.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkOpenGLClipPlanesPainter.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkOpenGLClipPlanesPainter.h"

#include "vtkActor.h"
#include "vtkMatrix4x4.h"
#include "vtkObjectFactory.h"
#include "vtkPlane.h"
#include "vtkPlaneCollection.h"

#ifndef VTK_IMPLEMENT_MESA_CXX
# include "vtkOpenGL.h"
#endif

#ifndef VTK_IMPLEMENT_MESA_CXX
vtkStandardNewMacro(vtkOpenGLClipPlanesPainter);
vtkCxxRevisionMacro(vtkOpenGLClipPlanesPainter, "1.4");
#endif
//-----------------------------------------------------------------------------
vtkOpenGLClipPlanesPainter::vtkOpenGLClipPlanesPainter()
{
}

//-----------------------------------------------------------------------------
vtkOpenGLClipPlanesPainter::~vtkOpenGLClipPlanesPainter()
{
}

//-----------------------------------------------------------------------------
void vtkOpenGLClipPlanesPainter::RenderInternal(vtkRenderer* renderer,
  vtkActor* actor, unsigned long typeflags)
{
  vtkPlaneCollection *clipPlanes;
  vtkPlane *plane;
  int i, numClipPlanes;
  double planeEquation[4];

  clipPlanes = this->ClippingPlanes;

  if (clipPlanes == NULL)
    {
    numClipPlanes = 0;
    }
  else
    {
    numClipPlanes = clipPlanes->GetNumberOfItems();
    if (numClipPlanes > 6)
      {
      vtkErrorMacro(<< "OpenGL guarantees at most 6 additional clipping planes");
      }
    }

  for (i = 0; i < numClipPlanes; i++)
    {
    glEnable((GLenum)(GL_CLIP_PLANE0+i));
    }

  if ( clipPlanes )
    {
    vtkMatrix4x4 *actorMatrix = vtkMatrix4x4::New();
    actor->GetMatrix( actorMatrix );
    actorMatrix->Invert();
    // OpenGL matrices are transposed compared to VTK matrices
    actorMatrix->Transpose();

    double origin[4], normal[3];

    for (i = 0; i < numClipPlanes; i++)
      {
      plane = (vtkPlane *)clipPlanes->GetItemAsObject(i);

      plane->GetOrigin(origin);
      plane->GetNormal(normal);

      glMatrixMode(GL_MODELVIEW);
      glPushMatrix();
      glMultMatrixd(actorMatrix->Element[0]);

      planeEquation[0] = normal[0];
      planeEquation[1] = normal[1];
      planeEquation[2] = normal[2];
      planeEquation[3] = -(planeEquation[0]*origin[0]+
        planeEquation[1]*origin[1]+
        planeEquation[2]*origin[2]);
      glClipPlane((GLenum)(GL_CLIP_PLANE0+i),planeEquation);

      glPopMatrix();
      }

    actorMatrix->Delete();
    }

  this->Superclass::RenderInternal(renderer, actor, typeflags);

  for (i = 0; i < numClipPlanes; i++)
    {
    glDisable((GLenum)(GL_CLIP_PLANE0+i));
    }
}

//-----------------------------------------------------------------------------
void vtkOpenGLClipPlanesPainter::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}
<|endoftext|>