CUGL
Cornell University Game Library
Public Member Functions | Protected Member Functions | Protected Attributes | Friends | List of all members
cugl::GestureInput Class Reference

#include <CUGestureInput.h>

Inheritance diagram for cugl::GestureInput:
cugl::InputDevice

Public Member Functions

bool ready () const
 
GestureState getState () const
 
float getTolerance () const
 
void setTolerance (float tolerance)
 
std::vector< std::string > getGestures () const
 
bool pause ()
 
bool resume ()
 
bool record (const std::string &key)
 
bool record (const char *key)
 
bool abort ()
 
bool remove (const std::string &key)
 
bool remove (const char *key)
 
bool rename (const std::string &key, const std::string &name)
 
bool rename (const char *key, const std::string &name)
 
bool rename (const std::string &key, const char *name)
 
bool rename (const char *key, const char *name)
 
bool load (const std::string &file)
 
bool load (const char *file)
 
bool load (const Pathname &file)
 
void loadAsync (const std::string &file, std::function< void(bool success)> callback)
 
void loadAsync (const char *file, std::function< void(bool success)> callback)
 
void loadAsync (const Pathname &file, std::function< void(bool success)> callback)
 
bool loadAsset (const std::string &file)
 
bool loadAsset (const char *file)
 
void loadAssetAsync (const std::string &file, std::function< void(bool success)> callback)
 
void loadAssetAsync (const char *file, std::function< void(bool success)> callback)
 
bool save (const std::string &file)
 
bool save (const char *file)
 
bool save (Pathname &file)
 
void saveAsync (const std::string &file, std::function< void(bool success)> callback)
 
void saveAsync (const char *file, std::function< void(bool success)> callback)
 
void saveAsync (Pathname &file, std::function< void(bool success)> callback)
 
bool didMatch () const
 
const std::string getKey () const
 
const float getError () const
 
int getFingers () const
 
virtual bool requestFocus (Uint32 key) override
 
bool isListener (Uint32 key) const
 
const GestureListener getMatchListener (Uint32 key) const
 
const GestureStateListener getStateListener (Uint32 key) const
 
bool addMatchListener (Uint32 key, GestureListener listener)
 
bool addStateListener (Uint32 key, GestureStateListener listener)
 
bool removeMatchListener (Uint32 key)
 
bool removeStateListener (Uint32 key)
 
- Public Member Functions inherited from cugl::InputDevice
Uint32 currentFocus () const
 
void releaseFocus ()
 

Protected Member Functions

void changeState (GestureState state, bool thread=true)
 
bool read (const std::string &file, std::function< void(bool success)> callback=nullptr)
 
bool store (Pathname &file, std::function< void(bool success)> callback=nullptr)
 
 GestureInput ()
 
virtual ~GestureInput ()
 
virtual void dispose () override
 
virtual void clearState () override
 
virtual bool updateState (const SDL_Event &event, const Timestamp &stamp) override
 
virtual void queryEvents (std::vector< Uint32 > &eventset) override
 
- Protected Member Functions inherited from cugl::InputDevice
 InputDevice ()
 
virtual ~InputDevice ()
 
virtual bool init ()
 

Protected Attributes

GestureState _state
 
GestureState _waits
 
float _tolerance
 
std::unordered_map< SDL_GestureID, std::string > _gestures
 
std::unordered_map< std::string, SDL_GestureID > _inverses
 
std::string _recrd
 
bool _match
 
GestureEvent _event
 
std::shared_ptr< ThreadPool_loader
 
std::mutex _lock
 
std::condition_variable _monitor
 
std::unordered_map< Uint32, GestureListener_matchListeners
 
std::unordered_map< Uint32, GestureStateListener_stateListeners
 
- Protected Attributes inherited from cugl::InputDevice
Uint32 _focus
 

Friends

class Input
 

Additional Inherited Members

