AboutSharedDataRefs

From X-Plane SDK
Jump to: navigation, search

Shared vs non-shared datarefs could be the most confusing abstraction in the SDK. What follows is an explanation of the infrastructure.

(Please remember that in the dataref world, x-plane is just another big fat plugin that is loaded before yours and barfs up about 3100 datarefs when it starts up.)

Owned DataRefs

The normal dataref sharing model has an "owner" (the plugin that registers the dataref). And the relationship between the owner and every other member of the plugin system is asymetric: the "owner" of the dataref receives a callback when the dataref is written to; therefore it does not need to "poll" the dataref to detect changes, and can execute one-time actions on write. (For example, the autopilot state dataref "pushes buttons" when you write to it.) By comparison every other plugin must poll the dataref and try to detect changes. If several plugins during a drawing phase write to the dataref, an observing plugin might not see every change!

In other words, for most plugins, normal datarefs are polled, they aren't event driven. This design decision really comes from the sim itself...x-plane writes to its data all over the place in the process of flight calculations and doesn't provide any notifications; putting a "subscription" system where a plugin could get a callback on all writes to dataref X would have been very expensive - even if x-plane's behavior were more well-defined (it's actually pretty understandable) the messaging costs would be huge. So we have the current system where you have to check for changes but the tons of dataref writes that happen in normal sim operation are free.

Motivation

Imagine a series of related small plugins that all want to extend the sim in the same way...for example, at one point we had X-pushback and Benedikt's 737 sharing the notion of whether the external power source is hooked up to the sim. One way to program this would be for each plugin to check for a dataref, and register it if it isn't already present.

There is one limitation to this solution: depending on load order, sometimes you own a dataref (and get notifies on change) and sometimes you don't (and have to poll). In other words, you can't share a dataref between two plugins AND get events as if you were the owner in both plugins.

Solution

So we created "Shared" datarefs. With the shared dataref API (which is different from the reguler XPLMRegisterDataAccessor) you don't get to own the local storage of the dataref EVER but you do get a notification of writes to the dataref EVERY time. So basically every plugin that creates a shared dataref is really subscribing to a dataref which is managed by the XPLM.

Generally you should only use shared datarefs if:

  • You are using a simple format like int -- it doesn't work for binary data, and
  • The dataref is needed by 2 or more plugins that may or may not be running at the same time and
  • More than one plugin needs an event-based notification when the dataref changes.

Shared datarefs do also provide all the functionality of regular datarefs (except that you don't get to own the data in memory), so you could use them even when you don't need event-based notification; it is just my personal opinion that shared datarefs should only be used in multilateral sharing situations.

Shared datarefs are written entirely on top of the regular dataref API - you could code them yourself in a DLL - the only thing we do that you can't is (1) translate Mach-O CFM on Mac and (2) allow the dataref to persist after your plugin is unloaded. (Shared datarefs can be thought of as being "owned" by the XPLM itself, getting around the unload-cleanup code.)