Browse Source

[c] More skin API changes, see #841.

badlogic 6 years ago
parent
commit
225472de93

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

@@ -41,7 +41,7 @@ extern "C" {
 #endif
 
 typedef struct spPointAttachment {
-	spVertexAttachment super;
+	spAttachment super;
 	float x, y, rotation;
 	spColor color;
 } spPointAttachment;

+ 30 - 2
spine-c/spine-c/include/spine/Skin.h

@@ -32,6 +32,10 @@
 
 #include <spine/dll.h>
 #include <spine/Attachment.h>
+#include <spine/IkConstraintData.h>
+#include <spine/TransformConstraintData.h>
+#include <spine/PathConstraintData.h>
+#include <spine/Array.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -42,18 +46,33 @@ extern "C" {
 
 struct spSkeleton;
 
+_SP_ARRAY_DECLARE_TYPE(spBoneDataArray, spBoneData*)
+_SP_ARRAY_DECLARE_TYPE(spIkConstraintDataArray, spIkConstraintData*)
+_SP_ARRAY_DECLARE_TYPE(spTransformConstraintDataArray, spTransformConstraintData*)
+_SP_ARRAY_DECLARE_TYPE(spPathConstraintDataArray, spPathConstraintData*)
+
 typedef struct spSkin {
 	const char* const name;
 
+	spBoneDataArray* bones;
+	spIkConstraintDataArray* ikConstraints;
+	spTransformConstraintDataArray* transformConstraints;
+	spPathConstraintDataArray* pathConstraints;
+
 #ifdef __cplusplus
 	spSkin() :
-		name(0) {
+		name(0),
+		bones(0),
+		ikConstraints(0),
+		transformConstraints(0),
+		pathConstraints(0) {
 	}
 #endif
 } spSkin;
 
 /* Private structs, needed by Skeleton */
 typedef struct _Entry _Entry;
+typedef struct _Entry spSkinEntry;
 struct _Entry {
 	int slotIndex;
 	const char* name;
@@ -64,7 +83,7 @@ struct _Entry {
 typedef struct _SkinHashTableEntry _SkinHashTableEntry;
 struct _SkinHashTableEntry {
 	_Entry* entry;
-	_SkinHashTableEntry* next;  /* list for elements with same hashes */
+	_SkinHashTableEntry* next;
 };
 
 typedef struct {
@@ -87,6 +106,15 @@ SP_API const char* spSkin_getAttachmentName (const spSkin* self, int slotIndex,
 /** Attach each attachment in this skin if the corresponding attachment in oldSkin is currently attached. */
 SP_API void spSkin_attachAll (const spSkin* self, struct spSkeleton* skeleton, const spSkin* oldspSkin);
 
+/** Adds all attachments, bones, and constraints from the specified skin to this skin. */
+SP_API void spSkin_addSkin(spSkin* self, const spSkin* other);
+
+/** Returns all attachments in this skin. */
+SP_API spSkinEntry* spSkin_getAttachments(const spSkin* self);
+
+/** Clears all attachments, bones, and constraints. */
+SP_API void spSkin_clear(spSkin* self);
+
 #ifdef SPINE_SHORT_NAMES
 typedef spSkin Skin;
 #define Skin_create(...) spSkin_create(__VA_ARGS__)

+ 1 - 1
spine-c/spine-c/include/spine/extension.h

@@ -277,7 +277,7 @@ void _spAttachmentLoader_setUnknownTypeError (spAttachmentLoader* self, spAttach
 /**/
 
 void _spAttachment_init (spAttachment* self, const char* name, spAttachmentType type,
-void (*dispose) (spAttachment* self));
+void (*dispose) (spAttachment* self), spAttachment* (*copy) (spAttachment* self));
 void _spAttachment_deinit (spAttachment* self);
 void _spVertexAttachment_init (spVertexAttachment* self);
 void _spVertexAttachment_deinit (spVertexAttachment* self);

+ 1 - 1
spine-c/spine-c/src/spine/AnimationState.c

@@ -1004,7 +1004,7 @@ void _spTrackEntry_computeNotLast(spTrackEntry* entry, spAnimationState* state)
 	spTimeline** timelines ;
 	int timelinesCount;
 	int* timelineMode;
-	int i, n;
+	int i;
 
 	timelines = entry->animation->timelines;
 	timelinesCount = entry->animation->timelinesCount;

+ 1 - 1
spine-c/spine-c/src/spine/AtlasAttachmentLoader.c

@@ -81,7 +81,7 @@ spAttachment* _spAtlasAttachmentLoader_createAttachment (spAttachmentLoader* loa
 	case SP_ATTACHMENT_PATH:
 		return SUPER(SUPER(spPathAttachment_create(name)));
 	case SP_ATTACHMENT_POINT:
-		return SUPER(SUPER(spPointAttachment_create(name)));
+		return SUPER(spPointAttachment_create(name));
 	case SP_ATTACHMENT_CLIPPING:
 		return SUPER(SUPER(spClippingAttachment_create(name)));
 	default:

+ 9 - 5
spine-c/spine-c/src/spine/Attachment.c

@@ -33,18 +33,18 @@
 
 typedef struct _spAttachmentVtable {
 	void (*dispose) (spAttachment* self);
+	spAttachment* (*copy) (spAttachment* self);
 } _spAttachmentVtable;
 
 void _spAttachment_init (spAttachment* self, const char* name, spAttachmentType type, /**/
-		void (*dispose) (spAttachment* self)) {
+		void (*dispose) (spAttachment* self), spAttachment* (*copy) (spAttachment* self)) {
 
 	CONST_CAST(_spAttachmentVtable*, self->vtable) = NEW(_spAttachmentVtable);
-	VTABLE(spAttachment, self) ->dispose = dispose;
+	VTABLE(spAttachment, self)->dispose = dispose;
+	VTABLE(spAttachment, self)->copy = copy;
 
 	MALLOC_STR(self->name, name);
 	CONST_CAST(spAttachmentType, self->type) = type;
-
-	self->refCount++;
 }
 
 void _spAttachment_deinit (spAttachment* self) {
@@ -53,8 +53,12 @@ void _spAttachment_deinit (spAttachment* self) {
 	FREE(self->name);
 }
 
+spAttachment* spAttachment_copy (spAttachment* self) {
+	return VTABLE(spAttachment, self) ->copy(self);
+}
+
 void spAttachment_dispose (spAttachment* self) {
 	self->refCount--;
-	if (self->refCount == 0)
+	if (self->refCount <= 0)
 		VTABLE(spAttachment, self) ->dispose(self);
 }

+ 5 - 1
spine-c/spine-c/src/spine/BoundingBoxAttachment.c

@@ -38,9 +38,13 @@ void _spBoundingBoxAttachment_dispose (spAttachment* attachment) {
 	FREE(self);
 }
 
+spAttachment* _spBoundingBoxAttachment_copy (spAttachment* attachment) {
+
+}
+
 spBoundingBoxAttachment* spBoundingBoxAttachment_create (const char* name) {
 	spBoundingBoxAttachment* self = NEW(spBoundingBoxAttachment);
 	_spVertexAttachment_init(SUPER(self));
-	_spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_BOUNDING_BOX, _spBoundingBoxAttachment_dispose);
+	_spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_BOUNDING_BOX, _spBoundingBoxAttachment_dispose, _spBoundingBoxAttachment_copy);
 	return self;
 }

+ 5 - 1
spine-c/spine-c/src/spine/ClippingAttachment.c

@@ -38,10 +38,14 @@ void _spClippingAttachment_dispose (spAttachment* attachment) {
 	FREE(self);
 }
 
+spAttachment* _spClippingAttachment_copy (spAttachment* attachment) {
+
+}
+
 spClippingAttachment* spClippingAttachment_create (const char* name) {
 	spClippingAttachment* self = NEW(spClippingAttachment);
 	_spVertexAttachment_init(SUPER(self));
-	_spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_CLIPPING, _spClippingAttachment_dispose);
+	_spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_CLIPPING, _spClippingAttachment_dispose, _spClippingAttachment_copy);
 	self->endSlot = 0;
 	return self;
 }

+ 7 - 2
spine-c/spine-c/src/spine/MeshAttachment.c

@@ -44,19 +44,24 @@ void _spMeshAttachment_dispose (spAttachment* attachment) {
 	FREE(self);
 }
 
+spAttachment* _spMeshAttachment_copy (spAttachment* attachment) {
+
+}
+
 spMeshAttachment* spMeshAttachment_create (const char* name) {
 	spMeshAttachment* self = NEW(spMeshAttachment);
 	_spVertexAttachment_init(SUPER(self));
 	spColor_setFromFloats(&self->color, 1, 1, 1, 1);
-	_spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_MESH, _spMeshAttachment_dispose);
+	_spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_MESH, _spMeshAttachment_dispose, _spMeshAttachment_copy);
 	return self;
 }
 
 void spMeshAttachment_updateUVs (spMeshAttachment* self) {
 	int i, n;
+	float* uvs;
 	int verticesLength = SUPER(self)->worldVerticesLength;
 	FREE(self->uvs);
-	float* uvs = self->uvs = MALLOC(float, verticesLength);
+	uvs = self->uvs = MALLOC(float, verticesLength);
 	n = verticesLength;
 	float u = self->regionU, v = self->regionV;
 	float width = 0, height = 0;

+ 5 - 1
spine-c/spine-c/src/spine/PathAttachment.c

@@ -39,9 +39,13 @@ void _spPathAttachment_dispose (spAttachment* attachment) {
 	FREE(self);
 }
 
+spAttachment* _spPathAttachment_copy (spAttachment* attachment) {
+
+}
+
 spPathAttachment* spPathAttachment_create (const char* name) {
 	spPathAttachment* self = NEW(spPathAttachment);
 	_spVertexAttachment_init(SUPER(self));
-	_spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_PATH, _spPathAttachment_dispose);
+	_spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_PATH, _spPathAttachment_dispose, _spPathAttachment_copy);
 	return self;
 }

+ 13 - 6
spine-c/spine-c/src/spine/PointAttachment.c

@@ -31,17 +31,24 @@
 #include <spine/extension.h>
 
 void _spPointAttachment_dispose (spAttachment* attachment) {
-	spPathAttachment* self = SUB_CAST(spPathAttachment, attachment);
-
-	_spVertexAttachment_deinit(SUPER(self));
-
+	spPointAttachment* self = SUB_CAST(spPointAttachment, attachment);
+	_spAttachment_deinit(attachment);
 	FREE(self);
 }
 
+spAttachment* _spPointAttachment_copy (spAttachment* attachment) {
+	spPointAttachment* self = SUB_CAST(spPointAttachment, attachment);
+	spPointAttachment* copy = spPointAttachment_create(attachment->name);
+	copy->x = self->x;
+	copy->y = self->y;
+	copy->rotation = self->rotation;
+	spColor_setFromColor(&copy->color, &self->color);
+	return SUPER(copy);
+}
+
 spPointAttachment* spPointAttachment_create (const char* name) {
 	spPointAttachment* self = NEW(spPointAttachment);
-	_spVertexAttachment_init(SUPER(self));
-	_spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_POINT, _spPointAttachment_dispose);
+	_spAttachment_init(SUPER(self), name, SP_ATTACHMENT_POINT, _spPointAttachment_dispose, _spPointAttachment_copy);
 	return self;
 }
 

