浏览代码

Refactor resource prefix path parameter to accept a list of paths.
Close #1000.

Yao Wei Tjong 姚伟忠 10 年之前
父节点
当前提交
22bd3de807

+ 3 - 1
Docs/GettingStarted.dox

@@ -369,7 +369,9 @@ The engine can be configured using the following command line options.
 -q           Enable quiet mode which does not log to standard output stream
 -b <length>  Sound buffer length in milliseconds
 -r <freq>    Sound mixing frequency in Hz
--pp <path>   Resource prefix path, default to URHO3D_PREFIX_PATH env-var or executable path
+-pp <paths>  Resource prefix path(s), separated by semicolons, default to executable path
+             The resource prefix paths can also be defined using URHO3D_PREFIX_PATH env-var
+             When both are defined, the paths set by -pp takes higher precedence
 -p <paths>   Resource path(s) to use, separated by semicolons, default to 'Data;CoreData'
 -pf <files>  Resource package file to use, separated by semicolons, default to none
 -ap <paths>  Resource autoload path(s), separated by semicolons, default to 'AutoLoad'

+ 2 - 2
Docs/Reference.dox

@@ -130,7 +130,7 @@ The full list of supported parameters, their datatypes and default values:
 - LogName (string) %Log filename. Default "Urho3D.log".
 - FrameLimiter (bool) Whether to cap maximum framerate to 200 (desktop) or 60 (Android/iOS.) Default true.
 - WorkerThreads (bool) Whether to create worker threads for the %WorkQueue subsystem according to available CPU cores. Default true.
-- ResourcePrefixPath (string) Override the resource prefix path to use. If not specified then the default prefix path is set to URHO3D_PREFIX_PATH environment variable (if defined) or executable path.
+- ResourcePrefixPaths (string) A semicolon-separated list of resource prefix paths to use. If not specified then the default prefix path is set to executable path. The resource prefix paths can also be defined using URHO3D_PREFIX_PATH env-var. When both are defined, the paths set by -pp takes higher precedence.
 - ResourcePaths (string) A semicolon-separated list of resource paths to use. If corresponding packages (ie. Data.pak for Data directory) exist they will be used instead. Default "Data;CoreData".
 - ResourcePackages (string) A semicolon-separated list of resource packages to use. Default empty.
 - AutoloadPaths (string) A semicolon-separated list of autoload paths to use. Any resource packages and subdirectories inside an autoload path will be added to the resource system. Default "Autoload".
@@ -2819,7 +2819,7 @@ The following sample demonstrates how to build a path from 2 points, assign a co
 
 	// Node to move along the path ('controlled node')
 	Node* movingNode =  scene_->CreateChild("MovingNode");
-	
+
 	// Spline path
 	Node* pathNode = scene_->CreateChild("PathNode");
 	SplinePath* path = pathNode->CreateComponent<SplinePath>();

+ 5 - 0
Source/Samples/Sample.inl

@@ -59,6 +59,11 @@ void Sample::Setup()
     engineParameters_["FullScreen"]  = false;
     engineParameters_["Headless"]    = false;
     engineParameters_["Sound"]       = false;
+
+    // Construct a search path to find the resource prefix with two entries:
+    // The first entry is an empty path which will be substituted with program/bin directory -- this entry is for binary when it is still in build tree
+    // The second entry is an relative path to the installed program/bin directory -- this entry is for binary when it is in the URho3D SDK installation location
+    engineParameters_["ResourcePrefixPaths"] = " ;../share/Urho3D/Resources";
 }
 
 void Sample::Start()

+ 5 - 0
Source/Tools/Urho3DPlayer/Urho3DPlayer.cpp

@@ -119,6 +119,11 @@ void Urho3DPlayer::Setup()
         // Use the script file name as the base name for the log file
         engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("urho3d", "logs") + GetFileNameAndExtension(scriptFileName_) + ".log";
     }
+
+    // Construct a search path to find the resource prefix with two entries:
+    // The first entry is an empty path which will be substituted with program/bin directory -- this entry is for binary when it is still in build tree
+    // The second entry is an relative path to the installed program/bin directory -- this entry is for binary when it is in the URho3D SDK installation location
+    engineParameters_["ResourcePrefixPaths"] = " ;../share/Urho3D/Resources";
 }
 
 void Urho3DPlayer::Start()