- Static Public Attributes inherited from cugl::InputDevice
static const Uint32 RESERVED_KEY = UINT32_MAX
 

Detailed Description

This class is an input device recognizing custom gestures events.

This input devices is an implementation of the SDL Dollar Gesture system. Dollar gestures are custom gestures that consist of a single stroke and can be made anywhere on the screen. An example of a dollar gesture is the spell casting system in Infinity Blade. These gestures can be performed with any number of fingers (the centroid of the fingers must follow the path of the gesture), but the number of fingers must be constant (e.g. a finger cannot go down in the middle of a gesture). The path of a gesture is considered the path from the time when the final finger went down, to the first time any finger comes up. For more information see

 http://depts.washington.edu/madlab/proj/dollar/index.html

If this input device is activated, every single finger up event will trigger and event to match it to a dollar template, and it will always return the closest matching template, no matter how bad the error. This is potentially very noisy and heavy-weight. Therefore, this device has the ability to pause and resume without losing state. Deactivating the device will cause it to lose all recorded gestures.

In addition, the input device has an error threshold. If the closest matching template has an error value exceeding the threshold, it will be ignored and no match will be reported.

Dollar gestures are not built-into the system. They must be recorded, either by the player (according to an on-screen calibration prompt) or the designer. Therefore this inpout device has support for both recording and pattern recognition.

Dollar gestures can be saved to and written into the special save directory ({

See also
Application::getSaveDirectory}). They are written into a special subdirectory that contains the binary data for each gesture and an index JSON mapping keys to hash IDs. We also allow dollar gestures to be loaded as an asset. That way the designer can record the gestures ahead of time an package them as an asset.

As with most devices, we provide support for both listeners and polling the mouse. Because gestures only fire when a finger is released, this input device is much better designed for listeners over polling. The events are queued and processed at the start of the animation frame, before the method Application#update(float) is called.

IMPORTANT: This input device is VERY thread unsafe. No methods in this class should ever be called outside the main CUGL thread.

In addition, because of the way SDL is designed, this device may not support recording or file loading immediately at the start of the application. On some platforms, touch devices are not recognized until they are touched for the first time. On these platforms, the state will start out as UNDEFINED instead of MATCHING. See getState() and ready() for more information.

Constructor & Destructor Documentation

cugl::GestureInput::GestureInput ( )
protected

Creates and initializes a new gesture input device.

WARNING: Never allocate a gesture input device directly. Always use the Input#activate() method instead.

virtual cugl::GestureInput::~GestureInput ( )
inlineprotectedvirtual

Deletes this input device, disposing of all resources

Member Function Documentation

bool cugl::GestureInput::abort ( )

Abort a gesture currently being recorded.

This method only succeeds if the device is currently in the recording state. It will delete the gesture on completion.

Returns
true if the recording was successfully aborted
bool cugl::GestureInput::addMatchListener ( Uint32  key,
GestureListener  listener 
)

Adds a gesture match listener for the given object key

There can only be one listener for a given key. If there is already a listener for the key, the method will fail and return false. You must remove a listener before adding a new one for the same key.

This listener is invoked when a gesture is matched. If threshold is negative (and the device is not paused), this will be whenever a finger is released. Otherwise, it will only return a match when the best match has an error value less than the tolerance.

Parameters
keyThe identifier for the listener
listenerThe listener to add
Returns
true if the listener was succesfully added
bool cugl::GestureInput::addStateListener ( Uint32  key,
GestureStateListener  listener 
)

Adds a state change listener for the given object key

There can only be one listener for a given key. If there is already a listener for the key, the method will fail and return false. You must remove a listener before adding a new one for the same key.

This listener is invoked when the input state changes. This includes synchronous methods such as pause or resume. It is not restricted to asynchronous changes.

Parameters
keyThe identifier for the listener
listenerThe listener to add
Returns
true if the listener was succesfully added
void cugl::GestureInput::changeState ( GestureState  state,
bool  thread = true 
)
protected

