Browse Source

Uncommented the package file download test from TestScene.as.
Fixed missing default arguments in the script API.
Fixed crash if a script file is unloaded while executing a script function.
Fixed Urho3D.exe not correcting the script file name to internal format (slashes instead of backslashes.)
Use black default background for the Direct3D9 window.

Lasse Öörni 14 years ago
parent
commit
1c154ef17e

+ 13 - 5
Bin/Data/Scripts/TestScene.as

@@ -38,14 +38,22 @@ void Start()
         network.StartServer(serverPort);
         SubscribeToEvent("ClientConnected", "HandleClientConnected");
 
-        //PackageFile@ packageFile = PackageFile(fileSystem.programDir + "Data.pak");
-        //cache.AddPackageFile(packageFile);
-        //testScene.AddRequiredPackageFile(packageFile);
+        // Test package download by adding all package files in the cache as requirements for the scene
+        Array<PackageFile@> packages = cache.packageFiles;
+        for (uint i = 0; i < packages.length; ++i)
+            testScene.AddRequiredPackageFile(packages[i]);
     }
     if (startClient)
     {
         testScene.Clear();
-        //network.packageCacheDir = fileSystem.programDir;
+
+        // Test package download. Remove existing Data.pak from resource cache so that it will be downloaded
+        // However, be sure to add the Data directory so that resource requests do not fail in the meanwhile
+        String packageName = fileSystem.programDir + "Data.pak";
+        cache.RemovePackageFile(packageName, false);
+        cache.AddResourceDir(fileSystem.programDir + "Data");
+
+        network.packageCacheDir = fileSystem.programDir;
         network.Connect(serverAddress, serverPort, testScene);
     }
 }
@@ -334,7 +342,7 @@ void HandleUpdate(StringHash eventType, VariantMap& eventData)
         if (connection.numDownloads > 0)
         {
             downloadsText.text = "Downloads: " + connection.numDownloads + " Current download: " +
-                connection.downloadName + " (" + connection.downloadProgress * 100.0 + "%)";
+                connection.downloadName + " (" + int(connection.downloadProgress * 100.0 + 0.5) + "%)";
         }
         else if (!downloadsText.text.empty)
             downloadsText.text = "";

+ 36 - 38
Docs/ScriptAPI.dox

@@ -236,7 +236,7 @@ Methods:<br>
 - Quaternion ToQuaternion() const
 - Vector2 ToVector2() const
 - Vector3 ToVector3() const
-- Vector4 ToVector4() const
+- Vector4 ToVector4(bool arg0 = false) const
 
 Properties:<br>
 - uint length (readonly)
@@ -645,7 +645,7 @@ Properties:<br>
 File
 
 Methods:<br>
-- bool Open(const String&, FileMode)
+- bool Open(const String&, FileMode arg1 = FILE_READ)
 - void Close()
 - bool WriteInt(int)
 - bool WriteShort(int16)
@@ -835,20 +835,20 @@ Properties:<br>
 ResourceCache
 
 Methods:<br>
-- bool AddResourcePath(const String&)
+- bool AddResourceDir(const String&)
 - void AddPackageFile(PackageFile@, bool arg1 = false)
 - bool AddManualResource(Resource@)
-- void RemoveResourcePath(const String&)
-- void RemovePackageFile(PackageFile@, bool, bool)
-- void RemovePackageFile(const String&, bool, bool)
-- void ReleaseResource(const String&, const String&, bool)
-- void ReleaseResources(const String&, bool)
-- void ReleaseResources(const String&, const String&, bool)
-- void ReleaseAllResources(bool)
+- void RemoveResourceDir(const String&)
+- void RemovePackageFile(PackageFile@, bool arg1 = true, bool arg2 = false)
+- void RemovePackageFile(const String&, bool arg1 = true, bool arg2 = false)
+- void ReleaseResource(const String&, const String&, bool arg2 = false)
+- void ReleaseResources(const String&, bool arg1 = false)
+- void ReleaseResources(const String&, const String&, bool arg2 = false)
+- void ReleaseAllResources(bool arg0 = false)
 - bool ReloadResource(Resource@)
 - bool Exists(const String&) const
 - File@ GetFile(const String&)
-- String GetPreferredResourcePath(const String&)
+- String GetPreferredResourceDir(const String&)
 - Resource@ GetResource(const String&, const String&)
 
 Properties:<br>
@@ -857,6 +857,8 @@ Properties:<br>
 - uint[] memoryBudget
 - uint[] memoryUse (readonly)
 - uint totalMemoryUse (readonly)
+- String[]@ resourceDirs (readonly)
+- PackageFile@[]@ packageFiles (readonly)
 
 
 Image
@@ -885,7 +887,7 @@ Methods:<br>
 - bool Load(File@)
 - bool Save(File@)
 - XMLElement CreateRoot(const String&)
-- XMLElement GetRoot(const String&)
+- XMLElement GetRoot(const String& arg0 = String ( ))
 
 Properties:<br>
 - ShortStringHash type (readonly)
@@ -900,10 +902,8 @@ XMLElement
 
 Methods:<br>
 - XMLElement CreateChild(const String&)
-- bool RemoveChild()
-- bool RemoveChild(const String&, bool)
-- bool RemoveChildren()
-- bool RemoveChildren(const String&)
+- bool RemoveChild(const String& arg0 = String ( ), bool arg1 = true)
+- bool RemoveChildren(const String& arg0 = String ( ))
 - bool SetAttribute(const String&, const String&)
 - bool SetBool(const String&, bool)
 - bool SetBoundingBox(const BoundingBox&)
@@ -925,10 +925,8 @@ Methods:<br>
 - String GetAttributes(const String&) const
 - String[]@ GetAttributeNames() const
 - bool HasChild(const String&) const
-- XMLElement GetChild() const
-- XMLElement GetChild(const String&) const
-- XMLElement GetNext() const
-- XMLElement GetNext(const String&) const
+- XMLElement GetChild(const String& arg0 = String ( )) const
+- XMLElement GetNext(const String& arg0 = String ( )) const
 - bool GetBool(const String&) const
 - BoundingBox GetBoundingBox() const
 - Color GetColor(const String&) const