+ 84 - 67
Source/Urho3D/Engine/Engine.cpp

@@ -212,116 +212,133 @@ bool Engine::Initialize(const VariantMap& parameters)
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     FileSystem* fileSystem = GetSubsystem<FileSystem>();
 
-    String resourcePrefixPath =
-        AddTrailingSlash(GetParameter(parameters, "ResourcePrefixPath", getenv("URHO3D_PREFIX_PATH")).GetString());
-    if (resourcePrefixPath.Empty())
-        resourcePrefixPath = fileSystem->GetProgramDir();
-    else if (!IsAbsolutePath(resourcePrefixPath))
-        resourcePrefixPath = fileSystem->GetProgramDir() + resourcePrefixPath;
+    Vector<String>
+        resourcePrefixPaths = GetParameter(parameters, "ResourcePrefixPaths", getenv("URHO3D_PREFIX_PATH")).GetString().Split(';');
+    if (resourcePrefixPaths.Empty())
+        resourcePrefixPaths.Push(String::EMPTY);
+    for (unsigned i = 0; i < resourcePrefixPaths.Size(); ++i)
+    {
+        if (resourcePrefixPaths[i].Empty())
+            resourcePrefixPaths[i] = fileSystem->GetProgramDir();
+        else if (!IsAbsolutePath(resourcePrefixPaths[i]))
+            resourcePrefixPaths[i] = AddTrailingSlash(fileSystem->GetProgramDir() + resourcePrefixPaths[i]);
+    }
     Vector<String> resourcePaths = GetParameter(parameters, "ResourcePaths", "Data;CoreData").GetString().Split(';');
     Vector<String> resourcePackages = GetParameter(parameters, "ResourcePackages").GetString().Split(';');
     Vector<String> autoLoadPaths = GetParameter(parameters, "AutoloadPaths", "Autoload").GetString().Split(';');
 
     for (unsigned i = 0; i < resourcePaths.Size(); ++i)
     {
-        bool success = false;
-
         // If path is not absolute, prefer to add it as a package if possible
         if (!IsAbsolutePath(resourcePaths[i]))
         {
-            String packageName = resourcePrefixPath + resourcePaths[i] + ".pak";
-            if (fileSystem->FileExists(packageName))
-                success = cache->AddPackageFile(packageName);
-
-            if (!success)
+            unsigned j = 0;
+            for (; j < resourcePrefixPaths.Size(); ++j)
             {
-                String pathName = resourcePrefixPath + resourcePaths[i];
+                String packageName = resourcePrefixPaths[j] + resourcePaths[i] + ".pak";
+                if (fileSystem->FileExists(packageName))
+                {
+                    if (cache->AddPackageFile(packageName))
+                        break;
+                    else
+                        return false;   // The root cause of the error should have already been logged
+                }
+                String pathName = resourcePrefixPaths[j] + resourcePaths[i];
                 if (fileSystem->DirExists(pathName))
-                    success = cache->AddResourceDir(pathName);
+                {
+                    if (cache->AddResourceDir(pathName))
+                        break;
+                    else
+                        return false;
+                }
+            }
+            if (j == resourcePrefixPaths.Size())
+            {
+                URHO3D_LOGERRORF(
+                    "Failed to add resource path '%s', check the documentation on how to set the 'resource prefix path'",
+                    resourcePaths[i].CString());
+                return false;
             }
         }
         else
         {
             String pathName = resourcePaths[i];
             if (fileSystem->DirExists(pathName))
-                success = cache->AddResourceDir(pathName);
-        }
-
-        if (!success)
-        {
-            URHO3D_LOGERRORF("Failed to add resource path '%s', check the documentation on how to set the 'resource prefix path'",
-                resourcePaths[i].CString());
-            return false;
+                if (!cache->AddResourceDir(pathName))
+                    return false;
         }
     }
 
     // Then add specified packages
     for (unsigned i = 0; i < resourcePackages.Size(); ++i)
     {
-        String packageName = resourcePrefixPath + resourcePackages[i];
-        if (fileSystem->FileExists(packageName))
+        unsigned j = 0;
+        for (; j < resourcePrefixPaths.Size(); ++j)
         {
-            if (!cache->AddPackageFile(packageName))
+            String packageName = resourcePrefixPaths[j] + resourcePackages[i];
+            if (fileSystem->FileExists(packageName))
             {
-                URHO3D_LOGERRORF("Failed to add resource package '%s', check the documentation on how to set the 'resource prefix path'",
-                    resourcePackages[i].CString());
-                return false;
+                if (cache->AddPackageFile(packageName))
+                    break;
+                else
+                    return false;
             }
         }
-        else
-            URHO3D_LOGDEBUGF(
-                "Skip specified resource package '%s' as it does not exist, check the documentation on how to set the 'resource prefix path'",
+        if (j == resourcePrefixPaths.Size())
+        {
+            URHO3D_LOGERRORF(
+                "Failed to add resource package '%s', check the documentation on how to set the 'resource prefix path'",
                 resourcePackages[i].CString());
+            return false;
+        }
     }
 
     // Add auto load folders. Prioritize these (if exist) before the default folders
     for (unsigned i = 0; i < autoLoadPaths.Size(); ++i)
     {
-        String autoLoadPath(autoLoadPaths[i]);
-        if (!IsAbsolutePath(autoLoadPath))
-            autoLoadPath = resourcePrefixPath + autoLoadPath;
+        bool autoLoadPathExist = false;
 
-        if (fileSystem->DirExists(autoLoadPath))
+        for (unsigned j = 0; j < resourcePrefixPaths.Size(); ++j)
         {
-            // Add all the subdirs (non-recursive) as resource directory
-            Vector<String> subdirs;
-            fileSystem->ScanDir(subdirs, autoLoadPath, "*", SCAN_DIRS, false);
-            for (unsigned y = 0; y < subdirs.Size(); ++y)
+            String autoLoadPath(autoLoadPaths[i]);
+            if (!IsAbsolutePath(autoLoadPath))
+                autoLoadPath = resourcePrefixPaths[j] + autoLoadPath;
+
+            if (fileSystem->DirExists(autoLoadPath))
             {
-                String dir = subdirs[y];
-                if (dir.StartsWith("."))
-                    continue;
+                autoLoadPathExist = true;
 
-                String autoResourceDir = autoLoadPath + "/" + dir;
-                if (!cache->AddResourceDir(autoResourceDir, 0))
+                // Add all the subdirs (non-recursive) as resource directory
+                Vector<String> subdirs;
+                fileSystem->ScanDir(subdirs, autoLoadPath, "*", SCAN_DIRS, false);
+                for (unsigned y = 0; y < subdirs.Size(); ++y)
                 {
-                    URHO3D_LOGERRORF(
-                        "Failed to add resource directory '%s' in autoload path %s, check the documentation on how to set the 'resource prefix path'",
-                        dir.CString(), autoLoadPaths[i].CString());
-                    return false;
-                }
-            }
+                    String dir = subdirs[y];
+                    if (dir.StartsWith("."))
+                        continue;
 
-            // Add all the found package files (non-recursive)
-            Vector<String> paks;
-            fileSystem->ScanDir(paks, autoLoadPath, "*.pak", SCAN_FILES, false);
-            for (unsigned y = 0; y < paks.Size(); ++y)
-            {
-                String pak = paks[y];
-                if (pak.StartsWith("."))
-                    continue;
+                    String autoResourceDir = autoLoadPath + "/" + dir;
+                    if (!cache->AddResourceDir(autoResourceDir, 0))
+                        return false;
+                }
 
-                String autoPackageName = autoLoadPath + "/" + pak;
-                if (!cache->AddPackageFile(autoPackageName, 0))
+                // Add all the found package files (non-recursive)
+                Vector<String> paks;
+                fileSystem->ScanDir(paks, autoLoadPath, "*.pak", SCAN_FILES, false);
+                for (unsigned y = 0; y < paks.Size(); ++y)
                 {
-                    URHO3D_LOGERRORF(
-                        "Failed to add package file '%s' in autoload path %s, check the documentation on how to set the 'resource prefix path'",
-                        pak.CString(), autoLoadPaths[i].CString());
-                    return false;
+                    String pak = paks[y];
+                    if (pak.StartsWith("."))
+                        continue;
+
+                    String autoPackageName = autoLoadPath + "/" + pak;
+                    if (!cache->AddPackageFile(autoPackageName, 0))
+                        return false;
                 }
             }
         }
-        else
+
+        if (!autoLoadPathExist)
             URHO3D_LOGDEBUGF(
                 "Skipped autoload path '%s' as it does not exist, check the documentation on how to set the 'resource prefix path'",
                 autoLoadPaths[i].CString());
@@ -813,7 +830,7 @@ VariantMap Engine::ParseParameters(const Vector<String>& arguments)
             }
             else if (argument == "pp" && !value.Empty())
             {
-                ret["ResourcePrefixPath"] = value;
+                ret["ResourcePrefixPaths"] = value;
                 ++i;
             }
             else if (argument == "p" && !value.Empty())

