Andre Weissflog 3 роки тому
батько
коміт
093bfb77cd
2 змінених файлів з 114 додано та 32 видалено
  1. 102 20
      tests/functional/sokol_spine_test.c
  2. 12 12
      util/sokol_spine.h

+ 102 - 20
tests/functional/sokol_spine_test.c

@@ -19,14 +19,18 @@ static void shutdown() {
     sg_shutdown();
 }
 
+// NOTE: this guarantees that the data is zero terminated (the returned size doesn't count the zero!)
 static sspine_range load_data(const char* path) {
     assert(path);
     FILE* fp = fopen(path, "rb");
     assert(fp);
     fseek(fp, 0, SEEK_END);
-    size_t size = (size_t)ftell(fp);
+    const size_t size = (size_t)ftell(fp);
     fseek(fp, 0, SEEK_SET);
-    void* ptr = malloc(size);
+    // room for terminating zero
+    const size_t alloc_size = size + 1;
+    uint8_t* ptr = (uint8_t*)malloc(alloc_size);
+    memset(ptr, 0, alloc_size);
     fread(ptr, size, 1, fp);
     fclose(fp);
     return (sspine_range) { .ptr = ptr, .size = size };
@@ -36,16 +40,46 @@ static void free_data(sspine_range r) {
     free((void*)r.ptr);
 }
 
+static sspine_atlas create_atlas(void) {
+    sspine_range atlas_data = load_data("spineboy.atlas");
+    sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){
+        .data = atlas_data
+    });
+    free_data(atlas_data);
+    return atlas;
+}
+
+static sspine_skeleton create_skeleton_json(sspine_atlas atlas) {
+    sspine_range skeleton_json_data = load_data("spineboy-pro.json");
+    sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
+        .atlas = atlas,
+        .json_data = (const char*)skeleton_json_data.ptr
+    });
+    free_data(skeleton_json_data);
+    return skeleton;
+}
+
 UTEST(sokol_spine, default_init_shutdown) {
     // FIXME!
     T(true);
 }
 
+UTEST(sokol_spine, make_destroy_atlas_ok) {
+    init();
+    sspine_atlas atlas = create_atlas();
+    T(sspine_get_atlas_resource_state(atlas) == SSPINE_RESOURCESTATE_VALID);
+    T(sspine_atlas_valid(atlas));
+    sspine_destroy_atlas(atlas);
+    T(sspine_get_atlas_resource_state(atlas) == SSPINE_RESOURCESTATE_INVALID);
+    T(!sspine_atlas_valid(atlas))
+    shutdown();
+}
+
 UTEST(sokol_spine, make_atlas_fail_no_data) {
     init();
     sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){0});
     T(atlas.id != SSPINE_INVALID_ID);
-    T(sspine_get_atlas_state(atlas) == SSPINE_RESOURCESTATE_FAILED);
+    T(sspine_get_atlas_resource_state(atlas) == SSPINE_RESOURCESTATE_FAILED);
     T(!sspine_atlas_valid(atlas));
     shutdown();
 }
@@ -63,25 +97,9 @@ UTEST(sokol_spine, failed_atlas_no_images) {
 
 // NOTE: spine-c doesn't detect wrong/corrupt atlas file data, so we can't test for that
 
-UTEST(sokol_spine, make_atlas_ok) {
-    init();
-    sspine_range data = load_data("spineboy.atlas");
-    sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){
-        .data = data
-    });
-    free_data(data);
-    T(sspine_get_atlas_state(atlas) == SSPINE_RESOURCESTATE_VALID);
-    T(sspine_atlas_valid(atlas));
-    shutdown();
-}
-
 UTEST(sokol_spine, atlas_image_info) {
     init();
-    sspine_range data = load_data("spineboy.atlas");
-    sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){
-        .data = data
-    });
-    free_data(data);
+    sspine_atlas atlas = create_atlas();
     T(sspine_atlas_valid(atlas));
     T(sspine_get_num_images(atlas) == 1);
     const sspine_image_info img_info = sspine_get_image_info(atlas, 0);
@@ -90,5 +108,69 @@ UTEST(sokol_spine, atlas_image_info) {
     T(strcmp(img_info.filename, "spineboy.png") == 0);
     T(img_info.min_filter == SG_FILTER_LINEAR);
     T(img_info.mag_filter == SG_FILTER_LINEAR);
+    T(img_info.wrap_u == SG_WRAP_MIRRORED_REPEAT);
+    T(img_info.wrap_v == SG_WRAP_MIRRORED_REPEAT);
+    T(img_info.width == 1024);
+    T(img_info.height == 256);
+    shutdown();
+}
+
+UTEST(sokol_spine, make_destroy_skeleton_ok) {
+    init();
+    sspine_skeleton skeleton = create_skeleton_json(create_atlas());
+    T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_VALID);
+    T(sspine_skeleton_valid(skeleton));
+    sspine_destroy_skeleton(skeleton);
+    T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_INVALID);
+    T(!sspine_skeleton_valid(skeleton));
+    shutdown();
+}
+
+UTEST(sokol_spine, make_skeleton_fail_no_data) {
+    init();
+    sspine_atlas atlas = create_atlas();
+    sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
+        .atlas = atlas
+    });
+    T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_FAILED);
+    T(!sspine_skeleton_valid(skeleton));
+    shutdown();
+}
+
+UTEST(sokol_spine, make_skeleton_fail_no_atlas) {
+    init();
+    sspine_range skeleton_json_data = load_data("spineboy-pro.json");
+    sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
+        .json_data = (const char*)skeleton_json_data.ptr
+    });
+    free_data(skeleton_json_data);
+    T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_FAILED);
+    T(!sspine_skeleton_valid(skeleton));
     shutdown();
 }
+
+UTEST(sokol_spine, make_skeleton_fail_with_failed_atlas) {
+    init();
+    sspine_atlas atlas = sspine_make_atlas(&(sspine_atlas_desc){0});
+    T(sspine_get_atlas_resource_state(atlas) == SSPINE_RESOURCESTATE_FAILED);
+    sspine_skeleton skeleton = create_skeleton_json(atlas);
+    T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_FAILED);
+    T(!sspine_skeleton_valid(skeleton));
+    shutdown();
+}
+
+UTEST(sokol_spine, make_skeleton_fail_corrupt_data) {
+    init();
+    sspine_atlas atlas = create_atlas();
+    const char* invalid_json_data = "This is not valid JSON!";
+    sspine_skeleton skeleton = sspine_make_skeleton(&(sspine_skeleton_desc){
+        .atlas = atlas,
+        .json_data = (const char*)invalid_json_data,
+    });
+    T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_FAILED);
+    sspine_destroy_skeleton(skeleton);
+    T(sspine_get_skeleton_resource_state(skeleton) == SSPINE_RESOURCESTATE_INVALID);
+    shutdown();
+}
+
+// FIXME: test for binary skeleton data

+ 12 - 12
util/sokol_spine.h

@@ -210,10 +210,10 @@ SOKOL_SPINE_API_DECL void sspine_destroy_skeleton(sspine_skeleton skeleton);
 SOKOL_SPINE_API_DECL void sspine_destroy_instance(sspine_instance instance);
 
 // get current resource state (INITIAL, ALLOC, VALID, FAILD, INVALID)
-SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_context_state(sspine_context context);
-SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_atlas_state(sspine_atlas atlas);
-SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_skeleton_state(sspine_skeleton skeleton);
-SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_instance_state(sspine_instance instance);
+SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_context_resource_state(sspine_context context);
+SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_atlas_resource_state(sspine_atlas atlas);
+SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_skeleton_resource_state(sspine_skeleton skeleton);
+SOKOL_SPINE_API_DECL sspine_resource_state sspine_get_instance_resource_state(sspine_instance instance);
 
 // shortcut for sspine_get_*_state() == SSPINE_RESOURCESTATE_VALID
 SOKOL_SPINE_API_DECL bool sspine_context_valid(sspine_context context);