Changes the device state to the one provided.

This method will call any attached listeners. It guarantees that the state change always happens in the primary CUGL thread.

Parameters
stateThe new device state
threadWhether the call is in the main thread
virtual void cugl::GestureInput::clearState ( )
overrideprotectedvirtual

Clears the state of this input device, readying it for the next frame.

Many devices keep track of what happened "this" frame. This method is necessary to advance the frame.

Implements cugl::InputDevice.

bool cugl::GestureInput::didMatch ( ) const
inline

Returns true if the device recognized a gesture this animation frame.

If the device is did not recognize a gesture this frame, all other polling methods will return the default value.

Returns
true if the device recognized a gesture this animation frame.
virtual void cugl::GestureInput::dispose ( )
overrideprotectedvirtual

Unintializes this device, returning it to its default state

An uninitialized device may not work without reinitialization.

Reimplemented from cugl::InputDevice.

const float cugl::GestureInput::getError ( ) const
inline

Returns the error value between the gesture and its best match

This value returns a negative value if there is no matching gesture.

Errors are normalized to be between 0 and 1, with 0 being accurate and 1 being an extreme error. However, errors greater than 1 are possible because of the normalization process.

Returns
the error value between the gesture and its best match
int cugl::GestureInput::getFingers ( ) const
inline

Returns the number of fingers involved in the current gesture.

This value is 0 if there are no matching gesture.

Returns
the number of fingers involved in the current gesture.
std::vector<std::string> cugl::GestureInput::getGestures ( ) const

Returns the list of gestures currently recorded

Returns
the list of gestures currently recorded
const std::string cugl::GestureInput::getKey ( ) const
inline

Returns the key of the currently matching gesture.

This method returns the empty string if there is no matching gesture.

Returns
the key of the currently matching gesture.
const GestureListener cugl::GestureInput::getMatchListener ( Uint32  key) const

Returns the gesture match listener for the given object key

This listener is invoked when a gesture is matched. If threshold is negative (and the device is not paused), this will be whenever a finger is released. Otherwise, it will only return a match when the best match has an error value less than the tolerance.

If there is no listener for the given key, it returns nullptr.

Parameters
keyThe identifier for the listener
Returns
the gesture match listener for the given object key
GestureState cugl::GestureInput::getState ( ) const
inline

Returns the current state of this input device.

Returns
the current state of this input device.
const GestureStateListener cugl::GestureInput::getStateListener ( Uint32  key) const

Returns the state change listener for the given object key

This listener is invoked when the input state changes. This includes synchronous methods such as pause or resume. It is not restricted to asynchronous changes.

If there is no listener for the given key, it returns nullptr.

Parameters
keyThe identifier for the listener
Returns
the state change listener for the given object key
float cugl::GestureInput::getTolerance ( ) const
inline

Returns the error tolerance for this input device

If tolerance is negative, the input device will always return a match on a finger up, no matter how bad the error. Otherwise, it will only return matches whose error is less than the tolerance.

Errors are normalized to be between 0 and 1, with 0 being accurate and 1 being an extreme error. However, errors greater than 1 are possible because of the normalization process.

Returns
the error tolerance for this input device
bool cugl::GestureInput::isListener ( Uint32  key) const

Returns true if key represents a listener object

An object is a listener if it is a listener for either a match or a state change.

Parameters
keyThe identifier for the listener
Returns
true if key represents a listener object
bool cugl::GestureInput::load ( const std::string &  file)
inline

Synchronously loads the stored gestures from the given gesture file.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

This method will fail if the device is not ready or involved in any blocking operations.

Parameters
fileThe name of the gesture file (directory)
Returns
true if the gestures were loaded successfully
bool cugl::GestureInput::load ( const char *  file)
inline

Synchronously loads the stored gestures from the given gesture file.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

This method will fail if the device is not ready or involved in any blocking operations.

