6e8fbca745
match the genesis editor version 1.3.0.653.
725 lines
20 KiB
C++
725 lines
20 KiB
C++
/****************************************************************************
|
||
Copyright (c) 2011-2013,WebJet Business Division,CYOU
|
||
|
||
http://www.genesis-3d.com.cn
|
||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
of this software and associated documentation files (the "Software"), to deal
|
||
in the Software without restriction, including without limitation the rights
|
||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
copies of the Software, and to permit persons to whom the Software is
|
||
furnished to do so, subject to the following conditions:
|
||
|
||
The above copyright notice and this permission notice shall be included in
|
||
all copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
THE SOFTWARE.
|
||
****************************************************************************/
|
||
#include "resource/resource_stdneb.h"
|
||
#include "resource/resourceserver.h"
|
||
|
||
// ÓÃÓÚ×¢²áĬÈϵĶÁдÆ÷
|
||
#include "resource/imageresloader.h"
|
||
#include "resource/meshresloader.h"
|
||
#include "resource/meshressaver.h"
|
||
#include "resource/skeletonresloader.h"
|
||
#include "resource/skeletonressaver.h"
|
||
#include "resource/animationresloader.h"
|
||
#include "resource/animationressaver.h"
|
||
#include "resource/physxmaterialloader.h"
|
||
#include "resource/rawres.h"
|
||
#include "resource/rawresloader.h"
|
||
#include "resource/rawressaver.h"
|
||
#include "resource/templateres.h"
|
||
#include "resource/templateresloader.h"
|
||
#include "resource/templateressaver.h"
|
||
#include "resource/audiores.h"
|
||
#include "resource/audioresloader.h"
|
||
#include "resource/audioressaver.h"
|
||
#include "resource/physxmaterialres.h"
|
||
#include "resource/physxmaterialloader.h"
|
||
#include "resource/physxmaterialsaver.h"
|
||
#include "resource/materialres.h"
|
||
#include "resource/materialresloader.h"
|
||
#include "resource/materialressaver.h"
|
||
#include "resource/spritepackageres.h"
|
||
#include "resource/spritepackageresloader.h"
|
||
#include "resource/spritepackageressaver.h"
|
||
|
||
#include "timing/timer.h"
|
||
|
||
#include "foundation/io/ioserver.h"
|
||
#include "foundation/io/stream.h"
|
||
|
||
#include "io/iointerface.h"
|
||
#include "serialization/serializeserver.h"
|
||
#include "serialization/xmserialize.h"
|
||
#include "profilesystem/ProfileSystem.h"
|
||
|
||
#if __ANDROID__
|
||
#include "io/ioserver.h"
|
||
#include "io/memorystream.h"
|
||
#include "rendersystem/gles/OpenGLES.h"
|
||
#endif
|
||
|
||
|
||
namespace Resources{
|
||
|
||
__ImplementClass(Resources::ResourceServer,'RSSR', Core::RefCounted);
|
||
__ImplementClass(Resources::ResCodecReg, 'RCRG', Core::RefCounted);
|
||
__ImplementImageSingleton( ResourceServer );
|
||
// ÅжÏÍⲿûÓÐÒýÓõÄ×ÊÔ´£¬ÆäÒýÓüÆÊýÊÇ1 £¨ResourceServer::mResources £©
|
||
const int UnRefResCounter = 1;
|
||
//------------------------------------------------------------------------
|
||
ResourceServer::ResourceServer()
|
||
:mIsOpen(false)
|
||
{
|
||
__ConstructImageSingleton;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
ResourceServer::~ResourceServer()
|
||
{
|
||
n_assert(!mIsOpen);
|
||
|
||
__DestructImageSingleton;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ResourceServer::Open()
|
||
{
|
||
n_assert(!mIsOpen);
|
||
|
||
// may be need open resCodec in thread
|
||
SizeT numReg = mResReg.Size();
|
||
for ( IndexT indexReg = 0; indexReg < numReg; ++indexReg )
|
||
{
|
||
ResFilterRegistry& resFilterReg = mResReg.ValueAtIndex( indexReg );
|
||
SizeT numFilter = resFilterReg.Size();
|
||
for ( IndexT indexFilter = 0; indexFilter < numFilter; ++indexFilter )
|
||
{
|
||
LoadSaveRegistry& reg = resFilterReg.ValueAtIndex( indexFilter );
|
||
if ( reg.codecReg.isvalid() )
|
||
{
|
||
reg.codecReg->Open();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
mThreadInterface = ResourceInterface::Create();
|
||
mThreadInterface->Open();
|
||
|
||
mIsOpen = true;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ResourceServer::Close()
|
||
{
|
||
n_assert(mIsOpen);
|
||
|
||
mThreadInterface->Close();
|
||
mThreadInterface = NULL;
|
||
|
||
mAsynPrepareQueue.Clear();
|
||
mAsynReadQueue.Clear();
|
||
|
||
mResources.Clear();
|
||
|
||
// may be need close resCodec in thread
|
||
SizeT numReg = mResReg.Size();
|
||
for ( IndexT indexReg = 0; indexReg < numReg; ++indexReg )
|
||
{
|
||
ResFilterRegistry& resFilterReg = mResReg.ValueAtIndex( indexReg );
|
||
SizeT numFilter = resFilterReg.Size();
|
||
for ( IndexT indexFilter = 0; indexFilter < numFilter; ++indexFilter )
|
||
{
|
||
LoadSaveRegistry& reg = resFilterReg.ValueAtIndex( indexFilter );
|
||
if ( reg.codecReg.isvalid() )
|
||
{
|
||
reg.codecReg->Close();
|
||
}
|
||
}
|
||
}
|
||
|
||
mResReg.Clear();
|
||
|
||
mIsOpen = false;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ResourceServer::RegisterResourceType( const Core::Rtti* resType,
|
||
const Util::FourCC& typeFilter,
|
||
const Core::Rtti* loaderType,
|
||
const Core::Rtti* saverType,
|
||
const GPtr<ResCodecReg>& codecReg )
|
||
{
|
||
if( IsOpen() )
|
||
{
|
||
n_assert(false);
|
||
return;
|
||
}
|
||
|
||
if ( resType == NULL )
|
||
{
|
||
return;
|
||
}
|
||
|
||
IndexT resIndex = mResReg.FindIndex( resType );
|
||
if ( InvalidIndex == resIndex )
|
||
{
|
||
mResReg.Add( resType, ResFilterRegistry() );
|
||
resIndex = mResReg.FindIndex(resType );
|
||
}
|
||
n_assert( InvalidIndex != resIndex );
|
||
|
||
ResFilterRegistry& resFilterReg = mResReg.ValueAtIndex( resIndex );
|
||
|
||
IndexT filterIndex = resFilterReg.FindIndex( typeFilter );
|
||
if ( InvalidIndex == filterIndex )
|
||
{
|
||
resFilterReg.Add(typeFilter, LoadSaveRegistry() );
|
||
filterIndex = resFilterReg.FindIndex( typeFilter );
|
||
}
|
||
n_assert( InvalidIndex != filterIndex );
|
||
|
||
LoadSaveRegistry& lsReg = resFilterReg.ValueAtIndex( filterIndex );
|
||
lsReg.Loader = loaderType;
|
||
lsReg.Saver = saverType;
|
||
lsReg.codecReg = codecReg;
|
||
|
||
if ( lsReg.Loader && !lsReg.Loader->IsDerivedFrom(ResourceLoader::RTTI ) )
|
||
{
|
||
n_warning("ResourceServer::RegisterResourceType: %s is not resource Loader\n", lsReg.Loader->GetName().AsCharPtr() );
|
||
lsReg.Loader = NULL;
|
||
}
|
||
|
||
if ( lsReg.Saver && !lsReg.Saver->IsDerivedFrom(ResourceSaver::RTTI ) )
|
||
{
|
||
n_warning("ResourceServer::RegisterResourceType: %s is not resource Saver\n", lsReg.Saver->GetName().AsCharPtr() );
|
||
lsReg.Saver = NULL;
|
||
}
|
||
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ResourceServer::RegisterDefaultResouceTypes()
|
||
{
|
||
if ( IsOpen() )
|
||
{
|
||
n_assert(false);
|
||
return;
|
||
}
|
||
|
||
RegisterResourceType( &MeshRes::RTTI, 'CYWJ', &MeshResLoader::RTTI, &MeshResSaver::RTTI ) ;
|
||
RegisterResourceType( &SkeletonRes::RTTI, 'CYWJ', &SkeletonResLoader::RTTI, &SkeletonResSaver::RTTI );
|
||
RegisterResourceType( &AnimationRes::RTTI, 'CYWJ', &AnimationResLoader::RTTI, &AnimationResSaver::RTTI );
|
||
RegisterResourceType( &RawRes::RTTI, 'CYWJ', &RawResLoader::RTTI, &RawResSaver::RTTI );
|
||
RegisterResourceType( &TemplateRes::RTTI, 'CYWJ', &TemplateResLoader::RTTI, &TemplateResSaver::RTTI );
|
||
RegisterResourceType( &AudioRes::RTTI, 'CYWJ', &AudioResLoader::RTTI, &AudioResSaver::RTTI );
|
||
RegisterResourceType( &PhysXMaterialRes::RTTI, 'CYWJ', &PhysXMaterialLoader::RTTI, &PhysXMaterialSaver::RTTI );
|
||
RegisterResourceType( &MaterialRes::RTTI, 'CYWJ', &MaterialLoader::RTTI, &MaterialSaver::RTTI );
|
||
RegisterResourceType( &SpritePackageRes::RTTI, 'CYWJ', &SpritePackageResLoader::RTTI, &SpritePackageResSaver::RTTI );
|
||
|
||
if ( !ImageResCodecReg::HasInstance() )
|
||
{
|
||
ImageResCodecReg::Create();
|
||
}
|
||
GPtr<ImageResCodecReg> imageCode = ImageResCodecReg::Instance();
|
||
RegisterResourceType( &ImageRes::RTTI, 'CYWJ', &ImageResLoader::RTTI, NULL, imageCode.upcast<ResCodecReg>() ) ;
|
||
|
||
|
||
// RegisterResourceType( , , , );
|
||
}
|
||
//------------------------------------------------------------------------
|
||
GPtr<Resource>
|
||
ResourceServer::CreateOrGetResource( const ResourceId& resID, const Core::Rtti* ResType )
|
||
{
|
||
n_assert(mIsOpen);
|
||
|
||
IndexT resFind = mResources.FindIndex( resID );
|
||
if ( InvalidIndex != resFind )
|
||
{
|
||
// exist
|
||
return mResources.ValueAtIndex( resFind );
|
||
}
|
||
else
|
||
{
|
||
if ( ResType == NULL || !ResType->IsDerivedFrom( Resource::RTTI ) )
|
||
{
|
||
return GPtr<Resource>(0);
|
||
}
|
||
else
|
||
{
|
||
GPtr<Core::RefCounted> pObject = ResType->Create();
|
||
n_assert( pObject.isvalid() );
|
||
GPtr<Resource> pRes = pObject.downcast<Resource>();
|
||
n_assert( pRes.isvalid() );
|
||
pRes->SetResourceId( resID );
|
||
mResources.Add(resID, pRes );
|
||
|
||
return pRes;
|
||
}
|
||
}
|
||
return GPtr<Resource>(0);
|
||
}
|
||
////------------------------------------------------------------------------
|
||
bool
|
||
ResourceServer::LoadResource( const GPtr<Resource>& res,
|
||
bool bAsyn /*= true*/,
|
||
const Util::FourCC& typeFilter /*= 'CYWJ'*/,
|
||
const Core::Rtti* manuLoaderType /*= NULL*/ )
|
||
{
|
||
n_assert(mIsOpen);
|
||
|
||
if( !res.isvalid() )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
// ²»Ö§³ÖÖؼÓÔØ£¬ÐèÒªÏÈUnLoad
|
||
if ( res->GetState() == Resource::Loaded )
|
||
{
|
||
return true;
|
||
}
|
||
if ( res->GetState() == Resource::Failed )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
GPtr<ResourceLoader> resLoader;
|
||
const Core::Rtti* loaderType = _ConstructLoaderOrSaverType(manuLoaderType, res->GetRtti(), typeFilter, true );
|
||
if ( !loaderType )
|
||
{
|
||
n_warning("ResourceServer::LoadResource %s: Can Not Get Loader\n", res->GetResourceId().AsString().AsCharPtr() );
|
||
res->SetState(Resource::Failed);
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
GPtr<Core::RefCounted> pObject = loaderType->Create();
|
||
n_assert( pObject.isvalid() );
|
||
resLoader = pObject.downcast<ResourceLoader>();
|
||
}
|
||
n_assert( resLoader.isvalid() );
|
||
|
||
// Òì²½¼ÓÔØ£¬Í¨¹ýÖ÷Ï߳̽øÐÐ
|
||
if ( bAsyn )
|
||
{
|
||
return _AsynPrepare(res, res->GetResourceId(), resLoader);//resURI
|
||
}
|
||
else
|
||
{
|
||
return _SynLoad(res, res->GetResourceId(), resLoader);//resURI
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool
|
||
ResourceServer::_SynLoad(const GPtr<Resource>& res, const ResourceId& resURI, const GPtr<ResourceLoader>& resLoader)
|
||
{
|
||
bool bLoadOK = false;
|
||
#ifdef __PROFILER_IO__
|
||
Util::String strResType;
|
||
strResType.Format("resID:%s",resURI.AsString().Get());
|
||
|
||
//begint tick
|
||
PROFILER_IO_TICKBEGIN(tickBegin);
|
||
PROFILER_IO_LOGTIMES("begin, %s",strResType.Get());
|
||
#endif
|
||
GPtr<IO::Stream> pStream;
|
||
|
||
#ifdef __GENESIS_EDITOR__
|
||
try
|
||
{
|
||
pStream = IO::IoServer::Instance()->ReadFileFromFileSystem(resURI);
|
||
}
|
||
catch(const Exceptions::MemoryException& )
|
||
{
|
||
n_warning("Resource is too large, lack of memory!\n");
|
||
|
||
IO::IoServer::Instance()->GetIOReadStream()->Close();
|
||
res->SetState(Resource::Failed);
|
||
return false;
|
||
}
|
||
#else
|
||
pStream = IO::IoServer::Instance()->ReadFileFromFileSystem(resURI);
|
||
#endif
|
||
|
||
if ( pStream )
|
||
{
|
||
pStream->SetAccessMode(IO::Stream::ReadAccess);
|
||
if ( pStream->Open() )
|
||
{
|
||
resLoader->SetStream(pStream);
|
||
res->SetAsynLoading(false);
|
||
bLoadOK = res->Load( resLoader );
|
||
if ( !bLoadOK )
|
||
{
|
||
res->SetState(Resource::Failed);
|
||
n_warning("SynLoad Load Resource %s Failed. Not Read From Stream \n", resURI.AsString().AsCharPtr());
|
||
}
|
||
else
|
||
{
|
||
n_printf("SynLoad Load Resource %s OK \n", resURI.AsString().AsCharPtr());
|
||
}
|
||
|
||
pStream->Close();
|
||
}
|
||
else
|
||
{
|
||
res->SetState(Resource::Failed);
|
||
n_warning("Syn Load Resource %s Failed. Not Open Stream \n", resURI.AsString().AsCharPtr());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
res->SetState(Resource::Failed);
|
||
n_warning("Syn Load Resource %s Failed. Can Not Create Stream \n", resURI.AsString().AsCharPtr());
|
||
}
|
||
|
||
#ifdef __PROFILER_IO__
|
||
//end tick
|
||
PROFILER_IO_TICKEND(tickBegin,delta);
|
||
PROFILER_IO_LOGTIMES2("end,%s,time consume: %f ms",strResType.Get(),__tick_delta_delta/1000.f);
|
||
if ( res->GetRtti() == &ImageRes::RTTI )
|
||
{
|
||
PROFILER_IO_READ_RES(mIoReadTexture,delta);
|
||
}
|
||
else
|
||
{
|
||
|
||
}
|
||
|
||
#endif
|
||
return bLoadOK;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool ResourceServer::_AsynPrepare(const GPtr<Resource>& res, const ResourceId& resURI, const GPtr<ResourceLoader>& resLoader)
|
||
{
|
||
// res ÒѾÔÚÒì²½¼ÓÔØÖС£ Éú³ÉÒ»¸öÐé¼ÙµÄ´æ¸ù¡£±ÜÃâ¶à´Î¼ÓÔØ
|
||
if ( res->IsAsynProcessing() )
|
||
{
|
||
return true;
|
||
}
|
||
|
||
// Òì²½¼ÓÔØ. ÏȽøÐÐÍⲿÉ豸µÄIO
|
||
// ±£´æ´æ¸ù
|
||
PrepareStub stub;
|
||
stub.res = res; // Real Res . not Temp Res
|
||
stub.msg_stream = IO::ReadStream::Create();
|
||
stub.loader = resLoader;
|
||
|
||
n_assert( stub.msg_stream.isvalid() );
|
||
stub.msg_stream->SetFileName( resURI );
|
||
stub.msg_stream->SetStream( IO::MemoryStream::Create() );
|
||
IO::IoInterface::Instance()->Send( stub.msg_stream );
|
||
res->SetAsynLoading(true);
|
||
// Ôö¼Ó×ÊÔ´µÄÒì²½·ÃÎʼÆÊý
|
||
res->AddAsynProcessingIndex();
|
||
|
||
mAsynPrepareQueue.AddBack(stub);
|
||
|
||
return true;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool
|
||
ResourceServer::SaveResource( const GPtr<Resource>& res,
|
||
const IO::URI& uri /*= IO::URI()*/,
|
||
const Util::FourCC& typeFilter /*= 'CYWJ'*/,
|
||
const Core::Rtti* manuSaverType /*= NULL*/ )
|
||
{
|
||
n_assert(mIsOpen);
|
||
|
||
if( !res.isvalid() )
|
||
{
|
||
n_warning("ResourceServer::SaveResource: res = null\n");
|
||
return false;
|
||
}
|
||
|
||
// get uri
|
||
IO::URI resURI = _ConstructURI(uri, res->GetResourceId());
|
||
if ( resURI.IsEmpty() )
|
||
{
|
||
n_warning("ResourceServer::SaveResource: Can Not Get URI\n");
|
||
return false;
|
||
}
|
||
|
||
// Get Saver
|
||
GPtr<ResourceSaver> resSaver;
|
||
const Core::Rtti* saverType = _ConstructLoaderOrSaverType(manuSaverType, res->GetRtti(), typeFilter, false );
|
||
if ( !saverType )
|
||
{
|
||
n_warning("ResourceServer::SaveResource %s: Can Not Get Saver\n", res->GetResourceId().AsString().AsCharPtr() );
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
GPtr<Core::RefCounted> pObject = saverType->Create();
|
||
n_assert( pObject.isvalid() );
|
||
resSaver = pObject.downcast<ResourceSaver>();
|
||
}
|
||
n_assert( resSaver.isvalid() );
|
||
|
||
// °²È«µÄдÈë·½·¨ÊÇÔÚÐòÁл¯Ïß³ÌÐòÁл¯µ½Äڴ棬Ȼºó´ÓIOÏß³Ìд³öµ½Ó²ÅÌ¡£
|
||
// ÐòÁл¯µ½ÄÚ´æ
|
||
GPtr<ResSaveMsg> msg_save = ResSaveMsg::Create();
|
||
msg_save->SetResource( res );
|
||
msg_save->SetSaver( resSaver );
|
||
msg_save->SetSream( IO::MemoryStream::Create() );
|
||
msg_save->GetStream()->SetURI(uri);
|
||
mThreadInterface->SendWait( msg_save );
|
||
if ( !msg_save->GetResult() )
|
||
{
|
||
return false;
|
||
}
|
||
return true;
|
||
|
||
//// д³öµ½Ó²ÅÌ
|
||
//GPtr<IO::WriteStream> io_msg = IO::WriteStream::Create();
|
||
//io_msg->SetStream( msg_save->GetStream() );
|
||
//io_msg->SetURI(uri);
|
||
//IO::IoInterface::Instance()->SendWait(io_msg);
|
||
|
||
//return io_msg->GetResult();
|
||
}
|
||
//------------------------------------------------------------------------
|
||
const Timing::Tick Max_Tick_One_Frame = 5; // ÿ֡ÔÊÐíµÄ×î´ótickʱ¼ä£¨ºÁÃ룩
|
||
void
|
||
ResourceServer::Flush(void)
|
||
{
|
||
// ʱ¼ä¿ØÖÆ£¬±ÜÃâflushµÄʱ¼äÌ«³¤£¬Ó°ÏìЧÂÊ
|
||
Timing::Timer t;
|
||
t.Start();
|
||
|
||
// ÓÅÏȽøÐз´ÐòÁл¯µÄ¹¤×÷
|
||
_FlushReadList(t, Max_Tick_One_Frame);
|
||
|
||
t.Reset();
|
||
_FlushPrepareList(t, Max_Tick_One_Frame);
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ResourceServer::_FlushReadList(const Timing::Timer& t, Timing::Tick max_tick)
|
||
{
|
||
ReadStubList::Iterator endItor = mAsynReadQueue.End();
|
||
for ( ReadStubList::Iterator itor = mAsynReadQueue.Begin(); itor != endItor; )
|
||
{
|
||
/*Timing::Tick tick = t.GetTicks();
|
||
if ( tick > Max_Tick_One_Frame)
|
||
{
|
||
return;
|
||
}*/
|
||
|
||
bool isRead = false;
|
||
|
||
// ×ÊÔ´µÄ״̬²»ÊÇUnload »òÕßÐé¼Ù´æ¸ù , ˵Ã÷ÔÚÖ÷Ï̼߳ÓÔعýÁË¡£²»½øÐÐÖظ´¼ÓÔØ
|
||
if( itor->res->GetState() != Resource::UnLoaded )
|
||
{
|
||
isRead = true;
|
||
}
|
||
|
||
if ( itor->msg_loader && itor->msg_loader->Handled() )
|
||
{
|
||
isRead = true;
|
||
if ( itor->msg_loader->GetResult() )
|
||
{
|
||
if( itor->res->SwapLoad( itor->msg_loader->GetResource() ) )
|
||
{
|
||
n_printf("Asyn Load Resource %s OK \n", itor->res->GetResourceId().AsString().AsCharPtr() );
|
||
}
|
||
else
|
||
{
|
||
n_warning("Asyn Load Resource %s Failed. Swap Load Failed \n", itor->res->GetResourceId().AsString().AsCharPtr() );
|
||
itor->res->SetState( Resource::Failed );
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
n_warning("Asyn Load Resource %s Failed. Not Read From Stream \n", itor->res->GetResourceId().AsString().AsCharPtr() );
|
||
itor->res->SetState( Resource::Failed );
|
||
}
|
||
}
|
||
|
||
if ( isRead )
|
||
{
|
||
// ¼õÉÙ×ÊÔ´µÄÒì²½·ÃÎʼÆÊý
|
||
itor->res->DecAsynProcessingIndex();
|
||
|
||
// ÒƳý´æ¸ù
|
||
ReadStubList::Iterator Removeitor = itor;
|
||
++itor;
|
||
mAsynReadQueue.Remove( Removeitor );
|
||
}
|
||
else
|
||
{
|
||
++itor;
|
||
}
|
||
}
|
||
}
|
||
void
|
||
ResourceServer::_FlushPrepareList(const Timing::Timer& t, Timing::Tick max_tick)
|
||
{
|
||
PrepareStubbList::Iterator endItor = mAsynPrepareQueue.End();
|
||
for ( PrepareStubbList::Iterator itor = mAsynPrepareQueue.Begin(); itor != endItor; )
|
||
{
|
||
Timing::Tick tick = t.GetTicks();
|
||
if ( tick > Max_Tick_One_Frame)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if ( itor->msg_stream->Handled() )
|
||
{
|
||
if ( itor->msg_stream->GetResult() )
|
||
{
|
||
// ¹¹ÔìÒ»¸ö´æ¸ù£¬½øÐз´ÐòÁл¯µÄ²Ù×÷
|
||
GPtr<ResLoadMsg> msg = ResLoadMsg::Create();
|
||
msg->SetLoader( itor->loader );
|
||
msg->SetSream( itor->msg_stream->GetStream() );
|
||
|
||
// ´´½¨Ò»¸öÁÙʱµÄ×ÊÔ´
|
||
GPtr<RefCounted> pTempResObject = itor->res->GetRtti()->Create();
|
||
n_assert( pTempResObject.isvalid() );
|
||
GPtr<Resource> pTempResData = pTempResObject.downcast<Resource>();
|
||
pTempResData->InitLoadParam( itor->res );
|
||
msg->SetResource( pTempResData ); // read to Temp Res
|
||
|
||
//±£´æ´æ¸ù
|
||
ReadStub stub;
|
||
stub.res = itor->res;
|
||
stub.msg_loader = msg;
|
||
mAsynReadQueue.AddBack(stub);
|
||
mThreadInterface->Send( msg );
|
||
}
|
||
else
|
||
{
|
||
n_warning("Asyn Load Resource %s Failed. Can Not Handle Stream!\n", itor->res->GetResourceId().AsString().AsCharPtr());
|
||
|
||
itor->res->SetState( Resource::Failed );
|
||
}
|
||
|
||
|
||
// ÒƳý´æ¸ù
|
||
PrepareStubbList::Iterator Removeitor = itor;
|
||
++itor;
|
||
mAsynPrepareQueue.Remove( Removeitor );
|
||
}
|
||
else
|
||
{
|
||
++itor;
|
||
}
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ResourceServer::UnLoadUnreferencedResources(void)
|
||
{
|
||
SizeT size = mResources.Size();
|
||
for ( IndexT index = 0; index < size; ++index )
|
||
{
|
||
const GPtr<Resource> res = mResources.ValueAtIndex( index );
|
||
if ( res->GetRefCount() <= UnRefResCounter && !res->IsManuLoad())
|
||
{
|
||
mResources.ValueAtIndex(index)->UnLoad();
|
||
}
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void
|
||
ResourceServer::DicardUnreferencedResources()
|
||
{
|
||
ResMap useRes;
|
||
useRes.Reserve( mResources.Size() );
|
||
|
||
useRes.BeginBulkAdd();
|
||
SizeT size = mResources.Size();
|
||
for ( IndexT index = 0; index < size; ++index )
|
||
{
|
||
if ( mResources.ValueAtIndex(index)->GetRefCount() > UnRefResCounter )
|
||
{
|
||
//»¹ÔÚʹÓõÄ×ÊÔ´
|
||
useRes.Add( mResources.KeyValuePairAtIndex(index) );
|
||
}
|
||
}
|
||
useRes.EndBulkAdd();
|
||
|
||
mResources.Swap(useRes);
|
||
}
|
||
//------------------------------------------------------------------------
|
||
IO::URI
|
||
ResourceServer::_ConstructURI( const IO::URI& defaultUri,
|
||
const ResourceId& resID )
|
||
{
|
||
IO::URI resURI = defaultUri;
|
||
|
||
if ( defaultUri.IsEmpty() )
|
||
{
|
||
if ( resID.IsValid() )
|
||
{
|
||
resURI.Set( resID.AsString() );
|
||
}
|
||
}
|
||
|
||
return resURI;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
const Core::Rtti*
|
||
ResourceServer::_ConstructLoaderOrSaverType( const Core::Rtti* defaultType,
|
||
const Core::Rtti* resType,
|
||
const Util::FourCC& typeFilter,
|
||
bool bloader )
|
||
{
|
||
const Core::Rtti* lsType = NULL;
|
||
|
||
if ( !defaultType )
|
||
{
|
||
// from registry, loader must be null or valid loaderk
|
||
IndexT resTypeFind = mResReg.FindIndex( resType );
|
||
if ( resTypeFind != InvalidIndex )
|
||
{
|
||
ResFilterRegistry& resFilterReg = mResReg.ValueAtIndex(resTypeFind);
|
||
IndexT resFilterFInd = resFilterReg.FindIndex( typeFilter );
|
||
if ( resFilterFInd != InvalidIndex )
|
||
{
|
||
LoadSaveRegistry& lsReg = resFilterReg.ValueAtIndex( resFilterFInd );
|
||
if ( bloader )
|
||
{
|
||
lsType = lsReg.Loader;
|
||
}
|
||
else
|
||
{
|
||
lsType = lsReg.Saver;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( bloader )
|
||
{
|
||
if ( !defaultType->IsDerivedFrom( ResourceLoader::RTTI ) )
|
||
{
|
||
lsType = NULL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( !defaultType->IsDerivedFrom( ResourceSaver::RTTI ) )
|
||
{
|
||
lsType = NULL;
|
||
}
|
||
}
|
||
}
|
||
|
||
return lsType;
|
||
}
|
||
|
||
|
||
|
||
} |