00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "ResourceLoader.h"
00018 #include "Log.h"
00019 #include "Exception.h"
00020 #include "Engine.h"
00021 #include "ResourceManager.h"
00022
00023 namespace nrEngine{
00024
00025
00026 IResourceLoader::IResourceLoader(const std::string& name) : mName(name)
00027 {
00028
00029 }
00030
00031
00032 IResourceLoader::~IResourceLoader()
00033 {
00034
00035 std::vector<SharedPtr<IResource> > lst;
00036 for (ResourceList::iterator it = mHandledResources.begin(); it != mHandledResources.end(); it ++)
00037 lst.push_back(*it);
00038
00039
00040 for (uint32 i=0; i < lst.size(); i++)
00041 remove(lst[i]);
00042 }
00043
00044
00045 SharedPtr<IResource> IResourceLoader::load(const std::string& name, const std::string& group, const std::string& fileName, const std::string& resourceType, PropertyList* param)
00046 {
00047
00048 if (Engine::sResourceManager()->isResourceRegistered(name))
00049 {
00050 NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader: You are trying to load resource %s which is already loaded.", name.c_str());
00051 return SharedPtr<IResource>();
00052 }
00053
00054 bool typeFound = false;
00055 std::string type;
00056 std::string newFileName = fileName;
00057
00058
00059 if (resourceType.length() == 0)
00060 {
00061 NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceLoader \"%s\" try to find according resource type by filename \"%s\"", mName.c_str(), fileName.c_str(), fileName.c_str());
00062
00063
00064 for (int32 i = fileName.length()-1; i >= 0 && !typeFound; i--){
00065 if ((char)fileName[i] == '.'){
00066 typeFound = true;
00067 }
00068 if (!typeFound) type = (char)fileName[i] + type;
00069 }
00070 if (!typeFound) type = "";
00071
00072
00073 if (typeFound && !supportFileType(type))
00074 {
00075 NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader \"%s\" can not load file of type \".%s\", because the type is not supported", mName.c_str(), type.c_str());
00076 return SharedPtr<IResource>();
00077 }
00078
00079 #if 0
00080
00081 if (!typeFound && resourceType.length() > 0)
00082 {
00083 type = getSuffix(resourceType);
00084 if (type.length() > 0)
00085 {
00086 typeFound = true;
00087 newFileName = fileName + std::string(".") + type;
00088 }
00089 }
00090 #endif
00091
00092
00093 if (!typeFound)
00094 {
00095 NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader %s: neither resource type nor valid file ending was found, give up!", mName.c_str());
00096 return SharedPtr<IResource>();
00097 }
00098 }
00099
00100
00101 SharedPtr<IResource> res;
00102 if (resourceType.length() == 0){
00103 res = create(mapFileTypeToResourceType(type), param);
00104 }else{
00105 res = create(resourceType, param);
00106 }
00107 if (res.get() == NULL) return res;
00108
00109
00110 res->addResourceFilename(newFileName);
00111 res->mResName = name;
00112 res->mResGroup = group;
00113
00114
00115 if (loadResource(res.get(), newFileName, param) != OK)
00116 {
00117 NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader %s can not load resource from file %s", mName.c_str(), newFileName.c_str());
00118 remove(res);
00119 return SharedPtr<IResource>();
00120 }
00121 res->mResIsLoaded = true;
00122
00123
00124 Engine::sResourceManager()->notifyLoaded(res.get());
00125
00126 return res;
00127 }
00128
00129
00130 SharedPtr<IResource> IResourceLoader::create(const std::string& resourceType, PropertyList* params)
00131 {
00132 NR_Log(Log::LOG_ENGINE, Log::LL_DEBUG, "ResourceLoader: Create resource of type %s", resourceType.c_str());
00133
00134
00135 if (!supportResourceType(resourceType))
00136 {
00137 NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader %s does not support resources of type %s", mName.c_str(), resourceType.c_str());
00138 return SharedPtr<IResource>();
00139 }
00140
00141
00142 SharedPtr<IResource> res (createResource(resourceType, params), IResource::_deleter());
00143
00144
00145 if (res.get() == NULL) return SharedPtr<IResource>();
00146
00147
00148 SharedPtr<IResource> empty = Engine::sResourceManager()->getEmpty(resourceType);
00149
00150
00151 if (empty == NULL)
00152 {
00153
00154 empty.reset( createEmptyResource(resourceType), IResource::_deleter() );
00155 empty->mResGroup = "_Empty_Resource_Group_";
00156 empty->mResName = "_Empty_" + resourceType;
00157 empty->mResHandle = Engine::sResourceManager()->getNewHandle();
00158 empty->mResIsEmpty = true;
00159 empty->mResLoader = getSharedPtrFromThis();
00160 empty->setResourceType(resourceType);
00161
00162
00163 Engine::sResourceManager()->setEmpty(resourceType, empty);
00164 }
00165
00166
00167 res->setResourceType(resourceType);
00168 res->mResHandle = Engine::sResourceManager()->getNewHandle();
00169 res->mResIsEmpty = false;
00170 res->mResLoader = getSharedPtrFromThis();
00171
00172
00173 mHandledResources.push_back(res);
00174
00175
00176 return res;
00177 }
00178
00179
00180 SharedPtr<IResource> IResourceLoader::create(const std::string& name, const std::string& group, const std::string& resourceType, PropertyList* params)
00181 {
00182
00183 if (!supportResourceType(resourceType))
00184 {
00185 NR_Log(Log::LOG_ENGINE, Log::LL_ERROR, "ResourceLoader %s does not support resources of type %s", mName.c_str(), resourceType.c_str());
00186 return SharedPtr<IResource>();
00187 }
00188
00189
00190 IResourcePtr res = Engine::sResourceManager()->getByName(name);
00191 if (!res.isNull()){
00192 NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "You are trying to create a resource %s of type %s which is already in the database", name.c_str(), resourceType.c_str());
00193 return SharedPtr<IResource>();
00194 }
00195
00196
00197 SharedPtr<IResource> r = create(resourceType, params);
00198 if (r.get() == NULL) return SharedPtr<IResource>();
00199
00200
00201 r->mResName = name;
00202 r->mResGroup = group;
00203
00204
00205 Engine::sResourceManager()->notifyCreated(r.get());
00206
00207 return r;
00208 }
00209 #if 0
00210
00211 Result IResourceLoader::unload(SharedPtr<IResource> resource)
00212 {
00213
00214 if (resource.get() == NULL) return OK;
00215
00216
00217 if (resource->mResIsLoaded){
00218
00219 Result ret = unloadResourceImpl(resource.get());
00220 if (ret != OK) return ret;
00221
00222
00223 resource->mResIsLoaded = false;
00224
00225
00226 Engine::sResourceManager()->notifyUnloaded(resource.get());
00227 }
00228
00229 return OK;
00230 }
00231
00232
00233 Result IResourceLoader::reload(SharedPtr<IResource> resource)
00234 {
00235
00236 if (std::find(mHandledResources.begin(), mHandledResources.end(), resource) == mHandledResources.end()){
00237 NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceLoader: You are trying to reload resource %s not handled by this loader %s", resource->getResName().c_str(), mName.c_str());
00238 return OK;
00239 }
00240
00241
00242 unload(resource);
00243
00244
00245 if (resource->mResIsLoaded == false)
00246 {
00247
00248 Result ret = reloadResourceImpl(resource.get());
00249 if (ret != OK) return ret;
00250
00251
00252 resource->mResIsLoaded = true;
00253
00254
00255 Engine::sResourceManager()->notifyLoaded(resource.get());
00256 }
00257
00258 return OK;
00259 }
00260 #endif
00261
00262 Result IResourceLoader::remove(SharedPtr<IResource> resource)
00263 {
00264
00265 if (resource.get() == NULL) return OK;
00266
00267
00268 if (std::find(mHandledResources.begin(), mHandledResources.end(), resource) == mHandledResources.end())
00269 {
00270 NR_Log(Log::LOG_ENGINE, Log::LL_WARNING, "ResourceLoader: You are trying to remove resource %s not handled by this loader %s!", resource->getResourceName().c_str(), mName.c_str());
00271 return OK;
00272 }
00273
00274
00275 resource->unload();
00276
00277
00278 notifyRemoveResource(resource);
00279
00280
00281 resource.reset();
00282
00283 return OK;
00284 }
00285
00286
00287 void IResourceLoader::notifyRemoveResource(SharedPtr<IResource> res)
00288 {
00289 ResourceList::iterator resit = std::find(mHandledResources.begin(), mHandledResources.end(), res);
00290
00291
00292 if (resit != mHandledResources.end() )
00293 {
00294
00295 mHandledResources.erase(resit);
00296
00297
00298 Engine::sResourceManager()->notifyRemove(res.get());
00299 }
00300 }
00301
00302 #if 0
00303
00304
00305 void IResourceLoader::notifyUnloadResource(SharedPtr<IResource> res)
00306 {
00307 if (res == NULL) return;
00308 if (std::find(mHandledResources.begin(), mHandledResources.end(), res) != mHandledResources.end() && res->mResIsLoaded){
00309 Engine::sResourceManager()->notifyUnloaded(res.get());
00310 }
00311 }
00312
00313
00314 Result IResourceLoader::unloadResourceImpl(IResource* res)
00315 {
00316 if (res == NULL) return OK;
00317 if (res->mResIsLoaded) return res->unloadRes();
00318 return OK;
00319 }
00320
00321
00322 Result IResourceLoader::reloadResourceImpl(IResource* res)
00323 {
00324 if (res == NULL) return OK;
00325
00326
00327
00328
00329
00330 if (res->mResIsLoaded == false) res->reloadRes();
00331
00332
00333
00334
00335
00336 return OK;
00337 }
00338 #endif
00339
00340 bool IResourceLoader::supportResourceType(const std::string& resourceType) const {
00341 std::vector<std::string>::const_iterator it;
00342 for (it = mSupportedResourceTypes.begin(); it != mSupportedResourceTypes.end(); it++){
00343 if ((*it) == resourceType) return true;
00344 }
00345 return false;
00346 }
00347
00348
00349 bool IResourceLoader::supportFileType(const std::string& fileType) const {
00350 std::vector<std::string>::const_iterator it;
00351 for (it = mSupportedFileTypes.begin(); it != mSupportedFileTypes.end(); it++){
00352 if ((*it) == fileType) {
00353 return true;
00354 }
00355 }
00356 return false;
00357 }
00358
00359 };
00360