Browse Source

Fixed performance problems caused by offscreen UI elements being queued for rendering unnecessarily. Fixed missing file extension filtering on Unix. Added String::StartsWith() & String::EndsWith() functions.

Lasse Öörni 14 years ago
parent
commit
861091d375

+ 2 - 2
Bin/Data/Scripts/Editor/EditorScene.as

@@ -290,9 +290,9 @@ void SceneRaycast(bool mouseClick)
             drawable = result[0].drawable;
             drawable = result[0].drawable;
             if (debug !is null)
             if (debug !is null)
                 drawable.DrawDebugGeometry(debug, false);
                 drawable.DrawDebugGeometry(debug, false);
+            if (mouseClick && input.mouseButtonPress[MOUSEB_LEFT])
+                SelectNode(drawable.node);
         }
         }
-        if (mouseClick && input.mouseButtonPress[MOUSEB_LEFT])
-            SelectNode(drawable.node);
     }
     }
 }
 }
 
 

+ 10 - 0
Engine/Container/String.cpp

@@ -584,6 +584,16 @@ unsigned String::FindLast(const String& str, unsigned startPos) const
     return NPOS;
     return NPOS;
 }
 }
 
 
+bool String::StartsWith(const String& str) const
+{
+    return Find(str) == 0;
+}
+
+bool String::EndsWith(const String& str) const
+{
+    return Find(str) == Length() - str.Length();
+}
+
 int String::Compare(const String& str, bool caseSensitive) const
 int String::Compare(const String& str, bool caseSensitive) const
 {
 {
     return Compare(str.CString(), caseSensitive);
     return Compare(str.CString(), caseSensitive);

+ 9 - 5
Engine/Container/StringBase.h

@@ -310,16 +310,20 @@ public:
     String ToUpper() const;
     String ToUpper() const;
     /// Return string in lowercase.
     /// Return string in lowercase.
     String ToLower() const;
     String ToLower() const;
-    /// Split string by a separator char.
+    /// Return substrings split by a separator char.
     Vector<String> Split(char separator) const;
     Vector<String> Split(char separator) const;
-    /// Find the first occurrence of a string, or NPOS if not found.
+    /// Return index to the first occurrence of a string, or NPOS if not found.
     unsigned Find(const String& str, unsigned startPos = 0) const;
     unsigned Find(const String& str, unsigned startPos = 0) const;
-    /// Find the first occurrence of a character, or NPOS if not found.
+    /// Return index to the first occurrence of a character, or NPOS if not found.
     unsigned Find(char c, unsigned startPos = 0) const;
     unsigned Find(char c, unsigned startPos = 0) const;
-    /// Find the last occurrence of a string, or NPOS if not found.
+    /// Return index to the last occurrence of a string, or NPOS if not found.
     unsigned FindLast(const String& str, unsigned startPos = NPOS) const;
     unsigned FindLast(const String& str, unsigned startPos = NPOS) const;
-    /// Find the last occurrence of a character, or NPOS if not found.
+    /// Return index to the last occurrence of a character, or NPOS if not found.
     unsigned FindLast(char c, unsigned startPos = NPOS) const;
     unsigned FindLast(char c, unsigned startPos = NPOS) const;
+    /// Return whether starts with a string.
+    bool StartsWith(const String& str) const;
+    /// Return whether ends with a string.
+    bool EndsWith(const String& str) const;
     /// Return the C string.
     /// Return the C string.
     const char* CString() const { return buffer_; }
     const char* CString() const { return buffer_; }
     /// Return length.
     /// Return length.

+ 8 - 2
Engine/IO/FileSystem.cpp

@@ -387,12 +387,12 @@ void FileSystem::ScanDirInternal(Vector<String>& result, String path, const Stri
     const String& filter, unsigned flags, bool recursive)
     const String& filter, unsigned flags, bool recursive)
 {
 {
     path = AddTrailingSlash(path);
     path = AddTrailingSlash(path);
-    String pathAndFilter = GetNativePath(path + filter);
     String deltaPath;
     String deltaPath;
     if (path.Length() > startPath.Length())
     if (path.Length() > startPath.Length())
         deltaPath = path.Substring(startPath.Length());
         deltaPath = path.Substring(startPath.Length());
     
     
     #ifdef WIN32
     #ifdef WIN32
+    String pathAndFilter = GetNativePath(path + filter);
     WIN32_FIND_DATA info;
     WIN32_FIND_DATA info;
     HANDLE handle = FindFirstFile(pathAndFilter.CString(), &info);
     HANDLE handle = FindFirstFile(pathAndFilter.CString(), &info);
     if (handle != INVALID_HANDLE_VALUE)
     if (handle != INVALID_HANDLE_VALUE)
@@ -420,6 +420,9 @@ void FileSystem::ScanDirInternal(Vector<String>& result, String path, const Stri
         FindClose(handle);
         FindClose(handle);
     }
     }
     #else
     #else
+    String filterExtension = filter.Substring(filter.Find('.'));
+    if (filterExtension.Find('*') != String::NPOS)
+        filterExtension.Clear();
     DIR *dir;
     DIR *dir;
     struct dirent *de;
     struct dirent *de;
     struct stat st;
     struct stat st;
@@ -440,7 +443,10 @@ void FileSystem::ScanDirInternal(Vector<String>& result, String path, const Stri
                         ScanDirInternal(result, path + fileName, startPath, filter, flags, recursive);
                         ScanDirInternal(result, path + fileName, startPath, filter, flags, recursive);
                 }
                 }
                 else if (flags & SCAN_FILES)
                 else if (flags & SCAN_FILES)
-                    result.Push(deltaPath + fileName);
+                {
+                    if (filterExtension.Empty() || fileName.EndsWith(filterExtension))
+                        result.Push(deltaPath + fileName);
+                }
             }
             }
         }
         }
         closedir(dir);
         closedir(dir);

