From 42fce39c77955f39573b8f74924fa3f3a2dd0643 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 11 Oct 2022 02:29:42 +0000 Subject: [PATCH] [Dart] Improve dart generator The implementation of the proxy(client) is improved. The delegate class is not exposed to the outside for developers. The delegate function is exposed for developers. Developers are able to register and deregister the delegate using the function. Change-Id: I30d1ce57b1ec0f30d3844977148ea2314a345158 Signed-off-by: Hwankyu Jhun --- idlc/gen/dart_gen_base.cc | 8 +--- idlc/gen/dart_gen_base_cb.h | 36 +++++++++++++----- idlc/gen/dart_proxy_gen.cc | 33 ++++++++++++++--- idlc/gen/dart_proxy_gen.h | 2 + idlc/gen/dart_proxy_gen_cb.h | 88 ++++++++++++++++++++++---------------------- 5 files changed, 101 insertions(+), 66 deletions(-) diff --git a/idlc/gen/dart_gen_base.cc b/idlc/gen/dart_gen_base.cc index 5f31c93..008b5c7 100644 --- a/idlc/gen/dart_gen_base.cc +++ b/idlc/gen/dart_gen_base.cc @@ -177,12 +177,8 @@ void DartGeneratorBase::GenMethodId(std::ofstream& stream) { } void DartGeneratorBase::GenCallbackBase(std::ofstream& stream) { - ReplaceAll(CB_CALLBACK_BASE, "", - IsProxy() ? CB_CALLBACK_BASE_ON_RECEIVED_EVENT : "") - .Transform([&](std::string str) { - return SmartIndent(std::move(str)); - }) - .Out(stream); + std::string code = IsProxy() ? CB_PROXY_CALLBACK_BASE : CB_STUB_CALLBACK_BASE; + stream << SmartIndent(std::move(code)); } void DartGeneratorBase::GenStructures(std::ofstream& stream) { diff --git a/idlc/gen/dart_gen_base_cb.h b/idlc/gen/dart_gen_base_cb.h index 36c55ed..4f93025 100644 --- a/idlc/gen/dart_gen_base_cb.h +++ b/idlc/gen/dart_gen_base_cb.h @@ -79,24 +79,20 @@ enum _DelegateId { constexpr const char CB_ENUM[] = R"__dart_cb(())__dart_cb"; -/** - * 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'; - + Future _onReceivedEvent(Parcel parcel); @override void serialize(Parcel parcel) { @@ -114,9 +110,29 @@ abstract class _CallbackBase extends Parcelable { } )__dart_cb"; -constexpr const char CB_CALLBACK_BASE_ON_RECEIVED_EVENT[] = +constexpr const char CB_STUB_CALLBACK_BASE[] = R"__dart_cb( -Future _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"; /** diff --git a/idlc/gen/dart_proxy_gen.cc b/idlc/gen/dart_proxy_gen.cc index 7364140..de1aac2 100644 --- a/idlc/gen/dart_proxy_gen.cc +++ b/idlc/gen/dart_proxy_gen.cc @@ -34,11 +34,16 @@ void DartProxyGen::OnInitGen(std::ofstream& stream) { 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) @@ -113,16 +118,17 @@ std::string DartProxyGen::GenMethodParcelWrite(const Declaration& decl) { continue; auto& type = param_type.GetBaseType(); - if (type.IsUserDefinedType()) { + if (IsDelegateType(type)) { + code += ReplaceAll(CB_METHOD_DELEGATE_WRITE, { + { "", ConvertTypeToString(type) }, + { "", p->GetID() } + }); + code += NLine(1); + } else if (type.IsUserDefinedType()) { code += ReplaceAll(CB_USER_DEFINED_PARCEL_WRITE, { { "", "parcel" }, { "", p->GetID() } }); - if (IsDelegateType(type)) { - code += ReplaceAll(CB_METHOD_DELEGATE_ADD, { - { "", p->GetID()}, - }); - } code += NLine(1); } else if (type.ToString() == "list" || type.ToString() == "array") { code += ReplaceAll(CB_LIST_PARCEL_WRITE, { @@ -272,6 +278,7 @@ void DartProxyGen::GenDelegateBase(std::ofstream& stream, { "", GetClassName(decl.GetID()) }, { "", id }, { "", GenDelegateParams(decl) }, + { "", GenDelegateParamTypes(decl) }, { "", GenDelegateParcelRead(decl) } }) .Transform([&](std::string str) { @@ -292,6 +299,20 @@ std::string DartProxyGen::GenDelegateParams(const Declaration& decl) { 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()) { diff --git a/idlc/gen/dart_proxy_gen.h b/idlc/gen/dart_proxy_gen.h index cd9b591..20cce6b 100644 --- a/idlc/gen/dart_proxy_gen.h +++ b/idlc/gen/dart_proxy_gen.h @@ -33,6 +33,7 @@ class DartProxyGen : public DartGeneratorBase { void OnFiniGen(std::ofstream& stream) override; private: + void GenOnDisconnected(std::ofstream& stream); void GenInterfaces(std::ofstream& stream); void GenInterface(std::ofstream& stream, const Interface& iface); void GenInterfaceBase(std::ofstream& stream, const Interface& iface); @@ -48,6 +49,7 @@ class DartProxyGen : public DartGeneratorBase { std::string GenMethodParams(const Declaration& decl); void GenDelegateBase(std::ofstream& stream, const Declaration& decl); std::string GenDelegateParams(const Declaration& decl); + std::string GenDelegateParamTypes(const Declaration& decl); std::string GenDelegateParcelRead(const Declaration& decl); }; diff --git a/idlc/gen/dart_proxy_gen_cb.h b/idlc/gen/dart_proxy_gen_cb.h index 33cd0f4..84a31f6 100644 --- a/idlc/gen/dart_proxy_gen_cb.h +++ b/idlc/gen/dart_proxy_gen_cb.h @@ -23,66 +23,59 @@ namespace tidl { * The name of the delegate. * The ID of the delegate. * Parameters of the delegate. + * Types of Parameters of the delegate. * The implementation to write arguments to the parcel. */ constexpr const char CB_DELEGATE_BASE[] = R"__dart_cb( -/// The class to invoke the delegate method. -abstract class extends _CallbackBase { - /// Constructor for this class. - ({bool once = false}) : super(_DelegateId..id, once); +/// Called when the event is received. +typedef = void Function(); - /// This abstract method will be called when the delegate is received event. - Future onReceived(String sender, String msg); +class _ extends _CallbackBase { + /// Constructor for this class. + _( callback, {bool once = false}) + : super(_DelegateId..id, once, callback); @override Future _onReceivedEvent(Parcel parcel) async { - await onReceived(); + callback?.call(); } } )__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"; + /** * The name of the interface. */ constexpr const char CB_INTERFACE_BASE[] = R"__dart_cb( -/// Abstract class for creating [] class for RPC. -abstract class extends ProxyBase { +/// [] class for RPC. +class extends ProxyBase { /// Constructor for this class. (String appid) : super(appid, ''); - bool _online = false; + bool _isOnline = false; final List<_CallbackBase> _delegateList = <_CallbackBase>[]; - - /// The abstract method for receiving connected event. - Future onConnected(); - - /// The abstract method for receiving disconnected event. - Future onDisconnected(); - - /// The abstract method for receiving rejected event. - Future onRejected(String errorMessage); - - @override - Future onConnectedEvent() async { - _online = true; - await onConnected(); - } + OnDisconnected? _onDisconnected; @override + @nonVirtual Future onDisconnectedEvent() async { - _online = false; - await onDisconnected(); - } - - @override - Future onRejectedEvent(String errorMessage) async { - await onRejected(errorMessage); + await super.onDisconnectedEvent(); + _isOnline = false; + _onDisconnected?.call(); } @override + @nonVirtual Future onReceivedEvent(Parcel parcel) async { final int cmd = parcel.readInt32(); if (cmd != _MethodId.callback.id) { @@ -96,7 +89,7 @@ abstract class extends ProxyBase { 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; @@ -108,11 +101,9 @@ abstract class extends ProxyBase { 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(); @@ -121,19 +112,23 @@ abstract class extends ProxyBase { /// Connects with the stub application. @override - Future connect() async { + Future connect({OnDisconnected? onDisconnected}) async { + _onDisconnected = onDisconnected; await super.connect(); + _isOnline = true; } /// Disconnects with the stub application. + @override Future 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); } @@ -163,7 +158,7 @@ Future<> () async { */ constexpr const char CB_METHOD_PARCEL_WRITE[] = R"__dart_cb( -if (!_online) { +if (!_isOnline) { throw Exception('NotConnectedSocketException'); } @@ -200,11 +195,16 @@ return ret; )__dart_cb"; /** - * The name of a delegate object. + * The name of the delegate object. + * 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(); +{ + final _ callbackBase = _(); + callbackBase.serialize(parcel); + _delegateList.add(callbackBase); +} )__dart_cb"; } // namespace tidl -- 2.7.4