Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//String includes
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Image includes
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Toonz Image cache
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//TTile class
Toshihiro Shimizu 890ddd
#include "ttile.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Trop include
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//File I/O includes
Toshihiro Shimizu 890ddd
//#include "tstream.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Qt classes
Toshihiro Shimizu 890ddd
#include <qregion></qregion>
Toshihiro Shimizu 890ddd
#include <qbytearray></qbytearray>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Resources pool manager
Toshihiro Shimizu 890ddd
#include "tcacheresourcepool.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcacheresource.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
//Debug
Toshihiro Shimizu 890ddd
#define DIAGNOSTICS
Toshihiro Shimizu 890ddd
#include "diagnostics.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Debug stuff
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  QString prefix("#resources.txt | RISORSE | ");
Toshihiro Shimizu 890ddd
  QString prefixMem("#memory.txt | ");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  QString traduce(const TRectD& rect)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    return "[" + QString::number(rect.x0) + " " + QString::number(rect.y0) + " "
Toshihiro Shimizu 890ddd
               + QString::number(rect.x1) + " " + QString::number(rect.y1) + "]";
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  QString traduce(const TRect& rect)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    return "[" + QString::number(rect.x0) + " " + QString::number(rect.y0) + " "
Toshihiro Shimizu 890ddd
               + QString::number(rect.x1+1) + " " + QString::number(rect.y1+1) + "]";
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  QString traduce(const TTile& tile)
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    TDimension size(tile.getRaster()->getSize());
Toshihiro Shimizu 890ddd
    TRectD tileRect(tile.m_pos, TDimensionD(size.lx,size.ly));
Toshihiro Shimizu 890ddd
    return traduce(tileRect);
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//====================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
The TCacheResource class models the idea of sparsely defined tile objects.
Toshihiro Shimizu 890ddd
Whereas common TTile instances can be used to represent images bounded on a specific
Toshihiro Shimizu 890ddd
rect of the plane, this model does not suit well in case the image object is
Toshihiro Shimizu 890ddd
sparse across the image plane.
Toshihiro Shimizu 890ddd
\n \n
Toshihiro Shimizu 890ddd
The TCacheResource internal  representation assumes that the image plane is split
Toshihiro Shimizu 890ddd
in a fixed-length integer lattice, each cell of which may host an image object in
Toshihiro Shimizu 890ddd
case some part of the complex inside the cell has been defined.
Toshihiro Shimizu 890ddd
The plane outside the complex is assumed to be transparent.
Toshihiro Shimizu 890ddd
\n
Toshihiro Shimizu 890ddd
The lattice origin must be specified in the complex's contructor, and all tiles
Toshihiro Shimizu 890ddd
uploaded into and downloaded from it must have an integer displacement with respect
Toshihiro Shimizu 890ddd
to it - in other words, it is required that the complex has a well-defined pixel geometry.
Toshihiro Shimizu 890ddd
\n \n
Toshihiro Shimizu 890ddd
Specific regions of the complex can be cleared through the apposite clear() method.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
\warning
Toshihiro Shimizu 890ddd
This class does not ensure thread-safety. Concurrent accesses must be dealt by users.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//====================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//  Docs stuff
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! \fn QRegion TCacheResource::getAvailableRegion() const
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Returns the current region currently available in the complex, with respect to
Toshihiro Shimizu 890ddd
the complex's origin.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! \fn int TCacheResource::getRasterType() const
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Returns the type of raster currently present in the tile complex. Only images
Toshihiro Shimizu 890ddd
providing a raster representation coherent with the complex's one may be exchanged
Toshihiro Shimizu 890ddd
with it.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*! \fn void TCacheResource::clear()
Toshihiro Shimizu 890ddd
Clears the whole complex. This is an overloaded method equivalent to
Toshihiro Shimizu 890ddd
clear(getAvailableRegion()), supplied for convience.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//====================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
//    Preliminaries
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
//Store tile textures of 512 x 512 pixels. Their memory usage ranges around 1-2 MB each.
Toshihiro Shimizu 890ddd
const int latticeStep = 512;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static unsigned long cacheId = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline int getRasterType(const TRasterP &ras)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if ((TRaster32P)ras)
Toshihiro Shimizu 890ddd
		return TCacheResource::RGBM32;
Toshihiro Shimizu 890ddd
	else if ((TRaster64P)ras)
Toshihiro Shimizu 890ddd
		return TCacheResource::RGBM64;
Toshihiro Shimizu 890ddd
	else if ((TRasterCM32P)ras)
Toshihiro Shimizu 890ddd
		return TCacheResource::CM32;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return TCacheResource::NONE;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline TRasterP getRaster(const TImageP &img)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterImageP rimg(img);
