[c++] Removed old test harness, added new one, added leak detector, fixed new operator overloads, Vector doesn't copy on insert etc. See #1073

This commit is contained in:
badlogic 2018-02-13 17:31:29 +01:00
parent 3f32e071a1
commit 3254747e94
55 changed files with 362 additions and 4700 deletions

View File

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

View File

@ -1,110 +0,0 @@
// SexyKanjiTestSuite.cpp : Defines the entry point for the console application.
//
#include "MiniCppUnit.hxx"
#ifdef WIN32
#include <direct.h>
#else
#include <unistd.h>
#endif // WIN32
#include <ctime>
#include "KString.h"
#include <stdio.h>
#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;
}

View File

@ -1,303 +0,0 @@
#include <list>
#include <map>
#include <stdarg.h>
#include <string>
#include <time.h>
#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 <mutex>
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<void*, KANJI_ALLOC_INFO>
{
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<int, int> allocCount; // [size] = count
typedef std::map<std::pair<std::string, int>, 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<std::string, int>(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;
}

View File

@ -1,189 +0,0 @@
#ifndef __KANJIMEMORY_H__
#define __KANJIMEMORY_H__
#include <stdlib.h>
#include <stdint.h>
#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 <typename T>
class ScopedAutoDeletePointerHelper
{
public:
ScopedAutoDeletePointerHelper(T pPtr) : _pPtr(pPtr) {}
~ScopedAutoDeletePointerHelper() { SAFE_DELETE(_pPtr); }
T _pPtr;
};
#define SCOPED_AUTO_SAFE_DELETE(p) ScopedAutoDeletePointerHelper<decltype(p)> 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 <new>
#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__

View File

@ -1,185 +0,0 @@
#include "KString.h"
#include <stdarg.h>
#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<char*>(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());
}

View File

@ -1,19 +0,0 @@
#pragma once
#include <string>
// 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);

View File

@ -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 <cmath>
#include <string>
#include <sstream>
#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);
}

View File

