The BLOCKS SDK
Discovering BLOCKS

Any BLOCKS application would be pretty limited without the ability to discover the BLOCKS that are connected to your computer.

This page gives an overview of the classes and methods available to aid BLOCKS discovery and provides sample code for getting notifications of any connections or disconnections.

The BlockTopology object

Groups of connected Lightpad and Control Blocks are described by a BlockTopology.

A BlockTopology contains an array of references to Block objects, which provide access to Lightpad and Control Block functionality, and an array of BlockDeviceConnection objects, which describe the connections between devices. Once you have a BlockTopology you have all the information required to visualise and interact with your Lightpads and Control Blocks. For more information about using Block objects see the The Block object section.

For Lightpads and Control Blocks a BlockTopology can be obtained from a PhysicalTopologySource.

The PhysicalTopologySource object

The current topology is provided by a PhysicalTopologySource. When instantiated, a PhysicalTopologySource monitors for any connections from your computer to any Lightpad and Control Blocks and the PhysicalTopologySource::getCurrentTopology() method returns the current BlockTopology.

In an environment where Lightpad and Control can be connected and disconnected dynamically it is convenient to register your code for topologyChanged() callbacks from a PhysicalTopologySource. Then, when the current BlockTopology changes, your application is able to react to the new configuration. You can do this by inheriting from the TopologySource::Listener class and registering as a listener to a PhysicalTopologySource object. When you inherit from TopologySource::Listener you must override the pure virtual method TopologySource::Listener::topologyChanged(), which is then called by a PhysicalTopologySource on topology changes when you register as a listener. A simple example is shown below.

BlockFinder.h:

/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include <BlocksHeader.h>
// Monitors a PhysicalTopologySource for changes to the connected BLOCKS and
// prints some information about the BLOCKS that are available.
class BlockFinder : private juce::TopologySource::Listener
{
public:
// Register as a listener to the PhysicalTopologySource, so that we receive
// callbacks in topologyChanged().
BlockFinder();
private:
// Called by the PhysicalTopologySource when the BLOCKS topology changes.
void topologyChanged() override;
// The PhysicalTopologySource member variable which reports BLOCKS changes.
juce::PhysicalTopologySource pts;
};

BlockFinder.cpp:

/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "BlockFinder.h"
using namespace juce;
BlockFinder::BlockFinder()
{
// Register to receive topologyChanged() callbacks from pts.
pts.addListener (this);
}
void BlockFinder::topologyChanged()
{
// We have a new topology, so find out what it isand store it in a local
// variable.
BlockTopology currentTopology = pts.getCurrentTopology();
Logger::writeToLog ("\nNew BLOCKS topology.");
// The blocks member of a BlockTopology contains an array of blocks. Here we
// loop over them and print some information.
Logger::writeToLog (String ("Detected ") + String (currentTopology.blocks.size()) + " blocks:");
for (auto& block : currentTopology.blocks)
{
Logger::writeToLog (String(" Description: ") + block->getDeviceDescription());
Logger::writeToLog (String(" Battery level: ") + String (block->getBatteryLevel()));
Logger::writeToLog (String(" UID: ") + String (block->uid));
Logger::writeToLog (String(" Serial number: ") + block->serialNumber);
}
}

When instantiated this class simply monitors for changes to the connected Lightpad and Control Blocks and prints some information about them to stdout. Once you have the current BlockTopology object you have access to the available Block objects and can start to interact with them. A more complex application would probably do much more in the topologyChanged() method—see the Example Applications page.

The Block object

A Block object is the main entry point for communicating between your application and any Lightpad and Control Blocks that are connected to your computer.

All the different Block types are subclasses of Block so they provide the same interface (see the Block class documentation). About half of the Block public member functions return information about the physical device it represents. In the example code above you can see that we use some of these methods to query each Block about its current status. The more interesting Block methods return pointers to objects you can use to control and receive events from individual BLOCKS. More detail about these methods can be obtained from the following pages:

Getting touch events

Getting control button events

Controlling LED grids

Controlling LED strips