Toshihiro Shimizu 890ddd
	if (rimg)
Toshihiro Shimizu 890ddd
		return rimg->getRaster();
Toshihiro Shimizu 890ddd
	TToonzImageP timg(img);
Toshihiro Shimizu 890ddd
	if (timg)
Toshihiro Shimizu 890ddd
		return timg->getRaster();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(!"Wrong image type!");
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline bool isEmpty(const TRect &rect) { return rect.x0 > rect.x1 || rect.y0 > rect.y1; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline QRect toQRect(const TRect &r) { return QRect(r.x0, r.y0, r.getLx(), r.getLy()); }
Toshihiro Shimizu 890ddd
inline TRect toTRect(const QRect &r) { return TRect(r.left(), r.top(), r.right(), r.bottom()); }
Toshihiro Shimizu 890ddd
inline QPoint toQPoint(const TPoint &p) { return QPoint(p.x, p.y); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline TRect getTileRect(const TTile &tile)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TRect(
Toshihiro Shimizu 890ddd
		TPoint(tfloor(tile.m_pos.x), tfloor(tile.m_pos.y)),
Toshihiro Shimizu 890ddd
		tile.getRaster()->getSize());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Qt's contains actually returns QRegion::intersected... I wonder why...
Toshihiro Shimizu 890ddd
inline bool contains(const QRegion ®ion, const TRect &rect)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return QRegion(toQRect(rect)).subtracted(region).isEmpty();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void saveCompressed(const TFilePath &fp, const TRasterP &ras)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(ras->getLx() == latticeStep && ras->getLy() == latticeStep);
Toshihiro Shimizu 890ddd
	unsigned int size = sq(latticeStep) * ras->getPixelSize();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ras->lock();
Toshihiro Shimizu 890ddd
	QByteArray data = qCompress((const char *)ras->getRawData(), size);
Toshihiro Shimizu 890ddd
	ras->unlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Tofstream oss(fp);
Toshihiro Shimizu 890ddd
	oss.write((const char *)&size, sizeof(unsigned int));
Toshihiro Shimizu 890ddd
	oss.write(data.constData(), data.size());
Toshihiro Shimizu 890ddd
	assert(!oss.fail());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void loadCompressed(const TFilePath &fp, TRasterP &ras, TCacheResource::Type rasType)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Tifstream is(fp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (rasType == TCacheResource::CM32)
Toshihiro Shimizu 890ddd
		ras = TRasterCM32P(latticeStep, latticeStep);
Toshihiro Shimizu 890ddd
	else if (rasType == TCacheResource::RGBM32)
Toshihiro Shimizu 890ddd
		ras = TRaster32P(latticeStep, latticeStep);
Toshihiro Shimizu 890ddd
	else if (rasType == TCacheResource::RGBM64)
Toshihiro Shimizu 890ddd
		ras = TRaster64P(latticeStep, latticeStep);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		assert(false);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ras->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	char *rawData = (char *)ras->getRawData();
Toshihiro Shimizu 890ddd
	unsigned int dataSize;
Toshihiro Shimizu 890ddd
	is.read((char *)&dataSize, sizeof(unsigned int));
Toshihiro Shimizu 890ddd
	is.read(rawData, dataSize);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Observe that QByteArray::fromRawData does NOT cause a deep copy to occur.
Toshihiro Shimizu 890ddd
	QByteArray data(QByteArray::fromRawData(rawData, dataSize));
Toshihiro Shimizu 890ddd
	data = qUncompress(data);
Toshihiro Shimizu 890ddd
	memcpy(rawData, data.constData(), data.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ras->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
//    TCacheResourceP implementation
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TCacheResourceP::TCacheResourceP(const std::string &imageName, bool createIfNone)
Toshihiro Shimizu 890ddd
	: m_pointer(TCacheResourcePool::instance()->getResource(imageName, createIfNone))
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_pointer)
Toshihiro Shimizu 890ddd
		m_pointer->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TCacheResourceP::~TCacheResourceP()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_pointer) {
Toshihiro Shimizu 890ddd
		m_pointer->release();
Toshihiro Shimizu 890ddd
		m_pointer = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
//    Member functions implementation
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=====================
Toshihiro Shimizu 890ddd
//    TCacheResource
Toshihiro Shimizu 890ddd
//---------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TCacheResource::TCacheResource()
Toshihiro Shimizu 890ddd
	: m_id(cacheId++), m_tileType(NONE), m_cellsCount(0), m_locksCount(0), m_backEnabled(false), m_invalidated(false)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TCacheResource::~TCacheResource()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::release()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if ((--m_refCount) <= 0) {
Toshihiro Shimizu 890ddd
		//Attempt release from the resource pool
Toshihiro Shimizu 890ddd
		TCacheResourcePool::instance()->releaseResource(this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline TCacheResource::PointLess TCacheResource::getCellIndex(const TPoint &pos) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return PointLess(
Toshihiro Shimizu 890ddd
		tfloor(pos.x / (double)latticeStep),
Toshihiro Shimizu 890ddd
		tfloor(pos.y / (double)latticeStep));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline TPoint TCacheResource::getCellPos(const PointLess &cellIndex) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TPoint(cellIndex.x * latticeStep, cellIndex.y * latticeStep);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Returns the lattice cell containing the position pos.
Toshihiro Shimizu 890ddd
inline TPoint TCacheResource::getCellPos(const TPoint &pos) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPoint cellIndex(
Toshihiro Shimizu 890ddd
		tfloor(pos.x / (double)latticeStep),
Toshihiro Shimizu 890ddd
		tfloor(pos.y / (double)latticeStep));
Toshihiro Shimizu 890ddd
	return TPoint(cellIndex.x * latticeStep, cellIndex.y * latticeStep);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//Returns the lattice cell containing the relative position pos.
Toshihiro Shimizu 890ddd
inline TPoint TCacheResource::getCellPos(const TPointD &pos) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPoint cellIndex(
Toshihiro Shimizu 890ddd
		tfloor(pos.x / (double)latticeStep),
Toshihiro Shimizu 890ddd
		tfloor(pos.y / (double)latticeStep));
Toshihiro Shimizu 890ddd
	return TPoint(cellIndex.x * latticeStep, cellIndex.y * latticeStep);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
//    Tough stuff
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TCacheResource::checkRasterType(const TRasterP &ras, int &rasType) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	rasType = ::getRasterType(ras);
Toshihiro Shimizu 890ddd
	if (rasType == NONE) {
Toshihiro Shimizu 890ddd
		assert(!"The passed raster has unkown type!");
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (m_tileType != NONE && m_tileType != rasType) {
Toshihiro Shimizu 890ddd
		assert(!"The passed raster has not the same type of the cache resource!");
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRasterP TCacheResource::buildCompatibleRaster(const TDimension &size)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterP result;
Toshihiro Shimizu 890ddd
	if (m_tileType == RGBM32)
Toshihiro Shimizu 890ddd
		result = TRaster32P(size);
Toshihiro Shimizu 890ddd
	else if (m_tileType == RGBM64)
Toshihiro Shimizu 890ddd
		result = TRaster64P(size);
Toshihiro Shimizu 890ddd
	else if (m_tileType == CM32)
Toshihiro Shimizu 890ddd
		result = TRasterCM32P(size);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return result;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TCacheResource::checkTile(const TTile &tile) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Ensure that tile has integer geoometry.
Toshihiro Shimizu 890ddd
	TPointD tileFracPos(tile.m_pos.x - tfloor(tile.m_pos.x), tile.m_pos.y - tfloor(tile.m_pos.y));
Toshihiro Shimizu 890ddd
	if (tileFracPos.x != 0.0 || tileFracPos.y != 0.0) {
Toshihiro Shimizu 890ddd
		assert(!"The passed tile must have integer geometry!");
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline std::string TCacheResource::getCellName(int idxX, int idxY) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "cell" + toString(idxX) + "," + toString(idxY);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline std::string TCacheResource::getCellCacheId(int idxX, int idxY) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return "TCacheResource" + toString(m_id) + getCellName(idxX, idxY);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline std::string TCacheResource::getCellCacheId(const TPoint &cellPos) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getCellCacheId(tfloor(cellPos.x / (double)latticeStep),
Toshihiro Shimizu 890ddd
						  tfloor(cellPos.y / (double)latticeStep));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline TRasterP TCacheResource::createCellRaster(int rasterType, const std::string &cacheId)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterP result;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (rasterType == TCacheResource::NONE) {
Toshihiro Shimizu 890ddd
		assert(!"Unknown raster type!");
Toshihiro Shimizu 890ddd
		return result;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageP img;
Toshihiro Shimizu 890ddd
	if (rasterType == TCacheResource::RGBM32) {
Toshihiro Shimizu 890ddd
		result = TRaster32P(latticeStep, latticeStep);
Toshihiro Shimizu 890ddd
		img = TRasterImageP(result);
Toshihiro Shimizu 890ddd
	} else if (rasterType == TCacheResource::RGBM64) {
Toshihiro Shimizu 890ddd
		result = TRaster64P(latticeStep, latticeStep);
Toshihiro Shimizu 890ddd
		img = TRasterImageP(result);
Toshihiro Shimizu 890ddd
	} else if (rasterType == TCacheResource::CM32) {
Toshihiro Shimizu 890ddd
		result = TRasterCM32P(latticeStep, latticeStep);
Toshihiro Shimizu 890ddd
		img = TToonzImageP(result, result->getBounds());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TImageCache::instance()->add(cacheId, img);
Toshihiro Shimizu 890ddd
	++m_cellsCount;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//DIAGNOSTICS_GLOADD("crCellsCnt", 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return result;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TCacheResource::canDownloadSome(const TRect &rect) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_region.intersects(toQRect(rect));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TCacheResource::canDownloadAll(const TRect &rect) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return contains(m_region, rect);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TCacheResource::canUpload(const TTile &tile) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int tileType;
Toshihiro Shimizu 890ddd
	return checkTile(tile) && checkRasterType(tile.getRaster(), tileType);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns true if the passed tile is compatible with the complex, and some
Toshihiro Shimizu 890ddd
//! part of it is downloadable.
Toshihiro Shimizu 890ddd
bool TCacheResource::canDownloadSome(const TTile &tile) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return checkTile(tile) && m_region.intersects(toQRect(getTileRect(tile)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns true if the passed tile is compatible, and it can be downloaded
Toshihiro Shimizu 890ddd
//! entirely.
Toshihiro Shimizu 890ddd
bool TCacheResource::canDownloadAll(const TTile &tile) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return checkTile(tile) && contains(m_region, getTileRect(tile));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Copies the passed tile in the tile complex. The passed tile \b must
Toshihiro Shimizu 890ddd
//! possess integer geometry (ie tile.m_pos must have integer coordinates),
Toshihiro Shimizu 890ddd
//! otherwise this function is a no-op.
Toshihiro Shimizu 890ddd
bool TCacheResource::upload(const TPoint &pos, TRasterP ras)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int tileType;
Toshihiro Shimizu 890ddd
	if (!checkRasterType(ras, tileType))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_tileType == NONE)
Toshihiro Shimizu 890ddd
		m_tileType = tileType;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//For all cells of the lattice which intersect the tile, upload the content in the
Toshihiro Shimizu 890ddd
	//complex
Toshihiro Shimizu 890ddd
	TRect tileRect(ras->getBounds() + pos);
Toshihiro Shimizu 890ddd
	TPoint initialPos(getCellPos(tileRect.getP00()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//DIAGNOSTICS_NUMBEREDSTRSET(prefix + QString::number((UINT) this) + " | Stack | ",
Toshihiro Shimizu 890ddd
	//"crStack", "upload", ::traduce(TRect(pos, ras->getSize())));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPoint currPos;
Toshihiro Shimizu 890ddd
	for (currPos.x = initialPos.x; currPos.x <= tileRect.x1; currPos.x += latticeStep)
Toshihiro Shimizu 890ddd
		for (currPos.y = initialPos.y; currPos.y <= tileRect.y1; currPos.y += latticeStep) {
Toshihiro Shimizu 890ddd
			//Copy tile's content into the cell's raster.
Toshihiro Shimizu 890ddd
			TRect cellRect(currPos, TDimension(latticeStep, latticeStep));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRect overlapRect(tileRect * cellRect);
Toshihiro Shimizu 890ddd
			assert(!overlapRect.isEmpty());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			PointLess cellIndex(getCellIndex(currPos));
Toshihiro Shimizu 890ddd
			std::pair<trasterp, *="" celldata=""> cellInfos(touch(cellIndex));</trasterp,>
Toshihiro Shimizu 890ddd
			TRasterP cellRas(cellInfos.first);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRect temp(overlapRect - currPos);
Toshihiro Shimizu 890ddd
			TRasterP overlappingCellRas(cellRas->extract(temp));
Toshihiro Shimizu 890ddd
			temp = TRect(overlapRect - tileRect.getP00());
Toshihiro Shimizu 890ddd
			TRasterP overlappingTileRas(ras->extract(temp));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			assert(overlappingCellRas->getBounds() == overlappingTileRas->getBounds());
Toshihiro Shimizu 890ddd
			TRop::copy(overlappingCellRas, overlappingTileRas);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			cellInfos.second->m_modified = true;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Update the complex's content region
Toshihiro Shimizu 890ddd
	m_region += toQRect(tileRect);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TCacheResource::upload(const TTile &tile)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!checkTile(tile))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return upload(TPoint(tile.m_pos.x, tile.m_pos.y), tile.getRaster());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Fills the passed tile with the data contained in the complex, returning
Toshihiro Shimizu 890ddd
//! the copied region.
Toshihiro Shimizu 890ddd
//! The same restriction of the upload() method applies here.
Toshihiro Shimizu 890ddd
QRegion TCacheResource::download(const TPoint &pos, TRasterP ras)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int tileType;
Toshihiro Shimizu 890ddd
	if (!checkRasterType(ras, tileType))
Toshihiro Shimizu 890ddd
		return QRegion();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Build the tile's rect
Toshihiro Shimizu 890ddd
	TRect tileRect(ras->getBounds() + pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!m_region.intersects(toQRect(tileRect)))
Toshihiro Shimizu 890ddd
		return QRegion();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//For all cells intersecting the tile's rect, copy all those intersecting the
Toshihiro Shimizu 890ddd
	//complex's content region.
Toshihiro Shimizu 890ddd
	TPoint initialPos(getCellPos(tileRect.getP00()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPoint currPos;
Toshihiro Shimizu 890ddd
	for (currPos.x = initialPos.x; currPos.x <= tileRect.x1; currPos.x += latticeStep)
Toshihiro Shimizu 890ddd
		for (currPos.y = initialPos.y; currPos.y <= tileRect.y1; currPos.y += latticeStep) {
Toshihiro Shimizu 890ddd
			TRect cellRect(currPos, TDimension(latticeStep, latticeStep));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRect overlapRect(tileRect * cellRect);
Toshihiro Shimizu 890ddd
			assert(!overlapRect.isEmpty());
Toshihiro Shimizu 890ddd
			QRect overlapQRect(toQRect(overlapRect));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (m_region.intersects(overlapQRect)) {
Toshihiro Shimizu 890ddd
				//Extract the associated rasters and perform the copy to the input tile.
Toshihiro Shimizu 890ddd
				std::pair<trasterp, *="" celldata=""> cellInfos(touch(getCellIndex(currPos)));</trasterp,>
Toshihiro Shimizu 890ddd
				TRasterP cellRas(cellInfos.first);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TRect temp(overlapRect - currPos);
Toshihiro Shimizu 890ddd
				TRasterP overlappingCellRas(cellRas->extract(temp));
Toshihiro Shimizu 890ddd
				temp = TRect(overlapRect - tileRect.getP00());
Toshihiro Shimizu 890ddd
				TRasterP overlappingTileRas(ras->extract(temp));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TRop::copy(overlappingTileRas, overlappingCellRas);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return m_region.intersected(QRegion(toQRect(tileRect)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
QRegion TCacheResource::download(TTile &tile)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!checkTile(tile))
Toshihiro Shimizu 890ddd
		return QRegion();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return download(TPoint(tile.m_pos.x, tile.m_pos.y), tile.getRaster());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TCacheResource::downloadAll(const TPoint &pos, TRasterP ras)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int tileType;
Toshihiro Shimizu 890ddd
	if (!checkRasterType(ras, tileType))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Build the tile's rect
Toshihiro Shimizu 890ddd
	TRect tileRect(ras->getBounds() + pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!contains(m_region, tileRect))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//DIAGNOSTICS_NUMBEREDSTRSET(prefix + QString::number((UINT) this) + " | Stack | ",
Toshihiro Shimizu 890ddd
	//"crStack", "downloadAll", ::traduce(TRect(pos, ras->getSize())));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//For all cells intersecting the tile's rect, copy all those intersecting the
Toshihiro Shimizu 890ddd
	//complex's content region.
Toshihiro Shimizu 890ddd
	TPoint initialPos(getCellPos(tileRect.getP00()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPoint currPos;
Toshihiro Shimizu 890ddd
	for (currPos.x = initialPos.x; currPos.x <= tileRect.x1; currPos.x += latticeStep)
Toshihiro Shimizu 890ddd
		for (currPos.y = initialPos.y; currPos.y <= tileRect.y1; currPos.y += latticeStep) {
Toshihiro Shimizu 890ddd
			TRect cellRect(currPos, TDimension(latticeStep, latticeStep));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			TRect overlapRect(tileRect * cellRect);
Toshihiro Shimizu 890ddd
			assert(!overlapRect.isEmpty());
Toshihiro Shimizu 890ddd
			QRect overlapQRect(toQRect(overlapRect));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (m_region.intersects(overlapQRect)) {
Toshihiro Shimizu 890ddd
				//Extract the associated rasters and perform the copy to the input tile.
Toshihiro Shimizu 890ddd
				std::pair<trasterp, *="" celldata=""> cellInfos(touch(getCellIndex(currPos)));</trasterp,>
Toshihiro Shimizu 890ddd
				TRasterP cellRas(cellInfos.first);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TRect temp(overlapRect - currPos);
Toshihiro Shimizu 890ddd
				TRasterP overlappingCellRas(cellRas->extract(temp));
Toshihiro Shimizu 890ddd
				temp = TRect(overlapRect - tileRect.getP00());
Toshihiro Shimizu 890ddd
				TRasterP overlappingTileRas(ras->extract(temp));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TRop::copy(overlappingTileRas, overlappingCellRas);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TCacheResource::downloadAll(TTile &tile)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!checkTile(tile))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return downloadAll(TPoint(tile.m_pos.x, tile.m_pos.y), tile.getRaster());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Clears the complex on the specified region. Please observe that the actually cleared region
Toshihiro Shimizu 890ddd
//! consists of all lattice cells intersecting the passed region, therefore resulting in a cleared region
Toshihiro Shimizu 890ddd
//! typically larger than passed one, up to the lattice granularity.
Toshihiro Shimizu 890ddd
void TCacheResource::clear(QRegion region)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_region.intersects(region))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Get the region bbox
Toshihiro Shimizu 890ddd
	TRect bbox(toTRect(region.boundingRect()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//For all cells intersecting the bbox
Toshihiro Shimizu 890ddd
	TPoint initialPos(getCellPos(bbox.getP00()));
Toshihiro Shimizu 890ddd
	TPoint pos;
Toshihiro Shimizu 890ddd
	for (pos.x = initialPos.x; pos.x <= bbox.x1; pos.x += latticeStep)
Toshihiro Shimizu 890ddd
		for (pos.y = initialPos.y; pos.y <= bbox.y1; pos.y += latticeStep) {
Toshihiro Shimizu 890ddd
			QRect cellQRect(toQRect(TRect(pos, TDimension(latticeStep, latticeStep))));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (region.intersects(cellQRect) && m_region.intersects(cellQRect)) {
Toshihiro Shimizu 890ddd
				//Release the associated cell from cache and clear the cell from the content region.
Toshihiro Shimizu 890ddd
				TImageCache::instance()->remove(getCellCacheId(pos));
Toshihiro Shimizu 890ddd
				m_region -= cellQRect;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				--m_cellsCount;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//DIAGNOSTICS_GLOADD("crCellsCnt", -1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//Release the cell from m_cellDatas
Toshihiro Shimizu 890ddd
				m_cellDatas[getCellIndex(pos)].m_modified = true;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_region.isEmpty()) {
Toshihiro Shimizu 890ddd
		m_tileType = NONE;
Toshihiro Shimizu 890ddd
		m_locksCount = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
//    Palette management
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TCacheResource::uploadPalette(TPaletteP palette)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_tileType == NONE)
Toshihiro Shimizu 890ddd
		m_tileType = CM32;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_tileType != CM32) {
Toshihiro Shimizu 890ddd
		assert(!"The resource already holds a non-colormap content!");
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_palette = palette;
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::downloadPalette(TPaletteP &palette)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	palette = m_palette;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
//    References management
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::addRef2(const TRect &rect)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//DIAGNOSTICS_NUMBEREDSTRSET(prefix + QString::number((UINT) this) + " | Stack | ",
Toshihiro Shimizu 890ddd
	//"crStack", "addRef", ::traduce(rect));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Add a reference to all cells intersecting the passed one
Toshihiro Shimizu 890ddd
	TPoint initialPos(getCellPos(rect.getP00()));
Toshihiro Shimizu 890ddd
	TPoint pos;
Toshihiro Shimizu 890ddd
	for (pos.x = initialPos.x; pos.x <= rect.x1; pos.x += latticeStep)
Toshihiro Shimizu 890ddd
		for (pos.y = initialPos.y; pos.y <= rect.y1; pos.y += latticeStep) {
Toshihiro Shimizu 890ddd
			PointLess cellIndex(getCellIndex(pos));
Toshihiro Shimizu 890ddd
			CellData &cellData = m_cellDatas[cellIndex];
Toshihiro Shimizu 890ddd
			cellData.m_referenced = true;
Toshihiro Shimizu 890ddd
			cellData.m_refsCount++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::release2(const TRect &rect)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//DIAGNOSTICS_NUMBEREDSTRSET(prefix + QString::number((UINT) this) + " | Stack | ",
Toshihiro Shimizu 890ddd
	//"crStack", "release", ::traduce(rect));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_locksCount > 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<pointless, celldata="">::iterator it;</pointless,>
Toshihiro Shimizu 890ddd
	for (it = m_cellDatas.begin(); it != m_cellDatas.end();) {
Toshihiro Shimizu 890ddd
		if (!it->second.m_referenced) {
Toshihiro Shimizu 890ddd
			++it;
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TPoint cellPos(getCellPos(it->first));
Toshihiro Shimizu 890ddd
		TRect cellRect(cellPos, TDimension(latticeStep, latticeStep));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (isEmpty(cellRect * rect)) {
Toshihiro Shimizu 890ddd
			++it;
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		QRect cellQRect(toQRect(cellRect));
Toshihiro Shimizu 890ddd
		if (--it->second.m_refsCount <= 0) {
Toshihiro Shimizu 890ddd
			releaseCell(cellQRect, it->first, it->second.m_modified);
Toshihiro Shimizu 890ddd
			std::map<pointless, celldata="">::iterator jt = it++;</pointless,>
Toshihiro Shimizu 890ddd
			m_cellDatas.erase(jt);
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			++it;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::addLock()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//DIAGNOSTICS_NUMBEREDSTR(prefix + QString::number((UINT) this) + " | Stack | ",
Toshihiro Shimizu 890ddd
	//"crStack", "addLock");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	++m_locksCount;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::releaseLock()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//DIAGNOSTICS_NUMBEREDSTR(prefix + QString::number((UINT) this) + " | Stack | ",
Toshihiro Shimizu 890ddd
	//"crStack", "releaseLock");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_locksCount = tmax(m_locksCount - 1, 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_locksCount > 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Check for released cells
Toshihiro Shimizu 890ddd
	std::map<pointless, celldata="">::iterator it;</pointless,>
Toshihiro Shimizu 890ddd
	for (it = m_cellDatas.begin(); it != m_cellDatas.end();)
Toshihiro Shimizu 890ddd
		if (it->second.m_referenced) {
Toshihiro Shimizu 890ddd
			TPoint cellPos(getCellPos(it->first));
Toshihiro Shimizu 890ddd
			QRect cellQRect(cellPos.x, cellPos.y, latticeStep, latticeStep);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			releaseCell(cellQRect, it->first, it->second.m_modified);
Toshihiro Shimizu 890ddd
			std::map<pointless, celldata="">::iterator jt = it++;</pointless,>
Toshihiro Shimizu 890ddd
			m_cellDatas.erase(jt);
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			++it;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::releaseCell(const QRect &cellQRect, const PointLess &cellIndex, bool doSave)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_region.intersects(cellQRect)) {
Toshihiro Shimizu 890ddd
		std::string cellCacheId(getCellCacheId(cellIndex.x, cellIndex.y));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!(doSave && save(cellIndex)))
Toshihiro Shimizu 890ddd
			m_region -= cellQRect;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TImageCache::instance()->remove(cellCacheId);
Toshihiro Shimizu 890ddd
		--m_cellsCount;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//DIAGNOSTICS_GLOADD("crCellsCnt", -1);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Returns the current size, in MB, of the cache resource.
Toshihiro Shimizu 890ddd
int TCacheResource::size() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//NOTE: It's better to store the size incrementally. This complies
Toshihiro Shimizu 890ddd
	//with the possibility of specifying a bbox to fit the stored cells to...
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return m_tileType == NONE ? 0 : m_tileType == RGBM64 ? (m_cellsCount << 11) : (m_cellsCount << 10);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
//    Hard disk backing procedures
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::enableBackup()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_backEnabled)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TCacheResourcePool::instance()->startBacking(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::invalidate()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_invalidated = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::setPath(const TFilePath &path)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_path = path;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TFilePath &TCacheResource::getPath() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_path;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TCacheResource::save(const PointLess &cellIndex, TRasterP cellRas) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_backEnabled || m_invalidated)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(!m_path.isEmpty());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!cellRas)
Toshihiro Shimizu 890ddd
		cellRas = getRaster(TImageCache::instance()->get(
Toshihiro Shimizu 890ddd
			getCellCacheId(cellIndex.x, cellIndex.y), false));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(m_tileType != NONE);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath fp(TCacheResourcePool::instance()->getPath() + m_path + getCellName(cellIndex.x, cellIndex.y));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_tileType == CM32) {
Toshihiro Shimizu 890ddd
		::saveCompressed(fp, cellRas);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		TImageWriter::save(fp.withType(".tif"), cellRas);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TRasterP TCacheResource::load(const PointLess &cellPos)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_path.isEmpty())
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFilePath cellPath(TCacheResourcePool::instance()->getPath() + m_path + TFilePath(getCellName(cellPos.x, cellPos.y)));
Toshihiro Shimizu 890ddd
	TRasterP ras;
Toshihiro Shimizu 890ddd
	if (m_tileType == CM32) {
Toshihiro Shimizu 890ddd
		::loadCompressed(cellPath, ras, CM32);
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		TImageReader::load(cellPath.withType(".tif"), ras);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return ras;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
std::pair<trasterp, *="" tcacheresource::celldata=""> TCacheResource::touch(const PointLess &cellIndex)</trasterp,>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::string cellId(getCellCacheId(cellIndex.x, cellIndex.y));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<pointless, celldata="">::iterator it = m_cellDatas.find(cellIndex);</pointless,>
Toshihiro Shimizu 890ddd
	if (it != m_cellDatas.end()) {
Toshihiro Shimizu 890ddd
		//Retrieve the raster from image cache
Toshihiro Shimizu 890ddd
		TImageP img(TImageCache::instance()->get(cellId, true));
Toshihiro Shimizu 890ddd
		if (img)
Toshihiro Shimizu 890ddd
			return std::make_pair(getRaster(img), &it->second);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	it = m_cellDatas.insert(std::make_pair(cellIndex, CellData())).first;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Then, attempt retrieval from back resource
Toshihiro Shimizu 890ddd
	TRasterP ras(load(cellIndex));
Toshihiro Shimizu 890ddd
	if (ras) {
Toshihiro Shimizu 890ddd
		TImageCache::instance()->add(cellId, TRasterImageP(ras));
Toshihiro Shimizu 890ddd
		return std::make_pair(ras, &it->second);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Else, create it
Toshihiro Shimizu 890ddd
	return std::make_pair(
Toshihiro Shimizu 890ddd
		createCellRaster(m_tileType, cellId), //increases m_cellsCount too
Toshihiro Shimizu 890ddd
		&it->second);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::save()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_backEnabled && !m_invalidated) {
Toshihiro Shimizu 890ddd
		assert(!m_path.isEmpty());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Save each modified cell raster
Toshihiro Shimizu 890ddd
		std::map<pointless, celldata="">::iterator it;</pointless,>
Toshihiro Shimizu 890ddd
		for (it = m_cellDatas.begin(); it != m_cellDatas.end(); ++it) {
Toshihiro Shimizu 890ddd
			if (it->second.m_modified)
Toshihiro Shimizu 890ddd
				save(it->first);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Save the palette, if any
Toshihiro Shimizu 890ddd
		//SHOULD BE MOVED TO THE CACHERESOURCEPOOL!!
Toshihiro Shimizu 890ddd
		/*if(m_palette)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
      TFilePath fp(TCacheResourcePool::instance()->getPath() + m_path);
Toshihiro Shimizu 890ddd
      TOStream oss(fp);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
      m_palette->saveData(oss);
Toshihiro Shimizu 890ddd
    }*/
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::save(const TFilePath &fp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(!fp.isEmpty());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::map<pointless, celldata="">::iterator it;</pointless,>
Toshihiro Shimizu 890ddd
	for (it = m_cellDatas.begin(); it != m_cellDatas.end(); ++it) {
Toshihiro Shimizu 890ddd
		TRasterP cellRas = getRaster(TImageCache::instance()->get(
Toshihiro Shimizu 890ddd
			getCellCacheId(it->first.x, it->first.y), false));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		assert(m_tileType != NONE);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TFilePath cellFp(fp + TFilePath(getCellName(it->first.x, it->first.y)));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_tileType == CM32)
Toshihiro Shimizu 890ddd
			::saveCompressed(cellFp, cellRas);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			TImageWriter::save(cellFp.withType(".tif"), cellRas);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TCacheResource::clear()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::map<pointless, celldata="">::iterator it;</pointless,>
Toshihiro Shimizu 890ddd
	for (it = m_cellDatas.begin(); it != m_cellDatas.end(); ++it) {
Toshihiro Shimizu 890ddd
		std::string cellCacheId(getCellCacheId(it->first.x, it->first.y));
Toshihiro Shimizu 890ddd
		TImageCache::instance()->remove(cellCacheId);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_cellDatas.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
//    Disk reference
Toshihiro Shimizu 890ddd
//****************************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qsettings></qsettings>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TCacheResource::DiskReference::DiskReference(const TFilePath& fp)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  QSettings settings(
Toshihiro Shimizu 890ddd
    QString::fromStdWString((TCacheResourcePool::instance()->getPath() + m_path + "resource.ini").getWideString()),
Toshihiro Shimizu 890ddd
    QSettings::IniFormat);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  settings.setValue("MemReference", 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TCacheResource::DiskReference::~DiskReference()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  QSettings settings(
Toshihiro Shimizu 890ddd
    QString::fromStdWString((TCacheResourcePool::instance()->getPath() + m_path + "resource.ini").getWideString()),
Toshihiro Shimizu 890ddd
    QSettings::IniFormat);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  int diskReference = settings.value("DiskReference").toInt();
Toshihiro Shimizu 890ddd
  if(diskReference == 0)
Toshihiro Shimizu 890ddd
    TCacheResourcePool::instance()->clearResource(QString::fromStdWString(m_path.getWideString()));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/