[flutter] Wrap Slot, SlotData, fix memory leak when parsing JSON.

This commit is contained in:
Mario Zechner 2022-08-30 10:45:00 +02:00
parent d0a4d3dfcb
commit d0576b784c
5 changed files with 565 additions and 21 deletions

View File

@ -71,7 +71,7 @@ class AnimationStateEvents extends StatelessWidget {
}
controller.skeleton?.setScaleX(0.5);
controller.skeleton?.setScaleY(0.5);
controller.skeleton?.setColor(Color(1, 1, 0, 1));
controller.skeleton?.findSlot("gun")?.setColor(Color(1, 0, 0, 1));
controller.animationState?.setAnimation(0, "walk", true)?.setListener((event) {
print("Walk animation event ${event.type}");
});

View File

@ -16,6 +16,24 @@ int majorVersion() => _bindings.spine_major_version();
int minorVersion() => _bindings.spine_minor_version();
void reportLeaks() => _bindings.spine_report_leaks();
class Color {
double r;
double g;
double b;
double a;
Color(this.r, this.g, this.b, this.a);
}
class Bounds {
double x;
double y;
double width;
double height;
Bounds(this.x, this.y, this.width, this.height);
}
class Atlas {
final Pointer<spine_atlas> _atlas;
final List<Image> atlasPages;
@ -88,6 +106,7 @@ class SkeletonData {
static SkeletonData fromJson(Atlas atlas, String json) {
final jsonNative = json.toNativeUtf8();
final result = _bindings.spine_skeleton_data_load_json(atlas._atlas, jsonNative.cast());
calloc.free(jsonNative);
if (result.error.address != nullptr.address) {
final Pointer<Utf8> error = result.error.cast();
final message = error.toDartString();
@ -118,16 +137,122 @@ class SkeletonData {
}
}
enum BlendMode {
Normal(0),
Additive(1),
Multiply(2),
Screen(3);
final int value;
const BlendMode(this.value);
}
class BoneData {
final spine_bone_data _data;
BoneData(this._data);
}
class Bone {
final spine_bone _bone;
Bone(this._bone);
}
class SlotData {
final spine_slot_data _data;
SlotData(this._data);
int getIndex() {
return _bindings.spine_slot_data_get_index(_data);
}
String getName() {
final Pointer<Utf8> value = _bindings.spine_slot_data_get_name(_data).cast();
return value.toDartString();
}
BoneData getBoneData() {
return BoneData(_bindings.spine_slot_data_get_bone_data(_data));
}
Color getColor() {
final color = _bindings.spine_slot_data_get_color(_data);
return Color(color.r, color.g, color.b, color.a);
}
Color getDarkColor() {
final color = _bindings.spine_slot_data_get_dark_color(_data);
return Color(color.r, color.g, color.b, color.a);
}
bool hasDarkColor() {
return _bindings.spine_slot_data_has_dark_color(_data) == -1;
}
String getAttachmentName() {
final Pointer<Utf8> value = _bindings.spine_slot_data_get_attachment_name(_data).cast();
return value.toDartString();
}
BlendMode getBlendMode() {
return BlendMode.values[_bindings.spine_slot_data_get_blend_mode(_data)];
}
}
class Slot {
final spine_slot _slot;
Slot(this._slot);
void setToSetupPose() {
_bindings.spine_slot_set_to_setup_pose(_slot);
}
SlotData getData() {
return SlotData(_bindings.spine_slot_get_data(_slot));
}
Bone getBone() {
return Bone(_bindings.spine_slot_get_bone(_slot));
}
Skeleton getSkeleton() {
return Skeleton(_bindings.spine_slot_get_skeleton(_slot));
}
Color getColor() {
final color = _bindings.spine_slot_get_color(_slot);
return Color(color.r, color.g, color.b, color.a);
}
void setColor(Color color) {
_bindings.spine_slot_set_color(_slot, color.r, color.g, color.b, color.a);
}
Color getDarkColor() {
final color = _bindings.spine_slot_get_dark_color(_slot);
return Color(color.r, color.g, color.b, color.a);
}
void setDarkColor(Color color) {
_bindings.spine_slot_set_dark_color(_slot, color.r, color.g, color.b, color.a);
}
bool hasDarkColor() {
return _bindings.spine_slot_has_dark_color(_slot) == -1;
}
Attachment? getAttachment() {
final attachment = _bindings.spine_slot_get_attachment(_slot);
if (attachment.address == nullptr.address) return null;
return Attachment(attachment);
}
void setAttachment(Attachment? attachment) {
_bindings.spine_slot_set_attachment(_slot, attachment != null ? attachment._attachment : nullptr);
}
}
class Attachment {
@ -142,15 +267,6 @@ class Skin {
Skin(this._skin);
}
class Color {
double r;
double g;
double b;
double a;
Color(this.r, this.g, this.b, this.a);
}
class IkConstraint {
final spine_ik_constraint _constraint;
@ -169,15 +285,6 @@ class PathConstraint {
PathConstraint(this._constraint);
}
class Bounds {
double x;
double y;
double width;
double height;
Bounds(this.x, this.y, this.width, this.height);
}
class Skeleton {
final spine_skeleton _skeleton;
@ -234,7 +341,7 @@ class Skeleton {
/// See Skeleton::setSlotsToSetupPose()
/// Also, often AnimationState::apply(Skeleton&) is called before the next time the
/// skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin.
/// @param newSkin May be NULL.
/// @param skinName May be NULL.
void setSkin(String skinName) {
final nameNative = skinName.toNativeUtf8();
_bindings.spine_skeleton_set_skin(_skeleton, nameNative.cast());

View File

@ -2162,6 +2162,296 @@ class SpineFlutterBindings {
'spine_event_get_balance');
late final _spine_event_get_balance =
_spine_event_get_balancePtr.asFunction<double Function(spine_event)>();
int spine_slot_data_get_index(
spine_slot_data slot,
) {
return _spine_slot_data_get_index(
slot,
);
}
late final _spine_slot_data_get_indexPtr =
_lookup<ffi.NativeFunction<ffi.Int32 Function(spine_slot_data)>>(
'spine_slot_data_get_index');
late final _spine_slot_data_get_index =
_spine_slot_data_get_indexPtr.asFunction<int Function(spine_slot_data)>();
ffi.Pointer<ffi.Int8> spine_slot_data_get_name(
spine_slot_data slot,
) {
return _spine_slot_data_get_name(
slot,
);
}
late final _spine_slot_data_get_namePtr = _lookup<
ffi.NativeFunction<ffi.Pointer<ffi.Int8> Function(spine_slot_data)>>(
'spine_slot_data_get_name');
late final _spine_slot_data_get_name = _spine_slot_data_get_namePtr
.asFunction<ffi.Pointer<ffi.Int8> Function(spine_slot_data)>();
spine_bone_data spine_slot_data_get_bone_data(
spine_slot_data slot,
) {
return _spine_slot_data_get_bone_data(
slot,
);
}
late final _spine_slot_data_get_bone_dataPtr =
_lookup<ffi.NativeFunction<spine_bone_data Function(spine_slot_data)>>(
'spine_slot_data_get_bone_data');
late final _spine_slot_data_get_bone_data = _spine_slot_data_get_bone_dataPtr
.asFunction<spine_bone_data Function(spine_slot_data)>();
spine_color spine_slot_data_get_color(
spine_slot_data slot,
) {
return _spine_slot_data_get_color(
slot,
);
}
late final _spine_slot_data_get_colorPtr =
_lookup<ffi.NativeFunction<spine_color Function(spine_slot_data)>>(
'spine_slot_data_get_color');
late final _spine_slot_data_get_color = _spine_slot_data_get_colorPtr
.asFunction<spine_color Function(spine_slot_data)>();
spine_color spine_slot_data_get_dark_color(
spine_slot_data slot,
) {
return _spine_slot_data_get_dark_color(
slot,
);
}
late final _spine_slot_data_get_dark_colorPtr =
_lookup<ffi.NativeFunction<spine_color Function(spine_slot_data)>>(
'spine_slot_data_get_dark_color');
late final _spine_slot_data_get_dark_color =
_spine_slot_data_get_dark_colorPtr
.asFunction<spine_color Function(spine_slot_data)>();
int spine_slot_data_has_dark_color(
spine_slot_data slot,
) {
return _spine_slot_data_has_dark_color(
slot,
);
}
late final _spine_slot_data_has_dark_colorPtr =
_lookup<ffi.NativeFunction<ffi.Int32 Function(spine_slot_data)>>(
'spine_slot_data_has_dark_color');
late final _spine_slot_data_has_dark_color =
_spine_slot_data_has_dark_colorPtr
.asFunction<int Function(spine_slot_data)>();
ffi.Pointer<ffi.Int8> spine_slot_data_get_attachment_name(
spine_slot_data slot,
) {
return _spine_slot_data_get_attachment_name(
slot,
);
}
late final _spine_slot_data_get_attachment_namePtr = _lookup<
ffi.NativeFunction<ffi.Pointer<ffi.Int8> Function(spine_slot_data)>>(
'spine_slot_data_get_attachment_name');
late final _spine_slot_data_get_attachment_name =
_spine_slot_data_get_attachment_namePtr
.asFunction<ffi.Pointer<ffi.Int8> Function(spine_slot_data)>();
int spine_slot_data_get_blend_mode(
spine_slot_data slot,
) {
return _spine_slot_data_get_blend_mode(
slot,
);
}
late final _spine_slot_data_get_blend_modePtr =
_lookup<ffi.NativeFunction<ffi.Int32 Function(spine_slot_data)>>(
'spine_slot_data_get_blend_mode');
late final _spine_slot_data_get_blend_mode =
_spine_slot_data_get_blend_modePtr
.asFunction<int Function(spine_slot_data)>();
void spine_slot_set_to_setup_pose(
spine_slot slot,
) {
return _spine_slot_set_to_setup_pose(
slot,
);
}
late final _spine_slot_set_to_setup_posePtr =
_lookup<ffi.NativeFunction<ffi.Void Function(spine_slot)>>(
'spine_slot_set_to_setup_pose');
late final _spine_slot_set_to_setup_pose =
_spine_slot_set_to_setup_posePtr.asFunction<void Function(spine_slot)>();
spine_slot_data spine_slot_get_data(
spine_slot slot,
) {
return _spine_slot_get_data(
slot,
);
}
late final _spine_slot_get_dataPtr =
_lookup<ffi.NativeFunction<spine_slot_data Function(spine_slot)>>(
'spine_slot_get_data');
late final _spine_slot_get_data = _spine_slot_get_dataPtr
.asFunction<spine_slot_data Function(spine_slot)>();
spine_bone spine_slot_get_bone(
spine_slot slot,
) {
return _spine_slot_get_bone(
slot,
);
}
late final _spine_slot_get_bonePtr =
_lookup<ffi.NativeFunction<spine_bone Function(spine_slot)>>(
'spine_slot_get_bone');
late final _spine_slot_get_bone =
_spine_slot_get_bonePtr.asFunction<spine_bone Function(spine_slot)>();
spine_skeleton spine_slot_get_skeleton(
spine_slot slot,
) {
return _spine_slot_get_skeleton(
slot,
);
}
late final _spine_slot_get_skeletonPtr =
_lookup<ffi.NativeFunction<spine_skeleton Function(spine_slot)>>(
'spine_slot_get_skeleton');
late final _spine_slot_get_skeleton = _spine_slot_get_skeletonPtr
.asFunction<spine_skeleton Function(spine_slot)>();
spine_color spine_slot_get_color(
spine_slot slot,
) {
return _spine_slot_get_color(
slot,
);
}
late final _spine_slot_get_colorPtr =
_lookup<ffi.NativeFunction<spine_color Function(spine_slot)>>(
'spine_slot_get_color');
late final _spine_slot_get_color =
_spine_slot_get_colorPtr.asFunction<spine_color Function(spine_slot)>();
void spine_slot_set_color(
spine_slot slot,
double r,
double g,
double b,
double a,
) {
return _spine_slot_set_color(
slot,
r,
g,
b,
a,
);
}
late final _spine_slot_set_colorPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(spine_slot, ffi.Float, ffi.Float, ffi.Float,
ffi.Float)>>('spine_slot_set_color');
late final _spine_slot_set_color = _spine_slot_set_colorPtr
.asFunction<void Function(spine_slot, double, double, double, double)>();
spine_color spine_slot_get_dark_color(
spine_slot slot,
) {
return _spine_slot_get_dark_color(
slot,
);
}
late final _spine_slot_get_dark_colorPtr =
_lookup<ffi.NativeFunction<spine_color Function(spine_slot)>>(
'spine_slot_get_dark_color');
late final _spine_slot_get_dark_color = _spine_slot_get_dark_colorPtr
.asFunction<spine_color Function(spine_slot)>();
void spine_slot_set_dark_color(
spine_slot slot,
double r,
double g,
double b,
double a,
) {
return _spine_slot_set_dark_color(
slot,
r,
g,
b,
a,
);
}
late final _spine_slot_set_dark_colorPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(spine_slot, ffi.Float, ffi.Float, ffi.Float,
ffi.Float)>>('spine_slot_set_dark_color');
late final _spine_slot_set_dark_color = _spine_slot_set_dark_colorPtr
.asFunction<void Function(spine_slot, double, double, double, double)>();
int spine_slot_has_dark_color(
spine_slot slot,
) {
return _spine_slot_has_dark_color(
slot,
);
}
late final _spine_slot_has_dark_colorPtr =
_lookup<ffi.NativeFunction<ffi.Int32 Function(spine_slot)>>(
'spine_slot_has_dark_color');
late final _spine_slot_has_dark_color =
_spine_slot_has_dark_colorPtr.asFunction<int Function(spine_slot)>();
spine_attachment spine_slot_get_attachment(
spine_slot slot,
) {
return _spine_slot_get_attachment(
slot,
);
}
late final _spine_slot_get_attachmentPtr =
_lookup<ffi.NativeFunction<spine_attachment Function(spine_slot)>>(
'spine_slot_get_attachment');
late final _spine_slot_get_attachment = _spine_slot_get_attachmentPtr
.asFunction<spine_attachment Function(spine_slot)>();
void spine_slot_set_attachment(
spine_slot slot,
spine_attachment attachment,
) {
return _spine_slot_set_attachment(
slot,
attachment,
);
}
late final _spine_slot_set_attachmentPtr = _lookup<
ffi.NativeFunction<ffi.Void Function(spine_slot, spine_attachment)>>(
'spine_slot_set_attachment');
late final _spine_slot_set_attachment = _spine_slot_set_attachmentPtr
.asFunction<void Function(spine_slot, spine_attachment)>();
}
class spine_atlas extends ffi.Struct {
@ -2284,3 +2574,5 @@ typedef spine_ik_constraint = ffi.Pointer<ffi.Void>;
typedef spine_transform_constraint = ffi.Pointer<ffi.Void>;
typedef spine_path_constraint = ffi.Pointer<ffi.Void>;
typedef spine_event_data = ffi.Pointer<ffi.Void>;
typedef spine_slot_data = ffi.Pointer<ffi.Void>;
typedef spine_bone_data = ffi.Pointer<ffi.Void>;

View File

@ -1041,4 +1041,128 @@ FFI_PLUGIN_EXPORT float spine_event_get_balance(spine_event event) {
if (event == nullptr) return 0;
Event *_event = (Event*)event;
return _event->getBalance();
}
// SlotData
FFI_PLUGIN_EXPORT int spine_slot_data_get_index(spine_slot_data slot) {
if (slot == nullptr) return 0;
SlotData *_slot = (SlotData*)slot;
return _slot->getIndex();
}
FFI_PLUGIN_EXPORT const char* spine_slot_data_get_name(spine_slot_data slot) {
if (slot == nullptr) return nullptr;
SlotData *_slot = (SlotData*)slot;
return _slot->getName().buffer();
}
FFI_PLUGIN_EXPORT spine_bone_data spine_slot_data_get_bone_data(spine_slot_data slot) {
if (slot == nullptr) return nullptr;
SlotData *_slot = (SlotData*)slot;
return &_slot->getBoneData();
}
FFI_PLUGIN_EXPORT spine_color spine_slot_data_get_color(spine_slot_data slot) {
spine_color color = { 0, 0, 0, 0 };
if (slot == nullptr) return color;
SlotData *_slot = (SlotData*)slot;
color = { _slot->getColor().r, _slot->getColor().g, _slot->getColor().b, _slot->getColor().a };
return color;
}
FFI_PLUGIN_EXPORT spine_color spine_slot_data_get_dark_color(spine_slot_data slot) {
spine_color color = { 0, 0, 0, 0 };
if (slot == nullptr) return color;
SlotData *_slot = (SlotData*)slot;
color = { _slot->getDarkColor().r, _slot->getDarkColor().g, _slot->getDarkColor().b, _slot->getDarkColor().a };
return color;
}
FFI_PLUGIN_EXPORT int spine_slot_data_has_dark_color(spine_slot_data slot) {
if (slot == nullptr) return 0;
SlotData *_slot = (SlotData*)slot;
return _slot->hasDarkColor() ? -1 : 0;
}
FFI_PLUGIN_EXPORT const char* spine_slot_data_get_attachment_name(spine_slot_data slot) {
if (slot == nullptr) return nullptr;
SlotData *_slot = (SlotData*)slot;
return _slot->getAttachmentName().buffer();
}
FFI_PLUGIN_EXPORT spine_blend_mode spine_slot_data_get_blend_mode(spine_slot_data slot) {
if (slot == nullptr) return SPINE_BLEND_MODE_NORMAL;
SlotData *_slot = (SlotData*)slot;
return (spine_blend_mode)_slot->getBlendMode();
}
// Slot
FFI_PLUGIN_EXPORT void spine_slot_set_to_setup_pose(spine_slot slot) {
if (slot == nullptr) return;
Slot *_slot = (Slot*)slot;
_slot->setToSetupPose();
}
FFI_PLUGIN_EXPORT spine_slot_data spine_slot_get_data(spine_slot slot) {
if (slot == nullptr) return nullptr;
Slot *_slot = (Slot*)slot;
return &_slot->getData();
}
FFI_PLUGIN_EXPORT spine_bone spine_slot_get_bone(spine_slot slot) {
if (slot == nullptr) return nullptr;
Slot *_slot = (Slot*)slot;
return &_slot->getBone();
}
FFI_PLUGIN_EXPORT spine_skeleton spine_slot_get_skeleton(spine_slot slot) {
if (slot == nullptr) return nullptr;
Slot *_slot = (Slot*)slot;
return &_slot->getSkeleton();
}
FFI_PLUGIN_EXPORT spine_color spine_slot_get_color(spine_slot slot) {
spine_color color = { 0, 0, 0, 0 };
if (slot == nullptr) return color;
Slot *_slot = (Slot*)slot;
color = { _slot->getColor().r, _slot->getColor().g, _slot->getColor().b, _slot->getColor().a };
return color;
}
FFI_PLUGIN_EXPORT void spine_slot_set_color(spine_slot slot, float r, float g, float b, float a) {
if (slot == nullptr) return;
Slot *_slot = (Slot*)slot;
_slot->getColor().set(r, g, b, a);
}
FFI_PLUGIN_EXPORT spine_color spine_slot_get_dark_color(spine_slot slot) {
spine_color color = { 0, 0, 0, 0 };
if (slot == nullptr) return color;
Slot *_slot = (Slot*)slot;
color = { _slot->getDarkColor().r, _slot->getDarkColor().g, _slot->getDarkColor().b, _slot->getDarkColor().a };
return color;
}
FFI_PLUGIN_EXPORT void spine_slot_set_dark_color(spine_slot slot, float r, float g, float b, float a) {
if (slot == nullptr) return;
Slot *_slot = (Slot*)slot;
_slot->getDarkColor().set(r, g, b, a);
}
FFI_PLUGIN_EXPORT int spine_slot_has_dark_color(spine_slot slot) {
if (slot == nullptr) return 0;
Slot *_slot = (Slot*)slot;
return _slot->hasDarkColor() ? -1 : 0;
}
FFI_PLUGIN_EXPORT spine_attachment spine_slot_get_attachment(spine_slot slot) {
if (slot == nullptr) return nullptr;
Slot *_slot = (Slot*)slot;
return _slot->getAttachment();
}
FFI_PLUGIN_EXPORT void spine_slot_set_attachment(spine_slot slot, spine_attachment attachment) {
if (slot == nullptr) return;
Slot *_slot = (Slot*)slot;
_slot->setAttachment((Attachment*)attachment);
}

View File

@ -250,4 +250,25 @@ FFI_PLUGIN_EXPORT int spine_event_get_int_value(spine_event event);
FFI_PLUGIN_EXPORT float spine_event_get_float_value(spine_event event);
FFI_PLUGIN_EXPORT const char* spine_event_get_string_value(spine_event event);
FFI_PLUGIN_EXPORT float spine_event_get_volume(spine_event event);
FFI_PLUGIN_EXPORT float spine_event_get_balance(spine_event event);
FFI_PLUGIN_EXPORT float spine_event_get_balance(spine_event event);
FFI_PLUGIN_EXPORT int spine_slot_data_get_index(spine_slot_data slot);
FFI_PLUGIN_EXPORT const char* spine_slot_data_get_name(spine_slot_data slot);
FFI_PLUGIN_EXPORT spine_bone_data spine_slot_data_get_bone_data(spine_slot_data slot);
FFI_PLUGIN_EXPORT spine_color spine_slot_data_get_color(spine_slot_data slot);
FFI_PLUGIN_EXPORT spine_color spine_slot_data_get_dark_color(spine_slot_data slot);
FFI_PLUGIN_EXPORT int spine_slot_data_has_dark_color(spine_slot_data slot);
FFI_PLUGIN_EXPORT const char* spine_slot_data_get_attachment_name(spine_slot_data slot);
FFI_PLUGIN_EXPORT spine_blend_mode spine_slot_data_get_blend_mode(spine_slot_data slot);
FFI_PLUGIN_EXPORT void spine_slot_set_to_setup_pose(spine_slot slot);
FFI_PLUGIN_EXPORT spine_slot_data spine_slot_get_data(spine_slot slot);
FFI_PLUGIN_EXPORT spine_bone spine_slot_get_bone(spine_slot slot);
FFI_PLUGIN_EXPORT spine_skeleton spine_slot_get_skeleton(spine_slot slot);
FFI_PLUGIN_EXPORT spine_color spine_slot_get_color(spine_slot slot);
FFI_PLUGIN_EXPORT void spine_slot_set_color(spine_slot slot, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT spine_color spine_slot_get_dark_color(spine_slot slot);
FFI_PLUGIN_EXPORT void spine_slot_set_dark_color(spine_slot slot, float r, float g, float b, float a);
FFI_PLUGIN_EXPORT int spine_slot_has_dark_color(spine_slot slot);
FFI_PLUGIN_EXPORT spine_attachment spine_slot_get_attachment(spine_slot slot);
FFI_PLUGIN_EXPORT void spine_slot_set_attachment(spine_slot slot, spine_attachment attachment);