From 3254747e94f5411b04cd0f931e1a16b3000a95c2 Mon Sep 17 00:00:00 2001 From: badlogic Date: Tue, 13 Feb 2018 17:31:29 +0100 Subject: [PATCH] [c++] Removed old test harness, added new one, added leak detector, fixed new operator overloads, Vector doesn't copy on insert etc. See #1073 --- spine-cpp/spine-cpp-unit-tests/CMakeLists.txt | 36 +- spine-cpp/spine-cpp-unit-tests/main.cpp | 110 --- .../spine-cpp-unit-tests/memory/KMemory.cpp | 303 ------- .../spine-cpp-unit-tests/memory/KMemory.h | 189 ---- .../spine-cpp-unit-tests/memory/KString.cpp | 185 ---- .../spine-cpp-unit-tests/memory/KString.h | 19 - .../minicppunit/MiniCppUnit.cxx | 279 ------ .../minicppunit/MiniCppUnit.hxx | 504 ----------- .../spine_unit_test.xcodeproj/project.pbxproj | 831 ------------------ .../contents.xcworkspacedata | 7 - .../spine-cpp-unit-tests/src/TestHarness.cpp | 84 ++ .../spine-cpp-unit-tests/src/TestHarness.h | 72 ++ spine-cpp/spine-cpp-unit-tests/src/main.cpp | 51 ++ .../spine-cpp-unit-tests/teamcity/README.txt | 30 - .../teamcity/teamcity_cppunit.cpp | 82 -- .../teamcity/teamcity_cppunit.h | 83 -- .../teamcity/teamcity_messages.cpp | 174 ---- .../teamcity/teamcity_messages.h | 59 -- .../tests/CPP_InterfaceTestFixture.cpp | 48 - .../tests/CPP_InterfaceTestFixture.h | 47 - .../tests/C_InterfaceTestFixture.cpp | 175 ---- .../tests/C_InterfaceTestFixture.h | 33 - .../tests/EmptyTestFixture.cpp | 25 - .../tests/EmptyTestFixture.h | 26 - .../spine-cpp-unit-tests/tests/MemoryTest.h | 444 ---------- .../tests/MemoryTestFixture.cpp | 0 .../tests/MemoryTestFixture.h | 0 .../spine-cpp-unit-tests/tests/SimpleTest.h | 197 ----- .../tests/SpineEventMonitor.cpp | 181 ---- .../tests/SpineEventMonitor.h | 121 --- .../CPP_InterfaceTestFixture.cpp | 26 - .../CPP_InterfaceTestFixture.h | 30 - .../TestFixtureGenerator/_TestFixture.cpp | 26 - .../tests/TestFixtureGenerator/_TestFixture.h | 30 - .../tests/TestFixtureGenerator/fnr.exe | Bin 185200 -> 0 bytes .../TestFixtureGenerator/makeFixture.bat | 17 - .../spine-cpp-unit-tests/tests/TestOptions.h | 32 - spine-cpp/spine-cpp-unit-tests/tests/main.cpp | 119 --- spine-cpp/spine-cpp/include/spine/Atlas.h | 8 +- spine-cpp/spine-cpp/include/spine/Extension.h | 29 +- spine-cpp/spine-cpp/include/spine/HashMap.h | 2 +- spine-cpp/spine-cpp/include/spine/Pool.h | 2 +- .../spine-cpp/include/spine/SpineObject.h | 3 +- spine-cpp/spine-cpp/include/spine/Vector.h | 48 +- .../spine-cpp/src/spine/AnimationState.cpp | 4 +- spine-cpp/spine-cpp/src/spine/Atlas.cpp | 26 +- .../src/spine/AtlasAttachmentLoader.cpp | 12 +- spine-cpp/spine-cpp/src/spine/Extension.cpp | 4 +- spine-cpp/spine-cpp/src/spine/Json.cpp | 12 +- spine-cpp/spine-cpp/src/spine/Skeleton.cpp | 12 +- .../spine-cpp/src/spine/SkeletonBinary.cpp | 112 +-- .../spine-cpp/src/spine/SkeletonBounds.cpp | 2 +- .../spine-cpp/src/spine/SkeletonJson.cpp | 58 +- spine-cpp/spine-cpp/src/spine/SpineObject.cpp | 9 + spine-sfml/c/CMakeLists.txt | 44 - 55 files changed, 362 insertions(+), 4700 deletions(-) delete mode 100755 spine-cpp/spine-cpp-unit-tests/main.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/memory/KMemory.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/memory/KMemory.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/memory/KString.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/memory/KString.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/minicppunit/MiniCppUnit.cxx delete mode 100755 spine-cpp/spine-cpp-unit-tests/minicppunit/MiniCppUnit.hxx delete mode 100644 spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test.xcodeproj/project.pbxproj delete mode 100644 spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 spine-cpp/spine-cpp-unit-tests/src/TestHarness.cpp create mode 100644 spine-cpp/spine-cpp-unit-tests/src/TestHarness.h create mode 100644 spine-cpp/spine-cpp-unit-tests/src/main.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/teamcity/README.txt delete mode 100755 spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_cppunit.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_cppunit.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_messages.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_messages.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/CPP_InterfaceTestFixture.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/CPP_InterfaceTestFixture.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/EmptyTestFixture.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/EmptyTestFixture.h delete mode 100644 spine-cpp/spine-cpp-unit-tests/tests/MemoryTest.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.h delete mode 100644 spine-cpp/spine-cpp-unit-tests/tests/SimpleTest.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/SpineEventMonitor.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/SpineEventMonitor.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/_TestFixture.cpp delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/_TestFixture.h delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/fnr.exe delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/makeFixture.bat delete mode 100755 spine-cpp/spine-cpp-unit-tests/tests/TestOptions.h delete mode 100644 spine-cpp/spine-cpp-unit-tests/tests/main.cpp diff --git a/spine-cpp/spine-cpp-unit-tests/CMakeLists.txt b/spine-cpp/spine-cpp-unit-tests/CMakeLists.txt index 02a2500e6..17a5f1907 100755 --- a/spine-cpp/spine-cpp-unit-tests/CMakeLists.txt +++ b/spine-cpp/spine-cpp-unit-tests/CMakeLists.txt @@ -3,42 +3,16 @@ project(spine_cpp_unit_test) set(CMAKE_INSTALL_PREFIX "./") set(CMAKE_VERBOSE_MAKEFILE ON) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -DKANJI_MEMTRACE -DUSE_CPP11_MUTEX -std=c++11") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++ ") -######################################################### -# set includes -######################################################### include_directories(../spine-cpp/include teamcity minicppunit tests memory) -######################################################### -# Add Sources -######################################################### -set(MINICPP_SRC - minicppunit/MiniCppUnit.cxx +set(SRC + src/main.cpp + src/TestHarness.cpp ) -set(TEAMCITY_SRC - teamcity/teamcity_cppunit.cpp - teamcity/teamcity_messages.cpp -) - -set(TEST_SRC - tests/SpineEventMonitor.cpp - tests/EmptyTestFixture.cpp - tests/C_InterfaceTestFixture.cpp - tests/CPP_InterfaceTestFixture.cpp - tests/MemoryTestFixture.cpp -) - -set(MEMLEAK_SRC - memory/KMemory.cpp - memory/KString.cpp -) - -######################################################### -# setup main project -######################################################### -add_executable(spine_cpp_unit_test main.cpp ${MINICPP_SRC} ${TEAMCITY_SRC} ${TEST_SRC} ${MEMLEAK_SRC}) +add_executable(spine_cpp_unit_test ${SRC}) target_link_libraries(spine_cpp_unit_test spine-cpp) diff --git a/spine-cpp/spine-cpp-unit-tests/main.cpp b/spine-cpp/spine-cpp-unit-tests/main.cpp deleted file mode 100755 index 3cfa5fcd4..000000000 --- a/spine-cpp/spine-cpp-unit-tests/main.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// SexyKanjiTestSuite.cpp : Defines the entry point for the console application. -// - -#include "MiniCppUnit.hxx" - -#ifdef WIN32 -#include -#else -#include -#endif // WIN32 - -#include -#include "KString.h" -#include - -#include "spine/Extension.h" - -#include "KMemory.h" // last include - -using namespace Spine; - -class KanjiSpineExtension : public DefaultSpineExtension -{ -public: - static KanjiSpineExtension* getInstance(); - - virtual ~KanjiSpineExtension(); - - virtual void* spineAlloc(size_t size, const char* file, int line); - - virtual void* spineCalloc(size_t num, size_t size, const char* file, int line); - - virtual void* spineRealloc(void* ptr, size_t size, const char* file, int line); - - virtual void spineFree(void* mem); - -protected: - KanjiSpineExtension(); -}; - -KanjiSpineExtension* KanjiSpineExtension::getInstance() -{ - static KanjiSpineExtension ret; - return &ret; -} - -KanjiSpineExtension::~KanjiSpineExtension() -{ - // Empty -} - -void* KanjiSpineExtension::spineAlloc(size_t size, const char* file, int line) -{ - return _kanjimalloc(size); -} - -void* KanjiSpineExtension::spineCalloc(size_t num, size_t size, const char* file, int line) -{ - void* ptr = _kanjimalloc(num * size, file, line); - if (ptr) - { - memset(ptr, 0, num * size); - } - - return ptr; -} - -void* KanjiSpineExtension::spineRealloc(void* ptr, size_t size, const char* file, int line) -{ - return _kanjirealloc(ptr, size); -} - -void KanjiSpineExtension::spineFree(void* mem) -{ - _kanjifree(mem); -} - -KanjiSpineExtension::KanjiSpineExtension() : DefaultSpineExtension() -{ - // Empty -} - -int main(int argc, char* argv[]) -{ - SpineExtension::setInstance(KanjiSpineExtension::getInstance()); - - // Start Timing - time_t start_time, end_time; - time(&start_time); - - /* Set working directory to current location for opening test data */ -#ifdef WIN32 - _chdir( GetFileDir(argv[0], false).c_str() ); -#else - chdir(GetFileDir(argv[0], false).c_str()); -#endif - - // Run Test Suite - if(JetBrains::underTeamcity()) gTeamCityListener.startSuite("Spine-CPP Test Suite"); - int ret_val = TestFixtureFactory::theInstance().runTests() ? 0 : -1; - if(JetBrains::underTeamcity()) gTeamCityListener.endSuite("Spine-CPP Test Suite"); - - // End Timing - time(&end_time); - double secs = difftime(end_time,start_time); - printf("\n\n%i minutes and %i seconds of your life taken from you by these tests.\n", ((int)secs) / 60, ((int)secs) % 60); - - return ret_val; -} - diff --git a/spine-cpp/spine-cpp-unit-tests/memory/KMemory.cpp b/spine-cpp/spine-cpp-unit-tests/memory/KMemory.cpp deleted file mode 100755 index a21cbafba..000000000 --- a/spine-cpp/spine-cpp-unit-tests/memory/KMemory.cpp +++ /dev/null @@ -1,303 +0,0 @@ -#include -#include -#include -#include -#include - -#include "KString.h" - -#include "KMemory.h" // last include - -/////////////////////////////////////////////////////////////////////////////// -// -// KANJI_DUMP_LEAKED_MEM will print out the memory block that was leaked. -// This is helpful when leaked objects have string identifiers. -// -/////////////////////////////////////////////////////////////////////////////// -//#define KANJI_DUMP_LEAKED_MEM - - -/////////////////////////////////////////////////////////////////////////////// -// -// KANJI_TRACK_MEM_USAGE will print out all memory allocations. -// -/////////////////////////////////////////////////////////////////////////////// -//#define KANJI_TRACK_MEM_USAGE - - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// Our memory system is thread-safe, but instead of linking massive libraries, -// we attempt to use C++11 std::mutex. -#ifdef USE_CPP11_MUTEX_DISABLED -#include -typedef std::recursive_mutex KSysLock; // rentrant -struct KAutoLock { - KAutoLock(KSysLock& lock) :mLock(lock) { mLock.lock(); } // acquire - ~KAutoLock() { mLock.unlock(); } // release - - KSysLock& mLock; -}; -#else // Fallback to unsafe. don't spawn threads -typedef int KSysLock; -struct KAutoLock { - KAutoLock(KSysLock) {} // acquire - ~KAutoLock() {} // release -}; -#endif - - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -struct KANJI_ALLOC_INFO -{ - size_t size; - std::string file; - int line; -}; -static bool showLeaks = false; -class KAllocMap : public std::map -{ -public: - KSysLock crit; - static bool allocMapValid; - -public: - KAllocMap() { allocMapValid = true; } - ~KAllocMap() - { - if (showLeaks) - KMemoryDumpUnfreed(); - - allocMapValid = false; - } -}; -bool KAllocMap::allocMapValid = false; -static KAllocMap allocMap; // once this static object destructs, it dumps unfreed memory - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -#ifdef KANJI_TRACK_MEM_USAGE -void KMemoryDumpUsage(); // forward declaration -class KAllocStat -{ -public: - typedef std::map allocCount; // [size] = count - typedef std::map, allocCount> allocInfo; // [file, line] = allocCount - - allocInfo memInfo; - static bool allocMapValid; - -public: - - KAllocStat() - { - allocMapValid = true; - } - ~KAllocStat() - { - if (showLeaks) - KMemoryDumpUsage(); - - allocMapValid = false; - } - void addTrack(const char* fname, int lnum, int asize) - { - allocCount& info = memInfo[std::pair(fname, lnum)]; - info[asize]++; - } -}; -bool KAllocStat::allocMapValid = false; -static KAllocStat allocStat; -#endif // KANJI_TRACK_MEM_USAGE - - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -extern void KMemoryAddTrack( void* addr, size_t asize, const char* fname, int lnum ) -{ - if (!KAllocMap::allocMapValid || asize == 0) - return; - - KAutoLock aCrit(allocMap.crit); - showLeaks = true; - - KANJI_ALLOC_INFO& info = allocMap[addr]; - info.file = fname; - info.line = lnum; - info.size = asize; - -#ifdef KANJI_TRACK_MEM_USAGE - if (KAllocStat::allocMapValid) - allocStat.addTrack(fname, lnum, asize); -#endif -}; - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void KMemoryRemoveTrack(void* addr) -{ - if (!KAllocMap::allocMapValid) - return; - - KAutoLock aCrit(allocMap.crit); - KAllocMap::iterator anItr = allocMap.find(addr); - if (anItr != allocMap.end()) - allocMap.erase(anItr); -}; - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -void KMemoryDumpUnfreed() -{ - if (!KAllocMap::allocMapValid) - return; - - KAutoLock aCrit(allocMap.crit); // prevent modification of the map while iterating - - size_t totalSize = 0; - char buf[8192]; - - FILE* f = fopen("mem_leaks.txt", "wt"); - if (!f) - return; - - time_t aTime = time(NULL); - sprintf(buf, "Memory Leak Report for %s\n", asctime(localtime(&aTime))); - fprintf(f, "%s", buf); - KOutputDebug(DEBUGLVL, "\n"); - KOutputDebug(INFOLVL, buf); - for(KAllocMap::iterator i = allocMap.begin(); i != allocMap.end(); ++i) - { - sprintf(buf, "%s(%d) : Leak %u byte%s @0x%08X\n", i->second.file.c_str(), i->second.line, i->second.size, i->second.size > 1 ? "s" : "", (size_t)i->first); - KOutputDebug(ERRORLVL, buf); - fprintf(f, "%s", buf); - -#ifdef KANJI_DUMP_LEAKED_MEM - unsigned char* data = (unsigned char*)i->first; - int count = 0; - char hex_dump[1024]; - char ascii_dump[1024]; - - for (int index = 0; index < i->second.size; index++) - { - unsigned char _c = *data; - - if (count == 0) - sprintf(hex_dump, "\t%02X ", _c); - else - sprintf(hex_dump, "%s%02X ", hex_dump, _c); // technically, this is undefined behavior - - if ((_c < 32) || (_c > 126)) - _c = '.'; - - if (count == 7) - sprintf(ascii_dump, "%s%c ", ascii_dump, _c); - else - sprintf(ascii_dump, "%s%c", count == 0 ? "\t" : ascii_dump, _c); // technically, this is undefined behavior - - - if (++count == 16) - { - count = 0; - sprintf(buf, "%s\t%s\n", hex_dump, ascii_dump); - fprintf(f, buf); - - memset((void*)hex_dump, 0, 1024); - memset((void*)ascii_dump, 0, 1024); - } - - data++; - } - - if (count != 0) - { - fprintf(f, hex_dump); - for (int index = 0; index < 16 - count; index++) - fprintf(f, "\t"); - - fprintf(f, ascii_dump); - - for (int index = 0; index < 16 - count; index++) - fprintf(f, "."); - } - - count = 0; - fprintf(f, "\n\n"); - memset((void*)hex_dump, 0, 1024); - memset((void*)ascii_dump, 0, 1024); - -#endif // KANJI_DUMP_LEAKED_MEM - - totalSize += i->second.size; - } - - ErrorLevel lvl = (totalSize > 0) ? ERRORLVL : INFOLVL; - - sprintf(buf, "-----------------------------------------------------------\n"); - fprintf(f, "%s", buf); - KOutputDebug(lvl, buf); - sprintf(buf, "Total Unfreed: %u bytes (%luKB)\n\n", totalSize, totalSize / 1024); - KOutputDebug(lvl, buf); - fprintf(f, "%s", buf); - fclose(f); -} - -#ifdef KANJI_TRACK_MEM_USAGE -void KMemoryDumpUsage() -{ - if (!KAllocStat::allocMapValid) - return; - - char buf[8192]; - FILE* f = fopen("mem_usage.txt", "wt"); - - time_t aTime = time(NULL); - sprintf(buf, "Memory Usage Report for %s\n", asctime(localtime(&aTime))); - if (f) fprintf(f, "%s", buf); - KOutputDebug("\n"); - KOutputDebug(buf); - - for(KAllocStat::allocInfo::iterator i = allocStat.memInfo.begin(); i != allocStat.memInfo.end(); ++i) - { - int aBytesTotal = 0; - int aCallsTotal = 0; - for (KAllocStat::allocCount::iterator index = i->second.begin(); index != i->second.end(); ++index) - { - aBytesTotal += index->first; - aCallsTotal += index->second; - sprintf(buf, "%s(%d) : %d bytes (%d %s)\n", i->first.first.c_str(), i->first.second, index->first, index->second, index->second == 1 ? "call" : "calls"); - if (f) fprintf(f, "%s", buf); - KOutputDebug(buf); - } - - if (i->second.size() > 1) - { - sprintf(buf, " %s(%d) : %d KB total (%d calls)\n", i->first.first.c_str(), i->first.second, aBytesTotal / 1024, aCallsTotal); - if (f) fprintf(f, "%s", buf); - KOutputDebug(buf); - } - } - if (f) fclose(f); -} -#endif // KANJI_TRACK_MEM_USAGE - -size_t KMemoryAllocated() -{ - if (!KAllocMap::allocMapValid) - return 0; - - KAutoLock aCrit(allocMap.crit); - - size_t size = 0; - for(auto i = allocMap.begin(); i != allocMap.end(); ++i) - { - KANJI_ALLOC_INFO& info = i->second; - size += info.size; - } - return size; -} diff --git a/spine-cpp/spine-cpp-unit-tests/memory/KMemory.h b/spine-cpp/spine-cpp-unit-tests/memory/KMemory.h deleted file mode 100755 index 470a5db7d..000000000 --- a/spine-cpp/spine-cpp-unit-tests/memory/KMemory.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef __KANJIMEMORY_H__ -#define __KANJIMEMORY_H__ - -#include -#include - -#if defined(_DEBUG) && !defined(KANJI_MEMTRACE) -#define KANJI_MEMTRACE -#endif - -#ifdef WIN32 -#pragma warning(disable : 4595) -#endif - -////////////////////////////////////////////////////////////////////////// -// HOW TO USE THIS FILE -// -// In the desired .CPP file (NOT header file), AFTER ALL of your -// #include declarations, do a #include "KMemory.h" or whatever you renamed -// this file to. It's very important that you do it only in the .cpp and -// after every other include file, otherwise it won't compile. The memory leaks -// will appear in a file called mem_leaks.txt and they will also be printed out -// in the output window when the program exits. -// -////////////////////////////////////////////////////////////////////////// - -#ifndef SAFE_DELETE -#define SAFE_DELETE(pPtr) { if(pPtr) delete pPtr; pPtr = 0; } -#endif - -#ifndef SCOPED_AUTO_SAFE_DELETE -template -class ScopedAutoDeletePointerHelper -{ -public: - ScopedAutoDeletePointerHelper(T pPtr) : _pPtr(pPtr) {} - ~ScopedAutoDeletePointerHelper() { SAFE_DELETE(_pPtr); } - - T _pPtr; -}; -#define SCOPED_AUTO_SAFE_DELETE(p) ScopedAutoDeletePointerHelper anAutoDelete##p(p); -#endif - -#ifndef SAFE_DELETE_ARRAY -#define SAFE_DELETE_ARRAY(pPtr) { if(pPtr) delete [] pPtr; pPtr = 0; } -#endif - -extern void KMemoryDumpUnfreed(); -extern size_t KMemoryAllocated(); - -#ifdef WIN32 -#define KMEM_CALLTYPE __cdecl -#else -#define KMEM_CALLTYPE -#endif - -#ifdef __APPLE__ -#define KMEM_THROWSPEC throw(std::bad_alloc) -#define KMEM_THROWS_BADALLOC -#include -#else -#define KMEM_THROWSPEC -#endif - -#if defined(KANJI_MEMTRACE) - -///////////////////////////////////////////// -// DO NOT CALL THESE TWO METHODS DIRECTLY // -///////////////////////////////////////////// - -extern void KMemoryAddTrack(void* addr, size_t asize, const char* fname, int lnum); -extern void KMemoryRemoveTrack(void* addr); - -//Replacement for the standard malloc/free, records size of allocation and the file/line number it was on -inline void* _kanjimalloc (size_t size, const char* file, int line) -{ - void* ptr = (void*)malloc(size); - KMemoryAddTrack(ptr, size, file, line); - return(ptr); -} - -inline void* _kanjimalloc (size_t size) -{ - return _kanjimalloc(size, "", 0); -} - -inline void _kanjifree (void* ptr) -{ - KMemoryRemoveTrack(ptr); - free(ptr); -} - -inline void* _kanjirealloc (void* ptr, size_t size, const char* file, int line) -{ - void* ptr2 = (void*)realloc(ptr, size); - if (ptr2) - { - KMemoryRemoveTrack(ptr); - KMemoryAddTrack(ptr2, size, file, line); - } - return ptr2; -} - -inline void* _kanjirealloc (void* ptr, size_t size) -{ - return _kanjirealloc(ptr, size, "", 0); -} - -#define kanjimalloc(size) _kanjimalloc((size), __FILE__, __LINE__) -#define kanjifree _kanjifree -#define kanjirealloc(ptr, size) _kanjirealloc(ptr, size, __FILE__, __LINE__) - -//Replacement for the standard "new" operator, records size of allocation and the file/line number it was on -inline void* KMEM_CALLTYPE operator new(size_t size, const char* file, int line) -{ - void* ptr = (void*)malloc(size); - KMemoryAddTrack(ptr, size, file, line); - return(ptr); -} - -//Same as above, but for arrays -inline void* KMEM_CALLTYPE operator new[](size_t size, const char* file, int line) -{ - void* ptr = (void*)malloc(size); - KMemoryAddTrack(ptr, size, file, line); - return(ptr); -} - - -// These single argument new operators allow vc6 apps to compile without errors -inline void* KMEM_CALLTYPE operator new(size_t size) KMEM_THROWSPEC -{ - void* ptr = (void*)malloc(size); -#ifdef KMEM_THROWS_BADALLOC - if(!ptr) throw std::bad_alloc(); -#endif - return(ptr); -} - -inline void* KMEM_CALLTYPE operator new[](size_t size) KMEM_THROWSPEC -{ - void* ptr = (void*)malloc(size); -#ifdef KMEM_THROWS_BADALLOC - if(!ptr) throw std::bad_alloc(); -#endif // KMEM_THROWS_BADALLOC - return(ptr); -} - - -//custom delete operators -inline void KMEM_CALLTYPE operator delete(void* p) throw() -{ - KMemoryRemoveTrack(p); - free(p); -} - -inline void KMEM_CALLTYPE operator delete[](void* p) throw() -{ - KMemoryRemoveTrack(p); - free(p); -} - -//needed in case in the constructor of the class we're newing, it throws an exception -inline void KMEM_CALLTYPE operator delete(void* pMem, const char* file, int line) -{ - free(pMem); -} - -inline void KMEM_CALLTYPE operator delete[](void* pMem, const char* file, int line) -{ - free(pMem); -} - -#define KDEBUG_NEW new(__FILE__, __LINE__) -#define new KDEBUG_NEW - -#else // KANJI_MEMTRACE NOT DEFINED - -#define kanjimalloc malloc -#define kanjifree free -#define kanjirealloc realloc - -inline void* _kanjimalloc(size_t size) { return malloc(size); } -inline void _kanjifree(void* ptr) { free(ptr); } -inline void* _kanjirealloc(void* ptr, size_t size) { return realloc(ptr, size); } - -#endif // KANJI_MEMTRACE - -#endif // __KANJIMEMORY_H__ \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/memory/KString.cpp b/spine-cpp/spine-cpp-unit-tests/memory/KString.cpp deleted file mode 100755 index bd7aef664..000000000 --- a/spine-cpp/spine-cpp-unit-tests/memory/KString.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include "KString.h" -#include - -#include "MiniCppUnit.hxx" - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -// String Helper - -static std::string vasprintf(const char* fmt, va_list argv) -{ - std::string result; - va_list argv_copy; // vsnprintf modifies argv, need copy -#ifndef va_copy - argv_copy = argv; -#else - va_copy(argv_copy, argv); -#endif - - int len = vsnprintf(NULL, 0, fmt, argv_copy); - if (len > 0 && len < 255) - { - // cover 90% of all calls - char str[256] = { 0 }; - int len2 = vsnprintf(str, 255, fmt, argv); - result = str; - } - else if (len > 0) - { - char* str = static_cast(alloca(len + 1)); // alloca on stack, space for null-termination - int len2 = vsnprintf(str, len + 1, fmt, argv); - result = str; - } - return result; -} - - -static void reportWarning(const std::string& warnStr) -{ - if (JetBrains::underTeamcity()) - gTeamCityListener.messages.messageWarning(warnStr); - else - fprintf(stderr, "%s", warnStr.c_str()); -} - -static void reportError(const std::string& errorStr) -{ - if (JetBrains::underTeamcity()) - gTeamCityListener.messages.messageError(errorStr); - else - fprintf(stderr, "%s", errorStr.c_str()); -} - -static void reportInfo(const std::string& infoStr) -{ - if (JetBrains::underTeamcity()) - gTeamCityListener.messages.messageNormal(infoStr); - else - fprintf(stderr, "%s", infoStr.c_str()); -} - -static void reportDebug(const std::string& debugStr) -{ - fprintf(stderr, "%s", debugStr.c_str()); -} - -static void report(ErrorLevel level, const std::string& Str) -{ - switch (level) { - case WARNLVL: reportWarning(Str); break; - case ERRORLVL: reportError(Str); break; - case INFOLVL: reportInfo(Str); break; - case DEBUGLVL: reportDebug(Str); break; - } -} - -void KOutputDebug(ErrorLevel lvl, const char* fmt ...) -{ - va_list argList; - va_start(argList, fmt); - std::string str = vasprintf(fmt, argList); - va_end(argList); - - report(lvl, str); -} - -#define K_MAX(a,b) ((a>b) ? a : b) - -std::string GetFileName(const std::string& thePath, bool noExtension) -{ - int aLastSlash = K_MAX((int)thePath.rfind('\\'), (int)thePath.rfind('/')); - - if (noExtension) - { - int aLastDot = (int)thePath.rfind('.'); - if (aLastDot > aLastSlash) - return thePath.substr(aLastSlash + 1, aLastDot - aLastSlash - 1); - } - - if (aLastSlash == -1) - return thePath; - else - return thePath.substr(aLastSlash + 1); -} - -std::string GetFileDir(const std::string& thePath, bool withSlash) -{ - int aLastSlash = K_MAX((int)thePath.rfind(('\\')), (int)thePath.rfind(('/'))); - - if (aLastSlash == -1) - return (""); - else - { - if (withSlash) - return thePath.substr(0, aLastSlash + 1); - else - return thePath.substr(0, aLastSlash); - } -} - -std::string GetFileExt(const std::string& thePath) -{ - std::string::size_type idx = thePath.find_last_of('.'); - - if (idx != std::string::npos) - return thePath.substr(idx + 1); - - return (""); -} - -/** - * g_ascii_strcasecmp: - * @s1: string to compare with @s2. - * @s2: string to compare with @s1. - * - * Compare two strings, ignoring the case of ASCII characters. - * - * Unlike the BSD strcasecmp() function, this only recognizes standard - * ASCII letters and ignores the locale, treating all non-ASCII - * bytes as if they are not letters. - * - * This function should be used only on strings that are known to be - * in encodings where the bytes corresponding to ASCII letters always - * represent themselves. This includes UTF-8 and the ISO-8859-* - * charsets, but not for instance double-byte encodings like the - * Windows Codepage 932, where the trailing bytes of double-byte - * characters include all ASCII letters. If you compare two CP932 - * strings using this function, you will get false matches. - * - * Return value: an integer less than, equal to, or greater than - * zero if @s1 is found, respectively, to be less than, - * to match, or to be greater than @s2. - **/ -static int g_ascii_compare_caseless(const char* s1, const char* s2) -{ -#define TOUPPER(c) (((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c)) -#define TOLOWER(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c)) -#define g_return_val_if_fail(expr,val) { if (!(expr)) return (val); } - - int c1, c2; - - g_return_val_if_fail(s1 != NULL, 0); - g_return_val_if_fail(s2 != NULL, 0); - - while (*s1 && *s2) - { - c1 = (int)(unsigned char)TOLOWER(*s1); - c2 = (int)(unsigned char)TOLOWER(*s2); - if (c1 != c2) - return (c1 - c2); - s1++; s2++; - } - - return (((int)(unsigned char)* s1) - ((int)(unsigned char)* s2)); - -#undef g_return_val_if_fail -#undef TOUPPER -#undef TOLOWER -} - - -int CompareNoCase(const std::string & str1, const std::string & str2) -{ - return g_ascii_compare_caseless(str1.c_str(), str2.c_str()); -} diff --git a/spine-cpp/spine-cpp-unit-tests/memory/KString.h b/spine-cpp/spine-cpp-unit-tests/memory/KString.h deleted file mode 100755 index 32a27cb44..000000000 --- a/spine-cpp/spine-cpp-unit-tests/memory/KString.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -// Error reporting with levels similar to Android and are automatically forwarded to Continuous integration server -enum ErrorLevel { - WARNLVL, - ERRORLVL, - INFOLVL, - DEBUGLVL -}; - -extern void KOutputDebug(ErrorLevel lvl, const char* fmt ...); - -extern std::string GetFileName(const std::string& thePath, bool noExtension); -extern std::string GetFileDir(const std::string& thePath, bool withSlash); -extern std::string GetFileExt(const std::string& thePath); - -extern int CompareNoCase(const std::string& str1, const std::string& str2); diff --git a/spine-cpp/spine-cpp-unit-tests/minicppunit/MiniCppUnit.cxx b/spine-cpp/spine-cpp-unit-tests/minicppunit/MiniCppUnit.cxx deleted file mode 100755 index f14e790fb..000000000 --- a/spine-cpp/spine-cpp-unit-tests/minicppunit/MiniCppUnit.cxx +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright (c) 2003-2004 Pau Arumí & David García - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "MiniCppUnit.hxx" - -JetBrains::TeamcityProgressListener gTeamCityListener; -bool gUseTeamCity = false; - -#include -#include -#include - -#define MIN(a,b) ((a < b) ? a : b) -#define MAX(a,b) ((a > b) ? a : b) - -TestsListener::TestsListener() : _currentTestName(0) -{ - _executed=_failed=_exceptions=0; - gUseTeamCity = JetBrains::underTeamcity(); -} - -TestsListener& TestsListener::theInstance() -{ - static TestsListener instancia; - return instancia; -} - -std::stringstream& TestsListener::errorsLog() -{ - if (_currentTestName) - { - _log << "\n" << errmsgTag_nameOfTest() << (*_currentTestName) << "\n"; - } - return _log; -} - -std::string TestsListener::logString() -{ - std::string aRetornar = _log.str(); - _log.str(""); - return aRetornar; -} -void TestsListener::currentTestName( std::string& name) -{ - _currentTestName = &name; - - if(gUseTeamCity)gTeamCityListener.startTest(name); -} -void TestsListener::testHasRun() // started -{ - std::cout << "."; - theInstance()._executed++; -} - -void TestsListener::testHasPassed() // finished without errors -{ - if(gUseTeamCity) - gTeamCityListener.endTest(*(theInstance()._currentTestName)); -} - -void TestsListener::testHasFailed(const char* reason, const char* file, int line) -{ - if(gUseTeamCity) - { - gTeamCityListener.addFailure(JetBrains::TestFailure(*(theInstance()._currentTestName), "", JetBrains::SourceLine(file, line), reason)); - gTeamCityListener.endTest(*(theInstance()._currentTestName)); - } - - std::cout << "F"; - theInstance()._failed++; - throw TestFailedException(); -} -void TestsListener::testHasThrown() -{ - if(gUseTeamCity) - { - gTeamCityListener.addFailure(JetBrains::TestFailure(*(theInstance()._currentTestName), "", JetBrains::SourceLine(), "Exception")); - gTeamCityListener.endTest(*(theInstance()._currentTestName)); - } - std::cout << "E"; - theInstance()._exceptions++; -} -std::string TestsListener::summary() -{ - std::ostringstream os; - os << "\nSummary:\n" - << Assert::bold() << "\tExecuted Tests: " - << _executed << Assert::normal() << std::endl - << Assert::green() << "\tPassed Tests: " - << (_executed-_failed-_exceptions) - << Assert::normal() << std::endl; - if (_failed > 0) - { - os << Assert::red() << "\tFailed Tests: " - << _failed << Assert::normal() << std::endl; - } - if (_exceptions > 0) - { - os << Assert::yellow() << "\tUnexpected exceptions: " - << _exceptions << Assert::normal() << std::endl; - } - os << std::endl; - return os.str(); -} -bool TestsListener::allTestsPassed() -{ - return !theInstance()._exceptions && !theInstance()._failed; -} - - - -void Assert::assertTrue(char* strExpression, bool expression, - const char* file, int linia) -{ - if (!expression) - { - TestsListener::theInstance().errorsLog() << "\n" - << errmsgTag_testFailedIn() << file - << errmsgTag_inLine() << linia << "\n" - << errmsgTag_failedExpression() - << bold() << strExpression << normal() << "\n"; - TestsListener::theInstance().testHasFailed(strExpression, file, linia); - } -} - -void Assert::assertTrueMissatge(char* strExpression, bool expression, - const char* missatge, const char* file, int linia) -{ - if (!expression) - { - TestsListener::theInstance().errorsLog() << "\n" - << errmsgTag_testFailedIn() << file - << errmsgTag_inLine() << linia << "\n" - << errmsgTag_failedExpression() - << bold() << strExpression << "\n" - << missatge<< normal() << "\n"; - TestsListener::theInstance().testHasFailed(strExpression, file, linia); - } -} - - - -void Assert::assertEquals( const char * expected, const char * result, - const char* file, int linia ) -{ - assertEquals(std::string(expected), std::string(result), - file, linia); - -} -void Assert::assertEquals( const bool& expected, const bool& result, - const char* file, int linia ) -{ - assertEquals( - (expected?"true":"false"), - (result?"true":"false"), - file, linia); -} - -// floating point numbers comparisons taken -// from c/c++ users journal. dec 04 pag 10 -bool isNaN(double x) -{ - bool b1 = (x < 0.0); - bool b2 = (x >= 0.0); - return !(b1 || b2); -} - -double scaledEpsilon(const double& expected, const double& fuzzyEpsilon ) -{ - const double aa = fabs(expected)+1; - return (std::isinf(aa))? fuzzyEpsilon: fuzzyEpsilon * aa; -} -bool fuzzyEquals(double expected, double result, double fuzzyEpsilon) -{ - return (expected==result) || ( fabs(expected-result) <= scaledEpsilon(expected, fuzzyEpsilon) ); -} -void Assert::assertEquals( const double& expected, const double& result, - const char* file, int linia ) -{ - const double fuzzyEpsilon = 0.000001; - assertEqualsEpsilon( expected, result, fuzzyEpsilon, file, linia ); -} - -void Assert::assertEquals( const float& expected, const float& result, - const char* file, int linia ) -{ - assertEquals((double)expected, (double)result, file, linia); -} -void Assert::assertEquals( const long double& expected, const long double& result, - const char* file, int linia ) -{ - assertEquals((double)expected, (double)result, file, linia); -} -void Assert::assertEqualsEpsilon( const double& expected, const double& result, const double& epsilon, - const char* file, int linia ) -{ - if (isNaN(expected) && isNaN(result) ) return; - if (!isNaN(expected) && !isNaN(result) && fuzzyEquals(expected, result, epsilon) ) return; - - std::stringstream anError; - anError - << errmsgTag_testFailedIn() << file - << errmsgTag_inLine() << linia << "\n" - << errmsgTag_expected() - << bold() << expected << normal() << " " - << errmsgTag_butWas() - << bold() << result << normal() << "\n"; - - TestsListener::theInstance().errorsLog() << anError.str(); - - TestsListener::theInstance().testHasFailed(anError.str().c_str(), file, linia); -} - -int Assert::notEqualIndex( const std::string & one, const std::string & other ) -{ - int end = MIN(one.length(), other.length()); - for ( int index = 0; index < end; index++ ) - if (one[index] != other[index] ) - return index; - return end; -} - - -/** - * we overload the assert with string doing colored diffs - * - * MS Visual6 doesn't allow string by reference :-( - */ -void Assert::assertEquals( const std::string expected, const std::string result, - const char* file, int linia ) -{ - if(expected == result) - return; - - int indexDiferent = notEqualIndex(expected, result); - - std::stringstream anError; - anError - << file << ", linia: " << linia << "\n" - << errmsgTag_expected() << "\n" << blue() - << expected.substr(0,indexDiferent) - << green() << expected.substr(indexDiferent) - << normal() << "\n" - << errmsgTag_butWas() << blue() << "\n" - << result.substr(0,indexDiferent) - << red() << result.substr(indexDiferent) - << normal() << std::endl; - - TestsListener::theInstance().errorsLog() << anError.str(); - - TestsListener::theInstance().testHasFailed(anError.str().c_str(), file, linia); -} -void Assert::fail(const char* motiu, const char* file, int linia) -{ - TestsListener::theInstance().errorsLog() << - file << errmsgTag_inLine() << linia << "\n" << - "Reason: " << motiu << "\n"; - - TestsListener::theInstance().testHasFailed(motiu, file, linia); -} - - diff --git a/spine-cpp/spine-cpp-unit-tests/minicppunit/MiniCppUnit.hxx b/spine-cpp/spine-cpp-unit-tests/minicppunit/MiniCppUnit.hxx deleted file mode 100755 index 7ce3d8fd6..000000000 --- a/spine-cpp/spine-cpp-unit-tests/minicppunit/MiniCppUnit.hxx +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright (c) 2003-2004 Pau Arum� & David Garc�a - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef MiniCppUnit_hxx -#define MiniCppUnit_hxx - -/** - * @mainpage - * miniCppUnit - * (C) 2003-2006 Pau Arumi & David Garcia - * - * @version 2.5 2006-03-14 - * - MS Visual compatibility: SConstruct ccflags, usage example, #ifdefs - * @version 2.4 2006-03-14 - * - exit test case after first failure - * - double and float comparison with fuzzy equals (using scalable epsilon) - * - have into account not a numbers - * - new ASSERT_EQUALS_EPSILON macro - * - more colors, and disabled when comiled in MS Visual - * - removed catalan location. - * - UsageExample.cxx now uses all macros and features - * @version 2.3 2006-02-13 added usage example and SConstruct - * @version 2.2 2004-11-28 code in english and tests suites - * @version 2.1 2004-11-04 char* especialization - * @version 2.0 2004-10-26 TestsFactory - * @version 1.0 2003-10-28 initial - * - * Example of use: - * - * @code - * #include "MiniCppUnit.hxx" - * class MyTests : public TestFixture - * { - * public: - * TEST_FIXTURE( MyTests ) - * { - * CAS_DE_TEST( testAddition ); - * // etc - * } - * void testAddition() - * { - * ASSERT_EQUALS( 4, 1+1+2 ); - * } - * // etc - * }; - * - * REGISTER_FIXTURE( MyTests ); - * @endcode - * @code - * int main() - * { - * return TestFixtureFactory::theInstance().runTests() ? 0 : -1; - * } - * @endcode - * Good things: - * - * - it's a tiny framework made up of two or three src files. - * => no need to install as a library - * - object oriented and makes use of several GoF patterns - * - very simple usage. Just needs to learn very few C macros - * - string asserts are simpler to use than cppunit - * - string asserts are enhanced with coloured diffs - * - concrete test classes are totally decoupled via static factory - * => no src file have to include them all. - * - it have test suite hierarchies - * - compatible with non-standard compliant VisualC6 - * (though not necessary good ;) - */ - -#include -#include -#include -#include - -#if _MSC_VER < 1300 -/** necesary for Visual 6 which don't define std::min */ -namespace std -{ - template T min(const T& a, const T& b) { return a < b ? a: b; } -} -#endif - -#include "../teamcity/teamcity_cppunit.h" - -extern JetBrains::TeamcityProgressListener gTeamCityListener; - -/** - * A singleton class. - * Receives tests results and stores messages to the test log - * for later listing. - * It's a singleton for an easy global access from the 'Asserts' - * methods but it is probably asking for a refactoring in order to limit - * access only to TestFixtures - */ -class TestsListener -{ -public: - /** accessor to the global (static) singleton instance */ - static TestsListener& theInstance(); - std::stringstream& errorsLog(); - std::string logString(); - void currentTestName( std::string& name); - static void testHasRun(); - static void testHasPassed(); - static void testHasFailed(const char* reason, const char* file, int line); - static void testHasThrown(); - /** the human readable summary of run tests*/ - std::string summary(); - /** returns wheather all run tests have passed */ - static bool allTestsPassed(); - -private: - static const char* errmsgTag_nameOfTest() { return "Test failed: "; } - - /** constructor private: force the singleton to be wellbehaved ! */ - TestsListener(); - - std::string* _currentTestName; - std::stringstream _log; - unsigned _executed; - unsigned _failed; - unsigned _exceptions; -}; - -class TestFailedException -{ -}; - -/** - * Abstract class with interface that allows run a test. That is runTest - * and name. It is implemented by TestFixture and TestCase - * - * It does the 'Component' role in the 'Composite' patten - **/ -class Test -{ -public: - virtual ~Test(){} - /** run the test: exercice the code and check results*/ - virtual void runTest() = 0; - /** the test human-readable name */ - virtual std::string name() const = 0; -}; - - -/** - * This class is just a placeholder for all assert functions --as static methods. - * It is meant for being used just by the assert macros - */ -class Assert -{ - static const char * errmsgTag_testFailedIn() { return "Test failed in "; } - static const char * errmsgTag_inLine() { return ", line: "; }; - static const char * errmsgTag_failedExpression() { return "Failed expression: "; } - static const char * errmsgTag_expected() { return "Expected: "; } - static const char * errmsgTag_butWas() { return "But was: "; } - -public: -#ifdef _MSC_VER - static const char * blue() { return ""; } - static const char * green() { return ""; } - static const char * red() { return ""; } - static const char * normal() { return ""; } - static const char * bold() { return ""; } - static const char * yellow() { return ""; } -#else - static const char * blue() { return "\033[36;1m"; } - static const char * green() { return "\033[32;1m"; } - static const char * red() { return "\033[31;1m"; } - static const char * normal() { return "\033[0m"; } - static const char * bold() { return "\033[" "1m"; } - static const char * yellow() { return "\033[93;1m"; } -#endif - template - static void assertEquals( const AType& expected, const AType& result, - const char* file="", int linia=0 ) - { - if(expected != result) - { - std::stringstream anError; - - anError - << file << ", linia: " << linia << "\n" - << errmsgTag_expected() << " " << expected << " " - << errmsgTag_butWas() << " " << result << "\n"; - - // TestsListener::theInstance().errorsLog() << anError; - - TestsListener::theInstance().testHasFailed(anError.str().c_str(), file, linia); - } - } - - static void assertTrue(char* strExpression, bool expression, - const char* file="", int linia=0); - - static void assertTrueMissatge(char* strExpression, bool expression, - const char* missatge, const char* file="", int linia=0); - - static void assertEquals( const char * expected, const char * result, - const char* file="", int linia=0 ); - - static void assertEquals( const bool& expected, const bool& result, - const char* file="", int linia=0 ); - - static void assertEquals( const double& expected, const double& result, - const char* file="", int linia=0 ); - - static void assertEquals( const float& expected, const float& result, - const char* file="", int linia=0 ); - - static void assertEquals( const long double& expected, const long double& result, - const char* file="", int linia=0 ); - - static void assertEqualsEpsilon( const double& expected, const double& result, const double& epsilon, - const char* file="", int linia=0 ); - - static int notEqualIndex( const std::string & one, const std::string & other ); - - /** - * we overload the assert with string doing colored diffs - * - * MS Visual6 doesn't allow string by reference :-( - */ - static void assertEquals( const std::string expected, const std::string result, - const char* file="", int linia=0 ); - - static void fail(const char* motiu, const char* file="", int linia=0); - - -}; - -/** - * A TestFixture is a class that contain TestCases --which corresponds to - * ConcreteTestFixture methods-- common objects uder tests, and setUp and - * tearDown methods which are automatically executed before and after each - * test case. - * - * Is the base class of ConcreteFixtures implemented by the framework user - * - * It does the 'Composite' role in the 'Composite' GoF pattern. - * Its composite children are TestCases, which wrapps the test methods. - * - * It is a template class parametrized by ConcreteTestFixture so that it can - * instantiate TestCase objects templatized with this same parameter: it needs the - * concrete class type for calling its non-static methods. - */ -template -class TestFixture : public Test -{ -protected: - - typedef ConcreteTestFixture ConcreteFixture; - typedef void(ConcreteTestFixture::*TestCaseMethod)(); - - /** - * Wrapper for the test methods of concrete TestFixtures. - * - * Makes the 'Leave' role in the 'Composite' GoF pattern because can't be - * be a composition of other tests. - * - * It's also a case of 'Command' pattern because it encapsules in an object - * certain functionality whose execution depends on some deferred entity. - */ - class TestCase : public Test - { - public: - TestCase(ConcreteFixture* parent, TestCaseMethod method, const std::string & name) : - _parent(parent), - _testCaseMethod(method), - _name(name) - { - } - /** calls TestFixture method. setUp and tearDown methods are called by - * its parent TestFixture (in its runTest method). - * it is robust to unexpected exceptions (throw) */ - void runTest() - { - TestsListener::theInstance().testHasRun(); - TestsListener::theInstance().currentTestName(_name); - try - { - (_parent->*_testCaseMethod)(); - TestsListener::theInstance().testHasPassed(); - } - catch( std::exception& error ) - { - TestsListener::theInstance().testHasThrown(); - TestsListener::theInstance().errorsLog() - << "std::exception catched by MiniCppUnit: \n" - << "what() : " - << Assert::yellow() << error.what() - << Assert::normal() << "\n"; - } - catch ( TestFailedException& ) //just for skiping current test case - { - // the assert() calls testHasFailed() - } - catch(...) - { - TestsListener::theInstance().testHasThrown(); - TestsListener::theInstance().errorsLog() - << "non standard exception catched by MiniCppUnit.\n"; - } - } - - /** the TestFixture method hame */ - std::string name() const - { - return _name; - } - - private: - ConcreteFixture* _parent; - TestCaseMethod _testCaseMethod; - std::string _name; - }; - //------------- end of class TestCase ---------------------------- - -private: - - typedef std::list TestCases; - TestCases _testCases; - std::string _name; - - void testsList() const - { - std::cout << "\n+ " << name() << "\n"; - for( TestCases::const_iterator it=_testCases.begin(); - it!=_testCases.end(); it++ ) - std::cout << " - "<< (*it)->name() << "\n"; - } - - -public: - virtual void setUp() {} - virtual void tearDown() {} - - std::string name() const - { - return _name; - }; - - TestFixture(const std::string& name="A text fixture") : _name(name) - { - } - - void afegeixCasDeTest(ConcreteFixture* parent, TestCaseMethod method, const char* name) - { - TestCase* casDeTest = new TestCase(parent, method, _name + "::" + name); - _testCases.push_back( casDeTest ); - } - /** calls each test after setUp and tearDown TestFixture methods */ - void runTest() - { - testsList(); - TestCases::iterator it; - for( it=_testCases.begin(); it!=_testCases.end(); it++) - { - setUp(); - (*it)->runTest(); - tearDown(); - } - } - /** TestCase that wrapps TestFixture methods are dynamically created and owned by - * the TestFixture. So here we clean it up*/ - virtual ~TestFixture() - { - TestCases::iterator it; - for( it =_testCases.begin(); it!=_testCases.end(); it++) - delete (*it); - } -}; - - -/** - * This class is aimed to hold a creator method for each concrete TestFixture - */ -class TestFixtureFactory -{ -private: - /** Well behaved singleton: - * Don't allow instantiation apart from theInstance(), so private ctr.*/ - TestFixtureFactory() - { - } - typedef Test* (*FixtureCreator)(); - std::list _creators; -public: - /** Accessor to the (static) singleton instance */ - static TestFixtureFactory& theInstance() - { - static TestFixtureFactory theFactory; - return theFactory; - } - bool runTests() - { - std::list::iterator it; - for(it=_creators.begin(); it!=_creators.end(); it++) - { - FixtureCreator creator = *it; - Test* test = creator(); - test->runTest(); - delete test; - } - std::string errors = TestsListener::theInstance().logString(); - if (errors!="") std::cout << "\n\nError Details:\n" << errors; - std::cout << TestsListener::theInstance().summary(); - - return TestsListener::theInstance().allTestsPassed(); - } - void addFixtureCreator(FixtureCreator creator) - { - _creators.push_back( creator ); - } - -}; - -/** - * Macro a usar despr�s de cada classe de test - */ -#define REGISTER_FIXTURE( ConcreteTestFixture ) \ -\ -Test* Creador##ConcreteTestFixture() { return new ConcreteTestFixture; } \ -\ -class Registrador##ConcreteTestFixture \ -{ \ -public: \ - Registrador##ConcreteTestFixture() \ - { \ - TestFixtureFactory::theInstance().addFixtureCreator( \ - Creador##ConcreteTestFixture); \ - } \ -}; \ -static Registrador##ConcreteTestFixture estatic##ConcreteTestFixture; - - -/** - * Assert macros to use in test methods. An assert is a test condition - * we want to check. - */ -#define ASSERT_EQUALS( expected, result) \ - Assert::assertEquals( expected, result, __FILE__, __LINE__ ); - -#define ASSERT_EQUALS_EPSILON( expected, result, epsilon) \ - Assert::assertEqualsEpsilon( expected, result, epsilon, __FILE__, __LINE__ ); - -#define ASSERT( exp ) \ - Assert::assertTrue(#exp, exp, __FILE__, __LINE__); - -#define ASSERT_MESSAGE( exp, message ) \ - Assert::assertTrueMissatge(#exp, exp, message, __FILE__, __LINE__); - -#define FAIL( why ) \ - Assert::fail(#why, __FILE__, __LINE__); - -/** - * Macros that allows to write the constructor of the concrete TestFixture. - * What the constructor does is agregate a wrapper for each test case (method) - * As easy to write as this: - * - * @code - * class MyTests : public TestFixture - * { - * public: - * TEST_FIXTURE( MyTests ) - * { - * TEST_CASE( test ); - * // etc - * } - * void test() - * { - * ASSERT_EQUALS( 4, 1+1+2 ); - * } - * @endcode - */ - -#define TEST_FIXTURE( ConcreteFixture ) \ - ConcreteFixture() : TestFixture( #ConcreteFixture ) - -#define TEST_CASE( methodName ) \ - afegeixCasDeTest( this, &ConcreteFixture::methodName, #methodName ); - - - - - -#endif // MiniCppUnit_hxx diff --git a/spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test.xcodeproj/project.pbxproj b/spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test.xcodeproj/project.pbxproj deleted file mode 100644 index b3171bc62..000000000 --- a/spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test.xcodeproj/project.pbxproj +++ /dev/null @@ -1,831 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 48; - objects = { - -/* Begin PBXBuildFile section */ - BB4E38561FD9C85600709FF2 /* spineboy-ess.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = BB4E38541FD9C85600709FF2 /* spineboy-ess.json */; }; - BB4E38571FD9C85600709FF2 /* spineboy.atlas in CopyFiles */ = {isa = PBXBuildFile; fileRef = BB4E38551FD9C85600709FF2 /* spineboy.atlas */; }; - BB4E385A1FD9C86400709FF2 /* raptor.atlas in CopyFiles */ = {isa = PBXBuildFile; fileRef = BB4E38581FD9C86400709FF2 /* raptor.atlas */; }; - BB4E385B1FD9C86400709FF2 /* raptor-pro.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = BB4E38591FD9C86400709FF2 /* raptor-pro.json */; }; - BB4E385E1FD9C87700709FF2 /* goblins-pro.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = BB4E385C1FD9C87600709FF2 /* goblins-pro.json */; }; - BB4E385F1FD9C87700709FF2 /* goblins.atlas in CopyFiles */ = {isa = PBXBuildFile; fileRef = BB4E385D1FD9C87700709FF2 /* goblins.atlas */; }; - BB6017131FD9289A009BD546 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017121FD9289A009BD546 /* main.cpp */; }; - BB6017A21FD928AC009BD546 /* Attachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017671FD928AC009BD546 /* Attachment.cpp */; }; - BB6017A31FD928AC009BD546 /* Skeleton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017681FD928AC009BD546 /* Skeleton.cpp */; }; - BB6017A41FD928AC009BD546 /* TranslateTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017691FD928AC009BD546 /* TranslateTimeline.cpp */; }; - BB6017A51FD928AC009BD546 /* Extension.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60176A1FD928AC009BD546 /* Extension.cpp */; }; - BB6017A61FD928AC009BD546 /* Updatable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60176B1FD928AC009BD546 /* Updatable.cpp */; }; - BB6017A71FD928AC009BD546 /* Bone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60176C1FD928AC009BD546 /* Bone.cpp */; }; - BB6017A81FD928AC009BD546 /* AtlasAttachmentLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60176D1FD928AC009BD546 /* AtlasAttachmentLoader.cpp */; }; - BB6017A91FD928AC009BD546 /* EventTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60176E1FD928AC009BD546 /* EventTimeline.cpp */; }; - BB6017AA1FD928AC009BD546 /* PathConstraint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60176F1FD928AC009BD546 /* PathConstraint.cpp */; }; - BB6017AB1FD928AC009BD546 /* VertexAttachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017701FD928AC009BD546 /* VertexAttachment.cpp */; }; - BB6017AC1FD928AC009BD546 /* TextureLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017711FD928AC009BD546 /* TextureLoader.cpp */; }; - BB6017AD1FD928AC009BD546 /* SkeletonData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017721FD928AC009BD546 /* SkeletonData.cpp */; }; - BB6017AE1FD928AC009BD546 /* TransformConstraintTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017731FD928AC009BD546 /* TransformConstraintTimeline.cpp */; }; - BB6017AF1FD928AC009BD546 /* IkConstraint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017741FD928AC009BD546 /* IkConstraint.cpp */; }; - BB6017B01FD928AC009BD546 /* CurveTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017751FD928AC009BD546 /* CurveTimeline.cpp */; }; - BB6017B11FD928AC009BD546 /* AnimationStateData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017761FD928AC009BD546 /* AnimationStateData.cpp */; }; - BB6017B21FD928AC009BD546 /* Constraint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017771FD928AC009BD546 /* Constraint.cpp */; }; - BB6017B31FD928AC009BD546 /* BoundingBoxAttachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017781FD928AC009BD546 /* BoundingBoxAttachment.cpp */; }; - BB6017B41FD928AC009BD546 /* PathAttachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017791FD928AC009BD546 /* PathAttachment.cpp */; }; - BB6017B51FD928AC009BD546 /* MeshAttachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60177A1FD928AC009BD546 /* MeshAttachment.cpp */; }; - BB6017B61FD928AC009BD546 /* TransformConstraint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60177B1FD928AC009BD546 /* TransformConstraint.cpp */; }; - BB6017B71FD928AC009BD546 /* Skin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60177C1FD928AC009BD546 /* Skin.cpp */; }; - BB6017B81FD928AC009BD546 /* RTTI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60177D1FD928AC009BD546 /* RTTI.cpp */; }; - BB6017B91FD928AC009BD546 /* MathUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60177E1FD928AC009BD546 /* MathUtil.cpp */; }; - BB6017BA1FD928AC009BD546 /* IkConstraintData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60177F1FD928AC009BD546 /* IkConstraintData.cpp */; }; - BB6017BB1FD928AC009BD546 /* Atlas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017801FD928AC009BD546 /* Atlas.cpp */; }; - BB6017BC1FD928AC009BD546 /* ClippingAttachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017811FD928AC009BD546 /* ClippingAttachment.cpp */; }; - BB6017BD1FD928AC009BD546 /* PathConstraintData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017821FD928AC009BD546 /* PathConstraintData.cpp */; }; - BB6017BE1FD928AC009BD546 /* Timeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017831FD928AC009BD546 /* Timeline.cpp */; }; - BB6017BF1FD928AC009BD546 /* SkeletonBinary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017841FD928AC009BD546 /* SkeletonBinary.cpp */; }; - BB6017C01FD928AC009BD546 /* ScaleTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017851FD928AC009BD546 /* ScaleTimeline.cpp */; }; - BB6017C11FD928AC009BD546 /* LinkedMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017861FD928AC009BD546 /* LinkedMesh.cpp */; }; - BB6017C21FD928AC009BD546 /* PointAttachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017871FD928AC009BD546 /* PointAttachment.cpp */; }; - BB6017C31FD928AC009BD546 /* RegionAttachment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017881FD928AC009BD546 /* RegionAttachment.cpp */; }; - BB6017C41FD928AC009BD546 /* DeformTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017891FD928AC009BD546 /* DeformTimeline.cpp */; }; - BB6017C51FD928AC009BD546 /* Animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60178A1FD928AC009BD546 /* Animation.cpp */; }; - BB6017C61FD928AC009BD546 /* AttachmentLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60178B1FD928AC009BD546 /* AttachmentLoader.cpp */; }; - BB6017C71FD928AC009BD546 /* DrawOrderTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60178C1FD928AC009BD546 /* DrawOrderTimeline.cpp */; }; - BB6017C81FD928AC009BD546 /* AttachmentTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60178D1FD928AC009BD546 /* AttachmentTimeline.cpp */; }; - BB6017C91FD928AC009BD546 /* EventData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60178E1FD928AC009BD546 /* EventData.cpp */; }; - BB6017CA1FD928AC009BD546 /* PathConstraintSpacingTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60178F1FD928AC009BD546 /* PathConstraintSpacingTimeline.cpp */; }; - BB6017CB1FD928AC009BD546 /* PathConstraintPositionTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017901FD928AC009BD546 /* PathConstraintPositionTimeline.cpp */; }; - BB6017CC1FD928AC009BD546 /* TransformConstraintData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017911FD928AC009BD546 /* TransformConstraintData.cpp */; }; - BB6017CD1FD928AC009BD546 /* SkeletonClipping.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017921FD928AC009BD546 /* SkeletonClipping.cpp */; }; - BB6017CE1FD928AC009BD546 /* TwoColorTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017931FD928AC009BD546 /* TwoColorTimeline.cpp */; }; - BB6017CF1FD928AC009BD546 /* Slot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017941FD928AC009BD546 /* Slot.cpp */; }; - BB6017D01FD928AC009BD546 /* AnimationState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017951FD928AC009BD546 /* AnimationState.cpp */; }; - BB6017D11FD928AC009BD546 /* SkeletonJson.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017961FD928AC009BD546 /* SkeletonJson.cpp */; }; - BB6017D21FD928AC009BD546 /* BoneData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017971FD928AC009BD546 /* BoneData.cpp */; }; - BB6017D31FD928AC009BD546 /* IkConstraintTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017981FD928AC009BD546 /* IkConstraintTimeline.cpp */; }; - BB6017D41FD928AC009BD546 /* Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017991FD928AC009BD546 /* Event.cpp */; }; - BB6017D51FD928AC009BD546 /* RotateTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60179A1FD928AC009BD546 /* RotateTimeline.cpp */; }; - BB6017D61FD928AC009BD546 /* PathConstraintMixTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60179B1FD928AC009BD546 /* PathConstraintMixTimeline.cpp */; }; - BB6017D71FD928AC009BD546 /* Triangulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60179C1FD928AC009BD546 /* Triangulator.cpp */; }; - BB6017D81FD928AC009BD546 /* Json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60179D1FD928AC009BD546 /* Json.cpp */; }; - BB6017D91FD928AC009BD546 /* SkeletonBounds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60179E1FD928AC009BD546 /* SkeletonBounds.cpp */; }; - BB6017DA1FD928AC009BD546 /* SlotData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB60179F1FD928AC009BD546 /* SlotData.cpp */; }; - BB6017DB1FD928AC009BD546 /* ShearTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017A01FD928AC009BD546 /* ShearTimeline.cpp */; }; - BB6017DC1FD928AC009BD546 /* ColorTimeline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017A11FD928AC009BD546 /* ColorTimeline.cpp */; }; - BB6017E21FD928F7009BD546 /* KMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017E01FD928F6009BD546 /* KMemory.cpp */; }; - BB6017E31FD928F7009BD546 /* KString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017E11FD928F6009BD546 /* KString.cpp */; }; - BB6017E71FD929D0009BD546 /* MiniCppUnit.cxx in Sources */ = {isa = PBXBuildFile; fileRef = BB6017E61FD929D0009BD546 /* MiniCppUnit.cxx */; }; - BB6017EE1FD929F4009BD546 /* teamcity_cppunit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017EA1FD929F4009BD546 /* teamcity_cppunit.cpp */; }; - BB6017EF1FD929F4009BD546 /* teamcity_messages.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017ED1FD929F4009BD546 /* teamcity_messages.cpp */; }; - BB6018081FD92AF4009BD546 /* SpineEventMonitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB6017FD1FD92AF3009BD546 /* SpineEventMonitor.cpp */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - BB4E38471FD9C72600709FF2 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = testdata/spineboy; - dstSubfolderSpec = 16; - files = ( - BB4E38561FD9C85600709FF2 /* spineboy-ess.json in CopyFiles */, - BB4E38571FD9C85600709FF2 /* spineboy.atlas in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BB4E384A1FD9C79D00709FF2 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = testdata/raptor; - dstSubfolderSpec = 16; - files = ( - BB4E385A1FD9C86400709FF2 /* raptor.atlas in CopyFiles */, - BB4E385B1FD9C86400709FF2 /* raptor-pro.json in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BB4E384B1FD9C79E00709FF2 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = testdata/goblins; - dstSubfolderSpec = 16; - files = ( - BB4E385E1FD9C87700709FF2 /* goblins-pro.json in CopyFiles */, - BB4E385F1FD9C87700709FF2 /* goblins.atlas in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BB60170D1FD9289A009BD546 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - BB4E38541FD9C85600709FF2 /* spineboy-ess.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = "spineboy-ess.json"; path = "../../../examples/spineboy/export/spineboy-ess.json"; sourceTree = ""; }; - BB4E38551FD9C85600709FF2 /* spineboy.atlas */ = {isa = PBXFileReference; lastKnownFileType = text; name = spineboy.atlas; path = ../../../examples/spineboy/export/spineboy.atlas; sourceTree = ""; }; - BB4E38581FD9C86400709FF2 /* raptor.atlas */ = {isa = PBXFileReference; lastKnownFileType = text; name = raptor.atlas; path = ../../../examples/raptor/export/raptor.atlas; sourceTree = ""; }; - BB4E38591FD9C86400709FF2 /* raptor-pro.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = "raptor-pro.json"; path = "../../../examples/raptor/export/raptor-pro.json"; sourceTree = ""; }; - BB4E385C1FD9C87600709FF2 /* goblins-pro.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = "goblins-pro.json"; path = "../../../examples/goblins/export/goblins-pro.json"; sourceTree = ""; }; - BB4E385D1FD9C87700709FF2 /* goblins.atlas */ = {isa = PBXFileReference; lastKnownFileType = text; name = goblins.atlas; path = ../../../examples/goblins/export/goblins.atlas; sourceTree = ""; }; - BB60170F1FD9289A009BD546 /* spine_unit_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = spine_unit_test; sourceTree = BUILT_PRODUCTS_DIR; }; - BB6017121FD9289A009BD546 /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; }; - BB60171C1FD928AC009BD546 /* DeformTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeformTimeline.h; sourceTree = ""; }; - BB60171D1FD928AC009BD546 /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Animation.h; sourceTree = ""; }; - BB60171E1FD928AC009BD546 /* EventData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventData.h; sourceTree = ""; }; - BB60171F1FD928AC009BD546 /* SlotData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlotData.h; sourceTree = ""; }; - BB6017201FD928AC009BD546 /* PathConstraintMixTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathConstraintMixTimeline.h; sourceTree = ""; }; - BB6017211FD928AC009BD546 /* SkeletonClipping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkeletonClipping.h; sourceTree = ""; }; - BB6017221FD928AC009BD546 /* Pool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pool.h; sourceTree = ""; }; - BB6017231FD928AC009BD546 /* TimelineType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimelineType.h; sourceTree = ""; }; - BB6017241FD928AC009BD546 /* TextureLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureLoader.h; sourceTree = ""; }; - BB6017251FD928AC009BD546 /* PositionMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PositionMode.h; sourceTree = ""; }; - BB6017261FD928AC009BD546 /* RTTI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTTI.h; sourceTree = ""; }; - BB6017271FD928AC009BD546 /* PathAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathAttachment.h; sourceTree = ""; }; - BB6017281FD928AC009BD546 /* MixDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MixDirection.h; sourceTree = ""; }; - BB6017291FD928AC009BD546 /* CurveTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CurveTimeline.h; sourceTree = ""; }; - BB60172A1FD928AC009BD546 /* PointAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PointAttachment.h; sourceTree = ""; }; - BB60172B1FD928AC009BD546 /* Event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Event.h; sourceTree = ""; }; - BB60172C1FD928AC009BD546 /* Bone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bone.h; sourceTree = ""; }; - BB60172D1FD928AC009BD546 /* Atlas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atlas.h; sourceTree = ""; }; - BB60172E1FD928AC009BD546 /* DrawOrderTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawOrderTimeline.h; sourceTree = ""; }; - BB60172F1FD928AC009BD546 /* TransformConstraintTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformConstraintTimeline.h; sourceTree = ""; }; - BB6017301FD928AC009BD546 /* IkConstraintTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IkConstraintTimeline.h; sourceTree = ""; }; - BB6017311FD928AC009BD546 /* VertexAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VertexAttachment.h; sourceTree = ""; }; - BB6017321FD928AC009BD546 /* AttachmentType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachmentType.h; sourceTree = ""; }; - BB6017331FD928AC009BD546 /* RotateMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RotateMode.h; sourceTree = ""; }; - BB6017341FD928AC009BD546 /* ClippingAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClippingAttachment.h; sourceTree = ""; }; - BB6017351FD928AC009BD546 /* PathConstraintPositionTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathConstraintPositionTimeline.h; sourceTree = ""; }; - BB6017361FD928AC009BD546 /* RotateTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RotateTimeline.h; sourceTree = ""; }; - BB6017371FD928AC009BD546 /* Triangulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Triangulator.h; sourceTree = ""; }; - BB6017381FD928AC009BD546 /* RegionAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegionAttachment.h; sourceTree = ""; }; - BB6017391FD928AC009BD546 /* Attachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Attachment.h; sourceTree = ""; }; - BB60173A1FD928AC009BD546 /* HashMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashMap.h; sourceTree = ""; }; - BB60173B1FD928AC009BD546 /* TransformConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformConstraint.h; sourceTree = ""; }; - BB60173C1FD928AC009BD546 /* TransformMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformMode.h; sourceTree = ""; }; - BB60173D1FD928AC009BD546 /* SkeletonJson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkeletonJson.h; sourceTree = ""; }; - BB60173E1FD928AC009BD546 /* IkConstraintData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IkConstraintData.h; sourceTree = ""; }; - BB60173F1FD928AC009BD546 /* MixPose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MixPose.h; sourceTree = ""; }; - BB6017401FD928AC009BD546 /* AnimationStateData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimationStateData.h; sourceTree = ""; }; - BB6017411FD928AC009BD546 /* TwoColorTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TwoColorTimeline.h; sourceTree = ""; }; - BB6017421FD928AC009BD546 /* Skeleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Skeleton.h; sourceTree = ""; }; - BB6017431FD928AC009BD546 /* ColorTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorTimeline.h; sourceTree = ""; }; - BB6017441FD928AC009BD546 /* SpacingMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpacingMode.h; sourceTree = ""; }; - BB6017451FD928AC009BD546 /* Vertices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vertices.h; sourceTree = ""; }; - BB6017461FD928AC009BD546 /* Constraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constraint.h; sourceTree = ""; }; - BB6017471FD928AC009BD546 /* LinkedMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkedMesh.h; sourceTree = ""; }; - BB6017481FD928AC009BD546 /* ShearTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShearTimeline.h; sourceTree = ""; }; - BB6017491FD928AC009BD546 /* Json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Json.h; sourceTree = ""; }; - BB60174A1FD928AC009BD546 /* AttachmentLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachmentLoader.h; sourceTree = ""; }; - BB60174B1FD928AC009BD546 /* Skin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Skin.h; sourceTree = ""; }; - BB60174C1FD928AC009BD546 /* AttachmentTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachmentTimeline.h; sourceTree = ""; }; - BB60174D1FD928AC009BD546 /* SkeletonBinary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkeletonBinary.h; sourceTree = ""; }; - BB60174E1FD928AC009BD546 /* SkeletonData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkeletonData.h; sourceTree = ""; }; - BB60174F1FD928AC009BD546 /* ContainerUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContainerUtil.h; sourceTree = ""; }; - BB6017501FD928AC009BD546 /* PathConstraintData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathConstraintData.h; sourceTree = ""; }; - BB6017511FD928AC009BD546 /* Updatable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Updatable.h; sourceTree = ""; }; - BB6017521FD928AC009BD546 /* TransformConstraintData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformConstraintData.h; sourceTree = ""; }; - BB6017531FD928AC009BD546 /* Extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Extension.h; sourceTree = ""; }; - BB6017541FD928AC009BD546 /* BlendMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlendMode.h; sourceTree = ""; }; - BB6017551FD928AC009BD546 /* PathConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathConstraint.h; sourceTree = ""; }; - BB6017561FD928AC009BD546 /* PathConstraintSpacingTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathConstraintSpacingTimeline.h; sourceTree = ""; }; - BB6017571FD928AC009BD546 /* ScaleTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScaleTimeline.h; sourceTree = ""; }; - BB6017581FD928AC009BD546 /* IkConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IkConstraint.h; sourceTree = ""; }; - BB6017591FD928AC009BD546 /* BoundingBoxAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BoundingBoxAttachment.h; sourceTree = ""; }; - BB60175A1FD928AC009BD546 /* MathUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathUtil.h; sourceTree = ""; }; - BB60175B1FD928AC009BD546 /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = ""; }; - BB60175C1FD928AC009BD546 /* SkeletonBounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkeletonBounds.h; sourceTree = ""; }; - BB60175D1FD928AC009BD546 /* Timeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Timeline.h; sourceTree = ""; }; - BB60175E1FD928AC009BD546 /* Slot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Slot.h; sourceTree = ""; }; - BB60175F1FD928AC009BD546 /* BoneData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BoneData.h; sourceTree = ""; }; - BB6017601FD928AC009BD546 /* TranslateTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TranslateTimeline.h; sourceTree = ""; }; - BB6017611FD928AC009BD546 /* AnimationState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimationState.h; sourceTree = ""; }; - BB6017621FD928AC009BD546 /* MeshAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MeshAttachment.h; sourceTree = ""; }; - BB6017631FD928AC009BD546 /* AtlasAttachmentLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtlasAttachmentLoader.h; sourceTree = ""; }; - BB6017641FD928AC009BD546 /* EventTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventTimeline.h; sourceTree = ""; }; - BB6017671FD928AC009BD546 /* Attachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Attachment.cpp; sourceTree = ""; }; - BB6017681FD928AC009BD546 /* Skeleton.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Skeleton.cpp; sourceTree = ""; }; - BB6017691FD928AC009BD546 /* TranslateTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TranslateTimeline.cpp; sourceTree = ""; }; - BB60176A1FD928AC009BD546 /* Extension.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Extension.cpp; sourceTree = ""; }; - BB60176B1FD928AC009BD546 /* Updatable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Updatable.cpp; sourceTree = ""; }; - BB60176C1FD928AC009BD546 /* Bone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Bone.cpp; sourceTree = ""; }; - BB60176D1FD928AC009BD546 /* AtlasAttachmentLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AtlasAttachmentLoader.cpp; sourceTree = ""; }; - BB60176E1FD928AC009BD546 /* EventTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventTimeline.cpp; sourceTree = ""; }; - BB60176F1FD928AC009BD546 /* PathConstraint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathConstraint.cpp; sourceTree = ""; }; - BB6017701FD928AC009BD546 /* VertexAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VertexAttachment.cpp; sourceTree = ""; }; - BB6017711FD928AC009BD546 /* TextureLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureLoader.cpp; sourceTree = ""; }; - BB6017721FD928AC009BD546 /* SkeletonData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkeletonData.cpp; sourceTree = ""; }; - BB6017731FD928AC009BD546 /* TransformConstraintTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TransformConstraintTimeline.cpp; sourceTree = ""; }; - BB6017741FD928AC009BD546 /* IkConstraint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IkConstraint.cpp; sourceTree = ""; }; - BB6017751FD928AC009BD546 /* CurveTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CurveTimeline.cpp; sourceTree = ""; }; - BB6017761FD928AC009BD546 /* AnimationStateData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimationStateData.cpp; sourceTree = ""; }; - BB6017771FD928AC009BD546 /* Constraint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Constraint.cpp; sourceTree = ""; }; - BB6017781FD928AC009BD546 /* BoundingBoxAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BoundingBoxAttachment.cpp; sourceTree = ""; }; - BB6017791FD928AC009BD546 /* PathAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathAttachment.cpp; sourceTree = ""; }; - BB60177A1FD928AC009BD546 /* MeshAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MeshAttachment.cpp; sourceTree = ""; }; - BB60177B1FD928AC009BD546 /* TransformConstraint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TransformConstraint.cpp; sourceTree = ""; }; - BB60177C1FD928AC009BD546 /* Skin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Skin.cpp; sourceTree = ""; }; - BB60177D1FD928AC009BD546 /* RTTI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTTI.cpp; sourceTree = ""; }; - BB60177E1FD928AC009BD546 /* MathUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathUtil.cpp; sourceTree = ""; }; - BB60177F1FD928AC009BD546 /* IkConstraintData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IkConstraintData.cpp; sourceTree = ""; }; - BB6017801FD928AC009BD546 /* Atlas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Atlas.cpp; sourceTree = ""; }; - BB6017811FD928AC009BD546 /* ClippingAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClippingAttachment.cpp; sourceTree = ""; }; - BB6017821FD928AC009BD546 /* PathConstraintData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathConstraintData.cpp; sourceTree = ""; }; - BB6017831FD928AC009BD546 /* Timeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timeline.cpp; sourceTree = ""; }; - BB6017841FD928AC009BD546 /* SkeletonBinary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkeletonBinary.cpp; sourceTree = ""; }; - BB6017851FD928AC009BD546 /* ScaleTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScaleTimeline.cpp; sourceTree = ""; }; - BB6017861FD928AC009BD546 /* LinkedMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinkedMesh.cpp; sourceTree = ""; }; - BB6017871FD928AC009BD546 /* PointAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PointAttachment.cpp; sourceTree = ""; }; - BB6017881FD928AC009BD546 /* RegionAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegionAttachment.cpp; sourceTree = ""; }; - BB6017891FD928AC009BD546 /* DeformTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeformTimeline.cpp; sourceTree = ""; }; - BB60178A1FD928AC009BD546 /* Animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Animation.cpp; sourceTree = ""; }; - BB60178B1FD928AC009BD546 /* AttachmentLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AttachmentLoader.cpp; sourceTree = ""; }; - BB60178C1FD928AC009BD546 /* DrawOrderTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DrawOrderTimeline.cpp; sourceTree = ""; }; - BB60178D1FD928AC009BD546 /* AttachmentTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AttachmentTimeline.cpp; sourceTree = ""; }; - BB60178E1FD928AC009BD546 /* EventData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventData.cpp; sourceTree = ""; }; - BB60178F1FD928AC009BD546 /* PathConstraintSpacingTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathConstraintSpacingTimeline.cpp; sourceTree = ""; }; - BB6017901FD928AC009BD546 /* PathConstraintPositionTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathConstraintPositionTimeline.cpp; sourceTree = ""; }; - BB6017911FD928AC009BD546 /* TransformConstraintData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TransformConstraintData.cpp; sourceTree = ""; }; - BB6017921FD928AC009BD546 /* SkeletonClipping.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkeletonClipping.cpp; sourceTree = ""; }; - BB6017931FD928AC009BD546 /* TwoColorTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TwoColorTimeline.cpp; sourceTree = ""; }; - BB6017941FD928AC009BD546 /* Slot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Slot.cpp; sourceTree = ""; }; - BB6017951FD928AC009BD546 /* AnimationState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimationState.cpp; sourceTree = ""; }; - BB6017961FD928AC009BD546 /* SkeletonJson.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkeletonJson.cpp; sourceTree = ""; }; - BB6017971FD928AC009BD546 /* BoneData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BoneData.cpp; sourceTree = ""; }; - BB6017981FD928AC009BD546 /* IkConstraintTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IkConstraintTimeline.cpp; sourceTree = ""; }; - BB6017991FD928AC009BD546 /* Event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Event.cpp; sourceTree = ""; }; - BB60179A1FD928AC009BD546 /* RotateTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RotateTimeline.cpp; sourceTree = ""; }; - BB60179B1FD928AC009BD546 /* PathConstraintMixTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathConstraintMixTimeline.cpp; sourceTree = ""; }; - BB60179C1FD928AC009BD546 /* Triangulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Triangulator.cpp; sourceTree = ""; }; - BB60179D1FD928AC009BD546 /* Json.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Json.cpp; sourceTree = ""; }; - BB60179E1FD928AC009BD546 /* SkeletonBounds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkeletonBounds.cpp; sourceTree = ""; }; - BB60179F1FD928AC009BD546 /* SlotData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlotData.cpp; sourceTree = ""; }; - BB6017A01FD928AC009BD546 /* ShearTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShearTimeline.cpp; sourceTree = ""; }; - BB6017A11FD928AC009BD546 /* ColorTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColorTimeline.cpp; sourceTree = ""; }; - BB6017DE1FD928F6009BD546 /* KMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KMemory.h; sourceTree = ""; }; - BB6017DF1FD928F6009BD546 /* KString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KString.h; sourceTree = ""; }; - BB6017E01FD928F6009BD546 /* KMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KMemory.cpp; sourceTree = ""; }; - BB6017E11FD928F6009BD546 /* KString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KString.cpp; sourceTree = ""; }; - BB6017E51FD929D0009BD546 /* MiniCppUnit.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MiniCppUnit.hxx; sourceTree = ""; }; - BB6017E61FD929D0009BD546 /* MiniCppUnit.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MiniCppUnit.cxx; sourceTree = ""; }; - BB6017E91FD929F4009BD546 /* teamcity_cppunit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = teamcity_cppunit.h; sourceTree = ""; }; - BB6017EA1FD929F4009BD546 /* teamcity_cppunit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = teamcity_cppunit.cpp; sourceTree = ""; }; - BB6017EB1FD929F4009BD546 /* teamcity_messages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = teamcity_messages.h; sourceTree = ""; }; - BB6017EC1FD929F4009BD546 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.txt; sourceTree = ""; }; - BB6017ED1FD929F4009BD546 /* teamcity_messages.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = teamcity_messages.cpp; sourceTree = ""; }; - BB6017F01FD92A5B009BD546 /* SimpleTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SimpleTest.h; sourceTree = ""; }; - BB6017FC1FD92AF3009BD546 /* SpineEventMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpineEventMonitor.h; sourceTree = ""; }; - BB6017FD1FD92AF3009BD546 /* SpineEventMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpineEventMonitor.cpp; sourceTree = ""; }; - BBFB507F1FDAF6CD005B22B6 /* MemoryTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MemoryTest.h; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - BB60170C1FD9289A009BD546 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - BB6017061FD9289A009BD546 = { - isa = PBXGroup; - children = ( - BB4E385C1FD9C87600709FF2 /* goblins-pro.json */, - BB4E385D1FD9C87700709FF2 /* goblins.atlas */, - BB4E38591FD9C86400709FF2 /* raptor-pro.json */, - BB4E38581FD9C86400709FF2 /* raptor.atlas */, - BB4E38541FD9C85600709FF2 /* spineboy-ess.json */, - BB4E38551FD9C85600709FF2 /* spineboy.atlas */, - BB6017F11FD92AF3009BD546 /* tests */, - BB6017E81FD929F4009BD546 /* teamcity */, - BB6017E41FD929D0009BD546 /* minicppunit */, - BB6017DD1FD928F6009BD546 /* memory */, - BB6017191FD928AC009BD546 /* spine-cpp */, - BB6017111FD9289A009BD546 /* spine_unit_test */, - BB6017101FD9289A009BD546 /* Products */, - ); - sourceTree = ""; - }; - BB6017101FD9289A009BD546 /* Products */ = { - isa = PBXGroup; - children = ( - BB60170F1FD9289A009BD546 /* spine_unit_test */, - ); - name = Products; - sourceTree = ""; - }; - BB6017111FD9289A009BD546 /* spine_unit_test */ = { - isa = PBXGroup; - children = ( - BB6017121FD9289A009BD546 /* main.cpp */, - BB6017F01FD92A5B009BD546 /* SimpleTest.h */, - BBFB507F1FDAF6CD005B22B6 /* MemoryTest.h */, - ); - path = spine_unit_test; - sourceTree = ""; - }; - BB6017191FD928AC009BD546 /* spine-cpp */ = { - isa = PBXGroup; - children = ( - BB60171A1FD928AC009BD546 /* include */, - BB6017651FD928AC009BD546 /* src */, - ); - name = "spine-cpp"; - path = "../../spine-cpp"; - sourceTree = ""; - }; - BB60171A1FD928AC009BD546 /* include */ = { - isa = PBXGroup; - children = ( - BB60171B1FD928AC009BD546 /* spine */, - ); - path = include; - sourceTree = ""; - }; - BB60171B1FD928AC009BD546 /* spine */ = { - isa = PBXGroup; - children = ( - BB60171D1FD928AC009BD546 /* Animation.h */, - BB6017611FD928AC009BD546 /* AnimationState.h */, - BB6017401FD928AC009BD546 /* AnimationStateData.h */, - BB60172D1FD928AC009BD546 /* Atlas.h */, - BB6017631FD928AC009BD546 /* AtlasAttachmentLoader.h */, - BB6017391FD928AC009BD546 /* Attachment.h */, - BB60174A1FD928AC009BD546 /* AttachmentLoader.h */, - BB60174C1FD928AC009BD546 /* AttachmentTimeline.h */, - BB6017321FD928AC009BD546 /* AttachmentType.h */, - BB6017541FD928AC009BD546 /* BlendMode.h */, - BB60172C1FD928AC009BD546 /* Bone.h */, - BB60175F1FD928AC009BD546 /* BoneData.h */, - BB6017591FD928AC009BD546 /* BoundingBoxAttachment.h */, - BB6017341FD928AC009BD546 /* ClippingAttachment.h */, - BB6017431FD928AC009BD546 /* ColorTimeline.h */, - BB6017461FD928AC009BD546 /* Constraint.h */, - BB60174F1FD928AC009BD546 /* ContainerUtil.h */, - BB6017291FD928AC009BD546 /* CurveTimeline.h */, - BB60171C1FD928AC009BD546 /* DeformTimeline.h */, - BB60172E1FD928AC009BD546 /* DrawOrderTimeline.h */, - BB60172B1FD928AC009BD546 /* Event.h */, - BB60171E1FD928AC009BD546 /* EventData.h */, - BB6017641FD928AC009BD546 /* EventTimeline.h */, - BB6017531FD928AC009BD546 /* Extension.h */, - BB60173A1FD928AC009BD546 /* HashMap.h */, - BB6017581FD928AC009BD546 /* IkConstraint.h */, - BB60173E1FD928AC009BD546 /* IkConstraintData.h */, - BB6017301FD928AC009BD546 /* IkConstraintTimeline.h */, - BB6017491FD928AC009BD546 /* Json.h */, - BB6017471FD928AC009BD546 /* LinkedMesh.h */, - BB60175A1FD928AC009BD546 /* MathUtil.h */, - BB6017621FD928AC009BD546 /* MeshAttachment.h */, - BB6017281FD928AC009BD546 /* MixDirection.h */, - BB60173F1FD928AC009BD546 /* MixPose.h */, - BB6017271FD928AC009BD546 /* PathAttachment.h */, - BB6017551FD928AC009BD546 /* PathConstraint.h */, - BB6017501FD928AC009BD546 /* PathConstraintData.h */, - BB6017201FD928AC009BD546 /* PathConstraintMixTimeline.h */, - BB6017351FD928AC009BD546 /* PathConstraintPositionTimeline.h */, - BB6017561FD928AC009BD546 /* PathConstraintSpacingTimeline.h */, - BB60172A1FD928AC009BD546 /* PointAttachment.h */, - BB6017221FD928AC009BD546 /* Pool.h */, - BB6017251FD928AC009BD546 /* PositionMode.h */, - BB6017381FD928AC009BD546 /* RegionAttachment.h */, - BB6017331FD928AC009BD546 /* RotateMode.h */, - BB6017361FD928AC009BD546 /* RotateTimeline.h */, - BB6017261FD928AC009BD546 /* RTTI.h */, - BB6017571FD928AC009BD546 /* ScaleTimeline.h */, - BB6017481FD928AC009BD546 /* ShearTimeline.h */, - BB6017421FD928AC009BD546 /* Skeleton.h */, - BB60174D1FD928AC009BD546 /* SkeletonBinary.h */, - BB60175C1FD928AC009BD546 /* SkeletonBounds.h */, - BB6017211FD928AC009BD546 /* SkeletonClipping.h */, - BB60174E1FD928AC009BD546 /* SkeletonData.h */, - BB60173D1FD928AC009BD546 /* SkeletonJson.h */, - BB60174B1FD928AC009BD546 /* Skin.h */, - BB60175E1FD928AC009BD546 /* Slot.h */, - BB60171F1FD928AC009BD546 /* SlotData.h */, - BB6017441FD928AC009BD546 /* SpacingMode.h */, - BB6017241FD928AC009BD546 /* TextureLoader.h */, - BB60175D1FD928AC009BD546 /* Timeline.h */, - BB6017231FD928AC009BD546 /* TimelineType.h */, - BB60173B1FD928AC009BD546 /* TransformConstraint.h */, - BB6017521FD928AC009BD546 /* TransformConstraintData.h */, - BB60172F1FD928AC009BD546 /* TransformConstraintTimeline.h */, - BB60173C1FD928AC009BD546 /* TransformMode.h */, - BB6017601FD928AC009BD546 /* TranslateTimeline.h */, - BB6017371FD928AC009BD546 /* Triangulator.h */, - BB6017411FD928AC009BD546 /* TwoColorTimeline.h */, - BB6017511FD928AC009BD546 /* Updatable.h */, - BB60175B1FD928AC009BD546 /* Vector.h */, - BB6017311FD928AC009BD546 /* VertexAttachment.h */, - BB6017451FD928AC009BD546 /* Vertices.h */, - ); - path = spine; - sourceTree = ""; - }; - BB6017651FD928AC009BD546 /* src */ = { - isa = PBXGroup; - children = ( - BB6017661FD928AC009BD546 /* spine */, - ); - path = src; - sourceTree = ""; - }; - BB6017661FD928AC009BD546 /* spine */ = { - isa = PBXGroup; - children = ( - BB60178A1FD928AC009BD546 /* Animation.cpp */, - BB6017951FD928AC009BD546 /* AnimationState.cpp */, - BB6017761FD928AC009BD546 /* AnimationStateData.cpp */, - BB6017801FD928AC009BD546 /* Atlas.cpp */, - BB60176D1FD928AC009BD546 /* AtlasAttachmentLoader.cpp */, - BB6017671FD928AC009BD546 /* Attachment.cpp */, - BB60178B1FD928AC009BD546 /* AttachmentLoader.cpp */, - BB60178D1FD928AC009BD546 /* AttachmentTimeline.cpp */, - BB60176C1FD928AC009BD546 /* Bone.cpp */, - BB6017971FD928AC009BD546 /* BoneData.cpp */, - BB6017781FD928AC009BD546 /* BoundingBoxAttachment.cpp */, - BB6017811FD928AC009BD546 /* ClippingAttachment.cpp */, - BB6017A11FD928AC009BD546 /* ColorTimeline.cpp */, - BB6017771FD928AC009BD546 /* Constraint.cpp */, - BB6017751FD928AC009BD546 /* CurveTimeline.cpp */, - BB6017891FD928AC009BD546 /* DeformTimeline.cpp */, - BB60178C1FD928AC009BD546 /* DrawOrderTimeline.cpp */, - BB6017991FD928AC009BD546 /* Event.cpp */, - BB60178E1FD928AC009BD546 /* EventData.cpp */, - BB60176E1FD928AC009BD546 /* EventTimeline.cpp */, - BB60176A1FD928AC009BD546 /* Extension.cpp */, - BB6017741FD928AC009BD546 /* IkConstraint.cpp */, - BB60177F1FD928AC009BD546 /* IkConstraintData.cpp */, - BB6017981FD928AC009BD546 /* IkConstraintTimeline.cpp */, - BB60179D1FD928AC009BD546 /* Json.cpp */, - BB6017861FD928AC009BD546 /* LinkedMesh.cpp */, - BB60177E1FD928AC009BD546 /* MathUtil.cpp */, - BB60177A1FD928AC009BD546 /* MeshAttachment.cpp */, - BB6017791FD928AC009BD546 /* PathAttachment.cpp */, - BB60176F1FD928AC009BD546 /* PathConstraint.cpp */, - BB6017821FD928AC009BD546 /* PathConstraintData.cpp */, - BB60179B1FD928AC009BD546 /* PathConstraintMixTimeline.cpp */, - BB6017901FD928AC009BD546 /* PathConstraintPositionTimeline.cpp */, - BB60178F1FD928AC009BD546 /* PathConstraintSpacingTimeline.cpp */, - BB6017871FD928AC009BD546 /* PointAttachment.cpp */, - BB6017881FD928AC009BD546 /* RegionAttachment.cpp */, - BB60179A1FD928AC009BD546 /* RotateTimeline.cpp */, - BB60177D1FD928AC009BD546 /* RTTI.cpp */, - BB6017851FD928AC009BD546 /* ScaleTimeline.cpp */, - BB6017A01FD928AC009BD546 /* ShearTimeline.cpp */, - BB6017681FD928AC009BD546 /* Skeleton.cpp */, - BB6017841FD928AC009BD546 /* SkeletonBinary.cpp */, - BB60179E1FD928AC009BD546 /* SkeletonBounds.cpp */, - BB6017921FD928AC009BD546 /* SkeletonClipping.cpp */, - BB6017721FD928AC009BD546 /* SkeletonData.cpp */, - BB6017961FD928AC009BD546 /* SkeletonJson.cpp */, - BB60177C1FD928AC009BD546 /* Skin.cpp */, - BB6017941FD928AC009BD546 /* Slot.cpp */, - BB60179F1FD928AC009BD546 /* SlotData.cpp */, - BB6017711FD928AC009BD546 /* TextureLoader.cpp */, - BB6017831FD928AC009BD546 /* Timeline.cpp */, - BB60177B1FD928AC009BD546 /* TransformConstraint.cpp */, - BB6017911FD928AC009BD546 /* TransformConstraintData.cpp */, - BB6017731FD928AC009BD546 /* TransformConstraintTimeline.cpp */, - BB6017691FD928AC009BD546 /* TranslateTimeline.cpp */, - BB60179C1FD928AC009BD546 /* Triangulator.cpp */, - BB6017931FD928AC009BD546 /* TwoColorTimeline.cpp */, - BB60176B1FD928AC009BD546 /* Updatable.cpp */, - BB6017701FD928AC009BD546 /* VertexAttachment.cpp */, - ); - path = spine; - sourceTree = ""; - }; - BB6017DD1FD928F6009BD546 /* memory */ = { - isa = PBXGroup; - children = ( - BB6017DE1FD928F6009BD546 /* KMemory.h */, - BB6017DF1FD928F6009BD546 /* KString.h */, - BB6017E01FD928F6009BD546 /* KMemory.cpp */, - BB6017E11FD928F6009BD546 /* KString.cpp */, - ); - name = memory; - path = ../memory; - sourceTree = ""; - }; - BB6017E41FD929D0009BD546 /* minicppunit */ = { - isa = PBXGroup; - children = ( - BB6017E51FD929D0009BD546 /* MiniCppUnit.hxx */, - BB6017E61FD929D0009BD546 /* MiniCppUnit.cxx */, - ); - name = minicppunit; - path = ../minicppunit; - sourceTree = ""; - }; - BB6017E81FD929F4009BD546 /* teamcity */ = { - isa = PBXGroup; - children = ( - BB6017E91FD929F4009BD546 /* teamcity_cppunit.h */, - BB6017EA1FD929F4009BD546 /* teamcity_cppunit.cpp */, - BB6017EB1FD929F4009BD546 /* teamcity_messages.h */, - BB6017EC1FD929F4009BD546 /* README.txt */, - BB6017ED1FD929F4009BD546 /* teamcity_messages.cpp */, - ); - name = teamcity; - path = ../teamcity; - sourceTree = ""; - }; - BB6017F11FD92AF3009BD546 /* tests */ = { - isa = PBXGroup; - children = ( - BB6017FC1FD92AF3009BD546 /* SpineEventMonitor.h */, - BB6017FD1FD92AF3009BD546 /* SpineEventMonitor.cpp */, - ); - name = tests; - path = ../tests; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - BB60170E1FD9289A009BD546 /* spine_unit_test */ = { - isa = PBXNativeTarget; - buildConfigurationList = BB6017161FD9289A009BD546 /* Build configuration list for PBXNativeTarget "spine_unit_test" */; - buildPhases = ( - BB60170B1FD9289A009BD546 /* Sources */, - BB60170C1FD9289A009BD546 /* Frameworks */, - BB60170D1FD9289A009BD546 /* CopyFiles */, - BB4E38471FD9C72600709FF2 /* CopyFiles */, - BB4E384A1FD9C79D00709FF2 /* CopyFiles */, - BB4E384B1FD9C79E00709FF2 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = spine_unit_test; - productName = spine_unit_test; - productReference = BB60170F1FD9289A009BD546 /* spine_unit_test */; - productType = "com.apple.product-type.tool"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - BB6017071FD9289A009BD546 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0920; - ORGANIZATIONNAME = "Noctis Games"; - TargetAttributes = { - BB60170E1FD9289A009BD546 = { - CreatedOnToolsVersion = 9.2; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = BB60170A1FD9289A009BD546 /* Build configuration list for PBXProject "spine_unit_test" */; - compatibilityVersion = "Xcode 8.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = BB6017061FD9289A009BD546; - productRefGroup = BB6017101FD9289A009BD546 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - BB60170E1FD9289A009BD546 /* spine_unit_test */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - BB60170B1FD9289A009BD546 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - BB6017CB1FD928AC009BD546 /* PathConstraintPositionTimeline.cpp in Sources */, - BB6017CD1FD928AC009BD546 /* SkeletonClipping.cpp in Sources */, - BB6017B51FD928AC009BD546 /* MeshAttachment.cpp in Sources */, - BB6017C01FD928AC009BD546 /* ScaleTimeline.cpp in Sources */, - BB6017D01FD928AC009BD546 /* AnimationState.cpp in Sources */, - BB6017A31FD928AC009BD546 /* Skeleton.cpp in Sources */, - BB6017BA1FD928AC009BD546 /* IkConstraintData.cpp in Sources */, - BB6017EE1FD929F4009BD546 /* teamcity_cppunit.cpp in Sources */, - BB6017CA1FD928AC009BD546 /* PathConstraintSpacingTimeline.cpp in Sources */, - BB6017C91FD928AC009BD546 /* EventData.cpp in Sources */, - BB6017B41FD928AC009BD546 /* PathAttachment.cpp in Sources */, - BB6017A91FD928AC009BD546 /* EventTimeline.cpp in Sources */, - BB6017A21FD928AC009BD546 /* Attachment.cpp in Sources */, - BB6017C81FD928AC009BD546 /* AttachmentTimeline.cpp in Sources */, - BB6017E21FD928F7009BD546 /* KMemory.cpp in Sources */, - BB6017E71FD929D0009BD546 /* MiniCppUnit.cxx in Sources */, - BB6017DA1FD928AC009BD546 /* SlotData.cpp in Sources */, - BB6017BE1FD928AC009BD546 /* Timeline.cpp in Sources */, - BB6017BF1FD928AC009BD546 /* SkeletonBinary.cpp in Sources */, - BB6017131FD9289A009BD546 /* main.cpp in Sources */, - BB6017B21FD928AC009BD546 /* Constraint.cpp in Sources */, - BB6017A41FD928AC009BD546 /* TranslateTimeline.cpp in Sources */, - BB6017A71FD928AC009BD546 /* Bone.cpp in Sources */, - BB6017DC1FD928AC009BD546 /* ColorTimeline.cpp in Sources */, - BB6017AE1FD928AC009BD546 /* TransformConstraintTimeline.cpp in Sources */, - BB6017BB1FD928AC009BD546 /* Atlas.cpp in Sources */, - BB6017C21FD928AC009BD546 /* PointAttachment.cpp in Sources */, - BB6017C11FD928AC009BD546 /* LinkedMesh.cpp in Sources */, - BB6017A61FD928AC009BD546 /* Updatable.cpp in Sources */, - BB6017DB1FD928AC009BD546 /* ShearTimeline.cpp in Sources */, - BB6017C31FD928AC009BD546 /* RegionAttachment.cpp in Sources */, - BB6017D71FD928AC009BD546 /* Triangulator.cpp in Sources */, - BB6017EF1FD929F4009BD546 /* teamcity_messages.cpp in Sources */, - BB6017D61FD928AC009BD546 /* PathConstraintMixTimeline.cpp in Sources */, - BB6017CC1FD928AC009BD546 /* TransformConstraintData.cpp in Sources */, - BB6017C71FD928AC009BD546 /* DrawOrderTimeline.cpp in Sources */, - BB6017B61FD928AC009BD546 /* TransformConstraint.cpp in Sources */, - BB6017BC1FD928AC009BD546 /* ClippingAttachment.cpp in Sources */, - BB6017B81FD928AC009BD546 /* RTTI.cpp in Sources */, - BB6017A51FD928AC009BD546 /* Extension.cpp in Sources */, - BB6017C41FD928AC009BD546 /* DeformTimeline.cpp in Sources */, - BB6017A81FD928AC009BD546 /* AtlasAttachmentLoader.cpp in Sources */, - BB6017AA1FD928AC009BD546 /* PathConstraint.cpp in Sources */, - BB6017B71FD928AC009BD546 /* Skin.cpp in Sources */, - BB6017D21FD928AC009BD546 /* BoneData.cpp in Sources */, - BB6017C61FD928AC009BD546 /* AttachmentLoader.cpp in Sources */, - BB6017CF1FD928AC009BD546 /* Slot.cpp in Sources */, - BB6017B91FD928AC009BD546 /* MathUtil.cpp in Sources */, - BB6017B11FD928AC009BD546 /* AnimationStateData.cpp in Sources */, - BB6018081FD92AF4009BD546 /* SpineEventMonitor.cpp in Sources */, - BB6017E31FD928F7009BD546 /* KString.cpp in Sources */, - BB6017D41FD928AC009BD546 /* Event.cpp in Sources */, - BB6017D81FD928AC009BD546 /* Json.cpp in Sources */, - BB6017CE1FD928AC009BD546 /* TwoColorTimeline.cpp in Sources */, - BB6017AD1FD928AC009BD546 /* SkeletonData.cpp in Sources */, - BB6017D11FD928AC009BD546 /* SkeletonJson.cpp in Sources */, - BB6017D31FD928AC009BD546 /* IkConstraintTimeline.cpp in Sources */, - BB6017AF1FD928AC009BD546 /* IkConstraint.cpp in Sources */, - BB6017AC1FD928AC009BD546 /* TextureLoader.cpp in Sources */, - BB6017C51FD928AC009BD546 /* Animation.cpp in Sources */, - BB6017B01FD928AC009BD546 /* CurveTimeline.cpp in Sources */, - BB6017BD1FD928AC009BD546 /* PathConstraintData.cpp in Sources */, - BB6017D91FD928AC009BD546 /* SkeletonBounds.cpp in Sources */, - BB6017B31FD928AC009BD546 /* BoundingBoxAttachment.cpp in Sources */, - BB6017D51FD928AC009BD546 /* RotateTimeline.cpp in Sources */, - BB6017AB1FD928AC009BD546 /* VertexAttachment.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - BB6017141FD9289A009BD546 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - }; - name = Debug; - }; - BB6017151FD9289A009BD546 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - }; - name = Release; - }; - BB6017171FD9289A009BD546 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../spine-cpp/include\""; - OTHER_LDFLAGS = "-DKANJI_MEMTRACE"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - BB6017181FD9289A009BD546 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../spine-cpp/include\""; - OTHER_LDFLAGS = "-DKANJI_MEMTRACE"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - BB60170A1FD9289A009BD546 /* Build configuration list for PBXProject "spine_unit_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BB6017141FD9289A009BD546 /* Debug */, - BB6017151FD9289A009BD546 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - BB6017161FD9289A009BD546 /* Build configuration list for PBXNativeTarget "spine_unit_test" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BB6017171FD9289A009BD546 /* Debug */, - BB6017181FD9289A009BD546 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = BB6017071FD9289A009BD546 /* Project object */; -} diff --git a/spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index af455f762..000000000 --- a/spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/spine-cpp/spine-cpp-unit-tests/src/TestHarness.cpp b/spine-cpp/spine-cpp-unit-tests/src/TestHarness.cpp new file mode 100644 index 000000000..03e0d2ba3 --- /dev/null +++ b/spine-cpp/spine-cpp-unit-tests/src/TestHarness.cpp @@ -0,0 +1,84 @@ +/****************************************************************************** + * Spine Runtimes Software License v2.5 + * + * Copyright (c) 2013-2016, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable, and + * non-transferable license to use, install, execute, and perform the Spine + * Runtimes software and derivative works solely for personal or internal + * use. Without the written permission of Esoteric Software (see Section 2 of + * the Spine Software License Agreement), you may not (a) modify, translate, + * adapt, or develop new applications using the Spine Runtimes or otherwise + * create derivative works or improvements of the Spine Runtimes or (b) remove, + * delete, alter, or obscure any trademarks or any copyright, trademark, patent, + * or other intellectual property or proprietary rights notices on or in the + * Software, including any copy thereof. Redistributions in binary or source + * form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF + * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + + +#include "TestHarness.h" + +void *Spine::TestSpineExtension::_alloc(size_t size, const char *file, int line) { + void* result = DefaultSpineExtension::_alloc(size, file, line); + allocated.push_back(Allocation(result, size, file, line)); + return result; +} + +void *Spine::TestSpineExtension::_calloc(size_t size, const char *file, int line) { + void* result = DefaultSpineExtension::_calloc(size, file, line); + allocated.push_back(Allocation(result, size, file, line)); + return result; +} + +void *Spine::TestSpineExtension::_realloc(void *ptr, size_t size, const char *file, int line) { + void* result = DefaultSpineExtension::_realloc(ptr, size, file, line); + + for (std::vector::iterator it = allocated.begin(); it != allocated.end(); it++) { + if (it->address == ptr) { + it->address = result; + it->size = size; + it->fileName = file; + it->line = line; + return result; + } + } + + allocated.push_back(Allocation(result, size, file, line)); + return result; +} + +void Spine::TestSpineExtension::_free(void *mem, const char *file, int line) { + DefaultSpineExtension::_free(mem, file, line); + + for (std::vector::iterator it = allocated.begin(); it != allocated.end(); it++) { + if (it->address == mem) { + allocated.erase(it); + return; + } + } + + printf("%s:%i (address %p): Double free or not allocatedö through SpineExtension", file, line, mem); +} + +void Spine::TestSpineExtension::reportLeaks() { + for (std::vector::iterator it = allocated.begin(); it != allocated.end(); it++) { + printf("\"%s:%i (%zu bytes at %p)\n", it->fileName, it->line, it->size, it->address); + } +} + +void Spine::TestSpineExtension::clearAllocations() { + allocated.resize(0); +} diff --git a/spine-cpp/spine-cpp-unit-tests/src/TestHarness.h b/spine-cpp/spine-cpp-unit-tests/src/TestHarness.h new file mode 100644 index 000000000..ee40045ed --- /dev/null +++ b/spine-cpp/spine-cpp-unit-tests/src/TestHarness.h @@ -0,0 +1,72 @@ +/****************************************************************************** + * Spine Runtimes Software License v2.5 + * + * Copyright (c) 2013-2016, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable, and + * non-transferable license to use, install, execute, and perform the Spine + * Runtimes software and derivative works solely for personal or internal + * use. Without the written permission of Esoteric Software (see Section 2 of + * the Spine Software License Agreement), you may not (a) modify, translate, + * adapt, or develop new applications using the Spine Runtimes or otherwise + * create derivative works or improvements of the Spine Runtimes or (b) remove, + * delete, alter, or obscure any trademarks or any copyright, trademark, patent, + * or other intellectual property or proprietary rights notices on or in the + * Software, including any copy thereof. Redistributions in binary or source + * form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF + * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + + +#ifndef SPINE_TESTHARNESS_H +#define SPINE_TESTHARNESS_H + +#include +#include + +namespace Spine { + struct Allocation { + void* address; + size_t size; + const char* fileName; + int line; + + Allocation() : Allocation (0, 0, 0, 0) { + } + + Allocation(void* a, size_t s, const char* f, int l) : address(a), size(s), fileName(f), line(l) { + } + }; + + class TestSpineExtension: public DefaultSpineExtension { + public: + void reportLeaks (); + void clearAllocations(); + + protected: + virtual void* _alloc(size_t size, const char* file, int line); + + virtual void* _calloc(size_t size, const char* file, int line); + + virtual void* _realloc(void* ptr, size_t size, const char* file, int line); + + virtual void _free(void* mem, const char* file, int line); + + private: + std::vector allocated; + }; +} + + +#endif //SPINE_TESTHARNESS_H diff --git a/spine-cpp/spine-cpp-unit-tests/src/main.cpp b/spine-cpp/spine-cpp-unit-tests/src/main.cpp new file mode 100644 index 000000000..1221ad9e5 --- /dev/null +++ b/spine-cpp/spine-cpp-unit-tests/src/main.cpp @@ -0,0 +1,51 @@ +/****************************************************************************** + * Spine Runtimes Software License v2.5 + * + * Copyright (c) 2013-2016, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable, and + * non-transferable license to use, install, execute, and perform the Spine + * Runtimes software and derivative works solely for personal or internal + * use. Without the written permission of Esoteric Software (see Section 2 of + * the Spine Software License Agreement), you may not (a) modify, translate, + * adapt, or develop new applications using the Spine Runtimes or otherwise + * create derivative works or improvements of the Spine Runtimes or (b) remove, + * delete, alter, or obscure any trademarks or any copyright, trademark, patent, + * or other intellectual property or proprietary rights notices on or in the + * Software, including any copy thereof. Redistributions in binary or source + * form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, BUSINESS INTERRUPTION, OR LOSS OF + * USE, DATA, OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include +#include + +#include "TestHarness.h" + +#define SPINEBOY_JSON "testdata/spineboy/spineboy-ess.json" +#define SPINEBOY_ATLAS "testdata/spineboy/spineboy.atlas" + +using namespace Spine; + +int main (int argc, char** argv) { + TestSpineExtension* ext = new TestSpineExtension(); + SpineExtension::setInstance(ext); + + Atlas* atlas = new (__FILE__, __LINE__) Atlas(SPINEBOY_ATLAS, 0); + + + delete atlas; + + ext->reportLeaks(); +} \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/teamcity/README.txt b/spine-cpp/spine-cpp-unit-tests/teamcity/README.txt deleted file mode 100755 index 04f7914b9..000000000 --- a/spine-cpp/spine-cpp-unit-tests/teamcity/README.txt +++ /dev/null @@ -1,30 +0,0 @@ -CppUnit listener for TeamCity ------------------------------ - -To report your tests result to TeamCity server -include teamcity_messages.* teamcity_cppunit.* -to your project and modify "main" function -as shown in example.cpp -(around JetBrains::underTeamcity and JetBrains::TeamcityProgressListener) - -Technical details ------------------ - -Reporting implemented by writing TeamCity service messages to stdout. - -See -http://www.jetbrains.net/confluence/display/TCD3/Build+Script+Interaction+with+TeamCity -for more details. - -Contact information -------------------- - -Mail to teamcity-feedback@jetbrains.com or see other options at - -http://www.jetbrains.com/support/teamcity - -License -------- - -Apache, version 2.0 -http://www.apache.org/licenses/LICENSE-2.0 diff --git a/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_cppunit.cpp b/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_cppunit.cpp deleted file mode 100755 index 86f163b9c..000000000 --- a/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_cppunit.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright 2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * $Revision: 88625 $ -*/ - -#include - -#include "teamcity_cppunit.h" - -using namespace std; - -namespace JetBrains { - -TeamcityProgressListener::TeamcityProgressListener() -{ - flowid = getFlowIdFromEnvironment(); -} - -TeamcityProgressListener::TeamcityProgressListener(const std::string& _flowid) -{ - flowid = _flowid; -} - -void TeamcityProgressListener::startTest(const std::string& test) { - messages.testStarted(test, flowid); -} - -static string sourceLine2string(const SourceLine &sline) { - stringstream ss; - - ss << sline.fileName << ":" << sline.lineNumber; - - return ss.str(); -} - -void TeamcityProgressListener::addFailure(const TestFailure &failure) -{ - - string details = failure.details; - - if (failure.sourceLine.isValid()) { - details.append(" at "); - details.append(sourceLine2string(failure.sourceLine)); - details.append("\n"); - } - - messages.testFailed( - failure.testName, - failure.description, - details, - flowid - ); -} - -void TeamcityProgressListener::endTest(const std::string& test) -{ - messages.testFinished(test, -1, flowid); -} - -void TeamcityProgressListener::startSuite(const std::string& test) -{ - messages.suiteStarted(test, flowid); -} - -void TeamcityProgressListener::endSuite(const std::string& test) -{ - messages.suiteFinished(test, flowid); -} - -} diff --git a/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_cppunit.h b/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_cppunit.h deleted file mode 100755 index 7541a5186..000000000 --- a/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_cppunit.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright 2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * $Revision: 88625 $ -*/ - -#pragma once - -#include - -#include "teamcity_messages.h" - -namespace JetBrains { - - class SourceLine - { - public: - SourceLine():lineNumber(-1){} - SourceLine(const std::string& theFile, int theLineNum):fileName(theFile),lineNumber(theLineNum){} - ~SourceLine(){} - - std::string fileName; - int lineNumber; - bool isValid() const {return (!fileName.empty() && lineNumber > -1);} - }; - - class TestFailure - { - public: - std::string details; - SourceLine sourceLine; - std::string testName; - std::string description; - public: - TestFailure(){} - ~TestFailure(){} - - TestFailure(const std::string& theTestName, const std::string& theDetails, SourceLine theSourcelLine, const std::string& theDescription) - { - testName = theTestName; - details = theDetails; - sourceLine = theSourcelLine; - description = theDescription; - } - }; - - class TeamcityProgressListener - { - public: - TeamcityMessages messages; - public: - TeamcityProgressListener(const std::string& _flowid); - TeamcityProgressListener(); - ~TeamcityProgressListener(){} - - void startTest(const std::string& test); - void addFailure(const TestFailure &failure); - void endTest(const std::string& test); - void startSuite(const std::string& test); - void endSuite(const std::string& test); - - private: - std::string flowid; - - // Prevents the use of the copy constructor. - TeamcityProgressListener(const TeamcityProgressListener ©); - - // Prevents the use of the copy operator. - void operator =(const TeamcityProgressListener ©); - }; - -} \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_messages.cpp b/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_messages.cpp deleted file mode 100755 index 6f88d1ee9..000000000 --- a/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_messages.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* Copyright 2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * $Revision: 88625 $ -*/ - -#include -#include - -#include "teamcity_messages.h" - -using namespace std; - -namespace JetBrains { - -std::string getFlowIdFromEnvironment() { - const char *flowId = getenv("TEAMCITY_PROCESS_FLOW_ID"); - return flowId == NULL ? "" : flowId; -} - -bool underTeamcity() { - return getenv("TEAMCITY_PROJECT_NAME") != NULL; -} - -TeamcityMessages::TeamcityMessages() -: m_out(&cout) -{} - -void TeamcityMessages::setOutput(ostream &out) { - m_out = &out; -} - -string TeamcityMessages::escape(string s) { - string result; - - for (size_t i = 0; i < s.length(); i++) { - char c = s[i]; - - switch (c) { - case '\n': result.append("|n"); break; - case '\r': result.append("|r"); break; - case '\'': result.append("|'"); break; - case '|': result.append("||"); break; - case ']': result.append("|]"); break; - default: result.append(&c, 1); - } - } - - return result; -} - -void TeamcityMessages::openMsg(const string &name) { - // endl for http://jetbrains.net/tracker/issue/TW-4412 - *m_out << endl << "##teamcity[" << name; -} - -void TeamcityMessages::closeMsg() { - *m_out << "]"; - // endl for http://jetbrains.net/tracker/issue/TW-4412 - *m_out << endl; - m_out->flush(); -} - -void TeamcityMessages::writeProperty(string name, string value) { - *m_out << " " << name << "='" << escape(value) << "'"; -} - -void TeamcityMessages::suiteStarted(string name, string flowid) { - openMsg("testSuiteStarted"); - writeProperty("name", name); - if(flowid.length() > 0) { - writeProperty("flowId", flowid); - } - - closeMsg(); -} - -void TeamcityMessages::suiteFinished(string name, string flowid) { - openMsg("testSuiteFinished"); - writeProperty("name", name); - if(flowid.length() > 0) { - writeProperty("flowId", flowid); - } - - closeMsg(); -} - -void TeamcityMessages::testStarted(string name, string flowid) { - openMsg("testStarted"); - writeProperty("name", name); - if(flowid.length() > 0) { - writeProperty("flowId", flowid); - } - - closeMsg(); -} - -void TeamcityMessages::testFinished(string name, int durationMs, string flowid) { - openMsg("testFinished"); - - writeProperty("name", name); - - if(flowid.length() > 0) { - writeProperty("flowId", flowid); - } - - if(durationMs >= 0) { - stringstream out; - out << durationMs; - writeProperty("duration", out.str()); - } - - closeMsg(); -} - -void TeamcityMessages::testFailed(string name, string message, string details, string flowid) { - openMsg("testFailed"); - writeProperty("name", name); - writeProperty("message", message); - writeProperty("details", details); - if(flowid.length() > 0) { - writeProperty("flowId", flowid); - } - - closeMsg(); -} - -void TeamcityMessages::testIgnored(std::string name, std::string message, string flowid) { - openMsg("testIgnored"); - writeProperty("name", name); - writeProperty("message", message); - if(flowid.length() > 0) { - writeProperty("flowId", flowid); - } - - closeMsg(); -} - -void TeamcityMessages::messageError(const std::string& text) -{ - openMsg("message"); - writeProperty("text", text); - writeProperty("status", "ERROR"); - closeMsg(); -} - -void TeamcityMessages::messageWarning(const std::string& text) -{ - openMsg("message"); - writeProperty("text", text); - writeProperty("status", "WARNING"); - closeMsg(); -} - -void TeamcityMessages::messageNormal(const std::string& text) -{ - openMsg("message"); - writeProperty("text", text); - writeProperty("status", "NORMAL"); - closeMsg(); -} - -} diff --git a/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_messages.h b/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_messages.h deleted file mode 100755 index 36ad80797..000000000 --- a/spine-cpp/spine-cpp-unit-tests/teamcity/teamcity_messages.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2011 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * $Revision: 88625 $ -*/ - -#ifndef H_TEAMCITY_MESSAGES -#define H_TEAMCITY_MESSAGES - -#include -#include - -namespace JetBrains { - -std::string getFlowIdFromEnvironment(); -bool underTeamcity(); - -class TeamcityMessages { - std::ostream *m_out; - -protected: - std::string escape(std::string s); - - void openMsg(const std::string &name); - void writeProperty(std::string name, std::string value); - void closeMsg(); - -public: - TeamcityMessages(); - - void setOutput(std::ostream &); - - void suiteStarted(std::string name, std::string flowid = ""); - void suiteFinished(std::string name, std::string flowid = ""); - - void testStarted(std::string name, std::string flowid = ""); - void testFailed(std::string name, std::string message, std::string details, std::string flowid = ""); - void testIgnored(std::string name, std::string message, std::string flowid = ""); - void testFinished(std::string name, int durationMs = -1, std::string flowid = ""); - - void messageError(const std::string& text); - void messageWarning(const std::string& text); - void messageNormal(const std::string& text); -}; - -} - -#endif /* H_TEAMCITY_MESSAGES */ diff --git a/spine-cpp/spine-cpp-unit-tests/tests/CPP_InterfaceTestFixture.cpp b/spine-cpp/spine-cpp-unit-tests/tests/CPP_InterfaceTestFixture.cpp deleted file mode 100755 index dde75c363..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/CPP_InterfaceTestFixture.cpp +++ /dev/null @@ -1,48 +0,0 @@ -////////////////////////////////////////////////////////////////////// -// filename: C_InterfaceTestFixture.cpp -// -// notes: There is no C++ interface! -// -///////////////////////////////////////////////////////////////////// - -#include "CPP_InterfaceTestFixture.h" - -CPP_InterfaceTestFixture::~CPP_InterfaceTestFixture() -{ - finalize(); -} - -void CPP_InterfaceTestFixture::initialize() -{ - // on a Per- Fixture Basis, before Test execution -} - -void CPP_InterfaceTestFixture::finalize() -{ - // on a Per- Fixture Basis, after all tests pass/fail -} - -void CPP_InterfaceTestFixture::setUp() -{ - // Setup on Per-Test Basis -} - -void CPP_InterfaceTestFixture::tearDown() -{ - // Tear Down on Per-Test Basis -} - -void CPP_InterfaceTestFixture::spineboyTestCase() -{ - // There is no C++ interface. -} - -void CPP_InterfaceTestFixture::raptorTestCase() -{ - // There is no C++ interface. -} - -void CPP_InterfaceTestFixture::goblinsTestCase() -{ - // No c++ interface -} diff --git a/spine-cpp/spine-cpp-unit-tests/tests/CPP_InterfaceTestFixture.h b/spine-cpp/spine-cpp-unit-tests/tests/CPP_InterfaceTestFixture.h deleted file mode 100755 index 8dc5fed36..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/CPP_InterfaceTestFixture.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -////////////////////////////////////////////////////////////////////// -// filename: C_InterfaceTestFixture.h -// -// purpose: Run example animations for regression testing -// on "C++" interface to make sure modifications to "C" -// interface doesn't cause memory leaks or regression -// errors. -///////////////////////////////////////////////////////////////////// - -#include "MiniCppUnit.hxx" -#include "TestOptions.h" - -class CPP_InterfaceTestFixture : public TestFixture < CPP_InterfaceTestFixture > -{ -public: - TEST_FIXTURE(CPP_InterfaceTestFixture){ - TEST_CASE(spineboyTestCase); - TEST_CASE(raptorTestCase); - TEST_CASE(goblinsTestCase); - - initialize(); - } - - virtual ~CPP_InterfaceTestFixture(); - - ////////////////////////////////////////////////////////////////////////// - // Test Cases - ////////////////////////////////////////////////////////////////////////// -public: - void spineboyTestCase(); - void raptorTestCase(); - void goblinsTestCase(); - - ////////////////////////////////////////////////////////////////////////// - // test fixture setup - ////////////////////////////////////////////////////////////////////////// - void initialize(); - void finalize(); -public: - virtual void setUp(); - virtual void tearDown(); - -}; -#if defined(gForceAllTests) || defined(gCPPInterfaceTestFixture) -REGISTER_FIXTURE(CPP_InterfaceTestFixture); -#endif diff --git a/spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.cpp b/spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.cpp deleted file mode 100755 index b6576bb7f..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "C_InterfaceTestFixture.h" -#include "SpineEventMonitor.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include "KMemory.h" // last include - -#define SPINEBOY_JSON "testdata/spineboy/spineboy-ess.json" -#define SPINEBOY_ATLAS "testdata/spineboy/spineboy.atlas" - -#define RAPTOR_JSON "testdata/raptor/raptor-pro.json" -#define RAPTOR_ATLAS "testdata/raptor/raptor.atlas" - -#define GOBLINS_JSON "testdata/goblins/goblins-pro.json" -#define GOBLINS_ATLAS "testdata/goblins/goblins.atlas" - -#define MAX_RUN_TIME 6000 // equal to about 100 seconds of execution - -void C_InterfaceTestFixture::setUp() -{ -} - -void C_InterfaceTestFixture::tearDown() -{ -} - -static Spine::SkeletonData* readSkeletonJsonData(const char* filename, Atlas* atlas) -{ - using namespace Spine; - - Vector atlasArray; - atlasArray.push_back(atlas); - - SkeletonJson* skeletonJson = NEW(SkeletonJson); - new (skeletonJson) SkeletonJson(atlasArray); - ASSERT(skeletonJson != 0); - - SkeletonData* skeletonData = skeletonJson->readSkeletonDataFile(filename); - ASSERT(skeletonData != 0); - - DESTROY(SkeletonJson, skeletonJson); - - return skeletonData; -} - -typedef std::vector AnimList; - -static size_t enumerateAnimations(AnimList& outList, SkeletonData* skeletonData) -{ - if (skeletonData) - { - for (int n = 0; n < skeletonData->getAnimations().size(); n++) - { - outList.push_back(skeletonData->getAnimations()[n]->getName()); - } - } - - return outList.size(); -} - -class MyTextureLoader : public TextureLoader -{ - virtual void load(AtlasPage& page, std::string path) - { - page.rendererObject = NULL; - page.width = 2048; - page.height = 2048; - } - - virtual void unload(void* texture) - { - // TODO - } -}; - -static void testRunner(const char* jsonName, const char* atlasName) -{ - /////////////////////////////////////////////////////////////////////////// - // Global Animation Information - MyTextureLoader myTextureLoader; - Atlas* atlas = NEW(Atlas); - new (atlas) Atlas(atlasName, myTextureLoader); - ASSERT(atlas != 0); - - SkeletonData* skeletonData = readSkeletonJsonData(jsonName, atlas); - ASSERT(skeletonData != 0); - - AnimationStateData* stateData = NEW(AnimationStateData); - new (stateData) AnimationStateData(skeletonData); - ASSERT(stateData != 0); - stateData->setDefaultMix(0.2f); // force mixing - - /////////////////////////////////////////////////////////////////////////// - // Animation Instance - Skeleton* skeleton = NEW(Skeleton); - new (skeleton) Skeleton(skeletonData); - ASSERT(skeleton != 0); - - AnimationState* state = NEW(AnimationState); - new (state) AnimationState(stateData); - ASSERT(state != 0); - - /////////////////////////////////////////////////////////////////////////// - // Run animation - skeleton->setToSetupPose(); - SpineEventMonitor eventMonitor(state); - - AnimList anims; // Let's chain all the animations together as a test - size_t count = enumerateAnimations(anims, skeletonData); - if (count > 0) - { - state->setAnimation(0, anims[0].c_str(), false); - } - - for (size_t i = 1; i < count; ++i) - { - state->addAnimation(0, anims[i].c_str(), false, 0.0f); - } - - // Run Loop - for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) - { - const float timeSlice = 1.0f / 60.0f; - skeleton->update(timeSlice); - state->update(timeSlice); - state->apply(*skeleton); - } - - /////////////////////////////////////////////////////////////////////////// - // Dispose Instance - DESTROY(Skeleton, skeleton); - DESTROY(AnimationState, state); - - /////////////////////////////////////////////////////////////////////////// - // Dispose Global - DESTROY(AnimationStateData, stateData); - DESTROY(SkeletonData, skeletonData); - DESTROY(Atlas, atlas); -} - -void C_InterfaceTestFixture::spineboyTestCase() -{ - testRunner(SPINEBOY_JSON, SPINEBOY_ATLAS); -} - -void C_InterfaceTestFixture::raptorTestCase() -{ - testRunner(RAPTOR_JSON, RAPTOR_ATLAS); -} - -void C_InterfaceTestFixture::goblinsTestCase() -{ - testRunner(GOBLINS_JSON, GOBLINS_ATLAS); -} diff --git a/spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.h b/spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.h deleted file mode 100755 index 2f30d2bea..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -////////////////////////////////////////////////////////////////////// -// filename: C_InterfaceTestFixture.h -// -// purpose: Run example animations for regression testing -// on "C" interface -///////////////////////////////////////////////////////////////////// - -#include "TestOptions.h" -#include "MiniCppUnit.hxx" - -class C_InterfaceTestFixture : public TestFixture -{ -public: - TEST_FIXTURE(C_InterfaceTestFixture) - { - // enable/disable individual tests here - TEST_CASE(spineboyTestCase); - TEST_CASE(raptorTestCase); - TEST_CASE(goblinsTestCase); - } - -public: - virtual void setUp(); - virtual void tearDown(); - - void spineboyTestCase(); - void raptorTestCase(); - void goblinsTestCase(); -}; -#if defined(gForceAllTests) || defined(gCInterfaceTestFixture) -REGISTER_FIXTURE(C_InterfaceTestFixture); -#endif \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/tests/EmptyTestFixture.cpp b/spine-cpp/spine-cpp-unit-tests/tests/EmptyTestFixture.cpp deleted file mode 100755 index d2260b7d5..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/EmptyTestFixture.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "EmptyTestFixture.h" - -#include "KMemory.h" // Last include - - -void EmptyTestFixture::setUp() -{ -} - -void EmptyTestFixture::tearDown() -{ -} - -void EmptyTestFixture::emptyTestCase_1() -{ - // char* pLeak = new char[256]; // test leak detector -} - -void EmptyTestFixture::emptyTestCase_2() -{ -} - -void EmptyTestFixture::emptyTestCase_3() -{ -} diff --git a/spine-cpp/spine-cpp-unit-tests/tests/EmptyTestFixture.h b/spine-cpp/spine-cpp-unit-tests/tests/EmptyTestFixture.h deleted file mode 100755 index c11cfd5f2..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/EmptyTestFixture.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#include "TestOptions.h" -#include "MiniCppUnit.hxx" - -class EmptyTestFixture : public TestFixture -{ -public: - TEST_FIXTURE(EmptyTestFixture) - { - // enable/disable individual tests here - TEST_CASE(emptyTestCase_1); - TEST_CASE(emptyTestCase_2); - TEST_CASE(emptyTestCase_3); - } - -public: - virtual void setUp(); - virtual void tearDown(); - - void emptyTestCase_1(); - void emptyTestCase_2(); - void emptyTestCase_3(); -}; -#if defined(gForceAllTests) || defined(gEmptyTestFixture) -REGISTER_FIXTURE(EmptyTestFixture); -#endif \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/tests/MemoryTest.h b/spine-cpp/spine-cpp-unit-tests/tests/MemoryTest.h deleted file mode 100644 index ed8705012..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/MemoryTest.h +++ /dev/null @@ -1,444 +0,0 @@ -// -// MemoryTest.h -// spine_unit_test -// -// Created by Stephen Gowen on 12/8/17. -// Copyright © 2017 Noctis Games. All rights reserved. -// - -#ifndef MemoryTest_h -#define MemoryTest_h - -#include "SpineEventMonitor.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "KMemory.h" // last include - -#define SPINEBOY_JSON "testdata/spineboy/spineboy-ess.json" -#define SPINEBOY_ATLAS "testdata/spineboy/spineboy.atlas" - -#define MAX_RUN_TIME 6000 // equal to about 100 seconds of execution - -namespace Spine -{ - class MemoryTest - { - public: - class MyTextureLoader : public TextureLoader - { - virtual void load(AtlasPage& page, std::string path) - { - page.rendererObject = NULL; - page.width = 2048; - page.height = 2048; - } - - virtual void unload(void* texture) - { - // TODO - } - }; - - ////////////////////////////////////////////////////////////////////////// - // Helper methods - static SkeletonData* readSkeletonJsonData(const char* filename, Atlas* atlas) - { - Vector atlasArray; - atlasArray.push_back(atlas); - - SkeletonJson* skeletonJson = NEW(SkeletonJson); - new (skeletonJson) SkeletonJson(atlasArray); - assert(skeletonJson != 0); - - SkeletonData* skeletonData = skeletonJson->readSkeletonDataFile(filename); - assert(skeletonData != 0); - - DESTROY(SkeletonJson, skeletonJson); - - return skeletonData; - } - - static void loadSpineboyExample(Atlas* &atlas, SkeletonData* &skeletonData, AnimationStateData* &stateData, Skeleton* &skeleton, AnimationState* &state) - { - /////////////////////////////////////////////////////////////////////////// - // Global Animation Information - static MyTextureLoader myTextureLoader; - atlas = NEW(Atlas); - new (atlas) Atlas(SPINEBOY_ATLAS, myTextureLoader); - assert(atlas != 0); - - skeletonData = readSkeletonJsonData(SPINEBOY_JSON, atlas); - assert(skeletonData != 0); - - stateData = NEW(AnimationStateData); - new (stateData) AnimationStateData(*skeletonData); - assert(stateData != 0); - stateData->setDefaultMix(0.2f); // force mixing - - /////////////////////////////////////////////////////////////////////////// - // Animation Instance - skeleton = NEW(Skeleton); - new (skeleton) Skeleton(*skeletonData); - assert(skeleton != 0); - - state = NEW(AnimationState); - new (state) AnimationState(*stateData); - assert(state != 0); - } - - static void disposeAll(Skeleton* skeleton, AnimationState* state, AnimationStateData* stateData, SkeletonData* skeletonData, Atlas* atlas) - { - /////////////////////////////////////////////////////////////////////////// - // Dispose Instance - DESTROY(Skeleton, skeleton); - DESTROY(AnimationState, state); - - /////////////////////////////////////////////////////////////////////////// - // Dispose Global - DESTROY(AnimationStateData, stateData); - DESTROY(SkeletonData, skeletonData); - DESTROY(Atlas, atlas); - } - - ////////////////////////////////////////////////////////////////////////// - // Reproduce Memory leak as described in Issue #776 - // https://github.com/EsotericSoftware/spine-runtimes/issues/776 - static void reproduceIssue_776() - { - Atlas* atlas = NULL; - SkeletonData* skeletonData = NULL; - AnimationStateData* stateData = NULL; - Skeleton* skeleton = NULL; - AnimationState* state = NULL; - - ////////////////////////////////////////////////////////////////////////// - // Initialize Animations - loadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); - - /////////////////////////////////////////////////////////////////////////// - // Run animation - skeleton->setToSetupPose(); - InterruptMonitor eventMonitor(state); - - // Interrupt the animation on this specific sequence of spEventType(s) - eventMonitor - .AddInterruptEvent(EventType_Interrupt, "jump") - .AddInterruptEvent(EventType_Start); - - state->setAnimation(0, "walk", true); - state->addAnimation(0, "jump", false, 0.0f); - state->addAnimation(0, "run", true, 0.0f); - state->addAnimation(0, "jump", false, 3.0f); - state->addAnimation(0, "walk", true, 0.0f); - state->addAnimation(0, "idle", false, 1.0f); - - for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) - { - const float timeSlice = 1.0f / 60.0f; - skeleton->update(timeSlice); - state->update(timeSlice); - state->apply(*skeleton); - } - - ////////////////////////////////////////////////////////////////////////// - // Cleanup Animations - disposeAll(skeleton, state, stateData, skeletonData, atlas); - } - - static void reproduceIssue_777() - { - Atlas* atlas = NULL; - SkeletonData* skeletonData = NULL; - AnimationStateData* stateData = NULL; - Skeleton* skeleton = NULL; - AnimationState* state = NULL; - - ////////////////////////////////////////////////////////////////////////// - // Initialize Animations - loadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); - - /////////////////////////////////////////////////////////////////////////// - // Run animation - skeleton->setToSetupPose(); - SpineEventMonitor eventMonitor(state); - - // Set Animation and Play for 5 frames - state->setAnimation(0, "walk", true); - for (int i = 0; i < 5; ++i) - { - const float timeSlice = 1.0f / 60.0f; - skeleton->update(timeSlice); - state->update(timeSlice); - state->apply(*skeleton); - } - - // Change animation twice in a row - state->setAnimation(0, "walk", false); - state->setAnimation(0, "run", false); - - // run normal update - for (int i = 0; i < 5; ++i) - { - const float timeSlice = 1.0f / 60.0f; - skeleton->update(timeSlice); - state->update(timeSlice); - state->apply(*skeleton); - } - - // Now we'd lose mixingFrom (the first "walk" entry we set above) and should leak - state->setAnimation(0, "run", false); - - ////////////////////////////////////////////////////////////////////////// - // Cleanup Animations - disposeAll(skeleton, state, stateData, skeletonData, atlas); - } - - static void spineAnimStateHandler(AnimationState* state, EventType type, TrackEntry* entry, Event* event) - { - if (type == EventType_Complete) - { - state->setAnimation(0, "walk", false); - state->update(0); - state->apply(*skeleton); - } - } - - static void reproduceIssue_Loop() - { - Atlas* atlas = NULL; - SkeletonData* skeletonData = NULL; - AnimationStateData* stateData = NULL; - AnimationState* state = NULL; - - ////////////////////////////////////////////////////////////////////////// - // Initialize Animations - loadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); - - /////////////////////////////////////////////////////////////////////////// - - if (state) - { - state->setOnAnimationEventFunc(spineAnimStateHandler); - } - - state->setAnimation(0, "walk", false); - - // run normal update - for (int i = 0; i < 50; ++i) - { - const float timeSlice = 1.0f / 60.0f; - skeleton->update(timeSlice); - state->update(timeSlice); - state->apply(*skeleton); - } - - disposeAll(skeleton, state, stateData, skeletonData, atlas); - } - - static void triangulator() - { - Triangulator* triangulator = NEW(Triangulator); - new (triangulator) Triangulator(); - - Vector polygon; - polygon.reserve(16); - polygon.push_back(0); - polygon.push_back(0); - polygon.push_back(100); - polygon.push_back(0); - polygon.push_back(100); - polygon.push_back(100); - polygon.push_back(0); - polygon.push_back(100); - - Vector triangles = triangulator->triangulate(polygon); - assert(triangles.size() == 6); - assert(triangles[0] == 3); - assert(triangles[1] == 0); - assert(triangles[2] == 1); - assert(triangles[3] == 3); - assert(triangles[4] == 1); - assert(triangles[5] == 2); - - Vector< Vector *> polys = triangulator->decompose(polygon, triangles); - assert(polys.size() == 1); - assert(polys[0]->size() == 8); - - assert(polys[0]->operator[](0) == 0); - assert(polys[0]->operator[](1) == 100); - assert(polys[0]->operator[](2) == 0); - assert(polys[0]->operator[](3) == 0); - assert(polys[0]->operator[](4) == 100); - assert(polys[0]->operator[](5) == 0); - assert(polys[0]->operator[](6) == 100); - assert(polys[0]->operator[](7) == 100); - - DESTROY(Triangulator, triangulator); - } - - static void skeletonClipper() - { - Atlas* atlas = NULL; - SkeletonData* skeletonData = NULL; - AnimationStateData* stateData = NULL; - Skeleton* skeleton = NULL; - AnimationState* state = NULL; - - ////////////////////////////////////////////////////////////////////////// - // Initialize Animations - loadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); - - SkeletonClipping* clipping = NEW(SkeletonClipping); - new (clipping) SkeletonClipping(); - - BoneData* boneData = NEW(BoneData); - new (boneData) BoneData(0, "bone", 0); - - Bone* bone = NEW(Bone); - new(bone) Bone(*boneData, *skeleton, NULL); - - bone->setA(1); - bone->setB(0); - bone->setC(0); - bone->setD(1); - bone->setWorldX(0); - bone->setWorldY(0); - - SlotData* slotData = NEW(SlotData); - new (slotData) SlotData(0, "slot", *boneData); - - Slot* slot = NEW(Slot); - new(slot) Slot(*slotData, *bone); - - ClippingAttachment* clip = NEW(ClippingAttachment); - new(clip) ClippingAttachment("clipping"); - - clip->setEndSlot(slotData); - clip->setWorldVerticesLength(4 * 2); - - Vector clipVertices; - clipVertices.reserve(8); - clipVertices.setSize(8); - - clip->setVertices(clipVertices); - clip->getVertices()[0] = 0; - clip->getVertices()[1] = 50; - clip->getVertices()[2] = 100; - clip->getVertices()[3] = 50; - clip->getVertices()[4] = 100; - clip->getVertices()[5] = 70; - clip->getVertices()[6] = 0; - clip->getVertices()[7] = 70; - - clipping->clipStart(*slot, clip); - - Vector vertices; - vertices.reserve(16); - vertices.push_back(0); - vertices.push_back(0); - vertices.push_back(100); - vertices.push_back(0); - vertices.push_back(50); - vertices.push_back(150); - - Vector uvs; - uvs.reserve(16); - uvs.push_back(0); - uvs.push_back(0); - uvs.push_back(1); - uvs.push_back(0); - uvs.push_back(0.5f); - uvs.push_back(1); - - Vector indices; - indices.reserve(16); - indices.push_back(0); - indices.push_back(1); - indices.push_back(2); - - clipping->clipTriangles(vertices, static_cast(vertices.size()), indices, static_cast(indices.size()), uvs); - - float expectedVertices[8] = { 83.333328, 50.000000, 76.666664, 70.000000, 23.333334, 70.000000, 16.666672, 50.000000 }; - assert(clipping->getClippedVertices().size() == 8); - for (int i = 0; i < clipping->getClippedVertices().size(); i++) - { - assert(abs(clipping->getClippedVertices()[i] - expectedVertices[i]) < 0.001); - } - - float expectedUVs[8] = { 0.833333f, 0.333333, 0.766667, 0.466667, 0.233333, 0.466667, 0.166667, 0.333333 }; - assert(clipping->getClippedUVs().size() == 8); - for (int i = 0; i < clipping->getClippedUVs().size(); i++) - { - assert(abs(clipping->getClippedUVs()[i] - expectedUVs[i]) < 0.001); - } - - short expectedIndices[6] = { 0, 1, 2, 0, 2, 3 }; - assert(clipping->getClippedTriangles().size() == 6); - for (int i = 0; i < clipping->getClippedTriangles().size(); i++) - { - assert(clipping->getClippedTriangles()[i] == expectedIndices[i]); - } - - DESTROY(SlotData, slotData); - DESTROY(Slot, slot); - DESTROY(BoneData, boneData); - DESTROY(Bone, bone); - DESTROY(ClippingAttachment, clip); - DESTROY(SkeletonClipping, clipping); - - ////////////////////////////////////////////////////////////////////////// - // Cleanup Animations - disposeAll(skeleton, state, stateData, skeletonData, atlas); - } - - static void test() - { - reproduceIssue_776(); - reproduceIssue_777(); - reproduceIssue_Loop(); - triangulator(); - skeletonClipper(); - } - - private: - static Skeleton* skeleton; - - // ctor, copy ctor, and assignment should be private in a Singleton - MemoryTest(); - MemoryTest(const MemoryTest&); - MemoryTest& operator=(const MemoryTest&); - }; -} - -Skeleton* MemoryTest::skeleton = NULL; - -#endif /* MemoryTest_h */ diff --git a/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.cpp b/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.cpp deleted file mode 100755 index e69de29bb..000000000 diff --git a/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.h b/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.h deleted file mode 100755 index e69de29bb..000000000 diff --git a/spine-cpp/spine-cpp-unit-tests/tests/SimpleTest.h b/spine-cpp/spine-cpp-unit-tests/tests/SimpleTest.h deleted file mode 100644 index 5f09bba0d..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/SimpleTest.h +++ /dev/null @@ -1,197 +0,0 @@ -// -// SimpleTest.h -// spine_unit_test -// -// Created by Stephen Gowen on 11/9/17. -// Copyright © 2017 Noctis Games. All rights reserved. -// - -#ifndef SimpleTest_h -#define SimpleTest_h - -#include "SpineEventMonitor.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include "KMemory.h" // last include - -#define SPINEBOY_JSON "testdata/spineboy/spineboy-ess.json" -#define SPINEBOY_ATLAS "testdata/spineboy/spineboy.atlas" - -#define RAPTOR_JSON "testdata/raptor/raptor-pro.json" -#define RAPTOR_ATLAS "testdata/raptor/raptor.atlas" - -#define GOBLINS_JSON "testdata/goblins/goblins-pro.json" -#define GOBLINS_ATLAS "testdata/goblins/goblins.atlas" - -#define MAX_RUN_TIME 6000 // equal to about 100 seconds of execution - -namespace Spine -{ - class SimpleTest - { - public: - static SkeletonData* readSkeletonJsonData(const char* filename, Atlas* atlas) - { - Vector atlasArray; - atlasArray.push_back(atlas); - - SkeletonJson* skeletonJson = NEW(SkeletonJson); - new (skeletonJson) SkeletonJson(atlasArray); - assert(skeletonJson != 0); - - SkeletonData* skeletonData = skeletonJson->readSkeletonDataFile(filename); - assert(skeletonData != 0); - - DESTROY(SkeletonJson, skeletonJson); - - return skeletonData; - } - - typedef std::vector AnimList; - - static size_t enumerateAnimations(AnimList& outList, SkeletonData* skeletonData) - { - if (skeletonData) - { - for (int n = 0; n < skeletonData->getAnimations().size(); n++) - { - outList.push_back(skeletonData->getAnimations()[n]->getName()); - } - } - - return outList.size(); - } - - class MyTextureLoader : public TextureLoader - { - virtual void load(AtlasPage& page, std::string path) - { - page.rendererObject = NULL; - page.width = 2048; - page.height = 2048; - } - - virtual void unload(void* texture) - { - // TODO - } - }; - - static void testRunner(const char* jsonName, const char* atlasName) - { - /////////////////////////////////////////////////////////////////////////// - // Global Animation Information - MyTextureLoader myTextureLoader; - Atlas* atlas = NEW(Atlas); - new (atlas) Atlas(atlasName, myTextureLoader); - assert(atlas != 0); - - SkeletonData* skeletonData = readSkeletonJsonData(jsonName, atlas); - assert(skeletonData != 0); - - AnimationStateData* stateData = NEW(AnimationStateData); - new (stateData) AnimationStateData(*skeletonData); - assert(stateData != 0); - stateData->setDefaultMix(0.2f); // force mixing - - /////////////////////////////////////////////////////////////////////////// - // Animation Instance - Skeleton* skeleton = NEW(Skeleton); - new (skeleton) Skeleton(*skeletonData); - assert(skeleton != 0); - - AnimationState* state = NEW(AnimationState); - new (state) AnimationState(*stateData); - assert(state != 0); - - /////////////////////////////////////////////////////////////////////////// - // Run animation - skeleton->setToSetupPose(); - SpineEventMonitor eventMonitor(state); - - AnimList anims; // Let's chain all the animations together as a test - size_t count = enumerateAnimations(anims, skeletonData); - if (count > 0) - { - state->setAnimation(0, anims[0].c_str(), false); - } - - for (size_t i = 1; i < count; ++i) - { - state->addAnimation(0, anims[i].c_str(), false, 0.0f); - } - - // Run Loop - for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) - { - const float timeSlice = 1.0f / 60.0f; - skeleton->update(timeSlice); - state->update(timeSlice); - state->apply(*skeleton); - } - - /////////////////////////////////////////////////////////////////////////// - // Dispose Instance - DESTROY(Skeleton, skeleton); - DESTROY(AnimationState, state); - - /////////////////////////////////////////////////////////////////////////// - // Dispose Global - DESTROY(AnimationStateData, stateData); - DESTROY(SkeletonData, skeletonData); - DESTROY(Atlas, atlas); - } - - static void spineboyTestCase() - { - testRunner(SPINEBOY_JSON, SPINEBOY_ATLAS); - } - - static void raptorTestCase() - { - testRunner(RAPTOR_JSON, RAPTOR_ATLAS); - } - - static void goblinsTestCase() - { - testRunner(GOBLINS_JSON, GOBLINS_ATLAS); - } - - static void test() - { - spineboyTestCase(); - raptorTestCase(); - goblinsTestCase(); - } - - private: - // ctor, copy ctor, and assignment should be private in a Singleton - SimpleTest(); - SimpleTest(const SimpleTest&); - SimpleTest& operator=(const SimpleTest&); - }; -} - -#endif /* SimpleTest_h */ diff --git a/spine-cpp/spine-cpp-unit-tests/tests/SpineEventMonitor.cpp b/spine-cpp/spine-cpp-unit-tests/tests/SpineEventMonitor.cpp deleted file mode 100755 index 9506e354c..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/SpineEventMonitor.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "SpineEventMonitor.h" - -#include "KString.h" - -#include -#include - -#include "KMemory.h" // Last include - -using namespace Spine; - -SpineEventMonitor::SpineEventMonitor(AnimationState* _pAnimationState /*= nullptr*/) -{ - bLogging = false; - RegisterListener(_pAnimationState); -} - -SpineEventMonitor::~SpineEventMonitor() -{ - pAnimState = 0; -} - -void SpineEventMonitor::RegisterListener(AnimationState * _pAnimationState) -{ - if (_pAnimationState) - { - _pAnimationState->setRendererObject(this); - _pAnimationState->setOnAnimationEventFunc(&SpineEventMonitor::spineAnimStateHandler); - } - pAnimState = _pAnimationState; -} - -bool SpineEventMonitor::isAnimationPlaying() -{ - if (pAnimState) - { - return pAnimState->getCurrent(0) != NULL; - } - return false; -} - -void SpineEventMonitor::spineAnimStateHandler(AnimationState* state, EventType type, TrackEntry* entry, Event* event) -{ - if (state && state->getRendererObject()) - { - SpineEventMonitor* pEventMonitor = (SpineEventMonitor*)state->getRendererObject(); - pEventMonitor->OnSpineAnimationStateEvent(state, type, entry, event); - } -} - -void SpineEventMonitor::OnSpineAnimationStateEvent(AnimationState* state, EventType type, TrackEntry* entry, Event* event) -{ - const char* eventName = 0; - if (state == pAnimState) - { - // only monitor ours - switch(type) - { - case EventType_Start: eventName = "EventType_Start"; break; - case EventType_Interrupt: eventName = "EventType_Interrupt"; break; - case EventType_End: eventName = "EventType_End"; break; - case EventType_Complete: eventName = "EventType_Complete"; break; - case EventType_Dispose: eventName = "EventType_Dispose"; break; - case EventType_Event: eventName = "EventType_Event"; break; - default: - break; - } - - if (bLogging && eventName && entry && entry->getAnimation()) - KOutputDebug(DEBUGLVL, "[%s : '%s']\n", eventName, entry->getAnimation()->getName().c_str());//*/ - } -} - -InterruptMonitor::InterruptMonitor(AnimationState * _pAnimationState): - SpineEventMonitor(_pAnimationState) -{ - bForceInterrupt = false; - mEventStackCursor = 0; // cursor used to track events -} - -bool InterruptMonitor::isAnimationPlaying() -{ - return !bForceInterrupt && SpineEventMonitor::isAnimationPlaying(); -} - -// Stops the animation on any occurance of the spEventType -InterruptMonitor& InterruptMonitor::AddInterruptEvent(int theEventType) -{ - InterruptEvent ev; - ev.mEventType = theEventType; - mEventStack.push_back(ev); - return *this; -} - -// Stops the animation when the [spEventType : 'animationName'] occurs -InterruptMonitor& InterruptMonitor::AddInterruptEvent(int theEventType, const std::string & theAnimationName) -{ - InterruptEvent ev; - ev.mEventType = theEventType; - ev.mAnimName = theAnimationName; - mEventStack.push_back(ev); - return *this; -} - -// stops the first encounter of spEventType on the specified TrackEntry -InterruptMonitor& InterruptMonitor::AddInterruptEvent(int theEventType, TrackEntry * theTrackEntry) -{ - InterruptEvent ev; - ev.mEventType = theEventType; - ev.mTrackEntry = theTrackEntry; - mEventStack.push_back(ev); - return *this; -} - -// Stops on the first SP_ANIMATION_EVENT with the string payload of 'theEventTriggerName' -InterruptMonitor& InterruptMonitor::AddInterruptEventTrigger(const std::string & theEventTriggerName) -{ - InterruptEvent ev; - ev.mEventType = EventType_Event; - ev.mEventName = theEventTriggerName; - mEventStack.push_back(ev); - return *this; -} - -void InterruptMonitor::OnSpineAnimationStateEvent(AnimationState * state, EventType type, TrackEntry * trackEntry, Event * event) -{ - SpineEventMonitor::OnSpineAnimationStateEvent(state, type, trackEntry, event); - - if (mEventStackCursor < mEventStack.size()) - { - if (mEventStack[mEventStackCursor].matches(state, type, trackEntry, event)) - { - ++mEventStackCursor; - } - - if (mEventStackCursor >= mEventStack.size()) - { - bForceInterrupt = true; - OnMatchingComplete(); - } - } -} - -inline bool InterruptMonitor::InterruptEvent::matches(AnimationState * state, EventType type, TrackEntry * trackEntry, Event * event) -{ - // Must match EventType {EventType_Start, EventType_Interrupt, EventType_End, EventType_Complete, EventType_Dispose, EventType_Event } - if (mEventType == type) - { - // Looking for specific TrackEntry by pointer - if (mTrackEntry != 0) - { - return mTrackEntry == trackEntry; - } - - // looking for Animation Track by name - if (!mAnimName.empty()) - { - if (trackEntry && trackEntry->getAnimation()) - { - if (CompareNoCase(trackEntry->getAnimation()->getName(), mAnimName) == 0) - { - return true; - } - } - return false; - } - - // looking for Event String Text - if (!mEventName.empty()) - { - if (event) - { - return (CompareNoCase(event->getStringValue(), mEventName) == 0); - } - return false; - } - - return true; // waiting for ANY spEventType that matches - } - return false; -} diff --git a/spine-cpp/spine-cpp-unit-tests/tests/SpineEventMonitor.h b/spine-cpp/spine-cpp-unit-tests/tests/SpineEventMonitor.h deleted file mode 100755 index 4590a1e6e..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/SpineEventMonitor.h +++ /dev/null @@ -1,121 +0,0 @@ -////////////////////////////////////////////////////////////////////// -// filename: SpineEventMonitor.h -// -// purpose: Monitor spAnimationState Events -///////////////////////////////////////////////////////////////////// - -#pragma once - -#include -#include - -#include - -using namespace Spine; - -////////////////////////////////////////////////////////////////////// -// class: SpineEventMonitor -// -// purpose: Monitor spAnimationState Events and report when there -// are no more TrackEntry(s) waiting to play on track 0; -// -// Also allows for debug printing of Events to console. -///////////////////////////////////////////////////////////////////// -class SpineEventMonitor -{ -public: - SpineEventMonitor(AnimationState* _pAnimationState = 0); - virtual ~SpineEventMonitor(); - - void RegisterListener(AnimationState* _pAnimationState); - - void SetDebugLogging(bool val) { bLogging = val; } - bool GetDebugLogging() { return bLogging; } - - virtual bool isAnimationPlaying(); - -protected: - static void spineAnimStateHandler(AnimationState* state, EventType type, TrackEntry* entry, Event* event); - virtual void OnSpineAnimationStateEvent(AnimationState* state, EventType type, TrackEntry* entry, Event* event); - -protected: - AnimationState *pAnimState; - bool bLogging; -}; - -////////////////////////////////////////////////////////////////////// -// class: InterruptMonitor -// -// purpose: Allows a programmer to interrupt/stop the updating -// of an animation based on a specific sequence of -// events generated by the animation. -///////////////////////////////////////////////////////////////////// -class InterruptMonitor : public SpineEventMonitor -{ -private: - struct InterruptEvent - { - InterruptEvent() { - mEventType = -1; // invalid - mTrackEntry = 0; - } - - bool matches(AnimationState* state, EventType type, TrackEntry* trackEntry, Event* event); - - std::string mAnimName; - int mEventType; - TrackEntry* mTrackEntry; - std::string mEventName; - }; - typedef std::vector InterruptEventStack; - - -public: - InterruptMonitor(AnimationState* _pAnimationState = 0); - ~InterruptMonitor() {} - - virtual bool isAnimationPlaying() override; - -public: - InterruptMonitor& AddInterruptEvent(int theEventType); - InterruptMonitor& AddInterruptEvent(int theEventType, const std::string& theAnimationName); - InterruptMonitor& AddInterruptEvent(int theEventType, TrackEntry* theTrackEntry); - InterruptMonitor& AddInterruptEventTrigger(const std::string& theEventTriggerName); - -protected: - virtual void OnSpineAnimationStateEvent(AnimationState* state, EventType type, TrackEntry* trackEntry, Event* event) override; - virtual void OnMatchingComplete() {} - -protected: - bool bForceInterrupt; - InterruptEventStack mEventStack; // must match these events in this order - size_t mEventStackCursor; -}; - -/* - -EXAMPLE -======= - -SpineEventMonitor eventMonitor(state); -eventMonitor.SetDebugLogging(true); - -while(eventMonitor.isAnimationPlaying()){ - // update... -} - - - -EXAMPLE -======= - -InterruptMonitor eventMonitor(state); -eventMonitor.SetDebugLogging(true); - -// Interrupt the animation on this specific sequence of spEventType(s) -eventMonitor - .AddInterruptEvent(SP_ANIMATION_INTERRUPT, "jump") // First, wait for INTERRUPT signal on the 'jump' animation TrackEntry - .AddInterruptEvent(SP_ANIMATION_START); // Then, stop on any following START signal - - -*/ diff --git a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.cpp b/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.cpp deleted file mode 100755 index 9c2a964a9..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "CPP_InterfaceTestFixture.h" - -CPP_InterfaceTestFixture::~CPP_InterfaceTestFixture() -{ - finalize(); -} - -void CPP_InterfaceTestFixture::initialize() -{ - // on a Per- Fixture Basis, before Test execution -} - -void CPP_InterfaceTestFixture::finalize() -{ - // on a Per- Fixture Basis, after all tests pass/fail -} - -void CPP_InterfaceTestFixture::setUp() -{ - // Setup on Per-Test Basis -} - -void CPP_InterfaceTestFixture::tearDown() -{ - // Tear Down on Per-Test Basis -} diff --git a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.h b/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.h deleted file mode 100755 index 5fcb99c79..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/CPP_InterfaceTestFixture.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "MiniCppUnit.hxx" - -class CPP_InterfaceTestFixture : public TestFixture < CPP_InterfaceTestFixture > -{ -public: - TEST_FIXTURE(CPP_InterfaceTestFixture){ - //TEST_CASE(parseJSON); - - initialize(); - } - - virtual ~CPP_InterfaceTestFixture(); - - ////////////////////////////////////////////////////////////////////////// - // Test Cases - ////////////////////////////////////////////////////////////////////////// -public: - // void parseJSON(); - - ////////////////////////////////////////////////////////////////////////// - // test fixture setup - ////////////////////////////////////////////////////////////////////////// - void initialize(); - void finalize(); -public: - virtual void setUp(); - virtual void tearDown(); -}; -REGISTER_FIXTURE(CPP_InterfaceTestFixture); \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/_TestFixture.cpp b/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/_TestFixture.cpp deleted file mode 100755 index 67780f31a..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/_TestFixture.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "[[FIXTURE_TYPE]].h" - -[[FIXTURE_TYPE]]::~[[FIXTURE_TYPE]]() -{ - finalize(); -} - -void [[FIXTURE_TYPE]]::initialize() -{ - // on a Per- Fixture Basis, before Test execution -} - -void [[FIXTURE_TYPE]]::finalize() -{ - // on a Per- Fixture Basis, after all tests pass/fail -} - -void [[FIXTURE_TYPE]]::setUp() -{ - // Setup on Per-Test Basis -} - -void [[FIXTURE_TYPE]]::tearDown() -{ - // Tear Down on Per-Test Basis -} diff --git a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/_TestFixture.h b/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/_TestFixture.h deleted file mode 100755 index 3103cda85..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/_TestFixture.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "MiniCppUnit.hxx" - -class [[FIXTURE_TYPE]] : public TestFixture < [[FIXTURE_TYPE]] > -{ -public: - TEST_FIXTURE([[FIXTURE_TYPE]]){ - //TEST_CASE(parseJSON); - - initialize(); - } - - virtual ~[[FIXTURE_TYPE]](); - - ////////////////////////////////////////////////////////////////////////// - // Test Cases - ////////////////////////////////////////////////////////////////////////// -public: - // void parseJSON(); - - ////////////////////////////////////////////////////////////////////////// - // test fixture setup - ////////////////////////////////////////////////////////////////////////// - void initialize(); - void finalize(); -public: - virtual void setUp(); - virtual void tearDown(); -}; -REGISTER_FIXTURE([[FIXTURE_TYPE]]); \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/fnr.exe b/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/fnr.exe deleted file mode 100755 index 548fc5d91fbc747827dbcc53514793a052e1099f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 185200 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[>4`JN{}c&;FiV|m>|slNX# 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 diff --git a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/makeFixture.bat b/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/makeFixture.bat deleted file mode 100755 index 634154a29..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/TestFixtureGenerator/makeFixture.bat +++ /dev/null @@ -1,17 +0,0 @@ -@echo off -if "%1"=="" goto blank - -copy "_TestFixture.cpp" "%1TestFixture.cpp" -copy "_TestFixture.h" "%1TestFixture.h" - - -fnr --cl --find "[[FIXTURE_TYPE]]" --replace "%1TestFixture" --fileMask "%1TestFixture.cpp" --dir %cd% -fnr --cl --find "[[FIXTURE_TYPE]]" --replace "%1TestFixture" --fileMask "%1TestFixture.h" --dir %cd% - -goto done - -:blank -echo Usage: -echo %~n0 FixtureTypeName - -:done \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/tests/TestOptions.h b/spine-cpp/spine-cpp-unit-tests/tests/TestOptions.h deleted file mode 100755 index 7f00ffbb7..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/TestOptions.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -////////////////////////////////////////////////////////////////////////// -// Force all Tests to 'ON.' Use this for final 'Regression' Testing. - -//#define gForceAllTests - -//#define TURN_ON_ALL_TESTS // Comment this line out to switch to fast testing only - -#ifdef TURN_ON_ALL_TESTS -////////////////////////////////////////////////////////////////////////// -// All tests are ON by default, but you can turn off individual tests. - -#define gEmptyTestFixture -#define gCInterfaceTestFixture -#define gCPPInterfaceTestFixture -#define gMemoryTestFixture - - -#else - -////////////////////////////////////////////////////////////////////////// -// Slow Tests are disabled by default. Use this section to turn on -// Individual tests. -#define gEmptyTestFixture // Fast - -#define gCInterfaceTestFixture // slow -#define gCPPInterfaceTestFixture // fast - -#define gMemoryTestFixture // medium - -#endif \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/tests/main.cpp b/spine-cpp/spine-cpp-unit-tests/tests/main.cpp deleted file mode 100644 index 5ed9971da..000000000 --- a/spine-cpp/spine-cpp-unit-tests/tests/main.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// -// main.cpp -// spine_unit_test -// -// Created by Stephen Gowen on 12/7/17. -// Copyright © 2017 Noctis Games. All rights reserved. -// - -#ifdef WIN32 -#include -#else -#include -#endif // WIN32 - -#include -#include "KString.h" -#include - -#include "spine/Extension.h" - -#include "SimpleTest.h" -#include "MemoryTest.h" - -#include "KMemory.h" // last include - -using namespace Spine; - -class KanjiSpineExtension : public DefaultSpineExtension -{ -public: - static KanjiSpineExtension* getInstance(); - - virtual ~KanjiSpineExtension(); - - virtual void* spineAlloc(size_t size, const char* file, int line); - - virtual void* spineCalloc(size_t num, size_t size, const char* file, int line); - - virtual void* spineRealloc(void* ptr, size_t size, const char* file, int line); - - virtual void spineFree(void* mem); - -protected: - KanjiSpineExtension(); -}; - -KanjiSpineExtension* KanjiSpineExtension::getInstance() -{ - static KanjiSpineExtension ret; - return &ret; -} - -KanjiSpineExtension::~KanjiSpineExtension() -{ - // Empty -} - -void* KanjiSpineExtension::spineAlloc(size_t size, const char* file, int line) -{ - return _kanjimalloc(size); -} - -void* KanjiSpineExtension::spineCalloc(size_t num, size_t size, const char* file, int line) -{ - void* ptr = spineAlloc(num * size, file, line); - if (ptr) - { - memset(ptr, 0, num * size); - } - - return ptr; -} - -void* KanjiSpineExtension::spineRealloc(void* ptr, size_t size, const char* file, int line) -{ - return _kanjirealloc(ptr, size); -} - -void KanjiSpineExtension::spineFree(void* mem) -{ - _kanjifree(mem); -} - -KanjiSpineExtension::KanjiSpineExtension() : DefaultSpineExtension() -{ - // Empty -} - -double timeNow() -{ - timespec lTimeVal; - clock_gettime(CLOCK_MONOTONIC, &lTimeVal); - return lTimeVal.tv_sec + (lTimeVal.tv_nsec * 1.0e-9); -} - -int main(int argc, char* argv[]) -{ - SpineExtension::setInstance(KanjiSpineExtension::getInstance()); - - double startTime = timeNow(); - - /* Set working directory to current location for opening test data */ -#ifdef WIN32 - _chdir( GetFileDir(argv[0], false).c_str() ); -#else - chdir(GetFileDir(argv[0], false).c_str()); -#endif - - SimpleTest::test(); - MemoryTest::test(); - - // End Timing - double endTime = timeNow(); - double timeElapsed = (endTime - startTime); - printf("\n\n%i minutes and %i seconds of your life taken from you by these tests.\n", ((int)timeElapsed) / 60, ((int)timeElapsed) % 60); - printf("timeElapsed: %f \n", timeElapsed); - - return 0; -} diff --git a/spine-cpp/spine-cpp/include/spine/Atlas.h b/spine-cpp/spine-cpp/include/spine/Atlas.h index d6d5dfad9..3a425df9c 100644 --- a/spine-cpp/spine-cpp/include/spine/Atlas.h +++ b/spine-cpp/spine-cpp/include/spine/Atlas.h @@ -94,11 +94,11 @@ namespace Spine { class TextureLoader; - class Atlas : SpineObject { + class Atlas : public SpineObject { public: - Atlas(const char* path, TextureLoader& textureLoader); + Atlas(const char* path, TextureLoader* textureLoader); - Atlas(const char* data, int length, const char* dir, TextureLoader& textureLoader); + Atlas(const char* data, int length, const char* dir, TextureLoader* textureLoader); ~Atlas(); @@ -114,7 +114,7 @@ namespace Spine { private: Vector _pages; Vector _regions; - TextureLoader& _textureLoader; + TextureLoader* _textureLoader; void load(const char* begin, int length, const char* dir); diff --git a/spine-cpp/spine-cpp/include/spine/Extension.h b/spine-cpp/spine-cpp/include/spine/Extension.h index bf38862d4..556e83794 100644 --- a/spine-cpp/spine-cpp/include/spine/Extension.h +++ b/spine-cpp/spine-cpp/include/spine/Extension.h @@ -33,22 +33,6 @@ #include -// #define SPINE_EXTENSION (SpineExtension::getInstance()) - -/* All allocation uses these. */ -/* -#define MALLOC(TYPE,COUNT) ((TYPE*)SPINE_EXTENSION->spineAlloc(sizeof(TYPE) * (COUNT), __FILE__, __LINE__)) -#define CALLOC(TYPE,COUNT) ((TYPE*)SPINE_EXTENSION->spineCalloc(COUNT, sizeof(TYPE), __FILE__, __LINE__)) -#define NEW(TYPE) CALLOC(TYPE,1) -#define REALLOC(PTR,TYPE,COUNT) ((TYPE*)SPINE_EXTENSION->spineRealloc(PTR, sizeof(TYPE) * (COUNT), __FILE__, __LINE__)) -*/ - -/* Frees memory. Can be used on const types. */ -// #define FREE(VALUE) SPINE_EXTENSION->spinefree(VALUE) - -/* Call destructor and then frees memory. Can be used on const types. */ -// #define DESTROY(TYPE,VALUE) VALUE->~TYPE(); SPINE_EXTENSION->spinefree(VALUE) - namespace Spine { class SpineExtension { public: @@ -64,8 +48,8 @@ namespace Spine { return (T*)getInstance()->_realloc(ptr, sizeof(T) * num, file, line); } - template static void free(T* ptr) { - getInstance()->_free((void*)ptr); + template static void free(T* ptr, const char* file, int line) { + getInstance()->_free((void*)ptr, file, line); } static char* readFile(const char* path, int* length) { @@ -87,18 +71,19 @@ namespace Spine { virtual void* _realloc(void* ptr, size_t size, const char* file, int line) = 0; /// If you provide a spineAllocFunc, you should also provide a spineFreeFunc - virtual void _free(void* mem) = 0; + virtual void _free(void* mem, const char* file, int line) = 0; virtual char* _readFile(const char* path, int* length); SpineExtension(); - + private: static SpineExtension* _instance; }; class DefaultSpineExtension : public SpineExtension { public: + DefaultSpineExtension(); virtual ~DefaultSpineExtension(); protected: @@ -108,9 +93,7 @@ namespace Spine { virtual void* _realloc(void* ptr, size_t size, const char* file, int line); - virtual void _free(void* mem); - - DefaultSpineExtension(); + virtual void _free(void* mem, const char* file, int line); }; } diff --git a/spine-cpp/spine-cpp/include/spine/HashMap.h b/spine-cpp/spine-cpp/include/spine/HashMap.h index 1beb41c62..428fec23c 100755 --- a/spine-cpp/spine-cpp/include/spine/HashMap.h +++ b/spine-cpp/spine-cpp/include/spine/HashMap.h @@ -130,7 +130,7 @@ namespace Spine { size_t index = hash(key); - Entry* entry = new Entry(); + Entry* entry = new (__FILE__, __LINE__) Entry(); entry->_key = key; entry->_value = value; diff --git a/spine-cpp/spine-cpp/include/spine/Pool.h b/spine-cpp/spine-cpp/include/spine/Pool.h index 43aa0651e..7f4df82de 100644 --- a/spine-cpp/spine-cpp/include/spine/Pool.h +++ b/spine-cpp/spine-cpp/include/spine/Pool.h @@ -57,7 +57,7 @@ namespace Spine { return ret; } else { - T* ret = new T(); + T* ret = new (__FILE__, __LINE__) T(); return ret; } diff --git a/spine-cpp/spine-cpp/include/spine/SpineObject.h b/spine-cpp/spine-cpp/include/spine/SpineObject.h index 45d987770..a79e0d049 100644 --- a/spine-cpp/spine-cpp/include/spine/SpineObject.h +++ b/spine-cpp/spine-cpp/include/spine/SpineObject.h @@ -36,8 +36,7 @@ namespace Spine { class SpineObject { public: - void* operator new(size_t sz); - void* operator new(size_t sz, void* p); + void* operator new(size_t sz, const char* file, int line); void operator delete(void* p); }; } diff --git a/spine-cpp/spine-cpp/include/spine/Vector.h b/spine-cpp/spine-cpp/include/spine/Vector.h index 17fb7bc13..48ff57d2a 100644 --- a/spine-cpp/spine-cpp/include/spine/Vector.h +++ b/spine-cpp/spine-cpp/include/spine/Vector.h @@ -50,31 +50,11 @@ namespace Spine { if (_capacity > 0) { _buffer = allocate(_capacity); for (size_t i = 0; i < _size; ++i) { - construct(_buffer + i, inVector._buffer[i]); + _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); @@ -105,7 +85,7 @@ namespace Spine { reserve(); } - construct(_buffer + _size++, inValue); + _buffer[_size++] = inValue; } void insert(size_t inIndex, const T& inValue) { @@ -116,11 +96,10 @@ namespace Spine { } for (size_t i = ++_size - 1; i > inIndex; --i) { - construct(_buffer + i, _buffer[i - 1]); - destroy(_buffer + (i - 1)); + _buffer[i] = _buffer[i - 1]; } - construct(_buffer + inIndex, inValue); + _buffer[inIndex] = inValue; } void erase(size_t inIndex) { @@ -133,15 +112,9 @@ namespace Spine { 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; } @@ -212,20 +185,9 @@ namespace Spine { void deallocate(T* buffer) { if (_buffer) { - SpineExtension::free(buffer); + 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(); - } }; } diff --git a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp index 7bace3609..0c286bc98 100644 --- a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp +++ b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp @@ -216,11 +216,11 @@ namespace Spine { } EventQueue* EventQueue::newEventQueue(AnimationState& state, Pool& trackEntryPool) { - return new EventQueue(state, trackEntryPool); + return new (__FILE__, __LINE__) EventQueue(state, trackEntryPool); } EventQueueEntry* EventQueue::newEventQueueEntry(EventType eventType, TrackEntry* entry, Event* event) { - return new EventQueueEntry(eventType, entry, event); + return new (__FILE__, __LINE__) EventQueueEntry(eventType, entry, event); } EventQueue::EventQueue(AnimationState& state, Pool& trackEntryPool) : _state(state), _trackEntryPool(trackEntryPool), _drainDisabled(false) { diff --git a/spine-cpp/spine-cpp/src/spine/Atlas.cpp b/spine-cpp/spine-cpp/src/spine/Atlas.cpp index 8fdab3fe3..8a8ca5006 100644 --- a/spine-cpp/spine-cpp/src/spine/Atlas.cpp +++ b/spine-cpp/spine-cpp/src/spine/Atlas.cpp @@ -37,7 +37,7 @@ #include namespace Spine { - Atlas::Atlas(const char* path, TextureLoader& textureLoader) : _textureLoader(textureLoader) { + Atlas::Atlas(const char* path, TextureLoader* textureLoader) : _textureLoader(textureLoader) { int dirLength; char *dir; int length; @@ -58,11 +58,11 @@ namespace Spine { load(data, length, dir); } - SpineExtension::free(data); - SpineExtension::free(dir); + SpineExtension::free(data, __FILE__, __LINE__); + SpineExtension::free(dir, __FILE__, __LINE__); } - Atlas::Atlas(const char* data, int length, const char* dir, TextureLoader& textureLoader) : _textureLoader(textureLoader) { + Atlas::Atlas(const char* data, int length, const char* dir, TextureLoader* textureLoader) : _textureLoader(textureLoader) { load(data, length, dir); } @@ -91,8 +91,9 @@ namespace Spine { } void Atlas::dispose() { + if (!_textureLoader) return; for (size_t i = 0, n = _pages.size(); i < n; ++i) { - _textureLoader.unload(_pages[i]->rendererObject); + _textureLoader->unload(_pages[i]->rendererObject); } } @@ -123,9 +124,9 @@ namespace Spine { } strcpy(path + dirLength + needsSlash, name); - page = new AtlasPage(std::string(name)); + page = new (__FILE__, __LINE__) AtlasPage(std::string(name)); - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); int tupleVal = readTuple(&begin, end, tuple); assert(tupleVal == 2); @@ -160,17 +161,20 @@ namespace Spine { } } - _textureLoader.load(*page, std::string(path)); + if (_textureLoader) _textureLoader->load(*page, std::string(path)); - SpineExtension::free(path); + SpineExtension::free(path, __FILE__, __LINE__); _pages.push_back(page); } else { - AtlasRegion* region = new AtlasRegion(); + AtlasRegion* region = new (__FILE__, __LINE__) AtlasRegion(); region->page = page; - region->name = mallocString(&str); + + char* name = mallocString(&str); + region->name = std::string(name); + SpineExtension::free(name, __FILE__, __LINE__); assert(readValue(&begin, end, &str)); region->rotate = equals(&str, "true"); diff --git a/spine-cpp/spine-cpp/src/spine/AtlasAttachmentLoader.cpp b/spine-cpp/spine-cpp/src/spine/AtlasAttachmentLoader.cpp index fbc0ab18e..d7c2e0550 100644 --- a/spine-cpp/spine-cpp/src/spine/AtlasAttachmentLoader.cpp +++ b/spine-cpp/spine-cpp/src/spine/AtlasAttachmentLoader.cpp @@ -53,7 +53,7 @@ namespace Spine { AtlasRegion& region = *regionP; - RegionAttachment* attachmentP = new RegionAttachment(name); + RegionAttachment* attachmentP = new (__FILE__, __LINE__) RegionAttachment(name); RegionAttachment& attachment = *attachmentP; attachment._rendererObject = regionP; @@ -74,7 +74,7 @@ namespace Spine { AtlasRegion& region = *regionP; - MeshAttachment* attachmentP = new MeshAttachment(name); + MeshAttachment* attachmentP = new (__FILE__, __LINE__) MeshAttachment(name); MeshAttachment& attachment = *attachmentP; attachment._rendererObject = regionP; @@ -94,19 +94,19 @@ namespace Spine { } BoundingBoxAttachment* AtlasAttachmentLoader::newBoundingBoxAttachment(Skin& skin, std::string name) { - return new BoundingBoxAttachment(name); + return new (__FILE__, __LINE__) BoundingBoxAttachment(name); } PathAttachment* AtlasAttachmentLoader::newPathAttachment(Skin& skin, std::string name) { - return new PathAttachment(name); + return new (__FILE__, __LINE__) PathAttachment(name); } PointAttachment* AtlasAttachmentLoader::newPointAttachment(Skin& skin, std::string name) { - return new PointAttachment(name); + return new (__FILE__, __LINE__) PointAttachment(name); } ClippingAttachment* AtlasAttachmentLoader::newClippingAttachment(Skin& skin, std::string name) { - return new ClippingAttachment(name); + return new (__FILE__, __LINE__) ClippingAttachment(name); } AtlasRegion* AtlasAttachmentLoader::findRegion(std::string name) { diff --git a/spine-cpp/spine-cpp/src/spine/Extension.cpp b/spine-cpp/spine-cpp/src/spine/Extension.cpp index 9a0bfd7b3..27aa764b2 100644 --- a/spine-cpp/spine-cpp/src/spine/Extension.cpp +++ b/spine-cpp/spine-cpp/src/spine/Extension.cpp @@ -94,8 +94,8 @@ namespace Spine { return ::realloc(ptr, size); } - void DefaultSpineExtension::_free(void* mem) { - free(mem); + void DefaultSpineExtension::_free(void* mem, const char* file, int line) { + ::free(mem); } DefaultSpineExtension::DefaultSpineExtension() : SpineExtension() { diff --git a/spine-cpp/spine-cpp/src/spine/Json.cpp b/spine-cpp/spine-cpp/src/spine/Json.cpp index bcc82f9a1..c3732d804 100644 --- a/spine-cpp/spine-cpp/src/spine/Json.cpp +++ b/spine-cpp/spine-cpp/src/spine/Json.cpp @@ -119,11 +119,11 @@ namespace Spine { } if (_valueString) { - SpineExtension::free(_valueString); + SpineExtension::free(_valueString, __FILE__, __LINE__); } if (_name) { - SpineExtension::free(_name); + SpineExtension::free(_name, __FILE__, __LINE__); } if (_next) { @@ -415,7 +415,7 @@ namespace Spine { return value + 1; /* empty array. */ } - item->_child = child = new Json(NULL); + item->_child = child = new (__FILE__, __LINE__) Json(NULL); if (!item->_child) { return NULL; /* memory fail */ } @@ -429,7 +429,7 @@ namespace Spine { item->_size = 1; while (*value == ',') { - Json *new_item = new Json(NULL); + Json *new_item = new (__FILE__, __LINE__) Json(NULL); if (!new_item) { return NULL; /* memory fail */ } @@ -471,7 +471,7 @@ namespace Spine { return value + 1; /* empty array. */ } - item->_child = child = new Json(NULL); + item->_child = child = new (__FILE__, __LINE__) Json(NULL); if (!item->_child) { return NULL; } @@ -494,7 +494,7 @@ namespace Spine { item->_size = 1; while (*value == ',') { - Json *new_item = new Json(NULL); + Json *new_item = new (__FILE__, __LINE__) Json(NULL); if (!new_item) { return NULL; /* memory fail */ } diff --git a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp index a59be5599..23f4255f4 100644 --- a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp @@ -71,11 +71,11 @@ namespace Spine { Bone* bone; if (data->getParent() == NULL) { - bone = new Bone(*data, *this, NULL); + bone = new (__FILE__, __LINE__) Bone(*data, *this, NULL); } else { Bone* parent = _bones[data->getParent()->getIndex()]; - bone = new Bone(*data, *this, parent); + bone = new (__FILE__, __LINE__) Bone(*data, *this, parent); parent->getChildren().push_back(bone); } @@ -88,7 +88,7 @@ namespace Spine { SlotData* data = (*i); Bone* bone = _bones[data->getBoneData().getIndex()]; - Slot* slot = new Slot(*data, *bone); + Slot* slot = new (__FILE__, __LINE__) Slot(*data, *bone); _slots.push_back(slot); _drawOrder.push_back(slot); @@ -98,7 +98,7 @@ namespace Spine { for (IkConstraintData** i = _data.getIkConstraints().begin(); i != _data.getIkConstraints().end(); ++i) { IkConstraintData* data = (*i); - IkConstraint* constraint = new IkConstraint(*data, *this); + IkConstraint* constraint = new (__FILE__, __LINE__) IkConstraint(*data, *this); _ikConstraints.push_back(constraint); } @@ -107,7 +107,7 @@ namespace Spine { for (TransformConstraintData** i = _data.getTransformConstraints().begin(); i != _data.getTransformConstraints().end(); ++i) { TransformConstraintData* data = (*i); - TransformConstraint* constraint = new TransformConstraint(*data, *this); + TransformConstraint* constraint = new (__FILE__, __LINE__) TransformConstraint(*data, *this); _transformConstraints.push_back(constraint); } @@ -116,7 +116,7 @@ namespace Spine { for (PathConstraintData** i = _data.getPathConstraints().begin(); i != _data.getPathConstraints().end(); ++i) { PathConstraintData* data = (*i); - PathConstraint* constraint = new PathConstraint(*data, *this); + PathConstraint* constraint = new (__FILE__, __LINE__) PathConstraint(*data, *this); _pathConstraints.push_back(constraint); } diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp index ba9b25fff..2ab05b83c 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp @@ -106,7 +106,7 @@ namespace Spine { TransformMode_NoScaleOrReflection }; - SkeletonBinary::SkeletonBinary(Atlas& atlasArray) : _attachmentLoader(new AtlasAttachmentLoader(atlasArray)), _error(), _scale(1), _ownsLoader(true) { + SkeletonBinary::SkeletonBinary(Atlas& atlasArray) : _attachmentLoader(new (__FILE__, __LINE__) AtlasAttachmentLoader(atlasArray)), _error(), _scale(1), _ownsLoader(true) { } @@ -126,21 +126,21 @@ namespace Spine { int i, ii, nonessential; SkeletonData* skeletonData; - DataInput* input = new DataInput(); + DataInput* input = new (__FILE__, __LINE__) DataInput(); input->cursor = binary; input->end = binary + length; _linkedMeshes.clear(); - skeletonData = new SkeletonData(); + skeletonData = new (__FILE__, __LINE__) SkeletonData(); char* skeletonData_hash = readString(input); skeletonData->_hash = std::string(skeletonData_hash); - SpineExtension::free(skeletonData_hash); + SpineExtension::free(skeletonData_hash, __FILE__, __LINE__); char* skeletonData_version = readString(input); skeletonData->_version = std::string(skeletonData_version); - SpineExtension::free(skeletonData_version); + SpineExtension::free(skeletonData_version, __FILE__, __LINE__); skeletonData->_width = readFloat(input); skeletonData->_height = readFloat(input); @@ -150,7 +150,7 @@ namespace Spine { if (nonessential) { /* Skip images path & fps */ readFloat(input); - SpineExtension::free(readString(input)); + SpineExtension::free(readString(input), __FILE__, __LINE__); } /* Bones. */ @@ -163,9 +163,9 @@ namespace Spine { const char* name = readString(input); BoneData* parent = i == 0 ? 0 : skeletonData->_bones[readVarint(input, 1)]; - data = new BoneData(i, std::string(name), parent); + data = new (__FILE__, __LINE__) BoneData(i, std::string(name), parent); - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); data->_rotation = readFloat(input); data->_x = readFloat(input) * _scale; @@ -212,9 +212,9 @@ namespace Spine { const char* slotName = readString(input); BoneData* boneData = skeletonData->_bones[readVarint(input, 1)]; - SlotData* slotData = new SlotData(i, std::string(slotName), *boneData); + SlotData* slotData = new (__FILE__, __LINE__) SlotData(i, std::string(slotName), *boneData); - SpineExtension::free(slotName); + SpineExtension::free(slotName, __FILE__, __LINE__); readColor(input, &slotData->_r, &slotData->_g, &slotData->_b, &slotData->_a); r = readByte(input); g = readByte(input); @@ -227,7 +227,7 @@ namespace Spine { } char* slotData_attachmentName = readString(input); slotData->_attachmentName = std::string(slotData_attachmentName); - SpineExtension::free(slotData_attachmentName); + SpineExtension::free(slotData_attachmentName, __FILE__, __LINE__); slotData->_blendMode = static_cast(readVarint(input, 1)); skeletonData->_slots[i] = slotData; @@ -240,11 +240,11 @@ namespace Spine { for (i = 0; i < ikConstraintsCount; ++i) { const char* name = readString(input); - IkConstraintData* data = new IkConstraintData(std::string(name)); + IkConstraintData* data = new (__FILE__, __LINE__) IkConstraintData(std::string(name)); data->_order = readVarint(input, 1); - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); int bonesCount = readVarint(input, 1); data->_bones.reserve(bonesCount); data->_bones.setSize(bonesCount); @@ -265,10 +265,10 @@ namespace Spine { for (i = 0; i < transformConstraintsCount; ++i) { const char* name = readString(input); - TransformConstraintData* data = new TransformConstraintData(std::string(name)); + TransformConstraintData* data = new (__FILE__, __LINE__) TransformConstraintData(std::string(name)); data->_order = readVarint(input, 1); - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); int bonesCount = readVarint(input, 1); data->_bones.reserve(bonesCount); data->_bones.setSize(bonesCount); @@ -299,10 +299,10 @@ namespace Spine { for (i = 0; i < pathConstraintsCount; ++i) { const char* name = readString(input); - PathConstraintData* data = new PathConstraintData(std::string(name)); + PathConstraintData* data = new (__FILE__, __LINE__) PathConstraintData(std::string(name)); data->_order = readVarint(input, 1); - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); int bonesCount = readVarint(input, 1); data->_bones.reserve(bonesCount); @@ -349,7 +349,7 @@ namespace Spine { for (i = skeletonData->_defaultSkin ? 1 : 0; i < skeletonData->_skins.size(); ++i) { const char* skinName = readString(input); skeletonData->_skins[i] = readSkin(input, skinName, skeletonData, nonessential); - SpineExtension::free(skinName); + SpineExtension::free(skinName, __FILE__, __LINE__); } /* Linked meshes. */ @@ -380,13 +380,13 @@ namespace Spine { skeletonData->_events.setSize(eventsCount); for (i = 0; i < eventsCount; ++i) { const char* name = readString(input); - EventData* eventData = new EventData(std::string(name)); - SpineExtension::free(name); + EventData* eventData = new (__FILE__, __LINE__) EventData(std::string(name)); + SpineExtension::free(name, __FILE__, __LINE__); eventData->_intValue = readVarint(input, 0); eventData->_floatValue = readFloat(input); const char* eventData_stringValue = readString(input); eventData->_stringValue = std::string(eventData_stringValue); - SpineExtension::free(eventData_stringValue); + SpineExtension::free(eventData_stringValue, __FILE__, __LINE__); skeletonData->_events[i] = eventData; } @@ -397,7 +397,7 @@ namespace Spine { for (i = 0; i < animationsCount; ++i) { const char* name = readString(input); Animation* animation = readAnimation(name, input, skeletonData); - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); if (!animation) { delete input; delete skeletonData; @@ -420,7 +420,7 @@ namespace Spine { return NULL; } skeletonData = readSkeletonData((unsigned char*)binary, length); - SpineExtension::free(binary); + SpineExtension::free(binary, __FILE__, __LINE__); return skeletonData; } @@ -522,7 +522,7 @@ namespace Spine { return NULL; } - skin = new Skin(std::string(skinName)); + skin = new (__FILE__, __LINE__) Skin(std::string(skinName)); for (i = 0; i < slotCount; ++i) { int slotIndex = readVarint(input, 1); @@ -532,7 +532,7 @@ namespace Spine { if (attachment) { skin->addAttachment(slotIndex, std::string(name), attachment); } - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); } } @@ -571,7 +571,7 @@ namespace Spine { region->updateOffset(); if (freeName) { - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); } return region; @@ -585,7 +585,7 @@ namespace Spine { readInt(input); } if (freeName) { - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); } return box; @@ -620,7 +620,7 @@ namespace Spine { } if (freeName) { - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); } return mesh; @@ -645,15 +645,15 @@ namespace Spine { mesh->_height = readFloat(input) * _scale; } - LinkedMesh* linkedMesh = new LinkedMesh(mesh, std::string(skinName), slotIndex, std::string(parent)); + LinkedMesh* linkedMesh = new (__FILE__, __LINE__) LinkedMesh(mesh, std::string(skinName), slotIndex, std::string(parent)); _linkedMeshes.push_back(linkedMesh); if (freeName) { - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); } - SpineExtension::free(skinName); - SpineExtension::free(parent); + SpineExtension::free(skinName, __FILE__, __LINE__); + SpineExtension::free(parent, __FILE__, __LINE__); return mesh; } @@ -677,7 +677,7 @@ namespace Spine { } if (freeName) { - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); } return path; @@ -709,7 +709,7 @@ namespace Spine { clip->_endSlot = skeletonData->_slots[endSlotIndex]; if (freeName) { - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); } return clip; @@ -717,7 +717,7 @@ namespace Spine { } if (freeName) { - SpineExtension::free(name); + SpineExtension::free(name, __FILE__, __LINE__); } return NULL; @@ -800,19 +800,19 @@ namespace Spine { int frameCount = readVarint(input, true); switch (timelineType) { case SLOT_ATTACHMENT: { - AttachmentTimeline* timeline = new AttachmentTimeline(frameCount); + AttachmentTimeline* timeline = new (__FILE__, __LINE__) AttachmentTimeline(frameCount); timeline->_slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { const char* attachmentName = readString(input); timeline->setFrame(frameIndex, readFloat(input), std::string(attachmentName)); - SpineExtension::free(attachmentName); + SpineExtension::free(attachmentName, __FILE__, __LINE__); } timelines.push_back(timeline); duration = MAX(duration, timeline->_frames[frameCount - 1]); break; } case SLOT_COLOR: { - ColorTimeline* timeline = new ColorTimeline(frameCount); + ColorTimeline* timeline = new (__FILE__, __LINE__) ColorTimeline(frameCount); timeline->_slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { float time = readFloat(input); @@ -831,7 +831,7 @@ namespace Spine { break; } case SLOT_TWO_COLOR: { - TwoColorTimeline* timeline = new TwoColorTimeline(frameCount); + TwoColorTimeline* timeline = new (__FILE__, __LINE__) TwoColorTimeline(frameCount); timeline->_slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { float time = readFloat(input); @@ -871,7 +871,7 @@ namespace Spine { int frameCount = readVarint(input, true); switch (timelineType) { case BONE_ROTATE: { - RotateTimeline* timeline = new RotateTimeline(frameCount); + RotateTimeline* timeline = new (__FILE__, __LINE__) RotateTimeline(frameCount); timeline->_boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { timeline->setFrame(frameIndex, readFloat(input), readFloat(input)); @@ -889,13 +889,13 @@ namespace Spine { TranslateTimeline* timeline; float timelineScale = 1; if (timelineType == BONE_SCALE) { - timeline = new ScaleTimeline(frameCount); + timeline = new (__FILE__, __LINE__) ScaleTimeline(frameCount); } else if (timelineType == BONE_SHEAR) { - timeline = new ShearTimeline(frameCount); + timeline = new (__FILE__, __LINE__) ShearTimeline(frameCount); } else { - timeline = new TranslateTimeline(frameCount); + timeline = new (__FILE__, __LINE__) TranslateTimeline(frameCount); timelineScale = scale; } timeline->_boneIndex = boneIndex; @@ -922,7 +922,7 @@ namespace Spine { for (int i = 0, n = readVarint(input, true); i < n; ++i) { int index = readVarint(input, true); int frameCount = readVarint(input, true); - IkConstraintTimeline* timeline = new IkConstraintTimeline(frameCount); + IkConstraintTimeline* timeline = new (__FILE__, __LINE__) IkConstraintTimeline(frameCount); timeline->_ikConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { timeline->setFrame(frameIndex, readFloat(input), readFloat(input), readSByte(input)); @@ -938,7 +938,7 @@ namespace Spine { for (int i = 0, n = readVarint(input, true); i < n; ++i) { int index = readVarint(input, true); int frameCount = readVarint(input, true); - TransformConstraintTimeline* timeline = new TransformConstraintTimeline(frameCount); + TransformConstraintTimeline* timeline = new (__FILE__, __LINE__) TransformConstraintTimeline(frameCount); timeline->_transformConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { timeline->setFrame(frameIndex, readFloat(input), readFloat(input), readFloat(input), readFloat(input), readFloat(input)); @@ -963,14 +963,14 @@ namespace Spine { PathConstraintPositionTimeline* timeline; float timelineScale = 1; if (timelineType == PATH_SPACING) { - timeline = new PathConstraintSpacingTimeline(frameCount); + timeline = new (__FILE__, __LINE__) PathConstraintSpacingTimeline(frameCount); if (data->_spacingMode == SpacingMode_Length || data->_spacingMode == SpacingMode_Fixed) { timelineScale = scale; } } else { - timeline = new PathConstraintPositionTimeline(frameCount); + timeline = new (__FILE__, __LINE__) PathConstraintPositionTimeline(frameCount); if (data->_positionMode == PositionMode_Fixed) { timelineScale = scale; @@ -988,7 +988,7 @@ namespace Spine { break; } case PATH_MIX: { - PathConstraintMixTimeline* timeline = new PathConstraintMixTimeline(frameCount); + PathConstraintMixTimeline* timeline = new (__FILE__, __LINE__) PathConstraintMixTimeline(frameCount); timeline->_pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { @@ -1017,11 +1017,11 @@ namespace Spine { if (!baseAttachment) { ContainerUtil::cleanUpVectorOfPointers(timelines); setError("Attachment not found: ", attachmentName); - SpineExtension::free(attachmentName); + SpineExtension::free(attachmentName, __FILE__, __LINE__); return NULL; } - SpineExtension::free(attachmentName); + SpineExtension::free(attachmentName, __FILE__, __LINE__); VertexAttachment* attachment = static_cast(baseAttachment); @@ -1031,7 +1031,7 @@ namespace Spine { int frameCount = readVarint(input, true); - DeformTimeline* timeline = new DeformTimeline(frameCount); + DeformTimeline* timeline = new (__FILE__, __LINE__) DeformTimeline(frameCount); timeline->_slotIndex = slotIndex; timeline->_attachment = attachment; @@ -1088,7 +1088,7 @@ namespace Spine { // Draw order timeline. int drawOrderCount = readVarint(input, true); if (drawOrderCount > 0) { - DrawOrderTimeline* timeline = new DrawOrderTimeline(drawOrderCount); + DrawOrderTimeline* timeline = new (__FILE__, __LINE__) DrawOrderTimeline(drawOrderCount); int slotCount = static_cast(skeletonData->_slots.size()); for (int i = 0; i < drawOrderCount; ++i) { @@ -1135,12 +1135,12 @@ namespace Spine { // Event timeline. int eventCount = readVarint(input, true); if (eventCount > 0) { - EventTimeline* timeline =new EventTimeline(eventCount); + EventTimeline* timeline = new (__FILE__, __LINE__) EventTimeline(eventCount); for (int i = 0; i < eventCount; ++i) { float time = readFloat(input); EventData* eventData = skeletonData->_events[readVarint(input, true)]; - Event* event = new Event(time, *eventData); + Event* event = new (__FILE__, __LINE__) Event(time, *eventData); event->_intValue = readVarint(input, false); event->_floatValue = readFloat(input); @@ -1148,7 +1148,7 @@ namespace Spine { const char* event_stringValue = freeString ? readString(input) : eventData->_stringValue.c_str(); event->_stringValue = std::string(event_stringValue); if (freeString) { - SpineExtension::free(event_stringValue); + SpineExtension::free(event_stringValue, __FILE__, __LINE__); } timeline->setFrame(i, event); } @@ -1157,7 +1157,7 @@ namespace Spine { duration = MAX(duration, timeline->_frames[eventCount - 1]); } - return new Animation(std::string(name), timelines, duration); + return new (__FILE__, __LINE__) Animation(std::string(name), timelines, duration); } void SkeletonBinary::readCurve(DataInput* input, int frameIndex, CurveTimeline* timeline) { diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBounds.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBounds.cpp index e4bf6c333..d826b3c2c 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBounds.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBounds.cpp @@ -68,7 +68,7 @@ namespace Spine { _polygonPool.erase(poolCount - 1); } else { - Polygon* polygonP = new Polygon(); + Polygon* polygonP = new (__FILE__, __LINE__) Polygon(); } _polygons.push_back(polygonP); diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp index 09252d237..2718c6fc8 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp @@ -86,7 +86,7 @@ #endif namespace Spine { - SkeletonJson::SkeletonJson(Atlas& atlas) : _attachmentLoader(new AtlasAttachmentLoader(atlas)), _scale(1), _ownsLoader(true) { + SkeletonJson::SkeletonJson(Atlas& atlas) : _attachmentLoader(new (__FILE__, __LINE__) AtlasAttachmentLoader(atlas)), _scale(1), _ownsLoader(true) { } SkeletonJson::SkeletonJson(AttachmentLoader* attachmentLoader) : _attachmentLoader(attachmentLoader), _scale(1), _ownsLoader(false) { @@ -112,7 +112,7 @@ namespace Spine { skeletonData = readSkeletonData(json); - SpineExtension::free(json); + SpineExtension::free(json, __FILE__, __LINE__); return skeletonData; } @@ -125,14 +125,14 @@ namespace Spine { _error.clear(); _linkedMeshes.clear(); - root = new Json(json); + root = new (__FILE__, __LINE__) Json(json); if (!root) { setError(NULL, "Invalid skeleton JSON: ", Json::getError()); return NULL; } - skeletonData = new SkeletonData(); + skeletonData = new (__FILE__, __LINE__) SkeletonData(); skeleton = Json::getItem(root, "skeleton"); if (skeleton) { @@ -162,7 +162,7 @@ namespace Spine { } } - data = new BoneData(bonesCount, Json::getString(boneMap, "name", 0), parent); + data = new (__FILE__, __LINE__) BoneData(bonesCount, Json::getString(boneMap, "name", 0), parent); data->_length = Json::getFloat(boneMap, "length", 0) * _scale; data->_x = Json::getFloat(boneMap, "x", 0) * _scale; @@ -214,7 +214,7 @@ namespace Spine { return NULL; } - data = new SlotData(i, Json::getString(slotMap, "name", 0), *boneData); + data = new (__FILE__, __LINE__) SlotData(i, Json::getString(slotMap, "name", 0), *boneData); color = Json::getString(slotMap, "color", 0); if (color) { @@ -264,7 +264,7 @@ namespace Spine { for (constraintMap = ik->_child, i = 0; constraintMap; constraintMap = constraintMap->_next, ++i) { const char* targetName; - IkConstraintData* data = new IkConstraintData(Json::getString(constraintMap, "name", 0)); + IkConstraintData* data = new (__FILE__, __LINE__) IkConstraintData(Json::getString(constraintMap, "name", 0)); data->_order = Json::getInt(constraintMap, "order", 0); @@ -304,7 +304,7 @@ namespace Spine { for (constraintMap = transform->_child, i = 0; constraintMap; constraintMap = constraintMap->_next, ++i) { const char* name; - TransformConstraintData* data = new TransformConstraintData(Json::getString(constraintMap, "name", 0)); + TransformConstraintData* data = new (__FILE__, __LINE__) TransformConstraintData(Json::getString(constraintMap, "name", 0)); data->_order = Json::getInt(constraintMap, "order", 0); @@ -356,7 +356,7 @@ namespace Spine { const char* name; const char* item; - PathConstraintData* data = new PathConstraintData(Json::getString(constraintMap, "name", 0)); + PathConstraintData* data = new (__FILE__, __LINE__) PathConstraintData(Json::getString(constraintMap, "name", 0)); data->_order = Json::getInt(constraintMap, "order", 0); @@ -437,7 +437,7 @@ namespace Spine { Json *attachmentsMap; Json *curves; - Skin* skin = new Skin(skinMap->_name); + Skin* skin = new (__FILE__, __LINE__) Skin(skinMap->_name); skeletonData->_skins[skinsIndex++] = skin; if (strcmp(skinMap->_name, "default") == 0) { @@ -567,7 +567,7 @@ namespace Spine { } else { mesh->_inheritDeform = Json::getInt(attachmentMap, "deform", 1); - LinkedMesh* linkedMesh = new LinkedMesh(mesh, std::string(Json::getString(attachmentMap, "skin", 0)), slotIndex, std::string(entry->_valueString)); + LinkedMesh* linkedMesh = new (__FILE__, __LINE__) LinkedMesh(mesh, std::string(Json::getString(attachmentMap, "skin", 0)), slotIndex, std::string(entry->_valueString)); _linkedMeshes.push_back(linkedMesh); } break; @@ -661,7 +661,7 @@ namespace Spine { skeletonData->_events.reserve(events->_size); skeletonData->_events.setSize(events->_size); for (eventMap = events->_child, i = 0; eventMap; eventMap = eventMap->_next, ++i) { - EventData* eventData = new EventData(std::string(eventMap->_name)); + EventData* eventData = new (__FILE__, __LINE__) EventData(std::string(eventMap->_name)); eventData->_intValue = Json::getInt(eventMap, "int", 0); eventData->_floatValue = Json::getFloat(eventMap, "float", 0); @@ -796,7 +796,7 @@ namespace Spine { for (timelineMap = slotMap->_child; timelineMap; timelineMap = timelineMap->_next) { if (strcmp(timelineMap->_name, "attachment") == 0) { - AttachmentTimeline *timeline = new AttachmentTimeline(timelineMap->_size); + AttachmentTimeline *timeline = new (__FILE__, __LINE__) AttachmentTimeline(timelineMap->_size); timeline->_slotIndex = slotIndex; @@ -811,7 +811,7 @@ namespace Spine { } else if (strcmp(timelineMap->_name, "color") == 0) { - ColorTimeline *timeline = new ColorTimeline(timelineMap->_size); + ColorTimeline *timeline = new (__FILE__, __LINE__) ColorTimeline(timelineMap->_size); timeline->_slotIndex = slotIndex; @@ -826,7 +826,7 @@ namespace Spine { } else if (strcmp(timelineMap->_name, "twoColor") == 0) { - TwoColorTimeline *timeline = new TwoColorTimeline(timelineMap->_size); + TwoColorTimeline *timeline = new (__FILE__, __LINE__) TwoColorTimeline(timelineMap->_size); timeline->_slotIndex = slotIndex; @@ -862,7 +862,7 @@ namespace Spine { for (timelineMap = boneMap->_child; timelineMap; timelineMap = timelineMap->_next) { if (strcmp(timelineMap->_name, "rotate") == 0) { - RotateTimeline *timeline = new RotateTimeline(timelineMap->_size); + RotateTimeline *timeline = new (__FILE__, __LINE__) RotateTimeline(timelineMap->_size); timeline->_boneIndex = boneIndex; @@ -882,13 +882,13 @@ namespace Spine { float timelineScale = isTranslate ? _scale: 1; TranslateTimeline *timeline = 0; if (isScale) { - timeline = new ScaleTimeline(timelineMap->_size); + timeline = new (__FILE__, __LINE__) ScaleTimeline(timelineMap->_size); } else if (isTranslate) { - timeline = new TranslateTimeline(timelineMap->_size); + timeline = new (__FILE__, __LINE__) TranslateTimeline(timelineMap->_size); } else if (isShear) { - timeline = new ShearTimeline(timelineMap->_size); + timeline = new (__FILE__, __LINE__) ShearTimeline(timelineMap->_size); } timeline->_boneIndex = boneIndex; @@ -913,7 +913,7 @@ namespace Spine { /** IK constraint timelines. */ for (constraintMap = ik ? ik->_child : 0; constraintMap; constraintMap = constraintMap->_next) { IkConstraintData* constraint = skeletonData->findIkConstraint(constraintMap->_name); - IkConstraintTimeline *timeline = new IkConstraintTimeline(constraintMap->_size); + IkConstraintTimeline *timeline = new (__FILE__, __LINE__) IkConstraintTimeline(constraintMap->_size); for (frameIndex = 0; frameIndex < static_cast(skeletonData->_ikConstraints.size()); ++frameIndex) { if (constraint == skeletonData->_ikConstraints[frameIndex]) { @@ -933,7 +933,7 @@ namespace Spine { /** Transform constraint timelines. */ for (constraintMap = transform ? transform->_child : 0; constraintMap; constraintMap = constraintMap->_next) { TransformConstraintData* constraint = skeletonData->findTransformConstraint(constraintMap->_name); - TransformConstraintTimeline *timeline = new TransformConstraintTimeline(constraintMap->_size); + TransformConstraintTimeline *timeline = new (__FILE__, __LINE__) TransformConstraintTimeline(constraintMap->_size); for (frameIndex = 0; frameIndex < skeletonData->_transformConstraints.size(); ++frameIndex) { if (constraint == skeletonData->_transformConstraints[frameIndex]) { @@ -975,14 +975,14 @@ namespace Spine { PathConstraintPositionTimeline* timeline; float timelineScale = 1; if (strcmp(timelineName, "spacing") == 0) { - timeline = new PathConstraintSpacingTimeline(timelineMap->_size); + timeline = new (__FILE__, __LINE__) PathConstraintSpacingTimeline(timelineMap->_size); if (data->_spacingMode == SpacingMode_Length || data->_spacingMode == SpacingMode_Fixed) { timelineScale = _scale; } } else { - timeline = new PathConstraintPositionTimeline(timelineMap->_size); + timeline = new (__FILE__, __LINE__) PathConstraintPositionTimeline(timelineMap->_size); if (data->_positionMode == PositionMode_Fixed) { timelineScale = _scale; @@ -999,7 +999,7 @@ namespace Spine { duration = MAX(duration, timeline->_frames[(timelineMap->_size - 1) * PathConstraintPositionTimeline::ENTRIES]); } else if (strcmp(timelineName, "mix") == 0) { - PathConstraintMixTimeline* timeline = new PathConstraintMixTimeline(timelineMap->_size); + PathConstraintMixTimeline* timeline = new (__FILE__, __LINE__) PathConstraintMixTimeline(timelineMap->_size); timeline->_pathConstraintIndex = constraintIndex; for (valueMap = timelineMap->_child, frameIndex = 0; valueMap; valueMap = valueMap->_next, ++frameIndex) { timeline->setFrame(frameIndex, Json::getFloat(valueMap, "time", 0), Json::getFloat(valueMap, "rotateMix", 1), Json::getFloat(valueMap, "translateMix", 1)); @@ -1041,7 +1041,7 @@ namespace Spine { tempDeform.push_back(0); } - timeline = new DeformTimeline(timelineMap->_size); + timeline = new (__FILE__, __LINE__) DeformTimeline(timelineMap->_size); timeline->_slotIndex = slotIndex; timeline->_attachment = attachment; @@ -1091,7 +1091,7 @@ namespace Spine { /** Draw order timeline. */ if (drawOrder) { - DrawOrderTimeline* timeline = new DrawOrderTimeline(drawOrder->_size); + DrawOrderTimeline* timeline = new (__FILE__, __LINE__) DrawOrderTimeline(drawOrder->_size); for (valueMap = drawOrder->_child, frameIndex = 0; valueMap; valueMap = valueMap->_next, ++frameIndex) { int ii; @@ -1145,7 +1145,7 @@ namespace Spine { /** Event timeline. */ if (events) { - EventTimeline* timeline = new EventTimeline(events->_size); + EventTimeline* timeline = new (__FILE__, __LINE__) EventTimeline(events->_size); for (valueMap = events->_child, frameIndex = 0; valueMap; valueMap = valueMap->_next, ++frameIndex) { Event* event; @@ -1156,7 +1156,7 @@ namespace Spine { return NULL; } - event = new Event(Json::getFloat(valueMap, "time", 0), *eventData); + event = new (__FILE__, __LINE__) Event(Json::getFloat(valueMap, "time", 0), *eventData); event->_intValue = Json::getInt(valueMap, "int", eventData->_intValue); event->_floatValue = Json::getFloat(valueMap, "float", eventData->_floatValue); event->_stringValue = Json::getString(valueMap, "string", eventData->_stringValue.c_str()); @@ -1167,7 +1167,7 @@ namespace Spine { duration = MAX(duration, timeline->_frames[events->_size - 1]); } - return new Animation(std::string(root->_name), timelines, duration); + return new (__FILE__, __LINE__) Animation(std::string(root->_name), timelines, duration); } void SkeletonJson::readVertices(Json* attachmentMap, VertexAttachment* attachment, int verticesLength) { diff --git a/spine-cpp/spine-cpp/src/spine/SpineObject.cpp b/spine-cpp/spine-cpp/src/spine/SpineObject.cpp index dff95a888..cab14625f 100644 --- a/spine-cpp/spine-cpp/src/spine/SpineObject.cpp +++ b/spine-cpp/spine-cpp/src/spine/SpineObject.cpp @@ -29,7 +29,16 @@ *****************************************************************************/ #include +#include namespace Spine { + void *SpineObject::operator new(size_t sz, const char* file, int line) { + return SpineExtension::alloc(sz, file, line); + } + + void SpineObject::operator delete(void *p) { + ((SpineObject*)p)->~SpineObject(); + SpineExtension::free(p, __FILE__, __LINE__); + } } \ No newline at end of file diff --git a/spine-sfml/c/CMakeLists.txt b/spine-sfml/c/CMakeLists.txt index 40e2f36c4..2d5bdcd93 100644 --- a/spine-sfml/c/CMakeLists.txt +++ b/spine-sfml/c/CMakeLists.txt @@ -1,48 +1,4 @@ cmake_minimum_required(VERSION 2.8.9) -# -# First download and extract SFML 2.3.2 for the respective OS we are on -# -set(DEPS_DIR "${CMAKE_CURRENT_LIST_DIR}/dependencies/") -message(${DEPS_DIR}) -if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(SFML_URL "http://www.sfml-dev.org/files/SFML-2.4.1-osx-clang.tar.gz") - set(SFML_DIR ${DEPS_DIR}/SFML-2.4.1-osx-clang) - if (NOT EXISTS "${SFML_DIR}") - message("Downloading SFML for Mac OS X") - file(DOWNLOAD "${SFML_URL}" "${DEPS_DIR}/sfml.tar.gz") - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xzf ${DEPS_DIR}/sfml.tar.gz - WORKING_DIRECTORY ${DEPS_DIR} - ) - # copy freetype over to Frameworks/ so rpath resoultion works - execute_process( - COMMAND ${CMAKE_COMMAND} -E copy_directory ${SFML_DIR}/extlibs/freetype.framework ${SFML_DIR}/Frameworks/freetype.framework - WORKING_DIRECTORY ${SFML_DIR} - ) - endif() -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set(SFML_URL "http://www.sfml-dev.org/files/SFML-2.4.1-linux-gcc-64-bit.tar.gz") - set(SFML_DIR ${DEPS_DIR}/SFML-2.4.1) - if (NOT EXISTS ${SFML_DIR}) - message("Downloading SFML for Linux 64-bit") - file(DOWNLOAD "${SFML_URL}" "${DEPS_DIR}/sfml.tar.gz") - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar xzf ${DEPS_DIR}/sfml.tar.gz - WORKING_DIRECTORY ${DEPS_DIR} - ) - endif() -else() - set(SFML_URL "http://www.sfml-dev.org/files/SFML-2.4.1-windows-vc14-32-bit.zip") - set(SFML_DIR ${DEPS_DIR}/SFML-2.4.1) - if (NOT EXISTS ${SFML_DIR}) - message("Downloading SFML for Windows 32-bit") - file(DOWNLOAD "${SFML_URL}" "${DEPS_DIR}/sfml.zip") - execute_process( - COMMAND ${CMAKE_COMMAND} -E tar x ${DEPS_DIR}/sfml.zip - WORKING_DIRECTORY ${DEPS_DIR} - ) - endif() -endif() # Define spine-sfml library include_directories(src ${SFML_DIR}/include)