@@ -1010,10 +1008,10 @@ Methods:<br>
 - void SetScale(float)
 - void Translate(const Vector3&)
 - void TranslateRelative(const Vector3&)
-- void Rotate(const Quaternion&, bool)
-- void Pitch(float, bool)
-- void Yaw(float, bool)
-- void Roll(float, bool)
+- void Rotate(const Quaternion&, bool arg1 = false)
+- void Pitch(float, bool arg1 = false)
+- void Yaw(float, bool arg1 = false)
+- void Roll(float, bool arg1 = false)
 - void Scale(float)
 - void Scale(const Vector3&)
 - Node@ CreateChild(const String& arg0 = "", CreateMode arg1 = REPLICATED)
@@ -1081,10 +1079,10 @@ Methods:<br>
 - void SetScale(float)
 - void Translate(const Vector3&)
 - void TranslateRelative(const Vector3&)
-- void Rotate(const Quaternion&, bool)
-- void Pitch(float, bool)
-- void Yaw(float, bool)
-- void Roll(float, bool)
+- void Rotate(const Quaternion&, bool arg1 = false)
+- void Pitch(float, bool arg1 = false)
+- void Yaw(float, bool arg1 = false)
+- void Roll(float, bool arg1 = false)
 - void Scale(float)
 - void Scale(const Vector3&)
 - Node@ CreateChild(const String& arg0 = "", CreateMode arg1 = REPLICATED)
@@ -1275,8 +1273,8 @@ Methods:<br>
 - bool Save(File@)
 - void SetNumLevels(uint)
 - void ClearDataLost()
-- void SetSize(int, int, uint, TextureUsage)
-- bool Load(Image@)
+- void SetSize(int, int, uint, TextureUsage arg3 = TEXTURE_STATIC)
+- bool Load(Image@, bool arg1 = false)
 
 Properties:<br>
 - ShortStringHash type (readonly)
@@ -1306,8 +1304,8 @@ Methods:<br>
 - bool Save(File@)
 - void SetNumLevels(uint)
 - void ClearDataLost()
-- void SetSize(int, uint, TextureUsage)
-- bool Load(CubeMapFace, Image@)
+- void SetSize(int, uint, TextureUsage arg2 = TEXTURE_STATIC)
+- bool Load(CubeMapFace, Image@, bool arg2 = false)
 
 Properties:<br>
 - ShortStringHash type (readonly)
@@ -1844,10 +1842,10 @@ Methods:<br>
 - bool SetAttribute(const String&, const Variant&)
 - Variant GetAttribute(const String&)
 - void Remove()
-- void AddLine(const Vector3&, const Vector3&, const Color&, bool)
-- void AddBoundingBox(const BoundingBox&, const Color&, bool)
-- void AddFrustum(const Frustum&, const Color&, bool)
-- void AddSkeleton(Skeleton@, const Color&, bool)
+- void AddLine(const Vector3&, const Vector3&, const Color&, bool arg3 = true)
+- void AddBoundingBox(const BoundingBox&, const Color&, bool arg2 = true)
+- void AddFrustum(const Frustum&, const Color&, bool arg2 = true)
+- void AddSkeleton(Skeleton@, const Color&, bool arg2 = true)
 
 Properties:<br>
 - ShortStringHash type (readonly)
@@ -2100,7 +2098,7 @@ Properties:<br>
 Audio
 
 Methods:<br>
-- void SetMode(int, int, bool, bool)
+- void SetMode(int, int, bool, bool arg3 = true)
 - bool Play()
 - void Stop()
 - void SetListenerTransform(const Vector3&, const Quaternion&)
@@ -3550,7 +3548,7 @@ Methods:<br>
 - void SetCylinder(float, float, const Vector3&, const Quaternion&)
 - void SetCapsule(float, float, const Vector3&, const Quaternion&)
 - void SetTriangleMesh(Model@, uint, const Vector3&, const Quaternion&)
-- void SetHeightfield(Model@, const IntVector2&, float, uint, const Vector3&, const Quaternion&)
+- void SetHeightfield(Model@, uint, uint, float, uint, const Vector3&, const Quaternion&)
 - void SetConvexHull(Model@, float, uint, const Vector3&, const Quaternion&)
 - void SetTransform(const Vector3&, const Quaternion&)
 

+ 4 - 4
Engine/Engine/APITemplates.h

