OLD | NEW |
| (Empty) |
1 {%- import "interface_macros.tmpl" as interface_macros %} | |
2 {%- import "struct_macros.tmpl" as struct_macros %} | |
3 {%- from "enum_macros.tmpl" import is_valid_enum_def %} | |
4 {%- from "enum_macros.tmpl" import global_enum_operators_def %} | |
5 | |
6 {%- set class_name = interface.name -%} | |
7 {%- set base_name = "internal::%s_Base"|format(interface.name) -%} | |
8 {%- set proxy_name = interface.name ~ "Proxy" -%} | |
9 | |
10 {%- macro alloc_params(struct) %} | |
11 {%- for param in struct.packed.packed_fields_in_ordinal_order %} | |
12 {{param.field.kind|cpp_result_type}} p_{{param.field.name}} {}; | |
13 {%- endfor %} | |
14 {{struct_macros.deserialize(struct, "params", "p_%s")}} | |
15 {%- endmacro %} | |
16 | |
17 {%- macro pass_params(parameters) %} | |
18 {%- for param in parameters %} | |
19 {%- if param.kind|is_move_only_kind -%} | |
20 p_{{param.name}}.Pass() | |
21 {%- else -%} | |
22 p_{{param.name}} | |
23 {%- endif -%} | |
24 {%- if not loop.last %}, {% endif %} | |
25 {%- endfor %} | |
26 {%- endmacro %} | |
27 | |
28 {%- macro build_message(struct, struct_display_name) -%} | |
29 {{struct_macros.serialize(struct, struct_display_name, "in_%s", "params", "bui
lder.buffer()", false)}} | |
30 params->EncodePointersAndHandles(builder.message()->mutable_handles()); | |
31 {%- endmacro %} | |
32 | |
33 {#--- ForwardToCallback definition #} | |
34 {%- for method in interface.methods -%} | |
35 {%- if method.response_parameters != None %} | |
36 class {{class_name}}_{{method.name}}_ForwardToCallback | |
37 : public mojo::MessageReceiver { | |
38 public: | |
39 {{class_name}}_{{method.name}}_ForwardToCallback( | |
40 const {{class_name}}::{{method.name}}Callback& callback) | |
41 : callback_(callback) { | |
42 } | |
43 bool Accept(mojo::Message* message) override; | |
44 private: | |
45 {{class_name}}::{{method.name}}Callback callback_; | |
46 MOJO_DISALLOW_COPY_AND_ASSIGN({{class_name}}_{{method.name}}_ForwardToCallback
); | |
47 }; | |
48 bool {{class_name}}_{{method.name}}_ForwardToCallback::Accept( | |
49 mojo::Message* message) { | |
50 internal::{{class_name}}_{{method.name}}_ResponseParams_Data* params = | |
51 reinterpret_cast<internal::{{class_name}}_{{method.name}}_ResponseParams_D
ata*>( | |
52 message->mutable_payload()); | |
53 | |
54 params->DecodePointersAndHandles(message->mutable_handles()); | |
55 {{alloc_params(method.response_param_struct)}} | |
56 callback_.Run({{pass_params(method.response_parameters)}}); | |
57 return true; | |
58 } | |
59 {%- endif %} | |
60 {%- endfor %} | |
61 | |
62 {{proxy_name}}::{{proxy_name}}(mojo::MessageReceiverWithResponder* receiver) | |
63 : ControlMessageProxy(receiver) { | |
64 } | |
65 | |
66 {#--- Proxy definitions #} | |
67 | |
68 {%- for method in interface.methods %} | |
69 {%- set message_name = | |
70 "%s::MessageOrdinals::%s"|format(base_name, method.name) %} | |
71 {%- set params_struct = method.param_struct %} | |
72 {%- set params_description = | |
73 "%s.%s request"|format(interface.name, method.name) %} | |
74 void {{proxy_name}}::{{method.name}}( | |
75 {{interface_macros.declare_request_params("in_", method)}}) { | |
76 {{struct_macros.get_serialized_size(params_struct, "in_%s")}} | |
77 | |
78 {%- if method.response_parameters != None %} | |
79 mojo::RequestMessageBuilder builder( | |
80 static_cast<uint32_t>({{message_name}}), size); | |
81 {%- else %} | |
82 mojo::MessageBuilder builder( | |
83 static_cast<uint32_t>({{message_name}}), size); | |
84 {%- endif %} | |
85 | |
86 {{build_message(params_struct, params_description)}} | |
87 | |
88 {%- if method.response_parameters != None %} | |
89 mojo::MessageReceiver* responder = | |
90 new {{class_name}}_{{method.name}}_ForwardToCallback(callback); | |
91 if (!receiver_->AcceptWithResponder(builder.message(), responder)) | |
92 delete responder; | |
93 {%- else %} | |
94 bool ok = receiver_->Accept(builder.message()); | |
95 // This return value may be ignored as !ok implies the Connector has | |
96 // encountered an error, which will be visible through other means. | |
97 MOJO_ALLOW_UNUSED_LOCAL(ok); | |
98 {%- endif %} | |
99 } | |
100 {%- endfor %} | |
101 | |
102 {#--- ProxyToResponder definition #} | |
103 {%- for method in interface.methods -%} | |
104 {%- if method.response_parameters != None %} | |
105 {%- set message_name = | |
106 "%s::MessageOrdinals::%s"|format(base_name, method.name) %} | |
107 {%- set response_params_struct = method.response_param_struct %} | |
108 {%- set params_description = | |
109 "%s.%s response"|format(interface.name, method.name) %} | |
110 // This class implements a method's response callback: it serializes the | |
111 // response args into a mojo message and passes it to the MessageReceiver it | |
112 // was created with. | |
113 class {{class_name}}_{{method.name}}_ProxyToResponder | |
114 : public {{class_name}}::{{method.name}}Callback::Runnable { | |
115 public: | |
116 ~{{class_name}}_{{method.name}}_ProxyToResponder() override { | |
117 // Is the Mojo application destroying the callback without running it | |
118 // and without first closing the pipe? | |
119 bool callback_was_dropped = responder_ && responder_->IsValid(); | |
120 // If the Callback was dropped then deleting the responder will close | |
121 // the pipe so the calling application knows to stop waiting for a reply. | |
122 delete responder_; | |
123 MOJO_DCHECK(!callback_was_dropped) << "The callback passed to " | |
124 "{{class_name}}::{{method.name}}({%- if method.parameters -%}{{pass_para
ms(method.parameters)}}, {% endif -%}callback) " | |
125 "was never run."; | |
126 } | |
127 | |
128 {{class_name}}_{{method.name}}_ProxyToResponder( | |
129 uint64_t request_id, | |
130 mojo::MessageReceiverWithStatus* responder) | |
131 : request_id_(request_id), | |
132 responder_(responder) { | |
133 } | |
134 | |
135 void Run({{interface_macros.declare_params_as_args("in_", method.response_para
meters)}}) const override; | |
136 | |
137 private: | |
138 uint64_t request_id_; | |
139 mutable mojo::MessageReceiverWithStatus* responder_; | |
140 MOJO_DISALLOW_COPY_AND_ASSIGN({{class_name}}_{{method.name}}_ProxyToResponder)
; | |
141 }; | |
142 | |
143 void {{class_name}}_{{method.name}}_ProxyToResponder::Run( | |
144 {{interface_macros.declare_params_as_args("in_", method.response_parameters)
}}) const { | |
145 {{struct_macros.get_serialized_size(response_params_struct, "in_%s")}} | |
146 mojo::ResponseMessageBuilder builder( | |
147 static_cast<uint32_t>({{message_name}}), size, request_id_); | |
148 {{build_message(response_params_struct, params_description)}} | |
149 bool ok = responder_->Accept(builder.message()); | |
150 MOJO_ALLOW_UNUSED_LOCAL(ok); | |
151 // TODO(darin): !ok returned here indicates a malformed message, and that may | |
152 // be good reason to close the connection. However, we don't have a way to do | |
153 // that from here. We should add a way. | |
154 delete responder_; | |
155 responder_ = nullptr; | |
156 } | |
157 {%- endif -%} | |
158 {%- endfor %} | |
159 | |
160 {{class_name}}Stub::{{class_name}}Stub() | |
161 : sink_(nullptr), | |
162 control_message_handler_({{interface.name}}::Version_) { | |
163 } | |
164 | |
165 {{class_name}}Stub::~{{interface.name}}Stub() {} | |
166 | |
167 {#--- Stub definition #} | |
168 | |
169 bool {{class_name}}Stub::Accept(mojo::Message* message) { | |
170 if (mojo::internal::ControlMessageHandler::IsControlMessage(message)) | |
171 return control_message_handler_.Accept(message); | |
172 {%- if interface.methods %} | |
173 {{base_name}}::MessageOrdinals method_ordinal = | |
174 static_cast<{{base_name}}::MessageOrdinals>(message->header()->name); | |
175 switch (method_ordinal) { | |
176 {%- for method in interface.methods %} | |
177 case {{base_name}}::MessageOrdinals::{{method.name}}: { | |
178 {%- if method.response_parameters == None %} | |
179 internal::{{class_name}}_{{method.name}}_Params_Data* params = | |
180 reinterpret_cast<internal::{{class_name}}_{{method.name}}_Params_Data*
>( | |
181 message->mutable_payload()); | |
182 | |
183 params->DecodePointersAndHandles(message->mutable_handles()); | |
184 {{alloc_params(method.param_struct)|indent(4)}} | |
185 // A null |sink_| means no implementation was bound. | |
186 assert(sink_); | |
187 sink_->{{method.name}}({{pass_params(method.parameters)}}); | |
188 return true; | |
189 {%- else %} | |
190 break; | |
191 {%- endif %} | |
192 } | |
193 {%- endfor %} | |
194 } | |
195 {%- endif %} | |
196 return false; | |
197 } | |
198 | |
199 bool {{class_name}}Stub::AcceptWithResponder( | |
200 mojo::Message* message, mojo::MessageReceiverWithStatus* responder) { | |
201 if (mojo::internal::ControlMessageHandler::IsControlMessage(message)) | |
202 return control_message_handler_.AcceptWithResponder(message, responder); | |
203 {%- if interface.methods %} | |
204 {{base_name}}::MessageOrdinals method_ordinal = | |
205 static_cast<{{base_name}}::MessageOrdinals>(message->header()->name); | |
206 switch (method_ordinal) { | |
207 {%- for method in interface.methods %} | |
208 case {{base_name}}::MessageOrdinals::{{method.name}}: { | |
209 {%- if method.response_parameters != None %} | |
210 internal::{{class_name}}_{{method.name}}_Params_Data* params = | |
211 reinterpret_cast<internal::{{class_name}}_{{method.name}}_Params_Data*
>( | |
212 message->mutable_payload()); | |
213 | |
214 params->DecodePointersAndHandles(message->mutable_handles()); | |
215 {{class_name}}::{{method.name}}Callback::Runnable* runnable = | |
216 new {{class_name}}_{{method.name}}_ProxyToResponder( | |
217 message->request_id(), responder); | |
218 {{class_name}}::{{method.name}}Callback callback(runnable); | |
219 {{alloc_params(method.param_struct)|indent(4)}} | |
220 // A null |sink_| means no implementation was bound. | |
221 assert(sink_); | |
222 sink_->{{method.name}}( | |
223 {%- if method.parameters -%}{{pass_params(method.parameters)}}, {% endif -%}call
back); | |
224 return true; | |
225 {%- else %} | |
226 break; | |
227 {%- endif %} | |
228 } | |
229 {%- endfor %} | |
230 } | |
231 {%- endif %} | |
232 return false; | |
233 } | |
OLD | NEW |