CUGL
Cornell University Game Library
|
#include <CUGestureInput.h>
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 |
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 ({
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.
|
protected |
Creates and initializes a new gesture input device.
WARNING: Never allocate a gesture input device directly. Always use the Input#activate() method instead.
|
inlineprotectedvirtual |
Deletes this input device, disposing of all resources
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.
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.
key | The identifier for the listener |
listener | The listener to add |
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.
key | The identifier for the listener |
listener | The listener to add |
|
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.
state | The new device state |
thread | Whether the call is in the main thread |
|
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.
|
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.
|
overrideprotectedvirtual |
Unintializes this device, returning it to its default state
An uninitialized device may not work without reinitialization.
Reimplemented from cugl::InputDevice.
|
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.
|
inline |
Returns the number of fingers involved in the current gesture.
This value is 0 if there are no matching gesture.
std::vector<std::string> cugl::GestureInput::getGestures | ( | ) | const |
Returns the list of gestures currently recorded
|
inline |
Returns the key of the currently matching gesture.
This method returns the empty string if there is no 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.
key | The identifier for the listener |
|
inline |
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.
key | The identifier for the listener |
|
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.
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.
key | The identifier for the listener |
|
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.
file | The name of the gesture file (directory) |
|
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.
file | The name of the gesture file (directory) |
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.
file | The name of the gesture file (directory) |
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.
file | The name of the gesture file (directory) |
|
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.
file | The name of the gesture file (directory) |
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.
file | The name of the gesture file (directory) |
callback | The callback to report success or failure |
|
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.
file | The name of the gesture file (directory) |
callback | The callback to report success or failure |
|
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.
file | The name of the gesture file (directory) |
callback | The callback to report success or failure |
|
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.
file | The name of the gesture file (directory) |
callback | The 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.
file | The name of the gesture file (directory) |
callback | The 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.
|
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.
eventset | The set to store the event types. |
Implements cugl::InputDevice.
|
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).
file | The name of the gesture file (directory) |
callback | An optional callback for asynchronous loading. |
|
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.
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.
key | The key to bind to the gesture |
|
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.
key | The key to bind to the gesture |
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.
key | The gesture to delete |
|
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.
key | The gesture to delete |
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.
key | The identifier for the listener |
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.
key | The identifier for the listener |
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.
key | The gesture to rename |
name | The new gesture 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.
key | The gesture to rename |
name | The new gesture 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.
key | The gesture to rename |
name | The new gesture 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.
key | The gesture to rename |
name | The new gesture name |
|
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
key | The identifier for the focus object |
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.
|
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.
file | The name of the gesture file (directory) |
|
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.
file | The name of the gesture file (directory) |
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.
file | The name of the gesture file (directory) |
|
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.
file | The name of the gesture file (directory) |
callback | The callback to report success or failure |
|
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.
file | The name of the gesture file (directory) |
callback | The 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.
file | The name of the gesture file (directory) |
callback | The callback to report success or failure |
|
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.
tolerance | The error tolerance for this input device |
|
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).
file | The path to the gesture file (directory) |
callback | An optional callback for asynchronous loading. |
|
overrideprotectedvirtual |
Processes an SDL_Event
The dispatcher guarantees that an input device only receives events that it subscribes to.
event | The input event to process |
stamp | The event timestamp in CUGL time |
Implements cugl::InputDevice.
|
protected |
The currently matched gesture event
|
protected |
The map from gesture keys to SDL identifiers
|
protected |
The map from SDL identifiers to gesture keys
|
protected |
The thread pool for asynchronous loading
|
protected |
A mutex for thread management
|
protected |
Whether or not we made a match this animation frame (for polling)
|
protected |
The set of listeners called whenever a gesture is recognized
|
protected |
A conditional variable for thread management
|
protected |
The name of the gesture currently being recorded
|
protected |
The current state of this input device
|
protected |
The set of listeners called whenever a state changes
|
protected |
The allowed error tolerance for matching gestures
|
protected |
The queued next state of this input device