[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