Parameters
fileThe name of the gesture file (directory)
Returns
true if the gestures were loaded successfully
bool cugl::GestureInput::load ( const Pathname file)

Synchronously loads the stored gestures from the given gesture file.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

This method will fail if the device is not ready or involved in any blocking operations.

Parameters
fileThe name of the gesture file (directory)
Returns
true if the gestures were loaded successfully
bool cugl::GestureInput::loadAsset ( const std::string &  file)

Synchronously loads the stored gestures from the given gesture file.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the asset directory.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

This method will fail if the device is not ready or involved in any blocking operations.

Parameters
fileThe name of the gesture file (directory)
Returns
true if the gestures were loaded successfully
bool cugl::GestureInput::loadAsset ( const char *  file)
inline

Synchronously loads the stored gestures from the given gesture file.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the asset directory.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

This method will fail if the device is not ready or involved in any blocking operations.

Parameters
fileThe name of the gesture file (directory)
Returns
true if the gestures were loaded successfully
void cugl::GestureInput::loadAssetAsync ( const std::string &  file,
std::function< void(bool success)>  callback 
)

Asynchronously loads the stored gestures from the given gesture file.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the asset directory.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

This method will load immediately if the device is ready. If it is not actively loading or saving a file, it will block until it can load. Otherwise, it will fail immediately. The callback function (which can be nullptr) will be called with the result when it is done.

Parameters
fileThe name of the gesture file (directory)
callbackThe callback to report success or failure
void cugl::GestureInput::loadAssetAsync ( const char *  file,
std::function< void(bool success)>  callback 
)
inline

Asynchronously loads the stored gestures from the given gesture file.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the asset directory.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

This method will load immediately if the device is ready. If it is not actively loading or saving a file, it will block until it can load. Otherwise, it will fail immediately. The callback function (which can be nullptr) will be called with the result when it is done.

Parameters
fileThe name of the gesture file (directory)
callbackThe callback to report success or failure
void cugl::GestureInput::loadAsync ( const std::string &  file,
std::function< void(bool success)>  callback 
)
inline

Asynchronously loads the stored gestures from the given gesture file.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

This method will load immediately if the device is ready. If it is not actively loading or saving a file, it will block until it can load. Otherwise, it will fail immediately. The callback function (which can be nullptr) will be called with the result when it is done.

Parameters
fileThe name of the gesture file (directory)
callbackThe callback to report success or failure
void cugl::GestureInput::loadAsync ( const char *  file,
std::function< void(bool success)>  callback 
)
inline

Asynchronously loads the stored gestures from the given gesture file.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

This method will load immediately if the device is ready. If it is not actively loading or saving a file, it will block until it can load. Otherwise, it will fail immediately. The callback function (which can be nullptr) will be called with the result when it is done.

Parameters
fileThe name of the gesture file (directory)
callbackThe callback to report success or failure
void cugl::GestureInput::loadAsync ( const Pathname file,
std::function< void(bool success)>  callback 
)

Asynchronously loads the stored gestures from the given gesture file.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

This method will load immediately if the device is ready. If it is not actively loading or saving a file, it will block until it can load. Otherwise, it will fail immediately. The callback function (which can be nullptr) will be called with the result when it is done.

Parameters
fileThe name of the gesture file (directory)
callbackThe callback to report success or failure
bool cugl::GestureInput::pause ( )

Pauses the input device, temporally disabling gesture matching.

Dollar template matching is potentionally very heavy-weight, particularly if there is no assigned error tolerance. However, deactivating the device will cause all of the recorded gestures to be lost. This method allows you to pause the device, without losing any gestures.

Pausing the input device will pause the underlying SDL dollar gesture system. If you have any other custom classes accessing the SDL dollar gesture system, it will no longer receive events until this device is resumed. In general, it is a bad idea to have more than on interface to the SDL input API anyway.

The device may only be paused if it is currently ready. Any blocking operations must complete before the device can be paused.

