Finalize API and add comments

This commit is contained in:
Vasily
2019-01-20 20:13:05 +01:00
parent 01b0070e66
commit 0c71c289b9
5 changed files with 111 additions and 4 deletions
+51 -1
View File
@@ -6,6 +6,17 @@
namespace input
{
/*!
Wrapper around the IVRInput GetAnalogActionData with error handling.
The struct is created and zero initalized in this function instead of being
passed as reference since the size is currently only 28 bytes, and currently
only two bools are used from the entire struct.
MSVC on /O2 will likely completely optimize the function call away but even if
it isn't the struct will still need to be created somewhere, and with move
semantics it almost doesn't matter if the struct is created in the calling
function and passed as reference, or created in this function.
*/
vr::InputDigitalActionData_t getDigitalActionData( Action& action )
{
if ( action.type() != ActionType::Digital )
@@ -37,6 +48,17 @@ vr::InputDigitalActionData_t getDigitalActionData( Action& action )
return handleData;
}
/*!
Wrapper around the IVRInput GetAnalogActionData with error handling.
The struct is created and zero initalized in this function instead of being
passed as reference since the size is currently only 28 bytes, and currently
only two bools are used from the entire struct.
MSVC on /O2 will likely completely optimize the function call away but even if
it isn't the struct will still need to be created somewhere, and with move
semantics it almost doesn't matter if the struct is created in the calling
function and passed as reference, or created in this function.
*/
vr::InputAnalogActionData_t getAnalogActionData( Action& action )
{
if ( action.type() != ActionType::Analog )
@@ -68,6 +90,12 @@ vr::InputAnalogActionData_t getAnalogActionData( Action& action )
return handleData;
}
/*!
Gets the action state of an Action.
This will only return true the first time the button is released. It is
necessary to release the button and the push it again in order for this function
to return true again.
*/
bool isDigitalActionActivatedOnce( Action& action )
{
const auto handleData = getDigitalActionData( action );
@@ -75,6 +103,10 @@ bool isDigitalActionActivatedOnce( Action& action )
return handleData.bState && handleData.bChanged;
}
/*!
Gets the action state of an Action.
This will continually return true while the button is held down.
*/
bool isDigitalActionActivatedConstant( Action& action )
{
const auto handleData = getDigitalActionData( action );
@@ -82,6 +114,14 @@ bool isDigitalActionActivatedConstant( Action& action )
return handleData.bState;
}
/*!
Sets up the input systems.
Actions should be added to the initializer list before the body of the
constructor. Actions should be certain that the action name strings are
correctly input, and that the correct type is provided.
Wrong action names may not result in direct error messages, but just features
mystically not working.
*/
SteamIVRInput::SteamIVRInput()
: m_manifest(), m_mainSet( input_strings::k_setMain ),
m_nextTrack( input_strings::k_actionNextTrack, ActionType::Digital )
@@ -90,13 +130,23 @@ SteamIVRInput::SteamIVRInput()
m_activeActionSet.ulRestrictedToDevice = vr::k_ulInvalidInputValueHandle;
m_activeActionSet.nPriority = 0;
}
/*!
Returns true if the next media track should be played.
Will only return true the first time that the button is pressed. Holding the
button down will result in false until it has been released and pushed again.
*/
bool SteamIVRInput::nextSong()
{
return isDigitalActionActivatedOnce( m_nextTrack );
}
void SteamIVRInput::Loop()
/*!
Updates the active action set(s).
Should be called every frame, or however often you want the input system to
update state.
*/
void SteamIVRInput::UpdateStates()
{
constexpr auto numberOfSets = 1;
+31 -2
View File
@@ -7,17 +7,40 @@
namespace input
{
/*!
Responsible for controller input.
UpdateStates should be called every frame.
Binary actions should only have one function,
and they should reflect the expected behaviour. I.e. if a button being pressed
and held should only return true the first time, that logic should be in the
function.
An action in the IVRInput API is entered in the actions manifest. This is a
.json file that is included with the final binary.
Currently an Action is created with a string and a type. The type determines
which function should be used for getting information from the API. The type in
the actions manifest must match the type in the source code.
Actions should be added as member objects to SteamIVRInput and initialized in
the constructor. They should then make a small number of accessor functions
available for outside use. The internal structs of the IVRInput API are not
entirely stable, and should not be leaked outside this class.
The name of the actions manifest must be set in ivrinput_manifest.h.
*/
class SteamIVRInput
{
public:
SteamIVRInput();
void Loop();
void UpdateStates();
bool nextSong();
// Destructor. There are no terminating calls for the IVRInput API, so it
// is left blank.
~SteamIVRInput() {}
// These have been explicitly deleted to make sure there are no attempts at
// copying the class in weird ways. It is not worth defining what should
// happen on copy because it simply shouldn't be done.
@@ -34,12 +57,18 @@ public:
private:
Manifest m_manifest;
ActionSet m_mainSet;
vr::VRActiveActionSet_t m_activeActionSet = {};
Action m_nextTrack;
};
/*!
The IVRInput system is _very_ finnicky about strings matching and if they don't
match there are usually no errors logged reflecting that. constexpr auto strings
should be used to refer to all action manifest strings.
*/
namespace input_strings
{
constexpr auto k_actionNextTrack = "/actions/main/in/PlayNextTrack";
+19
View File
@@ -4,6 +4,11 @@
namespace input
{
/*!
The type of function that should be called to get data for the action.
The IVRInput API does not give explicit warnings when the wrong functions are
called. This enum is an attempt at runtime checking.
*/
enum class ActionType
{
Undefined,
@@ -11,6 +16,10 @@ enum class ActionType
Analog,
};
/*!
Represents a single action from the actions manifest. Should be instantiated
with a name similar to that of the one in the actions manifest.
*/
class Action
{
public:
@@ -25,14 +34,24 @@ public:
<< "'. OpenVR Error: " << error;
}
}
/*!
An API internal handle that identifies an action.
*/
vr::VRActionHandle_t handle() const noexcept
{
return m_handle;
}
/*!
The actions manfiest name of the action. Used for error reporting.
*/
std::string name() const noexcept
{
return m_name;
}
/*!
The type of the action. Used for runtime checking that the wrong functions
aren't called.
*/
ActionType type() const noexcept
{
return m_type;
+9
View File
@@ -4,6 +4,9 @@
namespace input
{
/*!
Represents an action set from the action manifest.
*/
class ActionSet
{
public:
@@ -16,10 +19,16 @@ public:
<< "'. OpenVR Error: " << error;
}
}
/*!
The actions manfiest name of the set. Used for error reporting.
*/
std::string name()
{
return m_name;
}
/*!
An API internal handle that identifies a set.
*/
vr::VRActionSetHandle_t handle()
{
return m_handle;
+1 -1
View File
@@ -476,7 +476,7 @@ void OverlayController::OnTimeoutPumpEvents()
if ( !vr::VRSystem() )
return;
m_actions.Loop();
m_actions.UpdateStates();
if ( m_actions.nextSong() )
{