@ -1,504 +0,0 @@
/*
* Copyright (c) 2003-2004 Pau Arum<EFBFBD> & David Garc<EFBFBD>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<MyTests>
* {
* 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 <iostream>
#include <string>
#include <sstream>
#include <list>
#if _MSC_VER < 1300
/** necesary for Visual 6 which don't define std::min */
namespace std
{
template<typename T> 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<typename AType>
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 <typename ConcreteTestFixture>
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<Test*> 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<FixtureCreator> _creators;
public:
/** Accessor to the (static) singleton instance */
static TestFixtureFactory& theInstance()
{
static TestFixtureFactory theFactory;
return theFactory;
}
bool runTests()
{
std::list<FixtureCreator>::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<EFBFBD>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<MyTests>
* {
* public:
* TEST_FIXTURE( MyTests )
* {
* TEST_CASE( test );
* // etc
* }
* void test()
* {
* ASSERT_EQUALS( 4, 1+1+2 );
* }
* @endcode
*/
#define TEST_FIXTURE( ConcreteFixture ) \
ConcreteFixture() : TestFixture<ConcreteFixture>( #ConcreteFixture )
#define TEST_CASE( methodName ) \
afegeixCasDeTest( this, &ConcreteFixture::methodName, #methodName );
#endif // MiniCppUnit_hxx

View File

@ -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 = "<group>"; };
BB4E38551FD9C85600709FF2 /* spineboy.atlas */ = {isa = PBXFileReference; lastKnownFileType = text; name = spineboy.atlas; path = ../../../examples/spineboy/export/spineboy.atlas; sourceTree = "<group>"; };
BB4E38581FD9C86400709FF2 /* raptor.atlas */ = {isa = PBXFileReference; lastKnownFileType = text; name = raptor.atlas; path = ../../../examples/raptor/export/raptor.atlas; sourceTree = "<group>"; };
BB4E38591FD9C86400709FF2 /* raptor-pro.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = "raptor-pro.json"; path = "../../../examples/raptor/export/raptor-pro.json"; sourceTree = "<group>"; };
BB4E385C1FD9C87600709FF2 /* goblins-pro.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; name = "goblins-pro.json"; path = "../../../examples/goblins/export/goblins-pro.json"; sourceTree = "<group>"; };
BB4E385D1FD9C87700709FF2 /* goblins.atlas */ = {isa = PBXFileReference; lastKnownFileType = text; name = goblins.atlas; path = ../../../examples/goblins/export/goblins.atlas; sourceTree = "<group>"; };
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 = "<group>"; };
BB60171C1FD928AC009BD546 /* DeformTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeformTimeline.h; sourceTree = "<group>"; };
BB60171D1FD928AC009BD546 /* Animation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Animation.h; sourceTree = "<group>"; };
BB60171E1FD928AC009BD546 /* EventData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventData.h; sourceTree = "<group>"; };
BB60171F1FD928AC009BD546 /* SlotData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SlotData.h; sourceTree = "<group>"; };
BB6017201FD928AC009BD546 /* PathConstraintMixTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathConstraintMixTimeline.h; sourceTree = "<group>"; };
BB6017211FD928AC009BD546 /* SkeletonClipping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkeletonClipping.h; sourceTree = "<group>"; };
BB6017221FD928AC009BD546 /* Pool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pool.h; sourceTree = "<group>"; };
BB6017231FD928AC009BD546 /* TimelineType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimelineType.h; sourceTree = "<group>"; };
BB6017241FD928AC009BD546 /* TextureLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextureLoader.h; sourceTree = "<group>"; };
BB6017251FD928AC009BD546 /* PositionMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PositionMode.h; sourceTree = "<group>"; };
BB6017261FD928AC009BD546 /* RTTI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTTI.h; sourceTree = "<group>"; };
BB6017271FD928AC009BD546 /* PathAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathAttachment.h; sourceTree = "<group>"; };
BB6017281FD928AC009BD546 /* MixDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MixDirection.h; sourceTree = "<group>"; };
BB6017291FD928AC009BD546 /* CurveTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CurveTimeline.h; sourceTree = "<group>"; };
BB60172A1FD928AC009BD546 /* PointAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PointAttachment.h; sourceTree = "<group>"; };
BB60172B1FD928AC009BD546 /* Event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Event.h; sourceTree = "<group>"; };
BB60172C1FD928AC009BD546 /* Bone.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bone.h; sourceTree = "<group>"; };
BB60172D1FD928AC009BD546 /* Atlas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atlas.h; sourceTree = "<group>"; };
BB60172E1FD928AC009BD546 /* DrawOrderTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawOrderTimeline.h; sourceTree = "<group>"; };
BB60172F1FD928AC009BD546 /* TransformConstraintTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformConstraintTimeline.h; sourceTree = "<group>"; };
BB6017301FD928AC009BD546 /* IkConstraintTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IkConstraintTimeline.h; sourceTree = "<group>"; };
BB6017311FD928AC009BD546 /* VertexAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VertexAttachment.h; sourceTree = "<group>"; };
BB6017321FD928AC009BD546 /* AttachmentType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachmentType.h; sourceTree = "<group>"; };
BB6017331FD928AC009BD546 /* RotateMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RotateMode.h; sourceTree = "<group>"; };
BB6017341FD928AC009BD546 /* ClippingAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClippingAttachment.h; sourceTree = "<group>"; };
BB6017351FD928AC009BD546 /* PathConstraintPositionTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathConstraintPositionTimeline.h; sourceTree = "<group>"; };
BB6017361FD928AC009BD546 /* RotateTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RotateTimeline.h; sourceTree = "<group>"; };
BB6017371FD928AC009BD546 /* Triangulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Triangulator.h; sourceTree = "<group>"; };
BB6017381FD928AC009BD546 /* RegionAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegionAttachment.h; sourceTree = "<group>"; };
BB6017391FD928AC009BD546 /* Attachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Attachment.h; sourceTree = "<group>"; };
BB60173A1FD928AC009BD546 /* HashMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashMap.h; sourceTree = "<group>"; };
BB60173B1FD928AC009BD546 /* TransformConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformConstraint.h; sourceTree = "<group>"; };
BB60173C1FD928AC009BD546 /* TransformMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformMode.h; sourceTree = "<group>"; };
BB60173D1FD928AC009BD546 /* SkeletonJson.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkeletonJson.h; sourceTree = "<group>"; };
BB60173E1FD928AC009BD546 /* IkConstraintData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IkConstraintData.h; sourceTree = "<group>"; };
BB60173F1FD928AC009BD546 /* MixPose.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MixPose.h; sourceTree = "<group>"; };
BB6017401FD928AC009BD546 /* AnimationStateData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimationStateData.h; sourceTree = "<group>"; };
BB6017411FD928AC009BD546 /* TwoColorTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TwoColorTimeline.h; sourceTree = "<group>"; };
BB6017421FD928AC009BD546 /* Skeleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Skeleton.h; sourceTree = "<group>"; };
BB6017431FD928AC009BD546 /* ColorTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorTimeline.h; sourceTree = "<group>"; };
BB6017441FD928AC009BD546 /* SpacingMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpacingMode.h; sourceTree = "<group>"; };
BB6017451FD928AC009BD546 /* Vertices.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vertices.h; sourceTree = "<group>"; };
BB6017461FD928AC009BD546 /* Constraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constraint.h; sourceTree = "<group>"; };
BB6017471FD928AC009BD546 /* LinkedMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkedMesh.h; sourceTree = "<group>"; };
BB6017481FD928AC009BD546 /* ShearTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShearTimeline.h; sourceTree = "<group>"; };
BB6017491FD928AC009BD546 /* Json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Json.h; sourceTree = "<group>"; };
BB60174A1FD928AC009BD546 /* AttachmentLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachmentLoader.h; sourceTree = "<group>"; };
BB60174B1FD928AC009BD546 /* Skin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Skin.h; sourceTree = "<group>"; };
BB60174C1FD928AC009BD546 /* AttachmentTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachmentTimeline.h; sourceTree = "<group>"; };
BB60174D1FD928AC009BD546 /* SkeletonBinary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkeletonBinary.h; sourceTree = "<group>"; };
BB60174E1FD928AC009BD546 /* SkeletonData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkeletonData.h; sourceTree = "<group>"; };
BB60174F1FD928AC009BD546 /* ContainerUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContainerUtil.h; sourceTree = "<group>"; };
BB6017501FD928AC009BD546 /* PathConstraintData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathConstraintData.h; sourceTree = "<group>"; };
BB6017511FD928AC009BD546 /* Updatable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Updatable.h; sourceTree = "<group>"; };
BB6017521FD928AC009BD546 /* TransformConstraintData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TransformConstraintData.h; sourceTree = "<group>"; };
BB6017531FD928AC009BD546 /* Extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Extension.h; sourceTree = "<group>"; };
BB6017541FD928AC009BD546 /* BlendMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BlendMode.h; sourceTree = "<group>"; };
BB6017551FD928AC009BD546 /* PathConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathConstraint.h; sourceTree = "<group>"; };
BB6017561FD928AC009BD546 /* PathConstraintSpacingTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PathConstraintSpacingTimeline.h; sourceTree = "<group>"; };
BB6017571FD928AC009BD546 /* ScaleTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScaleTimeline.h; sourceTree = "<group>"; };
BB6017581FD928AC009BD546 /* IkConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IkConstraint.h; sourceTree = "<group>"; };
BB6017591FD928AC009BD546 /* BoundingBoxAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BoundingBoxAttachment.h; sourceTree = "<group>"; };
BB60175A1FD928AC009BD546 /* MathUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathUtil.h; sourceTree = "<group>"; };
BB60175B1FD928AC009BD546 /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = "<group>"; };
BB60175C1FD928AC009BD546 /* SkeletonBounds.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkeletonBounds.h; sourceTree = "<group>"; };
BB60175D1FD928AC009BD546 /* Timeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Timeline.h; sourceTree = "<group>"; };
BB60175E1FD928AC009BD546 /* Slot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Slot.h; sourceTree = "<group>"; };
BB60175F1FD928AC009BD546 /* BoneData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BoneData.h; sourceTree = "<group>"; };
BB6017601FD928AC009BD546 /* TranslateTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TranslateTimeline.h; sourceTree = "<group>"; };
BB6017611FD928AC009BD546 /* AnimationState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnimationState.h; sourceTree = "<group>"; };
BB6017621FD928AC009BD546 /* MeshAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MeshAttachment.h; sourceTree = "<group>"; };
BB6017631FD928AC009BD546 /* AtlasAttachmentLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtlasAttachmentLoader.h; sourceTree = "<group>"; };
BB6017641FD928AC009BD546 /* EventTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventTimeline.h; sourceTree = "<group>"; };
BB6017671FD928AC009BD546 /* Attachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Attachment.cpp; sourceTree = "<group>"; };
BB6017681FD928AC009BD546 /* Skeleton.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Skeleton.cpp; sourceTree = "<group>"; };
BB6017691FD928AC009BD546 /* TranslateTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TranslateTimeline.cpp; sourceTree = "<group>"; };
BB60176A1FD928AC009BD546 /* Extension.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Extension.cpp; sourceTree = "<group>"; };
BB60176B1FD928AC009BD546 /* Updatable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Updatable.cpp; sourceTree = "<group>"; };
BB60176C1FD928AC009BD546 /* Bone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Bone.cpp; sourceTree = "<group>"; };
BB60176D1FD928AC009BD546 /* AtlasAttachmentLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AtlasAttachmentLoader.cpp; sourceTree = "<group>"; };
BB60176E1FD928AC009BD546 /* EventTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventTimeline.cpp; sourceTree = "<group>"; };
BB60176F1FD928AC009BD546 /* PathConstraint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathConstraint.cpp; sourceTree = "<group>"; };
BB6017701FD928AC009BD546 /* VertexAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VertexAttachment.cpp; sourceTree = "<group>"; };
BB6017711FD928AC009BD546 /* TextureLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureLoader.cpp; sourceTree = "<group>"; };
BB6017721FD928AC009BD546 /* SkeletonData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkeletonData.cpp; sourceTree = "<group>"; };
BB6017731FD928AC009BD546 /* TransformConstraintTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TransformConstraintTimeline.cpp; sourceTree = "<group>"; };
BB6017741FD928AC009BD546 /* IkConstraint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IkConstraint.cpp; sourceTree = "<group>"; };
BB6017751FD928AC009BD546 /* CurveTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CurveTimeline.cpp; sourceTree = "<group>"; };
BB6017761FD928AC009BD546 /* AnimationStateData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimationStateData.cpp; sourceTree = "<group>"; };
BB6017771FD928AC009BD546 /* Constraint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Constraint.cpp; sourceTree = "<group>"; };
BB6017781FD928AC009BD546 /* BoundingBoxAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BoundingBoxAttachment.cpp; sourceTree = "<group>"; };
BB6017791FD928AC009BD546 /* PathAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathAttachment.cpp; sourceTree = "<group>"; };
BB60177A1FD928AC009BD546 /* MeshAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MeshAttachment.cpp; sourceTree = "<group>"; };
BB60177B1FD928AC009BD546 /* TransformConstraint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TransformConstraint.cpp; sourceTree = "<group>"; };
BB60177C1FD928AC009BD546 /* Skin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Skin.cpp; sourceTree = "<group>"; };
BB60177D1FD928AC009BD546 /* RTTI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RTTI.cpp; sourceTree = "<group>"; };
BB60177E1FD928AC009BD546 /* MathUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathUtil.cpp; sourceTree = "<group>"; };
BB60177F1FD928AC009BD546 /* IkConstraintData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IkConstraintData.cpp; sourceTree = "<group>"; };
BB6017801FD928AC009BD546 /* Atlas.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Atlas.cpp; sourceTree = "<group>"; };
BB6017811FD928AC009BD546 /* ClippingAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClippingAttachment.cpp; sourceTree = "<group>"; };
BB6017821FD928AC009BD546 /* PathConstraintData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathConstraintData.cpp; sourceTree = "<group>"; };
BB6017831FD928AC009BD546 /* Timeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Timeline.cpp; sourceTree = "<group>"; };
BB6017841FD928AC009BD546 /* SkeletonBinary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkeletonBinary.cpp; sourceTree = "<group>"; };
BB6017851FD928AC009BD546 /* ScaleTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScaleTimeline.cpp; sourceTree = "<group>"; };
BB6017861FD928AC009BD546 /* LinkedMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinkedMesh.cpp; sourceTree = "<group>"; };
BB6017871FD928AC009BD546 /* PointAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PointAttachment.cpp; sourceTree = "<group>"; };
BB6017881FD928AC009BD546 /* RegionAttachment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegionAttachment.cpp; sourceTree = "<group>"; };
BB6017891FD928AC009BD546 /* DeformTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeformTimeline.cpp; sourceTree = "<group>"; };
BB60178A1FD928AC009BD546 /* Animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Animation.cpp; sourceTree = "<group>"; };
BB60178B1FD928AC009BD546 /* AttachmentLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AttachmentLoader.cpp; sourceTree = "<group>"; };
BB60178C1FD928AC009BD546 /* DrawOrderTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DrawOrderTimeline.cpp; sourceTree = "<group>"; };
BB60178D1FD928AC009BD546 /* AttachmentTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AttachmentTimeline.cpp; sourceTree = "<group>"; };
BB60178E1FD928AC009BD546 /* EventData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventData.cpp; sourceTree = "<group>"; };
BB60178F1FD928AC009BD546 /* PathConstraintSpacingTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathConstraintSpacingTimeline.cpp; sourceTree = "<group>"; };
BB6017901FD928AC009BD546 /* PathConstraintPositionTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathConstraintPositionTimeline.cpp; sourceTree = "<group>"; };
BB6017911FD928AC009BD546 /* TransformConstraintData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TransformConstraintData.cpp; sourceTree = "<group>"; };
BB6017921FD928AC009BD546 /* SkeletonClipping.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkeletonClipping.cpp; sourceTree = "<group>"; };
BB6017931FD928AC009BD546 /* TwoColorTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TwoColorTimeline.cpp; sourceTree = "<group>"; };
BB6017941FD928AC009BD546 /* Slot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Slot.cpp; sourceTree = "<group>"; };
BB6017951FD928AC009BD546 /* AnimationState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AnimationState.cpp; sourceTree = "<group>"; };
BB6017961FD928AC009BD546 /* SkeletonJson.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkeletonJson.cpp; sourceTree = "<group>"; };
BB6017971FD928AC009BD546 /* BoneData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BoneData.cpp; sourceTree = "<group>"; };
BB6017981FD928AC009BD546 /* IkConstraintTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IkConstraintTimeline.cpp; sourceTree = "<group>"; };
BB6017991FD928AC009BD546 /* Event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Event.cpp; sourceTree = "<group>"; };
BB60179A1FD928AC009BD546 /* RotateTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RotateTimeline.cpp; sourceTree = "<group>"; };
BB60179B1FD928AC009BD546 /* PathConstraintMixTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathConstraintMixTimeline.cpp; sourceTree = "<group>"; };
BB60179C1FD928AC009BD546 /* Triangulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Triangulator.cpp; sourceTree = "<group>"; };
BB60179D1FD928AC009BD546 /* Json.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Json.cpp; sourceTree = "<group>"; };
BB60179E1FD928AC009BD546 /* SkeletonBounds.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SkeletonBounds.cpp; sourceTree = "<group>"; };
BB60179F1FD928AC009BD546 /* SlotData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlotData.cpp; sourceTree = "<group>"; };
BB6017A01FD928AC009BD546 /* ShearTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShearTimeline.cpp; sourceTree = "<group>"; };
BB6017A11FD928AC009BD546 /* ColorTimeline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColorTimeline.cpp; sourceTree = "<group>"; };
BB6017DE1FD928F6009BD546 /* KMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KMemory.h; sourceTree = "<group>"; };
BB6017DF1FD928F6009BD546 /* KString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KString.h; sourceTree = "<group>"; };
BB6017E01FD928F6009BD546 /* KMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KMemory.cpp; sourceTree = "<group>"; };
BB6017E11FD928F6009BD546 /* KString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KString.cpp; sourceTree = "<group>"; };
BB6017E51FD929D0009BD546 /* MiniCppUnit.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MiniCppUnit.hxx; sourceTree = "<group>"; };
BB6017E61FD929D0009BD546 /* MiniCppUnit.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MiniCppUnit.cxx; sourceTree = "<group>"; };
BB6017E91FD929F4009BD546 /* teamcity_cppunit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = teamcity_cppunit.h; sourceTree = "<group>"; };
BB6017EA1FD929F4009BD546 /* teamcity_cppunit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = teamcity_cppunit.cpp; sourceTree = "<group>"; };
BB6017EB1FD929F4009BD546 /* teamcity_messages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = teamcity_messages.h; sourceTree = "<group>"; };
BB6017EC1FD929F4009BD546 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.txt; sourceTree = "<group>"; };
BB6017ED1FD929F4009BD546 /* teamcity_messages.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = teamcity_messages.cpp; sourceTree = "<group>"; };
BB6017F01FD92A5B009BD546 /* SimpleTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SimpleTest.h; sourceTree = "<group>"; };
BB6017FC1FD92AF3009BD546 /* SpineEventMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpineEventMonitor.h; sourceTree = "<group>"; };
BB6017FD1FD92AF3009BD546 /* SpineEventMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpineEventMonitor.cpp; sourceTree = "<group>"; };
BBFB507F1FDAF6CD005B22B6 /* MemoryTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MemoryTest.h; sourceTree = "<group>"; };
/* 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 = "<group>";
};
BB6017101FD9289A009BD546 /* Products */ = {
isa = PBXGroup;
children = (
BB60170F1FD9289A009BD546 /* spine_unit_test */,
);
name = Products;
sourceTree = "<group>";
};
BB6017111FD9289A009BD546 /* spine_unit_test */ = {
isa = PBXGroup;
children = (
BB6017121FD9289A009BD546 /* main.cpp */,
BB6017F01FD92A5B009BD546 /* SimpleTest.h */,
BBFB507F1FDAF6CD005B22B6 /* MemoryTest.h */,
);
path = spine_unit_test;
sourceTree = "<group>";
};
BB6017191FD928AC009BD546 /* spine-cpp */ = {
isa = PBXGroup;
children = (
BB60171A1FD928AC009BD546 /* include */,
BB6017651FD928AC009BD546 /* src */,
);
name = "spine-cpp";
path = "../../spine-cpp";
sourceTree = "<group>";
};
BB60171A1FD928AC009BD546 /* include */ = {
isa = PBXGroup;
children = (
BB60171B1FD928AC009BD546 /* spine */,
);
path = include;
sourceTree = "<group>";
};
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 = "<group>";
};
BB6017651FD928AC009BD546 /* src */ = {
isa = PBXGroup;
children = (
BB6017661FD928AC009BD546 /* spine */,
);
path = src;
sourceTree = "<group>";
};
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 = "<group>";
};
BB6017DD1FD928F6009BD546 /* memory */ = {
isa = PBXGroup;
children = (
BB6017DE1FD928F6009BD546 /* KMemory.h */,
BB6017DF1FD928F6009BD546 /* KString.h */,
BB6017E01FD928F6009BD546 /* KMemory.cpp */,
BB6017E11FD928F6009BD546 /* KString.cpp */,
);
name = memory;
path = ../memory;
sourceTree = "<group>";
};
BB6017E41FD929D0009BD546 /* minicppunit */ = {
isa = PBXGroup;
children = (
BB6017E51FD929D0009BD546 /* MiniCppUnit.hxx */,
BB6017E61FD929D0009BD546 /* MiniCppUnit.cxx */,
);
name = minicppunit;
path = ../minicppunit;
sourceTree = "<group>";
};
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 = "<group>";
};
BB6017F11FD92AF3009BD546 /* tests */ = {
isa = PBXGroup;
children = (
BB6017FC1FD92AF3009BD546 /* SpineEventMonitor.h */,
BB6017FD1FD92AF3009BD546 /* SpineEventMonitor.cpp */,
);
name = tests;
path = ../tests;
sourceTree = "<group>";
};
/* 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 */;
}

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:spine_unit_test.xcodeproj">
</FileRef>
</Workspace>