+ 25 - 1
spine-c/spine-c/src/spine/RegionAttachment.c

@@ -41,12 +41,36 @@ void _spRegionAttachment_dispose (spAttachment* attachment) {
 	FREE(self);
 }
 
+spAttachment* _spRegionAttachment_copy (spAttachment* attachment) {
+	spRegionAttachment* self = SUB_CAST(spRegionAttachment, attachment);
+	spRegionAttachment* copy = spRegionAttachment_create(attachment->name);
+	copy->regionWidth = self->regionWidth;
+	copy->regionHeight = self->regionHeight;
+	copy->regionOffsetX = self->regionOffsetX;
+	copy->regionOffsetY = self->regionOffsetY;
+	copy->regionOriginalWidth = self->regionOriginalWidth;
+	copy->regionOriginalHeight = self->regionOriginalHeight;
+	copy->rendererObject = self->rendererObject;
+	MALLOC_STR(copy->path, self->path);
+	copy->x = self->x;
+	copy->y = self->y;
+	copy->scaleX = self->scaleX;
+	copy->scaleY = self->scaleY;
+	copy->rotation = self->rotation;
+	copy->width = self->width;
+	copy->height = self->height;
+	memcpy(copy->uvs, self->uvs, sizeof(float) * 8);
+	memcpy(copy->offset, self->offset, sizeof(float) * 8);
+	spColor_setFromColor(&copy->color, &self->color);
+	return SUPER(copy);
+}
+
 spRegionAttachment* spRegionAttachment_create (const char* name) {
 	spRegionAttachment* self = NEW(spRegionAttachment);
 	self->scaleX = 1;
 	self->scaleY = 1;
 	spColor_setFromFloats(&self->color, 1, 1, 1, 1);
-	_spAttachment_init(SUPER(self), name, SP_ATTACHMENT_REGION, _spRegionAttachment_dispose);
+	_spAttachment_init(SUPER(self), name, SP_ATTACHMENT_REGION, _spRegionAttachment_dispose, _spRegionAttachment_copy);
 	return self;
 }
 

