> For the complete documentation index, see [llms.txt](https://stage-precision.gitbook.io/grid/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://stage-precision.gitbook.io/grid/touch-designer-integration/point-cloud-interaction/react-to-active-and-inactive-points.md).

# React to active and inactive points

Create a graphic when a point becomes active and remove it when the point   becomes inactive using the SPNet Events DAT.

This example creates one text graphic for each active point. When a point becomes inactive, its graphic is removed.

The graphics form a simple overview of the active point IDs. A short DAT Execute script connects the incoming events to these actions.

Use the SPNet Data CHOP for continuous positions and movement. The Events DAT provides the transitions used to trigger actions.

### 1. Prepare Grid Studio

Use the Volume and Test Map Input from the previous examples.

Keep the SPNet Sender stopped while building this example. Start it after the event handler is ready so the initial active events are processed.

### 2. Add the SPNet Events DAT

In `/project1`:

1. Add **SPNet Events** from the Custom operators.
2. Rename it to `point_events`.
3. On its **Data** page, configure:

| Parameter   | Value    |
| ----------- | -------- |
| Data Type   | `Points` |
| Output Mode | `Events` |
| Timeout ms  | `1000`   |

On its **Connection** page, use:

| Parameter         | Value          |
| ----------------- | -------------- |
| Port              | `37373`        |
| Bind Address      | `0.0.0.0`      |
| Multicast Group   | `237.37.37.37` |
| Interface Address | `0.0.0.0`      |

On the **Events** page, set **Event History** to `256`.

#### Understand the event rows

| Column     | Purpose                                                               |
| ---------- | --------------------------------------------------------------------- |
| `event_id` | Identifies one transition.                                            |
| `event`    | Contains `active` or `inactive`.                                      |
| `key`      | Identifies the object, for example `point:7`.                         |
| `type`     | Contains `point` for this example.                                    |
| `id`       | The point's numeric ID.                                               |
| `reason`   | Explains the transition, such as `appeared`, `removed`, or `timeout`. |

An active event is generated when a point appears in the received data. An inactive event is generated when it disappears or the connection reaches the configured timeout.

{% hint style="info" %}
Events remain in the table as history. Process each event\_id once to avoid repeating actions when another event changes the table.
{% endhint %}

### 3. Create the graphic template

In `/project1`:

1. Create a **Text TOP** named `point_template`.
2. Set its Text to `Point`.
3. Use a resolution such as `256 × 128`.
4. Choose a readable font size and style.

The script copies this template and sets the text to the corresponding point ID.

### 4. Prepare the output

Create these nodes in `/project1`:

| Node         | Name             | Purpose                                            |
| ------------ | ---------------- | -------------------------------------------------- |
| Base COMP    | `point_graphics` | Contains the generated text graphics.              |
| Constant TOP | `empty`          | Supplies an empty image when no points are active. |
| Layout TOP   | `point_layout`   | Combines the generated graphics into one image.    |

Set the Constant TOP's color to black and its alpha to `0`.

On the Layout TOP:

1. Set **TOP** to `/project1/empty`.
2. Set its output resolution to a fixed size such as `1280 × 720`.

The script updates the TOP field as graphics appear and disappear.

### 5. Add the event handler

Create a **DAT Execute DAT** named `point_actions`.

Keep it inactive while editing, then configure:

| Parameter    | Value                    |
| ------------ | ------------------------ |
| DAT          | `/project1/point_events` |
| Table Change | `On`                     |
| Execute      | `End of Frame`           |

Disable the deprecated Row Change, Column Change, Cell Change, and Size Change options.

Replace the DAT Execute's contents with:

```python
def onTableChange(dat, prevDAT, info):
    if dat[0, 'event_id'] is None:
        return

    container = op('point_graphics')
    template = op('point_template')
    layout = op('point_layout')
    seen = set(me.fetch('seen_events', []))
    current_ids = set()

    for row in range(1, dat.numRows):
        event_id = dat[row, 'event_id'].val
        current_ids.add(event_id)
        if event_id in seen or dat[row, 'type'].val != 'point':
            continue

        point_id = str(int(dat[row, 'id'].val))
        name = 'point_' + point_id
        graphic = container.op(name)
        event = dat[row, 'event'].val

        if event == 'active':
            if graphic is None:
                graphic = container.copy(
                    template, name=name, includeDocked=False)
            graphic.par.text = 'Point ' + point_id
        elif event == 'inactive' and graphic is not None:
            graphic.destroy()

        seen.add(event_id)

    me.store('seen_events', list(seen & current_ids))
    paths = sorted(node.path for node in container.children
                   if node.name.startswith('point_'))
    layout.par.top = ' '.join(paths) if paths else op('empty').path
    return
```

Enable **Active** on `point_actions` after all nodes and the script are ready.

#### What the script does

For each new point event:

* **Active:** Copies the Text TOP template into `point_graphics` and assigns the point ID.
* **Inactive:** Removes the graphic associated with that ID.

The script remembers processed event IDs and keeps that list bounded to the retained event history.

After processing the events, it updates the Layout TOP. When no graphics remain, the layout displays `empty`.

### 6. Test the events

Start the SPNet Sender in Grid Studio and view `point_layout`.

With three generated points, you should see three graphics showing their IDs.

Try these changes:

| Action in Grid Studio | Expected result                                                          |
| --------------------- | ------------------------------------------------------------------------ |
| Increase Point Count  | Graphics appear for newly active IDs.                                    |
| Reduce Point Count    | Graphics are removed for IDs that disappear.                             |
| Move existing points  | Their graphics remain present.                                           |
| Stop the SPNet Sender | Graphics are removed when the connection reaches the one-second timeout. |
| Restart the sender    | Graphics appear for the received points.                                 |

You can inspect the generated Text TOPs inside `point_graphics` and the corresponding transitions in `point_events`.

### Repeating the test

Keep the DAT Execute active while stopping and restarting the sender so it can process both inactive and active transitions.

**Clear Events** clears the retained event log. It leaves current point membership unchanged and does not generate new active events for points already present.

### Build your own actions

The active and inactive branches are the places to add your own behavior.

For example, an active event could start an animation or timer. An inactive event could begin an exit animation before the graphic is removed.

Use the point ID or key to associate each action with the correct point.