View File

@ -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<Allocation>::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<Allocation>::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<Allocation>::iterator it = allocated.begin(); it != allocated.end(); it++) {
printf("\"%s:%i (%zu bytes at %p)\n", it->fileName, it->line, it->size, it->address);
}
}
void Spine::TestSpineExtension::clearAllocations() {
allocated.resize(0);
}

View File

@ -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 <spine/Extension.h>
#include <vector>
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<Allocation> allocated;
};
}
#endif //SPINE_TESTHARNESS_H

View File

@ -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 <stdio.h>
#include <spine/spine.h>
#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();
}

View File

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

View File

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

View File

@ -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 <string>
#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 &copy);
// Prevents the use of the copy operator.
void operator =(const TeamcityProgressListener &copy);
};
}

View File

@ -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 <stdlib.h>
#include <sstream>
#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();
}
}

View File

@ -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 <string>
#include <iostream>
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 */

View File

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

View File

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

View File

@ -1,175 +0,0 @@
#include "C_InterfaceTestFixture.h"
#include "SpineEventMonitor.h"
#include <spine/SkeletonJson.h>
#include <spine/SkeletonData.h>
#include <spine/Atlas.h>
#include <spine/AnimationStateData.h>
#include <spine/Skeleton.h>
#include <spine/AnimationState.h>
#include <spine/Animation.h>
#include <vector>
#include <spine/Extension.h>
#include <spine/TextureLoader.h>
#include <spine/Vector.h>
#include <spine/CurveTimeline.h>
#include <spine/VertexAttachment.h>
#include <spine/Json.h>
#include <spine/AttachmentLoader.h>
#include <spine/AtlasAttachmentLoader.h>
#include <spine/LinkedMesh.h>
#include <new>
#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<Atlas*> 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<std::string> 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);
}

