Browse Source

[cpp] Fixed up memory issues & crashes. HashMap is a linked list atm, need a better replacement.

badlogic 7 years ago
parent
commit
11d0a47360
49 changed files with 181 additions and 258 deletions
  1. 1 1
      spine-cpp/CMakeLists.txt
  2. 2 1
      spine-cpp/spine-cpp-unit-tests/CMakeLists.txt
  3. 2 0
      spine-cpp/spine-cpp-unit-tests/src/TestHarness.cpp
  4. 1 1
      spine-cpp/spine-cpp-unit-tests/src/TestHarness.h
  5. 2 2
      spine-cpp/spine-cpp-unit-tests/src/main.cpp
  6. 1 1
      spine-cpp/spine-cpp/include/spine/AtlasAttachmentLoader.h
  7. 1 1
      spine-cpp/spine-cpp/include/spine/Attachment.h
  8. 1 1
      spine-cpp/spine-cpp/include/spine/AttachmentLoader.h
  9. 1 1
      spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h
  10. 1 1
      spine-cpp/spine-cpp/include/spine/Bone.h
  11. 1 1
      spine-cpp/spine-cpp/include/spine/BoneData.h
  12. 1 1
      spine-cpp/spine-cpp/include/spine/BoundingBoxAttachment.h
  13. 1 1
      spine-cpp/spine-cpp/include/spine/ClippingAttachment.h
  14. 1 1
      spine-cpp/spine-cpp/include/spine/ColorTimeline.h
  15. 1 1
      spine-cpp/spine-cpp/include/spine/Constraint.h
  16. 1 1
      spine-cpp/spine-cpp/include/spine/CurveTimeline.h
  17. 1 1
      spine-cpp/spine-cpp/include/spine/DeformTimeline.h
  18. 1 1
      spine-cpp/spine-cpp/include/spine/DrawOrderTimeline.h
  19. 1 1
      spine-cpp/spine-cpp/include/spine/EventTimeline.h
  20. 44 166
      spine-cpp/spine-cpp/include/spine/HashMap.h
  21. 1 1
      spine-cpp/spine-cpp/include/spine/IkConstraint.h
  22. 1 1
      spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h
  23. 1 1
      spine-cpp/spine-cpp/include/spine/MeshAttachment.h
  24. 1 1
      spine-cpp/spine-cpp/include/spine/PathAttachment.h
  25. 1 1
      spine-cpp/spine-cpp/include/spine/PathConstraint.h
  26. 1 1
      spine-cpp/spine-cpp/include/spine/PathConstraintMixTimeline.h
  27. 1 1
      spine-cpp/spine-cpp/include/spine/PathConstraintPositionTimeline.h
  28. 1 1
      spine-cpp/spine-cpp/include/spine/PathConstraintSpacingTimeline.h
  29. 1 1
      spine-cpp/spine-cpp/include/spine/PointAttachment.h
  30. 1 1
      spine-cpp/spine-cpp/include/spine/RegionAttachment.h
  31. 1 1
      spine-cpp/spine-cpp/include/spine/RotateTimeline.h
  32. 1 1
      spine-cpp/spine-cpp/include/spine/ScaleTimeline.h
  33. 1 1
      spine-cpp/spine-cpp/include/spine/ShearTimeline.h
  34. 6 1
      spine-cpp/spine-cpp/include/spine/Skin.h
  35. 2 1
      spine-cpp/spine-cpp/include/spine/SpineObject.h
  36. 1 1
      spine-cpp/spine-cpp/include/spine/Timeline.h
  37. 1 1
      spine-cpp/spine-cpp/include/spine/TransformConstraint.h
  38. 1 1
      spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h
  39. 1 1
      spine-cpp/spine-cpp/include/spine/TransformMode.h
  40. 1 1
      spine-cpp/spine-cpp/include/spine/TranslateTimeline.h
  41. 1 1
      spine-cpp/spine-cpp/include/spine/TwoColorTimeline.h
  42. 1 1
      spine-cpp/spine-cpp/include/spine/Updatable.h
  43. 78 39
      spine-cpp/spine-cpp/include/spine/Vector.h
  44. 1 1
      spine-cpp/spine-cpp/include/spine/VertexAttachment.h
  45. 0 1
      spine-cpp/spine-cpp/src/spine/AtlasAttachmentLoader.cpp
  46. 3 6
      spine-cpp/spine-cpp/src/spine/Extension.cpp
  47. 1 1
      spine-cpp/spine-cpp/src/spine/Skeleton.cpp
  48. 0 3
      spine-cpp/spine-cpp/src/spine/Skin.cpp
  49. 4 0
      spine-cpp/spine-cpp/src/spine/SpineObject.cpp

