Skip to content

Commit a6a4dc5

Browse files
authored
Switch-up strategy for ensuring dynamic vars end up in LSP (#151)
1 parent 7b3b497 commit a6a4dc5

3 files changed

Lines changed: 90 additions & 59 deletions

File tree

crates/processing_pyo3/mewnala/__init__.py

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,54 @@
1717
"width",
1818
"height",
1919
"focused",
20+
"pixel_density",
2021
"pixel_width",
2122
"pixel_height",
22-
)
23-
_DYNAMIC_FUNCTIONS = (
2423
"mouse_x",
2524
"mouse_y",
2625
"pmouse_x",
2726
"pmouse_y",
27+
"mouse_is_pressed",
28+
"mouse_button",
29+
"mouse_wheel",
30+
"moved_x",
31+
"moved_y",
32+
"key",
33+
"key_code",
34+
"key_is_pressed",
35+
)
36+
37+
_DYNAMIC_TIME_ATTRS = (
2838
"frame_count",
2939
"delta_time",
3040
"elapsed_time",
3141
)
42+
43+
_DEFAULT_GRAPHICS_VALUES = {
44+
"width": 100,
45+
"height": 100,
46+
"focused": False,
47+
"pixel_density": 1.0,
48+
"pixel_width": 100,
49+
"pixel_height": 100,
50+
"mouse_x": 0.0,
51+
"mouse_y": 0.0,
52+
"pmouse_x": 0.0,
53+
"pmouse_y": 0.0,
54+
"mouse_is_pressed": False,
55+
"mouse_button": None,
56+
"mouse_wheel": 0.0,
57+
"moved_x": 0.0,
58+
"moved_y": 0.0,
59+
"key": None,
60+
"key_code": None,
61+
"key_is_pressed": False,
62+
}
63+
3264
_DYNAMIC = (
33-
_DYNAMIC_GRAPHICS_ATTRS + _DYNAMIC_FUNCTIONS + (
34-
"mouse_is_pressed",
35-
"mouse_button",
36-
"moved_x",
37-
"moved_y",
38-
"mouse_wheel",
39-
"key",
40-
"key_code",
41-
"key_is_pressed",
42-
"display_width",
43-
"display_height",
44-
"window_x",
45-
"window_y",
46-
)
65+
_DYNAMIC_GRAPHICS_ATTRS
66+
+ _DYNAMIC_TIME_ATTRS
67+
+ ("display_width", "display_height", "window_x", "window_y")
4768
)
4869

4970

@@ -56,20 +77,38 @@ def __getattr__(name):
5677
g = _get_graphics()
5778
if g is not None:
5879
return getattr(g, name)
59-
if name in _DYNAMIC_FUNCTIONS:
60-
fn = getattr(_native, name, None)
61-
if callable(fn):
80+
return _DEFAULT_GRAPHICS_VALUES[name]
81+
if name in _DYNAMIC_TIME_ATTRS:
82+
fn = getattr(_native, f"_dyn_{name}", None)
83+
if not callable(fn):
84+
return 0
85+
try:
6286
return fn()
87+
except RuntimeError:
88+
return 0 if name == "frame_count" else 0.0
6389
if name in ("display_width", "display_height"):
64-
mon = getattr(_native, "primary_monitor", lambda: None)()
90+
try:
91+
mon = getattr(_native, "primary_monitor", lambda: None)()
92+
except RuntimeError:
93+
return 0
6594
if mon is None:
6695
return 0
6796
return mon.width if name == "display_width" else mon.height
97+
if name in ("window_x", "window_y"):
98+
g = _get_graphics()
99+
if g is None:
100+
return 0
101+
x, y = g.surface.position
102+
return x if name == "window_x" else y
68103
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
69104

70105

71106
def __dir__():
72107
return sorted(set(list(globals().keys()) + list(_DYNAMIC)))
73108

74109

110+
__all__ = sorted(
111+
{n for n in dir(_native) if not n.startswith("_")} | set(_DYNAMIC)
112+
)
113+
75114
del _sys, _name, _sub

crates/processing_pyo3/src/lib.rs