+ 107 - 9
spine-c/spine-c/src/spine/Skin.c

@@ -30,6 +30,11 @@
 #include <spine/Skin.h>
 #include <spine/extension.h>
 
+_SP_ARRAY_IMPLEMENT_TYPE(spBoneDataArray, spBoneData*)
+_SP_ARRAY_IMPLEMENT_TYPE(spIkConstraintDataArray, spIkConstraintData*)
+_SP_ARRAY_IMPLEMENT_TYPE(spTransformConstraintDataArray, spTransformConstraintData*)
+_SP_ARRAY_IMPLEMENT_TYPE(spPathConstraintDataArray, spPathConstraintData*)
+
 _Entry* _Entry_create (int slotIndex, const char* name, spAttachment* attachment) {
 	_Entry* self = NEW(_Entry);
 	self->slotIndex = slotIndex;
@@ -59,6 +64,10 @@ static void _SkinHashTableEntry_dispose (_SkinHashTableEntry* self) {
 spSkin* spSkin_create (const char* name) {
 	spSkin* self = SUPER(NEW(_spSkin));
 	MALLOC_STR(self->name, name);
+	self->bones = spBoneDataArray_create(4);
+	self->ikConstraints = spIkConstraintDataArray_create(4);
+	self->transformConstraints = spTransformConstraintDataArray_create(4);
+	self->pathConstraints = spPathConstraintDataArray_create(4);
 	return self;
 }
 
@@ -86,21 +95,42 @@ void spSkin_dispose (spSkin* self) {
 		}
 	}
 
+	spBoneDataArray_dispose(self->bones);
+	spIkConstraintDataArray_dispose(self->ikConstraints);
+	spTransformConstraintDataArray_dispose(self->transformConstraints);
+	spPathConstraintDataArray_dispose(self->pathConstraints);
 	FREE(self->name);
 	FREE(self);
 }
 
 void spSkin_setAttachment (spSkin* self, int slotIndex, const char* name, spAttachment* attachment) {
-	_Entry* newEntry = _Entry_create(slotIndex, name, attachment);
-	newEntry->next = SUB_CAST(_spSkin, self)->entries;
-	SUB_CAST(_spSkin, self)->entries = newEntry;
-
-	{
-		unsigned int hashTableIndex = (unsigned int)slotIndex % SKIN_ENTRIES_HASH_TABLE_SIZE;
+	_SkinHashTableEntry* existingEntry = 0;
+	const _SkinHashTableEntry* hashEntry = SUB_CAST(_spSkin, self)->entriesHashTable[(unsigned int)slotIndex % SKIN_ENTRIES_HASH_TABLE_SIZE];
+	while (hashEntry) {
+		if (hashEntry->entry->slotIndex == slotIndex && strcmp(hashEntry->entry->name, name) == 0) {
+			existingEntry = hashEntry;
+			break;
+		}
+		hashEntry = hashEntry->next;
+	}
 
-		_SkinHashTableEntry* newHashEntry = _SkinHashTableEntry_create(newEntry);
-		newHashEntry->next = SUB_CAST(_spSkin, self)->entriesHashTable[hashTableIndex];
-		SUB_CAST(_spSkin, self)->entriesHashTable[hashTableIndex] = newHashEntry;
+	if (attachment) attachment->refCount++;
+
+	if (existingEntry) {
+		if (hashEntry->entry->attachment) spAttachment_dispose(hashEntry->entry->attachment);
+		hashEntry->entry->attachment = attachment;
+	} else {
+		_Entry* newEntry = _Entry_create(slotIndex, name, attachment);
+		newEntry->next = SUB_CAST(_spSkin, self)->entries;
+		SUB_CAST(_spSkin, self)->entries = newEntry;
+		{
+			unsigned int hashTableIndex = (unsigned int)slotIndex % SKIN_ENTRIES_HASH_TABLE_SIZE;
+			_SkinHashTableEntry** hashTable = SUB_CAST(_spSkin, self)->entriesHashTable;
+
+			_SkinHashTableEntry* newHashEntry = _SkinHashTableEntry_create(newEntry);
+			newHashEntry->next = hashTable[hashTableIndex];
+			SUB_CAST(_spSkin, self)->entriesHashTable[hashTableIndex] = newHashEntry;
+		}
 	}
 }
 
@@ -137,3 +167,71 @@ void spSkin_attachAll (const spSkin* self, spSkeleton* skeleton, const spSkin* o
 		entry = entry->next;
 	}
 }
