Crate translator_docs

Source
Expand description

§Writing a Surfer Translator Plugin

Surfer translators are web-asssembly binaries that are loaded at runtime by Surfer. They can be written in any language that has an extism plugin development kit https://extism.org/docs/concepts/pdk/.

For this example we will use Rust since that is what the rest of Surfer is written in, which allows us to reuse type definitions between Surfer itself and the plugin.

To create a plugin, create a new project

cargo init --lib cool_surfer_translator

then modify the Cargo.toml to set the library type to “cdylib”, and add the extism_pdk and surfer-translation-types library as dependencies

[lib]
crate-type = ["cdylib"]

[dependencies]
extism-pdk = "1.4.1"
surfer-translation-types.git = "https://gitlab.com/surfer-project/surfer.git"

In your new project, you now need to define a few functions which must all be annotated with #[plugin_fn] and have the right type signature. Click on each function to learn more

  • new: initializes the plugin
  • name: sets the name of the plugin in the format selection list
  • translates: allows the plugin to opt in or out of translating certain signals
  • variable_info: specifies the hierarchical structure of the signal
  • translate: does the actual translation of bit vectors to new values

In addition, there are a few optional functions that can be implemented for additional functionality

  • reload: Called when Surfer reloads the waveform
  • set_wave_source: Called when the current waveform changes

§Accessing Files

Surfer plugins are sandboxed and are in general not allowed any access to the external world. Translators may need to read the file system however, and for that, “host functions” are provided. To use them, define them in your plugin using

use extism_pdk::host_fn;

#[host_fn]
extern "ExtismHost" {
    pub fn read_file(filename: String) -> Vec<u8>;
    pub fn file_exists(filename: String) -> bool;
}

§Maintaining State

Plugins may need to maintain state between calls. This can be done by simply using static variables in the plugin.

static STATE: Mutex<bool> = Mutex::new(false)

NOTE: The static variables are shared between all “instances” of the translator, i.e. if you want to maintain different state for different variables, this must currently be handled on the plugin side.

§Testing and Installation

To build your plugin, call

cargo build --debug --target wasm32-unknown-unknown

which will create target/debug/cool_surfer_translator.wasm

This file can then be copied to the local or global plugin translator directories in order to be found and automatically loaded by Surfer

Local:

.surfer/translators/

Global

OsPath
Linux~/.config/surfer/translators.
WindowsC:\Users\<Name>\AppData\Roaming\surfer-project\surfer\config\translators.
macOS/Users/<Name>/Library/Application Support/org.surfer-project.surfer/translators

Modules§

optional
Documentation for functions which are not necessary for a basic translator but can do more advanced things.

Functions§

name
Returns the name of the plugin as shown to the user. This needs to be unique, so do not set it to a translator name that is already present in Surfer.
new
The new function is used to initialize a plugin. It is called once when the plugin is loaded
translate
Gets called once for every value of every signal being rendered, and returns the corresponding translated value.
translates
Returns a translation preference for the specified variable, which allows the translator to opt out of translating certain signals which it does not support.
variable_info
Returns information about the hierarchical structure of the signal. For translators which simply want to do bit vector to string and/or color translation, returning [VariableInfo::Bits] is sufficient.