@@ -490,10 +490,10 @@ template <class T> void RegisterNode(asIScriptEngine* engine, const char* classN
     engine->RegisterObjectMethod(className, "void SetScale(float)", asMETHODPR(T, SetScale, (float), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void Translate(const Vector3&in)", asMETHOD(T, Translate), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void TranslateRelative(const Vector3&in)", asMETHOD(T, TranslateRelative), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "void Rotate(const Quaternion&in, bool)", asMETHOD(T, Rotate), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "void Pitch(float, bool)", asMETHOD(T, Pitch), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "void Yaw(float, bool)", asMETHOD(T, Yaw), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "void Roll(float, bool)", asMETHOD(T, Roll), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void Rotate(const Quaternion&in, bool fixedAxis = false)", asMETHOD(T, Rotate), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void Pitch(float, bool fixedAxis = false)", asMETHOD(T, Pitch), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void Yaw(float, bool fixedAxis = false)", asMETHOD(T, Yaw), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void Roll(float, bool fixedAxis = false)", asMETHOD(T, Roll), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void Scale(float)", asMETHODPR(T, Scale, (float), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void Scale(const Vector3&in)", asMETHODPR(T, Scale, (const Vector3&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "Node@+ CreateChild(const String&in name = \"\", CreateMode mode = REPLICATED)", asMETHODPR(T, CreateChild, (const String&, CreateMode), Node*), asCALL_THISCALL);

+ 1 - 1
Engine/Engine/AudioAPI.cpp

@@ -69,7 +69,7 @@ static Audio* GetAudio()
 void RegisterAudio(asIScriptEngine* engine)
 {
     RegisterObject<Audio>(engine, "Audio");
-    engine->RegisterObjectMethod("Audio", "void SetMode(int, int, bool, bool)", asMETHOD(Audio, SetMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Audio", "void SetMode(int, int, bool, bool interpolate = true)", asMETHOD(Audio, SetMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("Audio", "bool Play()", asMETHOD(Audio, Play), asCALL_THISCALL);
     engine->RegisterObjectMethod("Audio", "void Stop()", asMETHOD(Audio, Stop), asCALL_THISCALL);
     engine->RegisterObjectMethod("Audio", "void SetListenerTransform(const Vector3&in, const Quaternion&in)", asMETHOD(Audio, SetListenerTransform), asCALL_THISCALL);

+ 1 - 1
Engine/Engine/CoreAPI.cpp

@@ -453,7 +453,7 @@ static void RegisterStringUtils(asIScriptEngine* engine)
     engine->RegisterObjectMethod("String", "Quaternion ToQuaternion() const", asFUNCTION(ToQuaternion), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "Vector2 ToVector2() const", asFUNCTION(ToVector2), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("String", "Vector3 ToVector3() const", asFUNCTION(ToVector3), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("String", "Vector4 ToVector4() const", asFUNCTION(ToVector4), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("String", "Vector4 ToVector4(bool allowMissingCoords = false) const", asFUNCTION(ToVector4), asCALL_CDECL_OBJFIRST);
     engine->RegisterGlobalFunction("String ToStringHex(int)", asFUNCTION(ToStringHex), asCALL_CDECL);
 }
 

+ 2 - 2
Engine/Engine/Engine.cpp

@@ -171,7 +171,7 @@ bool Engine::Initialize(const String& windowTitle, const String& logName, const
         cache->AddPackageFile(package);
     }
     else if (fileSystem->DirExists(exePath + "CoreData"))
-        cache->AddResourcePath(exePath + "CoreData");
+        cache->AddResourceDir(exePath + "CoreData");
     
     if (fileSystem->FileExists(exePath + "Data.pak"))
     {
@@ -180,7 +180,7 @@ bool Engine::Initialize(const String& windowTitle, const String& logName, const
         cache->AddPackageFile(package);
     }
     else if (fileSystem->DirExists(exePath + "Data"))
-        cache->AddResourcePath(exePath + "Data");
+        cache->AddResourceDir(exePath + "Data");
     
     // Initialize graphics & audio output
     if (!headless_)

+ 12 - 12
Engine/Engine/GraphicsAPI.cpp

@@ -155,14 +155,14 @@ static Camera* ViewportGetCamera(Viewport* ptr)
     return ptr->camera_;
 }
 
-static bool Texture2DLoad(Image* image, Texture2D* ptr)
+static bool Texture2DLoad(Image* image, bool useAlpha, Texture2D* ptr)
 {
-    return ptr->Load(SharedPtr<Image>(image));
+    return ptr->Load(SharedPtr<Image>(image), useAlpha);
 }
 
-static bool TextureCubeLoad(CubeMapFace face, Image* image, TextureCube* ptr)
+static bool TextureCubeLoad(CubeMapFace face, Image* image, bool useAlpha, TextureCube* ptr)
 {
-    return ptr->Load(face, SharedPtr<Image>(image));
+    return ptr->Load(face, SharedPtr<Image>(image), useAlpha);
 }
 
 static void RegisterTextures(asIScriptEngine* engine)
@@ -231,13 +231,13 @@ static void RegisterTextures(asIScriptEngine* engine)
     engine->RegisterObjectMethod("RenderSurface", "RenderSurface@+ get_linkedDepthBuffer() const", asMETHOD(RenderSurface, GetLinkedDepthBuffer), asCALL_THISCALL);
     
     RegisterTexture<Texture2D>(engine, "Texture2D");
-    engine->RegisterObjectMethod("Texture2D", "void SetSize(int, int, uint, TextureUsage)", asMETHOD(Texture2D, SetSize), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Texture2D", "bool Load(Image@+)", asFUNCTION(Texture2DLoad), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("Texture2D", "void SetSize(int, int, uint, TextureUsage usage = TEXTURE_STATIC)", asMETHOD(Texture2D, SetSize), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Texture2D", "bool Load(Image@+, bool useAlpha = false)", asFUNCTION(Texture2DLoad), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Texture2D", "RenderSurface@+ get_renderSurface() const", asMETHOD(Texture2D, GetRenderSurface), asCALL_THISCALL);
     
     RegisterTexture<TextureCube>(engine, "TextureCube");
-    engine->RegisterObjectMethod("TextureCube", "void SetSize(int, uint, TextureUsage)", asMETHOD(TextureCube, SetSize), asCALL_THISCALL);
-    engine->RegisterObjectMethod("TextureCube", "bool Load(CubeMapFace, Image@+)", asFUNCTION(TextureCubeLoad), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("TextureCube", "void SetSize(int, uint, TextureUsage usage = TEXTURE_STATIC)", asMETHOD(TextureCube, SetSize), asCALL_THISCALL);
+    engine->RegisterObjectMethod("TextureCube", "bool Load(CubeMapFace, Image@+, bool useAlpha = false)", asFUNCTION(TextureCubeLoad), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("TextureCube", "RenderSurface@+ get_renderSurface(CubeMapFace) const", asMETHOD(TextureCube, GetRenderSurface), asCALL_THISCALL);
 }
 
@@ -826,10 +826,10 @@ static DebugRenderer* SceneGetDebugRenderer(Scene* ptr)
 static void RegisterDebugRenderer(asIScriptEngine* engine)
 {
     RegisterComponent<DebugRenderer>(engine, "DebugRenderer");
-    engine->RegisterObjectMethod("DebugRenderer", "void AddLine(const Vector3&in, const Vector3&in, const Color&in, bool)", asMETHOD(DebugRenderer, AddLine), asCALL_THISCALL);
-    engine->RegisterObjectMethod("DebugRenderer", "void AddBoundingBox(const BoundingBox&in, const Color&in, bool)", asMETHODPR(DebugRenderer, AddBoundingBox, (const BoundingBox&, const Color&, bool), void), asCALL_THISCALL);
-    engine->RegisterObjectMethod("DebugRenderer", "void AddFrustum(const Frustum&in, const Color&in, bool)", asMETHOD(DebugRenderer, AddFrustum), asCALL_THISCALL);
-    engine->RegisterObjectMethod("DebugRenderer", "void AddSkeleton(Skeleton@+, const Color&in, bool)", asMETHOD(DebugRenderer, AddSkeleton), asCALL_THISCALL);
+    engine->RegisterObjectMethod("DebugRenderer", "void AddLine(const Vector3&in, const Vector3&in, const Color&in, bool depthTest = true)", asMETHOD(DebugRenderer, AddLine), asCALL_THISCALL);
+    engine->RegisterObjectMethod("DebugRenderer", "void AddBoundingBox(const BoundingBox&in, const Color&in, bool depthTest = true)", asMETHODPR(DebugRenderer, AddBoundingBox, (const BoundingBox&, const Color&, bool), void), asCALL_THISCALL);
+    engine->RegisterObjectMethod("DebugRenderer", "void AddFrustum(const Frustum&in, const Color&in, bool depthTest = true)", asMETHOD(DebugRenderer, AddFrustum), asCALL_THISCALL);
+    engine->RegisterObjectMethod("DebugRenderer", "void AddSkeleton(Skeleton@+, const Color&in, bool depthTest = true)", asMETHOD(DebugRenderer, AddSkeleton), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "DebugRenderer@+ get_debugRenderer() const", asFUNCTION(SceneGetDebugRenderer), asCALL_CDECL_OBJLAST);
     engine->RegisterGlobalFunction("DebugRenderer@+ get_debugRenderer()", asFUNCTION(GetDebugRenderer), asCALL_CDECL);
 }

+ 2 - 2
Engine/Engine/IOAPI.cpp

@@ -233,8 +233,8 @@ static void RegisterSerialization(asIScriptEngine* engine)
     
     RegisterObject<File>(engine, "File");
     engine->RegisterObjectBehaviour("File", asBEHAVE_FACTORY, "File@+ f()", asFUNCTION(ConstructFile), asCALL_CDECL);
-    engine->RegisterObjectBehaviour("File", asBEHAVE_FACTORY, "File@+ f(const String&in, FileMode)", asFUNCTION(ConstructFileAndOpen), asCALL_CDECL);
-    engine->RegisterObjectMethod("File", "bool Open(const String&in, FileMode)", asMETHODPR(File, Open, (const String&, FileMode), bool), asCALL_THISCALL);
+    engine->RegisterObjectBehaviour("File", asBEHAVE_FACTORY, "File@+ f(const String&in, FileMode mode = FILE_READ)", asFUNCTION(ConstructFileAndOpen), asCALL_CDECL);
+    engine->RegisterObjectMethod("File", "bool Open(const String&in, FileMode mode = FILE_READ)", asMETHODPR(File, Open, (const String&, FileMode), bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("File", "void Close()", asMETHOD(File, Close), asCALL_THISCALL);
     engine->RegisterObjectMethod("File", "FileMode get_mode() const", asMETHOD(File, GetMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("File", "bool get_open()", asMETHOD(File, IsOpen), asCALL_THISCALL);

+ 1 - 1
Engine/Engine/PhysicsAPI.cpp

@@ -125,7 +125,7 @@ static void RegisterCollisionShape(asIScriptEngine* engine)
     engine->RegisterObjectMethod("CollisionShape", "void SetCylinder(float, float, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetCylinder), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "void SetCapsule(float, float, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetCapsule), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "void SetTriangleMesh(Model@+, uint, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetTriangleMesh), asCALL_THISCALL);
-    engine->RegisterObjectMethod("CollisionShape", "void SetHeightfield(Model@+, const IntVector2&in, float, uint, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetHeightfield), asCALL_THISCALL);
+    engine->RegisterObjectMethod("CollisionShape", "void SetHeightfield(Model@+, uint, uint, float, uint, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetHeightfield), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "void SetConvexHull(Model@+, float, uint, const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetConvexHull), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "void SetTransform(const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetTransform), asCALL_THISCALL);
     engine->RegisterObjectMethod("CollisionShape", "Model@+ get_model()", asMETHOD(CollisionShape, GetModel), asCALL_THISCALL);

+ 27 - 38
Engine/Engine/ResourceAPI.cpp

@@ -23,6 +23,7 @@
 
 #include "Precompiled.h"
 #include "APITemplates.h"
+#include "PackageFile.h"
 #include "ResourceCache.h"
 
 void ArrayToVariantVector(CScriptArray* arr, VariantVector& dest);
@@ -82,28 +83,40 @@ static ResourceCache* GetResourceCache()
     return GetScriptContext()->GetSubsystem<ResourceCache>();
 }
 
+static CScriptArray* ResourceCacheGetResourceDirs(ResourceCache* ptr)
+{
+    return VectorToArray<String>(ptr->GetResourceDirs(), "Array<String>");
+}
+
+static CScriptArray* ResourceCacheGetPackageFiles(ResourceCache* ptr)
+{
+    return SharedPtrVectorToHandleArray<PackageFile>(ptr->GetPackageFiles(), "Array<PackageFile@>");
+}
+
 static void RegisterResourceCache(asIScriptEngine* engine)
 {
     RegisterObject<ResourceCache>(engine, "ResourceCache");
-    engine->RegisterObjectMethod("ResourceCache", "bool AddResourcePath(const String&in)", asMETHOD(ResourceCache, AddResourcePath), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ResourceCache", "bool AddResourceDir(const String&in)", asMETHOD(ResourceCache, AddResourceDir), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "void AddPackageFile(PackageFile@+, bool addAsFirst = false)", asMETHOD(ResourceCache, AddPackageFile), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "bool AddManualResource(Resource@+)", asMETHOD(ResourceCache, AddManualResource), asCALL_THISCALL);
-    engine->RegisterObjectMethod("ResourceCache", "void RemoveResourcePath(const String&in)", asMETHOD(ResourceCache, RemoveResourcePath), asCALL_THISCALL);
-    engine->RegisterObjectMethod("ResourceCache", "void RemovePackageFile(PackageFile@+, bool, bool)", asMETHODPR(ResourceCache, RemovePackageFile, (PackageFile*, bool, bool), void), asCALL_THISCALL);
-    engine->RegisterObjectMethod("ResourceCache", "void RemovePackageFile(const String&in, bool, bool)", asMETHODPR(ResourceCache, RemovePackageFile, (const String&, bool, bool), void), asCALL_THISCALL);
-    engine->RegisterObjectMethod("ResourceCache", "void ReleaseResource(const String&in, const String&in, bool)", asFUNCTION(ResourceCacheReleaseResource), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("ResourceCache", "void ReleaseResources(const String&in, bool)", asFUNCTION(ResourceCacheReleaseResources), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("ResourceCache", "void ReleaseResources(const String&in, const String&in, bool)", asFUNCTION(ResourceCacheReleaseResourcesPartial), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("ResourceCache", "void ReleaseAllResources(bool)", asMETHOD(ResourceCache, ReleaseAllResources), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ResourceCache", "void RemoveResourceDir(const String&in)", asMETHOD(ResourceCache, RemoveResourceDir), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ResourceCache", "void RemovePackageFile(PackageFile@+, bool releaseResources = true, bool forceRelease = false)", asMETHODPR(ResourceCache, RemovePackageFile, (PackageFile*, bool, bool), void), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ResourceCache", "void RemovePackageFile(const String&in, bool releaseResources = true, bool forceRelease = false)", asMETHODPR(ResourceCache, RemovePackageFile, (const String&, bool, bool), void), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ResourceCache", "void ReleaseResource(const String&in, const String&in, bool force = false)", asFUNCTION(ResourceCacheReleaseResource), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("ResourceCache", "void ReleaseResources(const String&in, bool force = false)", asFUNCTION(ResourceCacheReleaseResources), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("ResourceCache", "void ReleaseResources(const String&in, const String&in, bool force = false)", asFUNCTION(ResourceCacheReleaseResourcesPartial), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("ResourceCache", "void ReleaseAllResources(bool force = false)", asMETHOD(ResourceCache, ReleaseAllResources), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "bool ReloadResource(Resource@+)", asMETHOD(ResourceCache, ReloadResource), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "bool Exists(const String&in) const", asMETHODPR(ResourceCache, Exists, (const String&) const, bool), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "File@ GetFile(const String&in)", asFUNCTION(ResourceCacheGetFile), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("ResourceCache", "String GetPreferredResourcePath(const String&in)", asMETHOD(ResourceCache, GetPreferredResourcePath), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ResourceCache", "String GetPreferredResourceDir(const String&in)", asMETHOD(ResourceCache, GetPreferredResourceDir), asCALL_THISCALL);
     engine->RegisterObjectMethod("ResourceCache", "Resource@+ GetResource(const String&in, const String&in)", asFUNCTION(ResourceCacheGetResource), asCALL_CDECL_OBJLAST);
     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);
     engine->RegisterObjectMethod("ResourceCache", "uint get_totalMemoryUse() const", asMETHOD(ResourceCache, GetTotalMemoryUse), asCALL_THISCALL);
+    engine->RegisterObjectMethod("ResourceCache", "Array<String>@ get_resourceDirs() const", asFUNCTION(ResourceCacheGetResourceDirs), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("ResourceCache", "Array<PackageFile@>@ get_packageFiles() const", asFUNCTION(ResourceCacheGetPackageFiles), asCALL_CDECL_OBJLAST);
     engine->RegisterGlobalFunction("ResourceCache@+ get_resourceCache()", asFUNCTION(GetResourceCache), asCALL_CDECL);
     engine->RegisterGlobalFunction("ResourceCache@+ get_cache()", asFUNCTION(GetResourceCache), asCALL_CDECL);
 }
@@ -134,16 +147,6 @@ static void DestructXMLElement(XMLElement* ptr)
     ptr->~XMLElement();
 }
 
-static void XMLElementRemoveChildDefault(XMLElement* ptr)
-{
-    ptr->RemoveChild();
-}
-
-static void XMLElementRemoveChildrenDefault(XMLElement* ptr)
-{
-    ptr->RemoveChildren();
-}
-
 static void XMLElementSetVariantVector(CScriptArray* value, XMLElement* ptr)
 {
     VariantVector src;
@@ -151,16 +154,6 @@ static void XMLElementSetVariantVector(CScriptArray* value, XMLElement* ptr)
     ptr->SetVariantVector(src);
 }
 
-static XMLElement XMLElementGetChildDefault(XMLElement* ptr)
-{
-    return ptr->GetChild();
-}
-
-static XMLElement XMLElementGetNextDefault(XMLElement* ptr)
-{
-    return ptr->GetNext();
-}
-
 static CScriptArray* XMLElementGetAttributeNames(XMLElement* ptr)
 {
     return VectorToArray<String>(ptr->GetAttributeNames(), "Array<String>");
@@ -180,10 +173,8 @@ static void RegisterXMLElement(asIScriptEngine* engine)
     engine->RegisterObjectBehaviour("XMLElement", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructXMLElement), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("XMLElement", "XMLElement &opAssign(const XMLElement&in)", asMETHOD(XMLElement, operator =), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "XMLElement CreateChild(const String&in)", asMETHOD(XMLElement, CreateChild), asCALL_THISCALL);
-    engine->RegisterObjectMethod("XMLElement", "bool RemoveChild()", asFUNCTION(XMLElementRemoveChildDefault), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("XMLElement", "bool RemoveChild(const String&in, bool)", asMETHOD(XMLElement, RemoveChild), asCALL_THISCALL);
-    engine->RegisterObjectMethod("XMLElement", "bool RemoveChildren()", asFUNCTION(XMLElementRemoveChildrenDefault), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("XMLElement", "bool RemoveChildren(const String&in)", asMETHOD(XMLElement,RemoveChildren), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "bool RemoveChild(const String&in name = String(), bool last = true)", asMETHOD(XMLElement, RemoveChild), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "bool RemoveChildren(const String&in name = String())", asMETHOD(XMLElement,RemoveChildren), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool SetAttribute(const String&in, const String&in)", asMETHOD(XMLElement, SetAttribute), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool SetBool(const String&in, bool)", asMETHOD(XMLElement, SetBool), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool SetBoundingBox(const BoundingBox&in)", asMETHOD(XMLElement, SetBoundingBox), asCALL_THISCALL);
@@ -205,10 +196,8 @@ static void RegisterXMLElement(asIScriptEngine* engine)
     engine->RegisterObjectMethod("XMLElement", "String GetAttributes(const String&in) const", asMETHOD(XMLElement, GetAttribute), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "Array<String>@ GetAttributeNames() const", asFUNCTION(XMLElementGetAttributeNames), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("XMLElement", "bool HasChild(const String&in) const", asMETHOD(XMLElement, HasChild), asCALL_THISCALL);
-    engine->RegisterObjectMethod("XMLElement", "XMLElement GetChild() const", asFUNCTION(XMLElementGetChildDefault), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("XMLElement", "XMLElement GetChild(const String&in) const", asMETHOD(XMLElement, GetChild), asCALL_THISCALL);
-    engine->RegisterObjectMethod("XMLElement", "XMLElement GetNext() const", asFUNCTION(XMLElementGetNextDefault), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("XMLElement", "XMLElement GetNext(const String&in) const", asMETHOD(XMLElement, GetNext), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "XMLElement GetChild(const String&in name = String()) const", asMETHOD(XMLElement, GetChild), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLElement", "XMLElement GetNext(const String&in name = String()) const", asMETHOD(XMLElement, GetNext), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "bool GetBool(const String&in) const", asMETHOD(XMLElement, GetBool), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "BoundingBox GetBoundingBox() const", asMETHOD(XMLElement, GetBoundingBox), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLElement", "Color GetColor(const String&in) const", asMETHOD(XMLElement, GetColor), asCALL_THISCALL);
@@ -242,7 +231,7 @@ static XMLElement XMLFileGetRootDefault(XMLFile* ptr)
 static void RegisterXMLFile(asIScriptEngine* engine)
 {
     engine->RegisterObjectMethod("XMLFile", "XMLElement CreateRoot(const String&in)", asMETHOD(XMLFile, CreateRoot), asCALL_THISCALL);
-    engine->RegisterObjectMethod("XMLFile", "XMLElement GetRoot(const String&in)", asMETHOD(XMLFile, GetRoot), asCALL_THISCALL);
+    engine->RegisterObjectMethod("XMLFile", "XMLElement GetRoot(const String&in name = String())", asMETHOD(XMLFile, GetRoot), asCALL_THISCALL);
     engine->RegisterObjectMethod("XMLFile", "XMLElement get_root()", asFUNCTION(XMLFileGetRootDefault), asCALL_CDECL_OBJLAST);
 }
 

+ 1 - 1
Engine/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -1996,7 +1996,7 @@ bool Graphics::OpenWindow(int width, int height)
     wc.hInstance     = impl_->instance_;
     wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
     wc.hCursor       = LoadCursor(0, IDC_ARROW);
-    wc.hbrBackground = 0;
+    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
     wc.lpszMenuName  = 0;
     wc.lpszClassName = "D3DWindow";
     

+ 3 - 3
Engine/Network/Connection.cpp

@@ -385,7 +385,7 @@ void Connection::ProcessLoadScene(int msgID, MemoryBuffer& msg)
                 SharedPtr<PackageFile> newPackage(new PackageFile(context_, packageCacheDir + fileName));
                 if (newPackage->GetTotalSize() == fileSize && newPackage->GetChecksum() == checksum)
                 {
-                    // Add the package to the resource cache, as we will need it to load the scene
+                    // Add the package to the resource system now, as we will need it to load the scene
                     cache->AddPackageFile(newPackage, true);
                     found = true;
                     break;
@@ -393,14 +393,14 @@ void Connection::ProcessLoadScene(int msgID, MemoryBuffer& msg)
             }
         }
         
-        // Need to request a download
+        // Package not found, need to request a download
         if (!found)
         {
             if (!packageCacheDir.Empty())
                 RequestPackage(name, fileSize, checksum);
             else
             {
-                LOGERROR("Can not download required packages, as no package cache path is set");
+                LOGERROR("Can not download required packages, as package cache directory is not set");
                 OnSceneLoadFailed();
                 return;
             }

+ 1 - 1
Engine/Network/Network.h

@@ -122,6 +122,6 @@ private:
     float updateInterval_;
     /// Network update time accumulator
     float updateAcc_;
-    /// Package cache path
+    /// Package cache directory
     String packageCacheDir_;
 };

+ 2 - 2
Engine/Physics/CollisionShape.cpp

@@ -439,7 +439,7 @@ void CollisionShape::SetTriangleMesh(Model* model, unsigned lodLevel, const Vect
     CreateGeometry();
 }
 
-void CollisionShape::SetHeightfield(Model* model, const IntVector2& numPoints, float thickness, unsigned lodLevel, const Vector3& position, const Quaternion& rotation)
+void CollisionShape::SetHeightfield(Model* model, unsigned xPoints, unsigned zPoints, float thickness, unsigned lodLevel, const Vector3& position, const Quaternion& rotation)
 {
     PROFILE(SetHeightFieldShape);
     
@@ -453,7 +453,7 @@ void CollisionShape::SetHeightfield(Model* model, const IntVector2& numPoints, f
     
     model_ = model;
     shapeType_ = SHAPE_HEIGHTFIELD;
-    numPoints_ = numPoints;
+    numPoints_ = IntVector2(xPoints, zPoints);
     thickness_ = thickness;
     lodLevel_ = lodLevel;
     position_ = position;

+ 7 - 7
Engine/Physics/CollisionShape.h

@@ -107,19 +107,19 @@ public:
     /// Clear the collision geometry
     void Clear();
     /// Set as a sphere
-    void SetSphere(float radius, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
+    void SetSphere(float radius, const Vector3& position, const Quaternion& rotation);
     /// Set as a box
-    void SetBox(const Vector3& size, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
+    void SetBox(const Vector3& size, const Vector3& position, const Quaternion& rotation);
     /// Set as a cylinder
-    void SetCylinder(float radius, float height, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
+    void SetCylinder(float radius, float height, const Vector3& position, const Quaternion& rotation);
     /// Set as a capsule
-    void SetCapsule(float radius, float height, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
+    void SetCapsule(float radius, float height, const Vector3& position, const Quaternion& rotation);
     /// Set as a triangle mesh
-    void SetTriangleMesh(Model* model, unsigned lodLevel = M_MAX_UNSIGNED, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
+    void SetTriangleMesh(Model* model, unsigned lodLevel, const Vector3& position, const Quaternion& rotation);
     /// Set as a heightfield
-    void SetHeightfield(Model* model, const IntVector2& pointSize = IntVector2::ZERO, float thickness = 1.0f, unsigned lodLevel = M_MAX_UNSIGNED, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
+    void SetHeightfield(Model* model, unsigned xPoints, unsigned zPoints, float thickness, unsigned lodLevel, const Vector3& position, const Quaternion& rotation);
     /// Set as a convex hull (internally an ODE trimesh as well)
-    void SetConvexHull(Model* model, float skinWidth = 0.0f, unsigned lodLevel = M_MAX_UNSIGNED, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
+    void SetConvexHull(Model* model, float skinWidth, unsigned lodLevel, const Vector3& position, const Quaternion& rotation);
     /// Set offset position
     void SetPosition(const Vector3& position);
     /// Set rotation

+ 20 - 17
Engine/Resource/ResourceCache.cpp

@@ -61,25 +61,25 @@ ResourceCache::~ResourceCache()
 {
 }
 
-bool ResourceCache::AddResourcePath(const String& path)
+bool ResourceCache::AddResourceDir(const String& pathName)
 {
     FileSystem* fileSystem = GetSubsystem<FileSystem>();
-    if (!fileSystem || !fileSystem->DirExists(path))
+    if (!fileSystem || !fileSystem->DirExists(pathName))
     {
-        LOGERROR("Could not open directory " + path);
+        LOGERROR("Could not open directory " + pathName);
         return false;
     }
     
-    String fixedPath = AddTrailingSlash(path);
+    String fixedPath = AddTrailingSlash(pathName);
     
     // Check that the same path does not already exist
-    for (unsigned i = 0; i < resourcePaths_.Size(); ++i)
+    for (unsigned i = 0; i < resourceDirs_.Size(); ++i)
     {
-        if (!resourcePaths_[i].Compare(fixedPath, false))
+        if (!resourceDirs_[i].Compare(fixedPath, false))
             return true;
     }
     
-    resourcePaths_.Push(fixedPath);
+    resourceDirs_.Push(fixedPath);
     
     // Scan the path for files recursively and add their hash-to-name mappings
     Vector<String> fileNames;
@@ -132,14 +132,14 @@ bool ResourceCache::AddManualResource(Resource* resource)
     return true;
 }
 
-void ResourceCache::RemoveResourcePath(const String& path)
+void ResourceCache::RemoveResourceDir(const String& path)
 {
     String fixedPath = AddTrailingSlash(path);
-    for (Vector<String>::Iterator i = resourcePaths_.Begin(); i != resourcePaths_.End(); ++i)
+    for (Vector<String>::Iterator i = resourceDirs_.Begin(); i != resourceDirs_.End(); ++i)
     {
         if (!i->Compare(path, false))
         {
-            resourcePaths_.Erase(i);
+            resourceDirs_.Erase(i);
             return;
         }
     }
@@ -161,9 +161,12 @@ void ResourceCache::RemovePackageFile(PackageFile* package, bool ReleaseResource
 
 void ResourceCache::RemovePackageFile(const String& fileName, bool ReleaseResources, bool forceRelease)
 {
+    // Compare the name and extension only, not the path
+    String fileNameNoPath = GetFileNameAndExtension(fileName);
+    
     for (Vector<SharedPtr<PackageFile> >::Iterator i = packages_.Begin(); i != packages_.End(); ++i)
     {
-        if (!(*i)->GetName().Compare(fileName, false))
+        if (!GetFileNameAndExtension((*i)->GetName()).Compare(fileNameNoPath, false))
         {
             if (ReleaseResources)
                 ReleasePackageResources(*i, forceRelease);
@@ -316,13 +319,13 @@ SharedPtr<File> ResourceCache::GetFile(const String& name)
     FileSystem* fileSystem = GetSubsystem<FileSystem>();
     if (fileSystem)
     {
-        for (unsigned i = 0; i < resourcePaths_.Size(); ++i)
+        for (unsigned i = 0; i < resourceDirs_.Size(); ++i)
         {
-            if (fileSystem->FileExists(resourcePaths_[i] + name))
+            if (fileSystem->FileExists(resourceDirs_[i] + name))
             {
                 // Construct the file first with full path, then rename it to not contain the resource path,
                 // so that the file's name can be used in further GetFile() calls (for example over the network)
-                SharedPtr<File> file(new File(context_, resourcePaths_[i] + name));
+                SharedPtr<File> file(new File(context_, resourceDirs_[i] + name));
                 file->SetName(name);
                 return file;
             }
@@ -408,9 +411,9 @@ bool ResourceCache::Exists(const String& name) const
     FileSystem* fileSystem = GetSubsystem<FileSystem>();
     if (fileSystem)
     {
-        for (unsigned i = 0; i < resourcePaths_.Size(); ++i)
+        for (unsigned i = 0; i < resourceDirs_.Size(); ++i)
         {
-            if (fileSystem->FileExists(resourcePaths_[i] + name))
+            if (fileSystem->FileExists(resourceDirs_[i] + name))
                 return true;
         }
     }
@@ -458,7 +461,7 @@ const String& ResourceCache::GetResourceName(StringHash nameHash) const
         return i->second_;
 }
 
-String ResourceCache::GetPreferredResourcePath(const String& path)
+String ResourceCache::GetPreferredResourceDir(const String& path)
 {
     String fixedPath = AddTrailingSlash(path);
     

+ 9 - 9
Engine/Resource/ResourceCache.h

@@ -57,14 +57,14 @@ public:
     /// Destruct. Free all resources
     virtual ~ResourceCache();
     
-    /// Add a resource load path
-    bool AddResourcePath(const String& path);
+    /// Add a resource load directory
+    bool AddResourceDir(const String& pathName);
     /// Add a package file for loading resources from
     void AddPackageFile(PackageFile* package, bool addAsFirst = false);
     /// Add a manually created resource. Must be uniquely named
     bool AddManualResource(Resource* resource);
-    /// Remove a resource load path
-    void RemoveResourcePath(const String& path);
+    /// Remove a resource load directory
+    void RemoveResourceDir(const String& pathName);
     /// Remove a package file. Optionally release the resources loaded from it
     void RemovePackageFile(PackageFile* package, bool ReleaseResources = true, bool forceRelease = false);
     /// Remove a package file by name. Optionally release the resources loaded from it
@@ -94,8 +94,8 @@ public:
     void GetResources(PODVector<Resource*>& result, ShortStringHash type) const;
     /// Return all loaded resources
     const Map<ShortStringHash, ResourceGroup>& GetAllResources() const { return resourceGroups_; }
-    /// Return added resource load paths
-    const Vector<String>& GetResourcePaths() const { return resourcePaths_; }
+    /// Return added resource load directories
+    const Vector<String>& GetResourceDirs() const { return resourceDirs_; }
     /// Return added package files
     const Vector<SharedPtr<PackageFile> >& GetPackageFiles() const { return packages_; }
     /// Template version of returning a resource by name
@@ -117,7 +117,7 @@ public:
     /// Return resource name from hash, or empty if not found
     const String& GetResourceName(StringHash nameHash) const;
     /// Return either the path itself or its parent, based on which of them has recognized resource subdirectories
-    String GetPreferredResourcePath(const String& path);
+    String GetPreferredResourceDir(const String& path);
     
 private:
     /// Find a resource
@@ -131,8 +131,8 @@ private:
     
     /// Resources by type
     Map<ShortStringHash, ResourceGroup> resourceGroups_;
-    /// Resource load paths
-    Vector<String> resourcePaths_;
+    /// Resource load directories
+    Vector<String> resourceDirs_;
     /// Package files
     Vector<SharedPtr<PackageFile> > packages_;
     /// Mapping of hashes to filenames

+ 14 - 6
Engine/Script/ScriptFile.cpp

@@ -166,7 +166,11 @@ bool ScriptFile::Execute(asIScriptFunction* function, const VariantVector& param
     if (!compiled_ || !function)
         return false;
     
-    asIScriptContext* context = script_->GetScriptFileContext();
+    // It is possible that executing the function causes us to unload. Therefore do not rely on member variables
+    // However, we are not prepared for the whole script system getting destroyed during execution (should never happen)
+    Script* scriptSystem = script_;
+    
+    asIScriptContext* context = scriptSystem->GetScriptFileContext();
     if (!context)
     {
         LOGERROR("Maximum script execution nesting level exceeded");
@@ -178,11 +182,11 @@ bool ScriptFile::Execute(asIScriptFunction* function, const VariantVector& param
     
     SetParameters(context, function, parameters);
     
-    script_->IncScriptNestingLevel();
+    scriptSystem->IncScriptNestingLevel();
     bool success = context->Execute() >= 0;
     if (unprepare)
         context->Unprepare();
-    script_->DecScriptNestingLevel();
+    scriptSystem->DecScriptNestingLevel();
     
     return success;
 }
@@ -206,7 +210,11 @@ bool ScriptFile::Execute(asIScriptObject* object, asIScriptFunction* method, con
     if (!compiled_ || !object || !method)
         return false;
     
-    asIScriptContext* context = script_->GetScriptFileContext();
+    // It is possible that executing the method causes us to unload. Therefore do not rely on member variables
+    // However, we are not prepared for the whole script system getting destroyed during execution (should never happen)
+    Script* scriptSystem = script_;
+    
+    asIScriptContext* context = scriptSystem->GetScriptFileContext();
     if (!context)
     {
         LOGERROR("Maximum script execution nesting level exceeded");
@@ -219,11 +227,11 @@ bool ScriptFile::Execute(asIScriptObject* object, asIScriptFunction* method, con
     context->SetObject(object);
     SetParameters(context, method, parameters);
     
-    script_->IncScriptNestingLevel();
+    scriptSystem->IncScriptNestingLevel();
     bool success = context->Execute() >= 0;
     if (unprepare)
         context->Unprepare();
-    script_->DecScriptNestingLevel();
+    scriptSystem->DecScriptNestingLevel();
     
     return success;
 }

+ 3 - 2
Urho3D/Urho3D.cpp

@@ -85,7 +85,7 @@ void Run(const char* cmdLine)
         {
             if (arguments[i][0] != '-')
             {
-                scriptFileName = arguments[i];
+                scriptFileName = GetInternalPath(arguments[i]);
                 break;
             }
         }
@@ -114,8 +114,9 @@ void Run(const char* cmdLine)
         context->GetSubsystem<Time>()->SetTimerPeriod(5);
     
         // Execute the Start function from the script file, then run the engine loop until exited
+        // Hold a shared pointer to the script file to make sure it is not unloaded during runtime
         engine->InitializeScripting();
-        ScriptFile* scriptFile = context->GetSubsystem<ResourceCache>()->GetResource<ScriptFile>(scriptFileName);
+        SharedPtr<ScriptFile> scriptFile(context->GetSubsystem<ResourceCache>()->GetResource<ScriptFile>(scriptFileName));
         if (scriptFile && scriptFile->Execute("void Start()"))
         {
             while (!engine->IsExiting())