Lines changed: 5 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -603,9 +603,6 @@ mod mewnala {
603603
fn init(module: &Bound<'_, PyModule>) -> PyResult<()> {
604604
use processing::prelude::BlendMode;
605605

606-
module.add("width", super::DEFAULT_WIDTH)?;
607-
module.add("height", super::DEFAULT_HEIGHT)?;
608-
609606
module.add("BLEND", PyBlendMode::from_preset(BlendMode::Blend))?;
610607
module.add("ADD", PyBlendMode::from_preset(BlendMode::Add))?;
611608
module.add("SUBTRACT", PyBlendMode::from_preset(BlendMode::Subtract))?;
@@ -1762,38 +1759,6 @@ mod mewnala {
17621759
midi::play_notes(note, duration)
17631760
}
17641761

1765-
#[pyfunction]
1766-
#[pyo3(pass_module)]
1767-
fn mouse_x(module: &Bound<'_, PyModule>) -> PyResult<f32> {
1768-
let graphics =
1769-
get_graphics(module)?.ok_or_else(|| PyRuntimeError::new_err("call size() first"))?;
1770-
input::mouse_x(graphics.surface.entity, graphics.width)
1771-
}
1772-
1773-
#[pyfunction]
1774-
#[pyo3(pass_module)]
1775-
fn mouse_y(module: &Bound<'_, PyModule>) -> PyResult<f32> {
1776-
let graphics =
1777-
get_graphics(module)?.ok_or_else(|| PyRuntimeError::new_err("call size() first"))?;
1778-
input::mouse_y(graphics.surface.entity, graphics.height)
1779-
}
1780-
1781-
#[pyfunction]
1782-
#[pyo3(pass_module)]
1783-
fn pmouse_x(module: &Bound<'_, PyModule>) -> PyResult<f32> {
1784-
let graphics =
1785-
get_graphics(module)?.ok_or_else(|| PyRuntimeError::new_err("call size() first"))?;
1786-
input::pmouse_x(graphics.surface.entity, graphics.width)
1787-
}
1788-
1789-
#[pyfunction]
1790-
#[pyo3(pass_module)]
1791-
fn pmouse_y(module: &Bound<'_, PyModule>) -> PyResult<f32> {
1792-
let graphics =
1793-
get_graphics(module)?.ok_or_else(|| PyRuntimeError::new_err("call size() first"))?;
1794-
input::pmouse_y(graphics.surface.entity, graphics.height)
1795-
}
1796-
17971762
#[pyfunction]
17981763
fn key_is_down(key_code: u32) -> PyResult<bool> {
17991764
input::key_is_down(key_code)
@@ -1833,18 +1798,20 @@ mod mewnala {
18331798
graphics.surface.display_density()
18341799
}
18351800

1801+
// private stuff
1802+
18361803
#[pyfunction]
1837-
fn frame_count() -> PyResult<u32> {
1804+
fn _dyn_frame_count() -> PyResult<u32> {
18381805
time::frame_count()
18391806
}
18401807

18411808
#[pyfunction]
1842-
fn delta_time() -> PyResult<f32> {
1809+
fn _dyn_delta_time() -> PyResult<f32> {
18431810
time::delta_time()
18441811
}
18451812

18461813
#[pyfunction]
1847-
fn elapsed_time() -> PyResult<f32> {
1814+
fn _dyn_elapsed_time() -> PyResult<f32> {
18481815
time::elapsed_time()
18491816
}
18501817

tools/generate_stubs/src/main.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,32 @@ fn main() {
4646

4747
module.incomplete = false;
4848

49-
let stubs = module_stub_files(&module);
49+
let mut stubs = module_stub_files(&module);
50+
51+
// join in extras
52+
53+
let extras_dir = workspace_root()
54+
.join("crates")
55+
.join("processing_pyo3")
56+
.join("stubs");
57+
if extras_dir.is_dir() {
58+
for entry in fs::read_dir(&extras_dir).unwrap() {
59+
let entry = entry.unwrap();
60+
let path = entry.path();
61+
if path.extension().and_then(|s| s.to_str()) != Some("pyi") {
62+
continue;
63+
}
64+
let filename = path.file_name().unwrap().to_owned();
65+
let extra = fs::read_to_string(&path).unwrap();
66+
let target = stubs.entry(PathBuf::from(&filename)).or_default();
67+
if !target.is_empty() && !target.ends_with('\n') {
68+
target.push('\n');
69+
}
70+
target.push('\n');
71+
target.push_str(&extra);
72+
eprintln!("Appended extras: {}", path.display());
73+
}
74+
}
5075

5176
let output_dir = workspace_root()
5277
.join("crates")

0 commit comments

Comments
 (0)