mirror of
https://github.com/espressif/openthread.git
synced 2026-09-16 22:20:07 +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);
|
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:
|
protected:
|
||||||
CallbackBase(void)
|
CallbackBase(void)
|
||||||
: mHandler(nullptr)
|
: mHandler(nullptr)
|
||||||
|
|||||||
@@ -43,51 +43,27 @@ Notifier::Notifier(Instance &aInstance)
|
|||||||
: InstanceLocator(aInstance)
|
: InstanceLocator(aInstance)
|
||||||
, mTask(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;
|
Error error = kErrorNone;
|
||||||
ExternalCallback *unusedCallback = nullptr;
|
ExternalCallback newCallback;
|
||||||
|
|
||||||
VerifyOrExit(aCallback != nullptr);
|
newCallback.Set(aCallback, aContext);
|
||||||
|
VerifyOrExit(!mExternalCallbacks.Contains(newCallback), error = kErrorAlready);
|
||||||
for (ExternalCallback &callback : mExternalCallbacks)
|
error = mExternalCallbacks.PushBack(newCallback);
|
||||||
{
|
|
||||||
VerifyOrExit(!callback.Matches(aCallback, aContext), error = kErrorAlready);
|
|
||||||
|
|
||||||
if (!callback.IsSet() && (unusedCallback == nullptr))
|
|
||||||
{
|
|
||||||
unusedCallback = &callback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VerifyOrExit(unusedCallback != nullptr, error = kErrorNoBufs);
|
|
||||||
|
|
||||||
unusedCallback->Set(aCallback, aContext);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return error;
|
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)
|
callbackToRemove.Set(aCallback, aContext);
|
||||||
{
|
mExternalCallbacks.Remove(callbackToRemove);
|
||||||
if (callback.Matches(aCallback, aContext))
|
|
||||||
{
|
|
||||||
callback.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notifier::Signal(Event aEvent)
|
void Notifier::Signal(Event aEvent)
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <openthread/instance.h>
|
#include <openthread/instance.h>
|
||||||
#include <openthread/platform/toolchain.h>
|
#include <openthread/platform/toolchain.h>
|
||||||
|
|
||||||
|
#include "common/array.hpp"
|
||||||
#include "common/callback.hpp"
|
#include "common/callback.hpp"
|
||||||
#include "common/error.hpp"
|
#include "common/error.hpp"
|
||||||
#include "common/locator.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()`
|
* For core internal modules, `Notifier` class emits events directly to them by invoking method `HandleNotifierEvents()`
|
||||||
* on the module instance.
|
* 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
|
class Notifier : public InstanceLocator, private NonCopyable
|
||||||
{
|
{
|
||||||
public:
|
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.
|
* Initializes a `Notifier` instance.
|
||||||
*
|
*
|
||||||
@@ -195,7 +199,10 @@ public:
|
|||||||
explicit Notifier(Instance &aInstance);
|
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] aCallback A pointer to the handler function that is called to notify of the changes.
|
||||||
* @param[in] aContext A pointer to arbitrary context information.
|
* @param[in] aContext A pointer to arbitrary context information.
|
||||||
@@ -204,15 +211,15 @@ public:
|
|||||||
* @retval kErrorAlready The callback was already registered.
|
* @retval kErrorAlready The callback was already registered.
|
||||||
* @retval kErrorNoBufs Could not add the callback due to resource constraints.
|
* @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] aCallback A pointer to the callback function pointer.
|
||||||
* @param[in] aContext A pointer to arbitrary context information.
|
* @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.
|
* Schedules signaling of an event.
|
||||||
@@ -279,8 +286,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint16_t kMaxExternalHandlers = OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS;
|
|
||||||
|
|
||||||
// Character limit to divide the log into multiple lines in `LogChangedFlags()`.
|
// Character limit to divide the log into multiple lines in `LogChangedFlags()`.
|
||||||
static constexpr uint16_t kFlagsStringLineLimit = 70;
|
static constexpr uint16_t kFlagsStringLineLimit = 70;
|
||||||
|
|
||||||
@@ -289,19 +294,20 @@ private:
|
|||||||
|
|
||||||
static constexpr uint16_t kFlagsStringBufferSize = kFlagsStringLineLimit + kMaxFlagNameLength;
|
static constexpr uint16_t kFlagsStringBufferSize = kFlagsStringLineLimit + kMaxFlagNameLength;
|
||||||
|
|
||||||
typedef Callback<otStateChangedCallback> ExternalCallback;
|
typedef Callback<StateChangedCallback> ExternalCallback;
|
||||||
|
|
||||||
void EmitEvents(void);
|
void EmitEvents(void);
|
||||||
|
|
||||||
void LogEvents(Events aEvents) const;
|
void LogEvents(Events aEvents) const;
|
||||||
const char *EventToString(Event aEvent) 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 mEventsToSignal;
|
||||||
Events mSignaledEvents;
|
Events mSignaledEvents;
|
||||||
EmitEventsTask mTask;
|
EmitEventsTask mTask;
|
||||||
ExternalCallback mExternalCallbacks[kMaxExternalHandlers];
|
ExternalCallbackArray mExternalCallbacks;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user