@@ -1251,7 +1251,7 @@ SOKOL_API_IMPL void sspine_destroy_instance(sspine_instance instance_id) {
     _sspine_destroy_instance(instance_id);
 }
 
-SOKOL_API_IMPL sspine_resource_state sspine_get_context_state(sspine_context ctx_id) {
+SOKOL_API_IMPL sspine_resource_state sspine_get_context_resource_state(sspine_context ctx_id) {
     SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
     const _sspine_context_t* ctx = _sspine_lookup_context(ctx_id.id);
     if (ctx) {
@@ -1262,7 +1262,7 @@ SOKOL_API_IMPL sspine_resource_state sspine_get_context_state(sspine_context ctx
     }
 }
 
-SOKOL_API_IMPL sspine_resource_state sspine_get_atlas_state(sspine_atlas atlas_id) {
+SOKOL_API_IMPL sspine_resource_state sspine_get_atlas_resource_state(sspine_atlas atlas_id) {
     SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
     const _sspine_atlas_t* atlas = _sspine_lookup_atlas(atlas_id.id);
     if (atlas) {
@@ -1273,7 +1273,7 @@ SOKOL_API_IMPL sspine_resource_state sspine_get_atlas_state(sspine_atlas atlas_i
     }
 }
 
-SOKOL_API_IMPL sspine_resource_state sspine_get_skeleton_state(sspine_skeleton skeleton_id) {
+SOKOL_API_IMPL sspine_resource_state sspine_get_skeleton_resource_state(sspine_skeleton skeleton_id) {
     SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
     const _sspine_skeleton_t* skeleton = _sspine_lookup_skeleton(skeleton_id.id);
     if (skeleton) {
@@ -1284,7 +1284,7 @@ SOKOL_API_IMPL sspine_resource_state sspine_get_skeleton_state(sspine_skeleton s
     }
 }
 
-SOKOL_API_IMPL sspine_resource_state sspine_get_instance_state(sspine_instance instance_id) {
+SOKOL_API_IMPL sspine_resource_state sspine_get_instance_resource_state(sspine_instance instance_id) {
     SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
     const _sspine_instance_t* instance = _sspine_lookup_instance(instance_id.id);
     if (instance) {
@@ -1297,22 +1297,22 @@ SOKOL_API_IMPL sspine_resource_state sspine_get_instance_state(sspine_instance i
 
 SOKOL_API_IMPL bool sspine_context_valid(sspine_context ctx_id) {
     SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
-    return sspine_get_context_state(ctx_id) == SSPINE_RESOURCESTATE_VALID;
+    return sspine_get_context_resource_state(ctx_id) == SSPINE_RESOURCESTATE_VALID;
 }
 
 SOKOL_API_IMPL bool sspine_atlas_valid(sspine_atlas atlas_id) {
     SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
-    return sspine_get_atlas_state(atlas_id) == SSPINE_RESOURCESTATE_VALID;
+    return sspine_get_atlas_resource_state(atlas_id) == SSPINE_RESOURCESTATE_VALID;
 }
 
 SOKOL_API_IMPL bool sspine_skeleton_valid(sspine_skeleton skeleton_id) {
     SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
-    return sspine_get_skeleton_state(skeleton_id) == SSPINE_RESOURCESTATE_VALID;
+    return sspine_get_skeleton_resource_state(skeleton_id) == SSPINE_RESOURCESTATE_VALID;
 }
 
 SOKOL_API_IMPL bool sspine_instance_valid(sspine_instance instance_id) {
     SOKOL_ASSERT(_SSPINE_INIT_COOKIE == _sspine.init_cookie);
-    return sspine_get_instance_state(instance_id) == SSPINE_RESOURCESTATE_VALID;
+    return sspine_get_instance_resource_state(instance_id) == SSPINE_RESOURCESTATE_VALID;
 }
 
 SOKOL_API_IMPL int sspine_get_num_images(sspine_atlas atlas_id) {