[Android] Moved sensor implementation to the right place
This commit is contained in:
parent
7daaaa649e
commit
349fe380e4
@ -52,12 +52,15 @@ namespace sf
|
|||||||
{
|
{
|
||||||
namespace priv
|
namespace priv
|
||||||
{
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
ActivityStates* retrieveStates(ANativeActivity* activity)
|
ActivityStates* retrieveStates(ANativeActivity* activity)
|
||||||
{
|
{
|
||||||
// Hide the ugly cast we find in each callback function
|
// Hide the ugly cast we find in each callback function
|
||||||
return (ActivityStates*)activity->instance;
|
return (ActivityStates*)activity->instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void initializeMain(ActivityStates* states)
|
static void initializeMain(ActivityStates* states)
|
||||||
{
|
{
|
||||||
// Protect from concurent access
|
// Protect from concurent access
|
||||||
@ -72,6 +75,8 @@ static void initializeMain(ActivityStates* states)
|
|||||||
AConfiguration_fromAssetManager(states->config, states->activity->assetManager);
|
AConfiguration_fromAssetManager(states->config, states->activity->assetManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void terminateMain(ActivityStates* states)
|
static void terminateMain(ActivityStates* states)
|
||||||
{
|
{
|
||||||
// Protect from concurent access
|
// Protect from concurent access
|
||||||
@ -82,6 +87,8 @@ static void terminateMain(ActivityStates* states)
|
|||||||
ANativeActivity_finish(states->activity);
|
ANativeActivity_finish(states->activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
void* main(ActivityStates* states)
|
void* main(ActivityStates* states)
|
||||||
{
|
{
|
||||||
// Initialize the thread before giving the hand
|
// Initialize the thread before giving the hand
|
||||||
@ -111,10 +118,14 @@ void* main(ActivityStates* states)
|
|||||||
} // namespace priv
|
} // namespace priv
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onStart(ANativeActivity* activity)
|
static void onStart(ANativeActivity* activity)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onResume(ANativeActivity* activity)
|
static void onResume(ANativeActivity* activity)
|
||||||
{
|
{
|
||||||
// Retrieve our activity states from the activity instance
|
// Retrieve our activity states from the activity instance
|
||||||
@ -128,6 +139,8 @@ static void onResume(ANativeActivity* activity)
|
|||||||
states->pendingEvents.push_back(event);
|
states->pendingEvents.push_back(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onPause(ANativeActivity* activity)
|
static void onPause(ANativeActivity* activity)
|
||||||
{
|
{
|
||||||
// Retrieve our activity states from the activity instance
|
// Retrieve our activity states from the activity instance
|
||||||
@ -141,10 +154,14 @@ static void onPause(ANativeActivity* activity)
|
|||||||
states->pendingEvents.push_back(event);
|
states->pendingEvents.push_back(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onStop(ANativeActivity* activity)
|
static void onStop(ANativeActivity* activity)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onDestroy(ANativeActivity* activity)
|
static void onDestroy(ANativeActivity* activity)
|
||||||
{
|
{
|
||||||
// Retrieve our activity states from the activity instance
|
// Retrieve our activity states from the activity instance
|
||||||
@ -186,6 +203,8 @@ static void onDestroy(ANativeActivity* activity)
|
|||||||
// The application should now terminate
|
// The application should now terminate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window)
|
static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window)
|
||||||
{
|
{
|
||||||
sf::priv::ActivityStates* states = sf::priv::retrieveStates(activity);
|
sf::priv::ActivityStates* states = sf::priv::retrieveStates(activity);
|
||||||
@ -209,6 +228,8 @@ static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* wind
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window)
|
static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window)
|
||||||
{
|
{
|
||||||
sf::priv::ActivityStates* states = sf::priv::retrieveStates(activity);
|
sf::priv::ActivityStates* states = sf::priv::retrieveStates(activity);
|
||||||
@ -232,14 +253,20 @@ static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* wi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onNativeWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* window)
|
static void onNativeWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* window)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onNativeWindowResized(ANativeActivity* activity, ANativeWindow* window)
|
static void onNativeWindowResized(ANativeActivity* activity, ANativeWindow* window)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue)
|
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue)
|
||||||
{
|
{
|
||||||
// Retrieve our activity states from the activity instance
|
// Retrieve our activity states from the activity instance
|
||||||
@ -254,6 +281,8 @@ static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue)
|
static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue)
|
||||||
{
|
{
|
||||||
// Retrieve our activity states from the activity instance
|
// Retrieve our activity states from the activity instance
|
||||||
@ -268,16 +297,14 @@ static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onWindowFocusChanged(ANativeActivity* activity, int focused)
|
static void onWindowFocusChanged(ANativeActivity* activity, int focused)
|
||||||
{
|
{
|
||||||
// Retrieve our activity states from the activity instance
|
|
||||||
sf::priv::ActivityStates* states = sf::priv::retrieveStates(activity);
|
|
||||||
|
|
||||||
// Disable or enable sensors according the window focused state
|
|
||||||
if (states->enableSensors && states->disableSensors)
|
|
||||||
focused ? states->enableSensors() : states->disableSensors();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onContentRectChanged(ANativeActivity* activity, const ARect* rect)
|
static void onContentRectChanged(ANativeActivity* activity, const ARect* rect)
|
||||||
{
|
{
|
||||||
// Retrieve our activity states from the activity instance
|
// Retrieve our activity states from the activity instance
|
||||||
@ -293,10 +320,14 @@ static void onContentRectChanged(ANativeActivity* activity, const ARect* rect)
|
|||||||
states->pendingEvents.push_back(event);
|
states->pendingEvents.push_back(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onConfigurationChanged(ANativeActivity* activity)
|
static void onConfigurationChanged(ANativeActivity* activity)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen)
|
static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen)
|
||||||
{
|
{
|
||||||
*outLen = 0;
|
*outLen = 0;
|
||||||
@ -304,16 +335,22 @@ static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
static void onLowMemory(ANativeActivity* activity)
|
static void onLowMemory(ANativeActivity* activity)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
int dummyProcessEvent(int fd, int events, void* data)
|
int dummyProcessEvent(int fd, int events, void* data)
|
||||||
{
|
{
|
||||||
// Do nothing
|
// Do nothing
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize)
|
void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize)
|
||||||
{
|
{
|
||||||
// Create an activity states (will keep us in the know, about events we care)
|
// Create an activity states (will keep us in the know, about events we care)
|
||||||
|
@ -62,9 +62,6 @@ struct ActivityStates
|
|||||||
std::vector<Event> pendingEvents;
|
std::vector<Event> pendingEvents;
|
||||||
int (*processEvent)(int fd, int events, void* data);
|
int (*processEvent)(int fd, int events, void* data);
|
||||||
|
|
||||||
void (*enableSensors)();
|
|
||||||
void (*disableSensors)();
|
|
||||||
|
|
||||||
std::map<int, Vector2i> touchEvents;
|
std::map<int, Vector2i> touchEvents;
|
||||||
Vector2i mousePosition;
|
Vector2i mousePosition;
|
||||||
bool isButtonPressed[Mouse::ButtonCount];
|
bool isButtonPressed[Mouse::ButtonCount];
|
||||||
|
@ -26,101 +26,8 @@
|
|||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/JoystickImpl.hpp>
|
#include <SFML/Window/JoystickImpl.hpp>
|
||||||
#include <SFML/System/Android/Activity.hpp>
|
|
||||||
#include <SFML/System/Lock.hpp>
|
|
||||||
#include <SFML/System/Vector3.hpp>
|
|
||||||
#include <android/looper.h>
|
|
||||||
#include <android/sensor.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
Accelerometer,
|
|
||||||
Gyroscope,
|
|
||||||
Magnetometer,
|
|
||||||
UserAcceleration,
|
|
||||||
AbsoluteOrientation,
|
|
||||||
Count
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int32_t updateInterval = (1000L/60)*1000;
|
|
||||||
|
|
||||||
ALooper* looper;
|
|
||||||
ASensorManager* sensorManager;
|
|
||||||
ASensorEventQueue* sensorEventQueue;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
const ASensor* device;
|
|
||||||
sf::Vector3f data;
|
|
||||||
} sensors[Count];
|
|
||||||
|
|
||||||
bool areSensorsEnabled;
|
|
||||||
|
|
||||||
int processSensorEvents(int fd, int events, void* data)
|
|
||||||
{
|
|
||||||
ASensorEvent event;
|
|
||||||
|
|
||||||
while (ASensorEventQueue_getEvents(sensorEventQueue, &event, 1) > 0)
|
|
||||||
{
|
|
||||||
// Cache the latest data
|
|
||||||
switch (event.sensor)
|
|
||||||
{
|
|
||||||
case ASENSOR_TYPE_ACCELEROMETER:
|
|
||||||
sensors[Accelerometer].data.x = event.acceleration.x;
|
|
||||||
sensors[Accelerometer].data.y = event.acceleration.y;
|
|
||||||
sensors[Accelerometer].data.z = event.acceleration.z;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ASENSOR_TYPE_GYROSCOPE:
|
|
||||||
sensors[Gyroscope].data.x = event.vector.x;
|
|
||||||
sensors[Gyroscope].data.y = event.vector.y;
|
|
||||||
sensors[Gyroscope].data.z = event.vector.z;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ASENSOR_TYPE_MAGNETIC_FIELD:
|
|
||||||
sensors[Magnetometer].data.x = event.magnetic.x;
|
|
||||||
sensors[Magnetometer].data.y = event.magnetic.y;
|
|
||||||
sensors[Magnetometer].data.z = event.magnetic.z;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void enableSensors()
|
|
||||||
{
|
|
||||||
// (Re)start monitoring sensors with 60 events per second
|
|
||||||
for (unsigned int i = 0; i < Count; ++i)
|
|
||||||
{
|
|
||||||
if (sensors[i].device != NULL)
|
|
||||||
{
|
|
||||||
ASensorEventQueue_enableSensor(sensorEventQueue, sensors[i].device);
|
|
||||||
ASensorEventQueue_setEventRate(sensorEventQueue, sensors[i].device, updateInterval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
areSensorsEnabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disableSensors()
|
|
||||||
{
|
|
||||||
// Stop monitoring sensors (it avoids consuming battery)
|
|
||||||
for (unsigned int i = 0; i < Count; ++i)
|
|
||||||
{
|
|
||||||
if (sensors[i].device != NULL)
|
|
||||||
{
|
|
||||||
ASensorEventQueue_disableSensor(sensorEventQueue, sensors[i].device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
areSensorsEnabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
namespace priv
|
||||||
@ -128,46 +35,7 @@ namespace priv
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void JoystickImpl::initialize()
|
void JoystickImpl::initialize()
|
||||||
{
|
{
|
||||||
// Register callbacks to pause sensors when the device is in standby mode
|
// To implement
|
||||||
ActivityStates* states = getActivity(NULL);
|
|
||||||
|
|
||||||
{
|
|
||||||
Lock lock(states->mutex);
|
|
||||||
|
|
||||||
states->enableSensors = enableSensors;
|
|
||||||
states->disableSensors = disableSensors;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the unique sensor manager
|
|
||||||
sensorManager = ASensorManager_getInstance();
|
|
||||||
|
|
||||||
// Prepare available sensors
|
|
||||||
sensors[Accelerometer].device = ASensorManager_getDefaultSensor(sensorManager,
|
|
||||||
ASENSOR_TYPE_ACCELEROMETER);
|
|
||||||
sensors[Gyroscope].device = ASensorManager_getDefaultSensor(sensorManager,
|
|
||||||
ASENSOR_TYPE_GYROSCOPE);
|
|
||||||
sensors[Magnetometer].device = ASensorManager_getDefaultSensor(sensorManager,
|
|
||||||
ASENSOR_TYPE_MAGNETIC_FIELD);
|
|
||||||
|
|
||||||
// User acceleration and absolute orientation sensors are unavailable on Android
|
|
||||||
// (at least, unavailable from the android C API)
|
|
||||||
sensors[UserAcceleration].device = NULL;
|
|
||||||
sensors[AbsoluteOrientation].device = NULL;
|
|
||||||
|
|
||||||
// Get the looper associated with this thread
|
|
||||||
looper = ALooper_forThread();
|
|
||||||
|
|
||||||
// Create the sensor events queue and attach it to the looper
|
|
||||||
sensorEventQueue = ASensorManager_createEventQueue(sensorManager, looper,
|
|
||||||
1, &processSensorEvents, NULL);
|
|
||||||
|
|
||||||
// Set the event rate (not to consume too much battery)
|
|
||||||
ASensorEventQueue_setEventRate(sensorEventQueue, sensors[Accelerometer].device, updateInterval);
|
|
||||||
ASensorEventQueue_setEventRate(sensorEventQueue, sensors[Gyroscope].device, updateInterval);
|
|
||||||
ASensorEventQueue_setEventRate(sensorEventQueue, sensors[Magnetometer].device, updateInterval);
|
|
||||||
|
|
||||||
// Start monitoring sensors
|
|
||||||
enableSensors();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -175,33 +43,22 @@ void JoystickImpl::initialize()
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void JoystickImpl::cleanup()
|
void JoystickImpl::cleanup()
|
||||||
{
|
{
|
||||||
// Stop monitoring sensors
|
// To implement
|
||||||
disableSensors();
|
|
||||||
|
|
||||||
// Detach the sensor events queue from the looper and destroy it
|
|
||||||
ASensorManager_destroyEventQueue(sensorManager, sensorEventQueue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool JoystickImpl::isConnected(unsigned int index)
|
bool JoystickImpl::isConnected(unsigned int index)
|
||||||
{
|
{
|
||||||
// If sensors aren't paused and the requested sensor available
|
// To implement
|
||||||
return (areSensorsEnabled && sensors[index].device);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool JoystickImpl::open(unsigned int index)
|
bool JoystickImpl::open(unsigned int index)
|
||||||
{
|
{
|
||||||
// Save the index if sensor is available
|
// To implement
|
||||||
if(sensors[index].device)
|
|
||||||
{
|
|
||||||
m_index = index;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,41 +66,23 @@ bool JoystickImpl::open(unsigned int index)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void JoystickImpl::close()
|
void JoystickImpl::close()
|
||||||
{
|
{
|
||||||
// Nothing to do
|
// To implement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
JoystickCaps JoystickImpl::getCapabilities() const
|
JoystickCaps JoystickImpl::getCapabilities() const
|
||||||
{
|
{
|
||||||
JoystickCaps caps;
|
// To implement
|
||||||
|
return JoystickCaps();
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
JoystickState JoystickImpl::update()
|
JoystickState JoystickImpl::update()
|
||||||
{
|
{
|
||||||
JoystickState state;
|
// To implement
|
||||||
|
return JoystickState();
|
||||||
// Poll latest sensor events
|
|
||||||
ALooper_pollAll(0, NULL, NULL, NULL);
|
|
||||||
|
|
||||||
// Always connected
|
|
||||||
state.connected = sensors[m_index].device ? true : false;
|
|
||||||
|
|
||||||
// Use our cache
|
|
||||||
state.axes[Joystick::X] = sensors[m_index].data.x;
|
|
||||||
state.axes[Joystick::Y] = sensors[m_index].data.y;
|
|
||||||
state.axes[Joystick::Z] = sensors[m_index].data.z;
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
@ -28,8 +28,19 @@
|
|||||||
#include <SFML/Window/SensorImpl.hpp>
|
#include <SFML/Window/SensorImpl.hpp>
|
||||||
#include <SFML/System/Lock.hpp>
|
#include <SFML/System/Lock.hpp>
|
||||||
#include <SFML/System/Time.hpp>
|
#include <SFML/System/Time.hpp>
|
||||||
|
#include <SFML/System/Android/Activity.hpp>
|
||||||
|
#include <android/looper.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
ALooper* looper;
|
||||||
|
|
||||||
|
ASensorManager* sensorManager;
|
||||||
|
ASensorEventQueue* sensorEventQueue;
|
||||||
|
std::queue<sf::Sensor::Data> sensorData[sf::Sensor::Count];
|
||||||
|
}
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
namespace priv
|
||||||
@ -37,21 +48,55 @@ namespace priv
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SensorImpl::initialize()
|
void SensorImpl::initialize()
|
||||||
{
|
{
|
||||||
// To implement
|
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SensorImpl::cleanup()
|
void SensorImpl::cleanup()
|
||||||
{
|
{
|
||||||
// To implement
|
// Detach the sensor events queue from the looper and destroy it
|
||||||
|
ASensorManager_destroyEventQueue(sensorManager, sensorEventQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SensorCaps& SensorImpl::initialize(unsigned int type)
|
SensorCaps& SensorImpl::initialize(unsigned int type)
|
||||||
{
|
{
|
||||||
// To implement
|
// Get the default sensor matching the type
|
||||||
SensorCaps capabilities;
|
m_sensor = getDefaultSensor(type);
|
||||||
|
|
||||||
|
static SensorCaps capabilities;
|
||||||
|
|
||||||
|
if (!m_sensor)
|
||||||
|
{
|
||||||
|
// Sensor not available, stop here
|
||||||
capabilities.available = false;
|
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;
|
return capabilities;
|
||||||
}
|
}
|
||||||
@ -59,34 +104,126 @@ SensorCaps& SensorImpl::initialize(unsigned int type)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SensorImpl::terminate()
|
void SensorImpl::terminate()
|
||||||
{
|
{
|
||||||
// To implement
|
// Nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SensorState& SensorImpl::update()
|
SensorState& SensorImpl::update()
|
||||||
{
|
{
|
||||||
// To implement
|
// Update our pending sensor data lists
|
||||||
static SensorState state;
|
ALooper_pollAll(0, NULL, NULL, NULL);
|
||||||
return state;
|
|
||||||
|
return m_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool SensorImpl::isEnable()
|
bool SensorImpl::isEnable()
|
||||||
{
|
{
|
||||||
// To implement
|
return m_state.enabled;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SensorImpl::setEnable(bool enable)
|
void SensorImpl::setEnable(bool enable)
|
||||||
{
|
{
|
||||||
// To implement
|
if (enable)
|
||||||
|
ASensorEventQueue_enableSensor(sensorEventQueue, m_sensor);
|
||||||
|
else
|
||||||
|
ASensorEventQueue_disableSensor(sensorEventQueue, m_sensor);
|
||||||
|
|
||||||
|
m_state.enabled = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void SensorImpl::setRefreshRate(const Time& rate)
|
void SensorImpl::setRefreshRate(const Time& rate)
|
||||||
{
|
{
|
||||||
// To implement
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
int SensorImpl::processSensorEvents(int fd, int events, void* data)
|
||||||
|
{
|
||||||
|
ASensorEvent event;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
@ -25,6 +25,10 @@
|
|||||||
#ifndef SFML_SENSORIMPLANDROID_HPP
|
#ifndef SFML_SENSORIMPLANDROID_HPP
|
||||||
#define SFML_SENSORIMPLANDROID_HPP
|
#define SFML_SENSORIMPLANDROID_HPP
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <android/sensor.h>
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
@ -98,6 +102,35 @@ public :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void setRefreshRate(const Time& rate);
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
Loading…
Reference in New Issue
Block a user