Skip to content

Commit 370124f

Browse files
committed
Loop / no_loop.
1 parent 58809b8 commit 370124f

1 file changed

Lines changed: 63 additions & 6 deletions

File tree

  • crates/processing_pyo3/src

crates/processing_pyo3/src/lib.rs

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,36 @@ use std::ffi::{CStr, CString};
4141

4242
use bevy::log::warn;
4343
use gltf::Gltf;
44-
use std::cell::RefCell;
44+
use std::cell::{Cell, RefCell};
4545
use std::collections::HashMap;
4646
use std::env;
4747

48+
#[derive(Clone, Copy)]
49+
struct LoopState {
50+
looping: bool,
51+
redraw_requested: bool,
52+
}
53+
54+
impl Default for LoopState {
55+
fn default() -> Self {
56+
Self {
57+
looping: true,
58+
redraw_requested: true,
59+
}
60+
}
61+
}
62+
4863
thread_local! {
4964
static LAST_GLOBALS: RefCell<HashMap<&'static str, Py<PyAny>>> = RefCell::new(HashMap::new());
65+
static LOOP_STATE: Cell<LoopState> = Cell::new(LoopState::default());
66+
}
67+
68+
fn update_loop_state(f: impl FnOnce(&mut LoopState)) {
69+
LOOP_STATE.with(|s| {
70+
let mut state = s.get();
71+
f(&mut state);
72+
s.set(state);
73+
});
5074
}
5175

5276
/// Writes a new value to globals, iff the new value does not match a previous tracked value.
@@ -710,9 +734,26 @@ mod mewnala {
710734
}
711735

712736
#[pyfunction]
713-
#[pyo3(pass_module)]
714-
fn redraw(module: &Bound<'_, PyModule>) -> PyResult<()> {
715-
graphics!(module).present()
737+
fn redraw() -> PyResult<()> {
738+
update_loop_state(|s| {
739+
if !s.looping {
740+
s.redraw_requested = true;
741+
}
742+
});
743+
Ok(())
744+
}
745+
746+
#[pyfunction]
747+
#[pyo3(name = "loop")]
748+
fn loop_() -> PyResult<()> {
749+
update_loop_state(|s| s.looping = true);
750+
Ok(())
751+
}
752+
753+
#[pyfunction]
754+
fn no_loop() -> PyResult<()> {
755+
update_loop_state(|s| s.looping = false);
756+
Ok(())
716757
}
717758

718759
#[pyfunction]
@@ -856,14 +897,28 @@ mod mewnala {
856897
if !graphics.surface.poll_events() {
857898
break;
858899
}
859-
graphics.begin_draw()?;
860900
}
861901

902+
dispatch_event_callbacks(&locals)?;
903+
904+
let should_draw = LOOP_STATE.with(|s| {
905+
let state = s.get();
906+
state.looping || state.redraw_requested
907+
});
908+
909+
if !should_draw {
910+
std::thread::sleep(std::time::Duration::from_millis(16));
911+
continue;
912+
}
913+
914+
get_graphics_mut(module)?
915+
.ok_or_else(|| PyRuntimeError::new_err("call size() first"))?
916+
.begin_draw()?;
917+
862918
processing::prelude::advance_frame_count()
863919
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))?;
864920

865921
sync_globals(module, &globals)?;
866-
dispatch_event_callbacks(&locals)?;
867922

868923
draw_fn
869924
.call0()
@@ -872,6 +927,8 @@ mod mewnala {
872927
get_graphics(module)?
873928
.ok_or_else(|| PyRuntimeError::new_err("call size() first"))?
874929
.end_draw()?;
930+
931+
update_loop_state(|s| s.redraw_requested = false);
875932
}
876933

877934
Ok(())

0 commit comments

Comments
 (0)