-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BLE: Introduce ChainableEventHandler and subclasses #13734
Conversation
@AGlass0fMilk, thank you for your changes. |
That's very nice, we should add a mention in the gattserver class that this exists otherwise people might not even notice. It should be mentioned in the setEventHandler call. |
connectivity/FEATURE_BLE/include/ble/gatt/ChainableGattServerEventHandler.h
Outdated
Show resolved
Hide resolved
connectivity/FEATURE_BLE/include/ble/gatt/ChainableGattServerEventHandler.h
Outdated
Show resolved
Hide resolved
I ran into issues compiling the eg: mbed-os/connectivity/FEATURE_BLE/include/ble/Gap.h Lines 303 to 331 in ad40b1b
|
@AGlass0fMilk Did you try to use forwarding references ( |
connectivity/FEATURE_BLE/include/ble/common/ChainableEventHandler.h
Outdated
Show resolved
Hide resolved
@pan- That change seems to work well! Thanks for the suggestion! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great change, I left few comments for improvment.
connectivity/FEATURE_BLE/include/ble/common/ChainableEventHandler.h
Outdated
Show resolved
Hide resolved
connectivity/FEATURE_BLE/include/ble/common/ChainableEventHandler.h
Outdated
Show resolved
Hide resolved
700dcc0
to
929ba9c
Compare
@@ -83,6 +83,7 @@ class ChainableGapEventHandler : public ble::Gap::EventHandler, | |||
} | |||
|
|||
void onDisconnectionComplete(const ble::DisconnectionCompleteEvent &event) override { | |||
execute_on_all(&ble::Gap::EventHandler::onDisconnectionComplete, event); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I forgot to comment for that one 😅 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@pan- Do you have any good resources where I can learn why your Any search terms I could use would be appreciated 😄 Currently looking at these: |
6240874
to
10f64b3
Compare
Why it didn't work: A template function deduces the template types based on the parameter passed in input. template<typename T>
void foo(T v);
foo('a'); // T is a char
foo(0); // T is an int In our case, the arguments passed to the function template<typename... Args>
void execute_on_all(void (*fn)(Args...), Args... args);
void foo(const int&);
execute_on_all(foo, 0); // Error, Args is deduced as const int& from the function and int from the second parameter.
// using forwarding references
template<typename... Args>
void execute_on_all(void (*fn)(Args...), Args&&... args);
void foo(const int&);
execute_on_all(foo, 0); // Error, Args is deduced as const int& from the function and int& from the second parameter. Having two variadic arguments helps the compiler at recognizing the handler type and the parameter type. If they are not compatible with one another the compiler will complain at the call site.
One of the most confusing thing about lvalue and rvalue reference to me was the usage of the void foo(int&& a); // non template context: a is an lvalue reference
template<typename T>
void foo(T&& a); // template context: a is a forwarding reference, it is an lvalue reference or rvalue reference depending on what is passed in the function. I recommend reading the C++ proposal papers, they capture very well the reason why these constructs where introduced in the language by detailing the problem they solve:
|
@pan- Thanks for the detailed explanation! Let me know if this PR needs any more work. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@0xc0170 Glad to have you back 😄 I have rebased with master and cleaned up the history of this PR. Let me know if it's good to go. |
@AGlass0fMilk the history looks good but feature should not be one liner in the commit message. There are details in this PR that could be also in the commits, please add them there. |
41a24c3
to
aad3c4b
Compare
…lasses. Common functionality has been split off into a generic ChainableEventHandler for use by other EventHandler implementations. The ChainableEventHandler is essentially singly-linked list that propagates callbacks to all objects in the list. The ChainableGattServerEventHandler enables chaining together GattServer::EventHandlers. An application can register separate event handlers (eg: for different services that need to handle GattServer events) and then set the global GattServer::setEventHandler to the instance of ChainableGattServerEventHandler with all registered GattServer::EventHandlers.
The ChainableGapEventHandler enables chaining together Gap::EventHandlers so separate parts of an application can be notified of Gap events as needed. The application can register multiple Gap::EventHandler objects to one ChainableGapEventHandler and then set the global Gap::EventHandler to the ChainableGapEventHandler. All registered EventHandlers will then be called when a Gap Event occurs.
Update parameters passed to onDataSent, onUpdatesEnabled/Disabled, and onConfirmationReceived callbacks. Deprecate single-callback-registering functions for event handling in lieu of the new EventHandler-based API. Introduce new GattServer::EventHandler callback functions to replace the deprecated versions.
aad3c4b
to
9a6d207
Compare
@0xc0170 I have updated the commit messages. Let me know if they are OK. |
CI started |
Jenkins CI Test : ❌ FAILEDBuild Number: 2 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
CI restarted |
Jenkins CI Test : ✔️ SUCCESSBuild Number: 3 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
Summary of changes
Requires #13727 to be merged firstMerged #13727 since this PR is closely tied to it.
Introduces a
ChainableEventHandler
base class that is essentially a singly-linked-list of EventHandlers along with two subclasses:ChainableGattServerEventHandler
that enables chaining togetherGattServer::EventHandler
sChainableGapEventHandler
that enables chaining togetherGap::EventHandlers
sThe ChainableGattServerEventHandler class allows an application to
register
separate event handlers (eg: for different services that need to handleGattServer
events) and then set the globalGattServer::setEventHandler
to the instance ofChainableGattServerEventHandler
with all registeredGattServer::EventHandler
s.The ChainableGapEventHandler accomplishes that same as above for
Gap:EventHandler
implementations.Common functionality has been split off into
ChainableEventHandler
.See #13728 for discussion around this implementation.
Impact of changes
None
Migration actions required
None
Documentation
None
Pull request type
Test results
Reviewers
@pan- @paul-szczepanek-arm The code compiles but my template-class-function-pointer kung fu isn't flawless. Please look over my implementation and point out anything that looks suspect.
I will test this with an example in the near future.