Returns
true if the device was successfully paused
virtual void cugl::GestureInput::queryEvents ( std::vector< Uint32 > &  eventset)
overrideprotectedvirtual

Determine the SDL events of relevance and store there types in eventset.

An SDL_EventType is really Uint32. This method stores the SDL event types for this input device into the vector eventset, appending them to the end. The Input dispatcher then uses this information to set up subscriptions.

Parameters
eventsetThe set to store the event types.

Implements cugl::InputDevice.

bool cugl::GestureInput::read ( const std::string &  file,
std::function< void(bool success)>  callback = nullptr 
)
protected

Reads the stored gestures from the given gesture file.

This method is called directly for synchronous loading and as part of the thread pool in asynchronous loading. The optional callback function is called with the return value of the function.

The gesture file will be loaded in a non-destructive manner. That means if there is already a recorded gesture with the given key, it will not load a new version from the file. You will need to delete the recorded version before loading the file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information.

Because of this structure, some gestures may be read into memory even if the entire read fails (because of a bad gesture).

Parameters
fileThe name of the gesture file (directory)
callbackAn optional callback for asynchronous loading.
Returns
true if the entire read was successful
bool cugl::GestureInput::ready ( ) const
inline

Returns true if the input device is actively matching templates.

The matching state is the only non-blocking state of this devices. You should make sure the device is ready before performing any synchronous operations.

Returns
true if the input device is actively matching templates.
bool cugl::GestureInput::record ( const std::string &  key)

Records a gesture for the given key.

The key will be bound to the next recorded gesture. Gestures can be performed with any number of fingers (the centroid of the fingers must follow the path of the gesture), but the number of fingers must be constant (a finger cannot go down in the middle of a gesture). The path of a gesture is considered the path from the time when the final finger went down, to the first time any finger comes up.

This method fails if there is already a gesture for the given key.

Parameters
keyThe key to bind to the gesture
Returns
true if the key is available for recording
bool cugl::GestureInput::record ( const char *  key)
inline

Records a gesture for the given key.

The key will be bound to the next recorded gesture. Gestures can be performed with any number of fingers (the centroid of the fingers must follow the path of the gesture), but the number of fingers must be constant (a finger cannot go down in the middle of a gesture). The path of a gesture is considered the path from the time when the final finger went down, to the first time any finger comes up.

This method fails if there is already a gesture for the given key.

Parameters
keyThe key to bind to the gesture
Returns
true if the key is available for recording
bool cugl::GestureInput::remove ( const std::string &  key)

Deletes the gesture from the input device

This method will fail if the device is not matching and is involved in any blocking operations. It will also fail if there is no gesture with the given name.

Parameters
keyThe gesture to delete
Returns
true if the gesture was successfully deleted.
bool cugl::GestureInput::remove ( const char *  key)
inline

Deletes the gesture from the input device

This method will fail if the device is not matching and is involved in any blocking operations. It will also fail if there is no gesture with the given name.

Parameters
keyThe gesture to delete
Returns
true if the gesture was successfully deleted.
bool cugl::GestureInput::removeMatchListener ( Uint32  key)

Removes the gesture match listener for the given object key

If there is no active listener for the given key, this method fails and returns false.

This listener is invoked when a gesture is matched. If threshold is negative (and the device is not paused), this will be whenever a finger is released. Otherwise, it will only return a match when the best match has an error value less than the tolerance.

Parameters
keyThe identifier for the listener
Returns
true if the listener was succesfully removed
bool cugl::GestureInput::removeStateListener ( Uint32  key)

Removes the state change listener for the given object key

If there is no active listener for the given key, this method fails and returns false.

This listener is invoked when the input state changes. This includes synchronous methods such as pause or resume. It is not restricted to asynchronous changes.

Parameters
keyThe identifier for the listener
Returns
true if the listener was succesfully removed
bool cugl::GestureInput::rename ( const std::string &  key,
const std::string &  name 
)

