Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graph: Add EdgeWeight to Input #144

Open
Hendrik410 opened this issue Dec 27, 2020 · 1 comment
Open

Graph: Add EdgeWeight to Input #144

Hendrik410 opened this issue Dec 27, 2020 · 1 comment

Comments

@Hendrik410
Copy link

I'm currently trying to get some simple modular synth running using dasp_graph.
For that it would be required, to be able to distinguish the inputs of a node in the method, computing the node.

Seeing, that the definition of input currently looks like this:

/// A reference to another node that is an input to the current node.

////// *TODO: It may be useful to provide some information that can uniquely identify the input node./// This could be useful to allow to distinguish between side-chained and regular inputs for

/// example.*pub struct Input {buffers_ptr: *const Buffer,buffers_len: usize,}

was a bit unfortunate.

I dug around a little and pentagraph supports EdgeWeights, wich are generics, that can hold information on the edge.
It would be nice to be able to define EdgeWeights when creating the graph and have them put into the input.

I tried around, but the process method does not directly use the graph, so I'm a bit stuck.
The edge_weight() function is available, so if one could get the edge_id, the data can be read.
However, I don't see a possibility to get the edge_id as the find_edge() function is not available.

pub fn process<G, T>(processor: &mut Processor<G>, graph: &mut G, node: G::NodeId)
where
    G: Data<NodeWeight = NodeData<T>> + DataMapMut + Visitable,
    for<'a> &'a G: GraphBase<NodeId = G::NodeId> + IntoNeighborsDirected,
    T: Node,
{
    const NO_NODE: &str = "no node exists for the given index";
    processor.dfs_post_order.reset(Reversed(&*graph));
    processor.dfs_post_order.move_to(node);
    while let Some(n) = processor.dfs_post_order.next(Reversed(&*graph)) {
        let data: *mut NodeData<T> = graph.node_weight_mut(n).expect(NO_NODE) as *mut _;
        processor.inputs.clear();
        for in_n in (&*graph).neighbors_directed(n, Incoming) {
            // Skip edges that connect the node to itself to avoid aliasing `node`.
            if n == in_n {
                continue;
            }
            
            // ADDED Get Edge Information
            let edgeId = graph.find_edge(in_n, n).unwrap(); // this is not available
            let edge_weight = graph.edge_weight(edgeId);
            
            let input_container = graph.node_weight(in_n).expect(NO_NODE);
            let input = node::Input::new(&input_container.buffers); // The EdgeWeight would be added to this constructor
            processor.inputs.push(input);
        }
        // Here we deference our raw pointer to the `NodeData`. The only references to the graph at
        // this point in time are the input references and the node itself. We know that the input
        // references do not alias our node's mutable reference as we explicitly check for it while
        // looping through the inputs above.
        unsafe {
            (*data)
                .node
                .process(&processor.inputs, &mut (*data).buffers);
        }
    }
}

If somebody can point me in the right direction, I would gladly finish this up and prepare a pull request.
Or if somebody has already solved this in a different way, that would also be great to hear.

@chaosprint
Copy link

chaosprint commented Jan 26, 2021

Hi,
You may find this project of mine helpful as an example of using dasp graph.
https://github.com/chaosprint/glicol

If I remember correctly, the order of the Input is the reverse of the connecting order.
So, inputs[0] would be the latest connected one.
Of course, you also need to experiment on the direction of add_edge() to make it right.
I agree that the docs should cover that part and an optional unique ID would be great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants