Skip to content

Commit

Permalink
Add dynamic menu support.
Browse files Browse the repository at this point in the history
  • Loading branch information
tychedelia committed Jan 18, 2025
1 parent 22fb42c commit 7e6a3d4
Show file tree
Hide file tree
Showing 27 changed files with 315 additions and 21 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ members = [
"plugins/chop/python",
"plugins/chop/wasm",
"plugins/dat/filter",
"plugins/dat/dynamic_menu",
"plugins/sop/generator-sop",
"plugins/top/cpu-memory-top",
"plugins/top/stable-diffusion",
Expand Down
Empty file added CrashAutoSave.NewProject.1.toe
Empty file.
3 changes: 2 additions & 1 deletion plugins/chop/monome-grid/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use monome::{KeyDirection, Monome, MonomeDevice, MonomeEvent};
use td_rs_chop::cxx::OP_Inputs;
use td_rs_chop::*;
use td_rs_derive::{Param, Params};

Expand Down Expand Up @@ -70,7 +71,7 @@ impl Chop for MonomeGrid {
if let Some(ref mut device) = &mut self.device {
while let Some(event) = device.poll() {
match event {
MonomeEvent::GridKey { x, y, direction, } => {
MonomeEvent::GridKey { x, y, direction } => {
let index = (y * 16 + x) as usize;
if self.params.hold {
if matches!(direction, KeyDirection::Down) {
Expand Down
15 changes: 15 additions & 0 deletions plugins/dat/dynamic_menu/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "dynamic-menu"
version = "0.1.0"
edition = "2021"

[package.metadata.td-rs]
type = "dat"

[lib]
name = "dynamic_menu"
crate-type = ["staticlib"]

[dependencies]
td-rs-dat = { path = "../../../td-rs-dat" }
td-rs-derive = { path = "../../../td-rs-derive" }
91 changes: 91 additions & 0 deletions plugins/dat/dynamic_menu/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use td_rs_dat::chop::ChopInput;
use td_rs_dat::*;
use td_rs_derive::{Param, Params};

#[derive(Params, Default, Clone, Debug)]
struct DynamicMenuDatParams {
#[param(label = "Menu")]
menu: DynamicMenuParam,
}

/// Struct representing our DAT's state
pub struct DynamicMenuDat {
params: DynamicMenuDatParams,
}

impl OpNew for DynamicMenuDat {
fn new(_info: NodeInfo) -> Self {
Self {
params: Default::default(),
}
}
}

impl OpInfo for DynamicMenuDat {
const OPERATOR_TYPE: &'static str = "Dynamicmenu";
const OPERATOR_LABEL: &'static str = "Dynamic Menu";
const MIN_INPUTS: usize = 1;
// This Dat takes no input
const MAX_INPUTS: usize = 1;
}

impl Op for DynamicMenuDat {
fn params_mut(&mut self) -> Option<Box<&mut dyn OperatorParams>> {
Some(Box::new(&mut self.params))
}
}

impl Dat for DynamicMenuDat {
fn general_info(&self, _inputs: &OperatorInputs<DatInput>) -> DatGeneralInfo {
DatGeneralInfo {
cook_every_frame: false,
cook_every_frame_if_asked: false,
}
}

fn execute(&mut self, output: DatOutput, inputs: &OperatorInputs<DatInput>) {
if let Some(input) = inputs.input(0) {
match input.dat_type() {
DatType::Text => {
if let Some(output_text) = &self.params.menu.0 {
output
.text()
.set_text(&format!("Selected: {}", output_text));
} else {
output.text().set_text("");
}
}
_ => self.set_warning("Input must be a text DAT"),
}
}
}

fn build_dynamic_menu(
&mut self,
inputs: &OperatorInputs<DatInput>,
menu_info: &mut DynamicMenuInfo,
) {
if menu_info.param_name() == "Menu" {
if let Some(input) = inputs.input(0) {
match input.dat_type() {
DatType::Text => {
let text = input.text();
let labels = text
.split('\n')
.map(|s| s.to_string())
.collect::<Vec<String>>();
for label in labels {
let name = label.replace(" ", "");
menu_info.add_menu_entry(&name, &label);
}
}
_ => self.set_warning("Input must be a text DAT"),
}
}
}
}
}

impl DynamicMenuDat {}

dat_plugin!(DynamicMenuDat);
4 changes: 4 additions & 0 deletions td-rs-base/src/RustBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ void releaseDownloadResult(TD::OP_SmartRef<TD::OP_TOPDownloadResult> &result) {
result.release();
}

const char* getBuildDynamicMenuInfoNames(TD::OP_BuildDynamicMenuInfo &info) {
return info.name;
}

#endif // TD_RS_RUSTBASE_H
2 changes: 0 additions & 2 deletions td-rs-base/src/RustPy.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,12 @@ TD::PY_Context* getPyContext(TD::PY_Struct *pyStruct) {

void setPyInfo(TD::OP_CustomOPInfo &opInfo, void *pymethods, size_t size, void *pygetsets, size_t getsetsize) {
if (size == 0) {
std::cout << "No methods" << std::endl;
opInfo.pythonMethods = nullptr;
} else {
opInfo.pythonMethods = static_cast<PyMethodDef*>(pymethods);
}

if (getsetsize == 0) {
std::cout << "No getsets" << std::endl;
opInfo.pythonGetSets = nullptr;
} else {
opInfo.pythonGetSets = static_cast<PyGetSetDef*>(pygetsets);
Expand Down
2 changes: 2 additions & 0 deletions td-rs-base/src/cxx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ include_cpp! {
generate!("TD::OP_SmartRef")
generate_pod!("TD::OP_TextureDesc")
generate_pod!("TD::OP_TexDim")
generate!("TD::OP_BuildDynamicMenuInfo")

// util fns
generate!("setString")
Expand All @@ -44,6 +45,7 @@ include_cpp! {
generate!("getDownloadData")
generate!("getDownloadTextureDesc")
generate!("releaseDownloadResult")
generate!("getBuildDynamicMenuInfoNames")

// Custom ops
generate!("TD::OP_CustomOPInstance")
Expand Down
30 changes: 30 additions & 0 deletions td-rs-base/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![feature(associated_type_defaults)]
#![feature(min_specialization)]

use crate::cxx::OP_Inputs;

Check warning on line 4 in td-rs-base/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build (windows-latest)

unused import: `crate::cxx::OP_Inputs`

Check warning on line 4 in td-rs-base/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build (windows-latest)

unused import: `crate::cxx::OP_Inputs`
pub use param::*;
#[cfg(feature = "python")]
pub use py::*;
Expand Down Expand Up @@ -243,6 +244,30 @@ where
}
}

pub struct DynamicMenuInfo<'cook> {
pub menu_info: Pin<&'cook mut cxx::OP_BuildDynamicMenuInfo>,
}

impl<'cook> DynamicMenuInfo<'cook> {
pub fn new(menu_info: Pin<&'cook mut cxx::OP_BuildDynamicMenuInfo>) -> Self {
Self { menu_info }
}

pub fn param_name(&mut self) -> &str {
let name = cxx::getBuildDynamicMenuInfoNames(self.menu_info.as_mut());
unsafe { ffi::CStr::from_ptr(name).to_str().unwrap() }
}

pub fn add_menu_entry(&mut self, name: &str, label: &str) -> bool {
unsafe {
self.menu_info.as_mut().addMenuEntry(
ffi::CString::new(name).unwrap().into_raw(),
ffi::CString::new(label).unwrap().into_raw(),
)
}
}
}

/// Parameter inputs to an operator.
pub struct ParamInputs<'cook> {
inputs: &'cook crate::cxx::OP_Inputs,
Expand Down Expand Up @@ -276,6 +301,11 @@ impl<'cook> ParamInputs<'cook> {
let res = self
.inputs
.getParString(ffi::CString::new(name).unwrap().into_raw());

if res.is_null() {
return "";
}

ffi::CStr::from_ptr(res).to_str().unwrap()
}
}
Expand Down
27 changes: 26 additions & 1 deletion td-rs-base/src/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ pub struct ParameterManager<'cook> {
impl<'cook> ParameterManager<'cook> {
/// Create a new parameter manager. Should not be called by
/// users.
pub fn new(manager: Pin<&'cook mut crate::cxx::OP_ParameterManager>) -> ParameterManager<'cook> {
pub fn new(
manager: Pin<&'cook mut crate::cxx::OP_ParameterManager>,
) -> ParameterManager<'cook> {
Self { manager }
}

Expand Down Expand Up @@ -301,6 +303,12 @@ impl<'cook> ParameterManager<'cook> {
let param = param.into();
self.manager.as_mut().appendWH(&param);
}

/// Append a dynamic menu parameter.
pub fn append_dynamic_menu(&mut self, param: StringParameter) {
let param = param.into();
self.manager.as_mut().appendDynamicStringMenu(&param);
}
}

/// Options for creating parameters in derive macro.
Expand Down Expand Up @@ -704,3 +712,20 @@ impl Param for Color {
*self = (r, g, b, a).into();
}
}

#[derive(Default, Debug, Clone)]
pub struct DynamicMenuParam(pub Option<String>);

impl Param for DynamicMenuParam {
fn register(&self, options: ParamOptions, parameter_manager: &mut ParameterManager) {
let param = options.into();
parameter_manager.append_dynamic_menu(param);
}

fn update(&mut self, name: &str, inputs: &ParamInputs) {
let name = inputs.get_string(name);
if !name.is_empty() {
self.0 = Some(name.to_string());
}
}
}
7 changes: 2 additions & 5 deletions td-rs-base/src/py.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use pyo3::ffi::PyGetSetDef;
use crate::Op;
use pyo3::ffi::PyGetSetDef;

pub trait PyOp : Op {

}
pub trait PyOp: Op {}

pub trait PyGetSets {
fn get_get_sets() -> &'static [pyo3::ffi::PyGetSetDef];
Expand Down Expand Up @@ -32,7 +30,6 @@ pub(crate) unsafe fn py_op_info<T: PyMethods + PyGetSets>(
let m_len = methods.len();
let m_arr = methods.as_ptr() as *mut autocxx::prelude::c_void;
let get_sets = T::get_get_sets();
println!("get_sets: {:?}", get_sets);
let gs_len = get_sets.len();
let gs_arr = get_sets.as_ptr() as *mut autocxx::prelude::c_void;
crate::cxx::setPyInfo(op_info, m_arr, m_len, gs_arr, gs_len);
Expand Down
8 changes: 6 additions & 2 deletions td-rs-base/src/sop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ impl SopInput {
let custom_attribute = &*custom_attribute;

let name = custom_attribute._base.name;
let name = std::ffi::CStr::from_ptr(name).to_string_lossy().into_owned();
let name = std::ffi::CStr::from_ptr(name)
.to_string_lossy()
.into_owned();
let num_components = custom_attribute._base.numComponents as usize;
let attr_type = &custom_attribute._base.attribType;
let attr_type = attr_type.into();
Expand Down Expand Up @@ -109,7 +111,9 @@ impl SopInput {
}
}

pub fn custom_attributes(&self) -> impl Iterator<Item = (CustomAttributeInfo, CustomAttributeData)> + '_ {
pub fn custom_attributes(
&self,
) -> impl Iterator<Item = (CustomAttributeInfo, CustomAttributeData)> + '_ {
let num_custom_attributes = self.num_custom_attributes();
(0..num_custom_attributes).map(move |i| self.custom_attribute(i))
}
Expand Down
12 changes: 12 additions & 0 deletions td-rs-chop/src/RustChopPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ class ChopPlugin : public CHOP_CPlusPlusBase {
};

virtual void pulsePressed(const char *name) {}

virtual void buildDynamicMenu(const OP_Inputs *inputs,
OP_BuildDynamicMenuInfo *info,
void *reserved1) {
this->buildDynamicMenu(*inputs, *info);
}

virtual void buildDynamicMenu(const OP_Inputs &inputs,
OP_BuildDynamicMenuInfo &info) {}
};

class RustChopPlugin : public ChopPlugin {
Expand Down Expand Up @@ -138,6 +147,9 @@ class RustChopPlugin : public ChopPlugin {
virtual void setupParameters(OP_ParameterManager &manager) = 0;

virtual void pulsePressed(const char *name) = 0;

virtual void buildDynamicMenu(const OP_Inputs &inputs,
OP_BuildDynamicMenuInfo &info) = 0;
};

#endif //TD_RS_RUSTCHOP_H
11 changes: 10 additions & 1 deletion td-rs-chop/src/cxx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use autocxx::subclass::*;
pub use ffi::TD::*;
pub use ffi::*;
pub use td_rs_base::cxx::*;
use td_rs_base::{NodeInfo, OperatorInputs, ParameterManager};
use td_rs_base::{DynamicMenuInfo, NodeInfo, OperatorInputs, ParameterManager};

use crate::{Chop, ChopOutput};

Expand All @@ -25,6 +25,7 @@ include_cpp! {
extern_cpp_type!("TD::OP_InfoCHOPChan", td_rs_base::cxx::OP_InfoCHOPChan)
extern_cpp_type!("TD::OP_Inputs", td_rs_base::cxx::OP_Inputs)
extern_cpp_type!("TD::OP_CustomOPInfo", td_rs_base::cxx::OP_CustomOPInfo)
extern_cpp_type!("TD::OP_BuildDynamicMenuInfo", td_rs_base::cxx::OP_BuildDynamicMenuInfo)
pod!("TD::OP_CustomOPInfo")
generate_pod!("TD::CHOP_PluginInfo")
generate_pod!("TD::CHOP_GeneralInfo")
Expand Down Expand Up @@ -236,4 +237,12 @@ impl RustChopPlugin_methods for RustChopPluginImpl {
self.inner
.pulse_pressed(std::ffi::CStr::from_ptr(name).to_str().unwrap());
}

fn buildDynamicMenu(&mut self, inputs: &OP_Inputs, info: Pin<&mut OP_BuildDynamicMenuInfo>) {
#[cfg(feature = "tracing")]
let _span = { tracing_base::trace_span!("buildDynamicMenu").entered() };
let input = OperatorInputs::new(inputs);
let mut info = DynamicMenuInfo::new(info);
self.inner.build_dynamic_menu(&input, &mut info);
}
}
7 changes: 7 additions & 0 deletions td-rs-chop/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ pub trait Chop: Op {
fn output_info(&self, _input: &OperatorInputs<ChopInput>) -> Option<ChopOutputInfo> {
None
}

fn build_dynamic_menu(
&self,
inputs: &OperatorInputs<ChopInput>,

Check warning on line 126 in td-rs-chop/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build (windows-latest)

unused variable: `inputs`
menu_info: &mut DynamicMenuInfo,

Check warning on line 127 in td-rs-chop/src/lib.rs

View workflow job for this annotation

GitHub Actions / Build (windows-latest)

unused variable: `menu_info`
) {
}
}

#[macro_export]
Expand Down
Loading

0 comments on commit 7e6a3d4

Please sign in to comment.