+ 3 - 0
Source/Urho3D/IO/PackageFile.cpp

@@ -107,7 +107,10 @@ bool PackageFile::Open(const String& fileName, unsigned startOffset)
         newEntry.size_ = file->ReadUInt();
         newEntry.checksum_ = file->ReadUInt();
         if (!compressed_ && newEntry.offset_ + newEntry.size_ > totalSize_)
+        {
             URHO3D_LOGERROR("File entry " + entryName + " outside package file");
+            return false;
+        }
         else
             entries_[entryName] = newEntry;
     }

+ 3 - 0
Source/Urho3D/Resource/ResourceCache.cpp

@@ -139,7 +139,10 @@ bool ResourceCache::AddPackageFile(PackageFile* package, unsigned priority)
 
     // Do not add packages that failed to load
     if (!package || !package->GetNumFiles())
+    {
+        URHO3D_LOGERRORF("Could not add package file %s due to load failure", package->GetName().CString());
         return false;
+    }
 
     if (priority < packages_.Size())
         packages_.Insert(priority, SharedPtr<PackageFile>(package));

+ 2 - 3
bin/Editor.bat

@@ -1,5 +1,4 @@
 @echo off
 if exist "%~dp0Urho3DPlayer.exe" (set "DEBUG=") else (set "DEBUG=_d")
