Skip to content

Commit

Permalink
Finish pyo3.
Browse files Browse the repository at this point in the history
  • Loading branch information
tychedelia committed Nov 17, 2024
1 parent db0006e commit fcf7cb3
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 367 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 17 additions & 27 deletions plugins/chop/python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

use pyo3::impl_::pyclass::{PyClassImpl, PyMethods};
use pyo3::prelude::PyAnyMethods;
use pyo3::{pyclass, pymethods, Bound, PyAny, PyResult};
use pyo3::{pyclass, pymethods, Bound, PyAny, PyResult, Python};
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use td_rs_chop::cxx::AsPlugin;
use td_rs_chop::*;
use td_rs_derive::*;
Expand All @@ -31,9 +30,9 @@ struct PythonChopParams {
}

#[derive(PyOp)]
#[pyclass]
#[pyclass(unsendable)]
pub struct PythonChop {
info: Arc<Mutex<NodeInfo>>,
info: NodeInfo,
#[pyo3(get, set)]
speed: f32,
#[pyo3(get)]
Expand All @@ -60,7 +59,7 @@ impl PythonChop {
impl OpNew for PythonChop {
fn new(info: NodeInfo) -> Self {
Self {
info: Arc::new(Mutex::new(info)),
info,
speed: 1.0,
execute_count: 0,
offset: 0.0,
Expand Down Expand Up @@ -133,29 +132,20 @@ impl Chop for PythonChop {
// Apply Python class modifications
self.params.speed *= self.speed;

let info = self.info.lock().unwrap();
let arg_tuple = info
.context()
.create_arguments_tuple(1);

unsafe {
pyo3_ffi::PyTuple_SET_ITEM(
arg_tuple,
1,
pyo3_ffi::PyFloat_FromDouble(self.params.speed as std::ffi::c_double),
);
let res = info.context().call_python_callback(
Python::with_gil(|py| {
self.info.context().call_python_callback(
py,
"getSpeedAdjust",
arg_tuple,
std::ptr::null_mut(),
);
if !res.is_null() {
if pyo3_ffi::PyFloat_Check(res) != 0 {
self.params.speed = pyo3_ffi::PyFloat_AsDouble(res) as f32;
}
pyo3_ffi::Py_DECREF(res);
}
}
(self.speed,),
None,
|py, res| {
if let Ok(speed) = res.extract::<f32>(py) {
self.params.speed *= speed;
}
},
)
})
.unwrap();

let phase = 2.0 * std::f32::consts::PI / output.num_channels() as f32;
let num_samples = output.num_samples();
Expand Down
3 changes: 1 addition & 2 deletions td-rs-base/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ ref-cast = "1.0"
auto_ops = "0.3.0"
derive_more = { version = "1", features = ["full"] }
pyo3 = { git = "https://github.com/tychedelia/pyo3", branch = "td-rs", features = ["abi3-py311"], optional = true }
pyo3-ffi = { git = "https://github.com/tychedelia/pyo3", branch = "td-rs", features = ["abi3-py311"], optional = true }
tracing-base = { package = "tracing", version = "0.1", optional = true}
tracing-subscriber = { version = "0.3", optional = true }
tokio-core = { package = "tokio", version = "1", optional = true }
Expand All @@ -27,6 +26,6 @@ miette = { version = "5", features = [ "fancy" ] }

[features]
default = []
python = ["pyo3-ffi"]
python = ["pyo3"]
tracing = ["tracing-base", "tracing-subscriber", "tracing-subscriber/env-filter"]
tokio = ["tokio-core", "tokio-core/rt-multi-thread"]
97 changes: 56 additions & 41 deletions td-rs-base/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
#![feature(associated_type_defaults)]
#![feature(min_specialization)]

pub use param::*;
#[cfg(feature = "python")]
pub use py::*;
#[cfg(feature = "python")]
use pyo3::prelude::*;
use pyo3::types::{IntoPyDict, PyTuple};

Check failure on line 9 in td-rs-base/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build (macos-latest)

failed to resolve: use of undeclared crate or module `pyo3`
use pyo3::BoundObject;

Check failure on line 10 in td-rs-base/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build (macos-latest)

unresolved import `pyo3`
use std::ffi;
use std::ffi::c_int;
use std::fmt::Formatter;
use std::ops::Index;
use std::pin::Pin;
use std::sync::Mutex;

pub use param::*;
#[cfg(feature = "python")]
pub use py::*;

#[cfg(feature = "tokio")]
pub static RUNTIME: std::sync::LazyLock<tokio_core::runtime::Runtime> = std::sync::LazyLock::new(|| {
tokio_core::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("Failed to create tokio runtime")
});
pub static RUNTIME: std::sync::LazyLock<tokio_core::runtime::Runtime> =
std::sync::LazyLock::new(|| {
tokio_core::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("Failed to create tokio runtime")
});

pub mod chop;
pub mod cxx;
Expand Down Expand Up @@ -139,35 +144,47 @@ pub struct Context {

impl Context {
#[cfg(feature = "python")]
pub fn create_arguments_tuple(&self, nargs: usize) -> *mut pyo3_ffi::PyObject {
let obj = unsafe {
let mut ctx = Pin::new_unchecked(&mut *self.context);
let tuple = ctx
.createArgumentsTuple(autocxx::c_int(nargs as i32), std::ptr::null_mut());
tuple
};
obj as *mut pyo3_ffi::PyObject
}

#[cfg(feature = "python")]
pub fn call_python_callback(
pub fn call_python_callback<'py, F>(
&self,
py: Python<'py>,
callback: &str,
args: *mut pyo3_ffi::PyObject,
kw: *mut pyo3_ffi::PyObject,
) -> *mut pyo3_ffi::PyObject {
let callback = ffi::CString::new(callback).unwrap();
let obj = unsafe {
args: impl IntoPyObject<'py, Target = PyTuple>,
kwargs: Option<&Bound<'py, pyo3::types::PyDict>>,
f: F,
) -> PyResult<()>
where
F: FnOnce(Python, &PyObject),
{
unsafe {
let callback = ffi::CString::new(callback)?;
let args = args.into_pyobject(py).map_err(Into::into)?.into_bound();
let mut ctx = Pin::new_unchecked(&mut *self.context);
let op_tuple = ctx.createArgumentsTuple(autocxx::c_int(1), std::ptr::null_mut());
let op_tuple = op_tuple as *mut pyo3::ffi::PyObject;
let op_tuple = PyObject::from_owned_ptr(py, op_tuple);
let op_tuple = op_tuple.downcast_bound::<PyTuple>(py)?;
let op = op_tuple.get_item(0)?;
let mut args_elements = vec![op];

for args in args.iter() {
args_elements.push(args);
}
let args = PyTuple::new(py, &args_elements)?;

let mut ctx = Pin::new_unchecked(&mut *self.context);
let args = args.as_ptr();
let kwargs = kwargs.map(|kw| kw.as_ptr()).unwrap_or(std::ptr::null_mut());
let res = ctx.callPythonCallback(
callback.as_ptr(),
args as *mut cxx::_object,
kw as *mut cxx::_object,
kwargs as *mut cxx::_object,
std::ptr::null_mut(),
);
res
};
obj as *mut pyo3_ffi::PyObject
let res = res as *mut pyo3::ffi::PyObject;
let res = PyObject::from_owned_ptr(py, res);
f(py, &res);
Ok(())
}
}
}

Expand Down Expand Up @@ -332,15 +349,15 @@ impl<'cook> ParamInputs<'cook> {
}

#[cfg(feature = "python")]
fn get_python(&self, name: &str) -> *mut pyo3_ffi::PyObject {
fn get_python(&self, name: &str) -> *mut pyo3::ffi::PyObject {
unsafe {
let python = self
.inputs
.getParPython(ffi::CString::new(name).unwrap().into_raw());
if python.is_null() {
std::ptr::null_mut()
} else {
python as *mut pyo3_ffi::PyObject
python as *mut pyo3::ffi::PyObject
}
}
}
Expand Down Expand Up @@ -533,8 +550,8 @@ pub fn op_init() {
{
use tracing_subscriber::fmt;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::util::{SubscriberInitExt, TryInitError};
use tracing_subscriber::EnvFilter;

let fmt_layer = if cfg!(target_os = "windows") {
let mut f = fmt::layer();
Expand All @@ -549,14 +566,12 @@ pub fn op_init() {
.try_init();
match init {
Ok(_) => {}
Err(err) => {
match err {
TryInitError { .. } => {}
_ => {
eprintln!("Failed to initialize tracing: {}", err);
}
Err(err) => match err {
TryInitError { .. } => {}
_ => {
eprintln!("Failed to initialize tracing: {}", err);
}
}
},
}
}
}
4 changes: 2 additions & 2 deletions td-rs-base/src/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ impl DatParam {
}

#[cfg(feature = "python")]
impl Param for *mut pyo3_ffi::PyObject {
impl Param for *mut pyo3::ffi::PyObject {
fn register(&self, options: ParamOptions, parameter_manager: &mut ParameterManager) {
let param = options.into();
parameter_manager.append_python(param);
Expand All @@ -682,7 +682,7 @@ impl Param for *mut pyo3_ffi::PyObject {
fn update(&mut self, name: &str, inputs: &ParamInputs) {
// Ensure that the old object is decref'd
unsafe {
pyo3_ffi::Py_XDECREF(*self);
pyo3::ffi::Py_XDECREF(*self);
}
*self = inputs.get_python(name);
}
Expand Down
Loading

0 comments on commit fcf7cb3

Please sign in to comment.