+ 19 - 3
Engine/UI/UI.cpp

@@ -484,14 +484,14 @@ void UI::GetBatches(UIElement* element, IntRect currentScissor)
         {
         {
             while (j != children.End() && (*j)->GetPriority() == currentPriority)
             while (j != children.End() && (*j)->GetPriority() == currentPriority)
             {
             {
-                if ((*j)->IsVisible())
+                if (IsVisible(*j, currentScissor))
                     (*j)->GetBatches(batches_, quads_, currentScissor);
                     (*j)->GetBatches(batches_, quads_, currentScissor);
                 ++j;
                 ++j;
             }
             }
             // Now recurse into the children
             // Now recurse into the children
             while (i != j)
             while (i != j)
             {
             {
-                if ((*i)->IsVisible())
+                if (IsVisible(*i, currentScissor))
                     GetBatches(*i, currentScissor);
                     GetBatches(*i, currentScissor);
                 ++i;
                 ++i;
             }
             }
@@ -506,7 +506,8 @@ void UI::GetBatches(UIElement* element, IntRect currentScissor)
         {
         {
             if ((*i)->IsVisible())
             if ((*i)->IsVisible())
             {
             {
-                (*i)->GetBatches(batches_, quads_, currentScissor);
+                if (IsVisible(*i, currentScissor))
+                    (*i)->GetBatches(batches_, quads_, currentScissor);
                 GetBatches(*i, currentScissor);
                 GetBatches(*i, currentScissor);
             }
             }
             ++i;
             ++i;
@@ -514,6 +515,21 @@ void UI::GetBatches(UIElement* element, IntRect currentScissor)
     }
     }
 }
 }
 
 
+bool UI::IsVisible(UIElement* element, const IntRect& currentScissor)
+{
+    // First check element's visibility
+    if (!element->IsVisible())
+        return false;
+
+    // Then check element dimensions against the scissor rectangle
+    const IntVector2& screenPos = element->GetScreenPosition();
+    if (screenPos.x_ >= currentScissor.right_ || screenPos.x_ + element->GetWidth() <= currentScissor.left_ ||
+        screenPos.y_ >= currentScissor.bottom_ || screenPos.y_ + element->GetHeight() <= currentScissor.top_)
+        return false;
+    else
+        return true;
+}
+
 void UI::GetElementAt(UIElement*& result, UIElement* current, const IntVector2& position, bool activeOnly)
 void UI::GetElementAt(UIElement*& result, UIElement* current, const IntVector2& position, bool activeOnly)
 {
 {
     if (!current)
     if (!current)

+ 2 - 0
Engine/UI/UI.h

@@ -86,6 +86,8 @@ private:
     void Update(float timeStep, UIElement* element);
     void Update(float timeStep, UIElement* element);
     /// Generate batches from an UI element recursively.
     /// Generate batches from an UI element recursively.
     void GetBatches(UIElement* element, IntRect currentScissor);
     void GetBatches(UIElement* element, IntRect currentScissor);
+    /// Return whether element is visible and within the scissor rectangle
+    bool IsVisible(UIElement* element, const IntRect& currentScissor);
     /// Return UI element at screen position recursively.
     /// Return UI element at screen position recursively.
     void GetElementAt(UIElement*& result, UIElement* current, const IntVector2& position, bool activeOnly);
     void GetElementAt(UIElement*& result, UIElement* current, const IntVector2& position, bool activeOnly);
     /// Load a UI layout from an XML file recursively.
     /// Load a UI layout from an XML file recursively.

+ 2 - 1
Engine/UI/UIBatch.cpp

@@ -43,7 +43,7 @@ void UIBatch::AddQuad(UIElement& element, int x, int y, int width, int height, i
 {
 {
     if (!quads_)
     if (!quads_)
         return;
         return;
-    
+   
     UIQuad quad;
     UIQuad quad;
     const IntVector2& screenPos = element.GetScreenPosition();
     const IntVector2& screenPos = element.GetScreenPosition();
     
     
@@ -219,6 +219,7 @@ void UIBatch::Draw(Graphics* graphics) const
             *dest++ = topLeftUV.x_; *dest++ = bottomRightUV.y_;
             *dest++ = topLeftUV.x_; *dest++ = bottomRightUV.y_;
             
             
             *dest++ = bottomRight.x_; *dest++ = topLeft.y_; *dest++ = 0.0f;
             *dest++ = bottomRight.x_; *dest++ = topLeft.y_; *dest++ = 0.0f;
+
             *((unsigned*)dest) = quads[i].topRightColor_; dest++;
             *((unsigned*)dest) = quads[i].topRightColor_; dest++;
             *dest++ = bottomRightUV.x_; *dest++ = topLeftUV.y_;
             *dest++ = bottomRightUV.x_; *dest++ = topLeftUV.y_;