From 80431deef44c12023bc641e43bfc227d8594a41f Mon Sep 17 00:00:00 2001 From: Laurent Gomila Date: Mon, 7 Apr 2014 23:00:41 +0200 Subject: [PATCH] Reviewed the sensor API --- include/SFML/Window/Event.hpp | 14 +- include/SFML/Window/Sensor.hpp | 192 ++++++---------- src/SFML/Network/Ftp.cpp | 4 +- src/SFML/Window/Android/SensorImpl.cpp | 191 ++-------------- src/SFML/Window/Android/SensorImpl.hpp | 82 ++----- src/SFML/Window/CMakeLists.txt | 5 +- src/SFML/Window/JoystickImpl.hpp | 12 + .../OSX/{SensorImpl.mm => SensorImpl.cpp} | 67 +++--- src/SFML/Window/OSX/SensorImpl.hpp | 50 ++--- src/SFML/Window/Sensor.cpp | 40 +--- src/SFML/Window/SensorImpl.hpp | 63 +----- src/SFML/Window/SensorManager.cpp | 101 ++++----- src/SFML/Window/SensorManager.hpp | 72 +++--- src/SFML/Window/Unix/SensorImpl.cpp | 64 +++--- src/SFML/Window/Unix/SensorImpl.hpp | 55 ++--- src/SFML/Window/Win32/SensorImpl.cpp | 64 +++--- src/SFML/Window/Win32/SensorImpl.hpp | 47 ++-- src/SFML/Window/WindowImpl.cpp | 67 +++--- src/SFML/Window/WindowImpl.hpp | 8 +- src/SFML/Window/iOS/JoystickImpl.mm | 164 +------------- src/SFML/Window/iOS/SensorImpl.hpp | 58 ++--- src/SFML/Window/iOS/SensorImpl.mm | 209 +++++++++++++++--- 22 files changed, 637 insertions(+), 992 deletions(-) rename src/SFML/Window/OSX/{SensorImpl.mm => SensorImpl.cpp} (70%) diff --git a/include/SFML/Window/Event.hpp b/include/SFML/Window/Event.hpp index 59433bf95..7e2f1f025 100644 --- a/include/SFML/Window/Event.hpp +++ b/include/SFML/Window/Event.hpp @@ -154,13 +154,15 @@ public : }; //////////////////////////////////////////////////////////// - /// \brief Sensor events parameters (SensorEnabled, SensorData, SensorDisabled) + /// \brief Sensor event parameters (SensorChanged) /// //////////////////////////////////////////////////////////// struct SensorEvent { - Sensor::Type type; - Sensor::Data data; + Sensor::Type type; ///< Type of the sensor + float x; ///< Current value of the sensor on X axis + float y; ///< Current value of the sensor on Y axis + float z; ///< Current value of the sensor on Z axis }; //////////////////////////////////////////////////////////// @@ -190,9 +192,7 @@ public : TouchBegan, ///< A touch event began (data in event.touch) TouchMoved, ///< A touch moved (data in event.touch) TouchEnded, ///< A touch event ended (data in event.touch) - SensorEnabled, ///< A sensor was enabled (data in event.sensor) - SensorData, ///< A new sensor data arrived (data in event.sensor) - SensorDisabled, ///< A sensor was disabled (data in event.sensor) + SensorChanged, ///< A sensor value changed (data in event.sensor) Count ///< Keep last -- the total number of event types }; @@ -214,7 +214,7 @@ public : JoystickButtonEvent joystickButton; ///< Joystick button event parameters (Event::JoystickButtonPressed, Event::JoystickButtonReleased) JoystickConnectEvent joystickConnect; ///< Joystick (dis)connect event parameters (Event::JoystickConnected, Event::JoystickDisconnected) TouchEvent touch; ///< Touch events parameters (Event::TouchBegan, Event::TouchMoved, Event::TouchEnded) - SensorEvent sensor; ///< Sensor events parameters (Event::SensorEnabled, Event::SensorData, Event::SensorDisabled) + SensorEvent sensor; ///< Sensor event parameters (Event::SensorChanged) }; }; diff --git a/include/SFML/Window/Sensor.hpp b/include/SFML/Window/Sensor.hpp index 70e22486f..227bb7706 100644 --- a/include/SFML/Window/Sensor.hpp +++ b/include/SFML/Window/Sensor.hpp @@ -29,17 +29,14 @@ // Headers //////////////////////////////////////////////////////////// #include -#include #include #include namespace sf { -class Window; - //////////////////////////////////////////////////////////// -/// \brief Give access to the real-time state of the sensor +/// \brief Give access to the real-time state of the sensors /// //////////////////////////////////////////////////////////// class SFML_WINDOW_API Sensor @@ -52,44 +49,16 @@ public : //////////////////////////////////////////////////////////// enum Type { - Accelerometer, ///< The acceleration sensor measures the acceleration force - Gyroscope, ///< The gyroscope sensor measures the rate of rotation - Magnetometer, ///< The magnetic sensor measures the ambient magnetic field - Temperature, ///< The temperature sensor measures the ambient room temperature - Proximity, ///< The proximity sensor measures how close an object is - Gravity, ///< The gravity sensor measures the force of gravity - Light, ///< The light sensor measures the amount of ambient light or illumination - LinearAcceleration, ///< The linear acceleration sensor that measures acceleration - Orientation, ///< The orientation sensor that measures the degrees of orientation - Pressure, ///< The pressure sensor give air pressure readings - Altimeter, ///< The altimeter measures the altitude by using air pressure measurements - Compass, ///< The compass sensor give compass heading readings - - Count ///< Keep last -- the total number of sensor type + Accelerometer, ///< Measures the raw acceleration (m/sē) + Gyroscope, ///< Measures the raw rotation rates (degrees/s) + Magnetometer, ///< Measures the ambient magnetic field (micro-teslas) + Gravity, ///< Measures the direction and intensity of gravity, independent of device acceleration (m/sē) + UserAcceleration, ///< Measures the direction and intensity of device acceleration, independent of the gravity (m/sē) + Orientation, ///< Measures the absolute 3D orientation (degrees) + + Count ///< Keep last -- the total number of sensor types }; - - //////////////////////////////////////////////////////////// - /// \brief Sensor data - /// - //////////////////////////////////////////////////////////// - union Data - { - struct - { - float x; ///< X-axis data - float y; ///< Y-axis data - float z; ///< Z-axis data - } - acceleration, ///< Acceleration in m/s^2 (Sensor::Accelerometer, Sensor::Gravity, Sensor::LinearAcceleration) - magnetic, ///< Magnetic in uT (Sensor::Magnetometer) - vector, ///< Vector representing angle in degrees (Sensor::Orientation, Sensor::Compass) - gyroscope; ///< Gyroscope data in rad/s (Sensor::Gyroscope) - float temperature; ///< Temperature in degrees Celsius (Sensor::Temperature) - float distance; ///< Distance in meter (Sensor::Proximity, Sensor::Altimeter) - float light; ///< Illumination in lx (Sensor::Light) - float pressure; ///< Pressure in hPa (Sensor::Pressure) - }; - + //////////////////////////////////////////////////////////// /// \brief Check if a sensor is available on the underlying platform /// @@ -99,98 +68,83 @@ public : /// //////////////////////////////////////////////////////////// static bool isAvailable(Type sensor); - - //////////////////////////////////////////////////////////// - /// \brief Get the resolution of a sensor - /// - /// The resolution represents the sensitivity of a sensor. The - /// resolution of a sensor is the smallest change it can detect in - /// the quantity that it is measuring - /// - /// \param sensor Sensor to check - /// - /// \return The sensor's resolution in the sensor's unit. - /// - //////////////////////////////////////////////////////////// - static float getResolution(Type sensor); - - //////////////////////////////////////////////////////////// - /// \brief Get the maximum range of a sensor - /// - /// The resolution represents the sensitivity of a sensor. The - /// value returned is in the sensor's unit. - /// - /// \param sensor Sensor to check - /// - /// \return The sensor's resolution in the sensor's unit. - /// - //////////////////////////////////////////////////////////// - static Vector2f getMaximumRange(Type sensor); - - //////////////////////////////////////////////////////////// - /// \brief Get the minimum delay allowed between two events - /// - /// When setting the refresh rate of a sensor, you'll need to - /// make sure the value is a superior to the minimum delay - /// allowable - /// - /// \param sensor Sensor to check - /// - /// \return The minimum delay allowed between two events - /// - //////////////////////////////////////////////////////////// - Time getMinimumDelay(Type sensor); - - //////////////////////////////////////////////////////////// - /// \brief Check if a sensor is enabled - /// - /// \param sensor Sensor to check - /// - /// \return True if the sensor is enabled, false otherwise - /// - //////////////////////////////////////////////////////////// - static bool isEnable(Type sensor); - + //////////////////////////////////////////////////////////// /// \brief Enable or disable a sensor /// - /// A sensor is disabled by default otherwise it would consume too - /// much battery power. Once a sensor enabled, it will start sending - /// sensor events of that type (if available). + /// All sensors are disabled by default, to avoid consuming too + /// much battery power. Once a sensor is enabled, it starts + /// sending events of the corresponding type. /// - /// \param sensor Sensor to enable - /// \param enable True to enable, false to disable + /// This function does nothing if the sensor is unavailable. + /// + /// \param sensor Sensor to enable + /// \param enabled True to enable, false to disable /// //////////////////////////////////////////////////////////// - static void setEnable(Type sensor, bool enable = true); - + static void setEnabled(Type sensor, bool enabled); + //////////////////////////////////////////////////////////// - /// \brief Set the refresh rate of a sensor + /// \brief Get the current sensor value /// - /// This is the delay you want between each measure report + /// \param sensor Sensor to read /// - /// \param sensor Sensor to modify - /// \param rate Delay between each event + /// \return The current sensor value /// //////////////////////////////////////////////////////////// - static void setRefreshRate(Type sensor, const Time& rate); - - //////////////////////////////////////////////////////////// - /// \brief Get the current sensor data - /// - /// If the sensor support real-time retrieval, you'll get - /// the current sensor data otherwise this is likely the - /// latest data of this sensor type. - /// - /// \param sensor Sensor to check - /// - /// \return The current sensor data - /// - //////////////////////////////////////////////////////////// - static Data getData(Type sensor); + static Vector3f getValue(Type sensor); }; } // namespace sf #endif // SFML_SENSOR_HPP + + +//////////////////////////////////////////////////////////// +/// \class sf::Sensor +/// \ingroup window +/// +/// sf::Sensor provides an interface to the state of the +/// various sensors that a device provides. It only contains static +/// functions, so it's not meant to be instanciated. +/// +/// This class allows users to query the sensors values at any +/// time and directly, without having to deal with a window and +/// its events. Compared to the SensorChanged event, sf::Sensor +/// can retrieve the state of a sensor at any time (you don't need to +/// store and update its current value on your side). +/// +/// Depending on the OS and hardware of the device (phone, tablet, ...), +/// some sensor types may not be available. You should always check +/// the availability of a sensor before trying to read it, with the +/// sf::Sensor::isAvailable function. +/// +/// You may wonder why some sensor types look so similar, for example +/// Accelerometer and Gravity / UserAcceleration. The first one +/// is the raw measurement of the acceleration, and takes in account +/// both the earth gravity and the user movement. The others are +/// more precise: they provide these components separately, which is +/// usually more useful. In fact they are not direct sensors, they +/// are computed internally based on the raw acceleration and other sensors. +/// This is exactly the same for Gyroscope vs Orientation. +/// +/// Because sensors consume a non-negligible amount of current, they are +/// all disabled by default. You must call sf::Sensor::setEnabled for each +/// sensor in which you are interested. +/// +/// Usage example: +/// \code +/// if (sf::Sensor::isAvailable(sf::Sensor::Gravity)) +/// { +/// // gravity sensor is available +/// } +/// +/// // enable the gravity sensor +/// sf::Sensor::setEnabled(sf::Sensor::Gravity, true); +/// +/// // get the current value of gravity +/// sf::Vector3f gravity = sf::Sensor::getValue(sf::Sensor::Gravity); +/// \endcode +/// +//////////////////////////////////////////////////////////// diff --git a/src/SFML/Network/Ftp.cpp b/src/SFML/Network/Ftp.cpp index ffaad4b16..51553543a 100644 --- a/src/SFML/Network/Ftp.cpp +++ b/src/SFML/Network/Ftp.cpp @@ -28,9 +28,7 @@ #include #include #include -#ifdef SFML_SYSTEM_ANDROID - #include -#endif +#include #include #include #include diff --git a/src/SFML/Window/Android/SensorImpl.cpp b/src/SFML/Window/Android/SensorImpl.cpp index 821b2d85e..be5e439c8 100644 --- a/src/SFML/Window/Android/SensorImpl.cpp +++ b/src/SFML/Window/Android/SensorImpl.cpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2013 Jonathan De Wachter (dewachter.jonathan@gmail.com) +// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -26,21 +26,8 @@ // Headers //////////////////////////////////////////////////////////// #include -#include -#include -#include -#include -namespace -{ - ALooper* looper; - - ASensorManager* sensorManager; - ASensorEventQueue* sensorEventQueue; - std::queue sensorData[sf::Sensor::Count]; -} - namespace sf { namespace priv @@ -48,182 +35,52 @@ namespace priv //////////////////////////////////////////////////////////// void SensorImpl::initialize() { - // Get the looper associated with this thread - looper = ALooper_forThread(); - - // Get the unique sensor manager - sensorManager = ASensorManager_getInstance(); - - // Create the sensor events queue and attach it to the looper - sensorEventQueue = ASensorManager_createEventQueue(sensorManager, looper, - 1, &processSensorEvents, NULL); + // To be implemented } + //////////////////////////////////////////////////////////// void SensorImpl::cleanup() -{ - // Detach the sensor events queue from the looper and destroy it - ASensorManager_destroyEventQueue(sensorManager, sensorEventQueue); +{ + // To be implemented } //////////////////////////////////////////////////////////// -SensorCaps& SensorImpl::initialize(unsigned int type) +bool SensorImpl::isAvailable(Sensor::Type /*sensor*/) { - // Get the default sensor matching the type - m_sensor = getDefaultSensor(type); - - static SensorCaps capabilities; - - if (!m_sensor) - { - // Sensor not available, stop here - capabilities.available = false; - return capabilities; - } - else - capabilities.available = true; - - // Get the sensor resolution - capabilities.resolution = ASensor_getResolution(m_sensor); - - // Get the minimum delay allowed between events - capabilities.minimumDelay = microseconds(ASensor_getMinDelay(m_sensor)); - - // To get the maximum range we'll need to use JNI since it's not available from C (todo) - capabilities.maximumRange = Vector2f(); - - // Initialize SensorState attributes - setRefreshRate(capabilities.minimumDelay); // Set the event rate (not to consume too much battery) - setEnable(false); // Disable the sensor by default (initialize SensorState on the fly) - m_state.pendingData = &sensorData[type]; - - return capabilities; -} - -//////////////////////////////////////////////////////////// -void SensorImpl::terminate() -{ - // Nothing to do + // To be implemented + return false; } //////////////////////////////////////////////////////////// -SensorState& SensorImpl::update() +bool SensorImpl::open(Sensor::Type /*sensor*/) { - // Update our pending sensor data lists - ALooper_pollAll(0, NULL, NULL, NULL); - - return m_state; -} - -//////////////////////////////////////////////////////////// -bool SensorImpl::isEnable() -{ - return m_state.enabled; -} - -//////////////////////////////////////////////////////////// -void SensorImpl::setEnable(bool enable) -{ - if (enable) - ASensorEventQueue_enableSensor(sensorEventQueue, m_sensor); - else - ASensorEventQueue_disableSensor(sensorEventQueue, m_sensor); - - m_state.enabled = enable; -} - -//////////////////////////////////////////////////////////// -void SensorImpl::setRefreshRate(const Time& rate) -{ - ASensorEventQueue_setEventRate(sensorEventQueue, m_sensor, rate.asMicroseconds()); - m_state.refreshRate = rate; -} - -//////////////////////////////////////////////////////////// -ASensor const* SensorImpl::getDefaultSensor(unsigned int type) -{ - int sensorType = 0; - - switch(type) - { - case Sensor::Accelerometer: - sensorType = ASENSOR_TYPE_ACCELEROMETER; - break; - - case Sensor::Magnetometer: - sensorType = ASENSOR_TYPE_MAGNETIC_FIELD; - break; - - case Sensor::Gyroscope: - sensorType = ASENSOR_TYPE_GYROSCOPE; - break; - - case Sensor::Light: - sensorType = ASENSOR_TYPE_LIGHT; - break; - - case Sensor::Proximity: - sensorType = ASENSOR_TYPE_PROXIMITY; - break; - - default: - // The other sensors are unavailable on Android from the android C API - return NULL; - } - - return ASensorManager_getDefaultSensor(sensorManager, sensorType); + // To be implemented + return false; } //////////////////////////////////////////////////////////// -int SensorImpl::processSensorEvents(int fd, int events, void* data) +void SensorImpl::close() { - ASensorEvent event; + // To be implemented +} - while (ASensorEventQueue_getEvents(sensorEventQueue, &event, 1) > 0) - { - Sensor::Data data; - Sensor::Type type; - - switch (event.sensor) - { - case ASENSOR_TYPE_ACCELEROMETER: - type = Sensor::Accelerometer; - data.acceleration.x = event.acceleration.x; - data.acceleration.y = event.acceleration.y; - data.acceleration.z = event.acceleration.z; - break; - case ASENSOR_TYPE_GYROSCOPE: - type = Sensor::Gyroscope; - data.vector.x = event.vector.x; - data.vector.y = event.vector.y; - data.vector.z = event.vector.z; - break; +//////////////////////////////////////////////////////////// +Vector3f SensorImpl::update() +{ + // To be implemented + return Vector3f(0, 0, 0); +} - case ASENSOR_TYPE_MAGNETIC_FIELD: - type = Sensor::Magnetometer; - data.magnetic.x = event.magnetic.x; - data.magnetic.y = event.magnetic.y; - data.magnetic.z = event.magnetic.z; - break; - - case ASENSOR_TYPE_LIGHT: - type = Sensor::Light; - data.light = event.light; - break; - - case ASENSOR_TYPE_PROXIMITY: - type = Sensor::Proximity; - break; - } - - sensorData[type].push(data); - } - return 1; +//////////////////////////////////////////////////////////// +void SensorImpl::setEnabled(bool /*enabled*/) +{ + // To be implemented } } // namespace priv diff --git a/src/SFML/Window/Android/SensorImpl.hpp b/src/SFML/Window/Android/SensorImpl.hpp index 49e09865c..49386dd0c 100644 --- a/src/SFML/Window/Android/SensorImpl.hpp +++ b/src/SFML/Window/Android/SensorImpl.hpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2013 Jonathan De Wachter (dewachter.jonathan@gmail.com) +// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -25,10 +25,6 @@ #ifndef SFML_SENSORIMPLANDROID_HPP #define SFML_SENSORIMPLANDROID_HPP -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include namespace sf { @@ -55,82 +51,46 @@ public : static void cleanup(); //////////////////////////////////////////////////////////// - /// \brief Initialize the sensor + /// \brief Check if a sensor is available /// - /// \param type Index assigned to the sensor + /// \param sensor Sensor to check /// - /// \return The sensor capabilities + /// \return True if the sensor is available, false otherwise /// //////////////////////////////////////////////////////////// - SensorCaps& initialize(unsigned int type); + static bool isAvailable(Sensor::Type sensor); + + //////////////////////////////////////////////////////////// + /// \brief Open the sensor + /// + /// \param sensor Type of the sensor + /// + /// \return True on success, false on failure + /// + //////////////////////////////////////////////////////////// + bool open(Sensor::Type sensor); //////////////////////////////////////////////////////////// /// \brief Close the sensor /// //////////////////////////////////////////////////////////// - void terminate(); + void close(); //////////////////////////////////////////////////////////// - /// \brief Update the sensor and get its new state + /// \brief Update the sensor and get its new value /// - /// \return Sensor state + /// \return Sensor value /// //////////////////////////////////////////////////////////// - SensorState& update(); - - //////////////////////////////////////////////////////////// - /// \brief Check if the sensor is enabled - /// - /// \return True if the sensor is enabled, false otherwise - /// - //////////////////////////////////////////////////////////// - bool isEnable(); + Vector3f update(); //////////////////////////////////////////////////////////// /// \brief Enable or disable the sensor /// - /// \param enable True to enable, false to disable + /// \param enabled True to enable, false to disable /// //////////////////////////////////////////////////////////// - void setEnable(bool enable); - - //////////////////////////////////////////////////////////// - /// \brief Set the refresh rate of the sensor - /// - /// \param rate Delay between each refresh - /// - //////////////////////////////////////////////////////////// - void setRefreshRate(const Time& rate); - -private: - //////////////////////////////////////////////////////////// - /// \brief Get the default Android sensor matching the sensor type - /// - /// \param type Type of the sensor - /// - /// \return The default Android sensor, NULL otherwise - /// - //////////////////////////////////////////////////////////// - ASensor const* getDefaultSensor(unsigned int type); - - //////////////////////////////////////////////////////////// - /// \brief Process the pending sensor data available and add them to our lists - /// - /// \param fd File descriptor - /// \param events Bitmask of the poll events that were triggered - /// \param data Data pointer supplied - /// - /// \return Whether it should continue (1) or unregister the callback (0) - /// - //////////////////////////////////////////////////////////// - static int processSensorEvents(int fd, int events, void* data); - - //////////////////////////////////////////////////////////// - // Member data - //////////////////////////////////////////////////////////// - const ASensor* m_sensor; ///< Android sensor structure - unsigned int m_index; ///< Index of the sensor - SensorState m_state; ///< Sensor state + void setEnabled(bool enabled); }; } // namespace priv diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index 78a2f1c82..6375bb68d 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -57,6 +57,8 @@ if(SFML_OS_WINDOWS) ${SRCROOT}/Win32/InputImpl.hpp ${SRCROOT}/Win32/JoystickImpl.cpp ${SRCROOT}/Win32/JoystickImpl.hpp + ${SRCROOT}/Win32/SensorImpl.hpp + ${SRCROOT}/Win32/SensorImpl.cpp ${SRCROOT}/Win32/VideoModeImpl.cpp ${SRCROOT}/Win32/WindowImplWin32.cpp ${SRCROOT}/Win32/WindowImplWin32.hpp @@ -172,7 +174,8 @@ elseif(SFML_OS_ANDROID) ${SRCROOT}/Android/JoystickImpl.hpp ${SRCROOT}/Android/JoystickImpl.cpp ${SRCROOT}/Android/SensorImpl.hpp - ${SRCROOT}/Android/SensorImpl.cpp) + ${SRCROOT}/Android/SensorImpl.cpp + ) source_group("android" FILES ${PLATFORM_SRC}) endif() diff --git a/src/SFML/Window/JoystickImpl.hpp b/src/SFML/Window/JoystickImpl.hpp index 5c63c7a56..3877d63b5 100644 --- a/src/SFML/Window/JoystickImpl.hpp +++ b/src/SFML/Window/JoystickImpl.hpp @@ -79,17 +79,29 @@ struct JoystickState #if defined(SFML_SYSTEM_WINDOWS) + #include + #elif defined(SFML_SYSTEM_LINUX) + #include + #elif defined(SFML_SYSTEM_FREEBSD) + #include + #elif defined(SFML_SYSTEM_MACOS) + #include + #elif defined(SFML_SYSTEM_IOS) + #include + #elif defined(SFML_SYSTEM_ANDROID) + #include + #endif diff --git a/src/SFML/Window/OSX/SensorImpl.mm b/src/SFML/Window/OSX/SensorImpl.cpp similarity index 70% rename from src/SFML/Window/OSX/SensorImpl.mm rename to src/SFML/Window/OSX/SensorImpl.cpp index 37f7433c7..be5e439c8 100644 --- a/src/SFML/Window/OSX/SensorImpl.mm +++ b/src/SFML/Window/OSX/SensorImpl.cpp @@ -1,8 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2013 Marco Antognini (antognini.marco@gmail.com), -// Laurent Gomila (laurent.gom@gmail.com), +// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -36,56 +35,52 @@ namespace priv //////////////////////////////////////////////////////////// void SensorImpl::initialize() { - // Not applicable + // To be implemented } + //////////////////////////////////////////////////////////// void SensorImpl::cleanup() { - // Not applicable + // To be implemented } -//////////////////////////////////////////////////////////// -SensorCaps& SensorImpl::initialize(unsigned int type) -{ - // Not applicable - SensorCaps capabilities; - capabilities.available = false; - - return capabilities; -} //////////////////////////////////////////////////////////// -void SensorImpl::terminate() +bool SensorImpl::isAvailable(Sensor::Type /*sensor*/) { - // Not applicable -} - -//////////////////////////////////////////////////////////// -SensorState& SensorImpl::update() -{ - // Not applicable - static SensorState state; - return state; -} - -//////////////////////////////////////////////////////////// -bool SensorImpl::isEnable() -{ - // Not applicable + // To be implemented return false; } -//////////////////////////////////////////////////////////// -void SensorImpl::setEnable(bool enable) -{ - // Not applicable -} //////////////////////////////////////////////////////////// -void SensorImpl::setRefreshRate(const Time& rate) +bool SensorImpl::open(Sensor::Type /*sensor*/) { - // Not applicable + // To be implemented + return false; +} + + +//////////////////////////////////////////////////////////// +void SensorImpl::close() +{ + // To be implemented +} + + +//////////////////////////////////////////////////////////// +Vector3f SensorImpl::update() +{ + // To be implemented + return Vector3f(0, 0, 0); +} + + +//////////////////////////////////////////////////////////// +void SensorImpl::setEnabled(bool /*enabled*/) +{ + // To be implemented } } // namespace priv diff --git a/src/SFML/Window/OSX/SensorImpl.hpp b/src/SFML/Window/OSX/SensorImpl.hpp index c939410ef..e5e252e6f 100644 --- a/src/SFML/Window/OSX/SensorImpl.hpp +++ b/src/SFML/Window/OSX/SensorImpl.hpp @@ -1,8 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2013 Marco Antognini (antognini.marco@gmail.com), -// Laurent Gomila (laurent.gom@gmail.com), +// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -52,53 +51,46 @@ public : static void cleanup(); //////////////////////////////////////////////////////////// - /// \brief Initialize the sensor + /// \brief Check if a sensor is available /// - /// \param type Index assigned to the sensor + /// \param sensor Sensor to check /// - /// \return The sensor capabilities + /// \return True if the sensor is available, false otherwise /// //////////////////////////////////////////////////////////// - SensorCaps& initialize(unsigned int type); + static bool isAvailable(Sensor::Type sensor); + + //////////////////////////////////////////////////////////// + /// \brief Open the sensor + /// + /// \param sensor Type of the sensor + /// + /// \return True on success, false on failure + /// + //////////////////////////////////////////////////////////// + bool open(Sensor::Type sensor); //////////////////////////////////////////////////////////// /// \brief Close the sensor /// //////////////////////////////////////////////////////////// - void terminate(); + void close(); //////////////////////////////////////////////////////////// - /// \brief Update the sensor and get its new state + /// \brief Update the sensor and get its new value /// - /// \return Sensor state + /// \return Sensor value /// //////////////////////////////////////////////////////////// - SensorState& update(); - - //////////////////////////////////////////////////////////// - /// \brief Check if the sensor is enabled - /// - /// \return True if the sensor is enabled, false otherwise - /// - //////////////////////////////////////////////////////////// - bool isEnable(); + Vector3f update(); //////////////////////////////////////////////////////////// /// \brief Enable or disable the sensor /// - /// \param enable True to enable, false to disable + /// \param enabled True to enable, false to disable /// //////////////////////////////////////////////////////////// - void setEnable(bool enable); - - //////////////////////////////////////////////////////////// - /// \brief Set the refresh rate of the sensor - /// - /// \param rate Delay between each refresh - /// - //////////////////////////////////////////////////////////// - void setRefreshRate(const Time& rate); - + void setEnabled(bool enabled); }; } // namespace priv diff --git a/src/SFML/Window/Sensor.cpp b/src/SFML/Window/Sensor.cpp index 82dd2ba60..d90fcec34 100644 --- a/src/SFML/Window/Sensor.cpp +++ b/src/SFML/Window/Sensor.cpp @@ -35,49 +35,19 @@ namespace sf //////////////////////////////////////////////////////////// bool Sensor::isAvailable(Type sensor) { - return priv::SensorManager::getInstance().getCapabilities(sensor).available; + return priv::SensorManager::getInstance().isAvailable(sensor); } //////////////////////////////////////////////////////////// -float Sensor::getResolution(Type sensor) +void Sensor::setEnabled(Type sensor, bool enabled) { - return priv::SensorManager::getInstance().getCapabilities(sensor).resolution; + return priv::SensorManager::getInstance().setEnabled(sensor, enabled); } //////////////////////////////////////////////////////////// -Vector2f Sensor::getMaximumRange(Type sensor) +Vector3f Sensor::getValue(Type sensor) { - return priv::SensorManager::getInstance().getCapabilities(sensor).maximumRange; -} - -//////////////////////////////////////////////////////////// -Time Sensor::getMinimumDelay(Type sensor) -{ - return priv::SensorManager::getInstance().getCapabilities(sensor).minimumDelay; -} - -//////////////////////////////////////////////////////////// -bool Sensor::isEnable(Type sensor) -{ - return priv::SensorManager::getInstance().isEnable(sensor); -} - -//////////////////////////////////////////////////////////// -void Sensor::setEnable(Type sensor, bool enable) -{ - return priv::SensorManager::getInstance().setEnable(sensor, enable); -} - -//////////////////////////////////////////////////////////// -void Sensor::setRefreshRate(Type sensor, const Time& rate) -{ - priv::SensorManager::getInstance().setRefreshRate(sensor, rate); -} - -//////////////////////////////////////////////////////////// -Sensor::Data Sensor::getData(Type sensor) -{ - return priv::SensorManager::getInstance().getState(sensor).pendingData->back(); + return priv::SensorManager::getInstance().getValue(sensor); } } // namespace sf diff --git a/src/SFML/Window/SensorImpl.hpp b/src/SFML/Window/SensorImpl.hpp index ca3a702f0..d111ad2b2 100644 --- a/src/SFML/Window/SensorImpl.hpp +++ b/src/SFML/Window/SensorImpl.hpp @@ -30,70 +30,27 @@ //////////////////////////////////////////////////////////// #include #include -#include -#include -#include -#include - - -namespace sf -{ -namespace priv -{ -//////////////////////////////////////////////////////////// -/// \brief Structure holding a sensor's capabilities -/// -//////////////////////////////////////////////////////////// -struct SensorCaps -{ - SensorCaps() - { - available = false; - resolution = 0; - maximumRange = Vector2f(0, 0); - minimumDelay = Time::Zero; - } - - bool available; ///< Is the sensor available on the underlying platform - float resolution; ///< How sensible the sensor is in the sensor's unit - Vector2f maximumRange; ///< Maximum range of the sensor in the sensor's unit - Time minimumDelay; ///< Minimum delay allowed between two events -}; - - -//////////////////////////////////////////////////////////// -/// \brief Structure holding a sensor's state -/// -//////////////////////////////////////////////////////////// -struct SensorState -{ - SensorState() - { - pendingData = NULL; - enabled = false; - refreshRate = Time::Zero; - } - - std::queue* pendingData; ///< Pending sensor data - bool enabled; ///< Is the sensor currently enabled? - Time refreshRate; ///< Delay between two events -}; - -} // namespace priv - -} // namespace sf - #if defined(SFML_SYSTEM_WINDOWS) + #include + #elif defined(SFML_SYSTEM_LINUX) + #include + #elif defined(SFML_SYSTEM_MACOS) + #include + #elif defined(SFML_SYSTEM_IOS) + #include + #elif defined(SFML_SYSTEM_ANDROID) + #include + #endif diff --git a/src/SFML/Window/SensorManager.cpp b/src/SFML/Window/SensorManager.cpp index c17abf8f2..c80255477 100644 --- a/src/SFML/Window/SensorManager.cpp +++ b/src/SFML/Window/SensorManager.cpp @@ -42,16 +42,38 @@ SensorManager& SensorManager::getInstance() //////////////////////////////////////////////////////////// -const SensorCaps& SensorManager::getCapabilities(unsigned int sensor) const +bool SensorManager::isAvailable(Sensor::Type sensor) { - return m_sensors[sensor].capabilities; + return m_sensors[sensor].available; } //////////////////////////////////////////////////////////// -const SensorState& SensorManager::getState(unsigned int sensor) const +void SensorManager::setEnabled(Sensor::Type sensor, bool enabled) { - return m_sensors[sensor].state; + if (m_sensors[sensor].available) + { + m_sensors[sensor].enabled = enabled; + m_sensors[sensor].sensor.setEnabled(enabled); + } + else + { + err() << "Warning: trying to enable a sensor that is not available (call Sensor::isAvailable to check it)" << std::endl; + } +} + + +//////////////////////////////////////////////////////////// +bool SensorManager::isEnabled(Sensor::Type sensor) const +{ + return m_sensors[sensor].enabled; +} + + +//////////////////////////////////////////////////////////// +Vector3f SensorManager::getValue(Sensor::Type sensor) const +{ + return m_sensors[sensor].value; } @@ -60,68 +82,31 @@ void SensorManager::update() { for (int i = 0; i < Sensor::Count; ++i) { - Item& item = m_sensors[i]; - - // Skip unavailable sensors - if (!item.capabilities.available) - continue; - - // Get the current state of the sensor - item.state = item.sensor.update(); + // Only process available sensors + if (m_sensors[i].available) + m_sensors[i].value = m_sensors[i].sensor.update(); } } -//////////////////////////////////////////////////////////// -bool SensorManager::isEnable(unsigned int sensor) -{ - if (!m_sensors[sensor].capabilities.available) - { - err() << "This sensor isn't available on your system (call Sensor::isAvailable to check it)" << std::endl; - return false; - } - - return m_sensors[sensor].sensor.isEnable(); -} -//////////////////////////////////////////////////////////// -void SensorManager::setEnable(unsigned int sensor, bool enable) -{ - if (!m_sensors[sensor].capabilities.available) - { - err() << "This sensor isn't available on your system (call Sensor::isAvailable to check it)" << std::endl; - return; - } - - m_sensors[sensor].sensor.setEnable(enable); -} - -//////////////////////////////////////////////////////////// -void SensorManager::setRefreshRate(unsigned int sensor, const Time& rate) -{ - if (!m_sensors[sensor].capabilities.available) - { - err() << "This sensor isn't available on your system (call Sensor::isAvailable to check it)" << std::endl; - return; - } - - m_sensors[sensor].sensor.setRefreshRate(rate); -} - //////////////////////////////////////////////////////////// SensorManager::SensorManager() { // Global sensor initialization SensorImpl::initialize(); - + // Per sensor initialization for (int i = 0; i < Sensor::Count; ++i) { - // Initialize the sensor and get its capabilities - m_sensors[i].capabilities = m_sensors[i].sensor.initialize(i); + // Check which sensors are available + m_sensors[i].available = SensorImpl::isAvailable(static_cast(i)); - // Available sensors are disabled by default - if (m_sensors[i].capabilities.available) - m_sensors[i].sensor.setEnable(false); + // Open the available sensors + if (m_sensors[i].available) + { + m_sensors[i].sensor.open(static_cast(i)); + m_sensors[i].sensor.setEnabled(false); + } } } @@ -131,14 +116,8 @@ SensorManager::~SensorManager() // Per sensor cleanup for (int i = 0; i < Sensor::Count; ++i) { - if (m_sensors[i].capabilities.available) - { - // Disable the sensor - m_sensors[i].sensor.setEnable(false); - - // Terminate the sensor - m_sensors[i].sensor.terminate(); - } + if (m_sensors[i].available) + m_sensors[i].sensor.close(); } // Global sensor cleanup diff --git a/src/SFML/Window/SensorManager.hpp b/src/SFML/Window/SensorManager.hpp index 8617a3c1b..50e29392f 100644 --- a/src/SFML/Window/SensorManager.hpp +++ b/src/SFML/Window/SensorManager.hpp @@ -54,58 +54,49 @@ public : static SensorManager& getInstance(); //////////////////////////////////////////////////////////// - /// \brief Get the capabilities of a sensor + /// \brief Check if a sensor is available on the underlying platform /// - /// \param sensor Index of the sensor + /// \param sensor Sensor to check /// - /// \return Capabilities of the sensor + /// \return True if the sensor is available, false otherwise /// //////////////////////////////////////////////////////////// - const SensorCaps& getCapabilities(unsigned int sensor) const; + bool isAvailable(Sensor::Type sensor); //////////////////////////////////////////////////////////// - /// \brief Get the current state of a sensor + /// \brief Enable or disable a sensor /// - /// \param sensor Index of the sensor - /// - /// \return Current state of the sensor + /// \param sensor Sensor to modify + /// \param enabled Whether it should be enabled or not /// //////////////////////////////////////////////////////////// - const SensorState& getState(unsigned int sensor) const; + void setEnabled(Sensor::Type sensor, bool enabled); + + //////////////////////////////////////////////////////////// + /// \brief Check if a sensor is enabled + /// + /// \param sensor Sensor to check + /// + /// \return True if the sensor is enabled, false otherwise + /// + //////////////////////////////////////////////////////////// + bool isEnabled(Sensor::Type sensor) const; + + //////////////////////////////////////////////////////////// + /// \brief Get the current value of a sensor + /// + /// \param sensor Sensor to read + /// + /// \return Current value of the sensor + /// + //////////////////////////////////////////////////////////// + Vector3f getValue(Sensor::Type sensor) const; //////////////////////////////////////////////////////////// /// \brief Update the state of all the sensors /// //////////////////////////////////////////////////////////// void update(); - - //////////////////////////////////////////////////////////// - /// \brief Get the current status of a sensor - /// - /// \param sensor Index of the sensor - /// - /// \return True if the sensor is enabled, false otherwise - /// - //////////////////////////////////////////////////////////// - bool isEnable(unsigned int sensor); - - //////////////////////////////////////////////////////////// - /// \brief Enable or disable a sensor - /// - /// \param sensor Index of the sensor - /// \param enable Whether it should be enabled or not - /// - //////////////////////////////////////////////////////////// - void setEnable(unsigned int sensor, bool enable); - - //////////////////////////////////////////////////////////// - /// \brief Set the refresh rate of a sensor - /// - /// \param sensor Index of the sensor - /// \param rate Delay between each event - /// - //////////////////////////////////////////////////////////// - void setRefreshRate(unsigned int sensor, const Time& rate); private: @@ -127,9 +118,10 @@ private: //////////////////////////////////////////////////////////// struct Item { - SensorImpl sensor; ///< Sensor implementation - SensorState state; ///< The current sensor state - SensorCaps capabilities; ///< The sensor capabilities + bool available; ///< Is the sensor available on this device? + bool enabled; ///< Current enable state of the sensor + SensorImpl sensor; ///< Sensor implementation + Vector3f value; ///< The current sensor value }; //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/Unix/SensorImpl.cpp b/src/SFML/Window/Unix/SensorImpl.cpp index dcc53e39e..be5e439c8 100644 --- a/src/SFML/Window/Unix/SensorImpl.cpp +++ b/src/SFML/Window/Unix/SensorImpl.cpp @@ -35,56 +35,52 @@ namespace priv //////////////////////////////////////////////////////////// void SensorImpl::initialize() { - // Not applicable + // To be implemented } + //////////////////////////////////////////////////////////// void SensorImpl::cleanup() { - // Not applicable + // To be implemented } -//////////////////////////////////////////////////////////// -SensorCaps& SensorImpl::initialize(unsigned int type) -{ - // Not applicable - SensorCaps capabilities; - capabilities.available = false; - - return capabilities; -} //////////////////////////////////////////////////////////// -void SensorImpl::terminate() +bool SensorImpl::isAvailable(Sensor::Type /*sensor*/) { - // Not applicable -} - -//////////////////////////////////////////////////////////// -SensorState& SensorImpl::update() -{ - // Not applicable - static SensorState state; - return state; -} - -//////////////////////////////////////////////////////////// -bool SensorImpl::isEnable() -{ - // Not applicable + // To be implemented return false; } -//////////////////////////////////////////////////////////// -void SensorImpl::setEnable(bool enable) -{ - // Not applicable -} //////////////////////////////////////////////////////////// -void SensorImpl::setRefreshRate(const Time& rate) +bool SensorImpl::open(Sensor::Type /*sensor*/) { - // Not applicable + // To be implemented + return false; +} + + +//////////////////////////////////////////////////////////// +void SensorImpl::close() +{ + // To be implemented +} + + +//////////////////////////////////////////////////////////// +Vector3f SensorImpl::update() +{ + // To be implemented + return Vector3f(0, 0, 0); +} + + +//////////////////////////////////////////////////////////// +void SensorImpl::setEnabled(bool /*enabled*/) +{ + // To be implemented } } // namespace priv diff --git a/src/SFML/Window/Unix/SensorImpl.hpp b/src/SFML/Window/Unix/SensorImpl.hpp index 8925681a0..1d83bee51 100644 --- a/src/SFML/Window/Unix/SensorImpl.hpp +++ b/src/SFML/Window/Unix/SensorImpl.hpp @@ -22,8 +22,8 @@ // //////////////////////////////////////////////////////////// -#ifndef SFML_SENSORIMPLLINUX_HPP -#define SFML_SENSORIMPLLINUX_HPP +#ifndef SFML_SENSORIMPLUNIX_HPP +#define SFML_SENSORIMPLUNIX_HPP namespace sf @@ -31,7 +31,7 @@ namespace sf namespace priv { //////////////////////////////////////////////////////////// -/// \brief Linux implementation of sensors +/// \brief Unix implementation of sensors /// //////////////////////////////////////////////////////////// class SensorImpl @@ -51,53 +51,46 @@ public : static void cleanup(); //////////////////////////////////////////////////////////// - /// \brief Initialize the sensor + /// \brief Check if a sensor is available /// - /// \param type Index assigned to the sensor + /// \param sensor Sensor to check /// - /// \return The sensor capabilities + /// \return True if the sensor is available, false otherwise /// //////////////////////////////////////////////////////////// - SensorCaps& initialize(unsigned int type); + static bool isAvailable(Sensor::Type sensor); + + //////////////////////////////////////////////////////////// + /// \brief Open the sensor + /// + /// \param sensor Type of the sensor + /// + /// \return True on success, false on failure + /// + //////////////////////////////////////////////////////////// + bool open(Sensor::Type sensor); //////////////////////////////////////////////////////////// /// \brief Close the sensor /// //////////////////////////////////////////////////////////// - void terminate(); + void close(); //////////////////////////////////////////////////////////// - /// \brief Update the sensor and get its new state + /// \brief Update the sensor and get its new value /// - /// \return Sensor state + /// \return Sensor value /// //////////////////////////////////////////////////////////// - SensorState& update(); - - //////////////////////////////////////////////////////////// - /// \brief Check if the sensor is enabled - /// - /// \return True if the sensor is enabled, false otherwise - /// - //////////////////////////////////////////////////////////// - bool isEnable(); + Vector3f update(); //////////////////////////////////////////////////////////// /// \brief Enable or disable the sensor /// - /// \param enable True to enable, false to disable + /// \param enabled True to enable, false to disable /// //////////////////////////////////////////////////////////// - void setEnable(bool enable); - - //////////////////////////////////////////////////////////// - /// \brief Set the refresh rate of the sensor - /// - /// \param rate Delay between each refresh - /// - //////////////////////////////////////////////////////////// - void setRefreshRate(const Time& rate); - + void setEnabled(bool enabled); }; } // namespace priv @@ -105,4 +98,4 @@ public : } // namespace sf -#endif // SFML_SENSORIMPLLINUX_HPP +#endif // SFML_SENSORIMPLUNIX_HPP diff --git a/src/SFML/Window/Win32/SensorImpl.cpp b/src/SFML/Window/Win32/SensorImpl.cpp index dcc53e39e..be5e439c8 100644 --- a/src/SFML/Window/Win32/SensorImpl.cpp +++ b/src/SFML/Window/Win32/SensorImpl.cpp @@ -35,56 +35,52 @@ namespace priv //////////////////////////////////////////////////////////// void SensorImpl::initialize() { - // Not applicable + // To be implemented } + //////////////////////////////////////////////////////////// void SensorImpl::cleanup() { - // Not applicable + // To be implemented } -//////////////////////////////////////////////////////////// -SensorCaps& SensorImpl::initialize(unsigned int type) -{ - // Not applicable - SensorCaps capabilities; - capabilities.available = false; - - return capabilities; -} //////////////////////////////////////////////////////////// -void SensorImpl::terminate() +bool SensorImpl::isAvailable(Sensor::Type /*sensor*/) { - // Not applicable -} - -//////////////////////////////////////////////////////////// -SensorState& SensorImpl::update() -{ - // Not applicable - static SensorState state; - return state; -} - -//////////////////////////////////////////////////////////// -bool SensorImpl::isEnable() -{ - // Not applicable + // To be implemented return false; } -//////////////////////////////////////////////////////////// -void SensorImpl::setEnable(bool enable) -{ - // Not applicable -} //////////////////////////////////////////////////////////// -void SensorImpl::setRefreshRate(const Time& rate) +bool SensorImpl::open(Sensor::Type /*sensor*/) { - // Not applicable + // To be implemented + return false; +} + + +//////////////////////////////////////////////////////////// +void SensorImpl::close() +{ + // To be implemented +} + + +//////////////////////////////////////////////////////////// +Vector3f SensorImpl::update() +{ + // To be implemented + return Vector3f(0, 0, 0); +} + + +//////////////////////////////////////////////////////////// +void SensorImpl::setEnabled(bool /*enabled*/) +{ + // To be implemented } } // namespace priv diff --git a/src/SFML/Window/Win32/SensorImpl.hpp b/src/SFML/Window/Win32/SensorImpl.hpp index 62ace3d04..887c3d70b 100644 --- a/src/SFML/Window/Win32/SensorImpl.hpp +++ b/src/SFML/Window/Win32/SensorImpl.hpp @@ -51,53 +51,46 @@ public : static void cleanup(); //////////////////////////////////////////////////////////// - /// \brief Initialize the sensor + /// \brief Check if a sensor is available /// - /// \param type Index assigned to the sensor + /// \param sensor Sensor to check /// - /// \return The sensor capabilities + /// \return True if the sensor is available, false otherwise /// //////////////////////////////////////////////////////////// - SensorCaps& initialize(unsigned int type); + static bool isAvailable(Sensor::Type sensor); + + //////////////////////////////////////////////////////////// + /// \brief Open the sensor + /// + /// \param sensor Type of the sensor + /// + /// \return True on success, false on failure + /// + //////////////////////////////////////////////////////////// + bool open(Sensor::Type sensor); //////////////////////////////////////////////////////////// /// \brief Close the sensor /// //////////////////////////////////////////////////////////// - void terminate(); + void close(); //////////////////////////////////////////////////////////// - /// \brief Update the sensor and get its new state + /// \brief Update the sensor and get its new value /// - /// \return Sensor state + /// \return Sensor value /// //////////////////////////////////////////////////////////// - SensorState& update(); - - //////////////////////////////////////////////////////////// - /// \brief Check if the sensor is enabled - /// - /// \return True if the sensor is enabled, false otherwise - /// - //////////////////////////////////////////////////////////// - bool isEnable(); + Vector3f update(); //////////////////////////////////////////////////////////// /// \brief Enable or disable the sensor /// - /// \param enable True to enable, false to disable + /// \param enabled True to enable, false to disable /// //////////////////////////////////////////////////////////// - void setEnable(bool enable); - - //////////////////////////////////////////////////////////// - /// \brief Set the refresh rate of the sensor - /// - /// \param rate Delay between each refresh - /// - //////////////////////////////////////////////////////////// - void setRefreshRate(const Time& rate); - + void setEnabled(bool enabled); }; } // namespace priv diff --git a/src/SFML/Window/WindowImpl.cpp b/src/SFML/Window/WindowImpl.cpp index ca82a3b5a..7d3cd52e2 100644 --- a/src/SFML/Window/WindowImpl.cpp +++ b/src/SFML/Window/WindowImpl.cpp @@ -81,17 +81,16 @@ WindowImpl* WindowImpl::create(WindowHandle handle) //////////////////////////////////////////////////////////// WindowImpl::WindowImpl() : -m_joyThreshold(0.1f) +m_joystickThreshold(0.1f) { // Get the initial joystick states JoystickManager::getInstance().update(); for (unsigned int i = 0; i < Joystick::Count; ++i) - m_joyStates[i] = JoystickManager::getInstance().getState(i); + m_joystickStates[i] = JoystickManager::getInstance().getState(i); // Get the initial sensor states - SensorManager::getInstance().update(); for (unsigned int i = 0; i < Sensor::Count; ++i) - m_senStates[i] = SensorManager::getInstance().getState(i); + m_sensorValue[i] = Vector3f(0, 0, 0); } @@ -105,7 +104,7 @@ WindowImpl::~WindowImpl() //////////////////////////////////////////////////////////// void WindowImpl::setJoystickThreshold(float threshold) { - m_joyThreshold = threshold; + m_joystickThreshold = threshold; } @@ -114,11 +113,11 @@ bool WindowImpl::popEvent(Event& event, bool block) { // If the event queue is empty, let's first check if new events are available from the OS if (m_events.empty()) - { + { // Get events from the system processJoystickEvents(); processSensorEvents(); - processEvents(); + processEvents(); // In blocking mode, we must process events until one is triggered if (block) @@ -165,12 +164,12 @@ void WindowImpl::processJoystickEvents() for (unsigned int i = 0; i < Joystick::Count; ++i) { // Copy the previous state of the joystick and get the new one - JoystickState previousState = m_joyStates[i]; - m_joyStates[i] = JoystickManager::getInstance().getState(i); + JoystickState previousState = m_joystickStates[i]; + m_joystickStates[i] = JoystickManager::getInstance().getState(i); JoystickCaps caps = JoystickManager::getInstance().getCapabilities(i); // Connection state - bool connected = m_joyStates[i].connected; + bool connected = m_joystickStates[i].connected; if (previousState.connected ^ connected) { Event event; @@ -188,8 +187,8 @@ void WindowImpl::processJoystickEvents() { Joystick::Axis axis = static_cast(j); float prevPos = previousState.axes[axis]; - float currPos = m_joyStates[i].axes[axis]; - if (fabs(currPos - prevPos) >= m_joyThreshold) + float currPos = m_joystickStates[i].axes[axis]; + if (fabs(currPos - prevPos) >= m_joystickThreshold) { Event event; event.type = Event::JoystickMoved; @@ -205,7 +204,7 @@ void WindowImpl::processJoystickEvents() for (unsigned int j = 0; j < caps.buttonCount; ++j) { bool prevPressed = previousState.buttons[j]; - bool currPressed = m_joyStates[i].buttons[j]; + bool currPressed = m_joystickStates[i].buttons[j]; if (prevPressed ^ currPressed) { @@ -224,44 +223,30 @@ void WindowImpl::processJoystickEvents() //////////////////////////////////////////////////////////// void WindowImpl::processSensorEvents() { - // First update sensor states + // First update the sensor states SensorManager::getInstance().update(); for (unsigned int i = 0; i < Sensor::Count; ++i) { - // Copy the previous state of the sensor and get the new one - SensorState previousState = m_senStates[i]; - m_senStates[i] = SensorManager::getInstance().getState(i); + Sensor::Type sensor = static_cast(i); - // Check whether it's still enabled - bool enabled = m_senStates[i].enabled; - if (previousState.enabled ^ enabled) + // Only process enabled sensors + if (SensorManager::getInstance().isEnabled(sensor)) { - Event event; - event.type = enabled ? Event::SensorEnabled : Event::SensorDisabled; - event.sensor.type = static_cast(i); - pushEvent(event); - - // This sensor has been disabled, we don't want these pending data - if (!enabled) - { - while (!m_senStates[i].pendingData->empty()) - m_senStates[i].pendingData->pop(); - } - } + // Copy the previous value of the sensor and get the new one + Vector3f previousValue = m_sensorValue[i]; + m_sensorValue[i] = SensorManager::getInstance().getValue(sensor); - if (enabled) - { - // Send pending sensor data events - while (!m_senStates[i].pendingData->empty()) + // If the value has changed, trigger an event + if (m_sensorValue[i] != previousValue) // @todo use a threshold? { Event event; - event.type = Event::SensorData; - event.sensor.type = static_cast(i); - event.sensor.data = m_senStates[i].pendingData->front(); + event.type = Event::SensorChanged; + event.sensor.type = sensor; + event.sensor.x = m_sensorValue[i].x; + event.sensor.y = m_sensorValue[i].y; + event.sensor.z = m_sensorValue[i].z; pushEvent(event); - - m_senStates[i].pendingData->pop(); } } } diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp index 040028d7f..33c0f3790 100644 --- a/src/SFML/Window/WindowImpl.hpp +++ b/src/SFML/Window/WindowImpl.hpp @@ -237,10 +237,10 @@ private : //////////////////////////////////////////////////////////// // Member data //////////////////////////////////////////////////////////// - std::queue m_events; ///< Queue of available events - JoystickState m_joyStates[Joystick::Count]; ///< Previous state of the joysticks - SensorState m_senStates[Sensor::Count]; ///< Previous state of the sensors - float m_joyThreshold; ///< Joystick threshold (minimum motion for MOVE event to be generated) + std::queue m_events; ///< Queue of available events + JoystickState m_joystickStates[Joystick::Count]; ///< Previous state of the joysticks + Vector3f m_sensorValue[Sensor::Count]; ///< Previous value of the sensors + float m_joystickThreshold; ///< Joystick threshold (minimum motion for "move" event to be generated) }; } // namespace priv diff --git a/src/SFML/Window/iOS/JoystickImpl.mm b/src/SFML/Window/iOS/JoystickImpl.mm index acaa09eae..ae6db7a15 100644 --- a/src/SFML/Window/iOS/JoystickImpl.mm +++ b/src/SFML/Window/iOS/JoystickImpl.mm @@ -26,21 +26,8 @@ // Headers //////////////////////////////////////////////////////////// #include -#include -namespace -{ - enum - { - Accelerometer, - Gyroscope, - Magnetometer, - UserAcceleration, - AbsoluteOrientation - }; -} - namespace sf { namespace priv @@ -48,182 +35,53 @@ namespace priv //////////////////////////////////////////////////////////// void JoystickImpl::initialize() { - // Nothing to do + // Not implemented } //////////////////////////////////////////////////////////// void JoystickImpl::cleanup() { - // Nothing to do + // Not implemented } //////////////////////////////////////////////////////////// bool JoystickImpl::isConnected(unsigned int index) { - switch (index) - { - case Accelerometer: - return [SFAppDelegate getInstance].motionManager.accelerometerAvailable; - - case Gyroscope: - return [SFAppDelegate getInstance].motionManager.gyroAvailable; - - case Magnetometer: - return [SFAppDelegate getInstance].motionManager.magnetometerAvailable; - - case UserAcceleration: - case AbsoluteOrientation: - return [SFAppDelegate getInstance].motionManager.deviceMotionAvailable; - - default: - return false; - } + // Not implemented + return false; } //////////////////////////////////////////////////////////// bool JoystickImpl::open(unsigned int index) { - // Enable the corresponding sensor - static const NSTimeInterval updateInterval = 1. / 60.; - switch (index) - { - case Accelerometer: - [SFAppDelegate getInstance].motionManager.accelerometerUpdateInterval = updateInterval; - [[SFAppDelegate getInstance].motionManager startAccelerometerUpdates]; - break; - - case Gyroscope: - [SFAppDelegate getInstance].motionManager.gyroUpdateInterval = updateInterval; - [[SFAppDelegate getInstance].motionManager startGyroUpdates]; - break; - - case Magnetometer: - [SFAppDelegate getInstance].motionManager.magnetometerUpdateInterval = updateInterval; - [[SFAppDelegate getInstance].motionManager startMagnetometerUpdates]; - break; - - case UserAcceleration: - case AbsoluteOrientation: - if (![SFAppDelegate getInstance].motionManager.deviceMotionActive) - { - [SFAppDelegate getInstance].motionManager.deviceMotionUpdateInterval = updateInterval; - [[SFAppDelegate getInstance].motionManager startDeviceMotionUpdates]; - } - break; - - default: - break; - } - - // Save the index - m_index = index; - - return true; + // Not implemented + return false; } //////////////////////////////////////////////////////////// void JoystickImpl::close() { - // Disable the corresponding sensor - switch (m_index) - { - case Accelerometer: - if ([SFAppDelegate getInstance].motionManager.accelerometerActive) - [[SFAppDelegate getInstance].motionManager stopAccelerometerUpdates]; - break; - - case Gyroscope: - if ([SFAppDelegate getInstance].motionManager.gyroActive) - [[SFAppDelegate getInstance].motionManager stopGyroUpdates]; - break; - - case Magnetometer: - if ([SFAppDelegate getInstance].motionManager.magnetometerActive) - [[SFAppDelegate getInstance].motionManager stopMagnetometerUpdates]; - break; - - case UserAcceleration: - case AbsoluteOrientation: - if ([SFAppDelegate getInstance].motionManager.deviceMotionActive) - [[SFAppDelegate getInstance].motionManager stopDeviceMotionUpdates]; - break; - - default: - break; - } + // Not implemented } //////////////////////////////////////////////////////////// JoystickCaps JoystickImpl::getCapabilities() const { - JoystickCaps caps; - - // All the connected joysticks have (X, Y, Z) axes - caps.axes[Joystick::X] = true; - caps.axes[Joystick::Y] = true; - caps.axes[Joystick::Z] = true; - - return caps; + // Not implemented + return JoystickCaps(); } //////////////////////////////////////////////////////////// JoystickState JoystickImpl::update() { - JoystickState state; - - // Always connected - state.connected = true; - - CMMotionManager* manager = [SFAppDelegate getInstance].motionManager; - - switch (m_index) - { - case Accelerometer: - // Acceleration is given in G (reminder: 1G is regular earth gravity, 9.81 m/s^2), in range [-2, 2] (could be more on newer devices?) - state.axes[Joystick::X] = manager.accelerometerData.acceleration.x; - state.axes[Joystick::Y] = manager.accelerometerData.acceleration.y; - state.axes[Joystick::Z] = manager.accelerometerData.acceleration.z; - break; - - case Gyroscope: - // Rotation rates are given in rad/s, in range [?, ?] - state.axes[Joystick::X] = manager.gyroData.rotationRate.x; - state.axes[Joystick::Y] = manager.gyroData.rotationRate.y; - state.axes[Joystick::Z] = manager.gyroData.rotationRate.z; - break; - - case Magnetometer: - // Magnetic field is given in microteslas, in range [?, ?] - state.axes[Joystick::X] = manager.magnetometerData.magneticField.x; - state.axes[Joystick::Y] = manager.magnetometerData.magneticField.y; - state.axes[Joystick::Z] = manager.magnetometerData.magneticField.z; - break; - - case UserAcceleration: - // User acceleration (gravity removed), same unit and range as raw accelerometer values - state.axes[Joystick::X] = manager.deviceMotion.userAcceleration.x; - state.axes[Joystick::Y] = manager.deviceMotion.userAcceleration.y; - state.axes[Joystick::Z] = manager.deviceMotion.userAcceleration.z; - break; - - case AbsoluteOrientation: - // Absolute rotation (Euler) angles are given in radians, in range [-PI, PI] - state.axes[Joystick::X] = manager.deviceMotion.attitude.yaw; - state.axes[Joystick::Y] = manager.deviceMotion.attitude.pitch; - state.axes[Joystick::Z] = manager.deviceMotion.attitude.roll; - break; - - default: - break; - } - - return state; + // Not implemented + return JoystickState(); } } // namespace priv diff --git a/src/SFML/Window/iOS/SensorImpl.hpp b/src/SFML/Window/iOS/SensorImpl.hpp index bf0c11423..399fd8f11 100644 --- a/src/SFML/Window/iOS/SensorImpl.hpp +++ b/src/SFML/Window/iOS/SensorImpl.hpp @@ -25,6 +25,11 @@ #ifndef SFML_SENSORIMPLIOS_HPP #define SFML_SENSORIMPLIOS_HPP +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include + namespace sf { @@ -51,53 +56,54 @@ public : static void cleanup(); //////////////////////////////////////////////////////////// - /// \brief Initialize the sensor + /// \brief Check if a sensor is available /// - /// \param type Index assigned to the sensor + /// \param sensor Sensor to check /// - /// \return The sensor capabilities + /// \return True if the sensor is available, false otherwise /// //////////////////////////////////////////////////////////// - SensorCaps& initialize(unsigned int type); + static bool isAvailable(Sensor::Type sensor); + + //////////////////////////////////////////////////////////// + /// \brief Open the sensor + /// + /// \param sensor Type of the sensor + /// + /// \return True on success, false on failure + /// + //////////////////////////////////////////////////////////// + bool open(Sensor::Type sensor); //////////////////////////////////////////////////////////// /// \brief Close the sensor /// //////////////////////////////////////////////////////////// - void terminate(); + void close(); //////////////////////////////////////////////////////////// - /// \brief Update the sensor and get its new state + /// \brief Update the sensor and get its new value /// - /// \return Sensor state + /// \return Sensor value /// //////////////////////////////////////////////////////////// - SensorState& update(); - - //////////////////////////////////////////////////////////// - /// \brief Check if the sensor is enabled - /// - /// \return True if the sensor is enabled, false otherwise - /// - //////////////////////////////////////////////////////////// - bool isEnable(); + Vector3f update(); //////////////////////////////////////////////////////////// /// \brief Enable or disable the sensor /// - /// \param enable True to enable, false to disable + /// \param enabled True to enable, false to disable /// //////////////////////////////////////////////////////////// - void setEnable(bool enable); - - //////////////////////////////////////////////////////////// - /// \brief Set the refresh rate of the sensor - /// - /// \param rate Delay between each refresh - /// - //////////////////////////////////////////////////////////// - void setRefreshRate(const Time& rate); + void setEnabled(bool enabled); +private : + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + Sensor::Type m_sensor; ///< Type of the sensor + bool m_enabled; ///< Enable state of the sensor }; } // namespace priv diff --git a/src/SFML/Window/iOS/SensorImpl.mm b/src/SFML/Window/iOS/SensorImpl.mm index d8ba51da5..dd923fabd 100644 --- a/src/SFML/Window/iOS/SensorImpl.mm +++ b/src/SFML/Window/iOS/SensorImpl.mm @@ -28,6 +28,17 @@ #include +namespace +{ + unsigned int deviceMotionEnabledCount = 0; + + float toDegrees(float radians) + { + return radians * 180.f / 3.141592654f; + } +} + + namespace sf { namespace priv @@ -35,56 +46,194 @@ namespace priv //////////////////////////////////////////////////////////// void SensorImpl::initialize() { - // To implement + // Nothing to do } + //////////////////////////////////////////////////////////// void SensorImpl::cleanup() { - // To implement + // Nothing to do } -//////////////////////////////////////////////////////////// -SensorCaps& SensorImpl::initialize(unsigned int type) -{ - // To implement - SensorCaps capabilities; - capabilities.available = false; - - return capabilities; -} //////////////////////////////////////////////////////////// -void SensorImpl::terminate() +bool SensorImpl::isAvailable(Sensor::Type sensor) { - // To implement + switch (sensor) + { + case Sensor::Accelerometer: + return [SFAppDelegate getInstance].motionManager.accelerometerAvailable; + + case Sensor::Gyroscope: + return [SFAppDelegate getInstance].motionManager.gyroAvailable; + + case Sensor::Magnetometer: + return [SFAppDelegate getInstance].motionManager.magnetometerAvailable; + + case Sensor::Gravity: + case Sensor::UserAcceleration: + case Sensor::Orientation: + return [SFAppDelegate getInstance].motionManager.deviceMotionAvailable; + + default: + return false; + } } -//////////////////////////////////////////////////////////// -SensorState& SensorImpl::update() -{ - // To implement - static SensorState state; - return state; -} //////////////////////////////////////////////////////////// -bool SensorImpl::isEnable() +bool SensorImpl::open(Sensor::Type sensor) { - // To implement - return false; + // Store the sensor type + m_sensor = sensor; + + // The sensor is disabled by default + m_enabled = false; + + // Set the refresh rate (use the maximum allowed) + static const NSTimeInterval updateInterval = 1. / 60.; + switch (sensor) + { + case Sensor::Accelerometer: + [SFAppDelegate getInstance].motionManager.accelerometerUpdateInterval = updateInterval; + break; + + case Sensor::Gyroscope: + [SFAppDelegate getInstance].motionManager.gyroUpdateInterval = updateInterval; + break; + + case Sensor::Magnetometer: + [SFAppDelegate getInstance].motionManager.magnetometerUpdateInterval = updateInterval; + break; + + case Sensor::Gravity: + case Sensor::UserAcceleration: + case Sensor::Orientation: + [SFAppDelegate getInstance].motionManager.deviceMotionUpdateInterval = updateInterval; + break; + + default: + break; + } + + return true; } -//////////////////////////////////////////////////////////// -void SensorImpl::setEnable(bool enable) -{ - // To implement -} //////////////////////////////////////////////////////////// -void SensorImpl::setRefreshRate(const Time& rate) +void SensorImpl::close() { - // To implement + // Nothing to do +} + + +//////////////////////////////////////////////////////////// +Vector3f SensorImpl::update() +{ + Vector3f value; + CMMotionManager* manager = [SFAppDelegate getInstance].motionManager; + + switch (m_sensor) + { + case Sensor::Accelerometer: + // Acceleration is given in G, convert to m/sē + value.x = manager.accelerometerData.acceleration.x * 9.81f; + value.y = manager.accelerometerData.acceleration.y * 9.81f; + value.z = manager.accelerometerData.acceleration.z * 9.81f; + break; + + case Sensor::Gyroscope: + // Rotation rates are given in rad/s, convert to deg/s + value.x = toDegrees(manager.gyroData.rotationRate.x); + value.y = toDegrees(manager.gyroData.rotationRate.y); + value.z = toDegrees(manager.gyroData.rotationRate.z); + break; + + case Sensor::Magnetometer: + // Magnetic field is given in microteslas + value.x = manager.magnetometerData.magneticField.x; + value.y = manager.magnetometerData.magneticField.y; + value.z = manager.magnetometerData.magneticField.z; + break; + + case Sensor::UserAcceleration: + // User acceleration is given in G, convert to m/sē + value.x = manager.deviceMotion.userAcceleration.x * 9.81f; + value.y = manager.deviceMotion.userAcceleration.y * 9.81f; + value.z = manager.deviceMotion.userAcceleration.z * 9.81f; + break; + + case Sensor::Orientation: + // Absolute rotation (Euler) angles are given in radians, convert to degrees + value.x = toDegrees(manager.deviceMotion.attitude.yaw); + value.y = toDegrees(manager.deviceMotion.attitude.pitch); + value.z = toDegrees(manager.deviceMotion.attitude.roll); + break; + + default: + break; + } + + return value; +} + + +//////////////////////////////////////////////////////////// +void SensorImpl::setEnabled(bool enabled) +{ + // Don't do anything if the state is the same + if (enabled == m_enabled) + return; + + switch (index) + { + case Sensor::Accelerometer: + if (enabled) + [[SFAppDelegate getInstance].motionManager startAccelerometerUpdates]; + else + [[SFAppDelegate getInstance].motionManager stopAccelerometerUpdates]; + break; + + case Sensor::Gyroscope: + if (enabled) + [[SFAppDelegate getInstance].motionManager startGyroUpdates]; + else + [[SFAppDelegate getInstance].motionManager stopGyroUpdates]; + break; + + case Sensor::Magnetometer: + if (enabled) + [[SFAppDelegate getInstance].motionManager startMagnetometerUpdates]; + else + [[SFAppDelegate getInstance].motionManager stopMagnetometerUpdates]; + break; + + case Sensor::Gravity: + case Sensor::UserAcceleration: + case Sensor::Orientation: + // these 3 sensors all share the same implementation, so we must disable + // it only if the three sensors are disabled + if (enabled) + { + if (deviceMotionEnabledCount == 0) + [[SFAppDelegate getInstance].motionManager startDeviceMotionUpdates]; + deviceMotionEnabledCount++; + } + else + { + deviceMotionEnabledCount--; + if (deviceMotionEnabledCount == 0) + [[SFAppDelegate getInstance].motionManager stopDeviceMotionUpdates]; + } + break; + + default: + break; + } + + // Update the enable state + m_enabled = enabled; } } // namespace priv