mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[cpp] Fixed up memory issues & crashes. HashMap is a linked list atm, need a better replacement.
This commit is contained in:
parent
e7e240d109
commit
11d0a47360
@ -2,7 +2,7 @@ include_directories(include)
|
||||
file(GLOB INCLUDES "spine-cpp/include/**/*.h")
|
||||
file(GLOB SOURCES "spine-cpp/src/**/*.cpp")
|
||||
|
||||
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -Wall -std=c++03 -pedantic -fno-exceptions -fno-rtti")
|
||||
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -Wall -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic -std=c++03 -fno-exceptions -fno-rtti")
|
||||
add_library(spine-cpp STATIC ${SOURCES} ${INCLUDES})
|
||||
target_include_directories(spine-cpp PUBLIC spine-cpp/include)
|
||||
install(TARGETS spine-cpp DESTINATION dist/lib)
|
||||
|
||||
@ -3,7 +3,8 @@ project(spine_cpp_unit_test)
|
||||
|
||||
set(CMAKE_INSTALL_PREFIX "./")
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++ ")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic -std=c++03 -fno-exceptions -fno-rtti")
|
||||
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -Wall -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic -std=c++03 -fno-exceptions -fno-rtti")
|
||||
|
||||
include_directories(../spine-cpp/include teamcity minicppunit tests memory)
|
||||
|
||||
|
||||
@ -71,12 +71,14 @@ void Spine::TestSpineExtension::_free(void *mem, const char *file, int line) {
|
||||
}
|
||||
|
||||
printf("%s:%i (address %p): Double free or not allocated through SpineExtension\n", file, line, mem);
|
||||
DefaultSpineExtension::_free(mem, file, line);
|
||||
}
|
||||
|
||||
void Spine::TestSpineExtension::reportLeaks() {
|
||||
for (std::vector<Allocation>::iterator it = allocated.begin(); it != allocated.end(); it++) {
|
||||
printf("\"%s:%i (%zu bytes at %p)\n", it->fileName, it->line, it->size, it->address);
|
||||
}
|
||||
if (allocated.size() == 0) printf("No leaks detected");
|
||||
}
|
||||
|
||||
void Spine::TestSpineExtension::clearAllocations() {
|
||||
|
||||
@ -42,7 +42,7 @@ namespace Spine {
|
||||
const char* fileName;
|
||||
int line;
|
||||
|
||||
Allocation() : Allocation (0, 0, 0, 0) {
|
||||
Allocation() : address(0), size(0), fileName(0), line(0) {
|
||||
}
|
||||
|
||||
Allocation(void* a, size_t s, const char* f, int l) : address(a), size(s), fileName(f), line(l) {
|
||||
|
||||
@ -79,7 +79,7 @@ int main (int argc, char** argv) {
|
||||
TestSpineExtension* ext = new TestSpineExtension();
|
||||
SpineExtension::setInstance(ext);
|
||||
|
||||
reproduceIssue_776();
|
||||
reproduceIssue_776();
|
||||
|
||||
ext->reportLeaks();
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ namespace Spine {
|
||||
/// See http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data about Loading Skeleton Data in the Spine Runtimes Guide.
|
||||
///
|
||||
class AtlasAttachmentLoader : public AttachmentLoader {
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
AtlasAttachmentLoader(Atlas* atlas);
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
namespace Spine {
|
||||
class Attachment : public SpineObject {
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
Attachment(std::string name);
|
||||
|
||||
@ -45,7 +45,7 @@ namespace Spine {
|
||||
class ClippingAttachment;
|
||||
|
||||
class AttachmentLoader : public SpineObject {
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
AttachmentLoader();
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
AttachmentTimeline(int frameCount);
|
||||
|
||||
@ -59,7 +59,7 @@ namespace Spine {
|
||||
friend class ShearTimeline;
|
||||
friend class TranslateTimeline;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static void setYDown(bool inValue);
|
||||
|
||||
@ -52,7 +52,7 @@ namespace Spine {
|
||||
|
||||
/// The index of the bone in Skeleton.Bones
|
||||
const int getIndex();
|
||||
|
||||
|
||||
/// The name of the bone, which is unique within the skeleton.
|
||||
const std::string& getName();
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
namespace Spine {
|
||||
/// Attachment that has a polygon for bounds checking.
|
||||
class BoundingBoxAttachment : public VertexAttachment {
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
BoundingBoxAttachment(std::string name);
|
||||
};
|
||||
|
||||
@ -42,7 +42,7 @@ namespace Spine {
|
||||
|
||||
friend class SkeletonClipping;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
ClippingAttachment(std::string name);
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
namespace Spine {
|
||||
/// The interface for all constraints.
|
||||
class Constraint : public Updatable {
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
Constraint();
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
namespace Spine {
|
||||
/// Base class for frames that use an interpolation bezier curve.
|
||||
class CurveTimeline : public Timeline {
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
CurveTimeline(int frameCount);
|
||||
|
||||
@ -40,7 +40,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
DeformTimeline(int frameCount);
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
DrawOrderTimeline(int frameCount);
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
EventTimeline(int frameCount);
|
||||
|
||||
@ -75,194 +75,77 @@ namespace Spine {
|
||||
Entry* _entry;
|
||||
};
|
||||
|
||||
HashMap(size_t capacity = 65535) :
|
||||
HashMap() :
|
||||
_head(NULL),
|
||||
_hashFunction(),
|
||||
_capacity(capacity),
|
||||
_header(),
|
||||
_trailer(),
|
||||
_hashSize(0) {
|
||||
_hashTable.reserve(capacity);
|
||||
for (int i = 0; i < _capacity; ++i) {
|
||||
_hashTable.push_back(Entry());
|
||||
}
|
||||
|
||||
_header.prev = &_header;
|
||||
_header.next = &_trailer;
|
||||
_trailer.prev = &_header;
|
||||
_trailer.next = &_trailer;
|
||||
_size(0) {
|
||||
|
||||
}
|
||||
|
||||
~HashMap() {
|
||||
for (Iterator it = begin(); it != end(); ++it) {
|
||||
delete it._entry;
|
||||
}
|
||||
_hashSize = 0;
|
||||
}
|
||||
|
||||
size_t size() {
|
||||
return _hashSize;
|
||||
return _size;
|
||||
}
|
||||
|
||||
Iterator begin() {
|
||||
return Iterator(_header.next);
|
||||
return Iterator(_head);
|
||||
}
|
||||
|
||||
Iterator end() {
|
||||
return Iterator(&_trailer);
|
||||
return Iterator(NULL);
|
||||
}
|
||||
|
||||
std::pair<Iterator, bool> insert(const K& key, const V& value) {
|
||||
Iterator iter = find(key);
|
||||
|
||||
if (iter._entry != &_trailer) {
|
||||
return std::make_pair(iter, false);
|
||||
}
|
||||
|
||||
size_t index = hash(key);
|
||||
|
||||
Entry* entry = new (__FILE__, __LINE__) Entry();
|
||||
entry->_key = key;
|
||||
entry->_value = value;
|
||||
|
||||
_hashSize++;
|
||||
|
||||
if (_header.next == (&_trailer)) {
|
||||
_hashTable[index].next = entry;
|
||||
_hashTable[index].prev = entry;
|
||||
_header.next = entry;
|
||||
entry->prev = &_header;
|
||||
entry->next = &_trailer;
|
||||
_trailer.prev = entry;
|
||||
|
||||
return std::make_pair(Iterator(entry), true);
|
||||
}
|
||||
|
||||
if (_hashTable[index].next == NULL) {
|
||||
_hashTable[index].next = entry;
|
||||
_hashTable[index].prev = entry;
|
||||
if (index < hash(_header.next->_key)) {
|
||||
entry->next = _header.next;
|
||||
entry->prev = &_header;
|
||||
_header.next->prev = entry;
|
||||
_header.next = entry;
|
||||
void insert(const K& key, const V& value) {
|
||||
Entry* entry = find(key)._entry;
|
||||
if (entry) {
|
||||
entry->_key = key;
|
||||
entry->_value = value;
|
||||
} else {
|
||||
entry = new (__FILE__, __LINE__) Entry();
|
||||
entry->_key = key;
|
||||
entry->_value = value;
|
||||
|
||||
Entry* oldHead = _head;
|
||||
|
||||
if (oldHead) {
|
||||
_head = entry;
|
||||
oldHead->prev = entry;
|
||||
entry->next = oldHead;
|
||||
} else {
|
||||
_head = entry;
|
||||
}
|
||||
else {
|
||||
entry->next = &_trailer;
|
||||
entry->prev = _trailer.prev;
|
||||
_trailer.prev = entry;
|
||||
entry->prev->next = entry;
|
||||
}
|
||||
|
||||
return std::make_pair(Iterator(entry), true);
|
||||
}
|
||||
|
||||
if (index == hash(_header.next->_key)) {
|
||||
_header.next = entry;
|
||||
entry->next = _hashTable[index].next;
|
||||
entry->prev = &_header;
|
||||
_hashTable[index].next->prev = entry;
|
||||
_hashTable[index].next = entry;
|
||||
}
|
||||
else {
|
||||
entry->next = _hashTable[index].next;
|
||||
entry->prev = _hashTable[index].next->prev;
|
||||
entry->next->prev = entry;
|
||||
entry->prev->next = entry;
|
||||
_hashTable[index].next = entry;
|
||||
}
|
||||
|
||||
return std::make_pair(Iterator(entry), true);
|
||||
}
|
||||
|
||||
Iterator find(const K& key) {
|
||||
const size_t index = hash(key);
|
||||
Iterator iter(_hashTable[index].next);
|
||||
|
||||
if (iter._entry != NULL) {
|
||||
for ( ; hash(iter._entry->_key) == index ; ++iter) {
|
||||
if (iter._entry->_key == key) {
|
||||
return iter;
|
||||
}
|
||||
}
|
||||
for (Iterator it = begin(); it != end(); ++it) {
|
||||
if (it._entry && it.key() == key)
|
||||
return it;
|
||||
}
|
||||
|
||||
return Iterator(&_trailer);
|
||||
return end();
|
||||
}
|
||||
|
||||
Iterator erase(Iterator pos) {
|
||||
if (pos._entry != &_header && pos._entry != &_trailer) {
|
||||
Entry* next = pos._entry->next;
|
||||
|
||||
size_t index = hash(pos._entry->_key);
|
||||
|
||||
if (_hashTable[index].next == pos._entry && _hashTable[index].prev == pos._entry) {
|
||||
_hashTable[index].next = NULL;
|
||||
_hashTable[index].prev = NULL;
|
||||
|
||||
if (_header.next == pos._entry) {
|
||||
_header.next = pos._entry->next;
|
||||
pos._entry->next->prev = &_header;
|
||||
}
|
||||
else if (_trailer.prev == pos._entry) {
|
||||
_trailer.prev = pos._entry->prev;
|
||||
pos._entry->prev->next = &_trailer;
|
||||
}
|
||||
else {
|
||||
pos._entry->prev->next = pos._entry->next;
|
||||
pos._entry->next->prev = pos._entry->prev;
|
||||
}
|
||||
|
||||
delete pos._entry;
|
||||
}
|
||||
else if (_hashTable[index].next == pos._entry) {
|
||||
_hashTable[index].next = pos._entry->next;
|
||||
if (_header.next == pos._entry) {
|
||||
_header.next = pos._entry->next;
|
||||
pos._entry->next->prev = &_header;
|
||||
}
|
||||
else {
|
||||
pos._entry->prev->next = pos._entry->next;
|
||||
pos._entry->next->prev = pos._entry->prev;
|
||||
}
|
||||
|
||||
delete pos._entry;
|
||||
}
|
||||
else if (_hashTable[index].prev == pos._entry) {
|
||||
_hashTable[index].prev = pos._entry->prev;
|
||||
if (_trailer.prev == pos._entry) {
|
||||
_trailer.prev = pos._entry->prev;
|
||||
pos._entry->prev->next = &_trailer;
|
||||
}
|
||||
else {
|
||||
pos._entry->prev->next = pos._entry->next;
|
||||
pos._entry->next->prev = pos._entry->prev;
|
||||
}
|
||||
|
||||
delete pos._entry;
|
||||
}
|
||||
else {
|
||||
pos._entry->prev->next = pos._entry->next;
|
||||
pos._entry->next->prev = pos._entry->prev;
|
||||
|
||||
delete pos._entry;
|
||||
}
|
||||
|
||||
_hashSize--;
|
||||
|
||||
return Iterator(next);
|
||||
}
|
||||
|
||||
return Iterator(&_trailer);
|
||||
Entry* entry = pos._entry;
|
||||
Entry* prev = entry->prev;
|
||||
Entry* next = entry->next;
|
||||
|
||||
if (prev) prev->next = next;
|
||||
else _head = next;
|
||||
if (next) next->prev = entry->prev;
|
||||
|
||||
delete entry;
|
||||
return Iterator(next);
|
||||
}
|
||||
|
||||
V operator[](const K& key) {
|
||||
Iterator iter = find(key);
|
||||
|
||||
if (iter._entry != _trailer) {
|
||||
return iter._entry->_value;
|
||||
}
|
||||
|
||||
return V();
|
||||
return iter;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -272,18 +155,13 @@ namespace Spine {
|
||||
V _value;
|
||||
Entry* next;
|
||||
Entry* prev;
|
||||
|
||||
Entry () : next(NULL), prev(NULL) {}
|
||||
};
|
||||
|
||||
const H _hashFunction;
|
||||
const size_t _capacity;
|
||||
Vector<Entry> _hashTable;
|
||||
Entry _header;
|
||||
Entry _trailer;
|
||||
size_t _hashSize;
|
||||
|
||||
size_t hash(const K& key) {
|
||||
return _hashFunction(key) % _capacity;
|
||||
}
|
||||
Entry* _head;
|
||||
size_t _size;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ namespace Spine {
|
||||
friend class Skeleton;
|
||||
friend class IkConstraintTimeline;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
/// Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
@ -44,7 +44,7 @@ namespace Spine {
|
||||
friend class SkeletonJson;
|
||||
friend class AtlasAttachmentLoader;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
MeshAttachment(std::string name);
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
PathAttachment(std::string name);
|
||||
|
||||
@ -48,7 +48,7 @@ namespace Spine {
|
||||
friend class PathConstraintPositionTimeline;
|
||||
friend class PathConstraintSpacingTimeline;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
PathConstraint(PathConstraintData& data, Skeleton& skeleton);
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
PathConstraintSpacingTimeline(int frameCount);
|
||||
|
||||
@ -47,7 +47,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
PointAttachment(std::string name);
|
||||
|
||||
@ -48,7 +48,7 @@ namespace Spine {
|
||||
friend class SkeletonJson;
|
||||
friend class AtlasAttachmentLoader;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
RegionAttachment(std::string name);
|
||||
|
||||
@ -39,7 +39,7 @@ namespace Spine {
|
||||
friend class SkeletonJson;
|
||||
friend class AnimationState;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES = 2;
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
ScaleTimeline(int frameCount);
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
ShearTimeline(int frameCount);
|
||||
|
||||
@ -46,12 +46,17 @@ namespace Spine {
|
||||
friend class Skeleton;
|
||||
|
||||
public:
|
||||
class AttachmentKey : public SpineObject {
|
||||
class AttachmentKey {
|
||||
public:
|
||||
int _slotIndex;
|
||||
std::string _name;
|
||||
|
||||
AttachmentKey(int slotIndex = 0, std::string name = "");
|
||||
|
||||
AttachmentKey(const AttachmentKey &other) {
|
||||
this->_slotIndex = other._slotIndex;
|
||||
this->_name = other._name;
|
||||
}
|
||||
|
||||
bool operator==(const AttachmentKey &other) const;
|
||||
};
|
||||
|
||||
@ -37,9 +37,10 @@ namespace Spine {
|
||||
class SpineObject {
|
||||
public:
|
||||
void* operator new(size_t sz, const char* file, int line);
|
||||
void* operator new(size_t sz, void* ptr);
|
||||
void operator delete(void* p);
|
||||
virtual ~SpineObject();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -42,7 +42,7 @@ namespace Spine {
|
||||
class Event;
|
||||
|
||||
class Timeline : public SpineObject {
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
Timeline();
|
||||
|
||||
@ -44,7 +44,7 @@ namespace Spine {
|
||||
friend class Skeleton;
|
||||
friend class TransformConstraintTimeline;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
TransformConstraint(TransformConstraintData& data, Skeleton& skeleton);
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
TransformMode_OnlyTranslation = 7, // 0111
|
||||
TransformMode_NoRotationOrReflection = 1, // 0001
|
||||
TransformMode_NoScale = 2, // 0010
|
||||
TransformMode_NoScaleOrReflection = 6, // 0110
|
||||
TransformMode_NoScaleOrReflection = 6 // 0110
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Spine {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
|
||||
namespace Spine {
|
||||
class Updatable : public SpineObject {
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
Updatable();
|
||||
|
||||
@ -32,11 +32,12 @@
|
||||
#define Spine_Vector_h
|
||||
|
||||
#include <spine/Extension.h>
|
||||
#include <spine/SpineObject.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory>
|
||||
#include <assert.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/Extension.h>
|
||||
|
||||
namespace Spine {
|
||||
template <typename T>
|
||||
@ -45,106 +46,134 @@ namespace Spine {
|
||||
Vector() : _size(0), _capacity(0), _buffer(NULL) {
|
||||
// Empty
|
||||
}
|
||||
|
||||
|
||||
Vector(const Vector& inVector) : _size(inVector._size), _capacity(inVector._capacity), _buffer(NULL) {
|
||||
if (_capacity > 0) {
|
||||
_buffer = allocate(_capacity);
|
||||
for (size_t i = 0; i < _size; ++i) {
|
||||
_buffer[i] = inVector._buffer[i];
|
||||
construct(_buffer + i, inVector._buffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vector& operator=(Vector& inVector) {
|
||||
if (this != &inVector) {
|
||||
clear();
|
||||
deallocate(_buffer);
|
||||
_buffer = NULL;
|
||||
|
||||
_size = inVector._size;
|
||||
_capacity = inVector._capacity;
|
||||
|
||||
if (_capacity > 0) {
|
||||
_buffer = allocate(_capacity);
|
||||
for (size_t i = 0; i < _size; ++i) {
|
||||
construct(_buffer + i, inVector._buffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Vector() {
|
||||
clear();
|
||||
deallocate(_buffer);
|
||||
}
|
||||
|
||||
|
||||
bool contains(const T& inValue) {
|
||||
for (size_t i = 0; i < _size; ++i) {
|
||||
if (_buffer[i] == inValue) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int indexOf(const T& inValue) {
|
||||
for (size_t i = 0; i < _size; ++i) {
|
||||
if (_buffer[i] == inValue) {
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void push_back(const T& inValue) {
|
||||
if (_size == _capacity) {
|
||||
reserve();
|
||||
}
|
||||
|
||||
_buffer[_size++] = inValue;
|
||||
|
||||
construct(_buffer + _size++, inValue);
|
||||
}
|
||||
|
||||
|
||||
void insert(size_t inIndex, const T& inValue) {
|
||||
assert(inIndex < _size);
|
||||
|
||||
|
||||
if (_size == _capacity) {
|
||||
reserve();
|
||||
}
|
||||
|
||||
|
||||
for (size_t i = ++_size - 1; i > inIndex; --i) {
|
||||
_buffer[i] = _buffer[i - 1];
|
||||
construct(_buffer + i, _buffer[i - 1]);
|
||||
destroy(_buffer + (i - 1));
|
||||
}
|
||||
|
||||
_buffer[inIndex] = inValue;
|
||||
|
||||
construct(_buffer + inIndex, inValue);
|
||||
}
|
||||
|
||||
|
||||
void erase(size_t inIndex) {
|
||||
assert(inIndex < _size);
|
||||
|
||||
|
||||
--_size;
|
||||
|
||||
|
||||
if (inIndex != _size) {
|
||||
for (size_t i = inIndex; i < _size; ++i) {
|
||||
std::swap(_buffer[i], _buffer[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
destroy(_buffer + _size);
|
||||
}
|
||||
|
||||
|
||||
void clear() {
|
||||
for (size_t i = 0; i < _size; ++i) {
|
||||
destroy(_buffer + (_size - 1 - i));
|
||||
}
|
||||
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
|
||||
size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
|
||||
T& operator[](size_t inIndex) {
|
||||
assert(inIndex < _size);
|
||||
|
||||
|
||||
return _buffer[inIndex];
|
||||
}
|
||||
|
||||
|
||||
void reserve(size_t inCapacity = 0) {
|
||||
size_t newCapacity = inCapacity > 0 ? inCapacity : _capacity > 0 ? _capacity * 2 : 1;
|
||||
if (newCapacity > _capacity) {
|
||||
_buffer = (T*)SpineExtension::realloc<T>(_buffer, newCapacity, __FILE__, __LINE__);
|
||||
_buffer = SpineExtension::realloc<T>(_buffer, newCapacity, __FILE__, __LINE__);
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setSize(size_t inValue) {
|
||||
assert(inValue <= _capacity);
|
||||
|
||||
|
||||
_size = inValue;
|
||||
}
|
||||
|
||||
|
||||
T* begin() {
|
||||
return &_buffer[0];
|
||||
}
|
||||
|
||||
|
||||
T* end() {
|
||||
return &_buffer[_size];
|
||||
}
|
||||
@ -166,28 +195,38 @@ namespace Spine {
|
||||
friend bool operator!=(Vector<T>& lhs, Vector<T>& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
size_t _size;
|
||||
size_t _capacity;
|
||||
T* _buffer;
|
||||
|
||||
|
||||
T* allocate(size_t n) {
|
||||
assert(n > 0);
|
||||
|
||||
T* ptr = (T*)SpineExtension::alloc<T>(n, __FILE__, __LINE__);
|
||||
|
||||
|
||||
T* ptr = SpineExtension::alloc<T>(n, __FILE__, __LINE__);
|
||||
|
||||
assert(ptr);
|
||||
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
void deallocate(T* buffer) {
|
||||
if (_buffer) {
|
||||
SpineExtension::free<T>(buffer, __FILE__, __LINE__);
|
||||
// _buffer = 0;
|
||||
SpineExtension::free(buffer, __FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
void construct(T* buffer, const T& val) {
|
||||
/// This is a placement new operator
|
||||
/// which basically means we are contructing a new object
|
||||
/// using pre-allocated memory
|
||||
new (buffer) T(val);
|
||||
}
|
||||
|
||||
void destroy(T* buffer) {
|
||||
buffer->~T();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,7 @@ namespace Spine {
|
||||
friend class SkeletonJson;
|
||||
friend class DeformTimeline;
|
||||
|
||||
RTTI_DECL;
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
VertexAttachment(std::string name);
|
||||
|
||||
@ -64,7 +64,6 @@ namespace Spine {
|
||||
attachment._regionHeight = region.height;
|
||||
attachment._regionOriginalWidth = region.originalWidth;
|
||||
attachment._regionOriginalHeight = region.originalHeight;
|
||||
printf("New region attachment, %p %p\n", &attachmentP->getUVs(), &attachmentP->getOffset());
|
||||
return attachmentP;
|
||||
}
|
||||
|
||||
|
||||
@ -35,10 +35,11 @@
|
||||
#include <cstring>
|
||||
|
||||
namespace Spine {
|
||||
SpineExtension* SpineExtension::_instance = NULL;
|
||||
DefaultSpineExtension _defaultExtension;
|
||||
SpineExtension* SpineExtension::_instance = &_defaultExtension;
|
||||
|
||||
void SpineExtension::setInstance(SpineExtension* inValue) {
|
||||
assert(!_instance);
|
||||
assert(inValue);
|
||||
|
||||
_instance = inValue;
|
||||
}
|
||||
@ -81,7 +82,6 @@ namespace Spine {
|
||||
if (size == 0)
|
||||
return 0;
|
||||
void* ptr = ::malloc(size);
|
||||
printf("alloc %lu bytes at %p\n", size, ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -93,7 +93,6 @@ namespace Spine {
|
||||
if (ptr) {
|
||||
memset(ptr, 0, size);
|
||||
}
|
||||
printf("calloc %lu bytes at %p\n", size, ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -105,12 +104,10 @@ namespace Spine {
|
||||
mem = ::malloc(size);
|
||||
else
|
||||
mem = ::realloc(ptr, size);
|
||||
printf("realloc %lu bytes from %p to %p\n", size, ptr, mem);
|
||||
return mem;
|
||||
}
|
||||
|
||||
void DefaultSpineExtension::_free(void* mem, const char* file, int line) {
|
||||
printf("free %p\n", mem);
|
||||
::free(mem);
|
||||
}
|
||||
|
||||
|
||||
@ -656,7 +656,7 @@ namespace Spine {
|
||||
void Skeleton::sortPathConstraintAttachment(Skin* skin, int slotIndex, Bone& slotBone) {
|
||||
HashMap<Skin::AttachmentKey, Attachment*, Skin::HashAttachmentKey>& attachments = skin->getAttachments();
|
||||
|
||||
for (typename HashMap<Skin::AttachmentKey, Attachment*, Skin::HashAttachmentKey>::Iterator i = attachments.begin(); i != attachments.end(); ++i) {
|
||||
for (HashMap<Skin::AttachmentKey, Attachment*, Skin::HashAttachmentKey>::Iterator i = attachments.begin(); i != attachments.end(); ++i) {
|
||||
Skin::AttachmentKey key = i.key();
|
||||
if (key._slotIndex == slotIndex) {
|
||||
Attachment* value = i.value();
|
||||
|
||||
@ -60,12 +60,9 @@ namespace Spine {
|
||||
|
||||
Skin::~Skin() {
|
||||
HashMap<AttachmentKey, Attachment*, HashAttachmentKey>::Iterator i = _attachments.begin();
|
||||
printf("Disposing skin\n");
|
||||
for (; i != _attachments.end(); ++i) {
|
||||
printf("%p %s\n", i.value(), i.value()->getName().c_str());
|
||||
delete i.value();
|
||||
}
|
||||
printf("Disposing skin done\n");
|
||||
}
|
||||
|
||||
void Skin::addAttachment(int slotIndex, std::string name, Attachment* attachment) {
|
||||
|
||||
@ -37,6 +37,10 @@ namespace Spine {
|
||||
return SpineExtension::calloc<SpineObject>(sz, file, line);
|
||||
}
|
||||
|
||||
void *SpineObject::operator new(size_t sz, void* ptr) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void SpineObject::operator delete(void *p) {
|
||||
SpineExtension::free(p, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user