Renames the given gesture

This method will fail if the device is not matching and is involved in any blocking operations. It will also fail if there is no gesture with the given name.

Parameters
keyThe gesture to rename
nameThe new gesture name
Returns
true if the gesture was successfully renamed.
bool cugl::GestureInput::rename ( const char *  key,
const std::string &  name 
)
inline

Renames the given gesture

This method will fail if the device is not matching and is involved in any blocking operations. It will also fail if there is no gesture with the given name.

Parameters
keyThe gesture to rename
nameThe new gesture name
Returns
true if the gesture was successfully renamed.
bool cugl::GestureInput::rename ( const std::string &  key,
const char *  name 
)
inline

Renames the given gesture

This method will fail if the device is not matching and is involved in any blocking operations. It will also fail if there is no gesture with the given name.

Parameters
keyThe gesture to rename
nameThe new gesture name
Returns
true if the gesture was successfully renamed.
bool cugl::GestureInput::rename ( const char *  key,
const char *  name 
)
inline

Renames the given gesture

This method will fail if the device is not matching and is involved in any blocking operations. It will also fail if there is no gesture with the given name.

Parameters
keyThe gesture to rename
nameThe new gesture name
Returns
true if the gesture was successfully renamed.
virtual bool cugl::GestureInput::requestFocus ( Uint32  key)
overridevirtual

Requests focus for the given identifier

Only a listener can have focus. This method returns false if the key does not refer to an active listener

Parameters
keyThe identifier for the focus object
Returns
false if key does not refer to an active listener

Reimplemented from cugl::InputDevice.

bool cugl::GestureInput::resume ( )

Resumes the input device, temporally disabling gesture matching.

Dollar template matching is potentionally very heavy-weight, particularly if there is no assigned error tolerance. However, deactivating the device will cause all of the recorded gestures to be lost. This method allows you to pause the device, without losing any gestures.

Pausing the input device will resume the underlying SDL dollar gesture system. If you have any other custom classes accessing the SDL dollar gesture system, it will start to receive input events. In general, it is a bad idea to have more than on interface to the SDL input API anyway.

Returns
true if the device was successfully resumed
bool cugl::GestureInput::save ( const std::string &  file)
inline

Synchronously writes the current gestures to the given gesture file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be written to a file even if the entire write fails (because of bad access or other issues).

This method will fail if the device is not ready or involved in any blocking operations.

Parameters
fileThe name of the gesture file (directory)
Returns
true if the gestures were written successfully
bool cugl::GestureInput::save ( const char *  file)
inline

Synchronously writes the current gestures to the given gesture file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be written to a file even if the entire write fails (because of bad access or other issues).

This method will fail if the device is not ready or involved in any blocking operations.

Parameters
fileThe name of the gesture file (directory)
Returns
true if the gestures were written successfully
bool cugl::GestureInput::save ( Pathname file)

Synchronously writes the current gestures to the given gesture file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be written to a file even if the entire write fails (because of bad access or other issues).

This method will fail if the device is not ready or involved in any blocking operations.

Parameters
fileThe name of the gesture file (directory)
Returns
true if the gestures were written successfully
void cugl::GestureInput::saveAsync ( const std::string &  file,
std::function< void(bool success)>  callback 
)
inline

Asynchronously writes the current gestures to the given gesture file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be written to a file even if the entire write fails (because of bad access or other issues).

This method will write immediately if the device is ready. If it is not actively loading or saving a file, it will block until it can write. Otherwise, it will fail immediately. The callback function (which can be nullptr) will be called with the result when it is done.

Parameters
fileThe name of the gesture file (directory)
callbackThe callback to report success or failure
void cugl::GestureInput::saveAsync ( const char *  file,
std::function< void(bool success)>  callback 
)
inline

Asynchronously writes the current gestures to the given gesture file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be written to a file even if the entire write fails (because of bad access or other issues).

