瀏覽代碼

[c] Refactor atlas loading, fix up API consumers

Mario Zechner 1 月之前
父節點
當前提交
da70193a36
共有 5 個文件被更改,包括 54 次插入80 次删除
  1. 0 3
      spine-c/codegen/exclusions.txt
  2. 33 60
      spine-c/src/extensions.cpp
  3. 6 7
      spine-c/src/extensions.h
  4. 12 8
      spine-c/tests/headless-test.c
  5. 3 2
      spine-glfw/example/main-c.cpp

+ 0 - 3
spine-c/codegen/exclusions.txt

@@ -33,9 +33,6 @@ method: TrackEntry::setListener
 method: TrackEntry::getListener
 method: Atlas::Atlas
 
-# Exclude Atlas destructor - we handle atlas disposal in extensions.cpp
-method: Atlas::~Atlas
-
 # Used in UE4/cocos2dx, not used anywhere else
 method: AnimationState::setRendererObject
 method: TrackEntry::setRendererObject

+ 33 - 60
spine-c/src/extensions.cpp

@@ -40,10 +40,8 @@
 using namespace spine;
 
 // Internal structures
-struct _spine_atlas {
-	void *atlas;
-	const char **imagePaths;
-	int32_t numImagePaths;
+struct _spine_atlas_result {
+	spine_atlas atlas;
 	const char *error;
 };
 
@@ -169,7 +167,7 @@ float spine_vector_get_y(spine_vector vector) {
 }
 
 // Atlas functions
-class LiteTextureLoad : public TextureLoader {
+class SpineCTextureLoader : public TextureLoader {
 	void load(AtlasPage &page, const String &path) {
 		page.texture = (void *) (intptr_t) page.index;
 	}
@@ -177,20 +175,19 @@ class LiteTextureLoad : public TextureLoader {
 	void unload(void *texture) {
 	}
 };
-static LiteTextureLoad liteLoader;
+static SpineCTextureLoader textureLoader;
 
-spine_atlas spine_atlas_load(const char *atlasData) {
+spine_atlas_result spine_atlas_load(const char *atlasData) {
 	if (!atlasData) return nullptr;
+	_spine_atlas_result *result = SpineExtension::calloc<_spine_atlas_result>(1, __FILE__, __LINE__);
 	int32_t length = (int32_t) strlen(atlasData);
-	auto atlas = new (__FILE__, __LINE__) Atlas(atlasData, length, "", &liteLoader, true);
-	_spine_atlas *result = SpineExtension::calloc<_spine_atlas>(1, __FILE__, __LINE__);
-	result->atlas = atlas;
-	result->numImagePaths = (int32_t) atlas->getPages().size();
-	result->imagePaths = SpineExtension::calloc<const char *>(result->numImagePaths, __FILE__, __LINE__);
-	for (int i = 0; i < result->numImagePaths; i++) {
-		result->imagePaths[i] = atlas->getPages()[i]->texturePath.buffer();
+	auto atlas = new (__FILE__, __LINE__) Atlas(atlasData, length, "", &textureLoader, true);
+	if (!atlas) {
+		result->error = (const char *) strdup("Failed to load atlas");
+		return (spine_atlas_result) result;
 	}
-	return (spine_atlas) result;
+	result->atlas = (spine_atlas) atlas;
+	return (spine_atlas_result) result;
 }
 
 class CallbackTextureLoad : public TextureLoader {
@@ -216,69 +213,45 @@ public:
 };
 static CallbackTextureLoad callbackLoader;
 
-spine_atlas spine_atlas_load_callback(const char *atlasData, const char *atlasDir, spine_texture_loader_load_func load,
+spine_atlas_result spine_atlas_load_callback(const char *atlasData, const char *atlasDir, spine_texture_loader_load_func load,
 									  spine_texture_loader_unload_func unload) {
 	if (!atlasData) return nullptr;
+	_spine_atlas_result *result = SpineExtension::calloc<_spine_atlas_result>(1, __FILE__, __LINE__);
 	int32_t length = (int32_t) strlen(atlasData);
 	callbackLoader.setCallbacks(load, unload);
 	auto atlas = new (__FILE__, __LINE__) Atlas(atlasData, length, (const char *) atlasDir, &callbackLoader, true);
-	_spine_atlas *result = SpineExtension::calloc<_spine_atlas>(1, __FILE__, __LINE__);
-	result->atlas = atlas;
-	result->numImagePaths = (int32_t) atlas->getPages().size();
-	result->imagePaths = SpineExtension::calloc<const char *>(result->numImagePaths, __FILE__, __LINE__);
-	for (int i = 0; i < result->numImagePaths; i++) {
-		result->imagePaths[i] = atlas->getPages()[i]->texturePath.buffer();
+	if (!atlas) {
+		result->error = (const char *) strdup("Failed to load atlas");
+		return (spine_atlas_result) result;
 	}
-	return (spine_atlas) result;
+	result->atlas = (spine_atlas) atlas;
+	return (spine_atlas_result) result;
 }
 
-int32_t spine_atlas_get_num_image_paths(spine_atlas atlas) {
-	if (!atlas) return 0;
-	return ((_spine_atlas *) atlas)->numImagePaths;
-}
-
-const char *spine_atlas_get_image_path(spine_atlas atlas, int32_t index) {
-	if (!atlas) return nullptr;
-	_spine_atlas *_atlas = (_spine_atlas *) atlas;
-	if (index < 0 || index >= _atlas->numImagePaths) return nullptr;
-	return _atlas->imagePaths[index];
-}
-
-bool spine_atlas_is_pma(spine_atlas atlas) {
-	if (!atlas) return false;
-	Atlas *_atlas = (Atlas *) ((_spine_atlas *) atlas)->atlas;
-	for (size_t i = 0; i < _atlas->getPages().size(); i++) {
-		AtlasPage *page = _atlas->getPages()[i];
-		if (page->pma) return true;
-	}
-	return false;
+const char *spine_atlas_result_get_error(spine_atlas_result result) {
+	if (!result) return nullptr;
+	return ((_spine_atlas_result *) result)->error;
 }
 
-const char *spine_atlas_get_error(spine_atlas atlas) {
-	if (!atlas) return nullptr;
-	return ((_spine_atlas *) atlas)->error;
+spine_atlas spine_atlas_result_get_atlas(spine_atlas_result result) {
+	if (!result) return nullptr;
+	return ((_spine_atlas_result *) result)->atlas;
 }
 
-void spine_atlas_dispose(spine_atlas atlas) {
-	if (!atlas) return;
-	_spine_atlas *_atlas = (_spine_atlas *) atlas;
-	if (_atlas->atlas) {
-		delete (Atlas *) _atlas->atlas;
-	}
-	if (_atlas->imagePaths) {
-		SpineExtension::free(_atlas->imagePaths, __FILE__, __LINE__);
-	}
-	if (_atlas->error) {
-		SpineExtension::free(_atlas->error, __FILE__, __LINE__);
+void spine_atlas_result_dispose(spine_atlas_result result) {
+	if (!result) return;
+	_spine_atlas_result *_result = (_spine_atlas_result *) result;
+	if (_result->error) {
+		SpineExtension::free(_result->error, __FILE__, __LINE__);
 	}
-	SpineExtension::free(_atlas, __FILE__, __LINE__);
+	SpineExtension::free(_result, __FILE__, __LINE__);
 }
 
 // Skeleton data loading
 spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const char *skeletonData, const char *path) {
 	if (!atlas || !skeletonData) return nullptr;
 	_spine_skeleton_data_result *result = SpineExtension::calloc<_spine_skeleton_data_result>(1, __FILE__, __LINE__);
-	SkeletonJson json((Atlas *) ((_spine_atlas *) atlas)->atlas);
+	SkeletonJson json((Atlas *) atlas);
 	json.setScale(1);
 
 	SkeletonData *data = json.readSkeletonData(skeletonData);
@@ -314,7 +287,7 @@ spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, cons
 spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, const uint8_t *skeletonData, int32_t length, const char *path) {
 	if (!atlas || !skeletonData) return nullptr;
 	_spine_skeleton_data_result *result = SpineExtension::calloc<_spine_skeleton_data_result>(1, __FILE__, __LINE__);
-	SkeletonBinary binary((Atlas *) ((_spine_atlas *) atlas)->atlas);
+	SkeletonBinary binary((Atlas *) atlas);
 	binary.setScale(1);
 
 	SkeletonData *data = binary.readSkeletonData((const unsigned char *) skeletonData, length);

+ 6 - 7
spine-c/src/extensions.h

@@ -39,6 +39,7 @@ extern "C" {
 #include "generated/skeleton_data.h"
 
 // Custom types for spine-c-new (not generated)
+SPINE_OPAQUE_TYPE(spine_atlas_result)
 SPINE_OPAQUE_TYPE(spine_skeleton_data_result)
 SPINE_OPAQUE_TYPE(spine_bounds)
 SPINE_OPAQUE_TYPE(spine_vector)
@@ -73,14 +74,12 @@ SPINE_C_API float spine_vector_get_x(spine_vector vector);
 SPINE_C_API float spine_vector_get_y(spine_vector vector);
 
 // Atlas functions
-SPINE_C_API spine_atlas spine_atlas_load(const char *atlasData);
-SPINE_C_API spine_atlas spine_atlas_load_callback(const char *atlasData, const char *atlasDir, spine_texture_loader_load_func load,
+SPINE_C_API spine_atlas_result spine_atlas_load(const char *atlasData);
+SPINE_C_API spine_atlas_result spine_atlas_load_callback(const char *atlasData, const char *atlasDir, spine_texture_loader_load_func load,
 												  spine_texture_loader_unload_func unload);
-SPINE_C_API int32_t spine_atlas_get_num_image_paths(spine_atlas atlas);
-SPINE_C_API const char *spine_atlas_get_image_path(spine_atlas atlas, int32_t index);
-SPINE_C_API bool spine_atlas_is_pma(spine_atlas atlas);
-SPINE_C_API const char *spine_atlas_get_error(spine_atlas atlas);
-SPINE_C_API void spine_atlas_dispose(spine_atlas atlas);
+SPINE_C_API const char *spine_atlas_result_get_error(spine_atlas_result result);
+SPINE_C_API spine_atlas spine_atlas_result_get_atlas(spine_atlas_result result);
+SPINE_C_API void spine_atlas_result_dispose(spine_atlas_result result);
 
 // Skeleton data functions
 SPINE_C_API spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, const char *skeletonData, const char *path);

+ 12 - 8
spine-c/tests/headless-test.c

@@ -161,14 +161,18 @@ int main(int argc, char *argv[]) {
 	}
 
 	// Load atlas with headless texture loader
-	spine_atlas atlas = spine_atlas_load_callback((const char *) atlasBytes, atlasDir, headlessTextureLoader, headlessTextureUnloader);
+	spine_atlas_result atlasResult = spine_atlas_load_callback((const char *) atlasBytes, atlasDir, headlessTextureLoader, headlessTextureUnloader);
 	free(atlasBytes);
 
-	if (!atlas) {
-		fprintf(stderr, "Failed to load atlas\n");
+	const char *atlasError = spine_atlas_result_get_error(atlasResult);
+	if (atlasError) {
+		fprintf(stderr, "Failed to load atlas: %s\n", atlasError);
+		spine_atlas_result_dispose(atlasResult);
 		return 1;
 	}
 
+	spine_atlas atlas = spine_atlas_result_get_atlas(atlasResult);
+
 	// Load skeleton data
 	spine_skeleton_data_result result = {0};
 	spine_skeleton_data skeletonData = NULL;
@@ -178,7 +182,7 @@ int main(int argc, char *argv[]) {
 		uint8_t *skeletonBytes = read_file(skeletonPath, &skeletonLength);
 		if (!skeletonBytes) {
 			fprintf(stderr, "Failed to read skeleton file\n");
-			spine_atlas_dispose(atlas);
+			spine_atlas_result_dispose(atlasResult);
 			return 1;
 		}
 		result = spine_skeleton_data_load_json(atlas, (const char *) skeletonBytes, skeletonPath);
@@ -188,7 +192,7 @@ int main(int argc, char *argv[]) {
 		uint8_t *skeletonBytes = read_file(skeletonPath, &skeletonLength);
 		if (!skeletonBytes) {
 			fprintf(stderr, "Failed to read skeleton file\n");
-			spine_atlas_dispose(atlas);
+			spine_atlas_result_dispose(atlasResult);
 			return 1;
 		}
 		result = spine_skeleton_data_load_binary(atlas, skeletonBytes, skeletonLength, skeletonPath);
@@ -200,7 +204,7 @@ int main(int argc, char *argv[]) {
 		const char *error = spine_skeleton_data_result_get_error(result);
 		fprintf(stderr, "Failed to load skeleton data: %s\n", error ? error : "Unknown error");
 		spine_skeleton_data_result_dispose(result);
-		spine_atlas_dispose(atlas);
+		spine_atlas_result_dispose(atlasResult);
 		return 1;
 	}
 
@@ -227,7 +231,7 @@ int main(int argc, char *argv[]) {
 			spine_animation_state_data_dispose(stateData);
 			spine_skeleton_dispose(skeleton);
 			spine_skeleton_data_result_dispose(result);
-			spine_atlas_dispose(atlas);
+			spine_atlas_result_dispose(atlasResult);
 			return 1;
 		}
 		spine_animation_state_set_animation_1(state, 0, animationName, 1);
@@ -247,7 +251,7 @@ int main(int argc, char *argv[]) {
 	spine_animation_state_data_dispose(stateData);
 	spine_skeleton_dispose(skeleton);
 	spine_skeleton_data_result_dispose(result);
-	spine_atlas_dispose(atlas);
+	spine_atlas_result_dispose(atlasResult);
 
 	return 0;
 }

+ 3 - 2
spine-glfw/example/main-c.cpp

@@ -91,11 +91,12 @@ int main() {
 	// Load the atlas and the skeleton data
 	int atlas_length = 0;
 	uint8_t *atlas_bytes = read_file("data/spineboy-pma.atlas", &atlas_length);
-	spine_atlas atlas = spine_atlas_load_callback((const char *) atlas_bytes, "data/", load_texture, unload_texture);
+	spine_atlas_result result = spine_atlas_load_callback((const char *) atlas_bytes, "data/", load_texture, unload_texture);
+	spine_atlas atlas = spine_atlas_result_get_atlas(result);
+
 	int skeleton_length = 0;
 	// uint8_t *skeleton_bytes = read_file("data/spineboy-pro.skel", &skeleton_length);
 	// spine_skeleton_data_result result = spine_skeleton_data_load_binary(atlas, skeleton_bytes, skeleton_length);
-
 	uint8_t *skeleton_bytes = read_file("data/spineboy-pro.json", &skeleton_length);
 	spine_skeleton_data_result result2 = spine_skeleton_data_load_json(atlas, (const char *) skeleton_bytes, "data/");
 	spine_skeleton_data skeleton_data = spine_skeleton_data_result_get_data(result2);