constexpr const char CB_ENUM[] =
R"__dart_cb(<NAME>(<VALUE>))__dart_cb";
-/**
- * <ON_RECEIVED_EVENT> The definition for _onReceivedEvent method for proxy.
- */
-constexpr const char CB_CALLBACK_BASE[] =
+constexpr const char CB_PROXY_CALLBACK_BASE[] =
R"__dart_cb(
abstract class _CallbackBase extends Parcelable {
- _CallbackBase(this.id, this.once) {
+ _CallbackBase(this.id, this.once, this.callback) {
sequenceId = sequenceNum++;
}
int id = 0;
bool once = false;
int sequenceId = 0;
+ Function? callback;
static int sequenceNum = 0;
- /// Gets the tag.
- String get tag => '$id::$sequenceId';
- <ON_RECEIVED_EVENT>
+ Future<void> _onReceivedEvent(Parcel parcel);
@override
void serialize(Parcel parcel) {
}
)__dart_cb";
-constexpr const char CB_CALLBACK_BASE_ON_RECEIVED_EVENT[] =
+constexpr const char CB_STUB_CALLBACK_BASE[] =
R"__dart_cb(
-Future<void> _onReceivedEvent(Parcel parcel);
+abstract class _CallbackBase extends Parcelable {
+ _CallbackBase(this.id, this.once);
+
+ int id = 0;
+ bool once = false;
+ int sequenceId = 0;
+
+ @override
+ void serialize(Parcel parcel) {
+ parcel.writeInt32(id);
+ parcel.writeInt32(sequenceId);
+ parcel.writeBool(once);
+ }
+
+ @override
+ void deserialize(Parcel parcel) {
+ id = parcel.readInt32();
+ sequenceId = parcel.readInt32();
+ once = parcel.readBool();
+ }
+}
)__dart_cb";
/**
GenDelegateId(stream);
GenMethodId(stream);
GenStructures(stream);
+ GenOnDisconnected(stream);
GenInterfaces(stream);
}
void DartProxyGen::OnFiniGen(std::ofstream& stream) {}
+void DartProxyGen::GenOnDisconnected(std::ofstream& stream) {
+ stream << CB_ON_DISCONNECTED;
+}
+
void DartProxyGen::GenInterfaces(std::ofstream& stream) {
for (auto& i : GetDocument().GetBlocks()) {
if (i->GetType() != Block::TYPE_INTERFACE)
continue;
auto& type = param_type.GetBaseType();
- if (type.IsUserDefinedType()) {
+ if (IsDelegateType(type)) {
+ code += ReplaceAll(CB_METHOD_DELEGATE_WRITE, {
+ { "<DELEGATE_TYPE>", ConvertTypeToString(type) },
+ { "<DELEGATE_NAME>", p->GetID() }
+ });
+ code += NLine(1);
+ } else if (type.IsUserDefinedType()) {
code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, {
{ "<PARCEL>", "parcel" },
{ "<NAME>", p->GetID() }
});
- if (IsDelegateType(type)) {
- code += ReplaceAll(CB_METHOD_DELEGATE_ADD, {
- { "<DELEGATE>", p->GetID()},
- });
- }
code += NLine(1);
} else if (type.ToString() == "list" || type.ToString() == "array") {
code += ReplaceAll(CB_LIST_PARCEL_WRITE, {
{ "<DELEGATE_NAME>", GetClassName(decl.GetID()) },
{ "<DELEGATE_ID>", id },
{ "<DELEGATE_PARAMS>", GenDelegateParams(decl) },
+ { "<DELEGATE_PARAM_TYPES>", GenDelegateParamTypes(decl) },
{ "<DELEGATE_PARCEL_READ>", GenDelegateParcelRead(decl) }
})
.Transform([&](std::string str) {
return params;
}
+std::string DartProxyGen::GenDelegateParamTypes(const Declaration& decl) {
+ std::string types;
+ for (const auto& p : decl.GetParameters()) {
+ if (!types.empty())
+ types += ", ";
+
+ auto& param_type = p->GetParameterType();
+ auto& type = param_type.GetBaseType();
+ types += ConvertTypeToString(type);
+ }
+
+ return types;
+}
+
std::string DartProxyGen::GenDelegateParcelRead(const Declaration& decl) {
std::string code;
for (const auto& p : decl.GetParameters()) {
* <DELEGATE_NAME> The name of the delegate.
* <DELEGATE_ID> The ID of the delegate.
* <DELEGATE_PARAMS> Parameters of the delegate.
+ * <DELEGATE_PARAM_TYPES> Types of Parameters of the delegate.
* <DELEGATE_PARCEL_WRITE> The implementation to write arguments to the parcel.
*/
constexpr const char CB_DELEGATE_BASE[] =
R"__dart_cb(
-/// The <DELEGATE_NAME> class to invoke the delegate method.
-abstract class <DELEGATE_NAME> extends _CallbackBase {
- /// Constructor for this class.
- <DELEGATE_NAME>({bool once = false}) : super(_DelegateId.<DELEGATE_ID>.id, once);
+/// Called when the <DELEGATE_NAME> event is received.
+typedef <DELEGATE_NAME> = void Function(<DELEGATE_PARAM_TYPES>);
- /// This abstract method will be called when the delegate is received event.
- Future<void> onReceived(String sender, String msg);
+class _<DELEGATE_NAME> extends _CallbackBase {
+ /// Constructor for this class.
+ _<DELEGATE_NAME>(<DELEGATE_NAME> callback, {bool once = false})
+ : super(_DelegateId.<DELEGATE_ID>.id, once, callback);
@override
Future<void> _onReceivedEvent(Parcel parcel) async {
<DELEGATE_PARCEL_READ>
- await onReceived(<DELEGATE_PARAMS>);
+ callback?.call(<DELEGATE_PARAMS>);
}
}
)__dart_cb";
+constexpr const char CB_ON_DISCONNECTED[] =
+R"__dart_cb(
+/// Called when the disconnected event is received on rpc port.
+///
+/// This is used by the connect() of interfaces.
+typedef OnDisconnected = void Function();
+)__dart_cb";
+
/**
* <INTERFACE_NAME> The name of the interface.
*/
constexpr const char CB_INTERFACE_BASE[] =
R"__dart_cb(
-/// Abstract class for creating [<INTERFACE_NAME>] class for RPC.
-abstract class <INTERFACE_NAME> extends ProxyBase {
+/// [<INTERFACE_NAME>] class for RPC.
+class <INTERFACE_NAME> extends ProxyBase {
/// Constructor for this class.
<INTERFACE_NAME>(String appid) : super(appid, '<INTERFACE_NAME>');
- bool _online = false;
+ bool _isOnline = false;
final List<_CallbackBase> _delegateList = <_CallbackBase>[];
-
- /// The abstract method for receiving connected event.
- Future<void> onConnected();
-
- /// The abstract method for receiving disconnected event.
- Future<void> onDisconnected();
-
- /// The abstract method for receiving rejected event.
- Future<void> onRejected(String errorMessage);
-
- @override
- Future<void> onConnectedEvent() async {
- _online = true;
- await onConnected();
- }
+ OnDisconnected? _onDisconnected;
@override
+ @nonVirtual
Future<void> onDisconnectedEvent() async {
- _online = false;
- await onDisconnected();
- }
-
- @override
- Future<void> onRejectedEvent(String errorMessage) async {
- await onRejected(errorMessage);
+ await super.onDisconnectedEvent();
+ _isOnline = false;
+ _onDisconnected?.call();
}
@override
+ @nonVirtual
Future<void> onReceivedEvent(Parcel parcel) async {
final int cmd = parcel.readInt32();
if (cmd != _MethodId.callback.id) {
for (final _CallbackBase delegate in _delegateList) {
if (delegate.id == id && delegate.sequenceId == seqId) {
await delegate._onReceivedEvent(parcel);
- if (delegate.once) {
+ if (delegate.once && once) {
_delegateList.remove(delegate);
}
break;
try {
final Parcel parcel = Parcel.fromPort(port);
final int cmd = parcel.readInt32();
-
if (cmd != _MethodId.result.id) {
throw Exception('Received parcel is invalid. $cmd');
}
-
return parcel;
} catch (e) {
return Parcel();
/// Connects with the stub application.
@override
- Future<void> connect() async {
+ Future<void> connect({OnDisconnected? onDisconnected}) async {
+ _onDisconnected = onDisconnected;
await super.connect();
+ _isOnline = true;
}
/// Disconnects with the stub application.
+ @override
Future<void> disconnect() async {
- final Port port = getPort(PortType.main);
- port.disconnect();
+ await super.disconnect();
+ _isOnline = false;
}
/// Dispose registered delegate interface.
- void disposeCallback(String tag) {
- _delegateList.removeWhere((_CallbackBase element) => element.tag == tag);
+ void disposeCallback(Function callback) {
+ _delegateList
+ .removeWhere((_CallbackBase element) => element.callback == callback);
}
<METHODS>
*/
constexpr const char CB_METHOD_PARCEL_WRITE[] =
R"__dart_cb(
-if (!_online) {
+if (!_isOnline) {
throw Exception('NotConnectedSocketException');
}
)__dart_cb";
/**
- * <DELEGATE> The name of a delegate object.
+ * <DELEGATE_TYPE> The name of the delegate object.
+ * <DELEGATE_NAME> The name of the delegate object.
*/
-constexpr const char CB_METHOD_DELEGATE_ADD[] =
+constexpr const char CB_METHOD_DELEGATE_WRITE[] =
R"__dart_cb(
-_delegateList.add(<DELEGATE>);
+{
+ final _<DELEGATE_TYPE> callbackBase = _<DELEGATE_TYPE>(<DELEGATE_NAME>);
+ callbackBase.serialize(parcel);
+ _delegateList.add(callbackBase);
+}
)__dart_cb";
} // namespace tidl