Ihave a question concerning installation of plugins (also sceneries, planes, ...) to the Steam version of X-Plane... The usual installation starts by locating the X-Plane directory, which might be a challenge for a user, if the X-Plane was installed through Steam...
Could somebody who owns the Steam version of the X-Plane to verify these paths, so I can correct them if necessary? It would help to guide the unfortunate users who can't find the correct location to install a plugin, scenery or a plane...
A plugin is executable code that runs inside X-Plane, extending what X-Plane does. Plugins are modular, allowing developers to extend the simulator without having to have the source code to the simulator. This article describes the basics of what a plugin is, how it works, and describes how we write one.
If you are an experienced programmer, you may already be familiar with some of the material presented here. If you have not done modular programming using DLLs, we introduce the concepts and also provide step-by-step examples of writing a very basic plugin.
Before discussing how to write a plugin, we will describe to some extent what it can do. You may not need a plugin for what you are trying to accomplish, and a plugin may not be able to accomplish what you are trying to do.
DLLs are powerful because the program that uses the DLL finds and runs the code in the DLL when it is executed, not when it is compiled. Consider the case of a set of math functions for a calculator. If we simply compile the math functions into our program, then when we change the math programs (for example, to make them faster or more accurate), we have to recompile our whole program. If we know that the math functions are likely to change, we can put them into a DLL and have the calculator program find these functions when it runs. Since the calculator finds the math functions every time it runs, we can create a new DLL with the same function names but better implementations and substitute it for the old DLL. The calculator function will not care as long as the functions have the same names and take the same inputs. This allows us to upgrade or change the behavior of our calculator program without recompiling it.
The example above is a bit contrived, but what if one company makes the calculator program and another company makes the math functions? The company that makes the math functions might not have the code for the calculator and might not be able to recompile it, so building a single big application would not be acceptable. Furthermore, the company that makes the math functions might not want the company that makes the calculator to have their source code. DLLs address both of these problems. The company that makes the math functions can provide new math functions to the calculator company without needing to recompile the calculator. The company that makes the calculator can use the math functions without having access to their code.
A program uses a DLL by linking to it. This happens when the program is executed. When a program links to a DLL, it examines the DLLs directory and finds all of the exported functions it needs. There are two kinds of linking: hard-linking (also known as strong linking) and weak-linking (also known as soft linking). When a program is hard-linked to a DLL, the program must find every function it needs in the DLLs directory to run. If the DLL is missing functions, the program will not execute. When a program is weak-linked to a DLL, the program can run even if it does not find all of the functions it needs.
DLLs can also link to other DLLs. In this way a chain of DLLs can be created. For example, the company that makes the math functions might use yet another DLL by another company that just does some very basic calculations.
DLLs are not full programs; they do not run at the same time as programs, nor do they have their own memory. They are simply libraries of code. That code may share data with the host program if desired. For example, the calculator program may pass the math library the address of an internal buffer and then the math program may fill the buffer with numbers.
If multiple DLLs or programs link to one DLL, that one DLL that is being linked to is only loaded once, and may only have one set of global variables. This allows DLLs to communicate with each other. For example, several DLLs that the calculator program uses might all use one date-computing DLL that can figure out things like what day of the week it was three years ago. If that date-computing DLL has an internal variable for the current day of the week, all DLLs linking to it will see it. If one DLL changes that variable, the variable will be changed for all DLLs. In this way DLLs can communicate with each other by sharing the same data.
The X-Plane plugin system is based on DLLs. The central component of this system is the X-Plane Plugin Manager (or XPLM). The XPLM is a library of code (compiled as a DLL!) that manages plugins. X-Plane links to the XPLM and all plugins link to the XPLM. The XPLM then serves as the central hub in the plugin system.
Likewise, the XPLM contains the functions that the plugin needs to change the sim, read data, create user interface, etc. The XPLM exports these functions into its DLL directory so the plugin can find them and call them.
Each plugin has a signature. The plugin tells the XPLM its signature when it is first initialized. This signature uniquely identifies the plugin and differentiates it from all other plugins. Signatures are built based on left-to-right keyword combining, starting with the organization responsible for creating the plug-in. For example, if XYZResearch made a plug-in to measure engine performance as part of its flight diagnostics package, it might use a signature like:
A plugin may be enabled or disabled. An enabled plugin will have its callbacks called (if it has any that need to be called), but a disabled callback will not. A disabled plugin cannot affect the sim since its callbacks are not called. Disabling provides a way for users to turn off a plugin that they do not want to use or that is being problematic. A dialog box in the simulator allows users to enable and disable plugins.
All plugins start out disabled when they are loaded. Then they are each enabled one by one when the sim is ready to start. Plugins are disabled before they are unloaded when the user quits the simulator. If a user previously disabled a plugin before quitting the simulator or disables all plugins on startup (by holding down the shift key while the simulator is started), plugins will start disabled and stay disabled until the user enables them.
A plugin will receive a callback when it is enabled and disabled, but does not necessarily need to do anything in response to this callback. Windows will automatically be hidden, menu items disabled, and timers paused when a plugin is disabled. Plugins that allocate other resources might want to free them when disabled. For example, if the plugin communicates with a server over the internet, it might want to disconnect from the server when disabled and reconnect when enabled.
A plugin is a DLL with a number of functions. Among these are various callbacks that the XPLM calls to notify the plugin of events, as well as any helper functions, utilities, etc. that the plugin needs.
You can register callbacks from the required callbacks or from other callbacks. For example, you can register a callback that will be called in 5 minutes when the plugin is initialized. Then five minutes later in that callback, you can create a window and register a callback for when the window is clicked.
Programming a plugin is different from programming a regular application. In a regular application, we write a main program that is run once from start to finish. In a plugin, lots of small functions are called at different times. In this way, programming a plugin is similar to event-driven UI programming.
For example, suppose you want to make a plugin that implements a pause-the-sim menu item. Your plugin would simply call XPLMCommandKeyStroke() with the constant xplm_key_pause to from within your menu callback.
A programming idiom is a style of coding that is used to accomplish certain goals. The plugin APIs are written in C to provide access to the widest range of languages possible. However, the design of the system is somewhat object-oriented. To accomplish this in a non-object-oriented language, we use the following idioms:
The typical life of an object goes something like this: you first create the object and receive an opaque handle. You then make function calls passing in that handle to manipulate it. Finally, you call a function to free the object, passing the handle in again. From that point on the handle is no longer valid.
As discussed above, a callback is a function in the code that the simulator calls to accomplish specific behaviors. For example, when the simulator needs to draw the window, it calls the draw callback you specify when you create the window.
X-Plane runs on Mac, Windows, and Linux. All functionality in the plugin system works cross-platform. You may be able to write a plugin that can be compiled and deployed on both platforms with the same source code. Here are some of the subsystems to use and their implications:
Plugins always operate synchronously with respect to each other; no parallelization or multithreading is provided. If we need threading or a separate process to maintain simulator performance while running, we must implement this ourselves. Xplane handles each plugin in a serial fashion, it never calls into more than one plugin at the same time. It calls them in a round robin fashion.
Plugins share resources with the simulator. X-Plane normally uses all available CPU, memory, and graphics bandwidth in its operation (although it will be bounded by only one, varying from machine to machine). Any non-I/O resource consumption from the plugin directly takes away from the simulator.
3a8082e126