* TimedProcessing.c
 * This example plugin demonstrates how to use the timed processing callbacks
 * to continuously record sim data to disk.
 * This technique can be used to record data to disk or to the network.  Unlike
 * UDP data output, we can increase our frequency to capture data every single
 * sim frame.  (This example records once per second.)
 * Use the timed processing APIs to do any periodic or asynchronous action in
 * your plugin.

#if APL
#if defined(__MACH__)
#include <Carbon/Carbon.h>

#include <stdio.h>
#include <string.h>
#include "XPLMProcessing.h"
#include "XPLMDataAccess.h"
#include "XPLMUtilities.h"

/* File to write data to. */
static FILE *	gOutputFile;

/* Data refs we will record. */
static XPLMDataRef		gPlaneLat;
static XPLMDataRef		gPlaneLon;
static XPLMDataRef		gPlaneEl;

#if APL && __MACH__
static int ConvertPath(const char * inPath, char * outPath, int outPathMaxLen);

static float	MyFlightLoopCallback(
                                   float                inElapsedSinceLastCall,    
                                   float                inElapsedTimeSinceLastFlightLoop,    
                                   int                  inCounter,    
                                   void *               inRefcon);    

PLUGIN_API int XPluginStart(
						char *		outName,
						char *		outSig,
						char *		outDesc)
	char	outputPath[255];
	#if APL && __MACH__
	char outputPath2[255];
	int Result = 0;
	strcpy(outName, "TimedProcessing");
	strcpy(outSig, "xplanesdk.examples.timedprocessing");
	strcpy(outDesc, "A plugin that records sim data.");

	/* Open a file to write to.  We locate the X-System directory 
	 * and then concatenate our file name.  This makes us save in
	 * the X-System directory.  Open the file. */
	strcat(outputPath, "TimedProcessing.txt");

	#if APL && __MACH__
	Result = ConvertPath(outputPath, outputPath2, sizeof(outputPath));
	if (Result == 0)
		strcpy(outputPath, outputPath2);
		XPLMDebugString("TimedProccessing - Unable to convert path\n");
	gOutputFile = fopen(outputPath, "w");

	/* Find the data refs we want to record. */
	gPlaneLat = XPLMFindDataRef("sim/flightmodel/position/latitude");
	gPlaneLon = XPLMFindDataRef("sim/flightmodel/position/longitude");
	gPlaneEl = XPLMFindDataRef("sim/flightmodel/position/elevation");

	/* Register our callback for once a second.  Positive intervals
	 * are in seconds, negative are the negative of sim frames.  Zero
	 * registers but does not schedule a callback for time. */
			MyFlightLoopCallback,	/* Callback */
			1.0,					/* Interval */
			NULL);					/* refcon not used. */
	return 1;

PLUGIN_API void	XPluginStop(void)
	/* Unregister the callback */
	XPLMUnregisterFlightLoopCallback(MyFlightLoopCallback, NULL);
	/* Close the file */

PLUGIN_API void XPluginDisable(void)
	/* Flush the file when we are disabled.  This is convenient; you 
	 * can disable the plugin and then look at the output on disk. */

PLUGIN_API int XPluginEnable(void)
	return 1;

PLUGIN_API void XPluginReceiveMessage(
					XPLMPluginID	inFromWho,
					int				inMessage,
					void *			inParam)

float	MyFlightLoopCallback(
                                   float                inElapsedSinceLastCall,    
                                   float                inElapsedTimeSinceLastFlightLoop,    
                                   int                  inCounter,    
                                   void *               inRefcon)
	/* The actual callback.  First we read the sim's time and the data. */
	float	elapsed = XPLMGetElapsedTime();
	float	lat = XPLMGetDataf(gPlaneLat);
	float	lon = XPLMGetDataf(gPlaneLon);
	float	el = XPLMGetDataf(gPlaneEl);
	/* Write the data to a file. */
	fprintf(gOutputFile, "Time=%f, lat=%f,lon=%f,el=%f.\n",elapsed, lat, lon, el);
	/* Return 1.0 to indicate that we want to be called again in 1 second. */
	return 1.0;

#if APL && __MACH__
#include <Carbon/Carbon.h>
int ConvertPath(const char * inPath, char * outPath, int outPathMaxLen)
	CFStringRef inStr = CFStringCreateWithCString(kCFAllocatorDefault, inPath ,kCFStringEncodingMacRoman);
	if (inStr == NULL)
		return -1;
	CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, inStr, kCFURLHFSPathStyle,0);
	CFStringRef outStr = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
	if (!CFStringGetCString(outStr, outPath, outPathMaxLen, kCFURLPOSIXPathStyle))
		return -1;
	return 0;

3 comments on “TimedProcessing

  1. Hello!
    This code works great. I am a student and I am making a project for myself to save data of X-plane in .txt file. Now I am editing this code but I couldn’t figure out where to set intervals how often Plugin saves data to .txt file. I know that sim data is recorded in 1 sec and it’s written in 241 lines every time in approximately 5 sec, but I want to record just one line of data and write it to .txt file every 0.1 sec. Can anyone help me with that? Basically what I need is code that saves data to .txt file every 0.1 sec, is this even possible?
    Best regards

    1. Hi Rok Dolenc,

      1) About gOutputFile = fopen(outputPath, “w”);
      From //www.cplusplus.com/reference/cstdio/fopen/
      you can read: “w” write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.

      -> I don’t even understand why it doesn’t overwrite, but append. Strange and not logical ..

      2) Here: //developer.x-plane.com/sdk/XPLMRegisterFlightLoopCallback/
      you can read: inInterval defines when you will be called:
      – Positive number to specify seconds from registration time to the next callback
      – Negative number to indicate when you will be called (e.g. pass -1 to be called at the next cylcle)
      – 0 to not be called; your callback will be inactive.

      -> But for me the file (TimedProcessing.txt) is written about every 60/70 seconds instead of every second.

      Have you found a solution?
      Contact me on: foxjojofox@gmail.com


Leave a Reply

Your email address will not be published. Required fields are marked *

Please do not report bugs in the blog comments.
Only bugs reported via the X-Plane Bug Reporter are tracked.