From 2d41846b1f873d820ca2315c288932fe6ff529ad Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 22 Feb 2018 13:27:37 +0100 Subject: [PATCH] [cpp] Refactored hash map, it's really a linked list for simplicity --- .../include/spine/AnimationStateData.h | 2 +- spine-cpp/spine-cpp/include/spine/HashMap.h | 113 ++++++++++-------- spine-cpp/spine-cpp/include/spine/Skin.h | 4 +- .../src/spine/AnimationStateData.cpp | 11 +- spine-cpp/spine-cpp/src/spine/Skeleton.cpp | 9 +- spine-cpp/spine-cpp/src/spine/Skin.cpp | 52 ++++---- 6 files changed, 98 insertions(+), 93 deletions(-) diff --git a/spine-cpp/spine-cpp/include/spine/AnimationStateData.h b/spine-cpp/spine-cpp/include/spine/AnimationStateData.h index 6a8cc559b..2136f9862 100644 --- a/spine-cpp/spine-cpp/include/spine/AnimationStateData.h +++ b/spine-cpp/spine-cpp/include/spine/AnimationStateData.h @@ -85,7 +85,7 @@ namespace Spine { SkeletonData* _skeletonData; float _defaultMix; - HashMap _animationToMixTime; + HashMap _animationToMixTime; }; } diff --git a/spine-cpp/spine-cpp/include/spine/HashMap.h b/spine-cpp/spine-cpp/include/spine/HashMap.h index 5d74d567a..cca4b9aa4 100755 --- a/spine-cpp/spine-cpp/include/spine/HashMap.h +++ b/spine-cpp/spine-cpp/include/spine/HashMap.h @@ -36,53 +36,57 @@ #include namespace Spine { - template + template 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) { + 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; } - - Iterator& operator++() { - _entry = _entry->next; - return *this; - } - - bool operator==(const Iterator& p) const { - return _entry == p._entry; + + Pair next() { + assert(_entry); + assert(_hasChecked); + _entry = _entry->next; + Pair pair(_entry->_key, _entry->_value); + _hasChecked = false; + return pair; } - - bool operator!=(const Iterator& p) const { - return _entry != p._entry; + + bool hasNext() { + _hasChecked = true; + return _entry->next; } - - K& key() { - return _entry->_key; - } - - V& value() { - return _entry->_value; - } - + 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; }; diff --git a/spine-cpp/spine-cpp/include/spine/Skin.h b/spine-cpp/spine-cpp/include/spine/Skin.h index 33ecb35ea..f08ed7d99 100644 --- a/spine-cpp/spine-cpp/include/spine/Skin.h +++ b/spine-cpp/spine-cpp/include/spine/Skin.h @@ -86,11 +86,11 @@ namespace Spine { void findAttachmentsForSlot(int slotIndex, Vector& attachments); const String& getName(); - HashMap& getAttachments(); + HashMap& getAttachments(); private: const String _name; - HashMap _attachments; + HashMap _attachments; /// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached. void attachAll(Skeleton& skeleton, Skin& oldSkin); diff --git a/spine-cpp/spine-cpp/src/spine/AnimationStateData.cpp b/spine-cpp/spine-cpp/src/spine/AnimationStateData.cpp index 45f482153..673f6fb63 100644 --- a/spine-cpp/spine-cpp/src/spine/AnimationStateData.cpp +++ b/spine-cpp/spine-cpp/src/spine/AnimationStateData.cpp @@ -49,9 +49,7 @@ namespace Spine { assert(to != NULL); AnimationPair key(from, to); - HashMap::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::Iterator i = _animationToMixTime.find(key); - - if (i != _animationToMixTime.end()) { - return i.value(); - } - + if (_animationToMixTime.containsKey(key)) return _animationToMixTime[key]; return _defaultMix; } diff --git a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp index a9915ead0..557e4f44a 100644 --- a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp @@ -625,12 +625,13 @@ namespace Spine { } void Skeleton::sortPathConstraintAttachment(Skin* skin, int slotIndex, Bone& slotBone) { - HashMap& attachments = skin->getAttachments(); + HashMap& attachments = skin->getAttachments(); - for (HashMap::Iterator i = attachments.begin(); i != attachments.end(); ++i) { - Skin::AttachmentKey key = i.key(); + for (HashMap::Entries entries = attachments.getEntries(); entries.hasNext();) { + HashMap::Pair pair = entries.next(); + Skin::AttachmentKey& key = pair.key; if (key._slotIndex == slotIndex) { - Attachment* value = i.value(); + Attachment* value = pair.value; sortPathConstraintAttachment(value, slotBone); } } diff --git a/spine-cpp/spine-cpp/src/spine/Skin.cpp b/spine-cpp/spine-cpp/src/spine/Skin.cpp index f9a95c025..e25fc243d 100644 --- a/spine-cpp/spine-cpp/src/spine/Skin.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skin.cpp @@ -58,42 +58,43 @@ namespace Spine { } Skin::~Skin() { - HashMap::Iterator i = _attachments.begin(); - for (; i != _attachments.end(); ++i) { - delete i.value(); + HashMap::Entries entries = _attachments.getEntries(); + while(entries.hasNext()) { + HashMap::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::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& names) { - for (HashMap::Iterator i = _attachments.begin(); i != _attachments.end(); ++i) { - if (i.key()._slotIndex == slotIndex) { - names.add(i.key()._name); + HashMap::Entries entries = _attachments.getEntries(); + while(entries.hasNext()) { + HashMap::Pair pair = entries.next(); + if (pair.key._slotIndex == slotIndex) { + names.add(pair.key._name); } } } void Skin::findAttachmentsForSlot(int slotIndex, Vector& attachments) { - for (HashMap::Iterator i = _attachments.begin(); i != _attachments.end(); ++i) { - if (i.key()._slotIndex == slotIndex) { - attachments.add(i.value()); + HashMap::Entries entries = _attachments.getEntries(); + while(entries.hasNext()) { + HashMap::Pair pair = entries.next(); + if (pair.key._slotIndex == slotIndex) { + attachments.add(pair.value); } } } @@ -102,20 +103,21 @@ namespace Spine { return _name; } - HashMap& Skin::getAttachments() { + HashMap& Skin::getAttachments() { return _attachments; } void Skin::attachAll(Skeleton& skeleton, Skin& oldSkin) { Vector& slots = skeleton.getSlots(); - - for (HashMap::Iterator i = oldSkin.getAttachments().begin(); i != oldSkin.getAttachments().end(); ++i) { - int slotIndex = i.key()._slotIndex; + HashMap::Entries entries = oldSkin.getAttachments().getEntries(); + while(entries.hasNext()) { + HashMap::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); } }