mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 07:14:55 +08:00
[cpp] Refactored hash map, it's really a linked list for simplicity
This commit is contained in:
parent
ed7dc4ea93
commit
2d41846b1f
@ -85,7 +85,7 @@ namespace Spine {
|
||||
|
||||
SkeletonData* _skeletonData;
|
||||
float _defaultMix;
|
||||
HashMap<AnimationPair, float, HashAnimationPair> _animationToMixTime;
|
||||
HashMap<AnimationPair, float> _animationToMixTime;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
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;
|
||||
};
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user