This method will write immediately if the device is ready. If it is not actively loading or saving a file, it will block until it can write. Otherwise, it will fail immediately. The callback function (which can be nullptr) will be called with the result when it is done.

Parameters
fileThe name of the gesture file (directory)
callbackThe callback to report success or failure
void cugl::GestureInput::saveAsync ( Pathname file,
std::function< void(bool success)>  callback 
)

Asynchronously writes the current gestures to the given gesture file.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information. For this method, the gesture directory is assumed to be in the application save directory.

Because of this structure, some gestures may be written to a file even if the entire write fails (because of bad access or other issues).

This method will write immediately if the device is ready. If it is not actively loading or saving a file, it will block until it can write. Otherwise, it will fail immediately. The callback function (which can be nullptr) will be called with the result when it is done.

Parameters
fileThe name of the gesture file (directory)
callbackThe callback to report success or failure
void cugl::GestureInput::setTolerance ( float  tolerance)
inline

Sets the error tolerance for this input device

If tolerance is negative, the input device will always return a match on a finger up, no matter how bad the error. Otherwise, it will only return matches whose error is less than the tolerance.

Errors are normalized to be between 0 and 1, with 0 being accurate and 1 being an extreme error. However, errors greater than 1 are possible because of the normalization process.

Parameters
toleranceThe error tolerance for this input device
bool cugl::GestureInput::store ( Pathname file,
std::function< void(bool success)>  callback = nullptr 
)
protected

Writes the current gestures to the given gesture file.

This method is called directly for synchronous writing and as part of the thread pool in asynchronous writing. The optional callback function is called with the return value of the function.

Technically, gesture files are directories (a later refactoring should convert them into custom ZIP files). The directory has an index JSON mapping keys to hashes. For each hash, there is a separate SDL file with the gesture information.

Because of this structure, some gestures may be written to a file even if the entire write fails (because of bad access or other issues).

Parameters
fileThe path to the gesture file (directory)
callbackAn optional callback for asynchronous loading.
Returns
true if the entire write was successful
virtual bool cugl::GestureInput::updateState ( const SDL_Event &  event,
const Timestamp stamp 
)
overrideprotectedvirtual

Processes an SDL_Event

The dispatcher guarantees that an input device only receives events that it subscribes to.

Parameters
eventThe input event to process
stampThe event timestamp in CUGL time
Returns
false if the input indicates that the application should quit.

Implements cugl::InputDevice.

Member Data Documentation

GestureEvent cugl::GestureInput::_event
protected

The currently matched gesture event

std::unordered_map<SDL_GestureID, std::string> cugl::GestureInput::_gestures
protected

The map from gesture keys to SDL identifiers

std::unordered_map<std::string, SDL_GestureID> cugl::GestureInput::_inverses
protected

The map from SDL identifiers to gesture keys

std::shared_ptr<ThreadPool> cugl::GestureInput::_loader
protected

The thread pool for asynchronous loading

std::mutex cugl::GestureInput::_lock
protected

A mutex for thread management

bool cugl::GestureInput::_match
protected

Whether or not we made a match this animation frame (for polling)

std::unordered_map<Uint32, GestureListener> cugl::GestureInput::_matchListeners
protected

The set of listeners called whenever a gesture is recognized

std::condition_variable cugl::GestureInput::_monitor
protected

A conditional variable for thread management

std::string cugl::GestureInput::_recrd
protected

The name of the gesture currently being recorded

GestureState cugl::GestureInput::_state
protected

The current state of this input device

std::unordered_map<Uint32, GestureStateListener> cugl::GestureInput::_stateListeners
protected

The set of listeners called whenever a state changes

float cugl::GestureInput::_tolerance
protected

The allowed error tolerance for matching gestures

GestureState cugl::GestureInput::_waits
protected

The queued next state of this input device


The documentation for this class was generated from the following file: