Ember
Loading...
Searching...
No Matches
Parser System

Overview

Ember's parser system handles reading and writing behavior tree XML files. Built on libxml2, it provides robust parsing with extensive configuration options to support different XML formats.

Core Classes

LibXMLBehaviorTreeParser

The main parser class for reading XML files into behavior trees.

auto result = parser.ParseFile("behavior_tree.xml");
if (result.success) {
auto tree = result.tree;
// Use the tree...
} else {
for (const auto& error : result.errors) {
std::cerr << error.message << std::endl;
}
}
Thread-safe XML parser using libxml2 for behavior tree files.

Key Methods

Method Description
ParseFile(path) Parse a single XML file
ParseFromString(xml) Parse XML from string
ParseMultipleFiles(paths) Parse multiple files as project
SetConfig(config) Set parser configuration
SetProgressCallback(cb) Set progress reporting callback

LibXMLBehaviorTreeSerializer

Serializes behavior trees back to XML format.

bool success = serializer.SerializeToFile(tree, "output.xml");
XML serializer using libxml2 for behavior tree files.
bool SerializeToFile(std::shared_ptr< BehaviorTree > tree, const EmberCore::String &filepath)
Serialize behavior tree to file.

Features

  • Preserves comments and formatting
  • Maintains attribute order
  • Supports custom indentation
  • Round-trip safe (parse → serialize → parse yields same tree)

Parser Configuration

ParserConfig

ParserConfig controls parsing behavior with extensive options.

// Element names
config.root_element_name = "root";
config.tree_element_name = "BehaviorTree";
config.tree_id_attribute = "ID";
// Blackboard settings
config.blackboard_element_name = "Blackboard";
config.blackboard_entry_element = "Entry";
// Parsing options
config.preserve_whitespace = true;
config.validate_structure = true;
config.allow_unknown_nodes = false;
Configuration for XML parser behavior and element/attribute mappings.

Configuration Categories

Category Settings
Element Names Root, tree, node element names
Attributes ID, name, type attribute names
Blackboard Blackboard and entry element names
Validation Structure validation, unknown node handling
Formatting Whitespace, comment preservation

ParserProfile

ParserProfile wraps a ParserConfig with metadata for preset management.

profile.SetName("BehaviorTree.CPP v4");
profile.SetDescription("Standard BTCPP format");
profile.SetConfig(config);
// Save to JSON
profile.SaveToFile("btcpp_v4.json");
A named parser configuration profile with metadata.
void SetName(const String &name)
void SetConfig(const ParserConfig &config)
void SetDescription(const String &description)
bool SaveToFile(const String &filepath) const

Built-in Profiles

Profile Description
Default BehaviorTree.CPP v4 format
Generic Flexible format for custom schemas
Legacy BehaviorTree.CPP v3 compatibility

ConfigManager

Singleton managing parser profiles.

// Get available profiles
auto names = manager.GetProfileNames();
// Load a profile
auto profile = manager.GetProfile("Default");
// Create custom profile
manager.AddProfile(myProfile);
manager.SaveProfiles();
static ConfigManager & GetInstance()

Multi-File Projects

BehaviorTreeProject

Manages multiple XML files as a cohesive project.

// Add files
project.AddFile("main.xml");
project.AddFile("subtrees/combat.xml");
project.AddFile("subtrees/navigation.xml");
// Set main entry point
project.SetMainTree("main.xml", "MainBehavior");
// Validate project
auto report = project.Validate();
if (!report.is_valid) {
for (const auto& issue : report.issues) {
std::cerr << issue.message << std::endl;
}
}
Represents a BehaviorTree project containing multiple XML resources.

Project Features

  • Cross-file SubTree references: Reference trees in other files
  • Shared blackboards: Define blackboards accessible across files
  • Dependency tracking: Automatic detection of file dependencies
  • Validation: Check for missing references, circular dependencies

ProjectManager

Singleton for managing the active project.

// Create new project
pm.CreateProject("MyProject", "/path/to/project");
// Open existing project
pm.OpenProject("/path/to/project.emberproj");
// Save current project
pm.SaveProject();
// Check project state
if (pm.HasActiveProject()) {
auto path = pm.GetActiveProjectPath();
}
static ProjectManager & GetInstance()

Parse Results

ParseResult

Result structure from parsing operations.

struct ParseResult {
bool success;
std::shared_ptr<BehaviorTree> tree;
std::vector<ParseError> errors;
std::vector<ParseError> warnings;
// Metadata
std::string file_path;
double parse_time_ms;
};

ParseError

Error information from parsing.

struct ParseError {
std::string message;
std::string file;
int line;
int column;
ErrorSeverity severity; // Error, Warning, Info
};

Progress Reporting

For large files or multi-file projects, implement IParseProgressCallback:

class MyProgressCallback : public EmberCore::IParseProgressCallback {
public:
bool OnProgress(float progress, const std::string& message) override {
std::cout << (int)(progress * 100) << "% - " << message << std::endl;
return true; // Return false to cancel
}
};
MyProgressCallback callback;
parser.SetProgressCallback(&callback);
Callback interface for reporting parsing progress.
virtual bool OnProgress(const String &message, int current, int total)=0
Called to report progress during parsing.
void SetProgressCallback(IParseProgressCallback *callback)

XML Format Details

Standard Structure

<?xml version="1.0" encoding="UTF-8"?>
<root BTCPP_format="4">
<!-- Tree definitions -->
<BehaviorTree ID="MainTree">
<Sequence>
<Action ID="SomeAction"/>
</Sequence>
</BehaviorTree>
<!-- Node type definitions -->
<TreeNodesModel>
<Action ID="SomeAction">
<input_port name="param" type="string"/>
</Action>
</TreeNodesModel>
</root>

Blackboard Definitions

<root BTCPP_format="4">
<!-- Shared blackboard -->
<Blackboard>
<Entry key="target" type="Position" access="read_write"/>
<Entry key="health" type="int" default="100"/>
</Blackboard>
<BehaviorTree ID="MainTree">
<!-- Tree content -->
</BehaviorTree>
</root>

SubTree References

<!-- In main.xml -->
<BehaviorTree ID="MainTree">
<Sequence>
<SubTree ID="CombatTree"/>
<SubTree ID="subtrees/patrol.xml::PatrolTree"/>
</Sequence>
</BehaviorTree>
<!-- Same-file reference: just ID -->
<!-- Cross-file reference: file::TreeID -->

Error Handling

Common Parse Errors

Error Cause Solution
Missing root element No <root> tag Add root element
Unknown node type Unregistered node Add to TreeNodesModel or enable unknown nodes
SubTree not found Missing referenced tree Add tree or fix reference
Circular dependency SubTree loop Break the cycle
Invalid blackboard type Type mismatch Fix type declaration

Handling Errors

auto result = parser.ParseFile("file.xml");
if (!result.success) {
for (const auto& error : result.errors) {
switch (error.severity) {
case ErrorSeverity::Error:
LOG_ERROR("Parse", error.message);
break;
case ErrorSeverity::Warning:
LOG_WARNING("Parse", error.message);
break;
}
}
}
#define LOG_ERROR(category, message)
Definition Logger.h:116
#define LOG_WARNING(category, message)
Definition Logger.h:115

See Also