Browse Source

Added hashing support to Pair template class.
Use HashMap & HashSet more.
Tweaked precompiled headers.

Lasse Öörni 14 years ago
parent
commit
20a2a48ed9

+ 1 - 2
Bin/Data/Scripts/SnowBall.as

@@ -32,7 +32,7 @@ class SnowBall : GameObject
 
         // Setup interest management for networking
         node.priority = 100.0;
-        node.priorityDistanceFactor = 0.04;
+        node.priorityDistanceFactor = 0.02;
         node.minPriority = 25.0;
 
         // Create model
@@ -43,7 +43,6 @@ class SnowBall : GameObject
         model.castShadows = true;
     
         // Create collision shape. Create as local to avoid divergent simulation by the client
-        // (as the client does not have the logic scripts that destroy the snowball immediately on collision)
         CollisionShape@ shape = node.CreateComponent("CollisionShape", LOCAL);
         shape.SetBox(Vector3(15, 15, 15), Vector3(), Quaternion());
         shape.collisionGroup = 1;

+ 2 - 2
Engine/Audio/Precompiled.h

@@ -23,7 +23,7 @@
 
 #pragma once
 
+#include "HashMap.h"
+#include "HashSet.h"
 #include "Map.h"
-#include "Set.h"
 #include "StringBase.h"
-

+ 102 - 0
Engine/Container/Hash.h

@@ -0,0 +1,102 @@
+//
+// Urho3D Engine
+// Copyright (c) 2008-2011 Lasse Öörni
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+/// Pointer hash function
+template <class T> unsigned MakeHash(T* value)
+{
+    return ((unsigned)value) / sizeof(T);
+}
+
+/// Const pointer hash function
+template <class T> unsigned MakeHash(const T* value)
+{
+    return ((unsigned)value) / sizeof(T);
+}
+
+/// Generic hash function
+template <class T> unsigned MakeHash(const T& value)
+{
+    return value.ToHash();
+}
+
+/// Void pointer hash function
+template<> inline unsigned MakeHash(void* value)
+{
+    return (unsigned)value;
+}
+
+/// Const void pointer hash function
+template<> inline unsigned MakeHash(const void* value)
+{
+    return (unsigned)value;
+}
+
+/// Long long hash function
+template<> inline unsigned MakeHash(const long long& value)
+{
+    return (value >> 32) | (value & 0xffffffff);
+}
+
+/// Unsigned long long hash function
+template<> inline unsigned MakeHash(const unsigned long long& value)
+{
+    return (value >> 32) | (value & 0xffffffff);
+}
+
+/// Int hash function
+template<> inline unsigned MakeHash(const int& value)
+{
+    return value;
+}
+
+/// Unsigned hash function
+template<> inline unsigned MakeHash(const unsigned& value)
+{
+    return value;
+}
+
+/// Short hash function
+template<> inline unsigned MakeHash(const short& value)
+{
+    return value;
+}
+
+/// Unsigned short hash function
+template<> inline unsigned MakeHash(const unsigned short& value)
+{
+    return value;
+}
+
+/// Char hash function
+template<> inline unsigned MakeHash(const char& value)
+{
+    return value;
+}
+
+/// Unsigned char hash function
+template<> inline unsigned MakeHash(const unsigned char& value)
+{
+    return value;
+}

+ 1 - 78
Engine/Container/HashBase.h

@@ -24,86 +24,9 @@
 #pragma once
 
 #include "Allocator.h"
+#include "Hash.h"
 #include "Swap.h"
 
