mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 01:36:02 +08:00
[flutter] Skin.getEntries() extension
This commit is contained in:
parent
fd939f4401
commit
001f4d384f
@ -6494,80 +6494,6 @@ class SpineDartBindings {
|
|||||||
late final _spine_report_leaksPtr = _lookup<ffi.NativeFunction<ffi.Void Function()>>('spine_report_leaks');
|
late final _spine_report_leaksPtr = _lookup<ffi.NativeFunction<ffi.Void Function()>>('spine_report_leaks');
|
||||||
late final _spine_report_leaks = _spine_report_leaksPtr.asFunction<void Function()>();
|
late final _spine_report_leaks = _spine_report_leaksPtr.asFunction<void Function()>();
|
||||||
|
|
||||||
/// Bounds functions
|
|
||||||
double spine_bounds_get_x(
|
|
||||||
spine_bounds bounds,
|
|
||||||
) {
|
|
||||||
return _spine_bounds_get_x(
|
|
||||||
bounds,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
late final _spine_bounds_get_xPtr =
|
|
||||||
_lookup<ffi.NativeFunction<ffi.Float Function(spine_bounds)>>('spine_bounds_get_x');
|
|
||||||
late final _spine_bounds_get_x = _spine_bounds_get_xPtr.asFunction<double Function(spine_bounds)>();
|
|
||||||
|
|
||||||
double spine_bounds_get_y(
|
|
||||||
spine_bounds bounds,
|
|
||||||
) {
|
|
||||||
return _spine_bounds_get_y(
|
|
||||||
bounds,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
late final _spine_bounds_get_yPtr =
|
|
||||||
_lookup<ffi.NativeFunction<ffi.Float Function(spine_bounds)>>('spine_bounds_get_y');
|
|
||||||
late final _spine_bounds_get_y = _spine_bounds_get_yPtr.asFunction<double Function(spine_bounds)>();
|
|
||||||
|
|
||||||
double spine_bounds_get_width(
|
|
||||||
spine_bounds bounds,
|
|
||||||
) {
|
|
||||||
return _spine_bounds_get_width(
|
|
||||||
bounds,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
late final _spine_bounds_get_widthPtr =
|
|
||||||
_lookup<ffi.NativeFunction<ffi.Float Function(spine_bounds)>>('spine_bounds_get_width');
|
|
||||||
late final _spine_bounds_get_width = _spine_bounds_get_widthPtr.asFunction<double Function(spine_bounds)>();
|
|
||||||
|
|
||||||
double spine_bounds_get_height(
|
|
||||||
spine_bounds bounds,
|
|
||||||
) {
|
|
||||||
return _spine_bounds_get_height(
|
|
||||||
bounds,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
late final _spine_bounds_get_heightPtr =
|
|
||||||
_lookup<ffi.NativeFunction<ffi.Float Function(spine_bounds)>>('spine_bounds_get_height');
|
|
||||||
late final _spine_bounds_get_height = _spine_bounds_get_heightPtr.asFunction<double Function(spine_bounds)>();
|
|
||||||
|
|
||||||
/// Vector functions
|
|
||||||
double spine_vector_get_x(
|
|
||||||
spine_vector vector,
|
|
||||||
) {
|
|
||||||
return _spine_vector_get_x(
|
|
||||||
vector,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
late final _spine_vector_get_xPtr =
|
|
||||||
_lookup<ffi.NativeFunction<ffi.Float Function(spine_vector)>>('spine_vector_get_x');
|
|
||||||
late final _spine_vector_get_x = _spine_vector_get_xPtr.asFunction<double Function(spine_vector)>();
|
|
||||||
|
|
||||||
double spine_vector_get_y(
|
|
||||||
spine_vector vector,
|
|
||||||
) {
|
|
||||||
return _spine_vector_get_y(
|
|
||||||
vector,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
late final _spine_vector_get_yPtr =
|
|
||||||
_lookup<ffi.NativeFunction<ffi.Float Function(spine_vector)>>('spine_vector_get_y');
|
|
||||||
late final _spine_vector_get_y = _spine_vector_get_yPtr.asFunction<double Function(spine_vector)>();
|
|
||||||
|
|
||||||
/// Atlas functions
|
/// Atlas functions
|
||||||
spine_atlas_result spine_atlas_load(
|
spine_atlas_result spine_atlas_load(
|
||||||
ffi.Pointer<ffi.Char> atlasData,
|
ffi.Pointer<ffi.Char> atlasData,
|
||||||
@ -6724,7 +6650,7 @@ class SpineDartBindings {
|
|||||||
late final _spine_skeleton_data_result_dispose =
|
late final _spine_skeleton_data_result_dispose =
|
||||||
_spine_skeleton_data_result_disposePtr.asFunction<void Function(spine_skeleton_data_result)>();
|
_spine_skeleton_data_result_disposePtr.asFunction<void Function(spine_skeleton_data_result)>();
|
||||||
|
|
||||||
/// Skeleton drawable functions
|
/// Skeleton drawable functionsp
|
||||||
spine_skeleton_drawable spine_skeleton_drawable_create(
|
spine_skeleton_drawable spine_skeleton_drawable_create(
|
||||||
spine_skeleton_data skeletonData,
|
spine_skeleton_data skeletonData,
|
||||||
) {
|
) {
|
||||||
@ -6823,15 +6749,20 @@ class SpineDartBindings {
|
|||||||
_spine_skeleton_drawable_get_animation_state_eventsPtr
|
_spine_skeleton_drawable_get_animation_state_eventsPtr
|
||||||
.asFunction<spine_animation_state_events Function(spine_skeleton_drawable)>();
|
.asFunction<spine_animation_state_events Function(spine_skeleton_drawable)>();
|
||||||
|
|
||||||
/// Skin entries functions
|
/// Skin functions
|
||||||
spine_skin_entries spine_skin_entries_create() {
|
spine_skin_entries spine_skin_get_entries(
|
||||||
return _spine_skin_entries_create();
|
spine_skin skin,
|
||||||
|
) {
|
||||||
|
return _spine_skin_get_entries(
|
||||||
|
skin,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
late final _spine_skin_entries_createPtr =
|
late final _spine_skin_get_entriesPtr =
|
||||||
_lookup<ffi.NativeFunction<spine_skin_entries Function()>>('spine_skin_entries_create');
|
_lookup<ffi.NativeFunction<spine_skin_entries Function(spine_skin)>>('spine_skin_get_entries');
|
||||||
late final _spine_skin_entries_create = _spine_skin_entries_createPtr.asFunction<spine_skin_entries Function()>();
|
late final _spine_skin_get_entries = _spine_skin_get_entriesPtr.asFunction<spine_skin_entries Function(spine_skin)>();
|
||||||
|
|
||||||
|
/// Skin entries functions
|
||||||
void spine_skin_entries_dispose(
|
void spine_skin_entries_dispose(
|
||||||
spine_skin_entries entries,
|
spine_skin_entries entries,
|
||||||
) {
|
) {
|
||||||
@ -40752,16 +40683,6 @@ final class spine_skeleton_data_result_wrapper extends ffi.Struct {
|
|||||||
external int _dummy;
|
external int _dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
final class spine_bounds_wrapper extends ffi.Struct {
|
|
||||||
@ffi.Char()
|
|
||||||
external int _dummy;
|
|
||||||
}
|
|
||||||
|
|
||||||
final class spine_vector_wrapper extends ffi.Struct {
|
|
||||||
@ffi.Char()
|
|
||||||
external int _dummy;
|
|
||||||
}
|
|
||||||
|
|
||||||
final class spine_skeleton_drawable_wrapper extends ffi.Struct {
|
final class spine_skeleton_drawable_wrapper extends ffi.Struct {
|
||||||
@ffi.Char()
|
@ffi.Char()
|
||||||
external int _dummy;
|
external int _dummy;
|
||||||
@ -40787,8 +40708,6 @@ final class spine_texture_loader_wrapper extends ffi.Struct {
|
|||||||
external int _dummy;
|
external int _dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef spine_bounds = ffi.Pointer<spine_bounds_wrapper>;
|
|
||||||
typedef spine_vector = ffi.Pointer<spine_vector_wrapper>;
|
|
||||||
typedef spine_atlas_result = ffi.Pointer<spine_atlas_result_wrapper>;
|
typedef spine_atlas_result = ffi.Pointer<spine_atlas_result_wrapper>;
|
||||||
|
|
||||||
/// Texture loader callbacks
|
/// Texture loader callbacks
|
||||||
|
|||||||
@ -34,6 +34,15 @@ import 'dart:typed_data';
|
|||||||
import 'package:ffi/ffi.dart';
|
import 'package:ffi/ffi.dart';
|
||||||
import 'generated/atlas.dart';
|
import 'generated/atlas.dart';
|
||||||
import 'generated/skeleton_data.dart';
|
import 'generated/skeleton_data.dart';
|
||||||
|
import 'generated/skin.dart';
|
||||||
|
import 'generated/attachment.dart';
|
||||||
|
import 'generated/region_attachment.dart';
|
||||||
|
import 'generated/mesh_attachment.dart';
|
||||||
|
import 'generated/bounding_box_attachment.dart';
|
||||||
|
import 'generated/clipping_attachment.dart';
|
||||||
|
import 'generated/path_attachment.dart';
|
||||||
|
import 'generated/point_attachment.dart';
|
||||||
|
import 'generated/rtti.dart';
|
||||||
|
|
||||||
// Export generated classes
|
// Export generated classes
|
||||||
export 'generated/api.dart';
|
export 'generated/api.dart';
|
||||||
@ -130,3 +139,77 @@ SkeletonData loadSkeletonDataBinary(Atlas atlas, Uint8List binaryData, {String?
|
|||||||
SpineBindings.bindings.spine_skeleton_data_result_dispose(resultPtr.cast());
|
SpineBindings.bindings.spine_skeleton_data_result_dispose(resultPtr.cast());
|
||||||
return skeletonData;
|
return skeletonData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents an entry in a skin
|
||||||
|
class SkinEntry {
|
||||||
|
final int slotIndex;
|
||||||
|
final String name;
|
||||||
|
final Attachment? attachment;
|
||||||
|
|
||||||
|
SkinEntry._({required this.slotIndex, required this.name, required this.attachment});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extension method for Skin to get all entries
|
||||||
|
extension SkinExtensions on Skin {
|
||||||
|
/// Get all entries (slot/attachment pairs) in this skin
|
||||||
|
List<SkinEntry> getEntries() {
|
||||||
|
final entriesPtr = SpineBindings.bindings.spine_skin_get_entries(nativePtr.cast());
|
||||||
|
if (entriesPtr == nullptr) return [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
final numEntries = SpineBindings.bindings.spine_skin_entries_get_num_entries(entriesPtr.cast());
|
||||||
|
final entries = <SkinEntry>[];
|
||||||
|
|
||||||
|
for (int i = 0; i < numEntries; i++) {
|
||||||
|
final entryPtr = SpineBindings.bindings.spine_skin_entries_get_entry(entriesPtr.cast(), i);
|
||||||
|
if (entryPtr != nullptr) {
|
||||||
|
final slotIndex = SpineBindings.bindings.spine_skin_entry_get_slot_index(entryPtr.cast());
|
||||||
|
final namePtr = SpineBindings.bindings.spine_skin_entry_get_name(entryPtr.cast());
|
||||||
|
final name = namePtr.cast<Utf8>().toDartString();
|
||||||
|
|
||||||
|
final attachmentPtr = SpineBindings.bindings.spine_skin_entry_get_attachment(entryPtr.cast());
|
||||||
|
Attachment? attachment;
|
||||||
|
if (attachmentPtr.address != 0) {
|
||||||
|
// Use RTTI to determine the concrete attachment type
|
||||||
|
final rtti = SpineBindings.bindings.spine_attachment_get_rtti(attachmentPtr);
|
||||||
|
final className = SpineBindings.bindings.spine_rtti_get_class_name(rtti).cast<Utf8>().toDartString();
|
||||||
|
|
||||||
|
switch (className) {
|
||||||
|
case 'spine_region_attachment':
|
||||||
|
attachment = RegionAttachment.fromPointer(attachmentPtr.cast());
|
||||||
|
break;
|
||||||
|
case 'spine_mesh_attachment':
|
||||||
|
attachment = MeshAttachment.fromPointer(attachmentPtr.cast());
|
||||||
|
break;
|
||||||
|
case 'spine_bounding_box_attachment':
|
||||||
|
attachment = BoundingBoxAttachment.fromPointer(attachmentPtr.cast());
|
||||||
|
break;
|
||||||
|
case 'spine_clipping_attachment':
|
||||||
|
attachment = ClippingAttachment.fromPointer(attachmentPtr.cast());
|
||||||
|
break;
|
||||||
|
case 'spine_path_attachment':
|
||||||
|
attachment = PathAttachment.fromPointer(attachmentPtr.cast());
|
||||||
|
break;
|
||||||
|
case 'spine_point_attachment':
|
||||||
|
attachment = PointAttachment.fromPointer(attachmentPtr.cast());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Unknown attachment type, treat as generic Attachment
|
||||||
|
attachment = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.add(SkinEntry._(
|
||||||
|
slotIndex: slotIndex,
|
||||||
|
name: name,
|
||||||
|
attachment: attachment,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries;
|
||||||
|
} finally {
|
||||||
|
SpineBindings.bindings.spine_skin_entries_dispose(entriesPtr.cast());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -27,6 +27,30 @@ void main() async {
|
|||||||
print('Skeleton created successfully');
|
print('Skeleton created successfully');
|
||||||
print('Skeleton has ${skeleton.slots.length} slots and ${skeleton.bones.length} bones');
|
print('Skeleton has ${skeleton.slots.length} slots and ${skeleton.bones.length} bones');
|
||||||
|
|
||||||
|
// Test skin entries
|
||||||
|
print('\nTesting skin entries...');
|
||||||
|
final defaultSkin = skeletonData.defaultSkin;
|
||||||
|
if (defaultSkin != null) {
|
||||||
|
final entries = defaultSkin.getEntries();
|
||||||
|
print('Default skin has ${entries.length} entries');
|
||||||
|
|
||||||
|
// Print first few entries
|
||||||
|
for (int i = 0; i < 5 && i < entries.length; i++) {
|
||||||
|
final entry = entries[i];
|
||||||
|
print(' Entry $i: slot=${entry.slotIndex}, name="${entry.name}", attachment=${entry.attachment?.runtimeType}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test named skins
|
||||||
|
print('\nChecking named skins...');
|
||||||
|
for (int i = 0; i < skeletonData.skins.length; i++) {
|
||||||
|
final skin = skeletonData.skins[i];
|
||||||
|
if (skin != null) {
|
||||||
|
final entries = skin.getEntries();
|
||||||
|
print('Skin "${skin.name}" has ${entries.length} entries');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
skeleton.dispose();
|
skeleton.dispose();
|
||||||
skeletonData.dispose();
|
skeletonData.dispose();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user