View File

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

View File

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

View File

@ -1,26 +0,0 @@
#pragma once
#include "TestOptions.h"
#include "MiniCppUnit.hxx"
class EmptyTestFixture : public TestFixture<EmptyTestFixture>
{
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

View File

@ -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 <spine/SkeletonJson.h>
#include <spine/SkeletonData.h>
#include <spine/Atlas.h>
#include <spine/AnimationStateData.h>
#include <spine/Skeleton.h>
#include <spine/AnimationState.h>
#include <spine/Animation.h>
#include <vector>
#include <spine/Extension.h>
#include <spine/TextureLoader.h>
#include <spine/Vector.h>
#include <spine/CurveTimeline.h>
#include <spine/VertexAttachment.h>
#include <spine/Json.h>
#include <spine/AttachmentLoader.h>
#include <spine/AtlasAttachmentLoader.h>
#include <spine/LinkedMesh.h>
#include <spine/Triangulator.h>
#include <spine/SkeletonClipping.h>
#include <spine/BoneData.h>
#include <spine/Bone.h>
#include <spine/SlotData.h>
#include <spine/Slot.h>
#include <spine/ClippingAttachment.h>
#include <new>
#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<Atlas*> 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<float> 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<int> 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<float> *> 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<float> 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<float> 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<float> 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<int> indices;
indices.reserve(16);
indices.push_back(0);
indices.push_back(1);
indices.push_back(2);
clipping->clipTriangles(vertices, static_cast<int>(vertices.size()), indices, static_cast<int>(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 */

View File

@ -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 <spine/SkeletonJson.h>
#include <spine/SkeletonData.h>
#include <spine/Atlas.h>
#include <spine/AnimationStateData.h>
#include <spine/Skeleton.h>
#include <spine/AnimationState.h>
#include <spine/Animation.h>
#include <vector>
#include <spine/Extension.h>
#include <spine/TextureLoader.h>
#include <spine/Vector.h>
#include <spine/CurveTimeline.h>
#include <spine/VertexAttachment.h>
#include <spine/Json.h>
#include <spine/AttachmentLoader.h>
#include <spine/AtlasAttachmentLoader.h>
#include <spine/LinkedMesh.h>
#include <new>
#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<Atlas*> 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<std::string> 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 */

View File

@ -1,181 +0,0 @@
#include "SpineEventMonitor.h"
#include "KString.h"
#include <spine/Animation.h>
#include <spine/Event.h>
#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;
}

View File

@ -1,121 +0,0 @@
//////////////////////////////////////////////////////////////////////
// filename: SpineEventMonitor.h
//
// purpose: Monitor spAnimationState Events
/////////////////////////////////////////////////////////////////////
#pragma once
#include <vector>
#include <string>
#include <spine/AnimationState.h>
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<InterruptEvent> 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
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <direct.h>
#else
#include <unistd.h>
#endif // WIN32
#include <ctime>
#include "KString.h"
#include <stdio.h>
#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;
}

View File

@ -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<AtlasPage*> _pages;
Vector<AtlasRegion*> _regions;
TextureLoader& _textureLoader;
TextureLoader* _textureLoader;
void load(const char* begin, int length, const char* dir);

View File

@ -33,22 +33,6 @@
#include <stdlib.h>
// #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 <typename T> static void free(T* ptr) {
getInstance()->_free((void*)ptr);
template <typename T> 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);
};
}

