* Minor improvements to the handling of landing gear by the SetGear and HandlePOSI functions * sendPOSI command change (double for lat/lon/h) (#111) * Updated POSI to use doubles for lat/lon/alt, as step size for floats was unacceptably large at high longitudes. * Updated Java library for MATLAB, updated Java project, and updated Windows plugin binaries * Rolled back Java version to 1.7 for MATLAB compatibility * Update MessageHandlers.cpp * Update DataManager.cpp * Added pause functionality for individual a/c Adds new cases such that: 0: Unpauses all a/c 1: Pauses all a/c 2: Switches case for all a/c 100:119: Pauses a/c 0:19 200:219: Unpauses a/c 0:19 Updates log messages. Keeps the 0,1,2 arguments as they previously were. * Finished individual pause functionality * Update DataManager.cpp * Updated flags to allow for individual pause commands * Individual pause command documentation * Updated flags to allow for individual pause commands * Adding individual pause to documentation * Updated flags to allow for individual pause commands * Requested changes, cleaning * Update CMakeLists.txt Include "-fno-stack-protector" for linking and compiling for systems that do not have this have this flag as a default. * Enabling AI after setting position (#118) Previously, the code enabled the AI before setting the position of a/c, which negated its purpose. * Updated XPlane SDK to version 2.1.3 * Resolve function ambiguity for std::abs on mac Fixes #126 * Update copyright notice * Update Windows binaries * Update Linux binaries * Update version numbers * fix osx abs ambiguity (#142) * fix indexing error (#143) * Runway camera location control (#144) * update ignore * basics working * set cam pos remotely * log cam position * keep default behaviour, if short view message is received Compatibility with existing software * all to tabs * rename variable * option to use camera direction fields * Added UDP multicast for plugin discovery (#153) * Added Timer * Added UDPSocket::GetAddr * Added MessageHandlers::SendBeacon() * PoC of starting a timer on PluginEnable * C++11 * Added Timer to xcode project * C++11 in cmake * added Timer to cmake * use function pointer in Timer * moved Timer to namespace + wait for thread to join when stopping the timer * Windows: changed uint to unisgned short * Windows: Added Timer.h/cpp to project * GetAddr static * Send xplane and plugin version with BECN * SendBeacon with params * fixed file copyrights * Include functional to fix Linux compile error * review fixes * Send plugin receive port in BECN * review fixes * Fixed tabs vs spaces indentations (#157) * Java client BECN implementation (#155) * Added MS Azure Dev Ops CI integration (#162) * Do not build for i386 on macOS Use ARCHS_STANDARD to avoid the error “The i386 architecture is deprecated. You should update your ARCHS build setting to remove the i386 architecture.” * Fixed missing include The Visual Studio solution was not compiling * Fixed isnan ambigious refernce Ambigious reference when compiling on travis https://stackoverflow.com/questions/33770374/why-is-isnan-ambiguous-and-how-to-avoid-it * Set MSVC warning level to 3 Too many warnings were generated when building a Release build making Travis job to fail because of too much output * Use default toolset for Visual Studio AppVeyor recommends to set the default toolset * #include <cstdint> * Use MSVC ToolsVersion="14.0" # Conflicts: # xpcPlugin/xpcPlugin/xpcPlugin.vcxproj * Removed binaries from repository # Conflicts: # xpcPlugin/XPlaneConnect/64/win.xpl # xpcPlugin/XPlaneConnect/win.xpl * Added ms azure ci xcode linux linux + macos linux + macos removed branch filter win tests win tests Test all platfroms artifacts tests * output all binaries to ‘XPlaneConnect’ All platforms produce a binary in xpcPlugin/XPlaneConnect/ xpcPlugin/XPlaneConnect/64/ * Added ms azure GH deploy deploy stage GH release test trigger tags * Clean up yml file - Added variables - Added job decriptions * Ignore script to ignore .exp files + fixed output path * Renamed ms azure GH connection * Update service connection for azure pipeline * Added Python3 compatible xpc client. (#156) * Update Azure Pipelines service connection
176 lines
4.4 KiB
C++
176 lines
4.4 KiB
C++
// Copyright (c) 2013-2018 United States Government as represented by the Administrator of the
|
|
// National Aeronautics and Space Administration. All Rights Reserved.
|
|
#include "Log.h"
|
|
|
|
#include "XPLMUtilities.h"
|
|
|
|
#include <cstdarg>
|
|
#include <cstdio>
|
|
#include <ctime>
|
|
|
|
#ifndef LIN
|
|
#include <chrono>
|
|
#endif
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
|
|
// Implementation note: I initially wrote this class using C++ iostreams, but I couldn't find any
|
|
// way to implement FormatLine without adding in a call to sprintf. It therefore seems more
|
|
// efficient to me to just use C-style IO and call std::fprintf directly.
|
|
namespace XPC
|
|
{
|
|
static std::FILE* fd;
|
|
static void WriteTime(FILE* fd)
|
|
{
|
|
#ifdef LIN
|
|
// Can't provide high resolution logging on Linux because C++11 doesn't work with X-Plane.
|
|
time_t rawtime;
|
|
tm* timeinfo;
|
|
time(&rawtime);
|
|
timeinfo = localtime(&rawtime);
|
|
|
|
char buffer[16] = { 0 };
|
|
// Format is equivalent to [%F %T], but neither of those specifiers is
|
|
// supported on Windows as of Visual Studio 13
|
|
strftime(buffer, 16, "[%H:%M:%S] ", timeinfo);
|
|
|
|
fprintf(fd, buffer);
|
|
#else
|
|
using namespace std::chrono;
|
|
|
|
system_clock::time_point now = system_clock::now();
|
|
std::time_t now_tt = system_clock::to_time_t(now);
|
|
system_clock::time_point now_sec = system_clock::from_time_t(now_tt);
|
|
milliseconds ms = duration_cast<milliseconds>(now - now_sec);
|
|
std::tm * tm = std::localtime(&now_tt);
|
|
|
|
std::stringstream ss;
|
|
ss << std::setfill('0')
|
|
<< std::setw(2) << tm->tm_hour << ":"
|
|
<< std::setw(2) << tm->tm_min << ":"
|
|
<< std::setw(2) << tm->tm_sec << "."
|
|
<< std::setw(3) << ms.count() << "|";
|
|
|
|
std::fprintf(fd, ss.str().c_str());
|
|
#endif
|
|
}
|
|
|
|
static void WriteLevel(FILE* fd, int level)
|
|
{
|
|
const char* str;
|
|
switch (level)
|
|
{
|
|
case LOG_OFF:
|
|
str = " OFF|";
|
|
break;
|
|
case LOG_FATAL:
|
|
str = "FATAL|";
|
|
break;
|
|
case LOG_ERROR:
|
|
str = "ERROR|";
|
|
break;
|
|
case LOG_WARN:
|
|
str = " WARN|";
|
|
break;
|
|
case LOG_INFO:
|
|
str = " INFO|";
|
|
break;
|
|
case LOG_DEBUG:
|
|
str = "DEBUG|";
|
|
break;
|
|
case LOG_TRACE:
|
|
str = "TRACE|";
|
|
break;
|
|
default:
|
|
str = " UNK|";
|
|
break;
|
|
}
|
|
std::fprintf(fd, str);
|
|
}
|
|
|
|
void Log::Initialize(const std::string& version)
|
|
{
|
|
if (LOG_LEVEL == LOG_OFF)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Note: Mode "w" deletes an existing file with the same name. This means that we only
|
|
// ever get the log from the last run. This matches the way that X-Plane treats its
|
|
// log.
|
|
fd = std::fopen("XPCLog.txt", "w");
|
|
if (fd != NULL)
|
|
{
|
|
std::time_t rawtime;
|
|
std::tm* timeinfo;
|
|
std::time(&rawtime);
|
|
timeinfo = std::localtime(&rawtime);
|
|
|
|
char timeStr[16] = { 0 };
|
|
std::strftime(timeStr, 16, "%Y-%m-%d", timeinfo);
|
|
|
|
std::fprintf(fd, "X-Plane Connect [Version %s]\n", version.c_str());
|
|
std::fprintf(fd, "Compiled %s %s\n", __DATE__, __TIME__);
|
|
std::fprintf(fd, "Copyright (c) 2013-2018 United States Government as represented by the\n");
|
|
std::fprintf(fd, "Administrator of the National Aeronautics and Space Administration.\n");
|
|
std::fprintf(fd, "All Rights Reserved.\n\n");
|
|
|
|
std::fprintf(fd, "This file contains debugging information about the X-Plane Connect plugin.\n");
|
|
std::fprintf(fd, "If you have technical issues with the plugin, please report them by opening\n");
|
|
std::fprintf(fd, "an issue on GitHub (https://github.com/nasa/XPlaneConnect/issues) or by\n");
|
|
std::fprintf(fd, "emailing Christopher Teubert (christopher.a.teubert@nasa.gov).\n\n");
|
|
|
|
int xpVer;
|
|
int xplmVer;
|
|
XPLMHostApplicationID hostID;
|
|
XPLMGetVersions(&xpVer, &xplmVer, &hostID);
|
|
std::fprintf(fd, "X-Plane Version: %d\n", xpVer);
|
|
std::fprintf(fd, "Plugin Manager Version: %d\n", xplmVer);
|
|
std::fprintf(fd, "Host Application ID: %d\n", hostID);
|
|
std::fprintf(fd, "Log file generated on %s.\n", timeStr);
|
|
std::fflush(fd);
|
|
}
|
|
}
|
|
|
|
void Log::Close()
|
|
{
|
|
if (fd)
|
|
{
|
|
std::fclose(fd);
|
|
}
|
|
}
|
|
|
|
void Log::WriteLine(int level, const std::string& tag, const std::string& value)
|
|
{
|
|
if (level > LOG_LEVEL || !fd)
|
|
{
|
|
return;
|
|
}
|
|
|
|
WriteTime(fd);
|
|
WriteLevel(fd, level);
|
|
std::fprintf(fd, "%s|%s\n", tag.c_str(), value.c_str());
|
|
std::fflush(fd);
|
|
}
|
|
|
|
void Log::FormatLine(int level, const std::string& tag, std::string format, ...)
|
|
{
|
|
va_list args;
|
|
|
|
if (level > LOG_LEVEL || !fd)
|
|
{
|
|
return;
|
|
}
|
|
va_start(args, format);
|
|
|
|
WriteTime(fd);
|
|
WriteLevel(fd, level);
|
|
std::fprintf(fd, "%s|", tag.c_str());
|
|
std::vfprintf(fd, format.c_str(), args);
|
|
std::fprintf(fd, "\n");
|
|
std::fflush(fd);
|
|
|
|
va_end(args);
|
|
}
|
|
}
|