Explorar o código

Better class extension.

NathanSweet %!s(int64=12) %!d(string=hai) anos
pai
achega
e56050e3a7

+ 3 - 7
spine-c/example/main.c

@@ -23,8 +23,7 @@ void _ExampleAtlasPage_dispose (AtlasPage* page) {
 
 AtlasPage* AtlasPage_create (const char* name, const char* path) {
 	ExampleAtlasPage* self = NEW(ExampleAtlasPage);
-	_AtlasPage_init(SUPER(self), name);
-	VTABLE(AtlasPage, self) ->dispose = _ExampleAtlasPage_dispose;
+	_AtlasPage_init(SUPER(self), name, _ExampleAtlasPage_dispose);
 
 	self->extraData = 123;
 
@@ -49,8 +48,7 @@ void _ExampleSkeleton_dispose (Skeleton* skeleton) {
 
 Skeleton* Skeleton_create (SkeletonData* data) {
 	ExampleSkeleton* self = NEW(ExampleSkeleton);
-	_Skeleton_init(SUPER(self), data);
-	VTABLE(Skeleton, self) ->dispose = _ExampleSkeleton_dispose;
+	_Skeleton_init(SUPER(self), data, _ExampleSkeleton_dispose);
 
 	self->extraData = 789;
 
@@ -80,9 +78,7 @@ void _ExampleRegionAttachment_draw (Attachment* attachment, Slot* slot) {
 
 RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) {
 	ExampleRegionAttachment* self = NEW(ExampleRegionAttachment);
-	_RegionAttachment_init(SUPER(self), name);
-	VTABLE(Attachment, self) ->dispose = _ExampleRegionAttachment_dispose;
-	VTABLE(Attachment, self) ->draw = _ExampleRegionAttachment_draw;
+	_RegionAttachment_init(SUPER(self), name, _ExampleRegionAttachment_dispose, _ExampleRegionAttachment_draw);
 
 	self->extraData = 456;
 

+ 26 - 36
spine-c/include/spine/extension.h

@@ -35,17 +35,17 @@
 
  - Classes intended for inheritance provide init/deinit functions which subclasses must call in their create/dispose functions.
 
- - Polymorphism is done by a base class providing a "vtable" pointer to a struct containing function pointers. The public API
- delegates to the appropriate vtable function. Subclasses may change the vtable pointers.
+ - Polymorphism is done by a base class providing function pointers in its init function. The public API delegates to this
+ function.
 
  - Subclasses do not provide a dispose function, instead the base class' dispose function should be used, which will delegate to
- a dispose function in its vtable.
+ a dispose function.
 
  - Classes not designed for inheritance cannot be extended. They may use an internal subclass to hide private data and don't
- expose a vtable.
+ expose function pointers.
 
- - The public API hides implementation details such as vtable structs and init/deinit functions. An internal API is exposed in
- extension.h to allow classes to be extended. Internal structs and functions begin with underscore (_).
+ - The public API hides implementation details such init/deinit functions. An internal API is exposed in extension.h to allow
+ classes to be extended. Internal functions begin with underscore (_).
 
  - OOP in C tends to lose type safety. Macros are provided in extension.h to give context for why a cast is being done.
  */
@@ -108,62 +108,52 @@ char* _Util_readFile (const char* path, int* length);
 
 char* _readFile (const char* path, int* length);
 
-typedef struct _SkeletonVtable {
-	void (*dispose) (Skeleton* skeleton);
-} _SkeletonVtable;
-
-void _Skeleton_init (Skeleton* self, SkeletonData* data);
+void _Skeleton_init (Skeleton* self, SkeletonData* data, //
+		void (*dispose) (Skeleton* skeleton));
 void _Skeleton_deinit (Skeleton* self);
 
 /**/
 
-typedef struct _AttachmentVtable {
-	void (*draw) (Attachment* self, struct Slot* slot);
-	void (*dispose) (Attachment* self);
-} _AttachmentVtable;
-
-void _Attachment_init (Attachment* self, const char* name, AttachmentType type);
+void _Attachment_init (Attachment* self, const char* name, AttachmentType type, //
+		void (*dispose) (Attachment* self), //
+		void (*draw) (Attachment* self, struct Slot* slot));
 void _Attachment_deinit (Attachment* self);
 
 /**/
 
-void _RegionAttachment_init (RegionAttachment* self, const char* name);
+void _RegionAttachment_init (RegionAttachment* self, const char* name, //
+		void (*dispose) (Attachment* self), //
+		void (*draw) (Attachment* self, struct Slot* slot));
 void _RegionAttachment_deinit (RegionAttachment* self);
 
 /**/
 
-typedef struct _TimelineVtable {
-	void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha);
-	void (*dispose) (Timeline* self);
-} _TimelineVtable;
-
-void _Timeline_init (Timeline* self);
+void _Timeline_init (Timeline* self, //
+		void (*dispose) (Timeline* self), //
+		void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha));
 void _Timeline_deinit (Timeline* self);
 
 /**/
 
-void _CurveTimeline_init (CurveTimeline* self, int frameCount);
+void _CurveTimeline_init (CurveTimeline* self, int frameCount, //
+		void (*dispose) (Timeline* self), //
+		void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha));
 void _CurveTimeline_deinit (CurveTimeline* self);
 
 /**/
 
-typedef struct _AtlasPageVtable {
-	void (*dispose) (AtlasPage* self);
-} _AtlasPageVtable;
-
-void _AtlasPage_init (AtlasPage* self, const char* name);
+void _AtlasPage_init (AtlasPage* self, const char* name, //
+		void (*dispose) (AtlasPage* self));
 void _AtlasPage_deinit (AtlasPage* self);
 
 /**/
 
-typedef struct _AttachmentLoaderVtable {
-	Attachment* (*newAttachment) (AttachmentLoader* self, AttachmentType type, const char* name);
-	void (*dispose) (AttachmentLoader* self);
-} _AttachmentLoaderVtable;
-
-void _AttachmentLoader_init (AttachmentLoader* self);
+void _AttachmentLoader_init (AttachmentLoader* self, //
+		void (*dispose) (AttachmentLoader* self), //
+		Attachment* (*newAttachment) (AttachmentLoader* self, AttachmentType type, const char* name));
 void _AttachmentLoader_deinit (AttachmentLoader* self);
 void _AttachmentLoader_setError (AttachmentLoader* self, const char* error1, const char* error2);
+void _AttachmentLoader_setUnknownTypeError (AttachmentLoader* self, AttachmentType type);
 
 #ifdef __cplusplus
 }

+ 24 - 22
spine-c/src/spine/Animation.c

@@ -65,8 +65,17 @@ void Animation_mix (const Animation* self, Skeleton* skeleton, float time, int/*
 
 /**/
 
-void _Timeline_init (Timeline* self) {
+typedef struct _TimelineVtable {
+	void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha);
+	void (*dispose) (Timeline* self);
+} _TimelineVtable;
+
+void _Timeline_init (Timeline* self, //
+		void (*dispose) (Timeline* self), //
+		void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)) {
 	CONST_CAST(_TimelineVtable*, self->vtable) = NEW(_TimelineVtable);
+	VTABLE(Timeline, self) ->dispose = dispose;
+	VTABLE(Timeline, self) ->apply = apply;
 }
 
 void _Timeline_deinit (Timeline* self) {
@@ -87,8 +96,10 @@ static const float CURVE_LINEAR = 0;
 static const float CURVE_STEPPED = -1;
 static const int CURVE_SEGMENTS = 10;
 
-void _CurveTimeline_init (CurveTimeline* self, int frameCount) {
-	_Timeline_init(SUPER(self));
+void _CurveTimeline_init (CurveTimeline* self, int frameCount, //
+		void (*dispose) (Timeline* self), //
+		void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)) {
+	_Timeline_init(SUPER(self), dispose, apply);
 	self->curves = CALLOC(float, (frameCount - 1) * 6);
 }
 
@@ -192,10 +203,11 @@ void _BaseTimeline_dispose (Timeline* timeline) {
 }
 
 /* Many timelines have structure identical to struct BaseTimeline and extend CurveTimeline. **/
-struct BaseTimeline* _BaseTimeline_create (int frameCount, int frameSize) {
+struct BaseTimeline* _BaseTimeline_create (int frameCount, int frameSize, //
+		void (*apply) (const Timeline* self, Skeleton* skeleton, float time, float alpha)) {
+
 	struct BaseTimeline* self = NEW(struct BaseTimeline);
-	_CurveTimeline_init(SUPER(self), frameCount);
-	VTABLE(Timeline, self) ->dispose = _BaseTimeline_dispose;
+	_CurveTimeline_init(SUPER(self), frameCount, _BaseTimeline_dispose, apply);
 
 	CONST_CAST(int, self->framesLength) = frameCount * frameSize;
 	CONST_CAST(float*, self->frames) = CALLOC(float, self->framesLength);
@@ -246,9 +258,7 @@ void _RotateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float
 }
 
 RotateTimeline* RotateTimeline_create (int frameCount) {
-	RotateTimeline* self = _BaseTimeline_create(frameCount, 2);
-	VTABLE(Timeline, self) ->apply = _RotateTimeline_apply;
-	return self;
+	return _BaseTimeline_create(frameCount, 2, _RotateTimeline_apply);
 }
 
 void RotateTimeline_setFrame (RotateTimeline* self, int frameIndex, float time, float angle) {
@@ -291,9 +301,7 @@ void _TranslateTimeline_apply (const Timeline* timeline, Skeleton* skeleton, flo
 }
 
 TranslateTimeline* TranslateTimeline_create (int frameCount) {
-	TranslateTimeline* self = _BaseTimeline_create(frameCount, 3);
-	VTABLE(Timeline, self) ->apply = _TranslateTimeline_apply;
-	return self;
+	return _BaseTimeline_create(frameCount, 3, _TranslateTimeline_apply);
 }
 
 void TranslateTimeline_setFrame (TranslateTimeline* self, int frameIndex, float time, float x, float y) {
@@ -332,9 +340,7 @@ void _ScaleTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float t
 }
 
 ScaleTimeline* ScaleTimeline_create (int frameCount) {
-	ScaleTimeline* self = _BaseTimeline_create(frameCount, 3);
-	VTABLE(Timeline, self) ->apply = _ScaleTimeline_apply;
-	return self;
+	return _BaseTimeline_create(frameCount, 3, _ScaleTimeline_apply);
 }
 
 void ScaleTimeline_setFrame (ScaleTimeline* self, int frameIndex, float time, float x, float y) {
@@ -393,9 +399,7 @@ void _ColorTimeline_apply (const Timeline* timeline, Skeleton* skeleton, float t
 }
 
 ColorTimeline* ColorTimeline_create (int frameCount) {
-	ColorTimeline* self = (ColorTimeline*)_BaseTimeline_create(frameCount, 5);
-	VTABLE(Timeline, self) ->apply = _ColorTimeline_apply;
-	return self;
+	return (ColorTimeline*)_BaseTimeline_create(frameCount, 5, _ColorTimeline_apply);
 }
 
 void ColorTimeline_setFrame (ColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a) {
@@ -439,11 +443,9 @@ void _AttachmentTimeline_dispose (Timeline* timeline) {
 
 AttachmentTimeline* AttachmentTimeline_create (int frameCount) {
 	AttachmentTimeline* self = NEW(AttachmentTimeline);
-	_Timeline_init(SUPER(self));
-	VTABLE(Timeline, self) ->dispose = _AttachmentTimeline_dispose;
-	VTABLE(Timeline, self) ->apply = _AttachmentTimeline_apply;
-	CONST_CAST(char**, self->attachmentNames) = CALLOC(char*, frameCount);
+	_Timeline_init(SUPER(self), _AttachmentTimeline_dispose, _AttachmentTimeline_apply);
 
+	CONST_CAST(char**, self->attachmentNames) = CALLOC(char*, frameCount);
 	CONST_CAST(int, self->framesLength) = frameCount;
 	CONST_CAST(float*, self->frames) = CALLOC(float, frameCount);
 

+ 7 - 1
spine-c/src/spine/Atlas.c

@@ -31,8 +31,14 @@
 namespace spine {
 #endif
 
-void _AtlasPage_init (AtlasPage* self, const char* name) {
+typedef struct _AtlasPageVtable {
+	void (*dispose) (AtlasPage* self);
+} _AtlasPageVtable;
+
+void _AtlasPage_init (AtlasPage* self, const char* name, //
+		void (*dispose) (AtlasPage* self)) {
 	CONST_CAST(_AtlasPageVtable*, self->vtable) = NEW(_AtlasPageVtable);
+	VTABLE(AtlasPage, self) ->dispose = dispose;
 	MALLOC_STR(self->name, name);
 }
 

+ 3 - 9
spine-c/src/spine/AtlasAttachmentLoader.c

@@ -24,7 +24,6 @@
  ******************************************************************************/
 
 #include <spine/AtlasAttachmentLoader.h>
-#include <stdio.h>
 #include <spine/extension.h>
 
 #ifdef __cplusplus
@@ -46,21 +45,16 @@ Attachment* _AtlasAttachmentLoader_newAttachment (AttachmentLoader* loader, Atta
 		}
 		return SUPER_CAST(Attachment, RegionAttachment_create(name, region)) ;
 	}
-	default: {
-		char buffer[16];
-		sprintf(buffer, "%d", type);
-		_AttachmentLoader_setError(loader, "Unknown attachment type: ", buffer);
+	default:
+		_AttachmentLoader_setUnknownTypeError(loader, type);
 		return 0;
 	}
-	}
 }
 
 AtlasAttachmentLoader* AtlasAttachmentLoader_create (Atlas* atlas) {
 	AtlasAttachmentLoader* self = NEW(AtlasAttachmentLoader);
-	_AttachmentLoader_init(SUPER(self));
+	_AttachmentLoader_init(SUPER(self), _AtlasAttachmentLoader_dispose, _AtlasAttachmentLoader_newAttachment);
 	self->atlas = atlas;
-	VTABLE(AttachmentLoader, self) ->newAttachment = _AtlasAttachmentLoader_newAttachment;
-	VTABLE(AttachmentLoader, self) ->dispose = _AtlasAttachmentLoader_dispose;
 	return self;
 }
 

+ 14 - 3
spine-c/src/spine/Attachment.c

@@ -31,8 +31,19 @@
 namespace spine {
 #endif
 
-void _Attachment_init (Attachment* self, const char* name, AttachmentType type) {
+typedef struct _AttachmentVtable {
+	void (*draw) (Attachment* self, struct Slot* slot);
+	void (*dispose) (Attachment* self);
+} _AttachmentVtable;
+
+void _Attachment_init (Attachment* self, const char* name, AttachmentType type, //
+		void (*dispose) (Attachment* self), //
+		void (*draw) (Attachment* self, struct Slot* slot)) {
+
 	CONST_CAST(_AttachmentVtable*, self->vtable) = NEW(_AttachmentVtable);
+	VTABLE(Attachment, self) ->dispose = dispose;
+	VTABLE(Attachment, self) ->draw = draw;
+
 	MALLOC_STR(self->name, name);
 	self->type = type;
 }
@@ -43,11 +54,11 @@ void _Attachment_deinit (Attachment* self) {
 }
 
 void Attachment_dispose (Attachment* self) {
-	VTABLE(Attachment, self)->dispose(self);
+	VTABLE(Attachment, self) ->dispose(self);
 }
 
 void Attachment_draw (Attachment* self, Slot* slot) {
-	VTABLE(Attachment, self)->draw(self, slot);
+	VTABLE(Attachment, self) ->draw(self, slot);
 }
 
 #ifdef __cplusplus

+ 17 - 1
spine-c/src/spine/AttachmentLoader.c

@@ -24,14 +24,24 @@
  ******************************************************************************/
 
 #include <spine/AttachmentLoader.h>
+#include <stdio.h>
 #include <spine/extension.h>
 
 #ifdef __cplusplus
 namespace spine {
 #endif
 
-void _AttachmentLoader_init (AttachmentLoader* self) {
+typedef struct _AttachmentLoaderVtable {
+	Attachment* (*newAttachment) (AttachmentLoader* self, AttachmentType type, const char* name);
+	void (*dispose) (AttachmentLoader* self);
+} _AttachmentLoaderVtable;
+
+void _AttachmentLoader_init (AttachmentLoader* self, //
+		void (*dispose) (AttachmentLoader* self), //
+		Attachment* (*newAttachment) (AttachmentLoader* self, AttachmentType type, const char* name)) {
 	CONST_CAST(_AttachmentLoaderVtable*, self->vtable) = NEW(_AttachmentLoaderVtable);
+	VTABLE(AttachmentLoader, self) ->dispose = dispose;
+	VTABLE(AttachmentLoader, self) ->newAttachment = newAttachment;
 }
 
 void _AttachmentLoader_deinit (AttachmentLoader* self) {
@@ -59,6 +69,12 @@ void _AttachmentLoader_setError (AttachmentLoader* self, const char* error1, con
 	MALLOC_STR(self->error2, error2);
 }
 
+void _AttachmentLoader_setUnknownTypeError (AttachmentLoader* self, AttachmentType type) {
+	char buffer[16];
+	sprintf(buffer, "%d", type);
+	_AttachmentLoader_setError(self, "Unknown attachment type: ", buffer);
+}
+
 #ifdef __cplusplus
 }
 #endif

+ 4 - 2
spine-c/src/spine/RegionAttachment.c

@@ -31,10 +31,12 @@
 namespace spine {
 #endif
 
-void _RegionAttachment_init (RegionAttachment* self, const char* name) {
+void _RegionAttachment_init (RegionAttachment* self, const char* name, //
+		void (*dispose) (Attachment* self), //
+		void (*draw) (Attachment* self, struct Slot* slot)) {
 	self->scaleX = 1;
 	self->scaleY = 1;
-	_Attachment_init(SUPER(self), name, ATTACHMENT_REGION);
+	_Attachment_init(SUPER(self), name, ATTACHMENT_REGION, dispose, draw);
 }
 
 void _RegionAttachment_deinit (RegionAttachment* self) {

+ 6 - 1
spine-c/src/spine/Skeleton.c

@@ -31,10 +31,15 @@
 namespace spine {
 #endif
 
-void _Skeleton_init (Skeleton* self, SkeletonData* data) {
+typedef struct _SkeletonVtable {
+	void (*dispose) (Skeleton* skeleton);
+} _SkeletonVtable;
+
+void _Skeleton_init (Skeleton* self, SkeletonData* data, void (*dispose) (Skeleton* skeleton)) {
 	CONST_CAST(SkeletonData*, self->data) = data;
 
 	CONST_CAST(_SkeletonVtable*, self->vtable) = NEW(_SkeletonVtable);
+	VTABLE(Skeleton, self) ->dispose = dispose;
 
 	self->boneCount = self->data->boneCount;
 	self->bones = MALLOC(Bone*, self->boneCount);

+ 3 - 7
spine-cocos2d-iphone/src/spine/spine-cocos2d-iphone.m

@@ -48,8 +48,7 @@ void _Cocos2dAtlasPage_dispose (AtlasPage* page) {
 
 AtlasPage* AtlasPage_create (const char* name, const char* path) {
 	Cocos2dAtlasPage* self = NEW(Cocos2dAtlasPage);
-	_AtlasPage_init(SUPER(self), name);
-	VTABLE(AtlasPage, self) ->dispose = _Cocos2dAtlasPage_dispose;
+	_AtlasPage_init(SUPER(self), name, _Cocos2dAtlasPage_dispose);
 
 	self->texture = [[CCTextureCache sharedTextureCache] addImage:@(path)];
 	[self->texture retain];
@@ -73,8 +72,7 @@ void _Cocos2dSkeleton_dispose (Skeleton* self) {
 
 Skeleton* _Cocos2dSkeleton_create (SkeletonData* data, CCSkeleton* node) {
 	Cocos2dSkeleton* self = NEW(Cocos2dSkeleton);
-	_Skeleton_init(SUPER(self), data);
-	VTABLE(Skeleton, self) ->dispose = _Cocos2dSkeleton_dispose;
+	_Skeleton_init(SUPER(self), data, _Cocos2dSkeleton_dispose);
 
 	self->node = node;
 
@@ -149,9 +147,7 @@ void _Cocos2dRegionAttachment_draw (Attachment* attachment, Slot* slot) {
 
 RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) {
 	Cocos2dRegionAttachment* self = NEW(Cocos2dRegionAttachment);
-	_RegionAttachment_init(SUPER(self), name);
-	VTABLE(Attachment, self) ->dispose = _Cocos2dRegionAttachment_dispose;
-	VTABLE(Attachment, self) ->draw = _Cocos2dRegionAttachment_draw;
+	_RegionAttachment_init(SUPER(self), name, _Cocos2dRegionAttachment_dispose, _Cocos2dRegionAttachment_draw);
 
 	Cocos2dAtlasPage* page = SUB_CAST(Cocos2dAtlasPage, region->page);
 	self->textureAtlas = page->textureAtlas;

+ 3 - 7
spine-cocos2dx/src/spine/spine-cocos2dx.cpp

@@ -43,8 +43,7 @@ void _Cocos2dxAtlasPage_dispose (AtlasPage* page) {
 
 AtlasPage* AtlasPage_create (const char* name, const char* path) {
 	Cocos2dxAtlasPage* self = NEW(Cocos2dxAtlasPage);
-	_AtlasPage_init(SUPER(self), name);
-	VTABLE(AtlasPage, self) ->dispose = _Cocos2dxAtlasPage_dispose;
+	_AtlasPage_init(SUPER(self), name, _Cocos2dxAtlasPage_dispose);
 
 	self->texture = CCTextureCache::sharedTextureCache()->addImage(path);
 	self->texture->retain();
@@ -63,8 +62,7 @@ void _Cocos2dxSkeleton_dispose (Skeleton* self) {
 
 Skeleton* _Cocos2dxSkeleton_create (SkeletonData* data, CCSkeleton* node) {
 	Cocos2dxSkeleton* self = NEW(Cocos2dxSkeleton);
-	_Skeleton_init(SUPER(self), data);
-	VTABLE(Skeleton, self) ->dispose = _Cocos2dxSkeleton_dispose;
+	_Skeleton_init(SUPER(self), data, _Cocos2dxSkeleton_dispose);
 
 	self->node = node;
 
@@ -340,9 +338,7 @@ void _Cocos2dxRegionAttachment_draw (Attachment* attachment, Slot* slot) {
 
 RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) {
 	Cocos2dxRegionAttachment* self = NEW(Cocos2dxRegionAttachment);
-	_RegionAttachment_init(SUPER(self), name);
-	VTABLE(Attachment, self) ->dispose = _Cocos2dxRegionAttachment_dispose;
-	VTABLE(Attachment, self) ->draw = _Cocos2dxRegionAttachment_draw;
+	_RegionAttachment_init(SUPER(self), name, _Cocos2dxRegionAttachment_dispose, _Cocos2dxRegionAttachment_draw);
 
 	Cocos2dxAtlasPage* page = SUB_CAST(Cocos2dxAtlasPage, region->page);
 	self->textureAtlas = page->textureAtlas;

+ 3 - 7
spine-sfml/src/spine/spine-sfml.cpp

@@ -52,8 +52,7 @@ void _SfmlAtlasPage_dispose (AtlasPage* page) {
 
 AtlasPage* AtlasPage_create (const char* name, const char* path) {
 	SfmlAtlasPage* self = NEW(SfmlAtlasPage);
-	_AtlasPage_init(SUPER(self), name);
-	VTABLE(AtlasPage, self) ->dispose = _SfmlAtlasPage_dispose;
+	_AtlasPage_init(SUPER(self), name, _SfmlAtlasPage_dispose);
 
 	self->texture = new Texture();
 	self->texture->loadFromFile(path);
@@ -72,8 +71,7 @@ Skeleton* _SfmlSkeleton_create (SkeletonData* data, SkeletonDrawable* drawable)
 	Bone_setYDown(1);
 
 	SfmlSkeleton* self = NEW(SfmlSkeleton);
-	_Skeleton_init(SUPER(self), data);
-	VTABLE(Skeleton, self) ->dispose = _SfmlSkeleton_dispose;
+	_Skeleton_init(SUPER(self), data, _SfmlSkeleton_dispose);
 
 	CONST_CAST(SkeletonDrawable*, self->drawable) = drawable;
 
@@ -162,9 +160,7 @@ void _SfmlRegionAttachment_draw (Attachment* attachment, Slot* slot) {
 
 RegionAttachment* RegionAttachment_create (const char* name, AtlasRegion* region) {
 	SfmlRegionAttachment* self = NEW(SfmlRegionAttachment);
-	_RegionAttachment_init(SUPER(self), name);
-	VTABLE(Attachment, self) ->dispose = _SfmlRegionAttachment_dispose;
-	VTABLE(Attachment, self) ->draw = _SfmlRegionAttachment_draw;
+	_RegionAttachment_init(SUPER(self), name, _SfmlRegionAttachment_dispose, _SfmlRegionAttachment_draw);
 
 	self->texture = ((SfmlAtlasPage*)region->page)->texture;
 	int u = region->x;