Finalize API and add comments
This commit is contained in:
@@ -6,6 +6,17 @@
|
|||||||
|
|
||||||
namespace input
|
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 )
|
vr::InputDigitalActionData_t getDigitalActionData( Action& action )
|
||||||
{
|
{
|
||||||
if ( action.type() != ActionType::Digital )
|
if ( action.type() != ActionType::Digital )
|
||||||
@@ -37,6 +48,17 @@ vr::InputDigitalActionData_t getDigitalActionData( Action& action )
|
|||||||
return handleData;
|
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 )
|
vr::InputAnalogActionData_t getAnalogActionData( Action& action )
|
||||||
{
|
{
|
||||||
if ( action.type() != ActionType::Analog )
|
if ( action.type() != ActionType::Analog )
|
||||||
@@ -68,6 +90,12 @@ vr::InputAnalogActionData_t getAnalogActionData( Action& action )
|
|||||||
return handleData;
|
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 )
|
bool isDigitalActionActivatedOnce( Action& action )
|
||||||
{
|
{
|
||||||
const auto handleData = getDigitalActionData( action );
|
const auto handleData = getDigitalActionData( action );
|
||||||
@@ -75,6 +103,10 @@ bool isDigitalActionActivatedOnce( Action& action )
|
|||||||
return handleData.bState && handleData.bChanged;
|
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 )
|
bool isDigitalActionActivatedConstant( Action& action )
|
||||||
{
|
{
|
||||||
const auto handleData = getDigitalActionData( action );
|
const auto handleData = getDigitalActionData( action );
|
||||||
@@ -82,6 +114,14 @@ bool isDigitalActionActivatedConstant( Action& action )
|
|||||||
return handleData.bState;
|
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()
|
SteamIVRInput::SteamIVRInput()
|
||||||
: m_manifest(), m_mainSet( input_strings::k_setMain ),
|
: m_manifest(), m_mainSet( input_strings::k_setMain ),
|
||||||
m_nextTrack( input_strings::k_actionNextTrack, ActionType::Digital )
|
m_nextTrack( input_strings::k_actionNextTrack, ActionType::Digital )
|
||||||
@@ -90,13 +130,23 @@ SteamIVRInput::SteamIVRInput()
|
|||||||
m_activeActionSet.ulRestrictedToDevice = vr::k_ulInvalidInputValueHandle;
|
m_activeActionSet.ulRestrictedToDevice = vr::k_ulInvalidInputValueHandle;
|
||||||
m_activeActionSet.nPriority = 0;
|
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()
|
bool SteamIVRInput::nextSong()
|
||||||
{
|
{
|
||||||
return isDigitalActionActivatedOnce( m_nextTrack );
|
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;
|
constexpr auto numberOfSets = 1;
|
||||||
|
|
||||||
|
|||||||
+31
-2
@@ -7,17 +7,40 @@
|
|||||||
|
|
||||||
namespace input
|
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
|
class SteamIVRInput
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SteamIVRInput();
|
SteamIVRInput();
|
||||||
void Loop();
|
|
||||||
|
void UpdateStates();
|
||||||
bool nextSong();
|
bool nextSong();
|
||||||
|
|
||||||
// Destructor. There are no terminating calls for the IVRInput API, so it
|
// Destructor. There are no terminating calls for the IVRInput API, so it
|
||||||
// is left blank.
|
// is left blank.
|
||||||
~SteamIVRInput() {}
|
~SteamIVRInput() {}
|
||||||
|
|
||||||
// These have been explicitly deleted to make sure there are no attempts at
|
// 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
|
// copying the class in weird ways. It is not worth defining what should
|
||||||
// happen on copy because it simply shouldn't be done.
|
// happen on copy because it simply shouldn't be done.
|
||||||
@@ -34,12 +57,18 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Manifest m_manifest;
|
Manifest m_manifest;
|
||||||
|
|
||||||
ActionSet m_mainSet;
|
ActionSet m_mainSet;
|
||||||
vr::VRActiveActionSet_t m_activeActionSet = {};
|
vr::VRActiveActionSet_t m_activeActionSet = {};
|
||||||
|
|
||||||
Action m_nextTrack;
|
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
|
namespace input_strings
|
||||||
{
|
{
|
||||||
constexpr auto k_actionNextTrack = "/actions/main/in/PlayNextTrack";
|
constexpr auto k_actionNextTrack = "/actions/main/in/PlayNextTrack";
|
||||||
|
|||||||
@@ -4,6 +4,11 @@
|
|||||||
|
|
||||||
namespace input
|
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
|
enum class ActionType
|
||||||
{
|
{
|
||||||
Undefined,
|
Undefined,
|
||||||
@@ -11,6 +16,10 @@ enum class ActionType
|
|||||||
Analog,
|
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
|
class Action
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -25,14 +34,24 @@ public:
|
|||||||
<< "'. OpenVR Error: " << error;
|
<< "'. OpenVR Error: " << error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*!
|
||||||
|
An API internal handle that identifies an action.
|
||||||
|
*/
|
||||||
vr::VRActionHandle_t handle() const noexcept
|
vr::VRActionHandle_t handle() const noexcept
|
||||||
{
|
{
|
||||||
return m_handle;
|
return m_handle;
|
||||||
}
|
}
|
||||||
|
/*!
|
||||||
|
The actions manfiest name of the action. Used for error reporting.
|
||||||
|
*/
|
||||||
std::string name() const noexcept
|
std::string name() const noexcept
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
/*!
|
||||||
|
The type of the action. Used for runtime checking that the wrong functions
|
||||||
|
aren't called.
|
||||||
|
*/
|
||||||
ActionType type() const noexcept
|
ActionType type() const noexcept
|
||||||
{
|
{
|
||||||
return m_type;
|
return m_type;
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
namespace input
|
namespace input
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
Represents an action set from the action manifest.
|
||||||
|
*/
|
||||||
class ActionSet
|
class ActionSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -16,10 +19,16 @@ public:
|
|||||||
<< "'. OpenVR Error: " << error;
|
<< "'. OpenVR Error: " << error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*!
|
||||||
|
The actions manfiest name of the set. Used for error reporting.
|
||||||
|
*/
|
||||||
std::string name()
|
std::string name()
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
/*!
|
||||||
|
An API internal handle that identifies a set.
|
||||||
|
*/
|
||||||
vr::VRActionSetHandle_t handle()
|
vr::VRActionSetHandle_t handle()
|
||||||
{
|
{
|
||||||
return m_handle;
|
return m_handle;
|
||||||
|
|||||||
@@ -476,7 +476,7 @@ void OverlayController::OnTimeoutPumpEvents()
|
|||||||
if ( !vr::VRSystem() )
|
if ( !vr::VRSystem() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_actions.Loop();
|
m_actions.UpdateStates();
|
||||||
|
|
||||||
if ( m_actions.nextSong() )
|
if ( m_actions.nextSong() )
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user