mirror of
https://github.com/espressif/openthread.git
synced 2026-08-01 08:37:47 +00:00
[notifier] use Array to track external callbacks (#10907)
This commit simplifies `Notifier` by using `Array` to track registered callbacks.
This commit is contained in:
@@ -112,6 +112,19 @@ public:
|
||||
return (mHandler == aHandler) && (mContext == aContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloads operator `==` to evaluate whether or not two given `Callback` objects are equal.
|
||||
*
|
||||
* @param[in] aOtherCallback The callback to compare with.
|
||||
*
|
||||
* @retval TRUE The two callbacks are equal.
|
||||
* @retval FALSE The two callbacks are not equal.
|
||||
*/
|
||||
bool operator==(const CallbackBase &aOtherCallback) const
|
||||
{
|
||||
return Matches(aOtherCallback.mHandler, aOtherCallback.mContext);
|
||||
}
|
||||
|
||||
protected:
|
||||
CallbackBase(void)
|
||||
: mHandler(nullptr)
|
||||
|
||||
@@ -43,51 +43,27 @@ Notifier::Notifier(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mTask(aInstance)
|
||||
{
|
||||
for (ExternalCallback &callback : mExternalCallbacks)
|
||||
{
|
||||
callback.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
Error Notifier::RegisterCallback(otStateChangedCallback aCallback, void *aContext)
|
||||
Error Notifier::RegisterCallback(StateChangedCallback aCallback, void *aContext)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
ExternalCallback *unusedCallback = nullptr;
|
||||
Error error = kErrorNone;
|
||||
ExternalCallback newCallback;
|
||||
|
||||
VerifyOrExit(aCallback != nullptr);
|
||||
|
||||
for (ExternalCallback &callback : mExternalCallbacks)
|
||||
{
|
||||
VerifyOrExit(!callback.Matches(aCallback, aContext), error = kErrorAlready);
|
||||
|
||||
if (!callback.IsSet() && (unusedCallback == nullptr))
|
||||
{
|
||||
unusedCallback = &callback;
|
||||
}
|
||||
}
|
||||
|
||||
VerifyOrExit(unusedCallback != nullptr, error = kErrorNoBufs);
|
||||
|
||||
unusedCallback->Set(aCallback, aContext);
|
||||
newCallback.Set(aCallback, aContext);
|
||||
VerifyOrExit(!mExternalCallbacks.Contains(newCallback), error = kErrorAlready);
|
||||
error = mExternalCallbacks.PushBack(newCallback);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void Notifier::RemoveCallback(otStateChangedCallback aCallback, void *aContext)
|
||||
void Notifier::RemoveCallback(StateChangedCallback aCallback, void *aContext)
|
||||
{
|
||||
VerifyOrExit(aCallback != nullptr);
|
||||
ExternalCallback callbackToRemove;
|
||||
|
||||
for (ExternalCallback &callback : mExternalCallbacks)
|
||||
{
|
||||
if (callback.Matches(aCallback, aContext))
|
||||
{
|
||||
callback.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
callbackToRemove.Set(aCallback, aContext);
|
||||
mExternalCallbacks.Remove(callbackToRemove);
|
||||
}
|
||||
|
||||
void Notifier::Signal(Event aEvent)
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include <openthread/instance.h>
|
||||
#include <openthread/platform/toolchain.h>
|
||||
|
||||
#include "common/array.hpp"
|
||||
#include "common/callback.hpp"
|
||||
#include "common/error.hpp"
|
||||
#include "common/locator.hpp"
|
||||
@@ -179,14 +180,17 @@ private:
|
||||
*
|
||||
* For core internal modules, `Notifier` class emits events directly to them by invoking method `HandleNotifierEvents()`
|
||||
* on the module instance.
|
||||
*
|
||||
* A `otStateChangedCallback` callback can be explicitly registered with the `Notifier`. This is mainly intended for use
|
||||
* by external users (i.e.provided as an OpenThread public API). Max number of such callbacks that can be registered at
|
||||
* the same time is specified by `OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS` configuration parameter.
|
||||
*/
|
||||
class Notifier : public InstanceLocator, private NonCopyable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Maximum number of external callback handlers that can be registered.
|
||||
*/
|
||||
static constexpr uint16_t kMaxExternalHandlers = OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS;
|
||||
|
||||
typedef otStateChangedCallback StateChangedCallback; ///< State changed callback
|
||||
|
||||
/**
|
||||
* Initializes a `Notifier` instance.
|
||||
*
|
||||
@@ -195,7 +199,10 @@ public:
|
||||
explicit Notifier(Instance &aInstance);
|
||||
|
||||
/**
|
||||
* Registers an `otStateChangedCallback` handler.
|
||||
* Registers an external `StateChangedCallback`.
|
||||
*
|
||||
* This is intended for use by external users (i.e., provided as an OpenThread public API). `kMaxExternalHandlers`
|
||||
* specifies the maximum number of callbacks.
|
||||
*
|
||||
* @param[in] aCallback A pointer to the handler function that is called to notify of the changes.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
@@ -204,15 +211,15 @@ public:
|
||||
* @retval kErrorAlready The callback was already registered.
|
||||
* @retval kErrorNoBufs Could not add the callback due to resource constraints.
|
||||
*/
|
||||
Error RegisterCallback(otStateChangedCallback aCallback, void *aContext);
|
||||
Error RegisterCallback(StateChangedCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* Removes/unregisters a previously registered `otStateChangedCallback` handler.
|
||||
* Removes/unregisters a previously registered `StateChangedCallback` handler.
|
||||
*
|
||||
* @param[in] aCallback A pointer to the callback function pointer.
|
||||
* @param[in] aContext A pointer to arbitrary context information.
|
||||
*/
|
||||
void RemoveCallback(otStateChangedCallback aCallback, void *aContext);
|
||||
void RemoveCallback(StateChangedCallback aCallback, void *aContext);
|
||||
|
||||
/**
|
||||
* Schedules signaling of an event.
|
||||
@@ -279,8 +286,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr uint16_t kMaxExternalHandlers = OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS;
|
||||
|
||||
// Character limit to divide the log into multiple lines in `LogChangedFlags()`.
|
||||
static constexpr uint16_t kFlagsStringLineLimit = 70;
|
||||
|
||||
@@ -289,19 +294,20 @@ private:
|
||||
|
||||
static constexpr uint16_t kFlagsStringBufferSize = kFlagsStringLineLimit + kMaxFlagNameLength;
|
||||
|
||||
typedef Callback<otStateChangedCallback> ExternalCallback;
|
||||
typedef Callback<StateChangedCallback> ExternalCallback;
|
||||
|
||||
void EmitEvents(void);
|
||||
|
||||
void LogEvents(Events aEvents) const;
|
||||
const char *EventToString(Event aEvent) const;
|
||||
|
||||
using EmitEventsTask = TaskletIn<Notifier, &Notifier::EmitEvents>;
|
||||
using EmitEventsTask = TaskletIn<Notifier, &Notifier::EmitEvents>;
|
||||
using ExternalCallbackArray = Array<ExternalCallback, kMaxExternalHandlers>;
|
||||
|
||||
Events mEventsToSignal;
|
||||
Events mSignaledEvents;
|
||||
EmitEventsTask mTask;
|
||||
ExternalCallback mExternalCallbacks[kMaxExternalHandlers];
|
||||
Events mEventsToSignal;
|
||||
Events mSignaledEvents;
|
||||
EmitEventsTask mTask;
|
||||
ExternalCallbackArray mExternalCallbacks;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user