-
Notifications
You must be signed in to change notification settings - Fork 127
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
Documentation for new code generator tags, august2024 #1727
Changes from 4 commits
9521be1
4eb05e6
8426f7c
9320bf6
f75f567
e4dd6bc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,6 +76,165 @@ By default, when the `@json` tag is added, all methods in the COM-RPC interface | |
|
||
In older Thunder versions (<R4), JSON-RPC interfaces were defined using separate JSON schema files. These would then need to be manually wired up in the plugin. By using the code-generators, we can eliminate this step, making it much faster and easier to write plugins. It is no longer recommended to create JSON schema files for JSON-RPC interfaces. | ||
|
||
#### Overview | ||
|
||
* It is now possible to specify a separate JSON-RPC interface for handling connection issues and correct session management, and this will bring more options when the JSON-RPC interface deviates from the COM-RPC interface. | ||
|
||
* It is supported to send JSON-RPC over COM-RPC using the 'IDispatch' interface without the need for serialization. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? |
||
* This is particularly useful for out-of-process (OOP) and remote plugins. | ||
|
||
* The JSON-RPC generator now supports the usage of nested "plain-old data"(POD) types (such as plain C structs) in the C++ interface. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also nested PODs are supported |
||
* The JSON-RPC generator can now parse these structs and their usage in methods and generate a JSON-RPC interface for such cases. | ||
|
||
* `Core::hresult` is required as a return type value of all JSON-RPC enabled interfaces. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ? |
||
|
||
* `@text` metatag has been extended to have more options to influence the names used in generated code. | ||
* For more details click [here](../tags/#text). | ||
|
||
* Float type is now supported in the IDL header files. | ||
|
||
* `Core::instance_id` is now supported in the IDL header files. | ||
* It is presented as a 32/64 bit hexadecimal value in JSON-RPC. | ||
|
||
* `Core::Time` is now supported in the IDL header files. | ||
* It is presented as an [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) formatted string in JSON-RPC. | ||
|
||
* `Core::OptionalType<T>` allows a member to be optional (this superseded @optional), and must be used if an attribute is expected to be optional on JSON-RPC. In COM-RPC the OptionalType can be used to see if a value was set, and in JSON-RPC it is then allowed to omit this parameter. | ||
* A @default tag can be used to provide a value, in the case T is not set. See more [here](../tags/#default). | ||
* Note: Currently, OptionalType does not work with C-Style arrays. | ||
|
||
* JSON-RPC supports the usage of bitmask enums (a combination of enum values can be set in the same enum parameter at the same time). | ||
* This is mapped as an array of values in the JSON-RPC interface. | ||
* See more information about `/* bitmask */` [here](../tags/#bitmask). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
<hr/> | ||
|
||
#### Preventing Memory leaks | ||
|
||
A resource allocated by a remote client must still be freed in case the channel is disconnected before the client is able to do it on its own. | ||
|
||
To deal with this, a method can receive a ```Core::JSONRPC::Context``` as a parameter. | ||
|
||
Amongst other things, the context includes the channel ID, which enables the association of the JSON-RPC call with the client. | ||
|
||
Note: Context must be defined as the first parameter and will not be visible in the JSON-RPC messages. | ||
```cpp | ||
virtual Core::hresult Join(const Core::JSONRPC::Context& context,...) = 0; | ||
``` | ||
Note: ```IConnection::INotification``` can be used to be notified of the dropped channels. | ||
|
||
Examples: | ||
|
||
View [Messenger.h](https://github.com/WebPlatformForEmbedded/ThunderNanoServicesRDK/blob/master/Messenger/Messenger.h#L254-L255) to see how ```Core::JSONRPC::Context``` is used. | ||
|
||
<hr/> | ||
|
||
#### Notification Registration | ||
|
||
Notification registration is a way of tracking updates on a notification. | ||
|
||
Tagging a notification with @statuslistener will emit additional code that will allow you to be notified when a JSON-RPC client has registered (or unregistered) from this notification. As a result, an additional IHandler interface is generated, providing the callbacks. | ||
|
||
Examples: | ||
|
||
In [IMessenger.H](https://github.com/rdkcentral/ThunderInterfaces/blob/master/interfaces/IMessenger.h#L95-L111), @statuslistener is used on two methods. | ||
|
||
<hr/> | ||
This example will demonstrate the ability to be notified when a user performs a certain action. | ||
|
||
Suppose an interface "INotification" that contains a method "RoomUpdate", which tracks the availability of a room. The method is tagged with @statuslistener, which will allow for the creation of an "IHandler" interface. The "IHandler" interface will contain the required declaration of methods to allow for notification registration tracking. | ||
|
||
```cpp | ||
// @json 1.0.0 | ||
struct EXTERNAL IMessenger { | ||
virtual ~IMessenger() = default; | ||
|
||
/* @event */ | ||
struct EXTERNAL INotification { | ||
virtual ~INotification() = default; | ||
|
||
// @statuslistener | ||
virtual void RoomUpdate(...) = 0; | ||
} | ||
} | ||
``` | ||
An example of a generated IHandler interface providing the callbacks from the RoomUpdate() function. | ||
|
||
```cpp | ||
struct IHandler { | ||
virtual ~IHandler() = default; | ||
|
||
virtual void OnRoomUpdateEventRegistration(const string& client, const | ||
PluginHost::JSONRPCSupportsEventStatus::Status status) = 0; | ||
} | ||
``` | ||
|
||
Using the "IHandler" interface, its methods should be implemented to track the availability of the room. | ||
``` cpp | ||
|
||
class Messenger : public PluginHost::IPlugin | ||
, public JSONRPC::IMessenger | ||
, public JSONRPC::JMessenger::IHandler { | ||
|
||
// JSONRPC::JMessenger::IHandler override | ||
void OnRoomUpdateEventRegistration(const string& client, const | ||
PluginHost::JSONRPCSupportsEventStatus::Status status) { | ||
|
||
if(status == Status::registered) { | ||
|
||
for (const string& room: _rooms) { | ||
JMessenger::Event::RoomUpdate(...) | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
For a more detailed view, visit [Messenger.h](https://github.com/WebPlatformForEmbedded/ThunderNanoServicesRDK/blob/master/Messenger/Messenger.h). | ||
|
||
<hr/> | ||
|
||
#### Object lookup | ||
|
||
Object lookup defines the ability to create a JSON-RPC interface to access dynamically created objects (or sessions). | ||
This object interface is brought into JSON-RPC scope with a prefix. | ||
|
||
The format for this ability is to use the tag '@lookup:[prefix]' on a method. | ||
|
||
Note: If 'prefix' is not set, then the name of the object interface is used instead. | ||
|
||
##### Example | ||
|
||
The signature of a lookup function must be: | ||
|
||
```cpp | ||
virtual <Interface>* Method(const uint32_t id) = 0; | ||
``` | ||
|
||
An example of an IPlayer interface containing a playback session. Using tag @lookup, you are able to have multiple sessions, which can be differentiated by using JSON-RPC. | ||
|
||
```cpp | ||
struct IPlayer { | ||
struct IPlaybackSession { | ||
virtual Core::hresult Play() = 0; | ||
virtual Core::hresult Stop() = 0; | ||
}; | ||
|
||
// @lookup:session | ||
virtual IPlaySession* Session(const uint32_t id) = 0; | ||
|
||
virtual Core::hresult Create(uint32_t& id /* @out */) = 0; | ||
virtual Core::hresult Configure(const string& config) = 0; | ||
} | ||
``` | ||
An example of possible calls to the interface: the lookup method is used to convert the id to the object. | ||
|
||
``` | ||
Player.1.configure | ||
Player.1.create | ||
Player.1.session#1::play | ||
Player.1.session#1::stop | ||
``` | ||
|
||
### Code Generation | ||
|
||
The code generation tooling for Thunder lives in the [ThunderTools](https://github.com/rdkcentral/ThunderTools) repository. These tools are responsible for the generation of ProxyStub implementations for COM-RPC, JSON-RPC interfaces, JSON data types, and documentation. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,6 +106,8 @@ Ddefines a literal as a known identifier (equivalent of `#define` in C++ code) | |
|[@interface](#interface)| Specifies a parameter holding interface ID value for void* interface passing | | Yes | No |Method paramter| | ||
|[@length](#length)|Specifies the expression to evaluate length of an array parameter (can be other parameter name, or constant, or math expression)| | No | Yes | Method Parameter| | ||
|[@maxlength](#maxlength)|Specifies a maximum buffer length value | | No | Yes |Method parameter| | ||
|[@default](#default)|Provides a default value for an unset optional type | | Yes | Yes |Method parameter| | ||
|[@encode:base64](#encode:base64)|Encodes C-Style arrays as JSON-RPC base64 arrays | | Yes | Yes |Method parameter| | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be in line with the above documentation think the base64 should not be here but just document #encode influences the generated encoding and list the options (so also bitmask, see Sebastians presentation ) where the details are documented (so more like @text is documented). And isn't it only for json rpc so should it not be in the table below? And previously in the variable size arrays I'm sure it generated a string, so perhaps that is still the case? |
||
|
||
#### @in | ||
This tag will mark a parameter in a function as an input parameter. By default, all parameters in a function are treated as input paramter. | ||
|
@@ -208,6 +210,65 @@ When used with `@inout` it will use different buffer for output depending upon t | |
##### Example | ||
In [IPerformance.h](https://github.com/rdkcentral/ThunderInterfaces/blob/5fa166bd17c6b910696c6113c5520141bcdea07b/interfaces/IPerformance.h#L32) it specifies, the maximum length for the buffer. | ||
|
||
<hr/> | ||
|
||
#### @default | ||
This tag should be associated with optional types. It provides a default value for JSON-RPC, even if no explicit value was set. | ||
|
||
Note: Unless a parameter is optional, it must be set. | ||
|
||
Note: Currently, OptionalType does not work with C-Style arrays. | ||
|
||
##### Example | ||
|
||
In this example class, the OptionalType members have a default value that would be transmitted incase their values have not been set. | ||
|
||
```cpp | ||
struct Store { | ||
enum sizetype: uint8_t { | ||
S, M, L | ||
}; | ||
|
||
Core::OptionalType<string> Brand /* @default:"unknown" */; | ||
Core::OptionalType<sizetype> Size /* @default: M */; | ||
}; | ||
|
||
virtual Core::hresult Shirt(const Core::OptionalType<Store>& London) = 0; | ||
``` | ||
<hr/> | ||
|
||
In [IController.h](https://github.com/rdkcentral/Thunder/blob/master/Source/plugins/IController.h#L78) it specifies, the default value assigned incase the parameter is not set. | ||
|
||
<hr/> | ||
|
||
#### @encode:base64 | ||
|
||
This tag encodes C-Style arrays into JSON-RPC arrays as base64 strings, on the condition that the array base is type `uint8_t`. | ||
|
||
##### Example | ||
|
||
In this example, C-Style `uint8_t` arrays are encoded as base64. | ||
|
||
```cpp | ||
struct Fixated { | ||
struct BlueToothInfo { | ||
uint8_t Addr[6] /* encode:base64 */; | ||
uint32_t UUIDs[8]; | ||
string Descriptions[8]; | ||
}; | ||
|
||
Bluetooth BtAddr[5]; | ||
uint8_t Edid[128] /*encode:base64 */; | ||
}; | ||
|
||
``` | ||
|
||
<hr/> | ||
|
||
In [IDisplayInfo.h](https://github.com/rdkcentral/ThunderInterfaces/blob/a229ea291aa52dc99e9c27839938f4f2af4a6190/interfaces/IDisplayInfo.h#L101), the EDID data parameter is encoded. | ||
|
||
|
||
<hr/> | ||
|
||
### JSON-RPC Related Tags | ||
|
||
|
@@ -226,6 +287,9 @@ In [IPerformance.h](https://github.com/rdkcentral/ThunderInterfaces/blob/5fa166b | |
|[@opaque](#opaque)| Indicates that a string parameter is an opaque JSON object | | No | Yes |Method parameter| | ||
|[@alt](#alt)| Provides an alternative name a method can by called by | | No | Yes |Method| | ||
|[@text](#text)| Renames identifier Method, Parameter, PoD Member, Enum, Interface | | No | Yes |Enum, Method parameter, Method name, PoD member, Interface | | ||
|[@prefix](#prefix)| Prepends identifier for all JSON-RPC methods and properties in a class | | No | Yes | Class | | ||
|[@statuslistener](#statuslistener)| Notifies when a JSON-RPC client registers/unregisters from an notification | | No | Yes | Method | | ||
|[@lookup](#lookup)| Creates a JSON-RPC interface to access dynamically created sessions | | No | Yes | Method | | ||
|
||
#### @json | ||
This tag helps to generate JSON-RPC files for the given Class/Struct/enum. | ||
|
@@ -397,8 +461,19 @@ Indicates the string parameter contains a JSON document that should not be deser | |
#### @alt | ||
Provide an alternative name for the method. JSON-RPC methods will be generated for both the actual function name and the alternative name | ||
|
||
Note: @text, @alt, @deprecated can be used together. | ||
|
||
##### Example | ||
[IController](https://github.com/rdkcentral/Thunder/blob/R4.3/Source/plugins/IController.h#L38) uses @alt for the `Reboot()` method to generate an alternatively named method called `Harakiri` (for legacy reasons) | ||
|
||
Methods, properties and notifications can be marked by using: | ||
```cpp | ||
// @alt <alternative_name> | ||
// @alt:deprecated <alternative_deprecated_name> | ||
// @alt:obsolete <alternative_obsolete_name> | ||
``` | ||
<hr/> | ||
|
||
[IController.h](https://github.com/rdkcentral/Thunder/blob/R4.3/Source/plugins/IController.h#L38) uses @alt for the `Reboot()` method to generate an alternatively named method called `Harakiri` (for legacy reasons) | ||
|
||
<hr/> | ||
|
||
|
@@ -442,10 +517,40 @@ In this example now for all enums, method names, method parameters and PoD membe | |
/* @json 1.0.0 @text:keep */ | ||
struct EXTERNAL IExample : virtual public Core::IUnknown { | ||
``` | ||
</hr> | ||
<hr> | ||
|
||
#### @prefix | ||
Use this tag on a class to prepend all JSON-RPC methods with a prefix identifier. This is an alternative to using multiple @text tags. | ||
|
||
In this example, all registered methods would contain the prefix `source::` | ||
This is particularly useful for avoiding clashes, especially if several interfaces are implemented by the same plugin. | ||
|
||
```cpp | ||
// @json 1.0.0 | ||
// @prefix source | ||
struct EXTERNAL ISource: virtual public Core::IUnknown { | ||
``` | ||
</hr> | ||
<hr> | ||
|
||
#### @statuslistener | ||
|
||
Use this tag, to receive notifications when a JSON-RPC client has registered (or unregistered) from a notification. | ||
|
||
For more details, click [here](../interfaces/#notification-registration) | ||
|
||
</hr> | ||
<hr> | ||
|
||
#### @lookup | ||
|
||
This tag is used on methods, to create a JSON-RPC interface that is dynamically accessing created objects (or sessions). | ||
|
||
For more details, click [here](../interfaces/#object-lookup) | ||
|
||
</hr> | ||
<hr> | ||
|
||
### JSON-RPC Documentation Related Tags | ||
|
||
|
@@ -545,3 +650,5 @@ This tag adds description about each return codes specified in the generated mar | |
|
||
##### Example | ||
In [IVolumeControl.h](https://github.com/rdkcentral/ThunderInterfaces/blob/5fa166bd17c6b910696c6113c5520141bcdea07b/interfaces/IVolumeControl.h#L54), it uses this tag to add description about the returned error code. | ||
|
||
<hr/> |
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.
Perhaps we should also document that fixed size arrays are now supported (e.g. array[10], it is used in the new examples below) in certain cases.
We haven't yet documented although it was already possible but guess we should add it now that you can also use variable lenght arrays (so also for json rpc) : https://github.com/rdkcentral/ThunderInterfaces/blob/a229ea291aa52dc99e9c27839938f4f2af4a6190/interfaces/IDisplayInfo.h#L101