Skip to main content

Function Blocks

In OneVision Scripts, function blocks are a powerful feature that allows you to define asynchronous functions and manage their execution in a structured way. A function block is similar to a function that can run asynchronously, and it provides a mechanism to handle complex operations efficiently.

Defining a function block

A function block in OneVision Scripts is defined within a block named blockName {}. This creates a sort of class-like structure some built-in methods. Additionally, function blocks can define multiple input and output variables to pass parameters and retrieve results.

block blockName {
in var inputName1: type;
in var inputName2: type;
out var outputName1: type;
out var outputName2: type;

// Function block code
}
caution

You have to specify the type of the input and output variables.

For example:

block ProcessImage {
in var imageData: Ve.Image;
in var filterType: string;
out var processedData: Ve.Shape2d;
out var processingTime: number;

console.log("Processing image...");
let startTime = Date.now();

// Simulate some async complex operation
waitTime(2000);

// Finish function block
processedData = new Ve.Shape2d();
processingTime = Date.now() - startTime;
console.log("Image processed.");
}

Calling a function block

Once defined, you can instantiate the block by calling:

processImage = new ProcessImage(); 

Methods in function blocks

Function blocks in OneVision Scripts come with five built-in methods: : run(), wait(), runWait(), isRunning() and isDone(). These methods provide different ways to control the execution of the function block, making it easier to handle asynchronous operations.

  • run(): This method starts the execution of the function block asynchronously. This call won't wait the function block to finish, so it is useful to launch multiple asynchronous tasks at the same time to parallelize their execution.

    For example, using the function block defined above:


    // Define the function block inputs
    processImage.imageData = new Ve.Image(100, 100, Ve.EPixelFormat.BGR8);
    processImage.filterType = "blur";
    // Start processing image asynchronously
    processImage.run();
  • wait(): This method waits until the function block finishes executing. It is useful for synchronizing code execution.

    For example:


    // Define the function block inputs
    processImage.imageData = new Ve.Image(100, 100, Ve.EPixelFormat.BGR8);
    processImage.filterType = "blur";
    // Start processing image asynchronously
    processImage.run();
    // Wait until the image processing is complete
    processImage.wait();
    // Retrieve the function block results
    var data = processImage.processedData;
    var time = processImage.processingTime;
  • runWait(): This method combines run() and wait() into a single call. It starts the function block execution and waits for it to finish before proceeding.

    For example, the previous example could be simplified with:


    // Define the function block inputs
    processImage.imageData = new Ve.Image(100, 100, Ve.EPixelFormat.BGR8);
    processImage.filterType = "blur";
    // Start processing image and wait until it's done
    processImage.runWait();
    // Retrieve the function block results
    var data = processImage.processedData;
    var time = processImage.processingTime;
  • isRunning(): This method checks whether the function block is currently executing, returning true if the block is being executed and false otherwise.

    For example, you can use this method to control wait methods:

    block TON{
    in var timeout: number;
    waitTime(timeout);
    }
    var ton = new TON();
    ton.timeout = 3000;
    ton.run();
    waitOff(ton.isRunning());
    console.log("Done");
  • isDone(): This method checks whether the function block has finished executing, returning true if it has and false otherwise.

    For example:

    block TON{
    in var timeout: number;
    waitTime(timeout);
    }
    var ton = new TON();
    ton.timeout = 3000;
    ton.run();
    waitOn(ton.isDone());
    console.log("Done");

Practical usage

Function blocks are particularly useful in computer vision applications where tasks like image processing, data analysis, or hardware interaction might take considerable time and need to be performed asynchronously to maintain responsiveness in the system.

For example, consider a scenario where you need to process different parts of the image with some complex analysis. Using function blocks, you can structure this workflow efficiently and perform the operations in parallel, reducing cycle time of the application:

// Define the function block processing part of an image
block ComplexProcessing {
in var image: Ve.Image;
in var roi: Ve.Rect2d;

out var result: boolean;

// Get crop
var crop = Ve.cropImage(image, roi);

// Simulate complex processing
waitTime(2000);

// Return result
result = true;
}

var proc1 = new ComplexProcessing();
var proc2 = new ComplexProcessing();
var proc3 = new ComplexProcessing();

// Pass parameters to the function blocks
var image = new Ve.Image(1000, 1000, Ve.EPixelFormat.BGR8);
proc1.image = image;
proc2.image = image;
proc3.image = image;
proc1.roi = new Ve.Rect2d(100,100,100,100);
proc2.roi = new Ve.Rect2d(300,300,100,100);
proc3.roi = new Ve.Rect2d(500,500,100,100);

// Run the three function blocks in parallel.
proc1.run();
proc2.run();
proc3.run();

// Wait for the execution of all three blocks to finish.
proc1.wait();
proc2.wait();
proc3.wait();

console.log("Complex operations finished");