-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Minimize API surface that is templated for CommandHandler
#33620
Minimize API surface that is templated for CommandHandler
#33620
Conversation
PR #33620: Size comparison from 6b83689 to a32fb0c Increases above 0.2%:
Increases (37 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, esp32, linux, nrfconnect, stm32)
Decreases (79 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, cyw30739, efr32, esp32, linux, mbed, nrfconnect, nxp, psoc6, qpg, stm32, telink)
Full report (83 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, cyw30739, efr32, esp32, linux, mbed, nrfconnect, nxp, psoc6, qpg, stm32, telink)
|
PR #33620: Size comparison from 6b83689 to 46d905a Increases above 0.2%:
Increases (37 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, esp32, linux, nrfconnect, stm32)
Decreases (79 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, cyw30739, efr32, esp32, linux, mbed, nrfconnect, nxp, psoc6, qpg, stm32, telink)
Full report (83 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, cyw30739, efr32, esp32, linux, mbed, nrfconnect, nxp, psoc6, qpg, stm32, telink)
|
public: | ||
virtual ~EncoderToTLV() = default; | ||
|
||
virtual CHIP_ERROR Encode(TLV::TLVWriter &, TLV::Tag tag) = 0; |
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.
Suggest naming the writer arg
class DataModelEncoderToTLV : public EncoderToTLV | ||
{ | ||
public: | ||
DataModelEncoderToTLV(const T & value) : mValue(value) {} |
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.
This has an ownership time consideration. Consider documenting.
public: | ||
DataModelEncoderToTLV(const T & value) : mValue(value) {} | ||
|
||
virtual CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag) { return DataModel::Encode(writer, tag, mValue); } |
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.
Please remove virtual and specify override
@@ -350,9 +399,21 @@ class CommandHandler | |||
* @param [in] aData the data for the response. | |||
*/ | |||
template <typename CommandData> | |||
void AddResponse(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) | |||
inline void AddResponse(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) |
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.
Why inline?
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.
I looked to reduce actual template explosion of typed function code and wanted to leave it up to the caller to generate the equivalent 'encoder' logic.
I will check to see if inline has any effect on code sizes ... I would probably be biased to use whatever uses the least flash.
@@ -57,6 +57,32 @@ | |||
namespace chip { | |||
namespace app { | |||
|
|||
/// Defines an abstract class of something that can be encoded | |||
/// into a TLV with a given data tag | |||
class EncoderToTLV |
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.
Why is this CommandHandler-specific? And if it is, why is it in the chip::app namespace?
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.
Was the minimal delta. The correct thing is probably for this to live close to DataModel::Encode since it ends up being like that. I will move it as a followup.
virtual CHIP_ERROR Encode(TLV::TLVWriter &, TLV::Tag tag) = 0; | ||
}; | ||
|
||
/// An `EncoderToTLV` the uses `DataModel::Encode` to encode things. |
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.
"the uses"?
} | ||
|
||
/** | ||
* API for adding a data response. The encoded is generally expected to encode |
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.
What is "the encoded"?
* Most applications are likely to use `AddResponseData` as a more convenient | ||
* one-call that auto-sets command ID and creates the underlying encoders. | ||
*/ | ||
CHIP_ERROR AddResponseDataViaEncoder(const ConcreteCommandPath & aRequestCommandPath, CommandId commandId, |
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.
Why does this need the "ViaEncoder" suffix? Why not just call this AddResponseData
? It has different arguments from the template version, so confusion should not be an issue.
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.
It did not have different arguments originally (when I did not notice we need a commandId). I will change them back.
* The encoder would generally encode a ClusterName::Commands::CommandName::Type with | ||
* the corresponding `GetCommandId` call. | ||
*/ | ||
void AddResponseViaEncoder(const ConcreteCommandPath & aRequestCommandPath, CommandId commandId, EncoderToTLV & encoder) |
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.
Again, why the "ViaEncoder" suffix?
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.
I had it without ViaEncoder
at first however then <template typename T>void AddResponse(const ConcreteCommandPath&, T>
and void AddResponse(const ConcreteCommandPath&, EncoderToTLV &encoder)
seemed ambigous.
In the mean time I had to add commandId, so I could rename them as well I guess. This was iterated a few times, can be more.
@@ -640,26 +700,14 @@ class CommandHandler | |||
* responding to. | |||
* @param [in] aData the data for the response. | |||
*/ | |||
template <typename CommandData> | |||
CHIP_ERROR TryAddResponseData(const ConcreteCommandPath & aRequestCommandPath, const CommandData & aData) | |||
CHIP_ERROR TryAddResponseDataViaEncoder(const ConcreteCommandPath & aRequestCommandPath, CommandId commandId, |
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.
Again, why the ViaEncoder suffix?
// that genuinely require templating, minimizes duplicate compiled code. | ||
ConcreteCommandPath responseCommandPath = { aRequestCommandPath.mEndpointId, aRequestCommandPath.mClusterId, | ||
CommandData::GetCommandId() }; | ||
ConcreteCommandPath responseCommandPath = { aRequestCommandPath.mEndpointId, aRequestCommandPath.mClusterId, commandId }; | ||
ReturnErrorOnFailure(TryAddResponseDataPreEncode(aRequestCommandPath, responseCommandPath)); | ||
TLV::TLVWriter * writer = GetCommandDataIBTLVWriter(); |
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.
Since this stuff is no longer templated:
- We no longer need this fine-grained slicing into things that do or do not depend on the now-nonexistent template argument.
- We do not need this thing in the header. It shouldn't be.
This is in preparation to simplify CommandHandler usage in the CommandHandlerInterface: even though command handler has 50+ methods and 20+ data members, the external interface seems to be limited to 6 calls: addstatus/response/responsedata and some getters (fabricindex and subjectedescriptor) and an early flush call:
As a result, it seems highly desirable to have some
AddRespose
implementation that is non-templated and this also addresses a subset #31627 (and may save some flash as a result as the surface that is templated may become smaller even if that is not a primary goal of this PR).