Skip to content

Commit

Permalink
more docs. modules, errors cleanup.
Browse files Browse the repository at this point in the history
  • Loading branch information
jabuwu committed Nov 4, 2022
1 parent dc13b12 commit 66e41f1
Show file tree
Hide file tree
Showing 21 changed files with 283 additions and 89 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rusty_spine"
version = "0.4.0"
version = "0.5.0-dev"
edition = "2021"
description = "Spine runtime for Rust (and wasm!) transpiled from the official C Runtime."
homepage = "https://github.com/jabuwu/rusty_spine"
Expand Down
11 changes: 8 additions & 3 deletions examples/bevy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ use bevy::{
sprite::Mesh2dHandle,
};
use rusty_spine::{
draw::CullDirection, AnimationStateData, Atlas, Error, SkeletonController,
SkeletonControllerSettings, SkeletonJson,
controller::{SkeletonController, SkeletonControllerSettings},
draw::CullDirection,
AnimationStateData, Atlas, SkeletonJson, SpineError,
};

#[cfg(feature = "egui_debugger")]
Expand Down Expand Up @@ -387,7 +388,11 @@ fn spine_update(
}
}

fn load_skeleton(atlas: &Vec<u8>, json: &Vec<u8>, dir: &str) -> Result<SkeletonController, Error> {
fn load_skeleton(
atlas: &Vec<u8>,
json: &Vec<u8>,
dir: &str,
) -> Result<SkeletonController, SpineError> {
let atlas = Arc::new(Atlas::new(atlas, dir)?);
let skeleton_json = SkeletonJson::new(atlas.clone());
let skeleton_data = Arc::new(skeleton_json.read_skeleton_data(json)?);
Expand Down
2 changes: 1 addition & 1 deletion examples/simple.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::Arc;

use rusty_spine::*;
use rusty_spine::{controller::*, *};

fn main() {
let atlas_path = "assets/spineboy/export/spineboy.atlas";
Expand Down
43 changes: 34 additions & 9 deletions src/animation_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
spTrackEntry, spTrackEntry_getAnimationTime, spTrackEntry_getTrackComplete,
},
c_interface::{CTmpMut, CTmpRef, NewFromPtr, SyncPtr},
error::Error,
error::SpineError,
event::Event,
skeleton::Skeleton,
};
Expand Down Expand Up @@ -65,18 +65,23 @@ impl AnimationState {
unsafe { spAnimationState_apply(self.c_animation_state.0, skeleton.c_ptr()) != 0 }
}

/// Clears all animations in all track entries in this animation state.
pub fn clear_tracks(&mut self) {
unsafe {
spAnimationState_clearTracks(self.c_ptr());
}
}

/// Clears animations for the given track entry index in this animation state.
pub fn clear_track(&mut self, track_index: i32) {
unsafe {
spAnimationState_clearTrack(self.c_ptr(), track_index);
}
}

/// Sets the animation for the given track by name, clearing any queued tracks, and returning
/// the track index. If the track index doesn't exist then it will be created.
///
/// # Safety
///
/// This function should only be called with valid animation names. It is faster than the safe
Expand All @@ -100,12 +105,18 @@ impl AnimationState {
)
}

/// Sets the animation for the given track by name, clearing any queued tracks, and returning
/// the track index. If the track index doesn't exist then it will be created.
///
/// # Errors
///
/// Returns [`SpineError::NotFound`] if an animation doesn't exist with the given name.
pub fn set_animation_by_name(
&mut self,
track_index: i32,
animation_name: &str,
looping: bool,
) -> Result<CTmpMut<Self, TrackEntry>, Error> {
) -> Result<CTmpMut<Self, TrackEntry>, SpineError> {
if self
.data()
.skeleton_data()
Expand All @@ -116,10 +127,12 @@ impl AnimationState {
self.set_animation_by_name_unchecked(track_index, animation_name, looping)
})
} else {
Err(Error::NotFound)
Err(SpineError::new_not_found("Animation", animation_name))
}
}

/// Sets the animation for the given track, clearning any queued tracks, and returning the
/// track index. If the track index doesn't exist then it will be created.
pub fn set_animation(
&mut self,
track_index: i32,
Expand All @@ -139,6 +152,9 @@ impl AnimationState {
}
}

/// Queues the animation in the given track by name, returning the track index. If the track
/// index doesn't exist then it will be created.
///
/// # Safety
///
/// This function should only be called with valid animation names. It is faster than the safe
Expand All @@ -164,13 +180,19 @@ impl AnimationState {
)
}

/// Queues the animation in the given track by name, returning the track index. If the track
/// index doesn't exist then it will be created.
///
/// # Errors
///
/// Returns [`SpineError::NotFound`] if an animation doesn't exist with the given name.
pub fn add_animation_by_name(
&mut self,
track_index: i32,
animation_name: &str,
looping: bool,
delay: f32,
) -> Result<CTmpMut<Self, TrackEntry>, Error> {
) -> Result<CTmpMut<Self, TrackEntry>, SpineError> {
if self
.data()
.skeleton_data()
Expand All @@ -181,10 +203,12 @@ impl AnimationState {
self.add_animation_by_name_unchecked(track_index, animation_name, looping, delay)
})
} else {
Err(Error::NotFound)
Err(SpineError::new_not_found("Animation", animation_name))
}
}