+
+void spSkin_addSkin(spSkin* self, const spSkin* other) {
+	int i = 0;
+
+	for (i = 0; i < other->bones->size; i++) {
+		if (!spBoneDataArray_contains(self->bones, other->bones->items[i]))
+			spBoneDataArray_add(self->bones, other->bones->items[i]);
+	}
+
+	for (i = 0; i < other->ikConstraints->size; i++) {
+		if (!spIkConstraintDataArray_contains(self->ikConstraints, other->ikConstraints->items[i]))
+			spIkConstraintDataArray_add(self->ikConstraints, other->ikConstraints->items[i]);
+	}
+
+	for (i = 0; i < other->transformConstraints->size; i++) {
+		if (!spTransformConstraintDataArray_contains(self->transformConstraints, other->transformConstraints->items[i]))
+			spTransformConstraintDataArray_add(self->transformConstraints, other->transformConstraints->items[i]);
+	}
+
+	for (i = 0; i < other->pathConstraints->size; i++) {
+		if (!spPathConstraintDataArray_contains(self->pathConstraints, other->pathConstraints->items[i]))
+			spPathConstraintDataArray_add(self->pathConstraints, other->pathConstraints->items[i]);
+	}
+
+	spSkinEntry* entry = spSkin_getAttachments(other);
+	while (entry) {
+		spSkin_setAttachment(self, entry->slotIndex, entry->name, entry->attachment);
+		entry = entry->next;
+	}
+}
+
+spSkinEntry* spSkin_getAttachments(const spSkin* self) {
+	return SUB_CAST(_spSkin, self)->entries;
+}
+
+void spSkin_clear(spSkin* self) {
+	_Entry* entry = SUB_CAST(_spSkin, self)->entries;
+
+	while (entry) {
+		_Entry* nextEntry = entry->next;
+		_Entry_dispose(entry);
+		entry = nextEntry;
+	}
+
+	SUB_CAST(_spSkin, self)->entries = 0;
+
+	{
+		_SkinHashTableEntry** currentHashtableEntry = SUB_CAST(_spSkin, self)->entriesHashTable;
+		int i;
+
+		for (i = 0; i < SKIN_ENTRIES_HASH_TABLE_SIZE; ++i, ++currentHashtableEntry) {
+			_SkinHashTableEntry* hashtableEntry = *currentHashtableEntry;
+
+			while (hashtableEntry) {
+				_SkinHashTableEntry* nextEntry = hashtableEntry->next;
+				_SkinHashTableEntry_dispose(hashtableEntry);
+				hashtableEntry = nextEntry;
+			}
+
+			SUB_CAST(_spSkin, self)->entriesHashTable[i] = 0;
+		}
+	}
+
+	spBoneDataArray_clear(self->bones);
+	spIkConstraintDataArray_clear(self->ikConstraints);
+	spTransformConstraintDataArray_clear(self->transformConstraints);
+	spPathConstraintDataArray_clear(self->pathConstraints);
+}

