Browse Source

[cpp] Refactored hash map, it's really a linked list for simplicity

badlogic 7 years ago
parent
commit
2d41846b1f

+ 1 - 1
spine-cpp/spine-cpp/include/spine/AnimationStateData.h

@@ -85,7 +85,7 @@ namespace Spine {
         
         SkeletonData* _skeletonData;
         float _defaultMix;
-        HashMap<AnimationPair, float, HashAnimationPair> _animationToMixTime;
+        HashMap<AnimationPair, float> _animationToMixTime;
     };
 }
 

+ 61 - 52
spine-cpp/spine-cpp/include/spine/HashMap.h

@@ -36,53 +36,57 @@
 #include <spine/SpineObject.h>
 
 namespace Spine {
-    template <typename K, typename V, typename H>
+    template <typename K, typename V>
     class HashMap : public SpineObject {
     private:
         class Entry;
         
     public:
-        class Iterator : public SpineObject {
-            friend class HashMap;
-            
+        class Pair {
         public:
-            explicit Iterator(Entry* entry = NULL) : _entry(entry) {
-            }
-            
-            Iterator& operator++() {
-				_entry = _entry->next;
-				return *this;
-			}
-            
-            bool operator==(const Iterator& p) const {
-                return _entry == p._entry;
-            }
-            
-            bool operator!=(const Iterator& p) const {
-                return _entry != p._entry;
+            explicit Pair(K& k, V& v) : key(k), value(v) {}
+
+            K& key;
+            V& value;
+        };
+
+        class Entries {
+        public:
+            friend class HashMap;
+
+            explicit Entries(Entry *entry) : _entry(NULL), _hasChecked(false) {
+                _start.next = entry;
+                _entry = &_start;
             }
-            
-            K& key() {
-                return _entry->_key;
+
+            Pair next() {
+                assert(_entry);
+                assert(_hasChecked);
+                _entry = _entry->next;
+                Pair pair(_entry->_key, _entry->_value);
+                _hasChecked = false;
+                return pair;
             }
-            
-            V& value() {
-                return _entry->_value;
+
+            bool hasNext() {
+                _hasChecked = true;
+                return _entry->next;
             }
-            
+
         private:
+            bool _hasChecked;
+            Entry _start;
             Entry* _entry;
         };
-        
+
         HashMap() :
         _head(NULL),
-        _hashFunction(),
         _size(0) {
         }
         
         ~HashMap() {
-            for (Iterator it = begin(); it != end(); ++it) {
-                delete it._entry;
+            for (Entry* entry = _head; entry != NULL; entry = entry->next) {
+                delete entry;
             }
         }
         
@@ -90,16 +94,8 @@ namespace Spine {
             return _size;
         }
         
-        Iterator begin() {
-            return Iterator(_head);
-        }
-        
-        Iterator end() {
-            return Iterator(NULL);
-        }
-        
-        void insert(const K& key, const V& value) {
-            Entry* entry = find(key)._entry;
+        void put(const K& key, const V& value) {
+            Entry* entry = find(key);
             if (entry) {
                 entry->_key = key;
                 entry->_value = value;
@@ -117,19 +113,18 @@ namespace Spine {
                 } else {
                     _head = entry;
                 }
+                _size++;
             }
         }
         
-        Iterator find(const K& key) {
-            for (Iterator it = begin(); it != end(); ++it) {
-                if (it._entry && it.key() == key)
-                    return it;
-            }
-            return end();
+        bool containsKey(const K& key) {
+            return find(key) != NULL;
         }
         
-        Iterator erase(Iterator pos) {
-            Entry* entry = pos._entry;
+        bool remove(const K& key) {
+            Entry* entry = find(key);
+            if (!entry) return false;
+
             Entry* prev = entry->prev;
             Entry* next = entry->next;
 
@@ -138,15 +133,30 @@ namespace Spine {
             if (next) next->prev = entry->prev;
 
             delete entry;
-            return Iterator(next);
+            _size--;
+
+            return true;
         }
         
         V operator[](const K& key) {
-            Iterator iter = find(key);
-            return iter;
+            Entry* entry = find(key);
+            if (entry) return entry->_value;
+            else assert(false);
+        }
+
+        Entries getEntries() {
+            return Entries(_head);
         }
         
     private:
+        Entry* find(const K& key) {
+            for (Entry* entry = _head; entry != NULL; entry = entry->next) {
+                if (entry->_key == key)
+                    return entry;
+            }
+            return NULL;
+        }
+
         class Entry : public SpineObject {
         public:
             K _key;
@@ -156,8 +166,7 @@ namespace Spine {
 
             Entry () : next(NULL), prev(NULL) {}
         };
-        
-        const H _hashFunction;
+
         Entry* _head;
         size_t _size;
     };

+ 2 - 2
spine-cpp/spine-cpp/include/spine/Skin.h

@@ -86,11 +86,11 @@ namespace Spine {
         void findAttachmentsForSlot(int slotIndex, Vector<Attachment*>& attachments);
 
         const String& getName();
-        HashMap<AttachmentKey, Attachment*, HashAttachmentKey>& getAttachments();
+        HashMap<AttachmentKey, Attachment*>& getAttachments();
         
     private:
         const String _name;
-        HashMap<AttachmentKey, Attachment*, HashAttachmentKey> _attachments;
+        HashMap<AttachmentKey, Attachment*> _attachments;
         
         /// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached.
         void attachAll(Skeleton& skeleton, Skin& oldSkin);

+ 2 - 9
spine-cpp/spine-cpp/src/spine/AnimationStateData.cpp

@@ -49,9 +49,7 @@ namespace Spine {
         assert(to != NULL);
         
         AnimationPair key(from, to);
-        HashMap<AnimationPair, float, HashAnimationPair>::Iterator i = _animationToMixTime.find(key);
-        _animationToMixTime.erase(i);
-        _animationToMixTime.insert(key, duration);
+        _animationToMixTime.put(key, duration);
     }
     
     float AnimationStateData::getMix(Animation* from, Animation* to) {
@@ -60,12 +58,7 @@ namespace Spine {
         
         AnimationPair key(from, to);
         
-        HashMap<AnimationPair, float, HashAnimationPair>::Iterator i = _animationToMixTime.find(key);
-        
-        if (i != _animationToMixTime.end()) {
-            return i.value();
-        }
-        
+        if (_animationToMixTime.containsKey(key)) return _animationToMixTime[key];
         return _defaultMix;
     }
     

+ 5 - 4
spine-cpp/spine-cpp/src/spine/Skeleton.cpp

@@ -625,12 +625,13 @@ namespace Spine {
     }
     
     void Skeleton::sortPathConstraintAttachment(Skin* skin, int slotIndex, Bone& slotBone) {
-        HashMap<Skin::AttachmentKey, Attachment*, Skin::HashAttachmentKey>& attachments = skin->getAttachments();
+        HashMap<Skin::AttachmentKey, Attachment*>& attachments = skin->getAttachments();
         
-        for (HashMap<Skin::AttachmentKey, Attachment*, Skin::HashAttachmentKey>::Iterator i = attachments.begin(); i != attachments.end(); ++i) {
-            Skin::AttachmentKey key = i.key();
+        for (HashMap<Skin::AttachmentKey, Attachment*>::Entries entries = attachments.getEntries(); entries.hasNext();) {
+            HashMap<Skin::AttachmentKey, Attachment*>::Pair pair = entries.next();
+            Skin::AttachmentKey& key = pair.key;
             if (key._slotIndex == slotIndex) {
-                Attachment* value = i.value();
+                Attachment* value = pair.value;
                 sortPathConstraintAttachment(value, slotBone);
             }
         }

+ 27 - 25
spine-cpp/spine-cpp/src/spine/Skin.cpp

@@ -58,42 +58,43 @@ namespace Spine {
     }
 
     Skin::~Skin() {
-        HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = _attachments.begin();
-        for (; i != _attachments.end(); ++i) {
-			delete i.value();
+        HashMap<AttachmentKey, Attachment*>::Entries entries = _attachments.getEntries();
+        while(entries.hasNext()) {
+            HashMap<AttachmentKey, Attachment*>::Pair pair = entries.next();
+			delete pair.value;
         }
     }
     
     void Skin::addAttachment(int slotIndex, const String& name, Attachment* attachment) {
         assert(attachment);
-        
-        _attachments.insert(AttachmentKey(slotIndex, name), attachment);
+        _attachments.put(AttachmentKey(slotIndex, name), attachment);
     }
     
     Attachment* Skin::getAttachment(int slotIndex, const String& name) {
-        HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = _attachments.find(AttachmentKey(slotIndex, name));
-        
-        Attachment* ret = NULL;
-        
-        if (i != _attachments.end()) {
-            ret = i.value();
+        AttachmentKey key(slotIndex, name);
+        if (_attachments.containsKey(key)) {
+            return _attachments[key];
+        } else {
+            return NULL;
         }
-        
-        return ret;
     }
     
     void Skin::findNamesForSlot(int slotIndex, Vector<String>& names) {
-        for (HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = _attachments.begin(); i != _attachments.end(); ++i) {
-            if (i.key()._slotIndex == slotIndex) {
-                names.add(i.key()._name);
+        HashMap<AttachmentKey, Attachment*>::Entries entries = _attachments.getEntries();
+        while(entries.hasNext()) {
+            HashMap<AttachmentKey, Attachment*>::Pair pair = entries.next();
+            if (pair.key._slotIndex == slotIndex) {
+                names.add(pair.key._name);
             }
         }
     }
     
     void Skin::findAttachmentsForSlot(int slotIndex, Vector<Attachment*>& attachments) {
-        for (HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = _attachments.begin(); i != _attachments.end(); ++i) {
-            if (i.key()._slotIndex == slotIndex) {
-                attachments.add(i.value());
+        HashMap<AttachmentKey, Attachment*>::Entries entries = _attachments.getEntries();
+        while(entries.hasNext()) {
+            HashMap<AttachmentKey, Attachment*>::Pair pair = entries.next();
+            if (pair.key._slotIndex == slotIndex) {
+                attachments.add(pair.value);
             }
         }
     }
@@ -102,20 +103,21 @@ namespace Spine {
         return _name;
     }
     
-    HashMap<Skin::AttachmentKey, Attachment*, Skin::HashAttachmentKey>& Skin::getAttachments() {
+    HashMap<Skin::AttachmentKey, Attachment*>& Skin::getAttachments() {
         return _attachments;
     }
     
     void Skin::attachAll(Skeleton& skeleton, Skin& oldSkin) {
         Vector<Slot*>& slots = skeleton.getSlots();
-        
-        for (HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = oldSkin.getAttachments().begin(); i != oldSkin.getAttachments().end(); ++i) {
-            int slotIndex = i.key()._slotIndex;
+        HashMap<AttachmentKey, Attachment*>::Entries entries = oldSkin.getAttachments().getEntries();
+        while(entries.hasNext()) {
+            HashMap<AttachmentKey, Attachment*>::Pair pair = entries.next();
+            int slotIndex = pair.key._slotIndex;
             Slot* slot = slots[slotIndex];
             
-            if (slot->getAttachment() == i.value()) {
+            if (slot->getAttachment() == pair.value) {
                 Attachment* attachment = NULL;
-                if ((attachment = getAttachment(slotIndex, i.key()._name))) {
+                if ((attachment = getAttachment(slotIndex, pair.key._name))) {
                     slot->setAttachment(attachment);
                 }
             }