mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-26 22:49:01 +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;
|
SkeletonData* _skeletonData;
|
||||||
float _defaultMix;
|
float _defaultMix;
|
||||||
HashMap<AnimationPair, float, HashAnimationPair> _animationToMixTime;
|
HashMap<AnimationPair, float> _animationToMixTime;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,53 +36,57 @@
|
|||||||
#include <spine/SpineObject.h>
|
#include <spine/SpineObject.h>
|
||||||
|
|
||||||
namespace Spine {
|
namespace Spine {
|
||||||
template <typename K, typename V, typename H>
|
template <typename K, typename V>
|
||||||
class HashMap : public SpineObject {
|
class HashMap : public SpineObject {
|
||||||
private:
|
private:
|
||||||
class Entry;
|
class Entry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class Iterator : public SpineObject {
|
class Pair {
|
||||||
|
public:
|
||||||
|
explicit Pair(K& k, V& v) : key(k), value(v) {}
|
||||||
|
|
||||||
|
K& key;
|
||||||
|
V& value;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Entries {
|
||||||
|
public:
|
||||||
friend class HashMap;
|
friend class HashMap;
|
||||||
|
|
||||||
public:
|
explicit Entries(Entry *entry) : _entry(NULL), _hasChecked(false) {
|
||||||
explicit Iterator(Entry* entry = NULL) : _entry(entry) {
|
_start.next = entry;
|
||||||
|
_entry = &_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator& operator++() {
|
Pair next() {
|
||||||
_entry = _entry->next;
|
assert(_entry);
|
||||||
return *this;
|
assert(_hasChecked);
|
||||||
}
|
_entry = _entry->next;
|
||||||
|
Pair pair(_entry->_key, _entry->_value);
|
||||||
bool operator==(const Iterator& p) const {
|
_hasChecked = false;
|
||||||
return _entry == p._entry;
|
return pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Iterator& p) const {
|
bool hasNext() {
|
||||||
return _entry != p._entry;
|
_hasChecked = true;
|
||||||
}
|
return _entry->next;
|
||||||
|
|
||||||
K& key() {
|
|
||||||
return _entry->_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
V& value() {
|
|
||||||
return _entry->_value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _hasChecked;
|
||||||
|
Entry _start;
|
||||||
Entry* _entry;
|
Entry* _entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
HashMap() :
|
HashMap() :
|
||||||
_head(NULL),
|
_head(NULL),
|
||||||
_hashFunction(),
|
|
||||||
_size(0) {
|
_size(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~HashMap() {
|
~HashMap() {
|
||||||
for (Iterator it = begin(); it != end(); ++it) {
|
for (Entry* entry = _head; entry != NULL; entry = entry->next) {
|
||||||
delete it._entry;
|
delete entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,16 +94,8 @@ namespace Spine {
|
|||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator begin() {
|
void put(const K& key, const V& value) {
|
||||||
return Iterator(_head);
|
Entry* entry = find(key);
|
||||||
}
|
|
||||||
|
|
||||||
Iterator end() {
|
|
||||||
return Iterator(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void insert(const K& key, const V& value) {
|
|
||||||
Entry* entry = find(key)._entry;
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
entry->_key = key;
|
entry->_key = key;
|
||||||
entry->_value = value;
|
entry->_value = value;
|
||||||
@ -117,19 +113,18 @@ namespace Spine {
|
|||||||
} else {
|
} else {
|
||||||
_head = entry;
|
_head = entry;
|
||||||
}
|
}
|
||||||
|
_size++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator find(const K& key) {
|
bool containsKey(const K& key) {
|
||||||
for (Iterator it = begin(); it != end(); ++it) {
|
return find(key) != NULL;
|
||||||
if (it._entry && it.key() == key)
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
return end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator erase(Iterator pos) {
|
bool remove(const K& key) {
|
||||||
Entry* entry = pos._entry;
|
Entry* entry = find(key);
|
||||||
|
if (!entry) return false;
|
||||||
|
|
||||||
Entry* prev = entry->prev;
|
Entry* prev = entry->prev;
|
||||||
Entry* next = entry->next;
|
Entry* next = entry->next;
|
||||||
|
|
||||||
@ -138,15 +133,30 @@ namespace Spine {
|
|||||||
if (next) next->prev = entry->prev;
|
if (next) next->prev = entry->prev;
|
||||||
|
|
||||||
delete entry;
|
delete entry;
|
||||||
return Iterator(next);
|
_size--;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
V operator[](const K& key) {
|
V operator[](const K& key) {
|
||||||
Iterator iter = find(key);
|
Entry* entry = find(key);
|
||||||
return iter;
|
if (entry) return entry->_value;
|
||||||
|
else assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entries getEntries() {
|
||||||
|
return Entries(_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
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 {
|
class Entry : public SpineObject {
|
||||||
public:
|
public:
|
||||||
K _key;
|
K _key;
|
||||||
@ -157,7 +167,6 @@ namespace Spine {
|
|||||||
Entry () : next(NULL), prev(NULL) {}
|
Entry () : next(NULL), prev(NULL) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const H _hashFunction;
|
|
||||||
Entry* _head;
|
Entry* _head;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -86,11 +86,11 @@ namespace Spine {
|
|||||||
void findAttachmentsForSlot(int slotIndex, Vector<Attachment*>& attachments);
|
void findAttachmentsForSlot(int slotIndex, Vector<Attachment*>& attachments);
|
||||||
|
|
||||||
const String& getName();
|
const String& getName();
|
||||||
HashMap<AttachmentKey, Attachment*, HashAttachmentKey>& getAttachments();
|
HashMap<AttachmentKey, Attachment*>& getAttachments();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const String _name;
|
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.
|
/// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached.
|
||||||
void attachAll(Skeleton& skeleton, Skin& oldSkin);
|
void attachAll(Skeleton& skeleton, Skin& oldSkin);
|
||||||
|
|||||||
@ -49,9 +49,7 @@ namespace Spine {
|
|||||||
assert(to != NULL);
|
assert(to != NULL);
|
||||||
|
|
||||||
AnimationPair key(from, to);
|
AnimationPair key(from, to);
|
||||||
HashMap<AnimationPair, float, HashAnimationPair>::Iterator i = _animationToMixTime.find(key);
|
_animationToMixTime.put(key, duration);
|
||||||
_animationToMixTime.erase(i);
|
|
||||||
_animationToMixTime.insert(key, duration);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float AnimationStateData::getMix(Animation* from, Animation* to) {
|
float AnimationStateData::getMix(Animation* from, Animation* to) {
|
||||||
@ -60,12 +58,7 @@ namespace Spine {
|
|||||||
|
|
||||||
AnimationPair key(from, to);
|
AnimationPair key(from, to);
|
||||||
|
|
||||||
HashMap<AnimationPair, float, HashAnimationPair>::Iterator i = _animationToMixTime.find(key);
|
if (_animationToMixTime.containsKey(key)) return _animationToMixTime[key];
|
||||||
|
|
||||||
if (i != _animationToMixTime.end()) {
|
|
||||||
return i.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _defaultMix;
|
return _defaultMix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -625,12 +625,13 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Skeleton::sortPathConstraintAttachment(Skin* skin, int slotIndex, Bone& slotBone) {
|
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) {
|
for (HashMap<Skin::AttachmentKey, Attachment*>::Entries entries = attachments.getEntries(); entries.hasNext();) {
|
||||||
Skin::AttachmentKey key = i.key();
|
HashMap<Skin::AttachmentKey, Attachment*>::Pair pair = entries.next();
|
||||||
|
Skin::AttachmentKey& key = pair.key;
|
||||||
if (key._slotIndex == slotIndex) {
|
if (key._slotIndex == slotIndex) {
|
||||||
Attachment* value = i.value();
|
Attachment* value = pair.value;
|
||||||
sortPathConstraintAttachment(value, slotBone);
|
sortPathConstraintAttachment(value, slotBone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,42 +58,43 @@ namespace Spine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Skin::~Skin() {
|
Skin::~Skin() {
|
||||||
HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = _attachments.begin();
|
HashMap<AttachmentKey, Attachment*>::Entries entries = _attachments.getEntries();
|
||||||
for (; i != _attachments.end(); ++i) {
|
while(entries.hasNext()) {
|
||||||
delete i.value();
|
HashMap<AttachmentKey, Attachment*>::Pair pair = entries.next();
|
||||||
|
delete pair.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skin::addAttachment(int slotIndex, const String& name, Attachment* attachment) {
|
void Skin::addAttachment(int slotIndex, const String& name, Attachment* attachment) {
|
||||||
assert(attachment);
|
assert(attachment);
|
||||||
|
_attachments.put(AttachmentKey(slotIndex, name), attachment);
|
||||||
_attachments.insert(AttachmentKey(slotIndex, name), attachment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Attachment* Skin::getAttachment(int slotIndex, const String& name) {
|
Attachment* Skin::getAttachment(int slotIndex, const String& name) {
|
||||||
HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = _attachments.find(AttachmentKey(slotIndex, name));
|
AttachmentKey key(slotIndex, name);
|
||||||
|
if (_attachments.containsKey(key)) {
|
||||||
Attachment* ret = NULL;
|
return _attachments[key];
|
||||||
|
} else {
|
||||||
if (i != _attachments.end()) {
|
return NULL;
|
||||||
ret = i.value();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skin::findNamesForSlot(int slotIndex, Vector<String>& names) {
|
void Skin::findNamesForSlot(int slotIndex, Vector<String>& names) {
|
||||||
for (HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = _attachments.begin(); i != _attachments.end(); ++i) {
|
HashMap<AttachmentKey, Attachment*>::Entries entries = _attachments.getEntries();
|
||||||
if (i.key()._slotIndex == slotIndex) {
|
while(entries.hasNext()) {
|
||||||
names.add(i.key()._name);
|
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) {
|
void Skin::findAttachmentsForSlot(int slotIndex, Vector<Attachment*>& attachments) {
|
||||||
for (HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = _attachments.begin(); i != _attachments.end(); ++i) {
|
HashMap<AttachmentKey, Attachment*>::Entries entries = _attachments.getEntries();
|
||||||
if (i.key()._slotIndex == slotIndex) {
|
while(entries.hasNext()) {
|
||||||
attachments.add(i.value());
|
HashMap<AttachmentKey, Attachment*>::Pair pair = entries.next();
|
||||||
|
if (pair.key._slotIndex == slotIndex) {
|
||||||
|
attachments.add(pair.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,20 +103,21 @@ namespace Spine {
|
|||||||
return _name;
|
return _name;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap<Skin::AttachmentKey, Attachment*, Skin::HashAttachmentKey>& Skin::getAttachments() {
|
HashMap<Skin::AttachmentKey, Attachment*>& Skin::getAttachments() {
|
||||||
return _attachments;
|
return _attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skin::attachAll(Skeleton& skeleton, Skin& oldSkin) {
|
void Skin::attachAll(Skeleton& skeleton, Skin& oldSkin) {
|
||||||
Vector<Slot*>& slots = skeleton.getSlots();
|
Vector<Slot*>& slots = skeleton.getSlots();
|
||||||
|
HashMap<AttachmentKey, Attachment*>::Entries entries = oldSkin.getAttachments().getEntries();
|
||||||
for (HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = oldSkin.getAttachments().begin(); i != oldSkin.getAttachments().end(); ++i) {
|
while(entries.hasNext()) {
|
||||||
int slotIndex = i.key()._slotIndex;
|
HashMap<AttachmentKey, Attachment*>::Pair pair = entries.next();
|
||||||
|
int slotIndex = pair.key._slotIndex;
|
||||||
Slot* slot = slots[slotIndex];
|
Slot* slot = slots[slotIndex];
|
||||||
|
|
||||||
if (slot->getAttachment() == i.value()) {
|
if (slot->getAttachment() == pair.value) {
|
||||||
Attachment* attachment = NULL;
|
Attachment* attachment = NULL;
|
||||||
if ((attachment = getAttachment(slotIndex, i.key()._name))) {
|
if ((attachment = getAttachment(slotIndex, pair.key._name))) {
|
||||||
slot->setAttachment(attachment);
|
slot->setAttachment(attachment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user