-/// Pointer hash function
-template <class T> unsigned MakeHash(T* value)
-{
-    return ((unsigned)value) / sizeof(T);
-}
-
-/// Const pointer hash function
-template <class T> unsigned MakeHash(const T* value)
-{
-    return ((unsigned)value) / sizeof(T);
-}
-
-/// Generic hash function
-template <class T> unsigned MakeHash(const T& value)
-{
-    return value.ToHash();
-}
-
-/// Void pointer hash function
-template<> inline unsigned MakeHash(void* value)
-{
-    return (unsigned)value;
-}
-
-/// Const void pointer hash function
-template<> inline unsigned MakeHash(const void* value)
-{
-    return (unsigned)value;
-}
-
-/// Long long hash function
-template<> inline unsigned MakeHash(const long long& value)
-{
-    return (value >> 32) | (value & 0xffffffff);
-}
-
-/// Unsigned long long hash function
-template<> inline unsigned MakeHash(const unsigned long long& value)
-{
-    return (value >> 32) | (value & 0xffffffff);
-}
-
-/// Int hash function
-template<> inline unsigned MakeHash(const int& value)
-{
-    return value;
-}
-
-/// Unsigned hash function
-template<> inline unsigned MakeHash(const unsigned& value)
-{
-    return value;
-}
-
-/// Short hash function
-template<> inline unsigned MakeHash(const short& value)
-{
-    return value;
-}
-
-/// Unsigned short hash function
-template<> inline unsigned MakeHash(const unsigned short& value)
-{
-    return value;
-}
-
-/// Char hash function
-template<> inline unsigned MakeHash(const char& value)
-{
-    return value;
-}
-
-/// Unsigned char hash function
-template<> inline unsigned MakeHash(const unsigned char& value)
-{
-    return value;
-}
-
 /// Hash node base
 struct HashNodeBase
 {

+ 36 - 0
Engine/Container/HashMap.h

@@ -191,6 +191,42 @@ public:
         return *this;
     }
     
+    /// Test for equality with another hash map. Warning: this is much slower than checking equality of two maps
+    bool operator == (const HashMap<T, U>& rhs) const
+    {
+        if (rhs.size_ != size_)
+            return false;
+        
+        ConstIterator i = Begin();
+        while (i != End())
+        {
+            ConstIterator j = rhs.Find(i->first_);
+            if (j == rhs.End() || j->second_ != i->second_)
+                return false;
+            ++i;
+        }
+        
+        return true;
+    }
+    
+    /// Test for inequality with another hash map. Warning: this is much slower than checking inequality of two maps
+    bool operator != (const HashMap<T, U>& rhs) const
+    {
+        if (rhs.size_ != size_)
+            return true;
+        
+        ConstIterator i = Begin();
+        while (i != End())
+        {
+            ConstIterator j = rhs.Find(i->first_);
+            if (j == rhs.End() || j->second_ != i->second_)
+                return true;
+            ++i;
+        }
+        
+        return false;
+    }
+    
     /// Index the map. Create a new pair if key not found
     U& operator [] (const T& key)
     {

+ 34 - 0
Engine/Container/HashSet.h

@@ -162,6 +162,40 @@ public:
         return *this;
     }
     
