[cpp] Fixed up Skin and internal hashmap like structure.

This commit is contained in:
badlogic 2018-04-18 14:25:56 +02:00
parent bceee601ad
commit 6c29e8c2e9
8 changed files with 128 additions and 83 deletions

View File

@ -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++) {

View File

@ -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;
}

View File

@ -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>

View File

@ -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 {

View File

@ -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);

View File

@ -225,7 +225,7 @@ private:
buffer->~T();
}
Vector &operator=(const Vector &inVector) {};
// Vector &operator=(const Vector &inVector) {};
};
}

View File

@ -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);
}
}

View File

@ -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);
}
}