Cleanup, docs.

This commit is contained in:
NathanSweet 2013-03-31 20:40:57 +02:00
parent a3f23dd4bf
commit fe37451f93
15 changed files with 78 additions and 36 deletions

View File

@ -23,22 +23,74 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/*
Implementation notes:
- An OOP style is used where each "class" is made up of a struct and a number of functions prefixed with the struct name.
- struct fields that are const are readonly. Either they are set in a constructor and can never be changed, or they can only be
changed by calling a function.
- Inheritance is done using a struct field named "super" as the first field, allowing the struct to be cast to its "super class".
- Classes intended for inheritance provide init/deinit functions which subclasses must call in their new/free 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.
- Subclasses do not provide a free function, instead the base class' free function should be used, which will delegate to a free
function in its vtable.
- Classes not designed for inheritance cannot be extended. They may use an internal subclass to hide private data and don't
expose a vtable.
- 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.
- OOP in C tends to lose type safety. Macros are provided in extension.h to give more context about why a cast is being done.
*/
#ifndef SPINE_EXTENSION_H_
#define SPINE_EXTENSION_H_
/* All allocation uses these. */
#define MALLOC(TYPE,COUNT) ((TYPE*)malloc(sizeof(TYPE) * COUNT))
#define CALLOC(TYPE,COUNT) ((TYPE*)calloc(1, sizeof(TYPE) * COUNT))
#define NEW(TYPE) CALLOC(TYPE,1)
/* Gets the direct super class. Type safe. */
#define SUPER(VALUE) (&VALUE->super)
/* Cast to a super class. Not type safe, use with care. */
#define SUPER_CAST(TYPE,VALUE) ((TYPE*)VALUE)
/* Cast to a sub class. Not type safe, use with care. */
#define SUB_CAST(TYPE,VALUE) ((TYPE*)VALUE)
/* Casts away const. Can be used as an lvalue. Not type safe, use with care. */
#define CONST_CAST(TYPE,VALUE) (*(TYPE*)&VALUE)
/* Gets the vtable for the specified type. Can be used as an lvalue. */
#define VTABLE(TYPE,VALUE) ((_##TYPE##Vtable*)((TYPE*)VALUE)->vtable)
/* Frees memory. Can be used on const. */
#define FREE(VALUE) free((void*)VALUE)
#include <stdlib.h>
#include <spine/Skeleton.h>
#include <spine/RegionAttachment.h>
#include <spine/Animation.h>
#include <spine/Atlas.h>
#include <spine/AttachmentLoader.h>
#include <spine/util.h>
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
/* Public API that must be implemented: **/
/*
* Public API that must be implemented:
*/
Skeleton* Skeleton_new (SkeletonData* data);
@ -46,7 +98,9 @@ RegionAttachment* RegionAttachment_new (const char* name, AtlasRegion* region);
AtlasPage* AtlasPage_new (const char* name);
/* Internal API available for extension: **/
/*
* Internal API available for extension:
*/
typedef struct _SkeletonVtable {
void (*free) (Skeleton* skeleton);
@ -74,7 +128,7 @@ void _RegionAttachment_deinit (RegionAttachment* attachment);
typedef struct _TimelineVtable {
void (*apply) (const Timeline* timeline, Skeleton* skeleton, float time, float alpha);
void (*dispose) (Timeline* timeline);
void (*free) (Timeline* timeline);
} _TimelineVtable;
void _Timeline_init (Timeline* timeline);

View File

@ -26,6 +26,7 @@
#include <spine/Animation.h>
#include <math.h>
#include <spine/extension.h>
#include <spine/util.h>
Animation* Animation_new (int timelineCount) {
Animation* self = NEW(Animation);
@ -69,7 +70,7 @@ void _Timeline_deinit (Timeline* self) {
}
void Timeline_free (Timeline* self) {
VTABLE(Timeline, self) ->dispose(self);
VTABLE(Timeline, self) ->free(self);
}
void Timeline_apply (const Timeline* self, Skeleton* skeleton, float time, float alpha) {
@ -190,7 +191,7 @@ void _BaseTimeline_free (Timeline* timeline) {
struct BaseTimeline* _BaseTimeline_new (int frameCount, int frameSize) {
struct BaseTimeline* self = NEW(struct BaseTimeline);
_CurveTimeline_init(SUPER(self), frameCount);
VTABLE(Timeline, self) ->dispose = _BaseTimeline_free;
VTABLE(Timeline, self) ->free = _BaseTimeline_free;
CONST_CAST(int, self->framesLength) = frameCount * frameSize;
CONST_CAST(float*, self->frames) = CALLOC(float, self->framesLength);
@ -435,7 +436,7 @@ void _AttachmentTimeline_free (Timeline* timeline) {
AttachmentTimeline* AttachmentTimeline_new (int frameCount) {
AttachmentTimeline* self = NEW(AttachmentTimeline);
_Timeline_init(SUPER(self));
VTABLE(Timeline, self) ->dispose = _AttachmentTimeline_free;
VTABLE(Timeline, self) ->free = _AttachmentTimeline_free;
VTABLE(Timeline, self) ->apply = _AttachmentTimeline_apply;
CONST_CAST(char**, self->attachmentNames) = CALLOC(char*, frameCount);

View File

@ -26,6 +26,7 @@
#include <spine/Atlas.h>
#include <ctype.h>
#include <spine/extension.h>
#include <spine/util.h>
void _AtlasPage_init (AtlasPage* self, const char* name) {
CONST_CAST(_AtlasPageVtable*, self->vtable) = NEW(_AtlasPageVtable);

View File

@ -24,8 +24,9 @@
******************************************************************************/
#include <spine/AtlasAttachmentLoader.h>
#include <spine/extension.h>
#include <stdio.h>
#include <spine/extension.h>
#include <spine/util.h>
void _AtlasAttachmentLoader_free (AttachmentLoader* self) {
_AttachmentLoader_deinit(self);

View File

@ -25,6 +25,7 @@
#include <spine/Attachment.h>
#include <spine/extension.h>
#include <spine/util.h>
#include <spine/Slot.h>
void _Attachment_init (Attachment* self, const char* name, AttachmentType type) {

View File

@ -25,6 +25,7 @@
#include <spine/AttachmentLoader.h>
#include <spine/extension.h>
#include <spine/util.h>
void _AttachmentLoader_init (AttachmentLoader* self) {
CONST_CAST(_AttachmentLoaderVtable*, self->vtable) = NEW(_AttachmentLoaderVtable);

View File

@ -25,7 +25,7 @@
#include <spine/Bone.h>
#include <math.h>
#include <spine/util.h>
#include <spine/extension.h>
static int yDown;

View File

@ -24,6 +24,7 @@
******************************************************************************/
#include <spine/BoneData.h>
#include <spine/extension.h>
#include <spine/util.h>
BoneData* BoneData_new (const char* name, BoneData* parent) {

View File

@ -24,6 +24,7 @@
******************************************************************************/
#include <spine/Skeleton.h>
#include <string.h>
#include <spine/extension.h>
void _Skeleton_init (Skeleton* self, SkeletonData* data) {

View File

@ -24,7 +24,8 @@
******************************************************************************/
#include <spine/SkeletonData.h>
#include <spine/util.h>
#include <string.h>
#include <spine/extension.h>
SkeletonData* SkeletonData_new () {
return NEW(SkeletonData);

View File

@ -26,8 +26,9 @@
#include <spine/SkeletonJson.h>
#include <math.h>
#include <stdio.h>
#include <spine/util.h>
#include <math.h>
#include <spine/extension.h>
#include <spine/util.h>
#include <spine/Json.h>
#include <spine/RegionAttachment.h>
#include <spine/AtlasAttachmentLoader.h>

View File

@ -24,6 +24,7 @@
******************************************************************************/
#include <spine/Skin.h>
#include <spine/extension.h>
#include <spine/util.h>
SkinEntry* _SkinEntry_new (int slotIndex, const char* name, Attachment* attachment) {

View File

@ -24,7 +24,7 @@
******************************************************************************/
#include <spine/Slot.h>
#include <spine/util.h>
#include <spine/extension.h>
#include <spine/Skeleton.h>
typedef struct {

View File

@ -24,6 +24,7 @@
******************************************************************************/
#include <spine/SlotData.h>
#include <spine/extension.h>
#include <spine/util.h>
SlotData* SlotData_new (const char* name, BoneData* boneData) {

View File

@ -26,40 +26,17 @@
#ifndef SPINE_UTIL_H_
#define SPINE_UTIL_H_
#include <stdlib.h>
#include <string.h>
#include <spine/extension.h>
#ifdef __cplusplus
namespace spine {
extern "C" {
#endif
/* All allocation uses these. */
#define MALLOC(TYPE,COUNT) ((TYPE*)malloc(sizeof(TYPE) * COUNT))
#define CALLOC(TYPE,COUNT) ((TYPE*)calloc(1, sizeof(TYPE) * COUNT))
#define NEW(TYPE) CALLOC(TYPE,1)
/* Casts away const. Can be used as an lvalue. Not type safe, use with care. */
#define CONST_CAST(TYPE,VALUE) (*(TYPE*)&VALUE)
/* Gets the direct super class. Type safe. */
#define SUPER(VALUE) (&VALUE->super)
/* Cast to a super class. Not type safe, use with care. */
#define SUPER_CAST(TYPE,VALUE) ((TYPE*)VALUE)
/* Cast to a sub class. Not type safe, use with care. */
#define SUB_CAST(TYPE,VALUE) ((TYPE*)VALUE)
/* Gets the vtable for the specified type. Can be used as an lvalue. */
#define VTABLE(TYPE,VALUE) ((_##TYPE##Vtable*)((TYPE*)VALUE)->vtable)
/* Allocates a new char[], assigns it to TO, and copies FROM to it. Can be used on const. */
#define MALLOC_STR(TO,FROM) strcpy(CONST_CAST(char*, TO) = (char*)malloc(strlen(FROM)), FROM)
/* Frees memory. Can be used on const. */
#define FREE(VALUE) free((void*)VALUE)
/* Read file at specific path to a new char[]. Return value must be freed. */
const char* readFile (const char* path);