/*
* Node.java
* JCollider
*
* Copyright (c) 2004-2010 Hanns Holger Rutz. All rights reserved.
*
* This software is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either
* version 2, june 1991 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License (gpl.txt) along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* For further information, please contact Hanns Holger Rutz at
* contact@sciss.de , or visit http://www.sciss.de/jcollider
*
*
* JCollider is closely modelled after SuperCollider Language,
* often exhibiting a direct translation from Smalltalk to Java.
* SCLang is a software originally developed by James McCartney,
* which has become an Open Source project.
* See http://supercollider.sourceforge.net/ for details.
*
*
* Changelog:
* 04-Aug-05 created
* 03-Oct-05 removed all setGroup statements. to have the group
* set correctly, use a NodeWatcher instead
* ; implements TreeNode ; has predecessor / successor fields
* ; class is abstract now (removed basicNew()
* ; added traceMsg() ; changed printOn() ; nodes can be named
*/
package de.sciss.jcollider;
import java.io.IOException;
import java.io.PrintStream;
import javax.swing.tree.TreeNode;
import de.sciss.net.OSCMessage;
/**
* This is a client side representation of a node in the synthesis graph.
* It is the superclass of <code>Synth</code> and <code>Group</code> and
* as such abstract. The <code>javax.swing.tree.TreeNode</code> interface
* is implemented since it's a natural match and it allows classes such
* as <code>NodeTreeManager</code> to wrap scsynth's node graph on the
* client side into a usefull GUI representation.
* <p>
* Unlike SCLang, the status fields are not updated by the methods in this
* class. SCLang does this partly: It will update the node's parent group,
* while changing the running flag only when the node is freed. We decided to
* not copy this heterogenous behaviour. Parent group, running and playing
* flags as well as the newly introduced predecessor and successor fields
* must be updated by monitoring classes, typically a <code>NodeWatcher</code>.
*
* @warning not all methods are thorougly tested. before all methods have been
* thoroughly verified, excepted some of them to be wrong
* or behave different than expected. what certainly works
* is run-, set-, trace- and free-messages
*
* @author Hanns Holger Rutz
* @version 0.36, 11-Oct-09
*
* @see de.sciss.jcollider.gui.NodeTreeManager
* @see NodeWatcher
*/
public abstract class Node
implements Constants, TreeNode
{
private final Server server;
private final int nodeID;
private String name = null;
private Group group = null;
private Node predNode = null;
private Node succNode = null;
private boolean isPlaying = false;
private boolean isRunning = false;
/**
* Creates a Node representation for a given
* node ID. This method does not send any
* messages to the server.
*
* @param server the <code>Server</code> at which the <code>Node</code> resides
* @param nodeID the identifier of the <code>Node</code>
*/
protected Node( Server server, int nodeID )
{
this.server = server;
this.nodeID = nodeID;
}
/**
* Creates a Node representation. This method does not send any
* messages to the server. The node ID is automatically
* assigned from the server's allocator.
*
* @param server the <code>Server</code> at which the <code>Node</code> resides
*/
protected Node( Server server )
{
this( server, server.nextNodeID() );
}
/**
* Set a custom name for the node.
* This name is used in print out
* or GUI representation
*
* @param name a name for the node, or <code>null</node>
*/
public void setName( String name )
{
this.name = name;
}
/**
* Queries the custom name of the node.
* By default, a node has not an assigned name.
*
* @return the node's name or <code>null</code> if no name has been given
*/
public String getName()
{
return name;
}
/**
* Queries the group in which the node resides.
*
* @return the parent <code>Group</code> of the <code>Node</code> or <code>null</code>
* if no group has been assigned.
*/
public Group getGroup()
{
return group;
}
/**
* Queries the node's predecessor in the
* graph tree. This will only return a valid
* node, if the node was created on the server
* and is monitored by a node watcher. If the
* node is the head node of a group, this will
* return <code>null</code>.
*
* @return the node's predecessor or <code>null</code>
*/
public Node getPredNode()
{
return predNode;
}
/**
* Queries the node's successor in the
* graph tree. This will only return a valid
* node, if the node was created on the server
* and is monitored by a node watcher. If the
* node is the tail node of a group, this will
* return <code>null</code>.
*
* @return the node's successor or <code>null</code>
*/
public Node getSuccNode()
{
return succNode;
}
/**
* Queries the server at which the node resides
*
* @return the node's <code>Server</code>
*/
public Server getServer()
{
return server;
}
/**
* Sets the node's group. This method
* does not send any messages to the server.
* It merely stores the group object. This method
* may be called by a <code>NodeWatcher</code> for example
* when it receives a <code>/n_info</code> message.
*
* @param group the node's new <code>Group</code> or <code>null</code> (if the node is invalidated)
*/
protected void setGroup( Group group )
{
// if( group == null ) {
// if( this.group != null ) {
//
// }
// } else {
// if( this.group == null ) {
// this.group = group;
// if( group.getHeadNode() == null )
// } else if( this.group.getNodeID() != group.getNodeID() ) {
// if( (group.getHeadNode() != null) && (group.getHeadNode().getNodeID() == this.getNodeID()) ) {
// group.setHeadNode( this.getSuccNode() );
// }
// if( (group.getTailNode() != null) && (group.getTailNode().getNodeID() == this.getNodeID()) ) {
// group.setTailNode( this.getPredNode() );
// }
this.group = group;
// }
// }
}
/**
* Sets the node's predecessor node. This method
* does not send any messages to the server.
* It merely stores the passed in object. This method
* may be called by a <code>NodeWatcher</code> for example
* when it receives a <code>/n_info</code> message.
*
* @param predNode the node's new predecessor <code>Node</code> or <code>null</code>
*/
protected void setPredNode( Node predNode )
{
this.predNode = predNode;
// if( predNode != null ) {
// predNode.succNode = this;
// }
}
/**
* Sets the node's successor node. This method
* does not send any messages to the server.
* It merely stores the passed in object. This method
* may be called by a <code>NodeWatcher</code> for example
* when it receives a <code>/n_info</code> message.
*
* @param succNode the node's new successor <code>Node</code> or <code>null</code>
*/
protected void setSuccNode( Node succNode )
{
this.succNode = succNode;
// if( succNode != null ) {
// succNode.predNode = this;
// }
}
/**
* Queries the node's identifier.
*
* @return the identifier by which the node is known on the server side
*/
public int getNodeID()
{
return nodeID;
}
/**
* Queries whether the node exists on the server and is
* playing (not paused).
* This information is only valid when the node was
* tracked by a <code>NodeWatcher</code>.
*
* @return <code>true</code> if the node exists on the server and is playing (not paused),
* <code>false</code> otherwise
*/
public boolean isPlaying()
{
return isPlaying;
}
/**
* Specifies whether the node is playing (not paused).
* This method is supposed to be called by a <code>NodeWatcher</code>.
* Do not call it yourself.
*
* @param isPlaying <code>true</code> if the node is playing
* <code>false</code> if the node is paused
*/
protected void setPlaying( boolean isPlaying )
{
this.isPlaying = isPlaying;
}
/**
* Queries whether the node exists on the server.
* This information is only valid when the node was
* tracked by a <code>NodeWatcher</code>.
*
* @return <code>true</code> if the node exists on the server,
* <code>false</code> otherwise
*/
public boolean isRunning()
{
return isRunning;
}
/**
* Specifies whether the node exists on the server.
* This method is supposed to be called by a <code>NodeWatcher</code>.
* Do not call it yourself.
*
* @param isRunning <code>true</code> if the node exists on the server,
* <code>false</code> otherwise
*/
protected void setRunning( boolean isRunning )
{
this.isRunning = isRunning;
}
/**
* Two nodes are equal if they
* reside on the same server and
* have the same node ID. Note
* that in this implementation,
* object reference identity for the
* servers is assumed. You should
* not create several instances for
* the same server.
*/
public boolean equals( Object o )
{
if( o instanceof Node ) {
final Node node = (Node) o;
return( (node.getNodeID() == this.getNodeID()) && (node.getServer() == this.getServer()) );
} else {
return false;
}
}
/**
* @see #equals( Object )
*/
public int hashCode()
{
return( getServer().hashCode() ^ getNodeID() );
}
/**
* Frees the node on the server.
* This sends a <code>/n_free</code> message to the server.
*
* @see #freeMsg()
* @throws IOException if an error occurs while sending the OSC message
*/
public void free()
throws IOException
{
// free( true );
getServer().sendMsg( freeMsg() );
}
// public void free( boolean sendFlag )
// throws IOException
// {
// if( sendFlag ) {
// getServer().sendMsg( freeMsg() );
// }
//// removed 02-oct-05
//// setGroup( null );
//// setPlaying( false );
//// setRunning( false );
// }
/**
* Creates an OSC <code>/n_free</code> message for the node.
*
* @return an <code>OSCMessage</code> which can be sent to the server
*
* @see #free()
*/
public OSCMessage freeMsg()
{
return new OSCMessage( "/n_free", new Object[] { new Integer( getNodeID() )});
}
/**
* Resumes the node if it was paused.
* This sends a <code>[ /n_run, <nodeID>, 1 ]</code> message to the server.
*
* @see #runMsg()
* @throws IOException if an error occurs while sending the OSC message
*/
public void run()
throws IOException
{
run( true );
}
/**
* Pauses or resumes the node.
* This sends a <code>/n_run</code> message to the server.
*
* @param flag <code>false</code> to pause the node, <code>true</code> to resume the node.
*
* @see #runMsg( boolean )
* @throws IOException if an error occurs while sending the OSC message
*/
public void run( boolean flag )
throws IOException
{
getServer().sendMsg( runMsg( flag ));
}
/**
* Creates an OSC <code>[ /n_run, <nodeID>, 1 ]</code> message for the node.
*
* @return an <code>OSCMessage</code> which can be sent to the server
*
* @see #run()
*/
public OSCMessage runMsg()
{
return runMsg( true );
}
/**
* Creates an OSC <code>/n_run</code> message for the node.
*
* @param flag <code>false</code> to pause the node, <code>true</code> to resume the node.
* @return an <code>OSCMessage</code> which can be sent to the server
*
* @see #run( boolean )
*/
public OSCMessage runMsg( boolean flag )
{
return new OSCMessage( "/n_run", new Object[] { new Integer( getNodeID() ), new Integer( flag ? 1 : 0 )});
}
/**
* Sets a node's control parameter to a new value.
* This sends a <code>/n_set</code> message to the server.
* If the node is a <code>Synth</code>, it adjusts the synth's control value.
* If the node is a <code>Group</code>, it adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlName the name of the control (<code>SynthDef</code> argument)
* @param value the new value of the control
*
* @see #setMsg( String, float )
* @throws IOException if an error occurs while sending the OSC message
*/
public void set( String ctrlName, float value )
throws IOException
{
getServer().sendMsg( setMsg( ctrlName, value ));
}
/**
* Creates an OSC <code>/n_set</code> message to change a node's control parameter to a new value.
* Sending this message to a <code>Synth</code> adjusts the synth's control value.
* Sending this message to a <code>Group</code> adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlName the name of the control (<code>SynthDef</code> argument)
* @param value the new value of the control
*
* @see #set( String, float )
*/
public OSCMessage setMsg( String ctrlName, float value )
{
return new OSCMessage( "/n_set", new Object[] { new Integer( getNodeID() ), ctrlName, new Float( value )});
}
/**
* Sets a node's control parameter to a new value.
* This sends a <code>/n_set</code> message to the server.
* If the node is a <code>Synth</code>, it adjusts the synth's control value.
* If the node is a <code>Group</code>, it adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlIdx the index of the control (<code>SynthDef</code> argument)
* @param value the new value of the control
*
* @see #setMsg( int, float )
* @throws IOException if an error occurs while sending the OSC message
*/
public void set( int ctrlIdx, float value )
throws IOException
{
getServer().sendMsg( setMsg( ctrlIdx, value ));
}
/**
* Creates an OSC <code>/n_set</code> message to change a node's control parameter to a new value.
* Sending this message to a <code>Synth</code> adjusts the synth's control value.
* Sending this message to a <code>Group</code> adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlIdx the index of the control (<code>SynthDef</code> argument)
* @param value the new value of the control
*
* @see #set( int, float )
*/
public OSCMessage setMsg( int ctrlIdx, float value )
{
return new OSCMessage( "/n_set", new Object[] { new Integer( getNodeID() ), new Integer( ctrlIdx ), new Float( value )});
}
/**
* Sets a list of the node's control parameters to new values.
* This sends a <code>/n_set</code> message to the server.
* If the node is a <code>Synth</code>, it adjusts the synth's control values.
* If the node is a <code>Group</code>, it adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames an array of the names of the controls (<code>SynthDef</code> arguments)
* @param values an array of the new values of the controls. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>values</code> must be equal.
*
* @see #setMsg( String[], float[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void set( String[] ctrlNames, float[] values )
throws IOException
{
getServer().sendMsg( setMsg( ctrlNames, values ));
}
/**
* Creates an OSC <code>/n_set</code> message to adjust a list of the node's control parameters to new values.
* Sending this message to a <code>Synth</code> adjusts the synth's control values.
* Sending this message to a <code>Group</code> adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames an array of the names of the controls (<code>SynthDef</code> arguments)
* @param values an array of the new values of the controls. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>values</code> must be equal.
*
* @see #set( String[], float[] )
*/
public OSCMessage setMsg( String[] ctrlNames, float[] values )
{
final Object[] args = new Object[ (ctrlNames.length << 1) + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlNames.length; i++ ) {
args[ j++ ] = ctrlNames[ i ];
args[ j++ ] = new Float( values[ i ]);
}
return( new OSCMessage( "/n_set", args ));
}
/**
* Sets a list of the node's control parameters to new values.
* This sends a <code>/n_set</code> message to the server.
* If the node is a <code>Synth</code>, it adjusts the synth's control values.
* If the node is a <code>Group</code>, it adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices an array of the indices of the controls (<code>SynthDef</code> arguments)
* @param values an array of the new values of the controls. Each array element corresponds
* to the control index in <code>ctrlIndices</code> at the same array index. the array sizes of
* <code>ctrlIndices</code> and <code>values</code> must be equal.
*
* @see #setMsg( int[], float[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void set( int[] ctrlIndices, float[] values )
throws IOException
{
getServer().sendMsg( setMsg( ctrlIndices, values ));
}
/**
* Creates an OSC <code>/n_set</code> message to adjust a list of the node's control parameters to new values.
* Sending this message to a <code>Synth</code> adjusts the synth's control values.
* Sending this message to a <code>Group</code> adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices an array of the indices of the controls (<code>SynthDef</code> arguments)
* @param values an array of the new values of the controls. Each array element corresponds
* to the control index in <code>ctrlIndices</code> at the same array index. the array sizes of
* <code>ctrlIndices</code> and <code>values</code> must be equal.
*
* @see #set( int[], float[] )
*/
public OSCMessage setMsg( int[] ctrlIndices, float[] values )
{
final Object[] args = new Object[ (ctrlIndices.length << 1) + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlIndices.length; i++ ) {
args[ j++ ] = new Integer( ctrlIndices[ i ]);
args[ j++ ] = new Float( values[ i ]);
}
return( new OSCMessage( "/n_set", args ));
}
/**
* Sets ranges of the node's control parameters to new values.
* This sends a <code>/n_fill</code> message to the server.
* If the node is a <code>Synth</code>, it adjusts the synth's control values.
* If the node is a <code>Group</code>, it adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames the names of the first control to change
* @param numControls the numbers of successive controls to change
* @param values an array of the new values of the controls. the sizes
* of <code>ctrlNames</code>, <code>numControls</code> and <code>values</code>
* must be equal.
*
* @see #fillMsg( String[], int[], float[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void fill( String[] ctrlNames, int[] numControls, float[] values )
throws IOException
{
getServer().sendMsg( fillMsg( ctrlNames, numControls, values ));
}
/**
* Creates an OSC <code>/n_fill</code> message to adjust ranges of the node's control parameters to new values.
* Sending this message to a <code>Synth</code> adjusts the synth's control values.
* Sending this message to a <code>Group</code> adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames the names of the first control to change
* @param numControls the numbers of successive controls to change
* @param values an array of the new values of the controls. the sizes
* of <code>ctrlNames</code>, <code>numControls</code> and <code>values</code>
* must be equal.
*
* @see #fill( String[], int[], float[] )
*/
public OSCMessage fillMsg( String[] ctrlNames, int[] numControls, float[] values )
{
final Object[] args = new Object[ ctrlNames.length * 3 + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlNames.length; i++ ) {
args[ j++ ] = ctrlNames[ i ];
args[ j++ ] = new Integer( numControls[ i ]);
args[ j++ ] = new Float( values[ i ]);
}
return( new OSCMessage( "/n_fill", args ));
}
/**
* Sets ranges of the node's control parameters to new values.
* This sends a <code>/n_fill</code> message to the server.
* If the node is a <code>Synth</code>, it adjusts the synth's control values.
* If the node is a <code>Group</code>, it adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices the indices of the first control to change
* @param numControls the numbers of successive controls to change
* @param values an array of the new values of the controls. the sizes
* of <code>ctrlIndices</code>, <code>numControls</code> and <code>values</code>
* must be equal.
*
* @see #fillMsg( int[], int[], float[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void fill( int[] ctrlIndices, int[] numControls, float[] values )
throws IOException
{
getServer().sendMsg( fillMsg( ctrlIndices, numControls, values ));
}
/**
* Creates an OSC <code>/n_fill</code> message to adjust ranges of the node's control parameters to new values.
* Sending this message to a <code>Synth</code> adjusts the synth's control values.
* Sending this message to a <code>Group</code> adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices the indices of the first control to change
* @param numControls the numbers of successive controls to change
* @param values an array of the new values of the controls. the sizes
* of <code>ctrlIndices</code>, <code>numControls</code> and <code>values</code>
* must be equal.
*
* @see #fill( int[], int[], float[] )
*/
public OSCMessage fillMsg( int[] ctrlIndices, int[] numControls, float[] values )
{
final Object[] args = new Object[ ctrlIndices.length * 3 + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlIndices.length; i++ ) {
args[ j++ ] = new Integer( ctrlIndices[ i ]);
args[ j++ ] = new Integer( numControls[ i ]);
args[ j++ ] = new Float( values[ i ]);
}
return( new OSCMessage( "/n_fill", args ));
}
/**
* Sets ranges of the node's control parameters to new values.
* This sends a <code>/n_setn</code> message to the server.
* If the node is a <code>Synth</code>, it adjusts the synth's control values.
* If the node is a <code>Group</code>, it adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames the names of the first control to change
* @param values an array of arrays of the new values of the controls. each outer
* array corresponds to one element in <code>ctrlNames</code>, hence
* <code>ctrlNames.length</code> and <code>values.length</code>
* must be equal.
*
* @see #setnMsg( String[], float[][] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void setn( String[] ctrlNames, float[][] values )
throws IOException
{
getServer().sendMsg( setnMsg( ctrlNames, values ));
}
/**
* Creates an OSC <code>/n_setn</code> message to adjust ranges of the node's control parameters to new values.
* Sending this message to a <code>Synth</code> adjusts the synth's control values.
* Sending this message to a <code>Group</code> adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames the names of the first control to change
* @param values an array of arrays of the new values of the controls. each outer
* array corresponds to one element in <code>ctrlNames</code>, hence
* <code>ctrlNames.length</code> and <code>values.length</code>
* must be equal.
*
* @see #setn( String[], float[][] )
*/
public OSCMessage setnMsg( String[] ctrlNames, float[][] values )
{
final Object[] args;
float[] subV;
int numArgs = 1;
for( int i = 0; i < ctrlNames.length; i++ ) {
numArgs += values[ i ].length + 2;
}
args = new Object[ numArgs ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlNames.length; i++ ) {
args[ j++ ] = ctrlNames[ i ];
subV = values[ i ];
args[ j++ ] = new Integer( subV.length );
for( int k = 0; k < subV.length; k++ ) {
args[ j++ ] = new Float( subV[ k ]);
}
}
return( new OSCMessage( "/n_setn", args ));
}
/**
* Sets ranges of the node's control parameters to new values.
* This sends a <code>/n_setn</code> message to the server.
* If the node is a <code>Synth</code>, it adjusts the synth's control values.
* If the node is a <code>Group</code>, it adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices the indices of the first control to change
* @param values an array of arrays of the new values of the controls. each outer
* array corresponds to one element in <code>ctrlNames</code>, hence
* <code>ctrlNames.length</code> and <code>values.length</code>
* must be equal.
*
* @see #setnMsg( int[], float[][] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void setn( int[] ctrlIndices, float[][] values )
throws IOException
{
getServer().sendMsg( setnMsg( ctrlIndices, values ));
}
/**
* Creates an OSC <code>/n_setn</code> message to adjust ranges of the node's control parameters to new values.
* Sending this message to a <code>Synth</code> adjusts the synth's control values.
* Sending this message to a <code>Group</code> adjusts the control values of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices the indices of the first control to change
* @param values an array of arrays of the new values of the controls. each outer
* array corresponds to one element in <code>ctrlNames</code>, hence
* <code>ctrlNames.length</code> and <code>values.length</code>
* must be equal.
*
* @see #setn( String[], float[][] )
*/
public OSCMessage setnMsg( int[] ctrlIndices, float[][] values )
{
final Object[] args;
float[] subV;
int numArgs = 1;
for( int i = 0; i < ctrlIndices.length; i++ ) {
numArgs += values[ i ].length + 2;
}
args = new Object[ numArgs ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlIndices.length; i++ ) {
args[ j++ ] = new Integer( ctrlIndices[ i ]);
subV = values[ i ];
args[ j++ ] = new Integer( subV.length );
for( int k = 0; k < subV.length; k++ ) {
args[ j++ ] = new Float( subV[ k ]);
}
}
return( new OSCMessage( "/n_setn", args ));
}
/**
* Maps a list of the node's control parameters to be automatically read from global control busses.
* This sends a <code>/n_map</code> message to the server.
* If the node is a <code>Synth</code>, it maps the synth's controls.
* If the node is a <code>Group</code>, it maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices an array of the indices of the controls (<code>SynthDef</code> arguments)
* @param busIndices an array of the indices of the control busses. Each array element corresponds
* to the control index in <code>ctrlIndices</code> at the same array index. the array sizes of
* <code>ctrlIndices</code> and <code>values</code> must be equal. whenever a bus index is
* <code>-1</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #mapMsg( int[], int[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void map( int[] ctrlIndices, int[] busIndices )
throws IOException
{
getServer().sendMsg( mapMsg( ctrlIndices, busIndices ));
}
/**
* Creates an OSC <code>/n_map</code> message to map a list of the node's control parameters to
* be automatically read from global control busses.
* Sending this message to a <code>Synth</code> maps the synth's controls.
* Sending this message to a <code>Group</code> maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices an array of the indices of the controls (<code>SynthDef</code> arguments)
* @param busIndices an array of the indices of the control busses. Each array element corresponds
* to the control index in <code>ctrlIndices</code> at the same array index. the array sizes of
* <code>ctrlIndices</code> and <code>values</code> must be equal. whenever a bus index is
* <code>-1</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #map( int[], int[] )
*/
public OSCMessage mapMsg( int[] ctrlIndices, int[] busIndices )
{
final Object[] args = new Object[ (ctrlIndices.length << 1) + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlIndices.length; i++ ) {
args[ j++ ] = new Integer( ctrlIndices[ i ]);
args[ j++ ] = new Integer( busIndices[ i ]);
}
return( new OSCMessage( "/n_map", args ));
}
/**
* Maps a list of the node's control parameters to be automatically read from global control busses.
* This sends a <code>/n_map</code> message to the server.
* If the node is a <code>Synth</code>, it maps the synth's controls.
* If the node is a <code>Group</code>, it maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames an array of the names of the controls (<code>SynthDef</code> arguments)
* @param busIndices an array of the names of the control busses. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>values</code> must be equal. whenever a bus index is
* <code>-1</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #mapMsg( String[], int[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void map( String[] ctrlNames, int[] busIndices )
throws IOException
{
getServer().sendMsg( mapMsg( ctrlNames, busIndices ));
}
/**
* Creates an OSC <code>/n_map</code> message to map a list of the node's control parameters to
* be automatically read from global control busses.
* Sending this message to a <code>Synth</code> maps the synth's controls.
* Sending this message to a <code>Group</code> maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames an array of the names of the controls (<code>SynthDef</code> arguments)
* @param busIndices an array of the names of the control busses. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>values</code> must be equal. whenever a bus index is
* <code>-1</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #map( String[], int[] )
*/
public OSCMessage mapMsg( String[] ctrlNames, int[] busIndices )
{
final Object[] args = new Object[ (ctrlNames.length << 1) + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlNames.length; i++ ) {
args[ j++ ] = ctrlNames[ i ];
args[ j++ ] = new Integer( busIndices[ i ]);
}
return( new OSCMessage( "/n_map", args ));
}
/**
* Maps a list of the node's control parameters to be automatically read from global control busses.
* This sends a <code>/n_map</code> message to the server.
* If the node is a <code>Synth</code>, it maps the synth's controls.
* If the node is a <code>Group</code>, it maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices an array of the indices of the controls (<code>SynthDef</code> arguments)
* @param busses an array of control busses. Each array element corresponds
* to the control index in <code>ctrlIndices</code> at the same array index. the array sizes of
* <code>ctrlIndices</code> and <code>busses</code> must be equal. whenever a bus is
* <code>null</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #mapMsg( int[], Bus[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void map( int[] ctrlIndices, Bus[] busses )
throws IOException
{
getServer().sendMsg( mapMsg( ctrlIndices, busses ));
}
/**
* Creates an OSC <code>/n_map</code> message to map a list of the node's control parameters to
* be automatically read from global control busses.
* Sending this message to a <code>Synth</code> maps the synth's controls.
* Sending this message to a <code>Group</code> maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices an array of the indices of the controls (<code>SynthDef</code> arguments)
* @param busses an array of control busses. Each array element corresponds
* to the control index in <code>ctrlIndices</code> at the same array index. the array sizes of
* <code>ctrlIndices</code> and <code>busses</code> must be equal. whenever a bus is
* <code>null</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #map( int[], Bus[] )
*/
public OSCMessage mapMsg( int[] ctrlIndices, Bus[] busses )
{
final Object[] args = new Object[ (ctrlIndices.length << 1) + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlIndices.length; i++ ) {
args[ j++ ] = new Integer( ctrlIndices[ i ]);
args[ j++ ] = new Integer( busses[ i ] == null ? -1 : busses[ i ].getIndex() );
}
return( new OSCMessage( "/n_map", args ));
}
/**
* Maps a list of the node's control parameters to be automatically read from global control busses.
* This sends a <code>/n_map</code> message to the server.
* If the node is a <code>Synth</code>, it maps the synth's controls.
* If the node is a <code>Group</code>, it maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames an array of the names of the controls (<code>SynthDef</code> arguments)
* @param busses an array of control busses. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>busses</code> must be equal. whenever a bus is
* <code>null</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #mapMsg( String[], Bus[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void map( String[] ctrlNames, Bus[] busses )
throws IOException
{
getServer().sendMsg( mapMsg( ctrlNames, busses ));
}
/**
* Creates an OSC <code>/n_map</code> message to map a list of the node's control parameters to
* be automatically read from global control busses.
* Sending this message to a <code>Synth</code> maps the synth's controls.
* Sending this message to a <code>Group</code> maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames an array of the names of the controls (<code>SynthDef</code> arguments)
* @param busses an array of control busses. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>busses</code> must be equal. whenever a bus is
* <code>null</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #map( String[], Bus[] )
*/
public OSCMessage mapMsg( String[] ctrlNames, Bus[] busses )
{
final Object[] args = new Object[ (ctrlNames.length << 1) + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlNames.length; i++ ) {
args[ j++ ] = ctrlNames[ i ];
args[ j++ ] = new Integer( busses[ i ] == null ? -1 : busses[ i ].getIndex() );
}
return( new OSCMessage( "/n_map", args ));
}
/**
* Convenience method for a single mapping.
*/
public void map( String ctrlName, Bus bus )
throws IOException
{
getServer().sendMsg( mapMsg( ctrlName, bus ));
}
/**
* Convenience method for a single mapping.
*/
public OSCMessage mapMsg( String ctrlName, Bus bus )
{
return( new OSCMessage( "/n_map", new Object[] {
new Integer( getNodeID() ), ctrlName,
new Integer( bus == null ? -1 : bus.getIndex() )}));
}
/**
* Maps a list of the node's control parameters to be automatically read from global control busses.
* This sends a <code>/n_map</code> message to the server.
* If the node is a <code>Synth</code>, it maps the synth's controls.
* If the node is a <code>Group</code>, it maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices an array of the indices of the controls (<code>SynthDef</code> arguments)
* @param busIndices an array of the indices of the control busses. Each array element corresponds
* to the control index in <code>ctrlIndices</code> at the same array index. the array sizes of
* <code>ctrlIndices</code> and <code>values</code> must be equal. whenever a bus index is
* <code>-1</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
* @param numControls an array of the number of successive controls to map. this array must have the same size
* as <code>ctrlIndices</code>.
*
* @see #mapnMsg( int[], int[], int[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void mapn( int[] ctrlIndices, int[] busIndices, int[] numControls )
throws IOException
{
getServer().sendMsg( mapnMsg( ctrlIndices, busIndices, numControls ));
}
/**
* Creates an OSC <code>/n_map</code> message to map a list of the node's control parameters to
* be automatically read from global control busses.
* Sending this message to a <code>Synth</code> maps the synth's controls.
* Sending this message to a <code>Group</code> maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices an array of the indices of the controls (<code>SynthDef</code> arguments)
* @param busIndices an array of the indices of the control busses. Each array element corresponds
* to the control index in <code>ctrlIndices</code> at the same array index. the array sizes of
* <code>ctrlIndices</code> and <code>values</code> must be equal. whenever a bus index is
* <code>-1</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
* @param numControls an array of the number of successive controls to map. this array must have the same size
* as <code>ctrlIndices</code>.
*
* @see #mapn( int[], int[], int[] )
*/
public OSCMessage mapnMsg( int[] ctrlIndices, int[] busIndices, int[] numControls )
{
final Object[] args = new Object[ ctrlIndices.length * 3 + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlIndices.length; i++ ) {
args[ j++ ] = new Integer( ctrlIndices[ i ]);
args[ j++ ] = new Integer( busIndices[ i ]);
args[ j++ ] = new Integer( numControls[ i ]);
}
return( new OSCMessage( "/n_mapn", args ));
}
/**
* Maps a list of the node's control parameters to be automatically read from global control busses.
* This sends a <code>/n_mapn</code> message to the server.
* If the node is a <code>Synth</code>, it maps the synth's controls.
* If the node is a <code>Group</code>, it maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames an array of the names of the controls (<code>SynthDef</code> arguments)
* @param busIndices an array of the names of the control busses. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>values</code> must be equal. whenever a bus index is
* <code>-1</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
* @param numControls an array of the number of successive controls to map. this array must have the same size
* as <code>ctrlNames</code>.
*
* @see #mapnMsg( String[], int[], int[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void mapn( String[] ctrlNames, int[] busIndices, int[] numControls )
throws IOException
{
getServer().sendMsg( mapnMsg( ctrlNames, busIndices, numControls ));
}
/**
* Creates an OSC <code>/n_mapn</code> message to map a list of the node's control parameters to
* be automatically read from global control busses.
* Sending this message to a <code>Synth</code> maps the synth's controls.
* Sending this message to a <code>Group</code> maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames an array of the names of the controls (<code>SynthDef</code> arguments)
* @param busIndices an array of the names of the control busses. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>values</code> must be equal. whenever a bus index is
* <code>-1</code> the mapping is undone. Mapping is also undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
* @param numControls an array of the number of successive controls to map. this array must have the same size
* as <code>ctrlNames</code>.
*
* @see #mapn( String[], int[], int[] )
*/
public OSCMessage mapnMsg( String[] ctrlNames, int[] busIndices, int[] numControls )
{
final Object[] args = new Object[ ctrlNames.length * 3 + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlNames.length; i++ ) {
args[ j++ ] = ctrlNames[ i ];
args[ j++ ] = new Integer( busIndices[ i ]);
args[ j++ ] = new Integer( numControls[ i ]);
}
return( new OSCMessage( "/n_mapn", args ));
}
/**
* Maps a list of the node's control parameters to be automatically read from global control busses.
* This sends a <code>/n_mapn</code> message to the server.
* If the node is a <code>Synth</code>, it maps the synth's controls.
* If the node is a <code>Group</code>, it maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices an array of the indices of the controls (<code>SynthDef</code> arguments)
* @param busses an array of control busses. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>busses</code> must be equal. The number of successive
* controls is determined by each bus'es numChannels! Mapping is undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #mapnMsg( int[], Bus[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void mapn( int[] ctrlIndices, Bus[] busses )
throws IOException
{
getServer().sendMsg( mapnMsg( ctrlIndices, busses ));
}
/**
* Creates an OSC <code>/n_mapn</code> message to map a list of the node's control parameters to
* be automatically read from global control busses.
* Sending this message to a <code>Synth</code> maps the synth's controls.
* Sending this message to a <code>Group</code> maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlIndices an array of the indices of the controls (<code>SynthDef</code> arguments)
* @param busses an array of control busses. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>busses</code> must be equal. The number of successive
* controls is determined by each bus'es numChannels! Mapping is undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #mapn( int[], Bus[] )
*/
public OSCMessage mapnMsg( int[] ctrlIndices, Bus[] busses )
{
final Object[] args = new Object[ ctrlIndices.length * 3 + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlIndices.length; i++ ) {
args[ j++ ] = new Integer( ctrlIndices[ i ]);
args[ j++ ] = new Integer( busses[ i ].getIndex() );
args[ j++ ] = new Integer( busses[ i ].getNumChannels() );
}
return( new OSCMessage( "/n_mapn", args ));
}
/**
* Maps a list of the node's control parameters to be automatically read from global control busses.
* This sends a <code>/n_mapn</code> message to the server.
* If the node is a <code>Synth</code>, it maps the synth's controls.
* If the node is a <code>Group</code>, it maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames an array of the names of the controls (<code>SynthDef</code> arguments)
* @param busses an array of control busses. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>busses</code> must be equal. The number of successive
* controls is determined by each bus'es numChannels! Mapping is undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #mapnMsg( String[], Bus[] )
* @throws IOException if an error occurs while sending the OSC message
*/
public void mapn( String[] ctrlNames, Bus[] busses )
throws IOException
{
getServer().sendMsg( mapnMsg( ctrlNames, busses ));
}
/**
* Creates an OSC <code>/n_mapn</code> message to map a list of the node's control parameters to
* be automatically read from global control busses.
* Sending this message to a <code>Synth</code> maps the synth's controls.
* Sending this message to a <code>Group</code> maps the controls of
* all synths in this group and subgroups of this group.
*
* @param ctrlNames an array of the names of the controls (<code>SynthDef</code> arguments)
* @param busses an array of control busses. Each array element corresponds
* to the control name in <code>ctrlNames</code> at the same array index. the array sizes of
* <code>ctrlNames</code> and <code>busses</code> must be equal. The number of successive
* controls is determined by each bus'es numChannels! Mapping is undone by successive <code>/n_set</code>,
* <code>/n_setn</code> or <code>/n_fill</code> commands.
*
* @see #mapn( String[], Bus[] )
*/
public OSCMessage mapnMsg( String[] ctrlNames, Bus[] busses )
{
final Object[] args = new Object[ ctrlNames.length * 3 + 1 ];
args[ 0 ] = new Integer( getNodeID() );
for( int i = 0, j = 1; i < ctrlNames.length; i++ ) {
args[ j++ ] = ctrlNames[ i ];
args[ j++ ] = new Integer( busses[ i ].getIndex() );
args[ j++ ] = new Integer( busses[ i ].getNumChannels() );
}
return( new OSCMessage( "/n_mapn", args ));
}
/**
* Releases a node with default release time.
*
* @see #release( float )
*/
public void release()
throws IOException
{
getServer().sendMsg( releaseMsg() );
}
/**
* Releases a node. This assumes that that the <code>Synth</code>
* represented by the node or the synths in the <code>Group</code> represented
* by the node have specified a control named "gate" (usually used
* by an <code>EnvGen</code> envelope generator UGen). This sends a <code>/n_set</code>
* message for the "gate" control to the server.
*
* @param releaseTime the time in seconds for the envelope to be released, or <code>0.0f</code>
* to use the envelope's default release time
*
* @see #releaseMsg( float )
* @throws IOException if an error occurs while sending the OSC message
*/
public void release( float releaseTime )
throws IOException
{
getServer().sendMsg( releaseMsg( releaseTime ));
}
/**
* Creates an OSC <code>/n_set</code> message to release a node with default release time.
*
* @see #releaseMsg( float )
*/
public OSCMessage releaseMsg()
{
return releaseMsg( 0.0f );
}
/**
* Creates an OSC <code>/n_set</code> message to release a node. This assumes that that the <code>Synth</code>
* represented by the node or the synths in the <code>Group</code> represented
* by the node have specified a control named "gate" (usually used
* by an <code>EnvGen</code> envelope generator UGen).
*
* @param releaseTime the time in seconds for the envelope to be released, or <code>0.0f</code>
* to use the envelope's default release time
*
* @see #release( float )
*/
public OSCMessage releaseMsg( float releaseTime )
{
return new OSCMessage( "/n_set", new Object[] { new Integer( getNodeID() ), "gate",
new Float( releaseTime == 0.0f ? releaseTime : -1.0f - releaseTime )}); // so 1 sec. becomes -2 ??? XXX
}
/**
* Sends an OSC <code>/n_trace</code> message to the server.
* The server will print debugging information about the node into its terminal window.
* If the node is a synth, this information includes the current input and output values for UGens in the synth.
* If the node is a group, this information includes the node IDs inside the group.
*
* @see #traceMsg()
* @throws IOException if an error occurs while sending the OSC message
*/
public void trace()
throws IOException
{
getServer().sendMsg( traceMsg() );
}
/**
* Creates an OSC <code>/n_trace</code> message for the node.
* When this message is sent to the server, it will print debugging information about the node into its terminal window.
* If the node is a synth, this information includes the current input and output values for UGens in the synth.
* If the node is a group, this information includes the node IDs inside the group.
*
* @see #trace()
*/
public OSCMessage traceMsg()
{
return new OSCMessage( "/n_trace", new Object[] { new Integer( getNodeID() )});
}
/**
* A debugging method that prints the results
* of an OSC <code>/n_query</code> message into the server's default
* print stream.
*
* @see #query( PrintStream )
* @see Server#getPrintStream()
* @throws IOException if an error occurs while sending the OSC message
*/
public void query()
throws IOException
{
query( Server.getPrintStream() );
}
/**
* A debugging method that prints the results
* of an OSC <code>/n_query</code> message into a given print stream.
*
* @param out the stream to print out, e.g. <code>System.err</code>
*
* @see #query()
* @throws IOException if an error occurs while sending the OSC message
*/
public void query( PrintStream out )
throws IOException
{
final Object nodeIDArg = new Integer( getNodeID() );
final OSCMessage reply;
final Object parent, prev, next, head, tail;
final boolean isGroup;
// try {
reply = getServer().sendMsgSync( queryMsg(), "/n_info", null, 0, nodeIDArg, 4f );
if( reply == null ) {
out.println( "[ \"/n_query\", " + nodeIDArg + " ] -> timeout" );
return;
}
parent = reply.getArg( 1 );
prev = reply.getArg( 2 );
next = reply.getArg( 3 );
isGroup = ((Number) reply.getArg( 4 )).intValue() == 1;
out.println( (isGroup ? "Group : " : "Synth : ") + nodeIDArg + "\n parent: " + parent + "\n prev : " + prev + "\n next : " + next );
if( isGroup ) {
head = reply.getArg( 5 );
tail = reply.getArg( 6 );
out.println( " head : " + head + "\n tail : " + tail );
}
// }
// catch( IOException e1 ) {
// out.println( e1.toString() );
// }
}
public OSCMessage queryMsg()
{
return new OSCMessage( "/n_query", new Object[] { new Integer( getNodeID() )});
}
public void register()
throws IOException
{
register( false );
}
public void register( boolean assumePlaying )
throws IOException
{
final NodeWatcher watcher = NodeWatcher.newFrom( getServer() );
watcher.register( this, assumePlaying );
}
/**
* Moves the node before another node in the server graph.
*
* @param aNode the node before which this node is moved
*
* @throws IOException if the OSC message could not be sent
*
* @warning this does not set the group field of the node.
* the group field is only updated by a <code>NodeWatcher</code>
*
* @see #moveBeforeMsg( Node )
*/
public void moveBefore( Node aNode )
throws IOException
{
// NO
// setGroup() is called by moveBeforeMsg()
// this.setGroup( aNode.getGroup() );
getServer().sendMsg( moveBeforeMsg( aNode ));
}
/**
* Creates an OSC <code>/n_before</code> message. When the message is
* sent to the server, this node is moved before another node in the server graph.
*
* @param aNode the node before which this node is moved
*
* @warning this does not set the group field of the node.
* the group field is only updated by a <code>NodeWatcher</code>
*
* @see #moveBefore( Node )
*/
public OSCMessage moveBeforeMsg( Node aNode )
{
// removed 02-oct-05
// this.setGroup( aNode.getGroup() );
return( new OSCMessage( "/n_before", new Object[] {
new Integer( this.getNodeID() ), new Integer( aNode.getNodeID() )}));
}
/**
* Moves the node after another node in the server graph.
*
* @param aNode the node after which this node is moved
*
* @throws IOException if the OSC message could not be sent
*
* @warning this does not set the group field of the node.
* the group field is only updated by a <code>NodeWatcher</code>
*
* @see #moveAfterMsg( Node )
*/
public void moveAfter( Node aNode )
throws IOException
{
// NO
// setGroup() is called by moveAfterMsg()
// this.setGroup( aNode.getGroup() );
getServer().sendMsg( moveAfterMsg( aNode ));
}
/**
* Creates an OSC <code>/n_after</code> message. When the message is
* sent to the server, this node is moved before another node in the server graph.
*
* @param aNode the node before which this node is moved
*
* @warning this does not set the group field of the node.
* the group field is only updated by a <code>NodeWatcher</code>
*
* @see #moveAfter( Node )
*/
public OSCMessage moveAfterMsg( Node aNode )
{
// removed 02-oct-05
// this.setGroup( aNode.getGroup() );
return( new OSCMessage( "/n_after", new Object[] {
new Integer( this.getNodeID() ), new Integer( aNode.getNodeID() )}));
}
/**
* Moves the node to the head of a group in the server graph.
*
* @param aGroup the group to whose head this node is moved.
* if <code>null</code> the server's default group is used
*
* @throws IOException if the OSC message could not be sent
*
* @warning this does not set the group field of the node.
* the group field is only updated by a <code>NodeWatcher</code>
*
* @see #moveToHeadMsg( Group )
*/
public void moveToHead( Group aGroup )
throws IOException
{
(aGroup != null ? aGroup : getServer().getDefaultGroup()).moveNodeToHead( this );
}
/**
* Creates an OSC <code>/g_head</code> message. When the message is
* sent to the server, this node is moved to the head of a group in the server graph.
*
* @param aGroup the group to whose head this node is moved.
* if <code>null</code> the server's default group is used
*
* @warning this does not set the group field of the node.
* the group field is only updated by a <code>NodeWatcher</code>
*
* @see #moveToHead( Group )
*/
public OSCMessage moveToHeadMsg( Group aGroup )
{
return (aGroup != null ? aGroup : getServer().getDefaultGroup()).moveNodeToHeadMsg( this );
}
/**
* Moves the node to the tail of a group in the server graph.
*
* @param aGroup the group to whose tail this node is moved.
* if <code>null</code> the server's default group is used
*
* @throws IOException if the OSC message could not be sent
*
* @warning this does not set the group field of the node.
* the group field is only updated by a <code>NodeWatcher</code>
*
* @see #moveToTailMsg( Group )
*/
public void moveToTail( Group aGroup )
throws IOException
{
(aGroup != null ? aGroup : getServer().getDefaultGroup()).moveNodeToTail( this );
}
/**
* Creates an OSC <code>/g_tail</code> message. When the message is
* sent to the server, this node is moved to the tail of a group in the server graph.
*
* @param aGroup the group to whose tail this node is moved.
* if <code>null</code> the server's default group is used
*
* @warning this does not set the group field of the node.
* the group field is only updated by a <code>NodeWatcher</code>
*
* @see #moveToTail( Group )
*/
public OSCMessage moveToTailMsg( Group aGroup )
{
return (aGroup != null ? aGroup : getServer().getDefaultGroup()).moveNodeToTailMsg( this );
}
public void printOn( PrintStream stream )
{
stream.print( this.toString() );
}
// -------------- TreeNode interface (subclasses need to complete it) --------------
public TreeNode getParent()
{
return getGroup();
}
}