[Bf-blender-cvs] [f89460a8726] xr-controller-support: Use RAII customdata wrapper for ctor exceptions
Peter Kim
noreply at git.blender.org
Tue May 18 15:07:12 CEST 2021
Commit: f89460a87268c9352dd5f78f8186743a3cadbae9
Author: Peter Kim
Date: Sun May 16 01:09:39 2021 +0900
Branches: xr-controller-support
https://developer.blender.org/rBf89460a87268c9352dd5f78f8186743a3cadbae9
Use RAII customdata wrapper for ctor exceptions
===================================================================
M intern/ghost/intern/GHOST_XrAction.cpp
M intern/ghost/intern/GHOST_XrAction.h
M intern/ghost/intern/GHOST_Xr_intern.h
===================================================================
diff --git a/intern/ghost/intern/GHOST_XrAction.cpp b/intern/ghost/intern/GHOST_XrAction.cpp
index 3915a2c4553..601f580baa1 100644
--- a/intern/ghost/intern/GHOST_XrAction.cpp
+++ b/intern/ghost/intern/GHOST_XrAction.cpp
@@ -28,6 +28,32 @@
#include "GHOST_XrAction.h"
+/* -------------------------------------------------------------------- */
+/** \name CCustomDataWrapper
+ *
+ * RAII wrapper for typical C `void *` custom data.
+ * Used for exception safe custom-data handling during constructor calls.
+ *
+ * \{ */
+
+struct CCustomDataWrapper {
+ void *custom_data_;
+ GHOST_XrCustomdataFreeFn free_fn_;
+
+ CCustomDataWrapper(void *custom_data, GHOST_XrCustomdataFreeFn free_fn)
+ : custom_data_(custom_data), free_fn_(free_fn)
+ {
+ }
+ ~CCustomDataWrapper()
+ {
+ if (free_fn_ != nullptr && custom_data_ != nullptr) {
+ free_fn_(custom_data_);
+ }
+ }
+};
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name GHOST_XrActionSpace
*
@@ -152,16 +178,14 @@ GHOST_XrAction::GHOST_XrAction(XrInstance instance,
const GHOST_XrActionInfo &info)
: m_type(info.type),
m_states(info.states),
- m_customdata_free_fn(info.customdata_free_fn),
- m_customdata(info.customdata)
+ m_custom_data_(
+ std::make_unique<CCustomDataWrapper>(info.customdata, info.customdata_free_fn))
{
m_subaction_paths.resize(info.count_subaction_paths);
for (uint32_t i = 0; i < info.count_subaction_paths; ++i) {
- CHECK_XR_CALL(
- xrStringToPath(instance, info.subaction_paths[i], &m_subaction_paths[i]),
- (std::string("Failed to get user path \"") + info.subaction_paths[i] + "\".").data(),
- freeCustomData);
+ CHECK_XR(xrStringToPath(instance, info.subaction_paths[i], &m_subaction_paths[i]),
+ (std::string("Failed to get user path \"") + info.subaction_paths[i] + "\".").data());
}
XrActionCreateInfo action_info{XR_TYPE_ACTION_CREATE_INFO};
@@ -189,30 +213,20 @@ GHOST_XrAction::GHOST_XrAction(XrInstance instance,
action_info.countSubactionPaths = info.count_subaction_paths;
action_info.subactionPaths = m_subaction_paths.data();
- CHECK_XR_CALL(xrCreateAction(action_set, &action_info, &m_action),
- (std::string("Failed to create action \"") + info.name +
- "\". Action name and/or paths are invalid. Name must not contain upper "
- "case letters or special characters other than '-', '_', or '.'.")
- .data(),
- freeCustomData);
+ CHECK_XR(xrCreateAction(action_set, &action_info, &m_action),
+ (std::string("Failed to create action \"") + info.name +
+ "\". Action name and/or paths are invalid. Name must not contain upper "
+ "case letters or special characters other than '-', '_', or '.'.")
+ .data());
}
GHOST_XrAction::~GHOST_XrAction()
{
- freeCustomData();
-
if (m_action != XR_NULL_HANDLE) {
CHECK_XR_ASSERT(xrDestroyAction(m_action));
}
}
-void GHOST_XrAction::freeCustomData()
-{
- if (m_customdata_free_fn != nullptr && m_customdata != nullptr) {
- m_customdata_free_fn(m_customdata);
- }
-}
-
bool GHOST_XrAction::createSpace(XrInstance instance,
XrSession session,
const GHOST_XrActionSpaceInfo &info)
@@ -377,7 +391,10 @@ void GHOST_XrAction::stopHapticFeedback(XrSession session, const char *action_na
void *GHOST_XrAction::getCustomdata()
{
- return m_customdata;
+ if (m_custom_data_ == nullptr) {
+ return nullptr;
+ }
+ return m_custom_data_->custom_data_;
}
void GHOST_XrAction::getBindings(
@@ -396,7 +413,8 @@ void GHOST_XrAction::getBindings(
* \{ */
GHOST_XrActionSet::GHOST_XrActionSet(XrInstance instance, const GHOST_XrActionSetInfo &info)
- : m_customdata_free_fn(info.customdata_free_fn), m_customdata(info.customdata)
+ : m_custom_data_(
+ std::make_unique<CCustomDataWrapper>(info.customdata, info.customdata_free_fn))
{
XrActionSetCreateInfo action_set_info{XR_TYPE_ACTION_SET_CREATE_INFO};
strcpy(action_set_info.actionSetName, info.name);
@@ -405,18 +423,15 @@ GHOST_XrActionSet::GHOST_XrActionSet(XrInstance instance, const GHOST_XrActionSe
necessary. */
action_set_info.priority = 0; /* Use same (default) priority for all action sets. */
- CHECK_XR_CALL(xrCreateActionSet(instance, &action_set_info, &m_action_set),
- (std::string("Failed to create action set \"") + info.name +
- "\". Name must not contain upper case letters or special characters "
- "other than '-', '_', or '.'.")
- .data(),
- freeCustomData);
+ CHECK_XR(xrCreateActionSet(instance, &action_set_info, &m_action_set),
+ (std::string("Failed to create action set \"") + info.name +
+ "\". Name must not contain upper case letters or special characters "
+ "other than '-', '_', or '.'.")
+ .data());
}
GHOST_XrActionSet::~GHOST_XrActionSet()
{
- freeCustomData();
-
/* This needs to be done before xrDestroyActionSet() to avoid an assertion in the GHOST_XrAction
* destructor (which calls xrDestroyAction()). */
m_actions.clear();
@@ -426,13 +441,6 @@ GHOST_XrActionSet::~GHOST_XrActionSet()
}
}
-void GHOST_XrActionSet::freeCustomData()
-{
- if (m_customdata_free_fn != nullptr && m_customdata != nullptr) {
- m_customdata_free_fn(m_customdata);
- }
-}
-
bool GHOST_XrActionSet::createAction(XrInstance instance, const GHOST_XrActionInfo &info)
{
if (m_actions.find(info.name) != m_actions.end()) {
@@ -478,7 +486,10 @@ XrActionSet GHOST_XrActionSet::getActionSet() const
void *GHOST_XrActionSet::getCustomdata()
{
- return m_customdata;
+ if (m_custom_data_ == nullptr) {
+ return nullptr;
+ }
+ return m_custom_data_->custom_data_;
}
uint32_t GHOST_XrActionSet::getActionCount() const
diff --git a/intern/ghost/intern/GHOST_XrAction.h b/intern/ghost/intern/GHOST_XrAction.h
index 4e1def87f37..961e4c8d3ba 100644
--- a/intern/ghost/intern/GHOST_XrAction.h
+++ b/intern/ghost/intern/GHOST_XrAction.h
@@ -24,8 +24,11 @@
#pragma once
#include <map>
+#include <memory>
#include <string>
+struct CCustomDataWrapper;
+
/* -------------------------------------------------------------------- */
class GHOST_XrActionSpace {
@@ -103,15 +106,12 @@ class GHOST_XrAction {
/** States for each subaction path. */
void *m_states;
- GHOST_XrCustomdataFreeFn m_customdata_free_fn;
- void *m_customdata; /* wmXrAction */
+ std::unique_ptr<CCustomDataWrapper> m_custom_data_ = nullptr; /* wmXrAction */
/* Spaces identified by user (subaction) path. */
std::map<std::string, GHOST_XrActionSpace> m_spaces;
/* Profiles identified by interaction profile path. */
std::map<std::string, GHOST_XrActionProfile> m_profiles;
-
- void freeCustomData();
};
/* -------------------------------------------------------------------- */
@@ -139,12 +139,9 @@ class GHOST_XrActionSet {
private:
XrActionSet m_action_set = XR_NULL_HANDLE;
- GHOST_XrCustomdataFreeFn m_customdata_free_fn;
- void *m_customdata; /* wmXrActionSet */
+ std::unique_ptr<CCustomDataWrapper> m_custom_data_ = nullptr; /* wmXrActionSet */
std::map<std::string, GHOST_XrAction> m_actions;
-
- void freeCustomData();
};
/* -------------------------------------------------------------------- */
diff --git a/intern/ghost/intern/GHOST_Xr_intern.h b/intern/ghost/intern/GHOST_Xr_intern.h
index ed9225ed79e..32bea873d6f 100644
--- a/intern/ghost/intern/GHOST_Xr_intern.h
+++ b/intern/ghost/intern/GHOST_Xr_intern.h
@@ -47,20 +47,6 @@
} \
(void)0
-/**
- * Variation of CHECK_XR() that calls a (cleanup) function before throwing. Especially useful for
- * constructors, since destructors won't be called when throwing.
- */
-#define CHECK_XR_CALL(call, error_msg, func) \
- { \
- XrResult _res = call; \
- if (XR_FAILED(_res)) { \
- func(); \
- throw GHOST_XrException(error_msg, _res); \
- } \
- } \
- (void)0
-
inline void copy_ghost_pose_to_openxr_pose(const GHOST_XrPose &ghost_pose, XrPosef &r_oxr_pose)
{
/* Set and convert to OpenXR coodinate space. */
More information about the Bf-blender-cvs
mailing list