Browse Source

Minor enhancement on getting optional resources and error handling.

Yao Wei Tjong 姚伟忠 12 years ago
parent
commit
ffe7a7699f

+ 1 - 4
Source/Engine/Audio/Sound.cpp

@@ -376,10 +376,7 @@ void Sound::LoadParameters()
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     String xmlName = ReplaceExtension(GetName(), ".xml");
     
-    if (!cache->Exists(xmlName))
-        return;
-    
-    XMLFile* file = cache->GetResource<XMLFile>(xmlName);
+    XMLFile* file = cache->GetResource<XMLFile>(xmlName, false);
     if (!file)
         return;
     

+ 12 - 15
Source/Engine/Graphics/Animation.cpp

@@ -126,25 +126,22 @@ bool Animation::Load(Deserializer& source)
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     String xmlName = ReplaceExtension(GetName(), ".xml");
     
-    if (cache->Exists(xmlName))
+    XMLFile* file = cache->GetResource<XMLFile>(xmlName, false);
+    if (file)
     {
-        XMLFile* file = cache->GetResource<XMLFile>(xmlName);
-        if (file)
+        XMLElement rootElem = file->GetRoot();
+        XMLElement triggerElem = rootElem.GetChild("trigger");
+        while (triggerElem)
         {
-            XMLElement rootElem = file->GetRoot();
-            XMLElement triggerElem = rootElem.GetChild("trigger");
-            while (triggerElem)
-            {
-                if (triggerElem.HasAttribute("normalizedtime"))
-                    AddTrigger(triggerElem.GetFloat("normalizedtime"), true, triggerElem.GetVariant());
-                else if (triggerElem.HasAttribute("time"))
-                    AddTrigger(triggerElem.GetFloat("time"), false, triggerElem.GetVariant());
-                
-                triggerElem = triggerElem.GetNext("trigger");
-            }
+            if (triggerElem.HasAttribute("normalizedtime"))
+                AddTrigger(triggerElem.GetFloat("normalizedtime"), true, triggerElem.GetVariant());
+            else if (triggerElem.HasAttribute("time"))
+                AddTrigger(triggerElem.GetFloat("time"), false, triggerElem.GetVariant());
             
-            memoryUse += triggers_.Size() * sizeof(AnimationTriggerPoint);
+            triggerElem = triggerElem.GetNext("trigger");
         }
+
+        memoryUse += triggers_.Size() * sizeof(AnimationTriggerPoint);
     }
     
     SetMemoryUse(memoryUse);

+ 2 - 4
Source/Engine/Graphics/Direct3D9/D3D9Texture.cpp

@@ -239,11 +239,9 @@ void Texture::LoadParameters()
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     String xmlName = ReplaceExtension(GetName(), ".xml");
     
-    if (cache->Exists(xmlName))
-    {
-        XMLFile* file = cache->GetResource<XMLFile>(xmlName);
+    XMLFile* file = cache->GetResource<XMLFile>(xmlName, false);
+    if (file)
         LoadParameters(file);
-    }
 }
 
 void Texture::LoadParameters(XMLFile* file)

+ 2 - 4
Source/Engine/Graphics/OpenGL/OGLTexture.cpp

@@ -398,11 +398,9 @@ void Texture::LoadParameters()
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     String xmlName = ReplaceExtension(GetName(), ".xml");
     
-    if (cache->Exists(xmlName))
-    {
-        XMLFile* file = cache->GetResource<XMLFile>(xmlName);
+    XMLFile* file = cache->GetResource<XMLFile>(xmlName, false);
+    if (file)
         LoadParameters(file);
-    }
 }
 
 void Texture::LoadParameters(XMLFile* file)

+ 1 - 3
Source/Engine/Graphics/StaticModel.cpp

@@ -307,9 +307,7 @@ void StaticModel::ApplyMaterialList(const String& fileName)
         useFileName = ReplaceExtension(model_->GetName(), ".txt");
     
     ResourceCache* cache = GetSubsystem<ResourceCache>();
-    if (!cache->Exists(useFileName))
-        return;
-    SharedPtr<File> file = cache->GetFile(useFileName);
+    SharedPtr<File> file = cache->GetFile(useFileName, false);
     if (!file)
         return;
     

+ 5 - 8
Source/Engine/LuaScript/LuaScript.cpp

