mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-15 03:21:35 +08:00
[cpp] Fixed up Skin and internal hashmap like structure.
This commit is contained in:
parent
bceee601ad
commit
6c29e8c2e9
@ -92,7 +92,7 @@ struct TestData {
|
||||
|
||||
void testLoading() {
|
||||
Vector<TestData> testData;
|
||||
testData.add(TestData("testdata/coin/coin-pro.json", "testdata/coin/coin-pro.skel", "testdata/coin/coin.atlas"));
|
||||
/*testData.add(TestData("testdata/coin/coin-pro.json", "testdata/coin/coin-pro.skel", "testdata/coin/coin.atlas"));
|
||||
testData.add(TestData("testdata/goblins/goblins-pro.json", "testdata/goblins/goblins-pro.skel",
|
||||
"testdata/goblins/goblins.atlas"));
|
||||
testData.add(TestData("testdata/raptor/raptor-pro.json", "testdata/raptor/raptor-pro.skel",
|
||||
@ -100,7 +100,7 @@ void testLoading() {
|
||||
testData.add(TestData("testdata/spineboy/spineboy-pro.json", "testdata/spineboy/spineboy-pro.skel",
|
||||
"testdata/spineboy/spineboy.atlas"));
|
||||
testData.add(TestData("testdata/stretchyman/stretchyman-pro.json", "testdata/stretchyman/stretchyman-pro.skel",
|
||||
"testdata/stretchyman/stretchyman.atlas"));
|
||||
"testdata/stretchyman/stretchyman.atlas"));*/
|
||||
testData.add(TestData("testdata/tank/tank-pro.json", "testdata/tank/tank-pro.skel", "testdata/tank/tank.atlas"));
|
||||
|
||||
for (size_t i = 0; i < testData.size(); i++) {
|
||||
|
||||
@ -42,11 +42,11 @@ public:
|
||||
clamp();
|
||||
}
|
||||
|
||||
inline Color &set(float r, float g, float b, float a) {
|
||||
r = r;
|
||||
g = g;
|
||||
b = b;
|
||||
a = a;
|
||||
inline Color &set(float _r, float _g, float _b, float _a) {
|
||||
this->r = _r;
|
||||
this->g = _g;
|
||||
this->b = _b;
|
||||
this->a = _a;
|
||||
clamp();
|
||||
return *this;
|
||||
}
|
||||
@ -60,11 +60,11 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Color &add(float r, float g, float b, float a) {
|
||||
r += r;
|
||||
g += g;
|
||||
b += b;
|
||||
a += a;
|
||||
inline Color &add(float _r, float _g, float _b, float _a) {
|
||||
this->r += _r;
|
||||
this->g += _g;
|
||||
this->b += _b;
|
||||
this->a += _a;
|
||||
clamp();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -34,7 +34,6 @@
|
||||
#include <spine/Extension.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/String.h>
|
||||
|
||||
namespace Spine {
|
||||
template<typename K, typename V>
|
||||
|
||||
@ -97,6 +97,8 @@ struct Interpolation {
|
||||
virtual float interpolate(float start, float end, float a) {
|
||||
return start + (end - start) * apply(a);
|
||||
}
|
||||
|
||||
virtual ~Interpolation() {};
|
||||
};
|
||||
|
||||
struct PowInterpolation: public Interpolation {
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
#ifndef Spine_Skin_h
|
||||
#define Spine_Skin_h
|
||||
|
||||
#include <spine/HashMap.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/String.h>
|
||||
|
||||
@ -47,34 +46,70 @@ class Skin : public SpineObject {
|
||||
friend class Skeleton;
|
||||
|
||||
public:
|
||||
class AttachmentKey : public SpineObject {
|
||||
class AttachmentMap : public SpineObject {
|
||||
friend class Skin;
|
||||
|
||||
public:
|
||||
int _slotIndex;
|
||||
String _name;
|
||||
struct Entry {
|
||||
int _slotIndex;
|
||||
String _name;
|
||||
Attachment *_attachment;
|
||||
|
||||
explicit AttachmentKey(int slotIndex = 0, const String &name = 0);
|
||||
Entry(int slotIndex, const String &name, Attachment *attachment) :
|
||||
_slotIndex(slotIndex),
|
||||
_name(name),
|
||||
_attachment(attachment) {
|
||||
}
|
||||
};
|
||||
|
||||
// Used in Skin::getAttachment to avoid allocation of temporary string
|
||||
explicit AttachmentKey(int slotIndex, const char* name);
|
||||
class Entries {
|
||||
friend class AttachmentMap;
|
||||
|
||||
AttachmentKey(const AttachmentKey &other) {
|
||||
this->_slotIndex = other._slotIndex;
|
||||
this->_name = other._name;
|
||||
}
|
||||
public:
|
||||
bool hasNext() {
|
||||
while(true) {
|
||||
if (_slotIndex >= (int) _buckets.size()) return false;
|
||||
if (_bucketIndex >= (int) _buckets[_slotIndex].size()) {
|
||||
_bucketIndex = 0;
|
||||
++_slotIndex;
|
||||
continue;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const AttachmentKey &other) const;
|
||||
Entry &next() {
|
||||
Entry &result = _buckets[_slotIndex][_bucketIndex];
|
||||
++_bucketIndex;
|
||||
return result;
|
||||
}
|
||||
|
||||
int getSlotIndex() {
|
||||
return _slotIndex;
|
||||
}
|
||||
protected:
|
||||
Entries(Vector< Vector<Entry> > &buckets) : _buckets(buckets), _slotIndex(0), _bucketIndex(0) {
|
||||
}
|
||||
|
||||
String& getName() {
|
||||
return _name;
|
||||
}
|
||||
};
|
||||
private:
|
||||
Vector< Vector<Entry> > &_buckets;
|
||||
int _slotIndex;
|
||||
int _bucketIndex;
|
||||
};
|
||||
|
||||
struct HashAttachmentKey : public SpineObject {
|
||||
std::size_t operator()(const Spine::Skin::AttachmentKey &val) const;
|
||||
void put(int slotIndex, const String &attachmentName, Attachment *attachment);
|
||||
|
||||
Attachment *get(int slotIndex, const String &attachmentName);
|
||||
|
||||
void remove(int slotIndex, const String &attachmentName);
|
||||
|
||||
Entries getEntries();
|
||||
|
||||
protected:
|
||||
AttachmentMap();
|
||||
|
||||
private:
|
||||
|
||||
int findInBucket(Vector <Entry> &, const String &attachmentName);
|
||||
|
||||
Vector <Vector<Entry> > _buckets;
|
||||
};
|
||||
|
||||
explicit Skin(const String &name);
|
||||
@ -100,11 +135,11 @@ public:
|
||||
|
||||
const String &getName();
|
||||
|
||||
HashMap<AttachmentKey, Attachment *> &getAttachments();
|
||||
AttachmentMap::Entries getAttachments();
|
||||
|
||||
private:
|
||||
const String _name;
|
||||
HashMap<AttachmentKey, Attachment *> _attachments;
|
||||
AttachmentMap _attachments;
|
||||
|
||||
/// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached.
|
||||
void attachAll(Skeleton &skeleton, Skin &oldSkin);
|
||||
|
||||
@ -225,7 +225,7 @@ private:
|
||||
buffer->~T();
|
||||
}
|
||||
|
||||
Vector &operator=(const Vector &inVector) {};
|
||||
// Vector &operator=(const Vector &inVector) {};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -602,13 +602,12 @@ void Skeleton::sortTransformConstraint(TransformConstraint *constraint) {
|
||||
}
|
||||
|
||||
void Skeleton::sortPathConstraintAttachment(Skin *skin, int slotIndex, Bone &slotBone) {
|
||||
HashMap<Skin::AttachmentKey, Attachment *> &attachments = skin->getAttachments();
|
||||
Skin::AttachmentMap::Entries attachments = skin->getAttachments();
|
||||
|
||||
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 = pair.value;
|
||||
while (attachments.hasNext()) {
|
||||
Skin::AttachmentMap::Entry entry = attachments.next();
|
||||
if (entry._slotIndex == slotIndex) {
|
||||
Attachment *value = entry._attachment;
|
||||
sortPathConstraintAttachment(value, slotBone);
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,70 +39,80 @@
|
||||
|
||||
using namespace Spine;
|
||||
|
||||
Skin::AttachmentKey::AttachmentKey(int slotIndex, const char* name) :
|
||||
_slotIndex(slotIndex),
|
||||
_name(name, true) {
|
||||
Skin::AttachmentMap::AttachmentMap() {
|
||||
}
|
||||
|
||||
Skin::AttachmentKey::AttachmentKey(int slotIndex, const String &name) :
|
||||
_slotIndex(slotIndex),
|
||||
_name(name) {
|
||||
void Skin::AttachmentMap::put(int slotIndex, const String &attachmentName, Attachment *attachment) {
|
||||
if (slotIndex >= _buckets.size())
|
||||
_buckets.setSize(slotIndex + 1, Vector<Entry>());
|
||||
Vector<Entry> &bucket = _buckets[slotIndex];
|
||||
int existing = findInBucket(bucket, attachmentName);
|
||||
if (existing >= 0) {
|
||||
bucket[existing]._attachment = attachment;
|
||||
} else {
|
||||
bucket.add(Entry(slotIndex, attachmentName, attachment));
|
||||
}
|
||||
}
|
||||
|
||||
bool Skin::AttachmentKey::operator==(const AttachmentKey &other) const {
|
||||
return _slotIndex == other._slotIndex && _name == other._name;
|
||||
Attachment *Skin::AttachmentMap::get(int slotIndex, const String &attachmentName) {
|
||||
if (slotIndex >= _buckets.size()) return NULL;
|
||||
int existing = findInBucket(_buckets[slotIndex], attachmentName);
|
||||
return existing >= 0 ? _buckets[slotIndex][existing]._attachment : NULL;
|
||||
}
|
||||
|
||||
std::size_t Skin::HashAttachmentKey::operator()(const Spine::Skin::AttachmentKey &val) const {
|
||||
std::size_t h1 = val._slotIndex;
|
||||
return h1;
|
||||
void Skin::AttachmentMap::remove(int slotIndex, const String &attachmentName) {
|
||||
if (slotIndex >= _buckets.size()) return;
|
||||
int existing = findInBucket(_buckets[slotIndex], attachmentName);
|
||||
if (existing >= 0) _buckets[slotIndex].removeAt(existing);
|
||||
}
|
||||
|
||||
Skin::Skin(const String &name) : _name(name) {
|
||||
int Skin::AttachmentMap::findInBucket(Vector<Entry> &bucket, const String &attachmentName) {
|
||||
for (size_t i = 0; i < bucket.size(); i++)
|
||||
if (bucket[i]._name == attachmentName) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Skin::AttachmentMap::Entries Skin::AttachmentMap::getEntries() {
|
||||
return Skin::AttachmentMap::Entries(_buckets);
|
||||
}
|
||||
|
||||
Skin::Skin(const String &name) : _name(name), _attachments() {
|
||||
assert(_name.length() > 0);
|
||||
}
|
||||
|
||||
Skin::~Skin() {
|
||||
HashMap<AttachmentKey, Attachment *>::Entries entries = _attachments.getEntries();
|
||||
Skin::AttachmentMap::Entries entries = _attachments.getEntries();
|
||||
while (entries.hasNext()) {
|
||||
HashMap<AttachmentKey, Attachment *>::Pair pair = entries.next();
|
||||
delete pair.value;
|
||||
Skin::AttachmentMap::Entry entry = entries.next();
|
||||
delete entry._attachment;
|
||||
}
|
||||
}
|
||||
|
||||
void Skin::addAttachment(int slotIndex, const String &name, Attachment *attachment) {
|
||||
assert(attachment);
|
||||
_attachments.put(AttachmentKey(slotIndex, name), attachment);
|
||||
_attachments.put(slotIndex, name, attachment);
|
||||
}
|
||||
|
||||
Attachment *Skin::getAttachment(int slotIndex, const String &name) {
|
||||
AttachmentKey key(slotIndex, name.buffer());
|
||||
if (_attachments.containsKey(key)) {
|
||||
Attachment *attachment = _attachments[key];
|
||||
key.getName().unown();
|
||||
return attachment;
|
||||
} else {
|
||||
key.getName().unown();
|
||||
return NULL;
|
||||
}
|
||||
return _attachments.get(slotIndex, name);
|
||||
}
|
||||
|
||||
void Skin::findNamesForSlot(int slotIndex, Vector<String> &names) {
|
||||
HashMap<AttachmentKey, Attachment *>::Entries entries = _attachments.getEntries();
|
||||
Skin::AttachmentMap::Entries entries = _attachments.getEntries();
|
||||
while (entries.hasNext()) {
|
||||
HashMap<AttachmentKey, Attachment *>::Pair pair = entries.next();
|
||||
if (pair.key._slotIndex == slotIndex) {
|
||||
names.add(pair.key._name);
|
||||
Skin::AttachmentMap::Entry &entry = entries.next();
|
||||
if (entry._slotIndex == slotIndex) {
|
||||
names.add(entry._name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Skin::findAttachmentsForSlot(int slotIndex, Vector<Attachment *> &attachments) {
|
||||
HashMap<AttachmentKey, Attachment *>::Entries entries = _attachments.getEntries();
|
||||
Skin::AttachmentMap::Entries entries = _attachments.getEntries();
|
||||
while (entries.hasNext()) {
|
||||
HashMap<AttachmentKey, Attachment *>::Pair pair = entries.next();
|
||||
if (pair.key._slotIndex == slotIndex) {
|
||||
attachments.add(pair.value);
|
||||
Skin::AttachmentMap::Entry &entry = entries.next();
|
||||
if (entry._slotIndex == slotIndex) {
|
||||
attachments.add(entry._attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -111,21 +121,21 @@ const String &Skin::getName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
HashMap<Skin::AttachmentKey, Attachment *> &Skin::getAttachments() {
|
||||
return _attachments;
|
||||
Skin::AttachmentMap::Entries Skin::getAttachments() {
|
||||
return _attachments.getEntries();
|
||||
}
|
||||
|
||||
void Skin::attachAll(Skeleton &skeleton, Skin &oldSkin) {
|
||||
Vector<Slot *> &slots = skeleton.getSlots();
|
||||
HashMap<AttachmentKey, Attachment *>::Entries entries = oldSkin.getAttachments().getEntries();
|
||||
Skin::AttachmentMap::Entries entries = oldSkin.getAttachments();
|
||||
while (entries.hasNext()) {
|
||||
HashMap<AttachmentKey, Attachment *>::Pair pair = entries.next();
|
||||
int slotIndex = pair.key._slotIndex;
|
||||
Skin::AttachmentMap::Entry &entry = entries.next();
|
||||
int slotIndex = entry._slotIndex;
|
||||
Slot *slot = slots[slotIndex];
|
||||
|
||||
if (slot->getAttachment() == pair.value) {
|
||||
if (slot->getAttachment() == entry._attachment) {
|
||||
Attachment *attachment = NULL;
|
||||
if ((attachment = getAttachment(slotIndex, pair.key._name))) {
|
||||
if ((attachment = getAttachment(slotIndex, entry._name))) {
|
||||
slot->setAttachment(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user