+    /// Test for equality with another hash set. Warning: this is much slower than checking equality of two sets
+    bool operator == (const HashSet<T>& rhs) const
+    {
+        if (rhs.size_ != size_)
+            return false;
+        
+        ConstIterator i = Begin();
+        while (i != End())
+        {
+            if (!rhs.Contains(*i))
+                return false;
+            ++i;
+        }
+        
+        return true;
+    }
+    
+    /// Test for inequality with another hash set. Warning: this is much slower than checking inequality of two sets
+    bool operator != (const HashSet<T>& rhs) const
+    {
+        if (rhs.size_ != size_)
+            return true;
+        
+        ConstIterator i = Begin();
+        while (i != End())
+        {
+            if (!rhs.Contains(*i))
+                return true;
+            ++i;
+        }
+        
+        return false;
+    }
+    
     /// Insert a key. Return an iterator to it
     Iterator Insert(const T& key)
     {

+ 5 - 0
Engine/Container/Pair.h

@@ -23,6 +23,8 @@
 
 #pragma once
 
+#include "Hash.h"
+
 /// Pair template class
 template <class T, class U> class Pair
 {
@@ -64,6 +66,9 @@ public:
         return second_ > rhs.second_;
     }
     
+    /// Return hash value for HashSet & HashMap
+    unsigned ToHash() const { return (MakeHash(first_) & 0xffff) | (MakeHash(second_) << 16); }
+    
     /// First value
     T first_;
     /// Second value

+ 0 - 9
Engine/Container/Swap.cpp

@@ -27,15 +27,6 @@
 #include "TreeBase.h"
 #include "VectorBase.h"
 
-#include "Set.h"
-
-void Test()
-{
-    Set<int> testSet;
-    testSet.Insert(10);
-    testSet.Erase(10);
-}
-
 template<> void Swap<String>(String& first, String& second)
 {
     first.Swap(second);

+ 5 - 5
Engine/Core/Context.h

@@ -24,8 +24,8 @@
 #pragma once
 
 #include "Attribute.h"
+#include "HashSet.h"
 #include "Object.h"
-#include "Set.h"
 
 /// Execution context within a process. Provides access to the subsystems, object factories and attributes, and event receivers
 class Context : public RefCounted
@@ -81,7 +81,7 @@ public:
         {
             if (!dirtySpecificReceivers_.Empty())
             {
-                for (Set<Pair<Object*, StringHash> >::Iterator i = dirtySpecificReceivers_.Begin();
+                for (HashSet<Pair<Object*, StringHash> >::Iterator i = dirtySpecificReceivers_.Begin();
                     i != dirtySpecificReceivers_.End(); ++i)
                 {
                     PODVector<Object*>& receivers = specificEventReceivers_[*i];
@@ -98,7 +98,7 @@ public:
             
             if (!dirtyReceivers_.Empty())
             {
-                for (Set<StringHash>::Iterator i = dirtyReceivers_.Begin(); i != dirtyReceivers_.End(); ++i)
+                for (HashSet<StringHash>::Iterator i = dirtyReceivers_.Begin(); i != dirtyReceivers_.End(); ++i)
                 {
                     PODVector<Object*>& receivers = eventReceivers_[*i];
                     for (PODVector<Object*>::Iterator j = receivers.Begin(); j != receivers.End();)
@@ -187,9 +187,9 @@ private:
     /// Event sender stack
     PODVector<Object*> eventSenders_;
     /// Event types that have had receivers removed during event handling
-    Set<StringHash> dirtyReceivers_;
+    HashSet<StringHash> dirtyReceivers_;
     /// Event types for specific senders that have had receivers removed during event handling
-    Set<Pair<Object*, StringHash> > dirtySpecificReceivers_;
+    HashSet<Pair<Object*, StringHash> > dirtySpecificReceivers_;
     /// Active event handler. Not stored in a stack for performance reasons; is needed only in esoteric cases
     WeakPtr<EventHandler> eventHandler_;
 };

+ 1 - 1
Engine/Core/Object.cpp

@@ -177,7 +177,7 @@ void Object::SendEvent(StringHash eventType, VariantMap& eventData)
 {
     // Make a weak pointer to self to check for destruction during event handling
     WeakPtr<Object> self(this);
-    Set<Object*> processed;
+    HashSet<Object*> processed;
     
     context_->BeginSendEvent(this);
     

+ 1 - 0
Engine/Core/Object.h

@@ -23,6 +23,7 @@
 
 #pragma once
 
+#include "Map.h"
 #include "Ptr.h"
 #include "Variant.h"
 

+ 2 - 1
Engine/Core/Precompiled.h

@@ -23,6 +23,7 @@
 
 #pragma once
 
+#include "HashMap.h"
+#include "HashSet.h"
 #include "Map.h"
-#include "Set.h"
 #include "StringBase.h"

+ 2 - 2
Engine/Core/Variant.h

@@ -24,7 +24,7 @@
 #pragma once
 
 #include "Color.h"
-#include "Map.h"
+#include "HashMap.h"
 #include "Quaternion.h"
 #include "StringHash.h"
 #include "Vector4.h"
@@ -143,7 +143,7 @@ class Variant;
 /// Vector of variants
 typedef Vector<Variant> VariantVector;
 /// Map of variants
-typedef Map<ShortStringHash, Variant> VariantMap;
+typedef HashMap<ShortStringHash, Variant> VariantMap;
 
 /// Variable that supports a fixed set of types
 class Variant

+ 1 - 0
Engine/Engine/APITemplates.h

@@ -32,6 +32,7 @@
 #include "Resource.h"
 #include "Script.h"
 #include "ScriptInstance.h"
+#include "Set.h"
 #include "SoundSource.h"
 #include "Texture.h"
 

+ 2 - 0
Engine/Engine/Precompiled.h

@@ -23,5 +23,7 @@
 
 #pragma once
 
+#include "HashMap.h"
+#include "HashSet.h"
 #include "Map.h"
 #include "StringBase.h"

+ 2 - 1
Engine/Graphics/Batch.h

@@ -23,9 +23,10 @@
 
 #pragma once
 
+#include "GraphicsDefs.h"
 #include "HashMap.h"
+#include "Map.h"
 #include "MathDefs.h"
-#include "GraphicsDefs.h"
 #include "Ptr.h"
 #include "Vector4.h"
 

+ 0 - 1
Engine/Graphics/Precompiled.h

@@ -26,6 +26,5 @@
 #include "HashMap.h"
 #include "HashSet.h"
 #include "Map.h"
-#include "Set.h"
 #include "Sort.h"
 #include "StringBase.h"

+ 1 - 0
Engine/Graphics/View.cpp

@@ -36,6 +36,7 @@
 #include "Profiler.h"
 #include "Scene.h"
 #include "ShaderVariation.h"
+#include "Sort.h"
 #include "Technique.h"
 #include "Texture2D.h"
 #include "TextureCube.h"

+ 16 - 2
Engine/Graphics/View.h

@@ -26,7 +26,6 @@
 #include "Batch.h"
 #include "HashSet.h"
 #include "Object.h"
-#include "Set.h"
 
 class Camera;
 class DebugRenderer;
@@ -66,6 +65,21 @@ struct LitTransparencyCheck
     bool operator == (const LitTransparencyCheck& rhs) const { return light_ == rhs.light_ && drawable_ == rhs.drawable_ && batchIndex_ == rhs.batchIndex_; }
     /// Test for inequality with another lit transparency check
     bool operator != (const LitTransparencyCheck& rhs) const { return light_ != rhs.light_ || drawable_ != rhs.drawable_ || batchIndex_ != rhs.batchIndex_; }
+    
+    /// Test if less than another lit transparency check
+    bool operator < (const LitTransparencyCheck& rhs) const
+    {
+        if (light_ == rhs.light_)
+        {
+            if (drawable_ == rhs.drawable_)
+                return batchIndex_ < rhs.batchIndex_;
+            else
+                return drawable_ < rhs.drawable_;
+        }
+        else
+            return light_ < rhs.light_;
+    }
+    
     /// Return hash value for HashSet & HashMap
     unsigned ToHash() const { return ((unsigned)light_) / sizeof(Light) + ((unsigned)drawable_) / sizeof(Drawable) + batchIndex_; }
     
@@ -220,7 +234,7 @@ private:
     /// Lights
     PODVector<Light*> lights_;
     /// G-buffer size error displayed
-    Set<RenderSurface*> gBufferErrorDisplayed_;
+    HashSet<RenderSurface*> gBufferErrorDisplayed_;
     /// View-global shader parameters
     HashMap<StringHash, Vector4> shaderParameters_;
     

+ 2 - 1
Engine/IO/Precompiled.h

@@ -23,6 +23,7 @@
 
 #pragma once
 
+#include "HashMap.h"
+#include "HashSet.h"
 #include "Map.h"
-#include "Set.h"
 #include "StringBase.h"

+ 2 - 2
Engine/IO/Serializer.h

@@ -23,7 +23,7 @@
 
 #pragma once
 
-#include "Map.h"
+#include "HashMap.h"
 #include "StringHash.h"
 
 class Color;
@@ -39,7 +39,7 @@ struct ResourceRef;
 struct ResourceRefList;
 
 typedef Vector<Variant> VariantVector;
-typedef Map<ShortStringHash, Variant> VariantMap;
+typedef HashMap<ShortStringHash, Variant> VariantMap;
 
 /// Abstract stream for writing
 class Serializer

+ 2 - 0
Engine/Math/Precompiled.h

@@ -22,3 +22,5 @@
 //
 
 #pragma once
+
+#include "StringBase.h"

+ 1 - 1
Engine/Network/Precompiled.h

@@ -23,9 +23,9 @@
 
 #pragma once
 
+#include "HashMap.h"
 #include "HashSet.h"
 #include "Map.h"
-#include "Set.h"
 #include "StringBase.h"
 
 #include <kNet.h>

+ 2 - 3
Engine/Physics/PhysicsWorld.h

@@ -26,7 +26,6 @@
 #include "Component.h"
 #include "HashSet.h"
 #include "PhysicsDefs.h"
-#include "Set.h"
 #include "Vector3.h"
 
 class CollisionShape;
@@ -224,9 +223,9 @@ private:
     /// Collision contacts (PODVector<dContact>)
     void* contacts_;
     /// Collision pairs on this frame
-    Set<Pair<RigidBody*, RigidBody*> > currentCollisions_;
+    HashSet<Pair<RigidBody*, RigidBody*> > currentCollisions_;
     /// Collision pairs on the previous frame. Used to check if a collision is "new"
-    Set<Pair<RigidBody*, RigidBody*> > previousCollisions_;
+    HashSet<Pair<RigidBody*, RigidBody*> > previousCollisions_;
     /// Already processed rigid bodies during a poststep
     HashSet<RigidBody*> processedBodies_;
     /// Collision infos to be sent as events

+ 1 - 1
Engine/Physics/Precompiled.h

@@ -23,7 +23,7 @@
 
 #pragma once
 
+#include "HashMap.h"
 #include "HashSet.h"
 #include "Map.h"
-#include "Set.h"
 #include "StringBase.h"

+ 2 - 1
Engine/Resource/Precompiled.h

@@ -23,6 +23,7 @@
 
 #pragma once
 
+#include "HashMap.h"
+#include "HashSet.h"
 #include "Map.h"
-#include "Set.h"
 #include "StringBase.h"

+ 2 - 2
Engine/Resource/ResourceCache.cpp

@@ -514,7 +514,7 @@ const SharedPtr<Resource>& ResourceCache::FindResource(ShortStringHash type, Str
 
 void ResourceCache::ReleasePackageResources(PackageFile* package, bool force)
 {
-    Set<ShortStringHash> affectedGroups;
+    HashSet<ShortStringHash> affectedGroups;
     
     const Map<String, PackageEntry>& entries = package->GetEntries();
     for (Map<String, PackageEntry>::ConstIterator i = entries.Begin(); i != entries.End(); ++i)
@@ -539,7 +539,7 @@ void ResourceCache::ReleasePackageResources(PackageFile* package, bool force)
         }
     }
     
-    for (Set<ShortStringHash>::Iterator i = affectedGroups.Begin(); i != affectedGroups.End(); ++i)
+    for (HashSet<ShortStringHash>::Iterator i = affectedGroups.Begin(); i != affectedGroups.End(); ++i)
         UpdateResourceGroup(*i);
 }
 

+ 2 - 1
Engine/Scene/Precompiled.h

@@ -23,6 +23,7 @@
 
 #pragma once
 
+#include "HashMap.h"
+#include "HashSet.h"
 #include "Map.h"
-#include "Set.h"
 #include "StringBase.h"

+ 2 - 1
Engine/Script/Precompiled.h

@@ -23,6 +23,7 @@
 
 #pragma once
 
+#include "HashMap.h"
+#include "HashSet.h"
 #include "Map.h"
-#include "Set.h"
 #include "StringBase.h"

+ 2 - 2
Engine/UI/Precompiled.h

@@ -23,7 +23,7 @@
 
 #pragma once
 
+#include "HashMap.h"
+#include "HashSet.h"
 #include "Map.h"
-#include "Set.h"
-#include "Sort.h"
 #include "StringBase.h"

+ 2 - 2
Tools/OgreImporter/OgreImporter.cpp

@@ -650,7 +650,7 @@ void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubM
                 {
                     String name = anim.GetString("name");
                     float length = anim.GetFloat("length");
-                    Set<unsigned> usedPoses;
+                    HashSet<unsigned> usedPoses;
                     XMLElement tracks = anim.GetChild("tracks");
                     if (tracks)
                     {
@@ -688,7 +688,7 @@ void LoadMesh(const String& inputFileName, bool generateTangents, bool splitSubM
                         
                         unsigned bufIndex = 0;
                         
-                        for (Set<unsigned>::Iterator i = usedPoses.Begin(); i != usedPoses.End(); ++i)
+                        for (HashSet<unsigned>::Iterator i = usedPoses.Begin(); i != usedPoses.End(); ++i)
                         {
                             XMLElement pose = poses[*i];
                             unsigned targetSubMesh = pose.GetInt("index");