+ 41 - 0
spine-sfml/c/example/main.cpp

@@ -446,7 +446,48 @@ void test (SkeletonData* skeletonData, Atlas* atlas) {
 	Skeleton_dispose(skeleton);
 }
 
+void testSkinsApi(SkeletonData* skeletonData, Atlas* atlas) {
+	SkeletonDrawable* drawable = new SkeletonDrawable(skeletonData);
+	drawable->timeScale = 1;
+	drawable->setUsePremultipliedAlpha(true);
+
+	Skeleton* skeleton = drawable->skeleton;
+
+	spSkin* skin = spSkin_create("test-skin");
+	spSkin_addSkin(skin, spSkeletonData_findSkin(skeletonData, "goblingirl"));
+	spSkeleton_setSkin(skeleton, skin);
+	spSkeleton_setSlotsToSetupPose(skeleton);
+
+	skeleton->x = 320;
+	skeleton->y = 590;
+	Skeleton_updateWorldTransform(skeleton);
+
+	AnimationState_setAnimationByName(drawable->state, 0, "walk", true);
+
+	sf::RenderWindow window(sf::VideoMode(640, 640), "Spine SFML - skins api");
+	window.setFramerateLimit(60);
+	sf::Event event;
+	sf::Clock deltaClock;
+	while (window.isOpen()) {
+		while (window.pollEvent(event))
+			if (event.type == sf::Event::Closed) window.close();
+
+		float delta = deltaClock.getElapsedTime().asSeconds();
+		deltaClock.restart();
+
+		drawable->update(delta);
+
+		window.clear();
+		window.draw(*drawable);
+		window.display();
+	}
+
+	spSkin_clear(skin);
+	spSkin_dispose(skin);
+}
+
 int main () {
+	testcase(testSkinsApi, "data/goblins-pro.json", "data/goblins-pro.skel", "data/goblins-pma.atlas", 1.4f);
 	testcase(test, "data/tank-pro.json", "data/tank-pro.skel", "data/tank-pma.atlas", 1.0f);
 	testcase(spineboy, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f);
 	testcase(stretchyman, "data/stretchyman-stretchy-ik-pro.json", "data/stretchyman-stretchy-ik-pro.skel", "data/stretchyman-pma.atlas", 0.6f);