Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 106 additions & 81 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ path = "examples/rectangle.rs"
name = "background_image"
path = "examples/background_image.rs"

[[example]]
name = "update_pixels"
path = "examples/update_pixels.rs"

[profile.wasm-release]
inherits = "release"
opt-level = "z"
Expand Down
30 changes: 17 additions & 13 deletions crates/processing_ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ pub extern "C" fn processing_surface_resize(window_id: u64, width: u32, height:
pub extern "C" fn processing_background_color(window_id: u64, color: Color) {
error::clear_error();
let window_entity = Entity::from_bits(window_id);
error::check(|| record_command(window_entity, DrawCommand::BackgroundColor(color.into())));
error::check(|| {
graphics_record_command(window_entity, DrawCommand::BackgroundColor(color.into()))
});
}

/// Set the background image for the given window.
Expand All @@ -90,7 +92,9 @@ pub extern "C" fn processing_background_image(window_id: u64, image_id: u64) {
error::clear_error();
let window_entity = Entity::from_bits(window_id);
let image_entity = Entity::from_bits(image_id);
error::check(|| record_command(window_entity, DrawCommand::BackgroundImage(image_entity)));
error::check(|| {
graphics_record_command(window_entity, DrawCommand::BackgroundImage(image_entity))
});
}

/// Begins the draw for the given window.
Expand All @@ -102,7 +106,7 @@ pub extern "C" fn processing_background_image(window_id: u64, image_id: u64) {
pub extern "C" fn processing_begin_draw(window_id: u64) {
error::clear_error();
let window_entity = Entity::from_bits(window_id);
error::check(|| begin_draw(window_entity));
error::check(|| graphics_begin_draw(window_entity));
}

/// Flushes recorded draw commands for the given window.
Expand All @@ -114,7 +118,7 @@ pub extern "C" fn processing_begin_draw(window_id: u64) {
pub extern "C" fn processing_flush(window_id: u64) {
error::clear_error();
let window_entity = Entity::from_bits(window_id);
error::check(|| flush(window_entity));
error::check(|| graphics_flush(window_entity));
}

/// Ends the draw for the given window and presents the frame.
Expand All @@ -126,7 +130,7 @@ pub extern "C" fn processing_flush(window_id: u64) {
pub extern "C" fn processing_end_draw(window_id: u64) {
error::clear_error();
let window_entity = Entity::from_bits(window_id);
error::check(|| end_draw(window_entity));
error::check(|| graphics_end_draw(window_entity));
}

/// Shuts down internal resources with given exit code, but does *not* terminate the process.
Expand All @@ -151,7 +155,7 @@ pub extern "C" fn processing_set_fill(window_id: u64, r: f32, g: f32, b: f32, a:
error::clear_error();
let window_entity = Entity::from_bits(window_id);
let color = bevy::color::Color::srgba(r, g, b, a);
error::check(|| record_command(window_entity, DrawCommand::Fill(color)));
error::check(|| graphics_record_command(window_entity, DrawCommand::Fill(color)));
}

/// Set the stroke color.
Expand All @@ -165,7 +169,7 @@ pub extern "C" fn processing_set_stroke_color(window_id: u64, r: f32, g: f32, b:
error::clear_error();
let window_entity = Entity::from_bits(window_id);
let color = bevy::color::Color::srgba(r, g, b, a);
error::check(|| record_command(window_entity, DrawCommand::StrokeColor(color)));
error::check(|| graphics_record_command(window_entity, DrawCommand::StrokeColor(color)));
}

/// Set the stroke weight.
Expand All @@ -178,7 +182,7 @@ pub extern "C" fn processing_set_stroke_color(window_id: u64, r: f32, g: f32, b:
pub extern "C" fn processing_set_stroke_weight(window_id: u64, weight: f32) {
error::clear_error();
let window_entity = Entity::from_bits(window_id);
error::check(|| record_command(window_entity, DrawCommand::StrokeWeight(weight)));
error::check(|| graphics_record_command(window_entity, DrawCommand::StrokeWeight(weight)));
}

/// Disable fill for subsequent shapes.
Expand All @@ -191,7 +195,7 @@ pub extern "C" fn processing_set_stroke_weight(window_id: u64, weight: f32) {
pub extern "C" fn processing_no_fill(window_id: u64) {
error::clear_error();
let window_entity = Entity::from_bits(window_id);
error::check(|| record_command(window_entity, DrawCommand::NoFill));
error::check(|| graphics_record_command(window_entity, DrawCommand::NoFill));
}

/// Disable stroke for subsequent shapes.
Expand All @@ -204,7 +208,7 @@ pub extern "C" fn processing_no_fill(window_id: u64) {
pub extern "C" fn processing_no_stroke(window_id: u64) {
error::clear_error();
let window_entity = Entity::from_bits(window_id);
error::check(|| record_command(window_entity, DrawCommand::NoStroke));
error::check(|| graphics_record_command(window_entity, DrawCommand::NoStroke));
}

/// Draw a rectangle.
Expand All @@ -228,7 +232,7 @@ pub extern "C" fn processing_rect(
error::clear_error();
let window_entity = Entity::from_bits(window_id);
error::check(|| {
record_command(
graphics_record_command(
window_entity,
DrawCommand::Rect {
x,
Expand Down Expand Up @@ -318,15 +322,15 @@ pub extern "C" fn processing_image_resize(image_id: u64, new_width: u32, new_hei
/// - buffer_len must equal width * height of the image.
/// - This is called from the same thread as init.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn processing_image_load_pixels(
pub unsafe extern "C" fn processing_image_readback(
image_id: u64,
buffer: *mut Color,
buffer_len: usize,
) {
error::clear_error();
let image_entity = Entity::from_bits(image_id);
error::check(|| {
let colors = image_load_pixels(image_entity)?;
let colors = image_readback(image_entity)?;

// Validate buffer size
if colors.len() != buffer_len {
Expand Down
5 changes: 2 additions & 3 deletions crates/processing_pyo3/src/glfw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ impl GlfwContext {
self.glfw.poll_events();

for (_, event) in glfw::flush_messages(&self.events) {
match event {
WindowEvent::Close => return false,
_ => {}
if event == WindowEvent::Close {
return false;
}
}

Expand Down
57 changes: 38 additions & 19 deletions crates/processing_pyo3/src/graphics.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use bevy::prelude::Entity;
use processing::prelude::*;
use pyo3::exceptions::PyRuntimeError;
use pyo3::prelude::*;
use pyo3::types::PyAny;
use pyo3::{exceptions::PyRuntimeError, prelude::*, types::PyAny};

use crate::glfw::GlfwContext;

Expand All @@ -16,8 +14,8 @@ pub struct Graphics {
impl Graphics {
#[new]
pub fn new(width: u32, height: u32) -> PyResult<Self> {
let glfw_ctx = GlfwContext::new(width, height)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))?;
let glfw_ctx =
GlfwContext::new(width, height).map_err(|e| PyRuntimeError::new_err(format!("{e}")))?;

init().map_err(|e| PyRuntimeError::new_err(format!("{e}")))?;

Expand All @@ -32,43 +30,59 @@ impl Graphics {
pub fn background(&self, args: Vec<f32>) -> PyResult<()> {
let (r, g, b, a) = parse_color(&args)?;
let color = bevy::color::Color::srgba(r, g, b, a);
record_command(self.surface, DrawCommand::BackgroundColor(color))
graphics_record_command(self.surface, DrawCommand::BackgroundColor(color))
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

pub fn fill(&self, args: Vec<f32>) -> PyResult<()> {
let (r, g, b, a) = parse_color(&args)?;
let color = bevy::color::Color::srgba(r, g, b, a);
record_command(self.surface, DrawCommand::Fill(color))
graphics_record_command(self.surface, DrawCommand::Fill(color))
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

pub fn no_fill(&self) -> PyResult<()> {
record_command(self.surface, DrawCommand::NoFill)
graphics_record_command(self.surface, DrawCommand::NoFill)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

pub fn stroke(&self, args: Vec<f32>) -> PyResult<()> {
let (r, g, b, a) = parse_color(&args)?;
let color = bevy::color::Color::srgba(r, g, b, a);
record_command(self.surface, DrawCommand::StrokeColor(color))
graphics_record_command(self.surface, DrawCommand::StrokeColor(color))
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

pub fn no_stroke(&self) -> PyResult<()> {
record_command(self.surface, DrawCommand::NoStroke)
graphics_record_command(self.surface, DrawCommand::NoStroke)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

pub fn stroke_weight(&self, weight: f32) -> PyResult<()> {
record_command(self.surface, DrawCommand::StrokeWeight(weight))
graphics_record_command(self.surface, DrawCommand::StrokeWeight(weight))
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

pub fn rect(&self, x: f32, y: f32, w: f32, h: f32, tl: f32, tr: f32, br: f32, bl: f32) -> PyResult<()> {
record_command(
pub fn rect(
&self,
x: f32,
y: f32,
w: f32,
h: f32,
tl: f32,
tr: f32,
br: f32,
bl: f32,
) -> PyResult<()> {
graphics_record_command(
self.surface,
DrawCommand::Rect { x, y, w, h, radii: [tl, tr, br, bl] },
DrawCommand::Rect {
x,
y,
w,
h,
radii: [tl, tr, br, bl],
},
)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}
Expand All @@ -79,17 +93,17 @@ impl Graphics {
break;
}

begin_draw(self.surface)
graphics_begin_draw(self.surface)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))?;

if let Some(ref draw) = draw_fn {
Python::attach(|py| {
draw.call0(py).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
draw.call0(py)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
})?;
}

end_draw(self.surface)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))?;
graphics_end_draw(self.surface).map_err(|e| PyRuntimeError::new_err(format!("{e}")))?;
}
Ok(())
}
Expand All @@ -108,7 +122,12 @@ fn parse_color(args: &[f32]) -> PyResult<(f32, f32, f32, f32)> {
Ok((v, v, v, args[1] / 255.0))
}
3 => Ok((args[0] / 255.0, args[1] / 255.0, args[2] / 255.0, 1.0)),
4 => Ok((args[0] / 255.0, args[1] / 255.0, args[2] / 255.0, args[3] / 255.0)),
4 => Ok((
args[0] / 255.0,
args[1] / 255.0,
args[2] / 255.0,
args[3] / 255.0,
)),
_ => Err(PyRuntimeError::new_err("color requires 1-4 arguments")),
}
}
Expand Down
17 changes: 13 additions & 4 deletions crates/processing_pyo3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
mod glfw;
mod graphics;

use graphics::{get_graphics, get_graphics_mut, Graphics};
use pyo3::prelude::*;
use pyo3::types::PyAny;
use graphics::{Graphics, get_graphics, get_graphics_mut};
use pyo3::{prelude::*, types::PyAny};

#[pymodule]
fn processing(m: &Bound<'_, PyModule>) -> PyResult<()> {
Expand Down Expand Up @@ -82,6 +81,16 @@ fn stroke_weight(module: &Bound<'_, PyModule>, weight: f32) -> PyResult<()> {

#[pyfunction]
#[pyo3(pass_module, signature = (x, y, w, h, tl=0.0, tr=0.0, br=0.0, bl=0.0))]
fn rect(module: &Bound<'_, PyModule>, x: f32, y: f32, w: f32, h: f32, tl: f32, tr: f32, br: f32, bl: f32) -> PyResult<()> {
fn rect(
module: &Bound<'_, PyModule>,
x: f32,
y: f32,
w: f32,
h: f32,
tl: f32,
tr: f32,
br: f32,
bl: f32,
) -> PyResult<()> {
get_graphics(module)?.rect(x, y, w, h, tl, tr, br, bl)
}
8 changes: 6 additions & 2 deletions crates/processing_render/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ pub enum ProcessingError {
AppAccess,
#[error("Error initializing tracing: {0}")]
Tracing(#[from] tracing::subscriber::SetGlobalDefaultError),
#[error("Window not found")]
WindowNotFound,
#[error("Surface not found")]
SurfaceNotFound,
#[error("Handle error: {0}")]
HandleError(#[from] raw_window_handle::HandleError),
#[error("Invalid window handle provided")]
Expand All @@ -20,4 +20,8 @@ pub enum ProcessingError {
UnsupportedTextureFormat,
#[error("Invalid argument: {0}")]
InvalidArgument(String),
#[error("Graphics not found")]
GraphicsNotFound,
#[error("Invalid entity")]
InvalidEntity,
}
Loading