View File

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

View File

@ -57,7 +57,7 @@ namespace Spine {
return ret;
}
else {
T* ret = new T();
T* ret = new (__FILE__, __LINE__) T();
return ret;
}

View File

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

View File

@ -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<T>(buffer);
SpineExtension::free<T>(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();
}
};
}

View File

@ -216,11 +216,11 @@ namespace Spine {
}
EventQueue* EventQueue::newEventQueue(AnimationState& state, Pool<TrackEntry>& 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<TrackEntry>& trackEntryPool) : _state(state), _trackEntryPool(trackEntryPool), _drainDisabled(false) {

View File

@ -37,7 +37,7 @@
#include <cstring>
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");

View File

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

View File

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

View File

@ -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 */
}

View File

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

View File

@ -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<BlendMode>(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<VertexAttachment*>(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<int>(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) {

View File

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

View File

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

View File

@ -29,7 +29,16 @@
*****************************************************************************/
#include <spine/SpineObject.h>
#include <spine/Extension.h>
namespace Spine {
void *SpineObject::operator new(size_t sz, const char* file, int line) {
return SpineExtension::alloc<SpineObject>(sz, file, line);
}
void SpineObject::operator delete(void *p) {
((SpineObject*)p)->~SpineObject();
SpineExtension::free(p, __FILE__, __LINE__);
}
}

View File

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