[Dart] Improve dart generator 30/282730/5
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 11 Oct 2022 02:29:42 +0000 (02:29 +0000)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 11 Oct 2022 06:06:24 +0000 (06:06 +0000)
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 <h.jhun@samsung.com>
idlc/gen/dart_gen_base.cc
idlc/gen/dart_gen_base_cb.h
idlc/gen/dart_proxy_gen.cc
idlc/gen/dart_proxy_gen.h
idlc/gen/dart_proxy_gen_cb.h

index 5f31c93fa6e1a498e3f876a9da0e13d7915ef60f..008b5c722560fbf1d1bd08e53ca5007024621514 100644 (file)
@@ -177,12 +177,8 @@ void DartGeneratorBase::GenMethodId(std::ofstream& stream) {
 }
 
 void DartGeneratorBase::GenCallbackBase(std::ofstream& stream) {
-  ReplaceAll(CB_CALLBACK_BASE, "<ON_RECEIVED_EVENT>",
-      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) {
index 36c55ed0152cf5e20ed3745021ed4f008f426bcc..4f930254cf9328e32eeca3c9278d7c3712d0a288 100644 (file)
@@ -79,24 +79,20 @@ enum _DelegateId {
 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) {
@@ -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<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";
 
 /**
index 736414002f8a4e2382a8c08c7314ba2336cd1613..de1aac29a3bf3c74ca1f1e89f9fdfe8fd0a02316 100644 (file)
@@ -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, {
+            { "<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, {
@@ -272,6 +278,7 @@ void DartProxyGen::GenDelegateBase(std::ofstream& stream,
         { "<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) {
@@ -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()) {
index cd9b5913fd60cd949cca031366e6d66a2251d6c9..20cce6b5cb341c2dd8d768258093f629aae15ce7 100644 (file)
@@ -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);
 };
 
index 33cd0f448dc3d70d0d1da100c97f15ac166ef9bd..84a31f606277d8f711ed8d528706849b53fcbe94 100644 (file)
@@ -23,66 +23,59 @@ namespace tidl {
  * <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) {
@@ -96,7 +89,7 @@ abstract class <INTERFACE_NAME> 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 <INTERFACE_NAME> 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 <INTERFACE_NAME> extends ProxyBase {
 
   /// 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>
@@ -163,7 +158,7 @@ Future<<RETURN_TYPE>> <LOWER_METHOD_NAME>(<ARGS>) 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";
 
 /**
- * <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