76 lines
3.3 KiB
Markdown
76 lines
3.3 KiB
Markdown
# Creating Blocks Programmatically
|
|
|
|
This guide provides a concise overview of how to add and configure block nodes programmatically in a command-line or testing environment. This is essential for creating automated unit tests. We assume a working `App` instance is available, as set up in headless mode (see `main.cpp`).
|
|
|
|
## Process Overview
|
|
|
|
Creating and connecting a block involves several steps:
|
|
|
|
1. **Get Active Container**: Obtain a pointer to the current `RootContainer` from the `App` instance.
|
|
2. **Spawn Nodes**: Create the necessary nodes. For example, to use a `Log` block, you need to spawn the `Log` block itself and also any parameter nodes that will provide its inputs (like the file path).
|
|
3. **Configure Parameter Nodes**: Set the values for the parameter nodes you've created.
|
|
4. **Connect Nodes**: Find the corresponding input and output pins on the nodes and create a `Link` to connect them.
|
|
5. **Set Positions (Optional)**: If you plan to save the graph for visual inspection, set the node positions using `ed::SetNodePosition()`.
|
|
6. **Save Graph**: Persist the changes by calling `App::SaveGraph()`, passing the container and a file path.
|
|
|
|
## Example: Creating and Connecting a `Log` Block
|
|
|
|
The following function demonstrates adding a "Log" block, providing its required "FilePath" input via a "String" parameter node, connecting them, and saving the graph.
|
|
|
|
```cpp
|
|
#include "app.h"
|
|
#include "containers/root_container.h"
|
|
#include "blocks/parameter_node.h" // Required for ParameterInstance
|
|
|
|
// Assumes 'app' is an initialized App instance
|
|
void AddAndConnectLogBlock(App& app, const std::string& logFilePath, const std::string& savePath)
|
|
{
|
|
// 1. Get container
|
|
RootContainer* container = app.GetActiveRootContainer();
|
|
if (!container)
|
|
return;
|
|
|
|
// 2. Spawn the log block and a parameter node for the file path
|
|
Node* logNode = app.SpawnBlockNode("Log", -1);
|
|
Node* pathNode = app.SpawnParameterNode(PinType::String, -1);
|
|
if (!logNode || !pathNode)
|
|
return;
|
|
|
|
// 3. Configure the parameter node's value
|
|
pathNode->StringValue = logFilePath;
|
|
if (pathNode->ParameterInstance) {
|
|
pathNode->ParameterInstance->SetString(logFilePath.c_str());
|
|
}
|
|
|
|
// 4. Connect the nodes
|
|
// The String parameter node has one output.
|
|
Pin* pathOutputPin = &pathNode->Outputs[0];
|
|
|
|
// The Log block's 'FilePath' is its first non-flow input pin.
|
|
// Input[0] is 'Execute' (flow), Input[1] is 'FilePath'.
|
|
Pin* logInputPin = nullptr;
|
|
if (logNode->Inputs.size() > 1) {
|
|
logInputPin = &logNode->Inputs[1];
|
|
}
|
|
|
|
if (pathOutputPin && logInputPin)
|
|
{
|
|
Link newLink(app.GetNextLinkId(), pathOutputPin->ID, logInputPin->ID);
|
|
container->AddLink(newLink);
|
|
}
|
|
|
|
// 5. Set positions (optional, requires an editor context)
|
|
ed::SetNodePosition(logNode->ID, ImVec2(200.0f, 100.0f));
|
|
ed::SetNodePosition(pathNode->ID, ImVec2(0.0f, 100.0f));
|
|
|
|
// 6. Save the updated graph
|
|
app.SaveGraph(savePath, container);
|
|
}
|
|
```
|
|
|
|
This more detailed example provides a solid foundation for scripting graph creation for unit tests, ensuring that blocks are not only created but also correctly configured and connected.
|
|
|
|
## Block Reference
|
|
|
|
For a complete list of available blocks and their parameters, see the [Block Reference](./blocks.md).
|