Browse Source

Reverted previous commit due to bugs and performance loss.
Removed the deprecated Physics subdirectory from ResourceCache directory heuristic.
Updated documentation.

Lasse Öörni 14 years ago
parent
commit
3abd7eee88

+ 1 - 1
Docs/GettingStarted.dox

@@ -145,7 +145,7 @@ Urho3D uses the following conventions and principles:
 
 - Path names use slash instead of backslash. Paths will be converted internally into the necessary format when calling into the operating system.
 
-- In the script API, properties are used whenever appropriate instead of Set... and Get... functions. If the setter and getter require index parameters, the property will use array-style indexing, and its name will be in plural. For example model->SetMaterial(0, myMaterial) in C++ would become model.materials[0] = myMaterial in script.
+- In the script API, properties are used whenever appropriate instead of %Set... and Get... functions. If the setter and getter require index parameters, the property will use array-style indexing, and its name will be in plural. For example model->SetMaterial(0, myMaterial) in C++ would become model.materials[0] = myMaterial in script.
 
 - Raw pointers are used whenever possible in the classes' public API. This simplifies exposing functions & classes to script, and is relatively safe, because SharedPtr & WeakPtr use intrusive reference counting.
 

+ 3 - 3
Engine/Container/Allocator.h

@@ -50,16 +50,16 @@ struct AllocatorNode
     /// Data follows
 };
 
-/// Initialize a fixed allocator with the allocation size and initial capacity
+/// Initialize a fixed-size allocator with the node size and initial capacity
 AllocatorBlock* AllocatorInitialize(unsigned nodeSize, unsigned initialCapacity = 1);
-/// Uninitialize a fixed allocator. Frees all blocks in the chain
+/// Uninitialize a fixed-size allocator. Frees all blocks in the chain
 void AllocatorUninitialize(AllocatorBlock* allocator);
 /// Reserve a node. Creates a new block if necessary
 void* AllocatorReserve(AllocatorBlock* allocator);
 /// Free a node. Does not free any blocks
 void AllocatorFree(AllocatorBlock* allocator, void* ptr);
 
