APIC – States development guide

Best Practices — State Architecture & Usage

CRecorder – Recording Infrastructure

The CRecorder class is a static recording manager responsible for setting up configuring and controling the capturing runtime data into persistent storage. The class is globally accessible and operates as a centralized recording controller.

It provides:

  • Lifecycle control (start / stop)
  • Output path configuration
  • Frame-based flush policy
  • Change-based filtering
  • Selective streams, blocks and elements registration for recording
The recorder is designed to minimize I/O overhead and reduce redundant writes while preserving deterministic frame-aligned recording.
Design Characteristics
  • Fully static interface
  • Centralized state
  • Frame-aware flushing
  • Selective data capture
  • Optimized for high-rate systems

Public API


class CRecorder
{
public:
    static void StartRecording();
    static void StopRecording();

    static void SetRecorderPath(const char* path);
    static void SetRecordingFramesFlush(int iRecordingFlushEveryMinorFrame);
    static void SetRecordOnlyIfChanged(int bRecordOnlyIfChanged);
    static void SetRecordingProperties(const char* elementName,
                                       int64_t engSize = -1,
                                       int64_t rawSize = -1,
                                       bool bRecordOnlyIfReceived = false);
    static void AddRecordingItem(const char* itemName,
                                 int64_t engSize = -1,
                                 int64_t rawSize = -1,
                                 bool bRecordOnlyIfReceived = false);
};
    

Method Breakdown

Method Description
StartRecording() Initializes internal buffers, opens output files, and begins frame-aligned recording.
StopRecording() Stops recording, flushes remaining buffered data, and closes resources safely.
SetRecorderPath(path) Defines the directory or base path where recording files will be created.
SetRecordingFramesFlush(n) Controls how often buffers are flushed to disk (every n minor frames). Lower values increase safety, higher values improve performance.
SetRecordOnlyIfChanged(flag) Default is true, If enabled, data is recorded only when its value changes between frames, reducing file size and I/O load.
SetRecordingProperties(...) Defines metadata for a logical element. Allows explicit engineering/raw size declaration and optional “record only if received” gating.
AddRecordingItem(...) Registers a single recordable entity within the recorder configuration. The itemName represents the logical data source name (stream / block / element identifier) exactly as defined in the system.

Size Control:
  • engSize = -1 → Use the predefined engineering size as defined in the project DBSim.
  • engSize = 0 → Disable engineering value recording.
  • engSize > 0 → Record exactly the specified number of bytes for the engineering value.
The same logic applies to rawSize:
  • rawSize = -1 → Use predefined raw size as defined in the project DBSim.
  • rawSize = 0 → Disable raw value recording.
  • rawSize > 0 → Record the exact number of raw bytes specified.
Conditional Recording:
bRecordOnlyIfReceived — When enabled, the item is written only if new data was received during the current frame. This prevents recording stale or repeated values in event-driven or bus-based streams.

Recording Policy Controls

1. Frame-Based Flushing

Recording is aligned to simulation minor frames. The flush interval determines how often buffered data is committed to disk.

2. Change-Based Filtering

When SetRecordOnlyIfChanged(true) is enabled, identical consecutive values are not written again. This is especially effective for slow-changing or state-like signals.

3. Receive-Based Filtering

The bRecordOnlyIfReceived flag ensures an item is recorded only when fresh data is received during the frame, preventing duplication of stale values.

Typical Usage Flow


// Configure recorder
CRecorder::SetRecorderPath("C:/records/session1");
CRecorder::SetRecordingFramesFlush(10);
CRecorder::SetRecordOnlyIfChanged(true);

// Define properties
CRecorder::SetRecordingProperties("FlightModel", 64, 64);
CRecorder::AddRecordingItem("Altitude", 8, 8);
CRecorder::AddRecordingItem("Velocity", 8, 8);

// Start capture
CRecorder::StartRecording();

// ... simulation runs ...

CRecorder::StopRecording();
    

Best Practices

Architectural Role

CRecorder should be treated as an infrastructure service rather than a business-logic component. Modules register their items declaratively, while the recorder enforces consistent storage format and timing alignment.