Accessing Simulator Data and Sharing Data with Plugins

About Data Access

The data access API allows the sharing of data with X-Plane as well as other plugins.  The most common use of the data access APIs is to read data from X-Plane and change the values within X-Plane.  Plugins may also publish their own data, and read/write/share data with other plugins.

The data access APIs are the main interface to smulator data as well as some of the simpler simulator sub-systems.  For example, to control the weather in X-Plane, we simply write new weather values into the weather variables within the sim.  Subsystems that require more complex interaction have their own APIs.

The X-Plane plugin SDK gives access to hundreds of data references; a separate document contains the comprehensive list.

About Data References

A data reference is an opaque handle to a single variable within X-Plane or another plugin.  We may think of a data reference as a variable, or as an object that represents a value.  All of the communication with X-Plane takes place by reading and writing data references.

Data references exist to insulate plugins from X-Plane's internal data.  When we read a data reference, code inside X-Plane provides the value of the dataref.  If in the future the layout of the internal variables in X-Plane changes, the same data references may be used to access the new variables.

Data references are opaque handles whose values are unique within a single run of X-Plane but may change between runs.  For this reason we do not hard code the data references we use.  Instead we find them by calling a data access function and passing in the data reference's name.  The data reference's  name is a string that is globally unique to the data reference and does not change between runs of X-Plane.  Data reference names are hierarchial and picked to describe the data reference, e.g. "/sim/cockpit/radios/com1_frequency_hz".

Data Reference Types

Data references are typed; each data reference can be read in one or more formats.  Data references are defined via distinct bits in an enumeration; we can add them together to form sets of datatypes.

We must read a data type in its supported format; we will get back a default value (such as 0 or no data) if we read a data reference in an unsupported type.  We can inquire about a data reference's type at runtime or check the documentation for its type.

Data Reference Resolution

Every data reference has a unique string name.  In order to read a variable within X-Plane, we need its data reference.  To get its data reference, we pass the name of the data reference to the X-Plane Plugin Manager.  The X-Plane plugin Manager then returns a data reference for that variable that is good for the duration of the simulator's operation.

Do not ever save data references themselves.  For example, do not save a data reference to disk as a preference; the same variable will have a different data reference value the next time the simulator runs.  Instead, save the string name of the data reference.

Resolve data reference names to data references once when the plugin is initialized; it is faster to read a data reference than to find a data reference by name and then read it.

Reading and Writing Data References

A number of accessors are provided to read and write data references.  For each data reference type an accessor exists to read and write the data reference.  Writes to a data reference that is not writable, is invalid, or does not support that data type do nothing.  Reads from a data reference that is invalid or does not support that type returns 0 or no data.

Data Type Coersion

Some data references may have mutliple types.  If a data reference is published with multiple types, always read the most precise form published.  (For example, read the double-precision version rather than the single precision or integer version.)

Simulator Data References

X-Plane publishes hundreds of data references covering all parts of the simulator.  They are all named with the convention /sim/subsystem... in a hierarchial manner.  A separate HTML document covers the list of simulator data references in depth.

Simulator data references are generally very quick to read and write, but try to avoid unnecessary extra reading and writing; it's quicker to save a read as a local variable than to read it twice, for example.

Plugin Data References

Plugins may also create data references.  Plugin data references operate identically to simulator data references to other plugins, but will only be available when the plugin is installed.  If a plugin is disabled, the results of reading and writing its data reference is the same as if the data reference is invalid.

Publishing Owned Data

Plugins can publish internal data that they own as data references.  A plugin publishes data by providing a callback that provides the current value of the data reference, and optionally a callback that can change the value of the data reference (if the data reference is writable).

Plugins provide one 'read' callback (and optionally one 'write' callback) for each data type they support.  Multiple datatypes are supported via multiple callbacks.  If a data reference is writable, it must be writable via every data type.

Multiple data types are provided for backward compatbility; it allows a plugin to increase the resolution of a data reference (from int to float to double precision) while still supporting legacy clients.  Do not use multiple data types as a 'convenience' to clients; clients should know what the data type is and read it using the preferred format.

Owned data is 'owned' by exactly one plugin.  The owner gets notifications when any other plugin reads and writes the data; other plugins must poll for the current data value.  The advantage of publishing owned data is that the owner may represent the data internally in any form; the disadvantage is that clients cannot receive notifications when the data changes.

Publishing Shared Data

Shared data publishing overcomes two limitations of publishing owned data, but places a higher burdon on plugins.  
  1. Clients may 'subscribe' to shared data, receiving a notification whenever it changes.
  2. Multiple clients may publish the data reference and only one common copy is created.
To understand this second case, consider a number of plugins that simulate an advanced electrical system.  Each one might need access to a number of sim values.  Which plugins should own the data?  What if the wrong plugins are installed or only some are running?

With shared data, each plugin publishes the data it wants to share and receives notifications when it changes.  The memory for the data reference is stored inside the X-Plane plugin manager; each plugin uses the accessors to change the data reference.  Plugins receive a callback when the common data is changed, but cannot have direct access to the memory.

Using the Data Access APIs

This section describes some typical uses of the data reference APIs.

Using Simulator Data References

The typical use of the data access APIs is to communicate with X-Plane.

Finding a Data Reference

To find a data reference, we resolve it based on its name.

<code snippet: using XPLMFindDataRef to resolve a data reference.>

Reading from a Data Reference

Accessor functions are provided to read data references.  Use the XPLMGetData___ routine that serves the data type we are working with.

<code snippet: logging a data reference using XPLMGetDatai.

Writing to a Data Reference

If a data reference is writable, we may use the XPLMSetData___ routines to write data back to the simulator.

<code snippet: setting some cockpit junk>

Getting Information About a Data Reference

We can determine whether a data reference is valid, what types it serves, and whether it is writable.

<code example, dumping data ref info>

Sharing Plugin Data

Accessing data shared by other plugins is identical to reading simulator data above.

Publishing an Owned Data Reference

To share an owned data reference, we must first write accessors to read and write the data reference.  One accessor may serve multiple variables via a callback; use the refcon passed with the variable to distinguish them.

< code listing: accessors for an internal variable.>

Register the data accessors on startup and unregister them when the plugin shuts down.

<code listing: startup and shutdown>

Publishing a Shared Data Reference

To publish a shared data reference, provide an accessor function for when the data reference is modified and register it.

< code example: notifier and shared data >

To change the data reference, use the XPLMSetData___ APIs.
NOTE: the notifier will be called when we set the data reference.

Data Access API Reference

Further reference for the data access API is provided in the API references section.

A complete list of all data references published by X-Plane is available in a separate document.