From 7180f17af20325727fddf59ee74095cefa7bcc94 Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 1 Feb 2018 17:40:55 +0100 Subject: [PATCH] [cpp] All Spine objects derrive from SpineObject so we can override new/delete, which in turn calls SpineExtension allocation methods (not implemented yet). Refactored SpineExtension, removing use of macros, introducing use of templated static methods for more comfort. Rewired all allocation code throughout the runtime. See #1046. --- CMakeLists.txt | 7 +- spine-cpp/spine-cpp-unit-tests/CMakeLists.txt | 18 +- .../tests/C_InterfaceTestFixture.cpp | 134 +- .../spine_unit_test => tests}/MemoryTest.h | 0 .../tests/MemoryTestFixture.cpp | 339 -- .../tests/MemoryTestFixture.h | 50 - .../spine_unit_test => tests}/SimpleTest.h | 0 .../spine_unit_test => tests}/main.cpp | 0 spine-cpp/spine-cpp/include/spine/Animation.h | 3 +- .../spine-cpp/include/spine/AnimationState.h | 9 +- .../include/spine/AnimationStateData.h | 7 +- spine-cpp/spine-cpp/include/spine/Atlas.h | 7 +- .../include/spine/AtlasAttachmentLoader.h | 6 +- .../spine-cpp/include/spine/Attachment.h | 4 +- .../include/spine/AttachmentLoader.h | 4 +- .../include/spine/AttachmentTimeline.h | 2 +- spine-cpp/spine-cpp/include/spine/Bone.h | 2 +- spine-cpp/spine-cpp/include/spine/BoneData.h | 4 +- .../include/spine/BoundingBoxAttachment.h | 1 + .../spine-cpp/include/spine/ContainerUtil.h | 5 +- spine-cpp/spine-cpp/include/spine/Event.h | 4 +- spine-cpp/spine-cpp/include/spine/EventData.h | 4 +- spine-cpp/spine-cpp/include/spine/Extension.h | 68 +- spine-cpp/spine-cpp/include/spine/HashMap.h | 18 +- .../include/spine/IkConstraintData.h | 3 +- spine-cpp/spine-cpp/include/spine/Json.h | 4 +- .../spine-cpp/include/spine/LinkedMesh.h | 4 +- spine-cpp/spine-cpp/include/spine/MathUtil.h | 4 +- .../include/spine/PathConstraintData.h | 3 +- spine-cpp/spine-cpp/include/spine/Pool.h | 6 +- spine-cpp/spine-cpp/include/spine/RTTI.h | 3 +- spine-cpp/spine-cpp/include/spine/Skeleton.h | 3 +- .../spine-cpp/include/spine/SkeletonBinary.h | 7 +- .../spine-cpp/include/spine/SkeletonBounds.h | 5 +- .../include/spine/SkeletonClipping.h | 2 +- .../spine-cpp/include/spine/SkeletonData.h | 2 +- .../spine-cpp/include/spine/SkeletonJson.h | 5 +- spine-cpp/spine-cpp/include/spine/Skin.h | 6 +- spine-cpp/spine-cpp/include/spine/Slot.h | 3 +- spine-cpp/spine-cpp/include/spine/SlotData.h | 3 +- .../spine-cpp/include/spine/SpineObject.h | 118 +- .../spine-cpp/include/spine/TextureLoader.h | 4 +- spine-cpp/spine-cpp/include/spine/Timeline.h | 3 +- .../include/spine/TransformConstraintData.h | 3 +- .../spine-cpp/include/spine/Triangulator.h | 2 +- spine-cpp/spine-cpp/include/spine/Updatable.h | 3 +- spine-cpp/spine-cpp/include/spine/Vector.h | 9 +- spine-cpp/spine-cpp/include/spine/Vertices.h | 2 +- .../spine-cpp/src/spine/AnimationState.cpp | 12 +- spine-cpp/spine-cpp/src/spine/Atlas.cpp | 22 +- .../src/spine/AtlasAttachmentLoader.cpp | 38 +- spine-cpp/spine-cpp/src/spine/Extension.cpp | 25 +- spine-cpp/spine-cpp/src/spine/Json.cpp | 24 +- spine-cpp/spine-cpp/src/spine/Skeleton.cpp | 18 +- .../spine-cpp/src/spine/SkeletonBinary.cpp | 168 +- .../spine-cpp/src/spine/SkeletonBounds.cpp | 3 +- .../spine-cpp/src/spine/SkeletonJson.cpp | 124 +- spine-cpp/spine-cpp/src/spine/SpineObject.cpp | 35 + spine-sfml/CMakeLists.txt | 87 - spine-sfml/LICENSE | 27 - spine-sfml/README.md | 68 - spine-sfml/data/coin-pro.json | 178 - spine-sfml/data/coin-pro.skel | Bin 5922 -> 0 bytes spine-sfml/data/coin.atlas | 27 - spine-sfml/data/coin.png | Bin 56635 -> 0 bytes spine-sfml/data/goblins-pro.json | 1107 ----- spine-sfml/data/goblins-pro.skel | Bin 18127 -> 0 bytes spine-sfml/data/goblins.atlas | 293 -- spine-sfml/data/goblins.png | Bin 210574 -> 0 bytes spine-sfml/data/owl-pro.json | 549 --- spine-sfml/data/owl-pro.skel | Bin 13307 -> 0 bytes spine-sfml/data/owl.atlas | 195 - spine-sfml/data/owl.png | Bin 425664 -> 0 bytes spine-sfml/data/raptor-pro.json | 3840 ---------------- spine-sfml/data/raptor-pro.skel | Bin 89979 -> 0 bytes spine-sfml/data/raptor.atlas | 300 -- spine-sfml/data/raptor.png | Bin 522372 -> 0 bytes spine-sfml/data/spineboy-ess.json | 1783 -------- spine-sfml/data/spineboy-ess.skel | Bin 12134 -> 0 bytes spine-sfml/data/spineboy.atlas | 307 -- spine-sfml/data/spineboy.png | Bin 585797 -> 0 bytes spine-sfml/data/stretchyman-pro.json | 855 ---- spine-sfml/data/stretchyman-pro.skel | Bin 23749 -> 0 bytes spine-sfml/data/stretchyman.atlas | 41 - spine-sfml/data/stretchyman.png | Bin 134187 -> 0 bytes spine-sfml/data/tank-pro.json | 3842 ----------------- spine-sfml/data/tank-pro.skel | Bin 48389 -> 0 bytes spine-sfml/data/tank.atlas | 174 - spine-sfml/data/tank.png | Bin 594397 -> 0 bytes spine-sfml/data/vine-pro.json | 281 -- spine-sfml/data/vine-pro.skel | Bin 10176 -> 0 bytes spine-sfml/data/vine.atlas | 13 - spine-sfml/data/vine.png | Bin 160151 -> 0 bytes spine-sfml/example/main.cpp | 461 -- spine-sfml/src/spine/spine-sfml.cpp | 285 -- 95 files changed, 470 insertions(+), 15615 deletions(-) rename spine-cpp/spine-cpp-unit-tests/{spine_unit_test/spine_unit_test => tests}/MemoryTest.h (100%) rename spine-cpp/spine-cpp-unit-tests/{spine_unit_test/spine_unit_test => tests}/SimpleTest.h (100%) rename spine-cpp/spine-cpp-unit-tests/{spine_unit_test/spine_unit_test => tests}/main.cpp (100%) rename spine-sfml/src/spine/spine-sfml.h => spine-cpp/spine-cpp/include/spine/SpineObject.h (60%) create mode 100644 spine-cpp/spine-cpp/src/spine/SpineObject.cpp delete mode 100644 spine-sfml/CMakeLists.txt delete mode 100644 spine-sfml/LICENSE delete mode 100644 spine-sfml/README.md delete mode 100644 spine-sfml/data/coin-pro.json delete mode 100644 spine-sfml/data/coin-pro.skel delete mode 100644 spine-sfml/data/coin.atlas delete mode 100644 spine-sfml/data/coin.png delete mode 100644 spine-sfml/data/goblins-pro.json delete mode 100644 spine-sfml/data/goblins-pro.skel delete mode 100644 spine-sfml/data/goblins.atlas delete mode 100644 spine-sfml/data/goblins.png delete mode 100644 spine-sfml/data/owl-pro.json delete mode 100644 spine-sfml/data/owl-pro.skel delete mode 100644 spine-sfml/data/owl.atlas delete mode 100644 spine-sfml/data/owl.png delete mode 100644 spine-sfml/data/raptor-pro.json delete mode 100644 spine-sfml/data/raptor-pro.skel delete mode 100644 spine-sfml/data/raptor.atlas delete mode 100644 spine-sfml/data/raptor.png delete mode 100644 spine-sfml/data/spineboy-ess.json delete mode 100644 spine-sfml/data/spineboy-ess.skel delete mode 100644 spine-sfml/data/spineboy.atlas delete mode 100644 spine-sfml/data/spineboy.png delete mode 100644 spine-sfml/data/stretchyman-pro.json delete mode 100644 spine-sfml/data/stretchyman-pro.skel delete mode 100644 spine-sfml/data/stretchyman.atlas delete mode 100644 spine-sfml/data/stretchyman.png delete mode 100644 spine-sfml/data/tank-pro.json delete mode 100644 spine-sfml/data/tank-pro.skel delete mode 100644 spine-sfml/data/tank.atlas delete mode 100644 spine-sfml/data/tank.png delete mode 100644 spine-sfml/data/vine-pro.json delete mode 100644 spine-sfml/data/vine-pro.skel delete mode 100644 spine-sfml/data/vine.atlas delete mode 100644 spine-sfml/data/vine.png delete mode 100644 spine-sfml/example/main.cpp delete mode 100644 spine-sfml/src/spine/spine-sfml.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 40d6e03b5..8b3fe833b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,9 @@ set(SPINE_COCOS2D_X FALSE CACHE BOOL FALSE) if((${SPINE_SFML}) OR (${CMAKE_CURRENT_BINARY_DIR} MATCHES "spine-sfml")) add_subdirectory(spine-c) - add_subdirectory(spine-sfml) + add_subdirectory(spine-sfml/c) + add_subdirectory(spine-cpp) + add_subdirectory(spine-sfml/cpp) endif() if((${SPINE_COCOS2D_OBJC}) OR (${CMAKE_CURRENT_BINARY_DIR} MATCHES "spine-cocos2d-objc")) @@ -22,4 +24,5 @@ if((${SPINE_COCOS2D_X}) OR (${CMAKE_CURRENT_BINARY_DIR} MATCHES "spine-cocos2dx" add_subdirectory(spine-cocos2dx) endif() -add_subdirectory(spine-c/spine-c-unit-tests) \ No newline at end of file +add_subdirectory(spine-c/spine-c-unit-tests) +add_subdirectory(spine-cpp/spine-cpp-unit-tests) \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/CMakeLists.txt b/spine-cpp/spine-cpp-unit-tests/CMakeLists.txt index e08a7d3ba..02a2500e6 100755 --- a/spine-cpp/spine-cpp-unit-tests/CMakeLists.txt +++ b/spine-cpp/spine-cpp-unit-tests/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 2.8.9) -project(spine_unit_test) +project(spine_cpp_unit_test) set(CMAKE_INSTALL_PREFIX "./") set(CMAKE_VERBOSE_MAKEFILE ON) @@ -38,21 +38,21 @@ set(MEMLEAK_SRC ######################################################### # setup main project ######################################################### -add_executable(spine_unit_test main.cpp ${MINICPP_SRC} ${TEAMCITY_SRC} ${TEST_SRC} ${MEMLEAK_SRC}) -target_link_libraries(spine_unit_test spine-cpp) +add_executable(spine_cpp_unit_test main.cpp ${MINICPP_SRC} ${TEAMCITY_SRC} ${TEST_SRC} ${MEMLEAK_SRC}) +target_link_libraries(spine_cpp_unit_test spine-cpp) ######################################################### # copy resources to build output directory ######################################################### -add_custom_command(TARGET spine_unit_test PRE_BUILD +add_custom_command(TARGET spine_cpp_unit_test PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_LIST_DIR}/../../examples/spineboy/export $/testdata/spineboy) + ${CMAKE_CURRENT_LIST_DIR}/../../examples/spineboy/export $/testdata/spineboy) -add_custom_command(TARGET spine_unit_test PRE_BUILD +add_custom_command(TARGET spine_cpp_unit_test PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_LIST_DIR}/../../examples/raptor/export $/testdata/raptor) + ${CMAKE_CURRENT_LIST_DIR}/../../examples/raptor/export $/testdata/raptor) -add_custom_command(TARGET spine_unit_test PRE_BUILD +add_custom_command(TARGET spine_cpp_unit_test PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_LIST_DIR}/../../examples/goblins/export $/testdata/goblins) + ${CMAKE_CURRENT_LIST_DIR}/../../examples/goblins/export $/testdata/goblins) diff --git a/spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.cpp b/spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.cpp index 072c8531d..b6576bb7f 100755 --- a/spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.cpp +++ b/spine-cpp/spine-cpp-unit-tests/tests/C_InterfaceTestFixture.cpp @@ -1,28 +1,28 @@ #include "C_InterfaceTestFixture.h" #include "SpineEventMonitor.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include #include - -#include + +#include #include "KMemory.h" // last include @@ -35,7 +35,7 @@ #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 +#define MAX_RUN_TIME 6000 // equal to about 100 seconds of execution void C_InterfaceTestFixture::setUp() { @@ -45,21 +45,21 @@ void C_InterfaceTestFixture::tearDown() { } -static Spine::SkeletonData* readSkeletonJsonData(const char* filename, Atlas* atlas) -{ - using namespace Spine; - - Vector atlasArray; - atlasArray.push_back(atlas); +static Spine::SkeletonData* readSkeletonJsonData(const char* filename, Atlas* atlas) +{ + using namespace Spine; + + Vector atlasArray; + atlasArray.push_back(atlas); - SkeletonJson* skeletonJson = NEW(SkeletonJson); - new (skeletonJson) SkeletonJson(atlasArray); - ASSERT(skeletonJson != 0); + SkeletonJson* skeletonJson = NEW(SkeletonJson); + new (skeletonJson) SkeletonJson(atlasArray); + ASSERT(skeletonJson != 0); SkeletonData* skeletonData = skeletonJson->readSkeletonDataFile(filename); ASSERT(skeletonData != 0); - DESTROY(SkeletonJson, skeletonJson); + DESTROY(SkeletonJson, skeletonJson); return skeletonData; } @@ -68,78 +68,78 @@ typedef std::vector AnimList; static size_t enumerateAnimations(AnimList& outList, SkeletonData* skeletonData) { - if (skeletonData) + if (skeletonData) { for (int n = 0; n < skeletonData->getAnimations().size(); n++) - { - outList.push_back(skeletonData->getAnimations()[n]->getName()); + { + 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 - } +} + +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 + // Global Animation Information MyTextureLoader myTextureLoader; - Atlas* atlas = NEW(Atlas); + Atlas* atlas = NEW(Atlas); new (atlas) Atlas(atlasName, myTextureLoader); ASSERT(atlas != 0); SkeletonData* skeletonData = readSkeletonJsonData(jsonName, atlas); ASSERT(skeletonData != 0); - AnimationStateData* stateData = NEW(AnimationStateData); + AnimationStateData* stateData = NEW(AnimationStateData); new (stateData) AnimationStateData(skeletonData); ASSERT(stateData != 0); stateData->setDefaultMix(0.2f); // force mixing /////////////////////////////////////////////////////////////////////////// // Animation Instance - Skeleton* skeleton = NEW(Skeleton); + Skeleton* skeleton = NEW(Skeleton); new (skeleton) Skeleton(skeletonData); ASSERT(skeleton != 0); - AnimationState* state = NEW(AnimationState); + AnimationState* state = NEW(AnimationState); new (state) AnimationState(stateData); ASSERT(state != 0); /////////////////////////////////////////////////////////////////////////// // Run animation skeleton->setToSetupPose(); - SpineEventMonitor eventMonitor(state); + 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); - } + if (count > 0) + { + state->setAnimation(0, anims[0].c_str(), false); + } - for (size_t i = 1; i < count; ++i) - { + 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) + for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) { const float timeSlice = 1.0f / 60.0f; skeleton->update(timeSlice); @@ -149,13 +149,13 @@ static void testRunner(const char* jsonName, const char* atlasName) /////////////////////////////////////////////////////////////////////////// // Dispose Instance - DESTROY(Skeleton, skeleton); + DESTROY(Skeleton, skeleton); DESTROY(AnimationState, state); /////////////////////////////////////////////////////////////////////////// - // Dispose Global - DESTROY(AnimationStateData, stateData); - DESTROY(SkeletonData, skeletonData); + // Dispose Global + DESTROY(AnimationStateData, stateData); + DESTROY(SkeletonData, skeletonData); DESTROY(Atlas, atlas); } diff --git a/spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test/MemoryTest.h b/spine-cpp/spine-cpp-unit-tests/tests/MemoryTest.h similarity index 100% rename from spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test/MemoryTest.h rename to spine-cpp/spine-cpp-unit-tests/tests/MemoryTest.h diff --git a/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.cpp b/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.cpp index d06c196e6..e69de29bb 100755 --- a/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.cpp +++ b/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.cpp @@ -1,339 +0,0 @@ -#include -#include "MemoryTestFixture.h" -#include "SpineEventMonitor.h" - -#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 - -MemoryTestFixture::~MemoryTestFixture() -{ - finalize(); -} - -void MemoryTestFixture::initialize() -{ - // on a Per- Fixture Basis, before Test execution -} - -void MemoryTestFixture::finalize() -{ - // on a Per- Fixture Basis, after all tests pass/fail -} - -void MemoryTestFixture::setUp() -{ - // Setup on Per-Test Basis -} - -void MemoryTestFixture::tearDown() -{ - // Tear Down on Per-Test Basis -} - - -////////////////////////////////////////////////////////////////////////// -// Helper methods -static spSkeletonData* readSkeletonJsonData(const char* filename, spAtlas* atlas) { - spSkeletonJson* json = spSkeletonJson_create(atlas); - ASSERT(json != 0); - - spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, filename); - ASSERT(skeletonData != 0); - - spSkeletonJson_dispose(json); - return skeletonData; -} - -static void LoadSpineboyExample(spAtlas* &atlas, spSkeletonData* &skeletonData, spAnimationStateData* &stateData, spSkeleton* &skeleton, spAnimationState* &state) -{ - /////////////////////////////////////////////////////////////////////////// - // Global Animation Information - atlas = spAtlas_createFromFile(SPINEBOY_ATLAS, 0); - ASSERT(atlas != 0); - - skeletonData = readSkeletonJsonData(SPINEBOY_JSON, atlas); - ASSERT(skeletonData != 0); - - stateData = spAnimationStateData_create(skeletonData); - ASSERT(stateData != 0); - stateData->defaultMix = 0.4f; // force mixing - - /////////////////////////////////////////////////////////////////////////// - // Animation Instance - skeleton = spSkeleton_create(skeletonData); - ASSERT(skeleton != 0); - - state = spAnimationState_create(stateData); - ASSERT(state != 0); -} - -static void DisposeAll(spSkeleton* skeleton, spAnimationState* state, spAnimationStateData* stateData, spSkeletonData* skeletonData, spAtlas* atlas) -{ - /////////////////////////////////////////////////////////////////////////// - // Dispose Instance - spSkeleton_dispose(skeleton); - spAnimationState_dispose(state); - - /////////////////////////////////////////////////////////////////////////// - // Dispose Global - spAnimationStateData_dispose(stateData); - spSkeletonData_dispose(skeletonData); - spAtlas_dispose(atlas); -} - - -////////////////////////////////////////////////////////////////////////// -// Reproduce Memory leak as described in Issue #776 -// https://github.com/EsotericSoftware/spine-runtimes/issues/776 -void MemoryTestFixture::reproduceIssue_776() -{ - spAtlas* atlas = 0; - spSkeletonData* skeletonData = 0; - spAnimationStateData* stateData = 0; - spSkeleton* skeleton = 0; - spAnimationState* state = 0; - - ////////////////////////////////////////////////////////////////////////// - // Initialize Animations - LoadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); - - /////////////////////////////////////////////////////////////////////////// - // Run animation - spSkeleton_setToSetupPose(skeleton); - InterruptMonitor eventMonitor(state); - //eventMonitor.SetDebugLogging(true); - - // Interrupt the animation on this specific sequence of spEventType(s) - eventMonitor - .AddInterruptEvent(SP_ANIMATION_INTERRUPT, "jump") - .AddInterruptEvent(SP_ANIMATION_START); - - spAnimationState_setAnimationByName(state, 0, "walk", true); - spAnimationState_addAnimationByName(state, 0, "jump", false, 0.0f); - spAnimationState_addAnimationByName(state, 0, "run", true, 0.0f); - spAnimationState_addAnimationByName(state, 0, "jump", false, 3.0f); - spAnimationState_addAnimationByName(state, 0, "walk", true, 0.0f); - spAnimationState_addAnimationByName(state, 0, "idle", false, 1.0f); - - for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) { - const float timeSlice = 1.0f / 60.0f; - spSkeleton_update(skeleton, timeSlice); - spAnimationState_update(state, timeSlice); - spAnimationState_apply(state, skeleton); - } - - ////////////////////////////////////////////////////////////////////////// - // Cleanup Animations - DisposeAll(skeleton, state, stateData, skeletonData, atlas); -} - -void MemoryTestFixture::reproduceIssue_777() -{ - spAtlas* atlas = 0; - spSkeletonData* skeletonData = 0; - spAnimationStateData* stateData = 0; - spSkeleton* skeleton = 0; - spAnimationState* state = 0; - - ////////////////////////////////////////////////////////////////////////// - // Initialize Animations - LoadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); - - /////////////////////////////////////////////////////////////////////////// - // Run animation - spSkeleton_setToSetupPose(skeleton); - SpineEventMonitor eventMonitor(state); - //eventMonitor.SetDebugLogging(true); - - // Set Animation and Play for 5 frames - spAnimationState_setAnimationByName(state, 0, "walk", true); - for (int i = 0; i < 5; ++i) { - const float timeSlice = 1.0f / 60.0f; - spSkeleton_update(skeleton, timeSlice); - spAnimationState_update(state, timeSlice); - spAnimationState_apply(state, skeleton); - } - - // Change animation twice in a row - spAnimationState_setAnimationByName(state, 0, "walk", false); - spAnimationState_setAnimationByName(state, 0, "run", false); - - // run normal update - for (int i = 0; i < 5; ++i) { - const float timeSlice = 1.0f / 60.0f; - spSkeleton_update(skeleton, timeSlice); - spAnimationState_update(state, timeSlice); - spAnimationState_apply(state, skeleton); - } - - // Now we'd lose mixingFrom (the first "walk" entry we set above) and should leak - spAnimationState_setAnimationByName(state, 0, "run", false); - - ////////////////////////////////////////////////////////////////////////// - // Cleanup Animations - DisposeAll(skeleton, state, stateData, skeletonData, atlas); -} - -spSkeleton* skeleton = 0; -static void spineAnimStateHandler(spAnimationState* state, int type, spTrackEntry* entry, spEvent* event) -{ - if (type == SP_ANIMATION_COMPLETE) - { - spAnimationState_setAnimationByName(state, 0, "walk", false); - spAnimationState_update(state, 0); - spAnimationState_apply(state, skeleton); - } -} - -void MemoryTestFixture::reproduceIssue_Loop() -{ - spAtlas* atlas = 0; - spSkeletonData* skeletonData = 0; - spAnimationStateData* stateData = 0; - spAnimationState* state = 0; - - ////////////////////////////////////////////////////////////////////////// - // Initialize Animations - LoadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); - - /////////////////////////////////////////////////////////////////////////// - - if (state) - state->listener = (spAnimationStateListener)&spineAnimStateHandler; - - spAnimationState_setAnimationByName(state, 0, "walk", false); - - // run normal update - for (int i = 0; i < 50; ++i) { - const float timeSlice = 1.0f / 60.0f; - spSkeleton_update(skeleton, timeSlice); - spAnimationState_update(state, timeSlice); - spAnimationState_apply(state, skeleton); - } - - DisposeAll(skeleton, state, stateData, skeletonData, atlas); -} - -void MemoryTestFixture::triangulator() { - spTriangulator* triangulator = spTriangulator_create(); - spFloatArray* polygon = spFloatArray_create(16); - spFloatArray_add(polygon, 0); - spFloatArray_add(polygon, 0); - spFloatArray_add(polygon, 100); - spFloatArray_add(polygon, 0); - spFloatArray_add(polygon, 100); - spFloatArray_add(polygon, 100); - spFloatArray_add(polygon, 0); - spFloatArray_add(polygon, 100); - - spShortArray* triangles = spTriangulator_triangulate(triangulator, polygon); - ASSERT(triangles->size == 6); - ASSERT(triangles->items[0] == 3); - ASSERT(triangles->items[1] == 0); - ASSERT(triangles->items[2] == 1); - ASSERT(triangles->items[3] == 3); - ASSERT(triangles->items[4] == 1); - ASSERT(triangles->items[5] == 2); - - spArrayFloatArray* polys = spTriangulator_decompose(triangulator, polygon, triangles); - ASSERT(polys->size == 1); - ASSERT(polys->items[0]->size == 8); - ASSERT(polys->items[0]->items[0] == 0); - ASSERT(polys->items[0]->items[1] == 100); - ASSERT(polys->items[0]->items[2] == 0); - ASSERT(polys->items[0]->items[3] == 0); - ASSERT(polys->items[0]->items[4] == 100); - ASSERT(polys->items[0]->items[5] == 0); - ASSERT(polys->items[0]->items[6] == 100); - ASSERT(polys->items[0]->items[7] == 100); - - spFloatArray_dispose(polygon); - spTriangulator_dispose(triangulator); -} - -void MemoryTestFixture::skeletonClipper() { - spSkeletonClipping* clipping = spSkeletonClipping_create(); - - spBoneData* boneData = spBoneData_create(0, "bone", 0); - spBone* bone = spBone_create(boneData, 0, 0); - CONST_CAST(float, bone->a) = 1; - CONST_CAST(float, bone->b) = 0; - CONST_CAST(float, bone->c) = 0; - CONST_CAST(float, bone->d) = 1; - CONST_CAST(float, bone->worldX) = 0; - CONST_CAST(float, bone->worldY) = 0; - spSlotData* slotData = spSlotData_create(0, "slot", 0); - spSlot* slot = spSlot_create(slotData, bone); - spClippingAttachment* clip = spClippingAttachment_create("clipping"); - clip->endSlot = slotData; - clip->super.worldVerticesLength = 4 * 2; - clip->super.verticesCount = 4; - clip->super.vertices = MALLOC(float, 4 * 8); - clip->super.vertices[0] = 0; - clip->super.vertices[1] = 50; - clip->super.vertices[2] = 100; - clip->super.vertices[3] = 50; - clip->super.vertices[4] = 100; - clip->super.vertices[5] = 70; - clip->super.vertices[6] = 0; - clip->super.vertices[7] = 70; - - spSkeletonClipping_clipStart(clipping, slot, clip); - - spFloatArray* vertices = spFloatArray_create(16); - spFloatArray_add(vertices, 0); - spFloatArray_add(vertices, 0); - spFloatArray_add(vertices, 100); - spFloatArray_add(vertices, 0); - spFloatArray_add(vertices, 50); - spFloatArray_add(vertices, 150); - spFloatArray* uvs = spFloatArray_create(16); - spFloatArray_add(uvs, 0); - spFloatArray_add(uvs, 0); - spFloatArray_add(uvs, 1); - spFloatArray_add(uvs, 0); - spFloatArray_add(uvs, 0.5f); - spFloatArray_add(uvs, 1); - spUnsignedShortArray* indices = spUnsignedShortArray_create(16); - spUnsignedShortArray_add(indices, 0); - spUnsignedShortArray_add(indices, 1); - spUnsignedShortArray_add(indices, 2); - - spSkeletonClipping_clipTriangles(clipping, vertices->items, vertices->size, indices->items, indices->size, uvs->items, 2); - - float expectedVertices[8] = { 83.333328, 50.000000, 76.666664, 70.000000, 23.333334, 70.000000, 16.666672, 50.000000 }; - ASSERT(clipping->clippedVertices->size == 8); - for (int i = 0; i < clipping->clippedVertices->size; i++) { - ASSERT(ABS(clipping->clippedVertices->items[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->clippedUVs->size == 8); - for (int i = 0; i < clipping->clippedUVs->size; i++) { - ASSERT(ABS(clipping->clippedUVs->items[i] - expectedUVs[i]) < 0.001); - } - - short expectedIndices[6] = { 0, 1, 2, 0, 2, 3 }; - ASSERT(clipping->clippedTriangles->size == 6); - for (int i = 0; i < clipping->clippedTriangles->size; i++) { - ASSERT(clipping->clippedTriangles->items[i] == expectedIndices[i]); - } - - spFloatArray_dispose(vertices); - spFloatArray_dispose(uvs); - spUnsignedShortArray_dispose(indices); - - spSlotData_dispose(slotData); - spSlot_dispose(slot); - spBoneData_dispose(boneData); - spBone_dispose(bone); - _spClippingAttachment_dispose(SUPER(SUPER(clip))); - spSkeletonClipping_dispose(clipping); -} - - - diff --git a/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.h b/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.h index f45c35c86..e69de29bb 100755 --- a/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.h +++ b/spine-cpp/spine-cpp-unit-tests/tests/MemoryTestFixture.h @@ -1,50 +0,0 @@ -////////////////////////////////////////////////////////////////////// -// filename: MemoryTestFixture.h -// -// purpose: Reproduce Memory Error/Leak Bugs to help debug -// and for regression testing -///////////////////////////////////////////////////////////////////// - -#pragma once -#include "MiniCppUnit.hxx" -#include "TestOptions.h" - -class MemoryTestFixture : public TestFixture < MemoryTestFixture > -{ -public: - TEST_FIXTURE(MemoryTestFixture){ - - // Comment out here to disable individual test cases - TEST_CASE(reproduceIssue_776); - TEST_CASE(reproduceIssue_777); - TEST_CASE(reproduceIssue_Loop); - TEST_CASE(triangulator); - TEST_CASE(skeletonClipper); - - initialize(); - } - - virtual ~MemoryTestFixture(); - - ////////////////////////////////////////////////////////////////////////// - // Test Cases - ////////////////////////////////////////////////////////////////////////// -public: - void reproduceIssue_776(); - void reproduceIssue_777(); - void reproduceIssue_Loop(); // http://esotericsoftware.com/forum/spine-c-3-5-animation-jerking-7451 - void triangulator(); - void skeletonClipper(); - - ////////////////////////////////////////////////////////////////////////// - // test fixture setup - ////////////////////////////////////////////////////////////////////////// - void initialize(); - void finalize(); -public: - virtual void setUp(); - virtual void tearDown(); -}; -#if defined(gForceAllTests) || defined(gMemoryTestFixture) -REGISTER_FIXTURE(MemoryTestFixture); -#endif \ No newline at end of file diff --git a/spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test/SimpleTest.h b/spine-cpp/spine-cpp-unit-tests/tests/SimpleTest.h similarity index 100% rename from spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test/SimpleTest.h rename to spine-cpp/spine-cpp-unit-tests/tests/SimpleTest.h diff --git a/spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test/main.cpp b/spine-cpp/spine-cpp-unit-tests/tests/main.cpp similarity index 100% rename from spine-cpp/spine-cpp-unit-tests/spine_unit_test/spine_unit_test/main.cpp rename to spine-cpp/spine-cpp-unit-tests/tests/main.cpp diff --git a/spine-cpp/spine-cpp/include/spine/Animation.h b/spine-cpp/spine-cpp/include/spine/Animation.h index 6713fd6b2..1f430a0fe 100644 --- a/spine-cpp/spine-cpp/include/spine/Animation.h +++ b/spine-cpp/spine-cpp/include/spine/Animation.h @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -42,7 +43,7 @@ namespace Spine { class Skeleton; class Event; - class Animation { + class Animation : public SpineObject { friend class AnimationState; friend class TrackEntry; friend class AnimationStateData; diff --git a/spine-cpp/spine-cpp/include/spine/AnimationState.h b/spine-cpp/spine-cpp/include/spine/AnimationState.h index 404193400..4beca5437 100644 --- a/spine-cpp/spine-cpp/include/spine/AnimationState.h +++ b/spine-cpp/spine-cpp/include/spine/AnimationState.h @@ -34,6 +34,7 @@ #include #include #include +#include namespace Spine { enum EventType { @@ -57,7 +58,7 @@ namespace Spine { typedef void (*OnAnimationEventFunc) (AnimationState* state, EventType type, TrackEntry* entry, Event* event); /// State for the playback of an animation - class TrackEntry { + class TrackEntry : public SpineObject { friend class EventQueue; friend class AnimationState; @@ -238,7 +239,7 @@ namespace Spine { void reset(); }; - class EventQueueEntry { + class EventQueueEntry : public SpineObject { friend class EventQueue; public: @@ -249,7 +250,7 @@ namespace Spine { EventQueueEntry(EventType eventType, TrackEntry* trackEntry, Event* event = NULL); }; - class EventQueue { + class EventQueue : public SpineObject { friend class AnimationState; private: @@ -282,7 +283,7 @@ namespace Spine { void drain(); }; - class AnimationState { + class AnimationState : public SpineObject { friend class TrackEntry; friend class EventQueue; diff --git a/spine-cpp/spine-cpp/include/spine/AnimationStateData.h b/spine-cpp/spine-cpp/include/spine/AnimationStateData.h index 1ce86ca26..c0735b346 100644 --- a/spine-cpp/spine-cpp/include/spine/AnimationStateData.h +++ b/spine-cpp/spine-cpp/include/spine/AnimationStateData.h @@ -32,6 +32,7 @@ #define Spine_AnimationStateData_h #include +#include #include #include @@ -41,7 +42,7 @@ namespace Spine { class Animation; /// Stores mix (crossfade) durations to be applied when AnimationState animations are changed. - class AnimationStateData { + class AnimationStateData : public SpineObject { friend class AnimationState; public: @@ -68,7 +69,7 @@ namespace Spine { float getMix(Animation* from, Animation* to); private: - class AnimationPair { + class AnimationPair : public SpineObject { public: Animation* _a1; Animation* _a2; @@ -78,7 +79,7 @@ namespace Spine { bool operator==(const AnimationPair &other) const; }; - struct HashAnimationPair { + struct HashAnimationPair : public SpineObject { std::size_t operator()(const Spine::AnimationStateData::AnimationPair& val) const; }; diff --git a/spine-cpp/spine-cpp/include/spine/Atlas.h b/spine-cpp/spine-cpp/include/spine/Atlas.h index 1fc1afbee..d6d5dfad9 100644 --- a/spine-cpp/spine-cpp/include/spine/Atlas.h +++ b/spine-cpp/spine-cpp/include/spine/Atlas.h @@ -33,6 +33,7 @@ #include #include +#include #include @@ -63,7 +64,7 @@ namespace Spine { TextureWrap_Repeat }; - class AtlasPage { + class AtlasPage : public SpineObject { public: std::string name; Format format; @@ -77,7 +78,7 @@ namespace Spine { AtlasPage(std::string inName) : name(inName) {} }; - class AtlasRegion { + class AtlasRegion : public SpineObject { public: AtlasPage* page; std::string name; @@ -93,7 +94,7 @@ namespace Spine { class TextureLoader; - class Atlas { + class Atlas : SpineObject { public: Atlas(const char* path, TextureLoader& textureLoader); diff --git a/spine-cpp/spine-cpp/include/spine/AtlasAttachmentLoader.h b/spine-cpp/spine-cpp/include/spine/AtlasAttachmentLoader.h index a43f245db..9132ac1aa 100644 --- a/spine-cpp/spine-cpp/include/spine/AtlasAttachmentLoader.h +++ b/spine-cpp/spine-cpp/include/spine/AtlasAttachmentLoader.h @@ -32,9 +32,9 @@ #define Spine_AtlasAttachmentLoader_h #include - #include + namespace Spine { class Atlas; class AtlasRegion; @@ -47,7 +47,7 @@ namespace Spine { RTTI_DECL; public: - AtlasAttachmentLoader(Vector& inAtlasArray); + AtlasAttachmentLoader(Atlas& atlas); virtual RegionAttachment* newRegionAttachment(Skin& skin, std::string name, std::string path); @@ -64,7 +64,7 @@ namespace Spine { AtlasRegion* findRegion(std::string name); private: - Vector _atlasArray; + Atlas& _atlas; }; } diff --git a/spine-cpp/spine-cpp/include/spine/Attachment.h b/spine-cpp/spine-cpp/include/spine/Attachment.h index 8054e4d23..332d4f847 100644 --- a/spine-cpp/spine-cpp/include/spine/Attachment.h +++ b/spine-cpp/spine-cpp/include/spine/Attachment.h @@ -32,11 +32,11 @@ #define Spine_Attachment_h #include - +#include #include namespace Spine { - class Attachment { + class Attachment : public SpineObject { RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/AttachmentLoader.h b/spine-cpp/spine-cpp/include/spine/AttachmentLoader.h index 07eb4fdfb..f5e45bbe9 100644 --- a/spine-cpp/spine-cpp/include/spine/AttachmentLoader.h +++ b/spine-cpp/spine-cpp/include/spine/AttachmentLoader.h @@ -32,7 +32,7 @@ #define Spine_AttachmentLoader_h #include - +#include #include namespace Spine { @@ -44,7 +44,7 @@ namespace Spine { class PointAttachment; class ClippingAttachment; - class AttachmentLoader { + class AttachmentLoader : public SpineObject { RTTI_DECL; AttachmentLoader(); diff --git a/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h b/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h index f81586ccb..68b4d0a7c 100644 --- a/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/AttachmentTimeline.h @@ -32,7 +32,7 @@ #define Spine_AttachmentTimeline_h #include - +#include #include #include #include diff --git a/spine-cpp/spine-cpp/include/spine/Bone.h b/spine-cpp/spine-cpp/include/spine/Bone.h index d2e876f8c..f87c4f5aa 100644 --- a/spine-cpp/spine-cpp/include/spine/Bone.h +++ b/spine-cpp/spine-cpp/include/spine/Bone.h @@ -32,7 +32,7 @@ #define Spine_Bone_h #include - +#include #include namespace Spine { diff --git a/spine-cpp/spine-cpp/include/spine/BoneData.h b/spine-cpp/spine-cpp/include/spine/BoneData.h index 12b060f3f..358d466be 100644 --- a/spine-cpp/spine-cpp/include/spine/BoneData.h +++ b/spine-cpp/spine-cpp/include/spine/BoneData.h @@ -32,11 +32,11 @@ #define Spine_BoneData_h #include - +#include #include namespace Spine { - class BoneData { + class BoneData : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; diff --git a/spine-cpp/spine-cpp/include/spine/BoundingBoxAttachment.h b/spine-cpp/spine-cpp/include/spine/BoundingBoxAttachment.h index d0a707ed2..e79b1e8e9 100644 --- a/spine-cpp/spine-cpp/include/spine/BoundingBoxAttachment.h +++ b/spine-cpp/spine-cpp/include/spine/BoundingBoxAttachment.h @@ -32,6 +32,7 @@ #define Spine_BoundingBoxAttachment_h #include +#include namespace Spine { /// Attachment that has a polygon for bounds checking. diff --git a/spine-cpp/spine-cpp/include/spine/ContainerUtil.h b/spine-cpp/spine-cpp/include/spine/ContainerUtil.h index 3e764aeb3..862f2fd0a 100644 --- a/spine-cpp/spine-cpp/include/spine/ContainerUtil.h +++ b/spine-cpp/spine-cpp/include/spine/ContainerUtil.h @@ -34,12 +34,13 @@ #include #include #include +#include #include #include namespace Spine { - class ContainerUtil { + class ContainerUtil : public SpineObject { public: /// Finds an item by comparing each item's name. /// It is more efficient to cache the results of this method than to call it multiple times. @@ -110,7 +111,7 @@ namespace Spine { for (size_t i = 0; i < items.size(); ) { T* item = items[i]; - DESTROY(T, item); + delete item; items.erase(i); } diff --git a/spine-cpp/spine-cpp/include/spine/Event.h b/spine-cpp/spine-cpp/include/spine/Event.h index 179c74028..27aeba910 100644 --- a/spine-cpp/spine-cpp/include/spine/Event.h +++ b/spine-cpp/spine-cpp/include/spine/Event.h @@ -31,13 +31,15 @@ #ifndef Spine_Event_h #define Spine_Event_h +#include + #include namespace Spine { class EventData; /// Stores the current pose values for an Event. - class Event { + class Event : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; friend class AnimationState; diff --git a/spine-cpp/spine-cpp/include/spine/EventData.h b/spine-cpp/spine-cpp/include/spine/EventData.h index 691c5acbf..479dd1370 100644 --- a/spine-cpp/spine-cpp/include/spine/EventData.h +++ b/spine-cpp/spine-cpp/include/spine/EventData.h @@ -31,11 +31,13 @@ #ifndef Spine_EventData_h #define Spine_EventData_h +#include + #include namespace Spine { /// Stores the setup pose values for an Event. - class EventData { + class EventData : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; friend class Event; diff --git a/spine-cpp/spine-cpp/include/spine/Extension.h b/spine-cpp/spine-cpp/include/spine/Extension.h index 752d445e0..bf38862d4 100644 --- a/spine-cpp/spine-cpp/include/spine/Extension.h +++ b/spine-cpp/spine-cpp/include/spine/Extension.h @@ -33,42 +33,64 @@ #include -#define SPINE_EXTENSION (SpineExtension::getInstance()) +// #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((void*)VALUE) +// #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((void*)VALUE) +// #define DESTROY(TYPE,VALUE) VALUE->~TYPE(); SPINE_EXTENSION->spinefree(VALUE) namespace Spine { class SpineExtension { public: + template static T* alloc(size_t num, const char* file, int line) { + return (T*)getInstance()->_alloc(sizeof(T) * num, file, line); + } + + template static T* calloc(size_t num, const char* file, int line) { + return (T*)getInstance()->_calloc(sizeof(T) * num, file, line); + } + + template static T* realloc(T* ptr, size_t num, const char* file, int line) { + return (T*)getInstance()->_realloc(ptr, sizeof(T) * num, file, line); + } + + template static void free(T* ptr) { + getInstance()->_free((void*)ptr); + } + + static char* readFile(const char* path, int* length) { + return getInstance()->_readFile(path, length); + } + static void setInstance(SpineExtension* inSpineExtension); - + static SpineExtension* getInstance(); - + virtual ~SpineExtension(); - + + protected: /// Implement this function to use your own memory allocator - virtual void* spineAlloc(size_t size, const char* file, int line) = 0; + virtual void* _alloc(size_t size, const char* file, int line) = 0; - virtual void* spineCalloc(size_t num, size_t size, const char* file, int line) = 0; + virtual void* _calloc(size_t size, const char* file, int line) = 0; - virtual void* spineRealloc(void* ptr, size_t size, const char* file, int line) = 0; + 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 spineFree(void* mem) = 0; + virtual void _free(void* mem) = 0; - virtual char* spineReadFile(const char* path, int* length); - - protected: + virtual char* _readFile(const char* path, int* length); + SpineExtension(); private: @@ -77,19 +99,17 @@ namespace Spine { class DefaultSpineExtension : public SpineExtension { public: - static DefaultSpineExtension* getInstance(); - virtual ~DefaultSpineExtension(); - - 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: + 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); + DefaultSpineExtension(); }; } diff --git a/spine-cpp/spine-cpp/include/spine/HashMap.h b/spine-cpp/spine-cpp/include/spine/HashMap.h index 07a9b2ef3..1beb41c62 100755 --- a/spine-cpp/spine-cpp/include/spine/HashMap.h +++ b/spine-cpp/spine-cpp/include/spine/HashMap.h @@ -33,15 +33,16 @@ #include #include +#include namespace Spine { template - class HashMap { + class HashMap : public SpineObject { private: class Entry; public: - class Iterator { + class Iterator : public SpineObject { friend class HashMap; public: @@ -129,8 +130,7 @@ namespace Spine { size_t index = hash(key); - Entry* entry = NEW(Entry); - new (entry) Entry(); + Entry* entry = new Entry(); entry->_key = key; entry->_value = value; @@ -222,7 +222,7 @@ namespace Spine { pos._entry->next->prev = pos._entry->prev; } - DESTROY(Entry, pos._entry); + delete pos._entry; } else if (_hashTable[index].next == pos._entry) { _hashTable[index].next = pos._entry->next; @@ -235,7 +235,7 @@ namespace Spine { pos._entry->next->prev = pos._entry->prev; } - DESTROY(Entry, pos._entry); + delete pos._entry; } else if (_hashTable[index].prev == pos._entry) { _hashTable[index].prev = pos._entry->prev; @@ -248,13 +248,13 @@ namespace Spine { pos._entry->next->prev = pos._entry->prev; } - DESTROY(Entry, pos._entry); + delete pos._entry; } else { pos._entry->prev->next = pos._entry->next; pos._entry->next->prev = pos._entry->prev; - DESTROY(Entry, pos._entry); + delete pos._entry; } _hashSize--; @@ -276,7 +276,7 @@ namespace Spine { } private: - class Entry { + class Entry : public SpineObject { public: K _key; V _value; diff --git a/spine-cpp/spine-cpp/include/spine/IkConstraintData.h b/spine-cpp/spine-cpp/include/spine/IkConstraintData.h index 119563d2a..cd6f0fbbb 100644 --- a/spine-cpp/spine-cpp/include/spine/IkConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/IkConstraintData.h @@ -32,13 +32,14 @@ #define Spine_IkConstraintData_h #include +#include #include namespace Spine { class BoneData; - class IkConstraintData { + class IkConstraintData : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; friend class IkConstraint; diff --git a/spine-cpp/spine-cpp/include/spine/Json.h b/spine-cpp/spine-cpp/include/spine/Json.h index 083e22322..f99c73046 100644 --- a/spine-cpp/spine-cpp/include/spine/Json.h +++ b/spine-cpp/spine-cpp/include/spine/Json.h @@ -31,13 +31,15 @@ #ifndef Spine_Json_h #define Spine_Json_h +#include + #ifndef SPINE_JSON_HAVE_PREV /* Spine doesn't use the "prev" link in the Json sibling lists. */ #define SPINE_JSON_HAVE_PREV 0 #endif namespace Spine { - class Json { + class Json : public SpineObject { friend class SkeletonJson; public: diff --git a/spine-cpp/spine-cpp/include/spine/LinkedMesh.h b/spine-cpp/spine-cpp/include/spine/LinkedMesh.h index f8fde0944..ef838aee8 100644 --- a/spine-cpp/spine-cpp/include/spine/LinkedMesh.h +++ b/spine-cpp/spine-cpp/include/spine/LinkedMesh.h @@ -31,12 +31,14 @@ #ifndef Spine_LinkedMesh_h #define Spine_LinkedMesh_h +#include + #include namespace Spine { class MeshAttachment; - class LinkedMesh { + class LinkedMesh : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; diff --git a/spine-cpp/spine-cpp/include/spine/MathUtil.h b/spine-cpp/spine-cpp/include/spine/MathUtil.h index cd7d32f42..ffbb69ae9 100644 --- a/spine-cpp/spine-cpp/include/spine/MathUtil.h +++ b/spine-cpp/spine-cpp/include/spine/MathUtil.h @@ -31,6 +31,8 @@ #ifndef Spine_MathUtil_h #define Spine_MathUtil_h +#include + #include #include @@ -78,7 +80,7 @@ namespace Spine { return fminf(upper, fmaxf(x, lower)); } - class MathUtil { + class MathUtil : public SpineObject { public: MathUtil(); diff --git a/spine-cpp/spine-cpp/include/spine/PathConstraintData.h b/spine-cpp/spine-cpp/include/spine/PathConstraintData.h index c4e3812e5..01e3277e9 100644 --- a/spine-cpp/spine-cpp/include/spine/PathConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/PathConstraintData.h @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -42,7 +43,7 @@ namespace Spine { class BoneData; class SlotData; - class PathConstraintData { + class PathConstraintData : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; diff --git a/spine-cpp/spine-cpp/include/spine/Pool.h b/spine-cpp/spine-cpp/include/spine/Pool.h index 18f17a6e9..43aa0651e 100644 --- a/spine-cpp/spine-cpp/include/spine/Pool.h +++ b/spine-cpp/spine-cpp/include/spine/Pool.h @@ -34,10 +34,11 @@ #include #include #include +#include namespace Spine { template - class Pool { + class Pool : public SpineObject { public: Pool() { // Empty @@ -56,8 +57,7 @@ namespace Spine { return ret; } else { - T* ret = NEW(T); - new (ret) T(); + T* ret = new T(); return ret; } diff --git a/spine-cpp/spine-cpp/include/spine/RTTI.h b/spine-cpp/spine-cpp/include/spine/RTTI.h index 73db676cc..3ec312b16 100644 --- a/spine-cpp/spine-cpp/include/spine/RTTI.h +++ b/spine-cpp/spine-cpp/include/spine/RTTI.h @@ -31,10 +31,11 @@ #ifndef Spine_RTTI_h #define Spine_RTTI_h +#include #include namespace Spine { - class RTTI { + class RTTI : public SpineObject { public: RTTI(const std::string& className); diff --git a/spine-cpp/spine-cpp/include/spine/Skeleton.h b/spine-cpp/spine-cpp/include/spine/Skeleton.h index 8efd439a3..11232f5de 100644 --- a/spine-cpp/spine-cpp/include/spine/Skeleton.h +++ b/spine-cpp/spine-cpp/include/spine/Skeleton.h @@ -33,6 +33,7 @@ #include #include +#include #include #include // std::numeric_limits @@ -48,7 +49,7 @@ namespace Spine { class Skin; class Attachment; - class Skeleton { + class Skeleton : public SpineObject { friend class AnimationState; friend class SkeletonBounds; friend class SkeletonClipping; diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h b/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h index 17749fca4..a38ec122b 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h @@ -33,6 +33,7 @@ #include #include +#include #include @@ -47,7 +48,7 @@ namespace Spine { class Animation; class CurveTimeline; - class SkeletonBinary { + class SkeletonBinary : public SpineObject { public: static const int BONE_ROTATE; static const int BONE_TRANSLATE; @@ -68,7 +69,7 @@ namespace Spine { static const TransformMode TRANSFORM_MODE_VALUES[5]; - SkeletonBinary(Vector& atlasArray); + SkeletonBinary(Atlas& atlasArray); SkeletonBinary(AttachmentLoader* attachmentLoader); @@ -79,7 +80,7 @@ namespace Spine { SkeletonData* readSkeletonDataFile(const char* path); private: - struct DataInput { + struct DataInput : public SpineObject { const unsigned char* cursor; const unsigned char* end; }; diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonBounds.h b/spine-cpp/spine-cpp/include/spine/SkeletonBounds.h index 983600835..b96d72568 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonBounds.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonBounds.h @@ -32,6 +32,7 @@ #define Spine_SkeletonBounds_h #include +#include namespace Spine { class Skeleton; @@ -43,7 +44,7 @@ namespace Spine { /// Collects each BoundingBoxAttachment that is visible and computes the world vertices for its polygon. /// The polygon vertices are provided along with convenience methods for doing hit detection. /// - class SkeletonBounds { + class SkeletonBounds : public SpineObject { public: SkeletonBounds(); @@ -94,7 +95,7 @@ namespace Spine { void aabbCompute(); }; - class Polygon { + class Polygon : public SpineObject { public: Vector _vertices; int _count; diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonClipping.h b/spine-cpp/spine-cpp/include/spine/SkeletonClipping.h index 6d5667517..cbfb65af8 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonClipping.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonClipping.h @@ -38,7 +38,7 @@ namespace Spine { class Slot; class ClippingAttachment; - class SkeletonClipping { + class SkeletonClipping : public SpineObject { public: SkeletonClipping(); diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonData.h b/spine-cpp/spine-cpp/include/spine/SkeletonData.h index 53065ade0..a6002da36 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonData.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonData.h @@ -46,7 +46,7 @@ namespace Spine { class PathConstraintData; /// Stores the setup pose and all of the stateless data for a skeleton. - class SkeletonData { + class SkeletonData : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; friend class Skeleton; diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonJson.h b/spine-cpp/spine-cpp/include/spine/SkeletonJson.h index ef40a7a83..117ed4919 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonJson.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonJson.h @@ -32,6 +32,7 @@ #define Spine_SkeletonJson_h #include +#include #include @@ -45,9 +46,9 @@ namespace Spine { class AttachmentLoader; class LinkedMesh; - class SkeletonJson { + class SkeletonJson : public SpineObject { public: - SkeletonJson(Vector& atlasArray); + SkeletonJson(Atlas& atlas); SkeletonJson(AttachmentLoader* attachmentLoader); diff --git a/spine-cpp/spine-cpp/include/spine/Skin.h b/spine-cpp/spine-cpp/include/spine/Skin.h index 5756b65d3..57c69de42 100644 --- a/spine-cpp/spine-cpp/include/spine/Skin.h +++ b/spine-cpp/spine-cpp/include/spine/Skin.h @@ -42,11 +42,11 @@ namespace Spine { /// Stores attachments by slot index and attachment name. /// See SkeletonData::getDefaultSkin, Skeleton::getSkin, and /// http://esotericsoftware.com/spine-runtime-skins in the Spine Runtimes Guide. - class Skin { + class Skin : public SpineObject { friend class Skeleton; public: - class AttachmentKey { + class AttachmentKey : public SpineObject { public: int _slotIndex; std::string _name; @@ -56,7 +56,7 @@ namespace Spine { bool operator==(const AttachmentKey &other) const; }; - struct HashAttachmentKey { + struct HashAttachmentKey : public SpineObject { std::size_t operator()(const Spine::Skin::AttachmentKey& val) const; }; diff --git a/spine-cpp/spine-cpp/include/spine/Slot.h b/spine-cpp/spine-cpp/include/spine/Slot.h index 69f7f6666..ae5019451 100644 --- a/spine-cpp/spine-cpp/include/spine/Slot.h +++ b/spine-cpp/spine-cpp/include/spine/Slot.h @@ -32,6 +32,7 @@ #define Spine_Slot_h #include +#include #include @@ -41,7 +42,7 @@ namespace Spine { class Skeleton; class Attachment; - class Slot { + class Slot : public SpineObject { friend class VertexAttachment; friend class Skeleton; friend class SkeletonBounds; diff --git a/spine-cpp/spine-cpp/include/spine/SlotData.h b/spine-cpp/spine-cpp/include/spine/SlotData.h index 6e422e534..992b496e6 100644 --- a/spine-cpp/spine-cpp/include/spine/SlotData.h +++ b/spine-cpp/spine-cpp/include/spine/SlotData.h @@ -32,13 +32,14 @@ #define Spine_SlotData_h #include +#include #include namespace Spine { class BoneData; - class SlotData { + class SlotData : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; diff --git a/spine-sfml/src/spine/spine-sfml.h b/spine-cpp/spine-cpp/include/spine/SpineObject.h similarity index 60% rename from spine-sfml/src/spine/spine-sfml.h rename to spine-cpp/spine-cpp/include/spine/SpineObject.h index 1b8f89a2d..45d987770 100644 --- a/spine-sfml/src/spine/spine-sfml.h +++ b/spine-cpp/spine-cpp/include/spine/SpineObject.h @@ -1,73 +1,45 @@ -/****************************************************************************** - * 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_SFML_H_ -#define SPINE_SFML_H_ - -#include -#include -#include -#include -#include -#include -#include - -_SP_ARRAY_DECLARE_TYPE(spColorArray, spColor) - -namespace spine { - -class SkeletonDrawable: public sf::Drawable { -public: - spSkeleton* skeleton; - spAnimationState* state; - float timeScale; - sf::VertexArray* vertexArray; - spVertexEffect* vertexEffect; - - SkeletonDrawable (spSkeletonData* skeleton, spAnimationStateData* stateData = 0); - ~SkeletonDrawable (); - - void update (float deltaTime); - - virtual void draw (sf::RenderTarget& target, sf::RenderStates states) const; - - void setUsePremultipliedAlpha(bool usePMA) { usePremultipliedAlpha = usePMA; }; - bool getUsePremultipliedAlpha() { return usePremultipliedAlpha; }; -private: - bool ownsAnimationStateData; - float* worldVertices; - spFloatArray* tempUvs; - spColorArray* tempColors; - spSkeletonClipping* clipper; - bool usePremultipliedAlpha; -}; - -} /* namespace spine */ -#endif /* SPINE_SFML_H_ */ +/****************************************************************************** + * 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_Object_h +#define Spine_Object_h + +#include + +namespace Spine { + class SpineObject { + public: + void* operator new(size_t sz); + void* operator new(size_t sz, void* p); + void operator delete(void* p); + }; +} + +#endif \ No newline at end of file diff --git a/spine-cpp/spine-cpp/include/spine/TextureLoader.h b/spine-cpp/spine-cpp/include/spine/TextureLoader.h index f0b836910..54c32889a 100644 --- a/spine-cpp/spine-cpp/include/spine/TextureLoader.h +++ b/spine-cpp/spine-cpp/include/spine/TextureLoader.h @@ -31,12 +31,14 @@ #ifndef Spine_TextureLoader_h #define Spine_TextureLoader_h +#include + #include namespace Spine { class AtlasPage; - class TextureLoader { + class TextureLoader : public SpineObject { public: TextureLoader(); diff --git a/spine-cpp/spine-cpp/include/spine/Timeline.h b/spine-cpp/spine-cpp/include/spine/Timeline.h index d23a36753..1d69ace46 100644 --- a/spine-cpp/spine-cpp/include/spine/Timeline.h +++ b/spine-cpp/spine-cpp/include/spine/Timeline.h @@ -35,12 +35,13 @@ #include #include #include +#include namespace Spine { class Skeleton; class Event; - class Timeline { + class Timeline : public SpineObject { RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h b/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h index 090675a31..4e27659b4 100644 --- a/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/TransformConstraintData.h @@ -32,13 +32,14 @@ #define Spine_TransformConstraintData_h #include +#include #include namespace Spine { class BoneData; - class TransformConstraintData { + class TransformConstraintData : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; diff --git a/spine-cpp/spine-cpp/include/spine/Triangulator.h b/spine-cpp/spine-cpp/include/spine/Triangulator.h index d5fff1994..60ce246ff 100644 --- a/spine-cpp/spine-cpp/include/spine/Triangulator.h +++ b/spine-cpp/spine-cpp/include/spine/Triangulator.h @@ -35,7 +35,7 @@ #include namespace Spine { - class Triangulator { + class Triangulator : public SpineObject { public: Vector& triangulate(Vector& vertices); diff --git a/spine-cpp/spine-cpp/include/spine/Updatable.h b/spine-cpp/spine-cpp/include/spine/Updatable.h index d076e0439..7d831af6f 100644 --- a/spine-cpp/spine-cpp/include/spine/Updatable.h +++ b/spine-cpp/spine-cpp/include/spine/Updatable.h @@ -32,9 +32,10 @@ #define Spine_Updatable_h #include +#include namespace Spine { - class Updatable { + class Updatable : public SpineObject { RTTI_DECL; public: diff --git a/spine-cpp/spine-cpp/include/spine/Vector.h b/spine-cpp/spine-cpp/include/spine/Vector.h index 6fad04736..17fb7bc13 100644 --- a/spine-cpp/spine-cpp/include/spine/Vector.h +++ b/spine-cpp/spine-cpp/include/spine/Vector.h @@ -32,6 +32,7 @@ #define Spine_Vector_h #include +#include #include #include @@ -39,7 +40,7 @@ namespace Spine { template - class Vector { + class Vector : public SpineObject { public: Vector() : _size(0), _capacity(0), _buffer(NULL) { // Empty @@ -157,7 +158,7 @@ namespace Spine { void reserve(size_t inCapacity = 0) { size_t newCapacity = inCapacity > 0 ? inCapacity : _capacity > 0 ? _capacity * 2 : 1; if (newCapacity > _capacity) { - _buffer = REALLOC(_buffer, T, newCapacity); + _buffer = (T*)SpineExtension::realloc(_buffer, newCapacity, __FILE__, __LINE__); _capacity = newCapacity; } } @@ -202,7 +203,7 @@ namespace Spine { T* allocate(size_t n) { assert(n > 0); - T* ptr = MALLOC(T, n); + T* ptr = (T*)SpineExtension::alloc(n, __FILE__, __LINE__); assert(ptr); @@ -211,7 +212,7 @@ namespace Spine { void deallocate(T* buffer) { if (_buffer) { - FREE(buffer); + SpineExtension::free(buffer); } } diff --git a/spine-cpp/spine-cpp/include/spine/Vertices.h b/spine-cpp/spine-cpp/include/spine/Vertices.h index 0dff1321d..a2ffd1325 100644 --- a/spine-cpp/spine-cpp/include/spine/Vertices.h +++ b/spine-cpp/spine-cpp/include/spine/Vertices.h @@ -34,7 +34,7 @@ #include namespace Spine { - class Vertices { + class Vertices : public SpineObject { public: Vector _bones; Vector _vertices; diff --git a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp index 9d0140b82..7bace3609 100644 --- a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp +++ b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp @@ -216,17 +216,11 @@ namespace Spine { } EventQueue* EventQueue::newEventQueue(AnimationState& state, Pool& trackEntryPool) { - EventQueue* ret = NEW(EventQueue); - new (ret) EventQueue(state, trackEntryPool); - - return ret; + return new EventQueue(state, trackEntryPool); } EventQueueEntry* EventQueue::newEventQueueEntry(EventType eventType, TrackEntry* entry, Event* event) { - EventQueueEntry* ret = NEW(EventQueueEntry); - new (ret) EventQueueEntry(eventType, entry, event); - - return ret; + return new EventQueueEntry(eventType, entry, event); } EventQueue::EventQueue(AnimationState& state, Pool& trackEntryPool) : _state(state), _trackEntryPool(trackEntryPool), _drainDisabled(false) { @@ -321,7 +315,7 @@ namespace Spine { } AnimationState::~AnimationState() { - DESTROY(EventQueue, _queue); + delete _queue; } void AnimationState::update(float delta) { diff --git a/spine-cpp/spine-cpp/src/spine/Atlas.cpp b/spine-cpp/spine-cpp/src/spine/Atlas.cpp index 01ddc728d..8fdab3fe3 100644 --- a/spine-cpp/spine-cpp/src/spine/Atlas.cpp +++ b/spine-cpp/spine-cpp/src/spine/Atlas.cpp @@ -49,17 +49,17 @@ namespace Spine { const char* lastSlash = lastForwardSlash > lastBackwardSlash ? lastForwardSlash : lastBackwardSlash; if (lastSlash == path) lastSlash++; /* Never drop starting slash. */ dirLength = (int)(lastSlash ? lastSlash - path : 0); - dir = MALLOC(char, dirLength + 1); + dir = SpineExtension::alloc(dirLength + 1, __FILE__, __LINE__); memcpy(dir, path, dirLength); dir[dirLength] = '\0'; - data = SPINE_EXTENSION->spineReadFile(path, &length); + data = SpineExtension::readFile(path, &length); if (data) { load(data, length, dir); } - FREE(data); - FREE(dir); + SpineExtension::free(data); + SpineExtension::free(dir); } Atlas::Atlas(const char* data, int length, const char* dir, TextureLoader& textureLoader) : _textureLoader(textureLoader) { @@ -116,17 +116,16 @@ namespace Spine { } else if (!page) { char* name = mallocString(&str); - char* path = MALLOC(char, dirLength + needsSlash + strlen(name) + 1); + char* path = SpineExtension::alloc(dirLength + needsSlash + strlen(name) + 1, __FILE__, __LINE__); memcpy(path, dir, dirLength); if (needsSlash) { path[dirLength] = '/'; } strcpy(path + dirLength + needsSlash, name); - page = NEW(AtlasPage); - new (page) AtlasPage(std::string(name)); + page = new AtlasPage(std::string(name)); - FREE(name); + SpineExtension::free(name); int tupleVal = readTuple(&begin, end, tuple); assert(tupleVal == 2); @@ -163,13 +162,12 @@ namespace Spine { _textureLoader.load(*page, std::string(path)); - FREE(path); + SpineExtension::free(path); _pages.push_back(page); } else { - AtlasRegion* region = NEW(AtlasRegion); - new (region) AtlasRegion(); + AtlasRegion* region = new AtlasRegion(); region->page = page; region->name = mallocString(&str); @@ -333,7 +331,7 @@ namespace Spine { char* Atlas::mallocString(Str* str) { int length = (int)(str->end - str->begin); - char* string = MALLOC(char, length + 1); + char* string = SpineExtension::alloc(length + 1, __FILE__, __LINE__); memcpy(string, str->begin, length); string[length] = '\0'; return string; diff --git a/spine-cpp/spine-cpp/src/spine/AtlasAttachmentLoader.cpp b/spine-cpp/spine-cpp/src/spine/AtlasAttachmentLoader.cpp index ada9bde71..fbc0ab18e 100644 --- a/spine-cpp/spine-cpp/src/spine/AtlasAttachmentLoader.cpp +++ b/spine-cpp/spine-cpp/src/spine/AtlasAttachmentLoader.cpp @@ -43,7 +43,7 @@ namespace Spine { RTTI_IMPL(AtlasAttachmentLoader, AttachmentLoader); - AtlasAttachmentLoader::AtlasAttachmentLoader(Vector& inAtlasArray) : AttachmentLoader(), _atlasArray(inAtlasArray) { + AtlasAttachmentLoader::AtlasAttachmentLoader(Atlas& atlas) : AttachmentLoader(), _atlas(atlas) { // Empty } @@ -53,8 +53,7 @@ namespace Spine { AtlasRegion& region = *regionP; - RegionAttachment* attachmentP = NEW(RegionAttachment); - new (attachmentP) RegionAttachment(name); + RegionAttachment* attachmentP = new RegionAttachment(name); RegionAttachment& attachment = *attachmentP; attachment._rendererObject = regionP; @@ -75,8 +74,7 @@ namespace Spine { AtlasRegion& region = *regionP; - MeshAttachment* attachmentP = NEW(MeshAttachment); - new (attachmentP) MeshAttachment(name); + MeshAttachment* attachmentP = new MeshAttachment(name); MeshAttachment& attachment = *attachmentP; attachment._rendererObject = regionP; @@ -96,43 +94,23 @@ namespace Spine { } BoundingBoxAttachment* AtlasAttachmentLoader::newBoundingBoxAttachment(Skin& skin, std::string name) { - BoundingBoxAttachment* attachmentP = NEW(BoundingBoxAttachment); - new (attachmentP) BoundingBoxAttachment(name); - - return attachmentP; + return new BoundingBoxAttachment(name); } PathAttachment* AtlasAttachmentLoader::newPathAttachment(Skin& skin, std::string name) { - PathAttachment* attachmentP = NEW(PathAttachment); - new (attachmentP) PathAttachment(name); - - return attachmentP; + return new PathAttachment(name); } PointAttachment* AtlasAttachmentLoader::newPointAttachment(Skin& skin, std::string name) { - PointAttachment* attachmentP = NEW(PointAttachment); - new (attachmentP) PointAttachment(name); - - return attachmentP; + return new PointAttachment(name); } ClippingAttachment* AtlasAttachmentLoader::newClippingAttachment(Skin& skin, std::string name) { - ClippingAttachment* attachmentP = NEW(ClippingAttachment); - new (attachmentP) ClippingAttachment(name); - - return attachmentP; + return new ClippingAttachment(name); } AtlasRegion* AtlasAttachmentLoader::findRegion(std::string name) { AtlasRegion* ret; - - for (int i = 0; i < _atlasArray.size(); i++) { - ret = _atlasArray[i]->findRegion(name); - if (ret != NULL) { - return ret; - } - } - - return NULL; + return _atlas.findRegion(name); } } diff --git a/spine-cpp/spine-cpp/src/spine/Extension.cpp b/spine-cpp/spine-cpp/src/spine/Extension.cpp index 4e1294cdb..9a0bfd7b3 100644 --- a/spine-cpp/spine-cpp/src/spine/Extension.cpp +++ b/spine-cpp/spine-cpp/src/spine/Extension.cpp @@ -53,7 +53,7 @@ namespace Spine { // Empty } - char* SpineExtension::spineReadFile(const char* path, int* length) { + char* SpineExtension::_readFile(const char* path, int* length) { char *data; FILE *file = fopen(path, "rb"); if (!file) return 0; @@ -62,7 +62,7 @@ namespace Spine { *length = (int)ftell(file); fseek(file, 0, SEEK_SET); - data = MALLOC(char, *length); + data = SpineExtension::alloc(*length, __FILE__, __LINE__); fread(data, 1, *length, file); fclose(file); @@ -73,33 +73,28 @@ namespace Spine { // Empty } - DefaultSpineExtension* DefaultSpineExtension::getInstance() { - static DefaultSpineExtension ret; - return &ret; - } - DefaultSpineExtension::~DefaultSpineExtension() { // Empty } - void* DefaultSpineExtension::spineAlloc(size_t size, const char* file, int line) { - return malloc(size); + void* DefaultSpineExtension::_alloc(size_t size, const char* file, int line) { + return ::malloc(size); } - void* DefaultSpineExtension::spineCalloc(size_t num, size_t size, const char* file, int line) { - void* ptr = spineAlloc(num * size, file, line); + void* DefaultSpineExtension::_calloc(size_t size, const char* file, int line) { + void* ptr = _alloc(size, file, line); if (ptr) { - memset(ptr, 0, num * size); + memset(ptr, 0, size); } return ptr; } - void* DefaultSpineExtension::spineRealloc(void* ptr, size_t size, const char* file, int line) { - return realloc(ptr, size); + void* DefaultSpineExtension::_realloc(void* ptr, size_t size, const char* file, int line) { + return ::realloc(ptr, size); } - void DefaultSpineExtension::spineFree(void* mem) { + void DefaultSpineExtension::_free(void* mem) { free(mem); } diff --git a/spine-cpp/spine-cpp/src/spine/Json.cpp b/spine-cpp/spine-cpp/src/spine/Json.cpp index 2a5494f00..bcc82f9a1 100644 --- a/spine-cpp/spine-cpp/src/spine/Json.cpp +++ b/spine-cpp/spine-cpp/src/spine/Json.cpp @@ -115,19 +115,19 @@ namespace Spine { Json::~Json() { if (_child) { - DESTROY(Json, _child); + delete _child; } if (_valueString) { - FREE(_valueString); + SpineExtension::free(_valueString); } if (_name) { - FREE(_name); + SpineExtension::free(_name); } if (_next) { - DESTROY(Json, _next); + delete _next; } } @@ -223,7 +223,7 @@ namespace Spine { } } - out = MALLOC(char, len + 1); /* The length needed for the string, roughly. */ + out = (char*)SpineExtension::alloc(len + 1, __FILE__, __LINE__); /* The length needed for the string, roughly. */ if (!out) { return 0; } @@ -313,7 +313,7 @@ namespace Spine { } } - *ptr2 = NULL; + *ptr2 = 0; if (*ptr == '\"') { ptr++; /* TODO error handling if not \" or \0 ? */ @@ -415,8 +415,7 @@ namespace Spine { return value + 1; /* empty array. */ } - item->_child = child = NEW(Json); - new (item->_child) Json(NULL); + item->_child = child = new Json(NULL); if (!item->_child) { return NULL; /* memory fail */ } @@ -430,8 +429,7 @@ namespace Spine { item->_size = 1; while (*value == ',') { - Json *new_item = NEW(Json); - new (new_item) Json(NULL); + Json *new_item = new Json(NULL); if (!new_item) { return NULL; /* memory fail */ } @@ -473,8 +471,7 @@ namespace Spine { return value + 1; /* empty array. */ } - item->_child = child = NEW(Json); - new (item->_child) Json(NULL); + item->_child = child = new Json(NULL); if (!item->_child) { return NULL; } @@ -497,8 +494,7 @@ namespace Spine { item->_size = 1; while (*value == ',') { - Json *new_item = NEW(Json); - new (new_item) Json(NULL); + Json *new_item = new Json(NULL); if (!new_item) { return NULL; /* memory fail */ } diff --git a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp index 221298519..a59be5599 100644 --- a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp @@ -71,13 +71,11 @@ namespace Spine { Bone* bone; if (data->getParent() == NULL) { - bone = NEW(Bone); - new (bone) Bone(*data, *this, NULL); + bone = new Bone(*data, *this, NULL); } else { Bone* parent = _bones[data->getParent()->getIndex()]; - bone = NEW(Bone); - new (bone) Bone(*data, *this, parent); + bone = new Bone(*data, *this, parent); parent->getChildren().push_back(bone); } @@ -90,8 +88,7 @@ namespace Spine { SlotData* data = (*i); Bone* bone = _bones[data->getBoneData().getIndex()]; - Slot* slot = NEW(Slot); - new (slot) Slot(*data, *bone); + Slot* slot = new Slot(*data, *bone); _slots.push_back(slot); _drawOrder.push_back(slot); @@ -101,8 +98,7 @@ namespace Spine { for (IkConstraintData** i = _data.getIkConstraints().begin(); i != _data.getIkConstraints().end(); ++i) { IkConstraintData* data = (*i); - IkConstraint* constraint = NEW(IkConstraint); - new (constraint) IkConstraint(*data, *this); + IkConstraint* constraint = new IkConstraint(*data, *this); _ikConstraints.push_back(constraint); } @@ -111,8 +107,7 @@ namespace Spine { for (TransformConstraintData** i = _data.getTransformConstraints().begin(); i != _data.getTransformConstraints().end(); ++i) { TransformConstraintData* data = (*i); - TransformConstraint* constraint = NEW(TransformConstraint); - new (constraint) TransformConstraint(*data, *this); + TransformConstraint* constraint = new TransformConstraint(*data, *this); _transformConstraints.push_back(constraint); } @@ -121,8 +116,7 @@ namespace Spine { for (PathConstraintData** i = _data.getPathConstraints().begin(); i != _data.getPathConstraints().end(); ++i) { PathConstraintData* data = (*i); - PathConstraint* constraint = NEW(PathConstraint); - new (constraint) PathConstraint(*data, *this); + PathConstraint* constraint = new PathConstraint(*data, *this); _pathConstraints.push_back(constraint); } diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp index 364f128b0..ba9b25fff 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp @@ -106,8 +106,8 @@ namespace Spine { TransformMode_NoScaleOrReflection }; - SkeletonBinary::SkeletonBinary(Vector& atlasArray) : _attachmentLoader(NEW(AtlasAttachmentLoader)), _error(), _scale(1), _ownsLoader(true) { - new (_attachmentLoader) AtlasAttachmentLoader(atlasArray); + SkeletonBinary::SkeletonBinary(Atlas& atlasArray) : _attachmentLoader(new AtlasAttachmentLoader(atlasArray)), _error(), _scale(1), _ownsLoader(true) { + } SkeletonBinary::SkeletonBinary(AttachmentLoader* attachmentLoader) : _attachmentLoader(attachmentLoader), _error(), _scale(1), _ownsLoader(false) { @@ -118,7 +118,7 @@ namespace Spine { ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes); if (_ownsLoader) { - DESTROY(AttachmentLoader, _attachmentLoader); + delete _attachmentLoader; } } @@ -126,22 +126,21 @@ namespace Spine { int i, ii, nonessential; SkeletonData* skeletonData; - DataInput* input = CALLOC(DataInput, 1); + DataInput* input = new DataInput(); input->cursor = binary; input->end = binary + length; _linkedMeshes.clear(); - skeletonData = NEW(SkeletonData); - new (skeletonData) SkeletonData(); + skeletonData = new SkeletonData(); char* skeletonData_hash = readString(input); skeletonData->_hash = std::string(skeletonData_hash); - FREE(skeletonData_hash); + SpineExtension::free(skeletonData_hash); char* skeletonData_version = readString(input); skeletonData->_version = std::string(skeletonData_version); - FREE(skeletonData_version); + SpineExtension::free(skeletonData_version); skeletonData->_width = readFloat(input); skeletonData->_height = readFloat(input); @@ -151,7 +150,7 @@ namespace Spine { if (nonessential) { /* Skip images path & fps */ readFloat(input); - FREE(readString(input)); + SpineExtension::free(readString(input)); } /* Bones. */ @@ -164,10 +163,9 @@ namespace Spine { const char* name = readString(input); BoneData* parent = i == 0 ? 0 : skeletonData->_bones[readVarint(input, 1)]; - data = NEW(BoneData); - new (data) BoneData(i, std::string(name), parent); - - FREE(name); + data = new BoneData(i, std::string(name), parent); + + SpineExtension::free(name); data->_rotation = readFloat(input); data->_x = readFloat(input) * _scale; @@ -214,10 +212,9 @@ namespace Spine { const char* slotName = readString(input); BoneData* boneData = skeletonData->_bones[readVarint(input, 1)]; - SlotData* slotData = NEW(SlotData); - new (slotData) SlotData(i, std::string(slotName), *boneData); - - FREE(slotName); + SlotData* slotData = new SlotData(i, std::string(slotName), *boneData); + + SpineExtension::free(slotName); readColor(input, &slotData->_r, &slotData->_g, &slotData->_b, &slotData->_a); r = readByte(input); g = readByte(input); @@ -230,7 +227,7 @@ namespace Spine { } char* slotData_attachmentName = readString(input); slotData->_attachmentName = std::string(slotData_attachmentName); - FREE(slotData_attachmentName); + SpineExtension::free(slotData_attachmentName); slotData->_blendMode = static_cast(readVarint(input, 1)); skeletonData->_slots[i] = slotData; @@ -243,12 +240,11 @@ namespace Spine { for (i = 0; i < ikConstraintsCount; ++i) { const char* name = readString(input); - IkConstraintData* data = NEW(IkConstraintData); - new (data) IkConstraintData(std::string(name)); + IkConstraintData* data = new IkConstraintData(std::string(name)); data->_order = readVarint(input, 1); - - FREE(name); + + SpineExtension::free(name); int bonesCount = readVarint(input, 1); data->_bones.reserve(bonesCount); data->_bones.setSize(bonesCount); @@ -269,11 +265,10 @@ namespace Spine { for (i = 0; i < transformConstraintsCount; ++i) { const char* name = readString(input); - TransformConstraintData* data = NEW(TransformConstraintData); - new (data) TransformConstraintData(std::string(name)); + TransformConstraintData* data = new TransformConstraintData(std::string(name)); data->_order = readVarint(input, 1); - FREE(name); + SpineExtension::free(name); int bonesCount = readVarint(input, 1); data->_bones.reserve(bonesCount); data->_bones.setSize(bonesCount); @@ -304,11 +299,10 @@ namespace Spine { for (i = 0; i < pathConstraintsCount; ++i) { const char* name = readString(input); - PathConstraintData* data = NEW(PathConstraintData); - new (data) PathConstraintData(std::string(name)); + PathConstraintData* data = new PathConstraintData(std::string(name)); data->_order = readVarint(input, 1); - FREE(name); + SpineExtension::free(name); int bonesCount = readVarint(input, 1); data->_bones.reserve(bonesCount); @@ -355,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); - FREE(skinName); + SpineExtension::free(skinName); } /* Linked meshes. */ @@ -363,15 +357,15 @@ namespace Spine { LinkedMesh* linkedMesh = _linkedMeshes[i]; Skin* skin = linkedMesh->_skin.length() == 0 ? skeletonData->getDefaultSkin() : skeletonData->findSkin(linkedMesh->_skin); if (skin == NULL) { - FREE(input); - DESTROY(SkeletonData, skeletonData); + delete input; + delete skeletonData; setError("Skin not found: ", linkedMesh->_skin.c_str()); return NULL; } Attachment* parent = skin->getAttachment(linkedMesh->_slotIndex, linkedMesh->_parent); if (parent == NULL) { - FREE(input); - DESTROY(SkeletonData, skeletonData); + delete input; + delete skeletonData; setError("Parent mesh not found: ", linkedMesh->_parent.c_str()); return NULL; } @@ -386,14 +380,13 @@ namespace Spine { skeletonData->_events.setSize(eventsCount); for (i = 0; i < eventsCount; ++i) { const char* name = readString(input); - EventData* eventData = NEW(EventData); - new (eventData) EventData(std::string(name)); - FREE(name); + EventData* eventData = new EventData(std::string(name)); + SpineExtension::free(name); eventData->_intValue = readVarint(input, 0); eventData->_floatValue = readFloat(input); const char* eventData_stringValue = readString(input); eventData->_stringValue = std::string(eventData_stringValue); - FREE(eventData_stringValue); + SpineExtension::free(eventData_stringValue); skeletonData->_events[i] = eventData; } @@ -404,16 +397,16 @@ namespace Spine { for (i = 0; i < animationsCount; ++i) { const char* name = readString(input); Animation* animation = readAnimation(name, input, skeletonData); - FREE(name); + SpineExtension::free(name); if (!animation) { - FREE(input); - DESTROY(SkeletonData, skeletonData); + delete input; + delete skeletonData; return NULL; } skeletonData->_animations[i] = animation; } - FREE(input); + delete input; return skeletonData; } @@ -421,13 +414,13 @@ namespace Spine { SkeletonData* SkeletonBinary::readSkeletonDataFile(const char* path) { int length; SkeletonData* skeletonData; - const char* binary = SPINE_EXTENSION->spineReadFile(path, &length); + const char* binary = SpineExtension::readFile(path, &length); if (length == 0 || !binary) { setError("Unable to read skeleton file: ", path); return NULL; } skeletonData = readSkeletonData((unsigned char*)binary, length); - FREE(binary); + SpineExtension::free(binary); return skeletonData; } @@ -449,7 +442,7 @@ namespace Spine { if (length == 0) { return NULL; } - string = MALLOC(char, length); + string = SpineExtension::alloc(length, __FILE__, __LINE__); memcpy(string, input->cursor, length - 1); input->cursor += length - 1; string[length - 1] = '\0'; @@ -529,8 +522,7 @@ namespace Spine { return NULL; } - skin = NEW(Skin); - new (skin) Skin(std::string(skinName)); + skin = new Skin(std::string(skinName)); for (i = 0; i < slotCount; ++i) { int slotIndex = readVarint(input, 1); @@ -540,7 +532,7 @@ namespace Spine { if (attachment) { skin->addAttachment(slotIndex, std::string(name), attachment); } - FREE(name); + SpineExtension::free(name); } } @@ -579,7 +571,7 @@ namespace Spine { region->updateOffset(); if (freeName) { - FREE(name); + SpineExtension::free(name); } return region; @@ -593,7 +585,7 @@ namespace Spine { readInt(input); } if (freeName) { - FREE(name); + SpineExtension::free(name); } return box; @@ -628,7 +620,7 @@ namespace Spine { } if (freeName) { - FREE(name); + SpineExtension::free(name); } return mesh; @@ -653,16 +645,15 @@ namespace Spine { mesh->_height = readFloat(input) * _scale; } - LinkedMesh* linkedMesh = NEW(LinkedMesh); - new (linkedMesh) LinkedMesh(mesh, std::string(skinName), slotIndex, std::string(parent)); + LinkedMesh* linkedMesh = new LinkedMesh(mesh, std::string(skinName), slotIndex, std::string(parent)); _linkedMeshes.push_back(linkedMesh); if (freeName) { - FREE(name); + SpineExtension::free(name); } - FREE(skinName); - FREE(parent); + SpineExtension::free(skinName); + SpineExtension::free(parent); return mesh; } @@ -686,7 +677,7 @@ namespace Spine { } if (freeName) { - FREE(name); + SpineExtension::free(name); } return path; @@ -718,7 +709,7 @@ namespace Spine { clip->_endSlot = skeletonData->_slots[endSlotIndex]; if (freeName) { - FREE(name); + SpineExtension::free(name); } return clip; @@ -726,7 +717,7 @@ namespace Spine { } if (freeName) { - FREE(name); + SpineExtension::free(name); } return NULL; @@ -809,21 +800,19 @@ namespace Spine { int frameCount = readVarint(input, true); switch (timelineType) { case SLOT_ATTACHMENT: { - AttachmentTimeline* timeline = NEW(AttachmentTimeline); - new(timeline) AttachmentTimeline(frameCount); + AttachmentTimeline* timeline = new 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)); - FREE(attachmentName); + SpineExtension::free(attachmentName); } timelines.push_back(timeline); duration = MAX(duration, timeline->_frames[frameCount - 1]); break; } case SLOT_COLOR: { - ColorTimeline* timeline = NEW(ColorTimeline); - new(timeline) ColorTimeline(frameCount); + ColorTimeline* timeline = new ColorTimeline(frameCount); timeline->_slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { float time = readFloat(input); @@ -842,8 +831,7 @@ namespace Spine { break; } case SLOT_TWO_COLOR: { - TwoColorTimeline* timeline = NEW(TwoColorTimeline); - new(timeline) TwoColorTimeline(frameCount); + TwoColorTimeline* timeline = new TwoColorTimeline(frameCount); timeline->_slotIndex = slotIndex; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { float time = readFloat(input); @@ -883,8 +871,7 @@ namespace Spine { int frameCount = readVarint(input, true); switch (timelineType) { case BONE_ROTATE: { - RotateTimeline* timeline = NEW(RotateTimeline); - new(timeline) RotateTimeline(frameCount); + RotateTimeline* timeline = new RotateTimeline(frameCount); timeline->_boneIndex = boneIndex; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { timeline->setFrame(frameIndex, readFloat(input), readFloat(input)); @@ -902,16 +889,13 @@ namespace Spine { TranslateTimeline* timeline; float timelineScale = 1; if (timelineType == BONE_SCALE) { - timeline = NEW(ScaleTimeline); - new(timeline) ScaleTimeline(frameCount); + timeline = new ScaleTimeline(frameCount); } else if (timelineType == BONE_SHEAR) { - timeline = NEW(ShearTimeline); - new(timeline) ShearTimeline(frameCount); + timeline = new ShearTimeline(frameCount); } else { - timeline = NEW(TranslateTimeline); - new(timeline) TranslateTimeline(frameCount); + timeline = new TranslateTimeline(frameCount); timelineScale = scale; } timeline->_boneIndex = boneIndex; @@ -938,8 +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); - new(timeline) IkConstraintTimeline(frameCount); + IkConstraintTimeline* timeline = new IkConstraintTimeline(frameCount); timeline->_ikConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { timeline->setFrame(frameIndex, readFloat(input), readFloat(input), readSByte(input)); @@ -955,8 +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); - new(timeline) TransformConstraintTimeline(frameCount); + TransformConstraintTimeline* timeline = new 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)); @@ -981,16 +963,14 @@ namespace Spine { PathConstraintPositionTimeline* timeline; float timelineScale = 1; if (timelineType == PATH_SPACING) { - timeline = NEW(PathConstraintSpacingTimeline); - new(timeline) PathConstraintSpacingTimeline(frameCount); + timeline = new PathConstraintSpacingTimeline(frameCount); if (data->_spacingMode == SpacingMode_Length || data->_spacingMode == SpacingMode_Fixed) { timelineScale = scale; } } else { - timeline = NEW(PathConstraintPositionTimeline); - new(timeline) PathConstraintPositionTimeline(frameCount); + timeline = new PathConstraintPositionTimeline(frameCount); if (data->_positionMode == PositionMode_Fixed) { timelineScale = scale; @@ -1008,8 +988,7 @@ namespace Spine { break; } case PATH_MIX: { - PathConstraintMixTimeline* timeline = NEW(PathConstraintMixTimeline); - new(timeline) PathConstraintMixTimeline(frameCount); + PathConstraintMixTimeline* timeline = new PathConstraintMixTimeline(frameCount); timeline->_pathConstraintIndex = index; for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { @@ -1038,11 +1017,11 @@ namespace Spine { if (!baseAttachment) { ContainerUtil::cleanUpVectorOfPointers(timelines); setError("Attachment not found: ", attachmentName); - FREE(attachmentName); + SpineExtension::free(attachmentName); return NULL; } - FREE(attachmentName); + SpineExtension::free(attachmentName); VertexAttachment* attachment = static_cast(baseAttachment); @@ -1052,8 +1031,7 @@ namespace Spine { int frameCount = readVarint(input, true); - DeformTimeline* timeline = NEW(DeformTimeline); - new(timeline) DeformTimeline(frameCount); + DeformTimeline* timeline = new DeformTimeline(frameCount); timeline->_slotIndex = slotIndex; timeline->_attachment = attachment; @@ -1110,8 +1088,7 @@ namespace Spine { // Draw order timeline. int drawOrderCount = readVarint(input, true); if (drawOrderCount > 0) { - DrawOrderTimeline* timeline = NEW(DrawOrderTimeline); - new(timeline) DrawOrderTimeline(drawOrderCount); + DrawOrderTimeline* timeline = new DrawOrderTimeline(drawOrderCount); int slotCount = static_cast(skeletonData->_slots.size()); for (int i = 0; i < drawOrderCount; ++i) { @@ -1158,14 +1135,12 @@ namespace Spine { // Event timeline. int eventCount = readVarint(input, true); if (eventCount > 0) { - EventTimeline* timeline = NEW(EventTimeline); - new(timeline) EventTimeline(eventCount); + EventTimeline* timeline =new EventTimeline(eventCount); for (int i = 0; i < eventCount; ++i) { float time = readFloat(input); EventData* eventData = skeletonData->_events[readVarint(input, true)]; - Event* event = NEW(Event); - new(event) Event(time, *eventData); + Event* event = new Event(time, *eventData); event->_intValue = readVarint(input, false); event->_floatValue = readFloat(input); @@ -1173,7 +1148,7 @@ namespace Spine { const char* event_stringValue = freeString ? readString(input) : eventData->_stringValue.c_str(); event->_stringValue = std::string(event_stringValue); if (freeString) { - FREE(event_stringValue); + SpineExtension::free(event_stringValue); } timeline->setFrame(i, event); } @@ -1182,10 +1157,7 @@ namespace Spine { duration = MAX(duration, timeline->_frames[eventCount - 1]); } - Animation* ret = NEW(Animation); - new (ret) Animation(std::string(name), timelines, duration); - - return ret; + return new Animation(std::string(name), timelines, duration); } void SkeletonBinary::readCurve(DataInput* input, int frameIndex, CurveTimeline* timeline) { diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBounds.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBounds.cpp index 15ad8e4f4..e4bf6c333 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBounds.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBounds.cpp @@ -68,8 +68,7 @@ namespace Spine { _polygonPool.erase(poolCount - 1); } else { - Polygon* polygonP = NEW(Polygon); - new (polygonP) Polygon(); + Polygon* polygonP = new Polygon(); } _polygons.push_back(polygonP); diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp index 3dbddb488..09252d237 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp @@ -86,8 +86,7 @@ #endif namespace Spine { - SkeletonJson::SkeletonJson(Vector& atlasArray) : _attachmentLoader(NEW(AtlasAttachmentLoader)), _scale(1), _ownsLoader(true) { - new (_attachmentLoader) AtlasAttachmentLoader(atlasArray); + SkeletonJson::SkeletonJson(Atlas& atlas) : _attachmentLoader(new AtlasAttachmentLoader(atlas)), _scale(1), _ownsLoader(true) { } SkeletonJson::SkeletonJson(AttachmentLoader* attachmentLoader) : _attachmentLoader(attachmentLoader), _scale(1), _ownsLoader(false) { @@ -98,14 +97,14 @@ namespace Spine { ContainerUtil::cleanUpVectorOfPointers(_linkedMeshes); if (_ownsLoader) { - DESTROY(AttachmentLoader, _attachmentLoader); + delete _attachmentLoader; } } SkeletonData* SkeletonJson::readSkeletonDataFile(const char* path) { int length; SkeletonData* skeletonData; - const char* json = SPINE_EXTENSION->spineReadFile(path, &length); + const char* json = SpineExtension::readFile(path, &length); if (length == 0 || !json) { setError(NULL, "Unable to read skeleton file: ", path); return NULL; @@ -113,7 +112,7 @@ namespace Spine { skeletonData = readSkeletonData(json); - FREE(json); + SpineExtension::free(json); return skeletonData; } @@ -126,16 +125,14 @@ namespace Spine { _error.clear(); _linkedMeshes.clear(); - root = NEW(Json); - new (root) Json(json); + root = new Json(json); if (!root) { setError(NULL, "Invalid skeleton JSON: ", Json::getError()); return NULL; } - skeletonData = NEW(SkeletonData); - new (skeletonData) SkeletonData(); + skeletonData = new SkeletonData(); skeleton = Json::getItem(root, "skeleton"); if (skeleton) { @@ -159,14 +156,13 @@ namespace Spine { if (parentName) { parent = skeletonData->findBone(parentName); if (!parent) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Parent bone not found: ", parentName); return NULL; } } - data = NEW(BoneData); - new (data) BoneData(bonesCount, Json::getString(boneMap, "name", 0), parent); + data = new BoneData(bonesCount, Json::getString(boneMap, "name", 0), parent); data->_length = Json::getFloat(boneMap, "length", 0) * _scale; data->_x = Json::getFloat(boneMap, "x", 0) * _scale; @@ -213,13 +209,12 @@ namespace Spine { const char* boneName = Json::getString(slotMap, "bone", 0); BoneData* boneData = skeletonData->findBone(boneName); if (!boneData) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Slot bone not found: ", boneName); return NULL; } - data = NEW(SlotData); - new (data) SlotData(i, Json::getString(slotMap, "name", 0), *boneData); + data = new SlotData(i, Json::getString(slotMap, "name", 0), *boneData); color = Json::getString(slotMap, "color", 0); if (color) { @@ -269,8 +264,7 @@ namespace Spine { for (constraintMap = ik->_child, i = 0; constraintMap; constraintMap = constraintMap->_next, ++i) { const char* targetName; - IkConstraintData* data = NEW(IkConstraintData); - new (data) IkConstraintData(Json::getString(constraintMap, "name", 0)); + IkConstraintData* data = new IkConstraintData(Json::getString(constraintMap, "name", 0)); data->_order = Json::getInt(constraintMap, "order", 0); @@ -280,7 +274,7 @@ namespace Spine { for (boneMap = boneMap->_child, ii = 0; boneMap; boneMap = boneMap->_next, ++ii) { data->_bones[ii] = skeletonData->findBone(boneMap->_valueString); if (!data->_bones[ii]) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "IK bone not found: ", boneMap->_valueString); return NULL; } @@ -289,7 +283,7 @@ namespace Spine { targetName = Json::getString(constraintMap, "target", 0); data->_target = skeletonData->findBone(targetName); if (!data->_target) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Target bone not found: ", targetName); return NULL; } @@ -310,8 +304,7 @@ namespace Spine { for (constraintMap = transform->_child, i = 0; constraintMap; constraintMap = constraintMap->_next, ++i) { const char* name; - TransformConstraintData* data = NEW(TransformConstraintData); - new (data) TransformConstraintData(Json::getString(constraintMap, "name", 0)); + TransformConstraintData* data = new TransformConstraintData(Json::getString(constraintMap, "name", 0)); data->_order = Json::getInt(constraintMap, "order", 0); @@ -321,7 +314,7 @@ namespace Spine { for (boneMap = boneMap->_child, ii = 0; boneMap; boneMap = boneMap->_next, ++ii) { data->_bones[ii] = skeletonData->findBone(boneMap->_valueString); if (!data->_bones[ii]) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Transform bone not found: ", boneMap->_valueString); return NULL; } @@ -330,7 +323,7 @@ namespace Spine { name = Json::getString(constraintMap, "target", 0); data->_target = skeletonData->findBone(name); if (!data->_target) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Target bone not found: ", name); return NULL; } @@ -363,8 +356,7 @@ namespace Spine { const char* name; const char* item; - PathConstraintData* data = NEW(PathConstraintData); - new (data) PathConstraintData(Json::getString(constraintMap, "name", 0)); + PathConstraintData* data = new PathConstraintData(Json::getString(constraintMap, "name", 0)); data->_order = Json::getInt(constraintMap, "order", 0); @@ -374,7 +366,7 @@ namespace Spine { for (boneMap = boneMap->_child, ii = 0; boneMap; boneMap = boneMap->_next, ++ii) { data->_bones[ii] = skeletonData->findBone(boneMap->_valueString); if (!data->_bones[ii]) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Path bone not found: ", boneMap->_valueString); return NULL; } @@ -383,7 +375,7 @@ namespace Spine { name = Json::getString(constraintMap, "target", 0); data->_target = skeletonData->findSlot(name); if (!data->_target) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Target slot not found: ", name); return NULL; } @@ -445,8 +437,7 @@ namespace Spine { Json *attachmentsMap; Json *curves; - Skin* skin = NEW(Skin); - new (skin) Skin(skinMap->_name); + Skin* skin = new Skin(skinMap->_name); skeletonData->_skins[skinsIndex++] = skin; if (strcmp(skinMap->_name, "default") == 0) { @@ -486,7 +477,7 @@ namespace Spine { type = AttachmentType_Clipping; } else { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Unknown attachment type: ", typeString); return NULL; } @@ -495,7 +486,7 @@ namespace Spine { case AttachmentType_Region: { attachment = _attachmentLoader->newRegionAttachment(*skin, attachmentName, attachmentPath); if (!attachment) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Error reading attachment: ", skinAttachmentName); return NULL; } @@ -576,8 +567,7 @@ namespace Spine { } else { mesh->_inheritDeform = Json::getInt(attachmentMap, "deform", 1); - LinkedMesh* linkedMesh = NEW(LinkedMesh); - new (linkedMesh) LinkedMesh(mesh, std::string(Json::getString(attachmentMap, "skin", 0)), slotIndex, std::string(entry->_valueString)); + LinkedMesh* linkedMesh = new LinkedMesh(mesh, std::string(Json::getString(attachmentMap, "skin", 0)), slotIndex, std::string(entry->_valueString)); _linkedMeshes.push_back(linkedMesh); } break; @@ -649,13 +639,13 @@ namespace Spine { LinkedMesh* linkedMesh = _linkedMeshes[i]; Skin* skin = linkedMesh->_skin.length() == 0 ? skeletonData->getDefaultSkin() : skeletonData->findSkin(linkedMesh->_skin); if (skin == NULL) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Skin not found: ", linkedMesh->_skin.c_str()); return NULL; } Attachment* parent = skin->getAttachment(linkedMesh->_slotIndex, linkedMesh->_parent); if (parent == NULL) { - DESTROY(SkeletonData, skeletonData); + delete skeletonData; setError(root, "Parent mesh not found: ", linkedMesh->_parent.c_str()); return NULL; } @@ -671,8 +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); - new (eventData) EventData(std::string(eventMap->_name)); + EventData* eventData = new EventData(std::string(eventMap->_name)); eventData->_intValue = Json::getInt(eventMap, "int", 0); eventData->_floatValue = Json::getFloat(eventMap, "float", 0); @@ -692,15 +681,15 @@ namespace Spine { for (animationMap = animations->_child; animationMap; animationMap = animationMap->_next) { Animation* animation = readAnimation(animationMap, skeletonData); if (!animation) { - DESTROY(SkeletonData, skeletonData); - DESTROY(Json, root); + delete skeletonData; + delete root; return NULL; } skeletonData->_animations[animationsIndex++] = animation; } } - DESTROY(Json, root); + delete root; return skeletonData; } @@ -807,8 +796,7 @@ namespace Spine { for (timelineMap = slotMap->_child; timelineMap; timelineMap = timelineMap->_next) { if (strcmp(timelineMap->_name, "attachment") == 0) { - AttachmentTimeline *timeline = NEW(AttachmentTimeline); - new (timeline) AttachmentTimeline(timelineMap->_size); + AttachmentTimeline *timeline = new AttachmentTimeline(timelineMap->_size); timeline->_slotIndex = slotIndex; @@ -823,8 +811,7 @@ namespace Spine { } else if (strcmp(timelineMap->_name, "color") == 0) { - ColorTimeline *timeline = NEW(ColorTimeline); - new (timeline) ColorTimeline(timelineMap->_size); + ColorTimeline *timeline = new ColorTimeline(timelineMap->_size); timeline->_slotIndex = slotIndex; @@ -839,8 +826,7 @@ namespace Spine { } else if (strcmp(timelineMap->_name, "twoColor") == 0) { - TwoColorTimeline *timeline = NEW(TwoColorTimeline); - new (timeline) TwoColorTimeline(timelineMap->_size); + TwoColorTimeline *timeline = new TwoColorTimeline(timelineMap->_size); timeline->_slotIndex = slotIndex; @@ -876,8 +862,7 @@ namespace Spine { for (timelineMap = boneMap->_child; timelineMap; timelineMap = timelineMap->_next) { if (strcmp(timelineMap->_name, "rotate") == 0) { - RotateTimeline *timeline = NEW(RotateTimeline); - new (timeline) RotateTimeline(timelineMap->_size); + RotateTimeline *timeline = new RotateTimeline(timelineMap->_size); timeline->_boneIndex = boneIndex; @@ -897,16 +882,13 @@ namespace Spine { float timelineScale = isTranslate ? _scale: 1; TranslateTimeline *timeline = 0; if (isScale) { - timeline = NEW(ScaleTimeline); - new (timeline) ScaleTimeline(timelineMap->_size); + timeline = new ScaleTimeline(timelineMap->_size); } else if (isTranslate) { - timeline = NEW(TranslateTimeline); - new (timeline) TranslateTimeline(timelineMap->_size); + timeline = new TranslateTimeline(timelineMap->_size); } else if (isShear) { - timeline = NEW(ShearTimeline); - new (timeline) ShearTimeline(timelineMap->_size); + timeline = new ShearTimeline(timelineMap->_size); } timeline->_boneIndex = boneIndex; @@ -931,8 +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); - new (timeline) IkConstraintTimeline(constraintMap->_size); + IkConstraintTimeline *timeline = new IkConstraintTimeline(constraintMap->_size); for (frameIndex = 0; frameIndex < static_cast(skeletonData->_ikConstraints.size()); ++frameIndex) { if (constraint == skeletonData->_ikConstraints[frameIndex]) { @@ -952,8 +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); - new (timeline) TransformConstraintTimeline(constraintMap->_size); + TransformConstraintTimeline *timeline = new TransformConstraintTimeline(constraintMap->_size); for (frameIndex = 0; frameIndex < skeletonData->_transformConstraints.size(); ++frameIndex) { if (constraint == skeletonData->_transformConstraints[frameIndex]) { @@ -995,16 +975,14 @@ namespace Spine { PathConstraintPositionTimeline* timeline; float timelineScale = 1; if (strcmp(timelineName, "spacing") == 0) { - timeline = NEW(PathConstraintSpacingTimeline); - new (timeline) PathConstraintSpacingTimeline(timelineMap->_size); + timeline = new PathConstraintSpacingTimeline(timelineMap->_size); if (data->_spacingMode == SpacingMode_Length || data->_spacingMode == SpacingMode_Fixed) { timelineScale = _scale; } } else { - timeline = NEW(PathConstraintPositionTimeline); - new (timeline) PathConstraintPositionTimeline(timelineMap->_size); + timeline = new PathConstraintPositionTimeline(timelineMap->_size); if (data->_positionMode == PositionMode_Fixed) { timelineScale = _scale; @@ -1021,8 +999,7 @@ namespace Spine { duration = MAX(duration, timeline->_frames[(timelineMap->_size - 1) * PathConstraintPositionTimeline::ENTRIES]); } else if (strcmp(timelineName, "mix") == 0) { - PathConstraintMixTimeline* timeline = NEW(PathConstraintMixTimeline); - new (timeline) PathConstraintMixTimeline(timelineMap->_size); + PathConstraintMixTimeline* timeline = new 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)); @@ -1064,8 +1041,7 @@ namespace Spine { tempDeform.push_back(0); } - timeline = NEW(DeformTimeline); - new (timeline) DeformTimeline(timelineMap->_size); + timeline = new DeformTimeline(timelineMap->_size); timeline->_slotIndex = slotIndex; timeline->_attachment = attachment; @@ -1115,8 +1091,7 @@ namespace Spine { /** Draw order timeline. */ if (drawOrder) { - DrawOrderTimeline* timeline = NEW(DrawOrderTimeline); - new (timeline) DrawOrderTimeline(drawOrder->_size); + DrawOrderTimeline* timeline = new DrawOrderTimeline(drawOrder->_size); for (valueMap = drawOrder->_child, frameIndex = 0; valueMap; valueMap = valueMap->_next, ++frameIndex) { int ii; @@ -1170,8 +1145,7 @@ namespace Spine { /** Event timeline. */ if (events) { - EventTimeline* timeline = NEW(EventTimeline); - new (timeline) EventTimeline(events->_size); + EventTimeline* timeline = new EventTimeline(events->_size); for (valueMap = events->_child, frameIndex = 0; valueMap; valueMap = valueMap->_next, ++frameIndex) { Event* event; @@ -1182,8 +1156,7 @@ namespace Spine { return NULL; } - event = NEW(Event); - new (event) Event(Json::getFloat(valueMap, "time", 0), *eventData); + event = new 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()); @@ -1194,10 +1167,7 @@ namespace Spine { duration = MAX(duration, timeline->_frames[events->_size - 1]); } - Animation* ret = NEW(Animation); - new (ret) Animation(std::string(root->_name), timelines, duration); - - return ret; + return new Animation(std::string(root->_name), timelines, duration); } void SkeletonJson::readVertices(Json* attachmentMap, VertexAttachment* attachment, int verticesLength) { @@ -1257,7 +1227,7 @@ namespace Spine { _error = std::string(message); if (root) { - DESTROY(Json, root); + delete root; } } } diff --git a/spine-cpp/spine-cpp/src/spine/SpineObject.cpp b/spine-cpp/spine-cpp/src/spine/SpineObject.cpp new file mode 100644 index 000000000..dff95a888 --- /dev/null +++ b/spine-cpp/spine-cpp/src/spine/SpineObject.cpp @@ -0,0 +1,35 @@ +/****************************************************************************** +* 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 + +namespace Spine { + +} \ No newline at end of file diff --git a/spine-sfml/CMakeLists.txt b/spine-sfml/CMakeLists.txt deleted file mode 100644 index 33ce3282e..000000000 --- a/spine-sfml/CMakeLists.txt +++ /dev/null @@ -1,87 +0,0 @@ -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/") -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) -file(GLOB INCLUDES "src/**/*.h") -file(GLOB SOURCES "src/**/*.cpp") -add_library(spine-sfml STATIC ${SOURCES} ${INCLUDES}) -target_link_libraries(spine-sfml LINK_PUBLIC spine-c) -install(TARGETS spine-sfml DESTINATION dist/lib) -install(FILES ${INCLUDES} DESTINATION dist/include) - -# Define spine-sfml example executable -add_executable(spine-sfml-example example/main.cpp) - -# Link in SFML libraries and OS dependencies like OpenGL -if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - find_library(SFML SFML PATHS ${SFML_DIR}/Frameworks) - find_library(SFML_SYSTEM "sfml-system" PATHS ${SFML_DIR}/Frameworks) - find_library(SFML_WINDOW sfml-window PATHS ${SFML_DIR}/Frameworks) - find_library(SFML_GRAPHICS sfml-graphics PATHS ${SFML_DIR}/Frameworks) - target_link_libraries(spine-sfml-example ${SFML} ${SFML_SYSTEM} ${SFML_WINDOW} ${SFML_GRAPHICS}) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - target_link_libraries(spine-sfml-example sfml-graphics sfml-window sfml-system) -else() - set(SFML_LIBS ${SFML_DIR}/lib) - target_link_libraries(spine-sfml-example ${SFML_LIBS}/sfml-main-d.lib) - target_link_libraries(spine-sfml-example ${SFML_LIBS}/sfml-graphics-s-d.lib) - target_link_libraries(spine-sfml-example ${SFML_LIBS}/sfml-window-s-d.lib) - target_link_libraries(spine-sfml-example ${SFML_LIBS}/sfml-system-s-d.lib) - target_link_libraries(spine-sfml-example ${SFML_LIBS}/freetype.lib) - target_link_libraries(spine-sfml-example ${SFML_LIBS}/jpeg.lib) - target_link_libraries(spine-sfml-example opengl32) - target_link_libraries(spine-sfml-example gdi32) - target_link_libraries(spine-sfml-example winmm) - add_definitions(-DSFML_STATIC) -endif() - -# copy data to build directory -add_custom_command(TARGET spine-sfml-example PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_LIST_DIR}/data $/data) - -target_link_libraries(spine-sfml-example spine-c) -target_link_libraries(spine-sfml-example spine-sfml) diff --git a/spine-sfml/LICENSE b/spine-sfml/LICENSE deleted file mode 100644 index daceab94a..000000000 --- a/spine-sfml/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -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. \ No newline at end of file diff --git a/spine-sfml/README.md b/spine-sfml/README.md deleted file mode 100644 index 834641813..000000000 --- a/spine-sfml/README.md +++ /dev/null @@ -1,68 +0,0 @@ -# spine-sfml - -The spine-sfml runtime provides functionality to load, manipulate and render [Spine](http://esotericsoftware.com) skeletal animation data using [SFML](http://www.sfml-dev.org/). spine-sfml is based on [spine-c](../spine-c). - -## Licensing - -This Spine Runtime may only be used for personal or internal use, typically to evaluate Spine before purchasing. If you would like to incorporate a Spine Runtime into your applications, distribute software containing a Spine Runtime, or modify a Spine Runtime, then you will need a valid [Spine license](https://esotericsoftware.com/spine-purchase). Please see the [Spine Runtimes Software License](http://esotericsoftware.com/git/spine-runtimes/blob/LICENSE) for detailed information. - -The Spine Runtimes are developed with the intent to be used with data exported from Spine. By purchasing Spine, `Section 2` of the [Spine Software License](https://esotericsoftware.com/files/license.txt) grants the right to create and distribute derivative works of the Spine Runtimes. - -## Spine version - -spine-sfml works with data exported from Spine 3.6.xx. - -spine-sfml supports all Spine features. - -spine-sfml does not yet support loading the binary format. - -## Usage -1. Create a new SFML project. See the [SFML documentation](http://www.sfml-dev.org/tutorials/2.1/) or have a look at the example in this repository. -2. Download the Spine Runtimes source using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it as a zip via the download button above. -3. Add the sources from `spine-c/spine-c/src/spine` and `spine-sfml/src/spine` to your project -4. Add the folder `spine-c/spine-c/include` to your header search path. Note that includes are specified as `#inclue `, so the `spine` directory cannot be omitted when copying the source files. - -See the [Spine Runtimes documentation](http://esotericsoftware.com/spine-documentation#runtimesTitle) on how to use the APIs or check out the Spine SFML example. - -## Example -The Spine SFML example works on Windows, Linux and Mac OS X. - -### Windows -1. Install [Visual Studio 2015 Community](https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx). Make sure you install support for C++ as well as th Windows SDK for XP/7/8. -2. Install CMake via the [Windows installer package](https://cmake.org/download/). -3. Download the Spine Runtimes repository using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it as a zip via the download button above. -4. Run CMake GUI from the start menu -5. Click `Browse Source` and select the directory `spine-runtimes` -6. Click `Browse Build` and select the `spine-runtimes/spine-sfml/build` directory. You can create the `build` folder directly in the file dialog via `New Folder`. -7. Click `Configure`. Then click `Generate`. This will create a Visual Studio 2015 solution file called `spine.sln` in `spine-runtimes/spine-sfml/build` and also download the SFML dependencies. -8. Open the `spine.sln` file in Visual Studio 2015 -9. Right click the `spine-sfml-example` project in the solution explorer and select `Set as Startup Project` from the context menu -10. Right click the `spine-sfml-example` project in the solution explorer and select `Properties` from the context menu -11. Select `Debugging` in the left-hand list, then set `Working Directory` to `$(OutputPath)` -12. Click `Local Windows Debugger` to run the example - -The entire example code is contained in [main.cpp](example/main.cpp#L61) - -### Linux -1. Install the SFML dependencies, e.g. on Ubuntu/Debian via `sudo apt install libsfml-dev` -2. Install CMake, e.g. on Ubuntu/Debian via `sudo apt-get install -y cmake` -3. Download the Spine Runtimes repository using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it as a zip via the download button above. -4. Open a terminal, and `cd` into the `spine-runtimes/spine-sfml` folder -5. Type `mkdir build && cd build && cmake ../..` to generate Make files -6. Type `make` to compile the example -7. Run the example by `cd spine-sfml && ./spine-sfml-example` - -### Mac OS X -1. Install [Xcode](https://developer.apple.com/xcode/) -2. Install [Homebrew](http://brew.sh/) -3. Open a terminal and install CMake via `brew install cmake` -3. Download the Spine Runtimes repository using git (`git clone https://github.com/esotericsoftware/spine-runtimes`) or download it as a zip via the download button above. -4. Open a terminal, and `cd` into the `spine-runtimes/spine-sfml` folder -5. Type `mkdir build && cd build && cmake -G Xcode ../..` to generate an Xcode project called `spine.xcodeproj` -6. Open the Xcode project in `spine-runtimes/spine-sfml/build/` -7. In Xcode, set the active scheme from `ALL_BUILD` to `spine-sfml-example` -8. Click the `Run` button or type `CMD+R` to run the example - -## Notes - -- Atlas images should not use premultiplied alpha. diff --git a/spine-sfml/data/coin-pro.json b/spine-sfml/data/coin-pro.json deleted file mode 100644 index c3abaf5f0..000000000 --- a/spine-sfml/data/coin-pro.json +++ /dev/null @@ -1,178 +0,0 @@ -{ -"skeleton": { - "hash": "lfmnIwRt8cjfHaBQWvT0v4odYdY", - "spine": "3.7.08-beta", - "width": 260, - "height": 359.92, - "images": "./images/", - "audio": "" -}, -"bones": [ - { "name": "root" }, - { "name": "coin-root", "parent": "root", "y": 300, "color": "ff0000ff" }, - { "name": "coin", "parent": "coin-root", "color": "ffe037ff" }, - { "name": "clipping", "parent": "coin", "x": 7.25, "scaleX": 0.96, "scaleY": 0.967, "color": "ffe037ff" }, - { "name": "shine", "parent": "coin-root", "rotation": -24.17, "scaleY": 1.478, "color": "ffffffff" } -], -"slots": [ - { "name": "images/coin", "bone": "coin", "attachment": "coin" }, - { "name": "clipping", "bone": "clipping", "attachment": "clipping" }, - { "name": "images/shine", "bone": "shine", "color": "ffffff93", "attachment": "shine", "blend": "additive" } -], -"skins": { - "default": { - "clipping": { - "clipping": { - "type": "clipping", - "end": "images/coin", - "vertexCount": 36, - "vertices": [ 0.82, 120.87, 25.27, 118.4, 49.23, 110.99, 71.46, 98.15, 88.25, 83.08, 102.58, 64.8, 112.21, 46.03, 117.89, 28, 121.35, 9.23, 120.61, -11.52, 117.65, -30.29, 111.72, -48.08, 102.33, -65.61, 89.47, -82.23, 76.24, -94.71, 61.33, -105.13, 46.26, -112.54, 28.73, -118.22, 8.73, -120.89, -12.27, -120.89, -32.03, -116.94, -51.04, -110.27, -67.59, -101.63, -82.91, -88.78, -96.25, -74.21, -108.35, -55.68, -116.5, -35.43, -120.7, -14.19, -121.69, 5.57, -118.97, 27.56, -111.56, 49.04, -100.43, 69.69, -84.38, 87.47, -66.1, 102.29, -45.6, 112.67, -23.62, 118.59 ], - "color": "ce3a3aff" - } - }, - "images/coin": { - "coin": { - "type": "mesh", - "uvs": [ 1, 1, 0.51662, 0.99661, 0.38311, 0.99567, 0.29957, 0.96664, 0.22817, 0.93237, 0.16736, 0.88777, 0.11597, 0.83202, 0.06732, 0.76058, 0.03288, 0.69072, 0.00816, 0.61391, 0, 0.52843, 0, 0.43778, 0.02307, 0.33992, 0.06544, 0.24204, 0.11924, 0.16659, 0.17691, 0.10919, 0.24399, 0.06252, 0.31853, 0.02742, 0.41818, 0.0076, 0.52609, 1.0E-5, 1, 0, 0.45994, 0.99066, 0.37873, 0.97119, 0.30719, 0.94057, 0.24626, 0.89841, 0.19491, 0.85157, 0.14893, 0.79961, 0.11299, 0.73943, 0.08595, 0.67565, 0.06609, 0.60105, 0.05753, 0.52647, 0.05856, 0.44906, 0.07176, 0.36094, 0.10407, 0.28078, 0.15657, 0.19211, 0.22811, 0.1162, 0.29907, 0.0658, 0.38388, 0.02814, 0.46119, 0.00993 ], - "triangles": [ 38, 18, 19, 37, 17, 18, 37, 18, 38, 36, 16, 17, 36, 17, 37, 35, 15, 16, 35, 16, 36, 34, 14, 15, 34, 15, 35, 34, 33, 13, 34, 13, 14, 12, 13, 33, 32, 12, 33, 11, 12, 32, 31, 11, 32, 31, 10, 11, 30, 10, 31, 31, 33, 30, 29, 30, 33, 29, 9, 10, 29, 10, 30, 32, 33, 31, 34, 28, 29, 8, 9, 29, 8, 29, 28, 33, 34, 29, 25, 26, 27, 7, 8, 28, 7, 28, 27, 27, 28, 25, 26, 7, 27, 6, 7, 26, 34, 36, 28, 28, 36, 25, 6, 26, 25, 5, 6, 25, 34, 35, 36, 37, 24, 25, 5, 25, 24, 4, 5, 24, 36, 37, 25, 22, 23, 24, 4, 24, 23, 3, 4, 23, 24, 21, 22, 3, 23, 22, 38, 24, 37, 24, 1, 21, 2, 22, 21, 3, 22, 2, 1, 38, 19, 1, 24, 38, 2, 21, 1, 19, 20, 0, 1, 19, 0 ], - "vertices": [ 130, -123.5, 4.32, -122.66, -30.39, -122.43, -52.11, -115.26, -70.68, -106.8, -86.49, -95.78, -99.85, -82.01, -112.5, -64.36, -121.45, -47.11, -127.88, -28.14, -130, -7.02, -130, 15.37, -124, 39.54, -112.99, 63.72, -99, 82.35, -84, 96.53, -66.56, 108.06, -47.18, 116.73, -21.27, 121.62, 6.78, 123.5, 130, 123.5, -10.42, -121.19, -31.53, -116.39, -50.13, -108.82, -65.97, -98.41, -79.32, -86.84, -91.28, -74, -100.62, -59.14, -107.65, -43.39, -112.82, -24.96, -115.04, -6.54, -114.77, 12.58, -111.34, 34.35, -102.94, 54.15, -89.29, 76.05, -70.69, 94.8, -52.24, 107.25, -30.19, 116.55, -10.09, 121.05 ], - "hull": 21, - "edges": [ 0, 40, 42, 44, 44, 46, 46, 48, 48, 50, 50, 52, 52, 54, 54, 56, 56, 58, 58, 60, 60, 62, 62, 64, 64, 66, 66, 68, 68, 70, 70, 72, 72, 74, 74, 76, 36, 34, 34, 32, 32, 30, 30, 28, 28, 26, 26, 24, 24, 22, 20, 22, 20, 18, 18, 16, 16, 14, 14, 12, 12, 10, 10, 8, 8, 6, 6, 4, 0, 2, 2, 4, 42, 2, 38, 40, 36, 38, 76, 38, 2, 38 ], - "width": 259, - "height": 245 - }, - "coin-invert": { - "type": "mesh", - "uvs": [ 0.61921, 0.00932, 0.70137, 0.03058, 0.76675, 0.06301, 0.82357, 0.10192, 0.86533, 0.14084, 0.90128, 0.1866, 0.92763, 0.22768, 0.95707, 0.28353, 0.97795, 0.33937, 0.99074, 0.38663, 1, 0.45194, 1, 0.50671, 1, 0.56148, 0.98993, 0.62238, 0.97282, 0.6757, 0.95125, 0.73083, 0.91771, 0.78704, 0.88283, 0.83498, 0.84141, 0.87966, 0.79349, 0.91785, 0.73701, 0.95172, 0.65999, 0.98127, 0.60659, 0.991, 0.51662, 0.99661, 0, 1, 0, 0, 0.52609, 1.0E-5, 0.57849, 0.98348, 0.64806, 0.96162, 0.70899, 0.92882, 0.75987, 0.89639, 0.80219, 0.85685, 0.83745, 0.81722, 0.86381, 0.77794, 0.89445, 0.72582, 0.9167, 0.67213, 0.93142, 0.61628, 0.94164, 0.56011, 0.94506, 0.50823, 0.9437, 0.45454, 0.93514, 0.39905, 0.91905, 0.34031, 0.89748, 0.28194, 0.8691, 0.2284, 0.83932, 0.18768, 0.79995, 0.143, 0.76298, 0.10841, 0.71814, 0.07598, 0.66748, 0.04824, 0.61408, 0.0277, 0.5665, 0.01437 ], - "triangles": [ 50, 26, 0, 49, 50, 0, 48, 0, 1, 49, 0, 48, 47, 1, 2, 48, 1, 47, 46, 47, 2, 46, 2, 3, 45, 46, 3, 45, 3, 4, 44, 45, 4, 44, 4, 5, 43, 44, 5, 43, 5, 6, 42, 43, 6, 42, 6, 7, 41, 42, 7, 41, 7, 8, 40, 41, 8, 40, 8, 9, 39, 40, 9, 10, 39, 9, 39, 10, 11, 38, 39, 11, 41, 40, 38, 38, 40, 39, 38, 11, 12, 37, 38, 12, 38, 36, 41, 37, 36, 38, 13, 37, 12, 36, 37, 13, 36, 43, 41, 41, 43, 42, 14, 36, 13, 35, 36, 14, 44, 43, 36, 35, 34, 36, 15, 35, 14, 34, 35, 15, 44, 36, 45, 34, 33, 36, 16, 34, 15, 33, 34, 16, 48, 47, 49, 36, 33, 45, 17, 33, 16, 32, 33, 17, 32, 31, 33, 18, 32, 17, 31, 32, 18, 33, 29, 45, 45, 47, 46, 31, 30, 33, 19, 30, 31, 19, 31, 18, 49, 47, 45, 30, 29, 33, 20, 29, 30, 20, 30, 19, 50, 49, 29, 45, 29, 49, 21, 28, 29, 21, 29, 20, 29, 27, 50, 28, 27, 29, 22, 27, 28, 22, 28, 21, 23, 25, 26, 23, 26, 50, 23, 50, 27, 23, 27, 22, 24, 25, 23 ], - "vertices": [ 42.18, 121.2, 63.54, 115.95, 80.54, 107.94, 95.31, 98.32, 106.17, 88.71, 115.51, 77.41, 122.37, 67.26, 130.02, 53.47, 135.45, 39.68, 138.77, 28, 141.18, 11.87, 141.18, -1.66, 141.18, -15.19, 138.56, -30.23, 134.11, -43.4, 128.51, -57.02, 119.79, -70.9, 110.72, -82.74, 99.95, -93.78, 87.49, -103.21, 72.8, -111.58, 52.78, -118.87, 38.9, -121.28, 15.5, -122.66, -118.82, -123.5, -118.82, 123.5, 17.97, 123.5, 31.59, -119.42, 49.68, -114.02, 65.52, -105.92, 78.75, -97.91, 89.75, -88.14, 98.92, -78.35, 105.77, -68.65, 113.74, -55.78, 119.52, -42.52, 123.35, -28.72, 126.01, -14.85, 126.9, -2.03, 126.54, 11.23, 124.32, 24.94, 120.13, 39.44, 114.53, 53.86, 107.15, 67.09, 99.4, 77.14, 89.17, 88.18, 79.56, 96.72, 67.9, 104.73, 54.73, 111.59, 40.84, 116.66, 28.47, 119.95 ], - "hull": 27, - "edges": [ 46, 52, 46, 54, 54, 56, 56, 58, 58, 60, 60, 62, 62, 64, 64, 66, 66, 68, 68, 70, 70, 72, 72, 74, 74, 76, 76, 78, 78, 80, 80, 82, 82, 84, 84, 86, 86, 88, 88, 90, 90, 92, 92, 94, 94, 96, 96, 98, 98, 100, 100, 52, 52, 0, 0, 2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 20, 22, 22, 24, 24, 26, 26, 28, 28, 30, 30, 32, 32, 34, 34, 36, 36, 38, 38, 40, 40, 42, 42, 44, 44, 46, 48, 50, 50, 52, 46, 48, 16, 18, 18, 20 ], - "width": 259, - "height": 245 - } - }, - "images/shine": { - "shine": { "width": 72, "height": 245 } - } - } -}, -"animations": { - "rotate": { - "slots": { - "images/coin": { - "attachment": [ - { "time": 0.5, "name": "coin-invert" } - ] - }, - "images/shine": { - "color": [ - { "time": 0, "color": "ffffff00" }, - { "time": 0.2667, "color": "ffffffbc" }, - { "time": 0.5, "color": "ffffff00" }, - { "time": 0.7333, "color": "ffffffbc" }, - { "time": 1, "color": "ffffff00" } - ] - } - }, - "bones": { - "shine": { - "translate": [ - { - "time": 0, - "x": 175.08, - "y": 0, - "curve": [ 0.213, 0.65, 0.931, 0.67 ] - }, - { - "time": 0.5, - "x": -127.2, - "y": 0, - "curve": [ 0.55, 0.09, 0.931, 0.67 ] - }, - { "time": 1, "x": 175.08, "y": 0 } - ], - "scale": [ - { - "time": 0, - "x": 1, - "y": 1, - "curve": [ 0.213, 0.65, 0.931, 0.67 ] - }, - { - "time": 0.5, - "x": 2, - "y": 1, - "curve": [ 0.55, 0.09, 0.931, 0.67 ] - }, - { "time": 1, "x": 1, "y": 1 } - ] - }, - "coin": { - "translate": [ - { "time": 0, "x": 0, "y": 0 }, - { "time": 0.5, "x": 0.93, "y": 0 }, - { "time": 0.5011, "x": -9.18, "y": 0 }, - { "time": 1, "x": 2, "y": 0 } - ] - }, - "clipping": { - "translate": [ - { "time": 0, "x": -0.41, "y": 0 }, - { "time": 0.2667, "x": 1.2, "y": 1.21 }, - { "time": 0.5, "x": 0, "y": 0 }, - { "time": 0.7333, "x": -4.15, "y": 0 }, - { "time": 1, "x": -3.16, "y": 0 } - ], - "scale": [ - { "time": 0, "x": 1, "y": 1 }, - { "time": 0.2667, "x": 0.464, "y": 1.014 }, - { "time": 0.4667, "x": 0.067, "y": 1.002 }, - { "time": 0.5, "x": 0.033, "y": 1 }, - { "time": 0.7333, "x": 0.492, "y": 1.014 }, - { "time": 1, "x": 1, "y": 1 } - ] - } - }, - "deform": { - "default": { - "images/coin": { - "coin": [ - { - "time": 0, - "offset": 4, - "vertices": [ 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598, 0, 15.75598 ] - }, - { - "time": 0.2333, - "vertices": [ -57.61087, 0, 1.15225, 0, 15.20888, 0, 24.26007, 0, 31.99586, 0, 38.58396, 0, 44.15197, 0, 49.42246, 0, 53.15465, 0, 55.83239, 0, 56.71656, 0, 56.71656, 0, 54.21722, 0, 49.62682, 0, 43.79747, 0, 37.5494, 0, 30.28123, 0, 22.2055, 0, 11.40953, 0, 0, 0, -57.61087, 0, 8.04186, 0, 17.91416, 0, 26.61125, 0, 34.01835, 0, 40.26029, 0, 45.85036, 0, 50.21972, 0, 53.50714, 0, 55.9207, 0, 56.96101, 0, 56.83617, 0, 55.23131, 0, 51.30379, 0, 44.9216, 0, 36.22496, 0, 27.59846, 0, 17.28874, 0, 7.89076 ] - }, - { - "time": 0.4667, - "vertices": [ -115.22174, 0, 2.3045, 0, 20.08046, 0, 40.51821, 0, 57.98577, 0, 72.86182, 0, 85.43448, 0, 97.33535, 0, 105.76271, 0, 111.80908, 0, 113.80557, 0, 113.80557, 0, 108.16202, 0, 97.7968, 0, 84.63402, 0, 70.52576, 0, 54.11411, 0, 35.87894, 0, 11.50145, 1.74997, 0, 0, -115.22174, 0, 16.08371, 0, 35.82832, 0, 53.2225, 0, 68.0367, 0, 80.52058, 0, 91.70073, 0, 100.43944, 0, 107.01427, 0, 111.84139, 0, 113.92201, 0, 113.67234, 0, 110.46262, 0, 102.60757, 0, 89.84319, 0, 72.44992, 0, 55.19692, 0, 34.57748, 0, 15.78153 ] - }, - { - "time": 0.5, - "vertices": [ -123.45187, 0, 2.46911, 0, 21.49595, 0, 43.40345, 0, 62.12716, 0, 78.07299, 0, 91.54979, 0, 104.3065, 0, 113.33989, 0, 119.82108, 0, 121.96114, 0, 121.96114, 0, 115.91174, 0, 104.80113, 0, 90.69177, 0, 75.56894, 0, 57.97707, 0, 38.43056, 0, 12.3, 0, 0, 0, -123.45187, 0, 17.23255, 0, 38.38749, 0, 57.02411, 0, 72.89646, 0, 86.27205, 0, 98.25078, 0, 107.61369, 0, 114.65815, 0, 119.83006, 0, 122.0593, 0, 121.79179, 0, 118.35281, 0, 109.93669, 0, 96.26056, 0, 77.62492, 0, 59.13956, 0, 37.0473, 0, 16.90878 ] - } - ], - "coin-invert": [ - { - "time": 0.5, - "vertices": [ -23.47706, 1.27002, -43.40744, 0, -59.7846, 0, -74.77602, 0, -85.79382, 0, -95.27632, 0, -102.23021, 0, -109.99683, 0, -115.50598, 0, -118.87909, 0, -121.32259, 0, -121.32259, 0, -121.32258, 0, -118.66653, 0, -114.15101, 0, -108.4615, 0, -99.61115, 0, -90.41013, 0, -79.48267, 0, -66.83928, 0, -51.93813, 0, -31.61855, 0, -19.56224, -1.52396, -12.52719, 0, 120.72772, 0, 120.72777, 0, -14.97203, 0, -28.48602, 0, -46.43241, 0, -62.14667, 0, -75.27165, 0, -86.18799, 0, -95.28229, 0, -102.08092, 0, -109.98608, 0, -115.7252, 0, -119.52184, 0, -122.15746, 0, -123.04041, 0, -122.68725, 0, -120.4799, 0, -116.33008, 0, -110.76754, 0, -103.44593, 0, -95.76433, 0, -85.61052, 0, -76.07477, 0, -64.50826, 0, -51.44074, 0, -37.66688, 0, -25.39402 ] - }, - { - "time": 0.7667, - "vertices": [ -12.2558, 0, -21.82668, 0, -29.4435, 0, -36.06335, 0, -40.92855, 0, -45.1158, 0, -48.18647, 0, -51.61602, 0, -54.04874, 0, -55.53822, 0, -56.61722, 0, -56.61722, 0, -56.61721, 0, -55.44436, 0, -53.45041, 0, -50.93806, 0, -47.02994, 0, -42.967, 0, -38.1417, 0, -32.55868, 0, -25.97868, 0, -17.00604, 0, -10.78498, 0, -5.84602, 0, 56.33961, 0, 56.33963, 0, -6.98695, 0, -13.29348, 0, -21.66846, 0, -29.00178, 0, -35.12677, 0, -40.22107, 0, -44.46507, 0, -47.63776, 0, -51.32684, 0, -54.0051, 0, -55.77686, 0, -57.00682, 0, -57.41886, 0, -57.25405, 0, -56.22396, 0, -54.28737, 0, -51.69152, 0, -48.27477, 0, -44.69002, 0, -39.95158, 0, -35.50156, 0, -30.10386, 0, -24.00568, 0, -17.57788, 0, -11.85054 ] - }, - { - "time": 1, - "vertices": [ -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001, 0, -17.76001 ] - } - ] - } - } - } - } -} -} \ No newline at end of file diff --git a/spine-sfml/data/coin-pro.skel b/spine-sfml/data/coin-pro.skel deleted file mode 100644 index b5f1965fd61dc41afb2735bf20369c7c54cbe81f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5922 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 diff --git a/spine-sfml/data/coin.atlas b/spine-sfml/data/coin.atlas deleted file mode 100644 index 4b7fd8e37..000000000 --- a/spine-sfml/data/coin.atlas +++ /dev/null @@ -1,27 +0,0 @@ - -coin.png -size: 1024,256 -format: RGBA8888 -filter: Linear,Linear -repeat: none -coin - rotate: false - xy: 2, 2 - size: 259, 245 - orig: 259, 245 - offset: 0, 0 - index: -1 -coin-invert - rotate: false - xy: 263, 2 - size: 259, 245 - orig: 259, 245 - offset: 0, 0 - index: -1 -shine - rotate: false - xy: 524, 2 - size: 72, 245 - orig: 72, 245 - offset: 0, 0 - index: -1 diff --git a/spine-sfml/data/coin.png b/spine-sfml/data/coin.png deleted file mode 100644 index 7d14a6b6f98ce71fe63666b0f08922ddbab13bf7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56635 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 diff --git a/spine-sfml/data/goblins.atlas b/spine-sfml/data/goblins.atlas deleted file mode 100644 index 0f57a0f6a..000000000 --- a/spine-sfml/data/goblins.atlas +++ /dev/null @@ -1,293 +0,0 @@ - -goblins.png -size: 1024,128 -format: RGBA8888 -filter: Linear,Linear -repeat: none -dagger - rotate: true - xy: 372, 100 - size: 26, 108 - orig: 26, 108 - offset: 0, 0 - index: -1 -goblin/eyes-closed - rotate: false - xy: 2, 7 - size: 34, 12 - orig: 34, 12 - offset: 0, 0 - index: -1 -goblin/head - rotate: false - xy: 107, 36 - size: 103, 66 - orig: 103, 66 - offset: 0, 0 - index: -1 -goblin/left-arm - rotate: false - xy: 901, 56 - size: 37, 35 - orig: 37, 35 - offset: 0, 0 - index: -1 -goblin/left-foot - rotate: false - xy: 929, 95 - size: 65, 31 - orig: 65, 31 - offset: 0, 0 - index: -1 -goblin/left-hand - rotate: false - xy: 452, 2 - size: 36, 41 - orig: 36, 41 - offset: 0, 0 - index: -1 -goblin/left-lower-leg - rotate: true - xy: 713, 93 - size: 33, 70 - orig: 33, 70 - offset: 0, 0 - index: -1 -goblin/left-shoulder - rotate: false - xy: 610, 44 - size: 29, 44 - orig: 29, 44 - offset: 0, 0 - index: -1 -goblin/left-upper-leg - rotate: true - xy: 638, 93 - size: 33, 73 - orig: 33, 73 - offset: 0, 0 - index: -1 -goblin/neck - rotate: false - xy: 490, 2 - size: 36, 41 - orig: 36, 41 - offset: 0, 0 - index: -1 -goblin/pelvis - rotate: false - xy: 482, 45 - size: 62, 43 - orig: 62, 43 - offset: 0, 0 - index: -1 -goblin/right-arm - rotate: true - xy: 690, 2 - size: 23, 50 - orig: 23, 50 - offset: 0, 0 - index: -1 -goblin/right-foot - rotate: false - xy: 771, 58 - size: 63, 33 - orig: 63, 33 - offset: 0, 0 - index: -1 -goblin/right-hand - rotate: false - xy: 940, 56 - size: 36, 37 - orig: 36, 37 - offset: 0, 0 - index: -1 -goblin/right-lower-leg - rotate: true - xy: 482, 90 - size: 36, 76 - orig: 36, 76 - offset: 0, 0 - index: -1 -goblin/right-shoulder - rotate: true - xy: 602, 3 - size: 39, 45 - orig: 39, 45 - offset: 0, 0 - index: -1 -goblin/right-upper-leg - rotate: true - xy: 641, 57 - size: 34, 63 - orig: 34, 63 - offset: 0, 0 - index: -1 -goblin/torso - rotate: true - xy: 212, 34 - size: 68, 96 - orig: 68, 96 - offset: 0, 0 - index: -1 -goblin/undie-straps - rotate: false - xy: 380, 5 - size: 55, 19 - orig: 55, 19 - offset: 0, 0 - index: -1 -goblin/undies - rotate: false - xy: 174, 5 - size: 36, 29 - orig: 36, 29 - offset: 0, 0 - index: -1 -goblingirl/eyes-closed - rotate: false - xy: 269, 11 - size: 37, 21 - orig: 37, 21 - offset: 0, 0 - index: -1 -goblingirl/head - rotate: false - xy: 2, 21 - size: 103, 81 - orig: 103, 81 - offset: 0, 0 - index: -1 -goblingirl/left-arm - rotate: true - xy: 978, 56 - size: 37, 35 - orig: 37, 35 - offset: 0, 0 - index: -1 -goblingirl/left-foot - rotate: false - xy: 107, 3 - size: 65, 31 - orig: 65, 31 - offset: 0, 0 - index: -1 -goblingirl/left-hand - rotate: false - xy: 565, 2 - size: 35, 40 - orig: 35, 40 - offset: 0, 0 - index: -1 -goblingirl/left-lower-leg - rotate: true - xy: 785, 93 - size: 33, 70 - orig: 33, 70 - offset: 0, 0 - index: -1 -goblingirl/left-shoulder - rotate: true - xy: 690, 27 - size: 28, 46 - orig: 28, 46 - offset: 0, 0 - index: -1 -goblingirl/left-upper-leg - rotate: true - xy: 857, 93 - size: 33, 70 - orig: 33, 70 - offset: 0, 0 - index: -1 -goblingirl/neck - rotate: false - xy: 528, 2 - size: 35, 41 - orig: 35, 41 - offset: 0, 0 - index: -1 -goblingirl/pelvis - rotate: false - xy: 546, 45 - size: 62, 43 - orig: 62, 43 - offset: 0, 0 - index: -1 -goblingirl/right-arm - rotate: false - xy: 452, 48 - size: 28, 50 - orig: 28, 50 - offset: 0, 0 - index: -1 -goblingirl/right-foot - rotate: false - xy: 836, 58 - size: 63, 33 - orig: 63, 33 - offset: 0, 0 - index: -1 -goblingirl/right-hand - rotate: true - xy: 771, 20 - size: 36, 37 - orig: 36, 37 - offset: 0, 0 - index: -1 -goblingirl/right-lower-leg - rotate: true - xy: 560, 90 - size: 36, 76 - orig: 36, 76 - offset: 0, 0 - index: -1 -goblingirl/right-shoulder - rotate: false - xy: 649, 10 - size: 39, 45 - orig: 39, 45 - offset: 0, 0 - index: -1 -goblingirl/right-upper-leg - rotate: true - xy: 706, 57 - size: 34, 63 - orig: 34, 63 - offset: 0, 0 - index: -1 -goblingirl/torso - rotate: false - xy: 310, 2 - size: 68, 96 - orig: 68, 96 - offset: 0, 0 - index: -1 -goblingirl/undie-straps - rotate: false - xy: 212, 13 - size: 55, 19 - orig: 55, 19 - offset: 0, 0 - index: -1 -goblingirl/undies - rotate: false - xy: 810, 27 - size: 36, 29 - orig: 36, 29 - offset: 0, 0 - index: -1 -shield - rotate: false - xy: 380, 26 - size: 70, 72 - orig: 70, 72 - offset: 0, 0 - index: -1 -spear - rotate: true - xy: 2, 104 - size: 22, 368 - orig: 22, 368 - offset: 0, 0 - index: -1 diff --git a/spine-sfml/data/goblins.png b/spine-sfml/data/goblins.png deleted file mode 100644 index 9d1ae572a556c906b8636f0d6375f7c406ff24c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 210574 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