@@ -259,16 +259,13 @@ int LuaScript::Loader(lua_State* L)
     // Get module name
     const char* name = luaL_checkstring(L, 1);
 
-    // Try get .luc file. Use Exists() check here to avoid log error in case only the .lua file exists
+    // Attempt to get .luc file first.
     String lucFileName = String(name) + ".luc";
-    if (cache->Exists(lucFileName))
-    {
-        LuaFile* lucFile = cache->GetResource<LuaFile>(lucFileName);
-        if (lucFile)
-            return lucFile->LoadChunk(L) ? 1 : 0;
-    }
+    LuaFile* lucFile = cache->GetResource<LuaFile>(lucFileName, false);
+    if (lucFile)
+        return lucFile->LoadChunk(L) ? 1 : 0;
 
-    // Try get .lua file. If this also fails, error is logged
+    // Then try to get .lua file. If this also fails, error is logged and resource not found event is sent
     String luaFileName = String(name) + ".lua";
     LuaFile* luaFile = cache->GetResource<LuaFile>(luaFileName);
     if (luaFile)

+ 6 - 4
Source/Engine/LuaScript/pkgs/Resource/ResourceCache.pkg

@@ -14,7 +14,7 @@ class ResourceCache
     // SharedPtr<File> GetFile(const String& name);
     tolua_outside File* ResourceCacheGetFile @ GetFile(const String name);
 
-    Resource* GetResource(const String type, const String name);
+    Resource* GetResource(const String type, const String name, bool SendEventOnFailure = true);
     
     bool Exists(const String name) const;
     unsigned GetMemoryBudget(ShortStringHash type) const;
@@ -70,7 +70,8 @@ static int tolua_ResourceLuaAPI_ResourceCache_GetResource00(lua_State* tolua_S)
  !tolua_isusertype(tolua_S,1,"ResourceCache",0,&tolua_err) ||
  !tolua_isurho3dstring(tolua_S,2,0,&tolua_err) ||
  !tolua_isurho3dstring(tolua_S,3,0,&tolua_err) ||
- !tolua_isnoobj(tolua_S,4,&tolua_err)
+ !tolua_isboolean(tolua_S,4,1,&tolua_err) ||
+ !tolua_isnoobj(tolua_S,5,&tolua_err)
  )
  goto tolua_lerror;
  else
@@ -79,11 +80,12 @@ static int tolua_ResourceLuaAPI_ResourceCache_GetResource00(lua_State* tolua_S)
   ResourceCache* self = (ResourceCache*)  tolua_tousertype(tolua_S,1,0);
   const String type = ((const String)  tolua_tourho3dstring(tolua_S,2,0));
   const String name = ((const String)  tolua_tourho3dstring(tolua_S,3,0));
+  bool SendEventOnFailure = ((bool)  tolua_toboolean(tolua_S,4,true));
 #ifndef TOLUA_RELEASE
  if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetResource'", NULL);
 #endif
  {
-  Resource* tolua_ret = (Resource*)  self->GetResource(type,name);
+  Resource* tolua_ret = (Resource*)  self->GetResource(type,name,SendEventOnFailure);
   tolua_pushusertype(tolua_S,(void*)tolua_ret,type.CString());
  }
  }
@@ -94,4 +96,4 @@ static int tolua_ResourceLuaAPI_ResourceCache_GetResource00(lua_State* tolua_S)
  return 0;
 #endif
 }
-$}
+$}

+ 24 - 9
Source/Engine/Resource/ResourceCache.cpp

@@ -383,7 +383,7 @@ void ResourceCache::SetAutoReloadResources(bool enable)
     }
 }
 
-SharedPtr<File> ResourceCache::GetFile(const String& nameIn)
+SharedPtr<File> ResourceCache::GetFile(const String& nameIn, bool SendEventOnFailure)
 {
     String name = SanitateResourceName(nameIn);
     File* file = 0;
@@ -403,17 +403,27 @@ SharedPtr<File> ResourceCache::GetFile(const String& nameIn)
     
     if (file)
         return SharedPtr<File>(file);
-    
-    LOGERROR("Could not find resource " + name);
+
+    if (SendEventOnFailure)
+    {
+        LOGERROR("Could not find resource " + name);
+
+        using namespace ResourceNotFound;
+
+	    VariantMap& eventData = GetEventDataMap();
+	    eventData[P_RESOURCENAME] = name;
+	    SendEvent(E_RESOURCENOTFOUND, eventData);
+    }
+
     return SharedPtr<File>();
 }
 
