Jelajahi Sumber

GDExtension support, heavy WIP

Mario Zechner 1 tahun lalu
induk
melakukan
1101e71ec3

+ 1 - 0
.gitignore

@@ -204,3 +204,4 @@ spine-flutter/src/spine-cpp-lite
 spine-sdl/.vs
 spine-sdl/.vs
 spine-ts/spine-canvaskit/dist
 spine-ts/spine-canvaskit/dist
 spine-ts/output.png
 spine-ts/output.png
+spine-godot/godot-cpp

+ 25 - 0
spine-godot/CMakeLists.txt

@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.14)
+
+project(spine_godot_extension)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+file(GLOB INCLUDES "spine_godot/**/*.h")
+file(GLOB SOURCES "spine_godot/*.cpp")
+string(REPLACE ";" "\n" SOURCES_LIST "${SOURCES}")
+message(STATUS "Source files:\n${SOURCES_LIST}")
+
+include_directories(
+    spine_godot
+    spine_godot/spine-cpp/include
+    godot-cpp/gdextension
+    godot-cpp/include
+    godot-cpp/gen/include
+)
+
+add_library(spine_godot_extension SHARED ${SOURCES})
+target_compile_definitions(spine_godot_extension PRIVATE SPINE_GODOT_EXTENSION)
+
+# Link Godot's GDExtension API
+target_link_libraries(spine_godot_extension PRIVATE godot-cpp)

+ 13 - 0
spine-godot/build/setup.sh