-if exist "%~dp0..\share\Urho3D\Resources" (set "OPT1=-pp ..\share\Urho3D\Resources") else (set "OPT1=")
-if [%1] == [] (set "OPT2=-w -s") else (set "OPT2=")
-start "" "%~dp0Urho3DPlayer%DEBUG%" Scripts/Editor.as %OPT1% %OPT2% %*
+if [%1] == [] (set "OPT1=-w -s") else (set "OPT1=")
+start "" "%~dp0Urho3DPlayer%DEBUG%" Scripts/Editor.as %OPT1% %*

+ 2 - 3
bin/Editor.sh

@@ -1,4 +1,3 @@
 #!/usr/bin/env bash
-if [ -d $(dirname $0)/../share/Urho3D/Resources ]; then OPT1="-pp ../share/Urho3D/Resources"; fi
-if [ $# -eq 0 ]; then OPT2="-w -s"; fi
-$(dirname $0)/Urho3DPlayer Scripts/Editor.as $OPT1 $OPT2 $@
+if [ $# -eq 0 ]; then OPT1="-w -s"; fi
+$(dirname $0)/Urho3DPlayer Scripts/Editor.as $OPT1 $@

+ 1 - 2
bin/NinjaSnowWar.bat

@@ -11,5 +11,4 @@
 ::
 @echo off
 if exist "%~dp0Urho3DPlayer.exe" (set "DEBUG=") else (set "DEBUG=_d")
-if exist "%~dp0..\share\Urho3D\Resources" (set "OPT1=-pp ..\share\Urho3D\Resources") else (set "OPT1=")
-"%~dp0Urho3DPlayer%DEBUG%" Scripts/NinjaSnowWar.as %OPT1% %*
+"%~dp0Urho3DPlayer%DEBUG%" Scripts/NinjaSnowWar.as %*

+ 1 - 2
bin/NinjaSnowWar.sh

@@ -10,5 +10,4 @@
 #   Start the server with "./NinjaSnowWar.sh -w -server"
 #   Start the client on the same host with "./NinjaSnowWar.sh -w -nobgm -address `hostname`"
 #
-if [ -d $(dirname $0)/../share/Urho3D/Resources ]; then OPT1="-pp ../share/Urho3D/Resources"; fi
-$(dirname $0)/Urho3DPlayer Scripts/NinjaSnowWar.as $OPT1 $@
+$(dirname $0)/Urho3DPlayer Scripts/NinjaSnowWar.as $@