-Resource* ResourceCache::GetResource(ShortStringHash type, const char* name)
+Resource* ResourceCache::GetResource(ShortStringHash type, const String& name, bool SendEventOnFailure)
 {
-    return GetResource(type, String(name));
+    return GetResource(type, name.CString(), SendEventOnFailure);
 }
 
-Resource* ResourceCache::GetResource(ShortStringHash type, const String& nameIn)
+Resource* ResourceCache::GetResource(ShortStringHash type, const char* nameIn, bool SendEventOnFailure)
 {
     String name = SanitateResourceName(nameIn);
     
@@ -432,11 +442,18 @@ Resource* ResourceCache::GetResource(ShortStringHash type, const String& nameIn)
     if (!resource)
     {
         LOGERROR("Could not load unknown resource type " + String(type));
+
+        using namespace UnknownResourceType;
+
+        VariantMap& eventData = GetEventDataMap();
+        eventData[P_RESOURCETYPE] = type;
+        SendEvent(E_UNKNOWNRESOURCETYPE, eventData);
+
         return 0;
     }
     
     // Attempt to load the resource
-    SharedPtr<File> file = GetFile(name);
+    SharedPtr<File> file = GetFile(name, SendEventOnFailure);
     if (!file)
         return 0;
 
@@ -778,7 +795,6 @@ void ResourceCache::HandleBeginFrame(StringHash eventType, VariantMap& eventData
 
 File* ResourceCache::SearchResourceDirs(const String& nameIn)
 {
-    // Then the filesystem
     FileSystem* fileSystem = GetSubsystem<FileSystem>();
     for (unsigned i = 0; i < resourceDirs_.Size(); ++i)
     {
@@ -801,7 +817,6 @@ File* ResourceCache::SearchResourceDirs(const String& nameIn)
 
 File* ResourceCache::SearchPackages(const String& nameIn)
 {
-    // Check first the packages
     for (unsigned i = 0; i < packages_.Size(); ++i)
     {
         if (packages_[i]->Exists(nameIn))

+ 9 - 9
Source/Engine/Resource/ResourceCache.h

@@ -96,11 +96,11 @@ public:
     void SetSearchPackagesFirst(bool value) { searchPackagesFirst_ = value; }
 
     /// Open and return a file from the resource load paths or from inside a package file. If not found, use a fallback search with absolute path. Return null if fails.
-    SharedPtr<File> GetFile(const String& name);
+    SharedPtr<File> GetFile(const String& name, bool SendEventOnFailure = true);
     /// Return a resource by type and name. Load if not loaded yet. Return null if fails.
-    Resource* GetResource(ShortStringHash type, const String& name);
+    Resource* GetResource(ShortStringHash type, const String& name, bool SendEventOnFailure = true);
     /// Return a resource by type and name. Load if not loaded yet. Return null if fails.
-    Resource* GetResource(ShortStringHash type, const char* name);
+    Resource* GetResource(ShortStringHash type, const char* name, bool SendEventOnFailure = true);
     /// Return all loaded resources of a specific type.
     void GetResources(PODVector<Resource*>& result, ShortStringHash type) const;
     /// Return all loaded resources.
@@ -110,9 +110,9 @@ public:
     /// Return added package files.
     const Vector<SharedPtr<PackageFile> >& GetPackageFiles() const { return packages_; }
     /// Template version of returning a resource by name.
-    template <class T> T* GetResource(const String& name);
+    template <class T> T* GetResource(const String& name, bool SendEventOnFailure = true);
     /// Template version of returning a resource by name.
-    template <class T> T* GetResource(const char* name);
+    template <class T> T* GetResource(const char* name, bool SendEventOnFailure = true);
     /// Template version of returning loaded resources of a specific type.
     template <class T> void GetResources(PODVector<T*>& result) const;
     /// Return whether a file exists by name.
@@ -173,16 +173,16 @@ private:
     bool searchPackagesFirst_;
 };
 
-template <class T> T* ResourceCache::GetResource(const String& name)
+template <class T> T* ResourceCache::GetResource(const String& name, bool SendEventOnFailure)
 {
     ShortStringHash type = T::GetTypeStatic();
-    return static_cast<T*>(GetResource(type, name));
+    return static_cast<T*>(GetResource(type, name, SendEventOnFailure));
 }
 
-template <class T> T* ResourceCache::GetResource(const char* name)
+template <class T> T* ResourceCache::GetResource(const char* name, bool SendEventOnFailure)
 {
     ShortStringHash type = T::GetTypeStatic();
-    return static_cast<T*>(GetResource(type, name));
+    return static_cast<T*>(GetResource(type, name, SendEventOnFailure));
 }
 
 template <class T> void ResourceCache::GetResources(PODVector<T*>& result) const

+ 12 - 0
Source/Engine/Resource/ResourceEvents.h

@@ -42,4 +42,16 @@ EVENT(E_RELOADFAILED, ReloadFailed)
 {
 }
 
+/// Resource not found.
+EVENT(E_RESOURCENOTFOUND, ResourceNotFound)
+{
+    PARAM(P_RESOURCENAME, ResourceName);            // String
+}
+
+/// Unknown resource type.
+EVENT(E_UNKNOWNRESOURCETYPE, UnknownResourceType)
+{
+    PARAM(P_RESOURCETYPE, ResourceType);            // ShortStringHash
+}
+
 }

+ 4 - 4
Source/Engine/Script/ResourceAPI.cpp

@@ -36,9 +36,9 @@ void RegisterResource(asIScriptEngine* engine)
     RegisterResource<Resource>(engine, "Resource");
 }
 
-static Resource* ResourceCacheGetResource(const String& type, const String& name, ResourceCache* ptr)
+static Resource* ResourceCacheGetResource(const String& type, const String& name, bool SendEventOnFailure, ResourceCache* ptr)
 {
-    return ptr->GetResource(ShortStringHash(type), name);
+    return ptr->GetResource(ShortStringHash(type), name, SendEventOnFailure);
 }
 
 static File* ResourceCacheGetFile(const String& name, ResourceCache* ptr)
@@ -112,8 +112,8 @@ static void RegisterResourceCache(asIScriptEngine* engine)
     engine->RegisterObjectMethod("ResourceCache", "String SanitateResourceName(const String&in) const", asMETHOD(ResourceCache, SanitateResourceName), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "String SanitateResourceDirName(const String&in) const", asMETHOD(ResourceCache, SanitateResourceDirName), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "String GetResourceFileName(const String&in) const", asMETHOD(ResourceCache, GetResourceFileName), asCALL_THISCALL);
-    engine->RegisterObjectMethod("ResourceCache", "Resource@+ GetResource(const String&in, const String&in)", asFUNCTION(ResourceCacheGetResource), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("ResourceCache", "Resource@+ GetResource(ShortStringHash, const String&in)", asMETHODPR(ResourceCache, GetResource, (ShortStringHash, const String&), Resource*), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ResourceCache", "Resource@+ GetResource(const String&in, const String&in, bool SendEventOnFailure = true)", asFUNCTION(ResourceCacheGetResource), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("ResourceCache", "Resource@+ GetResource(ShortStringHash, const String&in, bool SendEventOnFailure = true)", asMETHODPR(ResourceCache, GetResource, (ShortStringHash, const String&, bool), Resource*), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "void set_memoryBudget(const String&in, uint)", asFUNCTION(ResourceCacheSetMemoryBudget), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("ResourceCache", "uint get_memoryBudget(const String&in) const", asFUNCTION(ResourceCacheGetMemoryBudget), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("ResourceCache", "uint get_memoryUse(const String&in) const", asFUNCTION(ResourceCacheGetMemoryUse), asCALL_CDECL_OBJLAST);

+ 2 - 3
Source/Engine/UI/Cursor.cpp

@@ -126,9 +126,8 @@ void Cursor::DefineShape(CursorShape shape, Image* image, const IntRect& imageRe
     CursorShapeInfo& info = shapeInfos_[shape];
 
     // Prefer to get the texture with same name from cache to prevent creating several copies of the texture
-    if (cache->Exists(image->GetName()))
-        info.texture_ = cache->GetResource<Texture2D>(image->GetName());
-    else
+    info.texture_ = cache->GetResource<Texture2D>(image->GetName(), false);
+    if (!info.texture_)
     {
         Texture2D* texture = new Texture2D(context_);
         texture->Load(SharedPtr<Image>(image));