@@ -18,10 +18,13 @@ if [ $# -lt 2 ] || [ $# -gt 4 ]; then
 fi
 fi
 
 
 branch=${1%/}
 branch=${1%/}
+godot_version=$(echo "$branch" | grep -o '^[0-9]*\.[0-9]*')
 dev=${2%/}
 dev=${2%/}
 mono=false
 mono=false
 repo=https://github.com/godotengine/godot.git
 repo=https://github.com/godotengine/godot.git
 
 
+echo "Godot version: $godot_version"
+
 if [[ $# -eq 3 && "$branch" != 3* ]]; then
 if [[ $# -eq 3 && "$branch" != 3* ]]; then
 	mono=${3%/}
 	mono=${3%/}
 fi
 fi
@@ -41,6 +44,16 @@ if [ $# -eq 4 ]; then
 fi
 fi
 
 
 pushd ..
 pushd ..
+
+echo "--- Cloning GDExtensions"
+rm -rf godot-cpp
+git clone https://github.com/godotengine/godot-cpp
+pushd godot-cpp
+git submodule update --init
+git checkout $godot_version
+popd
+
+echo "--- Cloning Godot"
 rm -rf godot
 rm -rf godot
 git clone --depth 1 $repo -b $branch
 git clone --depth 1 $repo -b $branch
 if [ $dev = "true" ]; then
 if [ $dev = "true" ]; then

+ 11 - 0
spine-godot/spine_godot/GodotSpineExtension.cpp

@@ -28,6 +28,11 @@
  *****************************************************************************/
  *****************************************************************************/
 
 
 #include "GodotSpineExtension.h"
 #include "GodotSpineExtension.h"
+#ifdef SPINE_GODOT_EXTENSION
+#include "SpineCommon.h"
+#include <godot_cpp/core/memory.hpp>
+#include <godot_cpp/classes/file_access.hpp>
+#else
 #include "core/os/memory.h"
 #include "core/os/memory.h"
 #include "core/version.h"
 #include "core/version.h"
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
@@ -35,6 +40,7 @@
 #else
 #else
 #include "core/os/file_access.h"
 #include "core/os/file_access.h"
 #endif
 #endif
+#endif
 #include <spine/SpineString.h>
 #include <spine/SpineString.h>
 
 
 spine::SpineExtension *spine::getDefaultExtension() {
 spine::SpineExtension *spine::getDefaultExtension() {
@@ -61,6 +67,10 @@ void GodotSpineExtension::_free(void *mem, const char *file, int line) {
 
 
 char *GodotSpineExtension::_readFile(const spine::String &path, int *length) {
 char *GodotSpineExtension::_readFile(const spine::String &path, int *length) {
 	Error error;
 	Error error;
+#ifdef SPINE_GODOT_EXTENSION
+	// FIXME no error parameter!
+	auto res = FileAccess::get_file_as_bytes(String(path.buffer()));
+#else
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
 	auto res = FileAccess::get_file_as_bytes(String(path.buffer()), &error);
 	auto res = FileAccess::get_file_as_bytes(String(path.buffer()), &error);
 #else
 #else
@@ -70,6 +80,7 @@ char *GodotSpineExtension::_readFile(const spine::String &path, int *length) {
 		if (length) *length = 0;
 		if (length) *length = 0;
 		return NULL;
 		return NULL;
 	}
 	}
+#endif
 	auto r = alloc<char>(res.size(), __FILE__, __LINE__);
 	auto r = alloc<char>(res.size(), __FILE__, __LINE__);
 	memcpy(r, res.ptr(), res.size());
 	memcpy(r, res.ptr(), res.size());
 	if (length) *length = res.size();
 	if (length) *length = res.size();

+ 5 - 0
spine-godot/spine_godot/SpineAnimationTrack.h

@@ -30,8 +30,13 @@
 #pragma once
 #pragma once
 
 
 #include "SpineSprite.h"
 #include "SpineSprite.h"
+#ifdef SPINE_GODOT_EXTENSION
+#include <godot_cpp/classes/animation_player.hpp>
+#include <godot_cpp/classes/animation.hpp>
+#else
 #include "scene/animation/animation_player.h"
 #include "scene/animation/animation_player.h"
 #include "scene/resources/animation.h"
 #include "scene/resources/animation.h"
+#endif
 
 
 class SpineAnimationTrack : public Node {
 class SpineAnimationTrack : public Node {
 	GDCLASS(SpineAnimationTrack, Node)
 	GDCLASS(SpineAnimationTrack, Node)

+ 23 - 3
spine-godot/spine_godot/SpineAtlasResource.cpp

@@ -29,8 +29,15 @@
 
 
 #include "SpineAtlasResource.h"
 #include "SpineAtlasResource.h"
 #include "SpineRendererObject.h"
 #include "SpineRendererObject.h"
+
+#ifdef SPINE_GODOT_EXTENSION
+#include <godot_cpp/classes/json.hpp>
+#include <godot_cpp/classes/texture.hpp>
+#include <godot_cpp/classes/file_access.hpp>
+#else
 #include "core/io/json.h"
 #include "core/io/json.h"
 #include "scene/resources/texture.h"
 #include "scene/resources/texture.h"
+#endif
 #include <spine/TextureLoader.h>
 #include <spine/TextureLoader.h>
 
 
 class GodotSpineTextureLoader : public spine::TextureLoader {
 class GodotSpineTextureLoader : public spine::TextureLoader {
@@ -44,16 +51,16 @@ public:
 	}
 	}
 
 
 	static String fix_path(const String &path) {
 	static String fix_path(const String &path) {
-		if (path.size() > 5 && path[4] == '/' && path[5] == '/') return path;
+		if (SSIZE(path) > 5 && path[4] == '/' && path[5] == '/') return path;
 		const String prefix = "res:/";
 		const String prefix = "res:/";
 		auto i = path.find(prefix);
 		auto i = path.find(prefix);
-		auto sub_str_pos = i + prefix.size() - 1;
+		auto sub_str_pos = i + SSIZE(prefix) - 1;
 		if (sub_str_pos < 0) return path;
 		if (sub_str_pos < 0) return path;
 		auto res = path.substr(sub_str_pos);
 		auto res = path.substr(sub_str_pos);
 
 
 		if (!EMPTY(res)) {
 		if (!EMPTY(res)) {
 			if (res[0] != '/') {
 			if (res[0] != '/') {
-				return prefix + "/" + res;
+				return prefix + String("/") + res;
 			} else {
 			} else {
 				return prefix + res;
 				return prefix + res;
 			}
 			}
@@ -65,10 +72,15 @@ public:
 		Error error = OK;
 		Error error = OK;
 		auto fixed_path = fix_path(String(path.buffer()));
 		auto fixed_path = fix_path(String(path.buffer()));
 
 
+#if SPINE_GODOT_EXTENSION
+		// FIXME no error parameter
+		Ref<Texture2D> texture = ResourceLoader::get_singleton()->load(fixed_path, "", ResourceLoader::CACHE_MODE_REUSE);
+#else
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
 		Ref<Texture2D> texture = ResourceLoader::load(fixed_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &error);
 		Ref<Texture2D> texture = ResourceLoader::load(fixed_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &error);
 #else
 #else
 		Ref<Texture> texture = ResourceLoader::load(fixed_path, "", false, &error);
 		Ref<Texture> texture = ResourceLoader::load(fixed_path, "", false, &error);
+#endif
 #endif
 #endif
 		if (error != OK || !texture.is_valid()) {
 		if (error != OK || !texture.is_valid()) {
 			ERR_PRINT(vformat("Can't load texture: \"%s\"", String(path.buffer())));
 			ERR_PRINT(vformat("Can't load texture: \"%s\"", String(path.buffer())));
@@ -85,11 +97,19 @@ public:
 		renderer_object->normal_map = Ref<Texture>(nullptr);
 		renderer_object->normal_map = Ref<Texture>(nullptr);
 
 
 		String new_path = vformat("%s/%s_%s", fixed_path.get_base_dir(), normal_map_prefix, fixed_path.get_file());
 		String new_path = vformat("%s/%s_%s", fixed_path.get_base_dir(), normal_map_prefix, fixed_path.get_file());
+#if SPINE_GODOT_EXTENSION
+		if (ResourceLoader::get_singleton()->exists(new_path)) {
+			Ref<Texture> normal_map = ResourceLoader::get_singleton()->load(new_path);
+			normal_maps->append(normal_map);
+			renderer_object->normal_map = normal_map;
+		}
+#else
 		if (ResourceLoader::exists(new_path)) {
 		if (ResourceLoader::exists(new_path)) {
 			Ref<Texture> normal_map = ResourceLoader::load(new_path);
 			Ref<Texture> normal_map = ResourceLoader::load(new_path);
 			normal_maps->append(normal_map);
 			normal_maps->append(normal_map);
 			renderer_object->normal_map = normal_map;
 			renderer_object->normal_map = normal_map;
 		}
 		}
+#endif
 
 
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
 		renderer_object->canvas_texture.instantiate();
 		renderer_object->canvas_texture.instantiate();

+ 25 - 0
spine-godot/spine_godot/SpineAtlasResource.h

@@ -30,10 +30,19 @@
 #pragma once
 #pragma once
 
 
 #include "SpineCommon.h"
 #include "SpineCommon.h"
+#ifdef SPINE_GODOT_EXTENSION
+#include <godot_cpp/classes/resource.hpp>
+#include <godot_cpp/classes/resource_loader.hpp>
+#include <godot_cpp/classes/resource_format_loader.hpp>
+#include <godot_cpp/classes/resource_saver.hpp>
+#include <godot_cpp/classes/resource_format_saver.hpp>
+#include <spine/Atlas.h>
+#else
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_saver.h"
 #include "core/io/resource_saver.h"
 #include "core/io/image_loader.h"
 #include "core/io/image_loader.h"
 #include <spine/Atlas.h>
 #include <spine/Atlas.h>
+#endif
 
 
 class GodotSpineTextureLoader;
 class GodotSpineTextureLoader;
 
 
@@ -89,6 +98,15 @@ class SpineAtlasResourceFormatLoader : public ResourceFormatLoader {
 	GDCLASS(SpineAtlasResourceFormatLoader, ResourceFormatLoader)
 	GDCLASS(SpineAtlasResourceFormatLoader, ResourceFormatLoader)
 
 
 public:
 public:
+#ifdef SPINE_GODOT_EXTENSION
+	PackedStringArray _get_recognized_extensions();
+
+	bool _handles_type(const StringName &type);
+
+	String _get_resource_type(const String &path);
+
+	Variant _load(const String &path, const String &original_path, bool use_sub_threads, int32_t cache_mode);
+#else
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
 	RES load(const String &path, const String &original_path, Error *error, bool use_sub_threads, float *progress, CacheMode cache_mode) override;
 	RES load(const String &path, const String &original_path, Error *error, bool use_sub_threads, float *progress, CacheMode cache_mode) override;
 #else
 #else
@@ -100,12 +118,18 @@ public:
 	bool handles_type(const String &type) const override;
 	bool handles_type(const String &type) const override;
 
 
 	String get_resource_type(const String &path) const override;
 	String get_resource_type(const String &path) const override;
+#endif
 };
 };
 
 
 class SpineAtlasResourceFormatSaver : public ResourceFormatSaver {
 class SpineAtlasResourceFormatSaver : public ResourceFormatSaver {
 	GDCLASS(SpineAtlasResourceFormatSaver, ResourceFormatSaver)
 	GDCLASS(SpineAtlasResourceFormatSaver, ResourceFormatSaver)
 
 
 public:
 public:
+#ifdef SPINE_GODOT_EXTENSION
+	Error _save(const Ref<Resource> &resource, const String &path, uint32_t flags) override;
+	bool _recognize(const Ref<Resource> &resource);
+	PackedStringArray _get_recognized_extensions(const Ref<Resource> &resource);
+#else
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
 	Error save(const RES &resource, const String &path, uint32_t flags) override;
 	Error save(const RES &resource, const String &path, uint32_t flags) override;
 #else
 #else
@@ -115,4 +139,5 @@ public:
 	void get_recognized_extensions(const RES &resource, List<String> *extensions) const override;
 	void get_recognized_extensions(const RES &resource, List<String> *extensions) const override;
 
 
 	bool recognize(const RES &resource) const override;
 	bool recognize(const RES &resource) const override;
+#endif
 };
 };

+ 1 - 1
spine-godot/spine_godot/SpineAttachment.h

@@ -48,7 +48,7 @@ public:
 
 
 	Ref<SpineAttachment> copy();
 	Ref<SpineAttachment> copy();
 
 
-	void set_spine_object(const SpineSkeletonDataResource *_owner, spine::Attachment *_object) {
+	void set_spine_object(const SpineSkeletonDataResource *_owner, spine::Attachment *_object) override {
 		if (get_spine_object()) get_spine_object()->dereference();
 		if (get_spine_object()) get_spine_object()->dereference();
 		_set_spine_object_internal(_owner, _object);
 		_set_spine_object_internal(_owner, _object);
 		if (_object) _object->reference();
 		if (_object) _object->reference();

+ 4 - 0
spine-godot/spine_godot/SpineBone.h

@@ -32,7 +32,11 @@
 #include "SpineCommon.h"
 #include "SpineCommon.h"
 #include "SpineBoneData.h"
 #include "SpineBoneData.h"
 #include "SpineConstant.h"
 #include "SpineConstant.h"
+#ifdef SPINE_GODOT_EXTENSION
+#include <godot_cpp/classes/node2d.hpp>
+#else
 #include "scene/2d/node_2d.h"
 #include "scene/2d/node_2d.h"
+#endif
 #include <spine/Bone.h>
 #include <spine/Bone.h>
 
 
 class SpineSkeleton;
 class SpineSkeleton;

+ 25 - 0
spine-godot/spine_godot/SpineCommon.h

@@ -30,6 +30,28 @@
 #ifndef SPINE_COMMON_H
 #ifndef SPINE_COMMON_H
 #define SPINE_COMMON_H
 #define SPINE_COMMON_H
 
 
+#ifdef SPINE_GODOT_EXTENSION
+#include <godot_cpp/core/version.hpp>
+#include <godot_cpp/classes/ref_counted.hpp>
+#include <godot_cpp/variant/string_name.hpp>
+using namespace godot;
+#define REFCOUNTED RefCounted
+#define EMPTY(x) ((x).is_empty())
+#define EMPTY_PTR(x) ((x)->is_empty())
+#define SSIZE(x) ((x).length())
+#define INSTANTIATE(x) (x).instantiate()
+#define NOTIFY_PROPERTY_LIST_CHANGED() notify_property_list_changed()
+#define VARIANT_FLOAT Variant::FLOAT
+#define PROPERTY_USAGE_NOEDITOR PROPERTY_USAGE_NO_EDITOR
+#define RES Ref<Resource>
+#define REF Ref<RefCounted>
+#define GEOMETRY2D Geometry2D
+#define VERSION_MAJOR GODOT_VERSION_MAJOR
+#define VERSION_MINOR GODOT_VERSION_MINOR
+// FIXME this doesn't do the same as the engine SNAME in terms of caching
+#define SNAME(name) StringName(name)
+#define RS RenderingServer
+#else
 #include "core/version.h"
 #include "core/version.h"
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
 #include "core/core_bind.h"
 #include "core/core_bind.h"
@@ -37,6 +59,7 @@
 #define REFCOUNTED RefCounted
 #define REFCOUNTED RefCounted
 #define EMPTY(x) ((x).is_empty())
 #define EMPTY(x) ((x).is_empty())
 #define EMPTY_PTR(x) ((x)->is_empty())
 #define EMPTY_PTR(x) ((x)->is_empty())
+#define SSIZE(x) ((x).size())
 #define INSTANTIATE(x) (x).instantiate()
 #define INSTANTIATE(x) (x).instantiate()
 #define NOTIFY_PROPERTY_LIST_CHANGED() notify_property_list_changed()
 #define NOTIFY_PROPERTY_LIST_CHANGED() notify_property_list_changed()
 #define VARIANT_FLOAT Variant::FLOAT
 #define VARIANT_FLOAT Variant::FLOAT
@@ -51,6 +74,7 @@
 #define REFCOUNTED Reference
 #define REFCOUNTED Reference
 #define EMPTY(x) ((x).empty())
 #define EMPTY(x) ((x).empty())
 #define EMPTY_PTR(x) ((x)->empty())
 #define EMPTY_PTR(x) ((x)->empty())
+#define SSIZE(x) ((x).size())
 #define INSTANTIATE(x) (x).instance()
 #define INSTANTIATE(x) (x).instance()
 #define NOTIFY_PROPERTY_LIST_CHANGED() property_list_changed_notify()
 #define NOTIFY_PROPERTY_LIST_CHANGED() property_list_changed_notify()
 #define VARIANT_FLOAT Variant::REAL
 #define VARIANT_FLOAT Variant::REAL
@@ -60,6 +84,7 @@
 #define SNAME(m_arg) ([]() -> const StringName & { static StringName sname = _scs_create(m_arg); return sname; })()
 #define SNAME(m_arg) ([]() -> const StringName & { static StringName sname = _scs_create(m_arg); return sname; })()
 #endif
 #endif
 #endif
 #endif
+#endif
 
 
 #define SPINE_CHECK(obj, ret)                      \
 #define SPINE_CHECK(obj, ret)                      \
 	if (!(obj)) {                                  \
 	if (!(obj)) {                                  \

+ 7 - 0
spine-godot/spine_godot/SpineRendererObject.h

@@ -30,11 +30,18 @@
 #ifndef GODOT_SPINERENDEREROBJECT_H
 #ifndef GODOT_SPINERENDEREROBJECT_H
 #define GODOT_SPINERENDEREROBJECT_H
 #define GODOT_SPINERENDEREROBJECT_H
 
 
+#include "SpineCommon.h"
+
+#ifdef SPINE_GODOT_EXTENSION
+#include <godot_cpp/classes/texture.hpp>
+#include <godot_cpp/classes/canvas_texture.hpp>
+#else
 #include <scene/resources/texture.h>
 #include <scene/resources/texture.h>
 
 
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
 #include <scene/main/canvas_item.h>
 #include <scene/main/canvas_item.h>
 #endif
 #endif
+#endif
 
 
 struct SpineRendererObject {
 struct SpineRendererObject {
 	Ref<Texture> texture;
 	Ref<Texture> texture;

+ 0 - 1
spine-godot/spine_godot/SpineSkeletonDataResource.cpp

@@ -29,7 +29,6 @@
 
 
 #include "SpineSkeletonDataResource.h"
 #include "SpineSkeletonDataResource.h"
 #include "SpineCommon.h"
 #include "SpineCommon.h"
-#include "core/io/marshalls.h"
 
 
 void SpineAnimationMix::_bind_methods() {
 void SpineAnimationMix::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_from", "from"),
 	ClassDB::bind_method(D_METHOD("set_from", "from"),

+ 5 - 0
spine-godot/spine_godot/SpineSkeletonFileResource.cpp

@@ -28,6 +28,10 @@
  *****************************************************************************/
  *****************************************************************************/
 
 
 #include "SpineSkeletonFileResource.h"
 #include "SpineSkeletonFileResource.h"
+#ifdef SPINE_GODOT_EXTENSION
+#include <godot_cpp/core/error_macros.hpp>
+#include <godot_cpp/classes/file_access.hpp>
+#else
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
 #include "core/error/error_list.h"
 #include "core/error/error_list.h"
 #include "core/error/error_macros.h"
 #include "core/error/error_macros.h"
@@ -37,6 +41,7 @@
 #include "core/error_macros.h"
 #include "core/error_macros.h"
 #include "core/os/file_access.h"
 #include "core/os/file_access.h"
 #endif
 #endif
+#endif
 #include <spine/Json.h>
 #include <spine/Json.h>
 #include <spine/Version.h>
 #include <spine/Version.h>
 #include <spine/Extension.h>
 #include <spine/Extension.h>

+ 26 - 0
spine-godot/spine_godot/SpineSkeletonFileResource.h

@@ -30,8 +30,18 @@
 #pragma once
 #pragma once
 
 
 #include "SpineCommon.h"
 #include "SpineCommon.h"
+#ifdef SPINE_GODOT_EXTENSION
+#include <godot_cpp/classes/resource_loader.hpp>
+#include <godot_cpp/classes/resource_format_loader.hpp>
+#include <godot_cpp/classes/resource_saver.hpp>
+#include <godot_cpp/classes/resource_format_saver.hpp>
+#include <godot_cpp/classes/resource.hpp>
+#include <godot_cpp/templates/vector.hpp>
+#else
 #include "core/io/resource_loader.h"
 #include "core/io/resource_loader.h"
 #include "core/io/resource_saver.h"
 #include "core/io/resource_saver.h"
+#endif
+#include <spine/Vector.h>
 
 
 class SpineSkeletonFileResource : public Resource {
 class SpineSkeletonFileResource : public Resource {
 	GDCLASS(SpineSkeletonFileResource, Resource);
 	GDCLASS(SpineSkeletonFileResource, Resource);
@@ -62,6 +72,15 @@ class SpineSkeletonFileResourceFormatLoader : public ResourceFormatLoader {
 	GDCLASS(SpineSkeletonFileResourceFormatLoader, ResourceFormatLoader);
 	GDCLASS(SpineSkeletonFileResourceFormatLoader, ResourceFormatLoader);
 
 
 public:
 public:
+#ifdef SPINE_GODOT_EXTENSION
+	PackedStringArray _get_recognized_extensions();
+
+	bool _handles_type(const StringName &type);
+
+	String _get_resource_type(const String &path);
+
+	Variant _load(const String &path, const String &original_path, bool use_sub_threads, int32_t cache_mode);
+#else
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
 	RES load(const String &path, const String &original_path, Error *error, bool use_sub_threads, float *progress, CacheMode cache_mode);
 	RES load(const String &path, const String &original_path, Error *error, bool use_sub_threads, float *progress, CacheMode cache_mode);
 #else
 #else
@@ -73,12 +92,18 @@ public:
 	bool handles_type(const String &type) const override;
 	bool handles_type(const String &type) const override;
 
 
 	String get_resource_type(const String &path) const override;
 	String get_resource_type(const String &path) const override;
+#endif
 };
 };
 
 
 class SpineSkeletonFileResourceFormatSaver : public ResourceFormatSaver {
 class SpineSkeletonFileResourceFormatSaver : public ResourceFormatSaver {
 	GDCLASS(SpineSkeletonFileResourceFormatSaver, ResourceFormatSaver);
 	GDCLASS(SpineSkeletonFileResourceFormatSaver, ResourceFormatSaver);
 
 
 public:
 public:
+#ifdef SPINE_GODOT_EXTENSION
+	Error _save(const Ref<Resource> &resource, const String &path, uint32_t flags) override;
+	bool _recognize(const Ref<Resource> &resource);
+	PackedStringArray _get_recognized_extensions(const Ref<Resource> &resource);
+#else
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
 	Error save(const RES &resource, const String &path, uint32_t flags) override;
 	Error save(const RES &resource, const String &path, uint32_t flags) override;
 #else
 #else
@@ -88,4 +113,5 @@ public:
 	void get_recognized_extensions(const RES &resource, List<String> *p_extensions) const override;
 	void get_recognized_extensions(const RES &resource, List<String> *p_extensions) const override;
 
 
 	bool recognize(const RES &p_resource) const override;
 	bool recognize(const RES &p_resource) const override;
+#endif
 };
 };

+ 13 - 1
spine-godot/spine_godot/SpineSprite.h

@@ -31,7 +31,15 @@
 
 
 #include "SpineSkeleton.h"
 #include "SpineSkeleton.h"
 #include "SpineAnimationState.h"
 #include "SpineAnimationState.h"
+#ifdef SPINE_GODOT_EXTENSION
+#include "SpineCommon.h"
+#include <godot_cpp/classes/node2d.hpp>
+#include <godot_cpp/templates/vector.hpp>
+#include <godot_cpp/classes/rendering_server.hpp>
+#include <godot_cpp/classes/canvas_item_material.hpp>
+#else
 #include "scene/2d/node_2d.h"
 #include "scene/2d/node_2d.h"
+#endif
 
 
 class SpineSlotNode;
 class SpineSlotNode;
 
 
@@ -84,7 +92,11 @@ public:
 	SpineMesh2D() : renderer_object(nullptr), indices_changed(true), num_vertices(0), num_indices(0), vertex_stride(0), normal_tangent_stride(0), attribute_stride(0){};
 	SpineMesh2D() : renderer_object(nullptr), indices_changed(true), num_vertices(0), num_indices(0), vertex_stride(0), normal_tangent_stride(0), attribute_stride(0){};
 	~SpineMesh2D() {
 	~SpineMesh2D() {
 		if (mesh.is_valid()) {
 		if (mesh.is_valid()) {
+#ifdef SPINE_GODOT_EXTENSION
+			RS::get_singleton()->free_rid(mesh);
+#else
 			RS::get_singleton()->free(mesh);
 			RS::get_singleton()->free(mesh);
+#endif
 		}
 		}
 	}
 	}
 #else
 #else
@@ -160,7 +172,7 @@ protected:
 	void draw();
 	void draw();
 	void draw_bone(spine::Bone *bone, const Color &color);
 	void draw_bone(spine::Bone *bone, const Color &color);
 
 
-	void callback(spine::AnimationState *state, spine::EventType type, spine::TrackEntry *entry, spine::Event *event);
+	void callback(spine::AnimationState *state, spine::EventType type, spine::TrackEntry *entry, spine::Event *event) override;
 
 
 public:
 public:
 	SpineSprite();
 	SpineSprite();

+ 3 - 0
spine-godot/spine_godot/register_types.cpp

@@ -28,7 +28,10 @@
  *****************************************************************************/
  *****************************************************************************/
 
 
 #include "SpineCommon.h"
 #include "SpineCommon.h"
+#ifdef SPINE_GODOT_EXTENSION
+#else
 #include "modules/register_module_types.h"
 #include "modules/register_module_types.h"
+#endif
 #include "register_types.h"
 #include "register_types.h"
 #include "SpineAtlasResource.h"
 #include "SpineAtlasResource.h"
 #include "SpineSkeletonFileResource.h"
 #include "SpineSkeletonFileResource.h"

+ 2 - 0
spine-godot/spine_godot/register_types.h

@@ -32,7 +32,9 @@
 #include "SpineCommon.h"
 #include "SpineCommon.h"
 
 
 #if VERSION_MAJOR > 3
 #if VERSION_MAJOR > 3
+#ifndef SPINE_GODOT_EXTENSION
 #include "modules/register_module_types.h"
 #include "modules/register_module_types.h"
+#endif
 void initialize_spine_godot_module(ModuleInitializationLevel level);
 void initialize_spine_godot_module(ModuleInitializationLevel level);
 void uninitialize_spine_godot_module(ModuleInitializationLevel level);
 void uninitialize_spine_godot_module(ModuleInitializationLevel level);
 #else
 #else