Skip to content

Commit b107cc7

Browse files
catilactychedelia
andauthored
Pycessing (#31)
Co-authored-by: charlotte 🌸 <[email protected]>
1 parent 9c4caf7 commit b107cc7

File tree

8 files changed

+336
-0
lines changed

8 files changed

+336
-0
lines changed

Cargo.lock

Lines changed: 100 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ bevy = { git = "https://github.com/bevyengine/bevy", branch = "main", no-default
2121
"bevy_color",
2222
] }
2323
processing = { path = "." }
24+
processing_pyo3 = { path = "crates/processing_pyo3" }
2425
processing_render = { path = "crates/processing_render" }
2526

2627
[dependencies]

crates/processing_pyo3/.gitignore

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/target
2+
3+
# Byte-compiled / optimized / DLL files
4+
__pycache__/
5+
.pytest_cache/
6+
*.py[cod]
7+
8+
# C extensions
9+
*.so
10+
11+
# Distribution / packaging
12+
.Python
13+
.venv/
14+
env/
15+
bin/
16+
build/
17+
develop-eggs/
18+
dist/
19+
eggs/
20+
lib/
21+
lib64/
22+
parts/
23+
sdist/
24+
var/
25+
include/
26+
man/
27+
venv/
28+
*.egg-info/
29+
.installed.cfg
30+
*.egg
31+
32+
# Installer logs
33+
pip-log.txt
34+
pip-delete-this-directory.txt
35+
pip-selfcheck.json
36+
37+
# Unit test / coverage reports
38+
htmlcov/
39+
.tox/
40+
.coverage
41+
.cache
42+
nosetests.xml
43+
coverage.xml
44+
45+
# Translations
46+
*.mo
47+
48+
# Mr Developer
49+
.mr.developer.cfg
50+
.project
51+
.pydevproject
52+
53+
# Rope
54+
.ropeproject
55+
56+
# Django stuff:
57+
*.log
58+
*.pot
59+
60+
.DS_Store
61+
62+
# Sphinx documentation
63+
docs/_build/
64+
65+
# PyCharm
66+
.idea/
67+
68+
# VSCode
69+
.vscode/
70+
71+
# Pyenv
72+
.python-version

crates/processing_pyo3/Cargo.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "processing_pyo3"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[lints]
7+
workspace = true
8+
9+
[lib]
10+
name = "pycessing"
11+
crate-type = ["cdylib"]
12+
13+
[dependencies]
14+
pyo3 = "0.27.0"
15+
processing = { workspace = true }
16+
glfw = "0.60.0"
17+
18+
[target.'cfg(target_os = "linux")'.dependencies]
19+
glfw = { version = "0.60.0", features = ["wayland"] }

crates/processing_pyo3/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Pycessing
2+
3+
Prototype for python bindings to libprocessing
4+
5+
## To Get Started
6+
7+
### Install venv and maturin
8+
Follow these [installation instructions](https://pyo3.rs/v0.27.2/getting-started.html)
9+
10+
### Running code
11+
```
12+
$ maturin develop
13+
#
14+
# ...
15+
#
16+
$ python
17+
>>> import pycessing
18+
>>> pycessing.size(500, 500)
19+
```
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[build-system]
2+
requires = ["maturin>=1.10,<2.0"]
3+
build-backend = "maturin"
4+
5+
[project]
6+
name = "pycessing"
7+
requires-python = ">=3.8"
8+
classifiers = [
9+
"Programming Language :: Rust",
10+
"Programming Language :: Python :: Implementation :: CPython",
11+
"Programming Language :: Python :: Implementation :: PyPy",
12+
]
13+
dynamic = ["version"]
14+
15+
[tool.maturin]
16+
manifest-path = "Cargo.toml"

crates/processing_pyo3/src/glfw.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/// Minimal GLFW helper for Processing examples
2+
use glfw::{Glfw, GlfwReceiver, PWindow, WindowEvent, WindowMode};
3+
use processing::prelude::error::Result;
4+
5+
pub struct GlfwContext {
6+
glfw: Glfw,
7+
window: PWindow,
8+
events: GlfwReceiver<(f64, WindowEvent)>,
9+
}
10+
11+
impl GlfwContext {
12+
pub fn new(width: u32, height: u32) -> Result<Self> {
13+
let mut glfw = glfw::init(glfw::fail_on_errors).unwrap();
14+
15+
glfw.window_hint(glfw::WindowHint::ClientApi(glfw::ClientApiHint::NoApi));
16+
glfw.window_hint(glfw::WindowHint::Visible(false));
17+
18+
let (mut window, events) = glfw
19+
.create_window(width, height, "Processing", WindowMode::Windowed)
20+
.unwrap();
21+
22+
window.set_all_polling(true);
23+
window.show();
24+
25+
Ok(Self {
26+
glfw,
27+
window,
28+
events,
29+
})
30+
}
31+
32+
#[cfg(target_os = "macos")]
33+
pub fn get_window(&self) -> u64 {
34+
self.window.get_cocoa_window() as u64
35+
}
36+
37+
#[cfg(target_os = "windows")]
38+
pub fn get_window(&self) -> u64 {
39+
self.window.get_win32_window() as u64
40+
}
41+
42+
#[cfg(target_os = "linux")]
43+
pub fn get_window(&self) -> u64 {
44+
self.window.get_wayland_window() as u64
45+
}
46+
47+
#[cfg(not(target_os = "linux"))]
48+
pub fn get_display(&self) -> u64 {
49+
0
50+
}
51+
52+
#[cfg(target_os = "linux")]
53+
pub fn get_display(&self) -> u64 {
54+
self.glfw.get_wayland_display() as u64
55+
}
56+
57+
pub fn poll_events(&mut self) -> bool {
58+
self.glfw.poll_events();
59+
60+
for (_, event) in glfw::flush_messages(&self.events) {
61+
match event {
62+
WindowEvent::Close => return false,
63+
_ => {}
64+
}
65+
}
66+
67+
!self.window.should_close()
68+
}
69+
}

crates/processing_pyo3/src/lib.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
mod glfw;
2+
use pyo3::prelude::*;
3+
4+
#[pymodule]
5+
mod pycessing {
6+
use crate::glfw::GlfwContext;
7+
use processing::prelude::*;
8+
use pyo3::prelude::*;
9+
10+
/// create surface
11+
#[pyfunction]
12+
fn size(width: u32, height: u32) -> PyResult<String> {
13+
let mut glfw_ctx = GlfwContext::new(400, 400).unwrap();
14+
init().unwrap();
15+
16+
let window_handle = glfw_ctx.get_window();
17+
let display_handle = glfw_ctx.get_display();
18+
let surface = surface_create(window_handle, display_handle, width, height, 1.0).unwrap();
19+
20+
while glfw_ctx.poll_events() {
21+
begin_draw(surface).unwrap();
22+
23+
record_command(
24+
surface,
25+
DrawCommand::Rect {
26+
x: 10.0,
27+
y: 10.0,
28+
w: 100.0,
29+
h: 100.0,
30+
radii: [0.0, 0.0, 0.0, 0.0],
31+
},
32+
)
33+
.unwrap();
34+
35+
end_draw(surface).unwrap();
36+
}
37+
38+
Ok("OK".to_string())
39+
}
40+
}

0 commit comments

Comments
 (0)