Releases: praxis-live/praxis-live
PraxisLIVE v6.0.0-beta2
The second beta release of PraxisLIVE v6 brings a few updates and bug fixes as we proceed towards a final release.
PraxisLIVE IDE changes
- Extend property wrappers to support all function controls eg. this function on a component can be called, and the result (or error) displayed, using the property tab or the component editor dialog -
@FN String upper(String in) { return in.toUpperCase(Locale.ROOT); }
- Add a stop / clean button to the output tab for each project.
- Update NetBeans platform to v23
- Support Java 23.
- Switch to upstream Project dashboard widget with history display.
- Update bundled JDK in installers to JDK 23, and add macOS aarch64 installer.
- Fix exception shown when displaying scene comments.
- Various tweaks to allow branding of CORE location and graph colours.
PraxisCORE changes
- Add LWJGL natives for running on Apple Silicon, and also suppress warning caused by resigning of binaries on both macOS architectures.
- Update to libP5X 4.430.1 - fix display issues on Linux Wayland by reverting to use GLFW X11 backend (via XWayland) by default.
- Allow access to all JDK modules in user code (eg. HTTPClient) by using
--add-modules=ALL-DEFAULT
in launcher and child launcher. - Update the default network timeout for hub messages to 60s, and make configurable by system property
praxis.hub.network.timeout
. In particular works around initial startup timeouts on slower systems. - Increased the maximum message size supported via network hub.
PraxisLIVE v6.0.0-beta1
This is the first beta release of PraxisCORE and PraxisLIVE v6.
Version 6 is a substantial rewrite of some key aspects of how PraxisCORE works. Expect some rough edges! Many deprecated and legacy features have been removed. The IDE and core now require minimum Java 21. Networked hubs now use Netty and Ion to provide a more robust and structured communication protocol than was possible with OSC. Key libraries have been updated, including libP5X now based on Processing 4. Runtime dependency management is now based on MiMa rather than Ivy. Much of the project saving and execution has been moved directly into PraxisCORE.
There are a bunch of other useful changes - custom roots can now specify use of table editing rather than the graph editor; containers can filter allowed child types and even specify custom types; annotations no longer require a weight / index parameter - eg. @P int x,y,z;
is now legal syntax! Examples and custom components are being updated and added to showing the new features.
The most obvious change is the new vector logo, window background actions, and revamped dashboard.
The IDE build system has been moved to Maven, and various IDE modules are also published, allowing use of PraxisCORE and PraxisLIVE as a platform for other projects.
Breaking changes
- Built in non-recodeable roots for MIDI, OSC and TinkerForge have been removed. These can now be replicated using custom roots. Examples showing this will follow. A migration path might be looked at for a later (post 6.0) release of the IDE.
- Most deprecated functions and types have been removed. eg. lower case casting functions like
d(..)
must useD(..)
; Propertyvalues()
linking must now usedoubles()
;PVector
is only available fromvideo:gl:p2d
andvideo:gl:p3d
components, etc. Make sure to migrate all deprecated functionality from inside the latest PraxisLIVE v5 before attempting to migrate a project to PraxisLIVE v6.
Known issues
- OpenGL output windows on Linux with Wayland are wrongly sized. A late update to LWJGL changed the default behaviour. Use an X11 session until beta 2. Possibly related LWJGL/lwjgl3#998
- macOS incorrectly reports incorrect OpenGL binaries. This is due to them being re-signed in packaging. Will be fixed in beta 2.
- Some settings windows (eg. GStreamer) are currently inactive.
- Minor display glitch due to graph position not being available on first sync.
PraxisLIVE v5.7.0
This is the last scheduled release in the v5 series of PraxisCORE and PraxisLIVE as we concentrate on v6 for release later this year. There are some major updates to Ref
types and handling, an Async.Queue
for handling async calls, and various deprecations for things that will no longer be supported in v6.
PraxisCORE
- Major updates to
Ref
, including reference ports and a publish / subscribe mechanism for sharing references from containers to child components.- Added
Ref::set
,Ref::setAsync
,Ref::orElse
andRef::onChange
methods. The existing async support inRef
is deprecated and rewritten to use the new method. - Added
@Ref.Publish
and@Ref.Subscribe
to be used on injectedRef
fields in parent and children respectively. References are automatically updated, and changes can be listened to usingRef::onChange
. - Added support for reference ports -
@In(1) Ref.In<T> in
and@Out(1) Ref<T> out
. The input type allows to access the list of connected values, and automatically updates on connections or changes to the output reference. - Updated semantics for
Ref::bind
which can now be configured prior to initialization, and will update on reference changes.
- Added
- Added an injectable queue for
Async
values -@Inject Async.Queue<T> queue
. Supports binding actions to happen on completion and limiting the queue size. For use with async returns fromask()
andasync()
. - Improvements to library support with a PackageURL parsing utility and better support for transient dependencies provided by the runtime itself.
- Added a
.supported-types
property to containers. This has minimal use in v5, but is important in development if some features in v6. - Various deprecations, including serializable properties,
Property::values
andInput::values
methods, andPVector
(from core types, but some supported will remain in video types).
PraxisLIVE
- No changes in the IDE in this release.
PraxisLIVE v5.6.0
This release provides support for recodeable root components, and a range of library updates and bug fixes.
PraxisCORE
- Added
root:custom
(Custom root), a recodeable root type. This is part of moves to finish making everything recodeable. Using the@Driver
annotation on a proxy interface it's possible to drive the root and its contained graph of components from an external callback. See use of this in the code roots testsuite test - more info to follow. - Improved root delegate API and thread context, with some concurrency improvements and monotonic clock fixes that should benefit all root types. Ensure pending calls are handled when a root is terminated.
- Updated libP5X to 0.353.0-beta-4 and LWJGL 3.3.2, with fix for memory leak when stopping and restarting video pipelines.
- Updated Ivy to 2.5.1 (security update - fixes warning, although never exploitable in PraxisCORE code)
- Updated JNA to 5.13.0.
PraxisLIVE
- Updated base IDE to Apache NetBeans 17.
- Added container actions to the scene background popup menu - access to code editing for custom root, but also any actions exposed by roots or custom containers.
- Speed up project builds at UI side by ensuring UI poll is triggered on call receipt (response) rather than on timer.
- Ensure root annotations are set in graph build (eg. show all properties not being set on load).
PraxisLIVE v5.5.0
PraxisLIVE v5.5.0 adds some key features in our evolution towards v6. These include sharing base code across components, function controls bound to methods, and an async API for calls and tasks.
The IDE is updated to be based on Apache NetBeans 16, with support for JDK 19. OpenJDK 17 LTS from Adoptium is still included in all OS specific bundles. Use the zip download to run with other JDKs or architectures.
Windows, macOS and Linux packages are now all built using NBPackage. The Windows and macOS installers are signed by Codelerity. We are no longer providing AppImages for Linux, but providing both DEB and RPM packages.
Key changes
Shared base components
It's now possible to share base component code across multiple components in a graph. Right-click on a component and select Create shared base
. You can then duplicate the component (CTRL-D
) and update all instances at the same time. Individual component code can still be added to extend or override the base component features.
The fast edit action (SHIFT-doubleclick
or SHIFT-RETURN
) will open the base component code for editing as long as the component has not extended the base code.
As a side effect of changes for base components, properties, controls and ports no longer have to have a unique index. They are sorted by index then alphabetically. This allows for code such as @In(1) PImage in1, in2;
or @P(1) @Type.Number(min=0, max=1) double x,y,z;
to work.
An important limitation on the current shared base component support in the IDE is that copy & paste of components across different graphs will not copy the shared base code - you must copy that in place manually first.
Function controls and value mapping
It's now possible to create function controls by annotating a method in a component with @FN
.
eg.
@P(1) @Type.String(def = "Hello") String greeting;
@FN String greet(String name) {
return greeting + " " + name;
}
This is most useful when used with the Async API (below) to call a component in another graph to process data for you.
As part of this support, mapping between Java types and PraxisCORE Value types has been improved. The various casting methods such as d(..)
and s(..)
have been deprecated and replaced with upper case (D(..)
and S(..)
) equivalents with improved behaviour. There is also V(..)
for converting from Java types to Value.
Async calls and tasks
There is now a basic Async API for making control calls where you want the return value, as well as support for arbitrary background tasks. Methods return an Async<T>
object that currently must be polled for the result. Store the async object in a field marked with @Persist
to ensure it survives code changes. Further improvements are underway here.
Calling a function control
Call a function control using ask(..)
@Persist Async<Call> response;
@T(1) void trigger() {
response = ask(ControlAddress.of("/data/greeter.greet"), "<NAME>");
}
@Override
public void update() {
if (response != null && response.done()) {
if (response.failed()) {
log(ERROR, "<FAIL> " + response.error());
} else {
log(INFO, response.result().args().get(0).toString());
}
response = null;
}
}
An async task
For basic tasks which don't rely on properties or data of another component, you can also async(..)
that will run the provided code in background thread. Be careful to pass in all required data in the first argument and not access any component data in the background thread!
@P(1) String name;
@Persist Async<String> response;
@T(1) void trigger() {
response = async(name, n -> "Hello " + n);
}
@Override
public void update() {
if (response != null && response.done()) {
if (response.failed()) {
log(ERROR, "<FAIL> " + response.error());
} else {
log(INFO, response.result());
}
response = null;
}
}
Further info
More information on new features will be added to the docs soon.
In the meantime, also check out the testsuite projects -
PraxisLIVE v5.4.0
PraxisLIVE v5.4.0 adds support for recodeable containers. This is the first visible part of much broader underlying changes.
The IDE is updated to be based on Apache NetBeans 12.6, with support for JDK 17. OpenJDK 17 from Adoptium is now included in all OS specific bundles (except the Arm AppImage which includes BellSoft Liberica.
Windows and Linux packages are now built using NBPackage, a DEB package is again provided, and the Windows installer is signed by Codelerity.
Recodeable containers
A core:container
can now be recoded. Additional controls and ports may be added. The children()
method returns a list of all child IDs. It's possible to send messages to a range of child components from a control or port. eg.
@In(1) void in(String value) {
children().forEach(c -> tell(self().resolve(c).control("value"), value));
}
Further capabilities for coding containers and roots are under development.
PraxisLIVE v5.3.0
PraxisLIVE v5.3.0 adds support for creating recodeable proxy interfaces (eg. for passing in as listeners to third-party code), persistent fields, and better support for injecting arbitrary types. The IDE is updated to be based on Apache NetBeans 12.4, and now bundles JDK 16 (with JDK 17 support to follow soon).
Changes
PraxisCORE runtime
- Added support for recodeable proxy interfaces. The interface reference is carried across code changes and automatically wraps the implementation so that the reference can be safely passed to other code while remaining updateable. See usage instructions below for more.
- Added support for persistent fields that retain their value across code changes but are not automatically injected. For select and careful use!
- Added support for reference providers in
@Inject
annotations so that arbitrary types can be injected while controllingRef
handling in a central place (eg. in shared code). See below. - Added a default reference provider, with initial support for
List
,Set
andMap
. These can now be used directly as an injected field type - eg.@Inject List<String> lines
. They are implemented byArrayList
,LinkedHashSet
andLinkedHashMap
respectively. This can be overridden by providing a custom provider. - Added a basic logging provider to log to System.err when running from CLI.
- FIX : ensure JLine terminal IO doesn't break when hub is restarted by splitting out and persisting the terminal IO across runs.
PraxisLIVE IDE
- Updated base IDE to Apache NetBeans 12.4, with support for JDK 16.
- Updated bundled JDK to JDK 16.
Proxy interfaces
Proxy interfaces are defined by fields, and are most easily used with lambdas or method references. Unusually for PraxisCORE annotated fields, the value requires initialization. eg.
@Proxy Runnable foo = this::doFoo;
@Proxy DoubleUnaryOperator bar = x -> sin(x*x);
It's important to be aware that the initialized value of the field will be wrapped by the proxy before init()
or any other code is called. Setting the field value after this point will not work as expected.
It's also important to note that the interface will be called on the root thread, blocking the calling thread. This makes it safe to call functions and send messages. Support for running on the calling thread will follow in a future release.
Persistent fields
Persistent fields allow for field values to be carried over from one iteration of code to the next. Unlike injected fields, persistent fields are not automatically set. They are most useful for temporary values.
Persistent fields are reset to default values (eg. 0
or null
) when the root is restarted, unless the autoReset
value of the annotation is set to false
. Like Ref
values, any AutoCloseable
values will be closed when removed or reset unless the autoClose
value of the annotation is set to false
.
@Persist int counter;
@Persist(autoReset = false) Future<String> result;
Inject Ref providers
Ref providers allow for custom field types to be injected without requiring the field itself to be of type Ref
. Instead, a Ref.Provider
class, usually in shared code, can manage initialization of the Ref
in one place. All of the features of Ref
(except async) can be used in the provider to control what happens on reset and disposal.
package SHARED;
// imports
public class Types extends Ref.Provider {
public Types() {
register(List.class, (Ref<List<?>> r) -> r.init(LinkedList::new).onReset(List::clear));
}
}
@Inject List<String> arrayList;
@Inject(provider = SHARED.Types.class) List<String> linkedList;
PraxisLIVE v5.2.0
PraxisLIVE v5.2.0 adds support for components to share common, rewritable code (within one graph). The IDE adds an
action for embedding the runtime inside a project for standalone running. And there's the usual range of small
tweaks and bug fixes.
Changes
PraxisCORE runtime
- Support shared, rewritable code across components within a single root.
- Sources for shared code are stored as a map property on the root component. All code is in the
SHARED
package. - Any component that imports shared code will be automatically recompiled whenever shared code changes.
- Breaking changes or deletions of shared code in use will fail.
- Data ports can pass shared types between components.
- NB. As part of this change, the full class name of component code has changed to accommodate compiling multiple
components at a time. This shouldn't cause major problems. - NB. As part of this change, the module providing audio and video root components changed. This shouldn't cause
major problems.
- Sources for shared code are stored as a map property on the root component. All code is in the
- Provided field for graphics object and easier access to underlying Processing graphics in
video:gl:p2d
and
video:gl:p3d
based components. Useg
to accessPGraphics
wrapper,g.unwrap()
to access Processing
PGraphics
andg.unwrap().parent
to accessPApplet
. NB. the underlying Processing graphics may change in
every call todraw()
due to reuse in the pipeline. - Added signal traps for child processes when running from terminal so that children aren't terminated before
parent. - FIX : incorrect info being reported for mapped ports on
core:container
. (The IDE may still show the wrong info
momentarily - to be fixed).
PraxisLIVE IDE
- Added UI and code editor support for shared code in the graph editor (see guide below).
- Added a basic action in the project popup menu to embed the PraxisCORE runtime, along with an optional JDK,
inside a project for standalone running and distribution. More options for exporting projects will be added in due
course. Standalone projects still support live code updates, distributed hubs, and the full range of command line
options including--interactive
. - Update of nb-javac library, and changed download and integration from upstream.
Using shared code
To access the UI panel for shared code, right-click on the graph background and toggle Shared Code
.
To create a new shared code type, right-click on the SHARED
folder and select New Type...
. The name must be a
valid Java type name. A class will be created by default and opened in the editor. It can be changed from class to
interface, enum, etc. if required.
To access shared code from a component's code, add an import - eg.
import SHARED.Foo;
import static SHARED.Utils.*;
Every time you edit and save a shared code file, all dependent components using shared code will be recompiled and
updated atomically. If a code edit or type deletion causes a compilation error in the shared code or any component,
the old iteration of code will continue to be used.
Updating the code of a component using shared code will not cause other components or shared code to be recompiled
(components continue to be isolated in separate classloaders that have the shared code as a parent).
TIP : You can CTRL-click
any shared code type or method to open it in the editor.
Just like with normal component code, saving the code updates the components in memory - make sure to save the graph
or project to disk!
PraxisLIVE v5.1.0
PraxisLIVE v5.1.0 adds support for running OpenGL(ES) on Raspberry Pi and other ARM devices, supports adding libraries to projects from the Maven Central repository, and brings a range of smaller improvements and bug fixes.
Changes
PraxisCORE runtime
- Support for running OpenGL(ES) projects on Raspberry Pi and other ARM devices. The default OpenGL renderer uses OpenGLES on all ARM devices. OpenGL2 can also be chosen explicitly on the Pi. More info below.
- Ability to add libraries from the Maven Central repository to projects, including resolution of transitive dependencies. Libraries are downloaded and (currently) cached external to each project. Further enhancements are planned in this area. Each library is referenced using a PURL or Package URL. More info below.
- Added commands for libraries support that can be used in interactive CLI mode, including
libraries-all
for querying all in use libraries including transitive dependencies, andlibraries-path
for showing the local file locations of libraries.
- Added commands for libraries support that can be used in interactive CLI mode, including
- Updated GStreamer (gst1-java-core) and JNA libraries - more efficient across OS, and support for MSVC build of GStreamer on Windows.
- Default location of GStreamer on Windows now queried from environment variables - should usually work correctly out of the box in most cases.
- Added initial JLine-based Terminal IO when working in interactive mode. Supports command history, multi-line editing and coloured output.
- FIX for server resources not being found with distributed hub, due to resource resolver not being correctly configured when working with server enabled.
- FIX for video playback across network not working correctly and not allowing seeking.
- FIX for some settings, including GStreamer settings, not being correctly persisted or visible to projects.
- FIX null pointer in MIDI support when no device selected.
PraxisLIVE IDE
- Added basic UI support in the libraries section of project properties for adding Maven Package URLs. Imported libraries will now be included as individual references, and added to a visible folder in the project. Updated editor support uses library path from runtime.
Working remotely with Raspberry Pi, etc.
As well as running the full PraxisLIVE IDE on the Pi, it's possible to just run the PraxisCORE runtime and connect to it from another computer.
The PraxisCORE runtime can be extracted from the praxiscore
directory inside the IDE or downloaded from https://github.com/praxis-live/praxiscore/releases
On the Pi, you must have OpenJDK 11 or above installed. From inside the praxiscore
directory run -
./bin/praxis --network all --port 42424
Feel free to use any port number. If launching via ssh, you probably want to use export DISPLAY=:0
first to ensure any windows are created on the Pi display.
In the IDE, open the project properties of the project you wish to run on the Pi (right-click on project node). Select the Hub Configuration section and replace the default text with this, changing <IP ADDRESS>
to the address of the Pi, and the port number if required.
enable-fileserver true
proxies {
all {
host <IP ADDRESS>
port 42424
id-pattern *
type-pattern *
}
}
Run the project and it should now run on the Pi. Any required files will be served from the IDE machine where they are not available at the same location (relative to user directory) on the Pi.
NB. this should only be done on a secure local network.
Further info at https://docs.praxislive.org/projects/#hub-configuration
Maven Package URLs
External libraries are referenced using a Package URL or PURL. This is a concise format that also works with various aspects of the existing library support that expect URLs.
To add a library URL to a project, access the project properties (right-click on project node) and use the libraries section. Click Add
to add a library URL. Libraries may not be removed from an active project (eg. built or running).
A Maven PURL has the following format :
pkg:maven/{group-id}/{artefact-id}@{version}
The PURL for any library can be found in searching at https://search.maven.org eg. the PURL for https://search.maven.org/artifact/org.apache.commons/commons-lang3/3.11/jar is pkg:maven/org.apache.commons/commons-lang3@3.11
Only pkg:maven
PURLs are supported at present, and query parameters are not yet supported.
The Maven dependency resolution is currently based on Apache Ivy. Cached dependencies are stored in the default (~/.ivy2/cache
) location.
PraxisLIVE v5.0.0
This is the first full release of PraxisCORE and PraxisLIVE v5.x. Windows and macOS bundles, as well as a zip bundle, are below. Linux users may try the new AppImage based packaging, which also includes an embedded JDK from AdoptOpenJDK, or use the zip bundle that uses the system installed JDK. To use the AppImage simply download, make it executable and run it.
v5 is a major rewrite of both the core runtime and the IDE. Much legacy and deprecated functionality has been removed. All of PraxisCORE has now been rewritten around the new base actor system introduced in parallel in 4.4.0. PraxisCORE is now built on top of the Java module system, rather than the Apache NetBeans platform (the PraxisLIVE IDE is still based on Apache NetBeans). The build for PraxisCORE has been moved to Maven, and individual modules will be deployed to central for re-use in other projects.
Both PraxisLIVE and PraxisCORE require at least Java 11 - an open-source Java 11 JDK from AdoptOpenJDK is included in the binary packages.
PraxisLIVE now supports running multiple projects at once. Distributed hub support has moved from the IDE into PraxisCORE, and is configured separately for each project. The default project configuration will run audio and video roots in separate Java processes.
The PraxisCORE runtime is included in the praxiscore
folder inside the IDE. It can be copied out and run from the CLI for networking or project running, or embedded inside a project to make it standalone.
Video support is now based on libp5x, a modularised fork of Processing that uses LWJGL for OpenGL rendering.
Audio support is now based around JAudioLibs Pipes v2, which is also available as a standalone library including all the unit generators available in PraxisCORE. (Pipes Graph replicates much of the built-in functionality of the PraxisCORE audio code).
Please report any problems at https://github.com/praxis-live/support/issues