From 12c4418bdac97252e6d442a8eb922cc8bea47c6f Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Wed, 22 Nov 2017 19:48:32 -0800 Subject: [PATCH] Added callbacks for CAN (#757) Added callback scheme for a pass through to something higher level. Since the ID is embedded into the arbitration ID, and some devices can use different schemes whether it is plugged in through a device or put into the daisy chain (pigeonImu), I made one "internal data object" for max reusability. --- .../main/native/include/MockData/CanData.h | 74 +++++ .../include/MockData/NotifyCallbackHelpers.h | 23 ++ hal/src/main/native/sim/CAN.cpp | 35 ++- .../native/sim/MockData/CanDataInternal.cpp | 286 ++++++++++++++++++ .../native/sim/MockData/CanDataInternal.h | 111 +++++++ .../sim/MockData/NotifyCallbackHelpers.cpp | 23 -- 6 files changed, 523 insertions(+), 29 deletions(-) create mode 100644 hal/src/main/native/include/MockData/CanData.h create mode 100644 hal/src/main/native/sim/MockData/CanDataInternal.cpp create mode 100644 hal/src/main/native/sim/MockData/CanDataInternal.h diff --git a/hal/src/main/native/include/MockData/CanData.h b/hal/src/main/native/include/MockData/CanData.h new file mode 100644 index 0000000000..a76614dd7e --- /dev/null +++ b/hal/src/main/native/include/MockData/CanData.h @@ -0,0 +1,74 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2017 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#pragma once + +#include "HAL/HAL.h" +#include "HAL_Value.h" +#include "NotifyListener.h" + +typedef void (*HAL_CAN_SendMessageCallback)(const char* name, void* param, + uint32_t messageID, + const uint8_t* data, + uint8_t dataSize, int32_t periodMs, + int32_t* status); + +typedef void (*HAL_CAN_ReceiveMessageCallback)( + const char* name, void* param, uint32_t* messageID, uint32_t messageIDMask, + uint8_t* data, uint8_t* dataSize, uint32_t* timeStamp, int32_t* status); + +typedef void (*HAL_CAN_OpenStreamSessionCallback)( + const char* name, void* param, uint32_t* sessionHandle, uint32_t messageID, + uint32_t messageIDMask, uint32_t maxMessages, int32_t* status); + +typedef void (*HAL_CAN_CloseStreamSessionCallback)(const char* name, + void* param, + uint32_t sessionHandle); + +typedef void (*HAL_CAN_ReadStreamSessionCallback)( + const char* name, void* param, uint32_t sessionHandle, + struct HAL_CANStreamMessage* messages, uint32_t messagesToRead, + uint32_t* messagesRead, int32_t* status); + +typedef void (*HAL_CAN_GetCANStatusCallback)( + const char* name, void* param, float* percentBusUtilization, + uint32_t* busOffCount, uint32_t* txFullCount, uint32_t* receiveErrorCount, + uint32_t* transmitErrorCount, int32_t* status); + +#ifdef __cplusplus +extern "C" { +#endif + +void HALSIM_ResetCanData(); + +int32_t HALSIM_RegisterCanSendMessageCallback( + HAL_CAN_SendMessageCallback callback, void* param); +void HALSIM_CancelCanSendMessageCallback(int32_t uid); + +int32_t HALSIM_RegisterCanReceiveMessageCallback( + HAL_CAN_ReceiveMessageCallback callback, void* param); +void HALSIM_CancelCanReceiveMessageCallback(int32_t uid); + +int32_t HALSIM_RegisterCanOpenStreamCallback( + HAL_CAN_OpenStreamSessionCallback callback, void* param); +void HALSIM_CancelCanOpenStreamCallback(int32_t uid); + +int32_t HALSIM_RegisterCanCloseStreamCallback( + HAL_CAN_CloseStreamSessionCallback callback, void* param); +void HALSIM_CancelCanCloseStreamCallback(int32_t uid); + +int32_t HALSIM_RegisterCanReadStreamCallback( + HAL_CAN_ReadStreamSessionCallback callback, void* param); +void HALSIM_CancelCanReadStreamCallback(int32_t uid); + +int32_t HALSIM_RegisterCanGetCANStatusCallback( + HAL_CAN_GetCANStatusCallback callback, void* param); +void HALSIM_CancelCanGetCANStatusCallback(int32_t uid); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/hal/src/main/native/include/MockData/NotifyCallbackHelpers.h b/hal/src/main/native/include/MockData/NotifyCallbackHelpers.h index 95c6ed9a48..ca2f7df557 100644 --- a/hal/src/main/native/include/MockData/NotifyCallbackHelpers.h +++ b/hal/src/main/native/include/MockData/NotifyCallbackHelpers.h @@ -11,6 +11,29 @@ #include "MockData/NotifyListenerVector.h" +template +std::shared_ptr RegisterCallbackImpl( + std::shared_ptr currentVector, const char* name, + CallbackType callback, void* param, int32_t* newUid) { + std::shared_ptr newCallbacks; + if (currentVector == nullptr) { + newCallbacks = std::make_shared( + param, callback, reinterpret_cast(newUid)); + } else { + newCallbacks = currentVector->emplace_back( + param, callback, reinterpret_cast(newUid)); + } + return newCallbacks; +} + +template +std::shared_ptr CancelCallbackImpl( + std::shared_ptr currentVector, int32_t uid) { + // Create a copy of the callbacks to erase from + auto newCallbacks = currentVector->erase(uid); + return newCallbacks; +} + std::shared_ptr RegisterCallback( std::shared_ptr currentVector, const char* name, HAL_NotifyCallback callback, void* param, int32_t* newUid); diff --git a/hal/src/main/native/sim/CAN.cpp b/hal/src/main/native/sim/CAN.cpp index 7b8d2133af..c27995f81b 100644 --- a/hal/src/main/native/sim/CAN.cpp +++ b/hal/src/main/native/sim/CAN.cpp @@ -7,22 +7,45 @@ #include "HAL/CAN.h" +#include "MockData/CanDataInternal.h" + +using namespace hal; + +CanData hal::SimCanData; + extern "C" { void HAL_CAN_SendMessage(uint32_t messageID, const uint8_t* data, - uint8_t dataSize, int32_t periodMs, int32_t* status) {} + uint8_t dataSize, int32_t periodMs, int32_t* status) { + SimCanData.SendMessage(messageID, data, dataSize, periodMs, status); +} void HAL_CAN_ReceiveMessage(uint32_t* messageID, uint32_t messageIDMask, uint8_t* data, uint8_t* dataSize, - uint32_t* timeStamp, int32_t* status) {} + uint32_t* timeStamp, int32_t* status) { + SimCanData.ReceiveMessage(messageID, messageIDMask, data, dataSize, timeStamp, + status); +} void HAL_CAN_OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID, uint32_t messageIDMask, uint32_t maxMessages, - int32_t* status) {} -void HAL_CAN_CloseStreamSession(uint32_t sessionHandle) {} + int32_t* status) { + SimCanData.OpenStreamSession(sessionHandle, messageID, messageIDMask, + maxMessages, status); +} +void HAL_CAN_CloseStreamSession(uint32_t sessionHandle) { + SimCanData.CloseStreamSession(sessionHandle); +} void HAL_CAN_ReadStreamSession(uint32_t sessionHandle, struct HAL_CANStreamMessage* messages, uint32_t messagesToRead, uint32_t* messagesRead, - int32_t* status) {} + int32_t* status) { + SimCanData.ReadStreamSession(sessionHandle, messages, messagesToRead, + messagesRead, status); +} void HAL_CAN_GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount, uint32_t* txFullCount, uint32_t* receiveErrorCount, - uint32_t* transmitErrorCount, int32_t* status) {} + uint32_t* transmitErrorCount, int32_t* status) { + SimCanData.GetCANStatus(percentBusUtilization, busOffCount, txFullCount, + receiveErrorCount, transmitErrorCount, status); +} + } // extern "C" diff --git a/hal/src/main/native/sim/MockData/CanDataInternal.cpp b/hal/src/main/native/sim/MockData/CanDataInternal.cpp new file mode 100644 index 0000000000..f68429a854 --- /dev/null +++ b/hal/src/main/native/sim/MockData/CanDataInternal.cpp @@ -0,0 +1,286 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2017 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#include "CanDataInternal.h" + +#include "MockData/NotifyCallbackHelpers.h" + +using namespace hal; + +void InvokeCallback(std::shared_ptr currentVector, + const char* name, uint32_t messageID, const uint8_t* data, + uint8_t dataSize, int32_t periodMs, int32_t* status) { + // Return if no callbacks are assigned + if (currentVector == nullptr) return; + // Get a copy of the shared_ptr, then iterate and callback listeners + auto newCallbacks = currentVector; + for (size_t i = 0; i < newCallbacks->size(); ++i) { + if (!(*newCallbacks)[i]) continue; // removed + auto listener = (*newCallbacks)[i]; + listener.callback(name, listener.param, messageID, data, dataSize, periodMs, + status); + } +} + +void InvokeCallback( + std::shared_ptr currentVector, + const char* name, uint32_t* messageID, uint32_t messageIDMask, + uint8_t* data, uint8_t* dataSize, uint32_t* timeStamp, int32_t* status) { + // Return if no callbacks are assigned + if (currentVector == nullptr) return; + // Get a copy of the shared_ptr, then iterate and callback listeners + auto newCallbacks = currentVector; + for (size_t i = 0; i < newCallbacks->size(); ++i) { + if (!(*newCallbacks)[i]) continue; // removed + auto listener = (*newCallbacks)[i]; + listener.callback(name, listener.param, messageID, messageIDMask, data, + dataSize, timeStamp, status); + } +} + +void InvokeCallback( + std::shared_ptr currentVector, + const char* name, uint32_t* sessionHandle, uint32_t messageID, + uint32_t messageIDMask, uint32_t maxMessages, int32_t* status) { + // Return if no callbacks are assigned + if (currentVector == nullptr) return; + // Get a copy of the shared_ptr, then iterate and callback listeners + auto newCallbacks = currentVector; + for (size_t i = 0; i < newCallbacks->size(); ++i) { + if (!(*newCallbacks)[i]) continue; // removed + auto listener = (*newCallbacks)[i]; + listener.callback(name, listener.param, sessionHandle, messageID, + messageIDMask, maxMessages, status); + } +} + +void InvokeCallback( + std::shared_ptr currentVector, + const char* name, uint32_t sessionHandle) { + // Return if no callbacks are assigned + if (currentVector == nullptr) return; + // Get a copy of the shared_ptr, then iterate and callback listeners + auto newCallbacks = currentVector; + for (size_t i = 0; i < newCallbacks->size(); ++i) { + if (!(*newCallbacks)[i]) continue; // removed + auto listener = (*newCallbacks)[i]; + listener.callback(name, listener.param, sessionHandle); + } +} + +void InvokeCallback( + std::shared_ptr currentVector, + const char* name, uint32_t sessionHandle, + struct HAL_CANStreamMessage* messages, uint32_t messagesToRead, + uint32_t* messagesRead, int32_t* status) { + // Return if no callbacks are assigned + if (currentVector == nullptr) return; + // Get a copy of the shared_ptr, then iterate and callback listeners + auto newCallbacks = currentVector; + for (size_t i = 0; i < newCallbacks->size(); ++i) { + if (!(*newCallbacks)[i]) continue; // removed + auto listener = (*newCallbacks)[i]; + listener.callback(name, listener.param, sessionHandle, messages, + messagesToRead, messagesRead, status); + } +} + +void InvokeCallback( + std::shared_ptr currentVector, + const char* name, float* percentBusUtilization, uint32_t* busOffCount, + uint32_t* txFullCount, uint32_t* receiveErrorCount, + uint32_t* transmitErrorCount, int32_t* status) { + // Return if no callbacks are assigned + if (currentVector == nullptr) return; + // Get a copy of the shared_ptr, then iterate and callback listeners + auto newCallbacks = currentVector; + for (size_t i = 0; i < newCallbacks->size(); ++i) { + if (!(*newCallbacks)[i]) continue; // removed + auto listener = (*newCallbacks)[i]; + listener.callback(name, listener.param, percentBusUtilization, busOffCount, + txFullCount, receiveErrorCount, transmitErrorCount, + status); + } +} + +void CanData::ResetData() { + m_sendMessageCallback = nullptr; + m_receiveMessageCallback = nullptr; + m_openStreamSessionCallback = nullptr; + m_closeStreamSessionCallback = nullptr; + m_readStreamSessionCallback = nullptr; + m_getCanStatusCallback = nullptr; +} + +void CanData::SendMessage(uint32_t messageID, const uint8_t* data, + uint8_t dataSize, int32_t periodMs, int32_t* status) { + InvokeCallback(m_sendMessageCallback, "SendMessage", messageID, data, + dataSize, periodMs, status); +} + +void CanData::ReceiveMessage(uint32_t* messageID, uint32_t messageIDMask, + uint8_t* data, uint8_t* dataSize, + uint32_t* timeStamp, int32_t* status) { + InvokeCallback(m_receiveMessageCallback, "ReceiveMessage", messageID, + messageIDMask, data, dataSize, timeStamp, status); +} + +void CanData::OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID, + uint32_t messageIDMask, uint32_t maxMessages, + int32_t* status) { + InvokeCallback(m_openStreamSessionCallback, "OpenStream", sessionHandle, + messageID, messageIDMask, maxMessages, status); +} + +void CanData::CloseStreamSession(uint32_t sessionHandle) { + InvokeCallback(m_closeStreamSessionCallback, "CloseStream", sessionHandle); +} + +void CanData::ReadStreamSession(uint32_t sessionHandle, + struct HAL_CANStreamMessage* messages, + uint32_t messagesToRead, uint32_t* messagesRead, + int32_t* status) { + InvokeCallback(m_readStreamSessionCallback, "ReadStream", sessionHandle, + messages, messagesToRead, messagesRead, status); +} + +void CanData::GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount, + uint32_t* txFullCount, uint32_t* receiveErrorCount, + uint32_t* transmitErrorCount, int32_t* status) { + InvokeCallback(m_getCanStatusCallback, "GetCanStatus", percentBusUtilization, + busOffCount, txFullCount, receiveErrorCount, + transmitErrorCount, status); +} + +int32_t CanData::RegisterSendMessageCallback( + HAL_CAN_SendMessageCallback callback, void* param) { + return RegisterCanCallback( + callback, m_sendMessageCallback, "SendMessage", param); +} +void CanData::CancelSendMessageCallback(int32_t uid) { + m_sendMessageCallback = CancelCallbackImpl( + m_sendMessageCallback, uid); +} + +int32_t CanData::RegisterReceiveMessageCallback( + HAL_CAN_ReceiveMessageCallback callback, void* param) { + return RegisterCanCallback( + callback, m_receiveMessageCallback, "ReceiveMessage", param); +} +void CanData::CancelReceiveMessageCallback(int32_t uid) { + m_receiveMessageCallback = CancelCallbackImpl( + m_receiveMessageCallback, uid); +} + +int32_t CanData::RegisterOpenStreamCallback( + HAL_CAN_OpenStreamSessionCallback callback, void* param) { + return RegisterCanCallback( + callback, m_openStreamSessionCallback, "OpenStream", param); +} +void CanData::CancelOpenStreamCallback(int32_t uid) { + m_openStreamSessionCallback = + CancelCallbackImpl( + m_openStreamSessionCallback, uid); +} + +int32_t CanData::RegisterCloseStreamCallback( + HAL_CAN_CloseStreamSessionCallback callback, void* param) { + return RegisterCanCallback( + callback, m_closeStreamSessionCallback, "CloseStream", param); +} +void CanData::CancelCloseStreamCallback(int32_t uid) { + m_closeStreamSessionCallback = + CancelCallbackImpl( + m_closeStreamSessionCallback, uid); +} + +int32_t CanData::RegisterReadStreamCallback( + HAL_CAN_ReadStreamSessionCallback callback, void* param) { + return RegisterCanCallback( + callback, m_readStreamSessionCallback, "ReadStream", param); +} +void CanData::CancelReadStreamCallback(int32_t uid) { + m_readStreamSessionCallback = + CancelCallbackImpl( + m_readStreamSessionCallback, uid); +} +int32_t CanData::RegisterGetCANStatusCallback( + HAL_CAN_GetCANStatusCallback callback, void* param) { + return RegisterCanCallback( + callback, m_getCanStatusCallback, "GetCANStatus", param); +} +void CanData::CancelGetCANStatusCallback(int32_t uid) { + m_getCanStatusCallback = + CancelCallbackImpl( + m_getCanStatusCallback, uid); +} + +extern "C" { + +void HALSIM_ResetCanData() { SimCanData.ResetData(); } + +int32_t HALSIM_RegisterCanSendMessageCallback( + HAL_CAN_SendMessageCallback callback, void* param) { + return SimCanData.RegisterSendMessageCallback(callback, param); +} +void HALSIM_CancelCanSendMessageCallback(int32_t uid) { + SimCanData.CancelSendMessageCallback(uid); +} + +int32_t HALSIM_RegisterCanReceiveMessageCallback( + HAL_CAN_ReceiveMessageCallback callback, void* param) { + return SimCanData.RegisterReceiveMessageCallback(callback, param); +} +void HALSIM_CancelCanReceiveMessageCallback(int32_t uid) { + SimCanData.CancelReceiveMessageCallback(uid); +} + +int32_t HALSIM_RegisterCanOpenStreamCallback( + HAL_CAN_OpenStreamSessionCallback callback, void* param) { + return SimCanData.RegisterOpenStreamCallback(callback, param); +} +void HALSIM_CancelCanOpenStreamCallback(int32_t uid) { + SimCanData.CancelOpenStreamCallback(uid); +} + +int32_t HALSIM_RegisterCanCloseStreamCallback( + HAL_CAN_CloseStreamSessionCallback callback, void* param) { + return SimCanData.RegisterCloseStreamCallback(callback, param); +} +void HALSIM_CancelCanCloseStreamCallback(int32_t uid) { + SimCanData.CancelCloseStreamCallback(uid); +} + +int32_t HALSIM_RegisterCanReadStreamCallback( + HAL_CAN_ReadStreamSessionCallback callback, void* param) { + return SimCanData.RegisterReadStreamCallback(callback, param); +} +void HALSIM_CancelCanReadStreamCallback(int32_t uid) { + SimCanData.CancelReadStreamCallback(uid); +} + +int32_t HALSIM_RegisterCanGetCANStatusCallback( + HAL_CAN_GetCANStatusCallback callback, void* param) { + return SimCanData.RegisterGetCANStatusCallback(callback, param); +} +void HALSIM_CancelCanGetCANStatusCallback(int32_t uid) { + SimCanData.CancelGetCANStatusCallback(uid); +} + +} // extern "C" diff --git a/hal/src/main/native/sim/MockData/CanDataInternal.h b/hal/src/main/native/sim/MockData/CanDataInternal.h new file mode 100644 index 0000000000..de08823d10 --- /dev/null +++ b/hal/src/main/native/sim/MockData/CanDataInternal.h @@ -0,0 +1,111 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2017 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#pragma once + +#include +#include +#include + +#include + +#include "MockData/CanData.h" +#include "MockData/NotifyCallbackHelpers.h" +#include "MockData/NotifyListenerVector.h" + +namespace hal { + +typedef HalCallbackListenerVectorImpl + CanSendMessageListenerVector; +typedef HalCallbackListenerVectorImpl + CanReceiveMessageListenerVector; +typedef HalCallbackListenerVectorImpl + CanOpenStreamSessionListenerVector; +typedef HalCallbackListenerVectorImpl + CanCloseStreamSessionListenerVector; +typedef HalCallbackListenerVectorImpl + CanReadStreamSessionListenerVector; +typedef HalCallbackListenerVectorImpl + CanGetCANStatusListenerVector; + +class CanData { + public: + void ResetData(); + + void SendMessage(uint32_t messageID, const uint8_t* data, uint8_t dataSize, + int32_t periodMs, int32_t* status); + void ReceiveMessage(uint32_t* messageID, uint32_t messageIDMask, + uint8_t* data, uint8_t* dataSize, uint32_t* timeStamp, + int32_t* status); + void OpenStreamSession(uint32_t* sessionHandle, uint32_t messageID, + uint32_t messageIDMask, uint32_t maxMessages, + int32_t* status); + void CloseStreamSession(uint32_t sessionHandle); + void ReadStreamSession(uint32_t sessionHandle, + struct HAL_CANStreamMessage* messages, + uint32_t messagesToRead, uint32_t* messagesRead, + int32_t* status); + void GetCANStatus(float* percentBusUtilization, uint32_t* busOffCount, + uint32_t* txFullCount, uint32_t* receiveErrorCount, + uint32_t* transmitErrorCount, int32_t* status); + + int32_t RegisterSendMessageCallback(HAL_CAN_SendMessageCallback callback, + void* param); + void CancelSendMessageCallback(int32_t uid); + + int32_t RegisterReceiveMessageCallback( + HAL_CAN_ReceiveMessageCallback callback, void* param); + void CancelReceiveMessageCallback(int32_t uid); + + int32_t RegisterOpenStreamCallback(HAL_CAN_OpenStreamSessionCallback callback, + void* param); + void CancelOpenStreamCallback(int32_t uid); + + int32_t RegisterCloseStreamCallback( + HAL_CAN_CloseStreamSessionCallback callback, void* param); + void CancelCloseStreamCallback(int32_t uid); + + int32_t RegisterReadStreamCallback(HAL_CAN_ReadStreamSessionCallback callback, + void* param); + void CancelReadStreamCallback(int32_t uid); + + int32_t RegisterGetCANStatusCallback(HAL_CAN_GetCANStatusCallback callback, + void* param); + void CancelGetCANStatusCallback(int32_t uid); + + protected: + template + int32_t RegisterCanCallback(CallbackType& callback, + std::shared_ptr& callbackVector, + const char* callbackName, void* param) { + // Must return -1 on a null callback for error handling + if (callback == nullptr) return -1; + int32_t newUid = 0; + { + std::lock_guard lock(m_registerMutex); + callbackVector = RegisterCallbackImpl(callbackVector, callbackName, + callback, param, &newUid); + } + return newUid; + } + + wpi::mutex m_registerMutex; + + std::shared_ptr m_sendMessageCallback; + std::shared_ptr m_receiveMessageCallback; + std::shared_ptr + m_openStreamSessionCallback; + std::shared_ptr + m_closeStreamSessionCallback; + std::shared_ptr + m_readStreamSessionCallback; + std::shared_ptr m_getCanStatusCallback; +}; + +extern CanData SimCanData; + +} // namespace hal diff --git a/hal/src/main/native/sim/MockData/NotifyCallbackHelpers.cpp b/hal/src/main/native/sim/MockData/NotifyCallbackHelpers.cpp index bd76d0f5ec..d6f4906e7e 100644 --- a/hal/src/main/native/sim/MockData/NotifyCallbackHelpers.cpp +++ b/hal/src/main/native/sim/MockData/NotifyCallbackHelpers.cpp @@ -9,29 +9,6 @@ using namespace hal; -template -std::shared_ptr RegisterCallbackImpl( - std::shared_ptr currentVector, const char* name, - CallbackType callback, void* param, int32_t* newUid) { - std::shared_ptr newCallbacks; - if (currentVector == nullptr) { - newCallbacks = std::make_shared( - param, callback, reinterpret_cast(newUid)); - } else { - newCallbacks = currentVector->emplace_back( - param, callback, reinterpret_cast(newUid)); - } - return newCallbacks; -} - -template -std::shared_ptr CancelCallbackImpl( - std::shared_ptr currentVector, int32_t uid) { - // Create a copy of the callbacks to erase from - auto newCallbacks = currentVector->erase(uid); - return newCallbacks; -} - std::shared_ptr RegisterCallback( std::shared_ptr currentVector, const char* name, HAL_NotifyCallback callback, void* param, int32_t* newUid) {