writeFlutterApi method
void
writeFlutterApi(
- CppOptions generatorOptions,
- Root root,
- Indent indent,
- AstFlutterApi api, {
- required String dartPackageName,
override
Writes a single Flutter Api to indent
.
Implementation
@override
void writeFlutterApi(
CppOptions generatorOptions,
Root root,
Indent indent,
AstFlutterApi api, {
required String dartPackageName,
}) {
if (getCodecClasses(api, root).isNotEmpty) {
_writeCodec(generatorOptions, root, indent, api);
}
indent.writeln(
'$_commentPrefix Generated class from Pigeon that represents Flutter messages that can be called from C++.');
_writeFunctionDefinition(
indent,
api.name,
scope: api.name,
parameters: <String>[
'flutter::BinaryMessenger* binary_messenger',
],
initializers: <String>[
'binary_messenger_(binary_messenger)',
'message_channel_suffix_("")'
],
);
_writeFunctionDefinition(
indent,
api.name,
scope: api.name,
parameters: <String>[
'flutter::BinaryMessenger* binary_messenger',
'const std::string& message_channel_suffix'
],
initializers: <String>[
'binary_messenger_(binary_messenger)',
'message_channel_suffix_(message_channel_suffix.length() > 0 ? std::string(".") + message_channel_suffix : "")'
],
);
final String codeSerializerName = getCodecClasses(api, root).isNotEmpty
? _getCodecSerializerName(api)
: _defaultCodecSerializer;
_writeFunctionDefinition(
indent,
'GetCodec',
scope: api.name,
returnType: 'const flutter::StandardMessageCodec&',
body: () {
indent.writeln(
'return flutter::StandardMessageCodec::GetInstance(&$codeSerializerName::GetInstance());');
},
);
for (final Method func in api.methods) {
final HostDatatype returnType =
getHostDatatype(func.returnType, _shortBaseCppTypeForBuiltinDartType);
// Determine the input parameter list, saved in a structured form for later
// use as platform channel call arguments.
final Iterable<_HostNamedType> hostParameters =
indexMap(func.parameters, (int i, NamedType arg) {
final HostDatatype hostType =
getFieldHostDatatype(arg, _shortBaseCppTypeForBuiltinDartType);
return _HostNamedType(_getSafeArgumentName(i, arg), hostType, arg.type);
});
final List<String> parameters = <String>[
...hostParameters.map((_HostNamedType arg) =>
'${_flutterApiArgumentType(arg.hostType)} ${arg.name}'),
..._flutterApiCallbackParameters(returnType),
];
_writeFunctionDefinition(indent, _makeMethodName(func),
scope: api.name,
returnType: _voidType,
parameters: parameters, body: () {
indent.writeln(
'const std::string channel_name = "${makeChannelName(api, func, dartPackageName)}" + message_channel_suffix_;');
indent.writeln('BasicMessageChannel<> channel(binary_messenger_, '
'channel_name, &GetCodec());');
// Convert arguments to EncodableValue versions.
const String argumentListVariableName = 'encoded_api_arguments';
indent.write('EncodableValue $argumentListVariableName = ');
if (func.parameters.isEmpty) {
indent.addln('EncodableValue();');
} else {
indent.addScoped('EncodableValue(EncodableList{', '});', () {
for (final _HostNamedType param in hostParameters) {
final String encodedArgument = _wrappedHostApiArgumentExpression(
root,
param.name,
param.originalType,
param.hostType,
false,
);
indent.writeln('$encodedArgument,');
}
});
}
indent.write('channel.Send($argumentListVariableName, '
// ignore: missing_whitespace_between_adjacent_strings
'[channel_name, on_success = std::move(on_success), on_error = std::move(on_error)]'
'(const uint8_t* reply, size_t reply_size) ');
indent.addScoped('{', '});', () {
String successCallbackArgument;
successCallbackArgument = 'return_value';
final String encodedReplyName = 'encodable_$successCallbackArgument';
final String listReplyName = 'list_$successCallbackArgument';
indent.writeln(
'std::unique_ptr<EncodableValue> response = GetCodec().DecodeMessage(reply, reply_size);');
indent.writeln('const auto& $encodedReplyName = *response;');
indent.writeln(
'const auto* $listReplyName = std::get_if<EncodableList>(&$encodedReplyName);');
indent.writeScoped('if ($listReplyName) {', '} ', () {
indent.writeScoped('if ($listReplyName->size() > 1) {', '} ', () {
indent.writeln(
'on_error(FlutterError(std::get<std::string>($listReplyName->at(0)), std::get<std::string>($listReplyName->at(1)), $listReplyName->at(2)));');
}, addTrailingNewline: false);
indent.addScoped('else {', '}', () {
if (func.returnType.isVoid) {
successCallbackArgument = '';
} else {
_writeEncodableValueArgumentUnwrapping(
indent,
root,
returnType,
argName: successCallbackArgument,
encodableArgName: '$listReplyName->at(0)',
apiType: ApiType.flutter,
);
}
indent.writeln('on_success($successCallbackArgument);');
});
}, addTrailingNewline: false);
indent.addScoped('else {', '} ', () {
indent.writeln('on_error(CreateConnectionError(channel_name));');
});
});
});
}
}