// Copyright (c) 2013 by István Váradi // This file is part of XPLRA, a remote-access plugin for X-Plane // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // The views and conclusions contained in the software and documentation are those // of the authors and should not be interpreted as representing official policies, // either expressed or implied, of the FreeBSD Project. #ifndef HU_VARADIISTVAN_XPLRA_XPLANE_H #define HU_VARADIISTVAN_XPLRA_XPLANE_H //----------------------------------------------------------------------------- #include "Exception.h" #include #include #include //----------------------------------------------------------------------------- namespace hu { namespace varadiistvan { namespace scpl { namespace io { class LocalClientSocket; class DataStream; } /* namespace hu::varadiistvan::scpl::io */ } /* namespace hu::varadiistvan::scpl */ } /* namespace hu::varadiistvan */ } /* namespace hu */ //------------------------------------------------------------------------------ namespace hu { namespace varadiistvan { namespace xplra { //------------------------------------------------------------------------------ class MultiBuffer; class MultiGetter; class MultiSetter; //------------------------------------------------------------------------------ /** * The main class to access X-Plane. * * The calls are synchronous and not thread-safe. */ class XPlane { private: /** * Type for the set of multi-dataref buffers. */ typedef std::set multiBuffers_t; /** * The waiter to use. */ scpl::io::Waiter waiter; /** * The local client socket over which we are communicating with X-Plane. */ scpl::io::LocalClientSocket* socket; /** * The data stream to handle the data conversions. */ scpl::io::DataStream* stream; /** * The buffers created by this object. */ multiBuffers_t multiBuffers; public: /** * Construct the object. It will not be connected to the simulator * yet. */ XPlane() throw(); /** * Destroy the object. If connected, the connection will be * closed. It destroys all existing buffers, so their references * become invalid. */ ~XPlane() throw(); /** * Connect to the simulator. */ void connect() throw(IOException); /** * Check if we are connected to the simulator. */ bool isConnected() const throw(); /** * Disconnect from the simulator. */ void disconnect() throw(); /** * Create a new getter of multiple datarefs and return a reference * to it. */ MultiGetter& createMultiGetter() throw(); /** * Create a new setter of multiple datarefs and return a reference * to it. */ MultiSetter& createMultiSetter() throw(); /** * Destroy the given getter or setter of multiple datarefs. As the * buffer is unregistered, if it has been registered previously, * and unregistration may fail, this function might throw an * exception. * * @return if the buffer was found and could be destroyed */ bool destroyMultiBuffer(MultiBuffer& buffer) throw(Exception); /** * Get the versions of X-Plane, XPLM and the XPLRA plugin. */ void getVersions(int& xplaneVersion, int& xplmVersion, int& xplraVersion) throw(Exception); /** * Reload the plugins loaded in X-Plane. After this the connection * fails. */ void reloadPlugins() throw(Exception); /** * Get the integer value of the dataref with the given name. */ int getInt(const char* name) throw(Exception); /** * Get a float value. */ float getFloat(const char* name) throw(Exception); /** * Get a double value. */ double getDouble(const char* name) throw(Exception); /** * Get a possibly partial array of floats. * * @param name the name of the dataref * @param dest the destination buffer * @param length the length of the destination buffer * @param offset the offset from which to get the array * * @return the number of values acquired actually */ size_t getFloatArray(const char* name, float* dest, size_t length, size_t offset = 0) throw(Exception); /** * Get a possibly partial array of floats. The result array will * be created with a length needed to hold the returned value. * * @param name the name of the dataref * @param length will contain the number of floats read * @param offset the offset from which to get the array */ float* getFloatArray(const char* name, size_t& length, size_t offset = 0) throw(Exception); /** * Get a possibly partial array of integers. * * @param name the name of the dataref * @param dest the destination buffer * @param length the length of the destination buffer * @param offset the offset from which to get the array * * @return the number of values acquired actually */ size_t getIntArray(const char* name, int32_t* dest, size_t length, size_t offset = 0) throw(Exception); /** * Get a possibly partial array of integers. The result array will * be created with a length needed to hold the returned value. * * @param name the name of the dataref * @param length will contain the number of integers read * @param offset the offset from which to get the array */ int32_t* getIntArray(const char* name, size_t& length, size_t offset = 0) throw(Exception); /** * Get a possibly partial array of bytes. * * @param name the name of the dataref * @param dest the destination buffer * @param length the length of the destination buffer * @param offset the offset from which to get the array * * @return the number of values acquired actually */ size_t getByteArray(const char* name, uint8_t* dest, size_t length, size_t offset = 0) throw(Exception); /** * Get a possibly partial array of bytes. The result array will * be created with a length needed to hold the returned value. * * @param name the name of the dataref * @param length will contain the number of bytes read on return * @param offset the offset from which to get the array */ uint8_t* getByteArray(const char* name, size_t& length, size_t offset = 0) throw(Exception); /** * Get a string. A string is a byte array. */ std::string getString(const char* name, size_t offset = 0) throw(Exception); /** * Set the given dataref to the given integer value. */ void setInt(const char* name, int value) throw(Exception); /** * Set the given dataref to the given float value. */ void setFloat(const char* name, float value) throw(Exception); /** * Set the given dataref to the given double value. */ void setDouble(const char* name, double value) throw(Exception); /** * Set the given float array to values in the given buffer. */ void setFloatArray(const char* name, const float* values, size_t length, size_t offset = 0) throw(Exception); /** * Set the given integer array to values in the given buffer. */ void setIntArray(const char* name, const int32_t* values, size_t length, size_t offset = 0) throw(Exception); /** * Set the given byte array to values in the given buffer. */ void setByteArray(const char* name, const uint8_t* values, size_t length, size_t offset = 0) throw(Exception); /** * Set the given string to the given value. Since strings are byte * arrays, and the bytes after the string should be zeroed, the * length must be given. The string will be converted to a byte * array of the given length, padded with 0s. */ void setString(const char* name, const char* value, size_t length, size_t offset = 0) throw(Exception); /** * Show a textual message for a certain duration. */ void showMessage(const char* message, float duration) throw(Exception); /** * Register the given hotkey codes for listening. If there is an * existing set of hotkeys registered, those will be overwritten. */ void registerHotkeys(const uint16_t* codes, size_t length) throw(Exception); /** * Query the registered hotkeys whether they were pressed. */ void queryHotkeys(uint8_t* states, size_t length) throw(Exception); /** * Unregister the hotkeys. */ void unregisterHotkeys(); private: /** * Check if we have a stream and if it has not failed. */ void checkStream() throw(NotConnectedException, IOException); /** * Check the given protocol result. If it signifies an error, * throw a ProtocolException with the correct error code. */ void checkResult(uint8_t result, bool hasParameter = false, long parameter = 0) throw(ProtocolException); /** * Read and check the result. If it signifies an error, * throw a ProtocolException with the correct error code. If there * is some problem with the stream, an IOException is thrown. */ void checkResult(bool multi = false) throw(ProtocolException, IOException); /** * Issue the command to get a single, scalar value. The result is * also checked, but the value should be read by the caller. */ void getScalar(const char* name, uint8_t type) throw(Exception); /** * Issue the command to get an array of values of the given * type. It checks the result and retrieves the number of value * items available. * * @return the number of value items available */ size_t getArray(const char* name, uint8_t type, ssize_t length, size_t offset) throw(Exception); /** * Issue the command to set a scalar value of the given type. */ void setScalar(const char* name, uint8_t type) throw(Exception); /** * Issue the command to set an array value of the given type. */ void setArray(const char* name, uint8_t type, size_t length, size_t offset) throw(Exception); friend class MultiBuffer; friend class MultiGetter; friend class MultiSetter; }; //------------------------------------------------------------------------------ // Inline definitions //------------------------------------------------------------------------------ inline XPlane::XPlane() throw() : socket(0), stream(0) { } //------------------------------------------------------------------------------ inline bool XPlane::isConnected() const throw() { return socket!=0; } //------------------------------------------------------------------------------ } /* namespace hu::varadiistvan::xplra */ } /* namespace hu::varadiistvan */ } /* namespace hu */ //------------------------------------------------------------------------------ #endif // HU_VARADIISTVAN_XPLRA_XPLANE_H // Local Variables: // mode: C++ // c-basic-offset: 4 // indent-tabs-mode: nil // End: