Ember
Loading...
Searching...
No Matches
System Architecture

Overview

Ember follows a 4-module layered architecture: EmberCore (framework-agnostic core logic), EmberUI (shared wxWidgets UI library), EmberForge (the behavior tree editor), and EmberMonitor (the real-time behavior tree monitor). This design enables:

  • Testability: Core logic can be unit tested without UI dependencies
  • Portability: EmberCore can be used with different UI frameworks
  • Maintainability: Clear boundaries between components
  • Code Reuse: EmberUI provides shared UI components, tabs, visualization, and utilities used by both EmberForge and EmberMonitor

Component Diagram

┌─────────────────────────────────────┐ ┌─────────────────────────────────────┐
│ EmberForge │ │ EmberMonitor │
│ ┌──────────┐ ┌──────────┐ │ │ ┌──────────┐ ┌───────────┐ │
│ │ Panels │ │ Dialogs │ │ │ │ Panels │ │ Network │ │
│ │ Tabs │ │ Scenes │ │ │ │ Tabs │ │ (TCPServer│ │
│ └────┬─────┘ └────┬─────┘ │ │ └────┬─────┘ └─────┬─────┘ │
│ └──────┬──────┘ │ │ └──────┬──────┘ │
└──────────────┼───────────────────────┘ └──────────────┼─────────────────────┘
│ Uses │ Uses
┌──────────────┴─────────────────────────────────────────┴─────────────────────┐
│ EmberUI │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Components │ │ Tabs │ │Visualization│ │ Utils │ │
│ │(Panel,Side │ │(Navigator, │ │(TreeCanvas, │ │(DPI,Layout,│ │
│ │ Panel,Dlg) │ │Properties) │ │StatusOverlay│ │Proportional│ │
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
│ ┌────────────┐ │
│ │ Interfaces │ │
│ │(ITab,IPanel│ │
│ │ IScene) │ │
│ └────────────┘ │
└──────────────────────────────────────┬───────────────────────────────────────┘
│ Uses
┌──────────────────────────────────────┴───────────────────────────────────────┐
│ EmberCore │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Core │ │ Parsers │ │ Adapters │ │ Network │ │
│ │ (Node, Tree,│ │(LibXML, XML │ │(DirectTree, │ │(Codec,Build,│ │
│ │ Blackboard) │ │ Serializer) │ │ NodeAdapter)│ │TCPTreeAdapt)│ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Interfaces │ │ Types │ │ Utils │ │
│ │(ITreeNode, │ │(Color, Rect,│ │ (Logger, │ │
│ │ITreeFactory)│ │ String) │ │SpdlogManager│ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘

EmberCore

EmberCore is the framework-agnostic core library containing all behavior tree logic. It has no dependencies on wxWidgets or any GUI framework.

Core Module

The Core module contains the fundamental data structures:

Class Purpose
Node Represents a single behavior tree node
BehaviorTree Container for a complete behavior tree with metadata
BehaviorTreeValidator Validates tree structure and constraints
BlackboardEntry Key-value storage for tree communication
Blackboard Collection of blackboard entries

Parsers Module

The Parsers module handles XML serialization:

Class Purpose
LibXMLBehaviorTreeParser Parses XML files into behavior trees
LibXMLBehaviorTreeSerializer Serializes trees back to XML
ParserConfig Configuration for parsing behavior
ParserProfile Named configuration presets
ConfigManager Manages parser configurations
BehaviorTreeProject Multi-file project management
ProjectManager Singleton for active project handling

Adapters Module

The Adapters module provides an abstraction layer between core data and visualization:

Class Purpose
ITreeNode Abstract interface for tree nodes
ITreeStructure Abstract interface for tree traversal
ITreeFactory Factory interface for node creation
DirectTreeAdapter Adapts BehaviorTree to ITreeStructure
NodeAdapter Adapts Node to ITreeNode

Interfaces Module

Pure virtual interfaces for extensibility:

Interface Purpose
ITreeNode Node access abstraction
ITreeStructure Tree structure abstraction
ITreeFactory Node creation abstraction
IParseProgressCallback Progress reporting for parsing

Types Module

Framework-agnostic type definitions:

Type Purpose
String std::string alias
Point 2D point (x, y)
Size 2D dimensions (width, height)
Rect Rectangle (position + size)
Color RGBA color representation

Utils Module

Utility classes:

Class Purpose
Logger Logging infrastructure
SpdlogManager spdlog integration (optional)

EmberUI

EmberUI is the shared wxWidgets UI library extracted from EmberForge. It provides reusable UI components, tabs, visualization, and utility classes used by both EmberForge and EmberMonitor.

Interfaces Module

Pure virtual interfaces for UI extensibility:

Interface Purpose
ITab Tab interface for panel content
IPanel Panel interface for dockable workspace areas
IScene Scene interface for visualization surfaces

Components Module

Reusable UI building blocks:

Class Purpose
Panel Base panel class for all dockable panels
SidePanel Tabbed side panel using wxAuiNotebook
ScalableDialog DPI-aware dialog base class

Tabs Module

Shared tab implementations:

Class Purpose
NavigatorTab Tree list with hierarchy view and search
PropertiesTabBase Shared property editor base class
TreeHierarchyTab Tree hierarchy view

Visualization Module

Shared visualization components:

Class Purpose
TreeCanvas Shared tree rendering canvas
StatusOverlay IStatusProvider + StatusColors for node status coloring

Utils Module

Shared UI utilities:

Class Purpose
DPI DPI scaling helpers
LayoutConstants Shared layout constants
ProportionalLayout Proportional AUI pane sizing

EmberForge

EmberForge is the wxWidgets-based GUI application that provides the visual editor for Ember. Panel, SidePanel, ITab, IScene, and visualization base classes have moved to EmberUI; EmberForge contains only Forge-specific subclasses and extensions.

Application Module

Class Purpose
App wxApp subclass, application entry point
MainFrame Main window, manages layout and menus

Panels Module

Forge-specific dockable panels:

Class Purpose
MainPanel Central panel containing scenes
LeftSidePanel Left dock (file explorer, hierarchy)
RightSidePanel Right dock (properties)
BottomPanel Bottom dock (logs, output)

Tabs Module

Forge-specific tab components:

Class Purpose
FileExplorerTab File browser tab
PropertiesTab Forge subclass of PropertiesTabBase
LogTab Log message viewer
ToolTab Tool palette

Scenes Module

Scene system for tree visualization:

Class Purpose
IScene Scene interface
BehaviorTreeScene Behavior tree visualization scene
SceneContainer Manages multiple scenes
TreeVisualization Canvas for rendering trees

Dialogs Module

Modal dialogs:

Class Purpose
PreferencesDialog Application preferences
ParserConfigDialog Parser configuration
BehaviorTreeProjectDialog Project management
ProjectManagerDialog Project selection
LoadingDialog Progress indicator

Utils Module

UI utilities:

Class Purpose
AppPreferences Persistent application settings
BehaviorTreeConfig Tree visualization settings
WxConverters Type conversion utilities
CustomTabArt Custom tab appearance

EmberMonitor

EmberMonitor is the real-time behavior tree monitoring application that receives tree data over TCP from a running client.

App Module

Class Purpose
MonitorApp wxApp entry point
MonitorFrame Main frame with AUI layout, TCP server, tree builder, state manager

Network Module

Class Purpose
TCPServer Single-client TCP server for receiving behavior tree data

Panels Module

Class Purpose
ConnectionPanel Connection management UI
MainPanel Central panel with MonitorTreeCanvas and search
RightSidePanel Right tabbed panel with navigator and properties

Tabs Module

Class Purpose
MonitorNavigatorTab Monitor navigator with live status refresh
PropertiesTab Read-only properties with status

Visualization Module

Class Purpose
MonitorTreeCanvas Tree canvas with status coloring and connection overlay

Data Flow

Loading a Behavior Tree

1. User selects File > Open
2. MainFrame calls LibXMLBehaviorTreeParser::ParseFile()
3. Parser returns ParseResult with BehaviorTree
4. MainFrame creates DirectTreeAdapter wrapping the tree
5. BehaviorTreeScene receives the adapter
6. TreeVisualization renders via ITreeStructure interface

Editing a Node

1. User selects node in TreeVisualization
2. Selection callback notifies MainFrame
3. MainFrame updates PropertiesTab with node data
4. User edits property in PropertiesTab
5. PropertiesTab updates Node via ITreeNode interface
6. TreeVisualization refreshes display

Saving a Project

1. User selects File > Save Project
2. MainFrame calls ProjectManager::SaveProject()
3. ProjectManager iterates project files
4. LibXMLBehaviorTreeSerializer writes each file
5. Project configuration saved to JSON

Monitor Data Flow

Receiving a Behavior Tree (TCP)

1. Client connects to TCPServer
2. Handshake is performed
3. Client sends TreeInit message
4. TreeBuilder constructs BehaviorTree from the message
5. TCPTreeAdapter wraps the BehaviorTree
6. MonitorTreeCanvas renders the tree

Tick Updates

1. Client sends TickUpdate message
2. StateManager applies state changes to nodes
3. RefreshStatus updates hierarchy icons
4. TreeCanvas repaints with status colors

Design Patterns

Adapter Pattern

The Adapters module implements the Adapter pattern to decouple EmberCore data structures from visualization code. This allows the same visualization code to work with different tree implementations. DirectTreeAdapter adapts XML-parsed trees, while TCPTreeAdapter adapts trees received over TCP.

Factory Pattern

ITreeFactory and DefaultTreeFactory implement the Factory pattern for creating tree nodes, enabling customization of node creation.

Singleton Pattern

ConfigManager and ProjectManager use the Singleton pattern for global access to configuration and project state.

Observer Pattern

Event callbacks (NodeSelectionCallback, TreeSelectionCallback) implement a simplified Observer pattern for UI updates.

Template Method Pattern

Panel and SidePanel use the Template Method pattern with virtual hooks (CreateLayout, CreateToolbar) for customization by subclasses.

Thread Safety

EmberCore is designed for single-threaded use. All UI operations in EmberForge occur on the main thread. Background operations (like parsing large files) should use wxWidgets threading primitives and communicate results via events.

EmberMonitor's TCPServer uses non-blocking sockets polled from the main thread via a timer, so all processing remains on the UI thread.

See Also