Coding in PraxisLIVE
PraxisLIVE is a code-first visual environment, in the sense that the code for almost every component is editable and can be adapted, even as it's running. If you can't find a built-in or existing custom component that does what you want, it's easy to adapt one or build one from scratch.
To get started, choose one of the base components and drag it into your graph. Alternatively,
choose a built-in component or custom component that does some of what you want and start from
there instead. Right-click on the component in the graph window and select Edit code
to open
the code in the code editor. Every time you hit Save
within the code editor your code will be
recompiled and inserted into your component, even as it's running.
Info
Saving code in the code editor updates the code of the component, it does not save everything to disk - make sure you also save your project!
Base types
The base types for different component types are listed here. Note that most base types
build on the functionality of core:custom
.
core:custom
: Base type for components that work with control signals inside any graph type. See Coding control componentsdata:custom
: Base type for components that work with control signals inside a data root. This base type should be used for components that are not real-time safe and so should not be added to other graph types. See Coding control componentsaudio:custom
: Base type for audio components. See Coding audio componentsvideo:custom
: Base type for simple video components. See Coding video componentsvideo:gl:p2d
: Video base type providing almost complete access to the Processing 2D API. Only supported in the OpenGL renderer. See Coding OpenGL video componentsvideo:gl:p3d
: Video base type providing almost complete access to the Processing 3D API. Only supported in the OpenGL renderer. See Coding OpenGL video components
Core syntax and functionality
The primary coding language used in PraxisLIVE is Java, although much should be familiar if you've used Processing before.
The code editor supports full code completion and will highlight any errors in your code. Even if you're new to coding, don't be afraid to experiment! You can always use undo or reset the code to the component default or last saved state.
Using annotations
PraxisCORE uses annotations on fields and methods to integrate your code with the environment, such as providing ports and controls, automatically saving state, allowing variables to be controlled from elsewhere, provide background loading of resources, etc.
@In(1) PImage in;
@P(1) @Config.Port(false) PImage image;
@P(2) @Type.Number(min = 0, max = 1) scale;
@T(1) void randomize() {
scale = random(1);
}
public void draw() {
// do something with image and scale
}
The above code is based on one of the video base components. It will provide a video input port, an image property (without port) that supports background loading of an image file, a numeric scale property and a trigger control that calls the annotated method. The graph editor in PraxisLIVE will use this information to show a node with file browser for image, a slider for the ranged scale, and a button for randomize.
Note that none of the fields are initialized by the code - all annotated fields will be automatically set by the environment, carried over from one code iteration to the next.
For more information see the documentation for individual annotations.
Properties and Triggers
All base component types support the use of the @P
and @T
annotations to define properties and triggers (actions).
The core fields types supported by the property annotation are double
, int
, String
, boolean
, as well
as Property
and any Value
subclass. Property also supports animation - see the full
Property documentation. Base types may extend the fields that can be marked
with the property annotation (eg. video base types support PImage
fields).
Values of property fields will normally be saved as part of the project file, unless
the property is marked with @Transient
or
@ReadOnly
. The @Inject
annotation also supports
properties that are hidden and transient - useful for maintaining state or animation while coding.
The trigger annotation can be placed on a zero argument method, or on a field of type boolean
or Trigger
. If using a boolean
field, the value will be set to true
when triggered
- you are responsible for resetting it.
Input and Output
All base components support the use of annotations to provide ports for control signal input and output. The auxillary annotations cause the ports to appear after property and trigger ports rather than before.
@In / @AuxIn
Use the @In
or @AuxIn
annotations on a
method to provide a port with which to receive control values -
@In(1) void in(double input) {
// do something with input
}
The method will be called at the correct time with the input value. Supported types are
double
, int
, String
and and Value
subclass.
@Out / @AuxOut
Use the @Out
or @AuxOut
annotation
on a field of type Output
to provide control signal output ports on your component.
The Output
object supports methods for sending double
, String
and Value
subclasses,
as well as an empty signal.
@Out(1) Output out;
@In(1) void in(double input) {
out.send(input);
}