+ 1 - 1
spine-cpp/CMakeLists.txt

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

+ 2 - 1
spine-cpp/spine-cpp-unit-tests/CMakeLists.txt

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

+ 2 - 0
spine-cpp/spine-cpp-unit-tests/src/TestHarness.cpp

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

+ 1 - 1
spine-cpp/spine-cpp-unit-tests/src/TestHarness.h

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

+ 2 - 2
spine-cpp/spine-cpp-unit-tests/src/main.cpp

@@ -79,7 +79,7 @@ int main (int argc, char** argv) {
 	TestSpineExtension* ext = new TestSpineExtension();
 	SpineExtension::setInstance(ext);
 
-	reproduceIssue_776();
+ 	reproduceIssue_776();
 
 	ext->reportLeaks();
-}
+}

+ 1 - 1
spine-cpp/spine-cpp/include/spine/AtlasAttachmentLoader.h

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

+ 1 - 1
spine-cpp/spine-cpp/include/spine/Attachment.h

@@ -37,7 +37,7 @@
 
 namespace Spine {
     class Attachment : public SpineObject {
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         Attachment(std::string name);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/AttachmentLoader.h

@@ -45,7 +45,7 @@ namespace Spine {
     class ClippingAttachment;
     
     class AttachmentLoader : public SpineObject {
-        RTTI_DECL;
+        RTTI_DECL
         
         AttachmentLoader();
         

+ 1 - 1
spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h

@@ -47,7 +47,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         AttachmentTimeline(int frameCount);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/Bone.h

@@ -59,7 +59,7 @@ namespace Spine {
         friend class ShearTimeline;
         friend class TranslateTimeline;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         static void setYDown(bool inValue);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/BoneData.h

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

+ 1 - 1
spine-cpp/spine-cpp/include/spine/BoundingBoxAttachment.h

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

+ 1 - 1
spine-cpp/spine-cpp/include/spine/ClippingAttachment.h

@@ -42,7 +42,7 @@ namespace Spine {
         
         friend class SkeletonClipping;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         ClippingAttachment(std::string name);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/ColorTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         static const int ENTRIES;

+ 1 - 1
spine-cpp/spine-cpp/include/spine/Constraint.h

@@ -36,7 +36,7 @@
 namespace Spine {
     /// The interface for all constraints.
     class Constraint : public Updatable {
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         Constraint();

+ 1 - 1
spine-cpp/spine-cpp/include/spine/CurveTimeline.h

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

+ 1 - 1
spine-cpp/spine-cpp/include/spine/DeformTimeline.h

@@ -40,7 +40,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         DeformTimeline(int frameCount);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/DrawOrderTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
     
     public:
         DrawOrderTimeline(int frameCount);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/EventTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         EventTimeline(int frameCount);

+ 44 - 166
spine-cpp/spine-cpp/include/spine/HashMap.h

@@ -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;
-                }
-                else {
-                    entry->next = &_trailer;
-                    entry->prev = _trailer.prev;
-                    _trailer.prev = entry;
-                    entry->prev->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;
                 }
-                
-                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;
     };
 }
 

+ 1 - 1
spine-cpp/spine-cpp/include/spine/IkConstraint.h

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

+ 1 - 1
spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         static const int ENTRIES;

+ 1 - 1
spine-cpp/spine-cpp/include/spine/MeshAttachment.h

@@ -44,7 +44,7 @@ namespace Spine {
         friend class SkeletonJson;
         friend class AtlasAttachmentLoader;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         MeshAttachment(std::string name);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/PathAttachment.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         PathAttachment(std::string name);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/PathConstraint.h

@@ -48,7 +48,7 @@ namespace Spine {
         friend class PathConstraintPositionTimeline;
         friend class PathConstraintSpacingTimeline;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         PathConstraint(PathConstraintData& data, Skeleton& skeleton);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/PathConstraintMixTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         static const int ENTRIES;

+ 1 - 1
spine-cpp/spine-cpp/include/spine/PathConstraintPositionTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         static const int ENTRIES;

+ 1 - 1
spine-cpp/spine-cpp/include/spine/PathConstraintSpacingTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         PathConstraintSpacingTimeline(int frameCount);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/PointAttachment.h

@@ -47,7 +47,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         PointAttachment(std::string name);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/RegionAttachment.h

@@ -48,7 +48,7 @@ namespace Spine {
         friend class SkeletonJson;
         friend class AtlasAttachmentLoader;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         RegionAttachment(std::string name);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/RotateTimeline.h

@@ -39,7 +39,7 @@ namespace Spine {
         friend class SkeletonJson;
         friend class AnimationState;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         static const int ENTRIES = 2;

+ 1 - 1
spine-cpp/spine-cpp/include/spine/ScaleTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         ScaleTimeline(int frameCount);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/ShearTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         ShearTimeline(int frameCount);

+ 6 - 1
spine-cpp/spine-cpp/include/spine/Skin.h

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

+ 2 - 1
spine-cpp/spine-cpp/include/spine/SpineObject.h

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

+ 1 - 1
spine-cpp/spine-cpp/include/spine/Timeline.h

@@ -42,7 +42,7 @@ namespace Spine {
     class Event;
     
     class Timeline : public SpineObject {
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         Timeline();

+ 1 - 1
spine-cpp/spine-cpp/include/spine/TransformConstraint.h

@@ -44,7 +44,7 @@ namespace Spine {
         friend class Skeleton;
         friend class TransformConstraintTimeline;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         TransformConstraint(TransformConstraintData& data, Skeleton& skeleton);

+ 1 - 1
spine-cpp/spine-cpp/include/spine/TransformConstraintTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         static const int ENTRIES;

+ 1 - 1
spine-cpp/spine-cpp/include/spine/TransformMode.h

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

+ 1 - 1
spine-cpp/spine-cpp/include/spine/TranslateTimeline.h

@@ -41,7 +41,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         static const int ENTRIES;

+ 1 - 1
spine-cpp/spine-cpp/include/spine/TwoColorTimeline.h

@@ -38,7 +38,7 @@ namespace Spine {
         friend class SkeletonBinary;
         friend class SkeletonJson;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         static const int ENTRIES;

+ 1 - 1
spine-cpp/spine-cpp/include/spine/Updatable.h

@@ -36,7 +36,7 @@
 
 namespace Spine {
     class Updatable : public SpineObject {
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         Updatable();

+ 78 - 39
spine-cpp/spine-cpp/include/spine/Vector.h

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

+ 1 - 1
spine-cpp/spine-cpp/include/spine/VertexAttachment.h

@@ -44,7 +44,7 @@ namespace Spine {
         friend class SkeletonJson;
         friend class DeformTimeline;
         
-        RTTI_DECL;
+        RTTI_DECL
         
     public:
         VertexAttachment(std::string name);

+ 0 - 1
spine-cpp/spine-cpp/src/spine/AtlasAttachmentLoader.cpp

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

+ 3 - 6
spine-cpp/spine-cpp/src/spine/Extension.cpp

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

+ 1 - 1
spine-cpp/spine-cpp/src/spine/Skeleton.cpp

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

+ 0 - 3
spine-cpp/spine-cpp/src/spine/Skin.cpp

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

+ 4 - 0
spine-cpp/spine-cpp/src/spine/SpineObject.cpp

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