Skip to content

Commit

Permalink
Simplify Drawdance Rust types
Browse files Browse the repository at this point in the history
Instead now the attached/detached state is a separate type, so functions
can just take a reference to the underlying persistent or transient
wrapper without having to use any templates or dyn.
  • Loading branch information
askmeaboutlo0m committed Oct 31, 2023
1 parent b2a5ef8 commit 56fd406
Show file tree
Hide file tree
Showing 15 changed files with 696 additions and 875 deletions.
26 changes: 12 additions & 14 deletions src/drawdance/libengine/dpengine/load_old_animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
use drawdance::{
engine::{
AttachedLayerPropsList, BaseCanvasState, BaseLayerList, BaseLayerProps, BaseLayerPropsList,
BaseTransientCanvasState, BaseTransientDocumentMetadata, BaseTransientLayerList,
BaseTransientLayerProps, BaseTransientLayerPropsList, BaseTransientTimeline,
BaseTransientTrack, CanvasState, TransientCanvasState, TransientKeyFrame,
TransientLayerGroup, TransientLayerList, TransientLayerProps, TransientLayerPropsList,
TransientTimeline, TransientTrack,
CArc, CanvasState, DetachedCanvasState, LayerPropsList, Persister, TransientCanvasState,
TransientKeyFrame, TransientLayerGroup, TransientLayerList, TransientLayerProps,
TransientLayerPropsList, TransientTimeline, TransientTrack,
},
DP_CanvasState, DP_DrawContext, DP_LoadResult, DP_TransientLayerProps, DP_TransientTrack,
DP_load_ora,
Expand All @@ -32,10 +30,10 @@ fn load_ora(
dc: *mut DP_DrawContext,
path: *const c_char,
out_result: *mut DP_LoadResult,
) -> (Option<CanvasState>, HashSet<c_int>) {
) -> (Option<DetachedCanvasState>, HashSet<c_int>) {
let mut fixed_layer_ids = HashSet::new();
let fixed_layer_ids_ptr: *mut HashSet<c_int> = &mut fixed_layer_ids;
let cs = CanvasState::new_noinc_nullable(unsafe {
let cs = CanvasState::new_detached_noinc_nullable(unsafe {
DP_load_ora(
dc,
path,
Expand Down Expand Up @@ -71,7 +69,7 @@ fn count_elements(

fn count_frame_run(
fixed_layer_ids: &HashSet<c_int>,
lpl: &AttachedLayerPropsList<CanvasState>,
lpl: &LayerPropsList,
layer_count: c_int,
start_index: c_int,
) -> c_int {
Expand All @@ -86,7 +84,7 @@ fn count_frame_run(
}

fn convert_animation(
cs: CanvasState,
cs: &CanvasState,
dc: *mut DP_DrawContext,
hold_time: c_int,
framerate: c_int,
Expand All @@ -103,7 +101,7 @@ fn convert_animation(

let mut tll = TransientLayerList::new_init(track_count);
let mut tlpl = TransientLayerPropsList::new_init(track_count);
let mut ttl = TransientTimeline::new(track_count);
let mut ttl = TransientTimeline::new_init(track_count);

let mut layer_index = 0;
let mut group_index = 0;
Expand Down Expand Up @@ -137,7 +135,7 @@ fn convert_animation(
let needs_blank_frame = key_frame_index + frame_run < key_frame_count;
let mut tt = TransientTrack::new_init(frame_run + c_int::from(needs_blank_frame));
tt.set_id(next_track_id);
unsafe { set_track_title(tt.transient_ptr(), group_index) };
unsafe { set_track_title(tt.as_mut_ptr(), group_index) };

for i in 0..frame_run {
child_tll.set_at_inc(&ll.at(layer_index), i);
Expand Down Expand Up @@ -186,15 +184,15 @@ fn convert_animation(
next_layer_id += 1;
}

let mut tcs = TransientCanvasState::new(&cs);
let mut tcs = TransientCanvasState::new(cs);
let mut tdm = tcs.transient_metadata();
tdm.set_framerate(framerate);
tdm.set_frame_count(1.max(key_frame_count * hold_time));
tcs.set_transient_layers_noinc(tll);
tcs.set_transient_layer_props_noinc(tlpl);
tcs.set_transient_timeline_noinc(ttl);
tcs.reindex_layer_routes(dc);
tcs.persist().leak_persistent()
tcs.persist().leak()
}

#[no_mangle]
Expand All @@ -209,7 +207,7 @@ pub extern "C" fn DP_load_old_animation(
) -> *mut DP_CanvasState {
match load_ora(dc, path, out_result) {
(Some(cs), fixed_layer_ids) => convert_animation(
cs,
&cs,
dc,
hold_time,
framerate,
Expand Down
90 changes: 44 additions & 46 deletions src/drawdance/libengine/dpengine/save_psd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ use drawdance::{
common::Output,
dp_error_set,
engine::{
AttachedCanvasState, BaseCanvasState, BaseLayerContent, BaseLayerGroup, BaseLayerList,
BaseLayerProps, BaseLayerPropsList, TransientLayerContent,
BaseCanvasState, BaseLayerContent, BaseLayerGroup, BaseLayerList, BaseLayerProps,
BaseLayerPropsList, CanvasState, LayerContent, LayerList, LayerProps, LayerPropsList,
TransientLayerContent,
},
DP_BlendMode, DP_CanvasState, DP_DrawContext, DP_SaveResult, DP_UPixel8,
DP_draw_context_pool_require, DP_BLEND_MODE_ADD, DP_BLEND_MODE_BURN, DP_BLEND_MODE_COLOR,
DP_BLEND_MODE_DARKEN, DP_BLEND_MODE_DIVIDE, DP_BLEND_MODE_DODGE, DP_BLEND_MODE_HARD_LIGHT,
DP_BLEND_MODE_HUE, DP_BLEND_MODE_LIGHTEN, DP_BLEND_MODE_LINEAR_BURN,
DP_BLEND_MODE_LINEAR_LIGHT, DP_BLEND_MODE_LUMINOSITY, DP_BLEND_MODE_MULTIPLY,
DP_BLEND_MODE_NORMAL, DP_BLEND_MODE_OVERLAY, DP_BLEND_MODE_SATURATION, DP_BLEND_MODE_SCREEN,
DP_BLEND_MODE_SOFT_LIGHT, DP_BLEND_MODE_SUBTRACT, DP_SAVE_RESULT_INTERNAL_ERROR,
DP_SAVE_RESULT_OPEN_ERROR, DP_SAVE_RESULT_SUCCESS, DP_SAVE_RESULT_WRITE_ERROR,
DP_BLEND_MODE_SOFT_LIGHT, DP_BLEND_MODE_SUBTRACT, DP_SAVE_RESULT_BAD_ARGUMENTS,
DP_SAVE_RESULT_INTERNAL_ERROR, DP_SAVE_RESULT_OPEN_ERROR, DP_SAVE_RESULT_SUCCESS,
DP_SAVE_RESULT_WRITE_ERROR,
};
use std::{
collections::HashMap,
Expand Down Expand Up @@ -80,11 +82,11 @@ fn write_size_prefix(out: &mut Output, start: usize, alignment: usize) -> Result
Ok(())
}

fn count_layers_recursive(lpl: &dyn BaseLayerPropsList) -> usize {
fn count_layers_recursive(lpl: &LayerPropsList) -> usize {
let count = lpl.count();
let mut total = count as usize;
for i in 0..count {
let lp = lpl.dyn_at(i);
let lp = lpl.at(i);
if let Some(child_lpl) = lp.children() {
// PSD needs two layers for every group.
total += 1 + count_layers_recursive(&child_lpl);
Expand Down Expand Up @@ -221,8 +223,8 @@ fn write_layer_info(
Ok(())
}

fn write_layer_props_info<LP: BaseLayerProps>(
lp: &LP,
fn write_layer_props_info(
lp: &LayerProps,
out: &mut Output,
section: Section,
isolated: bool,
Expand All @@ -247,8 +249,8 @@ fn write_layer_props_info<LP: BaseLayerProps>(
Ok(())
}

fn write_layer_content_info<LP: BaseLayerProps>(
lp: &LP,
fn write_layer_content_info(
lp: &LayerProps,
out: &mut Output,
layer_offsets: &mut HashMap<*mut c_void, usize>,
) -> Result<()> {
Expand All @@ -258,13 +260,13 @@ fn write_layer_content_info<LP: BaseLayerProps>(
}

fn write_layer_infos_recursive(
lpl: &dyn BaseLayerPropsList,
lpl: &LayerPropsList,
out: &mut Output,
layer_offsets: &mut HashMap<*mut c_void, usize>,
) -> Result<()> {
let count = lpl.count();
for i in 0..count {
let lp = lpl.dyn_at(i);
let lp = lpl.at(i);
if let Some(child_lpl) = lp.children() {
let isolated = lp.isolated();
write_layer_props_info(&lp, out, Section::Divider, isolated)?;
Expand Down Expand Up @@ -455,15 +457,15 @@ fn write_pixel_data(
Ok(())
}

fn write_background_pixel_data<CS: BaseCanvasState>(
cs: &CS,
fn write_background_pixel_data(
cs: &CanvasState,
dc: *mut DP_DrawContext,
out: &mut Output,
layer_offsets: &HashMap<*mut c_void, usize>,
) -> Result<()> {
let width = cs.width();
let height = cs.height();
let pixels = TransientLayerContent::new_init(width, height, cs.background_tile().as_ref())
let pixels = TransientLayerContent::new_init(width, height, cs.background_tile().as_deref())
.to_upixels8(0, 0, width, height);
write_pixel_data(
dc,
Expand All @@ -477,8 +479,8 @@ fn write_background_pixel_data<CS: BaseCanvasState>(
)
}

fn write_layer_content_pixel_data<LC: BaseLayerContent>(
lc: &LC,
fn write_layer_content_pixel_data(
lc: &LayerContent,
dc: *mut DP_DrawContext,
out: &mut Output,
offset: usize,
Expand All @@ -497,31 +499,31 @@ fn write_layer_content_pixel_data<LC: BaseLayerContent>(
}

fn write_layer_pixel_data_recursive(
ll: &dyn BaseLayerList,
lpl: &dyn BaseLayerPropsList,
ll: &LayerList,
lpl: &LayerPropsList,
dc: *mut DP_DrawContext,
out: &mut Output,
layer_offsets: &HashMap<*mut c_void, usize>,
) -> Result<()> {
let count = lpl.count();
for i in 0..count {
let lp = lpl.dyn_at(i);
let lp = lpl.at(i);
if let Some(child_lpl) = lp.children() {
write_pixel_data(dc, out, 0, &[], 0, 0, 0, 0)?;
let lg = ll.dyn_group_at(i);
let lg = ll.group_at(i);
write_layer_pixel_data_recursive(&lg.children(), &child_lpl, dc, out, layer_offsets)?;
write_pixel_data(dc, out, 0, &[], 0, 0, 0, 0)?;
} else {
let lc = ll.dyn_content_at(i);
let lc = ll.content_at(i);
let offset = *layer_offsets.get(&lp.persistent_ptr().cast()).unwrap();
write_layer_content_pixel_data(&lc, dc, out, offset)?;
}
}
Ok(())
}

fn write_layer_pixel_data_section<CS: BaseCanvasState>(
cs: &CS,
fn write_layer_pixel_data_section(
cs: &CanvasState,
dc: *mut DP_DrawContext,
out: &mut Output,
layer_offsets: &HashMap<*mut c_void, usize>,
Expand All @@ -533,8 +535,8 @@ fn write_layer_pixel_data_section<CS: BaseCanvasState>(
Ok(())
}

fn write_layer_info_section<CS: BaseCanvasState>(
cs: &CS,
fn write_layer_info_section(
cs: &CanvasState,
dc: *mut DP_DrawContext,
out: &mut Output,
layer_offsets: &mut HashMap<*mut c_void, usize>,
Expand Down Expand Up @@ -568,11 +570,7 @@ fn write_layer_info_section<CS: BaseCanvasState>(
Ok(())
}

fn write_layer_sections<CS: BaseCanvasState>(
cs: &CS,
dc: *mut DP_DrawContext,
out: &mut Output,
) -> Result<()> {
fn write_layer_sections(cs: &CanvasState, dc: *mut DP_DrawContext, out: &mut Output) -> Result<()> {
let section_start = write_preliminary_size_prefix(out)?;
let mut layer_offsets = HashMap::new();
write_layer_info_section(cs, dc, out, &mut layer_offsets)?;
Expand Down Expand Up @@ -602,11 +600,7 @@ fn write_merged_channel(
Ok(())
}

fn write_merged_image<CS: BaseCanvasState>(
cs: &CS,
dc: *mut DP_DrawContext,
mut out: Output,
) -> Result<()> {
fn write_merged_image(cs: &CanvasState, dc: *mut DP_DrawContext, mut out: Output) -> Result<()> {
out.write_bytes(&[0, 1])?; // Compression type: run-length encoding.

let rows = usize::try_from(cs.height())?;
Expand Down Expand Up @@ -650,7 +644,7 @@ fn write_merged_image<CS: BaseCanvasState>(
Ok(())
}

fn write_psd<CS: BaseCanvasState>(cs: CS, dc: *mut DP_DrawContext, mut out: Output) -> Result<()> {
fn write_psd(cs: &CanvasState, dc: *mut DP_DrawContext, mut out: Output) -> Result<()> {
// Magic "8BPS", 2 bytes for the version (0, 1), 6 reserved zero bytes.
out.write_bytes(&[
56, 66, 80, 83, // "8BPS" magic number.
Expand All @@ -668,8 +662,8 @@ fn write_psd<CS: BaseCanvasState>(cs: CS, dc: *mut DP_DrawContext, mut out: Outp
0, 0, 0, 0, // Color mode section length, always zero for RGB.
0, 0, 0, 0, // Image resources section length, we don't have any.
])?;
write_layer_sections(&cs, dc, &mut out)?;
write_merged_image(&cs, dc, out)?;
write_layer_sections(cs, dc, &mut out)?;
write_merged_image(cs, dc, out)?;
Ok(())
}

Expand All @@ -678,13 +672,17 @@ fn save_psd(
path: *const c_char,
dc: *mut DP_DrawContext,
) -> DP_SaveResult {
let out = match Output::new_from_path(path) {
Ok(o) => o,
Err(_) => return DP_SAVE_RESULT_OPEN_ERROR,
};
match write_psd(AttachedCanvasState::<()>::new(cs), dc, out) {
Ok(()) => DP_SAVE_RESULT_SUCCESS,
Err(_) => DP_SAVE_RESULT_WRITE_ERROR,
if let Some(acs) = unsafe { cs.as_mut() }.map(CanvasState::new_attached) {
let out = match Output::new_from_path(path) {
Ok(o) => o,
Err(_) => return DP_SAVE_RESULT_OPEN_ERROR,
};
match write_psd(&acs, dc, out) {
Ok(()) => DP_SAVE_RESULT_SUCCESS,
Err(_) => DP_SAVE_RESULT_WRITE_ERROR,
}
} else {
DP_SAVE_RESULT_BAD_ARGUMENTS
}
}

Expand Down
Loading

0 comments on commit 56fd406

Please sign in to comment.