/// Queues the animation in the given track, returning the track index. If the track index
/// doesn't exist then it will be created.
pub fn add_animation(
&mut self,
track_index: i32,
Expand Down Expand Up @@ -259,6 +283,8 @@ impl AnimationState {
}
}

/// Set the event listener on this animation state. An animation state can only have one event
/// listener at a time. See the documentation for [`Event`] for more information.
pub fn set_listener<F>(&mut self, listener: F)
where
F: Fn(&AnimationState, EventType, &TrackEntry, Option<&Event>) + 'static,
Expand Down Expand Up @@ -464,12 +490,11 @@ impl TrackEntry {
}

c_handle_indexed_decl!(
/// A storeable reference to a [TrackEntry](struct.TrackEntry.html).
/// A storeable reference to a [`TrackEntry`].
///
/// Can be acquired from a
/// [CTmpRef<AnimationState, TrackEntry>](c_interface/struct.CTmpRef.html) or
/// [CTmpMut<AnimationState, TrackEntry>](c_interface/struct.CTmpMut.html) acquired from an
/// [AnimationState](struct.AnimationState.html) instance.
/// [`CTmpRef<AnimationState, TrackEntry>`] or [`CTmpMut<AnimationState, TrackEntry>`] acquired
/// from an [`AnimationState`] instance.
///
/// ```
/// # #[path="./doctests.rs"]
Expand Down
5 changes: 4 additions & 1 deletion src/animation_state_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use crate::{
skeleton_data::SkeletonData,
};

/// Animation settings used to instantiate [AnimationState](struct.AnimationState.html).
#[allow(unused_imports)]
use crate::AnimationState;

/// Animation settings used to instantiate [`AnimationState`].
///
/// [Spine API Reference](http://esotericsoftware.com/spine-api-reference#AnimationStateData)
///
Expand Down
31 changes: 24 additions & 7 deletions src/atlas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::c_interface::{CTmpMut, CTmpRef, NewFromPtr, SyncPtr};
use crate::texture_region::TextureRegion;
use crate::{
c::{c_int, spAtlas, spAtlasPage, spAtlas_create, spAtlas_dispose},
error::Error,
error::SpineError,
};

use atlas::*;
Expand Down Expand Up @@ -37,14 +37,21 @@ impl NewFromPtr<spAtlas> for Atlas {

impl Atlas {
/// Create an Atlas from an in-memory vector.
///
/// ```
/// use rusty_spine::Atlas;
/// fn load_atlas() -> Atlas {
/// let atlas_file = std::fs::read("skeleton.atlas").unwrap();
/// Atlas::new(&atlas_file, "").unwrap()
/// }
/// ```
pub fn new<P: AsRef<Path>>(data: &[u8], dir: P) -> Result<Atlas, Error> {
///
/// # Errors
///
/// Returns the [`SpineError::NulError`] if `dir` or `data` contain an internal 0 byte. This
/// function does not error if the atlas file is invalid or malformed. The file is parsed
/// line-by-line and invalid lines are simply ignored.
pub fn new<P: AsRef<Path>>(data: &[u8], dir: P) -> Result<Atlas, SpineError> {
let c_data = CString::new(data)?;
let c_dir = CString::new(dir.as_ref().to_str().unwrap())?;
let c_atlas = unsafe {
Expand All @@ -64,11 +71,17 @@ impl Atlas {
/// Create an Atlas from a file.
/// ```
/// use rusty_spine::Atlas;
/// fn load_atlas() -> Result<Atlas, rusty_spine::Error>{
/// fn load_atlas() -> Result<Atlas, rusty_spine::SpineError>{
/// Ok(Atlas::new_from_file("skeleton.json")?)
/// }
/// ```
pub fn new_from_file<P: AsRef<Path>>(path: P) -> Result<Atlas, Error> {
///
/// # Errors
///
/// Returns [`SpineError::FailedToReadFile`] if the file could not be read, returns
/// [`SpineError::NulError`] if `path` contains an internal 0 byte or if the loaded atlas
/// contains a 0 byte.
pub fn new_from_file<P: AsRef<Path>>(path: P) -> Result<Atlas, SpineError> {
let c_path = CString::new(path.as_ref().to_str().unwrap())?;
let c_atlas = unsafe { spAtlas_createFromFile(c_path.as_ptr(), null_mut()) };
if !c_atlas.is_null() {
Expand All @@ -77,9 +90,9 @@ impl Atlas {
owns_memory: true,
})
} else {
Err(Error::FailedToReadFile(
path.as_ref().to_str().unwrap().to_owned(),
))
Err(SpineError::FailedToReadFile {
file: path.as_ref().to_str().unwrap().to_owned(),
})
}
}

Expand Down Expand Up @@ -142,6 +155,10 @@ impl Drop for Atlas {
}

pub mod atlas {
//! Types related to atlases.
//!
//! To load an atlas file, see [`Atlas`].
use super::*;

#[derive(Debug)]
Expand Down
16 changes: 7 additions & 9 deletions src/bone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,16 @@ use crate::{
#[cfg(feature = "mint")]
use mint::Vector2;

/// A bone within the [Skeleton](struct.Skeleton.html) hierarchy.
/// A bone within the [`Skeleton`] hierarchy.
///
/// [Spine API Reference](http://esotericsoftware.com/spine-api-reference#Bone)
///
/// Bones can be acquired from a [Skeleton](struct.Skeleton.html) and a safe
/// [BoneHandle](struct.BoneHandle.html) can be obtained using the
/// [handle](struct.Bone.html#method.handle) method to store long-term references to a specific
/// Bones can be acquired from a [`Skeleton`] and a safe [`BoneHandle`] can be obtained using the
/// [`Bone::handle`] method to store long-term references to a specific
/// bone.
///
/// The hierarchy can be traversed using [parent](struct.Bone.html#method.parent) and
/// [children](struct.Bone.html#method.children), and specific bones can be located using
/// [Skeleton::find_bone](struct.Skeleton.html#method.find_bone).
/// The hierarchy can be traversed using [`Bone::parent`] and [`Bone::children`], and specific
/// bones can be located using [`Skeleton::find_bone`].
#[derive(Debug)]
pub struct Bone {
c_bone: SyncPtr<spBone>,
Expand Down Expand Up @@ -352,9 +350,9 @@ impl Bone {
}

c_handle_decl!(
/// A storeable reference to a [Bone](struct.Bone.html).
/// A storeable reference to a [`Bone`].
///
/// Can be acquired from any instance of [Bone](struct.Bone.html).
/// Can be acquired from any instance of [`Bone`].
///
/// ```
/// # #[path="./doctests.rs"]
Expand Down
2 changes: 2 additions & 0 deletions src/skeleton_controller.rs → src/controller.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Provides [`SkeletonController`], a helper struct for updating and drawing Spine skeletons.
use std::{mem::take, sync::Arc};

use crate::{
Expand Down
30 changes: 27 additions & 3 deletions src/draw/combined.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,50 @@ use crate::{

use super::{ColorSpace, CullDirection};

#[allow(unused_imports)]
use crate::{draw::SimpleDrawer, extension};

/// Renderables generated from [`CombinedDrawer::draw`].
pub struct CombinedRenderable {
/// A list of vertex attributes for a mesh.
pub vertices: Vec<[f32; 2]>,
/// A list of UV attributes for a mesh.
pub uvs: Vec<[f32; 2]>,
/// A list of color attributes for a mesh.
pub colors: Vec<[f32; 4]>,
/// A list of dark color attributes for a mesh.
/// See the [Spine User Guide](http://en.esotericsoftware.com/spine-slots#Tint-black).
pub dark_colors: Vec<[f32; 4]>,
/// A list of indices for a mesh.
pub indices: Vec<u16>,
/// The blend mode to use when drawing this mesh.
pub blend_mode: BlendMode,
/// The attachment's renderer object as a raw pointer. Usually represents the texture created
/// from [`extension::set_create_texture_cb`].
pub attachment_renderer_object: Option<*const c_void>,
}

/// A combined drawer with a mesh combining optimization.
///
/// Assumes use of the default atlas attachment loader.
///
/// See [`CombinedDrawer::draw`]
pub struct CombinedDrawer {
pub cull_direction: CullDirection,
pub premultiplied_alpha: bool,
pub color_space: ColorSpace,
}

/// A combined drawer with a mesh combining optimization.
///
/// Assumes use of the default atlas attachment loader.
impl CombinedDrawer {
/// This function returns a list of [`CombinedRenderable`] structs containing all the necessary
/// data to create and render meshes. Attachments are batched together into a single renderable
/// so long as their blend mode or renderer object is not different from the previous
/// attachment. If a [`SkeletonClipping`] is provided, meshes will be properly clipped. The
/// renderables are expected to be rendered in the order provided with the first renderable
/// being drawn behind all the others.
///
/// This drawer can provide a significant performance advantage over the [`SimpleDrawer`] in
/// most cases.
pub fn draw(
&self,
skeleton: &mut Skeleton,
Expand Down
8 changes: 8 additions & 0 deletions src/draw/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
//! Helpers types for drawing Spine skeletons.
//!
//! Drawers generate mesh information ready to be used in graphics libraries and game engines.
//!
//! Two implementations are currently provided:
//! - [`SimpleDrawer`]
//! - [`CombinedDrawer`]
mod combined;
mod simple;

Expand Down
Loading

0 comments on commit 66e41f1

Please sign in to comment.