-/// Template allocator class
+/// Template allocator class. Allocates fixed-size objects of a specific class
 template <class T> class Allocator
 {
 public:

+ 64 - 18
Engine/Container/Map.h

@@ -23,10 +23,11 @@
 
 #pragma once
 
-#include "Pair.h"
 #include "TreeBase.h"
+#include "Pair.h"
 
-// Based on http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
+// Based on Red Black Trees by Julienne Walker
+// http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
 
 /// Map template class using a red-black tree
 template <class T, class U> class Map : public TreeBase
@@ -371,28 +372,38 @@ private:
         else
         {
             Node head;
-            Node* t = &head;
-            Node* q = GetRoot();
-            Node* p = 0;
-            Node* g = 0;
+            Node* g, * t, * p, * q;
+            
             unsigned dir = 0;
             unsigned last;
             
+            t = &head;
+            g = p = 0;
+            q = GetRoot();
             t->SetChild(1, GetRoot());
             
             for (;;)
             {
-                unsigned oldSize = size_;
                 if (!q)
                 {
-                    q = AllocateNode(key, value);
-                    p->SetChild(dir, q);
-                    ret = q;
+                    p->SetChild(dir, q = ret = new Node(key, value));
                     ++size_;
                 }
+                else if ((IsRed(q->link_[0])) && (IsRed(q->link_[1])))
+                {
+                    q->isRed_ = true;
+                    q->link_[0]->isRed_ = false;
+                    q->link_[1]->isRed_ = false;
+                }
                 
-                BalanceInsert(size_ != oldSize, last, reinterpret_cast<TreeNodeBase*&>(g), reinterpret_cast<TreeNodeBase*&>(p), 
-                    reinterpret_cast<TreeNodeBase*&>(q), reinterpret_cast<TreeNodeBase*&>(t));
+                if ((IsRed(q)) && (IsRed(p)))
+                {
+                    unsigned dir2 = (t->link_[1] == g);
+                    if (q == p->link_[last])
+                        t->SetChild(dir2, RotateSingle(g, !last));
+                    else
+                        t->SetChild(dir2, RotateDouble(g, !last));
+                }
                 
                 if (q->pair_.first_ == key)
                 {
@@ -427,13 +438,15 @@ private:
             return false;
         
         Node head;
-        Node* q = &head;
-        Node* p = 0;
-        Node* g = 0;
+        Node* q, * p, *g;
         Node* f = 0;
         unsigned dir = 1;
         bool removed = false;
         
+        q = &head;
+        g = p = 0;
+        q->SetChild(1, GetRoot());
+        
         while (q->link_[dir])
         {
             unsigned last = dir;
@@ -444,9 +457,42 @@ private:
             
             if (q->pair_.first_ == key)
                 f = q;
-            
-            BalanceRemove(dir, last, reinterpret_cast<TreeNodeBase*&>(g), reinterpret_cast<TreeNodeBase*&>(p),
-                reinterpret_cast<TreeNodeBase*&>(q));
+             
+            if ((!IsRed(q)) && (!IsRed(q->link_[dir])))
+            {
+                if (IsRed(q->link_[!dir]))
+                {
+                    p->SetChild(last, RotateSingle(q, dir));
+                    p = p->GetChild(last);
+                }
+                else if (!IsRed(q->link_[!dir]))
+                {
+                    Node* s = p->GetChild(!last);
+                    
+                    if (s)
+                    {
+                        if ((!IsRed(s->link_[!last])) && (!IsRed(s->link_[last])))
+                        {
+                            p->isRed_ = false;
+                            s->isRed_ = true;
+                            q->isRed_ = true;
+                        }
+                        else
+                        {
+                            int dir2 = (g->link_[1] == p);
+                            if (IsRed(s->link_[last]))
+                                g->SetChild(dir2, RotateDouble(p, last));
+                            else if (IsRed(s->link_[!last]))
+                                g->SetChild(dir2, RotateSingle(p, last));
+                            
+                            Node* t = g->GetChild(dir2);
+                            q->isRed_ = t->isRed_ = true;
+                            t->link_[0]->isRed_ = false;
+                            t->link_[1]->isRed_ = false;
+                        }
+                    }
+                }
+            }
         }
         
         if (f)

+ 62 - 18
Engine/Container/Set.h

@@ -25,7 +25,8 @@
 
 #include "TreeBase.h"
 
-// Based on http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
+// Based on Red Black Trees by Julienne Walker
+// http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
 
 /// Set template class using a red-black tree
 template <class T> class Set : public TreeBase
@@ -316,28 +317,38 @@ private:
         else
         {
             Node head;
-            Node* t = &head;
-            Node* q = GetRoot();
-            Node* p = 0;
-            Node* g = 0;
+            Node* g, * t, * p, * q;
+            
             unsigned dir = 0;
             unsigned last;
             
+            t = &head;
+            g = p = 0;
+            q = GetRoot();
             t->SetChild(1, GetRoot());
             
             for (;;)
             {
-                unsigned oldSize = size_;
                 if (!q)
                 {
-                    q = AllocateNode(key);
-                    p->SetChild(dir, q);
-                    ret = q;
+                    p->SetChild(dir, q = ret = AllocateNode(key));
                     ++size_;
                 }
+                else if ((IsRed(q->link_[0])) && (IsRed(q->link_[1])))
+                {
+                    q->isRed_ = true;
+                    q->link_[0]->isRed_ = false;
+                    q->link_[1]->isRed_ = false;
+                }
                 
-                BalanceInsert(size_ != oldSize, last, reinterpret_cast<TreeNodeBase*&>(g), reinterpret_cast<TreeNodeBase*&>(p), 
-                    reinterpret_cast<TreeNodeBase*&>(q), reinterpret_cast<TreeNodeBase*&>(t));
+                if ((IsRed(q)) && (IsRed(p)))
+                {
+                    unsigned dir2 = (t->link_[1] == g);
+                    if (q == p->link_[last])
+                        t->SetChild(dir2, RotateSingle(g, !last));
+                    else
+                        t->SetChild(dir2, RotateDouble(g, !last));
+                }
                 
                 if (q->key_ == key)
                 {
@@ -371,13 +382,13 @@ private:
             return false;
         
         Node head;
-        Node* q = &head;
-        Node* p = 0;
-        Node* g = 0;
+        Node* q, * p, *g;
         Node* f = 0;
         unsigned dir = 1;
         bool removed = false;
         
+        q = &head;
+        g = p = 0;
         q->SetChild(1, GetRoot());
         
         while (q->link_[dir])
@@ -390,15 +401,48 @@ private:
             
             if (q->key_ == key)
                 f = q;
-            
-            BalanceRemove(dir, last, reinterpret_cast<TreeNodeBase*&>(g), reinterpret_cast<TreeNodeBase*&>(p),
-                reinterpret_cast<TreeNodeBase*&>(q));
+             
+            if ((!IsRed(q)) && (!IsRed(q->link_[dir])))
+            {
+                if (IsRed(q->link_[!dir]))
+                {
+                    p->SetChild(last, RotateSingle(q, dir));
+                    p = p->GetChild(last);
+                }
+                else if (!IsRed(q->link_[!dir]))
+                {
+                    Node* s = p->GetChild(!last);
+                    
+                    if (s)
+                    {
+                        if ((!IsRed(s->link_[!last])) && (!IsRed(s->link_[last])))
+                        {
+                            p->isRed_ = false;
+                            s->isRed_ = true;
+                            q->isRed_ = true;
+                        }
+                        else
+                        {
+                            int dir2 = (g->link_[1] == p);
+                            if (IsRed(s->link_[last]))
+                                g->SetChild(dir2, RotateDouble(p, last));
+                            else if (IsRed(s->link_[!last]))
+                                g->SetChild(dir2, RotateSingle(p, last));
+                            
+                            Node* t = g->GetChild(dir2);
+                            q->isRed_ = t->isRed_ = true;
+                            t->link_[0]->isRed_ = false;
+                            t->link_[1]->isRed_ = false;
+                        }
+                    }
+                }
+            }
         }
         
         if (f)
         {
             f->key_ = q->key_;
-            p->SetChild(p->GetChild(1) == q, q->link_[q->GetChild(0) == 0]);
+            p->SetChild(p->link_[1] == q, q->link_[q->link_[0] == 0]);
             FreeNode(q);
             --size_;
             removed = true;

+ 2 - 1
Engine/Container/Sort.h

@@ -28,7 +28,8 @@
 
 static const int QUICKSORT_THRESHOLD = 16;
 
-// Based on http://warp.povusers.org/SortComparison/
+// Based on Comparison of several sorting algorithms by Juha Nieminen
+// http://warp.povusers.org/SortComparison/
 
 /// Perform insertion sort on an array
 template <class T> void InsertionSort(RandomAccessIterator<T> begin, RandomAccessIterator<T> end)

+ 1 - 0
Engine/Container/Swap.cpp

@@ -23,6 +23,7 @@
 
 #include "ListBase.h"
 #include "StringBase.h"
+#include "TreeBase.h"
 #include "VectorBase.h"
 
 #include "Set.h"

+ 3 - 63
Engine/Container/TreeBase.h

@@ -26,7 +26,8 @@
 #include "Allocator.h"
 #include "Swap.h"
 
-// Based on http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
+// Based on Red Black Trees by Julienne Walker
+// http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx
 
 /// Red-black tree node base
 struct TreeNodeBase
@@ -154,7 +155,7 @@ public:
     
 protected:
     /// Check whether a node is red
-    bool isRed(TreeNodeBase* node) const { return (node) && (node->isRed_); }
+    bool IsRed(TreeNodeBase* node) const { return (node) && (node->isRed_); }
     
     /// Single rotation
     TreeNodeBase* RotateSingle(TreeNodeBase* node, unsigned dir)
@@ -177,67 +178,6 @@ protected:
         return RotateSingle(node, dir);
     }
     
-    /// Balance during an insert
-    void BalanceInsert(bool newNode, unsigned& last, TreeNodeBase*& g, TreeNodeBase*& p, TreeNodeBase*& q, TreeNodeBase*& t)
-    {
-        if (!newNode)
-        {
-            if ((isRed(q->link_[0])) && (isRed(q->link_[1])))
-            {
-                q->isRed_ = true;
-                q->link_[0]->isRed_ = false;
-                q->link_[1]->isRed_ = false;
-            }
-        }
-        
-        if ((isRed(q)) && (isRed(p)))
-        {
-            unsigned dir2 = (t->link_[1] == g);
-            if (q == p->link_[last])
-                t->SetChild(dir2, RotateSingle(g, !last));
-            else
-                t->SetChild(dir2, RotateDouble(g, !last));
-        }
-    }
-    
-    /// Balance during a remove
-    void BalanceRemove(unsigned& dir, unsigned& last, TreeNodeBase*& g, TreeNodeBase*& p, TreeNodeBase*& q)
-    {
-        if ((!isRed(q)) && (!isRed(q->link_[dir])))
-        {
-            if (isRed(q->link_[!dir]))
-            {
-                p->SetChild(last, RotateSingle(q, dir));
-                p = p->link_[last];
-            }
-            else if (!isRed(q->link_[!dir]))
-            {
-                TreeNodeBase* s = p->link_[!last];
-                
-                if (s)
-                {
-                    if ((!isRed(s->link_[!last])) && (!isRed(s->link_[last])))
-                    {
-                        p->isRed_ = false;
-                        s->isRed_ = true;
-                        q->isRed_ = true;
-                    }
-                    else
-                    {
-                        int dir2 = (g->link_[1] == p);
-                        if (isRed(s->link_[last]))
-                            g->SetChild(dir2, RotateDouble(p, last));
-                        else if (isRed(s->link_[!last]))
-                            g->SetChild(dir2, RotateSingle(p, last));
-                        q->isRed_ = g->link_[dir2]->isRed_ = true;
-                        g->link_[dir2]->link_[0]->isRed_ = false;
-                        g->link_[dir2]->link_[1]->isRed_ = false;
-                    }
-                }
-            }
-        }
-    }
-    
     /// Root node
     TreeNodeBase* root_;
     /// Node allocator

+ 1 - 1
Engine/Container/Vector.h

@@ -285,7 +285,7 @@ public:
             if (capacity_)
             {
                 newBuffer = reinterpret_cast<T*>(new unsigned char[capacity_ * sizeof(T)]);
-                // Move the data into the new buffer
+                 Move the data into the new buffer
                 ConstructElements(newBuffer, GetBuffer(), size_);
             }
             

+ 0 - 1
Engine/Resource/ResourceCache.cpp

@@ -40,7 +40,6 @@ static const String checkDirs[] = {
     "Models",
     "Music",
     "Particle",
-    "Physics",
     "Scripts",
     "Sounds",
     "Shaders",