#include "trenderresourcemanager.h"
#include "trenderer.h"
//***********************************************************************************************
// Resource managers builder for instance-scoped resource managers
//***********************************************************************************************
/*
This manager class is used to create and destroy instance-scope managers through the
renderStart/renderEnd notifications. Observe that this involves maintenance of a container
structure of the active renderIds against resource managers.
*/
class RenderInstanceManagersBuilder : public TRenderResourceManager
{
T_RENDER_RESOURCE_MANAGER
typedef std::vector<TRenderResourceManager *> ManagersVector;
std::map<unsigned long, ManagersVector> m_managersMap;
public:
RenderInstanceManagersBuilder() {}
~RenderInstanceManagersBuilder() {}
static RenderInstanceManagersBuilder *instance();
TRenderResourceManager *getManager(unsigned long renderId, unsigned int idx) const;
void onRenderInstanceStart(unsigned long id);
void onRenderInstanceEnd(unsigned long id);
bool renderHasOwnership() { return false; }
};
//===============================================================================================
class RenderInstanceManagersBuilderGenerator : public TRenderResourceManagerGenerator
{
public:
TRenderResourceManager *operator()(void)
{
return RenderInstanceManagersBuilder::instance();
}
};
MANAGER_FILESCOPE_DECLARATION(RenderInstanceManagersBuilder, RenderInstanceManagersBuilderGenerator);
//***********************************************************************************************
// Stub managers and generators
//***********************************************************************************************
/*
These manager-generator stubs are substitutes used to maintain dependency order about managers
which have render instance scope. They retrieve ordered event calls that are passed to the
dedicated instanceScope handler.
*/
class InstanceResourceManagerStub : public TRenderResourceManager
{
TRenderResourceManagerGenerator *m_generator;
public:
InstanceResourceManagerStub(TRenderResourceManagerGenerator *generator)
: m_generator(generator)
{
}
void onRenderInstanceStart(unsigned long id);
void onRenderInstanceEnd(unsigned long id);
void onRenderFrameStart(double f);
void onRenderFrameEnd(double f);
virtual void onRenderStatusStart(int renderStatus);
virtual void onRenderStatusEnd(int renderStatus);
};
//===============================================================================================
class StubGenerator : public TRenderResourceManagerGenerator
{
TRenderResourceManagerGenerator *m_generator;
public:
StubGenerator(TRenderResourceManagerGenerator *generator)
: m_generator(generator)
{
}
TRenderResourceManager *operator()()
{
return new InstanceResourceManagerStub(m_generator);
}
};
//***********************************************************************************************
// TRenderResourceManagerGenerator methods
//***********************************************************************************************
std::vector<TRenderResourceManagerGenerator *> &TRenderResourceManagerGenerator::generators()
{
static std::vector<TRenderResourceManagerGenerator *> generatorsInstance;
return generatorsInstance;
}
//-------------------------------------------------------------------------
std::vector<TRenderResourceManagerGenerator *> &TRenderResourceManagerGenerator::generators(bool instanceScope)
{
static std::vector<TRenderResourceManagerGenerator *> generatorsInstance;
static std::vector<TRenderResourceManagerGenerator *> generatorsRenderer;
return instanceScope ? generatorsInstance : generatorsRenderer;
}
//===============================================================================================
TRenderResourceManagerGenerator::TRenderResourceManagerGenerator(bool renderInstanceScope)
: m_instanceScope(renderInstanceScope)
{
//In case this has a renderInstanceScope, build a stub generator
if (renderInstanceScope) {
RenderInstanceManagersBuilder::gen(); //Stubs depend on this manager
static std::vector<TRenderResourceManagerGenerator *> stubGenerators;
stubGenerators.push_back(new StubGenerator(this));
}
generators().push_back(this);
std::vector<TRenderResourceManagerGenerator *> &scopeGenerators =
generators(renderInstanceScope);
scopeGenerators.push_back(this);
m_managerIndex = scopeGenerators.size() - 1;
}
//-------------------------------------------------------------------------
TRenderResourceManager *TRenderResourceManagerGenerator::getManager(const TRenderer &renderer) const
{
return m_instanceScope ? 0 : renderer.getManager(m_managerIndex);
}
//-------------------------------------------------------------------------
TRenderResourceManager *TRenderResourceManagerGenerator::getManager(unsigned long renderId) const
{
return m_instanceScope ? RenderInstanceManagersBuilder::instance()->getManager(renderId, m_managerIndex) : 0;
}
//***********************************************************************************************
// "Instance-scoped Managers" - Management methods
//***********************************************************************************************
RenderInstanceManagersBuilder *RenderInstanceManagersBuilder::instance()
{
static RenderInstanceManagersBuilder theInstance;
return &theInstance;
}
//-------------------------------------------------------------------------
inline TRenderResourceManager *RenderInstanceManagersBuilder::
getManager(unsigned long renderId, unsigned int idx) const
{
std::map<unsigned long, ManagersVector>::const_iterator it = m_managersMap.find(renderId);
return it == m_managersMap.end() ? 0 : it->second[idx];
}
//-------------------------------------------------------------------------
void RenderInstanceManagersBuilder::onRenderInstanceStart(unsigned long id)
{
//Build the instance managers
std::map<unsigned long, ManagersVector>::iterator it =
m_managersMap.insert(std::make_pair(id, ManagersVector())).first;
std::vector<TRenderResourceManagerGenerator *> &instanceScopeGenerators =
TRenderResourceManagerGenerator::generators(true);
unsigned int i;
for (i = 0; i < instanceScopeGenerators.size(); ++i)
it->second.push_back((*instanceScopeGenerators[i])());
}
//-------------------------------------------------------------------------
void RenderInstanceManagersBuilder::onRenderInstanceEnd(unsigned long id)
{
//Delete the instance managers
std::map<unsigned long, ManagersVector>::iterator it =
m_managersMap.find(id);
assert(it != m_managersMap.end());
unsigned int i;
for (i = 0; i < it->second.size(); ++i) {
if (it->second[i]->renderHasOwnership())
delete it->second[i];
}
m_managersMap.erase(it);
}
//===============================================================================================
void InstanceResourceManagerStub::onRenderInstanceStart(unsigned long id)
{
RenderInstanceManagersBuilder::instance()->getManager(id,
m_generator->getGeneratorIndex())
->onRenderInstanceStart(id);
}
//-------------------------------------------------------------------------
void InstanceResourceManagerStub::onRenderInstanceEnd(unsigned long id)
{
RenderInstanceManagersBuilder::instance()->getManager(id,
m_generator->getGeneratorIndex())
->onRenderInstanceEnd(id);
}
//-------------------------------------------------------------------------
void InstanceResourceManagerStub::onRenderFrameStart(double f)
{
RenderInstanceManagersBuilder::instance()->getManager(
TRenderer::renderId(),
m_generator->getGeneratorIndex())
->onRenderFrameStart(f);
}
//-------------------------------------------------------------------------
void InstanceResourceManagerStub::onRenderFrameEnd(double f)
{
RenderInstanceManagersBuilder::instance()->getManager(
TRenderer::renderId(),
m_generator->getGeneratorIndex())
->onRenderFrameEnd(f);
}
//-------------------------------------------------------------------------
void InstanceResourceManagerStub::onRenderStatusStart(int renderStatus)
{
RenderInstanceManagersBuilder::instance()->getManager(
TRenderer::renderId(),
m_generator->getGeneratorIndex())
->onRenderStatusStart(renderStatus);
}
//-------------------------------------------------------------------------
void InstanceResourceManagerStub::onRenderStatusEnd(int renderStatus)
{
RenderInstanceManagersBuilder::instance()->getManager(
TRenderer::renderId(),
m_generator->getGeneratorIndex())
->onRenderStatusEnd(renderStatus);
}